From f6890e8077133b5dd2cc0a92270d2a328d6c5ab9 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 8 Oct 2022 17:04:40 +0100 Subject: Initial commit of a basic working network editor --- ui/builders/straight.cpp | 40 ++++++++++++++++++++++++ ui/builders/straight.h | 15 +++++++++ ui/editNetwork.cpp | 48 +++++++++++++++++++++++++---- ui/editNetwork.h | 45 ++++++++++++++++++++++++--- ui/gameMainSelector.cpp | 79 ++++++++++++++++++++++++++++++++---------------- ui/gameMainSelector.h | 17 +++++------ ui/gameMainWindow.cpp | 3 +- 7 files changed, 201 insertions(+), 46 deletions(-) create mode 100644 ui/builders/straight.cpp create mode 100644 ui/builders/straight.h diff --git a/ui/builders/straight.cpp b/ui/builders/straight.cpp new file mode 100644 index 0000000..7024746 --- /dev/null +++ b/ui/builders/straight.cpp @@ -0,0 +1,40 @@ +#include "straight.h" +#include + +void +BuilderStraight::render(const Shader &) const +{ +} + +std::string +BuilderStraight::hint() const +{ + if (p1) { + return "Pick straight end point"; + } + return "Pick straight start point"; +} + +void +BuilderStraight::click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) +{ + switch (e.button) { + case SDL_BUTTON_LEFT: + if (const auto p = geoData->intersectRay(ray)) { + if (p1) { + create(network, *p1, *p); + } + p1 = *p; + } + return; + case SDL_BUTTON_MIDDLE: + p1.reset(); + return; + } +} + +void +BuilderStraight::create(Network * network, glm::vec3 p1, glm::vec3 p2) const +{ + network->addStraight(p1, p2); +} diff --git a/ui/builders/straight.h b/ui/builders/straight.h new file mode 100644 index 0000000..77847dd --- /dev/null +++ b/ui/builders/straight.h @@ -0,0 +1,15 @@ +#pragma once +#include "../editNetwork.h" + +class Network; +class GeoData; + +class BuilderStraight : public EditNetwork::Builder { + void render(const Shader &) const override; + std::string hint() const override; + void click(Network * network, const GeoData * geoData, const SDL_MouseButtonEvent & e, const Ray & ray) override; + + void create(Network * network, glm::vec3 p1, glm::vec3 p2) const; + + std::optional p1; +}; diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp index 6cf0eae..a51d7fb 100644 --- a/ui/editNetwork.cpp +++ b/ui/editNetwork.cpp @@ -1,17 +1,53 @@ #include "editNetwork.h" +#include "builders/straight.h" +#include "text.h" +#include +#include -void -EditNetwork::click(const Ray &) +EditNetwork::EditNetwork(Network * n) : + network {n}, builderToolbar { + {"ui/icon/network.png", mode.toggle()}, + } { } -void -EditNetwork::move(const Ray &) +EditNetwork::~EditNetwork() = default; + +bool +EditNetwork::click(const SDL_MouseButtonEvent & e, const Ray & ray) +{ + if (builder) { + builder->click(network, gameState->geoData.get(), e, ray); + return true; + } + return false; +} + +bool +EditNetwork::move(const SDL_MouseMotionEvent &, const Ray &) { + return false; } bool -EditNetwork::handleMove() +EditNetwork::handleInput(const SDL_Event & e, const UIComponent::Position & parentPos) +{ + return builderToolbar.handleInput(e, parentPos); +} + +void +EditNetwork::render(const Shader & shader) const +{ + if (builder) { + builder->render(shader); + } +} + +void +EditNetwork::render(const UIShader & shader, const UIComponent::Position & parentPos) const { - return true; + if (builder) { + Text {builder->hint(), {{50, 10}, {0, 15}}, {1, 1, 0}}.render(shader, parentPos); + } + builderToolbar.render(shader, parentPos); } diff --git a/ui/editNetwork.h b/ui/editNetwork.h index 0a27609..72e0955 100644 --- a/ui/editNetwork.h +++ b/ui/editNetwork.h @@ -1,12 +1,49 @@ #pragma once #include "gameMainSelector.h" +#include "modeHelper.hpp" +#include "toolbar.h" +#include "worldOverlay.h" +#include +#include +#include class Ray; -class EditNetwork : public GameMainSelector::ClickReceiver { +class EditNetwork : public GameMainSelector::Component, public WorldOverlay { public: - void click(const Ray &) override; - void move(const Ray &) override; - bool handleMove() override; + explicit EditNetwork(Network *); + virtual ~EditNetwork(); + + bool click(const SDL_MouseButtonEvent & e, const Ray &) override; + bool move(const SDL_MouseMotionEvent & e, const Ray &) override; + bool handleInput(const SDL_Event & e, const UIComponent::Position &) override; + void render(const Shader &) const override; + void render(const UIShader & shader, const UIComponent::Position & pos) const override; + + using NetworkClickPos = std::variant; + + class Builder { + public: + virtual ~Builder() = default; + virtual void render(const Shader & shader) const = 0; + virtual std::string hint() const = 0; + virtual void click(Network *, const GeoData *, const SDL_MouseButtonEvent &, const Ray &) = 0; + }; + +private: + using BuilderPtr = std::unique_ptr; + + Network * network; + BuilderPtr builder; + Mode mode {builder}; + Toolbar builderToolbar; +}; + +template class EditNetworkOf : public EditNetwork { +public: + template + EditNetworkOf(P &&... p) : EditNetwork(gameState->world.findOrCreate(), std::forward

(p)...) + { + } }; diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp index 5011767..ff9afb7 100644 --- a/ui/gameMainSelector.cpp +++ b/ui/gameMainSelector.cpp @@ -15,43 +15,47 @@ #include GameMainSelector::GameMainSelector(const Camera * c, glm::vec2 size) : UIComponent {{{}, size}}, camera {c} { } +constexpr glm::vec2 TargetPos {5, 45}; void -GameMainSelector::render(const UIShader & shader, const Position & pos) const +GameMainSelector::render(const UIShader & shader, const Position & parentPos) const { + if (target) { + target->render(shader, parentPos + position + TargetPos); + } if (!clicked.empty()) { - Text {clicked, {{50, 10}, {0, 15}}, {1, 1, 0}}.render(shader, pos); + Text {clicked, {{50, 10}, {0, 15}}, {1, 1, 0}}.render(shader, parentPos); } } bool -GameMainSelector::handleInput(const SDL_Event & e, const Position &) +GameMainSelector::handleInput(const SDL_Event & e, const Position & parentPos) { - 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); + const auto getRay = [this](const auto & e) { + const auto mouse = glm::vec2 {e.x, e.y} / position.size; + return camera->unProject(mouse); + }; + if (target) { + switch (e.type) { + case SDL_MOUSEBUTTONDOWN: + if (target->click(e.button, getRay(e.button))) { + return true; } - else { - defaultClick(ray); + break; + case SDL_MOUSEMOTION: + if (target->move(e.motion, getRay(e.motion))) { + return true; } - 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); - - target->move(ray); - return true; - } - break; + break; + } + return target->handleInput(e, parentPos + position + TargetPos); + } + else { + switch (e.type) { + case SDL_MOUSEBUTTONDOWN: + defaultClick(getRay(e.button)); + break; + } } return false; } @@ -75,3 +79,26 @@ GameMainSelector::defaultClick(const Ray & ray) clicked.clear(); } } + +bool +GameMainSelector::Component::click(const SDL_MouseButtonEvent &, const Ray &) +{ + return false; +} + +bool +GameMainSelector::Component::move(const SDL_MouseMotionEvent &, const Ray &) +{ + return false; +} + +bool +GameMainSelector::Component::handleInput(const SDL_Event &, const Position &) +{ + return false; +} + +void +GameMainSelector::Component::render(const UIShader &, const UIComponent::Position &) const +{ +} diff --git a/ui/gameMainSelector.h b/ui/gameMainSelector.h index e0715c9..04f2fd7 100644 --- a/ui/gameMainSelector.h +++ b/ui/gameMainSelector.h @@ -1,5 +1,6 @@ #pragma once +#include "SDL_events.h" #include "special_members.hpp" #include "uiComponent.h" #include @@ -7,20 +8,18 @@ #include class Ray; class UIShader; -union SDL_Event; class Camera; class GameMainSelector : public UIComponent { public: - class ClickReceiver { + class Component { public: - ClickReceiver() = default; - virtual ~ClickReceiver() = default; - DEFAULT_MOVE_COPY(ClickReceiver); + virtual ~Component() = default; - virtual void click(const Ray &) = 0; - virtual void move(const Ray &) = 0; - virtual bool handleMove() = 0; + virtual bool click(const SDL_MouseButtonEvent &, const Ray &); + virtual bool move(const SDL_MouseMotionEvent &, const Ray &); + virtual bool handleInput(const SDL_Event &, const Position & pos); + virtual void render(const UIShader & shader, const Position & pos) const; }; GameMainSelector(const Camera * c, glm::vec2 size); @@ -31,7 +30,7 @@ public: void defaultClick(const Ray & ray); - std::unique_ptr target; + std::unique_ptr target; private: const Camera * camera; diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index daa5494..84d0ca6 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include // IWYU pragma: keep #include #include @@ -22,7 +23,7 @@ public: explicit GameMainToolbar(GameMainSelector * gms_) : Mode {gms_->target}, Toolbar { {"ui/icon/network.png", - toggle()}, + toggle>()}, } { } -- cgit v1.2.3