Skip to content

Commit

Permalink
Add return to main menu and play map buttons to the editor (#9512)
Browse files Browse the repository at this point in the history
  • Loading branch information
zenseii authored Feb 9, 2025
1 parent ab71479 commit 2512018
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 66 deletions.
13 changes: 2 additions & 11 deletions src/fheroes2/dialog/dialog_file.cpp
Original file line number Diff line number Diff line change
@@ -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) 2009 by Andrey Afletdinov <[email protected]> *
Expand Down Expand Up @@ -29,13 +29,11 @@
#include "game_interface.h"
#include "game_mode.h"
#include "icn.h"
#include "image.h"
#include "localevent.h"
#include "screen.h"
#include "settings.h"
#include "translations.h"
#include "ui_button.h"
#include "ui_constants.h"
#include "ui_dialog.h"
#include "ui_window.h"

Expand All @@ -48,13 +46,6 @@ namespace

fheroes2::Display & display = fheroes2::Display::instance();

const int32_t totalDialogWidth = 337;
const int32_t totalDialogHeight = 252;

// Prepare restorer of the adventure map when save feedback dialog is shown.
fheroes2::ImageRestorer back( display, ( display.width() - totalDialogWidth - fheroes2::borderWidthPx ) / 2,
( display.height() - totalDialogHeight + fheroes2::borderWidthPx ) / 2, totalDialogWidth, totalDialogHeight );

fheroes2::StandardWindow background( 289, 204, true, display );

fheroes2::Button buttonNew;
Expand Down Expand Up @@ -107,7 +98,7 @@ namespace
}
else if ( le.MouseClickLeft( buttonSave.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::WORLD_SAVE_GAME ) ) {
// Special case: since we show a window about file saving we don't want to display the current dialog anymore.
back.restore();
background.hideWindow();

return Interface::AdventureMap::Get().EventSaveGame();
}
Expand Down
136 changes: 90 additions & 46 deletions src/fheroes2/editor/editor_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include <string>
#include <vector>

#include "agg_image.h"
#include "artifact.h"
#include "audio_manager.h"
#include "color.h"
Expand All @@ -55,7 +54,6 @@
#include "heroes.h"
#include "history_manager.h"
#include "icn.h"
#include "image.h"
#include "interface_base.h"
#include "interface_border.h"
#include "interface_gamearea.h"
Expand Down Expand Up @@ -86,6 +84,7 @@
#include "ui_map_object.h"
#include "ui_text.h"
#include "ui_tool.h"
#include "ui_window.h"
#include "view_world.h"
#include "world.h"
#include "world_object_uid.h"
Expand Down Expand Up @@ -1149,35 +1148,40 @@ namespace Interface

fheroes2::GameMode EditorInterface::eventFileDialog()
{
const bool isEvilInterface = Settings::Get().isEvilInterfaceEnabled();
const int cpanbkg = isEvilInterface ? ICN::CPANBKGE : ICN::CPANBKG;
const fheroes2::Sprite & background = fheroes2::AGG::GetICN( cpanbkg, 0 );

const CursorRestorer cursorRestorer( true, Cursor::POINTER );

fheroes2::Display & display = fheroes2::Display::instance();

// Since the original image contains shadow it is important to remove it from calculation of window's position.
const fheroes2::Point rb( ( display.width() - background.width() - fheroes2::borderWidthPx ) / 2,
( display.height() - background.height() + fheroes2::borderWidthPx ) / 2 );
fheroes2::ImageRestorer back( display, rb.x, rb.y, background.width(), background.height() );
fheroes2::Blit( background, display, rb.x, rb.y );

fheroes2::Button buttonNew( rb.x + 62, rb.y + 31, isEvilInterface ? ICN::BUTTON_NEW_MAP_EVIL : ICN::BUTTON_NEW_MAP_GOOD, 0, 1 );
fheroes2::Button buttonLoad( rb.x + 195, rb.y + 31, isEvilInterface ? ICN::BUTTON_LOAD_MAP_EVIL : ICN::BUTTON_LOAD_MAP_GOOD, 0, 1 );
fheroes2::Button buttonSave( rb.x + 62, rb.y + 107, isEvilInterface ? ICN::BUTTON_SAVE_MAP_EVIL : ICN::BUTTON_SAVE_MAP_GOOD, 0, 1 );
fheroes2::Button buttonQuit( rb.x + 195, rb.y + 107, isEvilInterface ? ICN::BUTTON_QUIT_EVIL : ICN::BUTTON_QUIT_GOOD, 0, 1 );
fheroes2::Button buttonCancel( rb.x + 128, rb.y + 184, isEvilInterface ? ICN::BUTTON_SMALL_CANCEL_EVIL : ICN::BUTTON_SMALL_CANCEL_GOOD, 0, 1 );

buttonNew.draw();
buttonLoad.draw();
buttonSave.draw();
buttonQuit.draw();
buttonCancel.draw();

display.render( back.rect() );

fheroes2::GameMode result = fheroes2::GameMode::CANCEL;
fheroes2::StandardWindow background( 418 - fheroes2::borderWidthPx * 2, 236 - fheroes2::borderWidthPx * 2, true, display );

fheroes2::Button buttonNew;
fheroes2::Button buttonLoad;
fheroes2::Button buttonSave;
fheroes2::Button buttonQuit;
fheroes2::ButtonSprite buttonMainMenu;
fheroes2::ButtonSprite buttonPlayMap;
fheroes2::Button buttonCancel;

const Settings & conf = Settings::Get();
const bool isEvilInterface = conf.isEvilInterfaceEnabled();

const fheroes2::Point buttonOffsets = { 30, 15 };
background.renderButton( buttonNew, isEvilInterface ? ICN::BUTTON_NEW_MAP_EVIL : ICN::BUTTON_NEW_MAP_GOOD, 0, 1, buttonOffsets,
fheroes2::StandardWindow::Padding::TOP_LEFT );
background.renderButton( buttonLoad, isEvilInterface ? ICN::BUTTON_LOAD_MAP_EVIL : ICN::BUTTON_LOAD_MAP_GOOD, 0, 1, { 0, buttonOffsets.y },
fheroes2::StandardWindow::Padding::TOP_CENTER );
background.renderButton( buttonSave, isEvilInterface ? ICN::BUTTON_SAVE_MAP_EVIL : ICN::BUTTON_SAVE_MAP_GOOD, 0, 1, { buttonOffsets.x, buttonOffsets.y },
fheroes2::StandardWindow::Padding::CENTER_LEFT );
background.renderButton( buttonQuit, isEvilInterface ? ICN::BUTTON_QUIT_EVIL : ICN::BUTTON_QUIT_GOOD, 0, 1, { buttonOffsets.x, buttonOffsets.y },
fheroes2::StandardWindow::Padding::CENTER_RIGHT );
background.renderButtonSprite( buttonMainMenu, gettext_noop( "MAIN\nMENU" ), { buttonSave.area().width - 10, buttonSave.area().height }, { 0, buttonOffsets.y },
isEvilInterface, fheroes2::StandardWindow::Padding::CENTER_CENTER );
background.renderButtonSprite( buttonPlayMap, gettext_noop( "START\nMAP" ), { buttonSave.area().width - 10, buttonSave.area().height },
{ buttonOffsets.x, buttonOffsets.y }, isEvilInterface, fheroes2::StandardWindow::Padding::TOP_RIGHT );
background.renderButton( buttonCancel, isEvilInterface ? ICN::BUTTON_SMALL_CANCEL_EVIL : ICN::BUTTON_SMALL_CANCEL_GOOD, 0, 1, { 0, 11 },
fheroes2::StandardWindow::Padding::BOTTOM_CENTER );

display.render( background.totalArea() );

LocalEvent & le = LocalEvent::Get();

Expand All @@ -1186,36 +1190,75 @@ namespace Interface
buttonLoad.drawOnState( le.isMouseLeftButtonPressedInArea( buttonLoad.area() ) );
buttonSave.drawOnState( le.isMouseLeftButtonPressedInArea( buttonSave.area() ) );
buttonQuit.drawOnState( le.isMouseLeftButtonPressedInArea( buttonQuit.area() ) );
buttonMainMenu.drawOnState( le.isMouseLeftButtonPressedInArea( buttonMainMenu.area() ) );
buttonPlayMap.drawOnState( le.isMouseLeftButtonPressedInArea( buttonPlayMap.area() ) );
buttonCancel.drawOnState( le.isMouseLeftButtonPressedInArea( buttonCancel.area() ) );

if ( le.MouseClickLeft( buttonNew.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_NEW_MAP_MENU ) ) {
if ( eventNewMap() == fheroes2::GameMode::EDITOR_NEW_MAP ) {
result = fheroes2::GameMode::EDITOR_NEW_MAP;
break;
return fheroes2::GameMode::EDITOR_NEW_MAP;
}
}
else if ( le.MouseClickLeft( buttonLoad.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::MAIN_MENU_LOAD_GAME ) ) {
if ( le.MouseClickLeft( buttonLoad.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::MAIN_MENU_LOAD_GAME ) ) {
if ( eventLoadMap() == fheroes2::GameMode::EDITOR_LOAD_MAP ) {
result = fheroes2::GameMode::EDITOR_LOAD_MAP;
break;
return fheroes2::GameMode::EDITOR_LOAD_MAP;
}
}
else if ( le.MouseClickLeft( buttonSave.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::WORLD_SAVE_GAME ) ) {
back.restore();

if ( le.MouseClickLeft( buttonSave.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::WORLD_SAVE_GAME ) ) {
// Special case: since we show a window about file saving we don't want to display the current dialog anymore.
background.hideWindow();
Get().saveMapToFile();

break;
return fheroes2::GameMode::CANCEL;
}

if ( le.MouseClickLeft( buttonQuit.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::MAIN_MENU_QUIT ) ) {
if ( EventExit() == fheroes2::GameMode::QUIT_GAME ) {
result = fheroes2::GameMode::QUIT_GAME;
break;
return fheroes2::GameMode::QUIT_GAME;
}
}
if ( le.MouseClickLeft( buttonMainMenu.area() ) || Game::HotKeyPressEvent( Game::HotKeyEvent::EDITOR_TO_GAME_MAIN_MENU ) ) {
if ( fheroes2::showStandardTextMessage( _( "Main Menu" ),
_( "Do you wish to return to the game's Main Menu? (Any unsaved changes to the current map will be lost.)" ),
Dialog::YES | Dialog::NO )
== Dialog::YES ) {
return fheroes2::GameMode::MAIN_MENU;
}
}
else if ( le.MouseClickLeft( buttonPlayMap.area() ) ) {
bool isNameEmpty = conf.getCurrentMapInfo().name.empty();
if ( isNameEmpty
&& fheroes2::showStandardTextMessage(
_( "Unsaved Changes" ),
_( "This map has either terrain changes, undo history or has not yet been saved to a file.\n\nDo you wish to save the current map?" ),
Dialog::YES | Dialog::NO )
== Dialog::NO ) {
continue;
}
if ( isNameEmpty ) {
Get().saveMapToFile();
isNameEmpty = conf.getCurrentMapInfo().name.empty();
if ( isNameEmpty ) {
// Saving was aborted.
display.render( background.totalArea() );
continue;
}
}
if ( conf.getCurrentMapInfo().colorsAvailableForHumans == 0 ) {
fheroes2::showStandardTextMessage( _( "Unplayable Map" ),
_( "This map is not playable. You need at least one human player for the map to be playable." ), Dialog::OK );
}
else {
if ( fheroes2::
showStandardTextMessage( _( "Start Map" ),
_( "Do you wish to leave the Editor and start the map? (Any unsaved changes to the current map will be lost.)" ),
Dialog::YES | Dialog::NO )
== Dialog::YES ) {
return fheroes2::GameMode::NEW_STANDARD;
}
}
}
else if ( le.MouseClickLeft( buttonCancel.area() ) || Game::HotKeyCloseWindow() ) {
break;
return fheroes2::GameMode::CANCEL;
}

if ( le.isMouseRightButtonPressedInArea( buttonNew.area() ) ) {
Expand All @@ -1232,16 +1275,17 @@ namespace Interface
else if ( le.isMouseRightButtonPressedInArea( buttonQuit.area() ) ) {
fheroes2::showStandardTextMessage( _( "Quit" ), _( "Quit out of the map editor." ), Dialog::ZERO );
}
else if ( le.isMouseRightButtonPressedInArea( buttonMainMenu.area() ) ) {
fheroes2::showStandardTextMessage( _( "Main Menu" ), _( "Return to the game's Main Menu." ), Dialog::ZERO );
}
else if ( le.isMouseRightButtonPressedInArea( buttonPlayMap.area() ) ) {
fheroes2::showStandardTextMessage( _( "Start Map" ), _( "Leave the Editor and play the map in the Standard Game mode." ), Dialog::ZERO );
}
else if ( le.isMouseRightButtonPressedInArea( buttonCancel.area() ) ) {
fheroes2::showStandardTextMessage( _( "Cancel" ), _( "Exit this menu without doing anything." ), Dialog::ZERO );
}
}

// restore background
back.restore();
display.render( back.rect() );

return result;
return fheroes2::GameMode::CANCEL;
}

void EditorInterface::eventViewWorld()
Expand Down
2 changes: 1 addition & 1 deletion src/fheroes2/game/game_scenarioinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ namespace
}
levelCursor.redraw();

display.render();
fheroes2::validateFadeInAndRender();

fheroes2::GameMode result = fheroes2::GameMode::QUIT_GAME;

Expand Down
3 changes: 1 addition & 2 deletions src/fheroes2/gui/ui_button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,8 +900,7 @@ namespace fheroes2
pressedText.draw( pressedOffset.x + 1, pressedOffset.y + ( textAreaHeight - pressedTextSize.height ) / 2, textAreaWidth, pressed );
}

void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface,
const int backgroundIcnId )
void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const Size buttonSize, const bool isEvilInterface, const int backgroundIcnId )
{
fheroes2::Point releasedOffset;
fheroes2::Point pressedOffset;
Expand Down
11 changes: 5 additions & 6 deletions src/fheroes2/gui/ui_button.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,15 +346,14 @@ namespace fheroes2
ButtonSprite makeButtonWithShadow( int32_t offsetX, int32_t offsetY, const Sprite & released, const Sprite & pressed, const Image & background,
const Point & shadowOffset = Point( -4, 6 ) );

// The height of text area is only 16 pixels. If 'isTransparentBackground' is set to false the button sprite will have a default background pattern from
// STONEBAK or STONEBAK_EVIL (for Evil interface). The pattern is the same for all buttons.
// Generate released and pressed button sprites with custom sizes (width and height) for a chosen background ICN.
void getCustomNormalButton( Sprite & released, Sprite & pressed, const bool isEvilInterface, Size buttonSize, Point & releasedOffset, Point & pressedOffset,
const int backgroundIcnId );

// Makes a button that has the width necessary to fit a provided text using an empty button template
// Generates released and pressed button sprites with the width and height necessary to fit a provided text using an empty button template ICN and a chosen background
// ICN.
void getTextAdaptedSprite( Sprite & released, Sprite & pressed, const char * text, const int icnId, const int buttonBackgroundIcnID );

// Generate released and pressed button sprites with the text on it over a transparent or a default (STONEBAK/STONEBAK_EVIL) background.
void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const fheroes2::Size buttonSize, const bool isEvilInterface,
const int backgroundIcnId );
// Generate custom-size released and pressed button sprites with text on them over a chosen background ICN.
void makeButtonSprites( Sprite & released, Sprite & pressed, const std::string & text, const Size buttonSize, const bool isEvilInterface, const int backgroundIcnId );
}
5 changes: 5 additions & 0 deletions src/fheroes2/gui/ui_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ namespace fheroes2

static void renderBackgroundImage( fheroes2::Image & output, const Rect & roi, const int32_t borderOffset, const bool isEvilInterface );

void hideWindow()
{
_restorer.restore();
}

private:
Image & _output;
const Rect _activeArea;
Expand Down

0 comments on commit 2512018

Please sign in to comment.