diff --git a/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.cpp b/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.cpp index dbcee02dad..b6cb055e84 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.cpp +++ b/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.cpp @@ -29,15 +29,17 @@ enum { ID_MapDialogFilename = 1, ID_MapDialogNotebook, ID_ScenarioPage, - ID_SkirmishPage + ID_SkirmishPage, + ID_TutorialPage }; static const wxString scenarioPath(L"maps/scenarios/"); static const wxString skirmishPath(L"maps/skirmishes/"); +static const wxString tutorialPath(L"maps/tutorials/"); MapDialog::MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon) : wxDialog(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(600,400), wxCAPTION|wxRESIZE_BORDER|wxCLOSE_BOX|wxSYSTEM_MENU), - m_Type(type), m_SelectedPage(0) + m_Type(type) { Freeze(); @@ -59,14 +61,13 @@ MapDialog::MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon) wxSizer* pageSizer = new wxBoxSizer(wxVERTICAL); // TODO: Should display something nicer than raw VFS paths wxListBox* listBox = new wxListBox(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL); - const std::vector& scenarioFilenames = *qry.scenarioFilenames; - for (size_t i = 0; i < scenarioFilenames.size(); ++i) + for (const std::wstring& filename : *qry.scenarioFilenames) { - wxString name = scenarioFilenames[i].substr(scenarioPath.Length()); - listBox->Append(name, new wxStringClientData(scenarioFilenames[i])); + wxString name = filename.substr(scenarioPath.Length()); + listBox->Append(name, new wxStringClientData(filename)); } - pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand().Align(wxBOTTOM)); + pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand()); page->SetSizer(pageSizer); notebook->AddPage(page, _("Scenarios")); } @@ -75,17 +76,31 @@ MapDialog::MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon) wxSizer* pageSizer = new wxBoxSizer(wxVERTICAL); // TODO: Should display something nicer than raw VFS paths wxListBox* listBox = new wxListBox(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE|wxLB_HSCROLL); - const std::vector& skirmishFilenames = *qry.skirmishFilenames; - for (size_t i = 0; i < skirmishFilenames.size(); ++i) + for (const std::wstring& filename : *qry.skirmishFilenames) { - wxString name = skirmishFilenames[i].substr(skirmishPath.Length()); - listBox->Append(name, new wxStringClientData(skirmishFilenames[i])); + wxString name = filename.substr(skirmishPath.Length()); + listBox->Append(name, new wxStringClientData(filename)); } - pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand()); + pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand()); page->SetSizer(pageSizer); notebook->AddPage(page, _("Skirmishes")); } + { + wxPanel* page = new wxPanel(notebook, ID_TutorialPage); + wxSizer* pageSizer = new wxBoxSizer(wxVERTICAL); + // TODO: Should display something nicer than raw VFS paths + wxListBox* listBox = new wxListBox(page, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SINGLE | wxLB_HSCROLL); + for (const std::wstring& filename : *qry.tutorialFilenames) + { + wxString name = filename.substr(tutorialPath.Length()); + listBox->Append(name, new wxStringClientData(filename)); + } + + pageSizer->Add(listBox, wxSizerFlags().Proportion(1).Expand()); + page->SetSizer(pageSizer); + notebook->AddPage(page, _("Tutorials")); + } notebook->SetSelection(0); @@ -95,14 +110,12 @@ MapDialog::MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon) wxSizer* filenameSizer = new wxBoxSizer(wxHORIZONTAL); filenameSizer->AddSpacer(10); - filenameSizer->Add(new wxStaticText(this, wxID_ANY, _("Map name: ")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL)); - wxTextCtrl* filename = new wxTextCtrl(this, ID_MapDialogFilename, wxEmptyString); - if (m_Type == MAPDIALOG_OPEN) - filename->Disable(); + filenameSizer->Add(new wxStaticText(this, wxID_ANY, _(m_Type == MAPDIALOG_SAVE ? "Map name: " : "Map path: ")), wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL)); + wxTextCtrl* filename = new wxTextCtrl(this, ID_MapDialogFilename, wxEmptyString, wxDefaultPosition, wxDefaultSize, m_Type == MAPDIALOG_OPEN ? wxTE_READONLY : 0L); filenameSizer->Add(filename, wxSizerFlags().Proportion(1).Expand()); sizer->Add(filenameSizer, wxSizerFlags().Expand()); - sizer->AddSpacer(20); + sizer->AddSpacer(10); wxSizer* buttonSizer = new wxBoxSizer(wxHORIZONTAL); if (m_Type == MAPDIALOG_OPEN) @@ -120,26 +133,48 @@ MapDialog::MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon) Thaw(); } -wxString MapDialog::GetFilename() const +wxString MapDialog::GetSelectedFilePath() const { - wxFileName filename(m_Filename, wxPATH_UNIX); - filename.SetExt(L"xml"); - if (m_SelectedPage == 0) - return scenarioPath + filename.GetFullPath(wxPATH_UNIX); - else if (m_SelectedPage == 1) - return skirmishPath + filename.GetFullPath(wxPATH_UNIX); - else + wxNotebook* notebook = wxDynamicCast(FindWindow(ID_MapDialogNotebook), wxNotebook); + if (!notebook) return wxEmptyString; + + wxFileName fileName(m_FileName, wxPATH_UNIX); + fileName.SetExt(L"xml"); + switch (notebook->GetSelection()) + { + case 0: + return scenarioPath + fileName.GetFullPath(wxPATH_UNIX); + case 1: + return skirmishPath + fileName.GetFullPath(wxPATH_UNIX); + case 2: + return tutorialPath + fileName.GetFullPath(wxPATH_UNIX); + default: + return wxEmptyString; + } } void MapDialog::OnListBox(wxCommandEvent& evt) { if (evt.GetInt() < 0) - m_Filename = wxEmptyString; + m_FileName = wxEmptyString; else - m_Filename = evt.GetString(); + m_FileName = evt.GetString(); - wxDynamicCast(FindWindow(ID_MapDialogFilename), wxTextCtrl)->ChangeValue(m_Filename); + if (m_Type == MAPDIALOG_SAVE) + wxDynamicCast(FindWindow(ID_MapDialogFilename), wxTextCtrl)->ChangeValue(m_FileName); + else + { + wxString filePath = GetSelectedFilePath(); + AtlasMessage::qVFSFileExists qry(filePath.wc_str()); + qry.Post(); + if (!filePath.IsEmpty() && qry.exists) + { + AtlasMessage::qVFSFileRealPath qry(filePath.wc_str()); + qry.Post(); + wxDynamicCast(FindWindow(ID_MapDialogFilename), wxTextCtrl)->ChangeValue(*qry.realPath); + } + } if (evt.GetEventType() == wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) { @@ -167,21 +202,26 @@ void MapDialog::OnSave(wxCommandEvent& WXUNUSED(evt)) void MapDialog::OnFilename(wxCommandEvent& evt) { - m_Filename = evt.GetString(); + m_FileName = evt.GetString(); } void MapDialog::OnNotebookChanged(wxBookCtrlEvent& evt) { - m_SelectedPage = evt.GetSelection(); + if (m_Type != MAPDIALOG_OPEN) + return; + + wxWindow* window = FindWindow(ID_MapDialogFilename); + if (window) + wxDynamicCast(window, wxTextCtrl)->ChangeValue(wxEmptyString); } void MapDialog::OpenFile() { - wxString filename = GetFilename(); - if (filename.empty()) + wxString filePath = GetSelectedFilePath(); + if (filePath.empty()) return; - AtlasMessage::qVFSFileExists qry(filename.wc_str()); + AtlasMessage::qVFSFileExists qry(filePath.wc_str()); qry.Post(); if (!qry.exists) return; @@ -191,16 +231,16 @@ void MapDialog::OpenFile() void MapDialog::SaveFile() { - wxString filename = GetFilename(); - if (filename.empty()) + wxString filePath = GetSelectedFilePath(); + if (filePath.empty()) return; // TODO: this test would work better outside the VFS - AtlasMessage::qVFSFileExists qry(filename.wc_str()); + AtlasMessage::qVFSFileExists qry(filePath.wc_str()); qry.Post(); if (qry.exists) { - if (wxMessageBox(_("WARNING: '") + filename + _("' already exists, it may be overwritten. Continue?"), _("Overwrite map confirmation"), wxICON_EXCLAMATION | wxYES_NO) != wxYES) + if (wxMessageBox(_("WARNING: '") + filePath + _("' already exists, it may be overwritten. Continue?"), _("Overwrite map confirmation"), wxICON_EXCLAMATION | wxYES_NO) != wxYES) return; } diff --git a/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.h b/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.h index 6f4c00af35..6a601a94b3 100644 --- a/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.h +++ b/source/tools/atlas/AtlasUI/CustomControls/MapDialog/MapDialog.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -34,9 +34,9 @@ public: MapDialog(wxWindow* parent, MapDialogType type, const wxIcon& icon); /** - * Returns VFS path of selected map with .xml extension, else empty string + * Returns VFS path of the selected map with .xml extension, else empty string */ - wxString GetFilename() const; + wxString GetSelectedFilePath() const; private: @@ -50,10 +50,8 @@ private: void OpenFile(); void SaveFile(); - wxArrayString m_MapFilenames; - wxString m_Filename; + wxString m_FileName; MapDialogType m_Type; - int m_SelectedPage; DECLARE_EVENT_TABLE(); }; diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index 3ad5e77960..9ea3fe4d20 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -761,9 +761,9 @@ void ScenarioEditor::OnOpen(wxCommandEvent& WXUNUSED(event)) MapDialog dlg (NULL, MAPDIALOG_OPEN, m_Icon); if (dlg.ShowModal() == wxID_OK) { - wxString filename = dlg.GetFilename(); - if (!OpenFile(filename, filename)) - wxLogError(_("Map '%ls' does not exist"), filename.c_str()); + wxString filePath = dlg.GetSelectedFilePath(); + if (!OpenFile(filePath, filePath)) + wxLogError(_("Map '%ls' does not exist"), filePath.c_str()); } // TODO: Make this a non-undoable command @@ -846,16 +846,16 @@ void ScenarioEditor::OnSaveAs(wxCommandEvent& WXUNUSED(event)) MapDialog dlg(NULL, MAPDIALOG_SAVE, m_Icon); if (dlg.ShowModal() == wxID_OK) { - wxString filename(dlg.GetFilename()); - wxBusyInfo busy(_("Saving ") + filename); + wxString filePath(dlg.GetSelectedFilePath()); + wxBusyInfo busy(_("Saving ") + filePath); wxBusyCursor busyc; m_ToolManager.SetCurrentTool(_T("")); - std::wstring map(filename.wc_str()); + std::wstring map(filePath.wc_str()); POST_MESSAGE(SaveMap, (map)); - SetOpenFilename(filename); + SetOpenFilename(filePath); // Wait for it to finish saving qPing qry; diff --git a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp index 1613ccf07e..0b340a4a90 100644 --- a/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp +++ b/source/tools/atlas/GameInterface/Handlers/MapHandlers.cpp @@ -323,6 +323,16 @@ QUERYHANDLER(VFSFileExists) msg->exists = VfsFileExists(*msg->path); } +QUERYHANDLER(VFSFileRealPath) +{ + VfsPath pathname(*msg->path); + if (pathname.empty()) + return; + OsPath realPathname; + if (g_VFS->GetRealPath(pathname, realPathname) == INFO::OK) + msg->realPath = realPathname.string(); +} + static Status AddToFilenames(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData) { std::vector& filenames = *(std::vector*)cbData; @@ -332,13 +342,15 @@ static Status AddToFilenames(const VfsPath& pathname, const CFileInfo& UNUSED(fi QUERYHANDLER(GetMapList) { - std::vector scenarioFilenames; - vfs::ForEachFile(g_VFS, L"maps/scenarios/", AddToFilenames, (uintptr_t)&scenarioFilenames, L"*.xml", vfs::DIR_RECURSIVE); - msg->scenarioFilenames = scenarioFilenames; +#define GET_FILE_LIST(path, list) \ + std::vector list; \ + vfs::ForEachFile(g_VFS, path, AddToFilenames, (uintptr_t)&list, L"*.xml", vfs::DIR_RECURSIVE); \ + msg->list = list; - std::vector skirmishFilenames; - vfs::ForEachFile(g_VFS, L"maps/skirmishes/", AddToFilenames, (uintptr_t)&skirmishFilenames, L"*.xml", vfs::DIR_RECURSIVE); - msg->skirmishFilenames = skirmishFilenames; + GET_FILE_LIST(L"maps/scenarios/", scenarioFilenames); + GET_FILE_LIST(L"maps/skirmishes/", skirmishFilenames); + GET_FILE_LIST(L"maps/tutorials/", tutorialFilenames); +#undef GET_FILE_LIST } } diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index cc2247acb2..cf10aabddb 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2018 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -174,6 +174,7 @@ QUERY(GetMapList, , ((std::vector, scenarioFilenames)) ((std::vector, skirmishFilenames)) + ((std::vector, tutorialFilenames)) ); QUERY(GetMapSettings, @@ -209,6 +210,12 @@ QUERY(VFSFileExists, ((bool, exists)) ); +QUERY(VFSFileRealPath, + ((std::wstring, path)) + , + ((std::wstring, realPath)) + ); + ////////////////////////////////////////////////////////////////////////// // Messages for player panel