MainFrame: wire the frontend to the backend.

I *hate* wxListCtrl and wxImageList.
This commit is contained in:
Guillaume Jacquemin 2020-06-20 10:45:49 +02:00
parent ae53387351
commit 694e124d91
2 changed files with 256 additions and 91 deletions

View file

@ -18,6 +18,7 @@
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#include <wx/numdlg.h> #include <wx/numdlg.h>
#include <wx/regex.h> #include <wx/regex.h>
#include <wx/scrolwin.h>
#include <Corrade/Containers/Optional.h> #include <Corrade/Containers/Optional.h>
#include <Corrade/Utility/Directory.h> #include <Corrade/Utility/Directory.h>
@ -54,7 +55,9 @@ EvtMainFrame::EvtMainFrame(wxWindow* parent): MainFrame(parent) {
_watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_manager.saveDirectory()), wxPATH_WIN), _watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_manager.saveDirectory()), wxPATH_WIN),
wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE|wxFSW_EVENT_MODIFY|wxFSW_EVENT_RENAME, wxString::Format("*%s.sav", _manager.steamId())); wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE|wxFSW_EVENT_MODIFY|wxFSW_EVENT_RENAME, wxString::Format("*%s.sav", _manager.steamId()));
_watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_manager.stagingAreaDirectory()), wxPATH_WIN), _watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_manager.stagingAreaDirectory()), wxPATH_WIN),
wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE|wxFSW_EVENT_MODIFY|wxFSW_EVENT_RENAME, wxString::Format("*.sav")); wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE|wxFSW_EVENT_MODIFY|wxFSW_EVENT_RENAME, "*.sav");
_watcher.AddTree(wxFileName(Utility::Directory::toNativeSeparators(_manager.screenshotDirectory()), wxPATH_WIN),
wxFSW_EVENT_CREATE|wxFSW_EVENT_DELETE, "*.png"); // Not monitoring wxFSW_EVENT_{MODIFY,RENAME}, because they're a massive pain to handle. Ugh.
std::vector<std::string> v = _manager.initialiseStagingArea(); std::vector<std::string> v = _manager.initialiseStagingArea();
for(const std::string& s : v) { for(const std::string& s : v) {
@ -62,6 +65,10 @@ EvtMainFrame::EvtMainFrame(wxWindow* parent): MainFrame(parent) {
} }
_gameCheckTimer.Start(3000); _gameCheckTimer.Start(3000);
_screenshotsList->SetImageList(&_screenshotThumbs, wxIMAGE_LIST_NORMAL);
updateScreenshotList();
} }
EvtMainFrame::~EvtMainFrame() { EvtMainFrame::~EvtMainFrame() {
@ -230,6 +237,11 @@ void EvtMainFrame::stagingSelectionEvent(wxCommandEvent&) {
} }
void EvtMainFrame::deleteStagedEvent(wxCommandEvent&) { void EvtMainFrame::deleteStagedEvent(wxCommandEvent&) {
if(wxMessageBox("Are you sure you want to delete the selected M.A.S.S. ? This operation cannot be undone.",
"Are you sure ?", wxYES_NO|wxCENTRE|wxICON_QUESTION, this) == wxNO) {
return;
}
int selection = _stagingList->GetSelection(); int selection = _stagingList->GetSelection();
if(selection != wxNOT_FOUND) { if(selection != wxNOT_FOUND) {
@ -249,6 +261,55 @@ void EvtMainFrame::listColumnDragEvent(wxListEvent& event) {
event.Veto(); event.Veto();
} }
void EvtMainFrame::screenshotListSelectionEvent(wxListEvent&) {
updateCommandsState();
}
void EvtMainFrame::screenshotFilenameSortingEvent(wxCommandEvent&) {
_manager.sortScreenshots(SortType::Filename);
updateScreenshotList();
}
void EvtMainFrame::screenshotCreationDateSortingEvent(wxCommandEvent&) {
_manager.sortScreenshots(SortType::CreationDate);
updateScreenshotList();
}
void EvtMainFrame::screenshotAscendingSortingEvent(wxCommandEvent&) {
_manager.sortScreenshots(SortOrder::Ascending);
updateScreenshotList();
}
void EvtMainFrame::screenshotDescendingSortingEvent(wxCommandEvent&) {
_manager.sortScreenshots(SortOrder::Descending);
updateScreenshotList();
}
void EvtMainFrame::viewScreenshotEvent(wxCommandEvent&) {
viewScreenshot();
}
void EvtMainFrame::viewScreenshotEvent(wxListEvent&) {
viewScreenshot();
}
void EvtMainFrame::deleteScreenshotEvent(wxCommandEvent&) {
if(wxMessageBox("Are you sure you want to delete the selected screenshot ? This operation cannot be undone.",
"Are you sure ?", wxYES_NO|wxCENTRE|wxICON_QUESTION, this) == wxNO) {
return;
}
long selection = _screenshotsList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if(selection != -1) {
_manager.deleteScreenshot(selection);
}
}
void EvtMainFrame::openScreenshotDirEvent(wxCommandEvent&) {
wxExecute("explorer.exe " + Utility::Directory::toNativeSeparators(_manager.screenshotDirectory()));
}
void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) { void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) {
int event_type = event.GetChangeType(); int event_type = event.GetChangeType();
wxString event_file = event.GetPath().GetFullName(); wxString event_file = event.GetPath().GetFullName();
@ -261,6 +322,25 @@ void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) {
wxMilliSleep(50); wxMilliSleep(50);
if(event.GetPath().GetPath(wxPATH_GET_VOLUME, wxPATH_WIN) == Utility::Directory::toNativeSeparators(_manager.saveDirectory())) { if(event.GetPath().GetPath(wxPATH_GET_VOLUME, wxPATH_WIN) == Utility::Directory::toNativeSeparators(_manager.saveDirectory())) {
unitFileEventHandler(event_type, event_file, event);
}
else if(event.GetPath().GetPath(wxPATH_GET_VOLUME, wxPATH_WIN) == Utility::Directory::toNativeSeparators(_manager.stagingAreaDirectory())) {
stagingFileEventHandler(event_type, event_file, event);
}
else if(event.GetPath().GetPath(wxPATH_GET_VOLUME, wxPATH_WIN) == Utility::Directory::toNativeSeparators(_manager.screenshotDirectory())) {
screenshotFileEventHandler(event_type, event_file, event);
}
_lastWatcherEventType = event_type;
updateCommandsState();
}
void EvtMainFrame::gameCheckTimerEvent(wxTimerEvent&) {
isGameRunning();
}
void EvtMainFrame::unitFileEventHandler(int event_type, const wxString& event_file, const wxFileSystemWatcherEvent& event) {
wxRegEx regex; wxRegEx regex;
switch (event_type) { switch (event_type) {
@ -315,7 +395,8 @@ void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) {
break; break;
} }
} }
else if(event.GetPath().GetPath(wxPATH_GET_VOLUME, wxPATH_WIN) == Utility::Directory::toNativeSeparators(_manager.stagingAreaDirectory())) {
void EvtMainFrame::stagingFileEventHandler(int event_type, const wxString& event_file, const wxFileSystemWatcherEvent& event) {
int index; int index;
switch(event_type) { switch(event_type) {
@ -350,13 +431,22 @@ void EvtMainFrame::fileUpdateEvent(wxFileSystemWatcherEvent& event) {
} }
} }
_lastWatcherEventType = event_type; void EvtMainFrame::screenshotFileEventHandler(int event_type, const wxString& event_file) {
int index = -1;
updateCommandsState(); switch(event_type) {
case wxFSW_EVENT_CREATE:
_manager.updateScreenshot(event_file.ToUTF8().data());
updateScreenshotList();
break;
case wxFSW_EVENT_DELETE:
index = _screenshotsList->FindItem(-1, event_file, true);
if(index != -1) {
_manager.removeScreenshot(index);
_screenshotsList->DeleteItem(index);
}
break;
} }
void EvtMainFrame::gameCheckTimerEvent(wxTimerEvent&) {
isGameRunning();
} }
void EvtMainFrame::initialiseListView() { void EvtMainFrame::initialiseListView() {
@ -364,12 +454,11 @@ void EvtMainFrame::initialiseListView() {
_installedListView->InsertItem(i, wxString::Format("%.2i", i + 1)); _installedListView->InsertItem(i, wxString::Format("%.2i", i + 1));
} }
getActiveSlot();
_installedListView->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER); _installedListView->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
_installedListView->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER); _installedListView->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
refreshListView(); refreshListView();
getActiveSlot();
} }
void EvtMainFrame::isGameRunning() { void EvtMainFrame::isGameRunning() {
@ -404,9 +493,11 @@ void EvtMainFrame::refreshListView() {
void EvtMainFrame::getActiveSlot() { void EvtMainFrame::getActiveSlot() {
char slot = _manager.activeSlot(); char slot = _manager.activeSlot();
if(slot != -1) {
wxFont tmp_font = _installedListView->GetItemFont(slot); wxFont tmp_font = _installedListView->GetItemFont(slot);
tmp_font.SetWeight(wxFONTWEIGHT_NORMAL); tmp_font.SetWeight(wxFONTWEIGHT_NORMAL);
_installedListView->SetItemFont(slot, tmp_font); _installedListView->SetItemFont(slot, tmp_font);
}
slot = _manager.getActiveSlot(); slot = _manager.getActiveSlot();
@ -427,6 +518,10 @@ void EvtMainFrame::updateCommandsState() {
_deleteButton->Enable(selection != -1 && game_state != GameState::Running && hangar_state != HangarState::Empty); _deleteButton->Enable(selection != -1 && game_state != GameState::Running && hangar_state != HangarState::Empty);
_renameButton->Enable(selection != -1 && game_state != GameState::Running && hangar_state != HangarState::Empty); _renameButton->Enable(selection != -1 && game_state != GameState::Running && hangar_state != HangarState::Empty);
_deleteStagedButton->Enable(staged_selection != -1); _deleteStagedButton->Enable(staged_selection != -1);
long screenshot_selection = _screenshotsList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
_viewScreenshotButton->Enable(screenshot_selection != -1);
_deleteScreenshotButton->Enable(screenshot_selection != -1);
} }
void EvtMainFrame::refreshHangar(int slot) { void EvtMainFrame::refreshHangar(int slot) {
@ -449,6 +544,52 @@ void EvtMainFrame::refreshHangar(int slot) {
} }
} }
void EvtMainFrame::updateScreenshotList() {
_screenshotsList->DeleteAllItems();
_screenshotThumbs.RemoveAll();
int index = 0;
for(const Screenshot& s : _manager.screenshots()) {
_screenshotsList->InsertItem(index,
wxString::Format("%s\n%s", wxString::FromUTF8(s._filename.c_str()), s._creationDate.Format("%d/%m/%Y %H:%M:%S")),
_screenshotThumbs.Add(s._thumbnail));
++index;
}
}
void EvtMainFrame::viewScreenshot() {
long selection = _screenshotsList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if(selection == -1) {
return;
}
wxBitmap image(Utility::Directory::toNativeSeparators(Utility::Directory::join(_manager.screenshotDirectory(), _manager.screenshots().at(selection)._filename)), wxBITMAP_TYPE_PNG);
wxDialog view_dialog;
view_dialog.Create(this, wxID_ANY, "Screenshot viewer", wxDefaultPosition, wxSize{1024, 576}, wxCAPTION|wxCLOSE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU);
wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
wxScrolledWindow* scroller = new wxScrolledWindow(&view_dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL|wxHSCROLL);
scroller->SetScrollRate(5, 5);
wxBoxSizer* scroller_sizer = new wxBoxSizer(wxVERTICAL);
wxStaticBitmap* screenshot = new wxStaticBitmap(scroller, wxID_ANY, image);
scroller_sizer->Add(screenshot, 1, wxEXPAND, 5);
scroller->SetSizer(scroller_sizer);
scroller->Layout();
scroller_sizer->FitInside(scroller);
sizer->Add(scroller, 1, wxEXPAND, 5);
view_dialog.SetSizer(sizer);
view_dialog.Layout();
sizer->FitInside(&view_dialog);
view_dialog.Centre();
view_dialog.ShowModal();
}
void EvtMainFrame::infoMessage(const wxString& message) { void EvtMainFrame::infoMessage(const wxString& message) {
wxMessageBox(message, "Information", wxOK|wxCENTRE|wxICON_INFORMATION, this); wxMessageBox(message, "Information", wxOK|wxCENTRE|wxICON_INFORMATION, this);
} }

View file

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <wx/fswatcher.h> #include <wx/fswatcher.h>
#include <wx/imaglist.h>
#include "../MassManager/MassManager.h" #include "../MassManager/MassManager.h"
@ -33,6 +34,7 @@ class EvtMainFrame: public MainFrame {
auto ready() -> bool; auto ready() -> bool;
protected: protected:
// M.A.S.S.-related events
void importEvent(wxCommandEvent&); void importEvent(wxCommandEvent&);
void exportEvent(wxCommandEvent&); void exportEvent(wxCommandEvent&);
void moveEvent(wxCommandEvent&); void moveEvent(wxCommandEvent&);
@ -45,10 +47,27 @@ class EvtMainFrame: public MainFrame {
void stagingButtonEvent(wxCommandEvent&); void stagingButtonEvent(wxCommandEvent&);
void installedSelectionEvent(wxListEvent&); void installedSelectionEvent(wxListEvent&);
void listColumnDragEvent(wxListEvent&); void listColumnDragEvent(wxListEvent&);
// Screenshot events
void screenshotListSelectionEvent(wxListEvent&);
void screenshotFilenameSortingEvent(wxCommandEvent&);
void screenshotCreationDateSortingEvent(wxCommandEvent&);
void screenshotAscendingSortingEvent(wxCommandEvent&);
void screenshotDescendingSortingEvent(wxCommandEvent&);
void viewScreenshotEvent(wxCommandEvent&);
void viewScreenshotEvent(wxListEvent&);
void deleteScreenshotEvent(wxCommandEvent&);
void openScreenshotDirEvent(wxCommandEvent&);
// General events
void fileUpdateEvent(wxFileSystemWatcherEvent& event); void fileUpdateEvent(wxFileSystemWatcherEvent& event);
void gameCheckTimerEvent(wxTimerEvent&); void gameCheckTimerEvent(wxTimerEvent&);
private: private:
void unitFileEventHandler(int event_type, const wxString& event_file, const wxFileSystemWatcherEvent& event);
void stagingFileEventHandler(int event_type, const wxString& event_file, const wxFileSystemWatcherEvent& event);
void screenshotFileEventHandler(int event_type, const wxString& event_file);
void initialiseListView(); void initialiseListView();
void isGameRunning(); void isGameRunning();
void refreshListView(); void refreshListView();
@ -56,6 +75,9 @@ class EvtMainFrame: public MainFrame {
void updateCommandsState(); void updateCommandsState();
void refreshHangar(int slot); void refreshHangar(int slot);
void updateScreenshotList();
void viewScreenshot();
void infoMessage(const wxString& message); void infoMessage(const wxString& message);
void warningMessage(const wxString& message); void warningMessage(const wxString& message);
void errorMessage(const wxString& message); void errorMessage(const wxString& message);
@ -64,6 +86,8 @@ class EvtMainFrame: public MainFrame {
wxFileSystemWatcher _watcher; wxFileSystemWatcher _watcher;
int _lastWatcherEventType = 0; int _lastWatcherEventType = 0;
wxImageList _screenshotThumbs{160, 160, true, 0};
}; };
#endif // __EvtMainFrame__ #endif // __EvtMainFrame__