Card data in images (start)

* Add uuid implementation

* Simplify uid implementation

* Check for uid conflicts upon adding/copying cards

* Remove unnecessary checks

these are already checked as part of the first loop, since they were added to set.cards

* Implement card linking

* refactor to avoid triple loop

* Start link visualization

* Continue link visualization

* formatting

* add missing locale entries

* improve layout

* improve UI refresh

* copy links when copying cards

* implement second face editor

* refactor using macros

* get references

* pasting multiple cards and links

* start refactoring editors

* continue refactoring editors

* continue refactoring editors again

* finish refactoring editors

* refresh card list on link editor event

* tweak event handling

* Add insert_image script function

* change parameter type

* add script functions to get cards

* add dimensions_of script function

calculate both dimensions simultaneously while rendering the image only once.

* save value even if not editable

* add get_mse_locale script function

* Change zoom scale choices

* bug fixes

* Scale symbol spacing with font size

* sync locales

* standardize line ending

* handle links in new_card

* initial

waiting on wxWidgets 3.3.1

* update comment

* store rect in image filename

* store rect in temp file name

* Update package.cpp

* change line endings
This commit is contained in:
GenevensiS
2025-08-11 16:57:04 +02:00
committed by GitHub
parent 3bf9de18b1
commit 81e9a1e26f
16 changed files with 193 additions and 110 deletions
+20 -2
View File
@@ -113,9 +113,14 @@ Style::Style(const FieldP& field)
, visible(true) , visible(true)
, automatic_side(AUTO_UNKNOWN) , automatic_side(AUTO_UNKNOWN)
, content_dependent(false) , content_dependent(false)
{} {
field->styleP = this;
}
Style::~Style() {} Style::~Style()
{
fieldP->styleP = nullptr;
}
IMPLEMENT_REFLECTION(Style) { IMPLEMENT_REFLECTION(Style) {
REFLECT(z_index); REFLECT(z_index);
@@ -133,6 +138,7 @@ IMPLEMENT_REFLECTION(Style) {
void init_object(const FieldP& field, StyleP& style) { void init_object(const FieldP& field, StyleP& style) {
if (!style) style = field->newStyle(); if (!style) style = field->newStyle();
field->styleP = style;
} }
template <> StyleP read_new<Style>(Reader&) { template <> StyleP read_new<Style>(Reader&) {
throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already")); throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already"));
@@ -262,6 +268,18 @@ void mark_dependency_member(const Style& style, const String& name, const Depend
style.markDependencyMember(name,dep); style.markDependencyMember(name,dep);
} }
String Style::getRect() {
return _("---") +
wxString::Format(wxT("%i"), (int)(left)) +
_("-") +
wxString::Format(wxT("%i"), (int)(top)) +
_("-") +
wxString::Format(wxT("%i"), (int)(width)) +
_("-") +
wxString::Format(wxT("%i"), (int)(height)) +
_("---");
}
// ----------------------------------------------------------------------------- : StyleListener // ----------------------------------------------------------------------------- : StyleListener
void Style::addListener(StyleListener* listener) { void Style::addListener(StyleListener* listener) {
+5 -1
View File
@@ -63,7 +63,8 @@ public:
OptionalScript import_script; ///< The script to apply to the supplied value, when creating a new card. OptionalScript import_script; ///< The script to apply to the supplied value, when creating a new card.
Dependencies dependent_scripts; ///< Scripts that depend on values of this field Dependencies dependent_scripts; ///< Scripts that depend on values of this field
String package_relative_filename; String package_relative_filename;
StyleP styleP; ///< Style for this field, should have the right type! Can be null.
/// Creates a new Value corresponding to this Field /// Creates a new Value corresponding to this Field
virtual ValueP newValue() = 0; virtual ValueP newValue() = 0;
/// Creates a new Style corresponding to this Field /// Creates a new Style corresponding to this Field
@@ -163,6 +164,9 @@ public:
/** change_info is a subset of StyleChange flags */ /** change_info is a subset of StyleChange flags */
void tellListeners(int changes); void tellListeners(int changes);
/// Store where on the card the field goes, to save it in filenames
String getRect();
private: private:
DECLARE_REFLECTION_VIRTUAL(); DECLARE_REFLECTION_VIRTUAL();
/// Things that are listening to changes in this style /// Things that are listening to changes in this style
+6 -5
View File
@@ -71,6 +71,7 @@ CardsDataObject::CardsDataObject(const SetP& set, const vector<CardP>& cards) {
} }
WrappedCards data = { set->game.get(), set->game->name(), cards }; WrappedCards data = { set->game.get(), set->game->name(), cards };
SetText(serialize_for_clipboard(*set, data)); SetText(serialize_for_clipboard(*set, data));
queue_message(MESSAGE_WARNING, GetText());
// restore cards // restore cards
for (size_t i = 0 ; i < cards.size() ; ++i) { for (size_t i = 0 ; i < cards.size() ; ++i) {
if (has_styling[i]) { if (has_styling[i]) {
@@ -140,12 +141,12 @@ KeywordP KeywordDataObject::getKeyword(const SetP& set) {
// ----------------------------------------------------------------------------- : Card on clipboard // ----------------------------------------------------------------------------- : Card on clipboard
CardsOnClipboard::CardsOnClipboard(const SetP& set, const vector<CardP>& cards) { CardsOnClipboard::CardsOnClipboard(const SetP& set, const vector<CardP>& cards) {
// Conversion to text format // Conversion to image format
// TODO
//Add( new TextDataObject(_("card")))
// Conversion to bitmap format
if (cards.size() == 1) { if (cards.size() == 1) {
Add(new wxBitmapDataObject(export_bitmap(set, cards[0]))); Add(new wxImageDataObject(export_image(set, cards[0])));
}
else if (cards.size() < 6) {
Add(new wxImageDataObject(export_image(set, cards, true, 0, 1.0, 0.0)));
} }
else if (cards.size() < 6) { else if (cards.size() < 6) {
Add(new wxBitmapDataObject(export_bitmap(set, cards, true, 0, 1.0, 0.0))); Add(new wxBitmapDataObject(export_bitmap(set, cards, true, 0, 1.0, 0.0)));
+11 -13
View File
@@ -88,20 +88,18 @@ FileFormatP mtg_editor_file_format();
// ----------------------------------------------------------------------------- : Other ways to export // ----------------------------------------------------------------------------- : Other ways to export
/// Export images for each card in a set to a list of files /// Generate a wxBitmap of one or more cards
void export_images(Window* parent, const SetP& set);
/// Export the image for each card in a list of cards
void export_images(const SetP& set, const vector<CardP>& cards,
const String& path, const String& filename_template, FilenameConflicts conflicts);
/// Export the image of a single card
void export_image(const SetP& set, const CardP& card, const String& filename);
/// Generate a bitmap image of a card
Bitmap export_bitmap(const SetP& set, const CardP& card); Bitmap export_bitmap(const SetP& set, const CardP& card);
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians); Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians = 0.0);
Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians); Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians = 0.0);
/// Generate a wxImage of one or more cards
Image export_image(const SetP& set, const CardP& card);
Image export_image(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians = 0.0);
Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians = 0.0);
/// Export the image of a single card to a given filename
void export_image(const SetP& set, const CardP& card, const String& filename);
/// Export a set to Magic Workstation format /// Export a set to Magic Workstation format
void export_mws(Window* parent, const SetP& set); void export_mws(Window* parent, const SetP& set);
+43 -12
View File
@@ -9,6 +9,8 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <util/tagged_string.hpp> #include <util/tagged_string.hpp>
#include <data/format/formats.hpp> #include <data/format/formats.hpp>
#include <data/format/clipboard.hpp>
#include <data/game.hpp>
#include <data/set.hpp> #include <data/set.hpp>
#include <data/card.hpp> #include <data/card.hpp>
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
@@ -17,18 +19,14 @@
#include <render/card/viewer.hpp> #include <render/card/viewer.hpp>
#include <wx/filename.h> #include <wx/filename.h>
// ----------------------------------------------------------------------------- : Single card export #define wxIMAGE_OPTION_PNG_DESCRIPTION wxString("PngDescription")
void export_image(const SetP& set, const CardP& card, const String& filename) { // ----------------------------------------------------------------------------- : Card export
Image img = export_bitmap(set, card).ConvertToImage();
img.SaveFile(filename); // can't use Bitmap::saveFile, it wants to know the file type
// but image.saveFile determines it automagicly
}
class UnzoomedDataViewer : public DataViewer { class UnzoomedDataViewer : public DataViewer {
public: public:
UnzoomedDataViewer(); UnzoomedDataViewer();
UnzoomedDataViewer(double zoom, double angle); UnzoomedDataViewer(double zoom, Radians angle);
virtual ~UnzoomedDataViewer() {}; virtual ~UnzoomedDataViewer() {};
Rotation getRotation() const override; Rotation getRotation() const override;
private: private:
@@ -65,6 +63,8 @@ Rotation UnzoomedDataViewer::getRotation() const {
} }
} }
// ----------------------------------------------------------------------------- : wxBitmap export
Bitmap export_bitmap(const SetP& set, const CardP& card) { Bitmap export_bitmap(const SetP& set, const CardP& card) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
UnzoomedDataViewer viewer = UnzoomedDataViewer(); UnzoomedDataViewer viewer = UnzoomedDataViewer();
@@ -83,9 +83,9 @@ Bitmap export_bitmap(const SetP& set, const CardP& card) {
return bitmap; return bitmap;
} }
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle = 0.0) { Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
UnzoomedDataViewer viewer = UnzoomedDataViewer(zoom, angle); UnzoomedDataViewer viewer = UnzoomedDataViewer(zoom, angle_radians);
viewer.setSet(set); viewer.setSet(set);
viewer.setCard(card); viewer.setCard(card);
// size of cards // size of cards
@@ -102,7 +102,7 @@ Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, cons
} }
// put multiple card images into one bitmap // put multiple card images into one bitmap
Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle = 0.0) { Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
vector<Bitmap> bitmaps; vector<Bitmap> bitmaps;
int width = 0; int width = 0;
@@ -121,7 +121,7 @@ Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_
double dpi = max(set->stylesheetFor(card).card_dpi, 150.0); double dpi = max(set->stylesheetFor(card).card_dpi, 150.0);
scaled_zoom *= lowest_dpi / dpi; scaled_zoom *= lowest_dpi / dpi;
} }
UnzoomedDataViewer viewer = UnzoomedDataViewer(scaled_zoom, angle); UnzoomedDataViewer viewer = UnzoomedDataViewer(scaled_zoom, angle_radians);
viewer.setSet(set); viewer.setSet(set);
viewer.setCard(card); viewer.setCard(card);
RealSize size = viewer.getRotation().getExternalSize(); RealSize size = viewer.getRotation().getExternalSize();
@@ -152,8 +152,39 @@ Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_
return global_bitmap; return global_bitmap;
} }
// ----------------------------------------------------------------------------- : Multiple card export // ----------------------------------------------------------------------------- : wxImage export
Image export_image(const SetP& set, const CardP& card) {
Bitmap bitmap = export_bitmap(set, card);
Image img = bitmap.ConvertToImage();
vector<CardP> cards = { card };
CardsDataObject data(set, cards);
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>"));
return img;
}
Image export_image(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) {
Bitmap bitmap = export_bitmap(set, card, zoom, angle_radians);
Image img = bitmap.ConvertToImage();
vector<CardP> cards = { card };
CardsDataObject data(set, cards);
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>"));
return img;
}
Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians) {
Bitmap bitmap = export_bitmap(set, cards, scale_to_lowest_dpi, padding, zoom, angle_radians);
Image img = bitmap.ConvertToImage();
CardsDataObject data(set, cards);
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>"));
return img;
}
void export_image(const SetP& set, const CardP& card, const String& filename) {
Image img = export_image(set, card);
img.SaveFile(filename); // can't use Bitmap::saveFile, it wants to know the file type
// but image.saveFile determines it automagicly
}
void export_images(const SetP& set, const vector<CardP>& cards, void export_images(const SetP& set, const vector<CardP>& cards,
const String& path, const String& filename_template, FilenameConflicts conflicts) const String& path, const String& filename_template, FilenameConflicts conflicts)
+9 -9
View File
@@ -151,15 +151,15 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(StyleSheetSettings) {
REFLECT(card_draw_editing); REFLECT(card_draw_editing);
REFLECT(card_normal_export); REFLECT(card_normal_export);
REFLECT(card_spellcheck_enabled); REFLECT(card_spellcheck_enabled);
} }
// ----------------------------------------------------------------------------- : Printing settings // ----------------------------------------------------------------------------- : Printing settings
IMPLEMENT_REFLECTION_ENUM(CutterLinesType) { IMPLEMENT_REFLECTION_ENUM(CutterLinesType) {
VALUE_N("all", CUTTER_ALL); VALUE_N("all", CUTTER_ALL);
VALUE_N("no intersect", CUTTER_NO_INTERSECTION); VALUE_N("no intersect", CUTTER_NO_INTERSECTION);
VALUE_N("none", CUTTER_NONE); VALUE_N("none", CUTTER_NONE);
} }
// ----------------------------------------------------------------------------- : Settings // ----------------------------------------------------------------------------- : Settings
@@ -305,7 +305,7 @@ void Settings::read() {
wxFileInputStream file(filename); wxFileInputStream file(filename);
if (!file.Ok()) return; // failure is not an error if (!file.Ok()) return; // failure is not an error
Reader reader(file, nullptr, filename); Reader reader(file, nullptr, filename);
reader.handle_greedy(*this); reader.handle_greedy(*this);
if (locale.Trim().empty()) locale = _("en"); if (locale.Trim().empty()) locale = _("en");
} }
} }
+14
View File
@@ -18,6 +18,7 @@
#include <data/card.hpp> #include <data/card.hpp>
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
#include <data/action/set.hpp> #include <data/action/set.hpp>
#include <data/format/formats.hpp>
#include <gui/add_json_window.hpp> #include <gui/add_json_window.hpp>
#include <script/functions/json.hpp> #include <script/functions/json.hpp>
#include <script/functions/construction_helper.hpp> #include <script/functions/construction_helper.hpp>
@@ -171,6 +172,19 @@ void AddJSONWindow::onBrowseFiles(wxCommandEvent&) {
} }
void AddJSONWindow::onOk(wxCommandEvent&) { void AddJSONWindow::onOk(wxCommandEvent&) {
// debug test shit
export_image(set, set->cards.front(), "C:\\Users\\Oli\\Desktop\\tetest\\test.png");
auto extImg = make_intrusive<ExternalImage>("C:/Users/Oli/Desktop/tetest/test.png");
Image img = extImg->generate(GeneratedImage::Options(0, 0, set->stylesheet.get(), set.get()));
if (img.HasOption(wxIMAGE_OPTION_FILENAME)) queue_message(MESSAGE_ERROR, img.GetOption(wxIMAGE_OPTION_FILENAME));
else queue_message(MESSAGE_ERROR, _("no dice"));
return;
/// Perform the import /// Perform the import
wxBusyCursor wait; wxBusyCursor wait;
// Read the file // Read the file
+50 -50
View File
@@ -15,8 +15,8 @@
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#include <wx/dcbuffer.h> #include <wx/dcbuffer.h>
map<String, String> ImageSliceWindow::previously_used_settings_path; map<String, String> ImageSliceWindow::previously_used_settings_path;
map<pair<String, String>, pair<wxRect, int>> ImageSliceWindow::previously_used_settings_value; map<pair<String, String>, pair<wxRect, int>> ImageSliceWindow::previously_used_settings_value;
// ----------------------------------------------------------------------------- : ImageSlice // ----------------------------------------------------------------------------- : ImageSlice
@@ -101,15 +101,15 @@ ImageSliceWindow::ImageSliceWindow(Window* parent, const Image& source, const St
, slice(source, filename, cardname, target_size) , slice(source, filename, cardname, target_size)
, initialized(false) , initialized(false)
{ {
// init slice // init slice
pair<String, String> settings_entry = { filename, cardname }; pair<String, String> settings_entry = { filename, cardname };
if (previously_used_settings_value.find(settings_entry) != previously_used_settings_value.end()) { if (previously_used_settings_value.find(settings_entry) != previously_used_settings_value.end()) {
//slice.allow_outside = true; this currrently crashes //slice.allow_outside = true; this currrently crashes
slice.aspect_fixed = false; slice.aspect_fixed = false;
slice.sharpen = true; slice.sharpen = true;
slice.sharpen_amount = previously_used_settings_value[settings_entry].second; slice.sharpen_amount = previously_used_settings_value[settings_entry].second;
slice.selection = previously_used_settings_value[settings_entry].first; slice.selection = previously_used_settings_value[settings_entry].first;
slice.constrain(); slice.constrain();
} }
else { else {
slice.constrain(); slice.constrain();
@@ -149,7 +149,7 @@ ImageSliceWindow::ImageSliceWindow(Window* parent, const Image& source, const St
sharpen_amount = new wxSlider(this, ID_SHARPEN_AMOUNT, 0, 0, 100); sharpen_amount = new wxSlider(this, ID_SHARPEN_AMOUNT, 0, 0, 100);
// allowOutside= new CheckBox(&this, idSliceAllowOutside, _("Allow selection outside source")) // allowOutside= new CheckBox(&this, idSliceAllowOutside, _("Allow selection outside source"))
// bgColor = new ColorSelector(&this, wxID_ANY) // bgColor = new ColorSelector(&this, wxID_ANY)
String grids[] = { _LABEL_("none") String grids[] = { _LABEL_("none")
, _LABEL_("grid halves") , _LABEL_("grid halves")
, _LABEL_("grid thirds") , _LABEL_("grid thirds")
@@ -242,8 +242,8 @@ void ImageSliceWindow::onOk(wxCommandEvent&) {
EndModal(wxID_OK); EndModal(wxID_OK);
} }
Image ImageSliceWindow::getImage(double scale) const { Image ImageSliceWindow::getImage(double scale) const {
Image img = slice.getSlice(scale); Image img = slice.getSlice(scale);
previously_used_settings_path[slice.card_name] = slice.source_path; previously_used_settings_path[slice.card_name] = slice.source_path;
previously_used_settings_value[{ slice.source_path, slice.card_name }] = { slice.selection, slice.sharpen_amount }; previously_used_settings_value[{ slice.source_path, slice.card_name }] = { slice.selection, slice.sharpen_amount };
return img; return img;
@@ -275,13 +275,13 @@ void ImageSliceWindow::onChangeSize(wxCommandEvent&) {
slice.aspect_fixed = false; slice.aspect_fixed = false;
onUpdateFromControl(); onUpdateFromControl();
} }
} }
void ImageSliceWindow::onChangeGrid(wxCommandEvent&) { void ImageSliceWindow::onChangeGrid(wxCommandEvent&) {
if (!initialized) return; if (!initialized) return;
preview->grid = grid->GetSelection(); preview->grid = grid->GetSelection();
preview->update(); preview->update();
} }
void ImageSliceWindow::onChangeLeft(wxCommandEvent&) { void ImageSliceWindow::onChangeLeft(wxCommandEvent&) {
if (!initialized) return; if (!initialized) return;
@@ -502,39 +502,39 @@ void ImageSlicePreview::draw(DC& dc) {
bitmap = wxBitmap(bitmap.ConvertToImage().Scale(available_size.GetWidth(), available_size.GetHeight())); bitmap = wxBitmap(bitmap.ConvertToImage().Scale(available_size.GetWidth(), available_size.GetHeight()));
} }
if (bitmap.Ok()) { if (bitmap.Ok()) {
dc.DrawBitmap(bitmap, 0, 0); dc.DrawBitmap(bitmap, 0, 0);
if (grid == 1) { if (grid == 1) {
wxSize size = dc.GetSize(); wxSize size = dc.GetSize();
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.DrawLine(size.x * 1 / 2, 0, size.x * 1 / 2, size.y); dc.DrawLine(size.x * 1 / 2, 0, size.x * 1 / 2, size.y);
dc.DrawLine(0, size.y * 1 / 2, size.x, size.y * 1 / 2); dc.DrawLine(0, size.y * 1 / 2, size.x, size.y * 1 / 2);
} else if (grid == 2) { } else if (grid == 2) {
wxSize size = dc.GetSize(); wxSize size = dc.GetSize();
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.DrawLine(size.x * 1 / 3, 0, size.x * 1 / 3, size.y); dc.DrawLine(size.x * 1 / 3, 0, size.x * 1 / 3, size.y);
dc.DrawLine(size.x * 2 / 3, 0, size.x * 2 / 3, size.y); dc.DrawLine(size.x * 2 / 3, 0, size.x * 2 / 3, size.y);
dc.DrawLine(0, size.y * 1 / 3, size.x, size.y * 1 / 3); dc.DrawLine(0, size.y * 1 / 3, size.x, size.y * 1 / 3);
dc.DrawLine(0, size.y * 2 / 3, size.x, size.y * 2 / 3); dc.DrawLine(0, size.y * 2 / 3, size.x, size.y * 2 / 3);
} else if (grid == 3) { } else if (grid == 3) {
wxSize size = dc.GetSize(); wxSize size = dc.GetSize();
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.DrawLine(size.x * 1 / 4, 0, size.x * 1 / 4, size.y); dc.DrawLine(size.x * 1 / 4, 0, size.x * 1 / 4, size.y);
dc.DrawLine(size.x * 2 / 4, 0, size.x * 2 / 4, size.y); dc.DrawLine(size.x * 2 / 4, 0, size.x * 2 / 4, size.y);
dc.DrawLine(size.x * 3 / 4, 0, size.x * 3 / 4, size.y); dc.DrawLine(size.x * 3 / 4, 0, size.x * 3 / 4, size.y);
dc.DrawLine(0, size.y * 1 / 4, size.x, size.y * 1 / 4); dc.DrawLine(0, size.y * 1 / 4, size.x, size.y * 1 / 4);
dc.DrawLine(0, size.y * 2 / 4, size.x, size.y * 2 / 4); dc.DrawLine(0, size.y * 2 / 4, size.x, size.y * 2 / 4);
dc.DrawLine(0, size.y * 3 / 4, size.x, size.y * 3 / 4); dc.DrawLine(0, size.y * 3 / 4, size.x, size.y * 3 / 4);
} else if (grid == 4) { } else if (grid == 4) {
wxSize size = dc.GetSize(); wxSize size = dc.GetSize();
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.DrawLine(size.x * 1 / 5, 0, size.x * 1 / 5, size.y); dc.DrawLine(size.x * 1 / 5, 0, size.x * 1 / 5, size.y);
dc.DrawLine(size.x * 2 / 5, 0, size.x * 2 / 5, size.y); dc.DrawLine(size.x * 2 / 5, 0, size.x * 2 / 5, size.y);
dc.DrawLine(size.x * 3 / 5, 0, size.x * 3 / 5, size.y); dc.DrawLine(size.x * 3 / 5, 0, size.x * 3 / 5, size.y);
dc.DrawLine(size.x * 4 / 5, 0, size.x * 4 / 5, size.y); dc.DrawLine(size.x * 4 / 5, 0, size.x * 4 / 5, size.y);
dc.DrawLine(0, size.y * 1 / 5, size.x, size.y * 1 / 5); dc.DrawLine(0, size.y * 1 / 5, size.x, size.y * 1 / 5);
dc.DrawLine(0, size.y * 2 / 5, size.x, size.y * 2 / 5); dc.DrawLine(0, size.y * 2 / 5, size.x, size.y * 2 / 5);
dc.DrawLine(0, size.y * 3 / 5, size.x, size.y * 3 / 5); dc.DrawLine(0, size.y * 3 / 5, size.x, size.y * 3 / 5);
dc.DrawLine(0, size.y * 4 / 5, size.x, size.y * 4 / 5); dc.DrawLine(0, size.y * 4 / 5, size.x, size.y * 4 / 5);
} }
} }
} }
+1 -1
View File
@@ -98,7 +98,7 @@ private:
wxButton* link_unlink_1, *link_unlink_2, *link_unlink_3, *link_unlink_4, *link_select; wxButton* link_unlink_1, *link_unlink_2, *link_unlink_3, *link_unlink_4, *link_select;
HoverButton* collapse_notes; HoverButton* collapse_notes;
FilterCtrl* filter; FilterCtrl* filter;
String filter_value; // value of filter, need separate variable because the control is destroyed String filter_value; // value of filter, need separate variable because the control is destroyed
wxStaticText* counts; wxStaticText* counts;
bool notes_below_editor; bool notes_below_editor;
+12 -9
View File
@@ -20,18 +20,18 @@
IMPLEMENT_VALUE_EDITOR(Image) {} IMPLEMENT_VALUE_EDITOR(Image) {}
bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) { bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) {
String directory = settings.default_image_dir; String directory = settings.default_image_dir;
String filename = _(""); String filename = _("");
CardP card = parent.getCard(); CardP card = parent.getCard();
String cardname = card ? card->identification() : _("clipboard"); String cardname = card ? card->identification() : _("clipboard");
if (ImageSliceWindow::previously_used_settings_path.find(cardname) != ImageSliceWindow::previously_used_settings_path.end()) { if (ImageSliceWindow::previously_used_settings_path.find(cardname) != ImageSliceWindow::previously_used_settings_path.end()) {
String filepath = ImageSliceWindow::previously_used_settings_path[cardname]; String filepath = ImageSliceWindow::previously_used_settings_path[cardname];
size_t pos = filepath.rfind(wxFileName::GetPathSeparator()); size_t pos = filepath.rfind(wxFileName::GetPathSeparator());
if (pos != String::npos) { if (pos != String::npos) {
directory = filepath.substr(0, pos+1); directory = filepath.substr(0, pos+1);
filename = filepath.substr(pos+1); filename = filepath.substr(pos+1);
} }
} }
filename = wxFileSelector(_("Open image file"), directory, filename, _(""), filename = wxFileSelector(_("Open image file"), directory, filename, _(""),
_("All images|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.tif;*.tiff|Windows bitmaps (*.bmp)|*.bmp|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif;*.tiff)|*.tif;*.tiff"), _("All images|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.tif;*.tiff|Windows bitmaps (*.bmp)|*.bmp|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif;*.tiff)|*.tif;*.tiff"),
wxFD_OPEN, wxGetTopLevelParent(&editor())); wxFD_OPEN, wxGetTopLevelParent(&editor()));
@@ -53,12 +53,15 @@ void ImageValueEditor::sliceImage(const Image& image, const String& filename, co
GeneratedImage::Options options((int)style().width, (int)style().height, &parent.getStylePackage(), &parent.getLocalPackage()); GeneratedImage::Options options((int)style().width, (int)style().height, &parent.getStylePackage(), &parent.getLocalPackage());
AlphaMask mask; AlphaMask mask;
style().mask.getNoCache(options,mask); style().mask.getNoCache(options,mask);
// slice // slice
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, filename, cardname, style().getSize(), mask); ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, filename, cardname, style().getSize(), mask);
// clicked ok? // clicked ok?
if (s.ShowModal() == wxID_OK) { if (s.ShowModal() == wxID_OK) {
// store the image into the set // store the image into the set
LocalFileName new_image_file = getLocalPackage().newFileName(field().name, settings.internal_image_extension ? _(".png") : _("")); // a new unique name in the package StyleP style = field().styleP;
String rect = style ? style->getRect() : _("");
String extension = settings.internal_image_extension ? _(".png") : _("");
LocalFileName new_image_file = getLocalPackage().newFileName(field().name, rect + extension); // a new unique name in the package
// Specify a desired size based on the stylesheet and a scale multiplier defined within the user's settings. // 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. // Storing at a greater than 100% resolution allows for better exports >100%, but may change how images look when filters (sharpen) are applied.
+1 -1
View File
@@ -435,7 +435,7 @@ SCRIPT_FUNCTION(write_image_file) {
Image image; Image image;
GeneratedImage::Options options(width, height, ei.export_template.get(), ei.set.get()); GeneratedImage::Options options(width, height, ei.export_template.get(), ei.set.get());
if (card) { if (card) {
image = conform_image(export_bitmap(ei.set, card->getValue()).ConvertToImage(), options); image = conform_image(export_image(ei.set, card->getValue()), options);
} else { } else {
image = input->toImage()->generateConform(options); image = input->toImage()->generateConform(options);
} }
+2 -2
View File
@@ -38,10 +38,10 @@ SCRIPT_FUNCTION(to_card_image) {
SCRIPT_PARAM_DEFAULT(bool, use_user_settings, false); SCRIPT_PARAM_DEFAULT(bool, use_user_settings, false);
if (use_user_settings) { if (use_user_settings) {
// Use the User's Preferences for Export Zoom and Angle settings. // Use the User's Preferences for Export Zoom and Angle settings.
return make_intrusive<ArbitraryImage>(export_bitmap(set, input).ConvertToImage()); return make_intrusive<ArbitraryImage>(export_image(set, input));
} else { } else {
// Use the provided (or defaulted) Zoom and Angle. // Use the provided (or defaulted) Zoom and Angle.
return make_intrusive<ArbitraryImage>(export_bitmap(set, input, (zoom / 100), deg_to_rad(angle)).ConvertToImage()); return make_intrusive<ArbitraryImage>(export_image(set, input, (zoom / 100), deg_to_rad(angle)));
} }
} }
+7 -2
View File
@@ -272,6 +272,11 @@ String Package::nameOut(const String& file) {
} else { } else {
// create temp file // create temp file
String name = wxFileName::CreateTempFileName(_("mse")); String name = wxFileName::CreateTempFileName(_("mse"));
String rect = LocalFileName::getRect(file);
if (!rect.empty()) {
if (name.Contains(".")) name = name.BeforeLast('.') + rect + _(".") + name.AfterLast('.');
else name = name + rect;
}
it->second.tempName = name; it->second.tempName = name;
return name; return name;
} }
@@ -361,7 +366,7 @@ LocalFileName LocalFileName::fromReadString(String const& fn, String const& pref
if (!fn.empty() && clipboard_package()) { if (!fn.empty() && clipboard_package()) {
// copy file into current package // copy file into current package
try { try {
LocalFileName local_name = clipboard_package()->newFileName(_("image"),_("")); // a new unique name in the package, assume it's an image LocalFileName local_name = clipboard_package()->newFileName(_("image"), getRect(fn)); // a new unique name in the package, assume it's an image
auto out_stream = clipboard_package()->openOut(local_name); auto out_stream = clipboard_package()->openOut(local_name);
auto in_stream = Package::openAbsoluteFile(fn); auto in_stream = Package::openAbsoluteFile(fn);
out_stream->Write(*in_stream); // copy out_stream->Write(*in_stream); // copy
@@ -657,7 +662,7 @@ void Packaged::validate(Version) {
if (short_name.empty()) { if (short_name.empty()) {
if (!full_name.empty()) short_name = full_name; if (!full_name.empty()) short_name = full_name;
else short_name = folder_name; else short_name = folder_name;
} }
// check dependencies // check dependencies
FOR_EACH(dep, dependencies) { FOR_EACH(dep, dependencies) {
package_manager.checkDependency(*dep, true); package_manager.checkDependency(*dep, true);
+9
View File
@@ -53,6 +53,15 @@ public:
inline String const& toStringForKey() const { return fn; } inline String const& toStringForKey() const { return fn; }
/// Retreive a rect from a filename
static String getRect(const String& file) {
size_t first = file.find(_("---"));
if (first == String::npos) return _("");
size_t last = file.find(_("---"), first+3);
if (first == last) return _("");
return file.substr(first, last + 3 - first);
}
private: private:
LocalFileName(const wxString& fn) : fn(fn) {} LocalFileName(const wxString& fn) : fn(fn) {}
String fn; String fn;
+2 -2
View File
@@ -89,9 +89,9 @@ String tr(const String&, const String& subcat, const String& key, DefaultLocaleF
#define _HELP_1_(s,a) format_string(_HELP_(s), a) #define _HELP_1_(s,a) format_string(_HELP_(s), a)
/// A localized string for tooltip labels, with 1 argument (printf style) /// A localized string for tooltip labels, with 1 argument (printf style)
#define _TOOL_1_(s,a) format_string(_TOOL_(s), a) #define _TOOL_1_(s,a) format_string(_TOOL_(s), a)
/// A localized string for tooltip labels, with 2 argument (printf style) /// A localized string for tooltip labels, with 2 argument (printf style)
#define _TOOL_2_(s,a,b) format_string(_TOOL_(s), a, b) #define _TOOL_2_(s,a,b) format_string(_TOOL_(s), a, b)
/// A localized string for tooltip labels, with 3 argument (printf style) /// A localized string for tooltip labels, with 3 argument (printf style)
#define _TOOL_3_(s,a,b,c) format_string(_TOOL_(s), a, b, c) #define _TOOL_3_(s,a,b,c) format_string(_TOOL_(s), a, b, c)
+1 -1
View File
@@ -39,4 +39,4 @@ Additional tools (not needed for building MSE) also depend on:
- <a href="http://doxygen.org">doxygen</a> for generating the documentation. - <a href="http://doxygen.org">doxygen</a> for generating the documentation.
- Perl for small utility scripts - Perl for small utility scripts
*/ */