Skip to content

Commit

Permalink
Folders UI (in Options) (OpenXcom#1426)
Browse files Browse the repository at this point in the history
* Folders UI (in Options)

* Use Unicode::convWcToMb
  • Loading branch information
MeridianOXC committed Dec 3, 2023
1 parent 0d044bc commit 46ea814
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 1 deletion.
10 changes: 10 additions & 0 deletions bin/common/Language/en-GB.yml
Expand Up @@ -416,3 +416,13 @@ en-GB:
STR_THROWING_ACCURACY_ABBREVIATION: "THR"
STR_STRENGTH_ABBREVIATION: "STR"
STR_MELEE_ACCURACY_ABBREVIATION: "MEL"
STR_FOLDERS: "FOLDERS"
STR_DATA_FOLDER: "Data Folder (original resources)"
STR_USER_FOLDER: "User Folder (mods, openxcom.log)"
STR_SAVE_FOLDER: "Save Folder (saved games, screenshots)"
STR_CONFIG_FOLDER: "Config Folder (options.cfg)"
STR_DATA_FOLDER_DESC_1: "This is where OpenXcom looks for the original game resources (UFO and/or TFTD)."
STR_DATA_FOLDER_DESC_2: "OpenXcom internal resources are in the 'common' folder. OpenXcom built-in mods are in the 'standard' folder."
STR_USER_FOLDER_DESC: "The log file ('openxcom.log') is stored here. All custom mods belong here too (in the 'mods' sub-folder)."
STR_SAVE_FOLDER_DESC: "Your saved games are located here. Also, the mission generator settings ('battle.cfg') can be found here."
STR_CONFIG_FOLDER_DESC: "This is where OpenXcom settings ('options.cfg') are stored. Normally the same as the User Folder."
10 changes: 10 additions & 0 deletions bin/common/Language/en-US.yml
Expand Up @@ -416,3 +416,13 @@ en-US:
STR_THROWING_ACCURACY_ABBREVIATION: "THR"
STR_STRENGTH_ABBREVIATION: "STR"
STR_MELEE_ACCURACY_ABBREVIATION: "MEL"
STR_FOLDERS: "FOLDERS"
STR_DATA_FOLDER: "Data Folder (original resources)"
STR_USER_FOLDER: "User Folder (mods, openxcom.log)"
STR_SAVE_FOLDER: "Save Folder (saved games, screenshots)"
STR_CONFIG_FOLDER: "Config Folder (options.cfg)"
STR_DATA_FOLDER_DESC_1: "This is where OpenXcom looks for the original game resources (UFO and/or TFTD)."
STR_DATA_FOLDER_DESC_2: "OpenXcom internal resources are in the 'common' folder. OpenXcom built-in mods are in the 'standard' folder."
STR_USER_FOLDER_DESC: "The log file ('openxcom.log') is stored here. All custom mods belong here too (in the 'mods' sub-folder)."
STR_SAVE_FOLDER_DESC: "Your saved games are located here. Also, the mission generator settings ('battle.cfg') can be found here."
STR_CONFIG_FOLDER_DESC: "This is where OpenXcom settings ('options.cfg') are stored. Normally the same as the User Folder."
6 changes: 6 additions & 0 deletions bin/standard/xcom1/interfaces.rul
Expand Up @@ -109,6 +109,12 @@ interfaces:
color: 138 # yellow
color2: 239 # bright green
border: 133 # minty green
- type: foldersMenu
elements:
- id: text1
color: 239 # bright green
- id: text2
color: 138 # yellow
- type: modsMenu
elements:
- id: palette
Expand Down
6 changes: 6 additions & 0 deletions bin/standard/xcom2/interfaces.rul
Expand Up @@ -109,6 +109,12 @@ interfaces: #done
color: 1
color2: 239
border: 239
- type: foldersMenu
elements:
- id: text1
color: 239
- id: text2
color: 1
- type: modsMenu
elements:
- id: palette
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -220,6 +220,7 @@ set ( menu_src
Menu/OptionsConfirmState.cpp
Menu/OptionsControlsState.cpp
Menu/OptionsDefaultsState.cpp
Menu/OptionsFoldersState.cpp
Menu/OptionsGeoscapeState.cpp
Menu/ModConfirmExtendedState.cpp
Menu/ModListState.cpp
Expand Down
18 changes: 18 additions & 0 deletions src/Engine/CrossPlatform.cpp
Expand Up @@ -1215,6 +1215,24 @@ bool openExplorer(const std::string &url)
#endif
}

/**
* Gets the path to the executable file.
* @return Path to the EXE file.
*/
std::string getExeFolder()
{
#ifdef _WIN32
wchar_t dest[MAX_PATH + 1];
if (GetModuleFileNameW(NULL, dest, MAX_PATH) != 0)
{
PathRemoveFileSpecW(dest);
auto ret = Unicode::convWcToMb(dest) + "/";
return ret;
}
#endif
return std::string();
}

}

}
2 changes: 2 additions & 0 deletions src/Engine/CrossPlatform.h
Expand Up @@ -101,6 +101,8 @@ namespace CrossPlatform
void crashDump(void *ex, const std::string &err);
/// Opens a URL.
bool openExplorer(const std::string &url);
/// Gets the path to the executable file.
std::string getExeFolder();
}

}
11 changes: 11 additions & 0 deletions src/Menu/OptionsBaseState.cpp
Expand Up @@ -35,6 +35,7 @@
#include "OptionsVideoState.h"
#include "OptionsAudioState.h"
#include "OptionsNoAudioState.h"
#include "OptionsFoldersState.h"
#include "OptionsControlsState.h"
#include "OptionsGeoscapeState.h"
#include "OptionsBattlescapeState.h"
Expand Down Expand Up @@ -62,6 +63,7 @@ OptionsBaseState::OptionsBaseState(OptionsOrigin origin) : _origin(origin), _gro
_btnGeoscape = new TextButton(80, 16, 8, 68);
_btnBattlescape = new TextButton(80, 16, 8, 88);
_btnAdvanced = new TextButton(80, 16, 8, 108);
_btnFolders = new TextButton(80, 16, 8, 128);

_btnOk = new TextButton(100, 16, 8, 176);
_btnCancel = new TextButton(100, 16, 110, 176);
Expand All @@ -80,6 +82,7 @@ OptionsBaseState::OptionsBaseState(OptionsOrigin origin) : _origin(origin), _gro
add(_btnGeoscape, "button", "optionsMenu");
add(_btnBattlescape, "button", "optionsMenu");
add(_btnAdvanced, "button", "optionsMenu");
add(_btnFolders, "button", "optionsMenu");

add(_btnOk, "button", "optionsMenu");
add(_btnCancel, "button", "optionsMenu");
Expand Down Expand Up @@ -108,6 +111,9 @@ OptionsBaseState::OptionsBaseState(OptionsOrigin origin) : _origin(origin), _gro
_btnAdvanced->setText(tr("STR_ADVANCED"));
_btnAdvanced->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);

_btnFolders->setText(tr("STR_FOLDERS"));
_btnFolders->onMousePress((ActionHandler)&OptionsBaseState::btnGroupPress, SDL_BUTTON_LEFT);

_btnOk->setText(tr("STR_OK"));
_btnOk->onMouseClick((ActionHandler)&OptionsBaseState::btnOkClick);
_btnOk->onKeyboardPress((ActionHandler)&OptionsBaseState::btnOkClick, Options::keyOk);
Expand Down Expand Up @@ -174,6 +180,7 @@ void OptionsBaseState::setCategory(TextButton *button)
_btnGeoscape->setGroup(&_group);
_btnBattlescape->setGroup(&_group);
_btnAdvanced->setGroup(&_group);
_btnFolders->setGroup(&_group);
}

/**
Expand Down Expand Up @@ -283,6 +290,10 @@ void OptionsBaseState::btnGroupPress(Action *action)
{
_game->pushState(new OptionsAdvancedState(_origin));
}
else if (sender == _btnFolders)
{
_game->pushState(new OptionsFoldersState(_origin));
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Menu/OptionsBaseState.h
Expand Up @@ -43,7 +43,7 @@ class OptionsBaseState : public State
protected:
OptionsOrigin _origin;
Window *_window;
TextButton *_btnVideo, *_btnAudio, *_btnControls, *_btnGeoscape, *_btnBattlescape, *_btnAdvanced;
TextButton *_btnVideo, *_btnAudio, *_btnControls, *_btnGeoscape, *_btnBattlescape, *_btnAdvanced, *_btnFolders;
TextButton *_btnOk, *_btnCancel, *_btnDefault;
Text *_txtTooltip;
std::string _currentTooltip;
Expand Down
141 changes: 141 additions & 0 deletions src/Menu/OptionsFoldersState.cpp
@@ -0,0 +1,141 @@
/*
* Copyright 2010-2019 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom 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.
*
* OpenXcom 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 OpenXcom. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OptionsFoldersState.h"
#include "../Engine/Action.h"
#include "../Engine/CrossPlatform.h"
#include "../Engine/FileMap.h"
#include "../Engine/Options.h"
#include "../Interface/Text.h"

namespace OpenXcom
{

/**
* Initializes all the elements in the Folders Options screen.
* @param origin Game section that originated this state.
*/
OptionsFoldersState::OptionsFoldersState(OptionsOrigin origin) : OptionsBaseState(origin)
{
setCategory(_btnFolders);

// Create object
_txtDataFolder = new Text(218, 9, 94, 8);
_txtUserFolder = new Text(218, 9, 94, 59);
_txtSaveFolder = new Text(218, 9, 94, 86);
_txtConfigFolder = new Text(218, 9, 94, 121);

_txtDataFolderPath1 = new Text(218, 17, 94, 18);
_txtDataFolderPath2 = new Text(218, 17, 94, 38);
_txtUserFolderPath = new Text(218, 17, 94, 69);
_txtSaveFolderPath = new Text(218, 25, 94, 96);
_txtConfigFolderPath = new Text(218, 17, 94, 131);

add(_txtDataFolder, "text1", "foldersMenu");
add(_txtUserFolder, "text1", "foldersMenu");
add(_txtSaveFolder, "text1", "foldersMenu");
add(_txtConfigFolder, "text1", "foldersMenu");

add(_txtDataFolderPath1, "text2", "foldersMenu");
add(_txtDataFolderPath2, "text2", "foldersMenu");
add(_txtUserFolderPath, "text2", "foldersMenu");
add(_txtSaveFolderPath, "text2", "foldersMenu");
add(_txtConfigFolderPath, "text2", "foldersMenu");

centerAllSurfaces();

// Set up object
_txtDataFolder->setText(tr("STR_DATA_FOLDER"));
_txtUserFolder->setText(tr("STR_USER_FOLDER"));
_txtSaveFolder->setText(tr("STR_SAVE_FOLDER"));
_txtConfigFolder->setText(tr("STR_CONFIG_FOLDER"));

std::string file1 = "GEODATA/BACKPALS.DAT";
std::string file2 = "openxcom.png";

std::string origDataFolder = FileMap::getFilePath(file1); // OXC-specific: we are assuming it exists! otherwise `getFilePath` returns a dummy result.
origDataFolder = origDataFolder.substr(0, origDataFolder.find(file1));

std::string oxceDataFolder = FileMap::getFilePath(file2); // OXC-specific: we are assuming it exists! otherwise `getFilePath` returns a dummy result.
oxceDataFolder = oxceDataFolder.substr(0, oxceDataFolder.find(file2));

_txtDataFolderPath1->setText(origDataFolder);
_txtDataFolderPath1->setWordWrap(true);
_txtDataFolderPath1->setTooltip("STR_DATA_FOLDER_DESC_1");
_txtDataFolderPath1->onMouseIn((ActionHandler)&OptionsFoldersState::txtTooltipIn);
_txtDataFolderPath1->onMouseOut((ActionHandler)&OptionsFoldersState::txtTooltipOut);
_txtDataFolderPath1->onMouseClick((ActionHandler)&OptionsFoldersState::txtClick);

_txtDataFolderPath2->setText(oxceDataFolder);
_txtDataFolderPath2->setWordWrap(true);
_txtDataFolderPath2->setTooltip("STR_DATA_FOLDER_DESC_2");
_txtDataFolderPath2->onMouseIn((ActionHandler)&OptionsFoldersState::txtTooltipIn);
_txtDataFolderPath2->onMouseOut((ActionHandler)&OptionsFoldersState::txtTooltipOut);
_txtDataFolderPath2->onMouseClick((ActionHandler)&OptionsFoldersState::txtClick);

_txtUserFolderPath->setText(Options::getUserFolder());
_txtUserFolderPath->setWordWrap(true);
_txtUserFolderPath->setTooltip("STR_USER_FOLDER_DESC");
_txtUserFolderPath->onMouseIn((ActionHandler)&OptionsFoldersState::txtTooltipIn);
_txtUserFolderPath->onMouseOut((ActionHandler)&OptionsFoldersState::txtTooltipOut);
_txtUserFolderPath->onMouseClick((ActionHandler)&OptionsFoldersState::txtClick);

_txtSaveFolderPath->setText(Options::getMasterUserFolder());
_txtSaveFolderPath->setWordWrap(true);
_txtSaveFolderPath->setTooltip("STR_SAVE_FOLDER_DESC");
_txtSaveFolderPath->onMouseIn((ActionHandler)&OptionsFoldersState::txtTooltipIn);
_txtSaveFolderPath->onMouseOut((ActionHandler)&OptionsFoldersState::txtTooltipOut);
_txtSaveFolderPath->onMouseClick((ActionHandler)&OptionsFoldersState::txtClick);

_txtConfigFolderPath->setText(Options::getConfigFolder());
_txtConfigFolderPath->setWordWrap(true);
_txtConfigFolderPath->setTooltip("STR_CONFIG_FOLDER_DESC");
_txtConfigFolderPath->onMouseIn((ActionHandler)&OptionsFoldersState::txtTooltipIn);
_txtConfigFolderPath->onMouseOut((ActionHandler)&OptionsFoldersState::txtTooltipOut);
_txtConfigFolderPath->onMouseClick((ActionHandler)&OptionsFoldersState::txtClick);
}

/**
*
*/
OptionsFoldersState::~OptionsFoldersState()
{

}

/**
* Opens the location of the appropriate folder.
* @param action Pointer to an action.
*/
void OptionsFoldersState::txtClick(Action* action)
{
Text* sender = (Text*)action->getSender();
std::string path = sender->getText();
// Hint: whether the data folder is empty or not (i.e. using relative path or absolute path) depends on the compilation/environment
// for example, you can test:
// 1. absolute path: when running from Visual Studio 2022
// 2. relative path: when running a MXE cross-compiled executable
if (Options::getDataFolder().empty() && path.size() < 10)
{
// "UFO/", "TFTD/", "common/", "standard/"
path = CrossPlatform::getExeFolder() + path;
}
CrossPlatform::openExplorer(path);
}

}
44 changes: 44 additions & 0 deletions src/Menu/OptionsFoldersState.h
@@ -0,0 +1,44 @@
#pragma once
/*
* Copyright 2010-2019 OpenXcom Developers.
*
* This file is part of OpenXcom.
*
* OpenXcom 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.
*
* OpenXcom 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 OpenXcom. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OptionsBaseState.h"

namespace OpenXcom
{

class Text;

/**
* Screen that shows the user various folders used by OpenXcom.
*/
class OptionsFoldersState : public OptionsBaseState
{
private:
Text *_txtDataFolder, *_txtUserFolder, *_txtSaveFolder, *_txtConfigFolder;
Text* _txtDataFolderPath1, *_txtDataFolderPath2, *_txtUserFolderPath, *_txtSaveFolderPath, *_txtConfigFolderPath;
public:
/// Creates the Folders Options state.
OptionsFoldersState(OptionsOrigin origin);
/// Cleans up the Folders Options state.
~OptionsFoldersState();
/// Handler for opei.
void txtClick(Action* action);
};

}
2 changes: 2 additions & 0 deletions src/OpenXcom.2010.vcxproj
Expand Up @@ -519,6 +519,7 @@
<ClCompile Include="Menu\OptionsAudioState.cpp" />
<ClCompile Include="Menu\OptionsConfirmState.cpp" />
<ClCompile Include="Menu\OptionsDefaultsState.cpp" />
<ClCompile Include="Menu\OptionsFoldersState.cpp" />
<ClCompile Include="Menu\OptionsGeoscapeState.cpp" />
<ClCompile Include="Menu\MainMenuState.cpp" />
<ClCompile Include="Menu\NewBattleState.cpp" />
Expand Down Expand Up @@ -846,6 +847,7 @@
<ClInclude Include="Menu\OptionsAudioState.h" />
<ClInclude Include="Menu\OptionsConfirmState.h" />
<ClInclude Include="Menu\OptionsDefaultsState.h" />
<ClInclude Include="Menu\OptionsFoldersState.h" />
<ClInclude Include="Menu\OptionsGeoscapeState.h" />
<ClInclude Include="Menu\MainMenuState.h" />
<ClInclude Include="Menu\NewBattleState.h" />
Expand Down
6 changes: 6 additions & 0 deletions src/OpenXcom.2010.vcxproj.filters
Expand Up @@ -945,6 +945,9 @@
<ClCompile Include="Menu\ModConfirmExtendedState.cpp">
<Filter>Menu</Filter>
</ClCompile>
<ClCompile Include="Menu\OptionsFoldersState.cpp">
<Filter>Menu</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
Expand Down Expand Up @@ -1930,6 +1933,9 @@
<ClInclude Include="Menu\ModConfirmExtendedState.h">
<Filter>Menu</Filter>
</ClInclude>
<ClInclude Include="Menu\OptionsFoldersState.h">
<Filter>Menu</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Geoscape">
Expand Down

0 comments on commit 46ea814

Please sign in to comment.