diff --git a/data/en.mse-locale/locale b/data/en.mse-locale/locale index cf3f8a41..a6f895f3 100644 --- a/data/en.mse-locale/locale +++ b/data/en.mse-locale/locale @@ -485,14 +485,20 @@ label: # Preferences language : Language windows : Open sets - app language : Language of the user interface : - card display : Card Display - zoom : &Zoom : - export : &Export : + app language : Language of the user interface : + card display : Card Display + storage : Storage + zoom : &Zoom: + export : &Export: + scale : &Internal Scale: percent of normal: % of normal size external programs: External programs apprentice: &Apprentice: - apprentice exe: Apprentice Executable + apprentice exe: Apprentice Executable + internal scale desc: + Scale to internally store card images at. + Changing this may impact how Sharpening looks. + Does not retroactively apply to existing images. check at startup: Check for new versions at startup checking requires internet: Checking for updates requires an internet connection. @@ -521,8 +527,8 @@ label: html export options:Export options # Image slicer - original: Original: - result: Result: + original: Original (%s x %s): + result: Result (%s x %s): size: Size original size: &Original Size size to fit: Size to &Fit @@ -613,7 +619,8 @@ button: check now: Check &Now always: Always if internet connection exists: If internet connection exists - never: Never + never: Never + internal image extension: Store images internally with extension # Column select move up: Move &Up @@ -675,7 +682,8 @@ title: preferences: Preferences global: Global display: Display - directories: Directories + directories: Directories + internal: Internal updates: Updates update check: Update Check locate apprentice: Locate Apprentice diff --git a/src/data/settings.cpp b/src/data/settings.cpp index 4089c0df..12aeebae 100644 --- a/src/data/settings.cpp +++ b/src/data/settings.cpp @@ -171,7 +171,9 @@ Settings::Settings() , symbol_grid_size (30) , symbol_grid (true) , symbol_grid_snap (false) - , print_layout (LAYOUT_NO_SPACE) + , print_layout (LAYOUT_NO_SPACE) + , internal_scale (1.0) + , internal_image_extension(true) #if USE_OLD_STYLE_UPDATE_CHECKER , updates_url (_("http://magicseteditor.sourceforge.net/updates")) #endif @@ -257,7 +259,9 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(Settings) { REFLECT(symbol_grid_snap); REFLECT(default_game); REFLECT(print_layout); - REFLECT(apprentice_location); + REFLECT(apprentice_location); + REFLECT(internal_scale); + REFLECT(internal_image_extension); #if USE_OLD_STYLE_UPDATE_CHECKER REFLECT(updates_url); #else diff --git a/src/data/settings.hpp b/src/data/settings.hpp index fcb3d340..7d022df0 100644 --- a/src/data/settings.hpp +++ b/src/data/settings.hpp @@ -192,7 +192,11 @@ public: // --------------------------------------------------- : Special game stuff String apprentice_location; - + + // --------------------------------------------------- : Internal settings + double internal_scale; + bool internal_image_extension; + // --------------------------------------------------- : Update checking #if USE_OLD_STYLE_UPDATE_CHECKER String updates_url; diff --git a/src/gui/image_slice_window.cpp b/src/gui/image_slice_window.cpp index 9509bf8d..8e4e4636 100644 --- a/src/gui/image_slice_window.cpp +++ b/src/gui/image_slice_window.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include // ----------------------------------------------------------------------------- : ImageSlice @@ -133,11 +133,11 @@ ImageSliceWindow::ImageSliceWindow(Window* parent, const Image& source, const wx // top row: image editors wxSizer* s2 = new wxBoxSizer(wxHORIZONTAL); wxSizer* s3 = new wxBoxSizer(wxVERTICAL); - s3->Add(new wxStaticText(this, wxID_ANY, _LABEL_("original"))); + s3->Add(new wxStaticText(this, wxID_ANY, _LABEL_2_("original", to_string(slice.source.GetWidth()), to_string(slice.source.GetHeight())))); s3->Add(selector, 1, wxEXPAND | wxTOP, 4); s2->Add(s3, 1, wxEXPAND | wxALL, 4); wxSizer* s4 = new wxBoxSizer(wxVERTICAL); - s4->Add(new wxStaticText(this, wxID_ANY, _LABEL_("result"))); + s4->Add(new wxStaticText(this, wxID_ANY, _LABEL_2_("result", to_string(slice.target_size.GetWidth()), to_string(slice.target_size.GetHeight())))); s4->Add(preview, 0, wxTOP, 4); s2->Add(s4, 0, wxALL, 4); s->Add(s2, 1, wxEXPAND); @@ -388,8 +388,14 @@ void ImageSlicePreview::update() { wxSize ImageSlicePreview::DoGetBestSize() const { // We know the client size we want, calculate the size that goes with that - wxSize ws = GetSize(), cs = GetClientSize(); - return slice.target_size + ws - cs; + wxSize ws = GetSize(), cs = GetClientSize(); + + float target_ratio = ((float)slice.target_size.GetWidth()) / ((float)slice.target_size.GetHeight()); + if (target_ratio > 1.0) { + return wxSize(500, 500 / target_ratio); + } else { + return wxSize(500 * target_ratio, 500); + } } void ImageSlicePreview::onPaint(wxPaintEvent&) { @@ -413,7 +419,11 @@ void ImageSlicePreview::draw(DC& dc) { mdc.SelectObject(wxNullBitmap); } else { bitmap = Bitmap(image); - } + } + + // Rescale the bitmap based on the available size. + auto available_size = DoGetBestSize(); + bitmap = wxBitmap(bitmap.ConvertToImage().Scale(available_size.GetWidth(), available_size.GetHeight())); } if (bitmap.Ok()) { dc.DrawBitmap(bitmap, 0, 0); @@ -467,8 +477,14 @@ ImageSliceSelector::ImageSliceSelector(Window* parent, int id, ImageSlice& slice : wxControl(parent, id, wxDefaultPosition, wxDefaultSize, wxBORDER_THEME) , slice(slice) , mouse_down(false) -{ - SetMinSize(wxSize(400, 300)); +{ + + float target_ratio = ((float) slice.source.GetWidth()) / ((float) slice.source.GetHeight()); + if (target_ratio > 1.0) { + SetMinSize(wxSize(500, 500 / target_ratio)); + } else { + SetMinSize(wxSize(500 * target_ratio, 500)); + } SetBackgroundStyle(wxBG_STYLE_PAINT); } diff --git a/src/gui/preferences_window.cpp b/src/gui/preferences_window.cpp index 96d255c5..6065e69d 100644 --- a/src/gui/preferences_window.cpp +++ b/src/gui/preferences_window.cpp @@ -65,6 +65,23 @@ private: void updateZoom(); void onExportZoomChange(wxCommandEvent&); void updateExportZoom(); +}; + +class InternalPreferencesPage : public PreferencesPage { +public: + InternalPreferencesPage(Window* parent); + void store() override; + +private: + DECLARE_EVENT_TABLE(); + + wxCheckBox* internal_image_extension; + + wxComboBox* internal_scale; + int internal_scale_int; + + void onInternalScaleChange(wxCommandEvent&); + void updateInternalScale(); }; // Preferences page for directories of programs @@ -107,7 +124,8 @@ PreferencesWindow::PreferencesWindow(Window* parent) // init notebook wxNotebook* nb = new wxNotebook(this, ID_NOTEBOOK); nb->AddPage(new GlobalPreferencesPage (nb), _TITLE_("global")); - nb->AddPage(new DisplayPreferencesPage(nb), _TITLE_("display")); + nb->AddPage(new DisplayPreferencesPage(nb), _TITLE_("display")); + nb->AddPage(new InternalPreferencesPage(nb), _TITLE_("internal")); nb->AddPage(new DirsPreferencesPage (nb), _TITLE_("directories")); nb->AddPage(new UpdatePreferencesPage (nb), _TITLE_("updates")); @@ -184,7 +202,7 @@ void GlobalPreferencesPage::store() { // set the_locale? // open_sets_in_new_window settings.open_sets_in_new_window = open_sets_in_new_window->GetValue(); -} +} // ----------------------------------------------------------------------------- : Preferences page : display @@ -293,7 +311,61 @@ BEGIN_EVENT_TABLE(DisplayPreferencesPage, wxPanel) EVT_COMBOBOX(ID_EXPORT_ZOOM, DisplayPreferencesPage::onExportZoomChange) EVT_TEXT_ENTER(ID_EXPORT_ZOOM, DisplayPreferencesPage::onExportZoomChange) END_EVENT_TABLE () + +// ----------------------------------------------------------------------------- : Preferences page : internal + +InternalPreferencesPage::InternalPreferencesPage(Window* parent) : PreferencesPage(parent) { + internal_image_extension = new wxCheckBox(this, wxID_ANY, _BUTTON_("internal image extension")); + internal_scale = new wxComboBox(this, ID_INTERNAL_SCALE); + + internal_image_extension->SetValue(settings.internal_image_extension); + + internal_scale_int = static_cast(settings.internal_scale * 100); + internal_scale->SetValue(String::Format(_("%d%%"), internal_scale_int)); + + int choices[] = { 100,200 }; + for (unsigned int i = 0; i < sizeof(choices) / sizeof(choices[0]); ++i) { + internal_scale->Append(String::Format(_("%d%%"), choices[i])); + } + + wxSizer* s = new wxBoxSizer(wxVERTICAL); + wxSizer* s2 = new wxStaticBoxSizer(wxVERTICAL, this, _LABEL_("storage")); + wxSizer* s3 = new wxBoxSizer(wxHORIZONTAL); + s3->Add(new wxStaticText(this, wxID_ANY, _LABEL_("scale")), 0, wxALL & ~wxLEFT, 4); + s3->AddSpacer(2); + s3->Add(internal_scale); + s3->Add(new wxStaticText(this, wxID_ANY, _LABEL_("percent of normal")), 1, wxALL & ~wxRIGHT, 4); + s2->Add(s3); + s2->Add(new wxStaticText(this, wxID_ANY, _LABEL_("internal scale desc")), 0, wxALL & ~wxLEFT, 4); + s2->Add(internal_image_extension, 0, wxEXPAND | wxALL, 4); + s->Add(s2, 0, wxEXPAND | wxALL, 8); + s->SetSizeHints(this); + SetSizer(s); +} + +void InternalPreferencesPage::store() { + settings.internal_image_extension = internal_image_extension->GetValue(); + + updateInternalScale(); + settings.internal_scale = internal_scale_int / 100.0; +} + +void InternalPreferencesPage::onInternalScaleChange(wxCommandEvent&) { + updateInternalScale(); +} +void InternalPreferencesPage::updateInternalScale() { + String s = internal_scale->GetValue(); + int i = internal_scale_int; + if (wxSscanf(s.c_str(), _("%u"), &i)) { + internal_scale_int = min(max(i, 1), 1000); + } + internal_scale->SetValue(String::Format(_("%d%%"), (int)internal_scale_int)); +} + +BEGIN_EVENT_TABLE(InternalPreferencesPage, wxPanel) + EVT_COMBOBOX(ID_INTERNAL_SCALE, InternalPreferencesPage::onInternalScaleChange) +END_EVENT_TABLE() // ----------------------------------------------------------------------------- : Preferences page : directories diff --git a/src/gui/value/image.cpp b/src/gui/value/image.cpp index 9e32eaf2..2ba17163 100644 --- a/src/gui/value/image.cpp +++ b/src/gui/value/image.cpp @@ -40,12 +40,16 @@ void ImageValueEditor::sliceImage(const Image& image) { GeneratedImage::Options options((int)style().width, (int)style().height, &parent.getStylePackage(), &parent.getLocalPackage()); AlphaMask mask; style().mask.getNoCache(options,mask); - // slice - ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, style().getSize(), mask); + // slice + // Specify a desired size based on the stylesheet and a scale multiplier defined within the user's settings. + // Storing at a greater than 100% resolution allows for better exports >100%, but may change how images look when filters (sharpen) are applied. + // Additionally, this bloats the set file size as even under-resolution images are upscaled to the new minimum size. + RealSize desired_slice_size = RealSize(style().getSize().width * settings.internal_scale, style().getSize().height * settings.internal_scale); + ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, desired_slice_size, mask); // clicked ok? if (s.ShowModal() == wxID_OK) { // store the image into the set - LocalFileName new_image_file = getLocalPackage().newFileName(field().name,_(".png")); // a new unique name in the package + LocalFileName new_image_file = getLocalPackage().newFileName(field().name, settings.internal_image_extension ? _(".png") : _("")); // a new unique name in the package Image img = s.getImage(); img.SaveFile(getLocalPackage().nameOut(new_image_file), wxBITMAP_TYPE_PNG); // always use PNG images, see #69. Disk space is cheap anyway. addAction(value_action(valueP(), new_image_file)); diff --git a/src/util/locale.hpp b/src/util/locale.hpp index b6eae98a..8009cda4 100644 --- a/src/util/locale.hpp +++ b/src/util/locale.hpp @@ -87,7 +87,11 @@ String tr(const Package&, const String& subcat, const String& key, DefaultLocale #define _TOOLTIP_1_(s,a) format_string(_TOOLTIP_(s), a) /// A localized string for tooltip labels, with 1 argument (printf style) -#define _LABEL_1_(s,a) format_string(_LABEL_(s), a) +#define _LABEL_1_(s,a) format_string(_LABEL_(s), a) +/// A localized string for tooltip labels, with 2 argument (printf style) +#define _LABEL_2_(s,a,b) format_string(_LABEL_(s), a, b) +/// A localized string for tooltip labels, with 3 argument (printf style) +#define _LABEL_3_(s,a,b,c) format_string(_LABEL_(s), a, b, c) /// A localized string for button text, with 1 argument (printf style) #define _BUTTON_1_(s,a) format_string(_BUTTON_(s), a) diff --git a/src/util/window_id.hpp b/src/util/window_id.hpp index 2ec455f4..568046be 100644 --- a/src/util/window_id.hpp +++ b/src/util/window_id.hpp @@ -281,7 +281,9 @@ enum ControlID { ID_EXPORT_ZOOM_X, ID_EXPORT_ZOOM_Y, ID_SHARPEN, - ID_SHARPEN_AMOUNT, + ID_SHARPEN_AMOUNT, + // Internal window + ID_INTERNAL_SCALE, // Updates window ID_PACKAGE_LIST, ID_KEEP,