Add IdleRegister
to deal with destruction while idle func is queued
This adds a little helper class to `guiutils.*` that unregisters in-flight idle functions queued by `IdleRegister::add()`. It's best to call `IdleRegister::destroy()` in the destructor of the class owning the `IdleRegister` instance. Otherwise make sure, it is the last member which will be deleted first. `Resize` now makes use of this new facility in `setDimensions()`, which also fixes #3673.
This commit is contained in:
118
rtgui/resize.cc
118
rtgui/resize.cc
@@ -118,7 +118,7 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals
|
||||
|
||||
Resize::~Resize ()
|
||||
{
|
||||
|
||||
idle_register.destroy();
|
||||
delete scale;
|
||||
delete sizeBox;
|
||||
}
|
||||
@@ -352,68 +352,76 @@ void Resize::sizeChanged (int mw, int mh, int ow, int oh)
|
||||
|
||||
void Resize::setDimensions ()
|
||||
{
|
||||
const auto func = [](gpointer data) -> gboolean {
|
||||
Resize* const self = static_cast<Resize*>(data);
|
||||
|
||||
int refw, refh;
|
||||
self->wconn.block(true);
|
||||
self->hconn.block(true);
|
||||
self->scale->block(true);
|
||||
|
||||
wconn.block (true);
|
||||
hconn.block (true);
|
||||
scale->block(true);
|
||||
int refw, refh;
|
||||
|
||||
if (appliesTo->get_active_row_number() == 0 && cropw) {
|
||||
// Applies to Cropped area
|
||||
refw = cropw;
|
||||
refh = croph;
|
||||
} else {
|
||||
// Applies to Full image or crop is disabled
|
||||
refw = maxw;
|
||||
refh = maxh;
|
||||
}
|
||||
|
||||
GThreadLock lock;
|
||||
w->set_range (32, 4 * refw);
|
||||
h->set_range (32, 4 * refh);
|
||||
|
||||
double tmpScale;
|
||||
|
||||
switch (spec->get_active_row_number()) {
|
||||
case (0): // Scale mode
|
||||
w->set_value((double)((int)( (double)(refw) * scale->getValue() + 0.5) ));
|
||||
h->set_value((double)((int)( (double)(refh) * scale->getValue() + 0.5) ));
|
||||
break;
|
||||
|
||||
case (1): // Width mode
|
||||
tmpScale = w->get_value() / (double)refw;
|
||||
scale->setValue (tmpScale);
|
||||
h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) ));
|
||||
break;
|
||||
|
||||
case (2): // Height mode
|
||||
tmpScale = h->get_value() / (double)refh;
|
||||
scale->setValue (tmpScale);
|
||||
w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) ));
|
||||
break;
|
||||
|
||||
case (3): { // Bounding box mode
|
||||
double wSliderValue = w->get_value();
|
||||
double hSliderValue = h->get_value();
|
||||
|
||||
if ( (wSliderValue / hSliderValue) < ((double)refw / (double)refh)) {
|
||||
tmpScale = wSliderValue / (double)refw;
|
||||
if (self->appliesTo->get_active_row_number() == 0 && self->cropw) {
|
||||
// Applies to Cropped area
|
||||
refw = self->cropw;
|
||||
refh = self->croph;
|
||||
} else {
|
||||
tmpScale = hSliderValue / (double)refh;
|
||||
// Applies to Full image or crop is disabled
|
||||
refw = self->maxw;
|
||||
refh = self->maxh;
|
||||
}
|
||||
|
||||
scale->setValue (tmpScale);
|
||||
break;
|
||||
}
|
||||
self->w->set_range(32, 4 * refw);
|
||||
self->h->set_range(32, 4 * refh);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (self->spec->get_active_row_number()) {
|
||||
case 0: {
|
||||
// Scale mode
|
||||
self->w->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * self->scale->getValue() + 0.5)));
|
||||
self->h->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refh) * self->scale->getValue() + 0.5)));
|
||||
break;
|
||||
}
|
||||
|
||||
scale->block(false);
|
||||
wconn.block (false);
|
||||
hconn.block (false);
|
||||
case 1: {
|
||||
// Width mode
|
||||
const double tmp_scale = self->w->get_value() / static_cast<double>(refw);
|
||||
self->scale->setValue(tmp_scale);
|
||||
self->h->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refh) * tmp_scale + 0.5)));
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
// Height mode
|
||||
const double tmp_scale = self->h->get_value() / static_cast<double>(refh);
|
||||
self->scale->setValue(tmp_scale);
|
||||
self->w->set_value(static_cast<double>(static_cast<int>(static_cast<double>(refw) * tmp_scale + 0.5)));
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
// Bounding box mode
|
||||
const double tmp_scale =
|
||||
self->w->get_value() / self->h->get_value() < static_cast<double>(refw) / static_cast<double>(refh)
|
||||
? self->w->get_value() / static_cast<double>(refw)
|
||||
: self->h->get_value() / static_cast<double>(refh);
|
||||
|
||||
self->scale->setValue(tmp_scale);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self->scale->block(false);
|
||||
self->wconn.block(false);
|
||||
self->hconn.block(false);
|
||||
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
idle_register.add(func, this);
|
||||
}
|
||||
|
||||
void Resize::fitBoxScale()
|
||||
|
Reference in New Issue
Block a user