From 6915acc81a4039ec4fcac47d7af1b6c76c2cecba Mon Sep 17 00:00:00 2001 From: Zenseii Date: Sun, 26 Jan 2025 14:47:08 +0100 Subject: [PATCH] Add button shine to more buttons (#9471) --- src/fheroes2/agg/agg_image.cpp | 85 +++----- src/fheroes2/agg/icn.h | 2 - src/fheroes2/battle/battle_dialogs.cpp | 183 +++++++----------- src/fheroes2/dialog/dialog_audio.cpp | 46 ++--- src/fheroes2/dialog/dialog_game_settings.cpp | 34 ++-- .../dialog/dialog_graphics_settings.cpp | 33 ++-- src/fheroes2/dialog/dialog_system_options.cpp | 34 ++-- src/fheroes2/editor/editor_options.cpp | 37 ++-- src/fheroes2/gui/ui_button.cpp | 2 + src/fheroes2/gui/ui_option_item.cpp | 3 +- 10 files changed, 163 insertions(+), 296 deletions(-) diff --git a/src/fheroes2/agg/agg_image.cpp b/src/fheroes2/agg/agg_image.cpp index 6fb44aad9e2..ec61f9b10e3 100644 --- a/src/fheroes2/agg/agg_image.cpp +++ b/src/fheroes2/agg/agg_image.cpp @@ -94,8 +94,6 @@ namespace ICN::BUTTON_SMALL_CANCEL_EVIL, ICN::BUTTON_SMALL_OKAY_GOOD, ICN::BUTTON_SMALL_OKAY_EVIL, - ICN::BUTTON_SMALLER_OKAY_GOOD, - ICN::BUTTON_SMALLER_OKAY_EVIL, ICN::BUTTON_SMALL_ACCEPT_GOOD, ICN::BUTTON_SMALL_ACCEPT_EVIL, ICN::BUTTON_SMALL_DECLINE_GOOD, @@ -901,12 +899,10 @@ namespace break; } case ICN::BUTTON_SMALL_OKAY_GOOD: - case ICN::BUTTON_SMALL_OKAY_EVIL: - case ICN::BUTTON_SMALLER_OKAY_GOOD: - case ICN::BUTTON_SMALLER_OKAY_EVIL: { + case ICN::BUTTON_SMALL_OKAY_EVIL: { _icnVsSprite[id].resize( 2 ); - const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_OKAY_EVIL || id == ICN::BUTTON_SMALLER_OKAY_EVIL ); + const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_OKAY_EVIL ); const bool isSameResourceAsLanguage = useOriginalResources(); if ( isSameResourceAsLanguage && ( id == ICN::BUTTON_SMALL_OKAY_EVIL || id == ICN::BUTTON_SMALL_OKAY_GOOD ) ) { @@ -918,20 +914,9 @@ namespace break; } - if ( isSameResourceAsLanguage && ( id == ICN::BUTTON_SMALLER_OKAY_EVIL || id == ICN::BUTTON_SMALLER_OKAY_GOOD ) ) { - _icnVsSprite[id][0] = fheroes2::AGG::GetICN( isEvilInterface ? ICN::WINCMBBE : ICN::WINCMBTB, 0 ); - _icnVsSprite[id][1] = fheroes2::AGG::GetICN( isEvilInterface ? ICN::WINCMBBE : ICN::WINCMBTB, 1 ); - break; - } - int32_t textWidth = 86; - const char * text = gettext_noop( "OKAY" ); - if ( id == ICN::BUTTON_SMALLER_OKAY_EVIL || id == ICN::BUTTON_SMALLER_OKAY_GOOD ) { - textWidth = 70; - text = gettext_noop( "smallerButton|OKAY" ); - } - - createNormalButton( _icnVsSprite[id][0], _icnVsSprite[id][1], textWidth, text, isEvilInterface ); + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK ); break; } @@ -982,21 +967,17 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_LEARN_EVIL ); - const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; if ( useOriginalResources() ) { + const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; _icnVsSprite[id][0] = fheroes2::AGG::GetICN( baseIcnID, 9 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( baseIcnID, 10 ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnID, 11 + i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LEARN" ), { 7, 5 }, { 5, 6 }, { 86, 16 }, buttonFontColor ); + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "LEARN" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } @@ -1021,22 +1002,17 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_YES_EVIL ); - const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; if ( useOriginalResources() ) { + const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; _icnVsSprite[id][0] = fheroes2::AGG::GetICN( baseIcnID, 5 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( baseIcnID, 6 ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnID, 11 + i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "YES" ), { 6, 5 }, { 5, 6 }, { 86, 16 }, buttonFontColor ); - + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "YES" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } case ICN::BUTTON_SMALL_NO_GOOD: @@ -1044,22 +1020,17 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BUTTON_SMALL_NO_EVIL ); - const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; if ( useOriginalResources() ) { + const int baseIcnID = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; _icnVsSprite[id][0] = fheroes2::AGG::GetICN( baseIcnID, 7 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( baseIcnID, 8 ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnID, 11 + i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NO" ), { 6, 5 }, { 5, 6 }, { 86, 16 }, buttonFontColor ); - + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "NO" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } case ICN::BUTTON_SMALL_EXIT_GOOD: @@ -1636,15 +1607,10 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::BTNGIFT_EVIL ); - const int baseIcnId = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, 11 + i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "GIFT" ), { 5, 5 }, { 4, 6 }, { 88, 16 }, buttonFontColor ); + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "GIFT" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } @@ -1917,22 +1883,17 @@ namespace _icnVsSprite[id].resize( 2 ); const bool isEvilInterface = ( id == ICN::UNIFORM_EVIL_OKAY_BUTTON ); - const int baseIcnId = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; if ( useOriginalResources() ) { + const int baseIcnId = isEvilInterface ? ICN::SYSTEME : ICN::SYSTEM; _icnVsSprite[id][0] = fheroes2::AGG::GetICN( baseIcnId, 1 ); _icnVsSprite[id][1] = fheroes2::AGG::GetICN( baseIcnId, 2 ); break; } - for ( int32_t i = 0; i < static_cast( _icnVsSprite[id].size() ); ++i ) { - fheroes2::Sprite & out = _icnVsSprite[id][i]; - out = fheroes2::AGG::GetICN( baseIcnId, 11 + i ); - } - - const fheroes2::FontColor buttonFontColor = isEvilInterface ? fheroes2::FontColor::GRAY : fheroes2::FontColor::WHITE; - renderTextOnButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), { 6, 5 }, { 5, 6 }, { 86, 16 }, buttonFontColor ); - + fheroes2::getTextAdaptedButton( _icnVsSprite[id][0], _icnVsSprite[id][1], gettext_noop( "OKAY" ), + isEvilInterface ? ICN::EMPTY_EVIL_BUTTON : ICN::EMPTY_GOOD_BUTTON, + isEvilInterface ? ICN::UNIFORMBAK_EVIL : ICN::UNIFORMBAK_GOOD ); break; } case ICN::UNIFORM_GOOD_CANCEL_BUTTON: diff --git a/src/fheroes2/agg/icn.h b/src/fheroes2/agg/icn.h index 29825f70ad1..7fb443faeb6 100644 --- a/src/fheroes2/agg/icn.h +++ b/src/fheroes2/agg/icn.h @@ -1036,8 +1036,6 @@ namespace ICN BUTTON_SMALL_CANCEL_EVIL, BUTTON_SMALL_OKAY_GOOD, BUTTON_SMALL_OKAY_EVIL, - BUTTON_SMALLER_OKAY_GOOD, - BUTTON_SMALLER_OKAY_EVIL, BUTTON_SMALL_ACCEPT_GOOD, BUTTON_SMALL_ACCEPT_EVIL, BUTTON_SMALL_DECLINE_GOOD, diff --git a/src/fheroes2/battle/battle_dialogs.cpp b/src/fheroes2/battle/battle_dialogs.cpp index 27c7ff0f27e..2d851702ad0 100644 --- a/src/fheroes2/battle/battle_dialogs.cpp +++ b/src/fheroes2/battle/battle_dialogs.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2019 - 2024 * + * Copyright (C) 2019 - 2025 * * * * Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 * * Copyright (C) 2010 by Andrey Afletdinov * @@ -65,7 +65,6 @@ #include "tools.h" #include "translations.h" #include "ui_button.h" -#include "ui_constants.h" #include "ui_dialog.h" #include "ui_language.h" #include "ui_option_item.h" @@ -77,7 +76,6 @@ namespace { // DialogBattleSummary text related values const int bsTextWidth = 303; - const int bsTextXOffset = 25; const int bsTextYOffset = 160; const int bsTextIndent = 30; @@ -179,6 +177,31 @@ namespace std::queue _queue; }; + void setupAnimation( fheroes2::Display & display, const fheroes2::Rect & animationRoi, LoopedAnimationSequence & sequence ) + { + sequence.push( ICN::WINCMBT, true ); // needs specific for battle summary + const fheroes2::Sprite & sequenceBase = fheroes2::AGG::GetICN( sequence.id(), 0 ); + const fheroes2::Sprite & sequenceStart = fheroes2::AGG::GetICN( sequence.id(), 1 ); + Copy( sequenceBase, 0, 0, display, animationRoi.x, animationRoi.y, sequenceBase.width(), sequenceBase.height() ); + fheroes2::Blit( sequenceStart, display, animationRoi.x + sequenceStart.x(), animationRoi.y + sequenceStart.y() ); + } + + void updateAnimation( fheroes2::Display & display, int & lastSequence, LoopedAnimationSequence & sequence, const fheroes2::Rect & animationRoi ) + { + if ( Game::validateAnimationDelay( Game::BATTLE_DIALOG_DELAY ) && !sequence.nextFrame() ) { + if ( lastSequence != sequence.id() ) { + lastSequence = sequence.id(); + const fheroes2::Sprite & base = fheroes2::AGG::GetICN( lastSequence, 0 ); + + Copy( base, 0, 0, display, animationRoi.x + base.x(), animationRoi.y + base.y(), base.width(), base.height() ); + } + const fheroes2::Sprite & sequenceCurrent = fheroes2::AGG::GetICN( sequence.id(), sequence.frameId() ); + + fheroes2::Blit( sequenceCurrent, display, animationRoi.x + sequenceCurrent.x(), animationRoi.y + sequenceCurrent.y() ); + display.render( animationRoi ); + } + } + enum class DialogAction : int { Open, @@ -246,34 +269,29 @@ namespace DialogAction openBattleOptionDialog( bool & saveConfiguration ) { fheroes2::Display & display = fheroes2::Display::instance(); - LocalEvent & le = LocalEvent::Get(); - Settings & conf = Settings::Get(); // Set the cursor image. This dialog is called from the battlefield and does not require a cursor restorer. // Battlefield event processor will set the appropriate cursor after this dialog is closed. Cursor::Get().SetThemes( Cursor::POINTER ); - const bool isEvilInterface = conf.isEvilInterfaceEnabled(); + fheroes2::StandardWindow background( 289, 382, true, display ); - const fheroes2::Sprite & dialog = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::SPANBKGE : ICN::SPANBKG ), 0 ); - const fheroes2::Sprite & dialogShadow = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::SPANBKGE : ICN::SPANBKG ), 1 ); + const fheroes2::Rect windowRoi = background.activeArea(); - const fheroes2::Point dialogOffset( ( display.width() - dialog.width() ) / 2, ( display.height() - dialog.height() ) / 2 ); - const fheroes2::Point shadowOffset( dialogOffset.x - fheroes2::borderWidthPx, dialogOffset.y ); + Settings & conf = Settings::Get(); + const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - const fheroes2::ImageRestorer back( display, shadowOffset.x, shadowOffset.y, dialog.width() + fheroes2::borderWidthPx, - dialog.height() + fheroes2::borderWidthPx ); - const fheroes2::Rect pos_rt( dialogOffset.x, dialogOffset.y, dialog.width(), dialog.height() ); + fheroes2::Button buttonOk; + const int buttonOkIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + background.renderButton( buttonOk, buttonOkIcnId, 0, 1, { 0, 5 }, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); - fheroes2::Fill( display, pos_rt.x, pos_rt.y, pos_rt.width, pos_rt.height, 0 ); - fheroes2::Blit( dialogShadow, display, pos_rt.x - fheroes2::borderWidthPx, pos_rt.y + fheroes2::borderWidthPx ); - fheroes2::Blit( dialog, display, pos_rt.x, pos_rt.y ); + fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height ); const fheroes2::Sprite & panelSprite = fheroes2::AGG::GetICN( ICN::CSPANEL, 0 ); const int32_t panelWidth = panelSprite.width(); const int32_t panelHeight = panelSprite.height(); - const fheroes2::Point optionOffset( 36 + pos_rt.x, 47 + pos_rt.y ); + const fheroes2::Point optionOffset( windowRoi.x + 20, windowRoi.y + 31 ); const fheroes2::Point optionStep( 92, 110 ); std::vector optionAreas; @@ -285,17 +303,13 @@ namespace } } - const fheroes2::Point buttonOffset( 112 + pos_rt.x, 362 + pos_rt.y ); - fheroes2::Button buttonOkay( buttonOffset.x, buttonOffset.y, isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD, 0, 1 ); - - buttonOkay.draw(); - RedrawBattleSettings( optionAreas ); - display.render(); + display.render( background.totalArea() ); + LocalEvent & le = LocalEvent::Get(); while ( le.HandleEvents() ) { - buttonOkay.drawOnState( le.isMouseLeftButtonPressedInArea( buttonOkay.area() ) ); + buttonOk.drawOnState( le.isMouseLeftButtonPressedInArea( buttonOk.area() ) ); bool redrawScreen = false; @@ -379,19 +393,18 @@ namespace else if ( le.isMouseRightButtonPressedInArea( optionAreas[8] ) ) { fheroes2::showStandardTextMessage( _( "Damage Info" ), _( "Toggle to display damage information during the battle." ), 0 ); } - else if ( le.isMouseRightButtonPressedInArea( buttonOkay.area() ) ) { + else if ( le.isMouseRightButtonPressedInArea( buttonOk.area() ) ) { fheroes2::showStandardTextMessage( _( "Okay" ), _( "Exit this menu." ), 0 ); } - if ( Game::HotKeyCloseWindow() || le.MouseClickLeft( buttonOkay.area() ) ) { + if ( Game::HotKeyCloseWindow() || le.MouseClickLeft( buttonOk.area() ) ) { break; } if ( redrawScreen ) { - fheroes2::Blit( dialog, display, pos_rt.x, pos_rt.y ); + emptyDialogRestorer.restore(); RedrawBattleSettings( optionAreas ); - buttonOkay.draw(); - display.render(); + display.render( emptyDialogRestorer.rect() ); saveConfiguration = true; } @@ -556,11 +569,7 @@ bool Battle::Arena::DialogBattleSummary( const Result & res, const std::vector roi; @@ -146,20 +142,15 @@ namespace Dialog drawDialog( roi ); - const fheroes2::Point buttonOffset( 112 + dialogArea.x, 252 + dialogArea.y ); - fheroes2::Button buttonOkay( buttonOffset.x, buttonOffset.y, isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD, 0, 1 ); - - buttonOkay.draw(); - - display.render(); + display.render( background.totalArea() ); bool saveConfig = false; LocalEvent & le = LocalEvent::Get(); while ( le.HandleEvents() ) { - buttonOkay.drawOnState( le.isMouseLeftButtonPressedInArea( buttonOkay.area() ) ); + buttonOk.drawOnState( le.isMouseLeftButtonPressedInArea( buttonOk.area() ) ); - if ( le.MouseClickLeft( buttonOkay.area() ) || Game::HotKeyCloseWindow() ) { + if ( le.MouseClickLeft( buttonOk.area() ) || Game::HotKeyCloseWindow() ) { break; } @@ -250,15 +241,14 @@ namespace Dialog else if ( le.isMouseRightButtonPressedInArea( audio3D ) ) { fheroes2::showStandardTextMessage( _( "3D Audio" ), _( "Toggle the 3D effect of foreground sounds." ), 0 ); } - else if ( le.isMouseRightButtonPressedInArea( buttonOkay.area() ) ) { + else if ( le.isMouseRightButtonPressedInArea( buttonOk.area() ) ) { fheroes2::showStandardTextMessage( _( "Okay" ), _( "Exit this menu." ), 0 ); } if ( haveSettingsChanged ) { - fheroes2::Blit( dialog, display, dialogArea.x, dialogArea.y ); + emptyDialogRestorer.restore(); drawDialog( roi ); - buttonOkay.draw(); - display.render(); + display.render( background.totalArea() ); saveConfig = true; } diff --git a/src/fheroes2/dialog/dialog_game_settings.cpp b/src/fheroes2/dialog/dialog_game_settings.cpp index 78f95f0b8ec..693796a224b 100644 --- a/src/fheroes2/dialog/dialog_game_settings.cpp +++ b/src/fheroes2/dialog/dialog_game_settings.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2021 - 2024 * + * Copyright (C) 2021 - 2025 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -43,10 +43,10 @@ #include "settings.h" #include "translations.h" #include "ui_button.h" -#include "ui_constants.h" #include "ui_dialog.h" #include "ui_language.h" #include "ui_option_item.h" +#include "ui_window.h" namespace { @@ -65,7 +65,7 @@ namespace const fheroes2::Size offsetBetweenOptions{ 92, 110 }; - const fheroes2::Point optionOffset{ 36, 47 }; + const fheroes2::Point optionOffset{ 20, 31 }; const int32_t optionWindowSize{ 65 }; const fheroes2::Rect languageRoi{ optionOffset.x, optionOffset.y, optionWindowSize, optionWindowSize }; @@ -128,27 +128,19 @@ namespace { fheroes2::Display & display = fheroes2::Display::instance(); - const Settings & conf = Settings::Get(); - const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - const int dialogIcnId = isEvilInterface ? ICN::CSPANBKE : ICN::CSPANBKG; - const fheroes2::Sprite & dialog = fheroes2::AGG::GetICN( dialogIcnId, 0 ); - const fheroes2::Sprite & dialogShadow = fheroes2::AGG::GetICN( dialogIcnId, 1 ); + fheroes2::StandardWindow background( 289, 272, true, display ); - const fheroes2::Point dialogOffset( ( display.width() - dialog.width() ) / 2, ( display.height() - dialog.height() ) / 2 ); - const fheroes2::Point shadowOffset( dialogOffset.x - fheroes2::borderWidthPx, dialogOffset.y ); + const fheroes2::Rect windowRoi = background.activeArea(); - const fheroes2::Rect windowRoi{ dialogOffset.x, dialogOffset.y, dialog.width(), dialog.height() }; - - const fheroes2::ImageRestorer restorer( display, shadowOffset.x, shadowOffset.y, dialog.width() + fheroes2::borderWidthPx, - dialog.height() + fheroes2::borderWidthPx ); + const Settings & conf = Settings::Get(); + const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - fheroes2::Blit( dialogShadow, display, windowRoi.x - fheroes2::borderWidthPx, windowRoi.y + fheroes2::borderWidthPx ); - fheroes2::Blit( dialog, display, windowRoi.x, windowRoi.y ); + fheroes2::Button buttonOk; + const int buttonOkIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + background.renderButton( buttonOk, buttonOkIcnId, 0, 1, { 0, 11 }, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height ); - const int buttonIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; - const fheroes2::Rect windowLanguageRoi( languageRoi + windowRoi.getPosition() ); const fheroes2::Rect windowGraphicsRoi( graphicsRoi + windowRoi.getPosition() ); const fheroes2::Rect windowAudioRoi( audioRoi + windowRoi.getPosition() ); @@ -167,11 +159,7 @@ namespace drawOptions(); - fheroes2::ButtonSprite buttonOk( windowRoi.x + 112, windowRoi.y + 252, fheroes2::AGG::GetICN( buttonIcnId, 0 ), fheroes2::AGG::GetICN( buttonIcnId, 1 ) ); - - buttonOk.draw(); - - display.render(); + display.render( background.totalArea() ); bool isTextSupportModeEnabled = conf.isTextSupportModeEnabled(); diff --git a/src/fheroes2/dialog/dialog_graphics_settings.cpp b/src/fheroes2/dialog/dialog_graphics_settings.cpp index 51ba83d7faf..4a0084ea7e6 100644 --- a/src/fheroes2/dialog/dialog_graphics_settings.cpp +++ b/src/fheroes2/dialog/dialog_graphics_settings.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2022 - 2024 * + * Copyright (C) 2022 - 2025 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -36,10 +36,10 @@ #include "settings.h" #include "translations.h" #include "ui_button.h" -#include "ui_constants.h" #include "ui_dialog.h" #include "ui_option_item.h" #include "ui_text.h" +#include "ui_window.h" namespace { @@ -54,7 +54,7 @@ namespace }; const fheroes2::Size offsetBetweenOptions{ 118, 110 }; - const fheroes2::Point optionOffset{ 69, 47 }; + const fheroes2::Point optionOffset{ 53, 31 }; const int32_t optionWindowSize{ 65 }; const fheroes2::Rect resolutionRoi{ optionOffset.x, optionOffset.y, optionWindowSize, optionWindowSize }; @@ -109,6 +109,7 @@ namespace const bool isSystemInfoDisplayed = Settings::Get().isSystemInfoEnabled(); fheroes2::Sprite image = fheroes2::Crop( fheroes2::AGG::GetICN( ICN::ESPANBKG, 0 ), 69, 47, 65, 65 ); + image.setPosition( 0, 0 ); fheroes2::Text info; if ( isSystemInfoDisplayed ) { info.set( _( "FPS" ), fheroes2::FontType( fheroes2::FontSize::NORMAL, fheroes2::FontColor::YELLOW ) ); @@ -125,21 +126,16 @@ namespace { fheroes2::Display & display = fheroes2::Display::instance(); - const Settings & conf = Settings::Get(); - const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - const fheroes2::Sprite & dialog = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::ESPANBKG_EVIL : ICN::ESPANBKG ), 0 ); - const fheroes2::Sprite & dialogShadow = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::CSPANBKE : ICN::CSPANBKG ), 1 ); + fheroes2::StandardWindow background( 289, 272, true, display ); - const fheroes2::Point dialogOffset( ( display.width() - dialog.width() ) / 2, ( display.height() - dialog.height() ) / 2 ); - const fheroes2::Point shadowOffset( dialogOffset.x - fheroes2::borderWidthPx, dialogOffset.y ); + const fheroes2::Rect windowRoi = background.activeArea(); - const fheroes2::Rect windowRoi{ dialogOffset.x, dialogOffset.y, dialog.width(), dialog.height() }; - - const fheroes2::ImageRestorer restorer( display, shadowOffset.x, shadowOffset.y, dialog.width() + fheroes2::borderWidthPx, - dialog.height() + fheroes2::borderWidthPx ); + const Settings & conf = Settings::Get(); + const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - fheroes2::Blit( dialogShadow, display, windowRoi.x - fheroes2::borderWidthPx, windowRoi.y + fheroes2::borderWidthPx ); - fheroes2::Blit( dialog, display, windowRoi.x, windowRoi.y ); + fheroes2::Button buttonOk; + const int buttonOkIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + background.renderButton( buttonOk, buttonOkIcnId, 0, 1, { 0, 11 }, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height ); @@ -157,12 +153,7 @@ namespace drawOptions(); - const fheroes2::Point buttonOffset( 112 + windowRoi.x, 252 + windowRoi.y ); - fheroes2::Button buttonOk( buttonOffset.x, buttonOffset.y, isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD, 0, 1 ); - - buttonOk.draw(); - - display.render(); + display.render( background.totalArea() ); bool isFullScreen = fheroes2::engine().isFullScreen(); diff --git a/src/fheroes2/dialog/dialog_system_options.cpp b/src/fheroes2/dialog/dialog_system_options.cpp index 093451a348a..1a7e56ff815 100644 --- a/src/fheroes2/dialog/dialog_system_options.cpp +++ b/src/fheroes2/dialog/dialog_system_options.cpp @@ -48,10 +48,10 @@ #include "settings.h" #include "translations.h" #include "ui_button.h" -#include "ui_constants.h" #include "ui_dialog.h" #include "ui_language.h" #include "ui_option_item.h" +#include "ui_window.h" namespace { @@ -68,7 +68,7 @@ namespace }; const fheroes2::Size offsetBetweenOptions{ 92, 110 }; - const fheroes2::Point optionOffset{ 36, 47 }; + const fheroes2::Point optionOffset{ 20, 31 }; const int32_t optionWindowSize{ 65 }; const fheroes2::Rect languageRoi{ optionOffset.x, optionOffset.y, optionWindowSize, optionWindowSize }; @@ -199,25 +199,12 @@ namespace { const CursorRestorer cursorRestorer( true, Cursor::POINTER ); - Settings & conf = Settings::Get(); - const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - fheroes2::Display & display = fheroes2::Display::instance(); - const fheroes2::Sprite & dialog = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::SPANBKGE : ICN::SPANBKG ), 0 ); - const fheroes2::Sprite & dialogShadow = fheroes2::AGG::GetICN( ( isEvilInterface ? ICN::SPANBKGE : ICN::SPANBKG ), 1 ); - - const fheroes2::Point dialogOffset( ( display.width() - dialog.width() ) / 2, ( display.height() - dialog.height() ) / 2 ); - const fheroes2::Point shadowOffset( dialogOffset.x - fheroes2::borderWidthPx, dialogOffset.y ); + fheroes2::StandardWindow background( 289, 382, true, display ); - const fheroes2::ImageRestorer restorer( display, shadowOffset.x, shadowOffset.y, dialog.width() + fheroes2::borderWidthPx, - dialog.height() + fheroes2::borderWidthPx ); - const fheroes2::Rect windowRoi{ dialogOffset.x, dialogOffset.y, dialog.width(), dialog.height() }; - - fheroes2::Blit( dialogShadow, display, windowRoi.x - fheroes2::borderWidthPx, windowRoi.y + fheroes2::borderWidthPx ); - fheroes2::Blit( dialog, display, windowRoi.x, windowRoi.y ); - - fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height ); + const fheroes2::Rect windowRoi = background.activeArea(); + fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height - 30 ); const fheroes2::Rect windowLanguageRoi( languageRoi + windowRoi.getPosition() ); const fheroes2::Rect windowGraphicsRoi( graphicsRoi + windowRoi.getPosition() ); @@ -244,15 +231,16 @@ namespace drawOptions(); - const fheroes2::Point buttonOffset( 112 + windowRoi.x, 362 + windowRoi.y ); - fheroes2::Button buttonOk( buttonOffset.x, buttonOffset.y, isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD, 0, 1 ); + Settings & conf = Settings::Get(); + const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - buttonOk.draw(); + fheroes2::Button buttonOk; + const int buttonOkIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + background.renderButton( buttonOk, buttonOkIcnId, 0, 1, { 0, 5 }, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); - const auto refreshWindow = [&drawOptions, &emptyDialogRestorer, &buttonOk, &display]() { + const auto refreshWindow = [&drawOptions, &emptyDialogRestorer, &display]() { emptyDialogRestorer.restore(); drawOptions(); - buttonOk.draw(); display.render( emptyDialogRestorer.rect() ); }; diff --git a/src/fheroes2/editor/editor_options.cpp b/src/fheroes2/editor/editor_options.cpp index ff5d7e98b01..05a97ffc63f 100644 --- a/src/fheroes2/editor/editor_options.cpp +++ b/src/fheroes2/editor/editor_options.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2024 * + * Copyright (C) 2024 - 2025 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -37,7 +37,6 @@ #include "game_hotkeys.h" #include "game_language.h" #include "icn.h" -#include "image.h" #include "interface_base.h" #include "localevent.h" #include "math_base.h" @@ -46,10 +45,10 @@ #include "settings.h" #include "translations.h" #include "ui_button.h" -#include "ui_constants.h" #include "ui_dialog.h" #include "ui_language.h" #include "ui_option_item.h" +#include "ui_window.h" namespace { @@ -67,7 +66,7 @@ namespace }; const fheroes2::Size offsetBetweenOptions{ 92, 110 }; - const fheroes2::Point optionOffset{ 36, 47 }; + const fheroes2::Point optionOffset{ 20, 31 }; const int32_t optionWindowSize{ 65 }; const fheroes2::Rect languageRoi{ optionOffset.x, optionOffset.y, optionWindowSize, optionWindowSize }; @@ -128,26 +127,9 @@ namespace { fheroes2::Display & display = fheroes2::Display::instance(); - const Settings & conf = Settings::Get(); - const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - const int dialogIcnId = isEvilInterface ? ICN::CSPANBKE : ICN::CSPANBKG; - const fheroes2::Sprite & dialog = fheroes2::AGG::GetICN( dialogIcnId, 0 ); - const fheroes2::Sprite & dialogShadow = fheroes2::AGG::GetICN( dialogIcnId, 1 ); - - const fheroes2::Point dialogOffset( ( display.width() - dialog.width() ) / 2, ( display.height() - dialog.height() ) / 2 ); - const fheroes2::Point shadowOffset( dialogOffset.x - fheroes2::borderWidthPx, dialogOffset.y ); - - const fheroes2::Rect windowRoi{ dialogOffset.x, dialogOffset.y, dialog.width(), dialog.height() }; - - const fheroes2::ImageRestorer restorer( display, shadowOffset.x, shadowOffset.y, dialog.width() + fheroes2::borderWidthPx, - dialog.height() + fheroes2::borderWidthPx ); + fheroes2::StandardWindow background( 289, 272, true, display ); - fheroes2::Blit( dialogShadow, display, windowRoi.x - fheroes2::borderWidthPx, windowRoi.y + fheroes2::borderWidthPx ); - fheroes2::Blit( dialog, display, windowRoi.x, windowRoi.y ); - - const fheroes2::ImageRestorer emptyDialogRestorer( display, windowRoi.x, windowRoi.y, windowRoi.width, windowRoi.height ); - - const int buttonIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + const fheroes2::Rect windowRoi = background.activeArea(); const fheroes2::Rect windowLanguageRoi( languageRoi + windowRoi.getPosition() ); const fheroes2::Rect windowGraphicsRoi( graphicsRoi + windowRoi.getPosition() ); @@ -167,11 +149,14 @@ namespace drawOptions(); - fheroes2::ButtonSprite buttonOk( windowRoi.x + 112, windowRoi.y + 252, fheroes2::AGG::GetICN( buttonIcnId, 0 ), fheroes2::AGG::GetICN( buttonIcnId, 1 ) ); + const Settings & conf = Settings::Get(); + const bool isEvilInterface = conf.isEvilInterfaceEnabled(); - buttonOk.draw(); + fheroes2::Button buttonOk; + const int buttonOkIcnId = isEvilInterface ? ICN::BUTTON_SMALL_OKAY_EVIL : ICN::BUTTON_SMALL_OKAY_GOOD; + background.renderButton( buttonOk, buttonOkIcnId, 0, 1, { 0, 11 }, fheroes2::StandardWindow::Padding::BOTTOM_CENTER ); - display.render(); + display.render( background.totalArea() ); LocalEvent & le = LocalEvent::Get(); while ( le.HandleEvents() ) { diff --git a/src/fheroes2/gui/ui_button.cpp b/src/fheroes2/gui/ui_button.cpp index 3022688f679..6380b7b3887 100644 --- a/src/fheroes2/gui/ui_button.cpp +++ b/src/fheroes2/gui/ui_button.cpp @@ -738,6 +738,8 @@ namespace fheroes2 released = resizeButton( originalReleased, { width, originalReleased.height() } ); pressed = resizeButton( originalPressed, { width, originalPressed.height() } ); + addButtonShine( released, icnId ); + if ( !isTransparentBackground ) { const int backgroundIcnId = isEvilInterface ? ICN::STONEBAK_EVIL : ICN::STONEBAK; makeTransparentBackground( released, pressed, backgroundIcnId ); diff --git a/src/fheroes2/gui/ui_option_item.cpp b/src/fheroes2/gui/ui_option_item.cpp index 9301bd80213..507772c7782 100644 --- a/src/fheroes2/gui/ui_option_item.cpp +++ b/src/fheroes2/gui/ui_option_item.cpp @@ -1,6 +1,6 @@ /*************************************************************************** * fheroes2: https://github.com/ihhub/fheroes2 * - * Copyright (C) 2022 * + * Copyright (C) 2022 - 2025 * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -49,5 +49,6 @@ namespace fheroes2 name.draw( textHorizontalOffset, optionRoi.y + optionRoi.height + nameVerticalOffset, textMaxWidth, display ); Blit( icon, 0, 0, display, optionRoi.x, optionRoi.y, icon.width(), icon.height() ); + fheroes2::addGradientShadow( icon, display, { optionRoi.x, optionRoi.y }, { -5, 5 } ); } }