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:
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user