diff --git a/source/simulation2/components/CCmpCinemaManager.cpp b/source/simulation2/components/CCmpCinemaManager.cpp index 8b0879dc0e..a43c76ac86 100644 --- a/source/simulation2/components/CCmpCinemaManager.cpp +++ b/source/simulation2/components/CCmpCinemaManager.cpp @@ -197,6 +197,17 @@ public: m_PathQueue.clear(); } + virtual void DeletePath(const CStrW& name) + { + if (!HasPath(name)) + { + LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8()); + return; + } + m_PathQueue.remove_if([name](const CCinemaPath& path) { return path.GetName() == name; }); + m_Paths.erase(name); + } + virtual const std::map& GetPaths() const { return m_Paths; diff --git a/source/simulation2/components/ICmpCinemaManager.cpp b/source/simulation2/components/ICmpCinemaManager.cpp index da8ad66691..08167f138c 100644 --- a/source/simulation2/components/ICmpCinemaManager.cpp +++ b/source/simulation2/components/ICmpCinemaManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,7 @@ BEGIN_INTERFACE_WRAPPER(CinemaManager) DEFINE_INTERFACE_METHOD_1("AddPath", void, ICmpCinemaManager, AddPath, CCinemaPath) DEFINE_INTERFACE_METHOD_1("AddCinemaPathToQueue", void, ICmpCinemaManager, AddCinemaPathToQueue, CStrW) +DEFINE_INTERFACE_METHOD_1("DeletePath", void, ICmpCinemaManager, DeletePath, CStrW) DEFINE_INTERFACE_METHOD_0("Play", void, ICmpCinemaManager, Play) DEFINE_INTERFACE_METHOD_0("Stop", void, ICmpCinemaManager, Stop) END_INTERFACE_WRAPPER(CinemaManager) diff --git a/source/simulation2/components/ICmpCinemaManager.h b/source/simulation2/components/ICmpCinemaManager.h index 813eb575f7..5fec802922 100644 --- a/source/simulation2/components/ICmpCinemaManager.h +++ b/source/simulation2/components/ICmpCinemaManager.h @@ -54,6 +54,8 @@ public: */ virtual bool HasPath(const CStrW& name) const = 0; + virtual void DeletePath(const CStrW& name) = 0; + /** * Clears the playlist */ diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.cpp index 01839a1699..60bc0c0646 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.cpp @@ -27,6 +27,9 @@ using AtlasMessage::Shareable; enum { ID_PathsDrawing, + ID_PathsList, + ID_AddPath, + ID_DeletePath }; // Helper function for adding tooltips @@ -52,19 +55,34 @@ CinemaSidebar::CinemaSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarCo gridSizer->AddGrowableCol(1); gridSizer->Add(Tooltipped(m_DrawPath = new wxCheckBox(scrolledWindow, ID_PathsDrawing, _("Draw all paths")), - _("Display every cinematic path added to the map"))); + _("Display every cinematic path added to the map"))); commonSizer->Add(gridSizer, wxSizerFlags().Expand()); + + // Paths list panel + wxSizer* pathsSizer = new wxStaticBoxSizer(wxVERTICAL, scrolledWindow, _T("Paths")); + scrollSizer->Add(pathsSizer, wxSizerFlags().Proportion(1).Expand()); + + pathsSizer->Add(m_PathList = new wxListBox(scrolledWindow, ID_PathsList, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_SORT), wxSizerFlags().Proportion(1).Expand()); + scrollSizer->AddSpacer(3); + pathsSizer->Add(Tooltipped(new wxButton(scrolledWindow, ID_DeletePath, _("Delete")), _T("Delete selected path")), wxSizerFlags().Expand()); + + pathsSizer->Add(m_NewPathName = new wxTextCtrl(scrolledWindow, wxID_ANY), wxSizerFlags().Expand()); + pathsSizer->Add(new wxButton(scrolledWindow, ID_AddPath, _("Add")), wxSizerFlags().Expand()); } void CinemaSidebar::OnFirstDisplay() { m_DrawPath->SetValue(false); + + ReloadPathList(); } void CinemaSidebar::OnMapReload() { m_DrawPath->SetValue(false); + + ReloadPathList(); } void CinemaSidebar::OnTogglePathsDrawing(wxCommandEvent& evt) @@ -72,6 +90,47 @@ void CinemaSidebar::OnTogglePathsDrawing(wxCommandEvent& evt) POST_COMMAND(SetCinemaPathsDrawing, (evt.IsChecked())); } +void CinemaSidebar::OnAddPath(wxCommandEvent&) +{ + if (m_NewPathName->GetValue().empty()) + return; + + POST_COMMAND(AddCinemaPath, (m_NewPathName->GetValue().ToStdWstring())); + m_NewPathName->Clear(); + ReloadPathList(); +} + +void CinemaSidebar::OnDeletePath(wxCommandEvent&) +{ + int index = m_PathList->GetSelection(); + if (index < 0) + return; + + wxString pathName = m_PathList->GetString(index); + if (pathName.empty()) + return; + + POST_COMMAND(DeleteCinemaPath, (pathName.ToStdWstring())); + ReloadPathList(); +} + +void CinemaSidebar::ReloadPathList() +{ + int index = m_PathList->GetSelection(); + wxString pathName; + if (index >= 0) + pathName = m_PathList->GetString(index); + + AtlasMessage::qGetCinemaPaths query_paths; + query_paths.Post(); + + m_PathList->Clear(); + for (const AtlasMessage::sCinemaPath& path : *query_paths.paths) + m_PathList->Append(*path.name); +} + BEGIN_EVENT_TABLE(CinemaSidebar, Sidebar) EVT_CHECKBOX(ID_PathsDrawing, CinemaSidebar::OnTogglePathsDrawing) +EVT_BUTTON(ID_AddPath, CinemaSidebar::OnAddPath) +EVT_BUTTON(ID_DeletePath, CinemaSidebar::OnDeletePath) END_EVENT_TABLE(); diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.h b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.h index 5af5e5d791..d4d9e16d75 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.h +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Cinema/Cinema.h @@ -24,6 +24,10 @@ public: virtual void OnMapReload(); virtual void OnTogglePathsDrawing(wxCommandEvent& evt); + virtual void OnAddPath(wxCommandEvent& evt); + virtual void OnDeletePath(wxCommandEvent& evt); + + void ReloadPathList(); protected: virtual void OnFirstDisplay(); @@ -31,6 +35,8 @@ protected: private: wxScrolledWindow* scrolledWindow; wxCheckBox* m_DrawPath; + wxListBox* m_PathList; + wxTextCtrl* m_NewPathName; DECLARE_EVENT_TABLE(); }; diff --git a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp index 3b8599d6bb..3500989f10 100644 --- a/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp +++ b/source/tools/atlas/GameInterface/Handlers/CinemaHandler.cpp @@ -176,6 +176,71 @@ MESSAGEHANDLER(CinemaEvent) ENSURE(false); } +BEGIN_COMMAND(AddCinemaPath) +{ + void Do() + { + CmpPtr cmpCinemaManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); + if (!cmpCinemaManager) + return; + + CCinemaData pathData; + pathData.m_Name = *msg->pathName; + pathData.m_Timescale = fixed::FromInt(1); + pathData.m_Orientation = L"target"; + pathData.m_Mode = L"ease_inout"; + pathData.m_Style = L"default"; + + CVector3D focus = g_Game->GetView()->GetCamera()->GetFocus(); + CFixedVector3D target( + fixed::FromFloat(focus.X), + fixed::FromFloat(focus.Y), + fixed::FromFloat(focus.Z) + ); + + CVector3D camera = g_Game->GetView()->GetCamera()->GetOrientation().GetTranslation(); + CFixedVector3D position( + fixed::FromFloat(camera.X), + fixed::FromFloat(camera.Y), + fixed::FromFloat(camera.Z) + ); + + TNSpline positionSpline; + positionSpline.AddNode(position, CFixedVector3D(), fixed::FromInt(0)); + + TNSpline targetSpline; + targetSpline.AddNode(target, CFixedVector3D(), fixed::FromInt(0)); + + cmpCinemaManager->AddPath(CCinemaPath(pathData, positionSpline, targetSpline)); + } + void Redo() + { + } + void Undo() + { + } +}; +END_COMMAND(AddCinemaPath) + +BEGIN_COMMAND(DeleteCinemaPath) +{ + void Do() + { + CmpPtr cmpCinemaManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY); + if (!cmpCinemaManager) + return; + + cmpCinemaManager->DeletePath(*msg->pathName); + } + void Redo() + { + } + void Undo() + { + } +}; +END_COMMAND(DeleteCinemaPath) + BEGIN_COMMAND(SetCinemaPaths) { std::vector m_oldPaths, m_newPaths; diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index 206b7585af..eb077e82c5 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -654,6 +654,10 @@ QUERY(GetCameraInfo, ((AtlasMessage::sCameraInfo, info)) ); +COMMAND(AddCinemaPath, NOMERGE, ((std::wstring, pathName))); + +COMMAND(DeleteCinemaPath, NOMERGE, ((std::wstring, pathName))); + COMMAND(SetCinemaPaths, NOMERGE, ((std::vector, paths)) );