0ad/source/tools/atlas/AtlasUI/CustomControls/EditableListCtrl/QuickFileCtrl.cpp

169 lines
5.2 KiB
C++

#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& WXUNUSED(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();
}