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.
This commit is contained in:
252
rtgui/resize.cc
252
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<double>(refw);
|
||||
scale->setValue(tmp_scale);
|
||||
se->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refh) * tmp_scale + 0.5)));
|
||||
} else {
|
||||
const double tmp_scale = le->get_value() / static_cast<double>(refh);
|
||||
scale->setValue(tmp_scale);
|
||||
se->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * tmp_scale + 0.5)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
// Short edge mode
|
||||
if (refw > refh) {
|
||||
const double tmp_scale = se->get_value() / static_cast<double>(refh);
|
||||
scale->setValue(tmp_scale);
|
||||
le->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * tmp_scale + 0.5)));
|
||||
} else {
|
||||
const double tmp_scale = se->get_value() / static_cast<double>(refw);
|
||||
scale->setValue(tmp_scale);
|
||||
le->set_value(static_cast<double>(static_cast<int>(static_cast<double>(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:
|
||||
|
Reference in New Issue
Block a user