diff --git a/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp b/source/tools/atlas/AtlasUI/ActorEditor/ActorEditorListCtrl.cpp
index b0d845c852..6c1b03544b 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_Text());
- AddColumnType(_("Texture"), 160, "texture", 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(_("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 ec9e7d5bdb..8338eb5f1c 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/AnimListEditor.cpp
@@ -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_Text());
+ AddColumnType(_("File"), 200, "file", new FieldEditCtrl_File(_T("art/animation"), _("All files (*.*)|*.*")));
AddColumnType(_("Speed"), 50, "speed", new FieldEditCtrl_Text());
}
diff --git a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
index 521e78b038..e6da5e99e4 100644
--- a/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
+++ b/source/tools/atlas/AtlasUI/ActorEditor/PropListEditor.cpp
@@ -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, "model", new FieldEditCtrl_Text());
+ AddColumnType(_("Prop model"), 200, "model", new FieldEditCtrl_File(_T("art/actors"), _("Actor files (*.xml)|*.xml"))); // not *.*, in order to hide all the *.xmb files
}
void PropListEditorListCtrl::DoImport(AtObj& in)
diff --git a/source/tools/atlas/AtlasUI/AtlasUI.vcproj b/source/tools/atlas/AtlasUI/AtlasUI.vcproj
index f7efa22452..e8b54d6c3e 100644
--- a/source/tools/atlas/AtlasUI/AtlasUI.vcproj
+++ b/source/tools/atlas/AtlasUI/AtlasUI.vcproj
@@ -182,6 +182,12 @@
+
+
+
+
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
index 1cc4eb4023..21abd9bf24 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.cpp
@@ -4,8 +4,11 @@
#include "EditableListCtrlCommands.h"
#include "ListCtrlValidator.h"
+
#include "QuickTextCtrl.h"
#include "QuickComboBox.h"
+#include "QuickFileCtrl.h"
+
#include "AtlasDialog.h"
#include "EditableListCtrl.h"
#include "AtlasObject/AtlasObject.h"
@@ -42,7 +45,7 @@ void FieldEditCtrl_List::StartEdit(wxWindow* parent, wxRect rect, long row, int
//////////////////////////////////////////////////////////////////////////
-FieldEditCtrl_Dialog::FieldEditCtrl_Dialog(wxString dialogType)
+FieldEditCtrl_Dialog::FieldEditCtrl_Dialog(const wxString& dialogType)
: m_DialogType(dialogType)
{
}
@@ -72,3 +75,17 @@ void FieldEditCtrl_Dialog::StartEdit(wxWindow* parent, wxRect WXUNUSED(rect), lo
delete dialog;
}
+
+//////////////////////////////////////////////////////////////////////////
+
+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;
+}
+
+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));
+}
\ 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 d33778a59a..d309008e34 100644
--- a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/FieldEditCtrl.h
@@ -39,7 +39,7 @@ private:
class FieldEditCtrl_Dialog : public FieldEditCtrl
{
public:
- FieldEditCtrl_Dialog(wxString dialogType);
+ FieldEditCtrl_Dialog(const wxString& dialogType);
protected:
void StartEdit(wxWindow* parent, wxRect rect, long row, int col);
@@ -47,3 +47,19 @@ protected:
private:
wxString m_DialogType;
};
+
+//////////////////////////////////////////////////////////////////////////
+
+
+class FieldEditCtrl_File : public FieldEditCtrl
+{
+public:
+ FieldEditCtrl_File(const wxString& rootDir, const wxString& fileMask);
+
+protected:
+ void StartEdit(wxWindow* parent, wxRect rect, long row, int col);
+
+private:
+ wxString m_RootDir;
+ wxString m_FileMask;
+};
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp
new file mode 100644
index 0000000000..17cef587a7
--- /dev/null
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp
@@ -0,0 +1,167 @@
+#include "stdafx.h"
+
+#include "QuickFileCtrl.h"
+#include "wx/filename.h"
+
+const int verticalPadding = 2;
+
+//////////////////////////////////////////////////////////////////////////
+
+// Unpleasant hack: It's necessary to keep focus inside the QuickFileCtrl;
+// but since that's made of lots of controls, they each need to detect focus
+// changes, and compare the focus-recipient to every control inside the group,
+// to tell whether focus is leaving.
+//
+// So, create some unexciting classes:
+
+class FileCtrl_TextCtrl : public wxTextCtrl
+{
+public:
+ FileCtrl_TextCtrl(wxWindow* pParent, wxWindowID vId, const wxString& rsValue = wxEmptyString, const wxPoint& rPos = wxDefaultPosition, const wxSize& rSize = wxDefaultSize, long lStyle = 0, const wxValidator& rValidator = wxDefaultValidator, const wxString& rsName = wxTextCtrlNameStr)
+ : wxTextCtrl(pParent, vId, rsValue, rPos, rSize, lStyle, rValidator, rsName)
+ {}
+
+ void OnKillFocus(wxFocusEvent& WXUNUSED(event))
+ {
+ wxWindow* focused = wxWindow::FindFocus();
+ QuickFileCtrl* parent = wxDynamicCast(GetParent(), QuickFileCtrl);
+ wxASSERT(parent);
+ if (! (focused == parent->m_TextCtrl || focused == parent->m_ButtonBrowse))
+ parent->OnKillFocus();
+ }
+
+ void OnChar(wxKeyEvent& event)
+ {
+ QuickFileCtrl* parent = wxDynamicCast(GetParent(), QuickFileCtrl);
+ wxASSERT(parent);
+ if (event.GetKeyCode() == WXK_RETURN)
+ parent->OnKillFocus();
+ else if (event.GetKeyCode() == WXK_ESCAPE)
+ parent->Destroy();
+ else
+ event.Skip();
+ }
+
+ DECLARE_EVENT_TABLE();
+};
+
+BEGIN_EVENT_TABLE(FileCtrl_TextCtrl, wxTextCtrl)
+ EVT_KILL_FOCUS(FileCtrl_TextCtrl::OnKillFocus)
+ EVT_CHAR(FileCtrl_TextCtrl::OnChar)
+END_EVENT_TABLE()
+
+class FileCtrl_Button : public wxButton
+{
+public:
+ FileCtrl_Button(wxWindow* pParent, wxWindowID vId, const wxString& rsValue = wxEmptyString, const wxPoint& rPos = wxDefaultPosition, const wxSize& rSize = wxDefaultSize, long lStyle = 0, const wxValidator& rValidator = wxDefaultValidator, const wxString& rsName = wxTextCtrlNameStr)
+ : wxButton(pParent, vId, rsValue, rPos, rSize, lStyle, rValidator, rsName)
+ {}
+
+ void OnKillFocus(wxFocusEvent& WXUNUSED(event))
+ {
+ wxWindow* focused = wxWindow::FindFocus();
+ QuickFileCtrl* parent = wxDynamicCast(GetParent(), QuickFileCtrl);
+ wxASSERT(parent);
+ if (! (focused == parent->m_TextCtrl || focused == parent->m_ButtonBrowse))
+ parent->OnKillFocus();
+ }
+
+ virtual void OnPress(wxCommandEvent& event)=0;
+
+ DECLARE_EVENT_TABLE();
+};
+
+BEGIN_EVENT_TABLE(FileCtrl_Button, wxButton)
+ EVT_KILL_FOCUS(FileCtrl_Button::OnKillFocus)
+ EVT_BUTTON(wxID_ANY, FileCtrl_Button::OnPress)
+END_EVENT_TABLE()
+
+//////////////////////////////////////////////////////////////////////////
+
+class FileCtrl_Button_Browse : public FileCtrl_Button
+{
+public:
+ FileCtrl_Button_Browse(wxWindow* parent, const wxPoint& pos, const wxSize& size,
+ 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& event)
+ {
+ QuickFileCtrl* parent = wxDynamicCast(GetParent(), QuickFileCtrl);
+ wxASSERT(parent);
+
+ wxFileDialog dlg(this, _("Choose a file"), m_RootDir, wxEmptyString, m_FileMask, wxOPEN);
+
+ parent->m_DisableKillFocus = true;
+ int ret = dlg.ShowModal();
+ parent->m_DisableKillFocus = false;
+
+ if (ret != wxID_OK)
+ return;
+
+ wxFileName filename (dlg.GetPath());
+ filename.MakeRelativeTo(m_RootDir);
+ wxString filenameRel (filename.GetFullPath(wxPATH_UNIX));
+
+ parent->m_TextCtrl->SetValue(filenameRel);
+ }
+
+private:
+ wxString m_RootDir;
+ wxString m_FileMask;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
+
+IMPLEMENT_DYNAMIC_CLASS(QuickFileCtrl, wxPanel);
+
+QuickFileCtrl::QuickFileCtrl(wxWindow* parent,
+ wxRect& location,
+ const wxString& rootDir,
+ const wxString& fileMask,
+ const wxValidator& validator)
+ : wxPanel(parent, wxID_ANY,
+ location.GetPosition()-wxPoint(0,verticalPadding), wxDefaultSize,
+ wxNO_BORDER),
+ m_DisableKillFocus(false)
+{
+ wxBoxSizer* s = new wxBoxSizer(wxVERTICAL);
+
+ m_TextCtrl = new FileCtrl_TextCtrl(this, wxID_ANY, wxEmptyString,
+ wxDefaultPosition,
+ location.GetSize()+wxSize(0,verticalPadding*2),
+ wxSUNKEN_BORDER,
+ validator);
+
+ m_ButtonBrowse = new FileCtrl_Button_Browse(this,
+ // Position the button just below the text control
+ wxPoint(0, location.GetSize().GetHeight()+verticalPadding),
+ wxDefaultSize, wxBU_EXACTFIT,
+ rootDir, fileMask);
+
+ s->Add(m_TextCtrl);
+ s->Add(m_ButtonBrowse);
+ SetSizer(s);
+ s->SetSizeHints(this);
+
+ m_TextCtrl->GetValidator()->TransferToWindow();
+ m_TextCtrl->SetFocus();
+ m_TextCtrl->SetSelection(-1, -1);
+}
+
+void QuickFileCtrl::OnKillFocus()
+{
+ // (This is always called explicitly, never by the wx event system)
+
+ // Another unpleasant hack: TransferFromWindow happens to shift focus,
+ // which ends up with OnKillFocus being called again, so it ends up
+ // trying to destroy the window twice. So, only allow that to happen once:
+ if (m_DisableKillFocus) return;
+ m_DisableKillFocus = true;
+
+ m_TextCtrl->GetValidator()->TransferFromWindow();
+ Destroy();
+}
diff --git a/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h
new file mode 100644
index 0000000000..f36ad6af1e
--- /dev/null
+++ b/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h
@@ -0,0 +1,17 @@
+class QuickFileCtrl : public wxPanel
+{
+ DECLARE_DYNAMIC_CLASS(QuickFileCtrl);
+
+public:
+ QuickFileCtrl() {};
+ QuickFileCtrl(wxWindow* parent, wxRect& location,
+ const wxString& rootDir, const wxString& fileMask,
+ const wxValidator& validator = wxDefaultValidator);
+
+ void OnKillFocus();
+
+//private: // (or *theoretically* private)
+ wxTextCtrl* m_TextCtrl;
+ wxButton* m_ButtonBrowse;
+ bool m_DisableKillFocus;
+};
diff --git a/source/tools/atlas/AtlasUI/TODO.txt b/source/tools/atlas/AtlasUI/TODO.txt
index 826ff45a19..38225008df 100644
--- a/source/tools/atlas/AtlasUI/TODO.txt
+++ b/source/tools/atlas/AtlasUI/TODO.txt
@@ -5,8 +5,6 @@
* Copy and paste
-* Browse for meshes/actors/etc.
-
* Save on exit
* Help (tooltips, etc)
@@ -15,6 +13,8 @@
===
+* 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
* Window size memory