forked from 0ad/0ad
Actor Editor: Copy-and-paste. Folder memory. Entity creation. Fixed importing.
This was SVN commit r2084.
This commit is contained in:
parent
827e06b8e4
commit
b07d9954e0
@ -4,9 +4,21 @@
|
||||
|
||||
#include "ActorEditorListCtrl.h"
|
||||
#include "AtlasObject/AtlasObject.h"
|
||||
#include "Datafile.h"
|
||||
|
||||
#include "wx/file.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(ActorEditor, AtlasWindow)
|
||||
EVT_MENU(ID_Custom1, OnCreateEntity)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
static AtlasWindow::CustomMenu::CustomMenuItem menuItem1 = { _("Create &entity...") };
|
||||
static AtlasWindow::CustomMenu::CustomMenuItem* menuItems[] = { &menuItem1, NULL };
|
||||
static AtlasWindow::CustomMenu menu = { _("&Actor"), menuItems };
|
||||
|
||||
ActorEditor::ActorEditor(wxWindow* parent)
|
||||
: AtlasWindow(parent, _("Actor Editor"), wxSize(1024, 450))
|
||||
: AtlasWindow(parent, _("Actor Editor"), wxSize(1024, 450), &menu)
|
||||
{
|
||||
wxPanel* mainPanel = new wxPanel(this);
|
||||
|
||||
@ -265,3 +277,89 @@ AtObj ActorEditor::ExportData()
|
||||
out.set("actor", actor);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void ActorEditor::OnCreateEntity(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
// Create a very basic entity for this actor.
|
||||
|
||||
// The output should be an XML file like:
|
||||
//
|
||||
// <?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
|
||||
// <Entity Parent="celt_csw_b">
|
||||
// <Actor>units/celt_csw_a.xml</Actor>
|
||||
// </Entity>
|
||||
//
|
||||
// 'Actor' comes from this actor's filename.
|
||||
// 'Parent' comes from the filename of a user-selected entity.
|
||||
// The file will be saved into a user-selected location.
|
||||
|
||||
// Get the entity's expected name
|
||||
wxFileName currentFilename (GetCurrentFilename());
|
||||
if (! currentFilename.IsOk())
|
||||
{
|
||||
wxMessageDialog(this, _("Please save this actor before attempting to create an entity for it."),
|
||||
_("Gentle reminder"), wxOK | wxICON_INFORMATION).ShowModal();
|
||||
return;
|
||||
}
|
||||
wxString entityName = currentFilename.GetName();
|
||||
|
||||
// Work out where the entities are stored
|
||||
wxFileName entityPath (_T("../data/mods/official/entities/"));
|
||||
entityPath.MakeAbsolute(Datafile::GetSystemDirectory());
|
||||
|
||||
// Make sure the user knows what's going on
|
||||
static bool instructed = false; // only tell them once per session
|
||||
if (! instructed)
|
||||
{
|
||||
instructed = true;
|
||||
if (wxMessageBox(_("To create an entity, you will first be asked to choose a parent entity, and then asked where save the new entity."),
|
||||
_("Usage instructions"), wxICON_INFORMATION|wxOK|wxCANCEL, this) != wxOK)
|
||||
return; // cancelled by user
|
||||
}
|
||||
|
||||
wxString parentEntityFilename
|
||||
(wxFileSelector(_("Choose a parent entity"), entityPath.GetPath(), _T(""),
|
||||
_T("xml"), _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxOPEN, this));
|
||||
|
||||
if (! parentEntityFilename.Length())
|
||||
return; // cancelled by user
|
||||
|
||||
// Get the parent's name
|
||||
wxString parentName (wxFileName(parentEntityFilename).GetName());
|
||||
|
||||
wxString outputEntityFilename
|
||||
(wxFileSelector(_("Choose a filename to save as"), entityPath.GetPath(), entityName,
|
||||
_T("xml"), _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this));
|
||||
|
||||
if (! outputEntityFilename.Length())
|
||||
return; // cancelled by user
|
||||
|
||||
// Get this actor's filename, relative to actors/
|
||||
wxFileName actorPath (_T("../data/mods/official/art/actors/"));
|
||||
actorPath.MakeAbsolute(Datafile::GetSystemDirectory());
|
||||
wxFileName actorFilename (currentFilename);
|
||||
actorFilename.MakeRelativeTo(actorPath.GetFullPath());
|
||||
|
||||
// Create the XML data to be written
|
||||
// TODO: Native line endings
|
||||
wxString xml =
|
||||
_T("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\r\n")
|
||||
_T("\r\n")
|
||||
_T("<Entity Parent=\"") + parentName + _T("\">\r\n")
|
||||
_T("\t<Actor>") + actorFilename.GetFullPath(wxPATH_UNIX) + _T("</Actor>\r\n")
|
||||
_T("</Entity>\r\n");
|
||||
|
||||
wxFile file (outputEntityFilename.fn_str(), wxFile::write);
|
||||
if (! file.IsOpened())
|
||||
{
|
||||
wxLogError(_("Failed to open file"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (! file.Write(xml))
|
||||
{
|
||||
wxLogError(_("Failed to write XML data to file"));
|
||||
return;
|
||||
}
|
||||
}
|
@ -7,6 +7,9 @@ class ActorEditor : public AtlasWindow
|
||||
public:
|
||||
ActorEditor(wxWindow* parent);
|
||||
|
||||
private:
|
||||
void OnCreateEntity(wxCommandEvent& event);
|
||||
|
||||
protected:
|
||||
AtObj FreezeData();
|
||||
void ThawData(AtObj& in);
|
||||
@ -19,4 +22,6 @@ private:
|
||||
|
||||
wxCheckBox* m_CastShadows;
|
||||
wxTextCtrl* m_Material;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
@ -23,8 +23,8 @@ ActorEditorListCtrl::ActorEditorListCtrl(wxWindow* parent)
|
||||
|
||||
AddColumnType(_("Variant"), 100, "@name", new FieldEditCtrl_Text());
|
||||
AddColumnType(_("Freq"), 50, "@frequency", new FieldEditCtrl_Text());
|
||||
AddColumnType(_("Model"), 160, "mesh", new FieldEditCtrl_File(_T("art/meshes"), _("Mesh files (*.pmd)|*.pmd|All files (*.*)|*.*")));
|
||||
AddColumnType(_("Texture"), 160, "texture", new FieldEditCtrl_File(_T("art/textures/skins"), _("All files (*.*)|*.*"))); // could be dds, or tga, or png, or bmp, etc, so just allow *
|
||||
AddColumnType(_("Model"), 160, "mesh", new FieldEditCtrl_File(_T("art/meshes/"), _("Mesh files (*.pmd)|*.pmd|All files (*.*)|*.*")));
|
||||
AddColumnType(_("Texture"), 160, "texture", new FieldEditCtrl_File(_T("art/textures/skins/"), _("All files (*.*)|*.*"))); // could be dds, or tga, or png, or bmp, etc, so just allow *
|
||||
AddColumnType(_("Animations"), 250, "animations", new FieldEditCtrl_Dialog(_T("AnimListEditor")));
|
||||
AddColumnType(_("Props"), 250, "props", new FieldEditCtrl_Dialog(_T("PropListEditor")));
|
||||
}
|
||||
|
@ -31,6 +31,16 @@ AtObj AnimListEditor::FreezeData()
|
||||
return m_MainListBox->FreezeData();
|
||||
}
|
||||
|
||||
void AnimListEditor::ImportData(AtObj& in)
|
||||
{
|
||||
m_MainListBox->ImportData(in);
|
||||
}
|
||||
|
||||
AtObj AnimListEditor::ExportData()
|
||||
{
|
||||
return m_MainListBox->ExportData();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AnimListEditorListCtrl::AnimListEditorListCtrl(wxWindow* parent)
|
||||
@ -38,7 +48,7 @@ AnimListEditorListCtrl::AnimListEditorListCtrl(wxWindow* parent)
|
||||
wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL)
|
||||
{
|
||||
AddColumnType(_("Anim name"), 100, "@name", new FieldEditCtrl_List("animations"));
|
||||
AddColumnType(_("File"), 200, "@file", new FieldEditCtrl_File(_T("art/animation"), _("Animation files (*.psa)|*.psa|All files (*.*)|*.*")));
|
||||
AddColumnType(_("File"), 200, "@file", new FieldEditCtrl_File(_T("art/animation/"), _("Animation files (*.psa)|*.psa|All files (*.*)|*.*")));
|
||||
AddColumnType(_("Speed"), 50, "@speed", new FieldEditCtrl_Text());
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,9 @@ protected:
|
||||
AtObj FreezeData();
|
||||
void ThawData(AtObj& in);
|
||||
|
||||
AtObj ExportData();
|
||||
void ImportData(AtObj& in);
|
||||
|
||||
private:
|
||||
AnimListEditorListCtrl* m_MainListBox;
|
||||
};
|
||||
|
@ -31,6 +31,16 @@ AtObj PropListEditor::FreezeData()
|
||||
return m_MainListBox->FreezeData();
|
||||
}
|
||||
|
||||
void PropListEditor::ImportData(AtObj& in)
|
||||
{
|
||||
m_MainListBox->ImportData(in);
|
||||
}
|
||||
|
||||
AtObj PropListEditor::ExportData()
|
||||
{
|
||||
return m_MainListBox->ExportData();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PropListEditorListCtrl::PropListEditorListCtrl(wxWindow* parent)
|
||||
@ -38,7 +48,7 @@ PropListEditorListCtrl::PropListEditorListCtrl(wxWindow* parent)
|
||||
wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL)
|
||||
{
|
||||
AddColumnType(_("Attachment point"), 100, "@attachpoint", new FieldEditCtrl_List("attachpoints"));
|
||||
AddColumnType(_("Prop model"), 200, "@actor", new FieldEditCtrl_File(_T("art/actors"), _("Actor files (*.xml)|*.xml|All files (*.*)|*.*")));
|
||||
AddColumnType(_("Prop model"), 200, "@actor", new FieldEditCtrl_File(_T("art/actors/"), _("Actor files (*.xml)|*.xml|All files (*.*)|*.*")));
|
||||
}
|
||||
|
||||
void PropListEditorListCtrl::DoImport(AtObj& in)
|
||||
|
@ -17,6 +17,9 @@ protected:
|
||||
AtObj FreezeData();
|
||||
void ThawData(AtObj& in);
|
||||
|
||||
AtObj ExportData();
|
||||
void ImportData(AtObj& in);
|
||||
|
||||
private:
|
||||
PropListEditorListCtrl* m_MainListBox;
|
||||
};
|
||||
|
@ -124,6 +124,12 @@
|
||||
<Filter
|
||||
Name="General"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\General\AtlasClipboard.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\General\AtlasClipboard.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\General\AtlasWindowCommand.cpp">
|
||||
</File>
|
||||
|
@ -31,14 +31,14 @@ bool DragCommand::Do()
|
||||
|
||||
if (m_Tgt > m_Src)
|
||||
std::copy(
|
||||
m_Ctrl->m_ListData.begin()+m_Src+1,
|
||||
m_Ctrl->m_ListData.begin()+m_Tgt+1,
|
||||
m_Ctrl->m_ListData.begin()+m_Src);
|
||||
m_Ctrl->m_ListData.begin()+(m_Src+1),
|
||||
m_Ctrl->m_ListData.begin()+(m_Tgt+1),
|
||||
m_Ctrl->m_ListData.begin()+ m_Src);
|
||||
else if (m_Tgt < m_Src)
|
||||
std::copy_backward(
|
||||
m_Ctrl->m_ListData.begin()+m_Tgt,
|
||||
m_Ctrl->m_ListData.begin()+m_Src,
|
||||
m_Ctrl->m_ListData.begin()+m_Src+1);
|
||||
m_Ctrl->m_ListData.begin()+ m_Tgt,
|
||||
m_Ctrl->m_ListData.begin()+ m_Src,
|
||||
m_Ctrl->m_ListData.begin()+(m_Src+1));
|
||||
else // m_Tgt == m_Src
|
||||
; // do nothing - this item was just dragged onto itself
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "FieldEditCtrl.h"
|
||||
#include "AtlasObject/AtlasObject.h"
|
||||
#include "AtlasObject/AtlasObjectText.h"
|
||||
#include "AtlasClipboard.h"
|
||||
|
||||
const int BlanksAtEnd = 2;
|
||||
|
||||
@ -76,6 +77,37 @@ void EditableListCtrl::OnMouseEvent(wxMouseEvent& event)
|
||||
}
|
||||
}
|
||||
|
||||
void EditableListCtrl::OnKeyDown(wxKeyEvent& event)
|
||||
{
|
||||
// TODO: Don't use magic key-code numbers
|
||||
|
||||
// Check for Copy
|
||||
if ((event.GetKeyCode() == 3) || // ctrl+c
|
||||
(event.GetKeyCode() == WXK_INSERT && event.ControlDown())) // ctrl+insert
|
||||
{
|
||||
AtObj row;
|
||||
long selection = GetSelection();
|
||||
if (selection >= 0 && selection < (long)m_ListData.size())
|
||||
row = m_ListData[selection];
|
||||
AtlasClipboard::SetClipboard(row);
|
||||
}
|
||||
|
||||
// Check for Paste
|
||||
else
|
||||
if ((event.GetKeyCode() == 22) || // ctrl+v
|
||||
(event.GetKeyCode() == WXK_INSERT && event.ShiftDown())) // shift+insert
|
||||
{
|
||||
AtObj row;
|
||||
if (AtlasClipboard::GetClipboard(row))
|
||||
{
|
||||
long selection = GetSelection();
|
||||
AtlasWindowCommandProc* commandProc = AtlasWindowCommandProc::GetFromParentFrame(this);
|
||||
commandProc->Submit(new PasteCommand(this, selection, row));
|
||||
}
|
||||
}
|
||||
else
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
int EditableListCtrl::GetColumnAtPosition(wxPoint& pos)
|
||||
{
|
||||
@ -235,8 +267,6 @@ wxListItemAttr* EditableListCtrl::OnGetItemAttr(long item) const
|
||||
|
||||
void EditableListCtrl::ImportData(AtObj& in)
|
||||
{
|
||||
//AtlasWindowCommandProc* commandProc = AtlasWindowCommandProc::GetFromParentFrame(this);
|
||||
//commandProc->Submit(new ImportCommand(this, in));
|
||||
return DoImport(in);
|
||||
}
|
||||
|
||||
@ -267,4 +297,5 @@ AtObj EditableListCtrl::FreezeData()
|
||||
BEGIN_EVENT_TABLE(EditableListCtrl, wxListCtrl)
|
||||
EVT_LEFT_DCLICK(EditableListCtrl::OnMouseEvent)
|
||||
EVT_RIGHT_DOWN(EditableListCtrl::OnMouseEvent)
|
||||
EVT_CHAR(EditableListCtrl::OnKeyDown)
|
||||
END_EVENT_TABLE()
|
||||
|
@ -16,6 +16,7 @@ class EditableListCtrl : public wxListCtrl, public IAtlasSerialiser
|
||||
friend class DeleteCommand;
|
||||
friend class DragCommand;
|
||||
friend class ImportCommand;
|
||||
friend class PasteCommand;
|
||||
|
||||
public:
|
||||
EditableListCtrl(wxWindow *parent,
|
||||
@ -28,6 +29,7 @@ public:
|
||||
|
||||
~EditableListCtrl();
|
||||
|
||||
void OnKeyDown(wxKeyEvent& event);
|
||||
void OnMouseEvent(wxMouseEvent& event);
|
||||
|
||||
void MakeSizeAtLeast(int n);
|
||||
|
@ -6,35 +6,6 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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)
|
||||
@ -98,3 +69,36 @@ bool EditCommand_Text::Undo()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IMPLEMENT_CLASS(PasteCommand, AtlasWindowCommand);
|
||||
|
||||
PasteCommand::PasteCommand(EditableListCtrl* ctrl, long row, AtObj& newData)
|
||||
: AtlasWindowCommand(true, _("Paste")), m_Ctrl(ctrl), m_Row(row), m_NewData(newData)
|
||||
{
|
||||
}
|
||||
|
||||
bool PasteCommand::Do()
|
||||
{
|
||||
m_Ctrl->CloneListData(m_OldData);
|
||||
|
||||
m_Ctrl->MakeSizeAtLeast(m_Row);
|
||||
|
||||
m_Ctrl->m_ListData.insert(m_Ctrl->m_ListData.begin()+m_Row, m_NewData);
|
||||
|
||||
m_Ctrl->UpdateDisplay();
|
||||
m_Ctrl->SetSelection(m_Row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PasteCommand::Undo()
|
||||
{
|
||||
m_Ctrl->SetListData(m_OldData);
|
||||
|
||||
m_Ctrl->UpdateDisplay();
|
||||
m_Ctrl->SetSelection(m_Row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -4,23 +4,6 @@
|
||||
|
||||
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);
|
||||
@ -59,3 +42,20 @@ private:
|
||||
std::vector<AtObj> m_OldData;
|
||||
};
|
||||
|
||||
|
||||
class PasteCommand : public AtlasWindowCommand
|
||||
{
|
||||
DECLARE_CLASS(PasteCommand);
|
||||
|
||||
public:
|
||||
PasteCommand(EditableListCtrl* ctrl, long row, AtObj& newData);
|
||||
bool Do();
|
||||
bool Undo();
|
||||
|
||||
private:
|
||||
EditableListCtrl* m_Ctrl;
|
||||
long m_Row;
|
||||
AtObj m_NewData;
|
||||
std::vector<AtObj> m_OldData;
|
||||
};
|
||||
|
||||
|
@ -59,13 +59,13 @@ void FieldEditCtrl_Dialog::StartEdit(wxWindow* parent, wxRect WXUNUSED(rect), lo
|
||||
EditableListCtrl* editCtrl = (EditableListCtrl*)parent;
|
||||
|
||||
AtObj in (editCtrl->GetCellObject(row, col));
|
||||
dialog->ThawData(in);
|
||||
dialog->ImportData(in);
|
||||
|
||||
int ret = dialog->ShowModal();
|
||||
|
||||
if (ret == wxID_OK)
|
||||
{
|
||||
AtObj out (dialog->FreezeData());
|
||||
AtObj out (dialog->ExportData());
|
||||
|
||||
AtlasWindowCommandProc::GetFromParentFrame(parent)->Submit(
|
||||
new EditCommand_Dialog(editCtrl, row, col, out)
|
||||
@ -80,11 +80,15 @@ void FieldEditCtrl_Dialog::StartEdit(wxWindow* parent, wxRect WXUNUSED(rect), lo
|
||||
FieldEditCtrl_File::FieldEditCtrl_File(const wxString& rootDir, const wxString& fileMask)
|
||||
: m_FileMask(fileMask)
|
||||
{
|
||||
// Make the path correct, relative to binaries/system
|
||||
m_RootDir = _T("../data/mods/official/") + rootDir;
|
||||
// Make the rootDir path absolute (where rootDir is relative to binaries/system):
|
||||
wxFileName path (_T("../data/mods/official/") + rootDir);
|
||||
wxASSERT(path.IsOk());
|
||||
path.MakeAbsolute(Datafile::GetSystemDirectory());
|
||||
wxASSERT(path.IsOk());
|
||||
m_RememberedDir = m_RootDir = path.GetPath();
|
||||
}
|
||||
|
||||
void FieldEditCtrl_File::StartEdit(wxWindow* parent, wxRect rect, long row, int col)
|
||||
{
|
||||
new QuickFileCtrl(parent, rect, m_RootDir, m_FileMask, ListCtrlValidator((EditableListCtrl*)parent, row, col));
|
||||
new QuickFileCtrl(parent, rect, m_RootDir, m_FileMask, m_RememberedDir, ListCtrlValidator((EditableListCtrl*)parent, row, col));
|
||||
}
|
@ -54,6 +54,7 @@ private:
|
||||
class FieldEditCtrl_File : public FieldEditCtrl
|
||||
{
|
||||
public:
|
||||
// rootDir is relative to mods/official, and must end with a /
|
||||
FieldEditCtrl_File(const wxString& rootDir, const wxString& fileMask);
|
||||
|
||||
protected:
|
||||
@ -62,4 +63,5 @@ protected:
|
||||
private:
|
||||
wxString m_RootDir;
|
||||
wxString m_FileMask;
|
||||
wxString m_RememberedDir;
|
||||
};
|
||||
|
@ -13,6 +13,9 @@ const int verticalPadding = 2;
|
||||
// changes, and compare the focus-recipient to every control inside the group,
|
||||
// to tell whether focus is leaving.
|
||||
//
|
||||
// (This solution doesn't work very well, and I'd like to find a better
|
||||
// way of doing it...)
|
||||
//
|
||||
// So, create some unexciting classes:
|
||||
|
||||
class FileCtrl_TextCtrl : public wxTextCtrl
|
||||
@ -86,14 +89,30 @@ public:
|
||||
long style, const wxString& rootDir, const wxString& fileMask)
|
||||
: FileCtrl_Button(parent, wxID_ANY, _("&Browse..."), pos, size, style),
|
||||
m_RootDir(rootDir), m_FileMask(fileMask)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
void OnPress(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
QuickFileCtrl* parent = wxDynamicCast(GetParent(), QuickFileCtrl);
|
||||
wxASSERT(parent);
|
||||
|
||||
wxFileDialog dlg(this, _("Choose a file"), m_RootDir, wxEmptyString, m_FileMask, wxOPEN);
|
||||
wxString defaultDir, defaultFile;
|
||||
|
||||
wxFileName oldFilename (parent->m_TextCtrl->GetValue()); // TODO: use wxPATH_UNIX?
|
||||
if (oldFilename.IsOk())
|
||||
{
|
||||
oldFilename.MakeAbsolute(m_RootDir);
|
||||
defaultDir = oldFilename.GetPath();
|
||||
defaultFile = oldFilename.GetFullName();
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultDir = *parent->m_RememberedDir;
|
||||
defaultFile = wxEmptyString;
|
||||
}
|
||||
|
||||
wxFileDialog dlg(this, _("Choose a file"), defaultDir, defaultFile, m_FileMask, wxOPEN);
|
||||
|
||||
parent->m_DisableKillFocus = true;
|
||||
int ret = dlg.ShowModal();
|
||||
@ -103,6 +122,8 @@ public:
|
||||
return;
|
||||
|
||||
wxFileName filename (dlg.GetPath());
|
||||
*parent->m_RememberedDir = filename.GetPath();
|
||||
|
||||
filename.MakeRelativeTo(m_RootDir);
|
||||
wxString filenameRel (filename.GetFullPath(wxPATH_UNIX));
|
||||
|
||||
@ -123,11 +144,12 @@ QuickFileCtrl::QuickFileCtrl(wxWindow* parent,
|
||||
wxRect& location,
|
||||
const wxString& rootDir,
|
||||
const wxString& fileMask,
|
||||
wxString& rememberedDir,
|
||||
const wxValidator& validator)
|
||||
: wxPanel(parent, wxID_ANY,
|
||||
location.GetPosition()-wxPoint(0,verticalPadding), wxDefaultSize,
|
||||
wxNO_BORDER),
|
||||
m_DisableKillFocus(false)
|
||||
m_DisableKillFocus(false), m_RememberedDir(&rememberedDir)
|
||||
{
|
||||
wxBoxSizer* s = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
@ -148,9 +170,12 @@ QuickFileCtrl::QuickFileCtrl(wxWindow* parent,
|
||||
SetSizer(s);
|
||||
s->SetSizeHints(this);
|
||||
|
||||
m_DisableKillFocus = true; // yucky
|
||||
m_TextCtrl->GetValidator()->TransferToWindow();
|
||||
m_TextCtrl->SetFocus();
|
||||
m_TextCtrl->SetSelection(-1, -1);
|
||||
m_DisableKillFocus = false;
|
||||
m_TextCtrl->SetFocus();
|
||||
}
|
||||
|
||||
void QuickFileCtrl::OnKillFocus()
|
||||
|
@ -8,6 +8,7 @@ public:
|
||||
QuickFileCtrl() {};
|
||||
QuickFileCtrl(wxWindow* parent, wxRect& location,
|
||||
const wxString& rootDir, const wxString& fileMask,
|
||||
wxString& rememberedDir,
|
||||
const wxValidator& validator = wxDefaultValidator);
|
||||
|
||||
void OnKillFocus();
|
||||
@ -16,4 +17,6 @@ public:
|
||||
wxTextCtrl* m_TextCtrl;
|
||||
wxButton* m_ButtonBrowse;
|
||||
bool m_DisableKillFocus;
|
||||
|
||||
wxString* m_RememberedDir; // can't be wxString&, because DYNAMIC_CLASSes need default constructors, and there's no suitable string to store in here...
|
||||
};
|
||||
|
@ -16,6 +16,7 @@ public:
|
||||
AtlasDialog(wxWindow* parent, const wxString& title);
|
||||
virtual ~AtlasDialog() {}
|
||||
|
||||
private:
|
||||
void OnUndo(wxCommandEvent& event);
|
||||
void OnRedo(wxCommandEvent& event);
|
||||
|
||||
|
@ -54,17 +54,6 @@ END_EVENT_TABLE()
|
||||
|
||||
IMPLEMENT_CLASS(AtlasWindow, wxFrame);
|
||||
|
||||
enum
|
||||
{
|
||||
ID_Quit = 1,
|
||||
ID_New,
|
||||
// ID_Import,
|
||||
// ID_Export,
|
||||
ID_Open,
|
||||
ID_Save,
|
||||
ID_SaveAs
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(AtlasWindow, wxFrame)
|
||||
EVT_MENU(ID_New, AtlasWindow::OnNew)
|
||||
// EVT_MENU(ID_Import, AtlasWindow::OnImport)
|
||||
@ -81,7 +70,7 @@ BEGIN_EVENT_TABLE(AtlasWindow, wxFrame)
|
||||
EVT_CLOSE(AtlasWindow::OnClose)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size)
|
||||
AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size, CustomMenu* menu)
|
||||
: wxFrame(parent, wxID_ANY, _T(""), wxDefaultPosition, size),
|
||||
m_WindowTitle(title), m_FileHistory(9)
|
||||
{
|
||||
@ -117,6 +106,18 @@ AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize&
|
||||
m_CommandProc.SetEditMenu(menuEdit);
|
||||
m_CommandProc.Initialize();
|
||||
|
||||
|
||||
if (menu)
|
||||
{
|
||||
wxMenu* menuCustom = new wxMenu;
|
||||
menuBar->Append(menuCustom, menu->title);
|
||||
|
||||
int id = ID_Custom1;
|
||||
for (CustomMenu::CustomMenuItem** item = menu->items; *item; ++item)
|
||||
menuCustom->Append(id++, (*item)->name);
|
||||
}
|
||||
|
||||
|
||||
m_FileHistory.Load(*wxConfigBase::Get());
|
||||
|
||||
CreateStatusBar();
|
||||
|
@ -14,8 +14,34 @@ class AtlasWindow : public wxFrame, public IAtlasSerialiser
|
||||
DECLARE_CLASS(AtlasWindow);
|
||||
|
||||
public:
|
||||
AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size);
|
||||
|
||||
enum
|
||||
{
|
||||
ID_Quit = 1,
|
||||
ID_New,
|
||||
// ID_Import,
|
||||
// ID_Export,
|
||||
ID_Open,
|
||||
ID_Save,
|
||||
ID_SaveAs,
|
||||
|
||||
// IDs for custom window-specific menu items
|
||||
ID_Custom1,
|
||||
ID_Custom2,
|
||||
ID_Custom3
|
||||
};
|
||||
|
||||
// See ActorEditor.cpp for example usage
|
||||
struct CustomMenu {
|
||||
const wxChar* title;
|
||||
struct CustomMenuItem {
|
||||
const wxChar* name;
|
||||
}** items;
|
||||
};
|
||||
|
||||
AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size, CustomMenu* menu = NULL);
|
||||
|
||||
private:
|
||||
void OnNew(wxCommandEvent& event);
|
||||
// void OnImport(wxCommandEvent& event);
|
||||
// void OnExport(wxCommandEvent& event);
|
||||
|
20
source/tools/atlas/AtlasUI/General/AtlasClipboard.cpp
Normal file
20
source/tools/atlas/AtlasUI/General/AtlasClipboard.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "AtlasClipboard.h"
|
||||
|
||||
// TODO: Do this properly, using the native clipboard. (That probably
|
||||
// requires AtObj to be serialisable, though... Maybe just use XML?)
|
||||
|
||||
static AtObj g_Clipboard;
|
||||
|
||||
bool AtlasClipboard::SetClipboard(AtObj& in)
|
||||
{
|
||||
g_Clipboard = in;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AtlasClipboard::GetClipboard(AtObj& out)
|
||||
{
|
||||
out = g_Clipboard;
|
||||
return true;
|
||||
}
|
9
source/tools/atlas/AtlasUI/General/AtlasClipboard.h
Normal file
9
source/tools/atlas/AtlasUI/General/AtlasClipboard.h
Normal file
@ -0,0 +1,9 @@
|
||||
#include "AtlasObject/AtlasObject.h"
|
||||
|
||||
class AtlasClipboard
|
||||
{
|
||||
public:
|
||||
// Return true on success
|
||||
static bool SetClipboard(AtObj& in);
|
||||
static bool GetClipboard(AtObj& out);
|
||||
};
|
@ -11,6 +11,8 @@ public:
|
||||
// relative to the current working directory.
|
||||
static void SetSystemDirectory(const wxString& dir);
|
||||
|
||||
static wxString GetSystemDirectory() { return systemDir; }
|
||||
|
||||
private:
|
||||
static wxString systemDir;
|
||||
};
|
@ -15,6 +15,11 @@ class MyApp: public wxApp
|
||||
// Initialise the global config file
|
||||
wxConfigBase::Set(new wxConfig(_T("Atlas Editor"), _T("Wildfire Games")));
|
||||
|
||||
// Assume that the .exe is located in .../binaries/system. (We can't
|
||||
// just use the cwd, since that isn't correct when being executed by
|
||||
// dragging-and-dropping onto the program in Explorer.)
|
||||
Datafile::SetSystemDirectory(argv[0]);
|
||||
|
||||
// Display the Actor Editor window
|
||||
AtlasWindow *frame = new ActorEditor(NULL);
|
||||
frame->Show();
|
||||
@ -23,12 +28,6 @@ class MyApp: public wxApp
|
||||
// One argument => argv[1] is a filename to open
|
||||
if (argc > 1)
|
||||
{
|
||||
// We were probably executed by dragging a file onto the icon.
|
||||
// The working directory is then different to the exe's directory,
|
||||
// so we need to set it. (In the normal no-argument case, it should
|
||||
// be safe to assume that we're being run from the right directory.)
|
||||
Datafile::SetSystemDirectory(argv[0]);
|
||||
|
||||
wxChar* filename = argv[1];
|
||||
if (wxFile::Exists(filename))
|
||||
frame->OpenFile(filename);
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "wx/dialog.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/artprov.h"
|
||||
#include "wx/file.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -1,15 +1,13 @@
|
||||
* Open from prop-actor selection
|
||||
* Regression testing
|
||||
|
||||
* Open actors from prop-actor selection
|
||||
|
||||
* Make import undo work with multi-control windows, and update the title bar
|
||||
|
||||
===
|
||||
|
||||
* 'Create entity' button (take name, parent)
|
||||
|
||||
* Better input controls (=> export nicely, support undo, etc)
|
||||
|
||||
* Copy and paste
|
||||
|
||||
* Help (tooltips, etc)
|
||||
|
||||
* More efficient Datafile::ReadList (don't read from disk every time)
|
||||
@ -22,7 +20,8 @@
|
||||
|
||||
===
|
||||
|
||||
* Correct undo menu entry when selecting 'New' (so it's not 'Import')
|
||||
* Better copy and paste (e.g. between multiple instances of the program,
|
||||
and paste XML into other text-editing programs
|
||||
|
||||
* Save on exit: don't ask if no changes
|
||||
|
||||
@ -63,8 +62,11 @@
|
||||
|
||||
======
|
||||
|
||||
Done:
|
||||
Done: (newest at top)
|
||||
|
||||
* Copy and paste
|
||||
* 'Create entity' button (take name, parent)
|
||||
* Correct undo menu entry when selecting 'New' (so it's not 'Import')
|
||||
* MRU file list
|
||||
* 'New' menu item
|
||||
* Import/export filter, for validation(?) and for handling attributes
|
||||
|
Loading…
Reference in New Issue
Block a user