1
1
forked from 0ad/0ad

Actor Editor: Combo-box lists, loaded from XML. Allowed right click to edit cells.

This was SVN commit r2044.
This commit is contained in:
Ykkrosh 2005-03-24 12:53:48 +00:00
parent b58a6339bb
commit 6dbe768dd9
18 changed files with 390 additions and 15 deletions

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<lists>
<attachpoints>
<item> head </item>
<item> helmet </item>
<item> head_extra </item>
<item> l_hand </item>
<item> shield </item>
<item> l_forearm </item>
<item> l_shoulder </item>
<item> r_hand </item>
<item> r_forearm </item>
<item> r_shoulder </item>
<item> chest </item>
<item> back </item>
<item> shoulders </item>
<item> l_leg </item>
<item> r_leg </item>
<item> l_hip </item>
<item> r_hip </item>
</attachpoints>
<animations>
<item> Attack </item>
<item> AttackA </item>
<item> AttackB </item>
<item> AttackC </item>
<item> Death </item>
<item> DeathA </item>
<item> DeathB </item>
<item> Idle </item>
<item> IdleA </item>
<item> IdleB </item>
<item> IdleC </item>
<item> Run </item>
<item> Special </item>
<item> Walk </item>
<item> Pack </item>
</animations>
</lists>

View File

@ -80,6 +80,9 @@ bool AtIter::hasContent() const
if (p == NULL)
return false;
if (! p->iter->second)
return false;
return p->iter->second->hasContent();
}

View File

@ -91,5 +91,5 @@ wxListItemAttr* ActorEditorListCtrl::OnGetItemAttr(long item) const
return const_cast<wxListItemAttr*>(&m_ListItemAttr_Prop[item%2]);
}
return const_cast<wxListItemAttr*>(&m_ListItemAttr[item%2]);
return DraggableListCtrl::OnGetItemAttr(item);
}

View File

@ -37,7 +37,7 @@ AnimListEditorListCtrl::AnimListEditorListCtrl(wxWindow* parent)
: DraggableListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL)
{
AddColumnType(_("Anim name"), 100, "name", new FieldEditCtrl_Text());
AddColumnType(_("Anim name"), 100, "name", new FieldEditCtrl_List("animations"));
AddColumnType(_("File"), 200, "file", new FieldEditCtrl_Text());
AddColumnType(_("Speed"), 50, "speed", new FieldEditCtrl_Text());
}

View File

@ -37,7 +37,7 @@ PropListEditorListCtrl::PropListEditorListCtrl(wxWindow* parent)
: DraggableListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL)
{
AddColumnType(_("Attachment point"), 100, "attachpoint", new FieldEditCtrl_Text());
AddColumnType(_("Attachment point"), 100, "attachpoint", new FieldEditCtrl_List("attachpoints"));
AddColumnType(_("Prop model"), 200, "model", new FieldEditCtrl_Text());
}

View File

@ -136,6 +136,12 @@
<File
RelativePath=".\General\AtlasWindowCommandProc.h">
</File>
<File
RelativePath=".\General\Datafile.cpp">
</File>
<File
RelativePath=".\General\Datafile.h">
</File>
<File
RelativePath=".\General\IAtlasExporter.h">
</File>
@ -170,6 +176,12 @@
<File
RelativePath=".\CustomControls\EditableListCtrl\ListCtrlValidator.h">
</File>
<File
RelativePath=".\CustomControls\EditableListCtrl\QuickComboBox.cpp">
</File>
<File
RelativePath=".\CustomControls\EditableListCtrl\QuickComboBox.h">
</File>
<File
RelativePath=".\CustomControls\EditableListCtrl\QuickTextCtrl.cpp">
</File>

View File

@ -48,10 +48,10 @@ void EditableListCtrl::AddColumnType(const wxString& title, int width, const cha
void EditableListCtrl::OnMouseEvent(wxMouseEvent& event)
{
// Double-clicking on a cell lets the user edit it. The editing method
// depends on what column the cell is in.
// Double-clicking/right-clicking on a cell lets the user edit it.
// The editing method depends on what column the cell is in.
if (event.LeftDClick())
if (event.LeftDClick() || event.RightDown())
{
// Work out what cell was clicked on:
@ -224,8 +224,13 @@ wxString EditableListCtrl::OnGetItemText(long item, long column) const
wxListItemAttr* EditableListCtrl::OnGetItemAttr(long item) const
{
// Make the last two rows white
if (item >= (long)m_ListData.size())
return const_cast<wxListItemAttr*>(&m_ListItemAttr[0]);
// Make the background colours of rows alternate
return const_cast<wxListItemAttr*>(&m_ListItemAttr[item%2]);
else
return const_cast<wxListItemAttr*>(&m_ListItemAttr[item%2]);
}
void EditableListCtrl::Import(AtObj& in)
@ -242,4 +247,5 @@ AtObj EditableListCtrl::Export()
BEGIN_EVENT_TABLE(EditableListCtrl, wxListCtrl)
EVT_LEFT_DCLICK(EditableListCtrl::OnMouseEvent)
EVT_RIGHT_DOWN(EditableListCtrl::OnMouseEvent)
END_EVENT_TABLE()

View File

@ -66,10 +66,11 @@ private:
void TrimBlankEnds();
wxString OnGetItemText(long item, long column) const;
wxListItemAttr* OnGetItemAttr(long item) const;
protected:
wxListItemAttr* OnGetItemAttr(long item) const;
virtual void DoImport(AtObj&)=0;
virtual AtObj DoExport()=0;

View File

@ -0,0 +1,100 @@
#include "stdafx.h"
#include "EditableListCtrlCommands.h"
#include "EditableListCtrl.h"
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_CLASS(ImportCommand, AtlasWindowCommand);
ImportCommand::ImportCommand(EditableListCtrl* ctrl, AtObj& in)
: AtlasWindowCommand(true, _("Import")), m_Ctrl(ctrl), m_In(in)
{
}
bool ImportCommand::Do()
{
m_Ctrl->CloneListData(m_OldData);
m_Ctrl->DoImport(m_In);
m_Ctrl->UpdateDisplay();
return true;
}
bool ImportCommand::Undo()
{
m_Ctrl->SetListData(m_OldData);
m_Ctrl->UpdateDisplay();
return true;
}
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_CLASS(EditCommand_Dialog, AtlasWindowCommand);
EditCommand_Dialog::EditCommand_Dialog(EditableListCtrl* ctrl, long row, int col, AtObj& newData)
: AtlasWindowCommand(true, _("Edit")), m_Ctrl(ctrl), m_Row(row), m_Col(col), m_NewData(newData)
{
}
bool EditCommand_Dialog::Do()
{
m_Ctrl->CloneListData(m_OldData);
m_Ctrl->MakeSizeAtLeast(m_Row+1);
m_Ctrl->SetCellObject(m_Row, m_Col, m_NewData);
m_Ctrl->UpdateDisplay();
m_Ctrl->SetSelection(m_Row);
return true;
}
bool EditCommand_Dialog::Undo()
{
m_Ctrl->SetListData(m_OldData);
m_Ctrl->UpdateDisplay();
m_Ctrl->SetSelection(m_Row);
return true;
}
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_CLASS(EditCommand_Text, AtlasWindowCommand);
EditCommand_Text::EditCommand_Text(EditableListCtrl* ctrl, long row, int col, wxString newText)
: AtlasWindowCommand(true, _("Edit")), m_Ctrl(ctrl), m_Row(row), m_Col(col), m_NewText(newText)
{
}
bool EditCommand_Text::Do()
{
m_Ctrl->CloneListData(m_OldData);
m_Ctrl->MakeSizeAtLeast(m_Row+1);
m_Ctrl->SetCellString(m_Row, m_Col, m_NewText);
m_Ctrl->UpdateDisplay();
m_Ctrl->SetSelection(m_Row);
return true;
}
bool EditCommand_Text::Undo()
{
m_Ctrl->SetListData(m_OldData);
m_Ctrl->UpdateDisplay();
m_Ctrl->SetSelection(m_Row);
return true;
}

View File

@ -0,0 +1,61 @@
#include "AtlasWindowCommand.h"
#include "AtlasObject/AtlasObject.h"
class EditableListCtrl;
class ImportCommand : public AtlasWindowCommand
{
DECLARE_CLASS(ImportCommand);
public:
ImportCommand(EditableListCtrl* ctrl, AtObj& in);
bool Do();
bool Undo();
private:
EditableListCtrl* m_Ctrl;
AtObj m_In;
std::vector<AtObj> m_OldData;
};
class EditCommand_Dialog : public AtlasWindowCommand
{
DECLARE_CLASS(EditCommand_Dialog);
public:
EditCommand_Dialog(EditableListCtrl* ctrl, long row, int col, AtObj& newData);
bool Do();
bool Undo();
private:
EditableListCtrl* m_Ctrl;
long m_Row;
int m_Col;
AtObj m_NewData;
std::vector<AtObj> m_OldData;
};
class EditCommand_Text : public AtlasWindowCommand
{
DECLARE_CLASS(EditCommand_Text);
public:
EditCommand_Text(EditableListCtrl* ctrl, long row, int col, wxString newText);
bool Do();
bool Undo();
private:
EditableListCtrl* m_Ctrl;
long m_Row;
int m_Col;
wxString m_NewText;
std::vector<AtObj> m_OldData;
};

View File

@ -5,10 +5,12 @@
#include "EditableListCtrlCommands.h"
#include "ListCtrlValidator.h"
#include "QuickTextCtrl.h"
#include "QuickComboBox.h"
#include "AtlasDialog.h"
#include "EditableListCtrl.h"
#include "AtlasObject/AtlasObject.h"
#include "AtlasObject/AtlasObjectText.h"
#include "Datafile.h"
#include <string>
@ -21,6 +23,25 @@ void FieldEditCtrl_Text::StartEdit(wxWindow* parent, wxRect rect, long row, int
//////////////////////////////////////////////////////////////////////////
FieldEditCtrl_List::FieldEditCtrl_List(const char* listType)
: m_ListType(listType)
{
}
void FieldEditCtrl_List::StartEdit(wxWindow* parent, wxRect rect, long row, int col)
{
wxArrayString choices;
AtObj list (Datafile::ReadList(m_ListType));
AtIter items (list["item"]);
for (AtIter it = items; it.defined(); ++it)
choices.Add(it);
new QuickComboBox(parent, rect, choices, ListCtrlValidator((EditableListCtrl*)parent, row, col));
}
//////////////////////////////////////////////////////////////////////////
FieldEditCtrl_Dialog::FieldEditCtrl_Dialog(wxString dialogType)
: m_DialogType(dialogType)
{

View File

@ -21,6 +21,21 @@ protected:
//////////////////////////////////////////////////////////////////////////
class FieldEditCtrl_List : public FieldEditCtrl
{
public:
// listType must remain valid at least until StartEdit has been called
FieldEditCtrl_List(const char* listType);
protected:
void StartEdit(wxWindow* parent, wxRect rect, long row, int col);
private:
const char* m_ListType;
};
//////////////////////////////////////////////////////////////////////////
class FieldEditCtrl_Dialog : public FieldEditCtrl
{
public:

View File

@ -27,20 +27,39 @@ wxObject* ListCtrlValidator::Clone() const
bool ListCtrlValidator::TransferToWindow()
{
wxTextCtrl* textCtrl = wxDynamicCast(GetWindow(), wxTextCtrl);
wxString text (m_listCtrl->GetCellString(m_Row, m_Col));
textCtrl->SetValue(text);
wxTextCtrl* textCtrl; wxComboBox* comboBox; // one of these will be the right object
if (NULL != (textCtrl = wxDynamicCast(GetWindow(), wxTextCtrl)))
textCtrl->SetValue(text);
else if (NULL != (comboBox = wxDynamicCast(GetWindow(), wxComboBox)))
comboBox->SetValue(text);
else
{
wxLogError(L"Internal error: ListCtrlValidator::TransferToWindow: invalid window");
return false;
}
return true;
}
bool ListCtrlValidator::TransferFromWindow()
{
wxTextCtrl* textCtrl = wxDynamicCast(GetWindow(), wxTextCtrl);
wxString newText;
wxTextCtrl* textCtrl; wxComboBox* comboBox; // one of these will be the right object
wxString newText = textCtrl->GetValue();
if (NULL != (textCtrl = wxDynamicCast(GetWindow(), wxTextCtrl)))
newText = textCtrl->GetValue();
else if (NULL != (comboBox = wxDynamicCast(GetWindow(), wxComboBox)))
newText = comboBox->GetValue();
else
{
wxLogError(L"Internal error: ListCtrlValidator::TransferFromWindow: invalid window");
return false;
}
AtlasWindowCommandProc::GetFromParentFrame(m_listCtrl)->Submit(
new EditCommand_Text(m_listCtrl, m_Row, m_Col, newText)

View File

@ -0,0 +1,50 @@
#include "stdafx.h"
#include "QuickComboBox.h"
const int verticalPadding = 2;
QuickComboBox::QuickComboBox(wxWindow* parent,
wxRect& location,
const wxArrayString& choices,
const wxValidator& validator)
: wxComboBox(parent, wxID_ANY, wxEmptyString,
location.GetPosition()-wxPoint(0,verticalPadding),
location.GetSize()+wxSize(0,verticalPadding*2),
choices,
wxSUNKEN_BORDER | wxCB_DROPDOWN,
validator)
{
GetValidator()->TransferToWindow();
SetFocus();
}
void QuickComboBox::OnKillFocus(wxFocusEvent& event)
{
// We need to test whether there's actually a window receiving focus;
// otherwise it tries to destroy the control while wx is focusing
// on the text-input box, and everything crashes.
if (event.GetWindow())
{
GetValidator()->TransferFromWindow();
Destroy();
}
}
void QuickComboBox::OnChar(wxKeyEvent& event)
{
if (event.GetKeyCode() == WXK_RETURN)
GetParent()->SetFocus();
else if (event.GetKeyCode() == WXK_ESCAPE)
Destroy();
else
event.Skip();
}
BEGIN_EVENT_TABLE(QuickComboBox, wxComboBox)
EVT_KILL_FOCUS(QuickComboBox::OnKillFocus)
EVT_CHAR(QuickComboBox::OnChar)
END_EVENT_TABLE()

View File

@ -0,0 +1,13 @@
#include "wx/combobox.h"
class QuickComboBox : public wxComboBox
{
public:
QuickComboBox(wxWindow* parent, wxRect& location, const wxArrayString& choices, const wxValidator& validator = wxDefaultValidator);
void OnKillFocus(wxFocusEvent& event);
void OnChar(wxKeyEvent& event);
private:
DECLARE_EVENT_TABLE();
};

View File

@ -0,0 +1,21 @@
#include "stdafx.h"
#include "Datafile.h"
#include "wx/filename.h"
AtObj Datafile::ReadList(const char* section)
{
const wxString relativePath (_T("../data/tools/atlas/lists.xml"));
wxFileName filename (relativePath, wxPATH_UNIX);
if (! filename.FileExists())
{
wxLogError(_("Cannot find file 'lists.xml'"));
return AtObj();
}
AtObj lists (AtlasObject::LoadFromXML(filename.GetFullPath()));
return lists["lists"][section];
}

View File

@ -0,0 +1,9 @@
#include "AtlasObject/AtlasObject.h"
class Datafile
{
public:
// Read configuration data from data/tools/atlas/lists.xml
static AtObj ReadList(const char* section);
};

View File

@ -1,6 +1,3 @@
* Combo boxes for prop/anim names, loaded from file
* Right click to edit
===
@ -14,6 +11,8 @@
* Help (tooltips, etc)
* More efficient Datafile::ReadList (don't read from disk every time)
===
* Make import undo work with multi-control windows, and update the title bar
@ -38,6 +37,8 @@
* Use standard wxWidgets 2.5.4 release
* Fix Escape in combo boxes inside dialogs
===