From 07e307c49ae42a4a7918dd719d669fe1ad07df85 Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Fri, 27 May 2011 21:56:43 +0000 Subject: [PATCH] Move Atlas's terrain and object sections from JS back into C++, per http://www.wildfiregames.com/forum/index.php?showtopic=14741 This was SVN commit r9559. --- build/premake/premake.lua | 3 + .../tools/atlas/AtlasUI/General/Observable.h | 76 ++++- .../AtlasUI/ScenarioEditor/ScenarioEditor.cpp | 15 +- .../AtlasUI/ScenarioEditor/ScenarioEditor.h | 2 +- .../AtlasUI/ScenarioEditor/SectionLayout.cpp | 14 +- .../ScenarioEditor/Sections/Map/Map.cpp | 29 +- .../AtlasUI/ScenarioEditor/Sections/Map/Map.h | 19 +- .../ScenarioEditor/Sections/Object/Object.cpp | 312 ++++++++++++++---- .../ScenarioEditor/Sections/Object/Object.h | 12 +- .../Sections/Object/VariationControl.cpp | 2 +- .../Sections/Terrain/Terrain.cpp | 233 +++++++++---- .../ScenarioEditor/Sections/Terrain/Terrain.h | 10 +- .../ScenarioEditor/Tools/Common/Brushes.cpp | 4 +- .../Tools/Common/ObjectSettings.cpp | 11 +- .../Tools/Common/ObjectSettings.h | 2 + .../ScenarioEditor/Tools/Common/Tools.cpp | 15 +- .../ScenarioEditor/Tools/Common/Tools.h | 5 +- source/tools/atlas/GameInterface/View.cpp | 3 +- 18 files changed, 595 insertions(+), 172 deletions(-) diff --git a/build/premake/premake.lua b/build/premake/premake.lua index 14f25070e7..301756393c 100644 --- a/build/premake/premake.lua +++ b/build/premake/premake.lua @@ -824,6 +824,9 @@ function setup_atlas_packages() "ScenarioEditor/Sections/Common", "ScenarioEditor/Sections/Cinematic", "ScenarioEditor/Sections/Environment", + "ScenarioEditor/Sections/Map", + "ScenarioEditor/Sections/Object", + "ScenarioEditor/Sections/Terrain", "ScenarioEditor/Sections/Trigger", "ScenarioEditor/Tools", "ScenarioEditor/Tools/Common", diff --git a/source/tools/atlas/AtlasUI/General/Observable.h b/source/tools/atlas/AtlasUI/General/Observable.h index eb4f5fcbb7..ccd422090a 100644 --- a/source/tools/atlas/AtlasUI/General/Observable.h +++ b/source/tools/atlas/AtlasUI/General/Observable.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -54,6 +54,8 @@ public: explicit Observable(const T1& a1) : T(a1) {} template explicit Observable(T1& a1, T2& a2) : T(a1, a2) {} + template + explicit Observable(T1& a1, T2 a2) : T(a1, a2) {} template ObservableConnection RegisterObserver(int order, void (C::*callback) (const T&), C* obj) { @@ -94,16 +96,84 @@ public: } } - Observable* operator=(const T& rhs) + Observable& operator=(const T& rhs) { *dynamic_cast(this) = rhs; - return this; + return *this; } private: boost::signal m_Signal; }; +// A similar thing, but for wrapping pointers instead of objects +template class ObservablePtr +{ +public: + ObservablePtr() : m_Ptr(NULL) {} + + ObservablePtr(T* p) : m_Ptr(p) {} + + ObservablePtr& operator=(T* p) + { + m_Ptr = p; + return *this; + } + + T* operator->() + { + return m_Ptr; + } + + T* operator*() + { + return m_Ptr; + } + + template ObservableConnection RegisterObserver(int order, void (C::*callback) (T*), C* obj) + { + return m_Signal.connect(order, boost::bind(std::mem_fun(callback), obj, _1)); + } + + ObservableConnection RegisterObserver(int order, void (*callback) (T*)) + { + return m_Signal.connect(order, callback); + } + + void RemoveObserver(const ObservableConnection& conn) + { + conn.disconnect(); + } + + void NotifyObservers() + { + m_Signal(m_Ptr); + } + + // Use when an object is changing something that it's also observing, + // because it already knows about the change and doesn't need to be notified + // again (particularly since that may cause infinite loops). + void NotifyObserversExcept(ObservableConnection& conn) + { + if (conn.blocked()) + { + // conn is already blocked and won't see anything + NotifyObservers(); + } + else + { + // Temporarily disable conn + conn.block(); + NotifyObservers(); + conn.unblock(); + } + } + +private: + T* m_Ptr; + boost::signal m_Signal; +}; + class ObservableScopedConnections { public: diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 42cdbd35d4..fc36e4f506 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -115,7 +115,7 @@ private: void OnKeyDown(wxKeyEvent& evt) { - if (m_ScenarioEditor.GetToolManager().GetCurrentTool().OnKey(evt, ITool::KEY_DOWN)) + if (m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnKey(evt, ITool::KEY_DOWN)) { // Key event has been handled by the tool, so don't try // to use it for camera motion too @@ -134,7 +134,7 @@ private: void OnKeyUp(wxKeyEvent& evt) { - if (m_ScenarioEditor.GetToolManager().GetCurrentTool().OnKey(evt, ITool::KEY_UP)) + if (m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnKey(evt, ITool::KEY_UP)) return; if (KeyScroll(evt, false)) @@ -149,7 +149,7 @@ private: void OnChar(wxKeyEvent& evt) { - if (m_ScenarioEditor.GetToolManager().GetCurrentTool().OnKey(evt, ITool::KEY_CHAR)) + if (m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnKey(evt, ITool::KEY_CHAR)) return; // Alt+enter toggles fullscreen @@ -218,7 +218,7 @@ private: if (evt.Moving()) SetFocus(); - if (m_ScenarioEditor.GetToolManager().GetCurrentTool().OnMouse(evt)) + if (m_ScenarioEditor.GetToolManager().GetCurrentTool()->OnMouse(evt)) { // Mouse event has been handled by the tool, so don't try // to use it for camera motion too @@ -390,7 +390,7 @@ namespace ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterface) : wxFrame(parent, wxID_ANY, _T(""), wxDefaultPosition, wxSize(1024, 768)) , m_FileHistory(_T("Scenario Editor")), m_ScriptInterface(scriptInterface) -, m_ObjectSettings(g_SelectedObjects, m_ScriptInterface) +, m_ObjectSettings(g_SelectedObjects, AtlasMessage::eRenderView::GAME) , m_ToolManager(this) { // Global application initialisation: @@ -461,9 +461,6 @@ ScenarioEditor::ScenarioEditor(wxWindow* parent, ScriptInterface& scriptInterfac } - // Initialise things that rely on scripts - m_ObjectSettings.Init(AtlasMessage::eRenderView::GAME); - ////////////////////////////////////////////////////////////////////////// // Do some early game initialisation: @@ -653,7 +650,7 @@ static void UpdateTool(ToolManager& toolManager) // TODO: Smoother timing stuff? static double last = g_Timer.GetTime(); double time = g_Timer.GetTime(); - toolManager.GetCurrentTool().OnTick(time-last); + toolManager.GetCurrentTool()->OnTick(time-last); last = time; } } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h index da12993dd9..db9c92989c 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.h @@ -61,7 +61,7 @@ public: static float GetSpeedModifier(); ScriptInterface& GetScriptInterface() const { return m_ScriptInterface; } - ObjectSettings& GetObjectSettings() { return m_ObjectSettings; } + Observable& GetObjectSettings() { return m_ObjectSettings; } ToolManager& GetToolManager() { return m_ToolManager; } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp index 660bd771d4..1f8f002737 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp @@ -29,6 +29,9 @@ #include "Sections/Environment/Environment.h" #include "Sections/Cinematic/Cinematic.h" +#include "Sections/Map/Map.h" +#include "Sections/Object/Object.h" +#include "Sections/Terrain/Terrain.h" #include "Sections/Trigger/Trigger.h" #include "General/Datafile.h" @@ -313,14 +316,13 @@ void SectionLayout::Build(ScenarioEditor& scenarioEditor) m_PageMappings.insert(std::make_pair(name, (int)m_SidebarBook->GetPageCount()-1)); ADD_SIDEBAR_SCRIPT(_T("map"), _T("map.png"), _("Map")); - ADD_SIDEBAR_SCRIPT(_T("terrain"), _T("terrain.png"), _("Terrain")); - ADD_SIDEBAR_SCRIPT(_T("object"), _T("object.png"), _("Object")); +// ADD_SIDEBAR(MapSidebar, _T("map.png"), _("Map")); + ADD_SIDEBAR(TerrainSidebar, _T("terrain.png"), _("Terrain")); + ADD_SIDEBAR(ObjectSidebar, _T("object.png"), _("Object")); ADD_SIDEBAR(EnvironmentSidebar, _T("environment.png"), _("Environment")); - #ifndef ATLAS_PUBLIC_RELEASE - ADD_SIDEBAR(CinematicSidebar, _T("cinematic.png"), _("Cinema")); - ADD_SIDEBAR(TriggerSidebar, _T("trigger.png"), _("Trigger")); - #endif +// ADD_SIDEBAR(CinematicSidebar, _T("cinematic.png"), _("Cinema")); +// ADD_SIDEBAR(TriggerSidebar, _T("trigger.png"), _("Trigger")); #undef ADD_SIDEBAR diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp index 4c774f5ca7..a2282e3e14 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp @@ -1,4 +1,21 @@ -#include "stdafx.h" +/* Copyright (C) 2011 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + +#include "precompiled.h" #include "Map.h" @@ -30,8 +47,8 @@ enum }; bool IsPlaying(int s) { return (s == SimPlaying || s == SimPlayingFast || s == SimPlayingSlow); } -MapSidebar::MapSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer) - : Sidebar(sidebarContainer, bottomBarContainer), m_SimState(SimInactive) +MapSidebar::MapSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) + : Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer), m_SimState(SimInactive) { // TODO: Less ugliness // TODO: Intercept arrow keys and send them to the GL window @@ -60,7 +77,9 @@ MapSidebar::MapSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer) void MapSidebar::GenerateMap(wxCommandEvent& WXUNUSED(event)) { - POST_MESSAGE(GenerateMap, (9)); +// qGenerateMap qry(); +// qry.Post(); +// POST_MESSAGE(GenerateMap, (9)); } void MapSidebar::GenerateRMS(wxCommandEvent& WXUNUSED(event)) @@ -119,7 +138,7 @@ void MapSidebar::OnSimPlay(wxCommandEvent& event) if (m_SimState == SimInactive) { - POST_MESSAGE(SimStateSave, (L"default", true)); + POST_MESSAGE(SimStateSave, (L"default")); POST_MESSAGE(SimPlay, (speed)); m_SimState = newState; } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.h index ff7fc67911..1dc82a64d3 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.h @@ -1,9 +1,26 @@ +/* Copyright (C) 2011 Wildfire Games. + * This file is part of 0 A.D. + * + * 0 A.D. is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 0 A.D. is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with 0 A.D. If not, see . + */ + #include "../Common/Sidebar.h" class MapSidebar : public Sidebar { public: - MapSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer); + MapSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer); private: void GenerateMap(wxCommandEvent& event); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp index bb26ef7fa5..f524213719 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -29,71 +29,77 @@ #include "wx/busyinfo.h" -class ObjectSelectListBox : public wxListBox +enum { -public: - ObjectSelectListBox(wxWindow* parent, ToolManager& toolManager) - : wxListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL) - , m_ToolManager(toolManager) - { - } - - void OnSelect(wxCommandEvent& evt) - { - // On selecting an object, enable the PlaceObject tool with this object - wxString id = static_cast(evt.GetClientObject())->GetData(); - m_ToolManager.SetCurrentTool(_T("PlaceObject"), &id); - } - -private: - ToolManager& m_ToolManager; - DECLARE_EVENT_TABLE(); + ID_ObjectType = 1, + ID_SelectObject, + ID_ToggleViewer, + ID_ViewerWireframe, + ID_ViewerMove, + ID_ViewerGround, + ID_ViewerShadows, + ID_ViewerPolyCount, + ID_ViewerAnimation, + ID_ViewerPlay, + ID_ViewerPause, + ID_ViewerSlow }; -BEGIN_EVENT_TABLE(ObjectSelectListBox, wxListBox) - EVT_LISTBOX(wxID_ANY, ObjectSelectListBox::OnSelect) -END_EVENT_TABLE(); - -class ObjectChoiceCtrl : public wxChoice +// Helper function for adding tooltips +wxWindow* Tooltipped(wxWindow* window, const wxString& tip) { -public: - ObjectChoiceCtrl(wxWindow* parent, const wxArrayString& strings, ObjectSidebar& sidebar) - : wxChoice(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, strings), - m_Sidebar(sidebar) - { - SetSelection(0); - } - - void OnSelect(wxCommandEvent& evt) - { - // Switch between displayed lists of objects (e.g. entities vs actors) - m_Sidebar.SetObjectFilter(evt.GetSelection()); - } - -private: - ObjectSidebar& m_Sidebar; - - DECLARE_EVENT_TABLE(); -}; -BEGIN_EVENT_TABLE(ObjectChoiceCtrl, wxChoice) - EVT_CHOICE(wxID_ANY, ObjectChoiceCtrl::OnSelect) -END_EVENT_TABLE(); - -////////////////////////////////////////////////////////////////////////// - + window->SetToolTip(tip); + return window; +} class ObjectBottomBar : public wxPanel { public: - ObjectBottomBar(wxWindow* parent, Observable& objectSettings); + ObjectBottomBar(wxWindow* parent, Observable& objectSettings, ObjectSidebarImpl* p); + + void OnFirstDisplay(); + + void ShowActorViewer(bool show); + +private: + void OnViewerSetting(wxCommandEvent& evt); + void OnSelectAnim(wxCommandEvent& evt); + void OnSpeed(wxCommandEvent& evt); + + bool m_ViewerWireframe; + bool m_ViewerMove; + bool m_ViewerGround; + bool m_ViewerShadows; + bool m_ViewerPolyCount; + + wxPanel* m_ViewerPanel; + + ObjectSidebarImpl* p; + + DECLARE_EVENT_TABLE(); }; struct ObjectSidebarImpl { - ObjectSidebarImpl() : m_BottomBar(NULL), m_ObjectListBox(NULL) { } - wxWindow* m_BottomBar; + ObjectSidebarImpl() : + m_ObjectListBox(NULL), m_ActorViewerActive(false), + m_ActorViewerEntity(_T("actor|structures/fndn_1x1.xml")), m_ActorViewerAnimation(_T("idle")), m_ActorViewerSpeed(0.f) + { + } + wxListBox* m_ObjectListBox; std::vector m_Objects; + ObservableScopedConnection m_ToolConn; + + bool m_ActorViewerActive; + wxString m_ActorViewerEntity; + wxString m_ActorViewerAnimation; + float m_ActorViewerSpeed; + + void ActorViewerPostToGame() + { + POST_MESSAGE(SetActorViewer, (m_ActorViewerEntity.c_str(), m_ActorViewerAnimation.c_str(), m_ActorViewerSpeed, false)); + } }; ObjectSidebar::ObjectSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) @@ -102,12 +108,17 @@ ObjectSidebar::ObjectSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarCo wxArrayString strings; strings.Add(_("Entities")); strings.Add(_("Actors (all)")); - m_MainSizer->Add(new ObjectChoiceCtrl(this, strings, *this), wxSizerFlags().Expand()); + wxChoice* objectType = new wxChoice(this, ID_ObjectType, wxDefaultPosition, wxDefaultSize, strings); + m_MainSizer->Add(objectType, wxSizerFlags().Expand()); - p->m_ObjectListBox = new ObjectSelectListBox(this, scenarioEditor.GetToolManager()); + p->m_ObjectListBox = new wxListBox(this, ID_SelectObject, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL); m_MainSizer->Add(p->m_ObjectListBox, wxSizerFlags().Proportion(1).Expand()); - m_BottomBar = new ObjectBottomBar(bottomBarContainer, scenarioEditor.GetObjectSettings()); + m_MainSizer->Add(new wxButton(this, ID_ToggleViewer, _("Switch to Actor Viewer")), wxSizerFlags().Expand()); + + m_BottomBar = new ObjectBottomBar(bottomBarContainer, scenarioEditor.GetObjectSettings(), p); + + p->m_ToolConn = scenarioEditor.GetToolManager().GetCurrentTool().RegisterObserver(0, &ObjectSidebar::OnToolChange, this); } ObjectSidebar::~ObjectSidebar() @@ -115,8 +126,25 @@ ObjectSidebar::~ObjectSidebar() delete p; } +void ObjectSidebar::OnToolChange(ITool* tool) +{ + if (wxString(tool->GetClassInfo()->GetClassName()) == _T("ActorViewerTool")) + { + p->m_ActorViewerActive = true; + p->ActorViewerPostToGame(); + } + else + { + p->m_ActorViewerActive = false; + } + + static_cast(m_BottomBar)->ShowActorViewer(p->m_ActorViewerActive); +} + void ObjectSidebar::OnFirstDisplay() { + static_cast(m_BottomBar)->OnFirstDisplay(); + wxBusyInfo busy (_("Loading list of objects")); // Get the list of objects from the game @@ -143,6 +171,48 @@ void ObjectSidebar::SetObjectFilter(int type) p->m_ObjectListBox->Thaw(); } +void ObjectSidebar::ToggleViewer(wxCommandEvent& WXUNUSED(evt)) +{ + if (p->m_ActorViewerActive) + m_ScenarioEditor.GetToolManager().SetCurrentTool(_T(""), NULL); + else + m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("ActorViewerTool"), NULL); +} + +void ObjectSidebar::OnSelectType(wxCommandEvent& evt) +{ + // Switch between displayed lists of objects (e.g. entities vs actors) + SetObjectFilter(evt.GetSelection()); +} + +void ObjectSidebar::OnSelectObject(wxCommandEvent& evt) +{ + if (evt.GetInt() < 0) + return; + + wxString id = static_cast(evt.GetClientObject())->GetData(); + + // Always update the actor viewer's state even if it's inactive, + // so it will be correct when first enabled + p->m_ActorViewerEntity = id; + + if (p->m_ActorViewerActive) + { + p->ActorViewerPostToGame(); + } + else + { + // On selecting an object, enable the PlaceObject tool with this object + m_ScenarioEditor.GetToolManager().SetCurrentTool(_T("PlaceObject"), &id); + } +} + +BEGIN_EVENT_TABLE(ObjectSidebar, Sidebar) + EVT_CHOICE(ID_ObjectType, ObjectSidebar::OnSelectType) + EVT_LISTBOX(ID_SelectObject, ObjectSidebar::OnSelectObject) + EVT_BUTTON(ID_ToggleViewer, ObjectSidebar::ToggleViewer) +END_EVENT_TABLE(); + ////////////////////////////////////////////////////////////////////////// class PlayerComboBox : public wxComboBox @@ -179,11 +249,56 @@ END_EVENT_TABLE(); ////////////////////////////////////////////////////////////////////////// -ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable& objectSettings) - : wxPanel(parent, wxID_ANY) +ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable& objectSettings, ObjectSidebarImpl* p) + : wxPanel(parent, wxID_ANY), p(p) { - wxSizer* sizer = new wxBoxSizer(wxVERTICAL); - + m_ViewerWireframe = false; + m_ViewerMove = false; + m_ViewerGround = true; + m_ViewerShadows = true; + m_ViewerPolyCount = false; + + wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + + + m_ViewerPanel = new wxPanel(this, wxID_ANY); + wxSizer* viewerSizer = new wxBoxSizer(wxHORIZONTAL); + + wxSizer* viewerButtonsSizer = new wxStaticBoxSizer(wxVERTICAL, m_ViewerPanel, _("Display settings")); + viewerButtonsSizer->SetMinSize(140, -1); + viewerButtonsSizer->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerWireframe, _("Wireframe")), _("Toggle wireframe / solid rendering")), wxSizerFlags().Expand()); + viewerButtonsSizer->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerMove, _("Move")), _("Toggle movement along ground when playing walk/run animations")), wxSizerFlags().Expand()); + viewerButtonsSizer->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerGround, _("Ground")), _("Toggle the ground plane")), wxSizerFlags().Expand()); + viewerButtonsSizer->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerShadows, _("Shadows")), _("Toggle shadow rendering")), wxSizerFlags().Expand()); + viewerButtonsSizer->Add(Tooltipped(new wxButton(m_ViewerPanel, ID_ViewerPolyCount, _("Poly count")), _("Toggle polygon-count statistics - turn off ground and shadows for more useful data")), wxSizerFlags().Expand()); + viewerSizer->Add(viewerButtonsSizer, wxSizerFlags().Expand()); + + wxSizer* viewerAnimSizer = new wxStaticBoxSizer(wxVERTICAL, m_ViewerPanel, _("Animation")); + + wxString animChoices[] = { + _T("idle"), _T("walk"), _T("run"), _T("melee"), _T("death"), _T("build"), + _T("gather_fruit"), _T("gather_grain"), _T("gather_meat"), _T("gather_tree"), + _T("gather_rock"), _T("gather_ore"), _T("gather_ruins"), _T("gather_treasure") + }; // TODO: this list should come from the actor + wxChoice* viewerAnimSelector = new wxChoice(m_ViewerPanel, ID_ViewerAnimation, wxDefaultPosition, wxDefaultSize, sizeof(animChoices)/sizeof(animChoices[0]), animChoices); + viewerAnimSizer->Add(viewerAnimSelector, wxSizerFlags().Expand()); + + wxSizer* viewerAnimSpeedSizer = new wxBoxSizer(wxHORIZONTAL); + viewerAnimSpeedSizer->Add(new wxButton(m_ViewerPanel, ID_ViewerPlay, _("Play"), wxDefaultPosition, wxSize(50, -1)), wxSizerFlags().Expand()); + viewerAnimSpeedSizer->Add(new wxButton(m_ViewerPanel, ID_ViewerPause, _("Pause"), wxDefaultPosition, wxSize(50, -1)), wxSizerFlags().Expand()); + viewerAnimSpeedSizer->Add(new wxButton(m_ViewerPanel, ID_ViewerSlow, _("Slow"), wxDefaultPosition, wxSize(50, -1)), wxSizerFlags().Expand()); + viewerAnimSizer->Add(viewerAnimSpeedSizer); + + viewerSizer->Add(viewerAnimSizer, wxSizerFlags().Expand()); + + m_ViewerPanel->SetSizer(viewerSizer); + sizer->Add(m_ViewerPanel, wxSizerFlags().Expand()); + + m_ViewerPanel->Show(false); + + + wxSizer* playerVariationSizer = new wxBoxSizer(wxVERTICAL); + wxArrayString players; // TODO: get proper player names players.Add(_("Gaia")); @@ -196,13 +311,88 @@ ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable& o players.Add(_("Player 7")); players.Add(_("Player 8")); wxComboBox* playerSelect = new PlayerComboBox(this, players, objectSettings); - sizer->Add(playerSelect); + // TODO: make this a wxChoice instead + playerVariationSizer->Add(playerSelect); wxWindow* variationSelect = new VariationControl(this, objectSettings); variationSelect->SetMinSize(wxSize(160, -1)); wxSizer* variationSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Variation")); variationSizer->Add(variationSelect, wxSizerFlags().Proportion(1).Expand()); - sizer->Add(variationSizer, wxSizerFlags().Proportion(1)); + playerVariationSizer->Add(variationSizer, wxSizerFlags().Proportion(1)); + + sizer->Add(playerVariationSizer, wxSizerFlags().Expand()); SetSizer(sizer); } + +void ObjectBottomBar::OnFirstDisplay() +{ + // Initialise the game with the default settings + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"wireframe", m_ViewerWireframe)); + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"walk", m_ViewerMove)); + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"ground", m_ViewerGround)); + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"shadows", m_ViewerShadows)); + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"stats", m_ViewerPolyCount)); +} + +void ObjectBottomBar::ShowActorViewer(bool show) +{ + m_ViewerPanel->Show(show); + Layout(); +} + +void ObjectBottomBar::OnViewerSetting(wxCommandEvent& evt) +{ + switch (evt.GetId()) + { + case ID_ViewerWireframe: + m_ViewerWireframe = !m_ViewerWireframe; + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"wireframe", m_ViewerWireframe)); + break; + case ID_ViewerMove: + m_ViewerMove = !m_ViewerMove; + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"walk", m_ViewerMove)); + break; + case ID_ViewerGround: + m_ViewerGround = !m_ViewerGround; + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"ground", m_ViewerGround)); + break; + case ID_ViewerShadows: + m_ViewerShadows = !m_ViewerShadows; + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"shadows", m_ViewerShadows)); + break; + case ID_ViewerPolyCount: + m_ViewerPolyCount = !m_ViewerPolyCount; + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::ACTOR, L"stats", m_ViewerPolyCount)); + break; + } +} + +void ObjectBottomBar::OnSelectAnim(wxCommandEvent& evt) +{ + p->m_ActorViewerAnimation = evt.GetString(); + p->ActorViewerPostToGame(); +} + +void ObjectBottomBar::OnSpeed(wxCommandEvent& evt) +{ + switch (evt.GetId()) + { + case ID_ViewerPlay: p->m_ActorViewerSpeed = 1.0f; break; + case ID_ViewerPause: p->m_ActorViewerSpeed = 0.0f; break; + case ID_ViewerSlow: p->m_ActorViewerSpeed = 0.1f; break; + } + p->ActorViewerPostToGame(); +} + +BEGIN_EVENT_TABLE(ObjectBottomBar, wxPanel) + EVT_BUTTON(ID_ViewerWireframe, ObjectBottomBar::OnViewerSetting) + EVT_BUTTON(ID_ViewerMove, ObjectBottomBar::OnViewerSetting) + EVT_BUTTON(ID_ViewerGround, ObjectBottomBar::OnViewerSetting) + EVT_BUTTON(ID_ViewerShadows, ObjectBottomBar::OnViewerSetting) + EVT_BUTTON(ID_ViewerPolyCount, ObjectBottomBar::OnViewerSetting) + EVT_CHOICE(ID_ViewerAnimation, ObjectBottomBar::OnSelectAnim) + EVT_BUTTON(ID_ViewerPlay, ObjectBottomBar::OnSpeed) + EVT_BUTTON(ID_ViewerPause, ObjectBottomBar::OnSpeed) + EVT_BUTTON(ID_ViewerSlow, ObjectBottomBar::OnSpeed) +END_EVENT_TABLE(); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h index 3c02e0870a..2b2954666e 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -17,6 +17,8 @@ #include "../Common/Sidebar.h" +class ITool; + struct ObjectSidebarImpl; class ObjectSidebar : public Sidebar { @@ -29,5 +31,13 @@ protected: virtual void OnFirstDisplay(); private: + void OnToolChange(ITool* tool); + + void ToggleViewer(wxCommandEvent& evt); + void OnSelectType(wxCommandEvent& evt); + void OnSelectObject(wxCommandEvent& evt); + ObjectSidebarImpl* p; + + DECLARE_EVENT_TABLE(); }; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/VariationControl.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/VariationControl.cpp index 66bbb7400b..bba86935cb 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/VariationControl.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/VariationControl.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp index 4f7b9835f7..4b55b9954f 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -39,29 +39,29 @@ class TextureNotebook; class TerrainBottomBar : public wxPanel { public: - TerrainBottomBar(wxWindow* parent); + TerrainBottomBar(ScenarioEditor& scenarioEditor, wxWindow* parent); void LoadTerrain(); private: TextureNotebook* m_Textures; }; -TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) -: Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer) +enum { - // TODO: Less ugliness - - m_MainSizer->Add(new wxStaticText(this, wxID_ANY, _T("TODO: Make this much less ugly\n"))); + ID_Passability = 1, + ID_ShowPriorities +}; +TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer) : + Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer) +{ { wxSizer* sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Elevation tools")); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Modify"), _T("AlterElevation"), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T("SmoothElevation"), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Flatten"), _T("FlattenElevation"), wxSize(50,20))); -// sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T(""), wxSize(50,20))); -// sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Sample"), _T(""), wxSize(50,20))); - sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain"), wxSize(50,20))); - m_MainSizer->Add(sizer); + sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Modify"), _T("AlterElevation")), wxSizerFlags().Proportion(1)); + sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Smooth"), _T("SmoothElevation")), wxSizerFlags().Proportion(1)); + sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Flatten"), _T("FlattenElevation")), wxSizerFlags().Proportion(1)); + sizer->Add(new ToolButton(scenarioEditor.GetToolManager(), this, _("Paint"), _T("PaintTerrain")), wxSizerFlags().Proportion(1)); + m_MainSizer->Add(sizer, wxSizerFlags().Expand()); } { @@ -70,113 +70,208 @@ TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebar m_MainSizer->Add(sizer); } - m_BottomBar = new TerrainBottomBar(bottomBarContainer); + { + wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Visualise")); + m_MainSizer->Add(sizer); + + wxSizer* visSizer = new wxFlexGridSizer(2); + sizer->Add(visSizer); + + wxArrayString defaultChoices; + defaultChoices.Add(_("(none)")); + m_PassabilityChoice = new wxChoice(this, ID_Passability, wxDefaultPosition, wxDefaultSize, defaultChoices); + + visSizer->Add(new wxStaticText(this, wxID_ANY, _("Passability")), wxSizerFlags().Right()); + visSizer->Add(m_PassabilityChoice); + + visSizer->Add(new wxStaticText(this, wxID_ANY, _("Priorities")), wxSizerFlags().Right()); + visSizer->Add(new wxCheckBox(this, ID_ShowPriorities, _(""))); + } + + m_BottomBar = new TerrainBottomBar(scenarioEditor, bottomBarContainer); } void TerrainSidebar::OnFirstDisplay() { + AtlasMessage::qGetTerrainPassabilityClasses qry; + qry.Post(); + std::vector passClasses = *qry.classNames; + for (size_t i = 0; i < passClasses.size(); ++i) + m_PassabilityChoice->Append(passClasses[i]); + static_cast(m_BottomBar)->LoadTerrain(); } +void TerrainSidebar::OnPassabilityChoice(wxCommandEvent& evt) +{ + if (evt.GetSelection() == 0) + POST_MESSAGE(SetViewParamS, (AtlasMessage::eRenderView::GAME, L"passability", L"")); + else + POST_MESSAGE(SetViewParamS, (AtlasMessage::eRenderView::GAME, L"passability", evt.GetString().c_str())); +} + +void TerrainSidebar::OnShowPriorities(wxCommandEvent& evt) +{ + POST_MESSAGE(SetViewParamB, (AtlasMessage::eRenderView::GAME, L"priorities", evt.IsChecked())); +} + +BEGIN_EVENT_TABLE(TerrainSidebar, Sidebar) + EVT_CHOICE(ID_Passability, TerrainSidebar::OnPassabilityChoice) + EVT_CHECKBOX(ID_ShowPriorities, TerrainSidebar::OnShowPriorities) +END_EVENT_TABLE(); + ////////////////////////////////////////////////////////////////////////// class TextureNotebookPage : public wxPanel { +private: + static const int imageWidth = 120; + static const int imageHeight = 40; + public: - TextureNotebookPage(wxWindow* parent, const wxString& name) - : wxPanel(parent, wxID_ANY), m_Name(name), m_ListCtrl(NULL) + TextureNotebookPage(ScenarioEditor& scenarioEditor, wxWindow* parent, const wxString& name) + : wxPanel(parent, wxID_ANY), m_ScenarioEditor(scenarioEditor), m_Timer(this), m_Name(name), m_Loaded(false) { + m_ScrolledPanel = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL); + m_ScrolledPanel->SetScrollRate(0, 10); + m_ScrolledPanel->SetBackgroundColour(wxColour(255, 255, 255)); + + wxSizer* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(m_ScrolledPanel, wxSizerFlags().Proportion(1).Expand()); + SetSizer(sizer); + + m_ItemSizer = new wxGridSizer(6, 4, 0); + m_ScrolledPanel->SetSizer(m_ItemSizer); } void OnDisplay() { - if (m_ListCtrl) - { - int sel = m_ListCtrl->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (sel != -1) - SetSelection(m_ListCtrl->GetItemData(sel)); + // Trigger the terrain loading on first display + + if (m_Loaded) return; - } + + m_Loaded = true; wxBusyInfo busy (_("Loading terrain previews")); - m_TextureNames.Clear(); + ReloadPreviews(); + } - wxSizer* sizer = new wxBoxSizer(wxVERTICAL); + void ReloadPreviews() + { + Freeze(); - m_ListCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON | wxLC_SINGLE_SEL | wxLC_AUTOARRANGE); + m_ScrolledPanel->DestroyChildren(); + m_ItemSizer->Clear(); - const int imageWidth = 64; - const int imageHeight = 32; - wxImageList* imglist = new wxImageList(imageWidth, imageHeight, false, 0); + m_LastTerrainSelection = NULL; // clear any reference to deleted button AtlasMessage::qGetTerrainGroupPreviews qry(m_Name.c_str(), imageWidth, imageHeight); qry.Post(); std::vector previews = *qry.previews; - int i = 0; - for (std::vector::iterator it = previews.begin(); it != previews.end(); ++it) + bool allLoaded = true; + + for (size_t i = 0; i < previews.size(); ++i) { - unsigned char* buf = (unsigned char*)(malloc(it->imagedata.GetSize())); - // it->imagedata.GetBuffer() gives a Shareable*, which + if (!previews[i].loaded) + allLoaded = false; + + // Construct the wrapped-text label + wxString name = previews[i].name.c_str(); + + // Add spaces into the displayed name so there are more wrapping opportunities + wxString labelText = name; + labelText.Replace(_T("_"), _T(" ")); + wxStaticText* label = new wxStaticText(m_ScrolledPanel, wxID_ANY, labelText, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + label->Wrap(imageWidth); + + unsigned char* buf = (unsigned char*)(malloc(previews[i].imageData.GetSize())); + // imagedata.GetBuffer() gives a Shareable*, which // is stored the same as a unsigned char*, so we can just copy it. - memcpy(buf, it->imagedata.GetBuffer(), it->imagedata.GetSize()); + memcpy(buf, previews[i].imageData.GetBuffer(), previews[i].imageData.GetSize()); wxImage img (imageWidth, imageHeight, buf); - imglist->Add(wxBitmap(img)); - wxListItem item; + wxButton* button = new wxBitmapButton(m_ScrolledPanel, wxID_ANY, wxBitmap(img)); + // Store the texture name in the clientdata slot + button->SetClientObject(new wxStringClientData(name)); - wxString name = it->name.c_str(); - m_TextureNames.Add(name); - // Add spaces into the displayed name, so Windows doesn't just say - // "grass_..." in the list ctrl for every terrain - name.Replace(_T("_"), _T(" ")); - item.SetText(name); - - item.SetData(i); - item.SetId(i); - item.SetImage(i); - - m_ListCtrl->InsertItem(item); - ++i; + wxSizer* imageSizer = new wxBoxSizer(wxVERTICAL); + imageSizer->Add(button, wxSizerFlags().Center()); + imageSizer->Add(label, wxSizerFlags().Proportion(1).Center()); + m_ScrolledPanel->GetSizer()->Add(imageSizer, wxSizerFlags().Expand().Center()); } - m_ListCtrl->AssignImageList(imglist, wxIMAGE_LIST_NORMAL); - sizer->Add(m_ListCtrl, wxSizerFlags().Expand().Proportion(1)); - SetSizer(sizer); - Layout(); // required to make things size correctly + Layout(); + + Thaw(); + + // If not all textures were loaded yet, run a timer to reload the previews + // every so often until they've all finished + if (allLoaded && m_Timer.IsRunning()) + { + m_Timer.Stop(); + } + else if (!allLoaded && !m_Timer.IsRunning()) + { + m_Timer.Start(2000); + } } - void OnSelect(wxListEvent& evt) + void OnButton(wxCommandEvent& evt) { - SetSelection(evt.GetData()); + wxButton* button = wxDynamicCast(evt.GetEventObject(), wxButton); + wxString name = static_cast(button->GetClientObject())->GetData(); + g_SelectedTexture = name; + + if (m_LastTerrainSelection) + m_LastTerrainSelection->SetBackgroundColour(wxNullColour); + + button->SetBackgroundColour(wxColour(255, 255, 0)); + m_LastTerrainSelection = button; + + m_ScenarioEditor.GetToolManager().SetCurrentTool(L"PaintTerrain"); } - void SetSelection(int n) + void OnSize(wxSizeEvent& evt) { - if (n >= 0 && n < (int)m_TextureNames.GetCount()) - g_SelectedTexture = m_TextureNames[n]; + int numCols = std::max(1, (int)(evt.GetSize().GetWidth() / (imageWidth + 16))); + m_ItemSizer->SetCols(numCols); + evt.Skip(); + } + + void OnTimer(wxTimerEvent& WXUNUSED(evt)) + { + ReloadPreviews(); } private: - wxListCtrl* m_ListCtrl; + ScenarioEditor& m_ScenarioEditor; + bool m_Loaded; + wxTimer m_Timer; wxString m_Name; - wxArrayString m_TextureNames; + wxScrolledWindow* m_ScrolledPanel; + wxGridSizer* m_ItemSizer; + wxButton* m_LastTerrainSelection; // button that was last selected, so we can undo its colouring DECLARE_EVENT_TABLE(); }; BEGIN_EVENT_TABLE(TextureNotebookPage, wxPanel) - EVT_LIST_ITEM_SELECTED(wxID_ANY, TextureNotebookPage::OnSelect) + EVT_BUTTON(wxID_ANY, TextureNotebookPage::OnButton) + EVT_SIZE(TextureNotebookPage::OnSize) + EVT_TIMER(wxID_ANY, TextureNotebookPage::OnTimer) END_EVENT_TABLE(); class TextureNotebook : public wxNotebook { public: - TextureNotebook(wxWindow *parent) - : wxNotebook(parent, wxID_ANY/*, wxDefaultPosition, wxDefaultSize, wxNB_FIXEDWIDTH*/) + TextureNotebook(ScenarioEditor& scenarioEditor, wxWindow *parent) + : wxNotebook(parent, wxID_ANY/*, wxDefaultPosition, wxDefaultSize, wxNB_FIXEDWIDTH*/), + m_ScenarioEditor(scenarioEditor) { } @@ -190,7 +285,7 @@ public: // Get the list of terrain groups from the engine AtlasMessage::qGetTerrainGroups qry; qry.Post(); - std::vector groupnames = *qry.groupnames; + std::vector groupnames = *qry.groupNames; for (std::vector::iterator it = groupnames.begin(); it != groupnames.end(); ++it) m_TerrainGroups.Add(it->c_str()); @@ -199,7 +294,7 @@ public: wxString visibleName = m_TerrainGroups[i]; if (visibleName.Len()) visibleName[0] = wxToupper(visibleName[0]); - AddPage(new TextureNotebookPage(this, m_TerrainGroups[i]), visibleName); + AddPage(new TextureNotebookPage(m_ScenarioEditor, this, m_TerrainGroups[i]), visibleName); } } @@ -214,7 +309,9 @@ protected: } private: + ScenarioEditor& m_ScenarioEditor; wxArrayString m_TerrainGroups; + DECLARE_EVENT_TABLE(); }; @@ -224,11 +321,11 @@ END_EVENT_TABLE(); ////////////////////////////////////////////////////////////////////////// -TerrainBottomBar::TerrainBottomBar(wxWindow* parent) - : wxPanel(parent, wxID_ANY) +TerrainBottomBar::TerrainBottomBar(ScenarioEditor& scenarioEditor, wxWindow* parent) : + wxPanel(parent, wxID_ANY) { wxSizer* sizer = new wxBoxSizer(wxVERTICAL); - m_Textures = new TextureNotebook(this); + m_Textures = new TextureNotebook(scenarioEditor, this); sizer->Add(m_Textures, wxSizerFlags().Expand().Proportion(1)); SetSizer(sizer); } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h index 719b2a2cdf..d9bb46cb4e 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,4 +24,12 @@ public: protected: virtual void OnFirstDisplay(); + +private: + void OnPassabilityChoice(wxCommandEvent& evt); + void OnShowPriorities(wxCommandEvent& evt); + + wxChoice* m_PassabilityChoice; + + DECLARE_EVENT_TABLE(); }; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp index 5158cd5ea3..ccbc8027e1 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Brushes.cpp @@ -203,9 +203,9 @@ void Brush::CreateUI(wxWindow* parent, wxSizer* sizer) // TODO: These are yucky wxSizer* spinnerSizer = new wxFlexGridSizer(2); - spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Size"))); + spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Size")), wxSizerFlags().Right()); spinnerSizer->Add(new BrushSizeCtrl(parent, *this)); - spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Strength"))); + spinnerSizer->Add(new wxStaticText(parent, wxID_ANY, _("Strength")), wxSizerFlags().Right()); spinnerSizer->Add(new BrushStrengthCtrl(parent, *this)); sizer->Add(spinnerSizer); } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.cpp index 171267f41a..290b224457 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.cpp @@ -39,6 +39,11 @@ void ObjectSettings::SetPlayerID(int playerID) PostToGame(); } +void ObjectSettings::SetView(int view) +{ + m_View = view; +} + const std::set& ObjectSettings::GetActorSelections() const { return m_ActorSelections; @@ -53,7 +58,7 @@ void ObjectSettings::SetActorSelections(const std::set& selections) const std::vector ObjectSettings::GetActorVariation() const { std::vector variation; - + for (std::vector::const_iterator grp = m_VariantGroups.begin(); grp != m_VariantGroups.end(); ++grp) @@ -107,7 +112,7 @@ void ObjectSettings::OnSelectionChange(const std::vector if (selection.empty()) return; - + AtlasMessage::qGetObjectSettings qry (m_View, selection[0]); qry.Post(); @@ -116,7 +121,7 @@ void ObjectSettings::OnSelectionChange(const std::vector m_ActorSelections.clear(); m_VariantGroups.clear(); - std::vector > variation = *qry.settings->variantgroups; + std::vector > variation = *qry.settings->variantGroups; for (std::vector >::iterator grp = variation.begin(); grp != variation.end(); ++grp) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.h index 9d16d34b89..7866044a3f 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/ObjectSettings.h @@ -39,6 +39,8 @@ public: size_t GetPlayerID() const; void SetPlayerID(int playerID); + void SetView(int view); + struct Group { wxArrayString variants; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp index 8e6ac850e6..d9224f06f5 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,9 +34,8 @@ struct ToolManagerImpl { ToolManagerImpl() : CurrentTool(&dummy) {} - ITool* CurrentTool; + ObservablePtr CurrentTool; wxString CurrentToolName; - }; ToolManager::ToolManager(ScenarioEditor* scenarioEditor) @@ -49,19 +48,19 @@ ToolManager::~ToolManager() delete m; } -ITool& ToolManager::GetCurrentTool() +ObservablePtr& ToolManager::GetCurrentTool() { - return *m->CurrentTool; + return m->CurrentTool; } void SetActive(bool active, const wxString& name); void ToolManager::SetCurrentTool(const wxString& name, void* initData) { - if (m->CurrentTool != &dummy) + if (*m->CurrentTool != &dummy) { m->CurrentTool->Shutdown(); - delete m->CurrentTool; + delete *m->CurrentTool; m->CurrentTool = &dummy; } @@ -82,6 +81,8 @@ void ToolManager::SetCurrentTool(const wxString& name, void* initData) m->CurrentToolName = name; SetActive(true, m->CurrentToolName); + + m->CurrentTool.NotifyObservers(); } ////////////////////////////////////////////////////////////////////////// diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h index e9c1ca9a30..5e606d3522 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2011 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -19,6 +19,7 @@ #define INCLUDED_TOOLS #include "General/AtlasWindowCommand.h" +#include "General/Observable.h" class wxMouseEvent; class wxKeyEvent; @@ -44,7 +45,7 @@ class ToolManager public: ToolManager(ScenarioEditor* scenarioEditor); ~ToolManager(); - ITool& GetCurrentTool(); + ObservablePtr& GetCurrentTool(); void SetCurrentTool(const wxString& name, void* initData = NULL); private: ToolManagerImpl* m; diff --git a/source/tools/atlas/GameInterface/View.cpp b/source/tools/atlas/GameInterface/View.cpp index 7b77ca22ac..133155f830 100644 --- a/source/tools/atlas/GameInterface/View.cpp +++ b/source/tools/atlas/GameInterface/View.cpp @@ -31,6 +31,7 @@ #include "graphics/UnitManager.h" #include "lib/timer.h" #include "lib/utf8.h" +#include "maths/MathUtil.h" #include "ps/Game.h" #include "ps/GameSetup/GameSetup.h" #include "ps/World.h" @@ -79,7 +80,7 @@ void ViewActor::Render() SViewPort vp = { 0, 0, g_xres, g_yres }; CCamera& camera = GetCamera(); camera.SetViewPort(vp); - camera.SetProjection(CGameView::defaultNear, CGameView::defaultFar, CGameView::defaultFOV); + camera.SetProjection(2.f, 512.f, DEGTORAD(20.f)); camera.UpdateFrustum(); m_ActorViewer->Render();