examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

commit 319adf93a20711ce74b1b868952c5919e8f60f4a
parent f09b54a62fa959639adb1d20972e8f4a272dd383
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Fri, 28 Jun 2024 21:43:08 +0100

sdl-gl: Clickable UI

Diffstat:
Msrc/sdl-gl.cpp | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/src/sdl-gl.cpp b/src/sdl-gl.cpp @@ -135,6 +135,11 @@ struct rgb return {r + rhs.r, g + rhs.g, b + rhs.b}; } + rgb& operator *=(float rhs) { r *= rhs; g *= rhs; b *= rhs; return *this; } + rgb& operator /=(float rhs) { r /= rhs; g /= rhs; b /= rhs; return *this; } + rgb operator *(float rhs) const { return rgb{*this} *= rhs; } + rgb operator /(float rhs) const { return rgb{*this} /= rhs; } + static rgb random() { return {dis(gen), dis(gen), dis(gen)}; @@ -196,6 +201,7 @@ struct circle point pan = {0, 0}; +screen_coord mouse_coord; point mouse_pos; struct shp @@ -260,9 +266,18 @@ void presentScene(void) struct panel { screen_coord pos, size; + rgb colour; void draw() const; + bool colliding(screen_coord c) + { + auto br = pos + size; + return c.x >= pos.x && c.y >= pos.y && c.x < br.x && c.y < br.y; + } }; +panel menu; +bool details; + void panel::draw() const { auto tl = window_to_gl(pos); @@ -271,7 +286,7 @@ void panel::draw() const auto br = window_to_gl(pos + size); glBegin(GL_TRIANGLE_STRIP); - glColor3d(.5, .5, .5); + glColor(colour); glVertex(tl); glVertex(tr); glVertex(bl); @@ -289,14 +304,14 @@ void panel::draw() const bl.x += half.x; glBegin(GL_LINE_STRIP); - glColor3d(.25, .25, .25); + glColor(colour / 2.f); glVertex(bl); glVertex(br); glVertex(tr); glEnd(); glBegin(GL_LINE_STRIP); - glColor3d(.7, .7, .7); + glColor(colour * 1.5f); glVertex(bl); glVertex(tl); glVertex(tr); @@ -380,7 +395,8 @@ void key(SDL_KeyboardEvent& e) void mouse_motion(SDL_MouseMotionEvent& e) { - mouse_pos = window_to_local({e.x, e.y}) - pan; + mouse_coord = {e.x, e.y}; + mouse_pos = window_to_local(mouse_coord) - pan; } awaitable_value<SDL_MouseButtonEvent const> click_event; @@ -392,6 +408,12 @@ coroutine_task mouse_task() { SDL_MouseButtonEvent const& e = co_await click_event; point drag_pos = pan - window_to_local({e.x, e.y}); + if (menu.colliding(mouse_coord)) + { + if (e.button == SDL_BUTTON_LEFT) + details = !details; + continue; + } switch (e.button) { case SDL_BUTTON_RIGHT: @@ -522,7 +544,7 @@ void init_shape() shape.wireframe.push_back(i); } { - constexpr int n = 20; + constexpr int n = 64; shapes.emplace_back(); auto& shape = shapes.back(); shape.mode = GL_TRIANGLE_STRIP; @@ -646,11 +668,15 @@ font* fnt; void draw_UI() { std::vector<std::string> strings; + strings.push_back(std::format("scale: {:.2}", scale)); + strings.push_back(std::format(" pan: ({:.1}, {:.1})", pan.x, pan.y)); strings.push_back(std::format("{} shapes", shapes.size())); strings.push_back(std::format("{} objects", objs.size())); - size_t width = 2 + fnt->hdr.width * std::ranges::max(strings | std::views::transform([](auto const& s){ return s.size(); })); - size_t height = 2 + fnt->hdr.height * strings.size(); - panel{0, 0, (int)width, (int)height}.draw(); + int width = (int)(2 + fnt->hdr.width * std::ranges::max(strings | std::views::transform([](auto const& s){ return s.size(); }))); + int height = (int)(2 + fnt->hdr.height * strings.size()); + menu.size = {width, height}; + menu.colour = menu.colliding(mouse_coord) ? rgb{.6, .6, .6} : rgb{.4, .4, .4}; + menu.draw(); glColor3f(0, 0, 0); int y = 1; for (auto const& s : strings) @@ -658,6 +684,28 @@ void draw_UI() fnt->draw(s, {1, y}); y += fnt->hdr.height; } + + if (not details) + return; + + auto x = (int)width; + strings.clear(); + for (auto const& [i, o] : objs | deref | std::views::enumerate) + strings.push_back(std::format("{}: size {}", i, o.pos.radius)); + + if (strings.empty()) + return; + + width = (int)(2 + fnt->hdr.width * std::ranges::max(strings | std::views::transform([](auto const& s){ return s.size(); }))); + height = (int)(2 + fnt->hdr.height * strings.size()); + panel{{x, 0}, {width, height}, rgb{.4, .4, .4}}.draw(); + glColor3f(0, 0, 0); + y = 1; + for (auto const& s : strings) + { + fnt->draw(s, {x + 1, y}); + y += fnt->hdr.height; + } } int main()