// SPDX-License-Identifier: MIT // // ES-DE Frontend // ButtonComponent.cpp // // Basic button, used as a GUI element and for the virtual keyboard buttons. // #include "components/ButtonComponent.h" #include "Settings.h" #include "resources/Font.h" #include "utils/StringUtil.h" ButtonComponent::ButtonComponent(const std::string& text, const std::string& helpText, const std::function& func, bool upperCase, bool flatStyle) : mRenderer {Renderer::getInstance()} , mBox {":/graphics/button.svg"} , mPadding {0.0f, 0.0f, 0.0f, 0.0f} , mFocused {false} , mEnabled {true} , mFlatStyle {flatStyle} , mMinWidth {0.0f} , mTextColorFocused {mMenuColorButtonTextFocused} , mTextColorUnfocused {mMenuColorButtonTextUnfocused} , mFlatColorFocused {mMenuColorButtonFlatFocused} , mFlatColorUnfocused {mMenuColorButtonFlatUnfocused} { if (mFlatStyle) { mButtonText = std::make_unique("", Font::get(FONT_SIZE_MEDIUM), 0xFFFFFFFF, ALIGN_CENTER); } else { mButtonText = std::make_unique("DELETE", Font::get(FONT_SIZE_MEDIUM), 0xFFFFFFFF, ALIGN_CENTER); const glm::vec2 textCacheSize {mButtonText->getTextCache() == nullptr ? glm::vec2 {0.0f, 0.0f} : mButtonText->getTextCache()->metrics.size}; mMinWidth = textCacheSize.x + (12.0f * mRenderer->getScreenResolutionModifier()); } mBox.setSharpCorners(true); setPressedFunc(func); setText(text, helpText, upperCase); if (!mFlatStyle) updateImage(); } void ButtonComponent::onSizeChanged() { if (mFlatStyle) return; auto cornerSize = mBox.getCornerSize(); mBox.fitTo(glm::vec2 {mSize.x - mPadding.x - mPadding.z, mSize.y - mPadding.y - mPadding.w}, glm::vec3 {mPadding.x, mPadding.y, 0.0f}, glm::vec2 {-cornerSize.x * 2.0f, -cornerSize.y * 2.0f}); } void ButtonComponent::onFocusGained() { mFocused = true; if (!mFlatStyle) updateImage(); } void ButtonComponent::onFocusLost() { mFocused = false; if (!mFlatStyle) updateImage(); } void ButtonComponent::setText(const std::string& text, const std::string& helpText, bool upperCase, bool resize) { mText = upperCase ? Utils::String::toUpper(text) : text; mHelpText = helpText; mButtonText->setText(mText); if (resize) { setSize( std::max(mButtonText->getSize().x + (12.0f * mRenderer->getScreenResolutionModifier()), mMinWidth), mButtonText->getSize().y); } updateHelpPrompts(); } void ButtonComponent::setEnabled(bool state) { mEnabled = state; if (!mFlatStyle) updateImage(); } void ButtonComponent::setPadding(const glm::vec4 padding) { if (mPadding == padding) return; mPadding = padding; onSizeChanged(); } bool ButtonComponent::input(InputConfig* config, Input input) { if (config->isMappedTo("a", input) && input.value != 0) { if (mPressedFunc && mEnabled) mPressedFunc(); return true; } return GuiComponent::input(config, input); } void ButtonComponent::render(const glm::mat4& parentTrans) { glm::mat4 trans {parentTrans * getTransform()}; if (mFlatStyle) { if (mFocused) { mRenderer->setMatrix(trans); mRenderer->drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z, mSize.y - mPadding.y - mPadding.w, mFlatColorFocused, mFlatColorFocused); } else { mRenderer->setMatrix(trans); mRenderer->drawRect(mPadding.x, mPadding.y, mSize.x - mPadding.x - mPadding.z, mSize.y - mPadding.y - mPadding.w, mFlatColorUnfocused, mFlatColorUnfocused); } } else { mBox.render(trans); } const glm::vec3 centerOffset {(mSize.x - mButtonText->getSize().x) / 2.0f, (mSize.y - mButtonText->getSize().y) / 2.0f, 0.0f}; trans = glm::translate(trans, glm::round(centerOffset)); if (Settings::getInstance()->getBool("DebugText")) { mButtonText->setDebugRendering(false); mRenderer->drawRect(centerOffset.x, 0.0f, mButtonText->getSize().x, mSize.y, 0x00000033, 0x00000033); mRenderer->drawRect(mBox.getPosition().x, 0.0f, mBox.getSize().x, mSize.y, 0x0000FF33, 0x0000FF33); } mButtonText->setColor(getCurTextColor()); mButtonText->render(trans); } std::vector ButtonComponent::getHelpPrompts() { std::vector prompts; prompts.push_back(HelpPrompt("a", mHelpText.empty() ? mText.c_str() : mHelpText.c_str())); return prompts; } unsigned int ButtonComponent::getCurTextColor() const { if (!mFocused) return mTextColorUnfocused; else return mTextColorFocused; } void ButtonComponent::updateImage() { if (!mEnabled || !mPressedFunc) { mBox.setImagePath(":/graphics/button_filled.svg"); mBox.setFrameColor(0x770000FF); return; } mBox.setFrameColor(mMenuColorButtonFocused); mBox.setImagePath(mFocused ? ":/graphics/button_filled.svg" : ":/graphics/button.svg"); }