1
0
forked from 0ad/0ad

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.
This commit is contained in:
Ykkrosh 2011-05-27 21:56:43 +00:00
parent 4496fcd2df
commit 07e307c49a
18 changed files with 595 additions and 172 deletions

View File

@ -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",

View File

@ -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 <typename T1, typename T2>
explicit Observable(T1& a1, T2& a2) : T(a1, a2) {}
template <typename T1, typename T2>
explicit Observable(T1& a1, T2 a2) : T(a1, a2) {}
template<typename C> ObservableConnection RegisterObserver(int order, void (C::*callback) (const T&), C* obj)
{
@ -94,16 +96,84 @@ public:
}
}
Observable<T>* operator=(const T& rhs)
Observable<T>& operator=(const T& rhs)
{
*dynamic_cast<T*>(this) = rhs;
return this;
return *this;
}
private:
boost::signal<void (const T&)> m_Signal;
};
// A similar thing, but for wrapping pointers instead of objects
template <typename T> 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<typename C> 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<void (T*)> m_Signal;
};
class ObservableScopedConnections
{
public:

View File

@ -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;
}
}

View File

@ -61,7 +61,7 @@ public:
static float GetSpeedModifier();
ScriptInterface& GetScriptInterface() const { return m_ScriptInterface; }
ObjectSettings& GetObjectSettings() { return m_ObjectSettings; }
Observable<ObjectSettings>& GetObjectSettings() { return m_ObjectSettings; }
ToolManager& GetToolManager() { return m_ToolManager; }

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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);

View File

@ -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<wxStringClientData*>(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>& objectSettings);
ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& 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<AtlasMessage::sObjectsListItem> 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<ObjectBottomBar*>(m_BottomBar)->ShowActorViewer(p->m_ActorViewerActive);
}
void ObjectSidebar::OnFirstDisplay()
{
static_cast<ObjectBottomBar*>(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<wxStringClientData*>(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,10 +249,55 @@ END_EVENT_TABLE();
//////////////////////////////////////////////////////////////////////////
ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& objectSettings)
: wxPanel(parent, wxID_ANY)
ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& 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
@ -196,13 +311,88 @@ ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& 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();

View File

@ -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();
};

View File

@ -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

View File

@ -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<std::wstring> passClasses = *qry.classNames;
for (size_t i = 0; i < passClasses.size(); ++i)
m_PassabilityChoice->Append(passClasses[i]);
static_cast<TerrainBottomBar*>(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<AtlasMessage::sTerrainGroupPreview> previews = *qry.previews;
int i = 0;
for (std::vector<AtlasMessage::sTerrainGroupPreview>::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<unsigned char>*, 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<unsigned char>*, 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<wxStringClientData*>(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<std::wstring> groupnames = *qry.groupnames;
std::vector<std::wstring> groupnames = *qry.groupNames;
for (std::vector<std::wstring>::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);
}

View File

@ -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();
};

View File

@ -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);
}

View File

@ -39,6 +39,11 @@ void ObjectSettings::SetPlayerID(int playerID)
PostToGame();
}
void ObjectSettings::SetView(int view)
{
m_View = view;
}
const std::set<wxString>& ObjectSettings::GetActorSelections() const
{
return m_ActorSelections;
@ -116,7 +121,7 @@ void ObjectSettings::OnSelectionChange(const std::vector<AtlasMessage::ObjectID>
m_ActorSelections.clear();
m_VariantGroups.clear();
std::vector<std::vector<std::wstring> > variation = *qry.settings->variantgroups;
std::vector<std::vector<std::wstring> > variation = *qry.settings->variantGroups;
for (std::vector<std::vector<std::wstring> >::iterator grp = variation.begin();
grp != variation.end();
++grp)

View File

@ -39,6 +39,8 @@ public:
size_t GetPlayerID() const;
void SetPlayerID(int playerID);
void SetView(int view);
struct Group
{
wxArrayString variants;

View File

@ -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<ITool> CurrentTool;
wxString CurrentToolName;
};
ToolManager::ToolManager(ScenarioEditor* scenarioEditor)
@ -49,19 +48,19 @@ ToolManager::~ToolManager()
delete m;
}
ITool& ToolManager::GetCurrentTool()
ObservablePtr<ITool>& 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();
}
//////////////////////////////////////////////////////////////////////////

View File

@ -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<ITool>& GetCurrentTool();
void SetCurrentTool(const wxString& name, void* initData = NULL);
private:
ToolManagerImpl* m;

View File

@ -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();