Restore some old Atlas files

This was SVN commit r9558.
This commit is contained in:
Ykkrosh 2011-05-27 21:48:23 +00:00
parent 755802d0ce
commit 4496fcd2df
10 changed files with 1025 additions and 28 deletions

View File

@ -0,0 +1,168 @@
#include "stdafx.h"
#include "Map.h"
#include "General/Datafile.h"
#include "ScenarioEditor/Tools/Common/Tools.h"
#include "GameInterface/Messages.h"
#include "wx/filename.h"
enum
{
ID_GenerateMap,
ID_GenerateRMS,
ID_SimPlay,
ID_SimFast,
ID_SimSlow,
ID_SimPause,
ID_SimReset
};
enum
{
SimInactive,
SimPlaying,
SimPlayingFast,
SimPlayingSlow,
SimPaused
};
bool IsPlaying(int s) { return (s == SimPlaying || s == SimPlayingFast || s == SimPlayingSlow); }
MapSidebar::MapSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer)
: Sidebar(sidebarContainer, bottomBarContainer), m_SimState(SimInactive)
{
// TODO: Less ugliness
// TODO: Intercept arrow keys and send them to the GL window
m_MainSizer->Add(new wxButton(this, ID_GenerateMap, _("Generate empty map")));
{
wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
m_RMSText = new wxTextCtrl(this, wxID_ANY, _T("cantabrian_highlands"));
sizer->Add(m_RMSText);
sizer->Add(new wxButton(this, ID_GenerateRMS, _("Generate RMS")));
m_MainSizer->Add(sizer);
}
{
wxStaticBoxSizer* sizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Simulation test"));
sizer->Add(new wxButton(this, ID_SimPlay, _("Play")), wxSizerFlags().Proportion(1));
sizer->Add(new wxButton(this, ID_SimFast, _("Fast")), wxSizerFlags().Proportion(1));
sizer->Add(new wxButton(this, ID_SimSlow, _("Slow")), wxSizerFlags().Proportion(1));
sizer->Add(new wxButton(this, ID_SimPause, _("Pause")), wxSizerFlags().Proportion(1));
sizer->Add(new wxButton(this, ID_SimReset, _("Reset")), wxSizerFlags().Proportion(1));
UpdateSimButtons();
m_MainSizer->Add(sizer, wxSizerFlags().Expand().Border(wxTOP, 16));
}
}
void MapSidebar::GenerateMap(wxCommandEvent& WXUNUSED(event))
{
POST_MESSAGE(GenerateMap, (9));
}
void MapSidebar::GenerateRMS(wxCommandEvent& WXUNUSED(event))
{
wxChar* argv[] = { _T("rmgen.exe"), 0, _T("_atlasrm"), 0 };
wxString scriptName = m_RMSText->GetValue();
argv[1] = const_cast<wxChar*>(scriptName.c_str());
wxString cwd = wxFileName::GetCwd();
wxFileName::SetCwd(Datafile::GetDataDirectory());
wxExecute(argv, wxEXEC_SYNC);
wxFileName::SetCwd(cwd);
POST_MESSAGE(LoadMap, (L"_atlasrm.pmp"));
}
void MapSidebar::UpdateSimButtons()
{
wxButton* button;
button = wxDynamicCast(FindWindow(ID_SimPlay), wxButton);
wxCHECK(button, );
button->Enable(m_SimState != SimPlaying);
button = wxDynamicCast(FindWindow(ID_SimFast), wxButton);
wxCHECK(button, );
button->Enable(m_SimState != SimPlayingFast);
button = wxDynamicCast(FindWindow(ID_SimSlow), wxButton);
wxCHECK(button, );
button->Enable(m_SimState != SimPlayingSlow);
button = wxDynamicCast(FindWindow(ID_SimPause), wxButton);
wxCHECK(button, );
button->Enable(IsPlaying(m_SimState));
button = wxDynamicCast(FindWindow(ID_SimReset), wxButton);
wxCHECK(button, );
button->Enable(m_SimState != SimInactive);
}
void MapSidebar::OnSimPlay(wxCommandEvent& event)
{
float speed = 1.f;
int newState = SimPlaying;
if (event.GetId() == ID_SimFast)
{
speed = 8.f;
newState = SimPlayingFast;
}
else if (event.GetId() == ID_SimSlow)
{
speed = 0.125f;
newState = SimPlayingSlow;
}
if (m_SimState == SimInactive)
{
POST_MESSAGE(SimStateSave, (L"default", true));
POST_MESSAGE(SimPlay, (speed));
m_SimState = newState;
}
else // paused or already playing at a different speed
{
POST_MESSAGE(SimPlay, (speed));
m_SimState = newState;
}
UpdateSimButtons();
}
void MapSidebar::OnSimPause(wxCommandEvent& WXUNUSED(event))
{
if (IsPlaying(m_SimState))
{
POST_MESSAGE(SimPlay, (0.f));
m_SimState = SimPaused;
}
UpdateSimButtons();
}
void MapSidebar::OnSimReset(wxCommandEvent& WXUNUSED(event))
{
if (IsPlaying(m_SimState))
{
POST_MESSAGE(SimPlay, (0.f));
POST_MESSAGE(SimStateRestore, (L"default"));
m_SimState = SimInactive;
}
else if (m_SimState == SimPaused)
{
POST_MESSAGE(SimStateRestore, (L"default"));
m_SimState = SimInactive;
}
UpdateSimButtons();
}
BEGIN_EVENT_TABLE(MapSidebar, Sidebar)
EVT_BUTTON(ID_GenerateMap, MapSidebar::GenerateMap)
EVT_BUTTON(ID_GenerateRMS, MapSidebar::GenerateRMS)
EVT_BUTTON(ID_SimPlay, MapSidebar::OnSimPlay)
EVT_BUTTON(ID_SimFast, MapSidebar::OnSimPlay)
EVT_BUTTON(ID_SimSlow, MapSidebar::OnSimPlay)
EVT_BUTTON(ID_SimPause, MapSidebar::OnSimPause)
EVT_BUTTON(ID_SimReset, MapSidebar::OnSimReset)
END_EVENT_TABLE();

View File

@ -0,0 +1,22 @@
#include "../Common/Sidebar.h"
class MapSidebar : public Sidebar
{
public:
MapSidebar(wxWindow* sidebarContainer, wxWindow* bottomBarContainer);
private:
void GenerateMap(wxCommandEvent& event);
void GenerateRMS(wxCommandEvent& event);
wxTextCtrl* m_RMSText;
void OnSimPlay(wxCommandEvent& event);
void OnSimPause(wxCommandEvent& event);
void OnSimReset(wxCommandEvent& event);
void UpdateSimButtons();
int m_SimState;
DECLARE_EVENT_TABLE();
};

View File

@ -0,0 +1,208 @@
/* Copyright (C) 2009 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 "Object.h"
#include "Buttons/ToolButton.h"
#include "ScenarioEditor/ScenarioEditor.h"
#include "ScenarioEditor/Tools/Common/ObjectSettings.h"
#include "ScenarioEditor/Tools/Common/MiscState.h"
#include "VariationControl.h"
#include "GameInterface/Messages.h"
#include "wx/busyinfo.h"
class ObjectSelectListBox : public wxListBox
{
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();
};
BEGIN_EVENT_TABLE(ObjectSelectListBox, wxListBox)
EVT_LISTBOX(wxID_ANY, ObjectSelectListBox::OnSelect)
END_EVENT_TABLE();
class ObjectChoiceCtrl : public wxChoice
{
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();
//////////////////////////////////////////////////////////////////////////
class ObjectBottomBar : public wxPanel
{
public:
ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& objectSettings);
};
struct ObjectSidebarImpl
{
ObjectSidebarImpl() : m_BottomBar(NULL), m_ObjectListBox(NULL) { }
wxWindow* m_BottomBar;
wxListBox* m_ObjectListBox;
std::vector<AtlasMessage::sObjectsListItem> m_Objects;
};
ObjectSidebar::ObjectSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer)
: Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer), p(new ObjectSidebarImpl())
{
wxArrayString strings;
strings.Add(_("Entities"));
strings.Add(_("Actors (all)"));
m_MainSizer->Add(new ObjectChoiceCtrl(this, strings, *this), wxSizerFlags().Expand());
p->m_ObjectListBox = new ObjectSelectListBox(this, scenarioEditor.GetToolManager());
m_MainSizer->Add(p->m_ObjectListBox, wxSizerFlags().Proportion(1).Expand());
m_BottomBar = new ObjectBottomBar(bottomBarContainer, scenarioEditor.GetObjectSettings());
}
ObjectSidebar::~ObjectSidebar()
{
delete p;
}
void ObjectSidebar::OnFirstDisplay()
{
wxBusyInfo busy (_("Loading list of objects"));
// Get the list of objects from the game
AtlasMessage::qGetObjectsList qry;
qry.Post();
p->m_Objects = *qry.objects;
// Display first group of objects
SetObjectFilter(0);
}
void ObjectSidebar::SetObjectFilter(int type)
{
p->m_ObjectListBox->Freeze();
p->m_ObjectListBox->Clear();
for (std::vector<AtlasMessage::sObjectsListItem>::iterator it = p->m_Objects.begin(); it != p->m_Objects.end(); ++it)
{
if (it->type == type)
{
wxString id = it->id.c_str();
wxString name = it->name.c_str();
p->m_ObjectListBox->Append(name, new wxStringClientData(id));
}
}
p->m_ObjectListBox->Thaw();
}
//////////////////////////////////////////////////////////////////////////
class PlayerComboBox : public wxComboBox
{
public:
PlayerComboBox(wxWindow* parent, wxArrayString& choices, Observable<ObjectSettings>& objectSettings)
: wxComboBox(parent, -1, choices[objectSettings.GetPlayerID()], wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY)
, m_ObjectSettings(objectSettings)
{
m_Conn = m_ObjectSettings.RegisterObserver(1, &PlayerComboBox::OnObjectSettingsChange, this);
}
private:
ObservableScopedConnection m_Conn;
Observable<ObjectSettings>& m_ObjectSettings;
void OnObjectSettingsChange(const ObjectSettings& settings)
{
SetSelection((long)settings.GetPlayerID());
}
void OnSelect(wxCommandEvent& evt)
{
m_ObjectSettings.SetPlayerID(evt.GetInt());
m_ObjectSettings.NotifyObserversExcept(m_Conn);
}
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(PlayerComboBox, wxComboBox)
EVT_COMBOBOX(wxID_ANY, PlayerComboBox::OnSelect)
END_EVENT_TABLE();
//////////////////////////////////////////////////////////////////////////
ObjectBottomBar::ObjectBottomBar(wxWindow* parent, Observable<ObjectSettings>& objectSettings)
: wxPanel(parent, wxID_ANY)
{
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxArrayString players;
// TODO: get proper player names
players.Add(_("Gaia"));
players.Add(_("Player 1"));
players.Add(_("Player 2"));
players.Add(_("Player 3"));
players.Add(_("Player 4"));
players.Add(_("Player 5"));
players.Add(_("Player 6"));
players.Add(_("Player 7"));
players.Add(_("Player 8"));
wxComboBox* playerSelect = new PlayerComboBox(this, players, objectSettings);
sizer->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));
SetSizer(sizer);
}

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2009 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"
struct ObjectSidebarImpl;
class ObjectSidebar : public Sidebar
{
public:
ObjectSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer);
~ObjectSidebar();
void SetObjectFilter(int type);
protected:
virtual void OnFirstDisplay();
private:
ObjectSidebarImpl* p;
};

View File

@ -0,0 +1,146 @@
/* Copyright (C) 2009 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 "VariationControl.h"
#include "ScenarioEditor/Tools/Common/ObjectSettings.h"
VariationControl::VariationControl(wxWindow* parent, Observable<ObjectSettings>& objectSettings)
: wxScrolledWindow(parent, -1),
m_ObjectSettings(objectSettings)
{
m_Conn = m_ObjectSettings.RegisterObserver(1, &VariationControl::OnObjectSettingsChange, this);
SetScrollRate(0, 5);
m_Sizer = new wxBoxSizer(wxVERTICAL);
SetSizer(m_Sizer);
}
// Event handler shared by all the combo boxes created by this window
void VariationControl::OnSelect(wxCommandEvent& evt)
{
std::set<wxString> selections;
// It's possible for a variant name to appear in multiple groups.
// If so, assume that all the names in each group are the same, so
// we don't have to worry about some impossible combinations (e.g.
// one group "a,b", a second "b,c", and a third "c,a", where's there's
// no set of selections that matches one (and only one) of each group).
//
// So... When a combo box is changed from 'a' to 'b', add 'b' to the new
// selections and make sure any other combo boxes containing both 'a' and
// 'b' no longer contain 'a'.
wxComboBox* thisComboBox = wxDynamicCast(evt.GetEventObject(), wxComboBox);
wxCHECK(thisComboBox != NULL, );
wxString newValue = thisComboBox->GetValue();
selections.insert(newValue);
for (size_t i = 0; i < m_ComboBoxes.size(); ++i)
{
wxComboBox* comboBox = m_ComboBoxes[i];
// If our newly selected value is used in another combobox, we want
// that combobox to use the new value, so don't add its old value
// to the list of selections
if (comboBox->FindString(newValue) == wxNOT_FOUND)
selections.insert(comboBox->GetValue());
}
m_ObjectSettings.SetActorSelections(selections);
m_ObjectSettings.NotifyObserversExcept(m_Conn);
RefreshObjectSettings();
}
void VariationControl::OnObjectSettingsChange(const ObjectSettings& settings)
{
Freeze();
const std::vector<ObjectSettings::Group>& variation = settings.GetActorVariation();
// Creating combo boxes seems to be pretty expensive - so we create as
// few as possible, by never deleting any.
size_t oldCount = m_ComboBoxes.size();
size_t newCount = variation.size();
// If we have too many combo boxes, hide the excess ones
for (size_t i = newCount; i < oldCount; ++i)
{
m_ComboBoxes[i]->Show(false);
}
for (size_t i = 0; i < variation.size(); ++i)
{
const ObjectSettings::Group& group = variation[i];
if (i < oldCount)
{
// Already got enough boxes available, so use an old one
wxComboBox* comboBox = m_ComboBoxes[i];
// Replace the contents of the old combobox with the new data
comboBox->Freeze();
comboBox->Clear();
comboBox->Append(group.variants);
comboBox->SetValue(group.chosen);
comboBox->Show(true);
comboBox->Thaw();
}
else
{
// Create an initially empty combobox, because we can fill it
// quicker than the default constructor can
wxComboBox* combo = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition,
wxSize(80, wxDefaultCoord), wxArrayString(), wxCB_READONLY);
// Freeze it before adding all the values
combo->Freeze();
combo->Append(group.variants);
combo->SetValue(group.chosen);
combo->Thaw();
// Add the on-select event handler
combo->Connect(wxID_ANY, wxEVT_COMMAND_COMBOBOX_SELECTED,
wxCommandEventHandler(VariationControl::OnSelect), NULL, this);
// Add box to sizer and list
m_Sizer->Add(combo, wxSizerFlags().Expand());
m_ComboBoxes.push_back(combo);
}
}
Layout();
Thaw();
// Make the scrollbars appear when appropriate
FitInside();
}
void VariationControl::RefreshObjectSettings()
{
const std::vector<ObjectSettings::Group>& variation = m_ObjectSettings.GetActorVariation();
// For each group, set the corresponding combobox's value to the chosen one
size_t i = 0;
for (std::vector<ObjectSettings::Group>::const_iterator group = variation.begin();
group != variation.end() && i < m_ComboBoxes.size();
++group, ++i)
{
m_ComboBoxes[i]->SetValue(group->chosen);
}
}

View File

@ -0,0 +1,42 @@
/* Copyright (C) 2009 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/>.
*/
#ifndef INCLUDED_VARIATIONCONTROL
#define INCLUDED_VARIATIONCONTROL
#include "General/Observable.h"
class ObjectSettings;
class VariationControl : public wxScrolledWindow
{
public:
VariationControl(wxWindow* parent, Observable<ObjectSettings>& objectSettings);
private:
void OnSelect(wxCommandEvent& evt);
void OnObjectSettingsChange(const ObjectSettings& settings);
void RefreshObjectSettings();
ObservableScopedConnection m_Conn;
Observable<ObjectSettings>& m_ObjectSettings;
std::vector<wxComboBox*> m_ComboBoxes;
wxSizer* m_Sizer;
};
#endif // INCLUDED_VARIATIONCONTROL

View File

@ -0,0 +1,239 @@
/* Copyright (C) 2009 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 "Terrain.h"
#include "Buttons/ToolButton.h"
#include "General/Datafile.h"
#include "ScenarioEditor/ScenarioEditor.h"
#include "ScenarioEditor/Tools/Common/Brushes.h"
#include "ScenarioEditor/Tools/Common/MiscState.h"
#include "GameInterface/Messages.h"
#include "wx/spinctrl.h"
#include "wx/listctrl.h"
#include "wx/image.h"
#include "wx/imaglist.h"
#include "wx/busyinfo.h"
#include "wx/notebook.h"
class TextureNotebook;
class TerrainBottomBar : public wxPanel
{
public:
TerrainBottomBar(wxWindow* parent);
void LoadTerrain();
private:
TextureNotebook* m_Textures;
};
TerrainSidebar::TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer)
: Sidebar(scenarioEditor, sidebarContainer, bottomBarContainer)
{
// TODO: Less ugliness
m_MainSizer->Add(new wxStaticText(this, wxID_ANY, _T("TODO: Make this much less ugly\n")));
{
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);
}
{
wxSizer* sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Brush"));
g_Brush_Elevation.CreateUI(this, sizer);
m_MainSizer->Add(sizer);
}
m_BottomBar = new TerrainBottomBar(bottomBarContainer);
}
void TerrainSidebar::OnFirstDisplay()
{
static_cast<TerrainBottomBar*>(m_BottomBar)->LoadTerrain();
}
//////////////////////////////////////////////////////////////////////////
class TextureNotebookPage : public wxPanel
{
public:
TextureNotebookPage(wxWindow* parent, const wxString& name)
: wxPanel(parent, wxID_ANY), m_Name(name), m_ListCtrl(NULL)
{
}
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));
return;
}
wxBusyInfo busy (_("Loading terrain previews"));
m_TextureNames.Clear();
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
m_ListCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ICON | wxLC_SINGLE_SEL | wxLC_AUTOARRANGE);
const int imageWidth = 64;
const int imageHeight = 32;
wxImageList* imglist = new wxImageList(imageWidth, imageHeight, false, 0);
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)
{
unsigned char* buf = (unsigned char*)(malloc(it->imagedata.GetSize()));
// it->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());
wxImage img (imageWidth, imageHeight, buf);
imglist->Add(wxBitmap(img));
wxListItem item;
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;
}
m_ListCtrl->AssignImageList(imglist, wxIMAGE_LIST_NORMAL);
sizer->Add(m_ListCtrl, wxSizerFlags().Expand().Proportion(1));
SetSizer(sizer);
Layout(); // required to make things size correctly
}
void OnSelect(wxListEvent& evt)
{
SetSelection(evt.GetData());
}
void SetSelection(int n)
{
if (n >= 0 && n < (int)m_TextureNames.GetCount())
g_SelectedTexture = m_TextureNames[n];
}
private:
wxListCtrl* m_ListCtrl;
wxString m_Name;
wxArrayString m_TextureNames;
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(TextureNotebookPage, wxPanel)
EVT_LIST_ITEM_SELECTED(wxID_ANY, TextureNotebookPage::OnSelect)
END_EVENT_TABLE();
class TextureNotebook : public wxNotebook
{
public:
TextureNotebook(wxWindow *parent)
: wxNotebook(parent, wxID_ANY/*, wxDefaultPosition, wxDefaultSize, wxNB_FIXEDWIDTH*/)
{
}
void LoadTerrain()
{
wxBusyInfo busy (_("Loading terrain groups"));
DeleteAllPages();
m_TerrainGroups.Clear();
// Get the list of terrain groups from the engine
AtlasMessage::qGetTerrainGroups qry;
qry.Post();
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());
for (size_t i = 0; i < m_TerrainGroups.GetCount(); ++i)
{
wxString visibleName = m_TerrainGroups[i];
if (visibleName.Len())
visibleName[0] = wxToupper(visibleName[0]);
AddPage(new TextureNotebookPage(this, m_TerrainGroups[i]), visibleName);
}
}
protected:
void OnPageChanged(wxNotebookEvent& event)
{
if (event.GetSelection() >= 0 && event.GetSelection() < (int)GetPageCount())
{
static_cast<TextureNotebookPage*>(GetPage(event.GetSelection()))->OnDisplay();
}
event.Skip();
}
private:
wxArrayString m_TerrainGroups;
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(TextureNotebook, wxNotebook)
EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, TextureNotebook::OnPageChanged)
END_EVENT_TABLE();
//////////////////////////////////////////////////////////////////////////
TerrainBottomBar::TerrainBottomBar(wxWindow* parent)
: wxPanel(parent, wxID_ANY)
{
wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
m_Textures = new TextureNotebook(this);
sizer->Add(m_Textures, wxSizerFlags().Expand().Proportion(1));
SetSizer(sizer);
}
void TerrainBottomBar::LoadTerrain()
{
m_Textures->LoadTerrain();
}

View File

@ -0,0 +1,27 @@
/* Copyright (C) 2009 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 TerrainSidebar : public Sidebar
{
public:
TerrainSidebar(ScenarioEditor& scenarioEditor, wxWindow* sidebarContainer, wxWindow* bottomBarContainer);
protected:
virtual void OnFirstDisplay();
};

View File

@ -21,46 +21,133 @@
#include "GameInterface/Messages.h"
#include "ScenarioEditor/ScenarioEditor.h"
#include "AtlasScript/ScriptInterface.h"
ObjectSettings::ObjectSettings(Observable<std::vector<AtlasMessage::ObjectID> >& selectedObjects, ScriptInterface& scriptInterface)
: m_ScriptInterface(scriptInterface)
ObjectSettings::ObjectSettings(Observable<std::vector<AtlasMessage::ObjectID> >& selectedObjects, int view)
: m_PlayerID(0), m_SelectedObjects(selectedObjects), m_View(view)
{
m_Conn = selectedObjects.RegisterObserver(0, &ObjectSettings::OnSelectionChange, this);
m_Conn = m_SelectedObjects.RegisterObserver(0, &ObjectSettings::OnSelectionChange, this);
}
void ObjectSettings::Init(int view)
size_t ObjectSettings::GetPlayerID() const
{
m_ScriptInterface.SetValue(_T("Atlas.State.objectSettings.view"), view);
return m_PlayerID;
}
void ObjectSettings::SetPlayerID(int playerID)
{
m_ScriptInterface.SetValue(_T("Atlas.State.objectSettings.playerID"), playerID);
m_PlayerID = playerID;
PostToGame();
}
const std::set<wxString>& ObjectSettings::GetActorSelections() const
{
return m_ActorSelections;
}
void ObjectSettings::SetActorSelections(const std::set<wxString>& selections)
{
m_ActorSelections = selections;
PostToGame();
}
const std::vector<ObjectSettings::Group> ObjectSettings::GetActorVariation() const
{
std::vector<Group> variation;
for (std::vector<wxArrayString>::const_iterator grp = m_VariantGroups.begin();
grp != m_VariantGroups.end();
++grp)
{
Group group;
group.variants = *grp;
// Variant choice method, as used by the game: Choose the first variant
// which matches any of the selections
size_t chosen = 0; // default to first
for (size_t i = 0; i < grp->GetCount(); ++i)
{
if (m_ActorSelections.find(grp->Item(i)) != m_ActorSelections.end())
{
chosen = i;
break;
}
}
group.chosen = grp->Item(chosen);
variation.push_back(group);
}
return variation;
}
AtlasMessage::sObjectSettings ObjectSettings::GetSettings() const
{
AtlasMessage::sObjectSettings settings;
bool ok = m_ScriptInterface.Eval(_T("Atlas.State.objectSettings.toSObjectSettings()"), settings);
wxCHECK(ok, AtlasMessage::sObjectSettings());
settings.player = m_PlayerID;
// Copy selections from set into vector
std::vector<std::wstring> selections;
for (std::set<wxString>::const_iterator it = m_ActorSelections.begin();
it != m_ActorSelections.end();
++it)
{
selections.push_back(it->c_str());
}
settings.selections = selections;
return settings;
}
void ObjectSettings::OnSelectionChange(const std::vector<AtlasMessage::ObjectID>& selection)
{
// Convert to int so they can be passed to JS
// (manual loop instead of vector range ctor avoids conversion warning)
std::vector<int> objs;
objs.reserve(selection.size());
for(std::vector<AtlasMessage::ObjectID>::const_iterator it = selection.begin(); it != selection.end(); ++it)
objs.push_back((int)*it);
// TODO: what would be the sensible action if nothing's selected?
// and if multiple objects are selected?
m_ScriptInterface.SetValue(_T("Atlas.State.objectSettings.selectedObjects"), objs);
m_ScriptInterface.Eval(_T("Atlas.State.objectSettings.onSelectionChange()"));
if (selection.empty())
return;
AtlasMessage::qGetObjectSettings qry (m_View, selection[0]);
qry.Post();
m_PlayerID = qry.settings->player;
m_ActorSelections.clear();
m_VariantGroups.clear();
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)
{
wxArrayString variants;
for (std::vector<std::wstring>::iterator it = grp->begin();
it != grp->end();
++it)
{
variants.Add(it->c_str());
}
m_VariantGroups.push_back(variants);
}
std::vector<std::wstring> selections = *qry.settings->selections;
for (std::vector<std::wstring>::iterator sel = selections.begin();
sel != selections.end();
++sel)
{
m_ActorSelections.insert(sel->c_str());
}
static_cast<Observable<ObjectSettings>*>(this)->NotifyObservers();
}
void ObjectSettings::NotifyObservers()
void ObjectSettings::PostToGame()
{
m_ScriptInterface.Eval(_T("Atlas.State.objectSettings.notifyObservers()"));
if (m_SelectedObjects.empty())
return;
POST_COMMAND(SetObjectSettings, (m_View, m_SelectedObjects[0], GetSettings()));
}

View File

@ -19,37 +19,62 @@
#define INCLUDED_OBJECTSETTINGS
#include <vector>
#include <set>
#include "ScenarioEditor/Tools/Common/MiscState.h"
class ScriptInterface;
namespace AtlasMessage
{
struct sObjectSettings;
}
// This class is now just an interface to the JS Atlas.State.objectSettings,
// for old C++ code that hasn't been ported to JS yet.
// Various settings to be applied to newly created units, or to the currently
// selected unit. If a unit is selected or being previewed, it should match
// these settings.
class ObjectSettings
{
public:
ObjectSettings(Observable<std::vector<AtlasMessage::ObjectID> >& selectedObjects, ScriptInterface& scriptInterface);
void Init(int view);
ObjectSettings(Observable<std::vector<AtlasMessage::ObjectID> >& selectedObjects, int view);
size_t GetPlayerID() const;
void SetPlayerID(int playerID);
struct Group
{
wxArrayString variants;
wxString chosen;
};
const std::vector<Group> GetActorVariation() const;
const std::set<wxString>& GetActorSelections() const;
void SetActorSelections(const std::set<wxString>& selections);
// Constructs new sObjectSettings object from settings
AtlasMessage::sObjectSettings GetSettings() const;
void NotifyObservers();
private:
ScriptInterface& m_ScriptInterface;
Observable<std::vector<AtlasMessage::ObjectID> >& m_SelectedObjects;
int m_View;
// 0 = gaia, 1..inf = normal players
size_t m_PlayerID;
// Set of user-chosen actor selections, potentially a superset of any single
// actor's possible variants (since it doesn't get reset if you select
// a new actor, and will accumulate variant names)
std::set<wxString> m_ActorSelections;
// List of actor variant groups (each a list of variant names)
std::vector<wxArrayString> m_VariantGroups;
// Observe changes to unit selection
ObservableScopedConnection m_Conn;
void OnSelectionChange(const std::vector<AtlasMessage::ObjectID>& selection);
// Transfer current settings to the currently selected unit (if any)
void PostToGame();
};
#endif // INCLUDED_OBJECTSETTINGS