mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 13:23:56 -07:00
Make include-what-you-use happy with some files in source/tools/atlas and fix what needs to be fixed. Update premake script to include missing deps and drop various extra paths for simplification. Don't always include wx/wx.h via precompiled.h in case PCH is disabled. Ref: #8086 Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
241 lines
7.5 KiB
C++
241 lines
7.5 KiB
C++
/* Copyright (C) 2025 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "precompiled.h"
|
|
|
|
#include "QuickFileCtrl.h"
|
|
|
|
#include "tools/atlas/AtlasUI/General/Datafile.h"
|
|
|
|
#include <wx/anybutton.h>
|
|
#include <wx/button.h>
|
|
#include <wx/chartype.h>
|
|
#include <wx/debug.h>
|
|
#include <wx/event.h>
|
|
#include <wx/filedlg.h>
|
|
#include <wx/filename.h>
|
|
#include <wx/gdicmn.h>
|
|
#include <wx/log.h>
|
|
#include <wx/sizer.h>
|
|
#include <wx/string.h>
|
|
#include <wx/textctrl.h>
|
|
#include <wx/toolbar.h>
|
|
#include <wx/translation.h>
|
|
#include <wx/window.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.
|
|
//
|
|
// (This solution doesn't work very well, and I'd like to find a better
|
|
// way of doing it...)
|
|
//
|
|
// 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);
|
|
|
|
wxString defaultDir, defaultFile;
|
|
|
|
wxFileName oldFilename (parent->m_TextCtrl->GetValue()); // TODO: use wxPATH_UNIX?
|
|
if (oldFilename.IsOk())
|
|
{
|
|
// XXX: this assumes the file was in the 'public' mod, which is
|
|
// often untrue and will quite annoy users
|
|
wxFileName path (_T("mods/public/") + m_RootDir);
|
|
wxASSERT(path.IsOk());
|
|
path.MakeAbsolute(Datafile::GetDataDirectory());
|
|
wxASSERT(path.IsOk());
|
|
|
|
oldFilename.MakeAbsolute(path.GetPath());
|
|
defaultDir = oldFilename.GetPath();
|
|
defaultFile = oldFilename.GetFullName();
|
|
}
|
|
else
|
|
{
|
|
defaultDir = *parent->m_RememberedDir;
|
|
defaultFile = wxEmptyString;
|
|
}
|
|
|
|
wxFileDialog dlg(this, _("Choose a file"), defaultDir, defaultFile, m_FileMask, wxFD_OPEN);
|
|
|
|
parent->m_DisableKillFocus = true;
|
|
int ret = dlg.ShowModal();
|
|
parent->m_DisableKillFocus = false;
|
|
|
|
if (ret != wxID_OK)
|
|
return;
|
|
|
|
wxFileName filename (dlg.GetPath());
|
|
*parent->m_RememberedDir = filename.GetPath();
|
|
|
|
// The file should be in ".../mods/*/$m_RootDir/..." for some unknown '*'
|
|
// So assume it is, and just find the substring after the m_RootDir
|
|
// (XXX: This is pretty bogus because of case-insensitive filenames etc)
|
|
wxString filenameStr (filename.GetFullPath(wxPATH_UNIX));
|
|
int idx = filenameStr.Find(m_RootDir);
|
|
if (idx < 0)
|
|
{
|
|
wxLogError(_T("Selected file (%s) must be in a \"%s\" directory"), filenameStr.c_str(), m_RootDir.c_str());
|
|
return;
|
|
}
|
|
wxString filenameRel (filenameStr.Mid(idx + m_RootDir.Len()));
|
|
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,
|
|
wxString& rememberedDir,
|
|
const wxValidator& validator)
|
|
: wxPanel(parent, wxID_ANY,
|
|
location.GetPosition()-wxPoint(0,verticalPadding), wxDefaultSize,
|
|
wxNO_BORDER),
|
|
m_DisableKillFocus(false), m_RememberedDir(&rememberedDir)
|
|
{
|
|
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_DisableKillFocus = true; // yucky
|
|
m_TextCtrl->GetValidator()->TransferToWindow();
|
|
m_TextCtrl->SetFocus();
|
|
m_TextCtrl->SetSelection(-1, -1);
|
|
m_DisableKillFocus = false;
|
|
m_TextCtrl->SetFocus();
|
|
}
|
|
|
|
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();
|
|
}
|