Commit f349d345 authored by Laszlo Agocs's avatar Laszlo Agocs
Browse files

imgui: Add input

parent e22781cd
......@@ -118,6 +118,7 @@ void Window::customInit()
d.ps->build();
d.imgui.initialize(m_r);
d.imgui.setInputEventSource(this);
d.imgui.setFrameFunc([] {
d.imgui.demoWindow();
});
......
......@@ -36,6 +36,8 @@
#include "qrhiimgui_p.h"
#include <QFile>
#include <QMouseEvent>
#include <QKeyEvent>
QT_BEGIN_NAMESPACE
......@@ -90,6 +92,8 @@ bool QRhiImgui::imguiPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, QRhiRende
io.DisplaySize.y = outputSize.height() / dpr;
io.DisplayFramebufferScale = ImVec2(dpr, dpr);
d->updateInput();
ImGui::NewFrame();
if (d->frame)
d->frame();
......@@ -288,6 +292,9 @@ void QRhiImgui::releaseResources()
d->vbuf = d->ibuf = d->ubuf = nullptr;
d->ps = nullptr;
d->sampler = nullptr;
delete d->inputEventFilter;
d->inputEventFilter = nullptr;
}
QRhiImgui::FrameFunc QRhiImgui::frameFunc() const
......@@ -295,6 +302,21 @@ QRhiImgui::FrameFunc QRhiImgui::frameFunc() const
return d->frame;
}
void QRhiImgui::setInputEventSource(QObject *src)
{
if (d->inputEventSource && d->inputEventFilter)
d->inputEventSource->removeEventFilter(d->inputEventFilter);
d->inputEventSource = src;
if (!d->inputEventFilter) {
d->inputEventFilter = new QRhiImGuiInputEventFilter;
d->inputInitialized = false;
}
d->inputEventSource->installEventFilter(d->inputEventFilter);
}
QRhiImguiPrivate::QRhiImguiPrivate()
{
ImGui::CreateContext();
......@@ -305,4 +327,108 @@ QRhiImguiPrivate::~QRhiImguiPrivate()
ImGui::DestroyContext();
}
bool QRhiImGuiInputEventFilter::eventFilter(QObject *, QEvent *event)
{
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
{
QMouseEvent *me = static_cast<QMouseEvent *>(event);
mousePos = me->pos();
mouseButtonsDown = me->buttons();
modifiers = me->modifiers();
}
break;
case QEvent::Wheel:
{
QWheelEvent *we = static_cast<QWheelEvent *>(event);
mouseWheel += we->angleDelta().y() / 120.0f;
}
break;
case QEvent::KeyPress:
case QEvent::KeyRelease:
{
const bool down = event->type() == QEvent::KeyPress;
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
modifiers = ke->modifiers();
if (down)
keyText.append(ke->text());
int k = ke->key();
if (k <= 0xFF)
keyDown[k] = down;
else if (k >= FIRSTSPECKEY && k <= LASTSPECKEY)
keyDown[MAPSPECKEY(k)] = down;
}
break;
default:
break;
}
return false;
}
void QRhiImguiPrivate::updateInput()
{
if (!inputEventFilter)
return;
ImGuiIO &io = ImGui::GetIO();
if (!inputInitialized) {
inputInitialized = true;
io.KeyMap[ImGuiKey_Tab] = MAPSPECKEY(Qt::Key_Tab);
io.KeyMap[ImGuiKey_LeftArrow] = MAPSPECKEY(Qt::Key_Left);
io.KeyMap[ImGuiKey_RightArrow] = MAPSPECKEY(Qt::Key_Right);
io.KeyMap[ImGuiKey_UpArrow] = MAPSPECKEY(Qt::Key_Up);
io.KeyMap[ImGuiKey_DownArrow] = MAPSPECKEY(Qt::Key_Down);
io.KeyMap[ImGuiKey_PageUp] = MAPSPECKEY(Qt::Key_PageUp);
io.KeyMap[ImGuiKey_PageDown] = MAPSPECKEY(Qt::Key_PageDown);
io.KeyMap[ImGuiKey_Home] = MAPSPECKEY(Qt::Key_Home);
io.KeyMap[ImGuiKey_End] = MAPSPECKEY(Qt::Key_End);
io.KeyMap[ImGuiKey_Delete] = MAPSPECKEY(Qt::Key_Delete);
io.KeyMap[ImGuiKey_Backspace] = MAPSPECKEY(Qt::Key_Backspace);
io.KeyMap[ImGuiKey_Enter] = MAPSPECKEY(Qt::Key_Return);
io.KeyMap[ImGuiKey_Escape] = MAPSPECKEY(Qt::Key_Escape);
io.KeyMap[ImGuiKey_A] = Qt::Key_A;
io.KeyMap[ImGuiKey_C] = Qt::Key_C;
io.KeyMap[ImGuiKey_V] = Qt::Key_V;
io.KeyMap[ImGuiKey_X] = Qt::Key_X;
io.KeyMap[ImGuiKey_Y] = Qt::Key_Y;
io.KeyMap[ImGuiKey_Z] = Qt::Key_Z;
}
QRhiImGuiInputEventFilter *w = inputEventFilter;
io.MousePos = ImVec2(w->mousePos.x(), w->mousePos.y());
io.MouseDown[0] = w->mouseButtonsDown.testFlag(Qt::LeftButton);
io.MouseDown[1] = w->mouseButtonsDown.testFlag(Qt::RightButton);
io.MouseDown[2] = w->mouseButtonsDown.testFlag(Qt::MiddleButton);
io.MouseWheel = w->mouseWheel;
w->mouseWheel = 0;
io.KeyCtrl = w->modifiers.testFlag(Qt::ControlModifier);
io.KeyShift = w->modifiers.testFlag(Qt::ShiftModifier);
io.KeyAlt = w->modifiers.testFlag(Qt::AltModifier);
io.KeySuper = w->modifiers.testFlag(Qt::MetaModifier);
memcpy(io.KeysDown, w->keyDown, sizeof(w->keyDown));
if (!w->keyText.isEmpty()) {
for (const QChar &c : w->keyText) {
ImWchar u = c.unicode();
if (u)
io.AddInputCharacter(u);
}
w->keyText.clear();
}
}
QT_END_NAMESPACE
......@@ -59,6 +59,8 @@ public:
void releaseResources();
bool imguiPass(QRhiCommandBuffer *cb, QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp);
void setInputEventSource(QObject *src);
private:
Q_DISABLE_COPY(QRhiImgui)
QRhiImguiPrivate *d = nullptr;
......
......@@ -47,12 +47,36 @@
QT_BEGIN_NAMESPACE
#define FIRSTSPECKEY (0x01000000)
#define LASTSPECKEY (0x01000017)
#define MAPSPECKEY(k) ((k) - FIRSTSPECKEY + 256)
class QRhiImGuiInputEventFilter : public QObject
{
public:
QRhiImGuiInputEventFilter()
{
memset(keyDown, 0, sizeof(keyDown));
}
bool eventFilter(QObject *watched, QEvent *event) override;
QPointF mousePos;
Qt::MouseButtons mouseButtonsDown = Qt::NoButton;
float mouseWheel = 0;
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
bool keyDown[256 + (LASTSPECKEY - FIRSTSPECKEY + 1)];
QString keyText;
};
class QRhiImguiPrivate
{
public:
QRhiImguiPrivate();
~QRhiImguiPrivate();
void updateInput();
QRhiImgui::FrameFunc frame = nullptr;
bool showDemoWindow = true;
......@@ -71,6 +95,10 @@ public:
QRhiGraphicsPipeline *ps = nullptr;
QRhiSampler *sampler = nullptr;
QVector<QRhiResource *> releasePool;
QRhiImGuiInputEventFilter *inputEventFilter = nullptr;
QObject *inputEventSource = nullptr;
bool inputInitialized = false;
};
QT_END_NAMESPACE
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment