Merge remote-tracking branch 'origin/dev' into std-mutex
This commit is contained in:
@@ -20,7 +20,6 @@
|
||||
|
||||
#include "guiutils.h"
|
||||
#include "options.h"
|
||||
#include "../rtengine/rt_math.h"
|
||||
#include "../rtengine/utils.h"
|
||||
#include "../rtengine/procparams.h"
|
||||
#include "rtimage.h"
|
||||
@@ -169,7 +168,7 @@ bool confirmOverwrite (Gtk::Window& parent, const std::string& filename)
|
||||
bool safe = true;
|
||||
|
||||
if (Glib::file_test (filename, Glib::FILE_TEST_EXISTS)) {
|
||||
Glib::ustring msg_ = Glib::ustring ("<b>\"") + Glib::path_get_basename (filename) + "\": "
|
||||
Glib::ustring msg_ = Glib::ustring ("<b>\"") + escapeHtmlChars(Glib::path_get_basename (filename)) + "\": "
|
||||
+ M("MAIN_MSG_ALREADYEXISTS") + "</b>\n" + M("MAIN_MSG_QOVERWRITE");
|
||||
Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true);
|
||||
safe = (msgd.run () == Gtk::RESPONSE_YES);
|
||||
@@ -180,7 +179,7 @@ bool confirmOverwrite (Gtk::Window& parent, const std::string& filename)
|
||||
|
||||
void writeFailed (Gtk::Window& parent, const std::string& filename)
|
||||
{
|
||||
Glib::ustring msg_ = Glib::ustring::compose(M("MAIN_MSG_WRITEFAILED"), filename);
|
||||
Glib::ustring msg_ = Glib::ustring::compose(M("MAIN_MSG_WRITEFAILED"), escapeHtmlChars(filename));
|
||||
Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
||||
msgd.run ();
|
||||
}
|
||||
@@ -215,7 +214,7 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int
|
||||
cr->fill ();
|
||||
|
||||
// rectangle around the cropped area and guides
|
||||
if (cparams.guide != "None" && drawGuide) {
|
||||
if (cparams.guide != rtengine::procparams::CropParams::Guide::NONE && drawGuide) {
|
||||
double rectx1 = round(c1x) + imx + 0.5;
|
||||
double recty1 = round(c1y) + imy + 0.5;
|
||||
double rectx2 = round(c2x) + imx + 0.5;
|
||||
@@ -244,60 +243,98 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int
|
||||
cr->stroke ();
|
||||
cr->set_dash (std::valarray<double>(), 0);
|
||||
|
||||
if (cparams.guide != "Rule of diagonals" && cparams.guide != "Golden Triangle 1" && cparams.guide != "Golden Triangle 2") {
|
||||
if (
|
||||
cparams.guide != rtengine::procparams::CropParams::Guide::RULE_OF_DIAGONALS
|
||||
&& cparams.guide != rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_1
|
||||
&& cparams.guide != rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_2
|
||||
) {
|
||||
// draw guide lines
|
||||
std::vector<double> horiz_ratios;
|
||||
std::vector<double> vert_ratios;
|
||||
|
||||
if (cparams.guide == "Rule of thirds") {
|
||||
horiz_ratios.push_back (1.0 / 3.0);
|
||||
horiz_ratios.push_back (2.0 / 3.0);
|
||||
vert_ratios.push_back (1.0 / 3.0);
|
||||
vert_ratios.push_back (2.0 / 3.0);
|
||||
} else if (!strncmp(cparams.guide.data(), "Harmonic means", 14)) {
|
||||
horiz_ratios.push_back (1.0 - 0.618);
|
||||
horiz_ratios.push_back (0.618);
|
||||
vert_ratios.push_back (0.618);
|
||||
vert_ratios.push_back (1.0 - 0.618);
|
||||
} else if (cparams.guide == "Grid") {
|
||||
// To have even distribution, normalize it a bit
|
||||
const int longSideNumLines = 10;
|
||||
switch (cparams.guide) {
|
||||
case rtengine::procparams::CropParams::Guide::NONE:
|
||||
case rtengine::procparams::CropParams::Guide::FRAME:
|
||||
case rtengine::procparams::CropParams::Guide::RULE_OF_DIAGONALS:
|
||||
case rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_1:
|
||||
case rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_2: {
|
||||
break;
|
||||
}
|
||||
|
||||
int w = rectx2 - rectx1, h = recty2 - recty1;
|
||||
case rtengine::procparams::CropParams::Guide::RULE_OF_THIRDS: {
|
||||
horiz_ratios.push_back (1.0 / 3.0);
|
||||
horiz_ratios.push_back (2.0 / 3.0);
|
||||
vert_ratios.push_back (1.0 / 3.0);
|
||||
vert_ratios.push_back (2.0 / 3.0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (w > longSideNumLines && h > longSideNumLines) {
|
||||
if (w > h) {
|
||||
for (int i = 1; i < longSideNumLines; i++) {
|
||||
vert_ratios.push_back ((double)i / longSideNumLines);
|
||||
}
|
||||
case rtengine::procparams::CropParams::Guide::HARMONIC_MEANS: {
|
||||
horiz_ratios.push_back (1.0 - 0.618);
|
||||
horiz_ratios.push_back (0.618);
|
||||
vert_ratios.push_back (0.618);
|
||||
vert_ratios.push_back (1.0 - 0.618);
|
||||
break;
|
||||
}
|
||||
|
||||
int shortSideNumLines = (int)round(h * (double)longSideNumLines / w);
|
||||
case rtengine::procparams::CropParams::Guide::GRID: {
|
||||
// To have even distribution, normalize it a bit
|
||||
const int longSideNumLines = 10;
|
||||
|
||||
for (int i = 1; i < shortSideNumLines; i++) {
|
||||
horiz_ratios.push_back ((double)i / shortSideNumLines);
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < longSideNumLines; i++) {
|
||||
horiz_ratios.push_back ((double)i / longSideNumLines);
|
||||
}
|
||||
int w = rectx2 - rectx1, h = recty2 - recty1;
|
||||
|
||||
int shortSideNumLines = (int)round(w * (double)longSideNumLines / h);
|
||||
if (w > longSideNumLines && h > longSideNumLines) {
|
||||
if (w > h) {
|
||||
for (int i = 1; i < longSideNumLines; i++) {
|
||||
vert_ratios.push_back ((double)i / longSideNumLines);
|
||||
}
|
||||
|
||||
for (int i = 1; i < shortSideNumLines; i++) {
|
||||
vert_ratios.push_back ((double)i / shortSideNumLines);
|
||||
int shortSideNumLines = (int)round(h * (double)longSideNumLines / w);
|
||||
|
||||
for (int i = 1; i < shortSideNumLines; i++) {
|
||||
horiz_ratios.push_back ((double)i / shortSideNumLines);
|
||||
}
|
||||
} else {
|
||||
for (int i = 1; i < longSideNumLines; i++) {
|
||||
horiz_ratios.push_back ((double)i / longSideNumLines);
|
||||
}
|
||||
|
||||
int shortSideNumLines = (int)round(w * (double)longSideNumLines / h);
|
||||
|
||||
for (int i = 1; i < shortSideNumLines; i++) {
|
||||
vert_ratios.push_back ((double)i / shortSideNumLines);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case rtengine::procparams::CropParams::Guide::EPASSPORT: {
|
||||
/* Official measurements do not specify exact ratios, just min/max measurements within which the eyes and chin-crown distance must lie. I averaged those measurements to produce these guides.
|
||||
* The first horizontal guide is for the crown, the second is roughly for the nostrils, the third is for the chin.
|
||||
* http://www.homeoffice.gov.uk/agencies-public-bodies/ips/passports/information-photographers/
|
||||
* "(...) the measurement of the face from the bottom of the chin to the crown (ie the top of the head, not the top of the hair) is between 29mm and 34mm."
|
||||
*/
|
||||
horiz_ratios.push_back (7.0 / 45.0);
|
||||
horiz_ratios.push_back (26.0 / 45.0);
|
||||
horiz_ratios.push_back (37.0 / 45.0);
|
||||
vert_ratios.push_back (0.5);
|
||||
break;
|
||||
}
|
||||
|
||||
case rtengine::procparams::CropParams::Guide::CENTERED_SQUARE: {
|
||||
const double w = rectx2 - rectx1, h = recty2 - recty1;
|
||||
double ratio = w / h;
|
||||
if (ratio < 1.0) {
|
||||
ratio = 1.0 / ratio;
|
||||
horiz_ratios.push_back((ratio - 1.0) / (2.0 * ratio));
|
||||
horiz_ratios.push_back(1.0 - (ratio - 1.0) / (2.0 * ratio));
|
||||
} else {
|
||||
vert_ratios.push_back((ratio - 1.0) / (2.0 * ratio));
|
||||
vert_ratios.push_back(1.0 - (ratio - 1.0) / (2.0 * ratio));
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (cparams.guide == "ePassport") {
|
||||
/* Official measurements do not specify exact ratios, just min/max measurements within which the eyes and chin-crown distance must lie. I averaged those measurements to produce these guides.
|
||||
* The first horizontal guide is for the crown, the second is roughly for the nostrils, the third is for the chin.
|
||||
* http://www.homeoffice.gov.uk/agencies-public-bodies/ips/passports/information-photographers/
|
||||
* "(...) the measurement of the face from the bottom of the chin to the crown (ie the top of the head, not the top of the hair) is between 29mm and 34mm."
|
||||
*/
|
||||
horiz_ratios.push_back (7.0 / 45.0);
|
||||
horiz_ratios.push_back (26.0 / 45.0);
|
||||
horiz_ratios.push_back (37.0 / 45.0);
|
||||
vert_ratios.push_back (0.5);
|
||||
}
|
||||
|
||||
// Horizontals
|
||||
@@ -333,7 +370,7 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int
|
||||
ds.resize (0);
|
||||
cr->set_dash (ds, 0);
|
||||
}
|
||||
} else if (cparams.guide == "Rule of diagonals") {
|
||||
} else if (cparams.guide == rtengine::procparams::CropParams::Guide::RULE_OF_DIAGONALS) {
|
||||
double corners_from[4][2];
|
||||
double corners_to[4][2];
|
||||
int mindim = min(rectx2 - rectx1, recty2 - recty1);
|
||||
@@ -369,9 +406,12 @@ void drawCrop (Cairo::RefPtr<Cairo::Context> cr, int imx, int imy, int imw, int
|
||||
ds.resize (0);
|
||||
cr->set_dash (ds, 0);
|
||||
}
|
||||
} else if (cparams.guide == "Golden Triangle 1" || cparams.guide == "Golden Triangle 2") {
|
||||
} else if (
|
||||
cparams.guide == rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_1
|
||||
|| cparams.guide == rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_2
|
||||
) {
|
||||
// main diagonal
|
||||
if(cparams.guide == "Golden Triangle 2") {
|
||||
if(cparams.guide == rtengine::procparams::CropParams::Guide::GOLDEN_TRIANGLE_2) {
|
||||
std::swap(rectx1, rectx2);
|
||||
}
|
||||
|
||||
@@ -521,18 +561,21 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) :
|
||||
child(nullptr), headerWidget(nullptr), statusImage(nullptr),
|
||||
label(nullptr), useEnabled(useEnabled)
|
||||
{
|
||||
set_orientation(Gtk::ORIENTATION_VERTICAL);
|
||||
set_spacing(0);
|
||||
set_name("MyExpander");
|
||||
set_can_focus(false);
|
||||
setExpandAlignProperties(this, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
|
||||
|
||||
headerHBox = Gtk::manage( new Gtk::HBox());
|
||||
headerHBox = Gtk::manage( new Gtk::Box());
|
||||
headerHBox->set_can_focus(false);
|
||||
setExpandAlignProperties(headerHBox, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
|
||||
|
||||
if (useEnabled) {
|
||||
get_style_context()->add_class("OnOff");
|
||||
statusImage = Gtk::manage(new RTImage(disabledImage));
|
||||
imageEvBox = Gtk::manage(new Gtk::EventBox());
|
||||
imageEvBox->set_name("MyExpanderStatus");
|
||||
imageEvBox->add(*statusImage);
|
||||
imageEvBox->set_above_child(true);
|
||||
imageEvBox->signal_button_release_event().connect( sigc::mem_fun(this, & MyExpander::on_enabled_change) );
|
||||
@@ -540,6 +583,7 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) :
|
||||
imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false );
|
||||
headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0);
|
||||
} else {
|
||||
get_style_context()->add_class("Fold");
|
||||
statusImage = Gtk::manage(new RTImage(openedImage));
|
||||
headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0);
|
||||
}
|
||||
@@ -554,7 +598,7 @@ MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) :
|
||||
|
||||
titleEvBox = Gtk::manage(new Gtk::EventBox());
|
||||
titleEvBox->set_name("MyExpanderTitle");
|
||||
titleEvBox->set_border_width(2);
|
||||
titleEvBox->set_border_width(0);
|
||||
titleEvBox->add(*headerHBox);
|
||||
titleEvBox->set_above_child(false); // this is the key! By making it below the child, they will get the events first.
|
||||
titleEvBox->set_can_focus(false);
|
||||
@@ -573,17 +617,18 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) :
|
||||
child(nullptr), headerWidget(nullptr),
|
||||
label(nullptr), useEnabled(useEnabled)
|
||||
{
|
||||
set_orientation(Gtk::ORIENTATION_VERTICAL);
|
||||
set_spacing(0);
|
||||
set_name("MyExpander");
|
||||
set_can_focus(false);
|
||||
setExpandAlignProperties(this, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
|
||||
|
||||
headerHBox = Gtk::manage( new Gtk::HBox());
|
||||
headerHBox = Gtk::manage( new Gtk::Box());
|
||||
headerHBox->set_can_focus(false);
|
||||
setExpandAlignProperties(headerHBox, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_FILL);
|
||||
|
||||
|
||||
if (useEnabled) {
|
||||
get_style_context()->add_class("OnOff");
|
||||
statusImage = Gtk::manage(new RTImage(disabledImage));
|
||||
imageEvBox = Gtk::manage(new Gtk::EventBox());
|
||||
imageEvBox->set_name("MyExpanderStatus");
|
||||
@@ -594,6 +639,7 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) :
|
||||
imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false );
|
||||
headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0);
|
||||
} else {
|
||||
get_style_context()->add_class("Fold");
|
||||
statusImage = Gtk::manage(new RTImage(openedImage));
|
||||
headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0);
|
||||
}
|
||||
@@ -602,12 +648,12 @@ MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) :
|
||||
|
||||
label = Gtk::manage(new Gtk::Label());
|
||||
setExpandAlignProperties(label, true, false, Gtk::ALIGN_START, Gtk::ALIGN_CENTER);
|
||||
label->set_markup(Glib::ustring("<b>") + escapeHtmlChars(titleLabel) + Glib::ustring("</b>"));
|
||||
label->set_markup(escapeHtmlChars(titleLabel));
|
||||
headerHBox->pack_start(*label, Gtk::PACK_EXPAND_WIDGET, 0);
|
||||
|
||||
titleEvBox = Gtk::manage(new Gtk::EventBox());
|
||||
titleEvBox->set_name("MyExpanderTitle");
|
||||
titleEvBox->set_border_width(2);
|
||||
titleEvBox->set_border_width(0);
|
||||
titleEvBox->add(*headerHBox);
|
||||
titleEvBox->set_above_child(false); // this is the key! By make it below the child, they will get the events first.
|
||||
titleEvBox->set_can_focus(false);
|
||||
@@ -684,7 +730,7 @@ void MyExpander::setLevel (int level)
|
||||
void MyExpander::setLabel (Glib::ustring newLabel)
|
||||
{
|
||||
if (label) {
|
||||
label->set_markup(Glib::ustring("<b>") + escapeHtmlChars(newLabel) + Glib::ustring("</b>"));
|
||||
label->set_markup(escapeHtmlChars(newLabel));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,8 +758,10 @@ void MyExpander::set_inconsistent(bool isInconsistent)
|
||||
} else {
|
||||
if (enabled) {
|
||||
statusImage->set(enabledImage->get_surface());
|
||||
get_style_context()->add_class("enabledTool");
|
||||
} else {
|
||||
statusImage->set(disabledImage->get_surface());
|
||||
get_style_context()->remove_class("enabledTool");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -740,6 +788,7 @@ void MyExpander::setEnabled(bool isEnabled)
|
||||
|
||||
if (!inconsistent) {
|
||||
statusImage->set(disabledImage->get_surface());
|
||||
get_style_context()->remove_class("enabledTool");
|
||||
message.emit();
|
||||
}
|
||||
} else {
|
||||
@@ -747,6 +796,7 @@ void MyExpander::setEnabled(bool isEnabled)
|
||||
|
||||
if (!inconsistent) {
|
||||
statusImage->set(enabledImage->get_surface());
|
||||
get_style_context()->add_class("enabledTool");
|
||||
message.emit();
|
||||
}
|
||||
}
|
||||
@@ -774,12 +824,6 @@ void MyExpander::set_expanded( bool expanded )
|
||||
return;
|
||||
}
|
||||
|
||||
bool isVisible = expBox->is_visible();
|
||||
|
||||
if (isVisible == expanded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!useEnabled) {
|
||||
if (expanded ) {
|
||||
statusImage->set(openedImage->get_surface());
|
||||
@@ -855,9 +899,11 @@ bool MyExpander::on_enabled_change(GdkEventButton* event)
|
||||
if (enabled) {
|
||||
enabled = false;
|
||||
statusImage->set(disabledImage->get_surface());
|
||||
get_style_context()->remove_class("enabledTool");
|
||||
} else {
|
||||
enabled = true;
|
||||
statusImage->set(enabledImage->get_surface());
|
||||
get_style_context()->add_class("enabledTool");
|
||||
}
|
||||
|
||||
message.emit();
|
||||
@@ -945,7 +991,7 @@ MyScrolledToolbar::MyScrolledToolbar ()
|
||||
set_policy (Gtk::POLICY_EXTERNAL, Gtk::POLICY_NEVER);
|
||||
get_style_context()->add_class("scrollableToolbar");
|
||||
|
||||
// Works fine with Gtk 3.22, but a a custom made get_preferred_height had to be created as a workaround
|
||||
// Works fine with Gtk 3.22, but a custom made get_preferred_height had to be created as a workaround
|
||||
// taken from the official Gtk3.22 source code
|
||||
//set_propagate_natural_height(true);
|
||||
}
|
||||
@@ -1114,6 +1160,7 @@ MySpinButton::MySpinButton ()
|
||||
set_numeric(true);
|
||||
set_wrap(false);
|
||||
set_alignment(Gtk::ALIGN_END);
|
||||
set_update_policy(Gtk::SpinButtonUpdatePolicy::UPDATE_IF_VALID); // Avoid updating text if input is not a numeric
|
||||
}
|
||||
|
||||
void MySpinButton::updateSize()
|
||||
@@ -1146,19 +1193,19 @@ bool MySpinButton::on_key_press_event (GdkEventKey* event)
|
||||
double vMin, vMax;
|
||||
get_range(vMin, vMax);
|
||||
|
||||
if ( (event->string[0] >= 'a' && event->string[0] <= 'z')
|
||||
|| (event->string[0] >= 'A' && event->string[0] <= 'Z')
|
||||
|| event->string[0] == '+' || (event->string[0] == '-' && vMin >= 0)
|
||||
|| event->string[0] == '=' || event->string[0] == '_'
|
||||
) {
|
||||
return false;
|
||||
if ((event->keyval >= GDK_KEY_a && event->keyval <= GDK_KEY_z)
|
||||
|| (event->keyval >= GDK_KEY_A && event->keyval <= GDK_KEY_Z)
|
||||
|| event->keyval == GDK_KEY_equal || event->keyval == GDK_KEY_underscore
|
||||
|| event->keyval == GDK_KEY_plus || (event->keyval == GDK_KEY_minus && vMin >= 0)) {
|
||||
return false; // Event is propagated further
|
||||
} else {
|
||||
if(event->string[0] == ',') {
|
||||
event->keyval = GDK_KEY_period;
|
||||
event->string[0] = '.';
|
||||
if (event->keyval == GDK_KEY_comma || event->keyval == GDK_KEY_KP_Decimal) {
|
||||
set_text(get_text() + ".");
|
||||
set_position(get_text().length()); // When setting text, cursor position is reset at text start. Avoiding this with this code
|
||||
return true; // Event is not propagated further
|
||||
}
|
||||
|
||||
return Gtk::Widget::on_key_press_event(event);
|
||||
return Gtk::SpinButton::on_key_press_event(event); // Event is propagated normally
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,7 +1228,7 @@ bool MyHScale::on_scroll_event (GdkEventScroll* event)
|
||||
// event->delta_x, event->delta_y, (int)event->direction, (int)event->type, event->send_event);
|
||||
// If Shift is pressed, the widget is modified
|
||||
if (event->state & GDK_SHIFT_MASK) {
|
||||
Gtk::HScale::on_scroll_event(event);
|
||||
Gtk::Scale::on_scroll_event(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1211,7 +1258,7 @@ MyFileChooserButton::MyFileChooserButton(const Glib::ustring &title, Gtk::FileCh
|
||||
box_.pack_start(lbl_, true, true);
|
||||
Gtk::Image *img = Gtk::manage(new Gtk::Image());
|
||||
img->set_from_icon_name("folder-open", Gtk::ICON_SIZE_BUTTON);
|
||||
box_.pack_start(*Gtk::manage(new Gtk::VSeparator()), false, false, 5);
|
||||
box_.pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), false, false, 5);
|
||||
box_.pack_start(*img, false, false);
|
||||
box_.show_all_children();
|
||||
add(box_);
|
||||
@@ -1406,33 +1453,110 @@ TextOrIcon::TextOrIcon (const Glib::ustring &fname, const Glib::ustring &labelTx
|
||||
|
||||
}
|
||||
|
||||
MyImageMenuItem::MyImageMenuItem(Glib::ustring label, Glib::ustring imageFileName)
|
||||
class ImageAndLabel::Impl
|
||||
{
|
||||
box = Gtk::manage (new Gtk::Grid());
|
||||
this->label = Gtk::manage( new Gtk::Label(label));
|
||||
box->set_orientation(Gtk::ORIENTATION_HORIZONTAL);
|
||||
public:
|
||||
RTImage* image;
|
||||
Gtk::Label* label;
|
||||
|
||||
if (!imageFileName.empty()) {
|
||||
image = Gtk::manage( new RTImage(imageFileName) );
|
||||
box->attach_next_to(*image, Gtk::POS_LEFT, 1, 1);
|
||||
} else {
|
||||
image = nullptr;
|
||||
Impl(RTImage* image, Gtk::Label* label) : image(image), label(label) {}
|
||||
static std::unique_ptr<RTImage> createImage(const Glib::ustring& fileName);
|
||||
};
|
||||
|
||||
std::unique_ptr<RTImage> ImageAndLabel::Impl::createImage(const Glib::ustring& fileName)
|
||||
{
|
||||
if (fileName.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<RTImage>(new RTImage(fileName));
|
||||
}
|
||||
|
||||
ImageAndLabel::ImageAndLabel(const Glib::ustring& label, const Glib::ustring& imageFileName) :
|
||||
ImageAndLabel(label, Gtk::manage(Impl::createImage(imageFileName).release()))
|
||||
{
|
||||
}
|
||||
|
||||
ImageAndLabel::ImageAndLabel(const Glib::ustring& label, RTImage *image) :
|
||||
pimpl(new Impl(image, Gtk::manage(new Gtk::Label(label))))
|
||||
{
|
||||
Gtk::Grid* grid = Gtk::manage(new Gtk::Grid());
|
||||
grid->set_orientation(Gtk::ORIENTATION_HORIZONTAL);
|
||||
|
||||
if (image) {
|
||||
grid->attach_next_to(*image, Gtk::POS_LEFT, 1, 1);
|
||||
}
|
||||
|
||||
box->attach_next_to(*this->label, Gtk::POS_RIGHT, 1, 1);
|
||||
box->set_column_spacing(4);
|
||||
box->set_row_spacing(0);
|
||||
add(*box);
|
||||
grid->attach_next_to(*(pimpl->label), Gtk::POS_RIGHT, 1, 1);
|
||||
grid->set_column_spacing(4);
|
||||
grid->set_row_spacing(0);
|
||||
pack_start(*grid, Gtk::PACK_SHRINK, 0);
|
||||
}
|
||||
|
||||
const RTImage* ImageAndLabel::getImage() const
|
||||
{
|
||||
return pimpl->image;
|
||||
}
|
||||
|
||||
const Gtk::Label* ImageAndLabel::getLabel() const
|
||||
{
|
||||
return pimpl->label;
|
||||
}
|
||||
|
||||
class MyImageMenuItem::Impl
|
||||
{
|
||||
private:
|
||||
std::unique_ptr<ImageAndLabel> widget;
|
||||
|
||||
public:
|
||||
Impl(const Glib::ustring &label, const Glib::ustring &imageFileName) :
|
||||
widget(new ImageAndLabel(label, imageFileName)) {}
|
||||
Impl(const Glib::ustring &label, RTImage *itemImage) :
|
||||
widget(new ImageAndLabel(label, itemImage)) {}
|
||||
ImageAndLabel* getWidget() const { return widget.get(); }
|
||||
};
|
||||
|
||||
MyImageMenuItem::MyImageMenuItem(const Glib::ustring& label, const Glib::ustring& imageFileName) :
|
||||
pimpl(new Impl(label, imageFileName))
|
||||
{
|
||||
add(*(pimpl->getWidget()));
|
||||
}
|
||||
|
||||
MyImageMenuItem::MyImageMenuItem(const Glib::ustring& label, RTImage* itemImage) :
|
||||
pimpl(new Impl(label, itemImage))
|
||||
{
|
||||
add(*(pimpl->getWidget()));
|
||||
}
|
||||
|
||||
const RTImage *MyImageMenuItem::getImage () const
|
||||
{
|
||||
return image;
|
||||
return pimpl->getWidget()->getImage();
|
||||
}
|
||||
|
||||
const Gtk::Label* MyImageMenuItem::getLabel () const
|
||||
{
|
||||
return label;
|
||||
return pimpl->getWidget()->getLabel();
|
||||
}
|
||||
|
||||
class MyRadioImageMenuItem::Impl
|
||||
{
|
||||
std::unique_ptr<ImageAndLabel> widget;
|
||||
|
||||
public:
|
||||
Impl(const Glib::ustring &label, RTImage *image) :
|
||||
widget(new ImageAndLabel(label, image)) {}
|
||||
ImageAndLabel* getWidget() const { return widget.get(); }
|
||||
};
|
||||
|
||||
MyRadioImageMenuItem::MyRadioImageMenuItem(const Glib::ustring& label, RTImage *image, Gtk::RadioButton::Group& group) :
|
||||
Gtk::RadioMenuItem(group),
|
||||
pimpl(new Impl(label, image))
|
||||
{
|
||||
add(*(pimpl->getWidget()));
|
||||
}
|
||||
|
||||
const Gtk::Label* MyRadioImageMenuItem::getLabel() const
|
||||
{
|
||||
return pimpl->getWidget()->getLabel();
|
||||
}
|
||||
|
||||
MyProgressBar::MyProgressBar(int width) : w(rtengine::max(width, 10 * RTScalable::getScale())) {}
|
||||
|
Reference in New Issue
Block a user