From d86888e93f3c3999261cc5b32143449fc325a606 Mon Sep 17 00:00:00 2001 From: Bezierr <38507161+Bezierr@users.noreply.github.com> Date: Sat, 5 Jun 2021 05:37:09 +0000 Subject: [PATCH] Add resizing options "long edge" and "short edge" (#6263) Introduces "long edge" and "short edge" options to resize an image. The GUI is made such that the relevant spinboxes only appear for the selected option. Unrelated values (e.g. for box-mode) are not updated. --- rtdata/languages/default | 6 + rtengine/imagedata.cc | 1 - rtengine/ipresize.cc | 20 ++++ rtengine/procparams.cc | 8 ++ rtengine/procparams.h | 2 + rtengine/refreshmap.cc | 2 +- rtgui/filecatalog.cc | 4 + rtgui/options.cc | 12 ++ rtgui/options.h | 2 + rtgui/paramsedited.cc | 12 ++ rtgui/paramsedited.h | 2 + rtgui/resize.cc | 252 +++++++++++++++++++++++++++++++++++---- rtgui/resize.h | 16 ++- 13 files changed, 311 insertions(+), 28 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 69cc6adc3..792bd7fda 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1387,6 +1387,8 @@ HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift HISTORY_MSG_RAW_BORDER;Raw border HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling +HISTORY_MSG_RESIZE_LONGEDGE;Resize - Long Edge +HISTORY_MSG_RESIZE_SHORTEDGE;Resize - Short Edge HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace @@ -3472,10 +3474,14 @@ TP_RESIZE_H;Height: TP_RESIZE_HEIGHT;Height TP_RESIZE_LABEL;Resize TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_LE;Long Edge: +TP_RESIZE_LONG;Long Edge TP_RESIZE_METHOD;Method: TP_RESIZE_NEAREST;Nearest TP_RESIZE_SCALE;Scale TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_SE;Short Edge: +TP_RESIZE_SHORT;Short Edge TP_RESIZE_W;Width: TP_RESIZE_WIDTH;Width TP_RETINEX_CONTEDIT_HSL;HSL histogram diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc index 16b6a4c91..5ecfa8414 100644 --- a/rtengine/imagedata.cc +++ b/rtengine/imagedata.cc @@ -339,7 +339,6 @@ FrameData::FrameData(rtexif::TagDirectory* frameRootDir_, rtexif::TagDirectory* iso_speed = isoTag->toDouble(); } } - } if (lens == "Unknown") { diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index b9e234b63..b6bdc5ede 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -379,6 +379,26 @@ float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, in dScale = (dScale > 1.0 && !params->resize.allowUpscaling) ? 1.0 : dScale; break; + + case (4): + + // Long Edge + if (refw > refh) { + dScale = (double)params->resize.longedge / (double)refw; + } else { + dScale = (double)params->resize.longedge / (double)refh; + } + break; + + case (5): + + // Short Edge + if (refw > refh) { + dScale = (double)params->resize.shortedge / (double)refh; + } else { + dScale = (double)params->resize.shortedge / (double)refw; + } + break; default: // Scale diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 26c51e3c6..870a9a71e 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2228,6 +2228,8 @@ ResizeParams::ResizeParams() : dataspec(3), width(900), height(900), + longedge(900), + shortedge(900), allowUpscaling(false) { } @@ -2242,6 +2244,8 @@ bool ResizeParams::operator ==(const ResizeParams& other) const && dataspec == other.dataspec && width == other.width && height == other.height + && longedge == other.longedge + && shortedge == other.shortedge && allowUpscaling == other.allowUpscaling; } @@ -6540,6 +6544,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->resize.dataspec, "Resize", "DataSpecified", resize.dataspec, keyFile); saveToKeyfile(!pedited || pedited->resize.width, "Resize", "Width", resize.width, keyFile); saveToKeyfile(!pedited || pedited->resize.height, "Resize", "Height", resize.height, keyFile); + saveToKeyfile(!pedited || pedited->resize.longedge, "Resize", "LongEdge", resize.longedge, keyFile); + saveToKeyfile(!pedited || pedited->resize.shortedge, "Resize", "ShortEdge", resize.shortedge, keyFile); saveToKeyfile(!pedited || pedited->resize.allowUpscaling, "Resize", "AllowUpscaling", resize.allowUpscaling, keyFile); // Post demosaic sharpening @@ -8574,6 +8580,8 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Resize", "DataSpecified", pedited, resize.dataspec, pedited->resize.dataspec); assignFromKeyfile(keyFile, "Resize", "Width", pedited, resize.width, pedited->resize.width); assignFromKeyfile(keyFile, "Resize", "Height", pedited, resize.height, pedited->resize.height); + assignFromKeyfile(keyFile, "Resize", "LongEdge", pedited, resize.longedge, pedited->resize.longedge); + assignFromKeyfile(keyFile, "Resize", "ShortEdge", pedited, resize.shortedge, pedited->resize.shortedge); if (ppVersion >= 339) { assignFromKeyfile(keyFile, "Resize", "AllowUpscaling", pedited, resize.allowUpscaling, pedited->resize.allowUpscaling); } else { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index c9695a4ad..b0e7f9cd4 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1690,6 +1690,8 @@ struct ResizeParams { int dataspec; int width; int height; + int longedge; + int shortedge; bool allowUpscaling; ResizeParams(); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 451164b8c..722898642 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -74,7 +74,7 @@ int refreshmap[rtengine::NUMOFEVENTS] = { 0, // EvLDNEdgeTolerance: obsolete, 0, // EvCDNEnabled:obsolete, 0, // free entry - RGBCURVE | M_AUTOEXP, // EvDCPToneCurve, + RGBCURVE | M_AUTOEXP, // EvDCPToneCurve, ALLNORAW, // EvDCPIlluminant, LUMINANCECURVE, // EvSHEnabled, LUMINANCECURVE, // EvSHHighlights, diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index c45fc154f..58c1bbc1b 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -1215,9 +1215,13 @@ void FileCatalog::developRequested(const std::vector& tbe, bo if (params.resize.enabled) { params.resize.width = rtengine::min(params.resize.width, options.fastexport_resize_width); params.resize.height = rtengine::min(params.resize.height, options.fastexport_resize_height); + params.resize.longedge = rtengine::min(params.resize.longedge, options.fastexport_resize_longedge); + params.resize.shortedge = rtengine::min(params.resize.shortedge, options.fastexport_resize_shortedge); } else { params.resize.width = options.fastexport_resize_width; params.resize.height = options.fastexport_resize_height; + params.resize.longedge = options.fastexport_resize_longedge; + params.resize.shortedge = options.fastexport_resize_shortedge; } params.resize.enabled = options.fastexport_resize_enabled; diff --git a/rtgui/options.cc b/rtgui/options.cc index 1b6d09f4c..ec36eb166 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -539,6 +539,8 @@ void Options::setDefaults() fastexport_resize_dataspec = 3; fastexport_resize_width = 900; fastexport_resize_height = 900; + fastexport_resize_longedge = 900; + fastexport_resize_shortedge = 900; fastexport_use_fast_pipeline = true; clutsDir = "./cluts"; @@ -2018,6 +2020,14 @@ void Options::readFromFile(Glib::ustring fname) fastexport_resize_height = keyFile.get_integer("Fast Export", "fastexport_resize_height"); } + if (keyFile.has_key("Fast Export", "fastexport_resize_longedge")) { + fastexport_resize_longedge = keyFile.get_integer("Fast Export", "fastexport_resize_longedge"); + } + + if (keyFile.has_key("Fast Export", "fastexport_resize_shortedge")) { + fastexport_resize_shortedge = keyFile.get_integer("Fast Export", "fastexport_resize_shortedge"); + } + if (keyFile.has_key("Fast Export", "fastexport_use_fast_pipeline")) { fastexport_use_fast_pipeline = keyFile.get_integer("Fast Export", "fastexport_use_fast_pipeline"); } @@ -2454,6 +2464,8 @@ void Options::saveToFile(Glib::ustring fname) keyFile.set_integer("Fast Export", "fastexport_resize_dataspec", fastexport_resize_dataspec); keyFile.set_integer("Fast Export", "fastexport_resize_width", fastexport_resize_width); keyFile.set_integer("Fast Export", "fastexport_resize_height", fastexport_resize_height); + keyFile.set_integer("Fast Export", "fastexport_resize_longedge", fastexport_resize_longedge); + keyFile.set_integer("Fast Export", "fastexport_resize_shortedge", fastexport_resize_shortedge); keyFile.set_integer("Fast Export", "fastexport_use_fast_pipeline", fastexport_use_fast_pipeline); keyFile.set_string("Dialogs", "LastIccDir", lastIccDir); diff --git a/rtgui/options.h b/rtgui/options.h index 52e1c0270..19963ba39 100644 --- a/rtgui/options.h +++ b/rtgui/options.h @@ -424,6 +424,8 @@ public: int fastexport_resize_dataspec; int fastexport_resize_width; int fastexport_resize_height; + int fastexport_resize_longedge; + int fastexport_resize_shortedge; bool fastexport_use_fast_pipeline; std::vector favorites; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index a28d666b4..ada149b95 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -425,6 +425,8 @@ void ParamsEdited::set(bool v) resize.dataspec = v; resize.width = v; resize.height = v; + resize.longedge = v; + resize.shortedge = v; resize.enabled = v; spot.enabled = v; @@ -1718,6 +1720,8 @@ void ParamsEdited::initFrom(const std::vector& resize.dataspec = resize.dataspec && p.resize.dataspec == other.resize.dataspec; resize.width = resize.width && p.resize.width == other.resize.width; resize.height = resize.height && p.resize.height == other.resize.height; + resize.longedge = resize.longedge && p.resize.longedge == other.resize.longedge; + resize.shortedge = resize.shortedge && p.resize.shortedge == other.resize.shortedge; resize.enabled = resize.enabled && p.resize.enabled == other.resize.enabled; spot.enabled = spot.enabled && p.spot.enabled == other.spot.enabled; spot.entries = spot.entries && p.spot.entries == other.spot.entries; @@ -5718,6 +5722,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.resize.height = mods.resize.height; } + if (resize.longedge) { + toEdit.resize.longedge = mods.resize.longedge; + } + + if (resize.shortedge) { + toEdit.resize.shortedge = mods.resize.shortedge; + } + if (resize.enabled) { toEdit.resize.enabled = mods.resize.enabled; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index a422b653e..87f510e64 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -1083,6 +1083,8 @@ struct ResizeParamsEdited { bool dataspec; bool width; bool height; + bool longedge; + bool shortedge; bool enabled; bool allowUpscaling; }; diff --git a/rtgui/resize.cc b/rtgui/resize.cc index 314377049..55764d085 100644 --- a/rtgui/resize.cc +++ b/rtgui/resize.cc @@ -33,6 +33,8 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals { auto m = ProcEventMapper::getInstance(); EvResizeAllowUpscaling = m->newEvent(RESIZE, "HISTORY_MSG_RESIZE_ALLOWUPSCALING"); + EvResizeLongedge = m->newEvent (RESIZE, "HISTORY_MSG_RESIZE_LONGEDGE"); + EvResizeShortedge = m->newEvent (RESIZE, "HISTORY_MSG_RESIZE_SHORTEDGE"); cropw = 0; croph = 0; @@ -70,6 +72,8 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals spec->append (M("TP_RESIZE_WIDTH")); spec->append (M("TP_RESIZE_HEIGHT")); spec->append (M("TP_RESIZE_FITBOX")); + spec->append (M("TP_RESIZE_LONG")); + spec->append (M("TP_RESIZE_SHORT")); spec->set_active (0); spec->set_hexpand(); spec->set_halign(Gtk::ALIGN_FILL); @@ -91,19 +95,46 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals Gtk::Box* sbox = Gtk::manage (new Gtk::Box ()); Gtk::Box* wbox = Gtk::manage (new Gtk::Box ()); Gtk::Box* hbox = Gtk::manage (new Gtk::Box ()); + Gtk::Box* ebox = Gtk::manage (new Gtk::Box ()); + Gtk::Box* lebox = Gtk::manage (new Gtk::Box ()); + Gtk::Box* sebox = Gtk::manage (new Gtk::Box ()); + w = Gtk::manage (new MySpinButton ()); + w->set_width_chars(5); + setExpandAlignProperties(w, false, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER); h = Gtk::manage (new MySpinButton ()); - wbox->set_spacing(3); + h->set_width_chars(5); + setExpandAlignProperties(h, false, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + le = Gtk::manage (new MySpinButton ()); + le->set_width_chars(5); + setExpandAlignProperties(le, false, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + se = Gtk::manage (new MySpinButton ()); + se->set_width_chars(5); + setExpandAlignProperties(se, false, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER); + wbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_W"))), Gtk::PACK_SHRINK, 0); wbox->pack_start (*w); hbox->set_spacing(3); hbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_H"))), Gtk::PACK_SHRINK, 0); hbox->pack_start (*h); + lebox->set_spacing(3); + lebox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_LE"))), Gtk::PACK_SHRINK, 0); + lebox->pack_start (*le); + sebox->set_spacing(3); + sebox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_SE"))), Gtk::PACK_SHRINK, 0); + sebox->pack_start (*se); + sbox->set_spacing(4); sbox->pack_start (*wbox); sbox->pack_start (*hbox); - + sbox->set_homogeneous(); + ebox->set_spacing(4); + ebox->pack_start (*lebox); + ebox->pack_start (*sebox); + ebox->set_homogeneous(); + sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 0); + sizeBox->pack_start (*ebox, Gtk::PACK_SHRINK, 0); sizeBox->show_all (); sizeBox->reference (); @@ -113,16 +144,28 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals w->set_digits (0); w->set_increments (1, 100); - w->set_value (800); w->set_range (32, MAX_SCALE * maxw); + w->set_value (800); // Doesn't seem to have any effect (overwritten in Resize::read) h->set_digits (0); h->set_increments (1, 100); - h->set_value (600); h->set_range (32, MAX_SCALE * maxh); + h->set_value (600); // Doesn't seem to have any effect (overwritten in Resize::read) + + le->set_digits (0); + le->set_increments (1, 100); + le->set_range (32, MAX_SCALE * maxw); + le->set_value (900); + + se->set_digits (0); + se->set_increments (1, 100); + se->set_range (32, MAX_SCALE * maxh); + se->set_value (900); wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true); hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true); + leconn = le->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryLEChanged), true); + seconn = se->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entrySEChanged), true); aconn = appliesTo->signal_changed().connect ( sigc::mem_fun(*this, &Resize::appliesToChanged) ); method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) ); sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) ); @@ -149,15 +192,20 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) aconn.block (true); wconn.block (true); hconn.block (true); + leconn.block (true); + seconn.block (true); sconn.block (true); scale->block(true); scale->setValue (pp->resize.scale); w->set_value (pp->resize.width); h->set_value (pp->resize.height); + le->set_value (pp->resize.longedge); + se->set_value (pp->resize.shortedge); setEnabled (pp->resize.enabled); spec->set_active (pp->resize.dataspec); allowUpscaling->set_active(pp->resize.allowUpscaling); + setDimensions(); // Sets Width/Height in the GUI according to value of Specify after loading a .pp3 profile (same behavior as if changed manually) updateGUI(); appliesTo->set_active (0); @@ -178,10 +226,14 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) wDirty = false; hDirty = false; + leDirty = false; + seDirty = false; if (pedited) { wDirty = pedited->resize.width; hDirty = pedited->resize.height; + leDirty = pedited->resize.longedge; + seDirty = pedited->resize.shortedge; scale->setEditedState (pedited->resize.scale ? Edited : UnEdited); if (!pedited->resize.appliesTo) { @@ -193,7 +245,7 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) } if (!pedited->resize.dataspec) { - spec->set_active (4); + spec->set_active (6); } allowUpscaling->set_inconsistent(!pedited->resize.allowUpscaling); @@ -204,6 +256,8 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) sconn.block (false); wconn.block (false); hconn.block (false); + leconn.block (false); + seconn.block (false); aconn.block (false); enableListener (); } @@ -211,7 +265,7 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) void Resize::write (ProcParams* pp, ParamsEdited* pedited) { int dataSpec = spec->get_active_row_number(); - + pp->resize.scale = scale->getValue(); pp->resize.appliesTo = "Cropped area"; @@ -233,6 +287,8 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) pp->resize.dataspec = dataSpec; pp->resize.width = w->get_value_as_int (); pp->resize.height = h->get_value_as_int (); + pp->resize.longedge = le->get_value_as_int (); + pp->resize.shortedge = se->get_value_as_int (); pp->resize.enabled = getEnabled (); //printf(" L:%d H:%d\n", pp->resize.width, pp->resize.height); @@ -240,7 +296,7 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->resize.enabled = !get_inconsistent(); - pedited->resize.dataspec = dataSpec != MAX_SCALE; + pedited->resize.dataspec = dataSpec != 6; pedited->resize.appliesTo = appliesTo->get_active_row_number() != 2; pedited->resize.method = method->get_active_row_number() != 3; @@ -248,10 +304,14 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) pedited->resize.scale = scale->getEditedState (); pedited->resize.width = wDirty; pedited->resize.height = hDirty; + pedited->resize.longedge = leDirty; + pedited->resize.shortedge = seDirty; } else { pedited->resize.scale = false; pedited->resize.width = false; pedited->resize.height = false; + pedited->resize.longedge = false; + pedited->resize.shortedge = false; } pedited->resize.allowUpscaling = !allowUpscaling->get_inconsistent(); } @@ -285,31 +345,31 @@ void Resize::adjusterChanged(Adjuster* a, double newval) } } -int Resize::getComputedWidth() +int Resize::getComputedWidth(double height) { if (cropw && appliesTo->get_active_row_number() == 0) // we use the crop dimensions { - return (int)((double)(cropw) * (h->get_value() / (double)(croph)) + 0.5); + return (int)((double)(cropw) * (height / (double)(croph)) + 0.5); } else // we use the image dimensions { - return (int)((double)(maxw) * (h->get_value() / (double)(maxh)) + 0.5); + return (int)((double)(maxw) * (height / (double)(maxh)) + 0.5); } } -int Resize::getComputedHeight() +int Resize::getComputedHeight(double width) { if (croph && appliesTo->get_active_row_number() == 0) // we use the crop dimensions { - return (int)((double)(croph) * (w->get_value() / (double)(cropw)) + 0.5); + return (int)((double)(croph) * (width / (double)(cropw)) + 0.5); } else // we use the image dimensions { - return (int)((double)(maxh) * (w->get_value() / (double)(maxw)) + 0.5); + return (int)((double)(maxh) * (width / (double)(maxw)) + 0.5); } } @@ -379,8 +439,10 @@ void Resize::setDimensions () { wconn.block(true); hconn.block(true); + leconn.block(true); + seconn.block(true); scale->block(true); - + int refw, refh; if (appliesTo->get_active_row_number() == 0 && cropw) { @@ -431,6 +493,34 @@ void Resize::setDimensions () break; } + case 4: { + // Long edge mode + if (refw > refh) { + const double tmp_scale = le->get_value() / static_cast(refw); + scale->setValue(tmp_scale); + se->set_value(static_cast(static_cast(static_cast(refh) * tmp_scale + 0.5))); + } else { + const double tmp_scale = le->get_value() / static_cast(refh); + scale->setValue(tmp_scale); + se->set_value(static_cast(static_cast(static_cast(refw) * tmp_scale + 0.5))); + } + break; + } + + case 5: { + // Short edge mode + if (refw > refh) { + const double tmp_scale = se->get_value() / static_cast(refh); + scale->setValue(tmp_scale); + le->set_value(static_cast(static_cast(static_cast(refw) * tmp_scale + 0.5))); + } else { + const double tmp_scale = se->get_value() / static_cast(refw); + scale->setValue(tmp_scale); + le->set_value(static_cast(static_cast(static_cast(refh) * tmp_scale + 0.5))); + } + break; + } + default: { break; } @@ -439,6 +529,8 @@ void Resize::setDimensions () scale->block(false); wconn.block(false); hconn.block(false); + leconn.block(false); + seconn.block(false); return false; } @@ -489,7 +581,7 @@ void Resize::entryWChanged () hconn.block (true); scale->block (true); - h->set_value ((double)(getComputedHeight())); + h->set_value ((double)(getComputedHeight(w->get_value()))); scale->setValue (w->get_value () / (cropw && appliesTo->get_active_row_number() == 0 ? (double)cropw : (double)maxw)); scale->block (false); @@ -522,7 +614,7 @@ void Resize::entryHChanged () wconn.block (true); scale->block (true); - w->set_value ((double)(getComputedWidth())); + w->set_value ((double)(getComputedWidth(h->get_value()))); scale->setValue (h->get_value () / (croph && appliesTo->get_active_row_number() == 0 ? (double)croph : (double)maxh)); scale->block (false); @@ -541,25 +633,107 @@ void Resize::entryHChanged () } } +void Resize::entryLEChanged () +{ + + leDirty = true; + + // updating long edge + if (!batchMode && listener) { + int refw, refh; + + seconn.block (true); + scale->block (true); + + if (cropw && appliesTo->get_active_row_number() == 0) { + // we use the crop dimensions + refw = cropw; + refh = croph; + } else { + // we use the image dimensions + refw = maxw; + refh = maxh; + } + + if (refw > refh) { + se->set_value ((double) (getComputedHeight(le->get_value()))); + scale->setValue (le->get_value () / (cropw && appliesTo->get_active_row_number() == 0 ? (double)cropw : (double)maxw)); + } else { + se->set_value ((double)(getComputedWidth(le->get_value()))); + scale->setValue (le->get_value () / (croph && appliesTo->get_active_row_number() == 0 ? (double)croph : (double)maxh)); + } + + scale->block (false); + seconn.block (false); + } + + if (listener) { + if (getEnabled () || batchMode) { + listener->panelChanged (EvResizeLongedge, Glib::ustring::format (le->get_value_as_int())); + } + } +} + +void Resize::entrySEChanged () +{ + + seDirty = true; + + // updating short edge + if (!batchMode && listener) { + int refw, refh; + + leconn.block (true); + scale->block (true); + + if (cropw && appliesTo->get_active_row_number() == 0) { + // we use the crop dimensions + refw = cropw; + refh = croph; + } else { + // we use the image dimensions + refw = maxw; + refh = maxh; + } + + if (refw > refh) { + le->set_value ((double)(getComputedWidth(se->get_value()))); + scale->setValue (se->get_value () / (croph && appliesTo->get_active_row_number() == 0 ? (double)croph : (double)maxh)); + } else { + le->set_value ((double)(getComputedHeight(se->get_value()))); + scale->setValue (se->get_value () / (cropw && appliesTo->get_active_row_number() == 0 ? (double)cropw : (double)maxw)); + } + + scale->block (false); + leconn.block (false); + } + + if (listener) { + if (getEnabled () || batchMode) { + listener->panelChanged (EvResizeShortedge, Glib::ustring::format (se->get_value_as_int())); + } + } +} + void Resize::specChanged () { switch (spec->get_active_row_number()) { case (0): // Scale mode - scale->sliderChanged (); + scale->sliderChanged(); break; case (1): // Width mode - w->set_value((double)(getComputedWidth())); - entryWChanged (); + w->set_value((double)(getComputedWidth(h->get_value()))); + entryWChanged(); break; case (2): // Height mode - h->set_value((double)(getComputedHeight())); - entryHChanged (); + h->set_value((double)(getComputedHeight(w->get_value()))); + entryHChanged(); break; case (3): @@ -567,6 +741,16 @@ void Resize::specChanged () notifyBBox(); break; + case (4): + // Long edge mode + entryLEChanged(); + break; + + case (5): + // Short edge mode + entrySEChanged(); + break; + default: break; } @@ -593,6 +777,8 @@ void Resize::updateGUI () reorder_child(*allowUpscaling, 4); w->set_sensitive (true); h->set_sensitive (false); + w->get_parent()->get_parent()->show(); + le->get_parent()->get_parent()->hide(); break; case (2): @@ -601,6 +787,8 @@ void Resize::updateGUI () reorder_child(*allowUpscaling, 4); w->set_sensitive (false); h->set_sensitive (true); + w->get_parent()->get_parent()->show(); + le->get_parent()->get_parent()->hide(); break; case (3): @@ -609,6 +797,28 @@ void Resize::updateGUI () reorder_child(*allowUpscaling, 4); w->set_sensitive (true); h->set_sensitive (true); + w->get_parent()->get_parent()->show(); + le->get_parent()->get_parent()->hide(); + break; + + case (4): + // Long edge mode + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); + le->set_sensitive (true); + se->set_sensitive (false); + w->get_parent()->get_parent()->hide(); + le->get_parent()->get_parent()->show(); + break; + + case (5): + // Short edge mode + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + reorder_child(*allowUpscaling, 4); + le->set_sensitive (false); + se->set_sensitive (true); + w->get_parent()->get_parent()->hide(); + le->get_parent()->get_parent()->show(); break; default: diff --git a/rtgui/resize.h b/rtgui/resize.h index ec4907fd1..d13bf8aa4 100644 --- a/rtgui/resize.h +++ b/rtgui/resize.h @@ -48,6 +48,8 @@ public: void adjusterChanged (Adjuster* a, double newval) override; void entryWChanged (); void entryHChanged (); + void entryLEChanged (); + void entrySEChanged (); void appliesToChanged (); void methodChanged (); void specChanged (); @@ -62,25 +64,29 @@ public: private: void fitBoxScale (); - int getComputedWidth (); - int getComputedHeight (); + int getComputedWidth (double height); + int getComputedHeight (double width); void notifyBBox (); void updateGUI (); void allowUpscalingChanged(); rtengine::ProcEvent EvResizeAllowUpscaling; + rtengine::ProcEvent EvResizeLongedge; + rtengine::ProcEvent EvResizeShortedge; Adjuster* scale; - Gtk::Box* sizeBox; + Gtk::Box* sizeBox; MyComboBoxText* appliesTo; MyComboBoxText* method; MyComboBoxText* spec; MySpinButton* w; MySpinButton* h; + MySpinButton* le; + MySpinButton* se; Gtk::CheckButton *allowUpscaling; int maxw, maxh; int cropw, croph; - sigc::connection sconn, aconn, wconn, hconn; - bool wDirty, hDirty; + sigc::connection sconn, aconn, wconn, hconn, leconn, seconn; + bool wDirty, hDirty, leDirty, seDirty; ToolParamBlock* packBox; IdleRegister idle_register;