From 44928f1a8d8bdb3d1ced49bbd785b6123587bf32 Mon Sep 17 00:00:00 2001 From: Martin Plicht Date: Sat, 11 Dec 2010 19:50:38 +0100 Subject: [PATCH] Platform-specific code in C4Console.cpp gets factored out into C4Console(Win32/GTK).cpp --- .hgignore | 1 + CMakeLists.txt | 6 + src/C4FullScreen.cpp | 7 +- src/C4FullScreen.h | 3 +- src/editor/C4Console.cpp | 1265 +--------------------- src/editor/C4Console.h | 135 +-- src/editor/C4ConsoleGTK.cpp | 1622 +++++++++++++++++++++++++++++ src/editor/C4ConsoleGUI.h | 155 +++ src/editor/C4ConsoleGUICommon.cpp | 94 ++ src/editor/C4ConsoleWin32.cpp | 1201 +++++++++++++++++++++ src/editor/C4ConsoleX11.cpp | 13 + src/editor/C4PropertyDlg.cpp | 261 +---- src/editor/C4PropertyDlg.h | 27 +- src/editor/C4ToolsDlg.cpp | 952 +---------------- src/editor/C4ToolsDlg.h | 105 +- src/gui/C4Gui.h | 13 +- src/gui/C4GuiDialogs.cpp | 37 +- src/gui/C4Viewport.cpp | 6 +- src/gui/C4Viewport.h | 2 + src/platform/C4SoundSystem.cpp | 2 +- src/platform/C4ViewportWindow.cpp | 28 +- src/platform/C4ViewportWindow.h | 3 +- src/platform/StdAppCommon.cpp | 40 + src/platform/StdAppCommon.h | 16 + src/platform/StdGtkWindow.cpp | 6 + src/platform/StdWindow.cpp | 6 + src/platform/StdWindow.h | 36 +- src/platform/StdXWindow.cpp | 4 +- 28 files changed, 3359 insertions(+), 2687 deletions(-) create mode 100644 src/editor/C4ConsoleGTK.cpp create mode 100644 src/editor/C4ConsoleGUI.h create mode 100644 src/editor/C4ConsoleGUICommon.cpp create mode 100644 src/editor/C4ConsoleWin32.cpp create mode 100644 src/editor/C4ConsoleX11.cpp create mode 100644 src/platform/StdAppCommon.cpp create mode 100644 src/platform/StdAppCommon.h diff --git a/.hgignore b/.hgignore index e2e4a392c..65488f50a 100644 --- a/.hgignore +++ b/.hgignore @@ -93,6 +93,7 @@ BuildLog.htm # XCode temporary files + Xcode not temporary files .DS_Store +._* xcode/build *.xcodeproj diff --git a/CMakeLists.txt b/CMakeLists.txt index 002261a76..23e3b8eb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,6 +172,8 @@ set(OC_CLONK_SOURCES src/control/C4Teams.h src/editor/C4Console.cpp src/editor/C4Console.h + src/editor/C4ConsoleGUI.h + src/editor/C4ConsoleGUICommon.cpp src/editor/C4DevmodeDlg.cpp src/editor/C4DevmodeDlg.h src/editor/C4EditCursor.cpp @@ -478,6 +480,8 @@ set(OC_CLONK_SOURCES src/platform/StdVideo.cpp src/platform/StdVideo.h src/platform/StdWindow.h + src/platform/StdAppCommon.h + src/platform/StdAppCommon.cpp src/script/C4AList.cpp src/script/C4AList.h src/script/C4Aul.cpp @@ -518,6 +522,7 @@ if(WIN32) src/platform/StdJoystick.cpp src/platform/StdJoystick.h src/platform/C4FileClasses.cpp + src/editor/C4ConsoleWin32.cpp src/res/resource.h ) @@ -583,6 +588,7 @@ if(USE_GTK) list(APPEND OC_SYSTEM_SOURCES src/platform/StdGtkWindow.cpp src/platform/StdGtkWindow.h + src/editor/C4ConsoleGTK.cpp ) endif() diff --git a/src/C4FullScreen.cpp b/src/C4FullScreen.cpp index 9518464c4..86b6e1052 100644 --- a/src/C4FullScreen.cpp +++ b/src/C4FullScreen.cpp @@ -430,7 +430,7 @@ void C4FullScreen::Execute() // Execute menu if (pMenu) pMenu->Execute(); // Draw - ::GraphicsSystem.Execute(); + RequestUpdate(); } bool C4FullScreen::ViewportCheck() @@ -522,6 +522,11 @@ void C4FullScreen::CloseMenu() } } +void C4FullScreen::PerformUpdate() +{ + GraphicsSystem.Execute(); +} + bool C4FullScreen::MenuKeyControl(BYTE byCom) { if (pMenu) return pMenu->KeyControl(byCom); diff --git a/src/C4FullScreen.h b/src/C4FullScreen.h index 62dd7087f..3bc79fb45 100644 --- a/src/C4FullScreen.h +++ b/src/C4FullScreen.h @@ -50,9 +50,10 @@ public: virtual void CharIn(const char * c); #ifdef USE_X11 virtual void HandleMessage (XEvent &e); -#elif USE_SDL_MAINLOOP +#elif defined(USE_SDL_MAINLOOP) virtual void HandleMessage (SDL_Event &e); #endif + virtual void PerformUpdate(); }; extern C4FullScreen FullScreen; diff --git a/src/editor/C4Console.cpp b/src/editor/C4Console.cpp index 40b801463..0597004a4 100644 --- a/src/editor/C4Console.cpp +++ b/src/editor/C4Console.cpp @@ -43,54 +43,13 @@ #include #include -#ifdef _WIN32 -#include -#include "resource.h" - -bool SetMenuItemText(HMENU hMenu, WORD id, const char *szText); -#else -namespace -{ - const DWORD OFN_HIDEREADONLY = 1 << 0; - const DWORD OFN_OVERWRITEPROMPT = 1 << 1; - const DWORD OFN_FILEMUSTEXIST = 1 << 2; - const DWORD OFN_ALLOWMULTISELECT = 1 << 3; - - const DWORD OFN_EXPLORER = 0; // ignored -} -#ifdef USE_X11 -#include -#include -#endif -#endif // _WIN32 - -#ifdef WITH_DEVELOPER_MODE -# include -# include - -# include -# include -# include -# include -# include - -namespace -{ - GtkWidget* CreateImageFromInlinedPixbuf(const guint8* pixbuf_data) - { - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf_data, false, NULL); - GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); - gdk_pixbuf_unref(pixbuf); - return image; - } -} -#endif - #define FILE_SELECT_FILTER_FOR_C4S "Clonk 4 Scenario\0" \ "*.c4s;*.c4f;Scenario.txt\0" \ "\0" -C4Console::C4Console() +using namespace OpenFileFlags; + +C4Console::C4Console(): C4ConsoleGUI() { Active = false; Editing = true; @@ -100,184 +59,21 @@ C4Console::C4Console() #ifdef _WIN32 hWindow=NULL; - hbmCursor=NULL; - hbmCursor2=NULL; - hbmBrush=NULL; - hbmBrush2=NULL; - hbmPlay=NULL; - hbmPlay2=NULL; - hbmHalt=NULL; - hbmHalt2=NULL; -#elif defined(WITH_DEVELOPER_MODE) - cursorDefault = NULL; - cursorWait = NULL; - itemNet = NULL; - txtLog = NULL; - txtScript = NULL; -#endif // WITH_DEVELOPER_MODE / _WIN32 +#endif MenuIndexFile = 0, - MenuIndexComponents = 1, - MenuIndexPlayer = 2, - MenuIndexViewport = 3, - MenuIndexNet = -1, - MenuIndexHelp = 4; + MenuIndexComponents = 1, + MenuIndexPlayer = 2, + MenuIndexViewport = 3, + MenuIndexNet = -1, + MenuIndexHelp = 4; } C4Console::~C4Console() { -#ifdef _WIN32 - if (hbmCursor) DeleteObject(hbmCursor); - if (hbmCursor2) DeleteObject(hbmCursor2); - if (hbmBrush) DeleteObject(hbmBrush); - if (hbmBrush2) DeleteObject(hbmBrush2); - if (hbmPlay) DeleteObject(hbmPlay); - if (hbmPlay2) DeleteObject(hbmPlay2); - if (hbmHalt) DeleteObject(hbmHalt); - if (hbmHalt2) DeleteObject(hbmHalt2); -#elif defined(WITH_DEVELOPER_MODE) - if (cursorDefault) gdk_cursor_unref(cursorDefault); - if (cursorWait) gdk_cursor_unref(cursorWait); -#endif // WITH_DEVELOPER_MODE / _WIN32 } -#ifdef _WIN32 -INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - //------------------------------------------------------------------------------------------------------------ - case WM_ACTIVATEAPP: - Application.Active = wParam != 0; - return true; - //------------------------------------------------------------------------------------------------------------ - case WM_DESTROY: - StoreWindowPosition(hDlg, "Main", Config.GetSubkeyPath("Console"), false); - Application.Quit(); - return true; - //------------------------------------------------------------------------------------------------------------ - case WM_CLOSE: - Console.Close(); - return true; - //------------------------------------------------------------------------------------------------------------ - case MM_MCINOTIFY: - if (wParam == MCI_NOTIFY_SUCCESSFUL) - Application.MusicSystem.NotifySuccess(); - return true; - //------------------------------------------------------------------------------------------------------------ - case WM_INITDIALOG: - SendMessage(hDlg,DM_SETDEFID,(WPARAM)IDOK,(LPARAM)0); - Console.UpdateMenuText(GetMenu(hDlg)); - return true; - //------------------------------------------------------------------------------------------------------------ - case WM_COMMAND: - // Evaluate command - switch (LOWORD(wParam)) - { - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDOK: - // IDC_COMBOINPUT to Console.In() - char buffer[16000]; - GetDlgItemText(hDlg,IDC_COMBOINPUT,buffer,16000); - if (buffer[0]) - Console.In(buffer); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONHALT: - Console.DoHalt(); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONPLAY: - Console.DoPlay(); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODEPLAY: - Console.EditCursor.SetMode(C4CNS_ModePlay); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODEEDIT: - Console.EditCursor.SetMode(C4CNS_ModeEdit); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODEDRAW: - Console.EditCursor.SetMode(C4CNS_ModeDraw); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_QUIT: Console.FileQuit(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_SAVEAS: Console.FileSaveAs(false); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_SAVE: Console.FileSave(false); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_SAVEGAMEAS: Console.FileSaveAs(true); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_SAVEGAME: Console.FileSave(true); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_OPEN: Console.FileOpen(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_RECORD: Console.FileRecord(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_OPENWPLRS: Console.FileOpenWPlrs(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_FILE_CLOSE: Console.FileClose(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_HELP_ABOUT: Console.HelpAbout(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_PLAYER_JOIN: Console.PlayerJoin(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_VIEWPORT_NEW: Console.ViewportNew(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_COMPONENTS_TITLE: Console.EditTitle(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_COMPONENTS_INFO: Console.EditInfo(); return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDM_COMPONENTS_SCRIPT: Console.EditScript(); return true; - } - // New player viewport - if (Inside((int) LOWORD(wParam),IDM_VIEWPORT_NEW1,IDM_VIEWPORT_NEW2)) - { - ::Viewports.CreateViewport(LOWORD(wParam)-IDM_VIEWPORT_NEW1); - return true; - } - // Remove player - if (Inside((int) LOWORD(wParam),IDM_PLAYER_QUIT1,IDM_PLAYER_QUIT2)) - { - ::Control.Input.Add(CID_Script, new C4ControlScript( - FormatString("EliminatePlayer(%d)", LOWORD(wParam)-IDM_PLAYER_QUIT1).getData())); - return true; - } - // Remove client - if (Inside((int) LOWORD(wParam),IDM_NET_CLIENT1,IDM_NET_CLIENT2)) - { - if (!::Control.isCtrlHost()) return false; - Game.Clients.CtrlRemove(Game.Clients.getClientByID(LOWORD(wParam)-IDM_NET_CLIENT1), LoadResStr("IDS_MSG_KICKBYMENU")); - return true; - } - return false; - //------------------------------------------------------------------------------------------------------------ - case WM_USER_LOG: - if (SEqual2((const char *)lParam, "IDS_")) - Log(LoadResStr((const char *)lParam)); - else - Log((const char *)lParam); - return false; - //------------------------------------------------------------------------------------------------------------ - case WM_COPYDATA: - COPYDATASTRUCT* pcds = reinterpret_cast(lParam); - if (pcds->dwData == WM_USER_RELOADFILE) - { - // get path, ensure proper termination - const char *szPath = reinterpret_cast(pcds->lpData); - if (szPath[pcds->cbData - 1]) break; - // reload - Game.ReloadFile(szPath); - } - return false; - } - - return false; -} -#elif defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) +#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) void C4Console::HandleMessage (XEvent & e) { // Parent handling @@ -293,282 +89,13 @@ void C4Console::HandleMessage (XEvent & e) break; } } -#endif // _WIN32/USE_X11 +#endif // USE_X11 CStdWindow * C4Console::Init(CStdApp * pApp) { - // Active - Active = true; - // Editing (enable even if network) - Editing = true; - // Create dialog window -#ifdef _WIN32 - hWindow = CreateDialog(pApp->GetInstance(), MAKEINTRESOURCE(IDD_CONSOLE), NULL, ConsoleDlgProc); - if (!hWindow) - { - char * lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - 0, - (LPTSTR) &lpMsgBuf, - 0, - NULL); - Log(FormatString("Error creating dialog window: %s", lpMsgBuf).getData()); - // Free the buffer. - LocalFree(lpMsgBuf); - return NULL; - } - // Restore window position - RestoreWindowPosition(hWindow, "Main", Config.GetSubkeyPath("Console")); - // Set icon - SendMessage(hWindow,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(pApp->GetInstance(),MAKEINTRESOURCE(IDI_00_C4X))); - SendMessage(hWindow,WM_SETICON,ICON_SMALL,(LPARAM)LoadIcon(pApp->GetInstance(),MAKEINTRESOURCE(IDI_00_C4X))); - // Set text - SetCaption(LoadResStr("IDS_CNS_CONSOLE")); - // Load bitmaps - hbmMouse=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_MOUSE)); - hbmMouse2=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_MOUSE2)); - hbmCursor=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_CURSOR)); - hbmCursor2=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_CURSOR2)); - hbmBrush=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_BRUSH)); - hbmBrush2=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_BRUSH2)); - hbmPlay=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_PLAY)); - hbmPlay2=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_PLAY2)); - hbmHalt=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_HALT)); - hbmHalt2=(HBITMAP)LoadBitmap(pApp->GetInstance(),MAKEINTRESOURCE(IDB_HALT2)); - // Enable controls - UpdateHaltCtrls(true); - EnableControls(fGameOpen); - ClearViewportMenu(); - // Show window and set focus - ShowWindow(hWindow,SW_SHOWNORMAL); - UpdateWindow(hWindow); - SetFocus(hWindow); - ShowCursor(true); - // Success - return this; -#elif defined(WITH_DEVELOPER_MODE) - cursorWait = gdk_cursor_new(GDK_WATCH); - cursorDefault = gdk_cursor_new(GDK_ARROW); - - // Calls InitGUI - CStdWindow* retval = C4ConsoleBase::Init(pApp, LoadResStr("IDS_CNS_CONSOLE"), NULL, false); - UpdateHaltCtrls(true); - EnableControls(fGameOpen); - ClearViewportMenu(); - return retval; -#else - return C4ConsoleBase::Init(pApp, LoadResStr("IDS_CNS_CONSOLE"), NULL, false); -#endif // WITH_DEVELOPER_MODE / _WIN32 + return C4ConsoleGUI::CreateConsoleWindow(pApp); } -#ifdef WITH_DEVELOPER_MODE -GtkWidget* C4Console::InitGUI() -{ - // ------------ Play/Pause and Mode --------------------- - GtkWidget* image_play = CreateImageFromInlinedPixbuf(play_pixbuf_data); - GtkWidget* image_pause = CreateImageFromInlinedPixbuf(halt_pixbuf_data); - - GtkWidget* image_mode_play = CreateImageFromInlinedPixbuf(mouse_pixbuf_data); - GtkWidget* image_mode_edit = CreateImageFromInlinedPixbuf(cursor_pixbuf_data); - GtkWidget* image_mode_draw = CreateImageFromInlinedPixbuf(brush_pixbuf_data); - - btnPlay = gtk_toggle_button_new(); - btnHalt = gtk_toggle_button_new(); - btnModePlay = gtk_toggle_button_new(); - btnModeEdit = gtk_toggle_button_new(); - btnModeDraw = gtk_toggle_button_new(); - - gtk_container_add(GTK_CONTAINER(btnPlay), image_play); - gtk_container_add(GTK_CONTAINER(btnHalt), image_pause); - gtk_container_add(GTK_CONTAINER(btnModePlay), image_mode_play); - gtk_container_add(GTK_CONTAINER(btnModeEdit), image_mode_edit); - gtk_container_add(GTK_CONTAINER(btnModeDraw), image_mode_draw); - - GtkWidget* top_hbox = gtk_hbox_new(false, 18); - GtkWidget* play_hbox = gtk_hbox_new(false, 6); - GtkWidget* mode_hbox = gtk_hbox_new(false, 6); - - gtk_box_pack_start(GTK_BOX(play_hbox), btnPlay, false, true, 0); - gtk_box_pack_start(GTK_BOX(play_hbox), btnHalt, false, true, 0); - gtk_box_pack_start(GTK_BOX(mode_hbox), btnModePlay, false, true, 0); - gtk_box_pack_start(GTK_BOX(mode_hbox), btnModeEdit, false, true, 0); - gtk_box_pack_start(GTK_BOX(mode_hbox), btnModeDraw, false, true, 0); - - lblCursor = gtk_label_new(""); - gtk_misc_set_alignment(GTK_MISC(lblCursor), 0.0, 0.5); - - gtk_box_pack_start(GTK_BOX(top_hbox), lblCursor, true, true, 0); - gtk_box_pack_start(GTK_BOX(top_hbox), play_hbox, false, true, 0); - gtk_box_pack_start(GTK_BOX(top_hbox), mode_hbox, false, true, 0); - - // ------------ Statusbar --------------------- - GtkWidget* statusbar = gtk_hbox_new(false, 6); - - GtkWidget* status_frame = gtk_frame_new(NULL); - gtk_frame_set_shadow_type(GTK_FRAME(status_frame), GTK_SHADOW_IN); - gtk_container_add(GTK_CONTAINER(status_frame), statusbar); - - lblFrame = gtk_label_new("Frame: 0"); - lblScript = gtk_label_new("Script: 0"); - lblTime = gtk_label_new("00:00:00 (0 FPS)"); - - gtk_misc_set_alignment(GTK_MISC(lblFrame), 0.0, 0.5); - gtk_misc_set_alignment(GTK_MISC(lblScript), 0.0, 0.5); - gtk_misc_set_alignment(GTK_MISC(lblTime), 0.0, 0.5); - - GtkWidget* sep1 = gtk_vseparator_new(); - GtkWidget* sep2 = gtk_vseparator_new(); - - gtk_box_pack_start(GTK_BOX(statusbar), lblFrame, true, true, 0); - gtk_box_pack_start(GTK_BOX(statusbar), sep1, false, false, 0); - gtk_box_pack_start(GTK_BOX(statusbar), lblScript, true, true, 0); - gtk_box_pack_start(GTK_BOX(statusbar), sep2, false, false, 0); - gtk_box_pack_start(GTK_BOX(statusbar), lblTime, true, true, 0); - - // ------------ Log view and script entry --------------------- - GtkWidget* scroll = gtk_scrolled_window_new(NULL, NULL); - - txtLog = gtk_text_view_new(); - txtScript = gtk_entry_new(); - - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_text_view_set_editable(GTK_TEXT_VIEW(txtLog), false); - - gtk_container_add(GTK_CONTAINER(scroll), txtLog); - - // ------------ Menu ------------------- - menuBar = gtk_menu_bar_new(); - - GtkWidget* itemFile = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_FILE")); - GtkWidget* itemComponents = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_COMPONENTS")); - GtkWidget* itemPlayer = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_PLAYER")); - GtkWidget* itemViewport = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_VIEWPORT")); - GtkWidget* itemHelp = gtk_menu_item_new_with_label("?"); - - gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemFile); - gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemComponents); - gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemPlayer); - gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemViewport); - gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemHelp); - - GtkWidget* menuFile = gtk_menu_new(); - GtkWidget* menuComponents = gtk_menu_new(); - GtkWidget* menuHelp = gtk_menu_new(); - - menuPlayer = gtk_menu_new(); - menuViewport = gtk_menu_new(); - - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemFile), menuFile); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemComponents), menuComponents); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemPlayer), menuPlayer); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemViewport), menuViewport); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemHelp), menuHelp); - - fileOpen = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPEN")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpen); - - fileOpenWithPlayers = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPENWPLRS")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpenWithPlayers); - - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); - - fileSave = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIO")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSave); - - fileSaveAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIOAS")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveAs); - - fileSaveGame = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAME")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGame); - - fileSaveGameAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAMEAS")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGameAs); - - fileRecord = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_RECORD")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileRecord); - - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); - - fileClose = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_CLOSE")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileClose); - - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); - - fileQuit = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_QUIT")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileQuit); - - compObjects = gtk_menu_item_new_with_label(LoadResStr("IDS_BTN_OBJECTS")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compObjects); - - compScript = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SCRIPT")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compScript); - - compTitle = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_TITLE")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compTitle); - - compInfo = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_INFO")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compInfo); - - plrJoin = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_JOIN")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuPlayer), plrJoin); - - viewNew = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NEW")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuViewport), viewNew); - - helpAbout = gtk_menu_item_new_with_label(LoadResStr("IDS_MENU_ABOUT")); - gtk_menu_shell_append(GTK_MENU_SHELL(menuHelp), helpAbout); - - // ------------ Window --------------------- - GtkWidget* topbox = gtk_vbox_new(false, 0); - GtkWidget* midbox = gtk_vbox_new(false, 6); - gtk_container_set_border_width(GTK_CONTAINER(midbox), 6); - - gtk_box_pack_start(GTK_BOX(midbox), scroll, true, true, 0); - gtk_box_pack_start(GTK_BOX(midbox), txtScript, false, false, 0); - gtk_box_pack_start(GTK_BOX(midbox), top_hbox, false, true, 0); - - gtk_box_pack_start(GTK_BOX(topbox), menuBar, false, false, 0); - gtk_box_pack_start(GTK_BOX(topbox), midbox, true, true, 0); - gtk_box_pack_start(GTK_BOX(topbox), status_frame, false, false, 0); - - gtk_window_set_default_size(GTK_WINDOW(window), 320, 320); - - gtk_container_add(GTK_CONTAINER(window), topbox); - - // ------------ Signals --------------------- - handlerPlay = g_signal_connect(G_OBJECT(btnPlay), "toggled", G_CALLBACK(OnPlay), this); - handlerHalt = g_signal_connect(G_OBJECT(btnHalt), "toggled", G_CALLBACK(OnHalt), this); - handlerModePlay = g_signal_connect(G_OBJECT(btnModePlay), "toggled", G_CALLBACK(OnModePlay), this); - handlerModeEdit = g_signal_connect(G_OBJECT(btnModeEdit), "toggled", G_CALLBACK(OnModeEdit), this); - handlerModeDraw = g_signal_connect(G_OBJECT(btnModeDraw), "toggled", G_CALLBACK(OnModeDraw), this); - g_signal_connect(G_OBJECT(txtScript), "activate", G_CALLBACK(OnScriptEntry), this); - g_signal_connect(G_OBJECT(fileOpen), "activate", G_CALLBACK(OnFileOpen), this); - g_signal_connect(G_OBJECT(fileOpenWithPlayers), "activate", G_CALLBACK(OnFileOpenWPlrs), this); - g_signal_connect(G_OBJECT(fileSave), "activate", G_CALLBACK(OnFileSave), this); - g_signal_connect(G_OBJECT(fileSaveAs), "activate", G_CALLBACK(OnFileSaveAs), this); - g_signal_connect(G_OBJECT(fileSaveGame), "activate", G_CALLBACK(OnFileSaveGame), this); - g_signal_connect(G_OBJECT(fileSaveGameAs), "activate", G_CALLBACK(OnFileSaveGameAs), this); - g_signal_connect(G_OBJECT(fileRecord), "activate", G_CALLBACK(OnFileRecord), this); - g_signal_connect(G_OBJECT(fileClose), "activate", G_CALLBACK(OnFileClose), this); - g_signal_connect(G_OBJECT(fileQuit), "activate", G_CALLBACK(OnFileQuit), this); - g_signal_connect(G_OBJECT(compObjects), "activate", G_CALLBACK(OnCompObjects), this); - g_signal_connect(G_OBJECT(compScript), "activate", G_CALLBACK(OnCompScript), this); - g_signal_connect(G_OBJECT(compTitle), "activate", G_CALLBACK(OnCompTitle), this); - g_signal_connect(G_OBJECT(compInfo), "activate", G_CALLBACK(OnCompInfo), this); - g_signal_connect(G_OBJECT(plrJoin), "activate", G_CALLBACK(OnPlrJoin), this); - g_signal_connect(G_OBJECT(viewNew), "activate", G_CALLBACK(OnViewNew), this); - g_signal_connect(G_OBJECT(helpAbout), "activate", G_CALLBACK(OnHelpAbout), this); - - return C4ConsoleBase::InitGUI(); -} -#endif // WITH_DEVELOPER_MODE - bool C4Console::In(const char *szText) { if (!Active || !szText) return false; @@ -592,53 +119,6 @@ bool C4Console::In(const char *szText) return true; } -bool C4Console::Out(const char *szText) -{ -#ifdef _WIN32 - if (!Active) return false; - if (!szText || !*szText) return true; - int len,len2,lines; char *buffer, *buffer2; - len = 65000;//SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINELENGTH,(WPARAM)0,(LPARAM)0); - len2 = len+Min(strlen(szText)+2, 5000); - buffer = new char [len2]; - buffer[0]=0; - GetDlgItemText(hWindow,IDC_EDITOUTPUT,buffer,len); - if (buffer[0]) SAppend("\r\n",buffer); - SAppend(szText,buffer,len2-1); - if (strlen(buffer) > 60000) buffer2 = buffer + strlen(buffer) - 60000; else buffer2 = buffer; // max log length: Otherwise, discard beginning - SetDlgItemText(hWindow,IDC_EDITOUTPUT,buffer2); - delete [] buffer; - lines = SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_GETLINECOUNT,(WPARAM)0,(LPARAM)0); - SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,(LPARAM)lines); - UpdateWindow(hWindow); -#elif defined(WITH_DEVELOPER_MODE) - // Append text to log - if (!window) return true; - - GtkTextIter end; - GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtLog)); - gtk_text_buffer_get_end_iter(buffer, &end); - - gtk_text_buffer_insert(buffer, &end, szText, -1); - gtk_text_buffer_insert(buffer, &end, "\n", 1); - - gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(txtLog), gtk_text_buffer_get_insert(buffer), 0.0, false, 0.0, 0.0); -#endif // WITH_DEVELOPER_MODE / _WIN32 - return true; -} - -bool C4Console::ClearLog() -{ -#ifdef _WIN32 - SetDlgItemText(hWindow,IDC_EDITOUTPUT,""); - SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,0); - UpdateWindow(hWindow); -#elif defined(WITH_DEVELOPER_MODE) - gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtLog)), "", 0); -#endif // WITH_DEVELOPER_MODE / _WIN32 - return true; -} - // Someone defines Status as int.... #ifdef Status #undef Status @@ -663,12 +143,7 @@ bool C4Console::UpdateStatusBars() FrameCounter=Game.FrameCounter; StdStrBuf str; str.Format("Frame: %i",FrameCounter); -#ifdef _WIN32 - SetDlgItemText(hWindow,IDC_STATICFRAME,str.getData()); - UpdateWindow(GetDlgItem(hWindow,IDC_STATICFRAME)); -#elif defined(WITH_DEVELOPER_MODE) - gtk_label_set_label(GTK_LABEL(lblFrame), str.getData()); -#endif // WITH_DEVELOPER_MODE / _WIN32 + C4ConsoleGUI::DisplayInfoText(CONSOLE_FrameCounter, str); } // Script counter if (Game.Script.Counter!=ScriptCounter) @@ -676,12 +151,7 @@ bool C4Console::UpdateStatusBars() ScriptCounter=Game.Script.Counter; StdStrBuf str; str.Format("Script: %i",ScriptCounter); -#ifdef _WIN32 - SetDlgItemText(hWindow,IDC_STATICSCRIPT,str.getData()); - UpdateWindow(GetDlgItem(hWindow,IDC_STATICSCRIPT)); -#elif defined(WITH_DEVELOPER_MODE) - gtk_label_set_label(GTK_LABEL(lblScript), str.getData()); -#endif // WITH_DEVELOPER_MODE / _WIN32 + C4ConsoleGUI::DisplayInfoText(CONSOLE_ScriptCounter, str); } // Time & FPS if ((Game.Time!=Time) || (Game.FPS!=FPS)) @@ -690,41 +160,11 @@ bool C4Console::UpdateStatusBars() FPS=Game.FPS; StdStrBuf str; str.Format("%02d:%02d:%02d (%i FPS)",Time/3600,(Time%3600)/60,Time%60,FPS); -#ifdef _WIN32 - SetDlgItemText(hWindow,IDC_STATICTIME,str.getData()); - UpdateWindow(GetDlgItem(hWindow,IDC_STATICTIME)); -#elif defined(WITH_DEVELOPER_MODE) - gtk_label_set_label(GTK_LABEL(lblTime), str.getData()); -#endif // WITH_DEVELOPER_MODE + C4ConsoleGUI::DisplayInfoText(CONSOLE_TimeFPS, str); } return true; } -bool C4Console::UpdateHaltCtrls(bool fHalt) -{ - if (!Active) return false; -#ifdef _WIN32 - SendDlgItemMessage(hWindow,IDC_BUTTONPLAY,BM_SETSTATE,!fHalt,0); - UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONPLAY)); - SendDlgItemMessage(hWindow,IDC_BUTTONHALT,BM_SETSTATE,fHalt,0); - UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONHALT)); -#elif defined(WITH_DEVELOPER_MODE) - // Prevents recursion - g_signal_handler_block(btnPlay, handlerPlay); - g_signal_handler_block(btnHalt, handlerHalt); - - //gtk_widget_set_sensitive(btnPlay, fHalt); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btnPlay), !fHalt); - //gtk_widget_set_sensitive(btnHalt, !fHalt); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btnHalt), fHalt); - - g_signal_handler_unblock(btnPlay, handlerPlay); - g_signal_handler_unblock(btnHalt, handlerHalt); - -#endif // WITH_DEVELOPER_MODE / _WIN32 - return true; -} - bool C4Console::SaveGame(bool fSaveGame) { // Network hosts only @@ -744,16 +184,7 @@ bool C4Console::SaveGame(bool fSaveGame) // Save game to open scenario file bool fOkay=true; -#ifdef _WIN32 - SetCursor(LoadCursor(0,IDC_WAIT)); -#elif defined(WITH_DEVELOPER_MODE) - // Seems not to work. Don't know why... -#if GTK_CHECK_VERSION(2,14,0) - gdk_window_set_cursor(gtk_widget_get_window(window), cursorWait); -#else - gdk_window_set_cursor(window->window, cursorWait); -#endif -#endif + Console.SetCursor(C4ConsoleGUI::CURSOR_Wait); C4GameSave *pGameSave; if (fSaveGame) @@ -770,15 +201,7 @@ bool C4Console::SaveGame(bool fSaveGame) if (!Game.ScenarioFile.Open(Game.ScenarioFilename)) { Out("ScenarioFile::Open failed"); fOkay=false; } -#ifdef _WIN32 - SetCursor(LoadCursor(0,IDC_ARROW)); -#elif defined(WITH_DEVELOPER_MODE) -#if GTK_CHECK_VERSION(2,14,0) - gdk_window_set_cursor(gtk_widget_get_window(window), NULL); -#else - gdk_window_set_cursor(window->window, NULL); -#endif -#endif + Console.SetCursor(C4ConsoleGUI::CURSOR_Normal); // Initialize/script notification if (Game.fScriptCreatedObjects) @@ -842,97 +265,7 @@ bool C4Console::FileSaveAs(bool fSaveGame) bool C4Console::Message(const char *szMessage, bool fQuery) { if (!Active) return false; -#ifdef _WIN32 - return (IDOK==MessageBox(hWindow,szMessage,C4ENGINECAPTION,fQuery ? (MB_OKCANCEL | MB_ICONEXCLAMATION) : MB_ICONEXCLAMATION)); -#elif defined(WITH_DEVELOPER_MODE) - GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, fQuery ? (GTK_BUTTONS_OK_CANCEL) : (GTK_BUTTONS_OK), "%s", szMessage); - int response = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - return response == GTK_RESPONSE_OK; -#endif - return false; -} - -void C4Console::EnableControls(bool fEnable) -{ - if (!Active) return; - // disable Editing if no input allowed - Editing &= !::Control.NoInput(); - -#ifdef _WIN32 - // Set button images (edit modes & halt controls) - SendDlgItemMessage(hWindow,IDC_BUTTONMODEPLAY,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(fEnable ? hbmMouse : hbmMouse2)); - SendDlgItemMessage(hWindow,IDC_BUTTONMODEEDIT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((fEnable && Editing) ? hbmCursor : hbmCursor2)); - SendDlgItemMessage(hWindow,IDC_BUTTONMODEDRAW,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((fEnable && Editing) ? hbmBrush : hbmBrush2)); - SendDlgItemMessage(hWindow,IDC_BUTTONPLAY,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(::Network.isLobbyActive() || fEnable ? hbmPlay : hbmPlay2)); - SendDlgItemMessage(hWindow,IDC_BUTTONHALT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(::Network.isLobbyActive() || fEnable ? hbmHalt : hbmHalt2)); - - // OK - EnableWindow( GetDlgItem(hWindow,IDOK), fEnable); - - // Halt controls - EnableWindow(GetDlgItem(hWindow,IDC_BUTTONPLAY), ::Network.isLobbyActive() || fEnable); - EnableWindow(GetDlgItem(hWindow,IDC_BUTTONHALT), ::Network.isLobbyActive() || fEnable); - - // Edit modes - EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEPLAY),(fEnable)); - EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEEDIT),(fEnable && Editing)); - EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEDRAW),(fEnable && Editing)); - - // Console input - EnableWindow(GetDlgItem(hWindow,IDC_COMBOINPUT), fEnable); - - // File menu - // C4Network2 will have to handle that cases somehow (TODO: test) - EnableMenuItem(GetMenu(hWindow),IDM_FILE_OPEN, MF_BYCOMMAND | MF_ENABLED ); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_OPENWPLRS, MF_BYCOMMAND | MF_ENABLED ); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_RECORD, MF_BYCOMMAND | ((Game.IsRunning && ::Control.IsRuntimeRecordPossible()) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEGAME, MF_BYCOMMAND | ((fEnable && ::Players.GetCount()) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEGAMEAS, MF_BYCOMMAND | ((fEnable && ::Players.GetCount()) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVE, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEAS, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_FILE_CLOSE, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); - - // Components menu - EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_SCRIPT, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_INFO, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_TITLE, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); - - // Player & viewport menu - EnableMenuItem(GetMenu(hWindow),IDM_PLAYER_JOIN, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(GetMenu(hWindow),IDM_VIEWPORT_NEW, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); -#elif defined(WITH_DEVELOPER_MODE) - // Halt controls - gtk_widget_set_sensitive(btnPlay, ::Network.isLobbyActive() || fEnable); - gtk_widget_set_sensitive(btnHalt, ::Network.isLobbyActive() || fEnable); - - // Edit modes - gtk_widget_set_sensitive(btnModePlay, ::Network.isLobbyActive() || fEnable); - gtk_widget_set_sensitive(btnModeEdit, ::Network.isLobbyActive() || fEnable); - gtk_widget_set_sensitive(btnModeDraw, ::Network.isLobbyActive() || fEnable); - - // Console input - gtk_widget_set_sensitive(txtScript, ::Network.isLobbyActive() || fEnable); - - // File menu - // C4Network2 will have to handle that cases somehow (TODO: test) - gtk_widget_set_sensitive(fileRecord, Game.IsRunning && ::Control.IsRuntimeRecordPossible()); - gtk_widget_set_sensitive(fileSaveGame, fEnable && ::Players.GetCount()); - gtk_widget_set_sensitive(fileSaveGameAs, fEnable && ::Players.GetCount()); - gtk_widget_set_sensitive(fileSave, fEnable); - gtk_widget_set_sensitive(fileSaveAs, fEnable); - gtk_widget_set_sensitive(fileClose, fEnable); - - // Components menu - gtk_widget_set_sensitive(compObjects, fEnable && Editing); - gtk_widget_set_sensitive(compScript, fEnable && Editing); - gtk_widget_set_sensitive(compInfo, fEnable && Editing); - gtk_widget_set_sensitive(compTitle, fEnable && Editing); - - // Player & viewport menu - gtk_widget_set_sensitive(plrJoin, fEnable && Editing); - gtk_widget_set_sensitive(viewNew, fEnable); -#endif // WITH_DEVELOPER_MODE / _WIN32 + return C4ConsoleGUI::Message(szMessage, fQuery); } bool C4Console::FileOpen() @@ -996,149 +329,7 @@ bool C4Console::FileClose() bool C4Console::FileSelect(char *sFilename, int iSize, const char * szFilter, DWORD dwFlags, bool fSave) { -#ifdef _WIN32 - OPENFILENAME ofn; - ZeroMem(&ofn,sizeof(ofn)); - ofn.lStructSize=sizeof(ofn); - ofn.hwndOwner=hWindow; - ofn.lpstrFilter=szFilter; - ofn.lpstrFile=sFilename; - ofn.nMaxFile=iSize; - ofn.nFileOffset= GetFilename(sFilename) - sFilename; - ofn.nFileExtension= GetExtension(sFilename) - sFilename; - ofn.Flags=dwFlags; - - bool fResult; - const char *wd = GetWorkingDirectory(); - if (fSave) - fResult = !!GetSaveFileName(&ofn); - else - fResult = !!GetOpenFileName(&ofn); - - // Reset working directory to exe path as Windows file dialog might have changed it - SetCurrentDirectory(wd); - return fResult; -#elif defined(WITH_DEVELOPER_MODE) - GtkWidget* dialog = gtk_file_chooser_dialog_new(fSave ? "Save file..." : "Load file...", GTK_WINDOW(window), fSave ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, fSave ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); - - // TODO: Set dialog modal? - - if (g_path_is_absolute(sFilename) ) - gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sFilename); - else if (fSave) - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), sFilename); - - // Install file filter - while (*szFilter) - { - char pattern[16 + 1]; - - GtkFileFilter* filter = gtk_file_filter_new(); - gtk_file_filter_set_name(filter, szFilter); - szFilter+=SLen(szFilter)+1; - - while (true) - { - SCopyUntil(szFilter, pattern, ';', 16); - - int len = SLen(pattern); - char last_c = szFilter[len]; - - szFilter += (len + 1); - - // Got not all of the filter, try again. - if (last_c != ';' && last_c != '\0') - continue; - - gtk_file_filter_add_pattern(filter, pattern); - if (last_c == '\0') break; - } - - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); - } - - // TODO: Not in GTK+ 2.4, we could check GTK+ version at runtime and rely on lazy bindung -// gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_OVERWRITEPROMPT) != 0); - - // TODO: Not in GTK+ 2.4, we could check GTK+ version at runtime and rely on lazy binding -// gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_HIDEREADONLY) == 0); - - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_ALLOWMULTISELECT) != 0); - gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), true); - - int response; - while (true) - { - response = gtk_dialog_run(GTK_DIALOG(dialog)); - if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) break; - - bool error = false; - - // Check for OFN_FILEMUSTEXIST - if ((dwFlags & OFN_ALLOWMULTISELECT) == 0) - { - char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - - if ((dwFlags & OFN_FILEMUSTEXIST) && !g_file_test(filename, G_FILE_TEST_IS_REGULAR)) - { - Message(FormatString("File \"%s\" does not exist", filename).getData(), false); - error = true; - } - - g_free(filename); - } - - if (!error) break; - } - - if (response != GTK_RESPONSE_ACCEPT) - { - gtk_widget_destroy(dialog); - return false; - } - - // Build result string - if ((dwFlags & OFN_ALLOWMULTISELECT) == 0) - { - // Just the file name without multiselect - char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - SCopy(filename, sFilename, iSize); - g_free(filename); - } - else - { - // Otherwise its the folder followed by the file names, - // separated by '\0'-bytes - char* folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); - int len = SLen(folder); - - if (iSize > 0) SCopy(folder, sFilename, Min(len + 1, iSize)); - iSize -= (len + 1); sFilename += (len + 1); - g_free(folder); - - GSList* files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); - for (GSList* item = files; item != NULL; item = item->next) - { - const char* file = static_cast(item->data); - char* basefile = g_path_get_basename(file); - - int len = SLen(basefile); - if (iSize > 0) SCopy(basefile, sFilename, Min(len + 1, iSize)); - iSize -= (len + 1); sFilename += (len + 1); - - g_free(basefile); - g_free(item->data); - } - - // End of list - *sFilename = '\0'; - g_slist_free(files); - } - - gtk_widget_destroy(dialog); - return true; -#endif // WITH_DEVELOPER_MODE / _WIN32 - return 0; + return C4ConsoleGUI::FileSelect(sFilename, iSize, szFilter, dwFlags, fSave); } bool C4Console::FileRecord() @@ -1148,11 +339,7 @@ bool C4Console::FileRecord() // start record! ::Control.RequestRuntimeRecord(); // disable menuitem -#ifdef _WIN32 - EnableMenuItem(GetMenu(hWindow),IDM_FILE_RECORD, MF_BYCOMMAND | MF_GRAYED); -#elif defined(WITH_DEVELOPER_MODE) - gtk_widget_set_sensitive(fileRecord, false); -#endif + RecordingEnabled(); return true; } @@ -1172,13 +359,6 @@ void C4Console::Default() void C4Console::Clear() { C4ConsoleBase::Clear(); - -#ifdef WITH_DEVELOPER_MODE -// txtLog = NULL; -// txtScript = NULL; -// btnPlay = NULL; -// btnHalt = NULL; -#endif EditCursor.Clear(); PropertyDlg.Clear(); ToolsDlg.Clear(); @@ -1207,12 +387,7 @@ void C4Console::HelpAbout() { StdStrBuf strCopyright; strCopyright.Format("Copyright (c) %s %s", C4COPYRIGHT_YEAR, C4COPYRIGHT_COMPANY); -#ifdef _WIN32 - StdStrBuf strMessage; strMessage.Format("%s %s\n\n%s", C4ENGINECAPTION, C4VERSION, strCopyright.getData()); - MessageBox(NULL, strMessage.getData(), C4ENGINECAPTION, MB_ICONINFORMATION | MB_TASKMODAL); -#elif defined(WITH_DEVELOPER_MODE) - gtk_show_about_dialog(GTK_WINDOW(window), "name", C4ENGINECAPTION, "version", C4VERSION, "copyright", strCopyright.getData(), NULL); -#endif // WITH_DEVELOPER_MODE / _WIN32 + ShowAboutWithCopyright(strCopyright); } void C4Console::ViewportNew() @@ -1220,38 +395,15 @@ void C4Console::ViewportNew() ::Viewports.CreateViewport(NO_OWNER); } -bool C4Console::UpdateCursorBar(const char *szCursor) -{ - if (!Active) return false; -#ifdef _WIN32 - // Cursor - SetDlgItemText(hWindow,IDC_STATICCURSOR,szCursor); - UpdateWindow(GetDlgItem(hWindow,IDC_STATICCURSOR)); -#elif defined(WITH_DEVELOPER_MODE) - gtk_label_set_label(GTK_LABEL(lblCursor), szCursor); -#endif - return true; -} - bool C4Console::UpdateViewportMenu() { if (!Active) return false; ClearViewportMenu(); -#ifdef _WIN32 - HMENU hMenu = GetSubMenu(GetMenu(hWindow),MenuIndexViewport); -#endif for (C4Player *pPlr=::Players.First; pPlr; pPlr=pPlr->Next) { StdStrBuf sText; sText.Format(LoadResStr("IDS_CNS_NEWPLRVIEWPORT"),pPlr->GetName()); -#ifdef _WIN32 - AddMenuItem(hMenu,IDM_VIEWPORT_NEW1+pPlr->Number,sText.getData()); -#elif defined(WITH_DEVELOPER_MODE) - GtkWidget* menuItem = gtk_menu_item_new_with_label(sText.getData()); - gtk_menu_shell_append(GTK_MENU_SHELL(menuViewport), menuItem); - g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(OnViewNewPlr), GINT_TO_POINTER(pPlr->Number)); - gtk_widget_show(menuItem); -#endif // WITH_DEVELOPER_MODE / _WIN32 + C4ConsoleGUI::AddMenuItemForPlayer(pPlr, sText); } return true; } @@ -1259,63 +411,7 @@ bool C4Console::UpdateViewportMenu() void C4Console::ClearViewportMenu() { if (!Active) return; -#ifdef _WIN32 - HMENU hMenu = GetSubMenu(GetMenu(hWindow),MenuIndexViewport); - while (DeleteMenu(hMenu,1,MF_BYPOSITION)); -#elif defined(WITH_DEVELOPER_MODE) - GList* children = gtk_container_get_children(GTK_CONTAINER(menuViewport)); - for (GList* item = children; item != NULL; item = item->next) - { - if (item->data != viewNew) - gtk_container_remove(GTK_CONTAINER(menuViewport), GTK_WIDGET(item->data)); - } - g_list_free(children); -#endif // WITH_DEVELOPER_MODE / _WIN32 -} - -#ifdef _WIN32 -bool C4Console::AddMenuItem(HMENU hMenu, DWORD dwID, const char *szString, bool fEnabled) -{ - if (!Active) return false; - MENUITEMINFO minfo; - ZeroMem(&minfo,sizeof(minfo)); - minfo.cbSize = sizeof(minfo); - minfo.fMask = MIIM_ID | MIIM_TYPE | MIIM_DATA | MIIM_STATE; - minfo.fType = MFT_STRING; - minfo.wID = dwID; - minfo.dwTypeData = (char*) szString; - minfo.cch = SLen(szString); - if (!fEnabled) minfo.fState|=MFS_GRAYED; - return !!InsertMenuItem(hMenu,0,false,&minfo); -} - -#endif // _WIN32 -bool C4Console::UpdateModeCtrls(int iMode) -{ - if (!Active) return false; - -#ifdef _WIN32 - SendDlgItemMessage(hWindow,IDC_BUTTONMODEPLAY,BM_SETSTATE,(iMode==C4CNS_ModePlay),0); - UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEPLAY)); - SendDlgItemMessage(hWindow,IDC_BUTTONMODEEDIT,BM_SETSTATE,(iMode==C4CNS_ModeEdit),0); - UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEEDIT)); - SendDlgItemMessage(hWindow,IDC_BUTTONMODEDRAW,BM_SETSTATE,(iMode==C4CNS_ModeDraw),0); - UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEDRAW)); -#elif defined(WITH_DEVELOPER_MODE) - // Prevents recursion - g_signal_handler_block(btnModePlay, handlerModePlay); - g_signal_handler_block(btnModeEdit, handlerModeEdit); - g_signal_handler_block(btnModeDraw, handlerModeDraw); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btnModePlay), iMode == C4CNS_ModePlay); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btnModeEdit), iMode == C4CNS_ModeEdit); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btnModeDraw), iMode == C4CNS_ModeDraw); - - g_signal_handler_unblock(btnModePlay, handlerModePlay); - g_signal_handler_unblock(btnModeEdit, handlerModeEdit); - g_signal_handler_unblock(btnModeDraw, handlerModeDraw); -#endif // WITH_DEVELOPER_MODE / _WIN32 - return true; + C4ConsoleGUI::ClearViewportMenu(); } void C4Console::EditTitle() @@ -1346,64 +442,31 @@ void C4Console::UpdateInputCtrl() { int cnt; C4AulScriptFunc *pRef; -#ifdef _WIN32 - HWND hCombo = GetDlgItem(hWindow,IDC_COMBOINPUT); - // Clear - SendMessage(hCombo,CB_RESETCONTENT,0,0); -#elif defined(WITH_DEVELOPER_MODE) - GtkEntryCompletion* completion = gtk_entry_get_completion(GTK_ENTRY(txtScript)); - if (!completion) - { - completion = gtk_entry_completion_new(); - GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING); - gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store)); - g_object_unref(G_OBJECT(store)); - gtk_entry_completion_set_text_column(completion, 0); - gtk_entry_set_completion(GTK_ENTRY(txtScript), completion); - g_object_unref(G_OBJECT(completion)); - } - GtkTreeIter iter; - GtkListStore* store = GTK_LIST_STORE(gtk_entry_completion_get_model(completion)); - g_assert(store); - gtk_list_store_clear(store); -#endif // WITH_DEVELOPER_MODE / _WIN32 + ClearInput(); // add global and standard functions + std::vector functions; for (C4AulFunc *pFn = ::ScriptEngine.GetFirstFunc(); pFn; pFn = ::ScriptEngine.GetNextFunc(pFn)) + { if (pFn->GetPublic()) { -#ifdef _WIN32 - SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)pFn->Name); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, pFn->Name, -1); -#endif -#endif + functions.push_back(pFn->Name); } + } // Add scenario script functions -#ifdef _WIN32 - if ( (pRef=Game.Script.GetSFunc(0)) ) - SendMessage(hCombo,CB_INSERTSTRING,0,(LPARAM)"----------"); -#endif + if (pRef=Game.Script.GetSFunc(0)) + functions.push_back((char*)C4ConsoleGUI::LIST_DIVIDER); for (cnt=0; (pRef=Game.Script.GetSFunc(cnt)); cnt++) { -#ifdef _WIN32 - SendMessage(hCombo,CB_INSERTSTRING,0,(LPARAM)pRef->Name); -#elif defined(WITH_DEVELOPER_MODE) - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, pRef->Name, -1); -#endif + functions.push_back(pRef->Name); } + SetInputFunctions(functions); } bool C4Console::UpdatePlayerMenu() { if (!Active) return false; ClearPlayerMenu(); -#ifdef _WIN32 - HMENU hMenu = GetSubMenu(GetMenu(hWindow),MenuIndexPlayer); -#endif for (C4Player *pPlr=::Players.First; pPlr; pPlr=pPlr->Next) { StdStrBuf sText; @@ -1411,38 +474,11 @@ bool C4Console::UpdatePlayerMenu() sText.Format(LoadResStr("IDS_CNS_PLRQUITNET"),pPlr->GetName(),pPlr->AtClientName); else sText.Format(LoadResStr("IDS_CNS_PLRQUIT"),pPlr->GetName()); -#ifdef _WIN32 - AddMenuItem(hMenu,IDM_PLAYER_QUIT1+pPlr->Number,sText.getData(),(!::Network.isEnabled() || ::Network.isHost()) && Editing); -#elif defined(WITH_DEVELOPER_MODE) - // TODO: Implement AddMenuItem... - GtkWidget* menuItem = gtk_menu_item_new_with_label(sText.getData()); - gtk_menu_shell_append(GTK_MENU_SHELL(menuPlayer), menuItem); - g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(OnPlrQuit), GINT_TO_POINTER(pPlr->Number)); - gtk_widget_show(menuItem); - - gtk_widget_set_sensitive(menuItem, (!::Network.isEnabled() || ::Network.isHost()) && Editing); -#endif // WITH_DEVELOPER_MODE / _WIN32 + AddKickPlayerMenuItem(pPlr, sText, (!::Network.isEnabled() || ::Network.isHost()) && Editing); } return true; } -void C4Console::ClearPlayerMenu() -{ - if (!Active) return; -#ifdef _WIN32 - HMENU hMenu = GetSubMenu(GetMenu(hWindow),MenuIndexPlayer); - while (DeleteMenu(hMenu,1,MF_BYPOSITION)); -#elif defined(WITH_DEVELOPER_MODE) - GList* children = gtk_container_get_children(GTK_CONTAINER(menuPlayer)); - for (GList* item = children; item != NULL; item = item->next) - { - if (item->data != plrJoin) - gtk_container_remove(GTK_CONTAINER(menuPlayer), GTK_WIDGET(item->data)); - } - g_list_free(children); -#endif // _WIN32 -} - void C4Console::UpdateMenus() { if (!Active) return; @@ -1494,43 +530,6 @@ void C4Console::PlayerJoin() } -#ifdef _WIN32 -void C4Console::UpdateMenuText(HMENU hMenu) -{ - HMENU hSubMenu; - if (!Active) return; - // File - ModifyMenu(hMenu,MenuIndexFile,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_FILE")); - hSubMenu = GetSubMenu(hMenu,MenuIndexFile); - SetMenuItemText(hSubMenu,IDM_FILE_OPEN,LoadResStr("IDS_MNU_OPEN")); - SetMenuItemText(hSubMenu,IDM_FILE_OPENWPLRS,LoadResStr("IDS_MNU_OPENWPLRS")); - SetMenuItemText(hSubMenu,IDM_FILE_RECORD,LoadResStr("IDS_MNU_RECORD")); - SetMenuItemText(hSubMenu,IDM_FILE_SAVE,LoadResStr("IDS_MNU_SAVESCENARIO")); - SetMenuItemText(hSubMenu,IDM_FILE_SAVEAS,LoadResStr("IDS_MNU_SAVESCENARIOAS")); - SetMenuItemText(hSubMenu,IDM_FILE_SAVEGAME,LoadResStr("IDS_MNU_SAVEGAME")); - SetMenuItemText(hSubMenu,IDM_FILE_SAVEGAMEAS,LoadResStr("IDS_MNU_SAVEGAMEAS")); - SetMenuItemText(hSubMenu,IDM_FILE_CLOSE,LoadResStr("IDS_MNU_CLOSE")); - SetMenuItemText(hSubMenu,IDM_FILE_QUIT,LoadResStr("IDS_MNU_QUIT")); - // Components - ModifyMenu(hMenu,MenuIndexComponents,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_COMPONENTS")); - hSubMenu = GetSubMenu(hMenu,MenuIndexComponents); - SetMenuItemText(hSubMenu,IDM_COMPONENTS_SCRIPT,LoadResStr("IDS_MNU_SCRIPT")); - SetMenuItemText(hSubMenu,IDM_COMPONENTS_TITLE,LoadResStr("IDS_MNU_TITLE")); - SetMenuItemText(hSubMenu,IDM_COMPONENTS_INFO,LoadResStr("IDS_MNU_INFO")); - // Player - ModifyMenu(hMenu,MenuIndexPlayer,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_PLAYER")); - hSubMenu = GetSubMenu(hMenu,MenuIndexPlayer); - SetMenuItemText(hSubMenu,IDM_PLAYER_JOIN,LoadResStr("IDS_MNU_JOIN")); - // Viewport - ModifyMenu(hMenu,MenuIndexViewport,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_VIEWPORT")); - hSubMenu = GetSubMenu(hMenu,MenuIndexViewport); - SetMenuItemText(hSubMenu,IDM_VIEWPORT_NEW,LoadResStr("IDS_MNU_NEW")); - // Help - hSubMenu = GetSubMenu(hMenu,MenuIndexHelp); - SetMenuItemText(hSubMenu,IDM_HELP_ABOUT,LoadResStr("IDS_MENU_ABOUT")); -} -#endif // _WIN32 - void C4Console::UpdateNetMenu() { // Active & network hosting check @@ -1539,49 +538,24 @@ void C4Console::UpdateNetMenu() // Clear old ClearNetMenu(); // Insert menu -#ifdef _WIN32 - if (!InsertMenu(GetMenu(hWindow),MenuIndexHelp,MF_BYPOSITION | MF_POPUP,(UINT_PTR)CreateMenu(),LoadResStr("IDS_MNU_NET"))) return; -#elif defined(WITH_DEVELOPER_MODE) - itemNet = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NET")); - GtkWidget* menuNet = gtk_menu_new(); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemNet), menuNet); - gtk_menu_shell_insert(GTK_MENU_SHELL(menuBar), itemNet, MenuIndexHelp); -#endif + C4ConsoleGUI::UpdateNetMenu(C4ConsoleGUI::STAGE_Start); MenuIndexNet=MenuIndexHelp; MenuIndexHelp++; -#ifdef _WIN32 - DrawMenuBar(hWindow); - // Update menu - HMENU hMenu = GetSubMenu(GetMenu(hWindow),MenuIndexNet); -#endif + C4ConsoleGUI::UpdateNetMenu(C4ConsoleGUI::STAGE_Intermediate); // Host StdStrBuf str; str.Format(LoadResStr("IDS_MNU_NETHOST"),Game.Clients.getLocalName(),Game.Clients.getLocalID()); -#ifdef _WIN32 - AddMenuItem(hMenu,IDM_NET_CLIENT1+Game.Clients.getLocalID(),str.getData()); -#elif defined(WITH_DEVELOPER_MODE) - GtkWidget* item = gtk_menu_item_new_with_label(str.getData()); - gtk_menu_shell_append(GTK_MENU_SHELL(menuNet), item); - g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(OnNetClient), GINT_TO_POINTER(Game.Clients.getLocalID())); -#endif + AddNetMenuItemForPlayer(IDM_NET_CLIENT1+Game.Clients.getLocalID(), str); // Clients for (C4Network2Client *pClient=::Network.Clients.GetNextClient(NULL); pClient; pClient=::Network.Clients.GetNextClient(pClient)) { str.Format(LoadResStr(pClient->isActivated() ? "IDS_MNU_NETCLIENT" : "IDS_MNU_NETCLIENTDE"), pClient->getName(), pClient->getID()); -#ifdef _WIN32 - AddMenuItem(hMenu,IDM_NET_CLIENT1+pClient->getID(), str.getData()); -#elif defined(WITH_DEVELOPER_MODE) - item = gtk_menu_item_new_with_label(str.getData()); - gtk_menu_shell_append(GTK_MENU_SHELL(menuNet), item); - g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(OnNetClient), GINT_TO_POINTER(pClient->getID())); -#endif + AddNetMenuItemForPlayer(IDM_NET_CLIENT1+pClient->getID(), str); } -#ifdef WITH_DEVELOPER_MODE - gtk_widget_show_all(itemNet); -#endif + C4ConsoleGUI::UpdateNetMenu(C4ConsoleGUI::STAGE_End); return; } @@ -1589,29 +563,16 @@ void C4Console::ClearNetMenu() { if (!Active) return; if (MenuIndexNet<0) return; -#ifdef _WIN32 - DeleteMenu(GetMenu(hWindow),MenuIndexNet,MF_BYPOSITION); -#elif defined(WITH_DEVELOPER_MODE) - gtk_container_remove(GTK_CONTAINER(menuBar), itemNet); - itemNet = NULL; -#endif + C4ConsoleGUI::ClearNetMenu(C4ConsoleGUI::STAGE_Start); MenuIndexNet=-1; MenuIndexHelp--; -#ifdef _WIN32 - DrawMenuBar(hWindow); -#endif + C4ConsoleGUI::ClearNetMenu(C4ConsoleGUI::STAGE_End); } -void C4Console::SetCaption(const char *szCaption) +void C4Console::SetCaptionToFilename(const char* szFilename) { - if (!Active) return; -#ifdef _WIN32 - // Sorry, the window caption needs to be constant so - // the window can be found using FindWindow - SetTitle(C4ENGINECAPTION); -#else - SetTitle(szCaption); -#endif + SetCaption(GetFilename(szFilename)); + C4ConsoleGUI::SetCaptionToFileName(szFilename); } void C4Console::Execute() @@ -1653,6 +614,7 @@ bool C4Console::OpenGame() EnableControls(fGameOpen); UpdatePlayerMenu(); UpdateViewportMenu(); + SetCaptionToFilename(Game.ScenarioFilename); return true; } @@ -1673,142 +635,3 @@ bool C4Console::TogglePause() { return Game.TogglePause(); } - -// GTK+ callbacks -#ifdef WITH_DEVELOPER_MODE -void C4Console::OnScriptEntry(GtkWidget* entry, gpointer data) -{ - C4Console* console = static_cast(data); - console->In(gtk_entry_get_text(GTK_ENTRY(console->txtScript))); - gtk_editable_select_region(GTK_EDITABLE(console->txtScript), 0, -1); -} - -void C4Console::OnPlay(GtkWidget* button, gpointer data) -{ - static_cast(data)->DoPlay(); - - // Must update haltctrls even if DoPlay did noting to restore - // previous settings since GTK may have released this toggle button - static_cast(data)->UpdateHaltCtrls(!!Game.HaltCount); -} - -void C4Console::OnHalt(GtkWidget* button, gpointer data) -{ - static_cast(data)->DoHalt(); - - // Must update haltctrls even if DoPlay did noting to restore - // previous settings since GTK may have released this toggle button - static_cast(data)->UpdateHaltCtrls(!!Game.HaltCount); -} - -void C4Console::OnModePlay(GtkWidget* button, gpointer data) -{ - static_cast(data)->EditCursor.SetMode(C4CNS_ModePlay); -} - -void C4Console::OnModeEdit(GtkWidget* button, gpointer data) -{ - static_cast(data)->EditCursor.SetMode(C4CNS_ModeEdit); -} - -void C4Console::OnModeDraw(GtkWidget* button, gpointer data) -{ - static_cast(data)->EditCursor.SetMode(C4CNS_ModeDraw); -} - -void C4Console::OnFileOpen(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileOpen(); -} - -void C4Console::OnFileOpenWPlrs(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileOpenWPlrs(); -} - -void C4Console::OnFileSave(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileSave(false); -} - -void C4Console::OnFileSaveAs(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileSaveAs(false); -} - -void C4Console::OnFileSaveGame(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileSave(true); -} - -void C4Console::OnFileSaveGameAs(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileSaveAs(true); -} - -void C4Console::OnFileRecord(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileRecord(); -} - -void C4Console::OnFileClose(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileClose(); -} - -void C4Console::OnFileQuit(GtkWidget* item, gpointer data) -{ - static_cast(data)->FileQuit(); -} - -void C4Console::OnCompObjects(GtkWidget* item, gpointer data) -{ - static_cast(data)->EditObjects(); -} - -void C4Console::OnCompScript(GtkWidget* item, gpointer data) -{ - static_cast(data)->EditScript(); -} - -void C4Console::OnCompTitle(GtkWidget* item, gpointer data) -{ - static_cast(data)->EditTitle(); -} - -void C4Console::OnCompInfo(GtkWidget* item, gpointer data) -{ - static_cast(data)->EditInfo(); -} - -void C4Console::OnPlrJoin(GtkWidget* item, gpointer data) -{ - static_cast(data)->PlayerJoin(); -} - -void C4Console::OnPlrQuit(GtkWidget* item, gpointer data) -{ - ::Control.Input.Add(CID_Script, new C4ControlScript(FormatString("EliminatePlayer(%d)", GPOINTER_TO_INT(data)).getData())); -} - -void C4Console::OnViewNew(GtkWidget* item, gpointer data) -{ - static_cast(data)->ViewportNew(); -} - -void C4Console::OnViewNewPlr(GtkWidget* item, gpointer data) -{ - ::Viewports.CreateViewport(GPOINTER_TO_INT(data)); -} - -void C4Console::OnHelpAbout(GtkWidget* item, gpointer data) -{ - static_cast(data)->HelpAbout(); -} - -void C4Console::OnNetClient(GtkWidget* item, gpointer data) -{ - if (!::Control.isCtrlHost()) return; - Game.Clients.CtrlRemove(Game.Clients.getClientByID(GPOINTER_TO_INT(data)), LoadResStr("IDS_MSG_KICKBYMENU")); -} -#endif // WITH_DEVELOPER_MODE diff --git a/src/editor/C4Console.h b/src/editor/C4Console.h index 6ff580f10..b0d449932 100644 --- a/src/editor/C4Console.h +++ b/src/editor/C4Console.h @@ -24,6 +24,7 @@ #ifndef INC_C4Console #define INC_C4Console +#include "C4ConsoleGUI.h" #include "C4PropertyDlg.h" #include "C4ToolsDlg.h" #include "C4ObjectListDlg.h" @@ -31,10 +32,6 @@ #include -#ifdef WITH_DEVELOPER_MODE -# include -#endif - const int C4CNS_ModePlay = 0, C4CNS_ModeEdit = 1, C4CNS_ModeDraw = 2; @@ -53,16 +50,11 @@ typedef CStdGtkWindow C4ConsoleBase; typedef CStdWindow C4ConsoleBase; #endif -class C4Console: public C4ConsoleBase +class C4Console: public C4ConsoleGUI { public: C4Console(); virtual ~C4Console(); - bool Editing; - C4PropertyDlg PropertyDlg; - C4ToolsDlg ToolsDlg; - C4ObjectListDlg ObjectListDlg; - C4EditCursor EditCursor; void Default(); virtual void Clear(); virtual void Close(); @@ -71,28 +63,19 @@ public: void Execute(); void ClearPointers(C4Object *pObj); bool Message(const char *szMessage, bool fQuery=false); - void SetCaption(const char *szCaption); bool In(const char *szText); - bool Out(const char *szText); - bool ClearLog(); // empty log text void DoPlay(); - void DoHalt(); - bool UpdateCursorBar(const char *szCursor); - bool UpdateHaltCtrls(bool fHalt); - bool UpdateModeCtrls(int iMode); + void DoHalt(); void UpdateInputCtrl(); void UpdateMenus(); bool OpenGame(); bool TogglePause(); // key callpack: pause -protected: +public: bool CloseGame(); - bool fGameOpen; - void EnableControls(bool fEnable); bool UpdatePlayerMenu(); bool UpdateViewportMenu(); bool UpdateStatusBars(); - // Menu - void ClearPlayerMenu(); + // Menu void ClearViewportMenu(); void UpdateNetMenu(); void ClearNetMenu(); @@ -113,6 +96,12 @@ protected: bool FileClose(); bool FileQuit(); bool FileRecord(); + void SetCaptionToFilename(const char* szFilename); +public: + C4PropertyDlg PropertyDlg; + C4ToolsDlg ToolsDlg; + C4ObjectListDlg ObjectListDlg; + C4EditCursor EditCursor; int ScriptCounter; int FrameCounter; @@ -123,107 +112,7 @@ protected: int MenuIndexViewport; int MenuIndexNet; int MenuIndexHelp; -#ifdef _WIN32 - void UpdateMenuText(HMENU hMenu); - bool RegisterConsoleWindowClass(HINSTANCE hInst); - bool AddMenuItem(HMENU hMenu, DWORD dwID, const char *szString, bool fEnabled=true); - virtual bool Win32DialogMessageHandling(MSG * msg) - { - return (hWindow && IsDialogMessage(hWindow,msg)) || (PropertyDlg.hDialog && IsDialogMessage(PropertyDlg.hDialog,msg)); - }; - HBITMAP hbmMouse; - HBITMAP hbmMouse2; - HBITMAP hbmCursor; - HBITMAP hbmCursor2; - HBITMAP hbmBrush; - HBITMAP hbmBrush2; - HBITMAP hbmPlay; - HBITMAP hbmPlay2; - HBITMAP hbmHalt; - HBITMAP hbmHalt2; - friend INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); -#elif defined(WITH_DEVELOPER_MODE) - virtual GtkWidget* InitGUI(); - - GdkCursor* cursorDefault; - GdkCursor* cursorWait; - - GtkWidget* txtLog; - GtkWidget* txtScript; - GtkWidget* btnPlay; - GtkWidget* btnHalt; - GtkWidget* btnModePlay; - GtkWidget* btnModeEdit; - GtkWidget* btnModeDraw; - - GtkWidget* menuBar; - GtkWidget* itemNet; - - GtkWidget* menuViewport; - GtkWidget* menuPlayer; - - GtkWidget* fileOpen; - GtkWidget* fileOpenWithPlayers; - GtkWidget* fileSave; - GtkWidget* fileSaveAs; - GtkWidget* fileSaveGame; - GtkWidget* fileSaveGameAs; - GtkWidget* fileRecord; - GtkWidget* fileClose; - GtkWidget* fileQuit; - - GtkWidget* compScript; - GtkWidget* compTitle; - GtkWidget* compInfo; - GtkWidget* compObjects; - - GtkWidget* plrJoin; - - GtkWidget* viewNew; - - GtkWidget* helpAbout; - - GtkWidget* lblCursor; - GtkWidget* lblFrame; - GtkWidget* lblScript; - GtkWidget* lblTime; - - gulong handlerPlay; - gulong handlerHalt; - gulong handlerModePlay; - gulong handlerModeEdit; - gulong handlerModeDraw; - - static void OnScriptEntry(GtkWidget* entry, gpointer data); - static void OnPlay(GtkWidget* button, gpointer data); - static void OnHalt(GtkWidget* button, gpointer data); - static void OnModePlay(GtkWidget* button, gpointer data); - static void OnModeEdit(GtkWidget* button, gpointer data); - static void OnModeDraw(GtkWidget* button, gpointer data); - - static void OnFileOpen(GtkWidget* item, gpointer data); - static void OnFileOpenWPlrs(GtkWidget* item, gpointer data); - static void OnFileSave(GtkWidget* item, gpointer data); - static void OnFileSaveAs(GtkWidget* item, gpointer data); - static void OnFileSaveGame(GtkWidget* item, gpointer data); - static void OnFileSaveGameAs(GtkWidget* item, gpointer data); - static void OnFileRecord(GtkWidget* item, gpointer data); - static void OnFileClose(GtkWidget* item, gpointer data); - static void OnFileQuit(GtkWidget* item, gpointer data); - - static void OnCompObjects(GtkWidget* item, gpointer data); - static void OnCompScript(GtkWidget* item, gpointer data); - static void OnCompTitle(GtkWidget* item, gpointer data); - static void OnCompInfo(GtkWidget* item, gpointer data); - - static void OnPlrJoin(GtkWidget* item, gpointer data); - static void OnPlrQuit(GtkWidget* item, gpointer data); - static void OnViewNew(GtkWidget* item, gpointer data); - static void OnViewNewPlr(GtkWidget* item, gpointer data); - static void OnHelpAbout(GtkWidget* item, gpointer data); - - static void OnNetClient(GtkWidget* item, gpointer data); -#elif defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) +#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) virtual void HandleMessage (XEvent &); #endif }; diff --git a/src/editor/C4ConsoleGTK.cpp b/src/editor/C4ConsoleGTK.cpp new file mode 100644 index 000000000..081dbe54a --- /dev/null +++ b/src/editor/C4ConsoleGTK.cpp @@ -0,0 +1,1622 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +# include +# include + +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include +# include + +# include +# include +# include + +# include +# include + +using namespace OpenFileFlags; + +namespace +{ + /*GtkWidget* CreateImageFromInlinedPixbuf(const guint8* pixbuf_data) + { + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf_data, false, NULL); + GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); + gdk_pixbuf_unref(pixbuf); + return image; + }*/ + + void SelectComboBoxText(GtkComboBox* combobox, const char* text) + { + GtkTreeModel* model = gtk_combo_box_get_model(combobox); + + GtkTreeIter iter; + for (gboolean ret = gtk_tree_model_get_iter_first(model, &iter); ret; ret = gtk_tree_model_iter_next(model, &iter)) + { + gchar* col_text; + gtk_tree_model_get(model, &iter, 0, &col_text, -1); + + if (SEqualNoCase(text, col_text)) + { + g_free(col_text); + gtk_combo_box_set_active_iter(combobox, &iter); + return; + } + + g_free(col_text); + } + } + + gboolean RowSeparatorFunc(GtkTreeModel* model, GtkTreeIter* iter, void* user_data) + { + gchar* text; + gtk_tree_model_get(model, iter, 0, &text, -1); + + if (SEqual(text, "------")) { g_free(text); return true; } + g_free(text); + return false; + } + + GtkWidget* CreateImageFromInlinedPixbuf(const guint8* pixbuf_data) + { + GdkPixbuf* pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf_data, false, NULL); + GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); + gdk_pixbuf_unref(pixbuf); + return image; + } +} + +class C4ConsoleGUI::State: public C4ConsoleGUI::InternalState +{ +public: + GdkCursor* cursorDefault; + GdkCursor* cursorWait; + + GtkWidget* txtLog; + GtkWidget* txtScript; + GtkWidget* btnPlay; + GtkWidget* btnHalt; + GtkWidget* btnModePlay; + GtkWidget* btnModeEdit; + GtkWidget* btnModeDraw; + + GtkWidget* menuBar; + GtkWidget* itemNet; + GtkWidget* menuNet; + + GtkWidget* menuViewport; + GtkWidget* menuPlayer; + + GtkWidget* fileOpen; + GtkWidget* fileOpenWithPlayers; + GtkWidget* fileSave; + GtkWidget* fileSaveAs; + GtkWidget* fileSaveGame; + GtkWidget* fileSaveGameAs; + GtkWidget* fileRecord; + GtkWidget* fileClose; + GtkWidget* fileQuit; + + GtkWidget* compScript; + GtkWidget* compTitle; + GtkWidget* compInfo; + GtkWidget* compObjects; + + GtkWidget* plrJoin; + + GtkWidget* viewNew; + + GtkWidget* helpAbout; + + GtkWidget* lblCursor; + GtkWidget* lblFrame; + GtkWidget* lblScript; + GtkWidget* lblTime; + + gulong handlerPlay; + gulong handlerHalt; + gulong handlerModePlay; + gulong handlerModeEdit; + gulong handlerModeDraw; + + State(C4ConsoleGUI *console): Super(console) + { + cursorDefault = NULL; + cursorWait = NULL; + itemNet = NULL; + txtLog = NULL; + txtScript = NULL; + } + + void InitGUI(); + void DoEnableControls(bool fEnable); + + static void OnScriptEntry(GtkWidget* entry, gpointer data); + static void OnPlay(GtkWidget* button, gpointer data); + static void OnHalt(GtkWidget* button, gpointer data); + static void OnModePlay(GtkWidget* button, gpointer data); + static void OnModeEdit(GtkWidget* button, gpointer data); + static void OnModeDraw(GtkWidget* button, gpointer data); + + static void OnFileOpen(GtkWidget* item, gpointer data); + static void OnFileOpenWPlrs(GtkWidget* item, gpointer data); + static void OnFileSave(GtkWidget* item, gpointer data); + static void OnFileSaveAs(GtkWidget* item, gpointer data); + static void OnFileSaveGame(GtkWidget* item, gpointer data); + static void OnFileSaveGameAs(GtkWidget* item, gpointer data); + static void OnFileRecord(GtkWidget* item, gpointer data); + static void OnFileClose(GtkWidget* item, gpointer data); + static void OnFileQuit(GtkWidget* item, gpointer data); + + static void OnCompObjects(GtkWidget* item, gpointer data); + static void OnCompScript(GtkWidget* item, gpointer data); + static void OnCompTitle(GtkWidget* item, gpointer data); + static void OnCompInfo(GtkWidget* item, gpointer data); + + static void OnPlrJoin(GtkWidget* item, gpointer data); + static void OnPlrQuit(GtkWidget* item, gpointer data); + static void OnViewNew(GtkWidget* item, gpointer data); + static void OnViewNewPlr(GtkWidget* item, gpointer data); + static void OnHelpAbout(GtkWidget* item, gpointer data); + + static void OnNetClient(GtkWidget* item, gpointer data); +}; + +class C4PropertyDlg::State: public C4ConsoleGUI::InternalState +{ +public: +// GtkWidget* window; + GtkWidget* vbox; + GtkWidget* textview; + GtkWidget* entry; + + gulong handlerHide; + + static void OnScriptActivate(GtkWidget* widget, gpointer data); + static void OnWindowHide(GtkWidget* widget, gpointer data); +// static void OnDestroy(GtkWidget* widget, gpointer data); + + ~State() + { + if (vbox != NULL) + { + g_signal_handler_disconnect(G_OBJECT(C4DevmodeDlg::GetWindow()), handlerHide); + C4DevmodeDlg::RemovePage(vbox); + vbox = NULL; + } + } + + State(C4PropertyDlg* dlg): Super(dlg), vbox(NULL) {} + + bool Open(); + + void Clear() {} + void Default() {} +}; + +class C4ToolsDlg::State: public C4ConsoleGUI::InternalState +{ +public: + GtkWidget* hbox; + + GtkWidget* brush; + GtkWidget* line; + GtkWidget* rect; + GtkWidget* fill; + GtkWidget* picker; + + GtkWidget* landscape_dynamic; + GtkWidget* landscape_static; + GtkWidget* landscape_exact; + + GtkWidget* preview; + GtkWidget* scale; + + GtkWidget* ift; + GtkWidget* no_ift; + + GtkWidget* materials; + GtkWidget* textures; + + gulong handlerBrush; + gulong handlerLine; + gulong handlerRect; + gulong handlerFill; + gulong handlerPicker; + + gulong handlerDynamic; + gulong handlerStatic; + gulong handlerExact; + + gulong handlerIft; + gulong handlerNoIft; + + gulong handlerMaterials; + gulong handlerTextures; + gulong handlerScale; + + gulong handlerHide; + + //static void OnDestroy(GtkWidget* widget, gpointer data); + static void OnButtonModeDynamic(GtkWidget* widget, gpointer data); + static void OnButtonModeStatic(GtkWidget* widget, gpointer data); + static void OnButtonModeExact(GtkWidget* widget, gpointer data); + static void OnButtonBrush(GtkWidget* widget, gpointer data); + static void OnButtonLine(GtkWidget* widget, gpointer data); + static void OnButtonRect(GtkWidget* widget, gpointer data); + static void OnButtonFill(GtkWidget* widget, gpointer data); + static void OnButtonPicker(GtkWidget* widget, gpointer data); + static void OnButtonIft(GtkWidget* widget, gpointer data); + static void OnButtonNoIft(GtkWidget* widget, gpointer data); + static void OnComboMaterial(GtkWidget* widget, gpointer data); + static void OnComboTexture(GtkWidget* widget, gpointer data); + static void OnGrade(GtkWidget* widget, gpointer data); + static void OnWindowHide(GtkWidget* widget, gpointer data); + + State(C4ToolsDlg* dlg): Super(dlg), hbox(NULL) {} + bool Open(); + void UpdateToolCtrls(); + void InitMaterialCtrls(); + void UpdatePreview(); + void UpdateLandscapeModeCtrls(); + void UpdateIFTControls(); + + ~State() + { + if (hbox != NULL) + { + g_signal_handler_disconnect(G_OBJECT(C4DevmodeDlg::GetWindow()), handlerHide); + C4DevmodeDlg::RemovePage(hbox); + hbox = NULL; + } + } + + void Clear() {} + void Default() {} +}; + +void C4PropertyDlg::State::OnScriptActivate(GtkWidget* widget, gpointer data) +{ + const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget)); + if (text && text[0]) + Console.EditCursor.In(text); +} + +void C4PropertyDlg::State::OnWindowHide(GtkWidget* widget, gpointer user_data) +{ + static_cast(user_data)->Active = false; +} + +CStdWindow* C4ConsoleGUI::CreateConsoleWindow(CStdApp* pApp) +{ + state->cursorWait = gdk_cursor_new(GDK_WATCH); + state->cursorDefault = gdk_cursor_new(GDK_ARROW); + + // Calls InitGUI + CStdWindow* retval = C4ConsoleBase::Init(pApp, LoadResStr("IDS_CNS_CONSOLE"), NULL, false); + UpdateHaltCtrls(true); + EnableControls(fGameOpen); + ClearViewportMenu(); + return retval; +} + +GtkWidget* C4ConsoleGUI::InitGUI() +{ + state->InitGUI(); + return C4ConsoleBase::InitGUI(); +} + +void C4ConsoleGUI::State::InitGUI() +{ + // ------------ Play/Pause and Mode --------------------- + GtkWidget* image_play = CreateImageFromInlinedPixbuf(play_pixbuf_data); + GtkWidget* image_pause = CreateImageFromInlinedPixbuf(halt_pixbuf_data); + + GtkWidget* image_mode_play = CreateImageFromInlinedPixbuf(mouse_pixbuf_data); + GtkWidget* image_mode_edit = CreateImageFromInlinedPixbuf(cursor_pixbuf_data); + GtkWidget* image_mode_draw = CreateImageFromInlinedPixbuf(brush_pixbuf_data); + + btnPlay = gtk_toggle_button_new(); + btnHalt = gtk_toggle_button_new(); + btnModePlay = gtk_toggle_button_new(); + btnModeEdit = gtk_toggle_button_new(); + btnModeDraw = gtk_toggle_button_new(); + + gtk_container_add(GTK_CONTAINER(btnPlay), image_play); + gtk_container_add(GTK_CONTAINER(btnHalt), image_pause); + gtk_container_add(GTK_CONTAINER(btnModePlay), image_mode_play); + gtk_container_add(GTK_CONTAINER(btnModeEdit), image_mode_edit); + gtk_container_add(GTK_CONTAINER(btnModeDraw), image_mode_draw); + + GtkWidget* top_hbox = gtk_hbox_new(false, 18); + GtkWidget* play_hbox = gtk_hbox_new(false, 6); + GtkWidget* mode_hbox = gtk_hbox_new(false, 6); + + gtk_box_pack_start(GTK_BOX(play_hbox), btnPlay, false, true, 0); + gtk_box_pack_start(GTK_BOX(play_hbox), btnHalt, false, true, 0); + gtk_box_pack_start(GTK_BOX(mode_hbox), btnModePlay, false, true, 0); + gtk_box_pack_start(GTK_BOX(mode_hbox), btnModeEdit, false, true, 0); + gtk_box_pack_start(GTK_BOX(mode_hbox), btnModeDraw, false, true, 0); + + lblCursor = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(lblCursor), 0.0, 0.5); + + gtk_box_pack_start(GTK_BOX(top_hbox), lblCursor, true, true, 0); + gtk_box_pack_start(GTK_BOX(top_hbox), play_hbox, false, true, 0); + gtk_box_pack_start(GTK_BOX(top_hbox), mode_hbox, false, true, 0); + + // ------------ Statusbar --------------------- + GtkWidget* statusbar = gtk_hbox_new(false, 6); + + GtkWidget* status_frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(status_frame), GTK_SHADOW_IN); + gtk_container_add(GTK_CONTAINER(status_frame), statusbar); + + lblFrame = gtk_label_new("Frame: 0"); + lblScript = gtk_label_new("Script: 0"); + lblTime = gtk_label_new("00:00:00 (0 FPS)"); + + gtk_misc_set_alignment(GTK_MISC(lblFrame), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(lblScript), 0.0, 0.5); + gtk_misc_set_alignment(GTK_MISC(lblTime), 0.0, 0.5); + + GtkWidget* sep1 = gtk_vseparator_new(); + GtkWidget* sep2 = gtk_vseparator_new(); + + gtk_box_pack_start(GTK_BOX(statusbar), lblFrame, true, true, 0); + gtk_box_pack_start(GTK_BOX(statusbar), sep1, false, false, 0); + gtk_box_pack_start(GTK_BOX(statusbar), lblScript, true, true, 0); + gtk_box_pack_start(GTK_BOX(statusbar), sep2, false, false, 0); + gtk_box_pack_start(GTK_BOX(statusbar), lblTime, true, true, 0); + + // ------------ Log view and script entry --------------------- + GtkWidget* scroll = gtk_scrolled_window_new(NULL, NULL); + + txtLog = gtk_text_view_new(); + txtScript = gtk_entry_new(); + + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll), GTK_SHADOW_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_text_view_set_editable(GTK_TEXT_VIEW(txtLog), false); + + gtk_container_add(GTK_CONTAINER(scroll), txtLog); + + // ------------ Menu ------------------- + menuBar = gtk_menu_bar_new(); + + GtkWidget* itemFile = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_FILE")); + GtkWidget* itemComponents = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_COMPONENTS")); + GtkWidget* itemPlayer = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_PLAYER")); + GtkWidget* itemViewport = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_VIEWPORT")); + GtkWidget* itemHelp = gtk_menu_item_new_with_label("?"); + + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemFile); + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemComponents); + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemPlayer); + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemViewport); + gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemHelp); + + GtkWidget* menuFile = gtk_menu_new(); + GtkWidget* menuComponents = gtk_menu_new(); + GtkWidget* menuHelp = gtk_menu_new(); + + menuPlayer = gtk_menu_new(); + menuViewport = gtk_menu_new(); + + gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemFile), menuFile); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemComponents), menuComponents); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemPlayer), menuPlayer); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemViewport), menuViewport); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemHelp), menuHelp); + + fileOpen = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPEN")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpen); + + fileOpenWithPlayers = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPENWPLRS")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpenWithPlayers); + + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); + + fileSave = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIO")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSave); + + fileSaveAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIOAS")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveAs); + + fileSaveGame = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAME")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGame); + + fileSaveGameAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAMEAS")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGameAs); + + fileRecord = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_RECORD")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileRecord); + + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); + + fileClose = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_CLOSE")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileClose); + + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new())); + + fileQuit = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_QUIT")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileQuit); + + compObjects = gtk_menu_item_new_with_label(LoadResStr("IDS_BTN_OBJECTS")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compObjects); + + compScript = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SCRIPT")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compScript); + + compTitle = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_TITLE")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compTitle); + + compInfo = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_INFO")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compInfo); + + plrJoin = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_JOIN")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuPlayer), plrJoin); + + viewNew = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NEW")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuViewport), viewNew); + + helpAbout = gtk_menu_item_new_with_label(LoadResStr("IDS_MENU_ABOUT")); + gtk_menu_shell_append(GTK_MENU_SHELL(menuHelp), helpAbout); + + // ------------ Window --------------------- + GtkWidget* topbox = gtk_vbox_new(false, 0); + GtkWidget* midbox = gtk_vbox_new(false, 6); + gtk_container_set_border_width(GTK_CONTAINER(midbox), 6); + + gtk_box_pack_start(GTK_BOX(midbox), scroll, true, true, 0); + gtk_box_pack_start(GTK_BOX(midbox), txtScript, false, false, 0); + gtk_box_pack_start(GTK_BOX(midbox), top_hbox, false, true, 0); + + gtk_box_pack_start(GTK_BOX(topbox), menuBar, false, false, 0); + gtk_box_pack_start(GTK_BOX(topbox), midbox, true, true, 0); + gtk_box_pack_start(GTK_BOX(topbox), status_frame, false, false, 0); + + gtk_window_set_default_size(GTK_WINDOW(GetOwner()->window), 320, 320); + + gtk_container_add(GTK_CONTAINER(GetOwner()->window), topbox); + + // ------------ Signals --------------------- + handlerPlay = g_signal_connect(G_OBJECT(btnPlay), "toggled", G_CALLBACK(OnPlay), this); + handlerHalt = g_signal_connect(G_OBJECT(btnHalt), "toggled", G_CALLBACK(OnHalt), this); + handlerModePlay = g_signal_connect(G_OBJECT(btnModePlay), "toggled", G_CALLBACK(OnModePlay), this); + handlerModeEdit = g_signal_connect(G_OBJECT(btnModeEdit), "toggled", G_CALLBACK(OnModeEdit), this); + handlerModeDraw = g_signal_connect(G_OBJECT(btnModeDraw), "toggled", G_CALLBACK(OnModeDraw), this); + g_signal_connect(G_OBJECT(txtScript), "activate", G_CALLBACK(OnScriptEntry), this); + g_signal_connect(G_OBJECT(fileOpen), "activate", G_CALLBACK(OnFileOpen), this); + g_signal_connect(G_OBJECT(fileOpenWithPlayers), "activate", G_CALLBACK(OnFileOpenWPlrs), this); + g_signal_connect(G_OBJECT(fileSave), "activate", G_CALLBACK(OnFileSave), this); + g_signal_connect(G_OBJECT(fileSaveAs), "activate", G_CALLBACK(OnFileSaveAs), this); + g_signal_connect(G_OBJECT(fileSaveGame), "activate", G_CALLBACK(OnFileSaveGame), this); + g_signal_connect(G_OBJECT(fileSaveGameAs), "activate", G_CALLBACK(OnFileSaveGameAs), this); + g_signal_connect(G_OBJECT(fileRecord), "activate", G_CALLBACK(OnFileRecord), this); + g_signal_connect(G_OBJECT(fileClose), "activate", G_CALLBACK(OnFileClose), this); + g_signal_connect(G_OBJECT(fileQuit), "activate", G_CALLBACK(OnFileQuit), this); + g_signal_connect(G_OBJECT(compObjects), "activate", G_CALLBACK(OnCompObjects), this); + g_signal_connect(G_OBJECT(compScript), "activate", G_CALLBACK(OnCompScript), this); + g_signal_connect(G_OBJECT(compTitle), "activate", G_CALLBACK(OnCompTitle), this); + g_signal_connect(G_OBJECT(compInfo), "activate", G_CALLBACK(OnCompInfo), this); + g_signal_connect(G_OBJECT(plrJoin), "activate", G_CALLBACK(OnPlrJoin), this); + g_signal_connect(G_OBJECT(viewNew), "activate", G_CALLBACK(OnViewNew), this); + g_signal_connect(G_OBJECT(helpAbout), "activate", G_CALLBACK(OnHelpAbout), this); +} + +void C4ConsoleGUI::DisplayInfoText(InfoTextType type, StdStrBuf& text) +{ + GtkWidget* label; + switch (type) + { + case CONSOLE_FrameCounter: + label = state->lblFrame; + break; + case CONSOLE_ScriptCounter: + label = state->lblScript; + break; + case CONSOLE_TimeFPS: + label = state->lblTime; + } + gtk_label_set_label(GTK_LABEL(label), text.getData()); +} + +void C4ConsoleGUI::AddMenuItemForPlayer(C4Player *player, StdStrBuf &player_text) +{ + GtkWidget* menuItem = gtk_menu_item_new_with_label(player_text.getData()); + gtk_menu_shell_append(GTK_MENU_SHELL(state->menuViewport), menuItem); + g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(State::OnViewNewPlr), GINT_TO_POINTER(player->Number)); + gtk_widget_show(menuItem); +} + +void C4ConsoleGUI::SetCursor(Cursor cursor) +{ + // Seems not to work. Don't know why... + gdk_window_set_cursor(window->window, state->cursorWait); +} + +void C4ConsoleGUI::ClearViewportMenu() +{ + GList* children = gtk_container_get_children(GTK_CONTAINER(state->menuViewport)); + for (GList* item = children; item != NULL; item = item->next) + { + if (item->data != state->viewNew) + gtk_container_remove(GTK_CONTAINER(state->menuViewport), GTK_WIDGET(item->data)); + } + g_list_free(children); +} + +void C4ConsoleGUI::RecordingEnabled() +{ + gtk_widget_set_sensitive(state->fileRecord, false); +} + +void C4ConsoleGUI::ShowAboutWithCopyright(StdStrBuf ©right) +{ + gtk_show_about_dialog(GTK_WINDOW(window), "name", C4ENGINECAPTION, "version", C4VERSION, "copyright", copyright.getData(), NULL); +} + +bool C4ConsoleGUI::UpdateCursorBar(const char *szCursor) +{ + if (!Active) + return false; + gtk_label_set_label(GTK_LABEL(state->lblCursor), szCursor); + return true; +} + +bool C4ConsoleGUI::UpdateModeCtrls(int iMode) +{ + if (!Active) + return false; + + // Prevents recursion + g_signal_handler_block(state->btnModePlay, state->handlerModePlay); + g_signal_handler_block(state->btnModeEdit, state->handlerModeEdit); + g_signal_handler_block(state->btnModeDraw, state->handlerModeDraw); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->btnModePlay), iMode == C4CNS_ModePlay); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->btnModeEdit), iMode == C4CNS_ModeEdit); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->btnModeDraw), iMode == C4CNS_ModeDraw); + + g_signal_handler_unblock(state->btnModePlay, state->handlerModePlay); + g_signal_handler_unblock(state->btnModeEdit, state->handlerModeEdit); + g_signal_handler_unblock(state->btnModeDraw, state->handlerModeDraw); + return true; +} + +bool C4ConsoleGUI::FileSelect(char *sFilename, int iSize, const char * szFilter, DWORD dwFlags, bool fSave) +{ + GtkWidget* dialog = gtk_file_chooser_dialog_new(fSave ? "Save file..." : "Load file...", GTK_WINDOW(window), fSave ? GTK_FILE_CHOOSER_ACTION_SAVE : GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, fSave ? GTK_STOCK_SAVE : GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + + // TODO: Set dialog modal? + + if (g_path_is_absolute(sFilename) ) + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), sFilename); + else if (fSave) + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), sFilename); + + // Install file filter + while (*szFilter) + { + char pattern[16 + 1]; + + GtkFileFilter* filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, szFilter); + szFilter+=SLen(szFilter)+1; + + while (true) + { + SCopyUntil(szFilter, pattern, ';', 16); + + int len = SLen(pattern); + char last_c = szFilter[len]; + + szFilter += (len + 1); + + // Got not all of the filter, try again. + if (last_c != ';' && last_c != '\0') + continue; + + gtk_file_filter_add_pattern(filter, pattern); + if (last_c == '\0') break; + } + + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); + } + + // TODO: Not in GTK+ 2.4, we could check GTK+ version at runtime and rely on lazy bindung +// gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_OVERWRITEPROMPT) != 0); + + // TODO: Not in GTK+ 2.4, we could check GTK+ version at runtime and rely on lazy binding +// gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_HIDEREADONLY) == 0); + + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), (dwFlags & OFN_ALLOWMULTISELECT) != 0); + gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), true); + + int response; + while (true) + { + response = gtk_dialog_run(GTK_DIALOG(dialog)); + if (response == GTK_RESPONSE_CANCEL || response == GTK_RESPONSE_DELETE_EVENT) break; + + bool error = false; + + // Check for OFN_FILEMUSTEXIST + if ((dwFlags & OFN_ALLOWMULTISELECT) == 0) + { + char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + if ((dwFlags & OFN_FILEMUSTEXIST) && !g_file_test(filename, G_FILE_TEST_IS_REGULAR)) + { + Message(FormatString("File \"%s\" does not exist", filename).getData(), false); + error = true; + } + + g_free(filename); + } + + if (!error) break; + } + + if (response != GTK_RESPONSE_ACCEPT) + { + gtk_widget_destroy(dialog); + return false; + } + + // Build result string + if ((dwFlags & OFN_ALLOWMULTISELECT) == 0) + { + // Just the file name without multiselect + char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + SCopy(filename, sFilename, iSize); + g_free(filename); + } + else + { + // Otherwise its the folder followed by the file names, + // separated by '\0'-bytes + char* folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)); + int len = SLen(folder); + + if (iSize > 0) SCopy(folder, sFilename, Min(len + 1, iSize)); + iSize -= (len + 1); sFilename += (len + 1); + g_free(folder); + + GSList* files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); + for (GSList* item = files; item != NULL; item = item->next) + { + const char* file = static_cast(item->data); + char* basefile = g_path_get_basename(file); + + int len = SLen(basefile); + if (iSize > 0) SCopy(basefile, sFilename, Min(len + 1, iSize)); + iSize -= (len + 1); sFilename += (len + 1); + + g_free(basefile); + g_free(item->data); + } + + // End of list + *sFilename = '\0'; + g_slist_free(files); + } + + gtk_widget_destroy(dialog); + return true; +} + +bool C4ConsoleGUI::Message(const char *message, bool query) +{ + if (!Active) return false; + GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, query ? (GTK_BUTTONS_OK_CANCEL) : (GTK_BUTTONS_OK), "%s", message); + int response = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + return response == GTK_RESPONSE_OK; +} + +bool C4ConsoleGUI::Out(const char *message) +{ + // Append text to log + if (!window) return true; + + GtkTextIter end; + GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(state->txtLog)); + gtk_text_buffer_get_end_iter(buffer, &end); + + gtk_text_buffer_insert(buffer, &end, message, -1); + gtk_text_buffer_insert(buffer, &end, "\n", 1); + + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(state->txtLog), gtk_text_buffer_get_insert(buffer), 0.0, false, 0.0, 0.0); +} + +void C4ConsoleGUI::UpdateNetMenu(Stage stage) +{ + switch (stage) + { + case C4ConsoleGUI::STAGE_Start: + { + state->itemNet = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NET")); + state->menuNet = gtk_menu_new(); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(state->itemNet), state->menuNet); + gtk_menu_shell_insert(GTK_MENU_SHELL(state->menuBar), state->itemNet, Console.MenuIndexHelp); + break; + } + case C4ConsoleGUI::STAGE_Intermediate: + break; + case C4ConsoleGUI::STAGE_End: + gtk_widget_show_all(state->itemNet); + break; + } +} + +void C4ConsoleGUI::AddNetMenuItemForPlayer(int32_t index, StdStrBuf &text) +{ + GtkWidget* item = gtk_menu_item_new_with_label(text.getData()); + gtk_menu_shell_append(GTK_MENU_SHELL(state->menuNet), item); + g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(State::OnNetClient), GINT_TO_POINTER(Game.Clients.getLocalID())); +} + +void C4ConsoleGUI::ClearNetMenu(C4ConsoleGUI::Stage stage) +{ + switch (stage) + { + case C4ConsoleGUI::STAGE_Start: + gtk_container_remove(GTK_CONTAINER(state->menuBar), state->itemNet); + state->itemNet = NULL; + break; + case C4ConsoleGUI::STAGE_End: + break; + } +} + +void C4ConsoleGUI::ClearInput() +{ + GtkEntryCompletion* completion = gtk_entry_get_completion(GTK_ENTRY(state->txtScript)); + if (!completion) + { + completion = gtk_entry_completion_new(); + GtkListStore* store = gtk_list_store_new(1, G_TYPE_STRING); + gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store)); + g_object_unref(G_OBJECT(store)); + gtk_entry_completion_set_text_column(completion, 0); + gtk_entry_set_completion(GTK_ENTRY(state->txtScript), completion); + g_object_unref(G_OBJECT(completion)); + } + + GtkTreeIter iter; + GtkListStore* store = GTK_LIST_STORE(gtk_entry_completion_get_model(completion)); + g_assert(store); + gtk_list_store_clear(store); +} + +void C4ConsoleGUI::ClearPlayerMenu() +{ + GList* children = gtk_container_get_children(GTK_CONTAINER(state->menuPlayer)); + for (GList* item = children; item != NULL; item = item->next) + { + if (item->data != state->plrJoin) + gtk_container_remove(GTK_CONTAINER(state->menuPlayer), GTK_WIDGET(item->data)); + } + g_list_free(children); +} + +void C4ConsoleGUI::AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled) +{ + // TODO: Implement AddMenuItem... + GtkWidget* menuItem = gtk_menu_item_new_with_label(player_text.getData()); + gtk_menu_shell_append(GTK_MENU_SHELL(state->menuPlayer), menuItem); + g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(State::OnPlrQuit), GINT_TO_POINTER(player->Number)); + gtk_widget_show(menuItem); + + gtk_widget_set_sensitive(menuItem, (!::Network.isEnabled() || ::Network.isHost()) && Editing); +} + +bool C4ConsoleGUI::ClearLog() +{ + gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(state->txtLog)), "", 0); + return true; +} + +bool C4ConsoleGUI::DoUpdateHaltCtrls(bool fHalt) +{ + // Prevents recursion + g_signal_handler_block(state->btnPlay, state->handlerPlay); + g_signal_handler_block(state->btnHalt, state->handlerHalt); + + //gtk_widget_set_sensitive(btnPlay, fHalt); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->btnPlay), !fHalt); + //gtk_widget_set_sensitive(btnHalt, !fHalt); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(state->btnHalt), fHalt); + + g_signal_handler_unblock(state->btnPlay, state->handlerPlay); + g_signal_handler_unblock(state->btnHalt, state->handlerHalt); + return true; +} + +void C4ConsoleGUI::ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture) +{ + C4ToolsDlg::State* state = dlg->state; + g_signal_handler_block(state->textures, state->handlerTextures); + SelectComboBoxText(GTK_COMBO_BOX(state->textures), texture); + g_signal_handler_unblock(state->textures, state->handlerTextures); +} + +void C4ConsoleGUI::ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material) +{ + C4ToolsDlg::State* state = dlg->state; + g_signal_handler_block(state->materials, state->handlerMaterials); + SelectComboBoxText(GTK_COMBO_BOX(state->materials), material); + g_signal_handler_unblock(state->materials, state->handlerMaterials); +} + +void C4ConsoleGUI::PropertyDlgSetFunctions(C4PropertyDlg *dlg, std::vector &functions) +{ + GtkEntryCompletion* completion = gtk_entry_get_completion(GTK_ENTRY(dlg->state->entry)); + GtkListStore* store; + + // Uncouple list store from completion so that the completion is not + // notified for every row we are going to insert. This enhances + // performance significantly. + if (!completion) + { + completion = gtk_entry_completion_new(); + store = gtk_list_store_new(1, G_TYPE_STRING); + + gtk_entry_completion_set_text_column(completion, 0); + gtk_entry_set_completion(GTK_ENTRY(dlg->state->entry), completion); + g_object_unref(G_OBJECT(completion)); + } + else + { + store = GTK_LIST_STORE(gtk_entry_completion_get_model(completion)); + g_object_ref(G_OBJECT(store)); + gtk_entry_completion_set_model(completion, NULL); + } + + GtkTreeIter iter; + gtk_list_store_clear(store); + + for (std::vector::iterator it(functions.begin()); it != functions.end(); it++) + { + char* fn = *it; + if (fn != C4ConsoleGUI::LIST_DIVIDER) + { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, fn, -1); + } + } + + // Reassociate list store with completion + gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store)); +} + +void C4ConsoleGUI::DoEnableControls(bool fEnable) +{ + state->DoEnableControls(fEnable); +} + +void C4ConsoleGUI::State::DoEnableControls(bool fEnable) +{ + // Halt controls + gtk_widget_set_sensitive(btnPlay, ::Network.isLobbyActive() || fEnable); + gtk_widget_set_sensitive(btnHalt, ::Network.isLobbyActive() || fEnable); + + // Edit modes + gtk_widget_set_sensitive(btnModePlay, ::Network.isLobbyActive() || fEnable); + gtk_widget_set_sensitive(btnModeEdit, ::Network.isLobbyActive() || fEnable); + gtk_widget_set_sensitive(btnModeDraw, ::Network.isLobbyActive() || fEnable); + + // Console input + gtk_widget_set_sensitive(txtScript, ::Network.isLobbyActive() || fEnable); + + // File menu + // C4Network2 will have to handle that cases somehow (TODO: test) + gtk_widget_set_sensitive(fileRecord, Game.IsRunning && ::Control.IsRuntimeRecordPossible()); + gtk_widget_set_sensitive(fileSaveGame, fEnable && ::Players.GetCount()); + gtk_widget_set_sensitive(fileSaveGameAs, fEnable && ::Players.GetCount()); + gtk_widget_set_sensitive(fileSave, fEnable); + gtk_widget_set_sensitive(fileSaveAs, fEnable); + gtk_widget_set_sensitive(fileClose, fEnable); + + // Components menu + gtk_widget_set_sensitive(compObjects, fEnable && GetOwner()->Editing); + gtk_widget_set_sensitive(compScript, fEnable && GetOwner()->Editing); + gtk_widget_set_sensitive(compInfo, fEnable && GetOwner()->Editing); + gtk_widget_set_sensitive(compTitle, fEnable && GetOwner()->Editing); + + // Player & viewport menu + gtk_widget_set_sensitive(plrJoin, fEnable && GetOwner()->Editing); + gtk_widget_set_sensitive(viewNew, fEnable); +} + +bool C4ConsoleGUI::PropertyDlgOpen(class C4PropertyDlg* dlg) +{ + return dlg->state->Open(); +} + +bool C4PropertyDlg::State::Open() +{ + if (vbox == NULL) + { + vbox = gtk_vbox_new(false, 6); + + GtkWidget* scrolled_wnd = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_wnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_wnd), GTK_SHADOW_IN); + + textview = gtk_text_view_new(); + entry = gtk_entry_new(); + + gtk_container_add(GTK_CONTAINER(scrolled_wnd), textview); + gtk_box_pack_start(GTK_BOX(vbox), scrolled_wnd, true, true, 0); + gtk_box_pack_start(GTK_BOX(vbox), entry, false, false, 0); + + gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), false); + gtk_widget_set_sensitive(entry, Console.Editing); + + gtk_widget_show_all(vbox); + + C4DevmodeDlg::AddPage(vbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_PROPERTIES")); + + g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(OnScriptActivate), this); + + handlerHide = g_signal_connect(G_OBJECT(C4DevmodeDlg::GetWindow()), "hide", G_CALLBACK(OnWindowHide), this); + } + + C4DevmodeDlg::SwitchPage(vbox); + return true; +} + +void C4ConsoleGUI::PropertyDlgUpdate(class C4PropertyDlg* dlg, StdStrBuf &text) +{ + GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(dlg->state->textview)); + gtk_text_buffer_set_text(buffer, text.getData(), -1); +} + +bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg) +{ + return dlg->state->Open(); +} + +bool C4ToolsDlg::State::Open() +{ + if (hbox == NULL) + { + hbox = gtk_hbox_new(false, 12); + GtkWidget* vbox = gtk_vbox_new(false, 6); + + GtkWidget* image_brush = CreateImageFromInlinedPixbuf(brush_pixbuf_data); + GtkWidget* image_line = CreateImageFromInlinedPixbuf(line_pixbuf_data); + GtkWidget* image_rect = CreateImageFromInlinedPixbuf(rect_pixbuf_data); + GtkWidget* image_fill = CreateImageFromInlinedPixbuf(fill_pixbuf_data); + GtkWidget* image_picker = CreateImageFromInlinedPixbuf(picker_pixbuf_data); + + GtkWidget* image_dynamic = CreateImageFromInlinedPixbuf(dynamic_pixbuf_data); + GtkWidget* image_static = CreateImageFromInlinedPixbuf(static_pixbuf_data); + GtkWidget* image_exact = CreateImageFromInlinedPixbuf(exact_pixbuf_data); + + GtkWidget* image_ift = CreateImageFromInlinedPixbuf(ift_pixbuf_data); + GtkWidget* image_no_ift = CreateImageFromInlinedPixbuf(no_ift_pixbuf_data); + + landscape_dynamic = gtk_toggle_button_new(); + landscape_static = gtk_toggle_button_new(); + landscape_exact = gtk_toggle_button_new(); + + gtk_container_add(GTK_CONTAINER(landscape_dynamic), image_dynamic); + gtk_container_add(GTK_CONTAINER(landscape_static), image_static); + gtk_container_add(GTK_CONTAINER(landscape_exact), image_exact); + + gtk_box_pack_start(GTK_BOX(vbox), landscape_dynamic, false, false, 0); + gtk_box_pack_start(GTK_BOX(vbox), landscape_static, false, false, 0); + gtk_box_pack_start(GTK_BOX(vbox), landscape_exact, false, false, 0); + + gtk_box_pack_start(GTK_BOX(hbox), vbox, false, false, 0); + vbox = gtk_vbox_new(false, 12); + gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 0); + GtkWidget* local_hbox = gtk_hbox_new(false, 6); + + brush = gtk_toggle_button_new(); + line = gtk_toggle_button_new(); + rect = gtk_toggle_button_new(); + fill = gtk_toggle_button_new(); + picker = gtk_toggle_button_new(); + + gtk_container_add(GTK_CONTAINER(brush), image_brush); + gtk_container_add(GTK_CONTAINER(line), image_line); + gtk_container_add(GTK_CONTAINER(rect), image_rect); + gtk_container_add(GTK_CONTAINER(fill), image_fill); + gtk_container_add(GTK_CONTAINER(picker), image_picker); + + gtk_box_pack_start(GTK_BOX(local_hbox), brush, false, false, 0); + gtk_box_pack_start(GTK_BOX(local_hbox), line, false, false, 0); + gtk_box_pack_start(GTK_BOX(local_hbox), rect, false, false, 0); + gtk_box_pack_start(GTK_BOX(local_hbox), fill, false, false, 0); + gtk_box_pack_start(GTK_BOX(local_hbox), picker, false, false, 0); + + gtk_box_pack_start(GTK_BOX(vbox), local_hbox, false, false, 0); + local_hbox = gtk_hbox_new(false, 12); + gtk_box_pack_start(GTK_BOX(vbox), local_hbox, true, true, 0); + + preview = gtk_image_new(); + gtk_box_pack_start(GTK_BOX(local_hbox), preview, false, false, 0); + + scale = gtk_vscale_new(NULL); + gtk_box_pack_start(GTK_BOX(local_hbox), scale, false, false, 0); + + vbox = gtk_vbox_new(false, 6); + + ift = gtk_toggle_button_new(); + no_ift = gtk_toggle_button_new(); + + gtk_container_add(GTK_CONTAINER(ift), image_ift); + gtk_container_add(GTK_CONTAINER(no_ift), image_no_ift); + + gtk_box_pack_start(GTK_BOX(vbox), ift, false, false, 0); + gtk_box_pack_start(GTK_BOX(vbox), no_ift, false, false, 0); + + gtk_box_pack_start(GTK_BOX(local_hbox), vbox, false, false, 0); + + vbox = gtk_vbox_new(false, 6); + + materials = gtk_combo_box_new_text(); + textures = gtk_combo_box_new_text(); + + gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(materials), RowSeparatorFunc, NULL, NULL); + gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(textures), RowSeparatorFunc, NULL, NULL); + + gtk_box_pack_start(GTK_BOX(vbox), materials, true, false, 0); + gtk_box_pack_start(GTK_BOX(vbox), textures, true, false, 0); + + gtk_box_pack_start(GTK_BOX(local_hbox), vbox, true, true, 0); // ??? + gtk_widget_show_all(hbox); + + C4DevmodeDlg::AddPage(hbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_TOOLS")); + + //g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(OnDestroy), this); + handlerDynamic = g_signal_connect(G_OBJECT(landscape_dynamic), "toggled", G_CALLBACK(OnButtonModeDynamic), this); + handlerStatic = g_signal_connect(G_OBJECT(landscape_static), "toggled", G_CALLBACK(OnButtonModeStatic), this); + handlerExact = g_signal_connect(G_OBJECT(landscape_exact), "toggled", G_CALLBACK(OnButtonModeExact), this); + handlerBrush = g_signal_connect(G_OBJECT(brush), "toggled", G_CALLBACK(OnButtonBrush), this); + handlerLine = g_signal_connect(G_OBJECT(line), "toggled", G_CALLBACK(OnButtonLine), this); + handlerRect = g_signal_connect(G_OBJECT(rect), "toggled", G_CALLBACK(OnButtonRect), this); + handlerFill = g_signal_connect(G_OBJECT(fill), "toggled", G_CALLBACK(OnButtonFill), this); + handlerPicker = g_signal_connect(G_OBJECT(picker), "toggled", G_CALLBACK(OnButtonPicker), this); + handlerIft = g_signal_connect(G_OBJECT(ift), "toggled", G_CALLBACK(OnButtonIft), this); + handlerNoIft = g_signal_connect(G_OBJECT(no_ift), "toggled", G_CALLBACK(OnButtonNoIft), this); + handlerMaterials = g_signal_connect(G_OBJECT(materials), "changed", G_CALLBACK(OnComboMaterial), this); + handlerTextures = g_signal_connect(G_OBJECT(textures), "changed", G_CALLBACK(OnComboTexture), this); + handlerScale = g_signal_connect(G_OBJECT(scale), "value-changed", G_CALLBACK(OnGrade), this); + + handlerHide = g_signal_connect(G_OBJECT(C4DevmodeDlg::GetWindow()), "hide", G_CALLBACK(OnWindowHide), this); + } + + C4DevmodeDlg::SwitchPage(hbox); + return true; +} + +void C4ConsoleGUI::ToolsDlgInitMaterialCtrls(C4ToolsDlg *dlg) +{ + dlg->state->InitMaterialCtrls(); +} + +void C4ToolsDlg::State::InitMaterialCtrls() +{ + GtkListStore* list = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(materials))); + + g_signal_handler_block(materials, handlerMaterials); + gtk_list_store_clear(list); + + gtk_combo_box_append_text(GTK_COMBO_BOX(materials), C4TLS_MatSky); + for (int32_t cnt = 0; cnt < ::MaterialMap.Num; cnt++) + { + gtk_combo_box_append_text(GTK_COMBO_BOX(materials), ::MaterialMap.Map[cnt].Name); + } + g_signal_handler_unblock(materials, handlerMaterials); + SelectComboBoxText(GTK_COMBO_BOX(materials), GetOwner()->Material); +} + +void C4ToolsDlg::UpdateToolCtrls() +{ + state->UpdateToolCtrls(); +} + +void C4ToolsDlg::State::UpdateToolCtrls() +{ + C4ToolsDlg* dlg = GetOwner(); + g_signal_handler_block(brush, handlerBrush); + g_signal_handler_block(line, handlerLine); + g_signal_handler_block(rect, handlerRect); + g_signal_handler_block(fill, handlerFill); + g_signal_handler_block(picker, handlerPicker); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(brush), dlg->Tool == C4TLS_Brush); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(line), dlg->Tool == C4TLS_Line); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rect), dlg->Tool == C4TLS_Rect); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fill), dlg->Tool == C4TLS_Fill); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(picker), dlg->Tool == C4TLS_Picker); + + g_signal_handler_unblock(brush, handlerBrush); + g_signal_handler_unblock(line, handlerLine); + g_signal_handler_unblock(rect, handlerRect); + g_signal_handler_unblock(fill, handlerFill); + g_signal_handler_unblock(picker, handlerPicker); +} + +void C4ToolsDlg::UpdateTextures() +{ + // Refill dlg + GtkListStore* list = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(state->textures))); + gtk_list_store_clear(list); + // bottom-most: any invalid textures + bool fAnyEntry = false; int32_t cnt; const char *szTexture; + if (::Landscape.Mode!=C4LSC_Exact) + for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) + { + if (!::TextureMap.GetIndex(Material, szTexture, false)) + { + fAnyEntry = true; + gtk_combo_box_prepend_text(GTK_COMBO_BOX(state->textures), szTexture); + } + } + // separator + if (fAnyEntry) + { + gtk_combo_box_prepend_text(GTK_COMBO_BOX(state->textures), "-------"); + } + + // atop: valid textures + for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) + { + // Current material-texture valid? Always valid for exact mode + if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact) + { + gtk_combo_box_prepend_text(GTK_COMBO_BOX(state->textures), szTexture); + } + } + // reselect current + g_signal_handler_block(state->textures, state->handlerTextures); + SelectComboBoxText(GTK_COMBO_BOX(state->textures), Texture); + g_signal_handler_unblock(state->textures, state->handlerTextures); +} + +void C4ConsoleGUI::ToolsDlgSetTexture(class C4ToolsDlg *dlg, const char *texture) +{ + C4ToolsDlg::State* state = dlg->state; + g_signal_handler_block(state->textures, state->handlerTextures); + SelectComboBoxText(GTK_COMBO_BOX(state->textures), texture); + g_signal_handler_unblock(state->textures, state->handlerTextures); +} + +void C4ToolsDlg::NeedPreviewUpdate() +{ + state->UpdatePreview(); +} + +void C4ToolsDlg::State::UpdatePreview() +{ + if (!hbox) return; + C4ToolsDlg* dlg = GetOwner(); + + SURFACE sfcPreview; + + int32_t iPrvWdt,iPrvHgt; + + RECT rect; + /* TODO: Set size request for image to read size from image's size request? */ + rect.left = 0; + rect.top = 0; + rect.bottom = 64; + rect.right = 64; + + iPrvWdt=rect.right-rect.left; + iPrvHgt=rect.bottom-rect.top; + + if (!(sfcPreview=new CSurface(iPrvWdt,iPrvHgt))) return; + + // fill bg + BYTE bCol = 0; + CPattern Pattern; + // Sky material: sky as pattern only + if (SEqual(dlg->Material,C4TLS_MatSky)) + { + Pattern.Set(::Landscape.Sky.Surface, 0); + } + // Material-Texture + else + { + bCol=Mat2PixColDefault(::MaterialMap.Get(dlg->Material)); + // Get/Create TexMap entry + BYTE iTex = ::TextureMap.GetIndex(dlg->Material, dlg->Texture, true); + if (iTex) + { + // Define texture pattern + const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex); + // Security + if (pTex) + { + // Set drawing pattern + Pattern = pTex->GetPattern(); + } + } + } +#if GTK_CHECK_VERSION(2,18,0) + if (gtk_widget_is_sensitive(preview)) +#else + if (GTK_WIDGET_SENSITIVE(preview)) +#endif + lpDDraw->DrawPatternedCircle( sfcPreview, + iPrvWdt/2,iPrvHgt/2, + dlg->Grade, + bCol, Pattern, *::Landscape.GetPal()); + + // TODO: Can we optimize this? + GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, 64, 64); + guchar* data = gdk_pixbuf_get_pixels(pixbuf); + sfcPreview->Lock(); + for (int x = 0; x < 64; ++ x) for (int y = 0; y < 64; ++ y) + { + DWORD dw = sfcPreview->GetPixDw(x, y, true); + *data = (dw >> 16) & 0xff; ++ data; + *data = (dw >> 8 ) & 0xff; ++ data; + *data = (dw ) & 0xff; ++ data; + *data = 0xff - ((dw >> 24) & 0xff); ++ data; + } + + sfcPreview->Unlock(); + gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf); + gdk_pixbuf_unref(pixbuf); + delete sfcPreview; +} + +void C4ToolsDlg::UpdateLandscapeModeCtrls() +{ + state->UpdateLandscapeModeCtrls(); +} + +void C4ToolsDlg::State::UpdateLandscapeModeCtrls() +{ + int32_t iMode = ::Landscape.Mode; + g_signal_handler_block(landscape_dynamic, handlerDynamic); + g_signal_handler_block(landscape_static, handlerStatic); + g_signal_handler_block(landscape_exact, handlerExact); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_dynamic), iMode==C4LSC_Dynamic); + gtk_widget_set_sensitive(landscape_dynamic, iMode==C4LSC_Dynamic); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_static), iMode==C4LSC_Static); + gtk_widget_set_sensitive(landscape_static, ::Landscape.Map!=NULL); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_exact), iMode==C4LSC_Exact); + + g_signal_handler_unblock(landscape_dynamic, handlerDynamic); + g_signal_handler_unblock(landscape_static, handlerStatic); + g_signal_handler_unblock(landscape_exact, handlerExact); + + C4DevmodeDlg::SetTitle(hbox, LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT")); +} + +void C4ToolsDlg::UpdateIFTControls() +{ + state->UpdateIFTControls(); +} + +void C4ToolsDlg::State::UpdateIFTControls() +{ + if (!hbox) return; + g_signal_handler_block(no_ift, handlerNoIft); + g_signal_handler_block(ift, handlerIft); + + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_ift), GetOwner()->ModeIFT==0); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ift), GetOwner()->ModeIFT==1); + + g_signal_handler_unblock(no_ift, handlerNoIft); + g_signal_handler_unblock(ift, handlerIft); +} + +void C4ConsoleGUI::ToolsDlgSetMaterial(class C4ToolsDlg *dlg, const char *material) +{ +} + +void C4ToolsDlg::InitGradeCtrl() +{ + if (!state->hbox) return; + g_signal_handler_block(state->scale, state->handlerScale); + gtk_range_set_increments(GTK_RANGE(state->scale), 1, 5); + gtk_range_set_range(GTK_RANGE(state->scale), C4TLS_GradeMin, C4TLS_GradeMax); + gtk_scale_set_draw_value(GTK_SCALE(state->scale), false); + gtk_range_set_value(GTK_RANGE(state->scale), C4TLS_GradeMax-Grade); + g_signal_handler_unblock(state->scale, state->handlerScale); +} + +bool C4ToolsDlg::PopMaterial() +{ + if (!state->hbox) return false; + gtk_widget_grab_focus(state->materials); + gtk_combo_box_popup(GTK_COMBO_BOX(state->materials)); +} + +bool C4ToolsDlg::PopTextures() +{ + if (!state->hbox) return false; + gtk_widget_grab_focus(state->textures); + gtk_combo_box_popup(GTK_COMBO_BOX(state->textures)); +} + +void C4ConsoleGUI::ClearDlg(void* dlg) +{ + // nope +} + +void C4ConsoleGUI::SetCaptionToFileName(const char* file_name) +{ +} + +void C4ConsoleGUI::SetInputFunctions(std::vector& functions) +{ +} + +void C4ConsoleGUI::ToolsDlgEnableControls(C4ToolsDlg* dlg) +{ +} + +// GTK+ Callbacks + +void C4ConsoleGUI::State::OnScriptEntry(GtkWidget* entry, gpointer data) +{ + C4Console* console = static_cast(data); + console->In(gtk_entry_get_text(GTK_ENTRY(console->state->txtScript))); + gtk_editable_select_region(GTK_EDITABLE(console->state->txtScript), 0, -1); +} + +void C4ConsoleGUI::State::OnPlay(GtkWidget* button, gpointer data) +{ + static_cast(data)->DoPlay(); + + // Must update haltctrls even if DoPlay did noting to restore + // previous settings since GTK may have released this toggle button + static_cast(data)->UpdateHaltCtrls(!!Game.HaltCount); +} + +void C4ConsoleGUI::State::OnHalt(GtkWidget* button, gpointer data) +{ + static_cast(data)->DoHalt(); + + // Must update haltctrls even if DoPlay did noting to restore + // previous settings since GTK may have released this toggle button + static_cast(data)->UpdateHaltCtrls(!!Game.HaltCount); +} + +void C4ConsoleGUI::State::OnModePlay(GtkWidget* button, gpointer data) +{ + static_cast(data)->EditCursor.SetMode(C4CNS_ModePlay); +} + +void C4ConsoleGUI::State::OnModeEdit(GtkWidget* button, gpointer data) +{ + static_cast(data)->EditCursor.SetMode(C4CNS_ModeEdit); +} + +void C4ConsoleGUI::State::OnModeDraw(GtkWidget* button, gpointer data) +{ + static_cast(data)->EditCursor.SetMode(C4CNS_ModeDraw); +} + +void C4ConsoleGUI::State::OnFileOpen(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileOpen(); +} + +void C4ConsoleGUI::State::OnFileOpenWPlrs(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileOpenWPlrs(); +} + +void C4ConsoleGUI::State::OnFileSave(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileSave(false); +} + +void C4ConsoleGUI::State::OnFileSaveAs(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileSaveAs(false); +} + +void C4ConsoleGUI::State::OnFileSaveGame(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileSave(true); +} + +void C4ConsoleGUI::State::OnFileSaveGameAs(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileSaveAs(true); +} + +void C4ConsoleGUI::State::OnFileRecord(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileRecord(); +} + +void C4ConsoleGUI::State::OnFileClose(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileClose(); +} + +void C4ConsoleGUI::State::OnFileQuit(GtkWidget* item, gpointer data) +{ + static_cast(data)->FileQuit(); +} + +void C4ConsoleGUI::State::OnCompObjects(GtkWidget* item, gpointer data) +{ + static_cast(data)->EditObjects(); +} + +void C4ConsoleGUI::State::OnCompScript(GtkWidget* item, gpointer data) +{ + static_cast(data)->EditScript(); +} + +void C4ConsoleGUI::State::OnCompTitle(GtkWidget* item, gpointer data) +{ + static_cast(data)->EditTitle(); +} + +void C4ConsoleGUI::State::OnCompInfo(GtkWidget* item, gpointer data) +{ + static_cast(data)->EditInfo(); +} + +void C4ConsoleGUI::State::OnPlrJoin(GtkWidget* item, gpointer data) +{ + static_cast(data)->PlayerJoin(); +} + +void C4ConsoleGUI::State::OnPlrQuit(GtkWidget* item, gpointer data) +{ + ::Control.Input.Add(CID_Script, new C4ControlScript(FormatString("EliminatePlayer(%d)", GPOINTER_TO_INT(data)).getData())); +} + +void C4ConsoleGUI::State::OnViewNew(GtkWidget* item, gpointer data) +{ + static_cast(data)->ViewportNew(); +} + +void C4ConsoleGUI::State::OnViewNewPlr(GtkWidget* item, gpointer data) +{ + ::Viewports.CreateViewport(GPOINTER_TO_INT(data)); +} + +void C4ConsoleGUI::State::OnHelpAbout(GtkWidget* item, gpointer data) +{ + static_cast(data)->HelpAbout(); +} + +void C4ConsoleGUI::State::OnNetClient(GtkWidget* item, gpointer data) +{ + if (!::Control.isCtrlHost()) return; + Game.Clients.CtrlRemove(Game.Clients.getClientByID(GPOINTER_TO_INT(data)), LoadResStr("IDS_MSG_KICKBYMENU")); +} + +void C4ToolsDlg::State::OnButtonModeDynamic(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetLandscapeMode(C4LSC_Dynamic); +} + +void C4ToolsDlg::State::OnButtonModeStatic(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetLandscapeMode(C4LSC_Static); +} + +void C4ToolsDlg::State::OnButtonModeExact(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetLandscapeMode(C4LSC_Exact); +} + +void C4ToolsDlg::State::OnButtonBrush(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetTool(C4TLS_Brush, false); +} + +void C4ToolsDlg::State::OnButtonLine(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetTool(C4TLS_Line, false); +} + +void C4ToolsDlg::State::OnButtonRect(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetTool(C4TLS_Rect, false); +} + +void C4ToolsDlg::State::OnButtonFill(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetTool(C4TLS_Fill, false); +} + +void C4ToolsDlg::State::OnButtonPicker(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetTool(C4TLS_Picker, false); +} + +void C4ToolsDlg::State::OnButtonIft(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetIFT(true); +} + +void C4ToolsDlg::State::OnButtonNoIft(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->SetIFT(false); +} + +void C4ToolsDlg::State::OnComboMaterial(GtkWidget* widget, gpointer data) +{ + gchar* text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); + static_cast(data)->GetOwner()->SetMaterial(text); + g_free(text); +} + +void C4ToolsDlg::State::OnComboTexture(GtkWidget* widget, gpointer data) +{ + gchar* text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); + static_cast(data)->GetOwner()->SetTexture(text); + g_free(text); +} + +void C4ToolsDlg::State::OnGrade(GtkWidget* widget, gpointer data) +{ + C4ToolsDlg::State* state = static_cast(data); + int value = static_cast(gtk_range_get_value(GTK_RANGE(state->scale)) + 0.5); + state->GetOwner()->SetGrade(C4TLS_GradeMax-value); +} + +void C4ToolsDlg::State::OnWindowHide(GtkWidget* widget, gpointer data) +{ + static_cast(data)->GetOwner()->Active = false; +} + +#define CONSOLEGUICOMMONINCLUDE +#include "C4ConsoleGUICommon.cpp" diff --git a/src/editor/C4ConsoleGUI.h b/src/editor/C4ConsoleGUI.h new file mode 100644 index 000000000..c8164385e --- /dev/null +++ b/src/editor/C4ConsoleGUI.h @@ -0,0 +1,155 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +#ifndef C4CONSOLEGUI_INC +#define C4CONSOLEGUI_INC + +#include "C4Application.h" +#include "C4Player.h" +#include "C4GameControl.h" +#include "StdBuf.h" + +#ifdef WITH_DEVELOPER_MODE +#include +typedef CStdGtkWindow C4ConsoleBase; +#else +typedef CStdWindow C4ConsoleBase; +#endif + +namespace OpenFileFlags +{ + const DWORD OFN_HIDEREADONLY = 1 << 0; + const DWORD OFN_OVERWRITEPROMPT = 1 << 1; + const DWORD OFN_FILEMUSTEXIST = 1 << 2; + const DWORD OFN_ALLOWMULTISELECT = 1 << 3; + + const DWORD OFN_EXPLORER = 0; // ignored +} + +// Separate class containing GUI code for C4Console while C4Console itself only contains functionality +class C4ConsoleGUI: public C4ConsoleBase +{ +public: + + static const char *LIST_DIVIDER; + + template class InternalState + { + protected: + typedef class InternalState Super; + private: + T *owner; + public: + InternalState(T *owner): owner(owner) {} + T *GetOwner() {return owner;} + }; + + enum InfoTextType + { + CONSOLE_FrameCounter, + CONSOLE_ScriptCounter, + CONSOLE_TimeFPS + }; + + enum Stage + { + STAGE_Start, + STAGE_Intermediate, + STAGE_End, + }; + + enum Cursor + { + CURSOR_Normal, + CURSOR_Wait + }; + + class State; + +private: + State *state; +public: + bool Editing; + bool fGameOpen; + + C4ConsoleGUI(); + ~C4ConsoleGUI(); + + void SetCursor(Cursor cursor); + void RecordingEnabled(); + void ShowAboutWithCopyright(StdStrBuf ©right); + bool UpdateCursorBar(const char *szCursor); + bool UpdateModeCtrls(int iMode); + void UpdateNetMenu(Stage stage); + void ClearNetMenu(Stage stage); + void AddNetMenuItemForPlayer(int32_t index, StdStrBuf &text); + void ClearInput(); + void ClearPlayerMenu(); + void SetInputFunctions(std::vector &functions); + + CStdWindow* CreateConsoleWindow(CStdApp *application); + bool Out(const char* message); + bool ClearLog(); + void DisplayInfoText(InfoTextType type, StdStrBuf& text); + void SetCaptionToFileName(const char* file_name); + void SetCaption(const char *caption); + bool FileSelect(char *sFilename, int iSize, const char * szFilter, DWORD dwFlags, bool fSave); + void AddMenuItemForPlayer(C4Player *player, StdStrBuf& player_text); + void AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled); + void ClearViewportMenu(); + bool Message(const char *message, bool query); + + void EnableControls(bool fEnable) + { + if (!Active) return; + // disable Editing if no input allowed + Editing &= !::Control.NoInput(); + DoEnableControls(fEnable); + } + void DoEnableControls(bool fEnable); + + bool UpdateHaltCtrls(bool fHalt) + { + if (!Active) + return false; + DoUpdateHaltCtrls(fHalt); + return true; + } + bool DoUpdateHaltCtrls(bool fHalt); + + bool PropertyDlgOpen(class C4PropertyDlg *dlg); + void PropertyDlgUpdate(class C4PropertyDlg *dlg, StdStrBuf &text); + void PropertyDlgSetFunctions(C4PropertyDlg *dlg, std::vector &functions); + + bool ToolsDlgOpen(class C4ToolsDlg *dlg); + void ToolsDlgInitMaterialCtrls(class C4ToolsDlg *dlg); + void ToolsDlgSetTexture(class C4ToolsDlg *dlg, const char *texture); + void ToolsDlgSetMaterial(class C4ToolsDlg *dlg, const char *material); + void ToolsDlgEnableControls(C4ToolsDlg *dlg); + void ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture); + void ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material); + +#ifdef _WIN32 + void Win32KeepDialogsFloating(HWND hwnd = 0); + virtual bool Win32DialogMessageHandling(MSG *msg); +#endif +#ifdef WITH_DEVELOPER_MODE + virtual GtkWidget* InitGUI(); +#endif + + void ClearDlg(void *dlg); +}; + +#endif diff --git a/src/editor/C4ConsoleGUICommon.cpp b/src/editor/C4ConsoleGUICommon.cpp new file mode 100644 index 000000000..7d2670ca0 --- /dev/null +++ b/src/editor/C4ConsoleGUICommon.cpp @@ -0,0 +1,94 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +// To be directly included by platform-specific implementations + +#include + +#ifdef CONSOLEGUICOMMONINCLUDE + +C4ConsoleGUI::C4ConsoleGUI() +{ + state = new C4ConsoleGUI::State(this); +} + +C4ConsoleGUI::~C4ConsoleGUI() {delete state;} + +void C4ConsoleGUI::SetCaption(const char *caption) +{ + if (!Active) return; +#ifdef _WIN32 + // Sorry, the window caption needs to be constant so + // the window can be found using FindWindow + SetTitle(C4ENGINECAPTION); +#else + SetTitle(caption); +#endif +} + +#define DEFINE_STANDARD_DLG_METHODS(cls)\ +cls::cls()\ +{\ + state = new cls::State(this);\ + Default();\ +}\ +\ +cls::~cls()\ +{\ + Clear();\ + delete state;\ +}\ + +DEFINE_STANDARD_DLG_METHODS(C4ToolsDlg) + +void C4ToolsDlg::Clear() +{ + state->Clear(); + Console.ClearDlg(this); + Active = false; +} + +void C4ToolsDlg::Default() +{ + state->Default(); + Active = false; + Tool = SelectedTool = C4TLS_Brush; + Grade = C4TLS_GradeDefault; + ModeIFT = true; + SCopy("Earth",Material); + SCopy("earth",Texture); +} + +DEFINE_STANDARD_DLG_METHODS(C4PropertyDlg) + +void C4PropertyDlg::Default() +{ + state->Default(); + Active = false; + //idSelectedDef=C4ID::None; + Selection.Default(); +} + +void C4PropertyDlg::Clear() +{ + state->Clear(); + Selection.Clear(); + Console.ClearDlg(this); + Active = false; +} + +const char *C4ConsoleGUI::LIST_DIVIDER = "divid0r"; + +#endif diff --git a/src/editor/C4ConsoleWin32.cpp b/src/editor/C4ConsoleWin32.cpp new file mode 100644 index 000000000..5c00c0674 --- /dev/null +++ b/src/editor/C4ConsoleWin32.cpp @@ -0,0 +1,1201 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef USE_GL +#include +#endif + +#include "C4ConsoleGUI.h" +#include "C4Viewport.h" + +#include +#include "resource.h" + +bool SetMenuItemText(HMENU hMenu, WORD id, const char *szText); + +bool AddMenuItem(C4ConsoleGUI *console, HMENU hMenu, DWORD dwID, const char *szString, bool fEnabled) +{ + if (!console->Active) return false; + MENUITEMINFO minfo; + ZeroMem(&minfo,sizeof(minfo)); + minfo.cbSize = sizeof(minfo); + minfo.fMask = MIIM_ID | MIIM_TYPE | MIIM_DATA | MIIM_STATE; + minfo.fType = MFT_STRING; + minfo.wID = dwID; + minfo.dwTypeData = (char*) szString; + minfo.cch = SLen(szString); + if (!fEnabled) minfo.fState|=MFS_GRAYED; + return !!InsertMenuItem(hMenu,0,false,&minfo); +} + +class C4ConsoleGUI::State +{ +public: + BOOL RegisterConsoleWindowClass(HINSTANCE hInst); + bool AddMenuItem(HMENU hMenu, DWORD dwID, const char *szString, bool fEnabled=true); + HBITMAP hbmMouse; + HBITMAP hbmMouse2; + HBITMAP hbmCursor; + HBITMAP hbmCursor2; + HBITMAP hbmBrush; + HBITMAP hbmBrush2; + HBITMAP hbmPlay; + HBITMAP hbmPlay2; + HBITMAP hbmHalt; + HBITMAP hbmHalt2; + + State(C4ConsoleGUI *console) + { + hbmMouse=NULL; + hbmMouse2=NULL; + hbmCursor=NULL; + hbmCursor2=NULL; + hbmBrush=NULL; + hbmBrush2=NULL; + hbmPlay=NULL; + hbmPlay2=NULL; + hbmHalt=NULL; + hbmHalt2=NULL; + } + + ~State() + { + if (hbmMouse) DeleteObject(hbmMouse); + if (hbmMouse2) DeleteObject(hbmMouse2); + if (hbmCursor) DeleteObject(hbmCursor); + if (hbmCursor2) DeleteObject(hbmCursor2); + if (hbmBrush) DeleteObject(hbmBrush); + if (hbmBrush2) DeleteObject(hbmBrush2); + if (hbmPlay) DeleteObject(hbmPlay); + if (hbmPlay2) DeleteObject(hbmPlay2); + if (hbmHalt) DeleteObject(hbmHalt); + if (hbmHalt2) DeleteObject(hbmHalt2); + } + + void CreateBitmaps(CStdApp *application) + { + HINSTANCE instance = application->GetInstance(); + hbmMouse=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_MOUSE)); + hbmMouse2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_MOUSE2)); + hbmCursor=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_CURSOR)); + hbmCursor2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_CURSOR2)); + hbmBrush=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_BRUSH)); + hbmBrush2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_BRUSH2)); + hbmPlay=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_PLAY)); + hbmPlay2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_PLAY2)); + hbmHalt=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_HALT)); + hbmHalt2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_HALT2)); + } + + static void UpdateMenuText(C4Console &console, HMENU hMenu) + { + HMENU hSubMenu; + if (!console.Active) return; + // File + ModifyMenu(hMenu,console.MenuIndexFile,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_FILE")); + hSubMenu = GetSubMenu(hMenu,console.MenuIndexFile); + SetMenuItemText(hSubMenu,IDM_FILE_OPEN,LoadResStr("IDS_MNU_OPEN")); + SetMenuItemText(hSubMenu,IDM_FILE_OPENWPLRS,LoadResStr("IDS_MNU_OPENWPLRS")); + SetMenuItemText(hSubMenu,IDM_FILE_RECORD,LoadResStr("IDS_MNU_RECORD")); + SetMenuItemText(hSubMenu,IDM_FILE_SAVE,LoadResStr("IDS_MNU_SAVESCENARIO")); + SetMenuItemText(hSubMenu,IDM_FILE_SAVEAS,LoadResStr("IDS_MNU_SAVESCENARIOAS")); + SetMenuItemText(hSubMenu,IDM_FILE_SAVEGAME,LoadResStr("IDS_MNU_SAVEGAME")); + SetMenuItemText(hSubMenu,IDM_FILE_SAVEGAMEAS,LoadResStr("IDS_MNU_SAVEGAMEAS")); + SetMenuItemText(hSubMenu,IDM_FILE_CLOSE,LoadResStr("IDS_MNU_CLOSE")); + SetMenuItemText(hSubMenu,IDM_FILE_QUIT,LoadResStr("IDS_MNU_QUIT")); + // Components + ModifyMenu(hMenu,console.MenuIndexComponents,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_COMPONENTS")); + hSubMenu = GetSubMenu(hMenu,console.MenuIndexComponents); + SetMenuItemText(hSubMenu,IDM_COMPONENTS_SCRIPT,LoadResStr("IDS_MNU_SCRIPT")); + SetMenuItemText(hSubMenu,IDM_COMPONENTS_TITLE,LoadResStr("IDS_MNU_TITLE")); + SetMenuItemText(hSubMenu,IDM_COMPONENTS_INFO,LoadResStr("IDS_MNU_INFO")); + // Player + ModifyMenu(hMenu,console.MenuIndexPlayer,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_PLAYER")); + hSubMenu = GetSubMenu(hMenu,console.MenuIndexPlayer); + SetMenuItemText(hSubMenu,IDM_PLAYER_JOIN,LoadResStr("IDS_MNU_JOIN")); + // Viewport + ModifyMenu(hMenu,console.MenuIndexViewport,MF_BYPOSITION | MF_STRING,0,LoadResStr("IDS_MNU_VIEWPORT")); + hSubMenu = GetSubMenu(hMenu,console.MenuIndexViewport); + SetMenuItemText(hSubMenu,IDM_VIEWPORT_NEW,LoadResStr("IDS_MNU_NEW")); + // Help + hSubMenu = GetSubMenu(hMenu,console.MenuIndexHelp); + SetMenuItemText(hSubMenu,IDM_HELP_ABOUT,LoadResStr("IDS_MENU_ABOUT")); + } +}; + +void ClearDlg(HWND &handle) +{ + if (handle) + DestroyWindow(handle); + handle = NULL; +} + +class C4PropertyDlg::State: public C4ConsoleGUI::InternalState +{ + friend class C4ConsoleGUI; +public: + HWND hDialog; + State(C4PropertyDlg *dlg): Super(dlg), hDialog(0) {} + friend INT_PTR CALLBACK PropertyDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); + void Clear() + { + } + void Default() + { + } +}; + +INT_PTR CALLBACK ConsoleDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + //------------------------------------------------------------------------------------------------------------ + case WM_ACTIVATEAPP: + Application.Active = wParam != 0; + return true; + //------------------------------------------------------------------------------------------------------------ + case WM_DESTROY: + StoreWindowPosition(hDlg, "Main", Config.GetSubkeyPath("Console"), false); + Application.Quit(); + return true; + //------------------------------------------------------------------------------------------------------------ + case WM_CLOSE: + Console.Close(); + return true; + //------------------------------------------------------------------------------------------------------------ + case MM_MCINOTIFY: + if (wParam == MCI_NOTIFY_SUCCESSFUL) + Application.MusicSystem.NotifySuccess(); + return true; + //------------------------------------------------------------------------------------------------------------ + case WM_INITDIALOG: + SendMessage(hDlg,DM_SETDEFID,(WPARAM)IDOK,(LPARAM)0); + C4ConsoleGUI::State::UpdateMenuText(Console, GetMenu(hDlg)); + return true; + //------------------------------------------------------------------------------------------------------------ + case WM_COMMAND: + // Evaluate command + switch (LOWORD(wParam)) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDOK: + // IDC_COMBOINPUT to Console.In() + char buffer[16000]; + GetDlgItemText(hDlg,IDC_COMBOINPUT,buffer,16000); + if (buffer[0]) + Console.In(buffer); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONHALT: + Console.DoHalt(); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONPLAY: + Console.DoPlay(); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODEPLAY: + Console.EditCursor.SetMode(C4CNS_ModePlay); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODEEDIT: + Console.EditCursor.SetMode(C4CNS_ModeEdit); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODEDRAW: + Console.EditCursor.SetMode(C4CNS_ModeDraw); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_QUIT: Console.FileQuit(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_SAVEAS: Console.FileSaveAs(false); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_SAVE: Console.FileSave(false); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_SAVEGAMEAS: Console.FileSaveAs(true); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_SAVEGAME: Console.FileSave(true); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_OPEN: Console.FileOpen(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_RECORD: Console.FileRecord(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_OPENWPLRS: Console.FileOpenWPlrs(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_FILE_CLOSE: Console.FileClose(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_HELP_ABOUT: Console.HelpAbout(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_PLAYER_JOIN: Console.PlayerJoin(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_VIEWPORT_NEW: Console.ViewportNew(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_COMPONENTS_TITLE: Console.EditTitle(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_COMPONENTS_INFO: Console.EditInfo(); return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDM_COMPONENTS_SCRIPT: Console.EditScript(); return true; + } + // New player viewport + if (Inside((int) LOWORD(wParam),IDM_VIEWPORT_NEW1,IDM_VIEWPORT_NEW2)) + { + ::Viewports.CreateViewport(LOWORD(wParam)-IDM_VIEWPORT_NEW1); + return true; + } + // Remove player + if (Inside((int) LOWORD(wParam),IDM_PLAYER_QUIT1,IDM_PLAYER_QUIT2)) + { + ::Control.Input.Add(CID_Script, new C4ControlScript( + FormatString("EliminatePlayer(%d)", LOWORD(wParam)-IDM_PLAYER_QUIT1).getData())); + return true; + } + // Remove client + if (Inside((int) LOWORD(wParam),IDM_NET_CLIENT1,IDM_NET_CLIENT2)) + { + if (!::Control.isCtrlHost()) return false; + Game.Clients.CtrlRemove(Game.Clients.getClientByID(LOWORD(wParam)-IDM_NET_CLIENT1), LoadResStr("IDS_MSG_KICKBYMENU")); + return true; + } + return false; + //------------------------------------------------------------------------------------------------------------ + case WM_USER_LOG: + if (SEqual2((const char *)lParam, "IDS_")) + Log(LoadResStr((const char *)lParam)); + else + Log((const char *)lParam); + return false; + //------------------------------------------------------------------------------------------------------------ + case WM_COPYDATA: + COPYDATASTRUCT* pcds = reinterpret_cast(lParam); + if (pcds->dwData == WM_USER_RELOADFILE) + { + // get path, ensure proper termination + const char *szPath = reinterpret_cast(pcds->lpData); + if (szPath[pcds->cbData - 1]) break; + // reload + Game.ReloadFile(szPath); + } + return false; + } + + return false; +} + +class C4ToolsDlg::State: public C4ConsoleGUI::InternalState +{ +public: + HWND hDialog; +#ifdef USE_GL + CStdGLCtx* pGLCtx; +#endif + friend BOOL CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); + HBITMAP hbmBrush,hbmBrush2; + HBITMAP hbmLine,hbmLine2; + HBITMAP hbmRect,hbmRect2; + HBITMAP hbmFill,hbmFill2; + HBITMAP hbmPicker,hbmPicker2; + HBITMAP hbmIFT; + HBITMAP hbmNoIFT; + HBITMAP hbmDynamic; + HBITMAP hbmStatic; + HBITMAP hbmExact; + + State(C4ToolsDlg *toolsDlg): C4ConsoleGUI::InternalState(toolsDlg), hDialog(0), + hbmBrush(0), hbmBrush2(0), + hbmLine(0), hbmLine2(0), + hbmRect(0), hbmRect2(0), + hbmFill(0), hbmFill2(0), + hbmPicker(0), hbmPicker2(0), + hbmIFT(0), + hbmNoIFT(0), + hbmDynamic(0), + hbmStatic(0), + hbmExact(0) + { + pGLCtx = NULL; + } + + void LoadBitmaps(HINSTANCE instance) + { + if (!hbmBrush) hbmBrush=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_BRUSH)); + if (!hbmLine) hbmLine=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_LINE)); + if (!hbmRect) hbmRect=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_RECT)); + if (!hbmFill) hbmFill=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_FILL)); + if (!hbmPicker) hbmPicker=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_PICKER)); + if (!hbmBrush2) hbmBrush2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_BRUSH2)); + if (!hbmLine2) hbmLine2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_LINE2)); + if (!hbmRect2) hbmRect2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_RECT2)); + if (!hbmFill2) hbmFill2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_FILL2)); + if (!hbmPicker2) hbmPicker2=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_PICKER2)); + if (!hbmIFT) hbmIFT=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_IFT)); + if (!hbmNoIFT) hbmNoIFT=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_NOIFT)); + if (!hbmDynamic) hbmDynamic=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_DYNAMIC)); + if (!hbmStatic) hbmStatic=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_STATIC)); + if (!hbmExact) hbmExact=(HBITMAP)LoadBitmap(instance,MAKEINTRESOURCE(IDB_EXACT)); + } + + ~State() + { + Clear(); + } + + void Clear() + { + // Unload bitmaps + if (hbmBrush) DeleteObject(hbmBrush); + if (hbmLine) DeleteObject(hbmLine); + if (hbmRect) DeleteObject(hbmRect); + if (hbmFill) DeleteObject(hbmFill); + if (hbmIFT) DeleteObject(hbmIFT); + if (hbmNoIFT) DeleteObject(hbmNoIFT); +#ifdef USE_GL + if (pGLCtx) + { + delete pGLCtx; + pGLCtx = NULL; + } +#endif + if (hDialog) DestroyWindow(hDialog); hDialog=NULL; + } + + void Default() + { + } + +}; + +#include +BOOL CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + int32_t iValue; + switch (Msg) + { + //---------------------------------------------------------------------------------------------- + case WM_CLOSE: + Console.ToolsDlg.Clear(); + break; + //---------------------------------------------------------------------------------------------- + case WM_DESTROY: + StoreWindowPosition(hDlg, "Property", Config.GetSubkeyPath("Console"), false); + break; + //---------------------------------------------------------------------------------------------- + case WM_INITDIALOG: + return true; + //---------------------------------------------------------------------------------------------- + case WM_PAINT: + PostMessage(hDlg,WM_USER,0,0); // For user paint + return false; + //---------------------------------------------------------------------------------------------- + case WM_USER: + Console.ToolsDlg.NeedPreviewUpdate(); + return true; + //---------------------------------------------------------------------------------------------- + case WM_VSCROLL: + switch (LOWORD(wParam)) + { + case SB_THUMBTRACK: case SB_THUMBPOSITION: + iValue=HIWORD(wParam); + Console.ToolsDlg.SetGrade(C4TLS_GradeMax-iValue); + break; + case SB_PAGEUP: case SB_PAGEDOWN: + case SB_LINEUP: case SB_LINEDOWN: + iValue=SendDlgItemMessage(hDlg,IDC_SLIDERGRADE,TBM_GETPOS,0,0); + Console.ToolsDlg.SetGrade(C4TLS_GradeMax-iValue); + break; + } + return true; + //---------------------------------------------------------------------------------------------- + case WM_COMMAND: + // Evaluate command + switch (LOWORD(wParam)) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDOK: + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODEDYNAMIC: + Console.ToolsDlg.SetLandscapeMode(C4LSC_Dynamic); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODESTATIC: + Console.ToolsDlg.SetLandscapeMode(C4LSC_Static); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONMODEEXACT: + Console.ToolsDlg.SetLandscapeMode(C4LSC_Exact); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONBRUSH: + Console.ToolsDlg.SetTool(C4TLS_Brush, false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONLINE: + Console.ToolsDlg.SetTool(C4TLS_Line, false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONRECT: + Console.ToolsDlg.SetTool(C4TLS_Rect, false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONFILL: + Console.ToolsDlg.SetTool(C4TLS_Fill, false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONPICKER: + Console.ToolsDlg.SetTool(C4TLS_Picker, false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONIFT: + Console.ToolsDlg.SetIFT(true); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONNOIFT: + Console.ToolsDlg.SetIFT(false); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_COMBOMATERIAL: + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE: + { + char str[100]; + int32_t cursel = SendDlgItemMessage(hDlg,IDC_COMBOMATERIAL,CB_GETCURSEL,0,0); + SendDlgItemMessage(hDlg,IDC_COMBOMATERIAL,CB_GETLBTEXT,cursel,(LPARAM)str); + Console.ToolsDlg.SetMaterial(str); + break; + } + } + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_COMBOTEXTURE: + switch (HIWORD(wParam)) + { + case CBN_SELCHANGE: + { + char str[100]; + int32_t cursel = SendDlgItemMessage(hDlg,IDC_COMBOTEXTURE,CB_GETCURSEL,0,0); + SendDlgItemMessage(hDlg,IDC_COMBOTEXTURE,CB_GETLBTEXT,cursel,(LPARAM)str); + Console.ToolsDlg.SetTexture(str); + break; + } + } + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + } + return false; + //---------------------------------------------------------------------------------------- + } + return false; +} + +INT_PTR CALLBACK PropertyDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + switch (Msg) + { + //------------------------------------------------------------------------------------------------ + case WM_CLOSE: + Console.PropertyDlg.Clear(); + break; + //------------------------------------------------------------------------------------------------ + case WM_DESTROY: + StoreWindowPosition(hDlg, "Property", Config.GetSubkeyPath("Console"), false); + break; + //------------------------------------------------------------------------------------------------ + case WM_INITDIALOG: + SendMessage(hDlg,DM_SETDEFID,(WPARAM)IDOK,(LPARAM)0); + return true; + //------------------------------------------------------------------------------------------------ + case WM_COMMAND: + // Evaluate command + switch (LOWORD(wParam)) + { + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDOK: + // IDC_COMBOINPUT to Console.EditCursor.In() + char buffer[16000]; + GetDlgItemText(hDlg,IDC_COMBOINPUT,buffer,16000); + if (buffer[0]) + Console.EditCursor.In(buffer); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + case IDC_BUTTONRELOADDEF: + Game.ReloadDef( Console.PropertyDlg.idSelectedDef ); + return true; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + } + return false; + //----------------------------------------------------------------------------------------------- + } + return false; +} + +void C4ConsoleGUI::Win32KeepDialogsFloating(HWND hwnd) +{ + if (!hwnd) + hwnd = hWindow; + if (Console.PropertyDlg.state->hDialog) + SetWindowLongPtr(Console.PropertyDlg.state->hDialog, GWLP_HWNDPARENT, reinterpret_cast(hwnd)); + if (Console.ToolsDlg.state->hDialog) + SetWindowLongPtr(Console.ToolsDlg.state->hDialog, GWLP_HWNDPARENT, reinterpret_cast(hwnd)); +} + +bool C4ConsoleGUI::Win32DialogMessageHandling(MSG *msg) +{ + return (hWindow && IsDialogMessage(hWindow,msg)) || (Console.PropertyDlg.state->hDialog && IsDialogMessage(Console.PropertyDlg.state->hDialog,msg)); +} + +void C4ConsoleGUI::SetCursor(Cursor cursor) +{ + ::SetCursor(LoadCursor(0,IDC_WAIT)); +} + +bool C4ConsoleGUI::UpdateModeCtrls(int iMode) +{ + if (!Active) + return false; + + SendDlgItemMessage(hWindow,IDC_BUTTONMODEPLAY,BM_SETSTATE,(iMode==C4CNS_ModePlay),0); + UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEPLAY)); + SendDlgItemMessage(hWindow,IDC_BUTTONMODEEDIT,BM_SETSTATE,(iMode==C4CNS_ModeEdit),0); + UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEEDIT)); + SendDlgItemMessage(hWindow,IDC_BUTTONMODEDRAW,BM_SETSTATE,(iMode==C4CNS_ModeDraw),0); + UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONMODEDRAW)); + return true; +} + +CStdWindow* C4ConsoleGUI::CreateConsoleWindow(CStdApp *application) +{ + hWindow = CreateDialog(application->GetInstance(), MAKEINTRESOURCE(IDD_CONSOLE), NULL, ConsoleDlgProc); + if (!hWindow) + { + char * lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + 0, + (LPTSTR) &lpMsgBuf, + 0, + NULL); + Log(FormatString("Error creating dialog window: %s", lpMsgBuf).getData()); + // Free the buffer. + LocalFree(lpMsgBuf); + return NULL; + } + // Restore window position + RestoreWindowPosition(hWindow, "Main", Config.GetSubkeyPath("Console")); + // Set icon + SendMessage(hWindow,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(application->GetInstance(),MAKEINTRESOURCE(IDI_00_C4X))); + SendMessage(hWindow,WM_SETICON,ICON_SMALL,(LPARAM)LoadIcon(application->GetInstance(),MAKEINTRESOURCE(IDI_00_C4X))); + // Set text + SetCaption(LoadResStr("IDS_CNS_CONSOLE")); + // Load bitmaps + state->CreateBitmaps(application); + // Enable controls + UpdateHaltCtrls(true); + EnableControls(fGameOpen); + ClearViewportMenu(); + // Show window and set focus + ShowWindow(hWindow,SW_SHOWNORMAL); + UpdateWindow(hWindow); + SetFocus(hWindow); + ShowCursor(true); + // Success + return this; +} + +void C4ConsoleGUI::DoEnableControls(bool fEnable) +{ + // Set button images (edit modes & halt controls) + SendDlgItemMessage(hWindow,IDC_BUTTONMODEPLAY,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(fEnable ? state->hbmMouse : state->hbmMouse2)); + SendDlgItemMessage(hWindow,IDC_BUTTONMODEEDIT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((fEnable && Editing) ? state->hbmCursor : state->hbmCursor2)); + SendDlgItemMessage(hWindow,IDC_BUTTONMODEDRAW,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((fEnable && Editing) ? state->hbmBrush : state->hbmBrush2)); + SendDlgItemMessage(hWindow,IDC_BUTTONPLAY,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(::Network.isLobbyActive() || fEnable ? state->hbmPlay : state->hbmPlay2)); + SendDlgItemMessage(hWindow,IDC_BUTTONHALT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)(::Network.isLobbyActive() || fEnable ? state->hbmHalt : state->hbmHalt2)); + + // OK + EnableWindow( GetDlgItem(hWindow,IDOK), fEnable); + + // Halt controls + EnableWindow(GetDlgItem(hWindow,IDC_BUTTONPLAY), ::Network.isLobbyActive() || fEnable); + EnableWindow(GetDlgItem(hWindow,IDC_BUTTONHALT), ::Network.isLobbyActive() || fEnable); + + // Edit modes + EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEPLAY),(fEnable)); + EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEEDIT),(fEnable && Editing)); + EnableWindow(GetDlgItem(hWindow,IDC_BUTTONMODEDRAW),(fEnable && Editing)); + + // Console input + EnableWindow(GetDlgItem(hWindow,IDC_COMBOINPUT), fEnable); + + // File menu + // C4Network2 will have to handle that cases somehow (TODO: test) + EnableMenuItem(GetMenu(hWindow),IDM_FILE_OPEN, MF_BYCOMMAND | MF_ENABLED ); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_OPENWPLRS, MF_BYCOMMAND | MF_ENABLED ); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_RECORD, MF_BYCOMMAND | ((Game.IsRunning && ::Control.IsRuntimeRecordPossible()) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEGAME, MF_BYCOMMAND | ((fEnable && ::Players.GetCount()) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEGAMEAS, MF_BYCOMMAND | ((fEnable && ::Players.GetCount()) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVE, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_SAVEAS, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_FILE_CLOSE, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); + + // Components menu + EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_SCRIPT, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_INFO, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_COMPONENTS_TITLE, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); + + // Player & viewport menu + EnableMenuItem(GetMenu(hWindow),IDM_PLAYER_JOIN, MF_BYCOMMAND | ((fEnable && Editing) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(GetMenu(hWindow),IDM_VIEWPORT_NEW, MF_BYCOMMAND | (fEnable ? MF_ENABLED : MF_GRAYED)); +} + +bool C4ConsoleGUI::DoUpdateHaltCtrls(bool fHalt) +{ + SendDlgItemMessage(hWindow,IDC_BUTTONPLAY,BM_SETSTATE,!fHalt,0); + UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONPLAY)); + SendDlgItemMessage(hWindow,IDC_BUTTONHALT,BM_SETSTATE,fHalt,0); + UpdateWindow(GetDlgItem(hWindow,IDC_BUTTONHALT)); + return true; +} + +bool C4ConsoleGUI::Out(const char* message) +{ + if (!Active) return false; + if (!message || !*message) return true; + int len,len2,lines; char *buffer, *buffer2; + len = 65000;//SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINELENGTH,(WPARAM)0,(LPARAM)0); + len2 = len+Min(strlen(message)+2, 5000); + buffer = new char [len2]; + buffer[0]=0; + GetDlgItemText(hWindow,IDC_EDITOUTPUT,buffer,len); + if (buffer[0]) SAppend("\r\n",buffer); + SAppend(message,buffer,len2-1); + if (strlen(buffer) > 60000) buffer2 = buffer + strlen(buffer) - 60000; else buffer2 = buffer; // max log length: Otherwise, discard beginning + SetDlgItemText(hWindow,IDC_EDITOUTPUT,buffer2); + delete [] buffer; + lines = SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_GETLINECOUNT,(WPARAM)0,(LPARAM)0); + SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,(LPARAM)lines); + UpdateWindow(hWindow); + return true; +} + +bool C4ConsoleGUI::ClearLog() +{ + SetDlgItemText(hWindow,IDC_EDITOUTPUT,""); + SendDlgItemMessage(hWindow,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,0); + UpdateWindow(hWindow); + return true; +} + +void C4ConsoleGUI::SetCaptionToFileName(const char* file_name) +{ +} + +void C4ConsoleGUI::DisplayInfoText(C4ConsoleGUI::InfoTextType type, StdStrBuf& text) +{ + int dialog_item; + switch (type) + { + case CONSOLE_FrameCounter: + dialog_item = IDC_STATICFRAME; + break; + case CONSOLE_ScriptCounter: + dialog_item = IDC_STATICSCRIPT; + break; + case CONSOLE_TimeFPS: + dialog_item = IDC_STATICTIME; + break; + default: + assert(false); + } + SetDlgItemText(hWindow,dialog_item,text.getData()); + UpdateWindow(GetDlgItem(hWindow,dialog_item)); +} + +bool C4ConsoleGUI::Message(const char *message, bool query) +{ + return (IDOK==MessageBox(hWindow,message,C4ENGINECAPTION,query ? (MB_OKCANCEL | MB_ICONEXCLAMATION) : MB_ICONEXCLAMATION)); +} + +void C4ConsoleGUI::RecordingEnabled() +{ + EnableMenuItem(GetMenu(hWindow),IDM_FILE_RECORD, MF_BYCOMMAND | MF_GRAYED); +} + +void C4ConsoleGUI::ShowAboutWithCopyright(StdStrBuf ©right) +{ + StdStrBuf strMessage; strMessage.Format("%s %s\n\n%s", C4ENGINECAPTION, C4VERSION, copyright.getData()); + MessageBox(NULL, strMessage.getData(), C4ENGINECAPTION, MB_ICONINFORMATION | MB_TASKMODAL); +} + +bool C4ConsoleGUI::UpdateCursorBar(const char *szCursor) +{ + if (!Active) + return false; + // Cursor + SetDlgItemText(hWindow,IDC_STATICCURSOR,szCursor); + UpdateWindow(GetDlgItem(hWindow,IDC_STATICCURSOR)); + return true; +} + +bool C4ConsoleGUI::FileSelect(char *sFilename, int iSize, const char * szFilter, DWORD dwFlags, bool fSave) +{ + OPENFILENAME ofn; + ZeroMem(&ofn,sizeof(ofn)); + ofn.lStructSize=sizeof(ofn); + ofn.hwndOwner=hWindow; + ofn.lpstrFilter=szFilter; + ofn.lpstrFile=sFilename; + ofn.nMaxFile=iSize; + ofn.nFileOffset= GetFilename(sFilename) - sFilename; + ofn.nFileExtension= GetExtension(sFilename) - sFilename; + ofn.Flags=dwFlags; + + bool fResult; + const char *wd = GetWorkingDirectory(); + if (fSave) + fResult = !!GetSaveFileName(&ofn); + else + fResult = !!GetOpenFileName(&ofn); + + // Reset working directory to exe path as Windows file dialog might have changed it + SetCurrentDirectory(wd); + return fResult; +} + +void C4ConsoleGUI::AddMenuItemForPlayer(C4Player* player, StdStrBuf& player_text) +{ + AddMenuItem(this, GetSubMenu(GetMenu(hWindow),Console.MenuIndexViewport),IDM_VIEWPORT_NEW1+player->Number,player_text.getData(), true); +} + +void C4ConsoleGUI::AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled) +{ + AddMenuItem(this, GetSubMenu(GetMenu(hWindow),Console.MenuIndexPlayer),IDM_PLAYER_QUIT1+player->Number,player_text.getData(),(!::Network.isEnabled() || ::Network.isHost()) && Editing); +} + +void C4ConsoleGUI::UpdateNetMenu(Stage stage) +{ + switch (stage) + { + case C4ConsoleGUI::STAGE_Start: + if (!InsertMenu(GetMenu(hWindow),Console.MenuIndexHelp,MF_BYPOSITION | MF_POPUP,(UINT_PTR)CreateMenu(),LoadResStr("IDS_MNU_NET"))) return; + break; + case C4ConsoleGUI::STAGE_Intermediate: + DrawMenuBar(hWindow); + break; + case C4ConsoleGUI::STAGE_End: + break; + } +} + +void C4ConsoleGUI::ClearNetMenu(C4ConsoleGUI::Stage stage) +{ + switch (stage) + { + case C4ConsoleGUI::STAGE_Start: + DeleteMenu(GetMenu(hWindow),Console.MenuIndexNet,MF_BYPOSITION); + break; + case C4ConsoleGUI::STAGE_End: + DrawMenuBar(hWindow); + break; + } +} + +void C4ConsoleGUI::AddNetMenuItemForPlayer(int32_t index, StdStrBuf &text) +{ + AddMenuItem(this, GetSubMenu(GetMenu(hWindow),Console.MenuIndexNet), IDM_NET_CLIENT1+Game.Clients.getLocalID(), text.getData(), true); +} + +void C4ConsoleGUI::ClearViewportMenu() +{ + HMENU hMenu = GetSubMenu(GetMenu(hWindow),Console.MenuIndexViewport); + while (DeleteMenu(hMenu,1,MF_BYPOSITION)); +} + +void C4ConsoleGUI::ClearDlg(void *dlg) +{ + if (dlg == &Console.ToolsDlg) + ::ClearDlg(Console.ToolsDlg.state->hDialog); + else if (dlg == &Console.PropertyDlg) + ::ClearDlg(Console.PropertyDlg.state->hDialog); +} + +void C4ConsoleGUI::ToolsDlgSetTexture(class C4ToolsDlg *dlg, const char *texture) +{ + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)texture); +} + +void C4ConsoleGUI::ToolsDlgSetMaterial(class C4ToolsDlg *dlg, const char *material) +{ + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOMATERIAL,CB_SELECTSTRING,0,(LPARAM)material); +} + +bool C4ConsoleGUI::PropertyDlgOpen(C4PropertyDlg * dlg) +{ + if (Console.PropertyDlg.state->hDialog) return true; + dlg->state->hDialog = CreateDialog(Application.GetInstance(), + MAKEINTRESOURCE(IDD_PROPERTIES), + Console.hWindow, + (DLGPROC) PropertyDlgProc); + if (!Console.PropertyDlg.state->hDialog) return false; + // Set text + SetWindowText(Console.PropertyDlg.state->hDialog,LoadResStr("IDS_DLG_PROPERTIES")); + // Enable controls + EnableWindow( GetDlgItem(Console.PropertyDlg.state->hDialog,IDOK), Console.Editing ); + EnableWindow( GetDlgItem(Console.PropertyDlg.state->hDialog,IDC_COMBOINPUT), Console.Editing ); + EnableWindow( GetDlgItem(Console.PropertyDlg.state->hDialog,IDC_BUTTONRELOADDEF), Console.Editing ); + // Show window + RestoreWindowPosition(Console.PropertyDlg.state->hDialog, "Property", Config.GetSubkeyPath("Console")); + SetWindowPos(Console.PropertyDlg.state->hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(Console.PropertyDlg.state->hDialog,SW_SHOWNOACTIVATE); + return true; +} + +void C4ConsoleGUI::PropertyDlgUpdate(C4PropertyDlg *dlg, StdStrBuf &text) +{ + HWND hDialog = dlg->state->hDialog; + int iLine = SendDlgItemMessage(hDialog,IDC_EDITOUTPUT,EM_GETFIRSTVISIBLELINE,(WPARAM)0,(LPARAM)0); + SetDlgItemText(hDialog,IDC_EDITOUTPUT,text.getData()); + SendDlgItemMessage(hDialog,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,(LPARAM)iLine); + UpdateWindow(GetDlgItem(hDialog,IDC_EDITOUTPUT)); +} + +void SetComboItems(HWND hCombo, std::vector &items) +{ + for (std::vector::iterator it = items.begin(); it != items.end(); it++) + { + char *item = *it; + if (item == C4ConsoleGUI::LIST_DIVIDER) + SendMessage(hCombo,CB_INSERTSTRING,0,(LPARAM)"----------"); + else + SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)*it); + } +} + +void C4ConsoleGUI::PropertyDlgSetFunctions(C4PropertyDlg *dlg, std::vector &functions) +{ + HWND hCombo = GetDlgItem(dlg->state->hDialog, IDC_COMBOINPUT); + char szLastText[500+1]; + // Remember old window text + GetWindowText(hCombo, szLastText, 500); + // Clear + SendMessage(hCombo, CB_RESETCONTENT, 0, 0); + + SetComboItems(GetDlgItem(dlg->state->hDialog,IDC_COMBOINPUT), functions); + + // Restore + SetWindowText(hCombo, szLastText); +} + +void C4ConsoleGUI::SetInputFunctions(std::vector &functions) +{ + SetComboItems(GetDlgItem(hWindow,IDC_COMBOINPUT), functions); +} + +void C4ConsoleGUI::ClearPlayerMenu() +{ + if (!Active) return; + HMENU hMenu = GetSubMenu(GetMenu(hWindow),Console.MenuIndexPlayer); + while (DeleteMenu(hMenu,1,MF_BYPOSITION)); +} + +void C4ConsoleGUI::ClearInput() +{ + HWND hCombo = GetDlgItem(hWindow,IDC_COMBOINPUT); + // Clear + SendMessage(hCombo,CB_RESETCONTENT,0,0); +} + +/* +void C4ConsoleGUI::ClearPropertyDlg(C4PropertyDlg *dlg) +{ + if (dlg->state->hDialog) DestroyWindow(PropertyDlg.hDialog); PropertyDlg.hDialog=NULL; +} +*/ + +bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg) +{ + if (dlg->state->hDialog) return true; + dlg->state->hDialog = CreateDialog(Application.GetInstance(), + MAKEINTRESOURCE(IDD_TOOLS), + Console.hWindow, + (DLGPROC) ToolsDlgProc); + if (!dlg->state->hDialog) return false; + // Set text + SetWindowText(dlg->state->hDialog,LoadResStr("IDS_DLG_TOOLS")); + SetDlgItemText(dlg->state->hDialog,IDC_STATICMATERIAL,LoadResStr("IDS_CTL_MATERIAL")); + SetDlgItemText(dlg->state->hDialog,IDC_STATICTEXTURE,LoadResStr("IDS_CTL_TEXTURE")); + // Load bitmaps if necessary + dlg->state->LoadBitmaps(Application.GetInstance()); + // create target ctx for OpenGL rendering +#ifdef USE_GL + if (lpDDraw && !dlg->state->pGLCtx) + dlg->state->pGLCtx = lpDDraw->CreateContext(GetDlgItem(dlg->state->hDialog,IDC_PREVIEW), &Application); +#endif + // Show window + RestoreWindowPosition(dlg->state->hDialog, "Property", Config.GetSubkeyPath("Console")); + SetWindowPos(dlg->state->hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(dlg->state->hDialog,SW_SHOWNOACTIVATE); + return true; +} + +void C4ConsoleGUI::ToolsDlgInitMaterialCtrls(class C4ToolsDlg *dlg) +{ + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOMATERIAL,CB_ADDSTRING,0,(LPARAM)C4TLS_MatSky); + for (int32_t cnt=0; cnt< ::MaterialMap.Num; cnt++) + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOMATERIAL,CB_ADDSTRING,0,(LPARAM)::MaterialMap.Map[cnt].Name); + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOMATERIAL,CB_SELECTSTRING,0,(LPARAM)dlg->Material); +} + +void C4ToolsDlg::UpdateToolCtrls() +{ + HWND hDialog = state->hDialog; + int32_t Tool = Tool; + SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETSTATE,(Tool==C4TLS_Brush),0); + UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH)); + SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETSTATE,(Tool==C4TLS_Line),0); + UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONLINE)); + SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETSTATE,(Tool==C4TLS_Rect),0); + UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONRECT)); + SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETSTATE,(Tool==C4TLS_Fill),0); + UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONFILL)); + SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETSTATE,(Tool==C4TLS_Picker),0); + UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER)); +} + +void C4ConsoleGUI::ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture) +{ + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)texture); +} + +void C4ConsoleGUI::ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material) +{ + SendDlgItemMessage(dlg->state->hDialog,IDC_COMBOMATERIAL,CB_SELECTSTRING,0,(LPARAM)material); +} + +void C4ToolsDlg::UpdateTextures() +{ + // Refill dlg + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_RESETCONTENT,0,(LPARAM)0); + // bottom-most: any invalid textures + bool fAnyEntry = false; int32_t cnt; const char *szTexture; + if (::Landscape.Mode!=C4LSC_Exact) + for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) + { + if (!::TextureMap.GetIndex(Material, szTexture, false)) + { + fAnyEntry = true; + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)szTexture); + } + } + // separator + if (fAnyEntry) + { + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)"-------"); + } + + // atop: valid textures + for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) + { + // Current material-texture valid? Always valid for exact mode + if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact) + { + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)szTexture); + } + } + // reselect current + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)Texture); +} + +void C4ToolsDlg::NeedPreviewUpdate() +{ + if (!state->hDialog) return; + + SURFACE sfcPreview; + int32_t iPrvWdt,iPrvHgt; + RECT rect; + + GetClientRect(GetDlgItem(state->hDialog,IDC_PREVIEW),&rect); + + iPrvWdt=rect.right-rect.left; + iPrvHgt=rect.bottom-rect.top; + + if (!(sfcPreview=new CSurface(iPrvWdt,iPrvHgt))) return; + + // fill bg + lpDDraw->DrawBoxDw(sfcPreview,0,0,iPrvWdt-1,iPrvHgt-1,C4RGB(0x80,0x80,0x80)); + BYTE bCol = 0; + CPattern Pattern; + // Sky material: sky as pattern only + if (SEqual(Material,C4TLS_MatSky)) + { + Pattern.Set(::Landscape.Sky.Surface, 0); + } + // Material-Texture + else + { + bCol=Mat2PixColDefault(::MaterialMap.Get(Material)); + // Get/Create TexMap entry + BYTE iTex = ::TextureMap.GetIndex(Material, Texture, true); + if (iTex) + { + // Define texture pattern + const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex); + // Security + if (pTex) + { + // Set drawing pattern + Pattern = pTex->GetPattern(); + } + } + } + if (IsWindowEnabled(GetDlgItem(state->hDialog,IDC_PREVIEW))) + lpDDraw->DrawPatternedCircle( sfcPreview, + iPrvWdt/2,iPrvHgt/2, + Grade, + bCol, Pattern, *::Landscape.GetPal()); + + //Application.DDraw->AttachPrimaryPalette(sfcPreview); + +#ifdef USE_DIRECTX + if (pD3D) + pD3D->BlitSurface2Window( sfcPreview, + 0,0,iPrvWdt,iPrvHgt, + GetDlgItem(hDialog,IDC_PREVIEW), + rect.left,rect.top,rect.right,rect.bottom); +#endif +#ifdef USE_GL + // FIXME: This activates the wrong GL context. To avoid breaking the main window display, + // FIXME: it has been disabled for the moment + //if (pGLCtx->Select()) + //{ + // pGL->Blit(sfcPreview, 0,0,(float)iPrvWdt,(float)iPrvHgt, Application.pWindow->pSurface, rect.left,rect.top, iPrvWdt,iPrvHgt); + // Application.pWindow->pSurface->PageFlip(); + //} +#endif + delete sfcPreview; +} + +void C4ToolsDlg::InitGradeCtrl() +{ + if (!state->hDialog) return; + HWND hwndTrack = GetDlgItem(state->hDialog,IDC_SLIDERGRADE); + SendMessage(hwndTrack,TBM_SETPAGESIZE,0,(LPARAM)5); + SendMessage(hwndTrack,TBM_SETLINESIZE,0,(LPARAM)1); + SendMessage(hwndTrack,TBM_SETRANGE,(WPARAM)false, + (LPARAM) MAKELONG(C4TLS_GradeMin,C4TLS_GradeMax)); + SendMessage(hwndTrack,TBM_SETPOS,(WPARAM)true,(LPARAM)C4TLS_GradeMax-Grade); + UpdateWindow(hwndTrack); +} + +bool C4ToolsDlg::PopMaterial() +{ + if (!state->hDialog) return false; + SetFocus(GetDlgItem(state->hDialog,IDC_COMBOMATERIAL)); + SendDlgItemMessage(state->hDialog,IDC_COMBOMATERIAL,CB_SHOWDROPDOWN,true,0); + return true; +} + +bool C4ToolsDlg::PopTextures() +{ + if (!state->hDialog) return false; + SetFocus(GetDlgItem(state->hDialog,IDC_COMBOTEXTURE)); + SendDlgItemMessage(state->hDialog,IDC_COMBOTEXTURE,CB_SHOWDROPDOWN,true,0); + return true; +} + +void C4ToolsDlg::UpdateIFTControls() +{ + if (!state->hDialog) + return; + SendDlgItemMessage(state->hDialog,IDC_BUTTONNOIFT,BM_SETSTATE,(ModeIFT==0),0); + UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONNOIFT)); + SendDlgItemMessage(state->hDialog,IDC_BUTTONIFT,BM_SETSTATE,(ModeIFT==1),0); + UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONIFT)); +} + +void C4ToolsDlg::UpdateLandscapeModeCtrls() +{ + int32_t iMode = ::Landscape.Mode; + // Dynamic: enable only if dynamic anyway + SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETSTATE,(iMode==C4LSC_Dynamic),0); + EnableWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEDYNAMIC),(iMode==C4LSC_Dynamic)); + UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEDYNAMIC)); + // Static: enable only if map available + SendDlgItemMessage(state->hDialog,IDC_BUTTONMODESTATIC,BM_SETSTATE,(iMode==C4LSC_Static),0); + EnableWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODESTATIC),(::Landscape.Map!=NULL)); + UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODESTATIC)); + // Exact: enable always + SendDlgItemMessage(state->hDialog,IDC_BUTTONMODEEXACT,BM_SETSTATE,(iMode==C4LSC_Exact),0); + UpdateWindow(GetDlgItem(state->hDialog,IDC_BUTTONMODEEXACT)); + // Set dialog caption + SetWindowText(state->hDialog,LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT")); +} + +void C4ConsoleGUI::ToolsDlgEnableControls(C4ToolsDlg *dlg) +{ + HWND hDialog = dlg->state->hDialog; + int32_t iLandscapeMode=::Landscape.Mode; + // Set bitmap buttons + SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? dlg->state->hbmBrush : dlg->state->hbmBrush2)); + SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? dlg->state->hbmLine : dlg->state->hbmLine2)); + SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? dlg->state->hbmRect : dlg->state->hbmRect2)); + SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Exact) ? dlg->state->hbmFill : dlg->state->hbmFill2)); + SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? dlg->state->hbmPicker : dlg->state->hbmPicker2)); + SendDlgItemMessage(hDialog,IDC_BUTTONIFT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)dlg->state->hbmIFT); + SendDlgItemMessage(hDialog,IDC_BUTTONNOIFT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)dlg->state->hbmNoIFT); + SendDlgItemMessage(hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)dlg->state->hbmDynamic); + SendDlgItemMessage(hDialog,IDC_BUTTONMODESTATIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)dlg->state->hbmStatic); + SendDlgItemMessage(hDialog,IDC_BUTTONMODEEXACT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)dlg->state->hbmExact); + // Enable drawing controls + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONLINE),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONRECT),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONFILL),(iLandscapeMode>=C4LSC_Exact)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONIFT),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_BUTTONNOIFT),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_COMBOMATERIAL),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_COMBOTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(dlg->Material,C4TLS_MatSky)); + EnableWindow(GetDlgItem(hDialog,IDC_STATICMATERIAL),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_STATICTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(dlg->Material,C4TLS_MatSky)); + EnableWindow(GetDlgItem(hDialog,IDC_SLIDERGRADE),(iLandscapeMode>=C4LSC_Static)); + EnableWindow(GetDlgItem(hDialog,IDC_PREVIEW),(iLandscapeMode>=C4LSC_Static)); +} + +#define CONSOLEGUICOMMONINCLUDE +#include "C4ConsoleGUICommon.cpp" diff --git a/src/editor/C4ConsoleX11.cpp b/src/editor/C4ConsoleX11.cpp new file mode 100644 index 000000000..9d971c7c8 --- /dev/null +++ b/src/editor/C4ConsoleX11.cpp @@ -0,0 +1,13 @@ +namespace +{ + const DWORD OFN_HIDEREADONLY = 1 << 0; + const DWORD OFN_OVERWRITEPROMPT = 1 << 1; + const DWORD OFN_FILEMUSTEXIST = 1 << 2; + const DWORD OFN_ALLOWMULTISELECT = 1 << 3; + + const DWORD OFN_EXPLORER = 0; // ignored +} +#ifdef USE_X11 +#include +#include +#endif \ No newline at end of file diff --git a/src/editor/C4PropertyDlg.cpp b/src/editor/C4PropertyDlg.cpp index b612b24c2..cb78bf536 100644 --- a/src/editor/C4PropertyDlg.cpp +++ b/src/editor/C4PropertyDlg.cpp @@ -36,127 +36,9 @@ #include -#ifdef WITH_DEVELOPER_MODE -# include -# include - -# include -#endif - -#ifdef _WIN32 -#include "resource.h" - -INT_PTR CALLBACK PropertyDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) - { - //------------------------------------------------------------------------------------------------ - case WM_CLOSE: - Console.PropertyDlg.Clear(); - break; - //------------------------------------------------------------------------------------------------ - case WM_DESTROY: - StoreWindowPosition(hDlg, "Property", Config.GetSubkeyPath("Console"), false); - break; - //------------------------------------------------------------------------------------------------ - case WM_INITDIALOG: - SendMessage(hDlg,DM_SETDEFID,(WPARAM)IDOK,(LPARAM)0); - return true; - //------------------------------------------------------------------------------------------------ - case WM_COMMAND: - // Evaluate command - switch (LOWORD(wParam)) - { - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDOK: - // IDC_COMBOINPUT to Console.EditCursor.In() - char buffer[16000]; - GetDlgItemText(hDlg,IDC_COMBOINPUT,buffer,16000); - if (buffer[0]) - Console.EditCursor.In(buffer); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONRELOADDEF: - Game.ReloadDef( Console.PropertyDlg.idSelectedDef ); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - return false; - //----------------------------------------------------------------------------------------------- - } - return false; -} -#endif -C4PropertyDlg::C4PropertyDlg() -{ - Default(); -} - -C4PropertyDlg::~C4PropertyDlg() -{ - Clear(); - -#ifdef WITH_DEVELOPER_MODE - if (vbox != NULL) - { - g_signal_handler_disconnect(G_OBJECT(C4DevmodeDlg::GetWindow()), handlerHide); - C4DevmodeDlg::RemovePage(vbox); - vbox = NULL; - } -#endif // WITH_DEVELOPER_MODE -} - bool C4PropertyDlg::Open() { -#ifdef _WIN32 - if (hDialog) return true; - hDialog = CreateDialog(Application.GetInstance(), - MAKEINTRESOURCE(IDD_PROPERTIES), - Console.hWindow, - (DLGPROC) PropertyDlgProc); - if (!hDialog) return false; - // Set text - SetWindowText(hDialog,LoadResStr("IDS_DLG_PROPERTIES")); - // Enable controls - EnableWindow( GetDlgItem(hDialog,IDOK), Console.Editing ); - EnableWindow( GetDlgItem(hDialog,IDC_COMBOINPUT), Console.Editing ); - EnableWindow( GetDlgItem(hDialog,IDC_BUTTONRELOADDEF), Console.Editing ); - // Show window - RestoreWindowPosition(hDialog, "Property", Config.GetSubkeyPath("Console")); - SetWindowPos(hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE); - ShowWindow(hDialog,SW_SHOWNOACTIVATE); -#else // _WIN32 -#ifdef WITH_DEVELOPER_MODE - if (vbox == NULL) - { - vbox = gtk_vbox_new(false, 6); - - GtkWidget* scrolled_wnd = gtk_scrolled_window_new(NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_wnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_wnd), GTK_SHADOW_IN); - - textview = gtk_text_view_new(); - entry = gtk_entry_new(); - - gtk_container_add(GTK_CONTAINER(scrolled_wnd), textview); - gtk_box_pack_start(GTK_BOX(vbox), scrolled_wnd, true, true, 0); - gtk_box_pack_start(GTK_BOX(vbox), entry, false, false, 0); - - gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), false); - gtk_widget_set_sensitive(entry, Console.Editing); - - gtk_widget_show_all(vbox); - - C4DevmodeDlg::AddPage(vbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_PROPERTIES")); - - g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(OnScriptActivate), this); - - handlerHide = g_signal_connect(G_OBJECT(C4DevmodeDlg::GetWindow()), "hide", G_CALLBACK(OnWindowHide), this); - } - - C4DevmodeDlg::SwitchPage(vbox); -#endif // WITH_DEVELOPER_MODE -#endif // _WIN32 + Console.PropertyDlgOpen(this); Active = true; return true; } @@ -239,135 +121,41 @@ bool C4PropertyDlg::Update() break; } // Update info edit control -#ifdef _WIN32 - int iLine = SendDlgItemMessage(hDialog,IDC_EDITOUTPUT,EM_GETFIRSTVISIBLELINE,(WPARAM)0,(LPARAM)0); - SetDlgItemText(hDialog,IDC_EDITOUTPUT,Output.getData()); - SendDlgItemMessage(hDialog,IDC_EDITOUTPUT,EM_LINESCROLL,(WPARAM)0,(LPARAM)iLine); - UpdateWindow(GetDlgItem(hDialog,IDC_EDITOUTPUT)); -#else -#ifdef WITH_DEVELOPER_MODE - GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); - gtk_text_buffer_set_text(buffer, Output.getData(), -1); -#endif -#endif + Console.PropertyDlgUpdate(this, Output); return true; } -void C4PropertyDlg::Default() -{ -#ifdef _WIN32 - hDialog=NULL; -#else -#ifdef WITH_DEVELOPER_MODE - vbox = NULL; -#endif -#endif - Active = false; - idSelectedDef=C4ID::None; - Selection.Default(); -} - -void C4PropertyDlg::Clear() -{ - Selection.Clear(); -#ifdef _WIN32 - if (hDialog) DestroyWindow(hDialog); hDialog=NULL; -#else -#ifdef WITH_DEVELOPER_MODE - //if(vbox != NULL) - // C4DevmodeDlg::SwitchPage(NULL); -#endif -#endif - Active = false; -} - void C4PropertyDlg::UpdateInputCtrl(C4Object *pObj) { - int cnt; -#ifdef _WIN32 - HWND hCombo = GetDlgItem(hDialog,IDC_COMBOINPUT); - // Remember old window text - char szLastText[500+1]; - GetWindowText(hCombo,szLastText,500); - // Clear - SendMessage(hCombo,CB_RESETCONTENT,0,0); -#else // _WIN32 -#ifdef WITH_DEVELOPER_MODE - - GtkEntryCompletion* completion = gtk_entry_get_completion(GTK_ENTRY(entry)); - GtkListStore* store; - - // Uncouple list store from completion so that the completion is not - // notified for every row we are going to insert. This enhances - // performance significantly. - if (!completion) - { - completion = gtk_entry_completion_new(); - store = gtk_list_store_new(1, G_TYPE_STRING); - - gtk_entry_completion_set_text_column(completion, 0); - gtk_entry_set_completion(GTK_ENTRY(entry), completion); - g_object_unref(G_OBJECT(completion)); - } - else - { - store = GTK_LIST_STORE(gtk_entry_completion_get_model(completion)); - g_object_ref(G_OBJECT(store)); - gtk_entry_completion_set_model(completion, NULL); - } - - GtkTreeIter iter; - gtk_list_store_clear(store); -#endif // WITH_DEVELOPER_MODE -#endif // _WIN32 - // add global and standard functions + std::vector functions; for (C4AulFunc *pFn = ::ScriptEngine.GetFirstFunc(); pFn; pFn = ::ScriptEngine.GetNextFunc(pFn)) + { if (pFn->GetPublic()) { -#ifdef _WIN32 - SendMessage(hCombo,CB_ADDSTRING,0,(LPARAM)pFn->Name); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, pFn->Name, -1); -#endif -#endif + functions.push_back(pFn->Name); } + } // Add object script functions -#ifdef _WIN32 bool fDivider = false; -#endif C4AulScriptFunc *pRef; // Object script available if (pObj && pObj->Def) + { // Scan all functions - for (cnt=0; (pRef=pObj->Def->Script.GetSFunc(cnt)); cnt++) + for (int cnt=0; (pRef=pObj->Def->Script.GetSFunc(cnt)); cnt++) + { // Public functions only if ((pRef->Access=AA_PUBLIC)) { -#ifdef _WIN32 // Insert divider if necessary - if (!fDivider) { SendMessage(hCombo,CB_INSERTSTRING,0,(LPARAM)"----------"); fDivider=true; } -#endif + if (!fDivider) { functions.push_back((char*)C4ConsoleGUI::LIST_DIVIDER); fDivider=true; } // Add function -#ifdef _WIN32 - SendMessage(hCombo,CB_INSERTSTRING,0,(LPARAM)pRef->Name); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_list_store_append(store, &iter); - gtk_list_store_set(store, &iter, 0, pRef->Name, -1); -#endif -#endif + functions.push_back(pRef->Name); } - -#ifdef _WIN32 - // Restore old text - SetWindowText(hCombo,szLastText); -#elif defined(WITH_DEVELOPER_MODE) - // Reassociate list store with completion - gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(store)); -#endif + } + } + Console.PropertyDlgSetFunctions(this, functions); } void C4PropertyDlg::Execute() @@ -379,24 +167,3 @@ void C4PropertyDlg::ClearPointers(C4Object *pObj) { Selection.ClearPointers(pObj); } - -#ifdef WITH_DEVELOPER_MODE -// GTK+ callbacks -void C4PropertyDlg::OnScriptActivate(GtkWidget* widget, gpointer data) -{ - const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget)); - if (text && text[0]) - Console.EditCursor.In(text); -} - -void C4PropertyDlg::OnWindowHide(GtkWidget* widget, gpointer user_data) -{ - static_cast(user_data)->Active = false; -} - -/*void C4PropertyDlg::OnDestroy(GtkWidget* widget, gpointer data) -{ - static_cast(data)->window = NULL; - static_cast(data)->Active = false; -}*/ -#endif diff --git a/src/editor/C4PropertyDlg.h b/src/editor/C4PropertyDlg.h index 5830fecf7..c34013d59 100644 --- a/src/editor/C4PropertyDlg.h +++ b/src/editor/C4PropertyDlg.h @@ -26,12 +26,14 @@ #include "C4ObjectList.h" -#ifdef WITH_DEVELOPER_MODE -# include -#endif +#include "C4ConsoleGUI.h" class C4PropertyDlg { + friend class C4ConsoleGUI; +private: + class State; + State *state; public: C4PropertyDlg(); ~C4PropertyDlg(); @@ -44,24 +46,7 @@ public: bool Update(); bool Update(C4ObjectList &rSelection); bool Active; -#ifdef _WIN32 - HWND hDialog; - friend INT_PTR CALLBACK PropertyDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); -#else -#ifdef WITH_DEVELOPER_MODE -// GtkWidget* window; - GtkWidget* vbox; - GtkWidget* textview; - GtkWidget* entry; - - gulong handlerHide; - - static void OnScriptActivate(GtkWidget* widget, gpointer data); - static void OnWindowHide(GtkWidget* widget, gpointer data); -// static void OnDestroy(GtkWidget* widget, gpointer data); -#endif -#endif -protected: +public: // ToolsDlg fields are public as well... C4ID idSelectedDef; C4ObjectList Selection; }; diff --git a/src/editor/C4ToolsDlg.cpp b/src/editor/C4ToolsDlg.cpp index f8f0fa795..9ec8dcc90 100644 --- a/src/editor/C4ToolsDlg.cpp +++ b/src/editor/C4ToolsDlg.cpp @@ -37,369 +37,10 @@ #include #endif -#ifdef _WIN32 -#include "resource.h" -#endif - -#ifdef WITH_DEVELOPER_MODE -# include -# include - -# include - -# include -# include -# include -# include -# include - -# include -# include -# include - -# include -# include - -namespace -{ - void SelectComboBoxText(GtkComboBox* combobox, const char* text) - { - GtkTreeModel* model = gtk_combo_box_get_model(combobox); - - GtkTreeIter iter; - for (gboolean ret = gtk_tree_model_get_iter_first(model, &iter); ret; ret = gtk_tree_model_iter_next(model, &iter)) - { - gchar* col_text; - gtk_tree_model_get(model, &iter, 0, &col_text, -1); - - if (SEqualNoCase(text, col_text)) - { - g_free(col_text); - gtk_combo_box_set_active_iter(combobox, &iter); - return; - } - - g_free(col_text); - } - } - - gboolean RowSeparatorFunc(GtkTreeModel* model, GtkTreeIter* iter, void* user_data) - { - gchar* text; - gtk_tree_model_get(model, iter, 0, &text, -1); - - if (SEqual(text, "------")) { g_free(text); return true; } - g_free(text); - return false; - } - - GtkWidget* CreateImageFromInlinedPixbuf(const guint8* pixbuf_data) - { - GdkPixbuf* pixbuf = gdk_pixbuf_new_from_inline(-1, pixbuf_data, false, NULL); - GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); - gdk_pixbuf_unref(pixbuf); - return image; - } -} -#endif - -#ifdef _WIN32 -#include -INT_PTR CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - int32_t iValue; - switch (Msg) - { - //---------------------------------------------------------------------------------------------- - case WM_CLOSE: - Console.ToolsDlg.Clear(); - break; - //---------------------------------------------------------------------------------------------- - case WM_DESTROY: - StoreWindowPosition(hDlg, "Property", Config.GetSubkeyPath("Console"), false); - break; - //---------------------------------------------------------------------------------------------- - case WM_INITDIALOG: - return true; - //---------------------------------------------------------------------------------------------- - case WM_PAINT: - PostMessage(hDlg,WM_USER,0,0); // For user paint - return false; - //---------------------------------------------------------------------------------------------- - case WM_USER: - Console.ToolsDlg.UpdatePreview(); - return true; - //---------------------------------------------------------------------------------------------- - case WM_VSCROLL: - switch (LOWORD(wParam)) - { - case SB_THUMBTRACK: case SB_THUMBPOSITION: - iValue=HIWORD(wParam); - Console.ToolsDlg.SetGrade(C4TLS_GradeMax-iValue); - break; - case SB_PAGEUP: case SB_PAGEDOWN: - case SB_LINEUP: case SB_LINEDOWN: - iValue=SendDlgItemMessage(hDlg,IDC_SLIDERGRADE,TBM_GETPOS,0,0); - Console.ToolsDlg.SetGrade(C4TLS_GradeMax-iValue); - break; - } - return true; - //---------------------------------------------------------------------------------------------- - case WM_COMMAND: - // Evaluate command - switch (LOWORD(wParam)) - { - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDOK: - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODEDYNAMIC: - Console.ToolsDlg.SetLandscapeMode(C4LSC_Dynamic); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODESTATIC: - Console.ToolsDlg.SetLandscapeMode(C4LSC_Static); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONMODEEXACT: - Console.ToolsDlg.SetLandscapeMode(C4LSC_Exact); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONBRUSH: - Console.ToolsDlg.SetTool(C4TLS_Brush, false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONLINE: - Console.ToolsDlg.SetTool(C4TLS_Line, false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONRECT: - Console.ToolsDlg.SetTool(C4TLS_Rect, false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONFILL: - Console.ToolsDlg.SetTool(C4TLS_Fill, false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONPICKER: - Console.ToolsDlg.SetTool(C4TLS_Picker, false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONIFT: - Console.ToolsDlg.SetIFT(true); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_BUTTONNOIFT: - Console.ToolsDlg.SetIFT(false); - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_COMBOMATERIAL: - switch (HIWORD(wParam)) - { - case CBN_SELCHANGE: - { - char str[100]; - int32_t cursel = SendDlgItemMessage(hDlg,IDC_COMBOMATERIAL,CB_GETCURSEL,0,0); - SendDlgItemMessage(hDlg,IDC_COMBOMATERIAL,CB_GETLBTEXT,cursel,(LPARAM)str); - Console.ToolsDlg.SetMaterial(str); - break; - } - } - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case IDC_COMBOTEXTURE: - switch (HIWORD(wParam)) - { - case CBN_SELCHANGE: - { - char str[100]; - int32_t cursel = SendDlgItemMessage(hDlg,IDC_COMBOTEXTURE,CB_GETCURSEL,0,0); - SendDlgItemMessage(hDlg,IDC_COMBOTEXTURE,CB_GETLBTEXT,cursel,(LPARAM)str); - Console.ToolsDlg.SetTexture(str); - break; - } - } - return true; - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } - return false; - //---------------------------------------------------------------------------------------- - } - return false; -} -#endif -C4ToolsDlg::C4ToolsDlg() -{ - Default(); -#ifdef _WIN32 - hbmBrush=hbmLine=hbmRect=hbmFill=NULL; - hbmIFT=hbmNoIFT=NULL; -#endif -} - -C4ToolsDlg::~C4ToolsDlg() -{ - Clear(); -#ifdef WITH_DEVELOPER_MODE - if (hbox != NULL) - { - g_signal_handler_disconnect(G_OBJECT(C4DevmodeDlg::GetWindow()), handlerHide); - C4DevmodeDlg::RemovePage(hbox); - hbox = NULL; - } -#endif // WITH_DEVELOPER_MODE - - // Unload bitmaps -#ifdef _WIN32 - if (hbmBrush) DeleteObject(hbmBrush); - if (hbmLine) DeleteObject(hbmLine); - if (hbmRect) DeleteObject(hbmRect); - if (hbmFill) DeleteObject(hbmFill); - if (hbmIFT) DeleteObject(hbmIFT); - if (hbmNoIFT) DeleteObject(hbmNoIFT); -#endif -} - bool C4ToolsDlg::Open() { // Create dialog window -#ifdef _WIN32 - if (hDialog) return true; - hDialog = CreateDialog(Application.GetInstance(), - MAKEINTRESOURCE(IDD_TOOLS), - Console.hWindow, - (DLGPROC) ToolsDlgProc); - if (!hDialog) return false; - // Set text - SetWindowText(hDialog,LoadResStr("IDS_DLG_TOOLS")); - SetDlgItemText(hDialog,IDC_STATICMATERIAL,LoadResStr("IDS_CTL_MATERIAL")); - SetDlgItemText(hDialog,IDC_STATICTEXTURE,LoadResStr("IDS_CTL_TEXTURE")); - // Load bitmaps if necessary - LoadBitmaps(); - // create target ctx for OpenGL rendering -#ifdef USE_GL - if (lpDDraw && !pGLCtx) pGLCtx = lpDDraw->CreateContext(GetDlgItem(hDialog,IDC_PREVIEW), &Application); -#endif - // Show window - RestoreWindowPosition(hDialog, "Property", Config.GetSubkeyPath("Console")); - SetWindowPos(hDialog,Console.hWindow,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE); - ShowWindow(hDialog,SW_SHOWNOACTIVATE); -#else -#ifdef WITH_DEVELOPER_MODE - if (hbox == NULL) - { - hbox = gtk_hbox_new(false, 12); - GtkWidget* vbox = gtk_vbox_new(false, 6); - - GtkWidget* image_brush = CreateImageFromInlinedPixbuf(brush_pixbuf_data); - GtkWidget* image_line = CreateImageFromInlinedPixbuf(line_pixbuf_data); - GtkWidget* image_rect = CreateImageFromInlinedPixbuf(rect_pixbuf_data); - GtkWidget* image_fill = CreateImageFromInlinedPixbuf(fill_pixbuf_data); - GtkWidget* image_picker = CreateImageFromInlinedPixbuf(picker_pixbuf_data); - - GtkWidget* image_dynamic = CreateImageFromInlinedPixbuf(dynamic_pixbuf_data); - GtkWidget* image_static = CreateImageFromInlinedPixbuf(static_pixbuf_data); - GtkWidget* image_exact = CreateImageFromInlinedPixbuf(exact_pixbuf_data); - - GtkWidget* image_ift = CreateImageFromInlinedPixbuf(ift_pixbuf_data); - GtkWidget* image_no_ift = CreateImageFromInlinedPixbuf(no_ift_pixbuf_data); - - landscape_dynamic = gtk_toggle_button_new(); - landscape_static = gtk_toggle_button_new(); - landscape_exact = gtk_toggle_button_new(); - - gtk_container_add(GTK_CONTAINER(landscape_dynamic), image_dynamic); - gtk_container_add(GTK_CONTAINER(landscape_static), image_static); - gtk_container_add(GTK_CONTAINER(landscape_exact), image_exact); - - gtk_box_pack_start(GTK_BOX(vbox), landscape_dynamic, false, false, 0); - gtk_box_pack_start(GTK_BOX(vbox), landscape_static, false, false, 0); - gtk_box_pack_start(GTK_BOX(vbox), landscape_exact, false, false, 0); - - gtk_box_pack_start(GTK_BOX(hbox), vbox, false, false, 0); - vbox = gtk_vbox_new(false, 12); - gtk_box_pack_start(GTK_BOX(hbox), vbox, true, true, 0); - GtkWidget* local_hbox = gtk_hbox_new(false, 6); - - brush = gtk_toggle_button_new(); - line = gtk_toggle_button_new(); - rect = gtk_toggle_button_new(); - fill = gtk_toggle_button_new(); - picker = gtk_toggle_button_new(); - - gtk_container_add(GTK_CONTAINER(brush), image_brush); - gtk_container_add(GTK_CONTAINER(line), image_line); - gtk_container_add(GTK_CONTAINER(rect), image_rect); - gtk_container_add(GTK_CONTAINER(fill), image_fill); - gtk_container_add(GTK_CONTAINER(picker), image_picker); - - gtk_box_pack_start(GTK_BOX(local_hbox), brush, false, false, 0); - gtk_box_pack_start(GTK_BOX(local_hbox), line, false, false, 0); - gtk_box_pack_start(GTK_BOX(local_hbox), rect, false, false, 0); - gtk_box_pack_start(GTK_BOX(local_hbox), fill, false, false, 0); - gtk_box_pack_start(GTK_BOX(local_hbox), picker, false, false, 0); - - gtk_box_pack_start(GTK_BOX(vbox), local_hbox, false, false, 0); - local_hbox = gtk_hbox_new(false, 12); - gtk_box_pack_start(GTK_BOX(vbox), local_hbox, true, true, 0); - - preview = gtk_image_new(); - gtk_box_pack_start(GTK_BOX(local_hbox), preview, false, false, 0); - - scale = gtk_vscale_new(NULL); - gtk_box_pack_start(GTK_BOX(local_hbox), scale, false, false, 0); - - vbox = gtk_vbox_new(false, 6); - - ift = gtk_toggle_button_new(); - no_ift = gtk_toggle_button_new(); - - gtk_container_add(GTK_CONTAINER(ift), image_ift); - gtk_container_add(GTK_CONTAINER(no_ift), image_no_ift); - - gtk_box_pack_start(GTK_BOX(vbox), ift, false, false, 0); - gtk_box_pack_start(GTK_BOX(vbox), no_ift, false, false, 0); - - gtk_box_pack_start(GTK_BOX(local_hbox), vbox, false, false, 0); - - vbox = gtk_vbox_new(false, 6); - - materials = gtk_combo_box_new_text(); - textures = gtk_combo_box_new_text(); - - gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(materials), RowSeparatorFunc, NULL, NULL); - gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(textures), RowSeparatorFunc, NULL, NULL); - - gtk_box_pack_start(GTK_BOX(vbox), materials, true, false, 0); - gtk_box_pack_start(GTK_BOX(vbox), textures, true, false, 0); - - gtk_box_pack_start(GTK_BOX(local_hbox), vbox, true, true, 0); // ??? - gtk_widget_show_all(hbox); - - C4DevmodeDlg::AddPage(hbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_TOOLS")); - - //g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(OnDestroy), this); - handlerDynamic = g_signal_connect(G_OBJECT(landscape_dynamic), "toggled", G_CALLBACK(OnButtonModeDynamic), this); - handlerStatic = g_signal_connect(G_OBJECT(landscape_static), "toggled", G_CALLBACK(OnButtonModeStatic), this); - handlerExact = g_signal_connect(G_OBJECT(landscape_exact), "toggled", G_CALLBACK(OnButtonModeExact), this); - handlerBrush = g_signal_connect(G_OBJECT(brush), "toggled", G_CALLBACK(OnButtonBrush), this); - handlerLine = g_signal_connect(G_OBJECT(line), "toggled", G_CALLBACK(OnButtonLine), this); - handlerRect = g_signal_connect(G_OBJECT(rect), "toggled", G_CALLBACK(OnButtonRect), this); - handlerFill = g_signal_connect(G_OBJECT(fill), "toggled", G_CALLBACK(OnButtonFill), this); - handlerPicker = g_signal_connect(G_OBJECT(picker), "toggled", G_CALLBACK(OnButtonPicker), this); - handlerIft = g_signal_connect(G_OBJECT(ift), "toggled", G_CALLBACK(OnButtonIft), this); - handlerNoIft = g_signal_connect(G_OBJECT(no_ift), "toggled", G_CALLBACK(OnButtonNoIft), this); - handlerMaterials = g_signal_connect(G_OBJECT(materials), "changed", G_CALLBACK(OnComboMaterial), this); - handlerTextures = g_signal_connect(G_OBJECT(textures), "changed", G_CALLBACK(OnComboTexture), this); - handlerScale = g_signal_connect(G_OBJECT(scale), "value-changed", G_CALLBACK(OnGrade), this); - - handlerHide = g_signal_connect(G_OBJECT(C4DevmodeDlg::GetWindow()), "hide", G_CALLBACK(OnWindowHide), this); - } - - C4DevmodeDlg::SwitchPage(hbox); - -#endif -#endif + Console.ToolsDlgOpen(this); Active = true; // Update contols InitGradeCtrl(); @@ -411,189 +52,30 @@ bool C4ToolsDlg::Open() return true; } -void C4ToolsDlg::Default() -{ -#ifdef _WIN32 - hDialog=NULL; -#ifdef USE_GL - pGLCtx = NULL; -#endif -#else -#ifdef WITH_DEVELOPER_MODE - hbox = NULL; -#endif -#endif - Active = false; - Tool = SelectedTool = C4TLS_Brush; - Grade = C4TLS_GradeDefault; - ModeIFT = true; - SCopy("Earth",Material); - SCopy("earth",Texture); -} - -void C4ToolsDlg::Clear() -{ -#ifdef _WIN32 -#ifdef USE_GL - delete pGLCtx; pGLCtx = NULL; -#endif - if (hDialog) DestroyWindow(hDialog); hDialog=NULL; -#else -#ifdef WITH_DEVELOPER_MODE - //if(hbox != NULL) - // C4DevmodeDlg::switch_page(NULL); -#endif -#endif - Active = false; -} - bool C4ToolsDlg::SetTool(int32_t iTool, bool fTemp) { Tool=iTool; if (!fTemp) SelectedTool = Tool; UpdateToolCtrls(); - UpdatePreview(); + NeedPreviewUpdate(); return true; } -void C4ToolsDlg::UpdateToolCtrls() -{ -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETSTATE,(Tool==C4TLS_Brush),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH)); - SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETSTATE,(Tool==C4TLS_Line),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONLINE)); - SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETSTATE,(Tool==C4TLS_Rect),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONRECT)); - SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETSTATE,(Tool==C4TLS_Fill),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONFILL)); - SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETSTATE,(Tool==C4TLS_Picker),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER)); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(brush, handlerBrush); - g_signal_handler_block(line, handlerLine); - g_signal_handler_block(rect, handlerRect); - g_signal_handler_block(fill, handlerFill); - g_signal_handler_block(picker, handlerPicker); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(brush), Tool == C4TLS_Brush); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(line), Tool == C4TLS_Line); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rect), Tool == C4TLS_Rect); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fill), Tool == C4TLS_Fill); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(picker), Tool == C4TLS_Picker); - - g_signal_handler_unblock(brush, handlerBrush); - g_signal_handler_unblock(line, handlerLine); - g_signal_handler_unblock(rect, handlerRect); - g_signal_handler_unblock(fill, handlerFill); - g_signal_handler_unblock(picker, handlerPicker); -#endif -#endif -} - void C4ToolsDlg::InitMaterialCtrls() { // Materials -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOMATERIAL,CB_ADDSTRING,0,(LPARAM)C4TLS_MatSky); - for (int32_t cnt=0; cnt< ::MaterialMap.Num; cnt++) - SendDlgItemMessage(hDialog,IDC_COMBOMATERIAL,CB_ADDSTRING,0,(LPARAM)::MaterialMap.Map[cnt].Name); - SendDlgItemMessage(hDialog,IDC_COMBOMATERIAL,CB_SELECTSTRING,0,(LPARAM)Material); -#else -#ifdef WITH_DEVELOPER_MODE - GtkListStore* list = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(materials))); - - g_signal_handler_block(materials, handlerMaterials); - gtk_list_store_clear(list); - - gtk_combo_box_append_text(GTK_COMBO_BOX(materials), C4TLS_MatSky); - for (int32_t cnt = 0; cnt < ::MaterialMap.Num; cnt++) - { - gtk_combo_box_append_text(GTK_COMBO_BOX(materials), ::MaterialMap.Map[cnt].Name); - } - g_signal_handler_unblock(materials, handlerMaterials); - SelectComboBoxText(GTK_COMBO_BOX(materials), Material); -#endif -#endif + Console.ToolsDlgInitMaterialCtrls(this); // Textures UpdateTextures(); } -void C4ToolsDlg::UpdateTextures() -{ - // Refill dlg -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_RESETCONTENT,0,(LPARAM)0); -#else -#ifdef WITH_DEVELOPER_MODE - GtkListStore* list = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(textures))); - gtk_list_store_clear(list); -#endif -#endif - // bottom-most: any invalid textures - bool fAnyEntry = false; int32_t cnt; const char *szTexture; - if (::Landscape.Mode!=C4LSC_Exact) - for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) - { - if (!::TextureMap.GetIndex(Material, szTexture, false)) - { - fAnyEntry = true; -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)szTexture); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_combo_box_prepend_text(GTK_COMBO_BOX(textures), szTexture); -#endif -#endif - } - } - // separator - if (fAnyEntry) - { -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)"-------"); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_combo_box_prepend_text(GTK_COMBO_BOX(textures), "-------"); -#endif -#endif - } - - // atop: valid textures - for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++) - { - // Current material-texture valid? Always valid for exact mode - if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact) - { -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_INSERTSTRING,0,(LPARAM)szTexture); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_combo_box_prepend_text(GTK_COMBO_BOX(textures), szTexture); -#endif -#endif - } - } - // reselect current -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)Texture); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(textures, handlerTextures); - SelectComboBoxText(GTK_COMBO_BOX(textures), Texture); - g_signal_handler_unblock(textures, handlerTextures); -#endif -#endif -} - void C4ToolsDlg::SetMaterial(const char *szMaterial) { SCopy(szMaterial,Material,C4M_MaxName); AssertValidTexture(); EnableControls(); if (::Landscape.Mode==C4LSC_Static) UpdateTextures(); - UpdatePreview(); + NeedPreviewUpdate(); } void C4ToolsDlg::SetTexture(const char *szTexture) @@ -602,26 +84,18 @@ void C4ToolsDlg::SetTexture(const char *szTexture) if (!::TextureMap.GetTexture(szTexture)) { // ensure correct texture is in dlg -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)Texture); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(textures, handlerTextures); - SelectComboBoxText(GTK_COMBO_BOX(textures), Texture); - g_signal_handler_unblock(textures, handlerTextures); -#endif -#endif + Console.ToolsDlgSetTexture(this, szTexture); return; } SCopy(szTexture,Texture,C4M_MaxName); - UpdatePreview(); + NeedPreviewUpdate(); } bool C4ToolsDlg::SetIFT(bool fIFT) { if (fIFT) ModeIFT = 1; else ModeIFT=0; UpdateIFTControls(); - UpdatePreview(); + NeedPreviewUpdate(); return true; } @@ -629,258 +103,21 @@ void C4ToolsDlg::SetColorPattern(const char *szMaterial, const char *szTexture) { } -void C4ToolsDlg::UpdatePreview() -{ -#ifdef _WIN32 - if (!hDialog) return; -#else -#ifdef WITH_DEVELOPER_MODE - if (!hbox) return; -#endif -#endif - - SURFACE sfcPreview; - - int32_t iPrvWdt,iPrvHgt; - - RECT rect; -#ifdef _WIN32 - GetClientRect(GetDlgItem(hDialog,IDC_PREVIEW),&rect); -#else - /* TODO: Set size request for image to read size from image's size request? */ - rect.left = 0; - rect.top = 0; - rect.bottom = 64; - rect.right = 64; -#endif - - iPrvWdt=rect.right-rect.left; - iPrvHgt=rect.bottom-rect.top; - - if (!(sfcPreview=new CSurface(iPrvWdt,iPrvHgt))) return; - - // fill bg -#ifdef _WIN32 - lpDDraw->DrawBoxDw(sfcPreview,0,0,iPrvWdt-1,iPrvHgt-1,C4RGB(0x80,0x80,0x80)); -#endif - BYTE bCol = 0; - CPattern Pattern; - // Sky material: sky as pattern only - if (SEqual(Material,C4TLS_MatSky)) - { - Pattern.Set(::Landscape.Sky.Surface, 0); - } - // Material-Texture - else - { - bCol=Mat2PixColDefault(::MaterialMap.Get(Material)); - // Get/Create TexMap entry - BYTE iTex = ::TextureMap.GetIndex(Material, Texture, true); - if (iTex) - { - // Define texture pattern - const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex); - // Security - if (pTex) - { - // Set drawing pattern - Pattern = pTex->GetPattern(); - } - } - } -#ifdef _WIN32 - if (IsWindowEnabled(GetDlgItem(hDialog,IDC_PREVIEW))) -#else -#ifdef WITH_DEVELOPER_MODE -#if GTK_CHECK_VERSION(2,18,0) - if (gtk_widget_is_sensitive(preview)) -#else - if (GTK_WIDGET_SENSITIVE(preview)) -#endif -#endif -#endif - lpDDraw->DrawPatternedCircle( sfcPreview, - iPrvWdt/2,iPrvHgt/2, - Grade, - bCol, Pattern, *::Landscape.GetPal()); - -#ifdef _WIN32 -#ifdef USE_DIRECTX - if (pD3D) - pD3D->BlitSurface2Window( sfcPreview, - 0,0,iPrvWdt,iPrvHgt, - GetDlgItem(hDialog,IDC_PREVIEW), - rect.left,rect.top,rect.right,rect.bottom); -#endif -#ifdef USE_GL - if (pGL && pGLCtx) - { - // FIXME: This activates the wrong GL context. To avoid breaking the main window display, - // FIXME: it has been disabled for the moment - //if (pGLCtx->Select()) - //{ - // pGL->Blit(sfcPreview, 0,0,(float)iPrvWdt,(float)iPrvHgt, Application.pWindow->pSurface, rect.left,rect.top, iPrvWdt,iPrvHgt); - // Application.pWindow->pSurface->PageFlip(); - //} - } -#endif -#else -#ifdef WITH_DEVELOPER_MODE - // TODO: Can we optimize this? - GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, 64, 64); - guchar* data = gdk_pixbuf_get_pixels(pixbuf); - sfcPreview->Lock(); - for (int x = 0; x < 64; ++ x) for (int y = 0; y < 64; ++ y) - { - DWORD dw = sfcPreview->GetPixDw(x, y, true); - *data = (dw >> 16) & 0xff; ++ data; - *data = (dw >> 8 ) & 0xff; ++ data; - *data = (dw ) & 0xff; ++ data; - *data = 0xff - ((dw >> 24) & 0xff); ++ data; - } - - sfcPreview->Unlock(); - gtk_image_set_from_pixbuf(GTK_IMAGE(preview), pixbuf); - gdk_pixbuf_unref(pixbuf); -#endif -#endif - delete sfcPreview; -} - -void C4ToolsDlg::InitGradeCtrl() -{ -#ifdef _WIN32 - if (!hDialog) return; - HWND hwndTrack = GetDlgItem(hDialog,IDC_SLIDERGRADE); - SendMessage(hwndTrack,TBM_SETPAGESIZE,0,(LPARAM)5); - SendMessage(hwndTrack,TBM_SETLINESIZE,0,(LPARAM)1); - SendMessage(hwndTrack,TBM_SETRANGE,(WPARAM)false, - (LPARAM) MAKELONG(C4TLS_GradeMin,C4TLS_GradeMax)); - SendMessage(hwndTrack,TBM_SETPOS,(WPARAM)true,(LPARAM)C4TLS_GradeMax-Grade); - UpdateWindow(hwndTrack); -#else -#ifdef WITH_DEVELOPER_MODE - if (!hbox) return; - g_signal_handler_block(scale, handlerScale); - gtk_range_set_increments(GTK_RANGE(scale), 1, 5); - gtk_range_set_range(GTK_RANGE(scale), C4TLS_GradeMin, C4TLS_GradeMax); - gtk_scale_set_draw_value(GTK_SCALE(scale), false); - gtk_range_set_value(GTK_RANGE(scale), C4TLS_GradeMax-Grade); - g_signal_handler_unblock(scale, handlerScale); -#endif -#endif -} - bool C4ToolsDlg::SetGrade(int32_t iGrade) { Grade = BoundBy(iGrade,C4TLS_GradeMin,C4TLS_GradeMax); - UpdatePreview(); + NeedPreviewUpdate(); return true; } bool C4ToolsDlg::ChangeGrade(int32_t iChange) { Grade = BoundBy(Grade+iChange,C4TLS_GradeMin,C4TLS_GradeMax); - UpdatePreview(); + NeedPreviewUpdate(); InitGradeCtrl(); return true; } -bool C4ToolsDlg::PopMaterial() -{ -#ifdef _WIN32 - if (!hDialog) return false; - SetFocus(GetDlgItem(hDialog,IDC_COMBOMATERIAL)); - SendDlgItemMessage(hDialog,IDC_COMBOMATERIAL,CB_SHOWDROPDOWN,true,0); -#else -#ifdef WITH_DEVELOPER_MODE - if (!hbox) return false; - gtk_widget_grab_focus(materials); - gtk_combo_box_popup(GTK_COMBO_BOX(materials)); -#endif -#endif - return true; -} - -bool C4ToolsDlg::PopTextures() -{ -#ifdef _WIN32 - if (!hDialog) return false; - SetFocus(GetDlgItem(hDialog,IDC_COMBOTEXTURE)); - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_SHOWDROPDOWN,true,0); -#else -#ifdef WITH_DEVELOPER_MODE - if (!hbox) return false; - gtk_widget_grab_focus(textures); - gtk_combo_box_popup(GTK_COMBO_BOX(textures)); -#endif -#endif - return true; -} - -void C4ToolsDlg::UpdateIFTControls() -{ -#ifdef _WIN32 - if (!hDialog) return; - SendDlgItemMessage(hDialog,IDC_BUTTONNOIFT,BM_SETSTATE,(ModeIFT==0),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONNOIFT)); - SendDlgItemMessage(hDialog,IDC_BUTTONIFT,BM_SETSTATE,(ModeIFT==1),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONIFT)); -#else -#ifdef WITH_DEVELOPER_MODE - if (!hbox) return; - g_signal_handler_block(no_ift, handlerNoIft); - g_signal_handler_block(ift, handlerIft); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(no_ift), ModeIFT==0); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ift), ModeIFT==1); - - g_signal_handler_unblock(no_ift, handlerNoIft); - g_signal_handler_unblock(ift, handlerIft); -#endif -#endif -} - -void C4ToolsDlg::UpdateLandscapeModeCtrls() -{ - int32_t iMode = ::Landscape.Mode; -#ifdef _WIN32 - // Dynamic: enable only if dynamic anyway - SendDlgItemMessage(hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETSTATE,(iMode==C4LSC_Dynamic),0); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONMODEDYNAMIC),(iMode==C4LSC_Dynamic)); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONMODEDYNAMIC)); - // Static: enable only if map available - SendDlgItemMessage(hDialog,IDC_BUTTONMODESTATIC,BM_SETSTATE,(iMode==C4LSC_Static),0); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONMODESTATIC),(::Landscape.Map!=NULL)); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONMODESTATIC)); - // Exact: enable always - SendDlgItemMessage(hDialog,IDC_BUTTONMODEEXACT,BM_SETSTATE,(iMode==C4LSC_Exact),0); - UpdateWindow(GetDlgItem(hDialog,IDC_BUTTONMODEEXACT)); - // Set dialog caption - SetWindowText(hDialog,LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT")); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(landscape_dynamic, handlerDynamic); - g_signal_handler_block(landscape_static, handlerStatic); - g_signal_handler_block(landscape_exact, handlerExact); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_dynamic), iMode==C4LSC_Dynamic); - gtk_widget_set_sensitive(landscape_dynamic, iMode==C4LSC_Dynamic); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_static), iMode==C4LSC_Static); - gtk_widget_set_sensitive(landscape_static, ::Landscape.Map!=NULL); - - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(landscape_exact), iMode==C4LSC_Exact); - - g_signal_handler_unblock(landscape_dynamic, handlerDynamic); - g_signal_handler_unblock(landscape_static, handlerStatic); - g_signal_handler_unblock(landscape_exact, handlerExact); - - C4DevmodeDlg::SetTitle(hbox, LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT")); -#endif -#endif -} - bool C4ToolsDlg::SetLandscapeMode(int32_t iMode, bool fThroughControl) { int32_t iLastMode=::Landscape.Mode; @@ -916,72 +153,10 @@ bool C4ToolsDlg::SetLandscapeMode(int32_t iMode, bool fThroughControl) void C4ToolsDlg::EnableControls() { - int32_t iLandscapeMode=::Landscape.Mode; -#ifdef _WIN32 - // Set bitmap buttons - SendDlgItemMessage(hDialog,IDC_BUTTONBRUSH,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? hbmBrush : hbmBrush2)); - SendDlgItemMessage(hDialog,IDC_BUTTONLINE,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? hbmLine : hbmLine2)); - SendDlgItemMessage(hDialog,IDC_BUTTONRECT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? hbmRect : hbmRect2)); - SendDlgItemMessage(hDialog,IDC_BUTTONFILL,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Exact) ? hbmFill : hbmFill2)); - SendDlgItemMessage(hDialog,IDC_BUTTONPICKER,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)((iLandscapeMode>=C4LSC_Static) ? hbmPicker : hbmPicker2)); - SendDlgItemMessage(hDialog,IDC_BUTTONIFT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbmIFT); - SendDlgItemMessage(hDialog,IDC_BUTTONNOIFT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbmNoIFT); - SendDlgItemMessage(hDialog,IDC_BUTTONMODEDYNAMIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbmDynamic); - SendDlgItemMessage(hDialog,IDC_BUTTONMODESTATIC,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbmStatic); - SendDlgItemMessage(hDialog,IDC_BUTTONMODEEXACT,BM_SETIMAGE,IMAGE_BITMAP,(LPARAM)hbmExact); - // Enable drawing controls - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONBRUSH),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONLINE),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONRECT),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONFILL),(iLandscapeMode>=C4LSC_Exact)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONPICKER),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONIFT),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_BUTTONNOIFT),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_COMBOMATERIAL),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_COMBOTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(Material,C4TLS_MatSky)); - EnableWindow(GetDlgItem(hDialog,IDC_STATICMATERIAL),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_STATICTEXTURE),(iLandscapeMode>=C4LSC_Static) && !SEqual(Material,C4TLS_MatSky)); - EnableWindow(GetDlgItem(hDialog,IDC_SLIDERGRADE),(iLandscapeMode>=C4LSC_Static)); - EnableWindow(GetDlgItem(hDialog,IDC_PREVIEW),(iLandscapeMode>=C4LSC_Static)); -#else -#ifdef WITH_DEVELOPER_MODE - gtk_widget_set_sensitive(brush, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(line, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(rect, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(fill, iLandscapeMode>=C4LSC_Exact); - gtk_widget_set_sensitive(picker, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(ift, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(no_ift, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(materials, (iLandscapeMode>=C4LSC_Static)); - gtk_widget_set_sensitive(textures, iLandscapeMode >= C4LSC_Static && !SEqual(Material,C4TLS_MatSky)); - gtk_widget_set_sensitive(scale, iLandscapeMode>=C4LSC_Static); - gtk_widget_set_sensitive(preview, iLandscapeMode>=C4LSC_Static); -#endif // WITH_DEVELOPER_MODE -#endif // _WIN32 - UpdatePreview(); + Console.ToolsDlgEnableControls(this); + NeedPreviewUpdate(); } -#ifdef _WIN32 -void C4ToolsDlg::LoadBitmaps() -{ - HINSTANCE hInst = Application.GetInstance(); - if (!hbmBrush) hbmBrush=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BRUSH)); - if (!hbmLine) hbmLine=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_LINE)); - if (!hbmRect) hbmRect=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_RECT)); - if (!hbmFill) hbmFill=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_FILL)); - if (!hbmPicker) hbmPicker=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_PICKER)); - if (!hbmBrush2) hbmBrush2=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BRUSH2)); - if (!hbmLine2) hbmLine2=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_LINE2)); - if (!hbmRect2) hbmRect2=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_RECT2)); - if (!hbmFill2) hbmFill2=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_FILL2)); - if (!hbmPicker2) hbmPicker2=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_PICKER2)); - if (!hbmIFT) hbmIFT=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_IFT)); - if (!hbmNoIFT) hbmNoIFT=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_NOIFT)); - if (!hbmDynamic) hbmDynamic=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_DYNAMIC)); - if (!hbmStatic) hbmStatic=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_STATIC)); - if (!hbmExact) hbmExact=(HBITMAP)LoadBitmap(hInst,MAKEINTRESOURCE(IDB_EXACT)); -} -#endif void C4ToolsDlg::AssertValidTexture() { // Static map mode only @@ -1002,30 +177,14 @@ void C4ToolsDlg::AssertValidTexture() bool C4ToolsDlg::SelectTexture(const char *szTexture) { -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOTEXTURE,CB_SELECTSTRING,0,(LPARAM)szTexture); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(textures, handlerTextures); - SelectComboBoxText(GTK_COMBO_BOX(textures), szTexture); - g_signal_handler_unblock(textures, handlerTextures); -#endif -#endif + Console.ToolsDlgSelectTexture(this, szTexture); SetTexture(szTexture); return true; } bool C4ToolsDlg::SelectMaterial(const char *szMaterial) { -#ifdef _WIN32 - SendDlgItemMessage(hDialog,IDC_COMBOMATERIAL,CB_SELECTSTRING,0,(LPARAM)szMaterial); -#else -#ifdef WITH_DEVELOPER_MODE - g_signal_handler_block(materials, handlerMaterials); - SelectComboBoxText(GTK_COMBO_BOX(materials), szMaterial); - g_signal_handler_unblock(materials, handlerMaterials); -#endif -#endif + Console.ToolsDlgSetMaterial(this, szMaterial); SetMaterial(szMaterial); return true; } @@ -1041,88 +200,3 @@ void C4ToolsDlg::ResetAlternateTool() // reset tool to selected tool in case alternate tool was set SetTool(SelectedTool, true); } - -#ifdef WITH_DEVELOPER_MODE -// GTK+ callbacks -/*void C4ToolsDlg::OnDestroy(GtkWidget* widget, gpointer data) -{ - static_cast(data)->window = NULL; - static_cast(data)->Active = false; -}*/ - -void C4ToolsDlg::OnButtonModeDynamic(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetLandscapeMode(C4LSC_Dynamic); -} - -void C4ToolsDlg::OnButtonModeStatic(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetLandscapeMode(C4LSC_Static); -} - -void C4ToolsDlg::OnButtonModeExact(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetLandscapeMode(C4LSC_Exact); -} - -void C4ToolsDlg::OnButtonBrush(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetTool(C4TLS_Brush, false); -} - -void C4ToolsDlg::OnButtonLine(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetTool(C4TLS_Line, false); -} - -void C4ToolsDlg::OnButtonRect(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetTool(C4TLS_Rect, false); -} - -void C4ToolsDlg::OnButtonFill(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetTool(C4TLS_Fill, false); -} - -void C4ToolsDlg::OnButtonPicker(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetTool(C4TLS_Picker, false); -} - -void C4ToolsDlg::OnButtonIft(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetIFT(true); -} - -void C4ToolsDlg::OnButtonNoIft(GtkWidget* widget, gpointer data) -{ - static_cast(data)->SetIFT(false); -} - -void C4ToolsDlg::OnComboMaterial(GtkWidget* widget, gpointer data) -{ - gchar* text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); - static_cast(data)->SetMaterial(text); - g_free(text); -} - -void C4ToolsDlg::OnComboTexture(GtkWidget* widget, gpointer data) -{ - gchar* text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); - static_cast(data)->SetTexture(text); - g_free(text); -} - -void C4ToolsDlg::OnGrade(GtkWidget* widget, gpointer data) -{ - C4ToolsDlg* dlg = static_cast(data); - int value = static_cast(gtk_range_get_value(GTK_RANGE(dlg->scale)) + 0.5); - dlg->SetGrade(C4TLS_GradeMax-value); -} - -void C4ToolsDlg::OnWindowHide(GtkWidget* widget, gpointer data) -{ - static_cast(data)->Active = false; -} -#endif diff --git a/src/editor/C4ToolsDlg.h b/src/editor/C4ToolsDlg.h index 0288751a6..86f0c7df2 100644 --- a/src/editor/C4ToolsDlg.h +++ b/src/editor/C4ToolsDlg.h @@ -29,118 +29,45 @@ #endif #include "C4Constants.h" +#include "C4ConsoleGUI.h" -const int32_t C4TLS_Brush = 0, - C4TLS_Line = 1, - C4TLS_Rect = 2, - C4TLS_Fill = 3, - C4TLS_Picker = 4; +const int32_t + C4TLS_Brush = 0, + C4TLS_Line = 1, + C4TLS_Rect = 2, + C4TLS_Fill = 3, + C4TLS_Picker = 4; -const int32_t C4TLS_GradeMax = 50, - C4TLS_GradeMin = 1, - C4TLS_GradeDefault = 5; +const int32_t + C4TLS_GradeMax = 50, + C4TLS_GradeMin = 1, + C4TLS_GradeDefault = 5; #define C4TLS_MatSky "Sky" class C4ToolsDlg { -#ifdef _WIN32 - friend INT_PTR CALLBACK ToolsDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); -#endif + friend class C4ConsoleGUI; + private: + class State; + State *state; public: C4ToolsDlg(); ~C4ToolsDlg(); public: bool Active; -#ifdef _WIN32 - HWND hDialog; -#ifdef USE_GL - class CStdGLCtx *pGLCtx; // rendering context for OpenGL -#endif -#else -#ifdef WITH_DEVELOPER_MODE - GtkWidget* hbox; - - GtkWidget* brush; - GtkWidget* line; - GtkWidget* rect; - GtkWidget* fill; - GtkWidget* picker; - - GtkWidget* landscape_dynamic; - GtkWidget* landscape_static; - GtkWidget* landscape_exact; - - GtkWidget* preview; - GtkWidget* scale; - - GtkWidget* ift; - GtkWidget* no_ift; - - GtkWidget* materials; - GtkWidget* textures; - - gulong handlerBrush; - gulong handlerLine; - gulong handlerRect; - gulong handlerFill; - gulong handlerPicker; - - gulong handlerDynamic; - gulong handlerStatic; - gulong handlerExact; - - gulong handlerIft; - gulong handlerNoIft; - - gulong handlerMaterials; - gulong handlerTextures; - gulong handlerScale; - - gulong handlerHide; - - //static void OnDestroy(GtkWidget* widget, gpointer data); - static void OnButtonModeDynamic(GtkWidget* widget, gpointer data); - static void OnButtonModeStatic(GtkWidget* widget, gpointer data); - static void OnButtonModeExact(GtkWidget* widget, gpointer data); - static void OnButtonBrush(GtkWidget* widget, gpointer data); - static void OnButtonLine(GtkWidget* widget, gpointer data); - static void OnButtonRect(GtkWidget* widget, gpointer data); - static void OnButtonFill(GtkWidget* widget, gpointer data); - static void OnButtonPicker(GtkWidget* widget, gpointer data); - static void OnButtonIft(GtkWidget* widget, gpointer data); - static void OnButtonNoIft(GtkWidget* widget, gpointer data); - static void OnComboMaterial(GtkWidget* widget, gpointer data); - static void OnComboTexture(GtkWidget* widget, gpointer data); - static void OnGrade(GtkWidget* widget, gpointer data); - static void OnWindowHide(GtkWidget* widget, gpointer data); -#endif -#endif int32_t Tool, SelectedTool; int32_t Grade; bool ModeIFT; char Material[C4M_MaxName+1]; char Texture[C4M_MaxName+1]; -protected: -#ifdef _WIN32 - HBITMAP hbmBrush,hbmBrush2; - HBITMAP hbmLine,hbmLine2; - HBITMAP hbmRect,hbmRect2; - HBITMAP hbmFill,hbmFill2; - HBITMAP hbmPicker,hbmPicker2; - HBITMAP hbmIFT; - HBITMAP hbmNoIFT; - HBITMAP hbmDynamic; - HBITMAP hbmStatic; - HBITMAP hbmExact; -#endif public: void Default(); void Clear(); bool PopTextures(); bool PopMaterial(); bool ChangeGrade(int32_t iChange); - void UpdatePreview(); + void NeedPreviewUpdate(); bool Open(); bool SetGrade(int32_t iGrade); bool SetTool(int32_t iTool, bool fTemp); diff --git a/src/gui/C4Gui.h b/src/gui/C4Gui.h index 0ad6b7adf..a5d1b5446 100644 --- a/src/gui/C4Gui.h +++ b/src/gui/C4Gui.h @@ -414,6 +414,7 @@ namespace C4GUI virtual bool IsOwnPtrElement() { return false; } // if true is returned, item will not be deleted when container is cleared virtual bool IsExternalDrawDialog() { return false; } virtual bool IsMenu() { return false; } + virtual class DialogWindow* GetDialogWindow() { return NULL; } // return DialogWindow if this element is a dialog // for listbox-selection by character input virtual bool CheckNameHotkey(const char * c) { return false; } @@ -1937,16 +1938,21 @@ namespace C4GUI friend class ComboBox_FillCB; }; + class Dialog; + // EM window class class DialogWindow : public CStdWindow { public: + Dialog* pDialog; + DialogWindow(): CStdWindow(), pDialog(NULL) {} using CStdWindow::Init; - CStdWindow * Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID); + CStdWindow * Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID); virtual void Close(); -#if defined(USE_X11) +#ifdef USE_X11 virtual void HandleMessage (XEvent &); #endif + virtual void PerformUpdate(); }; // information on how to draw dialog borders and face @@ -1978,7 +1984,7 @@ namespace C4GUI }; // a dialog - class Dialog : public Window + class Dialog: public Window { private: enum Fade { eFadeNone=0, eFadeOut, eFadeIn }; @@ -2024,6 +2030,7 @@ namespace C4GUI void SetFocus(Control *pCtrl, bool fByMouse); Control *GetFocus() { return pActiveCtrl; } virtual Dialog *GetDlg() { return this; } // this is the dialog + virtual DialogWindow* GetDialogWindow() { return pWindow; } virtual bool CharIn(const char * c); // input: character key pressed - should return false for none-character-inputs (forward to focused control) virtual void MouseInput(CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam); // input: mouse. forwards to child controls diff --git a/src/gui/C4GuiDialogs.cpp b/src/gui/C4GuiDialogs.cpp index 5e2668fde..bf87fdb39 100644 --- a/src/gui/C4GuiDialogs.cpp +++ b/src/gui/C4GuiDialogs.cpp @@ -41,6 +41,7 @@ #ifdef _WIN32 #include "resource.h" #endif + #ifdef USE_X11 #define None Die_XLib_Die #include @@ -190,7 +191,7 @@ namespace C4GUI // DialogWindow #ifdef _WIN32 - CStdWindow * DialogWindow::Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID) + CStdWindow * DialogWindow::Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID) { Active = true; // calculate required size @@ -311,18 +312,21 @@ namespace C4GUI return !!RegisterClassEx(&WndClass); } #else - CStdWindow * DialogWindow::Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID) + CStdWindow * DialogWindow::Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, const C4Rect &rcBounds, const char *szID) { - if (CStdWindow::Init(pApp, Title, pParent, false)) + CStdWindow *result; + if (CStdWindow::Init(windowKind, pApp, Title, pParent, false)) { // update pos if (szID && *szID) RestorePosition(FormatString("ConsoleGUI_%s", szID).getData(), Config.GetSubkeyPath("Console"), false); else SetSize(rcBounds.Wdt, rcBounds.Hgt); - return this; + result = this; } - return NULL; + else + result = NULL; + return result; } #ifdef USE_X11 void DialogWindow::HandleMessage (XEvent &e) @@ -427,6 +431,26 @@ namespace C4GUI #endif #endif // _WIN32 + void DialogWindow::PerformUpdate() + { + if (!pDialog) + return; // safety + RECT r; + GetSize(&r); + if (pSurface) + { + pSurface->Wdt = r.right; + pSurface->Hgt = r.bottom; +#ifdef USE_GL + pGL->PrepareRendering(pSurface); + glClear(GL_COLOR_BUFFER_BIT); +#endif + } + C4TargetFacet cgo; + cgo.Set(NULL, 0, 0, r.right, r.bottom, 0, 0); + pDialog->Draw(cgo); + } + void DialogWindow::Close() { // FIXME: Close the dialog of this window @@ -440,7 +464,7 @@ namespace C4GUI if (pWindow) return true; // create it! pWindow = new DialogWindow(); - if (!pWindow->Init(&Application, TitleString.getData(), &Console, rcBounds, GetID())) + if (!pWindow->Init(CStdWindow::W_GuiWindow, &Application, TitleString.getData(), &Console, rcBounds, GetID())) { delete pWindow; pWindow = NULL; @@ -448,6 +472,7 @@ namespace C4GUI } // create rendering context pWindow->pSurface = new CSurface(&Application, pWindow); + pWindow->pDialog = this; return true; } diff --git a/src/gui/C4Viewport.cpp b/src/gui/C4Viewport.cpp index d88b39777..3801eb2b0 100644 --- a/src/gui/C4Viewport.cpp +++ b/src/gui/C4Viewport.cpp @@ -50,6 +50,7 @@ namespace #ifdef _WIN32 #include + bool C4Viewport::DropFiles(HANDLE hDrop) { if (!Console.Editing) { Console.Message(LoadResStr("IDS_CNS_NONETEDIT")); return false; } @@ -771,7 +772,10 @@ void C4ViewportList::Execute(bool DrawBackground) if (DrawBackground) DrawFullscreenBackground(); for (C4Viewport *cvp=FirstViewport; cvp; cvp=cvp->Next) - cvp->Execute(); + { + if (cvp->GetWindow()) + cvp->GetWindow()->RequestUpdate(); + } } void C4ViewportList::DrawFullscreenBackground() diff --git a/src/gui/C4Viewport.h b/src/gui/C4Viewport.h index 0d6c66b47..8865b3464 100644 --- a/src/gui/C4Viewport.h +++ b/src/gui/C4Viewport.h @@ -94,6 +94,8 @@ protected: void DrawPlayerInfo(C4TargetFacet &cgo); void BlitOutput(); void AdjustPosition(); +public: + C4ViewportWindow* GetWindow() {return pWindow;} bool UpdateOutputSize(); bool ViewPositionByScrollBars(); bool ScrollBarsByViewPosition(); diff --git a/src/platform/C4SoundSystem.cpp b/src/platform/C4SoundSystem.cpp index 5d58a39f8..d75389c7a 100644 --- a/src/platform/C4SoundSystem.cpp +++ b/src/platform/C4SoundSystem.cpp @@ -116,7 +116,7 @@ bool C4SoundEffect::Load(BYTE *pData, size_t iDataLen, bool fStatic, bool fRaw) // Set usage time UsageTime=Game.Time; Static=fStatic; - return pSample; + return !!pSample; } void C4SoundEffect::Execute() diff --git a/src/platform/C4ViewportWindow.cpp b/src/platform/C4ViewportWindow.cpp index e20b74c83..58a957e84 100644 --- a/src/platform/C4ViewportWindow.cpp +++ b/src/platform/C4ViewportWindow.cpp @@ -148,10 +148,7 @@ LRESULT APIENTRY ViewportWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa // posts a new WM_ACTIVATE to us, and so on, ultimately leading to a hang. if (LOWORD(wParam) == WA_INACTIVE) { - if (Console.PropertyDlg.hDialog) - SetWindowLongPtr(Console.PropertyDlg.hDialog, GWLP_HWNDPARENT, reinterpret_cast(Console.hWindow)); - if (Console.ToolsDlg.hDialog) - SetWindowLongPtr(Console.PropertyDlg.hDialog, GWLP_HWNDPARENT, reinterpret_cast(Console.hWindow)); + Console.Win32KeepDialogsFloating(); } else { @@ -159,10 +156,7 @@ LRESULT APIENTRY ViewportWinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPa case WM_MOUSEACTIVATE: // WM_MOUSEACTIVATE is emitted when the user hovers over a window and pushes a mouse button. // Setting the window owner here avoids z-order flickering. - if (Console.PropertyDlg.hDialog) - SetWindowLongPtr(Console.PropertyDlg.hDialog, GWLP_HWNDPARENT, reinterpret_cast(hwnd)); - if (Console.ToolsDlg.hDialog) - SetWindowLongPtr(Console.ToolsDlg.hDialog, GWLP_HWNDPARENT, reinterpret_cast(hwnd)); + Console.Win32KeepDialogsFloating(hwnd); } break; //---------------------------------------------------------------------------------------------------------------------------------- @@ -250,7 +244,7 @@ bool C4ViewportWindow::RegisterViewportClass(HINSTANCE hInst) return fViewportClassRegistered = C4GUI::Dialog::RegisterWindowClass(hInst); } -CStdWindow * C4ViewportWindow::Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, bool) +CStdWindow * C4ViewportWindow::Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, bool) { Active = true; // Create window @@ -665,10 +659,12 @@ void C4ViewportWindow::OnHScrollStatic(GtkAdjustment* adjustment, gpointer user_ static_cast(user_data)->cvp->ViewPositionByScrollBars(); } -#else // WITH_DEVELOPER_MODE +#endif // WITH_DEVELOPER_MODE + +#if defined(USE_X11) && !defined(WITH_DEVELOPER_MODE) bool C4Viewport::TogglePlayerLock() { return false; } bool C4Viewport::ScrollBarsByViewPosition() { return false; } -#if defined(USE_X11) + void C4ViewportWindow::HandleMessage (XEvent & e) { switch (e.type) @@ -800,7 +796,15 @@ void C4ViewportWindow::HandleMessage (XEvent & e) } } #endif // USE_X11 -#endif // WITH_DEVELOPER_MODE/_WIN32 + +void C4ViewportWindow::PerformUpdate() +{ + if (cvp) + { + cvp->UpdateOutputSize(); + cvp->Execute(); + } +} void C4ViewportWindow::Close() { diff --git a/src/platform/C4ViewportWindow.h b/src/platform/C4ViewportWindow.h index aac042d1f..afa3043bf 100644 --- a/src/platform/C4ViewportWindow.h +++ b/src/platform/C4ViewportWindow.h @@ -41,7 +41,7 @@ public: C4Viewport * cvp; C4ViewportWindow(C4Viewport * cvp): cvp(cvp) { } #ifdef _WIN32 - virtual CStdWindow * Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, bool); + virtual CStdWindow * Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, bool); static bool RegisterViewportClass(HINSTANCE hInst); #elif defined(WITH_DEVELOPER_MODE) virtual GtkWidget* InitGUI(); @@ -70,6 +70,7 @@ public: #endif void EditCursorMove(int X, int Y, uint16_t); virtual void Close(); + virtual void PerformUpdate(); }; #define C4ViewportClassName "C4Viewport" diff --git a/src/platform/StdAppCommon.cpp b/src/platform/StdAppCommon.cpp new file mode 100644 index 000000000..dbdf3bccd --- /dev/null +++ b/src/platform/StdAppCommon.cpp @@ -0,0 +1,40 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +#include +#include "StdAppCommon.h" + +void CStdApp::Run() +{ + // Main message loop + while (!fQuitMsgReceived) + ScheduleProcs(); +} + +bool CStdApp::ScheduleProcs(int iTimeout) +{ + // Always fail after quit message + if(fQuitMsgReceived) + return false; +#if defined(USE_SDL_MAINLOOP) + // Unfortunately, the SDL event loop needs to be polled + FlushMessages(); +#endif + return StdScheduler::ScheduleProcs(iTimeout); +} + +void CStdWindow::PerformUpdate() +{ +} \ No newline at end of file diff --git a/src/platform/StdAppCommon.h b/src/platform/StdAppCommon.h new file mode 100644 index 000000000..7c2e7879d --- /dev/null +++ b/src/platform/StdAppCommon.h @@ -0,0 +1,16 @@ +/* + * OpenClonk, http://www.openclonk.org + * + * Portions might be copyrighted by other authors who have contributed + * to OpenClonk. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * See isc_license.txt for full license and disclaimer. + * + * "Clonk" is a registered trademark of Matthes Bender. + * See clonk_trademark_license.txt for full license. + */ + +#include \ No newline at end of file diff --git a/src/platform/StdGtkWindow.cpp b/src/platform/StdGtkWindow.cpp index 24922ef4e..961bc1233 100644 --- a/src/platform/StdGtkWindow.cpp +++ b/src/platform/StdGtkWindow.cpp @@ -205,3 +205,9 @@ GtkWidget* CStdGtkWindow::InitGUI() { return window; } + +void CStdWindow::RequestUpdate() +{ + // just invoke directly + PerformUpdate(); +} diff --git a/src/platform/StdWindow.cpp b/src/platform/StdWindow.cpp index bc1ed6e68..81ebe9520 100644 --- a/src/platform/StdWindow.cpp +++ b/src/platform/StdWindow.cpp @@ -483,3 +483,9 @@ bool CStdApp::IsClipboardFull(bool fClipboard) void CStdApp::ClearClipboard(bool fClipboard) { } + +void CStdWindow::RequestUpdate() +{ + // just invoke directly + PerformUpdate(); +} \ No newline at end of file diff --git a/src/platform/StdWindow.h b/src/platform/StdWindow.h index 47fd4988b..dbd6fb0a4 100644 --- a/src/platform/StdWindow.h +++ b/src/platform/StdWindow.h @@ -240,6 +240,13 @@ typedef struct _XDisplay Display; class CStdWindow { +public: + enum WindowKind + { + W_GuiWindow, + W_Viewport, + W_Fullscreen + }; public: CStdWindow (); virtual ~CStdWindow (); @@ -253,7 +260,7 @@ public: virtual void CharIn(const char * c) { } virtual CStdWindow * Init(CStdApp * pApp); #ifndef _WIN32 - virtual CStdWindow * Init(CStdApp * pApp, const char * Title, CStdWindow * pParent = 0, bool HideCursor = true); + virtual CStdWindow * Init(WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent = 0, bool HideCursor = true); #endif bool StorePosition(const char *szWindowName, const char *szSubKey, bool fStoreSize = true); bool RestorePosition(const char *szWindowName, const char *szSubKey, bool fHidden = false); @@ -261,7 +268,7 @@ public: void SetSize(unsigned int cx, unsigned int cy); // resize void SetTitle(const char * Title); void FlashWindow(); -protected: + #ifdef _WIN32 public: HWND hWindow; @@ -287,6 +294,12 @@ private: protected: virtual void HandleMessage(SDL_Event&) {} #endif +public: + // request that this window be redrawn in the near future (including immediately) + virtual void RequestUpdate(); + // Invokes actual drawing code - should not be called directly + virtual void PerformUpdate(); +public: friend class CStdDDraw; friend class CStdGL; friend class CStdGLCtx; @@ -375,28 +388,13 @@ public: virtual void Clear(); bool Init(int argc, char * argv[]); - void Run() - { - // Main message loop - while (!fQuitMsgReceived) - ScheduleProcs(); - } + void Run(); virtual void Quit(); bool GetIndexedDisplayMode(int32_t iIndex, int32_t *piXRes, int32_t *piYRes, int32_t *piBitDepth, uint32_t iMonitor); bool SetVideoMode(unsigned int iXRes, unsigned int iYRes, unsigned int iColorDepth, unsigned int iMonitor, bool fFullScreen); void RestoreVideoMode(); - bool ScheduleProcs(int iTimeout = -1) - { - // Always fail after quit message - if (fQuitMsgReceived) - return false; -#if defined(USE_SDL_MAINLOOP) - // Unfortunately, the SDL event loop needs to be polled - FlushMessages(); -#endif - return StdScheduler::ScheduleProcs(iTimeout); - } + bool ScheduleProcs(int iTimeout = -1); bool FlushMessages(); CStdWindow * pWindow; bool fQuitMsgReceived; // if true, a quit message has been received and the application should terminate diff --git a/src/platform/StdXWindow.cpp b/src/platform/StdXWindow.cpp index 9c5977b2f..77a2a3d1c 100644 --- a/src/platform/StdXWindow.cpp +++ b/src/platform/StdXWindow.cpp @@ -60,10 +60,10 @@ CStdWindow::~CStdWindow () } CStdWindow * CStdWindow::Init(CStdApp * pApp) { - return Init(pApp, C4ENGINENAME); + return Init(CStdWindow::W_Viewport, pApp, C4ENGINENAME); } -CStdWindow * CStdWindow::Init(CStdApp * pApp, const char * Title, CStdWindow * pParent, bool HideCursor) +CStdWindow * CStdWindow::Init(CStdWindow::WindowKind windowKind, CStdApp * pApp, const char * Title, CStdWindow * pParent, bool HideCursor) { Active = true; dpy = pApp->dpy;