diff --git a/source/client/gui/MenuWidget.cpp b/source/client/gui/MenuWidget.cpp index a7a38f4cf..d596ecd15 100644 --- a/source/client/gui/MenuWidget.cpp +++ b/source/client/gui/MenuWidget.cpp @@ -76,7 +76,9 @@ TextButton &MenuWidget::addButton(const std::string &text, const TextButton::Cpp TextButton &button = m_buttons.back(); button.setText(text); button.setCallback(callback); + updateButtonPosition(button, x, y); + return button; } diff --git a/source/client/gui/TextButton.cpp b/source/client/gui/TextButton.cpp index d96cde43c..8c23af343 100644 --- a/source/client/gui/TextButton.cpp +++ b/source/client/gui/TextButton.cpp @@ -33,6 +33,14 @@ TextButton::TextButton(u16 width, Widget *parent) : Widget(width, 20, parent) { m_background.setClipRect(0, 66, width, 20); m_hoverBackground.setClipRect(0, 86, width, 20); m_disabledBackground.setClipRect(0, 46, width, 20); + + m_backgroundBorder.setClipRect(200 - 2, 66, 2, 20); + m_hoverBackgroundBorder.setClipRect(200 - 2, 86, 2, 20); + m_disabledBackgroundBorder.setClipRect(200 - 2, 46, 2, 20); + + m_backgroundBorder.setPosition(width - 2, 0); + m_hoverBackgroundBorder.setPosition(width - 2, 0); + m_disabledBackgroundBorder.setPosition(width - 2, 0); } TextButton::TextButton(const CppCallback &callback, Widget *parent) : TextButton(parent) { @@ -45,7 +53,7 @@ void TextButton::onEvent(const sf::Event &event) { if (m_isEnabled && m_isHovered && m_text.color() == gk::Color::White) m_text.setColor({255, 255, 160}); - else if (!m_isHovered && m_text.color() != gk::Color::White) + else if (m_isEnabled && !m_isHovered && m_text.color() != gk::Color::White) m_text.setColor(gk::Color::White); } else if (event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && m_isHovered && m_isEnabled) { @@ -66,12 +74,18 @@ void TextButton::setText(const std::string &text) { void TextButton::draw(gk::RenderTarget &target, gk::RenderStates states) const { states.transform *= getTransform(); - if (!m_isEnabled) + if (!m_isEnabled) { target.draw(m_disabledBackground, states); - else if (m_isHovered) + target.draw(m_disabledBackgroundBorder, states); + } + else if (m_isHovered) { target.draw(m_hoverBackground, states); - else + target.draw(m_hoverBackgroundBorder, states); + } + else { target.draw(m_background, states); + target.draw(m_backgroundBorder, states); + } target.draw(m_text, states); } diff --git a/source/client/gui/TextButton.hpp b/source/client/gui/TextButton.hpp index f569d0013..45d22f0dd 100644 --- a/source/client/gui/TextButton.hpp +++ b/source/client/gui/TextButton.hpp @@ -53,7 +53,11 @@ class TextButton : public Widget { void setCallback(const CppCallback &callback) { m_cppCallback = callback; } void setCallback(const LuaCallback &callback) { m_luaCallback = callback; } - void setEnabled(bool isEnabled) { m_isEnabled = isEnabled; } + void setEnabled(bool isEnabled) { + m_isEnabled = isEnabled; + m_text.setColor(isEnabled ? gk::Color::White : gk::Color{160, 160, 160}); + m_text.setShadowEnabled(isEnabled); + } private: void draw(gk::RenderTarget &target, gk::RenderStates states) const override; @@ -62,6 +66,10 @@ class TextButton : public Widget { gk::Image m_hoverBackground{"texture-widgets"}; gk::Image m_disabledBackground{"texture-widgets"}; + gk::Image m_backgroundBorder{"texture-widgets"}; + gk::Image m_hoverBackgroundBorder{"texture-widgets"}; + gk::Image m_disabledBackgroundBorder{"texture-widgets"}; + Text m_text; CppCallback m_cppCallback; diff --git a/source/client/states/WorldCreationState.cpp b/source/client/states/WorldCreationState.cpp index f412a0c98..c37f32955 100644 --- a/source/client/states/WorldCreationState.cpp +++ b/source/client/states/WorldCreationState.cpp @@ -60,8 +60,8 @@ WorldCreationState::WorldCreationState(TitleScreenState *titleScreen, const std: m_stateStack->pop(); // WorldSelectionState m_stateStack->push(titleScreen); } - - m_stateStack->pop(); + else + m_stateStack->pop(); if (originalName.empty()) titleScreen->startSingleplayer(true, worldName); diff --git a/source/client/states/WorldDeletionState.cpp b/source/client/states/WorldDeletionState.cpp index f98d5bb1a..675eabf9c 100644 --- a/source/client/states/WorldDeletionState.cpp +++ b/source/client/states/WorldDeletionState.cpp @@ -48,7 +48,6 @@ WorldDeletionState::WorldDeletionState(const std::string &worldName, TitleScreen if (fs::exists(saveFilepath)) fs::remove(saveFilepath); m_stateStack->pop(); // WorldDeletionState - m_stateStack->pop(); // WorldMenuState // FIXME: This is needed because there's currently no way to refresh WorldSelectionState m_stateStack->pop(); // WorldSelectionState diff --git a/source/client/states/WorldMenuState.cpp b/source/client/states/WorldMenuState.cpp deleted file mode 100644 index 38e5c7f1e..000000000 --- a/source/client/states/WorldMenuState.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * ===================================================================================== - * - * OpenMiner - * - * Copyright (C) 2018-2020 Unarelith, Quentin Bazin - * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) - * - * This file is part of OpenMiner. - * - * OpenMiner is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * OpenMiner is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with OpenMiner; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * ===================================================================================== - */ -#include -#include - -#include - -#include "Config.hpp" -#include "TitleScreenState.hpp" -#include "WorldDeletionState.hpp" -#include "WorldMenuState.hpp" -#include "WorldCreationState.hpp" -#include "WorldSelectionState.hpp" - -namespace fs = ghc::filesystem; - -WorldMenuState::WorldMenuState(const std::string &worldName, TitleScreenState *titleScreen) : InterfaceState(titleScreen) { - m_menuWidget.setScale(Config::guiScale, Config::guiScale); - - m_menuWidget.addButton("Play", [worldName, titleScreen](TextButton &) { - titleScreen->startSingleplayer(true, worldName); - }); - - m_menuWidget.addButton("Rename", [this, titleScreen, worldName](TextButton &) { - m_stateStack->push(titleScreen, worldName); - }); - - m_menuWidget.addButton("Delete", [this, worldName, titleScreen](TextButton &) { - m_stateStack->push(worldName, titleScreen); - }); - - m_cancelButton.setText("Cancel"); - m_cancelButton.setScale(Config::guiScale, Config::guiScale); - m_cancelButton.setCallback([this](TextButton &) { - m_stateStack->pop(); - }); - - updateWidgetPosition(); -} - -void WorldMenuState::onEvent(const sf::Event &event) { - InterfaceState::onEvent(event); - - if (event.type == sf::Event::Resized && !m_stateStack->empty() && &m_stateStack->top() != this) { - m_menuWidget.onEvent(event); - } - - if (!m_stateStack->empty() && &m_stateStack->top() == this) { - m_menuWidget.onEvent(event); - m_cancelButton.onEvent(event); - } -} - -void WorldMenuState::update() { -} - -void WorldMenuState::updateWidgetPosition() { - m_cancelButton.setPosition(Config::screenWidth / 2.0f - m_cancelButton.getGlobalBounds().sizeX / 2.0f, Config::screenHeight * 0.85); - - m_menuWidget.setPosition( - Config::screenWidth / 2.0 - m_menuWidget.getGlobalBounds().sizeX / 2.0, - Config::screenHeight / 2.0 - m_menuWidget.getGlobalBounds().sizeY / 2.0 - ); -} - -void WorldMenuState::draw(gk::RenderTarget &target, gk::RenderStates states) const { - if (m_parent) - target.draw(*m_parent, states); - - if (&m_stateStack->top() == this) { - prepareDraw(target, states); - - target.draw(m_menuWidget, states); - target.draw(m_cancelButton, states); - } -} diff --git a/source/client/states/WorldMenuState.hpp b/source/client/states/WorldMenuState.hpp deleted file mode 100644 index f932eab9c..000000000 --- a/source/client/states/WorldMenuState.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ===================================================================================== - * - * OpenMiner - * - * Copyright (C) 2018-2020 Unarelith, Quentin Bazin - * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) - * - * This file is part of OpenMiner. - * - * OpenMiner is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * OpenMiner is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with OpenMiner; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * ===================================================================================== - */ -#ifndef WORLDMENUSTATE_HPP_ -#define WORLDMENUSTATE_HPP_ - -#include "InterfaceState.hpp" -#include "MenuWidget.hpp" -#include "TextButton.hpp" - -class TitleScreenState; - -class WorldMenuState : public InterfaceState { - public: - WorldMenuState(const std::string &worldName, TitleScreenState *titleScreen); - - void onEvent(const sf::Event &event) override; - - void update() override; - - private: - void updateWidgetPosition() override; - - void draw(gk::RenderTarget &target, gk::RenderStates states) const override; - - MenuWidget m_menuWidget{1, 4}; - - TextButton m_cancelButton; -}; - -#endif // WORLDMENUSTATE_HPP_ diff --git a/source/client/states/WorldSelectionState.cpp b/source/client/states/WorldSelectionState.cpp index 7ec43ddf1..988f714d7 100644 --- a/source/client/states/WorldSelectionState.cpp +++ b/source/client/states/WorldSelectionState.cpp @@ -32,7 +32,7 @@ #include "Config.hpp" #include "TitleScreenState.hpp" #include "WorldCreationState.hpp" -#include "WorldMenuState.hpp" +#include "WorldDeletionState.hpp" #include "WorldSelectionState.hpp" namespace fs = ghc::filesystem; @@ -41,28 +41,44 @@ WorldSelectionState::WorldSelectionState(TitleScreenState *titleScreen) : InterfaceState(titleScreen), m_titleScreen(titleScreen) { m_title.setScale(Config::guiScale, Config::guiScale); - m_title.setString("Select or create a world"); + m_title.setString("Select World"); m_title.updateVertexBuffer(); m_background.setScale(Config::guiScale * 2, Config::guiScale * 2); - m_filter1.setFillColor(gk::Color(0, 0, 0, 128)); + m_filter1.setFillColor(gk::Color(0, 0, 0, 176)); m_filter2.setFillColor(gk::Color(0, 0, 0, 192)); m_worldList.setScale(Config::guiScale, Config::guiScale); - m_menuWidget.setScale(Config::guiScale, Config::guiScale); - m_menuWidget.addButton("New world", [this](TextButton &) { + m_menuWidget1.setScale(Config::guiScale, Config::guiScale); + m_menuWidget1.addButton("Play Selected World", [this](TextButton &) { + const ScrollableListElement *element = m_worldList.selectedElement(); + if (element) + m_titleScreen->startSingleplayer(true, element->line1()); + }); + m_menuWidget1.addButton("Create New World", [this](TextButton &) { m_stateStack->push(m_titleScreen); - }, 100); - m_menuWidget.addButton("Open", [this](TextButton &) { + }); + + m_menuWidget2.setScale(Config::guiScale, Config::guiScale); + m_menuWidget2.addButton("Edit", [this](TextButton &) { const ScrollableListElement *element = m_worldList.selectedElement(); if (element) - m_stateStack->push(element->line1(), m_titleScreen); - }, 100); - m_menuWidget.addButton("Cancel", [this](TextButton &) { + m_stateStack->push(m_titleScreen, element->line1()); + }, 98); + m_menuWidget2.addButton("Delete", [this](TextButton &) { + const ScrollableListElement *element = m_worldList.selectedElement(); + if (element) + m_stateStack->push(element->line1(), m_titleScreen); + }, 97); + + m_menuWidget3.setScale(Config::guiScale, Config::guiScale); + m_menuWidget3.addButton("Re-Create", [](TextButton &) { + }, 97).setEnabled(false); + m_menuWidget3.addButton("Cancel", [this](TextButton &) { m_stateStack->pop(); - }, 100); + }, 98); updateWidgetPosition(); loadSaveList(); @@ -77,7 +93,10 @@ void WorldSelectionState::onEvent(const sf::Event &event) { if (!m_stateStack->empty() && &m_stateStack->top() == this) { m_worldList.onEvent(event); - m_menuWidget.onEvent(event); + + m_menuWidget1.onEvent(event); + m_menuWidget2.onEvent(event); + m_menuWidget3.onEvent(event); } } @@ -90,23 +109,34 @@ void WorldSelectionState::updateWidgetPosition() { m_filter1.setSize(Config::screenWidth, Config::screenHeight); - const int borderSize = 25 * Config::guiScale; - m_filter2.setSize(Config::screenWidth, Config::screenHeight - borderSize * 2); - m_filter2.setPosition(0, borderSize); + const int topBorderSize = 25 * Config::guiScale; + const int bottomBorderSize = 50 * Config::guiScale; + m_filter2.setSize(Config::screenWidth, Config::screenHeight - topBorderSize - bottomBorderSize); + m_filter2.setPosition(0, topBorderSize); m_title.setPosition( Config::screenWidth / 2.0f - m_title.getSize().x * Config::guiScale / 2.0f, - borderSize / 2 - m_title.getSize().y * Config::guiScale / 2.0f + topBorderSize / 2.0f - m_title.getSize().y * Config::guiScale / 2.0f ); m_worldList.setPosition( Config::screenWidth / 2.0f - m_worldList.getGlobalBounds().sizeX / 2.0f, - borderSize + 2 * Config::guiScale + topBorderSize + 2.0f * Config::guiScale + ); + + m_menuWidget1.setPosition( + Config::screenWidth / 2.0f - m_menuWidget1.getGlobalBounds().sizeX / 2.0f, + Config::screenHeight - bottomBorderSize / 2.0f - m_menuWidget1.getGlobalBounds().sizeY - 2 + ); + + m_menuWidget2.setPosition( + Config::screenWidth / 2.0f - m_menuWidget2.getGlobalBounds().sizeX - 10, + Config::screenHeight - bottomBorderSize / 2.0f + 2 ); - m_menuWidget.setPosition( - Config::screenWidth / 2.0f - m_menuWidget.getGlobalBounds().sizeX / 2.0f, - Config::screenHeight - borderSize / 2 - m_menuWidget.getGlobalBounds().sizeY / 2.0f + m_menuWidget3.setPosition( + Config::screenWidth / 2.0f + 6, + Config::screenHeight - bottomBorderSize / 2.0f + 2 ); } @@ -146,7 +176,9 @@ void WorldSelectionState::draw(gk::RenderTarget &target, gk::RenderStates states target.draw(m_title, states); target.draw(m_worldList, states); - target.draw(m_menuWidget, states); + target.draw(m_menuWidget1, states); + target.draw(m_menuWidget2, states); + target.draw(m_menuWidget3, states); } } diff --git a/source/client/states/WorldSelectionState.hpp b/source/client/states/WorldSelectionState.hpp index 83b35fc28..5d990aedd 100644 --- a/source/client/states/WorldSelectionState.hpp +++ b/source/client/states/WorldSelectionState.hpp @@ -57,7 +57,9 @@ class WorldSelectionState : public InterfaceState { ScrollableList m_worldList; - MenuWidget m_menuWidget{3, 1}; + MenuWidget m_menuWidget1{2, 1}; + MenuWidget m_menuWidget2{2, 1}; + MenuWidget m_menuWidget3{2, 1}; }; #endif // WORLDSELECTIONSTATE_HPP_