* Removed hard coded events from ProcEventCode and RefreshMap * Change HISTORY_MSG_* to HISTORY_MSG_FRAMING_*
1094 lines
35 KiB
C++
1094 lines
35 KiB
C++
/*
|
|
* This file is part of RawTherapee.
|
|
*
|
|
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
|
|
*
|
|
* RawTherapee is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* RawTherapee is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with RawTherapee. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* 2024-2024 Daniel Gao <daniel.gao.work@gmail.com>
|
|
*/
|
|
|
|
#include "framing.h"
|
|
|
|
#include "aspectratios.h"
|
|
#include "colorpreview.h"
|
|
#include "eventmapper.h"
|
|
#include "paramsedited.h"
|
|
#include "resize.h"
|
|
|
|
#include "../rtengine/color.h"
|
|
#include "../rtengine/procparams.h"
|
|
|
|
#include <array>
|
|
#include <iomanip>
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
|
|
using namespace rtengine;
|
|
using rtengine::procparams::FramingParams;
|
|
|
|
constexpr int EMPTY_COMBO_INDEX = -1;
|
|
|
|
// Framing method combo box data
|
|
constexpr int INDEX_STANDARD = 0;
|
|
constexpr int INDEX_BBOX = 1;
|
|
constexpr int INDEX_FIXED = 2;
|
|
constexpr int INDEX_FRAMING_METHOD_UNCHANGED = 3;
|
|
constexpr std::array<const char*, 3> FRAMING_METHODS = {
|
|
"TP_FRAMING_METHOD_STANDARD",
|
|
"TP_FRAMING_METHOD_BBOX",
|
|
"TP_FRAMING_METHOD_FIXED"
|
|
};
|
|
|
|
int mapFramingMethod(FramingParams::FramingMethod framingMethod)
|
|
{
|
|
using FramingMethod = FramingParams::FramingMethod;
|
|
switch (framingMethod) {
|
|
case FramingMethod::STANDARD:
|
|
return INDEX_STANDARD;
|
|
case FramingMethod::BBOX:
|
|
return INDEX_BBOX;
|
|
case FramingMethod::FIXED_SIZE:
|
|
return INDEX_FIXED;
|
|
default:
|
|
return INDEX_STANDARD;
|
|
}
|
|
}
|
|
|
|
FramingParams::FramingMethod mapFramingMethod(int comboIndex)
|
|
{
|
|
using FramingMethod = FramingParams::FramingMethod;
|
|
switch (comboIndex) {
|
|
case INDEX_STANDARD:
|
|
return FramingMethod::STANDARD;
|
|
case INDEX_BBOX:
|
|
return FramingMethod::BBOX;
|
|
case INDEX_FIXED:
|
|
return FramingMethod::FIXED_SIZE;
|
|
default:
|
|
return FramingMethod::STANDARD;
|
|
}
|
|
}
|
|
|
|
// Orientation combo box data
|
|
constexpr int INDEX_AS_IMAGE = 0;
|
|
constexpr int INDEX_LANDSCAPE = 1;
|
|
constexpr int INDEX_PORTRAIT = 2;
|
|
constexpr int INDEX_ORIENTATION_UNCHANGED = 3;
|
|
constexpr std::array<const char*, 3> ORIENTATION = {
|
|
"GENERAL_ASIMAGE",
|
|
"GENERAL_LANDSCAPE",
|
|
"GENERAL_PORTRAIT"
|
|
};
|
|
|
|
int mapOrientation(FramingParams::Orientation orientation)
|
|
{
|
|
using Orientation = FramingParams::Orientation;
|
|
switch (orientation) {
|
|
case Orientation::AS_IMAGE:
|
|
return INDEX_AS_IMAGE;
|
|
case Orientation::LANDSCAPE:
|
|
return INDEX_LANDSCAPE;
|
|
case Orientation::PORTRAIT:
|
|
return INDEX_PORTRAIT;
|
|
default:
|
|
return INDEX_AS_IMAGE;
|
|
}
|
|
}
|
|
|
|
FramingParams::Orientation mapOrientation(int comboIndex)
|
|
{
|
|
using Orientation = FramingParams::Orientation;
|
|
switch (comboIndex) {
|
|
case INDEX_AS_IMAGE:
|
|
return Orientation::AS_IMAGE;
|
|
case INDEX_LANDSCAPE:
|
|
return Orientation::LANDSCAPE;
|
|
case INDEX_PORTRAIT:
|
|
return Orientation::PORTRAIT;
|
|
default:
|
|
return Orientation::AS_IMAGE;
|
|
}
|
|
}
|
|
|
|
// Border sizing method combo box data
|
|
constexpr int INDEX_SIZE_RELATIVE = 0;
|
|
constexpr int INDEX_SIZE_UNIFORM_RELATIVE = 1;
|
|
constexpr int INDEX_SIZE_ABSOLUTE = 2;
|
|
constexpr int INDEX_SIZE_UNCHANGED = 3;
|
|
constexpr std::array<const char*, 3> BORDER_SIZE_METHODS = {
|
|
"TP_FRAMING_BORDER_SIZE_RELATIVE",
|
|
"TP_FRAMING_BORDER_SIZE_UNIFORM_RELATIVE",
|
|
"TP_FRAMING_BORDER_SIZE_ABSOLUTE"
|
|
};
|
|
|
|
int mapBorderSizeMethod(FramingParams::BorderSizing sizing)
|
|
{
|
|
using BorderSizing = FramingParams::BorderSizing;
|
|
switch (sizing) {
|
|
case BorderSizing::PERCENTAGE:
|
|
return INDEX_SIZE_RELATIVE;
|
|
case BorderSizing::UNIFORM_PERCENTAGE:
|
|
return INDEX_SIZE_UNIFORM_RELATIVE;
|
|
case BorderSizing::FIXED_SIZE:
|
|
return INDEX_SIZE_ABSOLUTE;
|
|
default:
|
|
return INDEX_SIZE_RELATIVE;
|
|
}
|
|
}
|
|
|
|
FramingParams::BorderSizing mapBorderSizeMethod(int comboIndex)
|
|
{
|
|
using BorderSizing = FramingParams::BorderSizing;
|
|
switch (comboIndex) {
|
|
case INDEX_SIZE_RELATIVE:
|
|
return BorderSizing::PERCENTAGE;
|
|
case INDEX_SIZE_UNIFORM_RELATIVE:
|
|
return BorderSizing::UNIFORM_PERCENTAGE;
|
|
case INDEX_SIZE_ABSOLUTE:
|
|
return BorderSizing::FIXED_SIZE;
|
|
default:
|
|
return BorderSizing::PERCENTAGE;
|
|
}
|
|
}
|
|
|
|
// Relative sizing basis combo box data
|
|
constexpr int INDEX_BASIS_AUTO = 0;
|
|
constexpr int INDEX_BASIS_WIDTH = 1;
|
|
constexpr int INDEX_BASIS_HEIGHT = 2;
|
|
constexpr int INDEX_BASIS_LONG = 3;
|
|
constexpr int INDEX_BASIS_SHORT = 4;
|
|
constexpr int INDEX_BASIS_UNCHANGED = 5;
|
|
constexpr std::array<const char*, 5> BORDER_SIZE_BASIS = {
|
|
"TP_FRAMING_BASIS_AUTO",
|
|
"TP_FRAMING_BASIS_WIDTH",
|
|
"TP_FRAMING_BASIS_HEIGHT",
|
|
"TP_FRAMING_BASIS_LONG_SIDE",
|
|
"TP_FRAMING_BASIS_SHORT_SIDE"
|
|
};
|
|
|
|
int mapBasis(FramingParams::Basis basis)
|
|
{
|
|
using Basis = FramingParams::Basis;
|
|
switch(basis) {
|
|
case Basis::AUTO:
|
|
return INDEX_BASIS_AUTO;
|
|
case Basis::WIDTH:
|
|
return INDEX_BASIS_WIDTH;
|
|
case Basis::HEIGHT:
|
|
return INDEX_BASIS_HEIGHT;
|
|
case Basis::LONG:
|
|
return INDEX_BASIS_LONG;
|
|
case Basis::SHORT:
|
|
return INDEX_BASIS_SHORT;
|
|
default:
|
|
return INDEX_BASIS_AUTO;
|
|
}
|
|
}
|
|
|
|
FramingParams::Basis mapBasis(int comboIndex)
|
|
{
|
|
using Basis = FramingParams::Basis;
|
|
switch(comboIndex) {
|
|
case INDEX_BASIS_AUTO:
|
|
return Basis::AUTO;
|
|
case INDEX_BASIS_WIDTH:
|
|
return Basis::WIDTH;
|
|
case INDEX_BASIS_HEIGHT:
|
|
return Basis::HEIGHT;
|
|
case INDEX_BASIS_LONG:
|
|
return Basis::LONG;
|
|
case INDEX_BASIS_SHORT:
|
|
return Basis::SHORT;
|
|
default:
|
|
return Basis::AUTO;
|
|
}
|
|
}
|
|
|
|
constexpr int INITIAL_IMG_WIDTH = 100000;
|
|
constexpr int INITIAL_IMG_HEIGHT = 100000;
|
|
constexpr int MAX_COLOR_VAL = 255;
|
|
|
|
constexpr int ROW_SPACING = 4;
|
|
constexpr float FRAME_LABEL_ALIGN_X = 0.025;
|
|
constexpr float FRAME_LABEL_ALIGN_Y = 0.5;
|
|
|
|
Gtk::Label* createGridLabel(const char* text)
|
|
{
|
|
Gtk::Label* label = Gtk::manage(new Gtk::Label(M(text)));
|
|
label->set_halign(Gtk::ALIGN_START);
|
|
return label;
|
|
}
|
|
|
|
MySpinButton* createSpinButton()
|
|
{
|
|
MySpinButton* button = Gtk::manage(new MySpinButton());
|
|
button->set_width_chars(5);
|
|
button->set_digits(0);
|
|
button->set_increments(1, 100);
|
|
setExpandAlignProperties(button, false, false, Gtk::ALIGN_END, Gtk::ALIGN_CENTER);
|
|
return button;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
const Glib::ustring Framing::TOOL_NAME = "framing";
|
|
|
|
class Framing::AspectRatios
|
|
{
|
|
public:
|
|
static constexpr int INDEX_CURRENT = 0;
|
|
|
|
AspectRatios() :
|
|
ratios{{M("GENERAL_ASIMAGE")}}
|
|
{
|
|
fillAspectRatios(ratios);
|
|
}
|
|
|
|
void fillCombo(MyComboBoxText* combo) const
|
|
{
|
|
for (const auto& aspectRatio : ratios) {
|
|
combo->append(aspectRatio.label);
|
|
}
|
|
combo->set_active(INDEX_CURRENT);
|
|
}
|
|
|
|
int unchangedIndex() const { return ratios.size(); }
|
|
|
|
double value(int index) const
|
|
{
|
|
return ratios.at(index).value;
|
|
}
|
|
|
|
int findIndex(double aspectRatio) const
|
|
{
|
|
if (aspectRatio == FramingParams::AS_IMAGE_ASPECT_RATIO) return INDEX_CURRENT;
|
|
|
|
for (size_t i = 1; i < ratios.size(); i++) {
|
|
if (ratios[i].value == aspectRatio) return i;
|
|
}
|
|
|
|
// Couldn't find a matching value
|
|
return INDEX_CURRENT;
|
|
}
|
|
|
|
private:
|
|
std::vector<AspectRatio> ratios;
|
|
};
|
|
|
|
Framing::DimensionGui::DimensionGui(Gtk::Box* parent, const char* text)
|
|
{
|
|
box = Gtk::manage(new Gtk::Box());
|
|
Gtk::Label* label = Gtk::manage(new Gtk::Label(M(text)));
|
|
setExpandAlignProperties(label, false, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
|
value = createSpinButton();
|
|
box->pack_start(*label);
|
|
box->pack_start(*value);
|
|
parent->pack_start(*box);
|
|
}
|
|
|
|
void Framing::DimensionGui::connect(Framing& framing, CallbackFunc callback)
|
|
{
|
|
connection = value->signal_value_changed().connect(sigc::mem_fun(framing, callback), true);
|
|
}
|
|
|
|
Framing::Framing() :
|
|
FoldableToolPanel(this, TOOL_NAME, M("TP_FRAMING_LABEL"), false, true),
|
|
aspectRatioData(new AspectRatios),
|
|
imgWidth(INITIAL_IMG_WIDTH),
|
|
imgHeight(INITIAL_IMG_HEIGHT),
|
|
lastAllowUpscaling(false),
|
|
lastMinSizeEnabled(false)
|
|
{
|
|
setupEvents();
|
|
setupFramingMethodGui();
|
|
pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)));
|
|
setupBorderSizeGui();
|
|
pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL)));
|
|
setupBorderColorsGui();
|
|
}
|
|
|
|
Framing::~Framing() {
|
|
idleRegister.destroy();
|
|
}
|
|
|
|
void Framing::setupEvents()
|
|
{
|
|
auto m = ProcEventMapper::getInstance();
|
|
|
|
// clang-format off
|
|
EvFramingEnabled = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ENABLED");
|
|
EvFramingMethod = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_METHOD");
|
|
EvFramingAspectRatio = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ASPECT_RATIO");
|
|
EvFramingOrientation = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ORIENTATION");
|
|
EvFramingFramedWidth = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_FRAMED_WIDTH");
|
|
EvFramingFramedHeight = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_FRAMED_HEIGHT");
|
|
EvFramingAllowUpscaling = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ALLOW_UPSCALING");
|
|
EvFramingBorderSizingMethod = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BORDER_SIZE_METHOD");
|
|
EvFramingBasis = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BASIS");
|
|
EvFramingRelativeBorderSize = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BORDER_SIZE");
|
|
EvFramingMinSizeEnabled = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_MIN_SIZE_ENABLED");
|
|
EvFramingMinWidth = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_MIN_WIDTH");
|
|
EvFramingMinHeight = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_MIN_HEIGHT");
|
|
EvFramingAbsWidth = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ABSOLUTE_WIDTH");
|
|
EvFramingAbsHeight = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_ABSOLUTE_HEIGHT");
|
|
EvFramingBorderRed = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BORDER_RED");
|
|
EvFramingBorderGreen = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BORDER_GREEN");
|
|
EvFramingBorderBlue = m->newEvent(RESIZE, "HISTORY_MSG_FRAMING_BORDER_BLUE");
|
|
// clang-format on
|
|
}
|
|
|
|
void Framing::setupFramingMethodGui()
|
|
{
|
|
Gtk::Grid* combos = Gtk::manage(new Gtk::Grid());
|
|
combos->set_row_spacing(ROW_SPACING);
|
|
|
|
framingMethod = Gtk::manage(new MyComboBoxText());
|
|
for (auto label : FRAMING_METHODS) {
|
|
framingMethod->append(M(label));
|
|
}
|
|
framingMethod->set_active(INDEX_STANDARD);
|
|
framingMethod->set_hexpand();
|
|
framingMethod->set_halign(Gtk::ALIGN_FILL);
|
|
|
|
combos->attach(*createGridLabel("TP_FRAMING_METHOD"), 0, 0);
|
|
combos->attach(*framingMethod, 1, 0);
|
|
|
|
aspectRatioLabel = createGridLabel("TP_FRAMING_ASPECT_RATIO");
|
|
aspectRatio = Gtk::manage(new MyComboBoxText());
|
|
aspectRatioData->fillCombo(aspectRatio);
|
|
aspectRatio->set_hexpand();
|
|
aspectRatio->set_halign(Gtk::ALIGN_FILL);
|
|
|
|
combos->attach(*aspectRatioLabel, 0, 1);
|
|
combos->attach(*aspectRatio, 1, 1);
|
|
|
|
orientationLabel = createGridLabel("TP_FRAMING_ORIENTATION");
|
|
orientation = Gtk::manage(new MyComboBoxText());
|
|
for (auto label : ORIENTATION) {
|
|
orientation->append(M(label));
|
|
}
|
|
orientation->set_active(INDEX_AS_IMAGE);
|
|
orientation->set_hexpand();
|
|
orientation->set_halign(Gtk::ALIGN_FILL);
|
|
|
|
combos->attach(*orientationLabel, 0, 2);
|
|
combos->attach(*orientation, 1, 2);
|
|
pack_start(*combos);
|
|
|
|
width = DimensionGui(this, "TP_FRAMING_FRAMED_WIDTH");
|
|
width.setRange(Resize::MIN_SIZE, Resize::MAX_SCALE * imgWidth);
|
|
width.setValue(imgWidth);
|
|
height = DimensionGui(this, "TP_FRAMING_FRAMED_HEIGHT");
|
|
height.setRange(Resize::MIN_SIZE, Resize::MAX_SCALE * imgHeight);
|
|
height.setValue(imgHeight);
|
|
|
|
allowUpscaling = Gtk::manage(new Gtk::CheckButton(M("TP_FRAMING_ALLOW_UPSCALING")));
|
|
pack_start(*allowUpscaling);
|
|
|
|
updateFramingMethodGui();
|
|
|
|
framingMethodChanged = framingMethod->signal_changed().connect(
|
|
sigc::mem_fun(*this, &Framing::onFramingMethodChanged));
|
|
aspectRatioChanged = aspectRatio->signal_changed().connect(
|
|
sigc::mem_fun(*this, &Framing::onAspectRatioChanged));
|
|
orientationChanged = orientation->signal_changed().connect(
|
|
sigc::mem_fun(*this, &Framing::onOrientationChanged));
|
|
width.connect(*this, &Framing::onWidthChanged);
|
|
height.connect(*this, &Framing::onHeightChanged);
|
|
allowUpscalingConnection = allowUpscaling->signal_toggled().connect(
|
|
sigc::mem_fun(*this, &Framing::onAllowUpscalingToggled));
|
|
}
|
|
|
|
void Framing::setupBorderSizeGui()
|
|
{
|
|
Gtk::Grid* combos = Gtk::manage(new Gtk::Grid());
|
|
combos->set_row_spacing(ROW_SPACING);
|
|
|
|
borderSizeMethod = Gtk::manage(new MyComboBoxText());
|
|
for (auto label : BORDER_SIZE_METHODS) {
|
|
borderSizeMethod->append(M(label));
|
|
}
|
|
borderSizeMethod->set_active(INDEX_SIZE_RELATIVE);
|
|
borderSizeMethod->set_hexpand();
|
|
borderSizeMethod->set_halign(Gtk::ALIGN_FILL);
|
|
|
|
combos->attach(*createGridLabel("TP_FRAMING_BORDER_SIZE_METHOD"), 0, 0);
|
|
combos->attach(*borderSizeMethod, 1, 0);
|
|
|
|
basisLabel = createGridLabel("TP_FRAMING_BASIS");
|
|
basis = Gtk::manage(new MyComboBoxText());
|
|
for (auto label : BORDER_SIZE_BASIS) {
|
|
basis->append(M(label));
|
|
}
|
|
basis->set_active(INDEX_BASIS_AUTO);
|
|
basis->set_hexpand();
|
|
basis->set_halign(Gtk::ALIGN_FILL);
|
|
|
|
combos->attach(*basisLabel, 0, 1);
|
|
combos->attach(*basis, 1, 1);
|
|
|
|
pack_start(*combos);
|
|
|
|
relativeBorderSize = Gtk::manage(new Adjuster(M("TP_FRAMING_BORDER_SIZE"), 0, 1, 0.01, 0.1));
|
|
pack_start(*relativeBorderSize);
|
|
|
|
minSizeFrame = Gtk::manage(new Gtk::Frame());
|
|
minSizeFrame->set_label_align(FRAME_LABEL_ALIGN_X, FRAME_LABEL_ALIGN_Y);
|
|
minSizeEnabled = Gtk::manage(new Gtk::CheckButton(M("TP_FRAMING_LIMIT_MINIMUM")));
|
|
minSizeFrame->set_label_widget(*minSizeEnabled);
|
|
|
|
minSizeFrameContent = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
|
|
|
|
minWidth = DimensionGui(minSizeFrameContent, "TP_FRAMING_MIN_WIDTH");
|
|
minWidth.setRange(0, imgWidth);
|
|
minWidth.setValue(0);
|
|
minHeight = DimensionGui(minSizeFrameContent, "TP_FRAMING_MIN_HEIGHT");
|
|
minHeight.setRange(0, imgHeight);
|
|
minHeight.setValue(0);
|
|
|
|
minSizeFrame->add(*minSizeFrameContent);
|
|
pack_start(*minSizeFrame);
|
|
|
|
absWidth = DimensionGui(this, "TP_FRAMING_ABSOLUTE_WIDTH");
|
|
absWidth.setRange(0, imgWidth);
|
|
absWidth.setValue(0);
|
|
absHeight = DimensionGui(this, "TP_FRAMING_ABSOLUTE_HEIGHT");
|
|
absHeight.setRange(0, imgHeight);
|
|
absHeight.setValue(0);
|
|
|
|
updateBorderSizeGui();
|
|
|
|
borderSizeMethodChanged = borderSizeMethod->signal_changed().connect(
|
|
sigc::mem_fun(*this, &Framing::onBorderSizeMethodChanged));
|
|
basisChanged = basis->signal_changed().connect(
|
|
sigc::mem_fun(*this, &Framing::onBasisChanged));
|
|
relativeBorderSize->setAdjusterListener(this);
|
|
minSizeEnabledConnection = minSizeEnabled->signal_toggled().connect(
|
|
sigc::mem_fun(*this, &Framing::onMinSizeToggled));
|
|
minWidth.connect(*this, &Framing::onMinWidthChanged);
|
|
minHeight.connect(*this, &Framing::onMinHeightChanged);
|
|
absWidth.connect(*this, &Framing::onAbsWidthChanged);
|
|
absHeight.connect(*this, &Framing::onAbsHeightChanged);
|
|
}
|
|
|
|
void Framing::setupBorderColorsGui()
|
|
{
|
|
Gtk::Frame* const frame = Gtk::manage(new Gtk::Frame());
|
|
|
|
Gtk::Label* const label = Gtk::manage(new Gtk::Label(M("TP_FRAMING_BORDER_COLOR")));
|
|
frame->set_label_align(FRAME_LABEL_ALIGN_X, FRAME_LABEL_ALIGN_Y);
|
|
frame->set_label_widget(*label);
|
|
|
|
Gtk::Box* const box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
|
|
redAdj = Gtk::manage(new Adjuster(M("TP_FRAMING_RED"), 0, MAX_COLOR_VAL, 1, MAX_COLOR_VAL));
|
|
box->add(*redAdj);
|
|
greenAdj = Gtk::manage(new Adjuster(M("TP_FRAMING_GREEN"), 0, MAX_COLOR_VAL, 1, MAX_COLOR_VAL));
|
|
box->add(*greenAdj);
|
|
blueAdj = Gtk::manage(new Adjuster(M("TP_FRAMING_BLUE"), 0, MAX_COLOR_VAL, 1, MAX_COLOR_VAL));
|
|
box->add(*blueAdj);
|
|
|
|
Gtk::Frame* const colorFrame = Gtk::manage(new Gtk::Frame());
|
|
colorPreview = Gtk::manage(new ColorPreview());
|
|
colorFrame->add(*colorPreview);
|
|
box->add(*colorFrame);
|
|
|
|
frame->add(*box);
|
|
pack_start(*frame);
|
|
|
|
updateBorderColorGui();
|
|
|
|
redAdj->setAdjusterListener(this);
|
|
greenAdj->setAdjusterListener(this);
|
|
blueAdj->setAdjusterListener(this);
|
|
}
|
|
|
|
void Framing::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
|
|
{
|
|
DisableListener disableListener(this);
|
|
|
|
std::array<ConnectionBlocker, 13> blockers = {
|
|
ConnectionBlocker(framingMethodChanged),
|
|
ConnectionBlocker(aspectRatioChanged),
|
|
ConnectionBlocker(orientationChanged),
|
|
ConnectionBlocker(width.connection),
|
|
ConnectionBlocker(height.connection),
|
|
ConnectionBlocker(allowUpscalingConnection),
|
|
ConnectionBlocker(borderSizeMethodChanged),
|
|
ConnectionBlocker(basisChanged),
|
|
ConnectionBlocker(minSizeEnabledConnection),
|
|
ConnectionBlocker(minWidth.connection),
|
|
ConnectionBlocker(minHeight.connection),
|
|
ConnectionBlocker(absWidth.connection),
|
|
ConnectionBlocker(absHeight.connection)
|
|
};
|
|
|
|
BlockAdjusterEvents blockRelative(relativeBorderSize);
|
|
BlockAdjusterEvents blockRed(redAdj);
|
|
BlockAdjusterEvents blockGreen(greenAdj);
|
|
BlockAdjusterEvents blockBlue(blueAdj);
|
|
|
|
readParams(pp);
|
|
readEdited(pedited);
|
|
|
|
updateFramingMethodGui();
|
|
updateBorderSizeGui();
|
|
updateBorderColorGui();
|
|
setDimensions();
|
|
}
|
|
|
|
void Framing::readParams(const rtengine::procparams::ProcParams* pp)
|
|
{
|
|
const rtengine::procparams::FramingParams& params = pp->framing;
|
|
|
|
setEnabled(params.enabled);
|
|
|
|
framingMethod->set_active(mapFramingMethod(params.framingMethod));
|
|
aspectRatio->set_active(aspectRatioData->findIndex(params.aspectRatio));
|
|
orientation->set_active(mapOrientation(params.orientation));
|
|
width.setValue(params.framedWidth);
|
|
width.isDirty = false;
|
|
height.setValue(params.framedHeight);
|
|
height.isDirty = false;
|
|
allowUpscaling->set_active(params.allowUpscaling);
|
|
lastAllowUpscaling = params.allowUpscaling;
|
|
|
|
borderSizeMethod->set_active(mapBorderSizeMethod(params.borderSizingMethod));
|
|
basis->set_active(mapBasis(params.basis));
|
|
relativeBorderSize->setValue(params.relativeBorderSize);
|
|
minSizeEnabled->set_active(params.minSizeEnabled);
|
|
lastMinSizeEnabled = params.minSizeEnabled;
|
|
minWidth.setValue(params.minWidth);
|
|
minWidth.isDirty = false;
|
|
minHeight.setValue(params.minHeight);
|
|
minHeight.isDirty = false;
|
|
absWidth.setValue(params.absWidth);
|
|
absWidth.isDirty = false;
|
|
absHeight.setValue(params.absHeight);
|
|
absHeight.isDirty = false;
|
|
|
|
redAdj->setValue(params.borderRed);
|
|
greenAdj->setValue(params.borderGreen);
|
|
blueAdj->setValue(params.borderBlue);
|
|
}
|
|
|
|
void Framing::readEdited(const ParamsEdited* pedited)
|
|
{
|
|
if (!pedited) return;
|
|
|
|
const FramingParamsEdited& edits = pedited->framing;
|
|
|
|
set_inconsistent(multiImage && !edits.enabled);
|
|
|
|
if (!edits.framingMethod) {
|
|
framingMethod->set_active(EMPTY_COMBO_INDEX);
|
|
}
|
|
if (!edits.aspectRatio) {
|
|
aspectRatio->set_active(EMPTY_COMBO_INDEX);
|
|
}
|
|
if (!edits.orientation) {
|
|
orientation->set_active(EMPTY_COMBO_INDEX);
|
|
}
|
|
width.isDirty = edits.framedWidth;
|
|
height.isDirty = edits.framedHeight;
|
|
allowUpscaling->set_inconsistent(edits.allowUpscaling);
|
|
|
|
if (!edits.borderSizingMethod) {
|
|
borderSizeMethod->set_active(EMPTY_COMBO_INDEX);
|
|
}
|
|
if (!edits.basis) {
|
|
basis->set_active(EMPTY_COMBO_INDEX);
|
|
}
|
|
relativeBorderSize->setEditedState(edits.relativeBorderSize ? Edited : UnEdited);
|
|
minSizeEnabled->set_inconsistent(edits.minSizeEnabled);
|
|
minWidth.isDirty = edits.minWidth;
|
|
minHeight.isDirty = edits.minHeight;
|
|
absWidth.isDirty = edits.absWidth;
|
|
absHeight.isDirty = edits.absHeight;
|
|
|
|
redAdj->setEditedState(edits.borderRed ? Edited : UnEdited);
|
|
greenAdj->setEditedState(edits.borderGreen ? Edited : UnEdited);
|
|
blueAdj->setEditedState(edits.borderBlue ? Edited : UnEdited);
|
|
}
|
|
|
|
void Framing::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
|
|
{
|
|
writeParams(pp);
|
|
writeEdited(pedited);
|
|
}
|
|
|
|
void Framing::writeParams(rtengine::procparams::ProcParams* pp)
|
|
{
|
|
rtengine::procparams::FramingParams& params = pp->framing;
|
|
|
|
params.enabled = getEnabled();
|
|
|
|
params.framingMethod = mapFramingMethod(framingMethod->get_active_row_number());
|
|
params.aspectRatio = aspectRatioData->value(aspectRatio->get_active_row_number());
|
|
params.orientation = mapOrientation(orientation->get_active_row_number());
|
|
params.framedWidth = width.value->get_value_as_int();
|
|
params.framedHeight = height.value->get_value_as_int();
|
|
params.allowUpscaling = allowUpscaling->get_active();
|
|
|
|
params.borderSizingMethod = mapBorderSizeMethod(borderSizeMethod->get_active_row_number());
|
|
params.basis = mapBasis(basis->get_active_row_number());
|
|
params.relativeBorderSize = relativeBorderSize->getValue();
|
|
params.minSizeEnabled = minSizeEnabled->get_active();
|
|
params.minWidth = minWidth.value->get_value_as_int();
|
|
params.minHeight = minHeight.value->get_value_as_int();
|
|
params.absWidth = absWidth.value->get_value_as_int();
|
|
params.absHeight = absHeight.value->get_value_as_int();
|
|
|
|
params.borderRed = redAdj->getValue();
|
|
params.borderGreen = greenAdj->getValue();
|
|
params.borderBlue = blueAdj->getValue();
|
|
}
|
|
|
|
void Framing::writeEdited(ParamsEdited* pedited)
|
|
{
|
|
if (!pedited) return;
|
|
|
|
FramingParamsEdited& edits = pedited->framing;
|
|
|
|
edits.enabled = !get_inconsistent();
|
|
|
|
edits.framingMethod = framingMethod->get_active_row_number() != INDEX_FRAMING_METHOD_UNCHANGED;
|
|
edits.aspectRatio = aspectRatio->get_active_row_number() != aspectRatioData->unchangedIndex();
|
|
edits.orientation = orientation->get_active_row_number() != INDEX_ORIENTATION_UNCHANGED;
|
|
edits.framedWidth = width.isDirty;
|
|
edits.framedHeight = height.isDirty;
|
|
edits.allowUpscaling = !allowUpscaling->get_inconsistent();
|
|
|
|
edits.borderSizingMethod = borderSizeMethod->get_active_row_number() != INDEX_SIZE_UNCHANGED;
|
|
edits.basis = basis->get_active_row_number() != INDEX_BASIS_UNCHANGED;
|
|
edits.relativeBorderSize = relativeBorderSize->getEditedState();
|
|
edits.minSizeEnabled = !minSizeEnabled->get_inconsistent();
|
|
edits.minWidth = minWidth.isDirty;
|
|
edits.minHeight = minHeight.isDirty;
|
|
edits.absWidth = absWidth.isDirty;
|
|
edits.absHeight = absHeight.isDirty;
|
|
|
|
edits.borderRed = redAdj->getEditedState();
|
|
edits.borderGreen = greenAdj->getEditedState();
|
|
edits.borderBlue = blueAdj->getEditedState();
|
|
}
|
|
|
|
void Framing::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited)
|
|
{
|
|
const FramingParams& params = defParams->framing;
|
|
|
|
relativeBorderSize->setDefault(params.relativeBorderSize);
|
|
redAdj->setDefault(params.borderRed);
|
|
greenAdj->setDefault(params.borderGreen);
|
|
blueAdj->setDefault(params.borderBlue);
|
|
|
|
if (pedited) {
|
|
const FramingParamsEdited& edits = pedited->framing;
|
|
|
|
relativeBorderSize->setDefaultEditedState(edits.relativeBorderSize ? Edited : UnEdited);
|
|
redAdj->setDefaultEditedState(edits.borderRed ? Edited : UnEdited);
|
|
greenAdj->setDefaultEditedState(edits.borderGreen ? Edited : UnEdited);
|
|
blueAdj->setDefaultEditedState(edits.borderBlue ? Edited : UnEdited);
|
|
} else {
|
|
relativeBorderSize->setDefaultEditedState(Irrelevant);
|
|
redAdj->setDefaultEditedState(Irrelevant);
|
|
greenAdj->setDefaultEditedState(Irrelevant);
|
|
blueAdj->setDefaultEditedState(Irrelevant);
|
|
}
|
|
}
|
|
|
|
void Framing::trimValues(rtengine::procparams::ProcParams* pp)
|
|
{
|
|
relativeBorderSize->trimValue(pp->framing.relativeBorderSize);
|
|
redAdj->trimValue(pp->framing.borderRed);
|
|
greenAdj->trimValue(pp->framing.borderGreen);
|
|
blueAdj->trimValue(pp->framing.borderBlue);
|
|
}
|
|
|
|
void Framing::setBatchMode(bool batchMode)
|
|
{
|
|
framingMethod->append(M("GENERAL_UNCHANGED"));
|
|
aspectRatio->append(M("GENERAL_UNCHANGED"));
|
|
orientation->append(M("GENERAL_UNCHANGED"));
|
|
borderSizeMethod->append(M("GENERAL_UNCHANGED"));
|
|
basis->append(M("GENERAL_UNCHANGED"));
|
|
|
|
ToolPanel::setBatchMode(batchMode);
|
|
relativeBorderSize->showEditedCB();
|
|
redAdj->showEditedCB();
|
|
greenAdj->showEditedCB();
|
|
blueAdj->showEditedCB();
|
|
}
|
|
|
|
void Framing::enabledChanged()
|
|
{
|
|
if (listener) {
|
|
if (get_inconsistent()) {
|
|
listener->panelChanged(EvFramingEnabled, M("GENERAL_UNCHANGED"));
|
|
} else if (getEnabled()) {
|
|
listener->panelChanged(EvFramingEnabled, M("GENERAL_ENABLED"));
|
|
} else {
|
|
listener->panelChanged(EvFramingEnabled, M("GENERAL_DISABLED"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Framing::update(int originalWidth, int originalHeight)
|
|
{
|
|
// This is how it is checked in resize.cc
|
|
if (originalWidth && originalHeight) {
|
|
imgWidth = originalWidth;
|
|
imgHeight = originalHeight;
|
|
}
|
|
}
|
|
|
|
void Framing::setAdjusterBehavior(bool addRelativeBorderSize, bool addRed, bool addGreen,
|
|
bool addBlue)
|
|
{
|
|
relativeBorderSize->setAddMode(addRelativeBorderSize);
|
|
redAdj->setAddMode(addRed);
|
|
greenAdj->setAddMode(addGreen);
|
|
blueAdj->setAddMode(addBlue);
|
|
}
|
|
|
|
void Framing::setDimensions()
|
|
{
|
|
idleRegister.add([this]() -> bool {
|
|
std::array<ConnectionBlocker, 6> blockers = {
|
|
ConnectionBlocker(width.connection),
|
|
ConnectionBlocker(height.connection),
|
|
ConnectionBlocker(minWidth.connection),
|
|
ConnectionBlocker(minHeight.connection),
|
|
ConnectionBlocker(absWidth.connection),
|
|
ConnectionBlocker(absHeight.connection)
|
|
};
|
|
|
|
// 16x the full image size is probably a reasonable max
|
|
width.value->set_range(Resize::MIN_SIZE, Resize::MAX_SCALE * imgWidth);
|
|
height.value->set_range(Resize::MIN_SIZE, Resize::MAX_SCALE * imgHeight);
|
|
minWidth.value->set_range(0, Resize::MAX_SCALE * imgWidth);
|
|
minHeight.value->set_range(0, Resize::MAX_SCALE * imgHeight);
|
|
absWidth.value->set_range(0, Resize::MAX_SCALE * imgWidth);
|
|
absHeight.value->set_range(0, Resize::MAX_SCALE * imgHeight);
|
|
|
|
return false;
|
|
});
|
|
}
|
|
|
|
void Framing::updateFramingMethodGui()
|
|
{
|
|
if (batchMode) {
|
|
aspectRatioLabel->show();
|
|
aspectRatio->show();
|
|
orientationLabel->show();
|
|
orientation->show();
|
|
width.show();
|
|
height.show();
|
|
allowUpscaling->show();
|
|
return;
|
|
}
|
|
|
|
int activeRow = framingMethod->get_active_row_number();
|
|
if (activeRow == INDEX_STANDARD) {
|
|
aspectRatioLabel->show();
|
|
aspectRatio->show();
|
|
orientationLabel->show();
|
|
orientation->show();
|
|
width.hide();
|
|
height.hide();
|
|
allowUpscaling->hide();
|
|
} else if (activeRow == INDEX_BBOX) {
|
|
aspectRatioLabel->show();
|
|
aspectRatio->show();
|
|
orientationLabel->show();
|
|
orientation->show();
|
|
width.show();
|
|
height.show();
|
|
allowUpscaling->show();
|
|
} else if (activeRow == INDEX_FIXED) {
|
|
aspectRatioLabel->hide();
|
|
aspectRatio->hide();
|
|
orientationLabel->hide();
|
|
orientation->hide();
|
|
width.show();
|
|
height.show();
|
|
allowUpscaling->show();
|
|
}
|
|
}
|
|
|
|
void Framing::updateBorderSizeGui()
|
|
{
|
|
if (batchMode) {
|
|
basisLabel->show();
|
|
basis->show();
|
|
relativeBorderSize->show();
|
|
minSizeFrame->show();
|
|
absWidth.show();
|
|
absHeight.show();
|
|
|
|
aspectRatio->set_sensitive(true);
|
|
orientation->set_sensitive(true);
|
|
|
|
minSizeFrameContent->set_sensitive(true);
|
|
return;
|
|
}
|
|
|
|
int activeRow = borderSizeMethod->get_active_row_number();
|
|
if (activeRow == INDEX_SIZE_RELATIVE) {
|
|
basisLabel->show();
|
|
basis->show();
|
|
relativeBorderSize->show();
|
|
minSizeFrame->show();
|
|
absWidth.hide();
|
|
absHeight.hide();
|
|
|
|
aspectRatio->set_sensitive(true);
|
|
orientation->set_sensitive(true);
|
|
} else if (activeRow == INDEX_SIZE_UNIFORM_RELATIVE) {
|
|
basisLabel->show();
|
|
basis->show();
|
|
relativeBorderSize->show();
|
|
minSizeFrame->show();
|
|
absWidth.hide();
|
|
absHeight.hide();
|
|
|
|
aspectRatio->set_sensitive(false);
|
|
orientation->set_sensitive(false);
|
|
} else if (activeRow == INDEX_SIZE_ABSOLUTE) {
|
|
basisLabel->hide();
|
|
basis->hide();
|
|
relativeBorderSize->hide();
|
|
minSizeFrame->hide();
|
|
absWidth.show();
|
|
absHeight.show();
|
|
|
|
aspectRatio->set_sensitive(false);
|
|
orientation->set_sensitive(false);
|
|
}
|
|
|
|
minSizeFrameContent->set_sensitive(minSizeEnabled->get_active());
|
|
}
|
|
|
|
void Framing::updateBorderColorGui()
|
|
{
|
|
auto gamma = [](double val) {
|
|
// adjuster is [0.0, 255.0]
|
|
// gamma2curve expects [0, 65535]
|
|
// setRgb expects [0.0, 1.0]
|
|
return Color::gamma2curve[val * (MAX_COLOR_VAL + 1)] / 65535.0;
|
|
};
|
|
double r = gamma(redAdj->getValue());
|
|
double g = gamma(greenAdj->getValue());
|
|
double b = gamma(blueAdj->getValue());
|
|
colorPreview->setRgb(r, g, b);
|
|
}
|
|
|
|
void Framing::adjusterChanged(Adjuster* adj, double newVal)
|
|
{
|
|
if (adj == redAdj || adj == greenAdj || adj == blueAdj) {
|
|
updateBorderColorGui();
|
|
}
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
Glib::ustring costr;
|
|
if (adj == relativeBorderSize) {
|
|
costr = Glib::ustring::format(std::setw(3), std::fixed, std::setprecision(2),
|
|
adj->getValue());
|
|
} else {
|
|
costr = Glib::ustring::format(static_cast<int>(adj->getValue()));
|
|
}
|
|
|
|
if (adj == relativeBorderSize) {
|
|
listener->panelChanged(EvFramingRelativeBorderSize, costr);
|
|
} else if (adj == redAdj) {
|
|
listener->panelChanged(EvFramingBorderRed, costr);
|
|
} else if (adj == greenAdj) {
|
|
listener->panelChanged(EvFramingBorderGreen, costr);
|
|
} else if (adj == blueAdj) {
|
|
listener->panelChanged(EvFramingBorderBlue, costr);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Framing::onFramingMethodChanged()
|
|
{
|
|
updateFramingMethodGui();
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingMethod, framingMethod->get_active_text());
|
|
}
|
|
}
|
|
|
|
void Framing::onAspectRatioChanged()
|
|
{
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingAspectRatio, aspectRatio->get_active_text());
|
|
}
|
|
}
|
|
|
|
void Framing::onOrientationChanged()
|
|
{
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingOrientation, orientation->get_active_text());
|
|
}
|
|
}
|
|
|
|
void Framing::onWidthChanged()
|
|
{
|
|
width.isDirty = true;
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingFramedWidth,
|
|
Glib::ustring::format(width.value->get_value_as_int()));
|
|
}
|
|
}
|
|
|
|
void Framing::onHeightChanged()
|
|
{
|
|
height.isDirty = true;
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingFramedHeight,
|
|
Glib::ustring::format(height.value->get_value_as_int()));
|
|
}
|
|
}
|
|
|
|
void Framing::onAllowUpscalingToggled()
|
|
{
|
|
if (batchMode) {
|
|
if (allowUpscaling->get_inconsistent()) {
|
|
allowUpscaling->set_inconsistent(false);
|
|
ConnectionBlocker block(allowUpscalingConnection);
|
|
allowUpscaling->set_active(false);
|
|
} else if (lastAllowUpscaling) {
|
|
allowUpscaling->set_inconsistent(true);
|
|
}
|
|
|
|
lastAllowUpscaling = allowUpscaling->get_active();
|
|
}
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
if (allowUpscaling->get_inconsistent()) {
|
|
listener->panelChanged(EvFramingAllowUpscaling, M("GENERAL_UNCHANGED"));
|
|
} else if (allowUpscaling->get_active()) {
|
|
listener->panelChanged(EvFramingAllowUpscaling, M("GENERAL_ENABLED"));
|
|
} else {
|
|
listener->panelChanged(EvFramingAllowUpscaling, M("GENERAL_DISABLED"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Framing::onBorderSizeMethodChanged()
|
|
{
|
|
if (borderSizeMethod->get_active_row_number() == INDEX_SIZE_UNIFORM_RELATIVE) {
|
|
ConnectionBlocker block(minHeight.connection);
|
|
minHeight.isDirty = true;
|
|
minHeight.value->set_value(minWidth.value->get_value_as_int());
|
|
}
|
|
|
|
updateBorderSizeGui();
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingBorderSizingMethod, borderSizeMethod->get_active_text());
|
|
}
|
|
}
|
|
|
|
void Framing::onBasisChanged()
|
|
{
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingBasis, basis->get_active_text());
|
|
}
|
|
}
|
|
|
|
void Framing::onMinSizeToggled()
|
|
{
|
|
if (batchMode) {
|
|
if (minSizeEnabled->get_inconsistent()) {
|
|
minSizeEnabled->set_inconsistent(false);
|
|
ConnectionBlocker block(minSizeEnabledConnection);
|
|
minSizeEnabled->set_active(false);
|
|
} else if (lastMinSizeEnabled) {
|
|
minSizeEnabled->set_inconsistent(true);
|
|
}
|
|
|
|
lastMinSizeEnabled = minSizeEnabled->get_active();
|
|
}
|
|
|
|
updateBorderSizeGui();
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
if (minSizeEnabled->get_inconsistent()) {
|
|
listener->panelChanged(EvFramingMinSizeEnabled, M("GENERAL_UNCHANGED"));
|
|
} else if (minSizeEnabled->get_active()) {
|
|
listener->panelChanged(EvFramingMinSizeEnabled, M("GENERAL_ENABLED"));
|
|
} else {
|
|
listener->panelChanged(EvFramingMinSizeEnabled, M("GENERAL_DISABLED"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void Framing::onMinWidthChanged()
|
|
{
|
|
minWidth.isDirty = true;
|
|
int value = minWidth.value->get_value_as_int();
|
|
|
|
if (borderSizeMethod->get_active_row_number() == INDEX_SIZE_UNIFORM_RELATIVE) {
|
|
ConnectionBlocker block(minHeight.connection);
|
|
minHeight.isDirty = true;
|
|
minHeight.value->set_value(value);
|
|
}
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingMinWidth, Glib::ustring::format(value));
|
|
}
|
|
}
|
|
|
|
void Framing::onMinHeightChanged()
|
|
{
|
|
minHeight.isDirty = true;
|
|
int value = minHeight.value->get_value_as_int();
|
|
|
|
if (borderSizeMethod->get_active_row_number() == INDEX_SIZE_UNIFORM_RELATIVE) {
|
|
ConnectionBlocker block(minWidth.connection);
|
|
minWidth.isDirty = true;
|
|
minWidth.value->set_value(value);
|
|
}
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingMinHeight, Glib::ustring::format(value));
|
|
}
|
|
}
|
|
|
|
void Framing::onAbsWidthChanged()
|
|
{
|
|
absWidth.isDirty = true;
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingAbsWidth,
|
|
Glib::ustring::format(absWidth.value->get_value_as_int()));
|
|
}
|
|
}
|
|
|
|
void Framing::onAbsHeightChanged()
|
|
{
|
|
absHeight.isDirty = true;
|
|
|
|
if (listener && (getEnabled() || batchMode)) {
|
|
listener->panelChanged(EvFramingAbsHeight,
|
|
Glib::ustring::format(absHeight.value->get_value_as_int()));
|
|
}
|
|
}
|