diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp
index 613221ee48..2836a4cafc 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.cpp
@@ -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:
+ //
+ //
+ //
+ // units/celt_csw_a.xml
+ //
+ //
+ // '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("\r\n")
+ _T("\r\n")
+ _T("\r\n")
+ _T("\t") + actorFilename.GetFullPath(wxPATH_UNIX) + _T("\r\n")
+ _T("\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;
+ }
+}
\ No newline at end of file
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.h b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.h
index 563adca974..4c2cde9260 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.h
+++ b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditor.h
@@ -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();
};
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp
index 7e59939d01..7bfb15797e 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp
@@ -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")));
}
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp
index 63cb40c7e6..28a5474d03 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp
@@ -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());
}
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h
index ac95b3eed6..9bb84b7e92 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h
+++ b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.h
@@ -17,6 +17,9 @@ protected:
AtObj FreezeData();
void ThawData(AtObj& in);
+ AtObj ExportData();
+ void ImportData(AtObj& in);
+
private:
AnimListEditorListCtrl* m_MainListBox;
};
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
index 993f3bd163..ffe83808a1 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
@@ -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)
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h
index 99d32c5ae8..6307334e9d 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h
+++ b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.h
@@ -17,6 +17,9 @@ protected:
AtObj FreezeData();
void ThawData(AtObj& in);
+ AtObj ExportData();
+ void ImportData(AtObj& in);
+
private:
PropListEditorListCtrl* m_MainListBox;
};
diff --git a/source/tools/atlas/AtlasUI/AtlasUI.vcproj b/source/tools/atlas/AtlasUI/AtlasUI.vcproj
index e9c31628b3..decfe379cc 100644
--- a/source/tools/atlas/AtlasUI/AtlasUI.vcproj
+++ b/source/tools/atlas/AtlasUI/AtlasUI.vcproj
@@ -124,6 +124,12 @@
+
+
+
+
diff --git a/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrlCommands.cpp b/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrlCommands.cpp
index 7996c42f0c..7ebb45f7bd 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrlCommands.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/DraggableListCtrl/DraggableListCtrlCommands.cpp
@@ -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
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.cpp
index 288e7d9a20..52de393f89 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.cpp
@@ -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()
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.h
index 01f12cb4f6..434655b7d0 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrl.h
@@ -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);
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.cpp
index 13daccafd8..99691978e0 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.cpp
@@ -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;
+}
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.h
index ccae0d0e51..cffa4a2a91 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/EditableListCtrlCommands.h
@@ -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 m_OldData;
-};
-
-
class EditCommand_Dialog : public AtlasWindowCommand
{
DECLARE_CLASS(EditCommand_Dialog);
@@ -59,3 +42,20 @@ private:
std::vector 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 m_OldData;
+};
+
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
index df1c671c23..7e12fb8f7d 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
@@ -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));
}
\ No newline at end of file
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h
index d309008e34..25d32f1a8b 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h
@@ -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;
};
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp
index 350dfe0272..4a5099b08a 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp
@@ -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()
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h
index 75b5ab0cbc..466d0c867e 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h
@@ -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...
};
diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h
index 3445d865a9..b5ab334362 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasDialog.h
@@ -16,6 +16,7 @@ public:
AtlasDialog(wxWindow* parent, const wxString& title);
virtual ~AtlasDialog() {}
+private:
void OnUndo(wxCommandEvent& event);
void OnRedo(wxCommandEvent& event);
diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp
index c1bd343f8e..7136afd087 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.cpp
@@ -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();
diff --git a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h
index b5285a59bf..d6288e8a28 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/Windows/AtlasWindow.h
@@ -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);
diff --git a/source/tools/atlas/AtlasUI/General/AtlasClipboard.cpp b/source/tools/atlas/AtlasUI/General/AtlasClipboard.cpp
new file mode 100644
index 0000000000..2349552d86
--- /dev/null
+++ b/source/tools/atlas/AtlasUI/General/AtlasClipboard.cpp
@@ -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;
+}
\ No newline at end of file
diff --git a/source/tools/atlas/AtlasUI/General/AtlasClipboard.h b/source/tools/atlas/AtlasUI/General/AtlasClipboard.h
new file mode 100644
index 0000000000..d1134d8b44
--- /dev/null
+++ b/source/tools/atlas/AtlasUI/General/AtlasClipboard.h
@@ -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);
+};
\ No newline at end of file
diff --git a/source/tools/atlas/AtlasUI/General/Datafile.h b/source/tools/atlas/AtlasUI/General/Datafile.h
index 1947e767fe..72fe12d99d 100644
--- a/source/tools/atlas/AtlasUI/General/Datafile.h
+++ b/source/tools/atlas/AtlasUI/General/Datafile.h
@@ -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;
};
\ No newline at end of file
diff --git a/source/tools/atlas/AtlasUI/Misc/actored.cpp b/source/tools/atlas/AtlasUI/Misc/actored.cpp
index cdfb69a0a6..37f956477e 100644
--- a/source/tools/atlas/AtlasUI/Misc/actored.cpp
+++ b/source/tools/atlas/AtlasUI/Misc/actored.cpp
@@ -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);
diff --git a/source/tools/atlas/AtlasUI/Misc/stdafx.h b/source/tools/atlas/AtlasUI/Misc/stdafx.h
index 2108e81970..967d6277b7 100644
--- a/source/tools/atlas/AtlasUI/Misc/stdafx.h
+++ b/source/tools/atlas/AtlasUI/Misc/stdafx.h
@@ -17,6 +17,7 @@
#include "wx/dialog.h"
#include "wx/filename.h"
#include "wx/artprov.h"
+#include "wx/file.h"
#include
#include
diff --git a/source/tools/atlas/AtlasUI/TODO.txt b/source/tools/atlas/AtlasUI/TODO.txt
index c341f6a7ed..5b789480cd 100644
--- a/source/tools/atlas/AtlasUI/TODO.txt
+++ b/source/tools/atlas/AtlasUI/TODO.txt
@@ -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