From af7fa2fc6c2218586635b1d640ddaa52dd9d4e6d Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Thu, 24 Mar 2005 19:01:06 +0000 Subject: [PATCH] Actor Editor: File-selection dialogs in appropriate places. (They're not very nice, but they work most of the time) This was SVN commit r2045. --- .../ActorEditor/ActorEditorListCtrl.cpp | 4 +- .../AtlasUI/ActorEditor/AnimListEditor.cpp | 2 +- .../AtlasUI/ActorEditor/PropListEditor.cpp | 2 +- source/tools/atlas/AtlasUI/AtlasUI.vcproj | 6 + .../EditableListCtrl/FieldEditCtrl.cpp | 19 +- .../EditableListCtrl/FieldEditCtrl.h | 18 +- .../EditableListCtrl/QuickFileCtrl.cpp | 167 ++++++++++++++++++ .../EditableListCtrl/QuickFileCtrl.h | 17 ++ source/tools/atlas/AtlasUI/TODO.txt | 4 +- 9 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp create mode 100644 source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.h 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