Skip to content

Commit f5c09f8

Browse files
committed
Merge remote-tracking branch 'origin/egui-input' into egui_with_backend_temp
2 parents 09875ca + 7bae4f3 commit f5c09f8

16 files changed

+432
-99
lines changed

src/gfx/egui/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ endif()
99
add_library(gfx_egui
1010
egui_types.cpp
1111
renderer.cpp
12+
input.cpp
1213
)
1314
target_link_libraries(gfx_egui gfx)
1415

src/gfx/egui/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ fn main() {
1111

1212
let bindings = builder
1313
.header("rust_interop.hpp")
14+
.allowlist_type("egui::.*")
1415
.size_t_is_usize(true)
1516
.layout_tests(false)
1617
.generate()

src/gfx/egui/egui_types.hpp

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,143 @@ struct Vertex {
3232
#endif
3333
};
3434

35+
struct TouchDeviceId {
36+
uint64_t id;
37+
operator uint64_t() const { return id; }
38+
};
39+
40+
struct TouchId {
41+
uint64_t id;
42+
operator uint64_t() const { return id; }
43+
};
44+
45+
enum class InputEventType : uint8_t {
46+
Copy,
47+
Cut,
48+
Paste,
49+
Text,
50+
Key,
51+
PointerMoved,
52+
PointerButton,
53+
PointerGone,
54+
Scroll,
55+
Zoom,
56+
CompositionStart,
57+
CompositionUpdate,
58+
CompositionEnd,
59+
Touch
60+
};
61+
62+
enum class TouchPhase : uint8_t {
63+
Start,
64+
Move,
65+
End,
66+
Cancel,
67+
};
68+
69+
enum class PointerButton : uint8_t {
70+
Primary = 0,
71+
Secondary = 1,
72+
Middle = 2,
73+
};
74+
75+
struct ModifierKeys {
76+
bool alt;
77+
bool ctrl;
78+
bool shift;
79+
bool macCmd;
80+
bool command;
81+
};
82+
83+
union InputEvent {
84+
struct {
85+
InputEventType type;
86+
} common;
87+
struct {
88+
InputEventType type;
89+
} copy;
90+
struct {
91+
InputEventType type;
92+
} cut;
93+
struct {
94+
InputEventType type;
95+
const char *str;
96+
} paste;
97+
struct {
98+
InputEventType type;
99+
const char *str;
100+
} text;
101+
struct {
102+
InputEventType type;
103+
Pos2 pos;
104+
} pointerMoved;
105+
struct {
106+
InputEventType type;
107+
Pos2 pos;
108+
PointerButton button;
109+
bool pressed;
110+
ModifierKeys modifiers;
111+
} pointerButton;
112+
struct {
113+
InputEventType type;
114+
} pointerGone;
115+
struct {
116+
InputEventType type;
117+
Pos2 delta;
118+
} scroll;
119+
struct {
120+
InputEventType type;
121+
float delta;
122+
} zoom;
123+
struct {
124+
InputEventType type;
125+
} compositionStart;
126+
struct {
127+
InputEventType type;
128+
const char *text;
129+
} compositionUpdate;
130+
struct {
131+
InputEventType type;
132+
const char *text;
133+
} compositionEnd;
134+
struct {
135+
InputEventType type;
136+
TouchDeviceId deviceId;
137+
TouchId id;
138+
TouchPhase phase;
139+
Pos2 pos;
140+
float force;
141+
} touch;
142+
};
143+
144+
struct HoveredFile {
145+
const char *path;
146+
const char *mime;
147+
};
148+
149+
struct DroppedFile {
150+
const char *path;
151+
const char *name;
152+
const char *lastModified; // ISO 8601 timestamp / strftime("%FT%TZ")
153+
const uint8_t *data;
154+
size_t dataLength;
155+
};
156+
35157
struct Input {
36-
int cursorPosition[2];
37-
bool mouseButton{};
158+
Rect screenRect;
159+
float pixelsPerPoint;
160+
double time;
161+
float predictedDeltaTime;
162+
ModifierKeys modifierKeys;
163+
164+
const InputEvent *inputEvents;
165+
size_t numInputEvents;
166+
167+
const HoveredFile *hoveredFiles;
168+
size_t numHoveredFiles;
169+
170+
const DroppedFile *droppedFiles;
171+
size_t numDroppedFiles;
38172
};
39173

40174
struct TextureId {

src/gfx/egui/input.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "input.hpp"
2+
#include "../linalg.hpp"
3+
#include <SDL_events.h>
4+
#include <gfx/window.hpp>
5+
#include "renderer.hpp"
6+
7+
namespace gfx {
8+
const egui::Input *EguiInputTranslator::translateFromInputEvents(const std::vector<SDL_Event>& sdlEvents, Window &window, double time,
9+
float deltaTime) {
10+
using egui::InputEvent;
11+
using egui::InputEventType;
12+
13+
float drawScale = EguiRenderer::getDrawScale(window);
14+
float2 screenSize = window.getDrawableSize() / drawScale;
15+
16+
input.screenRect = egui::Rect{
17+
.min = egui::Pos2{0, 0},
18+
.max = egui::Pos2{screenSize.x, screenSize.y},
19+
};
20+
input.pixelsPerPoint = drawScale;
21+
22+
events.clear();
23+
auto newEvent = [&](egui::InputEventType type) -> InputEvent & {
24+
InputEvent &event = events.emplace_back();
25+
event.common.type = type;
26+
return event;
27+
};
28+
29+
SDL_Keymod sdlModifierKeys = SDL_GetModState();
30+
egui::ModifierKeys modifierKeys{
31+
.alt = (sdlModifierKeys & KMOD_ALT) != 0,
32+
.ctrl = (sdlModifierKeys & KMOD_CTRL) != 0,
33+
.shift = (sdlModifierKeys & KMOD_SHIFT) != 0,
34+
.macCmd = (sdlModifierKeys & KMOD_GUI) != 0,
35+
.command = (sdlModifierKeys & KMOD_GUI) != 0,
36+
};
37+
38+
auto updateCursorPosition = [&](int32_t x, int32_t y) -> const egui::Pos2 & {
39+
float2 virtualCursorPosition = float2(x, y) / drawScale;
40+
return lastCursorPosition = egui::Pos2{.x = virtualCursorPosition.x, .y = virtualCursorPosition.y};
41+
};
42+
43+
for (auto &sdlEvent : sdlEvents) {
44+
switch (sdlEvent.type) {
45+
case SDL_MOUSEBUTTONDOWN:
46+
case SDL_MOUSEBUTTONUP: {
47+
auto &ievent = sdlEvent.button;
48+
auto &oevent = newEvent(InputEventType::PointerButton).pointerButton;
49+
switch (ievent.button) {
50+
case SDL_BUTTON_LEFT:
51+
oevent.button = egui::PointerButton::Primary;
52+
break;
53+
case SDL_BUTTON_MIDDLE:
54+
oevent.button = egui::PointerButton::Middle;
55+
break;
56+
case SDL_BUTTON_RIGHT:
57+
oevent.button = egui::PointerButton::Secondary;
58+
break;
59+
default:
60+
// ignore this button
61+
events.pop_back();
62+
continue;
63+
break;
64+
}
65+
oevent.pressed = ievent.type == SDL_MOUSEBUTTONDOWN;
66+
oevent.modifiers = modifierKeys;
67+
oevent.pos = updateCursorPosition(ievent.x, ievent.y);
68+
}
69+
case SDL_MOUSEMOTION: {
70+
auto &ievent = sdlEvent.motion;
71+
auto &oevent = newEvent(InputEventType::PointerMoved).pointerMoved;
72+
oevent.pos = updateCursorPosition(ievent.x, ievent.y);
73+
break;
74+
}
75+
case SDL_MOUSEWHEEL: {
76+
auto &ievent = sdlEvent.wheel;
77+
auto &oevent = newEvent(InputEventType::Scroll).scroll;
78+
oevent.delta = egui::Pos2{
79+
.x = float(ievent.preciseX),
80+
.y = float(ievent.preciseY),
81+
};
82+
break;
83+
}
84+
}
85+
}
86+
87+
input.inputEvents = events.data();
88+
input.numInputEvents = events.size();
89+
90+
input.numDroppedFiles = 0;
91+
input.numHoveredFiles = 0;
92+
93+
input.time = time;
94+
input.predictedDeltaTime = deltaTime;
95+
input.modifierKeys = modifierKeys;
96+
97+
return &input;
98+
}
99+
} // namespace gfx

src/gfx/egui/input.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef CA4EC896_C746_4AC6_A229_560CF01EEFEA
2+
#define CA4EC896_C746_4AC6_A229_560CF01EEFEA
3+
4+
#include "egui_types.hpp"
5+
#include <vector>
6+
7+
namespace gfx {
8+
struct Window;
9+
/// <div rustbindgen opaque></div>
10+
struct EguiInputTranslator {
11+
private:
12+
egui::Input input;
13+
std::vector<std::string> strings;
14+
std::vector<egui::InputEvent> events;
15+
egui::Pos2 lastCursorPosition;
16+
17+
public:
18+
const egui::Input* translateFromInputEvents(const std::vector<SDL_Event>& sdlEvents, Window& window, double time, float deltaTime);
19+
};
20+
} // namespace gfx
21+
22+
#endif /* CA4EC896_C746_4AC6_A229_560CF01EEFEA */

src/gfx/egui/renderer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,8 @@ void EguiRenderer::render(const egui::FullOutput &output, const gfx::DrawQueuePt
193193

194194
EguiRenderer *EguiRenderer::create() { return new EguiRenderer(); }
195195
void EguiRenderer::destroy(EguiRenderer *renderer) { delete renderer; }
196+
float EguiRenderer::getDrawScale(Window &window) {
197+
float2 drawScaleVec = window.getDrawScale();
198+
return std::max<float>(drawScaleVec.x, drawScaleVec.y);
199+
}
196200
} // namespace gfx

src/gfx/egui/renderer.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <memory>
77

88
namespace gfx {
9+
struct Window;
910
struct EguiRendererImpl;
1011

1112
/// <div rustbindgen opaque></div>
@@ -18,6 +19,8 @@ struct EguiRenderer {
1819

1920
static EguiRenderer *create();
2021
static void destroy(EguiRenderer *renderer);
22+
23+
static float getDrawScale(Window& window);
2124
};
2225

2326
} // namespace gfx

src/gfx/egui/rust_interop.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
#include "../rust_interop.hpp"
55
#include "egui_types.hpp"
66
#include "renderer.hpp"
7+
#include "input.hpp"
78

89
#endif /* D51F59C5_BA16_47C5_B59B_0C4D8273CADB */

src/gfx/egui/src/color_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl ColorTest {
107107
}
108108

109109
ui.separator();
110-
/*
110+
111111
self.show_gradients(ui, BLACK, (BLACK, WHITE));
112112
ui.separator();
113113
self.show_gradients(ui, WHITE, (BLACK, TRANSPARENT));
@@ -128,7 +128,7 @@ impl ColorTest {
128128

129129
ui.separator();
130130

131-
blending_and_feathering_test(ui); */
131+
blending_and_feathering_test(ui);
132132
}
133133

134134
fn show_gradients(&mut self, ui: &mut Ui, bg_fill: Color32, (left, right): (Color32, Color32)) {

0 commit comments

Comments
 (0)