Fix issues relating to SDL and wxWidgets interaction in Atlas.
This fixes the transfer of key inputs from WxWidgets to SDL, making it possible to type in the in-game GUI from Atlas. Also fixes whitespace issues in some Atlas files. The following improvements are OSX specific: - fixes an SDL assertion related to unused subsystems in Atlas. - Remove the 'osxguiapplication' override. This fixes the editor starting up in the background and not accepting input when launched from in-game. - To prevent an issue with sdl/wxwidgets conflict when running from inside the game, actually boot a new instance (see #2427) Reported by: wik (Many thanks for your investigations) Tested by: trompetin17, Stan Fixes #2427 Fixes #2846 Differential Revision: https://code.wildfiregames.com/D2788 This was SVN commit r23926.
This commit is contained in:
parent
375c319639
commit
01118c1196
33
source/lib/sysdep/os/osx/osx_atlas.h
Normal file
33
source/lib/sysdep/os/osx/osx_atlas.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OSX_ATLAS_H
|
||||||
|
#define OSX_ATLAS_H
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a new pyrogenesis process with the -editor argument.
|
||||||
|
* Necessary because SDL and WxWidgets conflict.
|
||||||
|
*/
|
||||||
|
void startNewAtlasProcess();
|
||||||
|
|
||||||
|
#endif // OSX_ATLAS_H
|
54
source/lib/sysdep/os/osx/osx_atlas.mm
Normal file
54
source/lib/sysdep/os/osx/osx_atlas.mm
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <AvailabilityMacros.h> // MAC_OS_X_VERSION_MIN_REQUIRED
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
#import "osx_atlas.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "lib/types.h"
|
||||||
|
#include "ps/CStr.h"
|
||||||
|
|
||||||
|
extern std::vector<CStr> g_modsLoaded;
|
||||||
|
|
||||||
|
void startNewAtlasProcess()
|
||||||
|
{
|
||||||
|
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
NSMutableArray *args = [[NSMutableArray alloc] init];
|
||||||
|
[args addObject:@"--editor"];
|
||||||
|
|
||||||
|
// Pass mods on the command line.
|
||||||
|
for (const CStr& mod : g_modsLoaded)
|
||||||
|
{
|
||||||
|
std::string arg = std::string("-mod=") + mod;
|
||||||
|
[args addObject:[[NSString alloc] initWithUTF8String:arg.c_str()]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apple documents this as (deprecated) NSWorkspaceLaunchConfigurationKey, but that's not available in early SDKs.
|
||||||
|
NSDictionary<NSString*, id> *params = @{ NSWorkspaceLaunchConfigurationArguments: args };
|
||||||
|
|
||||||
|
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:[[NSRunningApplication currentApplication] executableURL] options:NSWorkspaceLaunchNewInstance configuration:params error:nil];
|
||||||
|
|
||||||
|
[pool drain];
|
||||||
|
}
|
@ -86,6 +86,10 @@ that of Atlas depending on commandline parameters.
|
|||||||
#include <unistd.h> // geteuid
|
#include <unistd.h> // geteuid
|
||||||
#endif // OS_UNIX
|
#endif // OS_UNIX
|
||||||
|
|
||||||
|
#if OS_MACOSX
|
||||||
|
#include "lib/sysdep/os/osx/osx_atlas.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if MSC_VERSION
|
#if MSC_VERSION
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#define getpid _getpid // Use the non-deprecated function name
|
#define getpid _getpid // Use the non-deprecated function name
|
||||||
@ -719,8 +723,13 @@ static void RunGameOrAtlas(int argc, const char* argv[])
|
|||||||
|
|
||||||
} while (g_Shutdown == ShutdownType::Restart);
|
} while (g_Shutdown == ShutdownType::Restart);
|
||||||
|
|
||||||
|
#if OS_MACOSX
|
||||||
|
if (g_Shutdown == ShutdownType::RestartAsAtlas)
|
||||||
|
startNewAtlasProcess();
|
||||||
|
#else
|
||||||
if (g_Shutdown == ShutdownType::RestartAsAtlas)
|
if (g_Shutdown == ShutdownType::RestartAsAtlas)
|
||||||
ATLAS_RunIfOnCmdLine(args, true);
|
ATLAS_RunIfOnCmdLine(args, true);
|
||||||
|
#endif
|
||||||
|
|
||||||
CXeromyces::Terminate();
|
CXeromyces::Terminate();
|
||||||
}
|
}
|
||||||
|
@ -300,7 +300,8 @@ static void ReportSDL(const ScriptInterface& scriptInterface, JS::HandleValue se
|
|||||||
snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", runtime.major, runtime.minor, runtime.patch);
|
snprintf(version, ARRAY_SIZE(version), "%d.%d.%d", runtime.major, runtime.minor, runtime.patch);
|
||||||
scriptInterface.SetProperty(settings, "sdl_runtime_version", version);
|
scriptInterface.SetProperty(settings, "sdl_runtime_version", version);
|
||||||
|
|
||||||
const char* backend = GetSDLSubsystem(g_VideoMode.GetWindow());
|
// This is null in atlas (and further the call triggers an assertion).
|
||||||
|
const char* backend = g_VideoMode.GetWindow() ? GetSDLSubsystem(g_VideoMode.GetWindow()) : "none";
|
||||||
scriptInterface.SetProperty(settings, "sdl_video_backend", backend ? backend : "unknown");
|
scriptInterface.SetProperty(settings, "sdl_video_backend", backend ? backend : "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2017 Wildfire Games.
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -180,13 +180,6 @@ class AtlasDLLApp : public wxApp
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#ifdef __WXOSX__
|
|
||||||
virtual bool OSXIsGUIApplication()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
virtual bool OnInit()
|
virtual bool OnInit()
|
||||||
{
|
{
|
||||||
// _CrtSetBreakAlloc(5632);
|
// _CrtSetBreakAlloc(5632);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2013 Wildfire Games.
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -77,6 +77,8 @@ int GetSDLKeyFromWxKeyCode(int wxkey)
|
|||||||
case WXK_F14: return SDLK_F14;
|
case WXK_F14: return SDLK_F14;
|
||||||
case WXK_F15: return SDLK_F15;
|
case WXK_F15: return SDLK_F15;
|
||||||
|
|
||||||
|
case WXK_BACK: return SDLK_BACKSPACE;
|
||||||
|
case WXK_DELETE: return SDLK_DELETE;
|
||||||
case WXK_NUMLOCK: return SDLK_NUMLOCKCLEAR;
|
case WXK_NUMLOCK: return SDLK_NUMLOCKCLEAR;
|
||||||
case WXK_SCROLL: return SDLK_SCROLLLOCK;
|
case WXK_SCROLL: return SDLK_SCROLLLOCK;
|
||||||
// case WXK_: return SDLK_CAPSLOCK;
|
// case WXK_: return SDLK_CAPSLOCK;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2019 Wildfire Games.
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -132,9 +132,7 @@ private:
|
|||||||
if (KeyScroll(evt, true))
|
if (KeyScroll(evt, true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Slight hack: Only pass 'special' keys; normal keys will generate a translated Char event instead
|
POST_MESSAGE(GuiKeyEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey(), true));
|
||||||
if (evt.GetKeyCode() >= 256)
|
|
||||||
POST_MESSAGE(GuiKeyEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey(), true));
|
|
||||||
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
@ -147,9 +145,7 @@ private:
|
|||||||
if (KeyScroll(evt, false))
|
if (KeyScroll(evt, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Slight hack: Only pass 'special' keys; normal keys will generate a translated Char event instead
|
POST_MESSAGE(GuiKeyEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey(), false));
|
||||||
if (evt.GetKeyCode() >= 256)
|
|
||||||
POST_MESSAGE(GuiKeyEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey(), false));
|
|
||||||
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
@ -189,8 +185,8 @@ private:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Slight hack: Only pass 'normal' keys; special keys will generate a KeyDown/KeyUp event instead
|
// Slight hack: Only pass 'alphanumeric' keys; special keys will generate a KeyDown/KeyUp event instead
|
||||||
if (evt.GetKeyCode() < 256)
|
if (evt.GetKeyCode() >= 33 && evt.GetKeyCode() <= 126)
|
||||||
POST_MESSAGE(GuiCharEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey()));
|
POST_MESSAGE(GuiCharEvent, (GetSDLKeyFromWxKeyCode(evt.GetKeyCode()), evt.GetUnicodeKey()));
|
||||||
|
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
@ -315,14 +311,14 @@ enum
|
|||||||
{
|
{
|
||||||
ID_Quit = 1,
|
ID_Quit = 1,
|
||||||
|
|
||||||
ID_New,
|
ID_New,
|
||||||
ID_Open,
|
ID_Open,
|
||||||
ID_Save,
|
ID_Save,
|
||||||
ID_SaveAs,
|
ID_SaveAs,
|
||||||
ID_ImportHeightmap,
|
ID_ImportHeightmap,
|
||||||
|
|
||||||
ID_Copy,
|
ID_Copy,
|
||||||
ID_Paste,
|
ID_Paste,
|
||||||
|
|
||||||
ID_Wireframe,
|
ID_Wireframe,
|
||||||
ID_MessageTrace,
|
ID_MessageTrace,
|
||||||
@ -345,7 +341,7 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
|
|||||||
EVT_CLOSE(ScenarioEditor::OnClose)
|
EVT_CLOSE(ScenarioEditor::OnClose)
|
||||||
EVT_TIMER(wxID_ANY, ScenarioEditor::OnTimer)
|
EVT_TIMER(wxID_ANY, ScenarioEditor::OnTimer)
|
||||||
|
|
||||||
EVT_MENU(ID_New, ScenarioEditor::OnNew)
|
EVT_MENU(ID_New, ScenarioEditor::OnNew)
|
||||||
EVT_MENU(ID_Open, ScenarioEditor::OnOpen)
|
EVT_MENU(ID_Open, ScenarioEditor::OnOpen)
|
||||||
EVT_MENU(ID_Save, ScenarioEditor::OnSave)
|
EVT_MENU(ID_Save, ScenarioEditor::OnSave)
|
||||||
EVT_MENU(ID_SaveAs, ScenarioEditor::OnSaveAs)
|
EVT_MENU(ID_SaveAs, ScenarioEditor::OnSaveAs)
|
||||||
@ -355,8 +351,8 @@ BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame)
|
|||||||
EVT_MENU(ID_Quit, ScenarioEditor::OnQuit)
|
EVT_MENU(ID_Quit, ScenarioEditor::OnQuit)
|
||||||
EVT_MENU(wxID_UNDO, ScenarioEditor::OnUndo)
|
EVT_MENU(wxID_UNDO, ScenarioEditor::OnUndo)
|
||||||
EVT_MENU(wxID_REDO, ScenarioEditor::OnRedo)
|
EVT_MENU(wxID_REDO, ScenarioEditor::OnRedo)
|
||||||
EVT_MENU(ID_Copy, ScenarioEditor::OnCopy)
|
EVT_MENU(ID_Copy, ScenarioEditor::OnCopy)
|
||||||
EVT_MENU(ID_Paste, ScenarioEditor::OnPaste)
|
EVT_MENU(ID_Paste, ScenarioEditor::OnPaste)
|
||||||
|
|
||||||
EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe)
|
EVT_MENU(ID_Wireframe, ScenarioEditor::OnWireframe)
|
||||||
EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace)
|
EVT_MENU(ID_MessageTrace, ScenarioEditor::OnMessageTrace)
|
||||||
@ -439,7 +435,7 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
|
|||||||
wxMenu *menuFile = new wxMenu;
|
wxMenu *menuFile = new wxMenu;
|
||||||
menuBar->Append(menuFile, _("&File"));
|
menuBar->Append(menuFile, _("&File"));
|
||||||
{
|
{
|
||||||
menuFile->Append(ID_New, _("&New..."));
|
menuFile->Append(ID_New, _("&New..."));
|
||||||
menuFile->Append(ID_Open, _("&Open..."));
|
menuFile->Append(ID_Open, _("&Open..."));
|
||||||
menuFile->Append(ID_Save, _("&Save"));
|
menuFile->Append(ID_Save, _("&Save"));
|
||||||
menuFile->Append(ID_SaveAs, _("Save &As..."));
|
menuFile->Append(ID_SaveAs, _("Save &As..."));
|
||||||
@ -459,14 +455,14 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent)
|
|||||||
{
|
{
|
||||||
menuEdit->Append(wxID_UNDO, _("&Undo"));
|
menuEdit->Append(wxID_UNDO, _("&Undo"));
|
||||||
menuEdit->Append(wxID_REDO, _("&Redo"));
|
menuEdit->Append(wxID_REDO, _("&Redo"));
|
||||||
menuEdit->AppendSeparator();
|
menuEdit->AppendSeparator();
|
||||||
menuEdit->Append(ID_Copy, _("&Copy"));
|
menuEdit->Append(ID_Copy, _("&Copy"));
|
||||||
menuEdit->Enable(ID_Copy, false);
|
menuEdit->Enable(ID_Copy, false);
|
||||||
menuEdit->Append(ID_Paste, _("&Paste"));
|
menuEdit->Append(ID_Paste, _("&Paste"));
|
||||||
menuEdit->Enable(ID_Paste, false);
|
menuEdit->Enable(ID_Paste, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_SelectedObjects.RegisterObserver(0, &ScenarioEditor::OnSelectedObjectsChange, this);
|
g_SelectedObjects.RegisterObserver(0, &ScenarioEditor::OnSelectedObjectsChange, this);
|
||||||
|
|
||||||
GetCommandProc().SetEditMenu(menuEdit);
|
GetCommandProc().SetEditMenu(menuEdit);
|
||||||
GetCommandProc().Initialize();
|
GetCommandProc().Initialize();
|
||||||
@ -636,13 +632,13 @@ float ScenarioEditor::GetSpeedModifier()
|
|||||||
|
|
||||||
void ScenarioEditor::OnClose(wxCloseEvent& event)
|
void ScenarioEditor::OnClose(wxCloseEvent& event)
|
||||||
{
|
{
|
||||||
if (event.CanVeto() && GetCommandProc().IsDirty())
|
if (event.CanVeto() && GetCommandProc().IsDirty())
|
||||||
{
|
{
|
||||||
if (wxMessageBox(_T("You have unsaved changes. Are you sure you want to quit?"), _T("Discard unsaved changes?"), wxICON_QUESTION | wxYES_NO) != wxYES)
|
if (wxMessageBox(_T("You have unsaved changes. Are you sure you want to quit?"), _T("Discard unsaved changes?"), wxICON_QUESTION | wxYES_NO) != wxYES)
|
||||||
{
|
{
|
||||||
event.Veto();
|
event.Veto();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ToolManager.SetCurrentTool(_T(""));
|
m_ToolManager.SetCurrentTool(_T(""));
|
||||||
@ -698,16 +694,16 @@ void ScenarioEditor::OnRedo(wxCommandEvent&)
|
|||||||
|
|
||||||
void ScenarioEditor::OnCopy(wxCommandEvent& WXUNUSED(event))
|
void ScenarioEditor::OnCopy(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (GetToolManager().GetCurrentToolName() == _T("TransformObject"))
|
if (GetToolManager().GetCurrentToolName() == _T("TransformObject"))
|
||||||
GetToolManager().GetCurrentTool()->OnCommand(_T("copy"), NULL);
|
GetToolManager().GetCurrentTool()->OnCommand(_T("copy"), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScenarioEditor::OnPaste(wxCommandEvent& WXUNUSED(event))
|
void ScenarioEditor::OnPaste(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
if (GetToolManager().GetCurrentToolName() != _T("TransformObject"))
|
if (GetToolManager().GetCurrentToolName() != _T("TransformObject"))
|
||||||
GetToolManager().SetCurrentTool(_T("TransformObject"), NULL);
|
GetToolManager().SetCurrentTool(_T("TransformObject"), NULL);
|
||||||
|
|
||||||
GetToolManager().GetCurrentTool()->OnCommand(_T("paste"), NULL);
|
GetToolManager().GetCurrentTool()->OnCommand(_T("paste"), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -837,7 +833,7 @@ void ScenarioEditor::OnSave(wxCommandEvent& event)
|
|||||||
qPing qry;
|
qPing qry;
|
||||||
qry.Post();
|
qry.Post();
|
||||||
|
|
||||||
GetCommandProc().MarkAsSaved();
|
GetCommandProc().MarkAsSaved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +857,7 @@ void ScenarioEditor::OnSaveAs(wxCommandEvent& WXUNUSED(event))
|
|||||||
qPing qry;
|
qPing qry;
|
||||||
qry.Post();
|
qry.Post();
|
||||||
|
|
||||||
GetCommandProc().MarkAsSaved();
|
GetCommandProc().MarkAsSaved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +974,7 @@ void ScenarioEditor::OnDumpState(wxCommandEvent& event)
|
|||||||
|
|
||||||
void ScenarioEditor::OnSelectedObjectsChange(const std::vector<ObjectID>& selectedObjects)
|
void ScenarioEditor::OnSelectedObjectsChange(const std::vector<ObjectID>& selectedObjects)
|
||||||
{
|
{
|
||||||
GetMenuBar()->Enable(ID_Copy, !selectedObjects.empty());
|
GetMenuBar()->Enable(ID_Copy, !selectedObjects.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScenarioEditor::OnHelp(wxCommandEvent& event)
|
void ScenarioEditor::OnHelp(wxCommandEvent& event)
|
||||||
@ -996,50 +992,50 @@ void ScenarioEditor::OnHelp(wxCommandEvent& event)
|
|||||||
|
|
||||||
void ScenarioEditor::OnMenuOpen(wxMenuEvent& event)
|
void ScenarioEditor::OnMenuOpen(wxMenuEvent& event)
|
||||||
{
|
{
|
||||||
// Ignore wxMSW system menu events, see https://trac.wildfiregames.com/ticket/5501
|
// Ignore wxMSW system menu events, see https://trac.wildfiregames.com/ticket/5501
|
||||||
const wxMenu* menu = event.GetMenu();
|
const wxMenu* menu = event.GetMenu();
|
||||||
if (!menu)
|
if (!menu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This could be done far more elegantly if wxMenuItem had changeable id.
|
// This could be done far more elegantly if wxMenuItem had changeable id.
|
||||||
wxMenu* pasteMenuItem = NULL;
|
wxMenu* pasteMenuItem = NULL;
|
||||||
menu->FindItem(ID_Paste, &pasteMenuItem);
|
menu->FindItem(ID_Paste, &pasteMenuItem);
|
||||||
|
|
||||||
GetMenuBar()->Enable(ID_Paste, false);
|
GetMenuBar()->Enable(ID_Paste, false);
|
||||||
|
|
||||||
if (!pasteMenuItem)
|
if (!pasteMenuItem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxString content;
|
wxString content;
|
||||||
if (wxTheClipboard->Open())
|
if (wxTheClipboard->Open())
|
||||||
{
|
{
|
||||||
if (wxTheClipboard->IsSupported(wxDF_TEXT))
|
if (wxTheClipboard->IsSupported(wxDF_TEXT))
|
||||||
{
|
{
|
||||||
wxTextDataObject data;
|
wxTextDataObject data;
|
||||||
wxTheClipboard->GetData(data);
|
wxTheClipboard->GetData(data);
|
||||||
content = data.GetText();
|
content = data.GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxTheClipboard->Close();
|
wxTheClipboard->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content.empty())
|
if (content.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxInputStream* is = new wxStringInputStream(content);
|
wxInputStream* is = new wxStringInputStream(content);
|
||||||
wxXmlDocument doc;
|
wxXmlDocument doc;
|
||||||
{
|
{
|
||||||
wxLogNull stopComplaining;
|
wxLogNull stopComplaining;
|
||||||
static_cast<void>(stopComplaining);
|
static_cast<void>(stopComplaining);
|
||||||
if (!doc.Load(*is))
|
if (!doc.Load(*is))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxXmlNode* root = doc.GetRoot();
|
wxXmlNode* root = doc.GetRoot();
|
||||||
if (!root || root->GetName() != wxT("Entities"))
|
if (!root || root->GetName() != wxT("Entities"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GetMenuBar()->Enable(ID_Paste, true);
|
GetMenuBar()->Enable(ID_Paste, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2019 Wildfire Games.
|
/* Copyright (C) 2020 Wildfire Games.
|
||||||
* This file is part of 0 A.D.
|
* This file is part of 0 A.D.
|
||||||
*
|
*
|
||||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||||
@ -198,16 +198,20 @@ MESSAGEHANDLER(GuiKeyEvent)
|
|||||||
|
|
||||||
MESSAGEHANDLER(GuiCharEvent)
|
MESSAGEHANDLER(GuiCharEvent)
|
||||||
{
|
{
|
||||||
// wxWidgets has special Char events but SDL doesn't, so convert it to
|
// Simulate special 'text input' events in the SDL
|
||||||
// a keydown+keyup sequence. (We do the conversion here instead of on
|
// This isn't quite compatible with WXWidget's handling,
|
||||||
// the wx side to avoid nondeterministic behaviour caused by async messaging.)
|
// so to avoid trouble we only send 'letter-like' ASCII input.
|
||||||
|
|
||||||
SDL_Event_ ev = { { 0 } };
|
SDL_Event_ ev = { { 0 } };
|
||||||
ev.ev.type = SDL_KEYDOWN;
|
ev.ev.type = SDL_TEXTEDITING;
|
||||||
ev.ev.key.keysym.sym = (SDL_Keycode)(int)msg->sdlkey;
|
ev.ev.text.type = SDL_TEXTEDITING;
|
||||||
|
ev.ev.text.text[0] = (char)msg->sdlkey;
|
||||||
|
ev.ev.text.text[1] = (char)0;
|
||||||
in_dispatch_event(&ev);
|
in_dispatch_event(&ev);
|
||||||
|
|
||||||
ev.ev.type = SDL_KEYUP;
|
ev.ev.type = SDL_TEXTINPUT;
|
||||||
|
ev.ev.text.type = SDL_TEXTINPUT;
|
||||||
|
ev.ev.text.text[0] = (char)msg->sdlkey;
|
||||||
|
ev.ev.text.text[1] = (char)0;
|
||||||
in_dispatch_event(&ev);
|
in_dispatch_event(&ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user