1
0
forked from mirrors/0ad

Actor Editor: Open / save / save as. Confirmation on exit. Allow launch from command line / Explorer.

This was SVN commit r2053.
This commit is contained in:
Ykkrosh
2005-03-30 10:35:43 +00:00
parent a321f1cc9f
commit 2fb2f80aa0
9 changed files with 237 additions and 65 deletions
@@ -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"), _("All files (*.*)|*.*")));
AddColumnType(_("Texture"), 160, "texture", new FieldEditCtrl_File(_T("art/textures"), _("All files (*.*)|*.*")));
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")));
}
@@ -38,7 +38,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"), _("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());
}
@@ -38,7 +38,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"))); // not *.*, in order to hide all the *.xmb files
AddColumnType(_("Prop model"), 200, "@actor", new FieldEditCtrl_File(_T("art/actors"), _("Actor files (*.xml)|*.xml|All files (*.*)|*.*")));
}
void PropListEditorListCtrl::DoImport(AtObj& in)
@@ -6,22 +6,74 @@
#include "wx/intl.h"
#include "wx/menu.h"
#include "wx/artprov.h"
//////////////////////////////////////////////////////////////////////////
class SaveOnExitDialog : public wxDialog
{
public:
SaveOnExitDialog(wxWindow* parent, bool allowCancel)
: wxDialog(parent, wxID_ANY, (wxString) _("Save changes?"))
{
wxBitmap bitmap = wxArtProvider::GetIcon(wxART_WARNING, wxART_MESSAGE_BOX);
wxBoxSizer* topsizer = new wxBoxSizer(wxHORIZONTAL);
topsizer->Add(new wxStaticBitmap(this, wxID_ANY, bitmap),
wxSizerFlags().Centre()/*.Border(wxALL, 14)*/);
topsizer->Add(new wxStaticText(this, wxID_ANY, _("Would you like to save your changes to the current document?")),
wxSizerFlags().Centre().Border(wxLEFT, 10));
wxStdDialogButtonSizer* buttons = new wxStdDialogButtonSizer();
buttons->AddButton(new wxButton(this, wxID_SAVE, _("&Save changes"))); // use _SAVE (instead of _YES) so that nice things happen on Macs
buttons->AddButton(new wxButton(this, wxID_NO, _("&Discard changes")));
if (allowCancel)
buttons->AddButton(new wxButton(this, wxID_CANCEL, _("&Cancel")));
buttons->Finalise();
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(topsizer, wxSizerFlags().Proportion(1).Centre().Border(wxLEFT|wxRIGHT|wxTOP, 10));
sizer->Add(buttons, wxSizerFlags().Centre().Border(wxALL, 10));
SetSizer(sizer);
sizer->SetSizeHints(this);
}
void OnSave(wxCommandEvent& WXUNUSED(event)) { EndDialog(wxID_SAVE); }
void OnNo(wxCommandEvent& WXUNUSED(event)) { EndDialog(wxID_NO); }
DECLARE_EVENT_TABLE();
};
BEGIN_EVENT_TABLE(SaveOnExitDialog, wxDialog)
EVT_BUTTON(wxID_SAVE, SaveOnExitDialog::OnSave)
EVT_BUTTON(wxID_NO, SaveOnExitDialog::OnNo)
END_EVENT_TABLE()
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_CLASS(AtlasWindow, wxFrame);
enum
{
ID_Quit = 1,
ID_Import,
ID_Export
// ID_Import,
// ID_Export,
ID_Open,
ID_Save,
ID_SaveAs
};
BEGIN_EVENT_TABLE(AtlasWindow, wxFrame)
EVT_MENU(ID_Quit, AtlasWindow::OnQuit)
EVT_MENU(ID_Import, AtlasWindow::OnImport)
EVT_MENU(ID_Export, AtlasWindow::OnExport)
// EVT_MENU(ID_Import, AtlasWindow::OnImport)
// EVT_MENU(ID_Export, AtlasWindow::OnExport)
EVT_MENU(ID_Open, AtlasWindow::OnOpen)
EVT_MENU(ID_Save, AtlasWindow::OnSave)
EVT_MENU(ID_SaveAs, AtlasWindow::OnSaveAs)
EVT_MENU(wxID_UNDO, AtlasWindow::OnUndo)
EVT_MENU(wxID_REDO, AtlasWindow::OnRedo)
EVT_CLOSE(AtlasWindow::OnClose)
END_EVENT_TABLE()
AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize& size)
@@ -35,12 +87,18 @@ AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize&
wxMenu *menuFile = new wxMenu;
menuBar->Append(menuFile, _("&File"));
{
menuFile->Append(ID_Import, _("&Import..."));
menuFile->Append(ID_Export, _("&Export..."));
// menuFile->Append(ID_Import, _("&Import..."));
// menuFile->Append(ID_Export, _("&Export..."));
menuFile->Append(ID_Open, _("&Open..."));
menuFile->Append(ID_Save, _("&Save"));
menuFile->Append(ID_SaveAs, _("Save &As..."));
menuFile->AppendSeparator();//-----------
menuFile->Append(ID_Quit, _("E&xit"));
}
m_menuItem_Save = menuFile->FindItem(ID_Save); // to let it be greyed out
wxASSERT(m_menuItem_Save);
wxMenu *menuEdit = new wxMenu;
menuBar->Append(menuEdit, _("&Edit"));
{
@@ -54,7 +112,7 @@ AtlasWindow::AtlasWindow(wxWindow* parent, const wxString& title, const wxSize&
CreateStatusBar();
//SetStatusText(_("Welcome to wxWidgets!"));
SetDisplayedFilename(_T(""));
SetCurrentFilename();
}
void AtlasWindow::OnQuit(wxCommandEvent& WXUNUSED(event))
@@ -62,6 +120,30 @@ void AtlasWindow::OnQuit(wxCommandEvent& WXUNUSED(event))
Close();
}
void AtlasWindow::OnClose(wxCloseEvent& event)
{
SaveOnExitDialog dialog(this, event.CanVeto());
int ret = dialog.ShowModal();
if (ret == wxID_SAVE)
{
if (SaveChanges(false))
event.Skip(); // save succeeded; exit
else
event.Veto(); // save failed; don't exit
}
else if (ret == wxID_NO)
{
// discard changes
event.Skip();
}
else
{
assert(ret == wxID_CANCEL);
event.Veto();
}
}
void AtlasWindow::OnUndo(wxCommandEvent& WXUNUSED(event))
{
m_CommandProc.Undo();
@@ -73,45 +155,89 @@ void AtlasWindow::OnRedo(wxCommandEvent& WXUNUSED(event))
}
void AtlasWindow::OnImport(wxCommandEvent& WXUNUSED(event))
//void AtlasWindow::OnImport(wxCommandEvent& WXUNUSED(event))
//{
// ...
//}
//
//void AtlasWindow::OnExport(wxCommandEvent& WXUNUSED(event))
//{
// ...
//}
void AtlasWindow::OnOpen(wxCommandEvent& WXUNUSED(event))
{
wxFileDialog dlg (this, _T("Select XML file to import"), _T(""), _T(""), _T("XML files (*.xml)|*.xml"), wxOPEN);
wxFileDialog dlg (this, _("Select XML file to open"), _T(""), _T(""), _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxOPEN);
if (dlg.ShowModal() != wxID_OK)
return;
wxString filename = dlg.GetPath();
OpenFile(dlg.GetPath());
}
AtObj file (AtlasObject::LoadFromXML(filename.c_str()));
void AtlasWindow::OnSave(wxCommandEvent& WXUNUSED(event))
{
SaveChanges(false);
}
void AtlasWindow::OnSaveAs(wxCommandEvent& WXUNUSED(event))
{
SaveChanges(true);
}
void AtlasWindow::SetCurrentFilename(wxFileName filename)
{
m_CurrentFilename = filename;
if (filename.IsOk())
SetTitle(m_WindowTitle + _T(" - ") + filename.GetName());
else
SetTitle(m_WindowTitle + _T(" - ") + _("Unnamed file"));
if (m_menuItem_Save)
m_menuItem_Save->Enable(filename.IsOk());
}
bool AtlasWindow::SaveChanges(bool forceSaveAs)
{
if (forceSaveAs || !GetCurrentFilename().IsOk())
{
wxFileDialog dlg (this, _("Select XML file to save as"),
GetCurrentFilename().GetPath(), GetCurrentFilename().GetFullName(),
//_T(""), _T(""),
_("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxSAVE | wxOVERWRITE_PROMPT);
if (dlg.ShowModal() != wxID_OK)
return false;
SetCurrentFilename(dlg.GetPath());
}
if (! GetCurrentFilename().IsOk())
{
wxLogError(_T("Invalid 'save as' filename"));
return false;
}
AtObj file (Export());
// TODO: Make sure it succeeded. Back up .xml file in case it didn't.
AtlasObject::SaveToXML(file, GetCurrentFilename().GetFullPath());
return true;
}
bool AtlasWindow::OpenFile(wxString filename)
{
AtObj file (AtlasObject::LoadFromXML(filename));
// TODO: Make sure it succeeded.
Import(file);
SetDisplayedFilename(dlg.GetFilename());
}
void AtlasWindow::OnExport(wxCommandEvent& WXUNUSED(event))
{
wxFileDialog dlg (this, _T("Select XML file to export"), _T(""), _T(""), _T("XML files (*.xml)|*.xml"), wxSAVE | wxOVERWRITE_PROMPT);
if (dlg.ShowModal() != wxID_OK)
return;
wxString filename = dlg.GetPath();
AtObj file (Export());
AtlasObject::SaveToXML(file, filename.c_str());
SetDisplayedFilename(dlg.GetFilename());
}
void AtlasWindow::SetDisplayedFilename(wxString filename)
{
if (filename == _T(""))
m_DisplayedFilename = _("Unnamed file");
else
m_DisplayedFilename = filename;
SetTitle(m_WindowTitle + _T(" - ") + m_DisplayedFilename);
SetCurrentFilename(filename);
return true;
}
@@ -3,6 +3,7 @@
#include "IAtlasExporter.h"
#include "wx/frame.h"
#include "wx/filename.h"
class AtObj;
@@ -17,21 +18,34 @@ public:
void OnQuit(wxCommandEvent& event);
void OnImport(wxCommandEvent& event);
void OnExport(wxCommandEvent& event);
// void OnImport(wxCommandEvent& event);
// void OnExport(wxCommandEvent& event);
// TODO: import/export vs open/save/saveas - how should it decide which to do?
void OnOpen(wxCommandEvent& event);
void OnSave(wxCommandEvent& event);
void OnSaveAs(wxCommandEvent& event);
void OnUndo(wxCommandEvent& event);
void OnRedo(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
protected:
// Call with the name of the currently opened file, or with the
// empty string for new unnamed documents
void SetDisplayedFilename(wxString filename);
void SetCurrentFilename(wxFileName filename = wxString());
wxFileName GetCurrentFilename() { return m_CurrentFilename; }
bool SaveChanges(bool forceSaveAs);
public:
bool OpenFile(wxString filename);
private:
AtlasWindowCommandProc m_CommandProc;
wxString m_DisplayedFilename;
wxMenuItem* m_menuItem_Save;
wxFileName m_CurrentFilename;
wxString m_WindowTitle;
DECLARE_EVENT_TABLE();
@@ -8,6 +8,7 @@ AtObj Datafile::ReadList(const char* section)
const wxString relativePath (_T("../data/tools/atlas/lists.xml"));
wxFileName filename (relativePath, wxPATH_UNIX);
filename.MakeAbsolute(systemDir);
if (! filename.FileExists())
{
@@ -18,4 +19,11 @@ AtObj Datafile::ReadList(const char* section)
AtObj lists (AtlasObject::LoadFromXML(filename.GetFullPath()));
return lists["lists"][section];
}
}
void Datafile::SetSystemDirectory(const wxString& dir)
{
systemDir = wxFileName(dir).GetPath();
}
wxString Datafile::systemDir;
@@ -6,4 +6,11 @@ public:
// Read configuration data from data/tools/atlas/lists.xml
static AtObj ReadList(const char* section);
// Specify the location of .../binaries/system, as an absolute path, or
// relative to the current working directory.
static void SetSystemDirectory(const wxString& dir);
private:
static wxString systemDir;
};
+27 -13
View File
@@ -3,24 +3,38 @@
#include "stdafx.h"
#include "ActorEditor/ActorEditor.h"
#include "Datafile.h"
#include "wx/app.h"
#include "wx/file.h"
class MyApp: public wxApp
{
bool OnInit();
bool OnInit()
{
// Display the Actor Editor window
AtlasWindow *frame = new ActorEditor(NULL);
frame->Show();
SetTopWindow(frame);
// 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);
else
wxLogError(_("Cannot find file '%s'"), filename);
}
return true;
}
};
IMPLEMENT_APP(MyApp)
#include <crtdbg.h>
bool MyApp::OnInit()
{
// _CrtSetBreakAlloc(1358);
// MyFrame *frame = new MyFrame("Hello World");
wxFrame *frame = new ActorEditor(NULL);
frame->Show();
SetTopWindow(frame);
return true;
}
+5 -2
View File
@@ -1,12 +1,13 @@
* Open from prop-actor selection
===
* 'Create entity' button (take name, parent)
* Better input controls (=> export nicely, support undo, etc)
* Copy and paste
* Save on exit
* Help (tooltips, etc)
* More efficient Datafile::ReadList (don't read from disk every time)
@@ -17,6 +18,8 @@
===
* Save on exit: don't ask if no changes
* Browse for meshes/actors/etc, in a more nice/correct/unbuggy way
* Make import undo work with multi-control windows, and update the title bar