Add files and update README.md.

This commit is contained in:
Guillaume Jacquemin 2020-01-09 13:59:19 +01:00
parent fb729b29ce
commit 573eb089e4
11 changed files with 1264 additions and 2 deletions

22
Application.manifest Normal file
View File

@ -0,0 +1,22 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true/pm</dpiAware>
</asmv3:windowsSettings>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<dpiAwareness>permonitorv2, permonitor, system</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="amd64"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

48
CMakeLists.txt Normal file
View File

@ -0,0 +1,48 @@
# wxMASSManager
# Copyright (C) 2020 Guillaume Jacquemin
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.5)
project(wxMASSManager LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(WITH_INTERCONNECT OFF CACHE BOOL "" FORCE)
set(WITH_PLUGINMANAGER OFF CACHE BOOL "" FORCE)
set(WITH_TESTSUITE OFF CACHE BOOL "" FORCE)
add_subdirectory(corrade)
find_package(Corrade REQUIRED Containers Utility)
include_directories(SYSTEM "C:/msys64/mingw64/lib/wx/include/msw-unicode-3.0")
include_directories(SYSTEM "C:/msys64/mingw64/include/wx-3.0")
add_executable(wxMASSManager WIN32
main.cpp
GUI/MainFrame.fbp
GUI/MainFrame.h
GUI/MainFrame.cpp
GUI/EvtMainFrame.h
GUI/EvtMainFrame.cpp
resource.rc)
target_link_libraries(wxMASSManager PRIVATE
Corrade::Containers
Corrade::Utility
wx_baseu-3.0
wx_mswu_core-3.0)

295
GUI/EvtMainFrame.cpp Normal file
View File

@ -0,0 +1,295 @@
// wxMASSManager
// Copyright (C) 2020 Guillaume Jacquemin
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
#include <algorithm>
#include <vector>
#include <wx/filedlg.h>
#include <wx/msgdlg.h>
#include <wx/numdlg.h>
#include <wx/regex.h>
#include <Corrade/Containers/Array.h>
#include <Corrade/Utility/Directory.h>
#include <Corrade/Utility/FormatStl.h>
#include "EvtMainFrame.h"
using namespace Corrade;
constexpr unsigned char mass_name_locator[] = { 'N', 'a', 'm', 'e', '_', '4', '5', '_', 'A', '0', '3', '7', 'C', '5', 'D', '5', '4', 'E', '5', '3', '4', '5', '6', '4', '0', '7', 'B', 'D', 'F', '0', '9', '1', '3', '4', '4', '5', '2', '9', 'B', 'B', '\0', 0x0C, '\0', '\0', '\0', 'S', 't', 'r', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', '\0' };
constexpr unsigned char steamid_locator[] = { 'A', 'c', 'c', 'o', 'u', 'n', 't', '\0', 0x0C, '\0', '\0', '\0', 'S', 't', 'r', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', '\0' };
EvtMainFrame::EvtMainFrame(wxWindow* parent): MainFrame(parent) {
SetIcon(wxIcon("MAINICON"));
getSaveDirectory();
getLocalSteamId();
initialiseListView();
_installedListView->Connect(wxEVT_LIST_ITEM_SELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this);
_installedListView->Connect(wxEVT_LIST_ITEM_DESELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this);
_installedListView->Connect(wxEVT_LIST_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
_installedListView->Connect(wxEVT_LIST_COL_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
warningMessage(wxString::FromUTF8("Before you start using this app, a few things you should know:\n\n"
"For this application to work properly, Steam Cloud syncing needs to be disabled for the game.\nTo disable it, right-click the game in your Steam library, click \"Properties\", go to the \"Updates\" tab, and uncheck \"Enable Steam Cloud synchronization for M.A.S.S. Builder\".\n\n"
"Please avoid using this application while the game is running. Bad Things™ could happen to your data.\n\n"
"DISCLAIMER: The developer of this application cannot be held responsible for data loss or corruption. PLEASE USE AT YOUR OWN RISK!\n\n"
"Last but not least, this application is released under the terms of the GNU General Public Licence version 3. Please see the COPYING file for more details."));
}
EvtMainFrame::~EvtMainFrame() {
_installedListView->Disconnect(wxEVT_LIST_ITEM_SELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this);
_installedListView->Disconnect(wxEVT_LIST_ITEM_DESELECTED, wxListEventHandler(EvtMainFrame::installedSelectionEvent), nullptr, this);
_installedListView->Disconnect(wxEVT_LIST_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
_installedListView->Disconnect(wxEVT_LIST_COL_BEGIN_DRAG, wxListEventHandler(EvtMainFrame::listColumnDragEvent), nullptr, this);
}
void EvtMainFrame::importEvent(wxCommandEvent&) {
std::string slot_state = _installedListView->GetItemText(_installedListView->GetFirstSelected(), 1).ToStdString();
if(slot_state != "<Empty>" && slot_state != "<Invalid data>" &&
wxMessageBox(wxString::Format("Hangar %.2d is already occupied by the M.A.S.S. named \"%s\". Are you sure you want to import a M.A.S.S. to this hangar ?", _installedListView->GetFirstSelected() + 1, slot_state),
"Question", wxYES_NO|wxCENTRE|wxICON_QUESTION, this) == wxNO) {
return;
}
wxFileDialog dialog(this, "Select a unit file", wxEmptyString, wxEmptyString, "M.A.S.S. Builder unit files (*.sav)|*.sav", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
if(dialog.ShowModal() == wxID_CANCEL) {
return;
}
const std::string source_file = dialog.GetPath().ToUTF8().data();
const std::string mass_name = getMassName(source_file);
if(mass_name == "") {
return;
}
if(wxMessageBox(wxString::Format("Are you sure you want to import the M.A.S.S. named \"%s\" to hangar %.2d ?", mass_name, _installedListView->GetFirstSelected() + 1),
"Question", wxYES_NO|wxCENTRE|wxICON_QUESTION, this) == wxNO) {
return;
}
const std::string dest_file = _saveDirectory + Utility::formatString("/Unit{:.2d}{}.sav", _installedListView->GetFirstSelected(), _localSteamId);
if(Utility::Directory::exists(dest_file)) {
Utility::Directory::rm(dest_file);
}
Utility::Directory::copy(source_file, dest_file);
{
auto mmap = Utility::Directory::map(dest_file);
auto iter = std::search(mmap.begin(), mmap.end(), &steamid_locator[0], &steamid_locator[23]);
if(iter == mmap.end()) {
errorMessage("Couldn't find the SteamID in the unit file at " + source_file + ". Aborting...");
Utility::Directory::rm(dest_file);
return;
}
iter += 37;
for(int i = 0; i < 17; ++i) {
*(iter + i) = _localSteamId[i];
}
}
refreshListView();
}
void EvtMainFrame::moveEvent(wxCommandEvent&) {
long source_slot = _installedListView->GetFirstSelected();
long choice = wxGetNumberFromUser(wxString::Format("Which hangar do you want to move the M.A.S.S. named \"%s\" to ?\nNotes:\n- If the destination hangar is the same as the source, nothing will happen.\n- If the destination already contains a M.A.S.S., the two will be swapped.\n- If the destination contains invalid data, it will be cleared first.", _installedListView->GetItemText(source_slot, 1)),
"Slot", "Choose a slot", source_slot + 1, 1, 32, this) - 1;
if(choice == -1 || choice == source_slot) {
return;
}
std::string orig_file = Utility::formatString("{}/Unit{:.2d}{}.sav", _saveDirectory, source_slot, _localSteamId);
std::string dest_status = _installedListView->GetItemText(choice, 1).ToStdString();
std::string dest_file = Utility::formatString("{}/Unit{:.2d}{}.sav", _saveDirectory, choice, _localSteamId);
if(dest_status == "<Invalid data>") {
Utility::Directory::rm(dest_file);
}
else if(dest_status != "<Empty>") {
Utility::Directory::move(dest_file, dest_file + ".tmp");
}
Utility::Directory::move(orig_file, dest_file);
if(dest_status != "<Empty>") {
Utility::Directory::move(dest_file + ".tmp", orig_file);
}
refreshListView();
}
void EvtMainFrame::deleteEvent(wxCommandEvent&) {
if(wxMessageBox(wxString::Format("Are you sure you want to delete the data in hangar %.2d ? This operation cannot be undone.", _installedListView->GetFirstSelected() + 1),
"Are you sure ?", wxYES_NO|wxCENTRE|wxICON_QUESTION, this) == wxNO) {
return;
}
std::string file = Utility::formatString("{}/Unit{:.2d}{}.sav", _saveDirectory, _installedListView->GetFirstSelected(), _localSteamId);
if(Utility::Directory::exists(file)) {
Utility::Directory::rm(file);
}
refreshListView();
}
void EvtMainFrame::openSaveDirEvent(wxCommandEvent&) {
wxExecute("explorer.exe " + Utility::Directory::toNativeSeparators(_saveDirectory));
}
void EvtMainFrame::installedSelectionEvent(wxListEvent&) {
updateCommandsState();
}
void EvtMainFrame::listColumnDragEvent(wxListEvent& event) {
event.Veto();
}
void EvtMainFrame::timerEvent(wxTimerEvent&) {
refreshListView();
}
void EvtMainFrame::getSaveDirectory() {
_saveDirectory = Utility::Directory::path(Utility::Directory::home()) + "/AppData/Local/MASS_Builder/Saved/SaveGames";
if(!Utility::Directory::exists(_saveDirectory)) {
errorMessage("Couldn't find the M.A.S.S. Builder save directory at " + _saveDirectory + ". Please run the game at least once to create it.");
Close();
}
}
void EvtMainFrame::getLocalSteamId() {
std::vector<std::string> listing = Utility::Directory::list(_saveDirectory);
wxRegEx regex;
if(!regex.Compile("Profile([0-9]{17}).sav", wxRE_ADVANCED)) {
errorMessage("Couldn't compile the regex.");
Close();
return;
}
for(const std::string& s : listing) {
if(regex.Matches(s)) {
_localSteamId = regex.GetMatch(s, 1);
return;
}
}
errorMessage("Couldn't find your save files. Please play at least once.");
Close();
}
void EvtMainFrame::initialiseListView() {
for(long i = 0; i < 32; i++) {
_installedListView->InsertItem(i, wxString::Format("%.2i", i + 1));
}
_installedListView->SetColumnWidth(0, wxLIST_AUTOSIZE_USEHEADER);
_installedListView->SetColumnWidth(1, wxLIST_AUTOSIZE_USEHEADER);
refreshListView();
updateCommandsState();
_refreshTimer.Start(1000);
}
void EvtMainFrame::refreshListView() {
for(long i = 0; i < 32; i++) {
_installedListView->SetItem(i, 1, getSlotMassName(i));
}
updateCommandsState();
}
void EvtMainFrame::updateCommandsState() {
long selection = _installedListView->GetFirstSelected();
if(selection != -1) {
_importButton->Enable();
wxString state = _installedListView->GetItemText(selection, 1);
if(state != "<Empty>" && state != "<Invalid data>") {
_moveButton->Enable();
}
else {
_moveButton->Disable();
}
if(state != "<Empty>") {
_deleteButton->Enable();
}
else {
_deleteButton->Disable();
}
}
else {
_importButton->Disable();
_moveButton->Disable();
_deleteButton->Disable();
}
}
std::string EvtMainFrame::getSlotMassName(int index) {
std::string unit_file = Utility::formatString("{}/Unit{:.2d}{}.sav", _saveDirectory, index, _localSteamId);
if(Utility::Directory::exists(unit_file)) {
std::string mass_name = getMassName(unit_file);
return (mass_name == "" ? "<Invalid data>" : mass_name);
}
else {
return "<Empty>";
}
}
std::string EvtMainFrame::getMassName(const std::string& filename) {
auto mmap = Utility::Directory::mapRead(filename);
auto iter = std::search(mmap.begin(), mmap.end(), &mass_name_locator[0], &mass_name_locator[56]);
if(iter == mmap.end()) {
return "";
}
return iter + 70;
}
void EvtMainFrame::infoMessage(const wxString& message) {
wxMessageBox(message, "Information", wxOK|wxCENTRE|wxICON_INFORMATION, this);
}
void EvtMainFrame::warningMessage(const wxString& message) {
wxMessageBox(message, "Warning", wxOK|wxCENTRE|wxICON_WARNING, this);
}
void EvtMainFrame::errorMessage(const wxString& message) {
wxMessageBox(message, "Error", wxOK|wxCENTRE|wxICON_ERROR, this);
}

55
GUI/EvtMainFrame.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef __EvtMainFrame__
#define __EvtMainFrame__
// wxMASSManager
// Copyright (C) 2020 Guillaume Jacquemin
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
#include <string>
#include "MainFrame.h"
class EvtMainFrame: public MainFrame {
public:
EvtMainFrame(wxWindow* parent);
~EvtMainFrame();
protected:
void importEvent(wxCommandEvent&);
void moveEvent(wxCommandEvent&);
void deleteEvent(wxCommandEvent&);
void openSaveDirEvent(wxCommandEvent&);
void installedSelectionEvent(wxListEvent&);
void listColumnDragEvent(wxListEvent&);
void timerEvent(wxTimerEvent&);
private:
void getSaveDirectory();
void getLocalSteamId();
void initialiseListView();
void refreshListView();
void updateCommandsState();
std::string getSlotMassName(int index);
std::string getMassName(const std::string& filename);
void infoMessage(const wxString& message);
void warningMessage(const wxString& message);
void errorMessage(const wxString& message);
std::string _saveDirectory;
std::string _localSteamId;
};
#endif // __EvtMainFrame__

103
GUI/MainFrame.cpp Normal file
View File

@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "MainFrame.h"
///////////////////////////////////////////////////////////////////////////
MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,600 ), wxDefaultSize );
this->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerMainUi;
bSizerMainUi = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbSizerInstalled;
sbSizerInstalled = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxT("Installed M.A.S.S.es") ), wxVERTICAL );
_installedListView = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_HRULES);
_installedListView->AppendColumn("Hangar", wxLIST_FORMAT_LEFT);
_installedListView->AppendColumn("M.A.S.S. name", wxLIST_FORMAT_LEFT);
sbSizerInstalled->Add( _installedListView, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerInstalledButtons;
bSizerInstalledButtons = new wxBoxSizer( wxHORIZONTAL );
_importButton = new wxButton( sbSizerInstalled->GetStaticBox(), wxID_ANY, wxT("Import"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerInstalledButtons->Add( _importButton, 1, wxALL|wxEXPAND, 5 );
_moveButton = new wxButton( sbSizerInstalled->GetStaticBox(), wxID_ANY, wxT("Move"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerInstalledButtons->Add( _moveButton, 1, wxALL|wxEXPAND, 5 );
_deleteButton = new wxButton( sbSizerInstalled->GetStaticBox(), wxID_ANY, wxT("Delete"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerInstalledButtons->Add( _deleteButton, 1, wxALL|wxEXPAND, 5 );
sbSizerInstalled->Add( bSizerInstalledButtons, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerSecondRow;
bSizerSecondRow = new wxBoxSizer( wxHORIZONTAL );
bSizerSecondRow->Add( 0, 0, 1, wxEXPAND, 5 );
_openSaveDirButton = new wxButton( sbSizerInstalled->GetStaticBox(), wxID_ANY, wxT("Open save directory"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerSecondRow->Add( _openSaveDirButton, 1, wxALL|wxEXPAND, 5 );
bSizerSecondRow->Add( 0, 0, 1, wxEXPAND, 5 );
sbSizerInstalled->Add( bSizerSecondRow, 0, wxEXPAND, 5 );
bSizerMainUi->Add( sbSizerInstalled, 1, wxEXPAND|wxALL, 5 );
bSizerMain->Add( bSizerMainUi, 1, wxEXPAND, 5 );
_riskLabel = new wxStaticText( this, wxID_ANY, wxT("USE THIS TOOL AT YOUR OWN RISK!"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL );
_riskLabel->Wrap( -1 );
_riskLabel->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxEmptyString ) );
_riskLabel->SetForegroundColour( wxColour( 255, 0, 0 ) );
bSizerMain->Add( _riskLabel, 0, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
_aboutText = new wxStaticText( this, wxID_ANY, wxT("This version of the application was tested on M.A.S.S. Builder early access version 0.2.4.\nIt may or may not work with other versions of the game.\nMade for the M.A.S.S. Builder community by Guillaume Jacquemin.\nhttps://github.com/williamjcm/wxMASSManager"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_HORIZONTAL );
_aboutText->Wrap( -1 );
bSizerMain->Add( _aboutText, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
_refreshTimer.SetOwner( this, wxID_ANY );
this->Centre( wxBOTH );
// Connect Events
_importButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::importEvent ), NULL, this );
_moveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this );
_deleteButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this );
_openSaveDirButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this );
this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( MainFrame::timerEvent ) );
}
MainFrame::~MainFrame()
{
// Disconnect Events
_importButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::importEvent ), NULL, this );
_moveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveEvent ), NULL, this );
_deleteButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteEvent ), NULL, this );
_openSaveDirButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openSaveDirEvent ), NULL, this );
this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( MainFrame::timerEvent ) );
}

617
GUI/MainFrame.fbp Normal file
View File

@ -0,0 +1,617 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration">; </property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">MainFrame</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">0</property>
<property name="name">Evt</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Frame" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg">wxSYS_COLOUR_WINDOW</property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,600</property>
<property name="name">MainFrame</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU</property>
<property name="subclass">; ; forward_declare</property>
<property name="title">M.A.S.S. Manager 0.1.0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxCLIP_CHILDREN|wxTAB_TRAVERSAL</property>
<property name="xrc_skip_sizer">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMainUi</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label">Installed M.A.S.S.es</property>
<property name="minimum_size"></property>
<property name="name">sbSizerInstalled</property>
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="CustomControl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="class"></property>
<property name="close_button">1</property>
<property name="construction">_installedListView = new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_HRULES);</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="declaration">wxListView* _installedListView;</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="include">#include &lt;wx/listctrl.h&gt;</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_installedListView</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="settings">_installedListView-&gt;AppendColumn(&quot;Hangar&quot;, wxLIST_FORMAT_LEFT);&#x0A;_installedListView-&gt;AppendColumn(&quot;M.A.S.S. name&quot;, wxLIST_FORMAT_LEFT);</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerInstalledButtons</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Import</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_importButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">importEvent</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Move</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_moveButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">moveEvent</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delete</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_deleteButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">deleteEvent</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerSecondRow</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Open save directory</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_openSaveDirButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">openSaveDirEvent</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg">255,0,0</property>
<property name="floatable">1</property>
<property name="font">,90,92,-1,70,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">USE THIS TOOL AT YOUR OWN RISK!</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_riskLabel</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_CENTER_HORIZONTAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">This version of the application was tested on M.A.S.S. Builder early access version 0.2.4.&#x0A;It may or may not work with other versions of the game.&#x0A;Made for the M.A.S.S. Builder community by Guillaume Jacquemin.&#x0A;https://github.com/williamjcm/wxMASSManager</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">_aboutText</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxALIGN_CENTER_HORIZONTAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
</object>
<object class="wxTimer" expanded="1">
<property name="enabled">0</property>
<property name="id">wxID_ANY</property>
<property name="name">_refreshTimer</property>
<property name="oneshot">0</property>
<property name="period">1000</property>
<property name="permission">protected</property>
<event name="OnTimer">timerEvent</event>
</object>
</object>
</object>
</wxFormBuilder_Project>

63
GUI/MainFrame.h Normal file
View File

@ -0,0 +1,63 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/listctrl.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/timer.h>
#include <wx/frame.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class MainFrame
///////////////////////////////////////////////////////////////////////////////
class MainFrame : public wxFrame
{
private:
protected:
wxListView* _installedListView;
wxButton* _importButton;
wxButton* _moveButton;
wxButton* _deleteButton;
wxButton* _openSaveDirButton;
wxStaticText* _riskLabel;
wxStaticText* _aboutText;
wxTimer _refreshTimer;
// Virtual event handlers, overide them in your derived class
virtual void importEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void moveEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void deleteEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void openSaveDirEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void timerEvent( wxTimerEvent& event ) { event.Skip(); }
public:
MainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("M.A.S.S. Manager 0.1.0"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxMINIMIZE_BOX|wxSYSTEM_MENU|wxCLIP_CHILDREN|wxTAB_TRAVERSAL );
~MainFrame();
};

View File

@ -4,8 +4,17 @@ A manager for M.A.S.S. save files, to facilitate sharing of M.A.S.S.es between u
## Installing
TODO
Get the `wxMASSManager-win64.zip` file from the Releases page, and extract it somewhere. Then, open the `wxMASSManager` folder and launch `wxMASSManager.exe`.
## Building on MSYS2
TODO
1. Install the 64-bit (`x86_64`) version of [MSYS2](https://www.msys2.org/) in its default path (`C:\msys64`), and update it fully.
2. Run `pacman -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw64/mingw-w64-x86_64-wxWidgets`.
3. In a `MINGW64` shell, type `git clone https://github.com/williamjcm/wxMASSManager`.
4. Type `cd wxMASSManager && git submodule init && git submodule update && mkdir build && cd build`.
5. Type `cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..`
6. Type `ninja`
7. ...
8. Profit!
You'll be able to find the executable in `build/Release/bin`.

31
main.cpp Normal file
View File

@ -0,0 +1,31 @@
// wxMASSManager
// Copyright (C) 2020 Guillaume Jacquemin
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
#include <wx/app.h>
#include "GUI/EvtMainFrame.h"
class MyApp: public wxApp {
public:
bool OnInit() {
EvtMainFrame* main_frame = new EvtMainFrame(nullptr);
main_frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);

BIN
mb.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 KiB

19
resource.rc Normal file
View File

@ -0,0 +1,19 @@
// wxMASSManager
// Copyright (C) 2020 Guillaume Jacquemin
//
// This program 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 3 of the License, or
// (at your option) any later version.
//
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
MAINICON ICON "mb.ico"
1 24 "Application.manifest"