diff --git a/common/makefile b/common/makefile index 9fe752a..e2d1029 100644 --- a/common/makefile +++ b/common/makefile @@ -4,5 +4,5 @@ all: $(MAKE) -C graphics $(MAKE) -C map $(MAKE) -C network -# $(MAKE) -C ui + $(MAKE) -C ui $(MAKE) -C utilities diff --git a/common/ui/button.cpp b/common/ui/button.cpp index c794c09..21b8b47 100644 --- a/common/ui/button.cpp +++ b/common/ui/button.cpp @@ -23,59 +23,148 @@ #include -Button::State Button::MouseMotion(SDL_MouseMotionEvent const& motion) { - return CalcState(motion.x, motion.y, motion.state & SDL_BUTTON_LMASK); +void Button::DrawTo(SDL_Renderer* renderer) { + image.SetClipY(image.GetClipH() * state); + image.DrawTo(renderer, posX, posY); } -Button::State Button::MouseButtonDown(SDL_MouseButtonEvent const& button) { - if (button.button == SDL_BUTTON_LEFT) { - return CalcState(button.x, button.y, true); +void Button::SetBackgroundTexture(SDL_Renderer* renderer, SDL_Texture* texture) { + //copy the given texture + image.Free(); + + //a null texture can simply free the image + if (!texture) { + return; } - return state; + + //get the w & h, & create + int w = 0, h = 0; + SDL_QueryTexture(texture, nullptr, nullptr, &w, &h); + image.Create(renderer, w, h); + + //copy + SDL_SetRenderTarget(renderer, image.GetTexture()); + SDL_RenderCopy(renderer, texture, nullptr, nullptr); + SDL_SetRenderTarget(renderer, nullptr); + + //prune + image.SetClipH(image.GetClipH() / 3); } -Button::State Button::MouseButtonUp(SDL_MouseButtonEvent const& button) { - if (button.button == SDL_BUTTON_LEFT) { - return CalcState(button.x, button.y, false); +void Button::SetText(SDL_Renderer* renderer, TTF_Font* font, std::string s, SDL_Color color) { + //make the surface (from SDL_ttf) + SDL_Surface* surf = TTF_RenderText_Solid(font, s.c_str(), color); + if (!surf) { + throw(std::runtime_error("Failed to create a TTF surface")); } - return state; + + //convert to texture + SDL_Texture* text = SDL_CreateTextureFromSurface(renderer, surf); + SDL_FreeSurface(surf); + if (!text) { + throw(std::runtime_error("Failed to create a TTF texture")); + } + + //get the dimensions & rects + int x, y, w, h; + SDL_QueryTexture(text, nullptr, nullptr, &w, &h); + x = (image.GetClipW() - w) / 2; + y = (image.GetClipH() - h) / 2; + SDL_Rect src = {0, 0, w, h}; + SDL_Rect dst; + + //draw the text to the background + SDL_SetRenderTarget(renderer, image.GetTexture()); + + for (int i = 0; i < 3; i++) { + dst = {x, y + image.GetClipH() * i, w, h}; + SDL_RenderCopy(renderer, text, &src, &dst); + } + + SDL_SetRenderTarget(renderer, nullptr); + + //free the texture + SDL_DestroyTexture(text); + + //DEBUG: testing +// image.SetClipH(image.GetClipH() * 3); } -void Button::DrawTo(SDL_Surface* const dest) { - if (!image || !font) { - throw(std::runtime_error("Surface not set for Button")); - } - image->SetClipY(state * image->GetClipH()); - image->DrawTo(dest, x, y); - font->DrawStringTo(text, dest, textX + x, textY + y); +void Button::SetX(int x) { + posX = x; } -std::string Button::SetText(std::string t) { - if (!image || !font) { - throw(std::runtime_error("Surface not set for Button")); - } - //one line, cache the position - text = t; - textX = (image->GetClipW() / 2) - (font->GetCharW() * text.size() / 2); - textY = (image->GetClipH() / 2) - (font->GetCharH() / 2); - return text; +void Button::SetY(int y) { + posY = y; } -Button::State Button::CalcState(Sint16 i, Sint16 j, bool leftPressed) { - if (!image || !font) { - throw(std::runtime_error("Surface not set for Button")); - } - //if out of bounds - if (i < x || i >= (x + image->GetClipW()) || - j < y || j >= (y + image->GetClipH()) - ) { - return state = State::NORMAL; +Button::State Button::MouseMotion(SDL_MouseMotionEvent const& event) { + //if out of bounds, exit + if (!CheckBounds(event.x, event.y)) { + return state = State::IDLE; } - if (leftPressed) { - return state = State::PRESSED; + //if in bounds, check button + if (event.state & SDL_BUTTON_LMASK && state == State::PRESSED) { + //stay pressed +// state = State::PRESSED; } else { - return state = State::HOVER; + state = State::HOVER; } + + return state; } + +Button::State Button::MouseButtonDown(SDL_MouseButtonEvent const& event) { + //if out of bounds, exit + if (!CheckBounds(event.x, event.y)) { + return state = State::IDLE; + } + + //if in bounds, check button + if (event.button == SDL_BUTTON_LEFT) { + return state = State::PRESSED; + } + + //NOTE: if not left button down, ignore + return State::HOVER; +} + +Button::State Button::MouseButtonUp(SDL_MouseButtonEvent const& event) { + //if out of bounds, exit + if (!CheckBounds(event.x, event.y)) { + return state = State::IDLE; + } + + //if not left button up, ignore + if (event.button != SDL_BUTTON_LEFT) { + return state; + } + + //if in bounds and left button up, send release signal + if (state == State::PRESSED) { + state = State::HOVER; + return State::RELEASED; + } + + return state; +} + +void Button::SetState(State s) { + state = s; +} + +Button::State Button::GetState() { + return state; +} + +bool Button::CheckBounds(int x, int y) { + //return if true (x, y) is within bounds, otherwise return false + return !( + x < posX || + y < posY || + x > posX + image.GetClipW() || + y > posY + image.GetClipH() + ); +} \ No newline at end of file diff --git a/common/ui/button.hpp b/common/ui/button.hpp index 16b6cac..71b8e02 100644 --- a/common/ui/button.hpp +++ b/common/ui/button.hpp @@ -21,7 +21,6 @@ */ #pragma once -#include "bounding_box.hpp" #include "image.hpp" #include "SDL2/SDL_ttf.h" @@ -30,29 +29,35 @@ class Button { public: - //states available - enum class State { - NORMAL, HOVER, PRESSED + enum State { + IDLE = 0, HOVER = 1, PRESSED = 2, RELEASED = 3 }; //methods Button() = default; ~Button() = default; - void RenderText(std::string s); - bool CaptureInput(int x, int y, bool pressed); - void DrawTo(SDL_Renderer*, int camX, int camY); + void DrawTo(SDL_Renderer*); - //accessors & mutators - int SetX(int x) { return posX = x; } - int SetY(int y) { return posY = y; } - int GetX() { return posX; } - int GetY() { return posY; } - Image* GetImage() { return ℑ } - BoundingBox* GetBoundingBox() { return &boundingBox; } + //setup + void SetBackgroundTexture(SDL_Renderer*, SDL_Texture*); + void SetText(SDL_Renderer*, TTF_Font*, std::string, SDL_Color); + void SetX(int x); + void SetY(int y); + + //capture input + State MouseMotion(SDL_MouseMotionEvent const&); + State MouseButtonDown(SDL_MouseButtonEvent const&); + State MouseButtonUp(SDL_MouseButtonEvent const&); + + //states + void SetState(State); //TODO: idle, busy or disabled + State GetState(); protected: + bool CheckBounds(int x, int y); + Image image; - BoundingBox boundingBox; int posX = 0, posY = 0; + State state = State::IDLE; }; diff --git a/common/ui/menu_bar.cpp b/common/ui/menu_bar.cpp deleted file mode 100644 index 45358cc..0000000 --- a/common/ui/menu_bar.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#include "menu_bar.hpp" - -#include -#include - -void MenuBar::DrawTo(SDL_Surface* const dest) { - for (auto& i : entries) { - i.DrawTo(dest); - } -} - -void MenuBar::MouseMotion(SDL_MouseMotionEvent const& motion) { - for (auto& i : entries) { - i.MouseMotion(motion); - } -} - -void MenuBar::MouseButtonDown(SDL_MouseButtonEvent const& button) { - for (auto& i : entries) { - i.MouseButtonDown(button); - } -} - -void MenuBar::MouseButtonUp(SDL_MouseButtonEvent const& button, int* entry, int* butt) { - *entry = *butt = -1; - int ret = -1; - for (auto& i : entries) { - ret = i.MouseButtonUp(button); - - if (ret != -1) { - *entry = (&i - entries.data()); - *butt = ret; - } - } -} - -void MenuBar::SetEntries(std::vector> info) { - if (!image || !font) { - throw(std::runtime_error("Surfaces not loaded into the menu bar")); - } - - entries.clear(); - for (int i = 0; i < info.size(); i++) { - //create the entry & the main button - entries.push_back(MenuBarEntry()); - entries[i].mainButton.SetImage(image); - entries[i].mainButton.SetFont(font); - entries[i].mainButton.SetText(info[i][0]); - entries[i].mainButton.SetX(i * image->GetClipW()); - entries[i].mainButton.SetY(0); - for (int j = 0; j < info[i].size()-1; j++) { - //create each drop button in this entry - entries[i].dropButtons.push_back(Button()); - entries[i].dropButtons[j].SetImage(image); - entries[i].dropButtons[j].SetFont(font); - entries[i].dropButtons[j].SetText(info[i][j+1]); - entries[i].dropButtons[j].SetX(i * image->GetClipW()); - entries[i].dropButtons[j].SetY((j+1) * image->GetClipH()); - } - } -} - -void MenuBar::MenuBarEntry::DrawTo(SDL_Surface* const dest) { - //only draw the dropButtons in the user has this menu open - mainButton.DrawTo(dest); - - if (!open) { - return; - } - - for (auto& i : dropButtons) { - i.DrawTo(dest); - } -} - -void MenuBar::MenuBarEntry::MouseMotion(SDL_MouseMotionEvent const& motion) { - //open the menu - bool o = mainButton.MouseMotion(motion) == Button::State::PRESSED; - - if (!(open |= o)) { - return; - } - - for (auto& i : dropButtons) { - //dragging down the menu - o |= i.MouseMotion(motion) == Button::State::PRESSED; - } - - open = o; -} - -void MenuBar::MenuBarEntry::MouseButtonDown(SDL_MouseButtonEvent const& button) { - //open the menu - if (!(open = mainButton.MouseButtonDown(button) == Button::State::PRESSED)) { - return; - } - - //update the others anyway - for (auto& i : dropButtons) { - i.MouseButtonDown(button); - } -} - -int MenuBar::MenuBarEntry::MouseButtonUp(SDL_MouseButtonEvent const& button) { - int ret = -1; - mainButton.MouseButtonUp(button); - - for (auto& i : dropButtons) { - //the user just released this button - if (i.GetState() != i.MouseButtonUp(button) && i.GetState() == Button::State::HOVER && open) { - //get this button's index - ret = (&i - dropButtons.data()); - } - } - - open = false; - return ret; -} diff --git a/common/ui/menu_bar.hpp b/common/ui/menu_bar.hpp deleted file mode 100644 index fa01f9c..0000000 --- a/common/ui/menu_bar.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright: (c) Kayne Ruse 2013-2015 - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. -*/ -#pragma once - -#include "image.hpp" -#include "button.hpp" - -#include -#include - -/* I've redesigned this so that the contents of the menu bar can't change during run time. - * This is more restrictive but I'm focusing on getting this working first. - * The Image and Font pointers must be set before the text data is entered. - * - * This class needs a rewrite. -*/ - -//TODO: This thing is fucking terrible, fix it and the button class -class MenuBar { -public: - MenuBar() = default; - ~MenuBar() = default; - - //yet another draw function - void DrawTo(SDL_Surface* const dest); - - //user inputs - void MouseMotion(SDL_MouseMotionEvent const&); - void MouseButtonDown(SDL_MouseButtonEvent const&); - void MouseButtonUp(SDL_MouseButtonEvent const&, int* entry, int* button); - - //manage the entries & buttons - void SetEntries(std::vector> info); - void ClearEntries() { entries.clear(); } - - //Accessors and mutators - Image* SetImage(Image* const ptr) { return image = ptr; } - Image* GetImage() { return image; } - RasterFont* SetFont(RasterFont* const ptr) { return font = ptr; } - RasterFont* GetFont() { return font; } - -private: - class MenuBarEntry; - - std::vector entries; - - Image* image = nullptr; - RasterFont* font = nullptr; -}; - -class MenuBar::MenuBarEntry { -public: - MenuBarEntry() = default; - ~MenuBarEntry() = default; - - void DrawTo(SDL_Surface* const dest); - - void MouseMotion(SDL_MouseMotionEvent const&); - void MouseButtonDown(SDL_MouseButtonEvent const&); - int MouseButtonUp(SDL_MouseButtonEvent const&); - -private: - Button mainButton; - - std::vector