Files
MagicSetEditor2/src/gui/value/image.cpp
T
Brendan Hagan c5d2bcf9d0 fix: apply image slice scale after slice window to avoid mask issues
MSE draws masks on the slice window and expects the sizes to be equivalent. This was presenting problems with the way I was trying to do internal scale as I was applying the scale upfront as the slice window loads and would need to scale the mask to match. Instead, applying the scale only when the output is generated from the slice window.
2022-07-09 14:51:59 -04:00

111 lines
4.3 KiB
C++

//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <gui/value/image.hpp>
#include <gui/image_slice_window.hpp>
#include <data/format/clipboard.hpp>
#include <data/action/value.hpp>
#include <wx/clipbrd.h>
#include <gui/util.hpp>
// ----------------------------------------------------------------------------- : ImageValueEditor
IMPLEMENT_VALUE_EDITOR(Image) {}
bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) {
String filename = wxFileSelector(_("Open image file"), settings.default_image_dir, _(""), _(""),
_("All images|*.bmp;*.jpg;*.png;*.gif|Windows bitmaps (*.bmp)|*.bmp|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|PNG images (*.png)|*.png|GIF images (*.gif)|*.gif|TIFF images (*.tif;*.tiff)|*.tif;*.tiff"),
wxFD_OPEN, wxGetTopLevelParent(&editor()));
if (!filename.empty()) {
settings.default_image_dir = wxPathOnly(filename);
wxImage image;
{
wxLogNull noLog;
image = wxImage(filename);
}
sliceImage(image);
}
return true;
}
void ImageValueEditor::sliceImage(const Image& image) {
if (!image.Ok()) return;
// mask
GeneratedImage::Options options((int)style().width, (int)style().height, &parent.getStylePackage(), &parent.getLocalPackage());
AlphaMask mask;
style().mask.getNoCache(options,mask);
// slice
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, style().getSize(), mask);
// clicked ok?
if (s.ShowModal() == wxID_OK) {
// store the image into the set
LocalFileName new_image_file = getLocalPackage().newFileName(field().name, settings.internal_image_extension ? _(".png") : _("")); // a new unique name in the package
// Specify a desired size based on the stylesheet and a scale multiplier defined within the user's settings.
// Storing at a greater than 100% resolution allows for better exports >100%, but may change how images look when filters (sharpen) are applied.
// It also disrupts some of the patterns in use for doing popout planeswalkers since you have to do the math at both scales.
// Additionally, this bloats the set file size as even under-resolution images are upscaled to the new minimum size.
Image img = s.getImage(settings.internal_scale);
img.SaveFile(getLocalPackage().nameOut(new_image_file), wxBITMAP_TYPE_PNG); // always use PNG images, see #69. Disk space is cheap anyway.
addAction(value_action(valueP(), new_image_file));
}
}
// ----------------------------------------------------------------------------- : Clipboard
bool ImageValueEditor::canCopy() const {
return !value().filename.empty();
}
bool ImageValueEditor::canPaste() const {
return wxTheClipboard->IsSupported(wxDF_BITMAP) &&
!wxTheClipboard->IsSupported(CardsDataObject::format); // we don't want to (accidentally) paste card images
}
bool ImageValueEditor::doCopy() {
// load image
auto image_file = getLocalPackage().openIn(value().filename);
Image image;
if (!image_load_file(image, *image_file)) return false;
// set data
if (!wxTheClipboard->Open()) return false;
bool ok = wxTheClipboard->SetData(new wxBitmapDataObject(image));
wxTheClipboard->Close();
return ok;
}
bool ImageValueEditor::doPaste() {
// get bitmap
if (!wxTheClipboard->Open()) return false;
wxBitmapDataObject data;
bool ok = wxTheClipboard->GetData(data);
wxTheClipboard->Close();
if (!ok) return false;
// slice
sliceImage(data.GetBitmap().ConvertToImage());
return true;
}
bool ImageValueEditor::doDelete() {
addAction(value_action(valueP(), LocalFileName()));
return true;
}
bool ImageValueEditor::onChar(wxKeyEvent& ev) {
if (ev.AltDown() || ev.ShiftDown() || ev.ControlDown()) return false;
switch (ev.GetKeyCode()) {
case WXK_DELETE:
doDelete();
return true;
default:
return false;
}
}