From 7c71ce4d1b72d8b522c68be62bfb78c4952c0c88 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Wed, 22 Jul 2020 16:12:21 +0900 Subject: [PATCH] Add starting help info, impl undo tri in progress --- src/imgui_helper.hpp | 33 +++++++++++++++++- src/state.cpp | 81 ++++++++++++++++++++++++++++++++++++++++---- src/state.hpp | 14 +++++--- 3 files changed, 117 insertions(+), 11 deletions(-) diff --git a/src/imgui_helper.hpp b/src/imgui_helper.hpp index 2315c70..9e4186f 100644 --- a/src/imgui_helper.hpp +++ b/src/imgui_helper.hpp @@ -5,6 +5,13 @@ #include "state.hpp" +#define SHOW_HELP_WIDTH (state->get_width() / 2.0f) +#define SHOW_HELP_HEIGHT (state->get_height() / 2.0f) + +#ifndef NDEBUG +# include +#endif + namespace Tri { // Seems misleading, but imgui handles setting up the window during update // so this should be called during update, not draw @@ -14,11 +21,35 @@ namespace Tri { ImGui::SetNextWindowSize(sf::Vector2f( state->get_width() - 20.0f, state->get_height() - 20.0f)); + ImGui::SetNextWindowBgAlpha(0.7f); ImGui::Begin("Help Window", nullptr, ImGuiWindowFlags_NoDecoration); - ImGui::Text("This is the help window."); + ImGui::Text("This is the help window. Press \"H\" to toggle this window."); + ImGui::Text("Click anywhere to create triangles, one point at a time"); + ImGui::Text("Press \"U\" to undo. Clicking will remove all future undo history"); + ImGui::Text("Press \"R\" to undo."); ImGui::End(); } } + + inline void draw_show_help(Tri::State *state) { + float alpha = state->get_starting_help_alpha(); + if(alpha > 0.0f) { + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, alpha); + + ImGui::SetNextWindowPos(sf::Vector2f( + (state->get_width() - SHOW_HELP_WIDTH) / 2.0f, + (state->get_height() - SHOW_HELP_HEIGHT) / 2.0f)); + ImGui::SetNextWindowSize(sf::Vector2f( + SHOW_HELP_WIDTH, + SHOW_HELP_HEIGHT)); + ImGui::Begin("Use Help Window", nullptr, ImGuiWindowFlags_NoDecoration); + ImGui::SetWindowFontScale(3.0f); + ImGui::Text("Press \"H\" for help"); + ImGui::End(); + + ImGui::PopStyleVar(); + } + } } #endif diff --git a/src/state.cpp b/src/state.cpp index 5e84d8d..fae405e 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,18 +1,27 @@ #include "state.hpp" #include +#include #include #include "imgui_helper.hpp" +#define STARTING_HELP_FADE_RATE 0.2f + +#ifndef NDEBUG +# include +#endif + Tri::State::State(int argc, char **argv) : width(800), height(600), dt(sf::microseconds(16666)), +starting_help_alpha(1.0f), window(sf::VideoMode(800, 600), "Triangles", sf::Style::Titlebar | sf::Style::Close), trisIndex(0), -currentTri_state(CurrentState::NONE) +currentTri_state(CurrentState::NONE), +currentTri_maxState(CurrentState::NONE) { flags.set(1); // is running ImGui::SFML::Init(window); @@ -40,23 +49,68 @@ void Tri::State::handle_events() { if(event.key.code == sf::Keyboard::H) { flags.flip(0); } else if(event.key.code == sf::Keyboard::U) { - if(trisIndex > 0) { + if(currentTri_state > 0) { + switch(currentTri_state) { + case FIRST: + currentTri_state = CurrentState::NONE; + break; + case SECOND: + currentTri_state = CurrentState::FIRST; + break; + default: + assert(!"Unreachable code"); + break; + } + } else if(trisIndex > 0) { --trisIndex; } } else if(event.key.code == sf::Keyboard::R) { - if(tris.size() > trisIndex) { + if(currentTri_state != CurrentState::NONE + && currentTri_state < currentTri_maxState) { + switch(currentTri_state) { + case NONE: + currentTri_state = CurrentState::FIRST; + break; + case FIRST: + currentTri_state = CurrentState::SECOND; + break; + default: + assert(!"Unreachable code"); + break; + } + } else if(tris.size() > trisIndex) { ++trisIndex; + } else if(currentTri_state < currentTri_maxState) { + switch(currentTri_state) { + case NONE: + currentTri_state = CurrentState::FIRST; + break; + case FIRST: + currentTri_state = CurrentState::SECOND; + break; + default: + assert(!"Unreachable code"); + break; + } } } } else if(event.type == sf::Event::MouseButtonPressed) { switch(currentTri_state) { case CurrentState::NONE: currentTri[0] = sf::Vector2f(event.mouseButton.x, event.mouseButton.y); + if(trisIndex < tris.size()) { + tris.resize(trisIndex); + } currentTri_state = CurrentState::FIRST; + currentTri_maxState = CurrentState::FIRST; break; case CurrentState::FIRST: currentTri[1] = sf::Vector2f(event.mouseButton.x, event.mouseButton.y); + if(trisIndex < tris.size()) { + tris.resize(trisIndex); + } currentTri_state = CurrentState::SECOND; + currentTri_maxState = CurrentState::SECOND; break; case CurrentState::SECOND: currentTri[2] = sf::Vector2f(event.mouseButton.x, event.mouseButton.y); @@ -70,6 +124,7 @@ void Tri::State::handle_events() { tris.back().setPoint(2, currentTri[2]); tris.back().setFillColor(sf::Color::White); // TODO use chosen color currentTri_state = CurrentState::NONE; + currentTri_maxState = CurrentState::NONE; break; } } @@ -79,7 +134,15 @@ void Tri::State::handle_events() { void Tri::State::update() { ImGui::SFML::Update(window, dt); + if(starting_help_alpha > 0.0f) { + starting_help_alpha -= dt.asSeconds() * STARTING_HELP_FADE_RATE; + if(starting_help_alpha < 0.0f) { + starting_help_alpha = 0.0f; + } + } + // Seems misleading, but imgui handles setting up the window during update + Tri::draw_show_help(this); Tri::draw_help(this); ImGui::EndFrame(); @@ -87,7 +150,6 @@ void Tri::State::update() { void Tri::State::draw() { window.clear(); - ImGui::SFML::Render(window); // draw tris for(unsigned int i = 0; i < trisIndex; ++i) { @@ -100,17 +162,24 @@ void Tri::State::draw() { window.draw(pointCircle); } + // draw gui stuff + ImGui::SFML::Render(window); + window.display(); } -unsigned int Tri::State::get_width() { +unsigned int Tri::State::get_width() const { return width; } -unsigned int Tri::State::get_height() { +unsigned int Tri::State::get_height() const { return height; } const Tri::State::BitsetType Tri::State::get_flags() const { return flags; } + +float Tri::State::get_starting_help_alpha() const { + return starting_help_alpha; +} diff --git a/src/state.hpp b/src/state.hpp index c6a0147..e64cb1a 100644 --- a/src/state.hpp +++ b/src/state.hpp @@ -12,22 +12,26 @@ namespace Tri { public: State(int argc, char **argv); ~State(); + + enum CurrentState {NONE = 0, FIRST = 1, SECOND = 2}; + private: /* * 0 - display help * 1 - is running */ - private: typedef std::bitset<64> BitsetType; BitsetType flags; unsigned int width; unsigned int height; const sf::Time dt; + float starting_help_alpha; sf::RenderWindow window; std::vector tris; unsigned int trisIndex; sf::Vector2f currentTri[3]; - enum CurrentState { NONE = 0, FIRST = 1, SECOND = 2} currentTri_state; + CurrentState currentTri_state; + CurrentState currentTri_maxState; sf::CircleShape pointCircle; sf::Event event; @@ -37,10 +41,12 @@ namespace Tri { void update(); void draw(); - unsigned int get_width(); - unsigned int get_height(); + unsigned int get_width() const; + unsigned int get_height() const; const BitsetType get_flags() const; + + float get_starting_help_alpha() const; }; }