2012-06-29 16:44:26 +02:00
//////////////////////////////////////////////////////////////////////
// This file is part of Remere's Map Editor
//////////////////////////////////////////////////////////////////////
2020-07-30 11:42:28 -03:00
// Remere's Map Editor is free software: you can redistribute it and/or modify
2012-06-29 16:44:26 +02:00
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
2016-09-29 19:24:45 -03:00
//
2020-07-30 11:42:28 -03:00
// Remere's Map Editor is distributed in the hope that it will be useful,
2012-06-29 16:44:26 +02:00
// but WITHOUT ANY WARRANTY; without even the implied warranty of
2020-07-30 11:42:28 -03:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2012-06-29 16:44:26 +02:00
// GNU General Public License for more details.
2016-09-29 19:24:45 -03:00
//
2012-06-29 16:44:26 +02:00
// You should have received a copy of the GNU General Public License
2020-07-30 11:42:28 -03:00
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2012-06-29 16:44:26 +02:00
//////////////////////////////////////////////////////////////////////
# include "main.h"
# include "application.h"
# include "sprites.h"
# include "editor.h"
# include "common_windows.h"
# include "palette_window.h"
# include "preferences.h"
# include "result_window.h"
# include "minimap_window.h"
# include "about_window.h"
# include "main_menubar.h"
# include "updater.h"
2019-06-04 17:42:28 -03:00
# include "artprovider.h"
2012-06-29 16:44:26 +02:00
# include "materials.h"
# include "map.h"
# include "complexitem.h"
2021-05-25 00:29:12 -03:00
# include "monster.h"
# include "npc.h"
2012-06-29 16:44:26 +02:00
2020-09-14 17:55:04 -03:00
# if defined(__LINUX__) || defined(__WINDOWS__)
2023-10-09 19:12:16 -07:00
# include <GL/glut.h>
2016-12-10 13:13:22 -03:00
# endif
2015-12-06 09:59:50 -03:00
# include "../brushes/icon/rme_icon.xpm"
2012-06-29 16:44:26 +02:00
BEGIN_EVENT_TABLE ( MainFrame , wxFrame )
2023-10-09 19:12:16 -07:00
EVT_CLOSE ( MainFrame : : OnExit )
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
// Update check complete
2012-06-29 16:44:26 +02:00
# ifdef _USE_UPDATER_
2023-10-09 19:12:16 -07:00
EVT_ON_UPDATE_CHECK_FINISHED ( wxID_ANY , MainFrame : : OnUpdateReceived )
2012-06-29 16:44:26 +02:00
# endif
2023-10-09 19:12:16 -07:00
EVT_ON_UPDATE_MENUS ( wxID_ANY , MainFrame : : OnUpdateMenus )
EVT_ON_UPDATE_ACTIONS ( wxID_ANY , MainFrame : : OnUpdateActions )
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
// Idle event handler
EVT_IDLE ( MainFrame : : OnIdle )
2012-06-29 16:44:26 +02:00
END_EVENT_TABLE ( )
BEGIN_EVENT_TABLE ( MapWindow , wxPanel )
2023-10-09 19:12:16 -07:00
EVT_SIZE ( MapWindow : : OnSize )
EVT_COMMAND_SCROLL_TOP ( MAP_WINDOW_HSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_BOTTOM ( MAP_WINDOW_HSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_THUMBTRACK ( MAP_WINDOW_HSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_LINEUP ( MAP_WINDOW_HSCROLL , MapWindow : : OnScrollLineUp )
EVT_COMMAND_SCROLL_LINEDOWN ( MAP_WINDOW_HSCROLL , MapWindow : : OnScrollLineDown )
EVT_COMMAND_SCROLL_PAGEUP ( MAP_WINDOW_HSCROLL , MapWindow : : OnScrollPageUp )
EVT_COMMAND_SCROLL_PAGEDOWN ( MAP_WINDOW_HSCROLL , MapWindow : : OnScrollPageDown )
EVT_COMMAND_SCROLL_TOP ( MAP_WINDOW_VSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_BOTTOM ( MAP_WINDOW_VSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_THUMBTRACK ( MAP_WINDOW_VSCROLL , MapWindow : : OnScroll )
EVT_COMMAND_SCROLL_LINEUP ( MAP_WINDOW_VSCROLL , MapWindow : : OnScrollLineUp )
EVT_COMMAND_SCROLL_LINEDOWN ( MAP_WINDOW_VSCROLL , MapWindow : : OnScrollLineDown )
EVT_COMMAND_SCROLL_PAGEUP ( MAP_WINDOW_VSCROLL , MapWindow : : OnScrollPageUp )
EVT_COMMAND_SCROLL_PAGEDOWN ( MAP_WINDOW_VSCROLL , MapWindow : : OnScrollPageDown )
EVT_BUTTON ( MAP_WINDOW_GEM , MapWindow : : OnGem )
2012-06-29 16:44:26 +02:00
END_EVENT_TABLE ( )
BEGIN_EVENT_TABLE ( MapScrollBar , wxScrollBar )
2023-10-09 19:12:16 -07:00
EVT_KEY_DOWN ( MapScrollBar : : OnKey )
EVT_KEY_UP ( MapScrollBar : : OnKey )
EVT_CHAR ( MapScrollBar : : OnKey )
EVT_SET_FOCUS ( MapScrollBar : : OnFocus )
EVT_MOUSEWHEEL ( MapScrollBar : : OnWheel )
2012-06-29 16:44:26 +02:00
END_EVENT_TABLE ( )
2012-07-01 13:41:59 +02:00
wxIMPLEMENT_APP ( Application ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
Application : : ~ Application ( ) {
2012-06-29 16:44:26 +02:00
// Destroy
}
2023-10-09 19:12:16 -07:00
bool Application : : OnInit ( ) {
2014-01-22 20:16:17 +01:00
# if defined __DEBUG_MODE__ && defined __WINDOWS__
2023-10-09 19:12:16 -07:00
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ) ;
2012-06-29 16:44:26 +02:00
# endif
2014-01-24 02:33:09 -02:00
std : : cout < < " This is free software: you are free to change and redistribute it. " < < std : : endl ;
std : : cout < < " There is NO WARRANTY, to the extent permitted by law. " < < std : : endl ;
std : : cout < < " Review COPYING in RME distribution for details. " < < std : : endl ;
2014-01-22 20:16:17 +01:00
mt_seed ( time ( nullptr ) ) ;
srand ( time ( nullptr ) ) ;
2012-06-29 16:44:26 +02:00
2014-01-24 02:33:09 -02:00
// Discover data directory
2016-09-29 20:30:54 -03:00
g_gui . discoverDataDirectory ( " clients.xml " ) ;
2014-01-24 02:33:09 -02:00
2012-06-29 16:44:26 +02:00
// Tell that we are the real thing
wxAppConsole : : SetInstance ( this ) ;
2019-06-04 17:42:28 -03:00
wxArtProvider : : Push ( new ArtProvider ( ) ) ;
2016-09-29 19:24:45 -03:00
2020-09-14 17:55:04 -03:00
# if defined(__LINUX__) || defined(__WINDOWS__)
2016-12-10 13:13:22 -03:00
int argc = 1 ;
2023-10-13 20:26:41 -03:00
char * arg = strdup ( wxString ( this - > argv [ 0 ] ) . char_str ( ) ) ;
char * argv [ ] = { arg } ;
2016-12-10 13:13:22 -03:00
glutInit ( & argc , argv ) ;
2023-10-13 20:26:41 -03:00
free ( arg ) ;
2016-12-10 13:13:22 -03:00
# endif
2012-06-29 16:44:26 +02:00
// Load some internal stuff
2016-09-29 20:37:43 -03:00
g_settings . load ( ) ;
2012-06-29 16:44:26 +02:00
FixVersionDiscrapencies ( ) ;
2016-09-29 20:30:54 -03:00
g_gui . LoadHotkeys ( ) ;
2012-06-29 16:44:26 +02:00
ClientVersion : : loadVersions ( ) ;
# ifdef _USE_PROCESS_COM
2023-10-09 19:12:16 -07:00
m_single_instance_checker = newd wxSingleInstanceChecker ; // Instance checker has to stay alive throughout the applications lifetime
2017-01-22 14:12:32 +01:00
if ( g_settings . getInteger ( Config : : ONLY_ONE_INSTANCE ) & & m_single_instance_checker - > IsAnotherRunning ( ) ) {
RMEProcessClient client ;
wxConnectionBase * connection = client . MakeConnection ( " localhost " , " rme_host " , " rme_talk " ) ;
if ( connection ) {
wxString fileName ;
if ( ParseCommandLineMap ( fileName ) ) {
2023-10-09 19:12:16 -07:00
wxLogNull nolog ; // We might get a timeout message if the file fails to open on the running instance. Let's not show that message.
2017-01-22 14:12:32 +01:00
connection - > Execute ( fileName ) ;
2012-06-29 16:44:26 +02:00
}
2017-01-22 14:12:32 +01:00
connection - > Disconnect ( ) ;
wxDELETE ( connection ) ;
2012-06-29 16:44:26 +02:00
}
2017-01-22 14:12:32 +01:00
wxDELETE ( m_single_instance_checker ) ;
2023-10-09 19:12:16 -07:00
return false ; // Since we return false - OnExit is never called
2017-01-22 14:12:32 +01:00
}
// We act as server then
m_proc_server = newd RMEProcessServer ( ) ;
2023-10-09 19:12:16 -07:00
if ( ! m_proc_server - > Create ( " rme_host " ) ) {
2017-01-22 14:12:32 +01:00
wxLogWarning ( " Could not register IPC service! " ) ;
2012-06-29 16:44:26 +02:00
}
# endif
// Image handlers
2023-10-09 19:12:16 -07:00
// wxImage::AddHandler(newd wxBMPHandler);
2023-10-15 18:51:57 -03:00
wxImage : : AddHandler ( newd < wxPNGHandler > ( ) . get ( ) ) ;
wxImage : : AddHandler ( newd < wxJPEGHandler > ( ) . get ( ) ) ;
wxImage : : AddHandler ( newd < wxTGAHandler > ( ) . get ( ) ) ;
2012-06-29 16:44:26 +02:00
2016-09-29 20:30:54 -03:00
g_gui . gfx . loadEditorSprites ( ) ;
2012-06-29 16:44:26 +02:00
# ifndef __DEBUG_MODE__
2023-10-09 19:12:16 -07:00
// wxHandleFatalExceptions(true);
2012-06-29 16:44:26 +02:00
# endif
2023-10-09 19:12:16 -07:00
// Load all the dependency files
std : : string error ;
StringVector warnings ;
2014-01-22 20:16:17 +01:00
2023-10-09 19:12:16 -07:00
m_file_to_open = wxEmptyString ;
ParseCommandLineMap ( m_file_to_open ) ;
2019-06-25 18:07:36 +02:00
2023-10-15 18:51:57 -03:00
g_gui . root = newd < MainFrame > ( __W_RME_APPLICATION_NAME__ , wxDefaultPosition , wxSize ( 700 , 500 ) ) ;
SetTopWindow ( g_gui . root . get ( ) ) ;
2016-11-05 15:28:14 +01:00
g_gui . SetTitle ( " " ) ;
2012-06-29 16:44:26 +02:00
2016-09-29 20:30:54 -03:00
g_gui . root - > LoadRecentFiles ( ) ;
2012-06-29 16:44:26 +02:00
// Load palette
2016-09-29 20:30:54 -03:00
g_gui . LoadPerspective ( ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
wxIcon icon ( rme_icon ) ;
g_gui . root - > SetIcon ( icon ) ;
2019-06-27 22:23:28 +02:00
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : WELCOME_DIALOG ) = = 1 & & m_file_to_open = = wxEmptyString ) {
g_gui . ShowWelcomeDialog ( icon ) ;
} else {
g_gui . root - > Show ( ) ;
}
2019-06-27 22:23:28 +02:00
2012-06-29 16:44:26 +02:00
// Set idle event handling mode
wxIdleEvent : : SetMode ( wxIDLE_PROCESS_SPECIFIED ) ;
// Goto RME website?
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : GOTO_WEBSITE_ON_BOOT ) = = 1 ) {
2016-11-05 15:28:14 +01:00
: : wxLaunchDefaultBrowser ( " http://www.remeresmapeditor.com/ " , wxBROWSER_NEW_WINDOW ) ;
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : GOTO_WEBSITE_ON_BOOT , 0 ) ;
2012-06-29 16:44:26 +02:00
}
// Check for updates
# ifdef _USE_UPDATER_
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_UPDATER ) = = - 1 ) {
2016-09-29 20:30:54 -03:00
int ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Notice " ,
" Do you want the editor to automatically check for updates? \n "
" It will connect to the internet if you choose yes. \n "
2023-10-09 19:12:16 -07:00
" You can change this setting in the preferences later. " ,
wxYES | wxNO
) ;
if ( ret = = wxID_YES ) {
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : USE_UPDATER , 1 ) ;
2015-12-06 11:42:37 -03:00
} else {
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : USE_UPDATER , 0 ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : USE_UPDATER ) = = 1 ) {
2012-06-29 16:44:26 +02:00
UpdateChecker updater ;
2016-09-29 20:30:54 -03:00
updater . connect ( g_gui . root ) ;
2012-06-29 16:44:26 +02:00
}
# endif
2019-06-25 18:07:36 +02:00
FileName save_failed_file = GUI : : GetLocalDataDirectory ( ) ;
2016-11-05 15:28:14 +01:00
save_failed_file . SetName ( " .saving.txt " ) ;
2023-10-09 19:12:16 -07:00
if ( save_failed_file . FileExists ( ) ) {
2012-06-29 16:44:26 +02:00
std : : ifstream f ( nstr ( save_failed_file . GetFullPath ( ) ) . c_str ( ) , std : : ios : : in ) ;
2021-05-25 00:29:12 -03:00
std : : string backup_otbm , backup_house , backup_spawn , backup_spawn_npc ;
2012-06-29 16:44:26 +02:00
getline ( f , backup_otbm ) ;
getline ( f , backup_house ) ;
getline ( f , backup_spawn ) ;
2021-05-25 00:29:12 -03:00
getline ( f , backup_spawn_npc ) ;
2012-06-29 16:44:26 +02:00
// Remove the file
f . close ( ) ;
std : : remove ( nstr ( save_failed_file . GetFullPath ( ) ) . c_str ( ) ) ;
// Query file retrieval if possible
2023-10-09 19:12:16 -07:00
if ( ! backup_otbm . empty ( ) ) {
2021-05-25 00:29:12 -03:00
long ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Editor Crashed " ,
2012-06-29 16:44:26 +02:00
wxString (
2016-11-05 15:28:14 +01:00
" IMPORTANT! THE EDITOR CRASHED WHILE SAVING! \n \n "
2023-10-09 19:12:16 -07:00
" Do you want to recover the lost map? (it will be opened immediately): \n "
) < < wxstr ( backup_otbm )
< < " \n "
< < wxstr ( backup_house ) < < " \n "
< < wxstr ( backup_spawn ) < < " \n "
< < wxstr ( backup_spawn_npc ) < < " \n " ,
wxYES | wxNO
) ;
if ( ret = = wxID_YES ) {
2012-06-29 16:44:26 +02:00
// Recover if the user so wishes
2012-07-04 23:18:15 +02:00
std : : remove ( backup_otbm . substr ( 0 , backup_otbm . size ( ) - 1 ) . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
std : : rename ( backup_otbm . c_str ( ) , backup_otbm . substr ( 0 , backup_otbm . size ( ) - 1 ) . c_str ( ) ) ;
2012-07-04 23:18:15 +02:00
2023-10-09 19:12:16 -07:00
if ( ! backup_house . empty ( ) ) {
2012-07-04 23:18:15 +02:00
std : : remove ( backup_house . substr ( 0 , backup_house . size ( ) - 1 ) . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
std : : rename ( backup_house . c_str ( ) , backup_house . substr ( 0 , backup_house . size ( ) - 1 ) . c_str ( ) ) ;
2012-07-04 23:18:15 +02:00
}
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn . empty ( ) ) {
2012-07-04 23:18:15 +02:00
std : : remove ( backup_spawn . substr ( 0 , backup_spawn . size ( ) - 1 ) . c_str ( ) ) ;
2012-06-29 16:44:26 +02:00
std : : rename ( backup_spawn . c_str ( ) , backup_spawn . substr ( 0 , backup_spawn . size ( ) - 1 ) . c_str ( ) ) ;
2012-07-04 23:18:15 +02:00
}
2023-10-09 19:12:16 -07:00
if ( ! backup_spawn_npc . empty ( ) ) {
2021-05-25 00:29:12 -03:00
std : : remove ( backup_spawn_npc . substr ( 0 , backup_spawn_npc . size ( ) - 1 ) . c_str ( ) ) ;
std : : rename ( backup_spawn_npc . c_str ( ) , backup_spawn_npc . substr ( 0 , backup_spawn_npc . size ( ) - 1 ) . c_str ( ) ) ;
}
2016-09-29 19:24:45 -03:00
2012-06-29 16:44:26 +02:00
// Load the map
2016-09-29 20:30:54 -03:00
g_gui . LoadMap ( wxstr ( backup_otbm . substr ( 0 , backup_otbm . size ( ) - 1 ) ) ) ;
2012-06-29 16:44:26 +02:00
return true ;
}
}
}
2023-10-09 19:12:16 -07:00
// Keep track of first event loop entry
m_startup = true ;
2012-06-29 16:44:26 +02:00
return true ;
}
2020-06-26 08:44:56 +02:00
void Application : : OnEventLoopEnter ( wxEventLoopBase * loop ) {
2023-10-09 19:12:16 -07:00
// First startup?
if ( ! m_startup ) {
return ;
}
m_startup = false ;
// Don't try to create a map if we didn't load the client map.
if ( ClientVersion : : getLatestVersion ( ) = = nullptr ) {
return ;
}
// Open a map.
if ( m_file_to_open ! = wxEmptyString ) {
g_gui . LoadMap ( FileName ( m_file_to_open ) ) ;
} else if ( ! g_gui . IsWelcomeDialogShown ( ) & & g_gui . NewMap ( ) ) { // Open a new empty map
// You generally don't want to save this map...
g_gui . GetCurrentEditor ( ) - > clearChanges ( ) ;
}
2020-06-26 08:44:56 +02:00
}
2023-10-09 19:12:16 -07:00
void Application : : MacOpenFiles ( const wxArrayString & fileNames ) {
2016-11-26 00:14:06 +01:00
if ( ! fileNames . IsEmpty ( ) ) {
2019-06-27 22:23:28 +02:00
g_gui . LoadMap ( FileName ( fileNames . Item ( 0 ) ) ) ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
void Application : : FixVersionDiscrapencies ( ) {
2012-06-29 16:44:26 +02:00
// Here the registry should be fixed, if the version has been changed
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : VERSION_ID ) < MAKE_VERSION_ID ( 1 , 0 , 5 ) ) {
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : USE_MEMCACHED_SPRITES_TO_SAVE , 0 ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
if ( g_settings . getInteger ( Config : : VERSION_ID ) < __RME_VERSION_ID__ & & ClientVersion : : getLatestVersion ( ) ! = nullptr ) {
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : DEFAULT_CLIENT_VERSION , ClientVersion : : getLatestVersion ( ) - > getID ( ) ) ;
2012-06-29 16:44:26 +02:00
}
2016-09-29 20:37:43 -03:00
wxString ss = wxstr ( g_settings . getString ( Config : : SCREENSHOT_DIRECTORY ) ) ;
2023-10-09 19:12:16 -07:00
if ( ss . empty ( ) ) {
2012-06-29 16:44:26 +02:00
ss = wxStandardPaths : : Get ( ) . GetDocumentsDir ( ) ;
# ifdef __WINDOWS__
2016-11-05 15:28:14 +01:00
ss + = " /My Pictures/RME/ " ;
2012-06-29 16:44:26 +02:00
# endif
}
2016-09-29 20:37:43 -03:00
g_settings . setString ( Config : : SCREENSHOT_DIRECTORY , nstr ( ss ) ) ;
2012-06-29 16:44:26 +02:00
// Set registry to newest version
2016-09-29 20:37:43 -03:00
g_settings . setInteger ( Config : : VERSION_ID , __RME_VERSION_ID__ ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void Application : : Unload ( ) {
2016-09-29 20:30:54 -03:00
g_gui . CloseAllEditors ( ) ;
g_gui . UnloadVersion ( ) ;
g_gui . SaveHotkeys ( ) ;
g_gui . SavePerspective ( ) ;
g_gui . root - > SaveRecentFiles ( ) ;
2012-06-29 16:44:26 +02:00
ClientVersion : : saveVersions ( ) ;
2012-07-01 16:53:39 +02:00
ClientVersion : : unloadVersions ( ) ;
2016-09-29 20:37:43 -03:00
g_settings . save ( true ) ;
2016-09-29 20:30:54 -03:00
g_gui . root = nullptr ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
int Application : : OnExit ( ) {
2012-06-29 16:44:26 +02:00
# ifdef _USE_PROCESS_COM
2017-01-22 14:12:32 +01:00
wxDELETE ( m_proc_server ) ;
wxDELETE ( m_single_instance_checker ) ;
2012-06-29 16:44:26 +02:00
# endif
return 1 ;
}
2023-10-09 19:12:16 -07:00
void Application : : OnFatalException ( ) {
2015-12-06 11:42:37 -03:00
////
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
bool Application : : ParseCommandLineMap ( wxString & fileName ) {
if ( argc = = 2 ) {
2016-12-02 16:40:51 +01:00
fileName = wxString ( argv [ 1 ] ) ;
2019-06-25 20:12:12 +02:00
return true ;
2012-06-29 16:44:26 +02:00
}
2019-06-25 20:12:12 +02:00
return false ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
MainFrame : : MainFrame ( const wxString & title , const wxPoint & pos , const wxSize & size ) :
wxFrame ( ( wxFrame * ) nullptr , - 1 , title , pos , size , wxDEFAULT_FRAME_STYLE ) {
2012-06-29 16:44:26 +02:00
// Receive idle events
SetExtraStyle ( wxWS_EX_PROCESS_IDLE ) ;
2016-12-05 21:53:41 +01:00
2023-10-09 19:12:16 -07:00
# if wxCHECK_VERSION(3, 1, 0) // 3.1.0 or higher
// Make sure ShowFullScreen() uses the full screen API on macOS
EnableFullScreenView ( true ) ;
# endif
2016-12-05 21:53:41 +01:00
2012-06-29 16:44:26 +02:00
// Creates the file-dropdown menu
2023-10-15 18:51:57 -03:00
menu_bar = newd < MainMenuBar > ( this ) ;
2012-06-29 16:44:26 +02:00
wxArrayString warnings ;
wxString error ;
2014-01-24 02:33:09 -02:00
wxFileName filename ;
2016-11-05 15:28:14 +01:00
filename . Assign ( g_gui . getFoundDataDirectory ( ) + " menubar.xml " ) ;
2023-10-09 19:12:16 -07:00
if ( ! filename . FileExists ( ) ) {
2019-06-25 18:07:36 +02:00
filename = FileName ( GUI : : GetDataDirectory ( ) + " menubar.xml " ) ;
2023-10-09 19:12:16 -07:00
}
2014-01-24 02:33:09 -02:00
2023-10-09 19:12:16 -07:00
if ( ! menu_bar - > Load ( filename , warnings , error ) ) {
2016-11-05 15:28:14 +01:00
wxLogError ( wxString ( ) + " Could not load menubar.xml, editor will NOT be able to show its menu. \n " ) ;
2014-01-24 02:33:09 -02:00
}
2012-06-29 16:44:26 +02:00
wxStatusBar * statusbar = CreateStatusBar ( ) ;
2016-02-25 21:32:05 -03:00
statusbar - > SetFieldsCount ( 4 ) ;
2019-06-25 18:07:36 +02:00
SetStatusText ( wxString ( " Welcome to " ) < < __W_RME_APPLICATION_NAME__ < < " " < < __W_RME_VERSION__ ) ;
2012-06-29 16:44:26 +02:00
// Le sizer
2023-10-15 18:51:57 -03:00
g_gui . aui_manager = newd < wxAuiManager > ( this ) ;
g_gui . tabbook = newd < MapTabbook > ( this , wxID_ANY ) ;
2016-09-29 19:24:45 -03:00
2023-10-15 18:51:57 -03:00
tool_bar = newd < MainToolBar > ( this , g_gui . aui_manager ) ;
2019-06-03 14:14:18 -03:00
2023-10-15 18:51:57 -03:00
g_gui . aui_manager - > AddPane ( g_gui . tabbook . get ( ) , wxAuiPaneInfo ( ) . CenterPane ( ) . Floatable ( false ) . CloseButton ( false ) . PaneBorder ( false ) ) ;
2016-09-29 20:30:54 -03:00
g_gui . aui_manager - > Update ( ) ;
2012-06-29 16:44:26 +02:00
UpdateMenubar ( ) ;
}
2019-06-25 18:07:36 +02:00
MainFrame : : ~ MainFrame ( ) = default ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
void MainFrame : : OnIdle ( wxIdleEvent & event ) {
2015-12-06 11:42:37 -03:00
////
2012-06-29 16:44:26 +02:00
}
# ifdef _USE_UPDATER_
2023-10-09 19:12:16 -07:00
void MainFrame : : OnUpdateReceived ( wxCommandEvent & event ) {
2012-06-29 16:44:26 +02:00
std : : string data = * ( std : : string * ) event . GetClientData ( ) ;
delete ( std : : string * ) event . GetClientData ( ) ;
size_t first_colon = data . find ( ' : ' ) ;
2023-10-09 19:12:16 -07:00
size_t second_colon = data . find ( ' : ' , first_colon + 1 ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( first_colon = = std : : string : : npos | | second_colon = = std : : string : : npos ) {
2012-06-29 16:44:26 +02:00
return ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
std : : string update = data . substr ( 0 , first_colon ) ;
2023-10-09 19:12:16 -07:00
std : : string verstr = data . substr ( first_colon + 1 , second_colon - first_colon - 1 ) ;
std : : string url = ( second_colon = = data . size ( ) ? " " : data . substr ( second_colon + 1 ) ) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( update = = " yes " ) {
2016-09-29 20:30:54 -03:00
int ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Update Notice " ,
2023-10-09 19:12:16 -07:00
wxString ( " There is a newd update available ( " ) < < wxstr ( verstr ) < < " ). Do you want to go to the website and download it? " ,
2012-06-29 16:44:26 +02:00
wxYES | wxNO ,
2016-11-05 15:28:14 +01:00
" I don't want any update notices " ,
2012-06-29 16:44:26 +02:00
Config : : AUTOCHECK_FOR_UPDATES
2023-10-09 19:12:16 -07:00
) ;
if ( ret = = wxID_YES ) {
: : wxLaunchDefaultBrowser ( wxstr ( url ) , wxBROWSER_NEW_WINDOW ) ;
}
2012-06-29 16:44:26 +02:00
}
}
# endif
2023-10-09 19:12:16 -07:00
void MainFrame : : OnUpdateMenus ( wxCommandEvent & ) {
2012-06-29 16:44:26 +02:00
UpdateMenubar ( ) ;
2016-09-29 20:30:54 -03:00
g_gui . UpdateMinimap ( true ) ;
g_gui . UpdateTitle ( ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void MainFrame : : OnUpdateActions ( wxCommandEvent & ) {
2023-10-09 23:02:37 -03:00
tool_bar - > UpdateButtons ( ) ;
g_gui . RefreshActions ( ) ;
}
2012-06-29 16:44:26 +02:00
# ifdef __WINDOWS__
2023-10-09 19:12:16 -07:00
bool MainFrame : : MSWTranslateMessage ( WXMSG * msg ) {
if ( g_gui . AreHotkeysEnabled ( ) ) {
if ( wxFrame : : MSWTranslateMessage ( msg ) ) {
2012-06-29 16:44:26 +02:00
return true ;
2023-10-09 19:12:16 -07:00
}
2015-12-06 11:42:37 -03:00
} else {
2023-10-09 19:12:16 -07:00
if ( wxWindow : : MSWTranslateMessage ( msg ) ) {
2012-06-29 16:44:26 +02:00
return true ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
}
return false ;
}
# endif
2023-10-09 19:12:16 -07:00
void MainFrame : : UpdateMenubar ( ) {
2012-06-29 16:44:26 +02:00
menu_bar - > Update ( ) ;
2019-06-03 14:14:18 -03:00
tool_bar - > UpdateButtons ( ) ;
2012-06-29 16:44:26 +02:00
}
bool MainFrame : : DoQueryClose ( ) {
2016-09-29 20:30:54 -03:00
Editor * editor = g_gui . GetCurrentEditor ( ) ;
2023-10-09 19:12:16 -07:00
if ( editor ) {
if ( editor - > IsLive ( ) ) {
2016-09-29 20:30:54 -03:00
long ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Must Close Server " ,
wxString ( " You are currently connected to a live server, to close this map the connection must be severed. " ) ,
2023-10-09 19:12:16 -07:00
wxOK | wxCANCEL
) ;
if ( ret = = wxID_OK ) {
2012-06-29 16:44:26 +02:00
editor - > CloseLiveServer ( ) ;
} else {
return false ;
}
}
}
return true ;
}
2023-10-09 19:12:16 -07:00
bool MainFrame : : DoQuerySave ( bool doclose ) {
if ( ! g_gui . IsEditorOpen ( ) ) {
2014-02-21 13:55:09 +01:00
return true ;
}
2016-09-29 19:24:45 -03:00
2023-10-09 19:12:16 -07:00
Editor & editor = * g_gui . GetCurrentEditor ( ) ;
if ( editor . IsLiveClient ( ) ) {
2016-09-29 20:30:54 -03:00
long ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Disconnect " ,
" Do you want to disconnect? " ,
2014-02-21 13:55:09 +01:00
wxYES | wxNO
) ;
2012-06-29 16:44:26 +02:00
2023-10-09 19:12:16 -07:00
if ( ret ! = wxID_YES ) {
2012-06-29 16:44:26 +02:00
return false ;
}
2014-02-21 13:55:09 +01:00
editor . CloseLiveServer ( ) ;
return DoQuerySave ( doclose ) ;
2023-10-09 19:12:16 -07:00
} else if ( editor . IsLiveServer ( ) ) {
2016-09-29 20:30:54 -03:00
long ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Shutdown " ,
" Do you want to shut down the server? (any clients will be disconnected) " ,
2014-02-21 13:55:09 +01:00
wxYES | wxNO
) ;
2023-10-09 19:12:16 -07:00
if ( ret ! = wxID_YES ) {
2012-06-29 16:44:26 +02:00
return false ;
}
2014-02-21 13:55:09 +01:00
editor . CloseLiveServer ( ) ;
return DoQuerySave ( doclose ) ;
2023-10-09 19:12:16 -07:00
} else if ( g_gui . ShouldSave ( ) ) {
2016-09-29 20:30:54 -03:00
long ret = g_gui . PopupDialog (
2016-11-05 15:28:14 +01:00
" Save changes " ,
" Do you want to save your changes to \" " + wxstr ( g_gui . GetCurrentMap ( ) . getName ( ) ) + " \" ? " ,
2014-02-21 13:55:09 +01:00
wxYES | wxNO | wxCANCEL
) ;
2023-10-09 19:12:16 -07:00
if ( ret = = wxID_YES ) {
if ( g_gui . GetCurrentMap ( ) . hasFile ( ) ) {
2016-09-29 20:30:54 -03:00
g_gui . SaveCurrentMap ( true ) ;
2014-02-21 13:55:09 +01:00
} else {
2019-06-25 18:07:36 +02:00
wxFileDialog file ( this , " Save... " , " " , " " , " *.otbm " , wxFD_SAVE | wxFD_OVERWRITE_PROMPT ) ;
2014-02-21 13:55:09 +01:00
int32_t result = file . ShowModal ( ) ;
2023-10-09 19:12:16 -07:00
if ( result = = wxID_OK ) {
2016-09-29 20:30:54 -03:00
g_gui . SaveCurrentMap ( file . GetPath ( ) , true ) ;
2014-02-21 13:55:09 +01:00
} else {
return false ;
2012-06-29 16:44:26 +02:00
}
}
2023-10-09 19:12:16 -07:00
} else if ( ret = = wxID_CANCEL ) {
2014-02-21 13:55:09 +01:00
return false ;
2012-06-29 16:44:26 +02:00
}
}
2014-02-21 13:55:09 +01:00
2023-10-09 19:12:16 -07:00
if ( doclose ) {
2014-02-21 13:55:09 +01:00
UnnamedRenderingLock ( ) ;
2016-09-29 20:30:54 -03:00
g_gui . CloseCurrentEditor ( ) ;
2014-02-21 13:55:09 +01:00
}
2012-06-29 16:44:26 +02:00
return true ;
}
2023-10-09 19:12:16 -07:00
bool MainFrame : : DoQueryImportCreatures ( ) {
2021-05-25 00:29:12 -03:00
// Monsters
2023-10-09 19:12:16 -07:00
if ( g_monsters . hasMissing ( ) ) {
2021-05-25 00:29:12 -03:00
long ret = g_gui . PopupDialog ( " Missing monsters " , " There are missing monsters in the editor, do you want to load them from an OT monster file? " , wxYES | wxNO ) ;
2023-10-09 19:12:16 -07:00
if ( ret = = wxID_YES ) {
2019-06-25 18:07:36 +02:00
do {
2023-10-15 18:51:57 -03:00
wxFileDialog dlg ( g_gui . root . get ( ) , " Import monster file " , " " , " " , " *.xml " , wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST ) ;
2023-10-09 19:12:16 -07:00
if ( dlg . ShowModal ( ) = = wxID_OK ) {
2012-06-29 16:44:26 +02:00
wxArrayString paths ;
dlg . GetPaths ( paths ) ;
2023-10-09 19:12:16 -07:00
for ( uint32_t i = 0 ; i < paths . GetCount ( ) ; + + i ) {
2012-06-29 16:44:26 +02:00
wxString error ;
wxArrayString warnings ;
2021-05-25 00:29:12 -03:00
bool ok = g_monsters . importXMLFromOT ( FileName ( paths [ i ] ) , error , warnings ) ;
2023-10-09 19:12:16 -07:00
if ( ok ) {
2016-11-05 15:28:14 +01:00
g_gui . ListDialog ( " Monster loader errors " , warnings ) ;
2023-10-09 19:12:16 -07:00
} else {
2023-10-15 18:51:57 -03:00
wxMessageBox ( " Error OT data file \" " + paths [ i ] + " \" . \n " + error , " Error " , wxOK | wxICON_INFORMATION , g_gui . root . get ( ) ) ;
2023-10-09 19:12:16 -07:00
}
2012-06-29 16:44:26 +02:00
}
2015-12-06 11:42:37 -03:00
} else {
2012-06-29 16:44:26 +02:00
break ;
}
2023-10-09 19:12:16 -07:00
} while ( g_monsters . hasMissing ( ) ) ;
2021-05-25 00:29:12 -03:00
}
}
// Npcs
2023-10-09 19:12:16 -07:00
if ( g_npcs . hasMissing ( ) ) {
2021-05-25 00:29:12 -03:00
long ret = g_gui . PopupDialog ( " Missing npcs " , " There are missing npcs in the editor, do you want to load them from an OT npc file? " , wxYES | wxNO ) ;
2023-10-09 19:12:16 -07:00
if ( ret = = wxID_YES ) {
2021-05-25 00:29:12 -03:00
do {
2023-10-15 18:51:57 -03:00
wxFileDialog dlg ( g_gui . root . get ( ) , " Import npc file " , " " , " " , " *.xml " , wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST ) ;
2023-10-09 19:12:16 -07:00
if ( dlg . ShowModal ( ) = = wxID_OK ) {
2021-05-25 00:29:12 -03:00
wxArrayString paths ;
dlg . GetPaths ( paths ) ;
2023-10-09 19:12:16 -07:00
for ( uint32_t i = 0 ; i < paths . GetCount ( ) ; + + i ) {
2021-05-25 00:29:12 -03:00
wxString error ;
wxArrayString warnings ;
bool ok = g_npcs . importXMLFromOT ( FileName ( paths [ i ] ) , error , warnings ) ;
2023-10-09 19:12:16 -07:00
if ( ok ) {
2021-05-25 00:29:12 -03:00
g_gui . ListDialog ( " Npc loader errors " , warnings ) ;
2023-10-09 19:12:16 -07:00
} else {
2023-10-15 18:51:57 -03:00
wxMessageBox ( " Error OT data file \" " + paths [ i ] + " \" . \n " + error , " Error " , wxOK | wxICON_INFORMATION , g_gui . root . get ( ) ) ;
2023-10-09 19:12:16 -07:00
}
2021-05-25 00:29:12 -03:00
}
} else {
break ;
}
2023-10-09 19:12:16 -07:00
} while ( g_npcs . hasMissing ( ) ) ;
2012-06-29 16:44:26 +02:00
}
}
2016-09-29 20:30:54 -03:00
g_gui . RefreshPalettes ( ) ;
2012-06-29 16:44:26 +02:00
return true ;
}
2023-10-09 19:12:16 -07:00
void MainFrame : : UpdateFloorMenu ( ) {
2012-06-29 16:44:26 +02:00
menu_bar - > UpdateFloorMenu ( ) ;
}
2023-10-09 19:12:16 -07:00
void MainFrame : : UpdateIndicatorsMenu ( ) {
2023-10-09 23:02:37 -03:00
menu_bar - > UpdateIndicatorsMenu ( ) ;
}
2023-10-09 19:12:16 -07:00
bool MainFrame : : LoadMap ( FileName name ) {
2016-09-29 20:30:54 -03:00
return g_gui . LoadMap ( name ) ;
2012-06-29 16:44:26 +02:00
}
2023-10-09 19:12:16 -07:00
void MainFrame : : OnExit ( wxCloseEvent & event ) {
while ( g_gui . IsEditorOpen ( ) ) {
if ( ! DoQuerySave ( ) ) {
if ( event . CanVeto ( ) ) {
2012-06-29 16:44:26 +02:00
event . Veto ( ) ;
return ;
2015-12-06 11:42:37 -03:00
} else {
2012-06-29 16:44:26 +02:00
break ;
}
}
}
2016-09-29 20:30:54 -03:00
g_gui . aui_manager - > UnInit ( ) ;
2023-10-09 19:12:16 -07:00
( ( Application & ) wxGetApp ( ) ) . Unload ( ) ;
2012-06-29 16:44:26 +02:00
# ifdef __RELEASE__
// Hack, "crash" gracefully in release builds, let OS handle cleanup of windows
exit ( 0 ) ;
# endif
Destroy ( ) ;
}
2023-10-09 19:12:16 -07:00
void MainFrame : : AddRecentFile ( const FileName & file ) {
2012-06-29 16:44:26 +02:00
menu_bar - > AddRecentFile ( file ) ;
}
2023-10-09 19:12:16 -07:00
void MainFrame : : LoadRecentFiles ( ) {
2012-06-29 16:44:26 +02:00
menu_bar - > LoadRecentFiles ( ) ;
}
2023-10-09 19:12:16 -07:00
void MainFrame : : SaveRecentFiles ( ) {
2012-06-29 16:44:26 +02:00
menu_bar - > SaveRecentFiles ( ) ;
}
2023-10-09 19:12:16 -07:00
std : : vector < wxString > MainFrame : : GetRecentFiles ( ) {
return menu_bar - > GetRecentFiles ( ) ;
2019-06-25 18:07:36 +02:00
}
2023-10-09 19:12:16 -07:00
void MainFrame : : PrepareDC ( wxDC & dc ) {
dc . SetLogicalOrigin ( 0 , 0 ) ;
dc . SetAxisOrientation ( 1 , 0 ) ;
dc . SetUserScale ( 1.0 , 1.0 ) ;
dc . SetMapMode ( wxMM_TEXT ) ;
2012-06-29 16:44:26 +02:00
}
2023-03-28 08:54:17 -03:00
# ifdef _MSC_VER
// This is necessary for cmake with visual studio link the executable
2023-10-09 19:12:16 -07:00
int main ( int argc , char * * argv ) {
2023-03-28 08:54:17 -03:00
wxEntryStart ( argc , argv ) ; // Start the wxWidgets library
Application * app = new Application ( ) ; // Create the application object
wxApp : : SetInstance ( app ) ; // Informs wxWidgets that app is the application object
wxEntry ( ) ; // Call the wxEntry() function to start the application execution
wxEntryCleanup ( ) ; // Clear the wxWidgets library
return 0 ;
}
# endif