diff --git a/source/graphics/UnitManager.cpp b/source/graphics/UnitManager.cpp index d7e37ddfd6..07f375fc33 100755 --- a/source/graphics/UnitManager.cpp +++ b/source/graphics/UnitManager.cpp @@ -116,7 +116,7 @@ CUnit* CUnitManager::PickUnit(const CVector3D& origin,const CVector3D& dir) cons /////////////////////////////////////////////////////////////////////////////// // CreateUnit: create a new unit and add it to the world -CUnit* CUnitManager::CreateUnit(CStr& actorName, CEntity* entity) +CUnit* CUnitManager::CreateUnit(const CStr& actorName, CEntity* entity) { CObjectEntry* obj = g_ObjMan.FindObject(actorName); diff --git a/source/graphics/UnitManager.h b/source/graphics/UnitManager.h index 35f2e8480e..3b3b339c75 100755 --- a/source/graphics/UnitManager.h +++ b/source/graphics/UnitManager.h @@ -40,7 +40,7 @@ public: void DeleteAll(); // creates a new unit and adds it to the world - CUnit* CreateUnit(CStr& actorName, CEntity* entity); + CUnit* CreateUnit(const CStr& actorName, CEntity* entity); // return the units const std::vector& GetUnits() const { return m_Units; } diff --git a/source/tools/atlas/AtlasUI/CustomControls/Buttons/ToolButton.cpp b/source/tools/atlas/AtlasUI/CustomControls/Buttons/ToolButton.cpp index e2be7a0938..f4441ca58e 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/Buttons/ToolButton.cpp +++ b/source/tools/atlas/AtlasUI/CustomControls/Buttons/ToolButton.cpp @@ -26,6 +26,7 @@ void ToolButton::OnClick(wxCommandEvent& WXUNUSED(evt)) { if (g_Current) g_Current->SetSelectedAppearance(false); + // TODO: set disabled when tool is changed via other (non-button) methods // Toggle on/off if (g_Current == this) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 0cb1f264ad..32661d756e 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -57,7 +57,7 @@ public: case WXK_RIGHT: dir = AtlasMessage::eScrollConstantDir::RIGHT; break; case WXK_UP: dir = AtlasMessage::eScrollConstantDir::FORWARDS; break; case WXK_DOWN: dir = AtlasMessage::eScrollConstantDir::BACKWARDS; break; - case WXK_SHIFT: dir = -1; break; + case WXK_SHIFT: case WXK_CONTROL: dir = -1; break; default: return false; } @@ -86,24 +86,54 @@ public: void OnKeyDown(wxKeyEvent& evt) { + if (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 + return; + } + if (KeyScroll(evt, true)) return; - GetCurrentTool().OnKey(evt, ITool::KEY_DOWN); - evt.Skip(); } void OnKeyUp(wxKeyEvent& evt) { + if (GetCurrentTool().OnKey(evt, ITool::KEY_UP)) + return; + if (KeyScroll(evt, false)) return; - GetCurrentTool().OnKey(evt, ITool::KEY_UP); - evt.Skip(); } + void OnChar(wxKeyEvent& evt) + { + if (GetCurrentTool().OnKey(evt, ITool::KEY_CHAR)) + return; + + int dir = 0; + if (evt.GetKeyCode() == '-' || evt.GetKeyCode() == '_') + dir = -1; + else if (evt.GetKeyCode() == '+' || evt.GetKeyCode() == '=') + dir = +1; + // TODO: internationalisation (-/_ and +/= don't always share a key) + + if (dir) + { + float speed = 16.f; + if (wxGetKeyState(WXK_SHIFT)) + speed *= 4.f; + POST_MESSAGE(SmoothZoom(speed*dir)); + } + else + evt.Skip(); + + } + void OnMouseCapture(wxMouseCaptureChangedEvent& WXUNUSED(evt)) { if (m_MouseCaptured) @@ -160,11 +190,12 @@ public: #ifndef UI_ONLY - GetCurrentTool().OnMouse(evt); - - // TODO: if the tool responded to the mouse action, should we avoid moving - // the camera too? (This is mostly avoided by not sharing buttons between - // camera and tools, so maybe it's not a problem.) + if (GetCurrentTool().OnMouse(evt)) + { + // Mouse event has been handled by the tool, so don't try + // to use it for camera motion too + return; + } if (evt.GetWheelRotation()) { @@ -230,6 +261,7 @@ BEGIN_EVENT_TABLE(Canvas, wxGLCanvas) EVT_SIZE (Canvas::OnResize) EVT_KEY_DOWN (Canvas::OnKeyDown) EVT_KEY_UP (Canvas::OnKeyUp) + EVT_CHAR (Canvas::OnChar) EVT_LEFT_DOWN (Canvas::OnMouse) EVT_LEFT_UP (Canvas::OnMouse) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp index 23e7e1ceaa..e1ac853c93 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/SectionLayout.cpp @@ -6,6 +6,7 @@ #include "Sections/Map/Map.h" #include "Sections/Terrain/Terrain.h" +#include "Sections/Object/Object.h" ////////////////////////////////////////////////////////////////////////// @@ -35,6 +36,9 @@ protected: if (event.GetSelection() != -1) newPage = wxDynamicCast(GetPage(event.GetSelection()), Sidebar); + if (newPage) + newPage->OnSwitchTo(); + if (m_Splitter->IsSplit()) { wxWindow* bottom; @@ -103,6 +107,7 @@ void SectionLayout::Build() wxNotebook* sidebar = new SidebarNotebook(m_HorizSplitter, m_VertSplitter); sidebar->AddPage(new MapSidebar(sidebar), _("Map"), false); sidebar->AddPage(new TerrainSidebar(sidebar), _("Terrain"), false); + sidebar->AddPage(new ObjectSidebar(sidebar), _("Object"), false); m_VertSplitter->SetDefaultSashPosition(-165); m_VertSplitter->Initialize(m_Canvas); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.cpp index 0dae31ad61..f4f4be3902 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.cpp @@ -5,7 +5,7 @@ IMPLEMENT_DYNAMIC_CLASS(Sidebar, wxPanel) Sidebar::Sidebar(wxWindow* parent) - : wxPanel(parent) + : wxPanel(parent), m_AlreadyDisplayed(false) { m_MainSizer = new wxBoxSizer(wxVERTICAL); SetSizer(m_MainSizer); @@ -15,3 +15,12 @@ wxWindow* Sidebar::GetBottomBar(wxWindow* WXUNUSED(parent)) { return NULL; } + +void Sidebar::OnSwitchTo() +{ + if (m_AlreadyDisplayed) + return; + + m_AlreadyDisplayed = true; + OnFirstDisplay(); +} diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.h index 7d86349d84..606167be4d 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Common/Sidebar.h @@ -9,12 +9,21 @@ public: Sidebar() {} Sidebar(wxWindow* parent); + void OnSwitchTo(); + virtual wxWindow* GetBottomBar(wxWindow* parent); // called whenever the bottom bar is made visible; should usually be // lazily constructed, then cached forever (to maximise responsiveness) protected: wxSizer* m_MainSizer; // vertical box sizer, used by most sidebars + + virtual void OnFirstDisplay() {} + // should be overridden when sidebars need to do expensive construction, + // so it can be delayed until it is required + +private: + bool m_AlreadyDisplayed; }; #endif // SIDEBAR_H__ diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp new file mode 100644 index 0000000000..628179f849 --- /dev/null +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.cpp @@ -0,0 +1,71 @@ +#include "stdafx.h" + +#include "Object.h" + +#include "Buttons/ActionButton.h" +#include "Buttons/ToolButton.h" +#include "ScenarioEditor/Tools/Common/Tools.h" + +#include "GameInterface/Messages.h" + +class ObjectSelectListBox : public wxListBox +{ +public: + ObjectSelectListBox(wxWindow* parent) + : wxListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE) + { + } + + void OnSelect(wxCommandEvent& evt) + { + wxString id = static_cast(evt.GetClientObject())->GetData(); + SetCurrentTool(_T("PlaceObject"), &id); + } +private: + DECLARE_EVENT_TABLE(); +}; +BEGIN_EVENT_TABLE(ObjectSelectListBox, wxListBox) + EVT_LISTBOX(wxID_ANY, ObjectSelectListBox::OnSelect) +END_EVENT_TABLE(); + +////////////////////////////////////////////////////////////////////////// + +ObjectSidebar::ObjectSidebar(wxWindow* parent) +: Sidebar(parent), m_BottomBar(NULL) +{ + m_ObjectListBox = new ObjectSelectListBox(this); + m_MainSizer->Add(m_ObjectListBox, wxSizerFlags().Proportion(1).Expand()); + +} + +wxWindow* ObjectSidebar::GetBottomBar(wxWindow* parent) +{ + if (m_BottomBar) + return m_BottomBar; + +// m_BottomBar = new ObjectBottomBar(parent); + return m_BottomBar; +} + +void ObjectSidebar::OnFirstDisplay() +{ + AtlasMessage::qGetEntitiesList qry; + qry.Post(); + for (std::vector::iterator it = qry.entities.begin(); it != qry.entities.end(); ++it) + { + wxString name = it->name.c_str(); + m_ObjectListBox->Append(name, new wxStringClientData(name)); + } +} + +////////////////////////////////////////////////////////////////////////// + + +//TerrainBottomBar::TerrainBottomBar(wxWindow* parent) +// : wxPanel(parent, wxID_ANY) +//{ +// wxSizer* sizer = new wxBoxSizer(wxVERTICAL); +// wxNotebook* notebook = new TextureNotebook(this); +// sizer->Add(notebook, wxSizerFlags().Expand().Proportion(1)); +// SetSizer(sizer); +//} diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h new file mode 100644 index 0000000000..ad3fa7fbf4 --- /dev/null +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Object/Object.h @@ -0,0 +1,22 @@ +#include "../Common/Sidebar.h" + +class ObjectSidebar : public Sidebar +{ +public: + ObjectSidebar(wxWindow* parent); + wxWindow* GetBottomBar(wxWindow* parent); + +protected: + void OnFirstDisplay(); + +private: + wxWindow* m_BottomBar; + wxListBox* m_ObjectListBox; +}; + +class ObjectBottomBar : public wxPanel +{ +public: + ObjectBottomBar(wxWindow* parent); +private: +}; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp index c893a37202..88b6969f42 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.cpp @@ -181,4 +181,4 @@ TerrainBottomBar::TerrainBottomBar(wxWindow* parent) wxNotebook* notebook = new TextureNotebook(this); sizer->Add(notebook, wxSizerFlags().Expand().Proportion(1)); SetSizer(sizer); -} \ No newline at end of file +} diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h index db14573965..40ea1ac001 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Terrain/Terrain.h @@ -15,4 +15,4 @@ class TerrainBottomBar : public wxPanel public: TerrainBottomBar(wxWindow* parent); private: -}; \ No newline at end of file +}; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp index 22fab397e6..8599bc9dca 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/AlterElevation.cpp @@ -20,12 +20,12 @@ public: } - void OnEnable(AlterElevation*) + void OnEnable() { g_Brush_Elevation.MakeActive(); } - void OnDisable(AlterElevation*) + void OnDisable() { POST_MESSAGE(BrushPreview(false, Position())); } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp index e524453c1c..e06aaae3b4 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.cpp @@ -5,9 +5,10 @@ class DummyTool : public ITool { + void Init(void*) {} void Shutdown() {} - void OnMouse(wxMouseEvent& evt) { evt.Skip(); } - void OnKey(wxKeyEvent& evt, KeyEventType) { evt.Skip(); } + bool OnMouse(wxMouseEvent& WXUNUSED(evt)) { return false; } + bool OnKey(wxKeyEvent& WXUNUSED(evt), KeyEventType) { return false; } void OnTick(float) {} } dummy; @@ -18,7 +19,7 @@ ITool& GetCurrentTool() return *g_CurrentTool; } -void SetCurrentTool(const wxString& name) +void SetCurrentTool(const wxString& name, void* initData) { if (g_CurrentTool != &dummy) { @@ -31,6 +32,7 @@ void SetCurrentTool(const wxString& name) { tool = wxDynamicCast(wxCreateDynamicObject(name), ITool); wxASSERT(tool); + tool->Init(initData); } if (tool == NULL) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h index 3ffb942e68..f4a19611a1 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/Common/Tools.h @@ -12,16 +12,18 @@ class ITool : public wxObject public: enum KeyEventType { KEY_DOWN, KEY_UP, KEY_CHAR }; + virtual void Init(void* initData) = 0; virtual void Shutdown() = 0; - virtual void OnMouse(wxMouseEvent& evt) = 0; - virtual void OnKey(wxKeyEvent& evt, KeyEventType dir) = 0; + virtual bool OnMouse(wxMouseEvent& evt) = 0; // return true if handled + virtual bool OnKey(wxKeyEvent& evt, KeyEventType dir) = 0; // return true if handled virtual void OnTick(float dt) = 0; // dt in seconds virtual ~ITool() {}; }; extern ITool& GetCurrentTool(); -extern void SetCurrentTool(const wxString& name); // should usually only be used by tool buttons +extern void SetCurrentTool(const wxString& name, void* initData = NULL); + // should usually only be used by tool buttons. (TODO: not true) ////////////////////////////////////////////////////////////////////////// @@ -58,6 +60,10 @@ public: { } + virtual void Init(void* WXUNUSED(initData)) + { + } + virtual void Shutdown() { // This can't be done in the destructor, because ~StateDrivenTool @@ -69,8 +75,8 @@ public: protected: // Called when the tool is enabled/disabled; always called in zero or // more enable-->disable pairs per object instance. - virtual void OnEnable(T* WXUNUSED(obj)) {} - virtual void OnDisable(T* WXUNUSED(obj)) {} + virtual void OnEnable() {} + virtual void OnDisable() {} struct State { @@ -87,8 +93,8 @@ protected: struct sDisabled : public State { - void OnEnter(T* obj) { obj->OnDisable(obj); } - void OnLeave(T* obj) { obj->OnEnable(obj); } + void OnEnter(T* obj) { obj->OnDisable(); } + void OnLeave(T* obj) { obj->OnEnable(); } } Disabled; @@ -103,14 +109,14 @@ protected: private: State* m_CurrentState; - virtual void OnMouse(wxMouseEvent& evt) + virtual bool OnMouse(wxMouseEvent& evt) { - m_CurrentState->OnMouse(static_cast(this), evt); + return m_CurrentState->OnMouse(static_cast(this), evt); } - virtual void OnKey(wxKeyEvent& evt, KeyEventType dir) + virtual bool OnKey(wxKeyEvent& evt, KeyEventType dir) { - m_CurrentState->OnKey(static_cast(this), evt, dir); + return m_CurrentState->OnKey(static_cast(this), evt, dir); } virtual void OnTick(float dt) diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PaintTerrain.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PaintTerrain.cpp index 61f7d14b79..3210c913c3 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PaintTerrain.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PaintTerrain.cpp @@ -20,13 +20,13 @@ public: } - void OnEnable(PaintTerrain*) + void OnEnable() { // TODO: multiple independent brushes? g_Brush_Elevation.MakeActive(); } - void OnDisable(PaintTerrain*) + void OnDisable() { POST_MESSAGE(BrushPreview(false, Position())); } diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp new file mode 100644 index 0000000000..34d04d78fa --- /dev/null +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Tools/PlaceObject.cpp @@ -0,0 +1,161 @@ +#include "stdafx.h" + +#include "Common/Tools.h" +#include "Common/Brushes.h" +#include "Common/MiscState.h" +#include "GameInterface/Messages.h" + +using AtlasMessage::Position; + +static float g_DefaultAngle = M_PI*3.0/4.0; + +class PlaceObject : public StateDrivenTool +{ + DECLARE_DYNAMIC_CLASS(PlaceObject); + + Position m_ScreenPos, m_ObjPos, m_Target; + wxString m_ObjectName; + +public: + PlaceObject() + { + SetState(&Waiting); + } + + void SendPreviewCommand() + { + int dragDistSq = + (m_ScreenPos.type1.x-m_Target.type1.x)*(m_ScreenPos.type1.x-m_Target.type1.x) + + (m_ScreenPos.type1.y-m_Target.type1.y)*(m_ScreenPos.type1.y-m_Target.type1.y); + bool useTarget = (dragDistSq >= 8*8); + POST_MESSAGE(EntityPreview(m_ObjectName.c_str(), m_ObjPos, useTarget, m_Target, g_DefaultAngle)); + } + + virtual void Init(void* initData) + { + wxASSERT(initData); + wxString& name = *static_cast(initData); + m_ObjectName = name; + SendPreviewCommand(); + } + + void OnEnable() + { + } + + void OnDisable() + { + m_ObjectName = _T(""); + SendPreviewCommand(); + } + + /* + Object placement: + * Select unit from list + * Move mouse around screen; preview of unit follows mouse + * Left mouse down -> remember position, fix preview to point + * Mouse move -> if moved > 8px, rotate unit to face mouse; else default orientation + * Left mouse release -> finalise placement of object on map + + * Scroll wheel -> rotate default orientation + + * Escape -> cancel placement tool + + TOOD: what happens if somebody saves while the preview is active? + */ + + bool OnMouseOverride(wxMouseEvent& evt) + { + if (evt.GetWheelRotation()) + { + float speed = M_PI/36.f; + if (wxGetKeyState(WXK_SHIFT) && wxGetKeyState(WXK_CONTROL)) + speed /= 64.f; + else if (wxGetKeyState(WXK_CONTROL)) + speed /= 4.f; + else if (wxGetKeyState(WXK_SHIFT)) + speed *= 4.f; + g_DefaultAngle += (evt.GetWheelRotation() * speed / evt.GetWheelDelta()); + SendPreviewCommand(); + return true; + } + else + return false; + } + + bool OnKeyOverride(wxKeyEvent& evt, KeyEventType dir) + { + if (dir == KEY_CHAR && evt.GetKeyCode() == WXK_ESCAPE) + { + SetState(&Disabled); + return true; + } + // TODO: arrow keys for rotation? + else + return false; + } + + + struct sWaiting : public State + { + bool OnMouse(PlaceObject* obj, wxMouseEvent& evt) + { + if (obj->OnMouseOverride(evt)) + return true; + else if (evt.LeftDown()) + { + obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target = Position(evt.GetPosition()); + obj->SendPreviewCommand(); + obj->m_ObjPos = Position::Unchanged(); // make sure object is stationary even if the camera moves + SET_STATE(Placing); + return true; + } + else if (evt.Moving()) + { + obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target = Position(evt.GetPosition()); + obj->SendPreviewCommand(); + return true; + } + else + return false; + } + bool OnKey(PlaceObject* obj, wxKeyEvent& evt, KeyEventType dir) + { + return obj->OnKeyOverride(evt, dir); + } + } + Waiting; + + struct sPlacing : public State + { + bool OnMouse(PlaceObject* obj, wxMouseEvent& evt) + { + if (obj->OnMouseOverride(evt)) + return true; + else if (evt.LeftUp()) + { + obj->m_Target = Position(evt.GetPosition()); + // TODO: createobject command, so you can actually place an object + SET_STATE(Waiting); + obj->m_ObjPos = obj->m_ScreenPos = obj->m_Target; + obj->SendPreviewCommand(); + return true; + } + else if (evt.Moving()) + { + obj->m_Target = Position(evt.GetPosition()); + obj->SendPreviewCommand(); + return true; + } + else + return false; + } + bool OnKey(PlaceObject* obj, wxKeyEvent& evt, KeyEventType dir) + { + return obj->OnKeyOverride(evt, dir); + } + } + Placing; +}; + +IMPLEMENT_DYNAMIC_CLASS(PlaceObject, StateDrivenTool); diff --git a/source/tools/atlas/AtlasUI/TODO.txt b/source/tools/atlas/AtlasUI/TODO.txt index d6159cc33c..413aa1b39b 100644 --- a/source/tools/atlas/AtlasUI/TODO.txt +++ b/source/tools/atlas/AtlasUI/TODO.txt @@ -1,3 +1,9 @@ +wxWidgets: +* alt+f with notebook tab focussed +* wxLogTrace "%s" wxGetMessage (msw/window.cpp) + +============================== + Colour tester: ============================== @@ -74,7 +80,6 @@ General and/or unsorted miscellany: * Don't create a row when editing a blank one then removing focus without typing anything - ====== Done: (newest at top) diff --git a/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp new file mode 100644 index 0000000000..03537599d1 --- /dev/null +++ b/source/tools/atlas/GameInterface/Handlers/ObjectHandlers.cpp @@ -0,0 +1,87 @@ +#include "precompiled.h" + +#include "MessageHandler.h" + +#include "simulation/BaseEntityCollection.h" +#include "graphics/Unit.h" +#include "graphics/UnitManager.h" +#include "graphics/Model.h" +#include "maths/Matrix3D.h" + +namespace AtlasMessage { + +QUERYHANDLER(GetEntitiesList) +{ + std::vector names; + g_EntityTemplateCollection.getBaseEntityNames(names); + for (std::vector::iterator it = names.begin(); it != names.end(); ++it) + { + sEntitiesListItem e; + e.name = *it; + msg->entities.push_back(e); + } +} + + +static CUnit* g_PreviewUnit = NULL; +static CStrW g_PreviewUnitName; + +MESSAGEHANDLER(EntityPreview) +{ + if (msg->name != g_PreviewUnitName) + { + // Delete old unit + if (g_PreviewUnit) + { + g_UnitMan.RemoveUnit(g_PreviewUnit); + delete g_PreviewUnit; + g_PreviewUnit = NULL; + } + + if (msg->name.length()) + { + // Create new unit + CBaseEntity* base = g_EntityTemplateCollection.getTemplate(msg->name); + if (base) + { + g_PreviewUnit = g_UnitMan.CreateUnit(base->m_actorName, 0); + // TODO: set player (for colour) + // TODO: variations + } + + } + g_PreviewUnitName = msg->name; + } + + // Position/orient unit + if (g_PreviewUnit) + { + static CVector3D pos; + msg->pos.GetWorldSpace(pos, pos); // if msg->pos is 'Unchanged', use the previous pos + + float s, c; +/* + if (msg->usetarget) + { + // TODO + s=1; c=0; + } + else +*/ + { + s = sin(msg->angle); + c = cos(msg->angle); + } + + CMatrix3D m; + m._11 = -c; m._12 = 0.0f; m._13 = -s; m._14 = pos.X; + m._21 = 0.0f; m._22 = 1.0f; m._23 = 0.0f; m._24 = pos.Y; + m._31 = s; m._32 = 0.0f; m._33 = -c; m._34 = pos.Z; + m._41 = 0.0f; m._42 = 0.0f; m._43 = 0.0f; m._44 = 1.0f; + g_PreviewUnit->GetModel()->SetTransform(m); + } + +} + + +} diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 317b6ce6ec..a26df4cda6 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -3,6 +3,8 @@ #include "MessagesSetup.h" +// TODO: organisation, documentation, etc + ////////////////////////////////////////////////////////////////////////// MESSAGE(CommandString, @@ -83,6 +85,28 @@ QUERY(GetTerrainGroupPreviews, ); +////////////////////////////////////////////////////////////////////////// + +struct sEntitiesListItem +{ + std::wstring name; + // ... +}; +QUERY(GetEntitiesList, + , // no inputs + ((std::vector, entities)) + ); + +MESSAGE(EntityPreview, + ((std::wstring, name)) // or empty string => disable + ((Position, pos)) + ((bool, usetarget)) // true => use 'target' for orientation; false => use 'angle' + ((Position, target)) + ((float, angle)) + ); + +////////////////////////////////////////////////////////////////////////// + QUERY(Exit,,); // no inputs nor outputs //////////////////////////////////////////////////////////////////////////