mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Add dark icon property
This commit is contained in:
@@ -52,6 +52,7 @@ IMPLEMENT_REFLECTION(Field) {
|
|||||||
REFLECT_LOCALIZED(caption);
|
REFLECT_LOCALIZED(caption);
|
||||||
REFLECT_LOCALIZED(description); // FIXME: This field is both unused and uninitialized.
|
REFLECT_LOCALIZED(description); // FIXME: This field is both unused and uninitialized.
|
||||||
REFLECT_N("icon", icon_filename);
|
REFLECT_N("icon", icon_filename);
|
||||||
|
REFLECT_N("dark_icon", dark_icon_filename);
|
||||||
REFLECT(editable);
|
REFLECT(editable);
|
||||||
REFLECT(save_value);
|
REFLECT(save_value);
|
||||||
REFLECT(show_statistics);
|
REFLECT(show_statistics);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public:
|
|||||||
LocalizedString caption; ///< Caption for NativeLookEditor
|
LocalizedString caption; ///< Caption for NativeLookEditor
|
||||||
LocalizedString description; ///< Description, used in status bar
|
LocalizedString description; ///< Description, used in status bar
|
||||||
String icon_filename; ///< Filename for an icon (for list of fields)
|
String icon_filename; ///< Filename for an icon (for list of fields)
|
||||||
|
String dark_icon_filename; ///< Filename for an icon (for list of fields) when a variant for dark mode is necessary
|
||||||
bool editable; ///< Can values of this field be edited?
|
bool editable; ///< Can values of this field be edited?
|
||||||
bool save_value; ///< Should values of this field be written to files? Can be false for script generated fields.
|
bool save_value; ///< Should values of this field be written to files? Can be false for script generated fields.
|
||||||
bool show_statistics; ///< Should this field appear as a group by choice in the statistics panel?
|
bool show_statistics; ///< Should this field appear as a group by choice in the statistics panel?
|
||||||
|
|||||||
+11
-4
@@ -37,16 +37,21 @@ IMPLEMENT_REFLECTION(Installer) {
|
|||||||
void Installer::validate(Version file_app_version) {
|
void Installer::validate(Version file_app_version) {
|
||||||
Packaged::validate(file_app_version);
|
Packaged::validate(file_app_version);
|
||||||
// load icons where possible
|
// load icons where possible
|
||||||
FOR_EACH(p,packages) {
|
FOR_EACH(p,packages) {
|
||||||
if (!p->icon_url.empty() && !starts_with(p->icon_url,_("http:"))) {
|
String url = p->icon_url;
|
||||||
|
if (settings.darkMode() && !p->dark_icon_url.empty()) {
|
||||||
|
url = p->dark_icon_url;
|
||||||
|
}
|
||||||
|
if (!url.empty() && !starts_with(url,_("http:"))) {
|
||||||
// TODO: support absolute icon names
|
// TODO: support absolute icon names
|
||||||
try{
|
try{
|
||||||
String filename = p->name + _("/") + p->icon_url;
|
String filename = p->name + _("/") + url;
|
||||||
auto img_stream = openIn(p->name + _("/") + p->icon_url);
|
auto img_stream = openIn(p->name + _("/") + url);
|
||||||
image_load_file(p->icon, *img_stream);
|
image_load_file(p->icon, *img_stream);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
// ignore errors, it's just an image
|
// ignore errors, it's just an image
|
||||||
p->icon_url.clear();
|
p->icon_url.clear();
|
||||||
|
p->dark_icon_url.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,6 +207,7 @@ PackageDescription::PackageDescription(const Packaged& package)
|
|||||||
, short_name(package.short_name)
|
, short_name(package.short_name)
|
||||||
, full_name(package.full_name)
|
, full_name(package.full_name)
|
||||||
, icon_url(package.icon_filename)
|
, icon_url(package.icon_filename)
|
||||||
|
, dark_icon_url(package.dark_icon_filename)
|
||||||
, installer_group(package.installer_group)
|
, installer_group(package.installer_group)
|
||||||
, position_hint(package.position_hint)
|
, position_hint(package.position_hint)
|
||||||
//, description(package.description)
|
//, description(package.description)
|
||||||
@@ -237,6 +243,7 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(PackageDescription) {
|
|||||||
REFLECT(short_name);
|
REFLECT(short_name);
|
||||||
REFLECT(full_name);
|
REFLECT(full_name);
|
||||||
REFLECT(icon_url);
|
REFLECT(icon_url);
|
||||||
|
REFLECT(dark_icon_url);
|
||||||
REFLECT(installer_group);
|
REFLECT(installer_group);
|
||||||
REFLECT(position_hint);
|
REFLECT(position_hint);
|
||||||
REFLECT(description);
|
REFLECT(description);
|
||||||
|
|||||||
+11
-10
@@ -60,16 +60,17 @@ public:
|
|||||||
PackageDescription();
|
PackageDescription();
|
||||||
PackageDescription(const Packaged& package);
|
PackageDescription(const Packaged& package);
|
||||||
|
|
||||||
String name; ///< Filename of the package
|
String name; ///< Filename of the package
|
||||||
Version version; ///< Version number of this package
|
Version version; ///< Version number of this package
|
||||||
String short_name; ///< Short name of this package
|
String short_name; ///< Short name of this package
|
||||||
String full_name; ///< Name of this package, for menus etc.
|
String full_name; ///< Name of this package, for menus etc.
|
||||||
String icon_url; ///< Filename or URL of icon to use in package lists
|
String icon_url; ///< Filename or URL of icon to use in package lists
|
||||||
Image icon; ///< Icon for the package
|
String dark_icon_url; ///< Filename or URL of icon to use in package lists
|
||||||
String installer_group; ///< Where to put this package in the installer
|
Image icon; ///< Icon for the package
|
||||||
int position_hint; ///< A hint for the package list
|
String installer_group; ///< Where to put this package in the installer
|
||||||
String description; ///< Changelog/description
|
int position_hint; ///< A hint for the package list
|
||||||
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
|
String description; ///< Changelog/description
|
||||||
|
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
|
||||||
|
|
||||||
/// Merge two descriptions a package. This package takes precedence
|
/// Merge two descriptions a package. This package takes precedence
|
||||||
/** Usually one of the descriptions will refer to the locally installed one, the other to the new one */
|
/** Usually one of the descriptions will refer to the locally installed one, the other to the new one */
|
||||||
|
|||||||
+28
-24
@@ -16,23 +16,24 @@ extern ScriptValueP script_primary_choice;
|
|||||||
// ----------------------------------------------------------------------------- : Statistics dimension
|
// ----------------------------------------------------------------------------- : Statistics dimension
|
||||||
|
|
||||||
StatsDimension::StatsDimension()
|
StatsDimension::StatsDimension()
|
||||||
: automatic (false)
|
: automatic (false)
|
||||||
, position_hint(0)
|
, position_hint (0)
|
||||||
, numeric (false)
|
, numeric (false)
|
||||||
, bin_size (0)
|
, bin_size (0)
|
||||||
, show_empty (false)
|
, show_empty (false)
|
||||||
, split_list (false)
|
, split_list (false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
StatsDimension::StatsDimension(const Field& field)
|
StatsDimension::StatsDimension(const Field& field)
|
||||||
: automatic (true)
|
: automatic (true)
|
||||||
, name (field.name)
|
, name (field.name)
|
||||||
, description (field.description)
|
, description (field.description)
|
||||||
, position_hint(field.position_hint)
|
, position_hint (field.position_hint)
|
||||||
, icon_filename(field.icon_filename)
|
, icon_filename (field.icon_filename)
|
||||||
, numeric (false)
|
, dark_icon_filename (field.dark_icon_filename)
|
||||||
, show_empty (false)
|
, numeric (false)
|
||||||
, split_list (false)
|
, show_empty (false)
|
||||||
|
, split_list (false)
|
||||||
{
|
{
|
||||||
// choice field?
|
// choice field?
|
||||||
const ChoiceField* choice_field = dynamic_cast<const ChoiceField*>(&field);
|
const ChoiceField* choice_field = dynamic_cast<const ChoiceField*>(&field);
|
||||||
@@ -67,6 +68,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) {
|
|||||||
REFLECT_LOCALIZED(description);
|
REFLECT_LOCALIZED(description);
|
||||||
REFLECT(position_hint);
|
REFLECT(position_hint);
|
||||||
REFLECT_N("icon", icon_filename);
|
REFLECT_N("icon", icon_filename);
|
||||||
|
REFLECT_N("dark_icon", dark_icon_filename);
|
||||||
REFLECT(script);
|
REFLECT(script);
|
||||||
REFLECT(global_script);
|
REFLECT(global_script);
|
||||||
REFLECT(numeric);
|
REFLECT(numeric);
|
||||||
@@ -81,19 +83,20 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) {
|
|||||||
// ----------------------------------------------------------------------------- : Statistics category
|
// ----------------------------------------------------------------------------- : Statistics category
|
||||||
|
|
||||||
StatsCategory::StatsCategory()
|
StatsCategory::StatsCategory()
|
||||||
: automatic(false)
|
: automatic (false)
|
||||||
, position_hint(0)
|
, position_hint (0)
|
||||||
, type(GRAPH_TYPE_BAR)
|
, type (GRAPH_TYPE_BAR)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
StatsCategory::StatsCategory(const StatsDimensionP& dim)
|
StatsCategory::StatsCategory(const StatsDimensionP& dim)
|
||||||
: automatic(true)
|
: automatic (true)
|
||||||
, name (dim->name)
|
, name (dim->name)
|
||||||
, description (dim->description)
|
, description (dim->description)
|
||||||
, position_hint(dim->position_hint)
|
, position_hint (dim->position_hint)
|
||||||
, icon_filename(dim->icon_filename)
|
, icon_filename (dim->icon_filename)
|
||||||
, dimensions(1, dim)
|
, dark_icon_filename (dim->dark_icon_filename)
|
||||||
, type(GRAPH_TYPE_BAR)
|
, dimensions (1, dim)
|
||||||
|
, type (GRAPH_TYPE_BAR)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) {
|
IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) {
|
||||||
@@ -102,6 +105,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) {
|
|||||||
REFLECT_LOCALIZED(description);
|
REFLECT_LOCALIZED(description);
|
||||||
REFLECT(position_hint);
|
REFLECT(position_hint);
|
||||||
REFLECT_N("icon", icon_filename);
|
REFLECT_N("icon", icon_filename);
|
||||||
|
REFLECT_N("dark_icon", dark_icon_filename);
|
||||||
REFLECT(type);
|
REFLECT(type);
|
||||||
REFLECT_N("dimensions", dimension_names);
|
REFLECT_N("dimensions", dimension_names);
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-23
@@ -27,20 +27,21 @@ public:
|
|||||||
StatsDimension();
|
StatsDimension();
|
||||||
StatsDimension(const Field&);
|
StatsDimension(const Field&);
|
||||||
|
|
||||||
const bool automatic; ///< Based on a card field?
|
const bool automatic; ///< Based on a card field?
|
||||||
String name; ///< Name of this dimension
|
String name; ///< Name of this dimension
|
||||||
LocalizedString description; ///< Description, used in status bar
|
LocalizedString description; ///< Description, used in status bar
|
||||||
int position_hint; ///< Hint for the ordering
|
int position_hint; ///< Hint for the ordering
|
||||||
String icon_filename; ///< Icon for lists
|
String icon_filename; ///< Icon for lists
|
||||||
Bitmap icon; ///< The loaded icon (optional of course)
|
String dark_icon_filename; ///< Icon for lists, if a variant for dark mode is needed
|
||||||
OptionalScript script; ///< Script that determines the value(s), ran on each card
|
Bitmap icon; ///< The loaded icon (optional of course)
|
||||||
OptionalScript global_script; ///< Script that determines the value(s), ran only once at the start
|
OptionalScript script; ///< Script that determines the value(s), ran on each card
|
||||||
bool numeric; ///< Are the values numeric? If so, they require special sorting
|
OptionalScript global_script; ///< Script that determines the value(s), ran only once at the start
|
||||||
double bin_size; ///< Bin adjecent numbers?
|
bool numeric; ///< Are the values numeric? If so, they require special sorting
|
||||||
bool show_empty; ///< Should "" be shown?
|
double bin_size; ///< Bin adjecent numbers?
|
||||||
bool split_list; ///< Split values into multiple ones separated by commas
|
bool show_empty; ///< Should "" be shown?
|
||||||
map<String,Color> colors; ///< Colors for the categories
|
bool split_list; ///< Split values into multiple ones separated by commas
|
||||||
vector<String> groups; ///< Order of the items
|
map<String,Color> colors; ///< Colors for the categories
|
||||||
|
vector<String> groups; ///< Order of the items
|
||||||
|
|
||||||
DECLARE_REFLECTION();
|
DECLARE_REFLECTION();
|
||||||
};
|
};
|
||||||
@@ -54,15 +55,16 @@ public:
|
|||||||
StatsCategory();
|
StatsCategory();
|
||||||
StatsCategory(const StatsDimensionP&);
|
StatsCategory(const StatsDimensionP&);
|
||||||
|
|
||||||
const bool automatic; ///< Automatically generated?
|
const bool automatic; ///< Automatically generated?
|
||||||
String name; ///< Name/label
|
String name; ///< Name/label
|
||||||
LocalizedString description; ///< Description, used in status bar
|
LocalizedString description; ///< Description, used in status bar
|
||||||
int position_hint; ///< Hint for the ordering
|
int position_hint; ///< Hint for the ordering
|
||||||
String icon_filename; ///< Icon for lists
|
String icon_filename; ///< Icon for lists
|
||||||
Bitmap icon; ///< The loaded icon (optional of course)
|
String dark_icon_filename; ///< Icon for lists when a variant for dark mode is needed
|
||||||
vector<String> dimension_names; ///< Names of the dimensions to use
|
Bitmap icon; ///< The loaded icon (optional of course)
|
||||||
vector<StatsDimensionP> dimensions; ///< Actual dimensions
|
vector<String> dimension_names; ///< Names of the dimensions to use
|
||||||
GraphType type; ///< Type of graph to use
|
vector<StatsDimensionP> dimensions; ///< Actual dimensions
|
||||||
|
GraphType type; ///< Type of graph to use
|
||||||
|
|
||||||
/// Initialize dimensions from dimension_names
|
/// Initialize dimensions from dimension_names
|
||||||
void find_dimensions(const vector<StatsDimensionP>& available);
|
void find_dimensions(const vector<StatsDimensionP>& available);
|
||||||
|
|||||||
@@ -159,13 +159,13 @@ public:
|
|||||||
PackageIconRequest(PackageUpdateList* list, PackageUpdateList::TreeItem* ti)
|
PackageIconRequest(PackageUpdateList* list, PackageUpdateList::TreeItem* ti)
|
||||||
: ThumbnailRequest(
|
: ThumbnailRequest(
|
||||||
list,
|
list,
|
||||||
_("package_") + ti->package->description->icon_url + _("_") + ti->package->description->version.toString(),
|
_("package_") + (settings.darkMode() && !ti->package->description->dark_icon_url.empty() ? ti->package->description->dark_icon_url : ti->package->description->icon_url) + _("_") + ti->package->description->version.toString(),
|
||||||
wxDateTime(1,wxDateTime::Jan,2000))
|
wxDateTime(1,wxDateTime::Jan,2000))
|
||||||
, list(list), ti(ti)
|
, list(list), ti(ti)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Image generate() override {
|
Image generate() override {
|
||||||
wxURL url(ti->package->description->icon_url);
|
wxURL url(settings.darkMode() && !ti->package->description->dark_icon_url.empty() ? ti->package->description->dark_icon_url : ti->package->description->icon_url);
|
||||||
unique_ptr<wxInputStream> isP(url.GetInputStream());
|
unique_ptr<wxInputStream> isP(url.GetInputStream());
|
||||||
if (!isP) return wxImage();
|
if (!isP) return wxImage();
|
||||||
SeekAtStartInputStream is2(*isP);
|
SeekAtStartInputStream is2(*isP);
|
||||||
@@ -219,8 +219,9 @@ void PackageUpdateList::initItems() {
|
|||||||
if (p && p->description->icon.Ok()) { // it has an icon
|
if (p && p->description->icon.Ok()) { // it has an icon
|
||||||
ti.setIcon(p->description->icon);
|
ti.setIcon(p->description->icon);
|
||||||
} else if (p) { // it doesn't have an icon (yet)
|
} else if (p) { // it doesn't have an icon (yet)
|
||||||
ti.setIcon(load_resource_image(_("installer_package")));
|
ti.setIcon(load_resource_image(_("installer_package")));
|
||||||
if (!p->description->icon_url.empty()) {
|
String icon_url = settings.darkMode() && !p->description->dark_icon_url.empty() ? p->description->dark_icon_url : p->description->icon_url;
|
||||||
|
if (!icon_url.empty()) {
|
||||||
// download icon
|
// download icon
|
||||||
thumbnail_thread.request(make_intrusive<PackageIconRequest>(this,&ti));
|
thumbnail_thread.request(make_intrusive<PackageIconRequest>(this,&ti));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,13 +228,19 @@ void StatDimensionList::drawItem(DC& dc, int x, int y, size_t item) {
|
|||||||
}
|
}
|
||||||
StatsDimension& dim = *dimensions.at(item - show_empty);
|
StatsDimension& dim = *dimensions.at(item - show_empty);
|
||||||
// draw icon
|
// draw icon
|
||||||
if (!dim.icon_filename.empty() && !dim.icon.Ok()) {
|
if(!dim.icon.Ok()) {
|
||||||
auto file = game->openIn(dim.icon_filename);
|
String filename = dim.icon_filename;
|
||||||
Image img(*file);
|
if (settings.darkMode() && !dim.dark_icon_filename.empty()) {
|
||||||
if (img.HasMask()) img.InitAlpha(); // we can't handle masks
|
filename = dim.dark_icon_filename;
|
||||||
Image resampled(21, 21);
|
}
|
||||||
resample_preserve_aspect(img, resampled);
|
if (!filename.empty()) {
|
||||||
if (img.Ok()) dim.icon = Bitmap(resampled);
|
auto file = game->openIn(filename);
|
||||||
|
Image img(*file);
|
||||||
|
if (img.HasMask()) img.InitAlpha(); // we can't handle masks
|
||||||
|
Image resampled(21, 21);
|
||||||
|
resample_preserve_aspect(img, resampled);
|
||||||
|
if (img.Ok()) dim.icon = Bitmap(resampled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (dim.icon.Ok()) {
|
if (dim.icon.Ok()) {
|
||||||
dc.DrawBitmap(dim.icon, x+1, y+1);
|
dc.DrawBitmap(dim.icon, x+1, y+1);
|
||||||
|
|||||||
+13
-3
@@ -572,6 +572,7 @@ IMPLEMENT_REFLECTION(Packaged) {
|
|||||||
REFLECT(full_name);
|
REFLECT(full_name);
|
||||||
REFLECT(folder_name);
|
REFLECT(folder_name);
|
||||||
REFLECT_N("icon", icon_filename);
|
REFLECT_N("icon", icon_filename);
|
||||||
|
REFLECT_N("dark_icon", dark_icon_filename);
|
||||||
REFLECT_NO_SCRIPT(position_hint);
|
REFLECT_NO_SCRIPT(position_hint);
|
||||||
REFLECT(installer_group);
|
REFLECT(installer_group);
|
||||||
REFLECT(version);
|
REFLECT(version);
|
||||||
@@ -584,9 +585,18 @@ Packaged::Packaged()
|
|||||||
, fully_loaded(true)
|
, fully_loaded(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
unique_ptr<wxInputStream> Packaged::openIconFile() {
|
unique_ptr<wxInputStream> Packaged::openIconFile() {
|
||||||
if (!icon_filename.empty()) {
|
String filename = icon_filename;
|
||||||
return openIn(icon_filename);
|
if (!dark_icon_filename.empty()) {
|
||||||
|
if (settings.darkMode()) {
|
||||||
|
wxFileName fn (dark_icon_filename);
|
||||||
|
String extension = fn.GetExt();
|
||||||
|
filename = dark_icon_filename.Replace(extension, _("")) + "_dark" + extension;
|
||||||
|
}
|
||||||
|
else filename = dark_icon_filename;
|
||||||
|
}
|
||||||
|
if (!filename.empty()) {
|
||||||
|
return openIn(filename);
|
||||||
} else {
|
} else {
|
||||||
return unique_ptr<wxInputStream>();
|
return unique_ptr<wxInputStream>();
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-9
@@ -305,15 +305,16 @@ public:
|
|||||||
Packaged();
|
Packaged();
|
||||||
virtual ~Packaged() {}
|
virtual ~Packaged() {}
|
||||||
|
|
||||||
Version version; ///< Version number of this package
|
Version version; ///< Version number of this package
|
||||||
Version compatible_version; ///< Earliest version number this package is compatible with
|
Version compatible_version; ///< Earliest version number this package is compatible with
|
||||||
String installer_group; ///< Group to place this package in in the installer
|
String installer_group; ///< Group to place this package in in the installer
|
||||||
String short_name; ///< Short name of this package
|
String short_name; ///< Short name of this package
|
||||||
String full_name; ///< Name of this package, for menus etc.
|
String full_name; ///< Name of this package, for menus etc.
|
||||||
String folder_name; ///< Name of the folder this package is loaded from.
|
String folder_name; ///< Name of the folder this package is loaded from.
|
||||||
String icon_filename; ///< Filename of icon to use in package lists
|
String icon_filename; ///< Filename of icon to use in package lists
|
||||||
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
|
String dark_icon_filename; ///< Filename of icon to use in package lists, when a variant for dark mode is needed
|
||||||
int position_hint; ///< A hint for the package list
|
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
|
||||||
|
int position_hint; ///< A hint for the package list
|
||||||
|
|
||||||
/// Get an input stream for the package icon, if there is any
|
/// Get an input stream for the package icon, if there is any
|
||||||
unique_ptr<wxInputStream> openIconFile();
|
unique_ptr<wxInputStream> openIconFile();
|
||||||
|
|||||||
Reference in New Issue
Block a user