diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/editNetwork.cpp | 17 | ||||
-rw-r--r-- | ui/editNetwork.h | 12 | ||||
-rw-r--r-- | ui/gameMainSelector.cpp | 79 | ||||
-rw-r--r-- | ui/gameMainSelector.h | 39 | ||||
-rw-r--r-- | ui/gameMainWindow.cpp | 77 |
5 files changed, 165 insertions, 59 deletions
diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp new file mode 100644 index 0000000..6cf0eae --- /dev/null +++ b/ui/editNetwork.cpp @@ -0,0 +1,17 @@ +#include "editNetwork.h" + +void +EditNetwork::click(const Ray &) +{ +} + +void +EditNetwork::move(const Ray &) +{ +} + +bool +EditNetwork::handleMove() +{ + return true; +} diff --git a/ui/editNetwork.h b/ui/editNetwork.h new file mode 100644 index 0000000..0a27609 --- /dev/null +++ b/ui/editNetwork.h @@ -0,0 +1,12 @@ +#pragma once + +#include "gameMainSelector.h" + +class Ray; + +class EditNetwork : public GameMainSelector::ClickReceiver { +public: + void click(const Ray &) override; + void move(const Ray &) override; + bool handleMove() override; +}; diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp new file mode 100644 index 0000000..635dce0 --- /dev/null +++ b/ui/gameMainSelector.cpp @@ -0,0 +1,79 @@ +#include "gameMainSelector.h" +#include "collection.hpp" +#include "text.h" +#include "ui/uiComponent.h" +#include <SDL2/SDL.h> +#include <game/gamestate.h> +#include <game/geoData.h> +#include <game/selectable.h> +#include <game/worldobject.h> // IWYU pragma: keep +#include <gfx/gl/camera.h> +#include <optional> +#include <span> +#include <stream_support.hpp> +#include <typeinfo> +#include <vector> + +GameMainSelector::GameMainSelector(const Camera * c, glm::vec2 size) : UIComponent {{{}, size}}, camera {c} { } + +void +GameMainSelector::render(const UIShader & shader, const Position & pos) const +{ + if (!clicked.empty()) { + Text {clicked, {{50, 10}, {0, 15}}, {1, 1, 0}}.render(shader, pos); + } +} + +bool +GameMainSelector::handleInput(const SDL_Event & e, const Position &) +{ + switch (e.type) { + case SDL_MOUSEBUTTONDOWN: + if (e.button.button == SDL_BUTTON_LEFT) { + const auto mouse = glm::vec2 {e.button.x, e.button.y} / position.size; + const auto ray = camera->unProject(mouse); + + if (target) { + target->click(ray); + } + else { + defaultClick(ray); + } + return true; + } + break; + + case SDL_MOUSEMOTION: + if (target && target->handleMove()) { + const auto mouse = glm::vec2 {e.motion.x, e.motion.y} / position.size; + const auto ray = camera->unProject(mouse); + + if (target) { + target->move(ray); + } + return true; + } + break; + } + return false; +} + +void +GameMainSelector::defaultClick(const Ray & ray) +{ + glm::vec2 baryPos {}; + float distance; + + if (const auto selected + = gameState->world.applyOne<Selectable>(&Selectable::intersectRay, ray, &baryPos, &distance); + selected != gameState->world.end()) { + const auto & ref = *selected.base()->get(); + clicked = typeid(ref).name(); + } + else if (const auto pos = gameState->geoData->intersectRay(ray)) { + clicked = streamed_string(*pos); + } + else { + clicked.clear(); + } +} diff --git a/ui/gameMainSelector.h b/ui/gameMainSelector.h new file mode 100644 index 0000000..e0715c9 --- /dev/null +++ b/ui/gameMainSelector.h @@ -0,0 +1,39 @@ +#pragma once + +#include "special_members.hpp" +#include "uiComponent.h" +#include <glm/glm.hpp> +#include <memory> +#include <string> +class Ray; +class UIShader; +union SDL_Event; +class Camera; + +class GameMainSelector : public UIComponent { +public: + class ClickReceiver { + public: + ClickReceiver() = default; + virtual ~ClickReceiver() = default; + DEFAULT_MOVE_COPY(ClickReceiver); + + virtual void click(const Ray &) = 0; + virtual void move(const Ray &) = 0; + virtual bool handleMove() = 0; + }; + + GameMainSelector(const Camera * c, glm::vec2 size); + + void render(const UIShader & shader, const Position & pos) const override; + + bool handleInput(const SDL_Event & e, const Position &) override; + + void defaultClick(const Ray & ray); + + std::unique_ptr<ClickReceiver> target; + +private: + const Camera * camera; + std::string clicked; +}; diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index f895a20..3617ca8 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -1,97 +1,56 @@ #include "gameMainWindow.h" +#include "editNetwork.h" +#include "gameMainSelector.h" #include "gfx/camera_controller.h" #include "manualCameraController.h" #include "maths.h" -#include "text.h" #include "toolbar.h" -#include "ui/uiComponent.h" #include "window.h" #include <GL/glew.h> #include <SDL2/SDL.h> #include <collection.hpp> #include <game/gamestate.h> -#include <game/geoData.h> -#include <game/selectable.h> #include <game/worldobject.h> // IWYU pragma: keep #include <gfx/renderable.h> #include <glm/glm.hpp> #include <memory> -#include <optional> -#include <span> -#include <string> -#include <typeinfo> -#include <vector> - -class UIShader; +#include <utility> class GameMainToolbar : public Toolbar { public: - GameMainToolbar() : + explicit GameMainToolbar(GameMainSelector * gms_) : Toolbar { {"ui/icon/network.png", - [](const SDL_Event &) { - // fprintf(stderr, "network click\n"); + [this](const SDL_Event &) { + toggleSetMode<EditNetwork>(); }}, - } + }, + gms {gms_} { } -}; - -#include <stream_support.hpp> - -class GameMainSelector : public UIComponent { -public: - GameMainSelector(const Camera * c, glm::vec2 size) : UIComponent {{{}, size}}, camera {c} { } +private: + template<typename UiMode, typename... Params> void - render(const UIShader & shader, const Position & pos) const override + toggleSetMode(Params &&... params) { - if (!clicked.empty()) { - Text {clicked, {{50, 10}, {0, 15}}, {1, 1, 0}}.render(shader, pos); + if (dynamic_cast<UiMode *>(gms->target.get())) { + gms->target.reset(); } - } - - bool - handleInput(const SDL_Event & e, const Position &) override - { - switch (e.type) { - case SDL_MOUSEBUTTONDOWN: - if (e.button.button == SDL_BUTTON_LEFT) { - const auto mouse = glm::vec2 {e.button.x, e.button.y} / position.size; - - glm::vec2 baryPos {}; - float distance; - - const auto ray = camera->unProject(mouse); - if (const auto selected = gameState->world.applyOne<Selectable>( - &Selectable::intersectRay, ray, &baryPos, &distance); - selected != gameState->world.end()) { - const auto & ref = *selected.base()->get(); - clicked = typeid(ref).name(); - } - else if (const auto pos = gameState->geoData->intersectRay(ray)) { - clicked = streamed_string(*pos); - } - else { - clicked.clear(); - } - return true; - } + else { + gms->target = std::make_unique<UiMode>(std::forward<Params>(params)...); } - return false; } -private: - const Camera * camera; - std::string clicked; + GameMainSelector * gms; }; GameMainWindow::GameMainWindow(size_t w, size_t h) : Window {w, h, "I Like Trains"}, camera {{-1250.0F, -1250.0F, 35.0F}, quarter_pi, rdiv(w, h), 0.1F, 10000.0F} { uiComponents.create<ManualCameraController>(glm::vec2 {-1150, -1150}); - uiComponents.create<GameMainSelector>(&camera, glm::vec2 {w, h}); - uiComponents.create<GameMainToolbar>(); + auto gms = uiComponents.create<GameMainSelector>(&camera, glm::vec2 {w, h}); + uiComponents.create<GameMainToolbar>(gms.get()); shader.setUniform("lightDirection", glm::normalize(glm::vec3 {1, 0, -1})); shader.setUniform("lightColor", {.6, .6, .6}); |