mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
convert to CRLF line endings
This commit is contained in:
@@ -212,7 +212,7 @@ String ChangeCardHasStylingAction::getName(bool to_undo) const {
|
||||
void ChangeCardHasStylingAction::perform(bool to_undo) {
|
||||
card->has_styling = !card->has_styling;
|
||||
swap(card->styling_data, styling_data);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Change notes
|
||||
|
||||
@@ -239,7 +239,7 @@ void ChangeCardUIDAction::perform(bool to_undo) {
|
||||
c->updateLink(card->uid, uid);
|
||||
}
|
||||
swap(card->uid, uid);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Pack types
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
Set& set; ///< The set to copy styling from
|
||||
CardP card; ///< The affected card
|
||||
IndexMap<FieldP,ValueP> styling_data; ///< The old styling of the card
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Change notes
|
||||
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
//private:
|
||||
CardP card; ///< The affected card
|
||||
String uid; ///< Its old uid
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Pack types
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ void ValueAction::setCard(CardP const& card) {
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Simple
|
||||
|
||||
|
||||
unique_ptr<ValueAction> value_action(const TextValueP& value, const Defaultable<String>& new_value) {
|
||||
return make_unique<SimpleValueAction<TextValue, false>>(value, new_value);
|
||||
}
|
||||
@@ -208,7 +208,7 @@ String ScriptStyleEvent::getName(bool) const {
|
||||
}
|
||||
void ScriptStyleEvent::perform(bool) {
|
||||
assert(false); // this action is just an event, it should not be performed
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Bulk action
|
||||
|
||||
@@ -235,7 +235,7 @@ void BulkAction::perform(bool to_undo) {
|
||||
|
||||
bool BulkAction::merge(const Action& action) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Action performer
|
||||
|
||||
|
||||
+8
-8
@@ -298,32 +298,32 @@ CardP Card::getLinkedOtherFace(const Set& set) {
|
||||
return getLinkedOtherFace(set.cards);
|
||||
}
|
||||
|
||||
vector<CardP> Card::getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card) {
|
||||
vector<CardP> other_cards;
|
||||
vector<CardP> Card::getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card) {
|
||||
vector<CardP> other_cards;
|
||||
THIS_LINKED_PAIRS(this_linked_pairs);
|
||||
FOR_EACH(this_linked_pair, this_linked_pairs) {
|
||||
String& this_linked_uid = this_linked_pair.first.get();
|
||||
String& this_linked_relation = this_linked_pair.second.get();
|
||||
String& this_linked_relation = this_linked_pair.second.get();
|
||||
if (this_linked_relation == link) {
|
||||
CardP other_card = getCardFromUid(cards, this_linked_uid);
|
||||
if (other_card) other_cards.push_back(other_card);
|
||||
if (other_card) other_cards.push_back(other_card);
|
||||
else if (erase_if_no_card) {
|
||||
this_linked_relation = _("");
|
||||
this_linked_uid = _("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return other_cards;
|
||||
return other_cards;
|
||||
}
|
||||
vector<CardP> Card::getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card) {
|
||||
return getLinkedCardsFromLink(set.cards, link, erase_if_no_card);
|
||||
}
|
||||
|
||||
CardP Card::getCardFromUid(const vector<CardP>& cards, const String& uid) {
|
||||
CardP Card::getCardFromUid(const vector<CardP>& cards, const String& uid) {
|
||||
FOR_EACH(card, cards) {
|
||||
if (card->uid == uid) return card;
|
||||
}
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
CardP Card::getCardFromUid(const Set& set, const String& uid) {
|
||||
return getCardFromUid(set.cards, uid);
|
||||
|
||||
+3
-3
@@ -90,10 +90,10 @@ public:
|
||||
void updateLink(String old_uid, String new_uid);
|
||||
|
||||
vector<pair<CardP, String>> getLinkedCards(const vector<CardP>& cards);
|
||||
vector<pair<CardP, String>> getLinkedCards(const Set& set);
|
||||
vector<pair<CardP, String>> getLinkedCards(const Set& set);
|
||||
|
||||
vector<CardP> getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card);
|
||||
vector<CardP> getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card);
|
||||
vector<CardP> getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card);
|
||||
vector<CardP> getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card);
|
||||
|
||||
CardP getLinkedOtherFace(const vector<CardP>& cards);
|
||||
CardP getLinkedOtherFace(const Set& set);
|
||||
|
||||
+8
-8
@@ -126,23 +126,23 @@ public:
|
||||
inline RealPoint getPos() const { return RealPoint(left, top); }
|
||||
inline RealSize getSize() const { return RealSize(width, height); }
|
||||
inline RealRect getExternalRect() const { return RealRect(left, top, width, height); }
|
||||
inline std::string getExternalRectString(double scale, Radians angle, double bleed, int img_width, int img_height, int img_offset) { ///< update the style before calling this
|
||||
inline std::string getExternalRectString(double scale, Radians angle, double bleed, int img_width, int img_height, int img_offset) { ///< update the style before calling this
|
||||
double x = left * scale, y = top * scale;
|
||||
double w = width * scale, h = height * scale;
|
||||
RealRect rect(x, y, w, h);
|
||||
int degrees = 0;
|
||||
RealRect rect(x, y, w, h);
|
||||
int degrees = 0;
|
||||
if (is_rad0(angle)) {
|
||||
} else if (is_rad180(angle)) {
|
||||
rect = RealRect(img_width - x - w, img_height - y - h, w, h);
|
||||
rect = RealRect(img_width - x - w, img_height - y - h, w, h);
|
||||
degrees = 180;
|
||||
} else if (is_rad90(angle)) {
|
||||
rect = RealRect(y, img_height - x - w, h, w);
|
||||
rect = RealRect(y, img_height - x - w, h, w);
|
||||
degrees = 90;
|
||||
} else if (is_rad270(angle)) {
|
||||
rect = RealRect(img_width - y - h, x, h, w);
|
||||
rect = RealRect(img_width - y - h, x, h, w);
|
||||
degrees = 270;
|
||||
} else {
|
||||
return "";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return "<mse-crop-data>" + std::to_string((int)std::ceil (rect.x + bleed + img_offset)) +
|
||||
"-" + std::to_string((int)std::ceil (rect.y + bleed)) +
|
||||
|
||||
@@ -39,7 +39,7 @@ IMPLEMENT_REFLECTION(ChoiceField) {
|
||||
}
|
||||
|
||||
void ChoiceField::after_reading(Version ver) {
|
||||
Field::after_reading(ver);
|
||||
Field::after_reading(ver);
|
||||
if (choices->choices.size() < 1) {
|
||||
choices->choices.push_back(make_intrusive<Choice>(name));
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
String default_name; ///< Name of "default" value
|
||||
map<String,Color> choice_colors; ///< Colors for the various choices (when color_cardlist)
|
||||
map<String,Color> choice_colors_cardlist; ///< Colors for the various choices, for in the card list
|
||||
bool is_slider = false; ///< Should the UI be displayed as a slider?
|
||||
bool is_slider = false; ///< Should the UI be displayed as a slider?
|
||||
|
||||
void initDependencies(Context&, const Dependency&) const override;
|
||||
void after_reading(Version ver) override;
|
||||
|
||||
@@ -89,9 +89,9 @@ void ColorStyle::checkContentDependencies(Context& ctx, const Dependency& dep) c
|
||||
left_width .initDependencies(ctx, dep);
|
||||
right_width .initDependencies(ctx, dep);
|
||||
top_width .initDependencies(ctx, dep);
|
||||
bottom_width.initDependencies(ctx, dep);
|
||||
bottom_width.initDependencies(ctx, dep);
|
||||
Style::checkContentDependencies(ctx, dep);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : ColorValue
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
Scriptable<double> bottom_width; ///< Width of the colored region on the bottom side
|
||||
ImageCombine combine; ///< How to combine image with the background
|
||||
|
||||
int update(Context&) override;
|
||||
int update(Context&) override;
|
||||
|
||||
void checkContentDependencies(Context&, const Dependency&) const override;
|
||||
};
|
||||
|
||||
+10
-10
@@ -54,17 +54,17 @@ public:
|
||||
ScriptableImage default_image; ///< Placeholder image when the user hasn't set one.
|
||||
Scriptable<bool> store_in_metadata; ///< Is the image stored in full in the metadata when exporting?
|
||||
|
||||
int update(Context&) override;
|
||||
|
||||
inline std::string getExternalImageString(const SetP& set, ImageValue* value) { ///< update the style before calling this
|
||||
int update(Context&) override;
|
||||
|
||||
inline std::string getExternalImageString(const SetP& set, ImageValue* value) { ///< update the style before calling this
|
||||
auto imageInputStream = set->openIn(value->filename);
|
||||
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_2_("file not found", value->filename.toStringForKey(), set));
|
||||
String temppath = wxFileName::CreateTempFileName(_("mse")) + _(".png");
|
||||
img.SaveFile(temppath);
|
||||
std::string s = "<mse-image-data>" + fileToUTF8(temppath.ToStdString()) + "</mse-image-data>";
|
||||
wxRemoveFile(temppath);
|
||||
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
|
||||
return s;
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_2_("file not found", value->filename.toStringForKey(), set));
|
||||
String temppath = wxFileName::CreateTempFileName(_("mse")) + _(".png");
|
||||
img.SaveFile(temppath);
|
||||
std::string s = "<mse-image-data>" + fileToUTF8(temppath.ToStdString()) + "</mse-image-data>";
|
||||
wxRemoveFile(temppath);
|
||||
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
|
||||
return s;
|
||||
}
|
||||
};
|
||||
|
||||
+4
-4
@@ -162,15 +162,15 @@ wxFont Font::toWxFont(double scale) const {
|
||||
|
||||
if (flags & FONT_CODE) {
|
||||
if (size_i < 2) {
|
||||
font = wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
|
||||
if (strikethrough()) font.MakeStrikethrough();
|
||||
font = wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
|
||||
if (strikethrough()) font.MakeStrikethrough();
|
||||
return font;
|
||||
} else {
|
||||
font = wxFont(size_i, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
|
||||
}
|
||||
} else if (name().empty()) {
|
||||
font = *wxNORMAL_FONT;
|
||||
font.SetPointSize(size > 1 ? size_i : int(scale * font.GetPointSize()));
|
||||
font.SetPointSize(size > 1 ? size_i : int(scale * font.GetPointSize()));
|
||||
if (strikethrough()) font.MakeStrikethrough();
|
||||
return font;
|
||||
} else if (flags & FONT_ITALIC && !italic_name().empty()) {
|
||||
@@ -188,7 +188,7 @@ wxFont Font::toWxFont(double scale) const {
|
||||
// make it independent of screen dpi, always use 96 dpi
|
||||
// TODO: do something more sensible, and more portable
|
||||
font.SetPixelSize(wxSize(0, -(int)(scale*size*96.0/72.0 + 0.5) ));
|
||||
#endif
|
||||
#endif
|
||||
if (strikethrough()) font.MakeStrikethrough();
|
||||
return font;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/keyword.hpp>
|
||||
#include <util/io/package.hpp>
|
||||
#include <script/scriptable.hpp>
|
||||
#include <script/scriptable.hpp>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/sstream.h>
|
||||
|
||||
@@ -145,20 +145,20 @@ KeywordP KeywordDataObject::getKeyword(const SetP& set) {
|
||||
|
||||
CardsOnClipboard::CardsOnClipboard(const SetP& set, const String id, const vector<CardP>& cards) {
|
||||
// Conversion to image file
|
||||
if (cards.size() < 6) {
|
||||
Image img;
|
||||
if (cards.size() == 1) {
|
||||
if (cards.size() < 6) {
|
||||
Image img;
|
||||
if (cards.size() == 1) {
|
||||
img = export_image(set, cards[0]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
img = export_image(set, cards);
|
||||
}
|
||||
String temp_path = wxFileName::CreateTempFileName(_("mse")) + _(".png");
|
||||
img.SaveFile(temp_path, wxBITMAP_TYPE_PNG);
|
||||
wxFileDataObject* data = new wxFileDataObject();
|
||||
data->AddFile(temp_path);
|
||||
}
|
||||
String temp_path = wxFileName::CreateTempFileName(_("mse")) + _(".png");
|
||||
img.SaveFile(temp_path, wxBITMAP_TYPE_PNG);
|
||||
wxFileDataObject* data = new wxFileDataObject();
|
||||
data->AddFile(temp_path);
|
||||
Add(data);
|
||||
}
|
||||
// Conversion to serialized card format
|
||||
// Conversion to serialized card format
|
||||
Add(new CardsDataObject(set, id, cards), true);
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
|
||||
Image export_image(const SetP& set, const vector<CardP>& cards, const int padding = 2, const double global_zoom = 1.0, const bool use_zoom_setting = true, const bool use_rotation_setting = true, const bool use_bleed_setting = false);
|
||||
|
||||
/// Export the image of one or more cards to a given filename, using the app's zoom, rotation and bleed settings, and including metadata
|
||||
void export_image(const SetP& set, const CardP& card, const String& filename);
|
||||
void export_image(const SetP& set, const vector<CardP>& cards, const String& path, const String& filename_template, FilenameConflicts conflicts);
|
||||
void export_image(const SetP& set, const CardP& card, const String& filename);
|
||||
void export_image(const SetP& set, const vector<CardP>& cards, const String& path, const String& filename_template, FilenameConflicts conflicts);
|
||||
|
||||
/// Export a set to Magic Workstation format
|
||||
void export_mws(Window* parent, const SetP& set);
|
||||
|
||||
+68
-68
@@ -19,14 +19,14 @@
|
||||
#include <data/settings.hpp>
|
||||
#include <script/functions/json.hpp>
|
||||
#include <gui/util.hpp>
|
||||
#include <render/card/viewer.hpp>
|
||||
#include <render/card/viewer.hpp>
|
||||
|
||||
class ZoomedUnrotatedDataViewer : public DataViewer {
|
||||
public:
|
||||
ZoomedUnrotatedDataViewer(double zoom) : zoom(zoom) {};
|
||||
virtual ~ZoomedUnrotatedDataViewer() {};
|
||||
Rotation getRotation() const override;
|
||||
private:
|
||||
Rotation getRotation() const override;
|
||||
private:
|
||||
double zoom;
|
||||
};
|
||||
|
||||
@@ -36,14 +36,14 @@ Rotation ZoomedUnrotatedDataViewer::getRotation() const {
|
||||
|
||||
// ----------------------------------------------------------------------------- : wxImage export
|
||||
|
||||
Image export_image(const SetP& set, const CardP& card, const bool write_metadata, const double zoom, const Radians angle_radians, const double bleed_pixels) {
|
||||
Image export_image(const SetP& set, const CardP& card, const bool write_metadata, const double zoom, const Radians angle_radians, const double bleed_pixels) {
|
||||
if (!set) throw Error(_("no set"));
|
||||
/// create and zoom
|
||||
/// create and zoom
|
||||
ZoomedUnrotatedDataViewer viewer = ZoomedUnrotatedDataViewer(zoom);
|
||||
viewer.setSet(set);
|
||||
viewer.setCard(card);
|
||||
RealSize size = viewer.getRotation().getExternalSize();
|
||||
int bleed = lround(bleed_pixels);
|
||||
int bleed = lround(bleed_pixels);
|
||||
Bitmap bitmap((int)size.width + 2 * bleed, (int)size.height + 2 * bleed);
|
||||
if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap"));
|
||||
wxMemoryDC dc;
|
||||
@@ -51,18 +51,18 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
|
||||
dc.SetDeviceOrigin(bleed, bleed);
|
||||
viewer.draw(dc);
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
Image img = bitmap.ConvertToImage();
|
||||
|
||||
/// rotate
|
||||
img = rotate_image(img, angle_radians);
|
||||
|
||||
/// add print bleed edge
|
||||
int width = img.GetWidth(), height = img.GetHeight();
|
||||
bleed = max(0, min(width-1, min(height-1, bleed)));
|
||||
Image img = bitmap.ConvertToImage();
|
||||
|
||||
/// rotate
|
||||
img = rotate_image(img, angle_radians);
|
||||
|
||||
/// add print bleed edge
|
||||
int width = img.GetWidth(), height = img.GetHeight();
|
||||
bleed = max(0, min(width-1, min(height-1, bleed)));
|
||||
if (size.width < bleed + 2 || size.height < bleed + 2) {
|
||||
queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge"));
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
if (!img.HasAlpha()) img.InitAlpha();
|
||||
Byte* pixels = img.GetData();
|
||||
Byte* alpha = img.GetAlpha();
|
||||
@@ -126,17 +126,17 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
|
||||
pixels[3 * pixel + 2] = pixels[3 * mirror + 2];
|
||||
alpha[pixel] = alpha[mirror];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// add metadata
|
||||
}
|
||||
}
|
||||
|
||||
/// add metadata
|
||||
if (write_metadata) {
|
||||
String metadata = _("<mse-card-data>[");
|
||||
IndexMap<FieldP, ValueP>& card_data = card->data;
|
||||
boost::json::object cardv = mse_to_json(card, set.get());
|
||||
boost::json::object& cardv_data = cardv["data"].as_object();
|
||||
StyleSheetP stylesheet = set->stylesheetForP(card);
|
||||
if (!settings.stylesheetSettingsFor(*stylesheet).card_notes_export()) cardv["notes"] = "";
|
||||
if (!settings.stylesheetSettingsFor(*stylesheet).card_notes_export()) cardv["notes"] = "";
|
||||
// iterate over all image fields
|
||||
for(IndexMap<FieldP, ValueP>::iterator it = card_data.begin() ; it != card_data.end() ; ++it) {
|
||||
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
|
||||
@@ -144,64 +144,64 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
|
||||
FieldP field = (*it)->fieldP;
|
||||
ImageStyle* style = dynamic_cast<ImageStyle*>(stylesheet->card_style.at(field->index).get());
|
||||
if (style) {
|
||||
style->update(set->getContext(card));
|
||||
// store the entire image in the metadata
|
||||
if (style->store_in_metadata()) {
|
||||
std::string bytes = style->getExternalImageString(set, value);
|
||||
cardv_data[field->name.ToStdString()] = bytes;
|
||||
}
|
||||
// store only crop coordinates
|
||||
else {
|
||||
style->update(set->getContext(card));
|
||||
// store the entire image in the metadata
|
||||
if (style->store_in_metadata()) {
|
||||
std::string bytes = style->getExternalImageString(set, value);
|
||||
cardv_data[field->name.ToStdString()] = bytes;
|
||||
}
|
||||
// store only crop coordinates
|
||||
else {
|
||||
std::string rect = style->getExternalRectString(zoom, angle_radians, bleed_pixels, width, height, 0);
|
||||
cardv_data[field->name.ToStdString()] = rect;
|
||||
cardv_data[field->name.ToStdString()] = rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
metadata += json_ugly_print(cardv) + _("]</mse-card-data>");
|
||||
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
Image export_image( const SetP& set, const vector<CardP>& cards,
|
||||
const int padding,
|
||||
const double global_zoom,
|
||||
const bool use_zoom_setting,
|
||||
const bool use_rotation_setting,
|
||||
Image export_image( const SetP& set, const vector<CardP>& cards,
|
||||
const int padding,
|
||||
const double global_zoom,
|
||||
const bool use_zoom_setting,
|
||||
const bool use_rotation_setting,
|
||||
const bool use_bleed_setting) {
|
||||
if (!set) throw Error(_("no set"));
|
||||
if (cards.size() == 0) throw Error(_("no cards"));
|
||||
vector<Image> imgs;
|
||||
vector<int> offsets;
|
||||
vector<int> offsets;
|
||||
vector<double> zooms;
|
||||
vector<double> angles;
|
||||
vector<double> bleeds;
|
||||
// Draw card images
|
||||
FOR_EACH(card, cards) {
|
||||
FOR_EACH(card, cards) {
|
||||
Settings::ExportSettings card_settings = settings.exportSettingsFor(set->stylesheetFor(card));
|
||||
double zoom = use_zoom_setting ? global_zoom * card_settings.zoom : global_zoom;
|
||||
double angle = use_rotation_setting ? card_settings.angle_radians : 0.0;
|
||||
double bleed = use_bleed_setting ? card_settings.bleed_pixels : 0.0;
|
||||
imgs.push_back(export_image(set, card, false, zoom, angle, bleed));
|
||||
zooms.push_back(zoom);
|
||||
angles.push_back(angle);
|
||||
imgs.push_back(export_image(set, card, false, zoom, angle, bleed));
|
||||
zooms.push_back(zoom);
|
||||
angles.push_back(angle);
|
||||
bleeds.push_back(bleed);
|
||||
}
|
||||
}
|
||||
int global_width = 0;
|
||||
int global_height = 0;
|
||||
vector<int> widths;
|
||||
vector<int> heights;
|
||||
FOR_EACH(img, imgs) {
|
||||
int width = img.GetWidth();
|
||||
int height = img.GetHeight();
|
||||
widths.push_back(width);
|
||||
heights.push_back(height);
|
||||
offsets.push_back(global_width);
|
||||
global_width += padding + width;
|
||||
global_height = max(global_height, height);
|
||||
}
|
||||
FOR_EACH(img, imgs) {
|
||||
int width = img.GetWidth();
|
||||
int height = img.GetHeight();
|
||||
widths.push_back(width);
|
||||
heights.push_back(height);
|
||||
offsets.push_back(global_width);
|
||||
global_width += padding + width;
|
||||
global_height = max(global_height, height);
|
||||
}
|
||||
global_width -= padding;
|
||||
// Draw global image
|
||||
Image global_img = Image(global_width, global_height);
|
||||
@@ -215,11 +215,11 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
|
||||
pixels[3 * i + 1] = 0;
|
||||
pixels[3 * i + 2] = 0;
|
||||
alpha[i] = 0;
|
||||
}
|
||||
}
|
||||
// Paste card images
|
||||
FOR_EACH_2(img, imgs, offset, offsets) {
|
||||
global_img.Paste(img, offset, 0);
|
||||
}
|
||||
FOR_EACH_2(img, imgs, offset, offsets) {
|
||||
global_img.Paste(img, offset, 0);
|
||||
}
|
||||
// Write metadata
|
||||
String metadata = _("<mse-card-data>[");
|
||||
for (int i = 0; i < cards.size(); ++i) {
|
||||
@@ -233,19 +233,19 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
|
||||
for(IndexMap<FieldP, ValueP>::iterator it = card_data.begin() ; it != card_data.end() ; ++it) {
|
||||
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
|
||||
if (value && !value->filename.empty()) {
|
||||
FieldP field = (*it)->fieldP;
|
||||
FieldP field = (*it)->fieldP;
|
||||
ImageStyle* style = dynamic_cast<ImageStyle*>(stylesheet->card_style.at(field->index).get());
|
||||
if (style) {
|
||||
style->update(set->getContext(card));
|
||||
// store the entire image in the metadata
|
||||
if (style->store_in_metadata()) {
|
||||
std::string bytes = style->getExternalImageString(set, value);
|
||||
cardv_data[field->name.ToStdString()] = bytes;
|
||||
}
|
||||
// store only crop coordinates
|
||||
else {
|
||||
style->update(set->getContext(card));
|
||||
// store the entire image in the metadata
|
||||
if (style->store_in_metadata()) {
|
||||
std::string bytes = style->getExternalImageString(set, value);
|
||||
cardv_data[field->name.ToStdString()] = bytes;
|
||||
}
|
||||
// store only crop coordinates
|
||||
else {
|
||||
std::string rect = style->getExternalRectString(zooms[i], angles[i], bleeds[i], widths[i], heights[i], offsets[i]);
|
||||
cardv_data[field->name.ToStdString()] = rect;
|
||||
cardv_data[field->name.ToStdString()] = rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,14 +253,14 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
|
||||
metadata += json_ugly_print(cardv);
|
||||
}
|
||||
metadata += _("]</mse-card-data>");
|
||||
global_img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
global_img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
|
||||
|
||||
return global_img;
|
||||
}
|
||||
|
||||
void export_image(const SetP& set, const CardP& card, const String& filename) {
|
||||
void export_image(const SetP& set, const CardP& card, const String& filename) {
|
||||
const StyleSheet& stylesheet = set->stylesheetFor(card);
|
||||
StyleSheetSettings& stylesheet_settings = settings.stylesheetSettingsFor(stylesheet);
|
||||
StyleSheetSettings& stylesheet_settings = settings.stylesheetSettingsFor(stylesheet);
|
||||
Settings::ExportSettings export_settings = settings.exportSettingsFor(stylesheet);
|
||||
Image img = export_image(set, card, true, export_settings.zoom, export_settings.angle_radians, export_settings.bleed_pixels);
|
||||
img.SaveFile(filename);
|
||||
|
||||
+17
-17
@@ -67,7 +67,7 @@ IMPLEMENT_REFLECTION(Game) {
|
||||
REFLECT_NO_SCRIPT(auto_replaces);
|
||||
}
|
||||
|
||||
void Game::validate(Version v) {
|
||||
void Game::validate(Version v) {
|
||||
// check that we have at least one card field
|
||||
if (card_fields.size() < 1) {
|
||||
throw Error(_ERROR_1_("no card fields", name()));
|
||||
@@ -123,11 +123,11 @@ void Game::validate(Version v) {
|
||||
card_fields_alt_names.emplace(unified_name, field->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
// front face/back face card link
|
||||
card_links.insert(card_links.begin(), make_intrusive<CardLink>());
|
||||
}
|
||||
// front face/back face card link
|
||||
card_links.insert(card_links.begin(), make_intrusive<CardLink>());
|
||||
card_links[0]->selected.default_ = _("Front Face");
|
||||
card_links[0]->selected.translations = std::unordered_map<String, String>{
|
||||
card_links[0]->selected.translations = std::unordered_map<String, String>{
|
||||
{_("ch-s"), _("卡片正面")},
|
||||
{_("ch-t"), _("卡片正面")},
|
||||
{_("da"), _("Forside")},
|
||||
@@ -140,9 +140,9 @@ void Game::validate(Version v) {
|
||||
{_("ko"), _("카드 앞면")},
|
||||
{_("pl"), _("Przód")},
|
||||
{_("pt-br"), _("Frente")},
|
||||
{_("ru"), _("Лицевая сторона")}
|
||||
};
|
||||
card_links[0]->linked.default_ = _("Back Face");
|
||||
{_("ru"), _("Лицевая сторона")}
|
||||
};
|
||||
card_links[0]->linked.default_ = _("Back Face");
|
||||
card_links[0]->linked.translations = std::unordered_map<String, String>{
|
||||
{_("ch-s"), _("卡片背面")},
|
||||
{_("ch-t"), _("卡片背面")},
|
||||
@@ -156,27 +156,27 @@ void Game::validate(Version v) {
|
||||
{_("ko"), _("카드 뒷면")},
|
||||
{_("pl"), _("Tył")},
|
||||
{_("pt-br"), _("Verso")},
|
||||
{_("ru"), _("Обратная сторона")}
|
||||
};
|
||||
{_("ru"), _("Обратная сторона")}
|
||||
};
|
||||
// localized card link names map
|
||||
for (auto it = card_links.begin(); it != card_links.end(); ++it) {
|
||||
CardLinkP link = *it;
|
||||
String selected_default = link->selected.default_;
|
||||
String selected_default = link->selected.default_;
|
||||
for (auto selected_it = link->selected.translations.begin(); selected_it != link->selected.translations.end(); selected_it++) {
|
||||
String selected_tr = unified_form(selected_it->second);
|
||||
String selected_tr = unified_form(selected_it->second);
|
||||
if (card_links_alt_names.find(selected_tr) != card_links_alt_names.end() && card_links_alt_names[selected_tr] != selected_default) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", selected_tr, card_links_alt_names[selected_tr], selected_default));
|
||||
}
|
||||
}
|
||||
card_links_alt_names.emplace(selected_tr, selected_default);
|
||||
}
|
||||
String linked_default = link->linked.default_;
|
||||
String linked_default = link->linked.default_;
|
||||
for (auto linked_it = link->linked.translations.begin(); linked_it != link->linked.translations.end(); linked_it++) {
|
||||
String linked_tr = unified_form(linked_it->second);
|
||||
String linked_tr = unified_form(linked_it->second);
|
||||
if (card_links_alt_names.find(linked_tr) != card_links_alt_names.end() && card_links_alt_names[linked_tr] != linked_default) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", linked_tr, card_links_alt_names[linked_tr], linked_default));
|
||||
}
|
||||
}
|
||||
card_links_alt_names.emplace(linked_tr, linked_default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ IMPLEMENT_REFLECTION(Installer) {
|
||||
void Installer::validate(Version file_app_version) {
|
||||
Packaged::validate(file_app_version);
|
||||
// load icons where possible
|
||||
FOR_EACH(p,packages) {
|
||||
String url = p->icon_url;
|
||||
FOR_EACH(p,packages) {
|
||||
String url = p->icon_url;
|
||||
if (settings.darkMode() && !p->dark_icon_url.empty()) {
|
||||
url = p->dark_icon_url;
|
||||
}
|
||||
|
||||
+5
-5
@@ -108,11 +108,11 @@ IndexMap<FieldP, ValueP>& Set::stylingDataFor(const CardP& card) {
|
||||
}
|
||||
|
||||
void Set::referenceActionStackFiles() {
|
||||
referenceActionStackFiles(true);
|
||||
referenceActionStackFiles(true);
|
||||
referenceActionStackFiles(false);
|
||||
}
|
||||
void Set::referenceActionStackFiles(bool undo) {
|
||||
for (auto&& action : undo ? actions.undo_actions : actions.redo_actions) {
|
||||
void Set::referenceActionStackFiles(bool undo) {
|
||||
for (auto&& action : undo ? actions.undo_actions : actions.redo_actions) {
|
||||
try {
|
||||
SimpleValueAction<ImageValue, false>& v = dynamic_cast<SimpleValueAction<ImageValue, false>&>(*action);
|
||||
if (ImageValue* v2 = dynamic_cast<ImageValue*>(v.valueP.get())) {
|
||||
@@ -125,9 +125,9 @@ void Set::referenceActionStackFiles(bool undo) {
|
||||
referenceFile(v.new_value.toStringForWriting());
|
||||
referenceFile(v2->filename.toStringForWriting());
|
||||
}
|
||||
} catch (...) {} }
|
||||
} catch (...) {} }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String Set::identification() const {
|
||||
// an identifying field
|
||||
|
||||
+4
-4
@@ -89,12 +89,12 @@ public:
|
||||
/// Styling information for a particular stylesheet
|
||||
IndexMap<FieldP, ValueP>& stylingDataFor(const StyleSheet&);
|
||||
/// Styling information for a particular card
|
||||
IndexMap<FieldP, ValueP>& stylingDataFor(const CardP& card);
|
||||
|
||||
/// Make sure the image and symbol files from
|
||||
IndexMap<FieldP, ValueP>& stylingDataFor(const CardP& card);
|
||||
|
||||
/// Make sure the image and symbol files from
|
||||
/// the ActionStack are saved so we can undo
|
||||
void referenceActionStackFiles();
|
||||
void referenceActionStackFiles(bool undo);
|
||||
void referenceActionStackFiles(bool undo);
|
||||
|
||||
/// Get the identification of this set, an identification is something like a name, title, etc.
|
||||
/** May return "" */
|
||||
|
||||
+40
-40
@@ -54,7 +54,7 @@ IMPLEMENT_REFLECTION_ENUM(FilenameConflicts) {
|
||||
}
|
||||
|
||||
const vector<int> Settings::scale_choices = { 50,66,75,80,100,120,125,150,175,200 };
|
||||
|
||||
|
||||
const int COLUMN_NOT_INITIALIZED = -100000;
|
||||
|
||||
ColumnSettings::ColumnSettings()
|
||||
@@ -103,11 +103,11 @@ void GameSettings::initDefaults(const Game& game) {
|
||||
ar->custom = false;
|
||||
auto_replaces.push_back(ar);
|
||||
}
|
||||
}
|
||||
// make sure things aren't in a problematic state
|
||||
}
|
||||
// make sure things aren't in a problematic state
|
||||
for (auto it = cardlist_columns.begin(); it != cardlist_columns.end(); ++it) {
|
||||
if (it->second.width < 20) it->second.width = 20;
|
||||
}
|
||||
}
|
||||
if (images_export_filename.Trim().empty()) images_export_filename = _("{card.name}.png");
|
||||
}
|
||||
|
||||
@@ -174,13 +174,13 @@ IMPLEMENT_REFLECTION_ENUM(CutterLinesType) {
|
||||
VALUE_N("none", CUTTER_NONE);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Dark mode settings
|
||||
|
||||
IMPLEMENT_REFLECTION_ENUM(DarkModeType) {
|
||||
VALUE_N("yes", DARKMODE_YES);
|
||||
VALUE_N("system", DARKMODE_SYSTEM);
|
||||
VALUE_N("no", DARKMODE_NO);
|
||||
}
|
||||
// ----------------------------------------------------------------------------- : Dark mode settings
|
||||
|
||||
IMPLEMENT_REFLECTION_ENUM(DarkModeType) {
|
||||
VALUE_N("yes", DARKMODE_YES);
|
||||
VALUE_N("system", DARKMODE_SYSTEM);
|
||||
VALUE_N("no", DARKMODE_NO);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Settings
|
||||
|
||||
@@ -234,7 +234,7 @@ GameSettings& Settings::gameSettingsFor(const Game& game) {
|
||||
if (!gs) gs = make_intrusive<GameSettings>();
|
||||
gs->initDefaults(game);
|
||||
return *gs;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnSettings& Settings::columnSettingsFor(const Game& game, const Field& field) {
|
||||
// Get game info
|
||||
@@ -248,7 +248,7 @@ ColumnSettings& Settings::columnSettingsFor(const Game& game, const Field& field
|
||||
cs.width = field.card_list_width;
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
}
|
||||
|
||||
StyleSheetSettings& Settings::stylesheetSettingsFor(const StyleSheet& stylesheet) {
|
||||
// Use the canonical form here since the stylesheet name will be used as a stored key.
|
||||
@@ -257,37 +257,37 @@ StyleSheetSettings& Settings::stylesheetSettingsFor(const StyleSheet& stylesheet
|
||||
if (!ss) ss = make_intrusive<StyleSheetSettings>();
|
||||
ss->useDefault(default_stylesheet_settings); // update default settings
|
||||
return *ss;
|
||||
}
|
||||
}
|
||||
|
||||
double Settings::exportScaleSettingsFor(const StyleSheet& stylesheet) {
|
||||
StyleSheetSettings& ss = stylesheetSettingsFor(stylesheet);
|
||||
int export_scale = ss.export_scale_selection();
|
||||
if (export_scale == 0) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
|
||||
if (export_scale == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
|
||||
if (export_scale == 2) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
|
||||
int export_scale = ss.export_scale_selection();
|
||||
if (export_scale == 0) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
|
||||
if (export_scale == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
|
||||
if (export_scale == 2) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
|
||||
return (double)scale_choices[export_scale - 3] / 100.0;
|
||||
}
|
||||
}
|
||||
|
||||
double Settings::importScaleSettingsFor(const StyleSheet& stylesheet) {
|
||||
if (import_scale_selection == 0) return exportScaleSettingsFor(stylesheet);
|
||||
if (import_scale_selection == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
|
||||
if (import_scale_selection == 2) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
|
||||
if (import_scale_selection == 3) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
|
||||
if (import_scale_selection == 0) return exportScaleSettingsFor(stylesheet);
|
||||
if (import_scale_selection == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
|
||||
if (import_scale_selection == 2) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
|
||||
if (import_scale_selection == 3) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
|
||||
return (double)scale_choices[import_scale_selection - 4] / 100.0;
|
||||
}
|
||||
|
||||
double Settings::adaptiveScaleSettingsFor(const StyleSheet& stylesheet, double dpi_target, double dpi_leeway) {
|
||||
if (abs(stylesheet.card_dpi - dpi_target) <= dpi_leeway) return 1.0;
|
||||
}
|
||||
|
||||
double Settings::adaptiveScaleSettingsFor(const StyleSheet& stylesheet, double dpi_target, double dpi_leeway) {
|
||||
if (abs(stylesheet.card_dpi - dpi_target) <= dpi_leeway) return 1.0;
|
||||
return dpi_target / max(10.0, stylesheet.card_dpi);
|
||||
}
|
||||
}
|
||||
|
||||
Settings::ExportSettings Settings::exportSettingsFor(const StyleSheet& stylesheet) {
|
||||
StyleSheetSettings& ss = stylesheetSettingsFor(stylesheet);
|
||||
double zoom = settings.exportScaleSettingsFor(stylesheet);
|
||||
double zoom = settings.exportScaleSettingsFor(stylesheet);
|
||||
double angle = ss.card_normal_export() ? 0.0 : deg_to_rad(ss.card_angle());
|
||||
double bleed = ss.card_bleed_export() ? (stylesheet.card_dpi / 300.0) * 36.0 * zoom : 0.0; // 36 pixels of bleed on a 300 DPI print
|
||||
double bleed = ss.card_bleed_export() ? (stylesheet.card_dpi / 300.0) * 36.0 * zoom : 0.0; // 36 pixels of bleed on a 300 DPI print
|
||||
return ExportSettings{zoom, angle, bleed};
|
||||
}
|
||||
}
|
||||
|
||||
IndexMap<FieldP,ValueP>& Settings::exportOptionsFor(const ExportTemplate& export_template) {
|
||||
return export_options.get(export_template.name(), export_template.option_fields);
|
||||
@@ -306,17 +306,17 @@ String Settings::settingsFile() {
|
||||
|
||||
bool Settings::darkMode() {
|
||||
return wxSystemSettings::GetAppearance().IsDark();
|
||||
}
|
||||
}
|
||||
|
||||
String Settings::darkModePrefix() {
|
||||
if (darkMode()) return _("dark_");
|
||||
if (darkMode()) return _("dark_");
|
||||
return _("");
|
||||
}
|
||||
}
|
||||
|
||||
Color Settings::darkModeColor() {
|
||||
if (darkMode()) return wxColor(15,8,0);
|
||||
if (darkMode()) return wxColor(15,8,0);
|
||||
return wxColor(240,247,255);
|
||||
}
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION_NO_SCRIPT(Settings) {
|
||||
REFLECT(locale);
|
||||
@@ -377,10 +377,10 @@ void Settings::read() {
|
||||
wxFileInputStream file(filename);
|
||||
if (!file.Ok()) return; // failure is not an error
|
||||
Reader reader(file, nullptr, filename);
|
||||
reader.handle_greedy(*this);
|
||||
// make sure things aren't in a problematic state
|
||||
if (locale.Trim().empty()) locale = _("en");
|
||||
if (symbol_grid_size < 30) symbol_grid_size = 30;
|
||||
reader.handle_greedy(*this);
|
||||
// make sure things aren't in a problematic state
|
||||
if (locale.Trim().empty()) locale = _("en");
|
||||
if (symbol_grid_size < 30) symbol_grid_size = 30;
|
||||
if (default_stylesheet_settings.card_zoom < 0.5) default_stylesheet_settings.card_zoom = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-29
@@ -113,22 +113,22 @@ public:
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Printing settings
|
||||
|
||||
enum CutterLinesType
|
||||
{ CUTTER_ALL
|
||||
, CUTTER_NO_INTERSECTION
|
||||
, CUTTER_NONE
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Dark mode settings
|
||||
|
||||
enum DarkModeType
|
||||
{ DARKMODE_SYSTEM
|
||||
, DARKMODE_NO
|
||||
, DARKMODE_YES
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Printing settings
|
||||
|
||||
enum CutterLinesType
|
||||
{ CUTTER_ALL
|
||||
, CUTTER_NO_INTERSECTION
|
||||
, CUTTER_NONE
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Dark mode settings
|
||||
|
||||
enum DarkModeType
|
||||
{ DARKMODE_SYSTEM
|
||||
, DARKMODE_NO
|
||||
, DARKMODE_YES
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Settings
|
||||
|
||||
@@ -175,10 +175,10 @@ public:
|
||||
String default_game;
|
||||
|
||||
// --------------------------------------------------- : Game/stylesheet specific
|
||||
|
||||
|
||||
struct ExportSettings {
|
||||
double zoom, angle_radians, bleed_pixels;
|
||||
};
|
||||
};
|
||||
|
||||
/// Get the settings object for a specific game
|
||||
GameSettings& gameSettingsFor (const Game& game);
|
||||
@@ -188,10 +188,10 @@ public:
|
||||
StyleSheetSettings& stylesheetSettingsFor (const StyleSheet& stylesheet);
|
||||
double exportScaleSettingsFor (const StyleSheet& stylesheet);
|
||||
double importScaleSettingsFor (const StyleSheet& stylesheet);
|
||||
double adaptiveScaleSettingsFor (const StyleSheet& stylesheet, double target_dpi, double leeway_dpi);
|
||||
ExportSettings exportSettingsFor (const StyleSheet& stylesheet);
|
||||
double adaptiveScaleSettingsFor (const StyleSheet& stylesheet, double target_dpi, double leeway_dpi);
|
||||
ExportSettings exportSettingsFor (const StyleSheet& stylesheet);
|
||||
|
||||
static const vector<int> scale_choices;
|
||||
static const vector<int> scale_choices;
|
||||
|
||||
private:
|
||||
map<String,GameSettingsP> game_settings;
|
||||
@@ -215,24 +215,24 @@ public:
|
||||
|
||||
// --------------------------------------------------- : Dark Mode
|
||||
|
||||
DarkModeType dark_mode_type;
|
||||
/// Is the app currently displayed in dark mode?
|
||||
bool darkMode();
|
||||
DarkModeType dark_mode_type;
|
||||
/// Is the app currently displayed in dark mode?
|
||||
bool darkMode();
|
||||
/// Prefix for resource files depending on dark mode
|
||||
String darkModePrefix();
|
||||
String darkModePrefix();
|
||||
/// Background color for windows depending on dark mode
|
||||
Color darkModeColor();
|
||||
Color darkModeColor();
|
||||
|
||||
// --------------------------------------------------- : Special game stuff
|
||||
|
||||
String apprentice_location;
|
||||
|
||||
// --------------------------------------------------- : Internal settings
|
||||
// --------------------------------------------------- : Internal settings
|
||||
|
||||
int import_scale_selection;
|
||||
bool allow_image_download;
|
||||
|
||||
// --------------------------------------------------- : Update checking
|
||||
// --------------------------------------------------- : Update checking
|
||||
|
||||
#if USE_OLD_STYLE_UPDATE_CHECKER
|
||||
String updates_url;
|
||||
@@ -243,7 +243,7 @@ public:
|
||||
bool check_updates_all; ///< Check updates of all packages, not just the program
|
||||
String website_url;
|
||||
|
||||
// --------------------------------------------------- : Installation settings
|
||||
// --------------------------------------------------- : Installation settings
|
||||
|
||||
InstallType install_type;
|
||||
|
||||
|
||||
+12
-12
@@ -484,24 +484,24 @@ wxMenu* InsertSymbolMenu::makeMenu(int id, SymbolFont& font) const {
|
||||
|
||||
wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, SymbolFont& font) const {
|
||||
String label = this->label.get();
|
||||
// ensure that we are not defining an accelerator...
|
||||
// ensure that we are not defining an accelerator...
|
||||
// everything after a tab is considered to be an accelerator by wxMenuItem
|
||||
int accel_pos = label.find_last_of('\t');
|
||||
if (accel_pos != label.npos && accel_pos > 0) {
|
||||
String accel = label.substr(accel_pos+1);
|
||||
int accel_pos = label.find_last_of('\t');
|
||||
if (accel_pos != label.npos && accel_pos > 0) {
|
||||
String accel = label.substr(accel_pos+1);
|
||||
#ifdef __WXMSW__
|
||||
// if there is a + or - in the accelerator, replace the tab with spaces (simply adding a space does not work)
|
||||
if (accel.Contains("+") || accel.Contains("-")) {
|
||||
label = label.substr(0, accel_pos) + _(" ") + accel;
|
||||
}
|
||||
// otherwise simply add a space after the tab if there isn't one
|
||||
else {
|
||||
// if there is a + or - in the accelerator, replace the tab with spaces (simply adding a space does not work)
|
||||
if (accel.Contains("+") || accel.Contains("-")) {
|
||||
label = label.substr(0, accel_pos) + _(" ") + accel;
|
||||
}
|
||||
// otherwise simply add a space after the tab if there isn't one
|
||||
else {
|
||||
label.Replace(_("\t "), _("\t"));
|
||||
label.Replace(_("\t"), _("\t "));
|
||||
label.Replace(_("\t"), _("\t "));
|
||||
}
|
||||
#else
|
||||
label = label.substr(0, accel_pos) + _(" ") + accel; // replace the tab with spaces
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (type == Type::SUBMENU) {
|
||||
wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, label,
|
||||
|
||||
+23
-23
@@ -332,8 +332,8 @@ Image BleedEdgedImage::generate(const Options& opt) {
|
||||
}
|
||||
bool is_landscape = w > h;
|
||||
int dw = int(w * (horizontal_size > 0.0 ? horizontal_size : is_landscape ? 0.037 : 0.048));
|
||||
int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037));
|
||||
dw = min(w-1, max(0, dw));
|
||||
int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037));
|
||||
dw = min(w-1, max(0, dw));
|
||||
dh = min(h-1, max(0, dh));
|
||||
if (dw <= 0 && dh <= 0) {
|
||||
return base_img;
|
||||
@@ -680,32 +680,32 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const {
|
||||
// ----------------------------------------------------------------------------- : ImportedImage
|
||||
|
||||
ImportedImage::ImportedImage(Set* set, const String& filepath)
|
||||
{
|
||||
loadpath = filepath;
|
||||
{
|
||||
loadpath = filepath;
|
||||
|
||||
// has the set already been saved at least once?
|
||||
if (set->needSaveAs()) throw ScriptError(_ERROR_1_("can't import image without set", loadpath));
|
||||
|
||||
// does the file pointed to by filepath exist?
|
||||
if (!wxFileName(loadpath, wxPATH_UNIX).FileExists()) throw ScriptError(_ERROR_1_("import not found", loadpath));
|
||||
|
||||
if (!wxFileName(loadpath, wxPATH_UNIX).FileExists()) throw ScriptError(_ERROR_1_("import not found", loadpath));
|
||||
|
||||
// is the file an image?
|
||||
Image img;
|
||||
img.LoadFile(loadpath);
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_1_("import not image", loadpath));
|
||||
Image img;
|
||||
img.LoadFile(loadpath);
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_1_("import not image", loadpath));
|
||||
|
||||
// add the file to the set (or overwrite it if pre-existing), save set
|
||||
savename = normalize_internal_filename(loadpath);
|
||||
savename.Replace(":", "-");
|
||||
savename.Replace("/", "-");
|
||||
auto outStream = set->openOut(savename);
|
||||
auto outStream = set->openOut(savename);
|
||||
img.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
|
||||
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", loadpath));
|
||||
outStream->Close();
|
||||
set->save(false);
|
||||
}
|
||||
|
||||
Image ImportedImage::generate(const Options& opt) {
|
||||
Image ImportedImage::generate(const Options& opt) {
|
||||
auto imageInputStream = opt.local_package->openIn(savename);
|
||||
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
|
||||
|
||||
@@ -722,34 +722,34 @@ bool ImportedImage::operator == (const GeneratedImage& that) const {
|
||||
// ----------------------------------------------------------------------------- : DownloadedImage
|
||||
|
||||
DownloadedImage::DownloadedImage(Set* set, const String& url)
|
||||
{
|
||||
loadpath = url;
|
||||
{
|
||||
loadpath = url;
|
||||
|
||||
// has the set already been saved at least once?
|
||||
if (set->needSaveAs()) throw ScriptError(_ERROR_1_("can't download image without set", loadpath));
|
||||
|
||||
// can we download the data?
|
||||
|
||||
// can we download the data?
|
||||
WebRequestWindow wnd(loadpath);
|
||||
if (wnd.ShowModal() != wxID_OK) throw ScriptError(_ERROR_1_("can't download image", loadpath));
|
||||
|
||||
// is the data an image?
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (!content_type.StartsWith(_("image"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
|
||||
if (wnd.ShowModal() != wxID_OK) throw ScriptError(_ERROR_1_("can't download image", loadpath));
|
||||
|
||||
// is the data an image?
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (!content_type.StartsWith(_("image"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
|
||||
Image img(*wnd.out.GetStream());
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_("web request corrupted"));
|
||||
if (!img.IsOk()) throw ScriptError(_ERROR_("web request corrupted"));
|
||||
|
||||
// add the file to the set (or overwrite it if pre-existing), save set
|
||||
savename = normalize_internal_filename(loadpath);
|
||||
savename.Replace(":", "-");
|
||||
savename.Replace("/", "-");
|
||||
auto outStream = set->openOut(savename);
|
||||
auto outStream = set->openOut(savename);
|
||||
img.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
|
||||
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", loadpath));
|
||||
outStream->Close();
|
||||
set->save(false);
|
||||
}
|
||||
|
||||
Image DownloadedImage::generate(const Options& opt) {
|
||||
Image DownloadedImage::generate(const Options& opt) {
|
||||
auto imageInputStream = opt.local_package->openIn(savename);
|
||||
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
DECLARE_POINTER_TYPE(GeneratedImage);
|
||||
DECLARE_POINTER_TYPE(SymbolVariation);
|
||||
class Package;
|
||||
class Set;
|
||||
class Set;
|
||||
|
||||
// ----------------------------------------------------------------------------- : GeneratedImage
|
||||
|
||||
@@ -455,10 +455,10 @@ private:
|
||||
class ExternalImage : public GeneratedImage {
|
||||
public:
|
||||
inline String toString() { return savename; }
|
||||
inline String toCode() const override { return _("<image>"); }
|
||||
inline String toCode() const override { return _("<image>"); }
|
||||
|
||||
protected:
|
||||
String loadpath;
|
||||
String loadpath;
|
||||
String savename;
|
||||
};
|
||||
|
||||
|
||||
@@ -134,9 +134,9 @@ Image resample(const Image& img_in, int width, int height) {
|
||||
return img_out;
|
||||
}
|
||||
}
|
||||
Image resample(const Image& img_in, double zoom) {
|
||||
Image resample(const Image& img_in, double zoom) {
|
||||
return resample(img_in, (int)(img_in.GetWidth() * zoom), (int)(img_in.GetHeight() * zoom));
|
||||
}
|
||||
}
|
||||
|
||||
void resample_and_clip(const Image& img_in, Image& img_out, wxRect rect) {
|
||||
// mask to alpha
|
||||
|
||||
@@ -33,14 +33,14 @@ void AboutWindow::onPaint(wxPaintEvent& ev) {
|
||||
draw(dc);
|
||||
}
|
||||
|
||||
const char* MSE_AUTHORS[] = {
|
||||
"Twan van Laarhoven (twanvl)",
|
||||
"Sean Hunt (coppro)",
|
||||
"Alissa Rao (Lymia)",
|
||||
"Olivier Bocksberger (G-e-n-e-v-e-n-s-i-S)",
|
||||
"Brendan Hagan (haganbmj)",
|
||||
"Thomas Tkacz (TomTkacz)",
|
||||
"CaiCai (247321453)"
|
||||
const char* MSE_AUTHORS[] = {
|
||||
"Twan van Laarhoven (twanvl)",
|
||||
"Sean Hunt (coppro)",
|
||||
"Alissa Rao (Lymia)",
|
||||
"Olivier Bocksberger (G-e-n-e-v-e-n-s-i-S)",
|
||||
"Brendan Hagan (haganbmj)",
|
||||
"Thomas Tkacz (TomTkacz)",
|
||||
"CaiCai (247321453)"
|
||||
};
|
||||
|
||||
void AboutWindow::draw(DC& dc) {
|
||||
|
||||
+143
-143
@@ -30,11 +30,11 @@
|
||||
#include <data/action/value.hpp>
|
||||
#include <script/functions/json.hpp>
|
||||
#include <util/window_id.hpp>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/webrequest.h>
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/webrequest.h>
|
||||
#include <wx/wfstream.h>
|
||||
#include <unordered_set>
|
||||
#include <fstream>
|
||||
#include <fstream>
|
||||
|
||||
DECLARE_POINTER_TYPE(ChoiceValue);
|
||||
|
||||
@@ -59,8 +59,8 @@ CardListBase* CardSelectEvent::getTheCardList() const {
|
||||
|
||||
CardListBase::CardListBase(Window* parent, int id, long additional_style)
|
||||
: ItemList(parent, id, additional_style, true)
|
||||
{
|
||||
drop_target = new CardListDropTarget(this);
|
||||
{
|
||||
drop_target = new CardListDropTarget(this);
|
||||
}
|
||||
|
||||
CardListBase::~CardListBase() {
|
||||
@@ -168,7 +168,7 @@ bool CardListBase::doCopy() {
|
||||
bool ok = wxTheClipboard->SetData(new CardsOnClipboard(set, _(""), cards_to_copy)); // ignore result
|
||||
wxTheClipboard->Close();
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::doCopyCardAndLinkedCards() {
|
||||
if (!canCopy()) return false;
|
||||
@@ -194,16 +194,16 @@ bool CardListBase::doCopyCardAndLinkedCards() {
|
||||
bool ok = wxTheClipboard->SetData(new CardsOnClipboard(set, _(""), cards_to_copy)); // ignore result
|
||||
wxTheClipboard->Close();
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::doPaste() {
|
||||
if (!canPaste()) return false;
|
||||
if (!wxTheClipboard->Open()) return false;
|
||||
bool ok = wxTheClipboard->GetData(*drop_target->data_object);
|
||||
wxTheClipboard->Close();
|
||||
if (ok) return parseData(false);
|
||||
wxTheClipboard->Close();
|
||||
if (ok) return parseData(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::doDelete() {
|
||||
// cards to delete
|
||||
@@ -213,7 +213,7 @@ bool CardListBase::doDelete() {
|
||||
// delete cards
|
||||
set->actions.addAction(make_unique<AddCardAction>(REMOVE, *set, cards_to_delete));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::doAddCSV() {
|
||||
AddCSVWindow wnd(this, set, true);
|
||||
@@ -231,7 +231,7 @@ bool CardListBase::doAddJSON() {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::doBulkModification() {
|
||||
BulkModificationWindow wnd(this, set, true);
|
||||
@@ -240,133 +240,133 @@ bool CardListBase::doBulkModification() {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CardListBase::parseUrl(String& url, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
size_t pos = url.find("URL=");
|
||||
if (pos != std::string::npos) {
|
||||
url = url.substr(pos+4);
|
||||
}
|
||||
if (!url.StartsWith(_("http"))) return false;
|
||||
|
||||
WebRequestWindow wnd(url);
|
||||
if (wnd.ShowModal() == wxID_OK) {
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (content_type.StartsWith(_("image"))) {
|
||||
Image img(*wnd.out.GetStream());
|
||||
if (img.IsOk()) {
|
||||
parseImage(img, out);
|
||||
}
|
||||
else {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("web request corrupted"));
|
||||
}
|
||||
}
|
||||
else if (content_type.StartsWith(_("text"))) {
|
||||
String text = wnd.out.AsString();
|
||||
parseText(text, out);
|
||||
}
|
||||
else {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("web request unsupported format"));
|
||||
}
|
||||
}
|
||||
return j < out.size();
|
||||
}
|
||||
}
|
||||
|
||||
bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
bool CardListBase::parseUrl(String& url, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
size_t pos = url.find("URL=");
|
||||
if (pos != std::string::npos) {
|
||||
url = url.substr(pos+4);
|
||||
}
|
||||
if (!url.StartsWith(_("http"))) return false;
|
||||
|
||||
WebRequestWindow wnd(url);
|
||||
if (wnd.ShowModal() == wxID_OK) {
|
||||
const String& content_type = wnd.out.GetContentType();
|
||||
if (content_type.StartsWith(_("image"))) {
|
||||
Image img(*wnd.out.GetStream());
|
||||
if (img.IsOk()) {
|
||||
parseImage(img, out);
|
||||
}
|
||||
else {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("web request corrupted"));
|
||||
}
|
||||
}
|
||||
else if (content_type.StartsWith(_("text"))) {
|
||||
String text = wnd.out.AsString();
|
||||
parseText(text, out);
|
||||
}
|
||||
else {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("web request unsupported format"));
|
||||
}
|
||||
}
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
for (size_t i = 0; i < filenames.size(); i++) {
|
||||
// if it's an image file, try to get meta_data
|
||||
Image image_file;
|
||||
image_file.SetLoadFlags(image_file.GetLoadFlags() & ~wxImage::Load_Verbose);
|
||||
if (image_file.LoadFile(filenames[i])) {
|
||||
Image image_file;
|
||||
image_file.SetLoadFlags(image_file.GetLoadFlags() & ~wxImage::Load_Verbose);
|
||||
if (image_file.LoadFile(filenames[i])) {
|
||||
parseImage(image_file, out);
|
||||
} else {
|
||||
} else {
|
||||
// if it's an url, request the data
|
||||
std::ifstream ifs(filenames[i].ToStdString());
|
||||
std::ifstream ifs(filenames[i].ToStdString());
|
||||
if (ifs.bad() || ifs.fail() || !ifs.good() || !ifs.is_open()) continue;
|
||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
wxString text(content);
|
||||
if (!parseUrl(text, out)) parseText(text, out);
|
||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
wxString text(content);
|
||||
if (!parseUrl(text, out)) parseText(text, out);
|
||||
}
|
||||
}
|
||||
return j < out.size();
|
||||
}
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
auto text = image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION);
|
||||
parseText(text, out);
|
||||
// crop image rects to populate image fields
|
||||
|
||||
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
|
||||
auto text = image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION);
|
||||
parseText(text, out);
|
||||
// crop image rects to populate image fields
|
||||
for (; j < out.size(); j++) {
|
||||
CardP& card = out[j];
|
||||
CardP& card = out[j];
|
||||
for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
|
||||
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
|
||||
if (value && !value->filename.empty()) {
|
||||
wxRect rect = wxRect(0,0,0,0);
|
||||
int degrees = 0;
|
||||
value->filename.getExternalRect(rect, degrees);
|
||||
if (rect.width > 0 && rect.height > 0) {
|
||||
Image img = image.GetSubImage(rect);
|
||||
img = rotate_image(img, deg_to_rad(360-degrees));
|
||||
if (value && !value->filename.empty()) {
|
||||
wxRect rect = wxRect(0,0,0,0);
|
||||
int degrees = 0;
|
||||
value->filename.getExternalRect(rect, degrees);
|
||||
if (rect.width > 0 && rect.height > 0) {
|
||||
Image img = image.GetSubImage(rect);
|
||||
img = rotate_image(img, deg_to_rad(360-degrees));
|
||||
LocalFileName filename = set->newFileName("cropped_image", _(".png")); // a new unique name in the package
|
||||
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
|
||||
value->filename = filename;
|
||||
}
|
||||
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
|
||||
value->filename = filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
}
|
||||
|
||||
bool CardListBase::parseText(String& text, vector<CardP>& out) {
|
||||
size_t j = out.size();
|
||||
if (size_t pos = text.find("<mse-card-data>") != wxString::npos) {
|
||||
text = text.substr(pos + 14, text.find("</mse-card-data>") - pos - 14);
|
||||
}
|
||||
try {
|
||||
ScriptValueP sv = json_to_mse(text, set.get());
|
||||
if (size_t pos = text.find("<mse-card-data>") != wxString::npos) {
|
||||
text = text.substr(pos + 14, text.find("</mse-card-data>") - pos - 14);
|
||||
}
|
||||
try {
|
||||
ScriptValueP sv = json_to_mse(text, set.get());
|
||||
if (sv->type() == SCRIPT_COLLECTION) {
|
||||
if (ScriptCustomCollection* custom = dynamic_cast<ScriptCustomCollection*>(sv.get())) {
|
||||
if (ScriptCustomCollection* custom = dynamic_cast<ScriptCustomCollection*>(sv.get())) {
|
||||
for (size_t i = 0; i < custom->value.size(); i++) {
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(custom->value[i].get())) {
|
||||
out.push_back(make_intrusive<Card>(*c->getValue()));
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(custom->value[i].get())) {
|
||||
out.push_back(make_intrusive<Card>(*c->getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(sv.get())) {
|
||||
out.push_back(make_intrusive<Card>(*c->getValue()));
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
// recreate images to populate image fields
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
// recreate images to populate image fields
|
||||
for (int k = j; k < out.size(); k++) {
|
||||
CardP& card = out[k];
|
||||
CardP& card = out[k];
|
||||
for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
|
||||
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
|
||||
if (value) {
|
||||
Image img = value->filename.getExternalImage();
|
||||
if (img.IsOk()) {
|
||||
if (value) {
|
||||
Image img = value->filename.getExternalImage();
|
||||
if (img.IsOk()) {
|
||||
LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package
|
||||
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
|
||||
value->filename = filename;
|
||||
}
|
||||
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
|
||||
value->filename = filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return j < out.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
wxBusyCursor wait;
|
||||
wxDataFormat format = drop_target->data_object->GetReceivedFormat();
|
||||
wxDataObject *data = drop_target->data_object->GetObject(format);
|
||||
wxDataObject *data = drop_target->data_object->GetObject(format);
|
||||
vector<CardP> new_cards;
|
||||
|
||||
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
|
||||
|
||||
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
|
||||
String id = ignore_cards_from_own_card_list ? drop_target->ignored_id : _("");
|
||||
card_data->getCards(set, id, new_cards);
|
||||
}
|
||||
@@ -374,25 +374,25 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
{
|
||||
case wxDF_FILENAME:
|
||||
{
|
||||
wxFileDataObject* file_data = static_cast<wxFileDataObject*>(data);
|
||||
wxArrayString filenames = file_data->GetFilenames();
|
||||
wxFileDataObject* file_data = static_cast<wxFileDataObject*>(data);
|
||||
wxArrayString filenames = file_data->GetFilenames();
|
||||
parseFiles(filenames, new_cards);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case wxDF_PNG:
|
||||
{
|
||||
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
|
||||
Image image = image_data->GetImage();
|
||||
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
|
||||
Image image = image_data->GetImage();
|
||||
parseImage(image, new_cards);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case wxDF_BITMAP:
|
||||
{
|
||||
{
|
||||
wxBitmapDataObject* bitmap_data = static_cast<wxBitmapDataObject*>(data);
|
||||
wxBitmap bitmap = bitmap_data->GetBitmap();
|
||||
Image image = bitmap.ConvertToImage();
|
||||
wxBitmap bitmap = bitmap_data->GetBitmap();
|
||||
Image image = bitmap.ConvertToImage();
|
||||
parseImage(image, new_cards);
|
||||
}
|
||||
break;
|
||||
@@ -401,24 +401,24 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
|
||||
case wxDF_TEXT:
|
||||
case wxDF_HTML:
|
||||
{
|
||||
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
|
||||
String text = text_data->GetText();
|
||||
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
|
||||
String text = text_data->GetText();
|
||||
if (!parseUrl(text, new_cards)) parseText(text, new_cards);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
{
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("unknown data format"));
|
||||
}
|
||||
}
|
||||
|
||||
if (new_cards.size() > 0) {
|
||||
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (new_cards.size() > 0) {
|
||||
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------- : CardListBase : Card linking
|
||||
|
||||
@@ -624,18 +624,18 @@ void CardListBase::onChar(wxKeyEvent& ev) {
|
||||
} else {
|
||||
ev.Skip();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CardListBase::onBeginDrag(wxListEvent&) {
|
||||
vector<CardP> cards;
|
||||
getSelection(cards);
|
||||
String transaction_id = generate_uid();
|
||||
CardsOnClipboard* card_data = new CardsOnClipboard(set, transaction_id, cards);
|
||||
drop_target->ignored_id = transaction_id;
|
||||
void CardListBase::onBeginDrag(wxListEvent&) {
|
||||
vector<CardP> cards;
|
||||
getSelection(cards);
|
||||
String transaction_id = generate_uid();
|
||||
CardsOnClipboard* card_data = new CardsOnClipboard(set, transaction_id, cards);
|
||||
drop_target->ignored_id = transaction_id;
|
||||
wxDropSource drag_source(this);
|
||||
drag_source.SetData(*card_data);
|
||||
drag_source.DoDragDrop(wxDrag_CopyOnly);
|
||||
}
|
||||
}
|
||||
|
||||
void CardListBase::onDrag(wxMouseEvent& ev) {
|
||||
ev.Skip();
|
||||
@@ -679,31 +679,31 @@ void CardListBase::onItemActivate(wxListEvent& ev) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : CardListDropTarget
|
||||
|
||||
CardListDropTarget::CardListDropTarget(CardListBase* card_list)
|
||||
: card_list(card_list), ignored_id(_(""))
|
||||
{
|
||||
data_object = new wxDataObjectComposite();
|
||||
CardListDropTarget::CardListDropTarget(CardListBase* card_list)
|
||||
: card_list(card_list), ignored_id(_(""))
|
||||
{
|
||||
data_object = new wxDataObjectComposite();
|
||||
data_object->Add(new CardsDataObject(), true);
|
||||
data_object->Add(new wxFileDataObject());
|
||||
data_object->Add(new wxImageDataObject());
|
||||
data_object->Add(new wxTextDataObject());
|
||||
SetDataObject(data_object);
|
||||
SetDataObject(data_object);
|
||||
}
|
||||
|
||||
CardListDropTarget::~CardListDropTarget() {}
|
||||
|
||||
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
|
||||
if (!GetData()) return wxDragNone;
|
||||
if (!card_list->parseData(true)) return wxDragError;
|
||||
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
|
||||
if (!GetData()) return wxDragNone;
|
||||
if (!card_list->parseData(true)) return wxDragError;
|
||||
return wxDragCopy;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : CardListBase : Event table
|
||||
|
||||
BEGIN_EVENT_TABLE(CardListBase, ItemList)
|
||||
EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick)
|
||||
EVT_LIST_COL_END_DRAG (wxID_ANY, CardListBase::onColumnResize)
|
||||
EVT_LIST_ITEM_ACTIVATED (wxID_ANY, CardListBase::onItemActivate)
|
||||
EVT_LIST_ITEM_ACTIVATED (wxID_ANY, CardListBase::onItemActivate)
|
||||
EVT_LIST_BEGIN_DRAG (wxID_ANY, CardListBase::onBeginDrag)
|
||||
EVT_CHAR ( CardListBase::onChar)
|
||||
EVT_MOTION ( CardListBase::onDrag)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <gui/control/item_list.hpp>
|
||||
#include <data/card.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <wx/dnd.h>
|
||||
#include <wx/dnd.h>
|
||||
|
||||
DECLARE_POINTER_TYPE(ChoiceField);
|
||||
DECLARE_POINTER_TYPE(Field);
|
||||
@@ -70,8 +70,8 @@ public:
|
||||
inline void setCard(const CardP& card, bool event = false) { selectItem(card, true, event); }
|
||||
|
||||
// --------------------------------------------------- : Clipboard and Drag'n'Drop
|
||||
|
||||
CardListDropTarget* drop_target;
|
||||
|
||||
CardListDropTarget* drop_target;
|
||||
|
||||
bool canCut() const override;
|
||||
bool canCopy() const override;
|
||||
@@ -81,20 +81,20 @@ public:
|
||||
bool doCopy() override;
|
||||
bool doCopyCardAndLinkedCards();
|
||||
bool doPaste() override;
|
||||
bool doDelete() override;
|
||||
|
||||
bool doDelete() override;
|
||||
|
||||
// Try to perform a bulk operation, return success
|
||||
bool doAddCSV();
|
||||
bool doAddJSON();
|
||||
bool doAddJSON();
|
||||
|
||||
bool doBulkModification();
|
||||
|
||||
// Look for cards inside some given data
|
||||
bool parseData(bool ignore_cards_from_own_card_list);
|
||||
bool parseUrl (String& url, vector<CardP>& out);
|
||||
bool parseFiles(wxArrayString& filenames, vector<CardP>& out);
|
||||
bool parseText (String& text, vector<CardP>& out);
|
||||
bool parseImage(Image& image, vector<CardP>& out);
|
||||
|
||||
// Look for cards inside some given data
|
||||
bool parseData(bool ignore_cards_from_own_card_list);
|
||||
bool parseUrl (String& url, vector<CardP>& out);
|
||||
bool parseFiles(wxArrayString& filenames, vector<CardP>& out);
|
||||
bool parseText (String& text, vector<CardP>& out);
|
||||
bool parseImage(Image& image, vector<CardP>& out);
|
||||
|
||||
// --------------------------------------------------- : Card linking
|
||||
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
void onBeginDrag (wxListEvent&);
|
||||
void onDrag (wxMouseEvent&);
|
||||
void onContextMenu (wxContextMenuEvent&);
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Drag'n'Drop
|
||||
|
||||
@@ -179,12 +179,12 @@ public:
|
||||
CardListDropTarget(CardListBase* card_list);
|
||||
~CardListDropTarget();
|
||||
|
||||
wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) override;
|
||||
wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) override;
|
||||
|
||||
wxDataObjectComposite* data_object; ///< the object that acquires the data from the Clipboard or a Drag'n'Drop
|
||||
wxDataObjectComposite* data_object; ///< the object that acquires the data from the Clipboard or a Drag'n'Drop
|
||||
|
||||
String ignored_id; ///< the id of the transaction we need to ignore (the one coming from our own card_list)
|
||||
private:
|
||||
private:
|
||||
CardListBase* card_list; ///< the card list we are the drop target of
|
||||
};
|
||||
|
||||
|
||||
@@ -42,22 +42,22 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item) {
|
||||
if (d->image.Ok()) {
|
||||
dc.DrawBitmap(d->image, x + int(align_delta_x(ALIGN_CENTER, item_size.x, d->image.GetWidth())), y + 3, true);
|
||||
}
|
||||
// draw short name
|
||||
// draw short name
|
||||
wxFont font = wxFont(11,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_("Arial"));
|
||||
dc.SetFont(font);
|
||||
dc.GetTextExtent(capitalize(d->package->short_name), &w, &h);
|
||||
pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect);
|
||||
dc.DrawText(capitalize(d->package->short_name), max(x+1,(int)pos.x), (int)pos.y + 110);
|
||||
// draw full name
|
||||
// draw full name
|
||||
font.SetPointSize(9);
|
||||
font.SetWeight(wxFONTWEIGHT_NORMAL);
|
||||
dc.SetFont(font);
|
||||
dc.GetTextExtent(d->package->full_name, &w, &h);
|
||||
if (w > item_size.x) {
|
||||
font.SetPointSize(max(7,9*item_size.x/w));
|
||||
dc.GetTextExtent(d->package->full_name, &w, &h);
|
||||
if (w > item_size.x) {
|
||||
font.SetPointSize(max(7,9*item_size.x/w));
|
||||
dc.SetFont(font);
|
||||
dc.GetTextExtent(d->package->full_name, &w, &h);
|
||||
}
|
||||
dc.GetTextExtent(d->package->full_name, &w, &h);
|
||||
}
|
||||
RealPoint text_pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect);
|
||||
dc.DrawText(d->package->full_name, max(x+1,(int)text_pos.x), (int)(text_pos.y + 130 + 9-font.GetPointSize()));
|
||||
dc.DestroyClippingRegion();
|
||||
@@ -92,9 +92,9 @@ void PackageList::showData(const String& pattern) {
|
||||
Image img;
|
||||
Bitmap bmp;
|
||||
if (stream && image_load_file(img, *stream)) {
|
||||
bmp = Bitmap(img);
|
||||
if (bmp.GetWidth() > 150 || bmp.GetHeight() > 150) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_1_("icon too large", p->relativeFilename()));
|
||||
bmp = Bitmap(img);
|
||||
if (bmp.GetWidth() > 150 || bmp.GetHeight() > 150) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_1_("icon too large", p->relativeFilename()));
|
||||
}
|
||||
}
|
||||
// add to list
|
||||
|
||||
@@ -34,11 +34,11 @@ private:
|
||||
|
||||
bool ProcessEvent(wxEvent& ev) override {
|
||||
int t = ev.GetEventType();
|
||||
bool is_tab = false;
|
||||
try {
|
||||
bool is_tab = false;
|
||||
try {
|
||||
is_tab = dynamic_cast<wxKeyEvent&>(ev).GetUnicodeKey() == WXK_TAB;
|
||||
} catch (...) {}
|
||||
if ( is_tab
|
||||
if ( is_tab
|
||||
|| t == wxEVT_LEFT_DOWN || t == wxEVT_RIGHT_DOWN
|
||||
|| t == wxEVT_MOVE
|
||||
|| t == wxEVT_MENU_HIGHLIGHT || t == wxEVT_MENU_OPEN
|
||||
|
||||
@@ -482,7 +482,7 @@ void ImageSlicePreview::draw(DC& dc) {
|
||||
assert(image.GetWidth() == slice.target_size.GetWidth() && image.GetHeight() == slice.target_size.GetHeight());
|
||||
mask.setAlpha(image);
|
||||
if (image.HasAlpha()) {
|
||||
// create bitmap
|
||||
// create bitmap
|
||||
int width = image.GetWidth(), height = image.GetHeight();
|
||||
bitmap = Bitmap(width, height);
|
||||
wxMemoryDC mdc; mdc.SelectObject(bitmap);
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
Color background; ///< Color for areas outside the source image
|
||||
bool allow_outside; ///< Allow the slice to extend outside the source image? TODO: This currently crashes
|
||||
bool aspect_fixed; ///< Aspect ratio lock?
|
||||
|
||||
|
||||
// Filters
|
||||
bool sharpen;
|
||||
int sharpen_amount;
|
||||
@@ -71,9 +71,9 @@ public:
|
||||
Image getImage() const;
|
||||
|
||||
// --------------------------------------------------- : Previously Used Settings
|
||||
|
||||
static map<String, String> previously_used_settings_path; // map from cardname to filename
|
||||
static map<pair<String, String>, pair<wxRect, int>> previously_used_settings_value; // map from filename+cardname pair to settings
|
||||
|
||||
static map<String, String> previously_used_settings_path; // map from cardname to filename
|
||||
static map<pair<String, String>, pair<wxRect, int>> previously_used_settings_value; // map from filename+cardname pair to settings
|
||||
|
||||
// --------------------------------------------------- : Data
|
||||
private:
|
||||
@@ -133,8 +133,8 @@ public:
|
||||
|
||||
/// Notify that the slice was updated
|
||||
void update();
|
||||
|
||||
int grid;
|
||||
|
||||
int grid;
|
||||
|
||||
// --------------------------------------------------- : Data
|
||||
private:
|
||||
|
||||
@@ -219,7 +219,7 @@ void PackageUpdateList::initItems() {
|
||||
if (p && p->description->icon.Ok()) { // it has an icon
|
||||
ti.setIcon(p->description->icon);
|
||||
} else if (p) { // it doesn't have an icon (yet)
|
||||
ti.setIcon(load_resource_image(_("installer_package")));
|
||||
ti.setIcon(load_resource_image(_("installer_package")));
|
||||
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
|
||||
|
||||
@@ -168,10 +168,10 @@ GlobalPreferencesPage::GlobalPreferencesPage(Window* parent)
|
||||
}
|
||||
n++;
|
||||
}
|
||||
open_sets_in_new_window->SetValue(settings.open_sets_in_new_window);
|
||||
dark_mode->Append(_LABEL_("dark mode system"));
|
||||
dark_mode->Append(_LABEL_("dark mode no"));
|
||||
dark_mode->Append(_LABEL_("dark mode yes"));
|
||||
open_sets_in_new_window->SetValue(settings.open_sets_in_new_window);
|
||||
dark_mode->Append(_LABEL_("dark mode system"));
|
||||
dark_mode->Append(_LABEL_("dark mode no"));
|
||||
dark_mode->Append(_LABEL_("dark mode yes"));
|
||||
dark_mode->SetSelection((int)settings.dark_mode_type);
|
||||
// init sizer
|
||||
wxSizer* s = new wxBoxSizer(wxVERTICAL);
|
||||
@@ -285,22 +285,22 @@ TransfersPreferencesPage::TransfersPreferencesPage(Window* parent) : Preferences
|
||||
non_normal_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("rotation export"));
|
||||
bleed_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("bleed export"));
|
||||
notes_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("notes export"));
|
||||
export_scale = new wxChoice (this, ID_EXPORT_ZOOM);
|
||||
|
||||
export_scale = new wxChoice (this, ID_EXPORT_ZOOM);
|
||||
|
||||
allow_image_download = new wxCheckBox(this, wxID_ANY, _BUTTON_("allow image download"));
|
||||
import_scale = new wxChoice (this, ID_IMPORT_ZOOM);
|
||||
|
||||
|
||||
// set values
|
||||
non_normal_export-> SetValue(!settings.default_stylesheet_settings.card_normal_export());
|
||||
bleed_export-> SetValue( settings.default_stylesheet_settings.card_bleed_export());
|
||||
notes_export-> SetValue( settings.default_stylesheet_settings.card_notes_export());
|
||||
export_scale->Append(_LABEL_("export around 300"));
|
||||
export_scale->Append(_LABEL_("export force 300"));
|
||||
export_scale->Append(_LABEL_("export force 150"));
|
||||
export_scale->Append(_LABEL_("export force 150"));
|
||||
for (int i : Settings::scale_choices) {
|
||||
export_scale->Append(String::Format(_("%d%%"), i));
|
||||
}
|
||||
int default_export_scale = settings.default_stylesheet_settings.export_scale_selection();
|
||||
}
|
||||
int default_export_scale = settings.default_stylesheet_settings.export_scale_selection();
|
||||
if (default_export_scale < 0 || default_export_scale > (int)export_scale->GetCount() - 1) default_export_scale = 0;
|
||||
export_scale->SetSelection(default_export_scale);
|
||||
|
||||
@@ -311,13 +311,13 @@ TransfersPreferencesPage::TransfersPreferencesPage(Window* parent) : Preferences
|
||||
import_scale->Append(_LABEL_("export force 150"));
|
||||
for (int i : Settings::scale_choices) {
|
||||
import_scale->Append(String::Format(_("%d%%"), i));
|
||||
}
|
||||
int default_import_scale = settings.import_scale_selection;
|
||||
}
|
||||
int default_import_scale = settings.import_scale_selection;
|
||||
if (default_import_scale < 0 || default_import_scale > import_scale->GetCount() - 1) default_import_scale = 0;
|
||||
import_scale->SetSelection(default_import_scale);
|
||||
|
||||
|
||||
// init sizers
|
||||
wxSizer* s = new wxBoxSizer(wxVERTICAL);
|
||||
wxSizer* s = new wxBoxSizer(wxVERTICAL);
|
||||
wxSizer* s2 = new wxStaticBoxSizer(wxVERTICAL, this, _LABEL_("export"));
|
||||
s2->Add(new wxStaticText(this, wxID_ANY, _LABEL_("export desc")), 0, wxALL & ~wxLEFT, 4);
|
||||
wxSizer* s3 = new wxBoxSizer(wxHORIZONTAL);
|
||||
@@ -348,9 +348,9 @@ void TransfersPreferencesPage::store() {
|
||||
settings.default_stylesheet_settings.card_normal_export = !non_normal_export->GetValue();
|
||||
settings.default_stylesheet_settings.card_bleed_export = bleed_export->GetValue();
|
||||
settings.default_stylesheet_settings.card_notes_export = notes_export->GetValue();
|
||||
settings.default_stylesheet_settings.export_scale_selection = export_scale->GetSelection();
|
||||
settings.default_stylesheet_settings.export_scale_selection = export_scale->GetSelection();
|
||||
|
||||
settings.allow_image_download = allow_image_download->GetValue();
|
||||
settings.allow_image_download = allow_image_download->GetValue();
|
||||
settings.import_scale_selection = import_scale->GetSelection();
|
||||
}
|
||||
|
||||
|
||||
+33
-33
@@ -22,64 +22,64 @@ DECLARE_POINTER_TYPE(PrintJob);
|
||||
|
||||
class PrintJob : public IntrusivePtrBase<PrintJob> {
|
||||
public:
|
||||
PrintJob(const SetP& set, const vector<CardP>& cards)
|
||||
PrintJob(const SetP& set, const vector<CardP>& cards)
|
||||
: set(set), cards(cards) {
|
||||
default_size_mm.width = set->stylesheet->card_width * 25.4 / set->stylesheet->card_dpi;
|
||||
default_size_mm.height = set->stylesheet->card_height * 25.4 / set->stylesheet->card_dpi;
|
||||
|
||||
threshold_top = 0.75 * default_size_mm.width;
|
||||
threshold_bottom = 0.1;
|
||||
threshold_size = RealSize(0.03 * default_size_mm.width, 0.03 * default_size_mm.height);
|
||||
default_size_mm.height = set->stylesheet->card_height * 25.4 / set->stylesheet->card_dpi;
|
||||
|
||||
threshold_top = 0.75 * default_size_mm.width;
|
||||
threshold_bottom = 0.1;
|
||||
threshold_size = RealSize(0.03 * default_size_mm.width, 0.03 * default_size_mm.height);
|
||||
}
|
||||
|
||||
SetP set;
|
||||
vector<CardP> cards; ///< Cards selected by the user for print
|
||||
RealSize default_size_mm; ///< Size of a card with the default stylesheet in millimetres, without bleed
|
||||
|
||||
// align cards that are at most this far appart in millimeters
|
||||
double threshold_top;
|
||||
// consider cards that are this close to already be aligned
|
||||
double threshold_bottom;
|
||||
// snap cards that are within this to the default size
|
||||
|
||||
// align cards that are at most this far appart in millimeters
|
||||
double threshold_top;
|
||||
// consider cards that are this close to already be aligned
|
||||
double threshold_bottom;
|
||||
// snap cards that are within this to the default size
|
||||
RealSize threshold_size;
|
||||
|
||||
struct CardLayout {
|
||||
CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, double bleed_size_px, Radians rotation)
|
||||
: card(card), size_mm(size_mm), size_px(size_px), bleed_size_px(bleed_size_px), rot(rotation), other_face(-1) {}
|
||||
|
||||
|
||||
struct CardLayout {
|
||||
CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, double bleed_size_px, Radians rotation)
|
||||
: card(card), size_mm(size_mm), size_px(size_px), bleed_size_px(bleed_size_px), rot(rotation), other_face(-1) {}
|
||||
|
||||
bool operator<(const CardLayout& that) const {
|
||||
return size_mm.width > that.size_mm.width; // put the widest cards first
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CardP card;
|
||||
RealSize size_mm;
|
||||
RealSize size_px;
|
||||
double bleed_size_px;
|
||||
Radians rot;
|
||||
double bleed_size_px;
|
||||
Radians rot;
|
||||
RealSize pos;
|
||||
int other_face;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void init(const RealSize& page_size);
|
||||
|
||||
RealSize page_size; ///< Size of a page in millimetres
|
||||
vector<CardLayout> card_layouts; ///< Locations of the cards on the pages
|
||||
vector<CardLayout> sorted_layouts; ///< Same as card_layouts, but sorted from widest to narrowest
|
||||
vector<vector<CardLayout>> page_layouts; ///< The CardLayout grouped by page
|
||||
vector<RealSize> page_margins; ///< The empty space on the sides of the pages
|
||||
vector<CardLayout> card_layouts; ///< Locations of the cards on the pages
|
||||
vector<CardLayout> sorted_layouts; ///< Same as card_layouts, but sorted from widest to narrowest
|
||||
vector<vector<CardLayout>> page_layouts; ///< The CardLayout grouped by page
|
||||
vector<RealSize> page_margins; ///< The empty space on the sides of the pages
|
||||
|
||||
/// Is this job uninitialized?
|
||||
inline bool empty() const { return page_layouts.empty(); }
|
||||
|
||||
inline bool empty() const { return page_layouts.empty(); }
|
||||
|
||||
private:
|
||||
// calculate the width and height of each card in millimeters
|
||||
// calculate the width and height of each card in millimeters
|
||||
void measure_cards();
|
||||
CardLayout measure_card(const CardP& card);
|
||||
// calculate where the cards go on the pages
|
||||
// calculate where the cards go on the pages
|
||||
void layout_cards();
|
||||
// if two cards are almost aligned, align them
|
||||
// if two cards are almost aligned, align them
|
||||
void align_cards();
|
||||
// center the cards on the middle of each page
|
||||
// center the cards on the middle of each page
|
||||
void center_cards();
|
||||
};
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ CardsPanel::CardsPanel(Window* parent, int id)
|
||||
collapse_notes = new HoverButton(nodes_panel, ID_COLLAPSE_NOTES, _("btn_collapse"), Color(), false);
|
||||
collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES);
|
||||
filter = nullptr;
|
||||
editor->next_in_tab_order = card_list;
|
||||
SetDropTarget(card_list->drop_target);
|
||||
editor->next_in_tab_order = card_list;
|
||||
SetDropTarget(card_list->drop_target);
|
||||
wxFont font = link_relation_1->GetFont();
|
||||
font.SetWeight(wxFONTWEIGHT_BOLD);
|
||||
link_relation_1->SetFont(font);
|
||||
@@ -152,8 +152,8 @@ CardsPanel::CardsPanel(Window* parent, int id)
|
||||
|
||||
menuFormat = new wxMenu();
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", wxITEM_CHECK);
|
||||
@@ -286,8 +286,8 @@ wxMenu* CardsPanel::makeAddCardsSubmenu(bool add_single_card_option) {
|
||||
void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||
// Toolbar
|
||||
add_tool_tr(tb, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", false, wxITEM_CHECK);
|
||||
@@ -455,7 +455,7 @@ void CardsPanel::onCommand(int id) {
|
||||
}
|
||||
case ID_CARD_AND_LINK_COPY:
|
||||
card_list->doCopyCardAndLinkedCards();
|
||||
break;
|
||||
break;
|
||||
case ID_CARD_BULK:
|
||||
card_list->doBulkModification();
|
||||
break;
|
||||
|
||||
@@ -103,9 +103,9 @@ private:
|
||||
bool notes_below_editor;
|
||||
|
||||
/// Update card counts
|
||||
void updateCardCounts();
|
||||
int selected_cards_count = 0;
|
||||
int filtered_cards_count = 0;
|
||||
void updateCardCounts();
|
||||
int selected_cards_count = 0;
|
||||
int filtered_cards_count = 0;
|
||||
int total_cards_count = 0;
|
||||
/// Move the notes panel below the editor or below the card list
|
||||
void updateNotesPosition();
|
||||
|
||||
@@ -35,8 +35,8 @@ void SetInfoPanel::onChangeSet() {
|
||||
void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||
// Toolbar
|
||||
add_tool_tr(tb, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", false, wxITEM_CHECK);
|
||||
add_tool_tr(tb, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", false, wxITEM_CHECK);
|
||||
@@ -44,8 +44,8 @@ void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||
// Menus
|
||||
auto menuFormat = new wxMenu();
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", wxITEM_CHECK);
|
||||
add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", wxITEM_CHECK);
|
||||
|
||||
+22
-22
@@ -185,21 +185,21 @@ protected:
|
||||
private:
|
||||
GameP game;
|
||||
bool show_empty;
|
||||
vector<StatsDimensionP> dimensions; ///< Dimensions, sorted by position_hint
|
||||
vector<StatsDimensionP> dimensions; ///< Dimensions, sorted by position_hint
|
||||
|
||||
static const int NAME_COLUMN_WIDTH = 210;
|
||||
static const int DIMENSION_COLUMN_WIDTH = 18;
|
||||
static const int COLUMN_HEIGHT = 23;
|
||||
|
||||
static const int COLUMN_HEIGHT = 23;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
void onMotion(wxMouseEvent& ev) {
|
||||
void onMotion(wxMouseEvent& ev) {
|
||||
wxFrame* frame = dynamic_cast<wxFrame*>(wxGetTopLevelParent(this));
|
||||
if (frame) frame->SetStatusText(dimensions[findItem(ev)]->description.get());
|
||||
if (frame) frame->SetStatusText(dimensions[findItem(ev)]->description.get());
|
||||
}
|
||||
void onMouseLeave(wxMouseEvent& ev) {
|
||||
void onMouseLeave(wxMouseEvent& ev) {
|
||||
wxFrame* frame = dynamic_cast<wxFrame*>(wxGetTopLevelParent(this));
|
||||
if (frame) frame->SetStatusText(String());
|
||||
if (frame) frame->SetStatusText(String());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -243,11 +243,11 @@ void StatDimensionList::drawItem(DC& dc, int x, int y, size_t item) {
|
||||
}
|
||||
StatsDimension& dim = *dimensions.at(item - show_empty);
|
||||
// draw icon
|
||||
if(!dim.icon.Ok()) {
|
||||
String filename = dim.icon_filename;
|
||||
if(!dim.icon.Ok()) {
|
||||
String filename = dim.icon_filename;
|
||||
if (settings.darkMode() && !dim.dark_icon_filename.empty()) {
|
||||
filename = dim.dark_icon_filename;
|
||||
}
|
||||
}
|
||||
if (!filename.empty()) {
|
||||
auto file = game->openIn(filename);
|
||||
Image img(*file);
|
||||
@@ -493,12 +493,12 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
|
||||
dim->groups.empty() ? nullptr : &dim->groups
|
||||
)
|
||||
);
|
||||
}
|
||||
// find global_script values
|
||||
vector<ScriptValueP> global_values;
|
||||
Context& global_ctx = set->getContext();
|
||||
ScriptValueP global_ctx_value = global_ctx.getVariableOpt("global_value");
|
||||
for (size_t d = 0 ; d < dims.size() ; ++d) {
|
||||
}
|
||||
// find global_script values
|
||||
vector<ScriptValueP> global_values;
|
||||
Context& global_ctx = set->getContext();
|
||||
ScriptValueP global_ctx_value = global_ctx.getVariableOpt("global_value");
|
||||
for (size_t d = 0 ; d < dims.size() ; ++d) {
|
||||
auto& dim = dims[d];
|
||||
try {
|
||||
ScriptValueP global_value = dim->global_script.invoke(global_ctx);
|
||||
@@ -513,7 +513,7 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
|
||||
Context& ctx = set->getContext(set->cards[i]);
|
||||
GraphElementP e = make_intrusive<GraphElement>(i);
|
||||
bool show = true;
|
||||
for (size_t d = 0 ; d < dims.size() ; ++d) {
|
||||
for (size_t d = 0 ; d < dims.size() ; ++d) {
|
||||
auto& dim = dims[d];
|
||||
ctx.setVariable("global_value", global_values[d]);
|
||||
try {
|
||||
@@ -534,8 +534,8 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
|
||||
assert(e->values.size() == dims.size());
|
||||
d.elements.push_back(e);
|
||||
}
|
||||
}
|
||||
// restore old global value if any
|
||||
}
|
||||
// restore old global value if any
|
||||
if (global_ctx_value) global_ctx.setVariable("global_value", global_ctx_value);
|
||||
// split lists
|
||||
size_t dim_id = 0;
|
||||
@@ -590,14 +590,14 @@ void StatsPanel::filterCards() {
|
||||
|
||||
BEGIN_EVENT_TABLE(StatsPanel, wxPanel)
|
||||
EVT_GRAPH_SELECT(wxID_ANY, StatsPanel::onGraphSelect)
|
||||
END_EVENT_TABLE()
|
||||
END_EVENT_TABLE()
|
||||
|
||||
#if USE_DIMENSION_LISTS
|
||||
#if USE_DIMENSION_LISTS
|
||||
BEGIN_EVENT_TABLE(StatDimensionList, GalleryList)
|
||||
EVT_MOTION(StatDimensionList::onMotion)
|
||||
EVT_LEAVE_WINDOW(StatDimensionList::onMouseLeave)
|
||||
END_EVENT_TABLE()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------- : Selection
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ END_EVENT_TABLE()
|
||||
|
||||
DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
|
||||
: DropDownChoiceListBase(parent, is_submenu, cve, group)
|
||||
{
|
||||
{
|
||||
// determine if slider
|
||||
if (itemCount() > 1 && field().is_slider) {
|
||||
is_slider = true;
|
||||
|
||||
@@ -51,17 +51,17 @@ bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) {
|
||||
void ImageValueEditor::sliceImage(const Image& image, const String& filename, const String& cardname) {
|
||||
if (!image.Ok()) return;
|
||||
// determine import scale based on the user's settings.
|
||||
double import_scale = 1.0;
|
||||
StyleSheetP stylesheet = editor().getCard()->stylesheet;
|
||||
if (!stylesheet) stylesheet = editor().getSet()->stylesheet;
|
||||
if (stylesheet) import_scale = settings.importScaleSettingsFor(*stylesheet);
|
||||
RealSize target_size = RealSize(style().getSize() * import_scale);
|
||||
target_size = RealSize((int)target_size.width, (int)target_size.height);
|
||||
double import_scale = 1.0;
|
||||
StyleSheetP stylesheet = editor().getCard()->stylesheet;
|
||||
if (!stylesheet) stylesheet = editor().getSet()->stylesheet;
|
||||
if (stylesheet) import_scale = settings.importScaleSettingsFor(*stylesheet);
|
||||
RealSize target_size = RealSize(style().getSize() * import_scale);
|
||||
target_size = RealSize((int)target_size.width, (int)target_size.height);
|
||||
// mask
|
||||
GeneratedImage::Options options((int)target_size.width, (int)target_size.height, &parent.getStylePackage(), &parent.getLocalPackage());
|
||||
AlphaMask mask;
|
||||
style().mask.getNoCache(options, mask);
|
||||
// slice
|
||||
// slice
|
||||
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, filename, cardname, target_size, mask);
|
||||
// clicked ok?
|
||||
if (s.ShowModal() == wxID_OK) {
|
||||
|
||||
@@ -44,7 +44,7 @@ void SymbolValueEditor::drawButton(RotatedDC& dc, int button, const String& text
|
||||
double y = 0;
|
||||
// draw button
|
||||
draw_button(&editor(), dc.getDC(), dc.trRectToBB(RealRect(x,y,width,height)), false, down, true);
|
||||
// draw text
|
||||
// draw text
|
||||
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
|
||||
RealSize text_size = dc.GetTextExtent(text);
|
||||
dc.DrawText(text, align_in_rect((Alignment)(ALIGN_BOTTOM | ALIGN_CENTER), text_size, RealRect(x, y, width,height*0.9)));
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ int MSE::OnRun() {
|
||||
cli.init();
|
||||
package_manager.init();
|
||||
settings.read();
|
||||
SetAppearance((Appearance)settings.dark_mode_type);
|
||||
SetAppearance((Appearance)settings.dark_mode_type);
|
||||
the_locale = Locale::byName(settings.locale);
|
||||
nag_about_ascii_version();
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
// ----------------------------------------------------------------------------- : CompoundTextElement
|
||||
|
||||
void CompoundTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end, bool native_look) const {
|
||||
void CompoundTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end, bool native_look) const {
|
||||
for (auto const& e : children) {
|
||||
size_t start_ = max(start, e->start);
|
||||
size_t end_ = min(end, e->end);
|
||||
|
||||
@@ -19,15 +19,15 @@ void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, co
|
||||
if (!text.empty() && text.GetChar(text.size() - 1) == _('\n')) {
|
||||
text = text.substr(0, text.size() - 1); // don't draw last \n
|
||||
}
|
||||
// draw
|
||||
Color font_color = font->color;
|
||||
RealSize margin(0, 0);
|
||||
if (native_look) {
|
||||
font->color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
// draw
|
||||
Color font_color = font->color;
|
||||
RealSize margin(0, 0);
|
||||
if (native_look) {
|
||||
font->color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
}
|
||||
dc.SetFont(*font, scale);
|
||||
dc.DrawTextWithShadow(text, *font, rect.position() + margin);
|
||||
dc.DrawTextWithShadow(text, *font, rect.position() + margin);
|
||||
if (native_look) font->color = font_color;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ bool ChoiceValueViewer::prepare(RotatedDC& dc) {
|
||||
}
|
||||
void ChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
drawFieldBorder(dc);
|
||||
if (style().render_style & RENDER_HIDDEN) return;
|
||||
// render background
|
||||
if (style().render_style & RENDER_HIDDEN) return;
|
||||
// render background
|
||||
if (nativeLook()) {
|
||||
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
@@ -107,17 +107,17 @@ void draw_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style,
|
||||
Alignment text_align = style.alignment;
|
||||
if (style.render_style & RENDER_IMAGE) {
|
||||
text_align = ALIGN_MIDDLE_LEFT; // can't align both text and image in the same way
|
||||
}
|
||||
}
|
||||
Font& font = style.font;
|
||||
Color font_color = font.color;
|
||||
if (viewer.nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin += 1.;
|
||||
Color font_color = font.color;
|
||||
if (viewer.nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin += 1.;
|
||||
}
|
||||
dc.SetFont(font, 1.0);
|
||||
RealSize size = dc.GetTextExtent(text);
|
||||
RealPoint text_pos = align_in_rect(text_align, size, dc.getInternalRect()) + RealSize(margin, 0);
|
||||
dc.DrawTextWithShadow(text, font, text_pos);
|
||||
dc.DrawTextWithShadow(text, font, text_pos);
|
||||
if (viewer.nativeLook()) font.color = font_color;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@ void ColorValueViewer::draw(RotatedDC& dc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// draw background
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
dc.DrawRectangle(RealRect(40, 0, dc.getWidth()-40, dc.getHeight()));
|
||||
// draw color
|
||||
// draw color
|
||||
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
|
||||
dc.SetBrush(value().value());
|
||||
dc.DrawRectangle(RealRect(0, 0, 40, dc.getHeight()));
|
||||
|
||||
@@ -24,13 +24,13 @@ bool MultipleChoiceValueViewer::prepare(RotatedDC& dc) {
|
||||
void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
drawFieldBorder(dc);
|
||||
if (style().render_style & RENDER_HIDDEN) return;
|
||||
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), dc.getInternalRect());
|
||||
// render background
|
||||
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), dc.getInternalRect());
|
||||
// render background
|
||||
if (nativeLook()) {
|
||||
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
|
||||
}
|
||||
}
|
||||
// selected choices
|
||||
vector<String> selected;
|
||||
value().get(selected);
|
||||
@@ -44,7 +44,7 @@ void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
if (active) select_it++;
|
||||
drawChoice(dc, pos, choice, active);
|
||||
}
|
||||
} else if (style().render_style & RENDER_LIST) {
|
||||
} else if (style().render_style & RENDER_LIST) {
|
||||
// render only selected choices
|
||||
FOR_EACH(choice, selected) {
|
||||
drawChoice(dc, pos, choice);
|
||||
@@ -76,21 +76,21 @@ void MultipleChoiceValueViewer::drawChoice(RotatedDC& dc, RealPoint& pos, const
|
||||
}
|
||||
}
|
||||
if (style().render_style & RENDER_TEXT) {
|
||||
// draw text
|
||||
// draw text
|
||||
Font& font = style().font;
|
||||
Color font_color = font.color;
|
||||
RealSize margin(0, 0);
|
||||
if (nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
Color font_color = font.color;
|
||||
RealSize margin(0, 0);
|
||||
if (nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
}
|
||||
String text = tr(getStylePackage(), choice, capitalize_sentence);
|
||||
dc.SetFont(font,1);
|
||||
RealSize text_size = dc.GetTextExtent(text);
|
||||
RealPoint text_pos = align_in_rect(ALIGN_MIDDLE_LEFT, text_size, RealRect(pos.x + size.width + 1, pos.y, 0,size.height)) + margin;
|
||||
RealPoint text_pos = align_in_rect(ALIGN_MIDDLE_LEFT, text_size, RealRect(pos.x + size.width + 1, pos.y, 0,size.height)) + margin;
|
||||
dc.DrawTextWithShadow(text, font, text_pos);
|
||||
size = add_horizontal(size, text_size);
|
||||
if (nativeLook()) font.color = font_color;
|
||||
if (nativeLook()) font.color = font_color;
|
||||
}
|
||||
// next position
|
||||
pos = move_in_direction(style().direction, pos, size, style().spacing);
|
||||
|
||||
@@ -43,9 +43,9 @@ void PackageChoiceValueViewer::initItems() {
|
||||
}
|
||||
|
||||
void PackageChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
drawFieldBorder(dc);
|
||||
// draw background
|
||||
if (nativeLook()) {
|
||||
drawFieldBorder(dc);
|
||||
// draw background
|
||||
if (nativeLook()) {
|
||||
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
|
||||
@@ -67,16 +67,16 @@ void PackageChoiceValueViewer::draw(RotatedDC& dc) {
|
||||
if (image.Ok()) {
|
||||
dc.DrawBitmap(image, RealPoint(0,0));
|
||||
}
|
||||
// draw text
|
||||
// draw text
|
||||
Font& font = style().font;
|
||||
Color font_color = font.color;
|
||||
RealSize margin(0, 0);
|
||||
if (nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
Color font_color = font.color;
|
||||
RealSize margin(0, 0);
|
||||
if (nativeLook()) {
|
||||
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
margin = RealSize(1., 0);
|
||||
}
|
||||
dc.SetFont(font, 1.0);
|
||||
RealPoint pos = align_in_rect(ALIGN_MIDDLE_LEFT, RealSize(0, dc.GetCharHeight()), dc.getInternalRect()) + RealSize(17., 0) + margin;
|
||||
dc.DrawTextWithShadow(text, font, pos);
|
||||
dc.DrawTextWithShadow(text, font, pos);
|
||||
if (nativeLook()) font.color = font_color;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ bool TextValueViewer::prepare(RotatedDC& dc) {
|
||||
}
|
||||
|
||||
void TextValueViewer::draw(RotatedDC& dc) {
|
||||
drawFieldBorder(dc);
|
||||
// draw background
|
||||
if (nativeLook()) {
|
||||
drawFieldBorder(dc);
|
||||
// draw background
|
||||
if (nativeLook()) {
|
||||
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
|
||||
|
||||
+109
-109
@@ -764,7 +764,7 @@ SCRIPT_FUNCTION(get_card_export_settings) {
|
||||
ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(input.get());
|
||||
ScriptObject<Set*>* s = dynamic_cast<ScriptObject<Set*>*>(set.get());
|
||||
if (s && c) {
|
||||
Settings::ExportSettings card_settings = settings.exportSettingsFor(s->getValue()->stylesheetFor(c->getValue()));
|
||||
Settings::ExportSettings card_settings = settings.exportSettingsFor(s->getValue()->stylesheetFor(c->getValue()));
|
||||
ScriptCustomCollectionP ret(new ScriptCustomCollection());
|
||||
ret->value.push_back(to_script(lround(card_settings.zoom * 100)));
|
||||
ret->value.push_back(to_script(lround(rad_to_deg(card_settings.angle_radians))));
|
||||
@@ -782,148 +782,148 @@ SCRIPT_FUNCTION(get_card_from_uid) {
|
||||
|
||||
SCRIPT_FUNCTION(get_cards_from_link) {
|
||||
SCRIPT_PARAM_C(Set*, set);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
SCRIPT_PARAM(String, linked_relation);
|
||||
ScriptCustomCollectionP ret(new ScriptCustomCollection());
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation, true);
|
||||
if (other_cards.size() > 0) {
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
ScriptCustomCollectionP ret(new ScriptCustomCollection());
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation, true);
|
||||
if (other_cards.size() > 0) {
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
}
|
||||
else if (set->game->card_links_alt_names.find(linked_relation) != set->game->card_links_alt_names.end()) {
|
||||
other_cards = input_card->getLinkedCardsFromLink(*set, set->game->card_links_alt_names[linked_relation], true);
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
}
|
||||
else if (set->game->card_links_alt_names.find(linked_relation) != set->game->card_links_alt_names.end()) {
|
||||
other_cards = input_card->getLinkedCardsFromLink(*set, set->game->card_links_alt_names[linked_relation], true);
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(get_front_face) {
|
||||
SCRIPT_PARAM_C(Set*, set);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Front Face", true);
|
||||
if (other_cards.size() == 0) return script_nil;
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Front Face", true);
|
||||
if (other_cards.size() == 0) return script_nil;
|
||||
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple front faces", input_card->identification()));
|
||||
SCRIPT_RETURN(other_cards[0]);
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(get_back_face) {
|
||||
SCRIPT_PARAM_C(Set*, set);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Back Face", true);
|
||||
if (other_cards.size() == 0) return script_nil;
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Back Face", true);
|
||||
if (other_cards.size() == 0) return script_nil;
|
||||
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple back faces", input_card->identification()));
|
||||
SCRIPT_RETURN(other_cards[0]);
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(add_link) {
|
||||
SCRIPT_PARAM_C(Set*, set);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
SCRIPT_PARAM(ScriptValueP, linked_card);
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return script_nil;
|
||||
}
|
||||
SCRIPT_PARAM(ScriptValueP, linked_card);
|
||||
CardP other_card = nullptr;
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
|
||||
other_card = c->getValue();
|
||||
}
|
||||
else if (linked_card->type() == SCRIPT_STRING) {
|
||||
other_card = Card::getCardFromUid(*set, linked_card->toString());
|
||||
}
|
||||
if (!other_card) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
|
||||
return script_nil;
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
|
||||
other_card = c->getValue();
|
||||
}
|
||||
else if (linked_card->type() == SCRIPT_STRING) {
|
||||
other_card = Card::getCardFromUid(*set, linked_card->toString());
|
||||
}
|
||||
if (!other_card) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
|
||||
return script_nil;
|
||||
}
|
||||
SCRIPT_PARAM(String, selected_relation);
|
||||
SCRIPT_PARAM(String, linked_relation);
|
||||
input_card->link(*set, other_card, selected_relation, linked_relation);
|
||||
SCRIPT_PARAM(String, linked_relation);
|
||||
input_card->link(*set, other_card, selected_relation, linked_relation);
|
||||
SCRIPT_RETURN(other_card);
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(remove_links) {
|
||||
SCRIPT_PARAM_C(Set*, set);
|
||||
ScriptCustomCollectionP ret(new ScriptCustomCollection());
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return ret;
|
||||
}
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
CardP input_card = nullptr;
|
||||
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
|
||||
input_card = ic->getValue();
|
||||
}
|
||||
else if (input->type() == SCRIPT_STRING) {
|
||||
input_card = Card::getCardFromUid(*set, input->toString());
|
||||
}
|
||||
if (!input_card) {
|
||||
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
|
||||
return ret;
|
||||
}
|
||||
vector<CardP> other_cards;
|
||||
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_card, script_nil);
|
||||
if (linked_card != script_nil) {
|
||||
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_card, script_nil);
|
||||
if (linked_card != script_nil) {
|
||||
CardP other_card = nullptr;
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
|
||||
other_card = c->getValue();
|
||||
}
|
||||
else if (linked_card->type() == SCRIPT_STRING) {
|
||||
other_card = Card::getCardFromUid(*set, linked_card->toString());
|
||||
}
|
||||
if (!other_card) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
|
||||
}
|
||||
else other_cards.push_back(other_card);
|
||||
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
|
||||
other_card = c->getValue();
|
||||
}
|
||||
else if (linked_card->type() == SCRIPT_STRING) {
|
||||
other_card = Card::getCardFromUid(*set, linked_card->toString());
|
||||
}
|
||||
if (!other_card) {
|
||||
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
|
||||
}
|
||||
else other_cards.push_back(other_card);
|
||||
}
|
||||
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_relation, script_nil);
|
||||
if (linked_relation != script_nil) {
|
||||
if (linked_relation->type() == SCRIPT_STRING) {
|
||||
vector<CardP> other_other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation->toString(), true);
|
||||
other_cards.insert(other_cards.end(), other_other_cards.begin(), other_other_cards.end());
|
||||
if (linked_relation != script_nil) {
|
||||
if (linked_relation->type() == SCRIPT_STRING) {
|
||||
vector<CardP> other_other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation->toString(), true);
|
||||
other_cards.insert(other_cards.end(), other_other_cards.begin(), other_other_cards.end());
|
||||
}
|
||||
}
|
||||
input_card->unlink(other_cards);
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
}
|
||||
input_card->unlink(other_cards);
|
||||
FOR_EACH(other_card, other_cards) {
|
||||
ret->value.push_back(to_script(other_card));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,16 @@ SCRIPT_FUNCTION(new_card) {
|
||||
// create a new card object
|
||||
CardP new_card = make_intrusive<Card>(*game);
|
||||
// iterate on the given key/value pairs
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
// check for a stylesheet first, since other things depend on it
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
// check for a stylesheet first, since other things depend on it
|
||||
ScriptValueP it = input->makeIterator();
|
||||
ScriptValueP key;
|
||||
while (ScriptValueP value = it->next(&key)) {
|
||||
assert(key);
|
||||
if (key == script_nil || value == script_nil) continue;
|
||||
String key_name = key->toString();
|
||||
if (set_stylesheet_container(*game, new_card, value, key_name, ignore_field_not_found)) break;
|
||||
}
|
||||
if (set_stylesheet_container(*game, new_card, value, key_name, ignore_field_not_found)) break;
|
||||
}
|
||||
// set the rest of the key/value pairs
|
||||
it = input->makeIterator();
|
||||
while (ScriptValueP value = it->next(&key)) {
|
||||
@@ -60,7 +60,7 @@ SCRIPT_FUNCTION(new_card) {
|
||||
ScriptValueP script_input = field->import_script.invoke(ctx, true);
|
||||
// if the script result is a collection, iterate on the key/value pairs
|
||||
// treat the keys as field names and the values as what to populate those fields with
|
||||
if (script_input->type() == SCRIPT_COLLECTION) {
|
||||
if (script_input->type() == SCRIPT_COLLECTION) {
|
||||
// check for a stylesheet first, since other things depend on it
|
||||
ScriptValueP script_it = script_input->makeIterator();
|
||||
ScriptValueP script_key;
|
||||
@@ -68,8 +68,8 @@ SCRIPT_FUNCTION(new_card) {
|
||||
assert(script_key);
|
||||
if (script_key == script_nil || script_value == script_nil) continue;
|
||||
String script_key_name = script_key->toString();
|
||||
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
|
||||
}
|
||||
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
|
||||
}
|
||||
// iterate on the rest of the key/value pairs given by the script
|
||||
script_it = script_input->makeIterator();
|
||||
while (ScriptValueP script_value = script_it->next(&script_key)) {
|
||||
@@ -103,7 +103,7 @@ SCRIPT_FUNCTION(new_card) {
|
||||
ScriptValueP ctx_card = ctx.getVariableOpt(SCRIPT_VAR_card);
|
||||
ctx.setVariable(SCRIPT_VAR_card, to_script(new_card));
|
||||
ScriptValueP script_input = game->import_script.invoke(ctx, true);
|
||||
if (script_input->type() == SCRIPT_COLLECTION) {
|
||||
if (script_input->type() == SCRIPT_COLLECTION) {
|
||||
// check for a stylesheet first, since other things depend on it
|
||||
ScriptValueP script_it = script_input->makeIterator();
|
||||
ScriptValueP script_key;
|
||||
@@ -111,7 +111,7 @@ SCRIPT_FUNCTION(new_card) {
|
||||
assert(script_key);
|
||||
if (script_key == script_nil || script_value == script_nil) continue;
|
||||
String script_key_name = script_key->toString();
|
||||
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
|
||||
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
|
||||
}
|
||||
// iterate on the rest of the key/value pairs given by the script
|
||||
script_it = script_input->makeIterator();
|
||||
|
||||
@@ -440,7 +440,7 @@ SCRIPT_FUNCTION(write_image_file) {
|
||||
// get image
|
||||
Image img;
|
||||
SCRIPT_PARAM(Set*, set);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
ScriptObject<CardP>* card = dynamic_cast<ScriptObject<CardP>*>(input.get()); // is the input a card or image?
|
||||
if (card) {
|
||||
SCRIPT_PARAM_DEFAULT(double, zoom, 100.0);
|
||||
|
||||
@@ -39,12 +39,12 @@ SCRIPT_FUNCTION(to_card_image) {
|
||||
if (use_user_settings) {
|
||||
// Use the User's Preferences for Export Zoom, Angle and Bleed settings.
|
||||
Settings::ExportSettings card_settings = settings.exportSettingsFor(set->stylesheetFor(input));
|
||||
zoom = card_settings.zoom;
|
||||
angle = card_settings.angle_radians;
|
||||
zoom = card_settings.zoom;
|
||||
angle = card_settings.angle_radians;
|
||||
bleed = card_settings.bleed_pixels;
|
||||
} else {
|
||||
// Use the provided (or defaulted) Zoom, Angle and Bleed.
|
||||
zoom = zoom / 100.0;
|
||||
zoom = zoom / 100.0;
|
||||
angle = deg_to_rad(angle);
|
||||
}
|
||||
return make_intrusive<ArbitraryImage>(export_image(set, input, true, zoom, angle, bleed));
|
||||
@@ -56,7 +56,7 @@ SCRIPT_FUNCTION(import_image) {
|
||||
return make_intrusive<ImportedImage>(set, input);
|
||||
}
|
||||
|
||||
SCRIPT_FUNCTION(download_image) {
|
||||
SCRIPT_FUNCTION(download_image) {
|
||||
if (!settings.allow_image_download) return script_nil;
|
||||
SCRIPT_PARAM(Set*, set);
|
||||
SCRIPT_PARAM(String, input);
|
||||
|
||||
+12
-12
@@ -106,11 +106,11 @@ void CachedScriptableImage::generateCached(const GeneratedImage::Options& option
|
||||
*size = cached_size;
|
||||
// do the options match?
|
||||
Radians relative_rotation = options.angle + rad360 - cached_options_angle;
|
||||
bool ok = almost_equal(cached_options_size.width, options.width) &&
|
||||
almost_equal(cached_options_size.height, options.height) &&
|
||||
almost_equal(cached_options_zoom, options.zoom) &&
|
||||
cached_options_preserve_aspect == options.preserve_aspect &&
|
||||
cached_options_saturate == options.saturate &&
|
||||
bool ok = almost_equal(cached_options_size.width, options.width) &&
|
||||
almost_equal(cached_options_size.height, options.height) &&
|
||||
almost_equal(cached_options_zoom, options.zoom) &&
|
||||
cached_options_preserve_aspect == options.preserve_aspect &&
|
||||
cached_options_saturate == options.saturate &&
|
||||
is_straight(relative_rotation); // we only need an {0,90,180,270} degree rotation compared to the cached one, this doesn't reduce image quality
|
||||
// image or bitmap?
|
||||
if (*combine <= COMBINE_NORMAL) {
|
||||
@@ -131,19 +131,19 @@ void CachedScriptableImage::generateCached(const GeneratedImage::Options& option
|
||||
*image = cached_i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// store the options as they were asked for
|
||||
cached_options_size = RealSize(options.width, options.height);
|
||||
cached_options_zoom = options.zoom;
|
||||
cached_options_preserve_aspect = options.preserve_aspect;
|
||||
cached_options_saturate = options.saturate;
|
||||
}
|
||||
// store the options as they were asked for
|
||||
cached_options_size = RealSize(options.width, options.height);
|
||||
cached_options_zoom = options.zoom;
|
||||
cached_options_preserve_aspect = options.preserve_aspect;
|
||||
cached_options_saturate = options.saturate;
|
||||
cached_options_angle = options.angle;
|
||||
// hack(part1): temporarily set angle to 0, do actual rotation after applying mask
|
||||
const_cast<GeneratedImage::Options&>(options).angle = 0;
|
||||
// generate
|
||||
cached_i = generate(options);
|
||||
assert(cached_i.Ok());
|
||||
const_cast<GeneratedImage::Options&>(options).angle = cached_options_angle;
|
||||
const_cast<GeneratedImage::Options&>(options).angle = cached_options_angle;
|
||||
// store the size as it actually is (may have been changed by conform_image() when we generated the image)
|
||||
*size = cached_size = RealSize(options.width, options.height);
|
||||
if (mask) {
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
private:
|
||||
Image cached_i; ///< The cached image
|
||||
Bitmap cached_b; ///< *or* the cached bitmap
|
||||
RealSize cached_size; ///< The size of the image before rotating, may be different than the options size
|
||||
RealSize cached_size; ///< The size of the image before rotating, may be different than the options size
|
||||
/// The options as they were last specified
|
||||
RealSize cached_options_size = RealSize(-1.0,-1.0);
|
||||
double cached_options_zoom;
|
||||
|
||||
@@ -223,8 +223,8 @@ public:
|
||||
inline ScriptConcatCollection(ScriptValueP a, ScriptValueP b) : a(a), b(b) {}
|
||||
ScriptValueP getMember(const String& name) const override;
|
||||
ScriptValueP getIndex(int index) const override;
|
||||
ScriptValueP makeIterator() const override;
|
||||
ScriptValueP getA() { return a; }
|
||||
ScriptValueP makeIterator() const override;
|
||||
ScriptValueP getA() { return a; }
|
||||
ScriptValueP getB() { return b; }
|
||||
|
||||
int itemCount() const override { return a->itemCount() + b->itemCount(); }
|
||||
|
||||
@@ -106,8 +106,8 @@ public:
|
||||
/// Actions to be undone.
|
||||
vector<unique_ptr<Action>> undo_actions;
|
||||
/// Actions to be redone
|
||||
vector<unique_ptr<Action>> redo_actions;
|
||||
|
||||
vector<unique_ptr<Action>> redo_actions;
|
||||
|
||||
private:
|
||||
/// Point at which the file was saved, corresponds to the top of the undo stack at that point
|
||||
const Action* save_point;
|
||||
|
||||
+16
-16
@@ -20,7 +20,7 @@
|
||||
// ----------------------------------------------------------------------------- : Package : outside
|
||||
|
||||
IMPLEMENT_DYNAMIC_ARG(Package*, writing_package, nullptr);
|
||||
IMPLEMENT_DYNAMIC_ARG(Package*, clipboard_package, nullptr);
|
||||
IMPLEMENT_DYNAMIC_ARG(Package*, clipboard_package, nullptr);
|
||||
|
||||
Package::Package()
|
||||
: zipStream (nullptr)
|
||||
@@ -98,8 +98,8 @@ void Package::save(bool remove_unused) {
|
||||
saveAs(filename, remove_unused);
|
||||
}
|
||||
|
||||
void Package::saveAs(const String& name, bool remove_unused, bool as_directory) {
|
||||
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
|
||||
void Package::saveAs(const String& name, bool remove_unused, bool as_directory) {
|
||||
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
|
||||
// type of package
|
||||
if (wxDirExists(name) || as_directory) {
|
||||
saveToDirectory(name, remove_unused, false);
|
||||
@@ -111,7 +111,7 @@ void Package::saveAs(const String& name, bool remove_unused, bool as_directory)
|
||||
reopen();
|
||||
}
|
||||
|
||||
void Package::saveCopy(const String& name) {
|
||||
void Package::saveCopy(const String& name) {
|
||||
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
|
||||
saveToZipfile(name, true, true);
|
||||
clearKeepFlag();
|
||||
@@ -227,15 +227,15 @@ unique_ptr<wxInputStream> Package::openIn(const String& file) {
|
||||
FileInfos::iterator it = files.find(normalize_internal_filename(file));
|
||||
if (it == files.end()) {
|
||||
// does it look like a relative filename?
|
||||
if (size_t pos = filename.find(_(".mse-")) != String::npos) {
|
||||
// check for nested folder
|
||||
pos = filename.find_last_of(_("/\\"));
|
||||
String nestedFilename = filename + filename.SubString(pos, filename.size()) + wxFileName::GetPathSeparator() + file;
|
||||
if (size_t pos = filename.find(_(".mse-")) != String::npos) {
|
||||
// check for nested folder
|
||||
pos = filename.find_last_of(_("/\\"));
|
||||
String nestedFilename = filename + filename.SubString(pos, filename.size()) + wxFileName::GetPathSeparator() + file;
|
||||
if (wxFileExists(nestedFilename)) {
|
||||
throw PackageError(_ERROR_1_("nested folder", filename));
|
||||
}
|
||||
else {
|
||||
throw PackageError(_ERROR_2_("file not found package like", file, filename));
|
||||
else {
|
||||
throw PackageError(_ERROR_2_("file not found package like", file, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -593,14 +593,14 @@ Packaged::Packaged()
|
||||
, fully_loaded(true)
|
||||
{}
|
||||
|
||||
unique_ptr<wxInputStream> Packaged::openIconFile() {
|
||||
String filename = icon_filename;
|
||||
unique_ptr<wxInputStream> Packaged::openIconFile() {
|
||||
String filename = icon_filename;
|
||||
if (!dark_icon_filename.empty()) {
|
||||
if (settings.darkMode()) {
|
||||
wxFileName fn (dark_icon_filename);
|
||||
if (settings.darkMode()) {
|
||||
wxFileName fn (dark_icon_filename);
|
||||
String extension = fn.GetExt();
|
||||
filename = dark_icon_filename.Replace(extension, _("")) + "_dark" + extension;
|
||||
}
|
||||
filename = dark_icon_filename.Replace(extension, _("")) + "_dark" + extension;
|
||||
}
|
||||
else filename = dark_icon_filename;
|
||||
}
|
||||
if (!filename.empty()) {
|
||||
|
||||
+44
-44
@@ -13,7 +13,7 @@
|
||||
#include <util/error.hpp>
|
||||
#include <util/file_utils.hpp>
|
||||
#include <util/vcs.hpp>
|
||||
#include <data/format/file_to_text.h>
|
||||
#include <data/format/file_to_text.h>
|
||||
|
||||
class Package;
|
||||
class wxFileInputStream;
|
||||
@@ -55,70 +55,70 @@ public:
|
||||
inline String const& toStringForKey() const { return fn; }
|
||||
|
||||
/// Retreive a rect from a filename
|
||||
inline static void getExternalRect(const String& filename, wxRect& rect_out, int& degrees_out) {
|
||||
inline static void getExternalRect(const String& filename, wxRect& rect_out, int& degrees_out) {
|
||||
size_t first = filename.find(_("<mse-crop-data>"));
|
||||
if (first == String::npos) return;
|
||||
size_t last = filename.find(_("</mse-crop-data>"), first + 15);
|
||||
if (last == String::npos) return;
|
||||
String string = filename.substr(first + 15, last - (first + 15));
|
||||
if (string.empty()) return;
|
||||
|
||||
size_t last = filename.find(_("</mse-crop-data>"), first + 15);
|
||||
if (last == String::npos) return;
|
||||
String string = filename.substr(first + 15, last - (first + 15));
|
||||
if (string.empty()) return;
|
||||
|
||||
size_t divider = string.find(_("-"));
|
||||
if (divider == String::npos) return;
|
||||
if (divider == 0) return;
|
||||
int x;
|
||||
if(!string.substr(0, divider).ToInt(&x)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
int x;
|
||||
if(!string.substr(0, divider).ToInt(&x)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
divider = string.find(_("-"));
|
||||
if (divider == String::npos) return;
|
||||
if (divider == 0) return;
|
||||
int y;
|
||||
if(!string.substr(0, divider).ToInt(&y)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
int y;
|
||||
if(!string.substr(0, divider).ToInt(&y)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
divider = string.find(_("-"));
|
||||
if (divider == String::npos) return;
|
||||
if (divider == 0) return;
|
||||
int width;
|
||||
if(!string.substr(0, divider).ToInt(&width)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
int width;
|
||||
if(!string.substr(0, divider).ToInt(&width)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
divider = string.find(_("-"));
|
||||
if (divider == String::npos) return;
|
||||
if (divider == 0) return;
|
||||
int height;
|
||||
if(!string.substr(0, divider).ToInt(&height)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
if(!string.ToInt(°rees_out)) return;
|
||||
|
||||
int height;
|
||||
if(!string.substr(0, divider).ToInt(&height)) return;
|
||||
string = string.substr(divider + 1);
|
||||
|
||||
if(!string.ToInt(°rees_out)) return;
|
||||
|
||||
rect_out = wxRect(x, y, width, height);
|
||||
}
|
||||
inline void getExternalRect(wxRect& rect_out, int& degrees_out) {
|
||||
getExternalRect(fn, rect_out, degrees_out);
|
||||
}
|
||||
inline void getExternalRect(wxRect& rect_out, int& degrees_out) {
|
||||
getExternalRect(fn, rect_out, degrees_out);
|
||||
}
|
||||
|
||||
/// Retreive an image from a filename
|
||||
inline static Image getExternalImage(const String& filename) {
|
||||
Image img;
|
||||
inline static Image getExternalImage(const String& filename) {
|
||||
Image img;
|
||||
size_t first = filename.find(_("<mse-image-data>"));
|
||||
if (first == String::npos) return img;
|
||||
size_t last = filename.find(_("</mse-image-data>"), first + 16);
|
||||
if (last == String::npos) return img;
|
||||
std::string s = filename.substr(first + 16, last - (first + 16)).ToStdString();
|
||||
if (s.empty()) return img;
|
||||
|
||||
const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString();
|
||||
UTF8ToFile(temppath, s);
|
||||
img.LoadFile(temppath, wxBITMAP_TYPE_PNG);
|
||||
wxRemoveFile(temppath);
|
||||
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
|
||||
return img;
|
||||
size_t last = filename.find(_("</mse-image-data>"), first + 16);
|
||||
if (last == String::npos) return img;
|
||||
std::string s = filename.substr(first + 16, last - (first + 16)).ToStdString();
|
||||
if (s.empty()) return img;
|
||||
|
||||
const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString();
|
||||
UTF8ToFile(temppath, s);
|
||||
img.LoadFile(temppath, wxBITMAP_TYPE_PNG);
|
||||
wxRemoveFile(temppath);
|
||||
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
|
||||
return img;
|
||||
}
|
||||
inline Image getExternalImage() {
|
||||
return getExternalImage(fn);
|
||||
}
|
||||
inline Image getExternalImage() {
|
||||
return getExternalImage(fn);
|
||||
}
|
||||
|
||||
private:
|
||||
LocalFileName(const wxString& fn) : fn(fn) {}
|
||||
|
||||
@@ -357,14 +357,14 @@ template <> void Reader::handle(Vector2D& vec) {
|
||||
template <> void Reader::handle(LocalFileName& f) {
|
||||
f = LocalFileName::fromReadString(this->getValue());
|
||||
}
|
||||
|
||||
String Reader::addLocale(String filename) {
|
||||
return filename + _("_") + settings.locale;
|
||||
}
|
||||
|
||||
String Reader::addDark(String filename) {
|
||||
return filename + (settings.darkMode() ? _("_dark") : _(""));
|
||||
}
|
||||
|
||||
String Reader::addLocale(String filename) {
|
||||
return filename + _("_") + settings.locale;
|
||||
}
|
||||
|
||||
String Reader::addDark(String filename) {
|
||||
return filename + (settings.darkMode() ? _("_dark") : _(""));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : EnumReader
|
||||
|
||||
|
||||
@@ -116,10 +116,10 @@ public:
|
||||
|
||||
/// The package being read from
|
||||
inline Packaged* getPackage() const { return package; }
|
||||
|
||||
String addLocale(String);
|
||||
String addDark(String);
|
||||
|
||||
|
||||
String addLocale(String);
|
||||
String addDark(String);
|
||||
|
||||
/// Set the value that will be returned by the next getValue() call (may mess up the state of the reader)
|
||||
inline void setValue(const String& value) { state = UNHANDLED; previous_value = value; };
|
||||
|
||||
@@ -181,7 +181,7 @@ private:
|
||||
/** Maybe the key is "include file" */
|
||||
template <typename T>
|
||||
void unknownKey(T& v) {
|
||||
if (key == _("include_file") || key == _("include_localized_file") || key == _("include_dark_file")) {
|
||||
if (key == _("include_file") || key == _("include_localized_file") || key == _("include_dark_file")) {
|
||||
value = key == _("include_localized_file") ? addLocale(value) : key == _("include_dark_file") ? addDark(value) : value;
|
||||
auto [stream, include_package] = openFileFromPackage(package, value);
|
||||
Reader sub_reader(*stream, include_package, value, ignore_invalid);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
using boost::tribool;
|
||||
|
||||
// ----------------------------------------------------------------------------- : Writer
|
||||
|
||||
|
||||
Writer::Writer(OutputStream& output)
|
||||
: indentation(0)
|
||||
, output(output)
|
||||
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
// special behaviour
|
||||
void handle(const GameP&);
|
||||
void handle(const StyleSheetP&);
|
||||
|
||||
|
||||
/// Indentation of the current block
|
||||
int indentation;
|
||||
private:
|
||||
|
||||
@@ -115,7 +115,7 @@ enum ChildMenuID {
|
||||
ID_CARD_ADD_CSV_BROWSE,
|
||||
ID_CARD_ADD_JSON,
|
||||
ID_CARD_ADD_JSON_ARRAY,
|
||||
ID_CARD_ADD_JSON_BROWSE,
|
||||
ID_CARD_ADD_JSON_BROWSE,
|
||||
ID_CARD_BULK,
|
||||
ID_CARD_BULK_TYPE,
|
||||
ID_CARD_BULK_FIELD,
|
||||
|
||||
Reference in New Issue
Block a user