mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Merge remote-tracking branch 'origin/sorting-ux'
This commit is contained in:
@@ -25,6 +25,7 @@ set (BOSS_GUI_SRC ${BOSS_SRC}
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/settings.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/editor.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/viewer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/gui/misc.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/resource.rc")
|
||||
|
||||
set (BOSS_API_SRC ${BOSS_SRC}
|
||||
|
||||
+10
-6
@@ -153,16 +153,19 @@ Visual C++ Redistributable for Visual Studio 2013 (x86)</a>. BOSS can be install
|
||||
<p>The <q>Help</q> menu provides a link to this readme and an about page that contains the version of BOSS being run, some legal information and a link to the <a href="http://boss-developers.github.io">project homepage</a>.
|
||||
|
||||
<h3 id="usage-sort">Sorting Plugins</h3>
|
||||
<figure>
|
||||
<img src="images/confirm.png">
|
||||
<figcaption>Editing BOSS's calculated load order.</figcaption>
|
||||
<figure class="slideshow">
|
||||
<img alt="BOSS confirmation dialog" src="images/confirm-1.png">
|
||||
<img alt="BOSS confirmation dialog with editing panel visible" src="images/confirm-2.png">
|
||||
<figcaption style="padding-top:510px;">Viewing & editing BOSS's calculated load order.</figcaption>
|
||||
</figure>
|
||||
<p>Clicking the <q>Sort Plugins</q> button in the main window will begin the sorting process.
|
||||
|
||||
<p>Provided that masterlist updating <a href="#settingsUpdateMasterlist">is enabled</a> and that a masterlist repository URL <a href="#settingsMasterlistURL">is set</a>, BOSS checks for updates to its masterlist and downloads any that are available. If there are any syntax errors in the latest masterlist (due to human error by its maintainers), the updater rolls back one version at a time until it finds a version that works. If any other errors are encountered, updating is cancelled.
|
||||
|
||||
<p>During the sorting process, BOSS extracts information from each of the plugins installed in the game's Data folder and combines this information with any relevant metadata provided by the masterlist and userlist. It then uses the combined data to build a directed graph of all the interactions between all the installed plugins. A topological sort is then carried out on the graph to produce a list of plugins in their optimal load order, according to BOSS's criteria. If a cycle is detected (eg. A depends on B depends on A), then sorting is cancelled as it becomes impossible to generate a load order that satisfies all conditions.
|
||||
<p>If successful, the calculated load order is then displayed in the dialog shown above, which allows the user to edit the load order before it is applied. Multiple plugins may be selected and moved at once. Plugins which are empty (ie. only contain a header record) are displayed in <span style="color: #7A7A7A;">grey text</span>, and plugins that are not empty and load BSAs are displayed in <span style="color: #008EDB;">blue text</span>. If <q>OK</q> button is clicked, it is then applied, and any edits made are recorded in the userlist for re-application when BOSS next sorts the game's plugins. If the <q>Cancel</q> button is clicked, then the load order and any edits made are discarded.
|
||||
<p>If successful, the calculated load order is then displayed in the dialog shown above. Plugins which are empty (ie. only contain a header record) are displayed in <span style="color: #7A7A7A;">grey text</span>, and plugins that are not empty and load BSAs are displayed in <span style="color: #008EDB;">blue text</span>.
|
||||
Clicking on a plugin in the list will display the editing panel, where its load order related metadata can be edited. The <q>Show only conflicting plugins</q> checkbox filters the plugin list so that only plugins which can be validly added to the <q>Load After</q> list and either contain conflicting records or (if the selected plugin loads a BSA) load BSAs that <i>may</i> contain conflicting resources. The checkbox must be ticked before plugins can be added to the <q>Load After</q> list, which is done by drag 'n' dropping them from the plugin list, and it must be unticked to select another plugin for editing. The priority value is explained <a href="#editingPriority">below</a>.
|
||||
<p>If the <q>Apply</q> button is clicked, BOSS does one of two things: if no edits were made, then it immediately applies the load order, but if edits were made, then it repeats the sorting process with the new edits applied. If the <q>Cancel</q> button is clicked, then the load order and any edits made are discarded.
|
||||
<p>BOSS then generates a report and displays it either in a new window or in your default browser, according to the value of the <a href="#settingsViewReports">relevant setting</a>. Any errors encountered during the sorting process will be displayed in this report, including those due to graph cycles, missing dependencies or installed incompatible plugins. See the next section for more information on the report.
|
||||
<p>BOSS is able to sort plugins ghosted by <abbr title="Wrye Bash, Wrye Flash or Wrye Flash NV">Wrye *ash</abbr>, and can extract Bash Tags and version numbers from plugin descriptions. Provided that they have the <code>Filter</code> Bash Tag present in their description, BOSS can recognise filter patches and so avoid displaying unnecessary error messages for any of their masters that may be missing.
|
||||
<p>While reading very large plugins, such as the game's main master file, BOSS may appear to stop responding: this is not an issue. The time it takes for BOSS to sort your load order depends primarily on the size of the masterlist being used, the total size of the files in your load order, and the number of plugins in your load order. The first run is likely to be longer than subsequent runs as BOSS needs to download the full masterlist, rather than just the changes made by updates. In testing, it was found that sorting ~90 plugins with a total size of ~350 MB and a 5 MB masterlist takes around 15 seconds, though performance will vary with computer hardware.
|
||||
@@ -176,7 +179,7 @@ Visual C++ Redistributable for Visual Studio 2013 (x86)</a>. BOSS can be install
|
||||
</figure>
|
||||
|
||||
<p>BOSS's results report can be displayed either in BOSS's own report viewer, or in your default web browser, according to the value of the <a href="#settingsViewReports">relevant setting</a>.
|
||||
<p>The report is comprised of three main sections:
|
||||
<p>The report is comprised of two sections:
|
||||
<ul>
|
||||
<li>The <q>Summary</q> tab gives information on the versions of BOSS and the masterlist used, whether masterlist updating is enabled, and breaks down the numbers of each message type in the Summary and Details tabs. It also notifies you if there have been no changes in the <q>Details</q> tab since you last ran BOSS for the same game. Finally, the <q>Summary</q> tab is also where any global messages supplied in the masterlist and any errors encountered during sorting are displayed.
|
||||
<li>The <q>Details</q> tab lists the plugins BOSS sorted in their new load order, along with any messages BOSS has provided for them. BOSS will also display the plugin's <abbr title="Cyclic Redundancy Check">CRC</abbr> value and extract its version if found in the plugin's description field. If BOSS suggests any Bash Tags to be added, they will be displayed in <span style="color:green;">green text</span>, while any Bash Tags to be removed will be displayed in <span style="color:red;">red text</span>.
|
||||
@@ -210,7 +213,7 @@ Visual C++ Redistributable for Visual Studio 2013 (x86)</a>. BOSS can be install
|
||||
<tr><th>Field<th>Description
|
||||
<tbody>
|
||||
<tr><td>Enable User Changes<td>If this is checked, BOSS will use the metadata you supplied when sorting the current plugin. Otherwise, your metadata will be ignored.
|
||||
<tr><td>Priority<td>This is a very rough control for determining how far up or down the load order a plugin should go. Plugins with equal priority will be compared as normal by the sorting algorithm, but plugins with a larger priority value will load later in the load order than plugins with a smaller priority value, unless the former depends on the latter or the latter is explicity told to load after the former. Plugins have a default priority of <code>0</code>.
|
||||
<tr><td id="editingPriority">Priority<td>This is a very rough control for determining how far up or down the load order a plugin should go. Plugins with equal priority will be compared as normal by the sorting algorithm, but plugins with a larger priority value will load later in the load order than plugins with a smaller priority value, unless the former depends on the latter or the latter is explicity told to load after the former. Plugins have a default priority of <code>0</code>.
|
||||
<tr><td>Requirements<td>This is a list of files that are required by the current plugin for it to function correctly. BOSS will display an error message if any of the listed files are missing.
|
||||
<p>Any file, not just plugins, can be listed here, and each file has three sub-fields:
|
||||
<ul>
|
||||
@@ -370,6 +373,7 @@ To translate the BOSS application:
|
||||
<li>Ysne58: For keeping the thread links on BOSS's Nexus site pages up to date.
|
||||
<li>Łukasz Niemczyk: For the Polish translation of v3.
|
||||
<li>bluesky404: For the Chinese translation of v3.
|
||||
<li>Kaos: For the French translation of v3.
|
||||
<li>For beta testing: Surazal, myk002, Hickory, Ysne58, the <a href="http://tesalliance.org/forums/">Beta Testing & Analysis Guild at TES Alliance</a>, AndalayBay, dAb, dj2005, Dubiousness, hyno111, Invader, matter2003, NightStar, olminator, saebel, Telyn, wiz0floyd, wormheart, Zanderat, zone22 and many more.
|
||||
</ul>
|
||||
<p>BOSS is written in C++ and makes use of the <a href="http://www.davekoelle.com/alphanum.html">Alphanum</a>, <a href="http://www.boost.org/">Boost</a>, <a href="http://github.com/WrinklyNinja/libespm">libespm</a>, <a href="http://github.com/libgit2/libgit2">libgit2</a>, <a href="http://github.com/WrinklyNinja/libloadorder">libloadorder</a>, <a href="http://code.google.com/p/pugixml/">PugiXML</a>, <a href="http://www.wxwidgets.org/">wxWidgets</a> and <a href="http://code.google.com/p/yaml-cpp/">yaml-cpp</a> libraries. BOSS's reports are written in HTML5/CSS3/Javascript and make use of <a href="http://github.com/inexorabletash/polyfill">Polyfill.js</a> to provide Internet Explorer 8 compatibility. Copyright license information for all these may be found <a href="licenses/Licenses.txt">here</a>.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -741,7 +741,7 @@ namespace boss {
|
||||
}
|
||||
|
||||
bool alpha_sort(const Plugin& lhs, const Plugin& rhs) {
|
||||
return boost::ilexicographical_compare(lhs.Name(), rhs.Name());
|
||||
return boost::ilexicographical_compare(rhs.Name(), lhs.Name());
|
||||
}
|
||||
|
||||
bool master_sort(const Plugin& lhs, const Plugin& rhs) {
|
||||
|
||||
+433
-538
File diff suppressed because it is too large
Load Diff
+72
-104
@@ -24,54 +24,103 @@
|
||||
#define __BOSS_GUI_EDITOR__
|
||||
|
||||
#include "ids.h"
|
||||
#include "misc.h"
|
||||
#include "../backend/metadata.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/dnd.h>
|
||||
|
||||
class MessageList : public wxListView {
|
||||
/* Have two versions of the editor: one mini editor that only contains
|
||||
controls for editing the load order related metadata, and a full editor
|
||||
that contains controls for editing all the metadata.
|
||||
|
||||
Both editors need to convert between metadata and control data, and to
|
||||
keep track of what edits have been made.
|
||||
|
||||
Have a immutable plugin list to keep track of non-user-edit metadata,
|
||||
and a mutable plugin list to keep track of user-edit metadata. When
|
||||
recording edits, diff the metadata obtained from the control values with
|
||||
the metadata in the immutable plugin entry to get the new user-edit metadata.
|
||||
|
||||
If a metadata type's corresponding control is not present (ie. in the mini
|
||||
editor), then use the immutable plugin entry's metadata for that type.
|
||||
*/
|
||||
|
||||
class TextDropTarget : public wxTextDropTarget { //Class to override virtual functions.
|
||||
public:
|
||||
MessageList(wxWindow * parent, wxWindowID id, const unsigned int language);
|
||||
|
||||
void SetItems(const std::vector<boss::Message>& messages);
|
||||
std::vector<boss::Message> GetItems() const;
|
||||
|
||||
boss::Message GetItem(long item) const;
|
||||
void SetItem(long item, const boss::Message& message);
|
||||
void AppendItem(const boss::Message& message);
|
||||
|
||||
void OnDeleteItem(wxListEvent& event);
|
||||
protected:
|
||||
wxString OnGetItemText(long item, long column) const;
|
||||
|
||||
TextDropTarget(wxListView * owner, wxStaticText * name);
|
||||
virtual bool OnDropText(wxCoord x, wxCoord y, const wxString &data);
|
||||
private:
|
||||
std::vector<boss::Message> _messages;
|
||||
const unsigned int _language;
|
||||
wxListView * targetOwner;
|
||||
wxStaticText * targetName;
|
||||
};
|
||||
|
||||
class Editor : public wxFrame {
|
||||
class CommonEditor {
|
||||
public:
|
||||
Editor(wxWindow *parent, const wxString& title, const std::string userlistPath, const std::vector<boss::Plugin>& basePlugins, std::vector<boss::Plugin>& editedPlugins, const unsigned int language, const boss::Game& game);
|
||||
CommonEditor(const std::list<boss::Plugin>& plugins, const boss::Game& game);
|
||||
CommonEditor(const std::list<boss::Plugin>& plugins, const boss::Game& game, std::list<boss::Plugin>& editedPlugins);
|
||||
protected:
|
||||
const boss::Game& _game;
|
||||
const std::list<boss::Plugin> _basePlugins;
|
||||
std::list<boss::Plugin> _editedPlugins;
|
||||
|
||||
boss::Plugin GetMasterData(const wxString& plugin) const;
|
||||
boss::Plugin GetUserData(const wxString& plugin) const;
|
||||
virtual boss::Plugin GetNewData(const wxString& plugin) const = 0;
|
||||
|
||||
void ApplyEdits(const wxString& plugin, wxListView * list);
|
||||
|
||||
boss::File RowToFile(wxListView * list, long row) const;
|
||||
boss::Tag RowToTag(wxListView * list, long row) const;
|
||||
boss::PluginDirtyInfo RowToPluginDirtyInfo(wxListView * list, long row) const;
|
||||
};
|
||||
|
||||
class MiniEditor : public wxDialog, public CommonEditor {
|
||||
public:
|
||||
MiniEditor(wxWindow *parent, const wxString& title, const std::list<boss::Plugin>& plugins, const boss::Game& game);
|
||||
|
||||
void OnPluginSelect(wxListEvent& event);
|
||||
void OnRowSelect(wxListEvent& event);
|
||||
void OnRemoveRow(wxCommandEvent& event);
|
||||
void OnFilterToggle(wxCommandEvent& event);
|
||||
void OnDragStart(wxListEvent& event);
|
||||
void OnApply(wxCommandEvent& event);
|
||||
|
||||
const std::list<boss::Plugin>& GetEditedPlugins() const;
|
||||
private:
|
||||
wxListView * pluginList;
|
||||
wxPanel * editingPanel;
|
||||
wxButton * removeBtn;
|
||||
wxListView * loadAfterList;
|
||||
wxCheckBox * filterCheckbox;
|
||||
wxSpinCtrl * prioritySpin;
|
||||
wxStaticText * pluginText;
|
||||
wxStaticText * descText;
|
||||
|
||||
boss::Plugin GetNewData(const wxString& plugin) const;
|
||||
};
|
||||
|
||||
class Editor : public wxFrame, public CommonEditor {
|
||||
public:
|
||||
Editor(wxWindow *parent, const wxString& title, const std::string userlistPath, const std::list<boss::Plugin>& basePlugins, std::list<boss::Plugin>& editedPlugins, const unsigned int language, const boss::Game& game);
|
||||
|
||||
void OnPluginSelect(wxListEvent& event);
|
||||
void OnPluginListRightClick(wxListEvent& event);
|
||||
void OnPluginCopyName(wxCommandEvent& event);
|
||||
void OnPluginCopyMetadata(wxCommandEvent& event);
|
||||
void OnPluginClearMetadata(wxCommandEvent& event);
|
||||
void OnEnabledToggle(wxCommandEvent& event);
|
||||
void OnPriorityChange(wxSpinEvent& event);
|
||||
void OnListBookChange(wxBookCtrlEvent& event);
|
||||
void OnAddRow(wxCommandEvent& event);
|
||||
void OnEditRow(wxCommandEvent& event);
|
||||
void OnRemoveRow(wxCommandEvent& event);
|
||||
void OnRecalc(wxCommandEvent& event);
|
||||
void OnRowSelect(wxListEvent& event);
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
private:
|
||||
|
||||
wxMenu * pluginMenu;
|
||||
wxButton * addBtn;
|
||||
wxButton * editBtn;
|
||||
@@ -91,88 +140,7 @@ private:
|
||||
wxStaticText * pluginText;
|
||||
|
||||
const std::string _userlistPath;
|
||||
const std::vector<boss::Plugin> _basePlugins;
|
||||
const boss::Game& _game;
|
||||
std::vector<boss::Plugin> _editedPlugins;
|
||||
std::vector<boss::Message> currentMessages;
|
||||
|
||||
void ApplyEdits(const wxString& plugin);
|
||||
|
||||
boss::Plugin GetMasterData(const wxString& plugin) const;
|
||||
boss::Plugin GetUserData(const wxString& plugin) const;
|
||||
boss::Plugin GetNewData(const wxString& plugin) const;
|
||||
|
||||
boss::File RowToFile(wxListView * list, long row) const;
|
||||
boss::Tag RowToTag(wxListView * list, long row) const;
|
||||
boss::PluginDirtyInfo RowToPluginDirtyInfo(wxListView * list, long row) const;
|
||||
};
|
||||
|
||||
class FileEditDialog : public wxDialog {
|
||||
public:
|
||||
FileEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetValues(const wxString& name, const wxString& display, const wxString& condition);
|
||||
wxString GetName() const;
|
||||
wxString GetDisplayName() const;
|
||||
wxString GetCondition() const;
|
||||
private:
|
||||
wxTextCtrl * _name;
|
||||
wxTextCtrl * _display;
|
||||
wxTextCtrl * _condition;
|
||||
};
|
||||
|
||||
class MessageEditDialog : public wxDialog {
|
||||
public:
|
||||
MessageEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetMessage(const boss::Message& message);
|
||||
boss::Message GetMessage() const;
|
||||
|
||||
void OnSelect(wxListEvent& event);
|
||||
void OnAdd(wxCommandEvent& event);
|
||||
void OnEdit(wxCommandEvent& event);
|
||||
void OnRemove(wxCommandEvent& event);
|
||||
private:
|
||||
wxButton * addBtn;
|
||||
wxButton * editBtn;
|
||||
wxButton * removeBtn;
|
||||
wxChoice * _type;
|
||||
wxChoice * _language;
|
||||
wxListView * _content;
|
||||
wxTextCtrl * _condition;
|
||||
wxTextCtrl * _str;
|
||||
};
|
||||
|
||||
class TagEditDialog : public wxDialog {
|
||||
public:
|
||||
TagEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetValues(int state, const wxString& name, const wxString& condition);
|
||||
wxString GetState() const;
|
||||
wxString GetName() const;
|
||||
wxString GetCondition() const;
|
||||
private:
|
||||
wxChoice * _state;
|
||||
wxTextCtrl * _name;
|
||||
wxTextCtrl * _condition;
|
||||
};
|
||||
|
||||
class DirtInfoEditDialog : public wxDialog {
|
||||
public:
|
||||
DirtInfoEditDialog(wxWindow * parent, const wxString& title);
|
||||
|
||||
void SetValues(const wxString& crc, unsigned int itm, unsigned int udr, unsigned int nav, const wxString& utility);
|
||||
wxString GetCRC() const;
|
||||
wxString GetUtility() const;
|
||||
unsigned int GetITMs() const;
|
||||
unsigned int GetUDRs() const;
|
||||
unsigned int GetDeletedNavmeshes() const;
|
||||
private:
|
||||
wxTextCtrl * _crc;
|
||||
wxSpinCtrl * _itm;
|
||||
wxSpinCtrl * _udr;
|
||||
wxSpinCtrl * _nav;
|
||||
wxTextCtrl * _utility;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+203
-368
File diff suppressed because it is too large
Load Diff
@@ -70,23 +70,4 @@ private:
|
||||
std::vector<boss::Game>& _games;
|
||||
};
|
||||
|
||||
class LoadOrderPreview : public wxDialog {
|
||||
public:
|
||||
LoadOrderPreview(wxWindow *parent, const wxString title, const std::list<boss::Plugin>& plugins, const boss::Game& game);
|
||||
|
||||
void OnPluginSelect(wxListEvent& event);
|
||||
void OnMoveUp(wxCommandEvent& event);
|
||||
void OnMoveDown(wxCommandEvent& event);
|
||||
|
||||
std::list<boss::Plugin> GetLoadOrder() const;
|
||||
private:
|
||||
wxListView * _loadOrder;
|
||||
wxButton * _moveUp;
|
||||
wxButton * _moveDown;
|
||||
|
||||
const std::list<boss::Plugin> _plugins;
|
||||
std::set<std::string> _movedPlugins;
|
||||
const boss::Game& _game;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,480 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2013-2014 WrinklyNinja
|
||||
|
||||
This file is part of BOSS.
|
||||
|
||||
BOSS 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.
|
||||
|
||||
BOSS 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 BOSS. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "misc.h"
|
||||
#include "../backend/helpers.h"
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
MessageList::MessageList(wxWindow * parent, wxWindowID id, const unsigned int language) : wxListView(parent, id, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_VIRTUAL | wxLC_SINGLE_SEL), _language(language) {
|
||||
InsertColumn(0, translate("Type"));
|
||||
InsertColumn(1, translate("Content"));
|
||||
InsertColumn(2, translate("Condition"));
|
||||
InsertColumn(3, translate("Language"));
|
||||
|
||||
Bind(wxEVT_LIST_DELETE_ITEM, &MessageList::OnDeleteItem, this);
|
||||
|
||||
SetItemCount(0);
|
||||
}
|
||||
|
||||
std::vector<boss::Message> MessageList::GetItems() const {
|
||||
return _messages;
|
||||
}
|
||||
|
||||
void MessageList::SetItems(const std::vector<boss::Message>& messages) {
|
||||
_messages = messages;
|
||||
SetItemCount(_messages.size());
|
||||
RefreshItems(0, _messages.size() - 1);
|
||||
}
|
||||
|
||||
boss::Message MessageList::GetItem(long item) const {
|
||||
return _messages[item];
|
||||
}
|
||||
|
||||
void MessageList::SetItem(long item, const boss::Message& message) {
|
||||
_messages[item] = message;
|
||||
RefreshItem(item);
|
||||
}
|
||||
|
||||
void MessageList::AppendItem(const boss::Message& message) {
|
||||
_messages.push_back(message);
|
||||
SetItemCount(_messages.size());
|
||||
RefreshItem(_messages.size() - 1);
|
||||
}
|
||||
|
||||
void MessageList::OnDeleteItem(wxListEvent& event) {
|
||||
_messages.erase(_messages.begin() + event.GetIndex());
|
||||
SetItemCount(_messages.size());
|
||||
RefreshItems(event.GetIndex(), _messages.size() - 1);
|
||||
}
|
||||
|
||||
wxString MessageList::OnGetItemText(long item, long column) const {
|
||||
if (column < 0 || column > 3 || item < 0 || item > _messages.size() - 1)
|
||||
return wxString();
|
||||
|
||||
if (column == 0) {
|
||||
if (_messages[item].Type() == boss::g_message_say)
|
||||
return Type[0];
|
||||
else if (_messages[item].Type() == boss::g_message_warn)
|
||||
return Type[1];
|
||||
else
|
||||
return Type[2];
|
||||
}
|
||||
else if (column == 1) {
|
||||
return FromUTF8(_messages[item].ChooseContent(_language).Str());
|
||||
}
|
||||
else if (column == 2) {
|
||||
return FromUTF8(_messages[item].Condition());
|
||||
}
|
||||
else {
|
||||
return FromUTF8(boss::Language(_messages[item].ChooseContent(_language).Language()).Name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FileEditDialog::FileEditDialog(wxWindow *parent, const wxString& title) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
|
||||
|
||||
_name = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_EMPTY));
|
||||
_display = new wxTextCtrl(this, wxID_ANY);
|
||||
_condition = new wxTextCtrl(this, wxID_ANY);
|
||||
|
||||
wxSizerFlags leftItem(0);
|
||||
leftItem.Left();
|
||||
|
||||
wxSizerFlags rightItem(1);
|
||||
rightItem.Right().Expand();
|
||||
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxFlexGridSizer * GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
GridSizer->AddGrowableCol(1, 1);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Filename (required):")), leftItem);
|
||||
GridSizer->Add(_name, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Displayed Name:")), leftItem);
|
||||
GridSizer->Add(_display, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Condition:")), leftItem);
|
||||
GridSizer->Add(_condition, rightItem);
|
||||
|
||||
bigBox->Add(GridSizer, 0, wxEXPAND | wxALL, 15);
|
||||
|
||||
bigBox->AddSpacer(10);
|
||||
bigBox->AddStretchSpacer(1);
|
||||
|
||||
//Need to add 'OK' and 'Cancel' buttons.
|
||||
wxSizer * sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
|
||||
if (sizer != NULL)
|
||||
bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15);
|
||||
|
||||
SetBackgroundColour(wxColour(255, 255, 255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void FileEditDialog::SetValues(const wxString& name, const wxString& display, const wxString& condition) {
|
||||
|
||||
_name->SetValue(name);
|
||||
_display->SetValue(display);
|
||||
_condition->SetValue(condition);
|
||||
}
|
||||
|
||||
wxString FileEditDialog::GetName() const {
|
||||
return _name->GetValue();
|
||||
}
|
||||
|
||||
wxString FileEditDialog::GetDisplayName() const {
|
||||
return _display->GetValue();
|
||||
}
|
||||
|
||||
wxString FileEditDialog::GetCondition() const {
|
||||
return _condition->GetValue();
|
||||
}
|
||||
|
||||
MessageEditDialog::MessageEditDialog(wxWindow *parent, const wxString& title) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
|
||||
|
||||
wxArrayString languages;
|
||||
vector<string> langs = boss::Language::Names();
|
||||
for (size_t i = 0; i < langs.size(); i++) {
|
||||
languages.Add(FromUTF8(langs[i]));
|
||||
}
|
||||
|
||||
//Initialise controls.
|
||||
_type = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 3, Type);
|
||||
_language = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, languages);
|
||||
|
||||
_condition = new wxTextCtrl(this, wxID_ANY);
|
||||
_str = new wxTextCtrl(this, wxID_ANY);
|
||||
|
||||
_content = new wxListView(this, LIST_MessageContent, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL);
|
||||
|
||||
addBtn = new wxButton(this, BUTTON_AddContent, translate("Add Content"));
|
||||
editBtn = new wxButton(this, BUTTON_EditContent, translate("Edit Content"));
|
||||
removeBtn = new wxButton(this, BUTTON_RemoveContent, translate("Remove Content"));
|
||||
|
||||
_content->InsertColumn(0, translate("Language"));
|
||||
_content->InsertColumn(1, translate("String"));
|
||||
|
||||
//Set up event handling.
|
||||
Bind(wxEVT_BUTTON, &MessageEditDialog::OnAdd, this, BUTTON_AddContent);
|
||||
Bind(wxEVT_BUTTON, &MessageEditDialog::OnEdit, this, BUTTON_EditContent);
|
||||
Bind(wxEVT_BUTTON, &MessageEditDialog::OnRemove, this, BUTTON_RemoveContent);
|
||||
Bind(wxEVT_LIST_ITEM_SELECTED, &MessageEditDialog::OnSelect, this, LIST_MessageContent);
|
||||
|
||||
wxSizerFlags leftItem(0);
|
||||
leftItem.Left();
|
||||
|
||||
wxSizerFlags rightItem(1);
|
||||
rightItem.Right();
|
||||
|
||||
wxSizerFlags wholeItem(0);
|
||||
wholeItem.Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 15);
|
||||
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxFlexGridSizer * GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
GridSizer->AddGrowableCol(1, 1);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Type:")), leftItem);
|
||||
GridSizer->Add(_type, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Condition:")), leftItem);
|
||||
GridSizer->Add(_condition, rightItem);
|
||||
|
||||
bigBox->AddSpacer(15);
|
||||
|
||||
bigBox->Add(GridSizer, wholeItem);
|
||||
|
||||
bigBox->Add(_content, wholeItem);
|
||||
|
||||
wxFlexGridSizer * GridSizer2 = new wxFlexGridSizer(2, 5, 5);
|
||||
GridSizer2->AddGrowableCol(1, 1);
|
||||
|
||||
GridSizer2->Add(new wxStaticText(this, wxID_ANY, translate("Language:")), leftItem);
|
||||
GridSizer2->Add(_language, rightItem);
|
||||
|
||||
GridSizer2->Add(new wxStaticText(this, wxID_ANY, translate("Content:")), leftItem);
|
||||
GridSizer2->Add(_str, rightItem);
|
||||
|
||||
bigBox->Add(GridSizer2, wholeItem);
|
||||
|
||||
wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL);
|
||||
hbox->Add(addBtn, 0, wxRIGHT, 5);
|
||||
hbox->Add(editBtn, 0, wxLEFT | wxRIGHT, 5);
|
||||
hbox->Add(removeBtn, 0, wxLEFT, 5);
|
||||
bigBox->Add(hbox, 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 15);
|
||||
|
||||
bigBox->AddSpacer(10);
|
||||
bigBox->AddStretchSpacer(1);
|
||||
|
||||
//Need to add 'OK' and 'Cancel' buttons.
|
||||
wxSizer * sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
|
||||
if (sizer != NULL)
|
||||
bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15);
|
||||
|
||||
//Set defaults.
|
||||
_type->SetSelection(0);
|
||||
_language->SetSelection(0);
|
||||
editBtn->Enable(false);
|
||||
removeBtn->Enable(false);
|
||||
|
||||
SetBackgroundColour(wxColour(255, 255, 255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void MessageEditDialog::SetMessage(const boss::Message& message) {
|
||||
|
||||
if (message.Type() == boss::g_message_say)
|
||||
_type->SetSelection(0);
|
||||
else if (message.Type() == boss::g_message_warn)
|
||||
_type->SetSelection(1);
|
||||
else
|
||||
_type->SetSelection(2);
|
||||
|
||||
_condition->SetValue(FromUTF8(message.Condition()));
|
||||
|
||||
vector<boss::MessageContent> contents = message.Content();
|
||||
for (size_t i = 0, max = contents.size(); i < max; ++i) {
|
||||
_content->InsertItem(i, FromUTF8(boss::Language(contents[i].Language()).Name()));
|
||||
_content->SetItem(i, 1, FromUTF8(contents[i].Str()));
|
||||
}
|
||||
}
|
||||
|
||||
boss::Message MessageEditDialog::GetMessage() const {
|
||||
|
||||
unsigned int type;
|
||||
string condition;
|
||||
if (_type->GetSelection() == 0)
|
||||
type = boss::g_message_say;
|
||||
else if (_type->GetSelection() == 1)
|
||||
type = boss::g_message_warn;
|
||||
else
|
||||
type = boss::g_message_error;
|
||||
|
||||
condition = string(_condition->GetValue().ToUTF8());
|
||||
|
||||
vector<boss::MessageContent> contents;
|
||||
for (size_t i = 0, max = _content->GetItemCount(); i < max; ++i) {
|
||||
|
||||
string str = string(_content->GetItemText(i, 1).ToUTF8());
|
||||
unsigned int lang = boss::Language(string(_content->GetItemText(i, 0).ToUTF8())).Code();
|
||||
|
||||
contents.push_back(boss::MessageContent(str, lang));
|
||||
}
|
||||
|
||||
return boss::Message(type, contents, condition);
|
||||
}
|
||||
|
||||
void MessageEditDialog::OnSelect(wxListEvent& event) {
|
||||
_language->SetSelection(boss::Language(string(_content->GetItemText(event.GetIndex(), 0).ToUTF8())).Code());
|
||||
_str->SetValue(_content->GetItemText(event.GetIndex(), 1));
|
||||
editBtn->Enable(true);
|
||||
removeBtn->Enable(true);
|
||||
}
|
||||
|
||||
void MessageEditDialog::OnAdd(wxCommandEvent& event) {
|
||||
long i = _content->GetItemCount();
|
||||
_content->InsertItem(i, FromUTF8(boss::Language(_language->GetSelection()).Name()));
|
||||
_content->SetItem(i, 1, _str->GetValue());
|
||||
}
|
||||
|
||||
void MessageEditDialog::OnEdit(wxCommandEvent& event) {
|
||||
if (_content->GetFirstSelected() == -1) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Attempting to edit message content, but no content row selected.";
|
||||
wxMessageBox(
|
||||
translate("Error: No content row selected."),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
long i = _content->GetFirstSelected();
|
||||
_content->SetItem(i, 0, FromUTF8(boss::Language(_language->GetSelection()).Name()));
|
||||
_content->SetItem(i, 1, _str->GetValue());
|
||||
}
|
||||
|
||||
void MessageEditDialog::OnRemove(wxCommandEvent& event) {
|
||||
if (_content->GetFirstSelected() == -1) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Attempting to remove message content, but no content row selected.";
|
||||
wxMessageBox(
|
||||
translate("Error: No content row selected."),
|
||||
translate("BOSS: Error"),
|
||||
wxOK | wxICON_ERROR,
|
||||
NULL);
|
||||
return;
|
||||
}
|
||||
_content->DeleteItem(_content->GetFirstSelected());
|
||||
editBtn->Enable(false);
|
||||
removeBtn->Enable(false);
|
||||
}
|
||||
|
||||
TagEditDialog::TagEditDialog(wxWindow *parent, const wxString& title) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
|
||||
|
||||
//Initialise controls.
|
||||
_state = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 2, State);
|
||||
|
||||
_name = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_EMPTY));
|
||||
_condition = new wxTextCtrl(this, wxID_ANY);
|
||||
|
||||
wxSizerFlags leftItem(0);
|
||||
leftItem.Left();
|
||||
|
||||
wxSizerFlags rightItem(1);
|
||||
rightItem.Right().Expand();
|
||||
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxFlexGridSizer * GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
GridSizer->AddGrowableCol(1, 1);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Add/Remove:")), leftItem);
|
||||
GridSizer->Add(_state, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Name (required):")), leftItem);
|
||||
GridSizer->Add(_name, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Condition:")), leftItem);
|
||||
GridSizer->Add(_condition, rightItem);
|
||||
|
||||
bigBox->Add(GridSizer, 0, wxEXPAND | wxALL, 15);
|
||||
|
||||
bigBox->AddSpacer(10);
|
||||
bigBox->AddStretchSpacer(1);
|
||||
|
||||
//Need to add 'OK' and 'Cancel' buttons.
|
||||
wxSizer * sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
|
||||
if (sizer != NULL)
|
||||
bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15);
|
||||
|
||||
//Set defaults.
|
||||
_state->SetSelection(0);
|
||||
|
||||
SetBackgroundColour(wxColour(255, 255, 255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void TagEditDialog::SetValues(int state, const wxString& name, const wxString& condition) {
|
||||
|
||||
_state->SetSelection(state);
|
||||
_name->SetValue(name);
|
||||
_condition->SetValue(condition);
|
||||
}
|
||||
|
||||
wxString TagEditDialog::GetState() const {
|
||||
return State[_state->GetSelection()];
|
||||
}
|
||||
|
||||
wxString TagEditDialog::GetName() const {
|
||||
return _name->GetValue();
|
||||
}
|
||||
|
||||
wxString TagEditDialog::GetCondition() const {
|
||||
return _condition->GetValue();
|
||||
}
|
||||
|
||||
DirtInfoEditDialog::DirtInfoEditDialog(wxWindow * parent, const wxString& title) : wxDialog(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) {
|
||||
//Initialise controls.
|
||||
wxTextValidator val(wxFILTER_EMPTY | wxFILTER_INCLUDE_CHAR_LIST);
|
||||
val.SetCharIncludes("0123456789ABCDEFabcdef");
|
||||
|
||||
_itm = new wxSpinCtrl(this, wxID_ANY, "0");
|
||||
_udr = new wxSpinCtrl(this, wxID_ANY, "0");
|
||||
_nav = new wxSpinCtrl(this, wxID_ANY, "0");
|
||||
_crc = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, val);
|
||||
_utility = new wxTextCtrl(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_EMPTY));
|
||||
|
||||
wxSizerFlags leftItem(0);
|
||||
leftItem.Left();
|
||||
|
||||
wxSizerFlags rightItem(1);
|
||||
rightItem.Right().Expand();
|
||||
|
||||
wxBoxSizer * bigBox = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxFlexGridSizer * GridSizer = new wxFlexGridSizer(2, 5, 5);
|
||||
GridSizer->AddGrowableCol(1, 1);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("CRC (required):")), leftItem);
|
||||
GridSizer->Add(_crc, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("ITM Count:")), leftItem);
|
||||
GridSizer->Add(_itm, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("UDR Count:")), leftItem);
|
||||
GridSizer->Add(_udr, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Deleted Navmesh Count:")), leftItem);
|
||||
GridSizer->Add(_nav, rightItem);
|
||||
|
||||
GridSizer->Add(new wxStaticText(this, wxID_ANY, translate("Cleaning Utility (required):")), leftItem);
|
||||
GridSizer->Add(_utility, rightItem);
|
||||
|
||||
bigBox->Add(GridSizer, 0, wxEXPAND | wxALL, 15);
|
||||
|
||||
bigBox->AddSpacer(10);
|
||||
bigBox->AddStretchSpacer(1);
|
||||
|
||||
//Need to add 'OK' and 'Cancel' buttons.
|
||||
wxSizer * sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL);
|
||||
if (sizer != NULL)
|
||||
bigBox->Add(sizer, 0, wxEXPAND | wxLEFT | wxBOTTOM | wxRIGHT, 15);
|
||||
|
||||
SetBackgroundColour(wxColour(255, 255, 255));
|
||||
SetIcon(wxIconLocation("BOSS.exe"));
|
||||
SetSizerAndFit(bigBox);
|
||||
}
|
||||
|
||||
void DirtInfoEditDialog::SetValues(const wxString& crc, unsigned int itm, unsigned int udr, unsigned int nav, const wxString& utility) {
|
||||
_crc->SetValue(crc);
|
||||
_itm->SetValue(itm);
|
||||
_udr->SetValue(udr);
|
||||
_nav->SetValue(nav);
|
||||
_utility->SetValue(utility);
|
||||
}
|
||||
|
||||
wxString DirtInfoEditDialog::GetCRC() const {
|
||||
return _crc->GetValue();
|
||||
}
|
||||
|
||||
unsigned int DirtInfoEditDialog::GetITMs() const {
|
||||
return _itm->GetValue();
|
||||
}
|
||||
|
||||
unsigned int DirtInfoEditDialog::GetUDRs() const {
|
||||
return _udr->GetValue();
|
||||
}
|
||||
|
||||
unsigned int DirtInfoEditDialog::GetDeletedNavmeshes() const {
|
||||
return _nav->GetValue();
|
||||
}
|
||||
|
||||
wxString DirtInfoEditDialog::GetUtility() const {
|
||||
return _utility->GetValue();
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/* BOSS
|
||||
|
||||
A plugin load order optimiser for games that use the esp/esm plugin system.
|
||||
|
||||
Copyright (C) 2013-2014 WrinklyNinja
|
||||
|
||||
This file is part of BOSS.
|
||||
|
||||
BOSS 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.
|
||||
|
||||
BOSS 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 BOSS. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef __BOSS_GUI_MISC__
|
||||
#define __BOSS_GUI_MISC__
|
||||
|
||||
#include "ids.h"
|
||||
#include "../backend/metadata.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
const wxString Type[3] = {
|
||||
translate("Note"),
|
||||
translate("Warning"),
|
||||
translate("Error")
|
||||
};
|
||||
|
||||
const wxString State[2] = {
|
||||
translate("Add"),
|
||||
translate("Remove")
|
||||
};
|
||||
|
||||
class MessageList : public wxListView {
|
||||
public:
|
||||
MessageList(wxWindow * parent, wxWindowID id, const unsigned int language);
|
||||
|
||||
void SetItems(const std::vector<boss::Message>& messages);
|
||||
std::vector<boss::Message> GetItems() const;
|
||||
|
||||
boss::Message GetItem(long item) const;
|
||||
void SetItem(long item, const boss::Message& message);
|
||||
void AppendItem(const boss::Message& message);
|
||||
|
||||
void OnDeleteItem(wxListEvent& event);
|
||||
protected:
|
||||
wxString OnGetItemText(long item, long column) const;
|
||||
|
||||
private:
|
||||
std::vector<boss::Message> _messages;
|
||||
const unsigned int _language;
|
||||
};
|
||||
|
||||
class FileEditDialog : public wxDialog {
|
||||
public:
|
||||
FileEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetValues(const wxString& name, const wxString& display, const wxString& condition);
|
||||
wxString GetName() const;
|
||||
wxString GetDisplayName() const;
|
||||
wxString GetCondition() const;
|
||||
private:
|
||||
wxTextCtrl * _name;
|
||||
wxTextCtrl * _display;
|
||||
wxTextCtrl * _condition;
|
||||
};
|
||||
|
||||
class MessageEditDialog : public wxDialog {
|
||||
public:
|
||||
MessageEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetMessage(const boss::Message& message);
|
||||
boss::Message GetMessage() const;
|
||||
|
||||
void OnSelect(wxListEvent& event);
|
||||
void OnAdd(wxCommandEvent& event);
|
||||
void OnEdit(wxCommandEvent& event);
|
||||
void OnRemove(wxCommandEvent& event);
|
||||
private:
|
||||
wxButton * addBtn;
|
||||
wxButton * editBtn;
|
||||
wxButton * removeBtn;
|
||||
wxChoice * _type;
|
||||
wxChoice * _language;
|
||||
wxListView * _content;
|
||||
wxTextCtrl * _condition;
|
||||
wxTextCtrl * _str;
|
||||
};
|
||||
|
||||
class TagEditDialog : public wxDialog {
|
||||
public:
|
||||
TagEditDialog(wxWindow *parent, const wxString& title);
|
||||
|
||||
void SetValues(int state, const wxString& name, const wxString& condition);
|
||||
wxString GetState() const;
|
||||
wxString GetName() const;
|
||||
wxString GetCondition() const;
|
||||
private:
|
||||
wxChoice * _state;
|
||||
wxTextCtrl * _name;
|
||||
wxTextCtrl * _condition;
|
||||
};
|
||||
|
||||
class DirtInfoEditDialog : public wxDialog {
|
||||
public:
|
||||
DirtInfoEditDialog(wxWindow * parent, const wxString& title);
|
||||
|
||||
void SetValues(const wxString& crc, unsigned int itm, unsigned int udr, unsigned int nav, const wxString& utility);
|
||||
wxString GetCRC() const;
|
||||
wxString GetUtility() const;
|
||||
unsigned int GetITMs() const;
|
||||
unsigned int GetUDRs() const;
|
||||
unsigned int GetDeletedNavmeshes() const;
|
||||
private:
|
||||
wxTextCtrl * _crc;
|
||||
wxSpinCtrl * _itm;
|
||||
wxSpinCtrl * _udr;
|
||||
wxSpinCtrl * _nav;
|
||||
wxTextCtrl * _utility;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user