diff --git a/share/ui/align-and-distribute.ui b/share/ui/align-and-distribute.ui index b38122bcb0963e63a90d6274f67775a25d2d84a4..6a15876d4c4ca5f6ca2a91f1b42463e5e7da1533 100644 --- a/share/ui/align-and-distribute.ui +++ b/share/ui/align-and-distribute.ui @@ -802,10 +802,9 @@ - + True RemoveOverlap_HGap - True Minimum horizontal gap (in pixel units) between bounding boxes @@ -816,10 +815,9 @@ - + True RemoveOverlap_VGap - True Minimum vertical gap (in pixel units) between bounding boxes diff --git a/share/ui/dialog-export.glade b/share/ui/dialog-export.glade index 658b056e7450c490eeb0a475b5e3d5785213f15d..1a4d7a04eada9c70a5d943171c11aa707c8e0e8c 100644 --- a/share/ui/dialog-export.glade +++ b/share/ui/dialog-export.glade @@ -1,6 +1,7 @@ - + + ExportDialog vertical @@ -19,7 +20,7 @@ False vertical - 5 + 4 True @@ -34,8 +35,9 @@ vertical + 0 start - 5 + 4 4 True @@ -132,69 +134,66 @@ + 0 True - 6 - 6 - 5 - 5 - 10 + 0 + 0 + 4 + 4 + 4 - + True center True - 0 - 0 + 8 1 - 0 + 1 - + True center True - 0 - 0 + 8 - 3 - 1 + 4 + 2 - + True center True - 0 - 0 + 8 1 - 2 + 3 - + True center True - 0 - 0 + 8 - 3 - 2 + 4 + 3 center - 5 - 5 + 0 + 0 Image Size 0 @@ -202,34 +201,32 @@ 0 - 4 + 5 4 - + True center True - 0 - 0 + 8 - 3 - 0 + 4 + 1 - + True center True - 0 - 0 + 8 1 - 1 + 2 @@ -240,8 +237,8 @@ True 0 - 2 - 2 + 3 + 3 @@ -253,7 +250,7 @@ 0 0 - 2 + 3 @@ -265,7 +262,7 @@ 0 0 - 0 + 1 @@ -277,7 +274,7 @@ 0 0 - 1 + 2 @@ -288,8 +285,8 @@ True 0 - 2 - 1 + 3 + 2 @@ -300,58 +297,56 @@ True 0 - 2 - 0 + 3 + 1 - Width -(px) + Width True 0 0 - 5 + 6 - Height -(px) + Height True 0 - 2 - 5 + 3 + 6 - + True center True - 0 - 0 + 8 + px 1 - 5 + 6 - + True center True - 0 - 0 + 8 + px - 3 - 5 + 4 + 6 @@ -363,20 +358,19 @@ 0 0 - 6 + 7 - + True center True - 0 - 0 + 8 1 - 6 + 7 @@ -401,8 +395,19 @@ 0 - 3 - 4 + 4 + 5 + + + + + + + -1 + 4 + + 2 + 0 @@ -477,7 +482,7 @@ - 5 + 4 4 @@ -770,10 +775,10 @@ - 5 - 5 - 10 - 10 + 4 + 4 + 4 + 4 0 5 @@ -806,7 +811,7 @@ 5 - 5 + 4 4 diff --git a/share/ui/dialog-measure-tool-settings.ui b/share/ui/dialog-measure-tool-settings.ui index 6be6806bab62eaefd94d38c3c851aeea9b498c1c..55e7af777174eee708a392055766e2ab1b3a1e02 100644 --- a/share/ui/dialog-measure-tool-settings.ui +++ b/share/ui/dialog-measure-tool-settings.ui @@ -96,7 +96,7 @@ - + start True 2 diff --git a/share/ui/dialog-trace.glade b/share/ui/dialog-trace.glade index e8a5ae7992f70f1065a397bb6cd6a7954d58f4f2..e1520fc37679116dabc19a6350707a83e26a6f7d 100644 --- a/share/ui/dialog-trace.glade +++ b/share/ui/dialog-trace.glade @@ -403,7 +403,7 @@ - + center True SS_BC_T @@ -415,7 +415,7 @@ - + center True SS_ED_T @@ -427,7 +427,7 @@ - + center True SS_CQ_T @@ -438,7 +438,7 @@ - + center True SS_AT_FI_T @@ -449,7 +449,7 @@ - + center True SS_AT_ET_T @@ -461,7 +461,7 @@ - + center True Speckles of up to this many pixels will be suppressed @@ -473,7 +473,7 @@ - + center True Increase this to smooth corners more @@ -486,7 +486,7 @@ - + center True Increase this to reduce the number of nodes in the trace by more aggressive optimization @@ -607,7 +607,7 @@ - + center True The desired number of scans @@ -648,7 +648,7 @@ - + center True Speckles of up to this many pixels will be suppressed @@ -700,7 +700,7 @@ - + center True Increase this to smooth corners more @@ -740,7 +740,7 @@ - + center True Increase this to reduce the number of nodes in the trace by more aggressive optimization @@ -856,13 +856,12 @@ - + center True The heuristic computed vote will be multiplied by this value PA_curves 3 - True 1 2 @@ -871,12 +870,11 @@ - + center True A constant vote value PA_islands - True 5 2 @@ -885,12 +883,11 @@ - + center True The radius of the window analyzed PA_sparse1 - True 2 2 @@ -899,13 +896,12 @@ - + center True The heuristic computed vote will be multiplied by this value PA_sparse2 3 - True 1 2 diff --git a/share/ui/page-properties.glade b/share/ui/page-properties.glade index b4fa4f6d3a956ac1c2c245247121c9800bd78b89..0acd29e5da4543c1f509ede0ef453c6f0e64ee17 100644 --- a/share/ui/page-properties.glade +++ b/share/ui/page-properties.glade @@ -144,7 +144,7 @@ - + True Width of front page 9 @@ -190,7 +190,7 @@ - + True Height of front page 9 @@ -409,7 +409,7 @@ - + center True Document scale establishes size of user units. @@ -481,7 +481,7 @@ SVG element positions are expressed in user units. - + True 9 adj-viewbox-x @@ -497,7 +497,7 @@ SVG element positions are expressed in user units. - + True 9 adj-viewbox-y @@ -513,7 +513,7 @@ SVG element positions are expressed in user units. - + True 9 adj-viewbox-width @@ -529,7 +529,7 @@ SVG element positions are expressed in user units. - + True 9 adj-viewbox-height diff --git a/share/ui/textpath-popover-box.ui b/share/ui/textpath-popover-box.ui index 72becca514fd960f04a2ba41147cc5e1288eaeba..0c650443c0bacdef7b50dcefde0c95e74463694e 100644 --- a/share/ui/textpath-popover-box.ui +++ b/share/ui/textpath-popover-box.ui @@ -23,7 +23,7 @@ - + 1 0 start-offset-adj diff --git a/share/ui/toolbar-arc.ui b/share/ui/toolbar-arc.ui index e210dc6a5d1c2dce2ab2322096eb36a12046f35e..e7796b717525c24d3fcab81469aff5b840cc49c2 100644 --- a/share/ui/toolbar-arc.ui +++ b/share/ui/toolbar-arc.ui @@ -36,16 +36,16 @@ Horizontal radius of the circle, ellipse, or arc + + + + + + - - 5 + Rx - - - - True - 6 _rx_adj 0.10 3 @@ -56,17 +56,16 @@ Vertical radius of the circle, ellipse, or arc + + + + + + - - 5 + Ry - - - - True - 6 - 0.000 _ry_adj 0.10 3 @@ -92,10 +91,10 @@ - + + ellipse-start-angle + ° True - 6 - 0.000 _start_adj 0.10 3 @@ -113,10 +112,10 @@ - + + ellipse-end-angle + ° True - 6 - 0.000 _end_adj 0.10 3 diff --git a/share/ui/toolbar-box3d.ui b/share/ui/toolbar-box3d.ui index f50cbc9183b264eab0c7e382a1e965409eeb7690..a4d6a7408d30f6d815a4e133334f870a59dde71b 100644 --- a/share/ui/toolbar-box3d.ui +++ b/share/ui/toolbar-box3d.ui @@ -32,13 +32,12 @@ - + True - 2 - 0.000 _angle_x_adj 0.10 3 + ° @@ -67,13 +66,12 @@ - + True - 2 - 0.000 _angle_y_adj 0.10 3 + ° @@ -102,13 +100,12 @@ - + True - 2 - 0.000 _angle_z_adj 0.10 3 + ° diff --git a/share/ui/toolbar-calligraphy.ui b/share/ui/toolbar-calligraphy.ui index ae37c426926be34552fed62cf81345c8d124a98e..6706de9dbf2144909e4dd208f8a566a410f71bf0 100644 --- a/share/ui/toolbar-calligraphy.ui +++ b/share/ui/toolbar-calligraphy.ui @@ -50,7 +50,7 @@ center True - + Choose a preset 3 @@ -83,11 +83,9 @@ - + calligraphy-width True - 6 - 0.000 _width_adj 1 3 @@ -146,10 +144,8 @@ - + True - 1 - 0.001 _thinning_adj 1 @@ -168,10 +164,8 @@ - + True - 1 - 0.001 _mass_adj 1 0.001 @@ -199,11 +193,9 @@ - + calligraphy-angle True - 1 - 0 _angle_adj 1 0.001 @@ -243,10 +235,8 @@ - + True - 1 - 0 _flatness_adj 1 @@ -275,10 +265,8 @@ - + True - 1 - 0 _cap_rounding_adj 1 2 @@ -309,10 +297,8 @@ - + True - 1 - 0 _tremor_adj 1 0.001 @@ -332,10 +318,8 @@ - + True - 1 - 0 _wiggle_adj 1 0.001 diff --git a/share/ui/toolbar-connector.ui b/share/ui/toolbar-connector.ui index 646ca4741013d0f6187f44b2999c5a2295db6945..508a315111cd500093f99e9c703476ef73ce1945 100644 --- a/share/ui/toolbar-connector.ui +++ b/share/ui/toolbar-connector.ui @@ -80,10 +80,8 @@ - + True - 5 - 0.000 _curvature_adj 0.10 @@ -100,10 +98,8 @@ - + True - 5 - 0 _spacing_adj 0.10 0.01 @@ -142,10 +138,8 @@ - + True - 7 - 0 _length_adj 0.10 diff --git a/share/ui/toolbar-eraser.ui b/share/ui/toolbar-eraser.ui index be7b54c5ff78c8013a96870aba71c023ac4579fa..e702c1461c1104c62c2d39704d4a17bc815e1c8f 100644 --- a/share/ui/toolbar-eraser.ui +++ b/share/ui/toolbar-eraser.ui @@ -90,11 +90,9 @@ - + eraser-width True - 2 - 0.000 _width_adj 1 @@ -128,10 +126,8 @@ - + True - 2 - 0.000 _thinning_adj 0.10 @@ -151,9 +147,8 @@ - + True - 2 _cap_rounding_adj 0.10 2 @@ -174,10 +169,8 @@ - + True - 5 - 0.000 _tremor_adj 1 @@ -197,10 +190,8 @@ - + True - 5 - 0 _mass_adj 1 diff --git a/share/ui/toolbar-gradient.ui b/share/ui/toolbar-gradient.ui index 8d62029a1c5fbfdf579aec2bfa1f34e83173f14c..7916133f7e145b1ad70e5dcf6b9c5bdbea95d7a7 100644 --- a/share/ui/toolbar-gradient.ui +++ b/share/ui/toolbar-gradient.ui @@ -126,11 +126,9 @@ - + True Width of selection - 2 - 0.000 _offset_adj 0.10 2 diff --git a/share/ui/toolbar-measure.ui b/share/ui/toolbar-measure.ui index 22cca9ffa76c93b6e6958a4b141a271feb222197..3e5240f0af502dcc84bdaa85795c53eccde27ae2 100644 --- a/share/ui/toolbar-measure.ui +++ b/share/ui/toolbar-measure.ui @@ -43,10 +43,8 @@ - + True - 2 - 0.000 _font_size_adj 0.10 2 @@ -64,10 +62,8 @@ - + True - 1 - 0.000 _precision_adj 0.10 @@ -83,16 +79,16 @@ 5 - Scale % + Scale - + True - 2 _scale_adj 0.10 3 + % @@ -298,10 +294,8 @@ - + True - 2 - 0 _offset_adj 0.10 2 diff --git a/share/ui/toolbar-mesh.ui b/share/ui/toolbar-mesh.ui index 5f037b5c51564a7df36c807aea0784d8c61df021..62cf49dc13273e6bfe148e3be86179c058b4290b 100644 --- a/share/ui/toolbar-mesh.ui +++ b/share/ui/toolbar-mesh.ui @@ -85,10 +85,8 @@ - + True - 2 - 0.000 _row_adj 1 @@ -105,10 +103,8 @@ - + True - 2 - 0.000 _col_adj 0.10 diff --git a/share/ui/toolbar-node.ui b/share/ui/toolbar-node.ui index 84ef58fe6bbc4741c126ded19edd624ac2a15d6d..50c48440c7b917358358f17338a83fef70570401 100644 --- a/share/ui/toolbar-node.ui +++ b/share/ui/toolbar-node.ui @@ -358,16 +358,10 @@ - - 5 + X - - - - True X - Horizontal position of selected node(s) - 7 _nodes_x_adj 0.10 3 @@ -381,17 +375,10 @@ - - 5 + Y - - - - True Y - Vertical position of selected node(s) - 7 - 0.000 _nodes_y_adj 0.10 3 @@ -405,17 +392,10 @@ - - 5 - D - - - - + + D True Distance between two selected nodes. - 7 - 0.000 _nodes_d_adj 0.10 3 diff --git a/share/ui/toolbar-page.ui b/share/ui/toolbar-page.ui index 07f19e70d07da05e81952b4a1019b88c03688248..b3b7e81420dd2f41b44e77fedbd5e5105b9fb633 100644 --- a/share/ui/toolbar-page.ui +++ b/share/ui/toolbar-page.ui @@ -240,7 +240,7 @@ - + True center 5 @@ -256,7 +256,7 @@ - + True center adjust_margin_top @@ -268,7 +268,7 @@ - + True center 5 @@ -284,7 +284,7 @@ - + True center 5 diff --git a/share/ui/toolbar-paintbucket.ui b/share/ui/toolbar-paintbucket.ui index e0525ad61e516b18feafa18957e42defa1f2c76d..f8219b323923e99c2e5b095ca995e8f0acc09701 100644 --- a/share/ui/toolbar-paintbucket.ui +++ b/share/ui/toolbar-paintbucket.ui @@ -34,10 +34,8 @@ - + True - 1 - 0.000 _threshold_adj 0.10 @@ -54,10 +52,8 @@ - + True - 2 - 0.000 _offset_adj 1 2 diff --git a/share/ui/toolbar-pencil.ui b/share/ui/toolbar-pencil.ui index 0af5fe22209d988f8d00a2160755bbe7bca7033f..455634e0dc1187fe4beca61946d5a3f2363a730d 100644 --- a/share/ui/toolbar-pencil.ui +++ b/share/ui/toolbar-pencil.ui @@ -127,10 +127,8 @@ - + True - 5 - 0 _minpressure_adj 1 @@ -147,10 +145,8 @@ - + True - 1 - 0 _maxpressure_adj 1 @@ -176,10 +172,8 @@ - + True - 2 - 0 _tolerance_adj 1 2 @@ -233,10 +227,8 @@ - + True - 1 - 0 _shapescale_adj 1 2 diff --git a/share/ui/toolbar-rect.ui b/share/ui/toolbar-rect.ui index 9cff8c383e206f64119dd6362495bbfd80d05987..3e632e05fed5e39203b7ba9deef0b69b5fc4b2f4 100644 --- a/share/ui/toolbar-rect.ui +++ b/share/ui/toolbar-rect.ui @@ -35,16 +35,9 @@ Width of rectangle - - 5 + W - - - - True - 7 - 0.000 _width_adj 0.10 3 @@ -56,16 +49,9 @@ Height of rectangle - - 5 + H - - - - True - 7 - 0.000 _height_adj 0.10 3 @@ -80,15 +66,9 @@ - - 5 + Rx - - - - True - 7 _rx_adj 0.10 3 @@ -103,16 +83,9 @@ - - 5 + Ry - - - - True - 10 - 0.000 _ry_adj 0.10 3 diff --git a/share/ui/toolbar-select.ui b/share/ui/toolbar-select.ui index 309133c8a13537d112cb5b20941f49dd18b0bb8a..f8d2a694ab8c2f6b279a0a19a05def6fdaf64784 100644 --- a/share/ui/toolbar-select.ui +++ b/share/ui/toolbar-select.ui @@ -350,16 +350,10 @@ - - 5 + X - - - - True Horizontal coordinate of selection - 7 _x_adj 1.0 3 @@ -373,17 +367,10 @@ - - 5 + Y - - - - True Vertical coordinate of selection - 7 - 0.000 _y_adj 1.0 3 @@ -397,17 +384,10 @@ - - 5 - W - - - - + + W True Width of selection - 7 - 0.000 _w_adj 1.0 3 @@ -418,34 +398,13 @@ - - - center - True - False - When locked, change width and height by the same proportion - False - - - object-unlocked - - - - - - 5 + H - - - - True Height of selection - 7 - 0.000 _h_adj 1.0 3 @@ -456,6 +415,20 @@ + + + center + True + False + When locked, change width and height by the same proportion + False + + + object-unlocked + + + + diff --git a/share/ui/toolbar-spiral.ui b/share/ui/toolbar-spiral.ui index 814c0326c28b648a2bb34ab3b05c485716fbe97d..be8aae664cc720404b632e2194a734e300507980 100644 --- a/share/ui/toolbar-spiral.ui +++ b/share/ui/toolbar-spiral.ui @@ -37,10 +37,8 @@ - + True - 5 - 0.000 _revolution_adj 0.10 2 @@ -58,10 +56,8 @@ - + True - 5 - 0.000 _expansion_adj 0.10 3 @@ -79,10 +75,8 @@ - + True - 5 - 0.000 _t0_adj 0.10 3 diff --git a/share/ui/toolbar-spray.ui b/share/ui/toolbar-spray.ui index a02618e49006b304cd58b4352d54ff96d5a6a682..b4be3ddf4436ef23bf163f7c6db837ca02e674ff 100644 --- a/share/ui/toolbar-spray.ui +++ b/share/ui/toolbar-spray.ui @@ -110,11 +110,9 @@ - + spray-width True - 1 - 0.000 _width_adj 1 @@ -142,11 +140,9 @@ - + spray-population True - 1 - 0 _population_adj 1 @@ -181,10 +177,8 @@ - + True - 1 - 0.000 _rotation_adj 0.10 @@ -204,9 +198,8 @@ - + True - 5 _scale_adj 0.10 2 @@ -248,10 +241,8 @@ - + True - 1 - 0.000 _sd_adj 1 @@ -271,10 +262,8 @@ - + True - 1 - 0 _mean_adj 1 @@ -357,10 +346,8 @@ - + True - 1 - 0 _mean_adj 1 diff --git a/share/ui/toolbar-star.ui b/share/ui/toolbar-star.ui index ab2be8113ce50cd89f72b8f39d88150c89b8d1e4..51c3b1a6e29760f7093ab84566d68ba03f490aaf 100644 --- a/share/ui/toolbar-star.ui +++ b/share/ui/toolbar-star.ui @@ -98,10 +98,8 @@ - + True - 1 - 0.000 _magnitude_adj 0.10 @@ -121,10 +119,8 @@ - + True - 7 - 0.000 _spoke_adj 0.10 3 @@ -145,9 +141,8 @@ - + True - 2 _roundedness_adj 0.10 3 @@ -168,10 +163,8 @@ - + True - 2 - 0.000 _randomization_adj 0.10 3 @@ -214,10 +207,8 @@ - + True - 7 - 0.000 _length_adj 0.10 3 diff --git a/share/ui/toolbar-text.ui b/share/ui/toolbar-text.ui index ef70056387f5c9a1d709aa9ccc9d28a7444f7b7b..2e4659a9e9c94774dfbbb1e7a1e99054835e050a 100644 --- a/share/ui/toolbar-text.ui +++ b/share/ui/toolbar-text.ui @@ -20,7 +20,7 @@ 0.10 - 1000 + 10000 0.10 1 @@ -132,18 +132,13 @@ - - text_line_spacing - - - - + True - 1 - 0.000 _line_height_adj 0.10 - 2 + 3 + 10 + text_line_spacing @@ -395,18 +390,12 @@ - - text_letter_spacing - - - - + True - 5 - 0 _letter_spacing_adj 0.10 2 + text_letter_spacing @@ -418,18 +407,12 @@ - - text_word_spacing - - - - + True - 5 - 0.00 _word_spacing_adj 0.10 2 + text_word_spacing @@ -441,18 +424,12 @@ - - text_horz_kern - - - - + True - 5 - 0.00 _dx_adj 0.10 2 + text_horz_kern @@ -464,18 +441,12 @@ - - text_vert_kern - - - - + True - 5 - 0.00 _dy_adj 0.10 2 + text_vert_kern @@ -487,18 +458,12 @@ - - text_rotation - - - - + True - 5 - 0.00 _rotation_adj 0.10 2 + text_rotation diff --git a/share/ui/toolbar-tweak.ui b/share/ui/toolbar-tweak.ui index 9334e91d0e8b7043dea92da8377b03059ff7ef2b..90ad71687342573dfc3819a2d4a302595d0d06d1 100644 --- a/share/ui/toolbar-tweak.ui +++ b/share/ui/toolbar-tweak.ui @@ -193,11 +193,9 @@ - + tweak-width True - 1 - 0 _width_adj 1 @@ -217,11 +215,9 @@ - + tweak-force True - 1 - 0 _force_adj 1 @@ -255,10 +251,8 @@ - + True - 5 - 0 _fidelity_adj 1 diff --git a/src/ui/dialog-events.cpp b/src/ui/dialog-events.cpp index 372f4e3697fb77bcb294094c27f842f09afc91f4..917d8d68da5ace5194a691815d01e6374b2545c6 100644 --- a/src/ui/dialog-events.cpp +++ b/src/ui/dialog-events.cpp @@ -16,6 +16,8 @@ #include #include +#include "widget/spinbutton.h" + #ifdef GDK_WINDOWING_X11 #include #endif @@ -54,8 +56,10 @@ void sp_dialog_defocus_on_enter(Gtk::SpinButton &s) #endif } -void sp_dialog_defocus_on_enter(Inkscape::UI::Widget::InkSpinButton &s) { - //todo +void sp_dialog_defocus_on_enter(Inkscape::UI::Widget::SpinButton& s) { + s.signal_activate().connect([&] { + sp_dialog_defocus(dynamic_cast(s.get_root())); + }); } /** diff --git a/src/ui/dialog-events.h b/src/ui/dialog-events.h index 3c781a5204c45ff3e7684326810c6d914be16593..ceb9e75eb538ddc0d77ecd42ee73e58df6638c17 100644 --- a/src/ui/dialog-events.h +++ b/src/ui/dialog-events.h @@ -14,6 +14,7 @@ #define SEEN_DIALOG_EVENTS_H namespace Inkscape::UI::Widget { +class SpinButton; class InkSpinButton; } @@ -26,7 +27,7 @@ class Window; void sp_dialog_defocus(Gtk::Window *win); void sp_dialog_defocus_on_enter(Gtk::Entry *e); void sp_dialog_defocus_on_enter(Gtk::SpinButton &s); -void sp_dialog_defocus_on_enter(Inkscape::UI::Widget::InkSpinButton &s); +void sp_dialog_defocus_on_enter(Inkscape::UI::Widget::SpinButton& s); void sp_transientize(Gtk::Window &win); #endif // SEEN_DIALOG_EVENTS_H diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index cd78da593546af547a09bf2168a0284d5ef05bb3..2033a65e66d45d8522d61b140a991c61d66665d0 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -32,6 +32,7 @@ #include "ui/builder-utils.h" #include "ui/dialog/dialog-base.h" // Tool switching. #include "ui/util.h" +#include "ui/widget/spinbutton.h" namespace Inkscape::UI::Dialog { @@ -52,8 +53,8 @@ AlignAndDistribute::AlignAndDistribute(Inkscape::UI::Dialog::DialogBase *dlg) // Remove overlap , remove_overlap_button(get_widget(builder, "remove-overlap-button")) - , remove_overlap_hgap(get_widget(builder, "remove-overlap-hgap")) - , remove_overlap_vgap(get_widget(builder, "remove-overlap-vgap")) + , remove_overlap_hgap(get_derived_widget(builder, "remove-overlap-hgap")) + , remove_overlap_vgap(get_derived_widget(builder, "remove-overlap-vgap")) // Node , align_relative_node(get_widget(builder, "align-relative-node")) diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h index 4ce605df3044040f341f4670d225b0aa802f1243..05affbb7d82ee137a57a2bf190940fea29f8aec5 100644 --- a/src/ui/dialog/align-and-distribute.h +++ b/src/ui/dialog/align-and-distribute.h @@ -36,6 +36,9 @@ class SPDesktop; namespace Inkscape { namespace UI { +namespace Widget { +class SpinButton; +} namespace Tools { class ToolBase; @@ -70,8 +73,8 @@ private: // Remove overlap Gtk::Button &remove_overlap_button; - Gtk::SpinButton &remove_overlap_hgap; - Gtk::SpinButton &remove_overlap_vgap; + UI::Widget::SpinButton &remove_overlap_hgap; + UI::Widget::SpinButton &remove_overlap_vgap; // Valid relative alignment entries for single selection. std::set single_selection_relative_categories = {"drawing", "page"}; diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 696005bf7b171fb2d3d88a1dfb7465f2b9b5f655..22e98f979042451110952e64ca2acaefb5f8bf24 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -49,6 +49,7 @@ #include "ui/widget/notebook-page.h" #include "ui/widget/page-properties.h" #include "ui/widget/generic/popover-menu.h" +#include "ui/widget/generic/spin-button.h" #include "util/expression-evaluator.h" namespace Inkscape::UI { @@ -1970,7 +1971,7 @@ GridWidget::GridWidget(SPGrid *grid) std::vector widgets; for_each_descendant(*main_grid, [&](Gtk::Widget& w){ - if (dynamic_cast(&w) || + if (dynamic_cast(&w) || dynamic_cast(&w) || dynamic_cast(&w) || dynamic_cast(&w) || diff --git a/src/ui/dialog/export-single.cpp b/src/ui/dialog/export-single.cpp index 180bd212ca8d096063ecc67f3c14ad4954017411..f5e6cca9a156b57a727640422fb5d7969ae38276 100644 --- a/src/ui/dialog/export-single.cpp +++ b/src/ui/dialog/export-single.cpp @@ -41,6 +41,7 @@ #include "ui/util.h" #include "ui/widget/color-picker.h" #include "ui/widget/export-lists.h" +#include "ui/widget/spinbutton.h" #include "ui/widget/unit-menu.h" using Inkscape::Util::UnitTable; @@ -82,15 +83,15 @@ SingleExport::SingleExport(BaseObjectType *cobject, const Glib::RefPtr(builder, "si_s_selection"); selection_buttons[SELECTION_CUSTOM] = &get_widget(builder, "si_s_custom"); - spin_buttons[SPIN_X0] = &get_widget(builder, "si_left_sb"); - spin_buttons[SPIN_X1] = &get_widget(builder, "si_right_sb"); - spin_buttons[SPIN_Y0] = &get_widget(builder, "si_top_sb"); - spin_buttons[SPIN_Y1] = &get_widget(builder, "si_bottom_sb"); - spin_buttons[SPIN_HEIGHT] = &get_widget(builder, "si_height_sb"); - spin_buttons[SPIN_WIDTH] = &get_widget(builder, "si_width_sb"); - spin_buttons[SPIN_BMHEIGHT] = &get_widget(builder, "si_img_height_sb"); - spin_buttons[SPIN_BMWIDTH] = &get_widget(builder, "si_img_width_sb"); - spin_buttons[SPIN_DPI] = &get_widget(builder, "si_dpi_sb"); + spin_buttons[SPIN_X0] = &get_derived_widget(builder, "si_left_sb"); + spin_buttons[SPIN_X1] = &get_derived_widget(builder, "si_right_sb"); + spin_buttons[SPIN_Y0] = &get_derived_widget(builder, "si_top_sb"); + spin_buttons[SPIN_Y1] = &get_derived_widget(builder, "si_bottom_sb"); + spin_buttons[SPIN_HEIGHT] = &get_derived_widget(builder, "si_height_sb"); + spin_buttons[SPIN_WIDTH] = &get_derived_widget(builder, "si_width_sb"); + spin_buttons[SPIN_BMHEIGHT] = &get_derived_widget(builder, "si_img_height_sb"); + spin_buttons[SPIN_BMWIDTH] = &get_derived_widget(builder, "si_img_width_sb"); + spin_buttons[SPIN_DPI] = &get_derived_widget(builder, "si_dpi_sb"); spin_labels[SPIN_X0] = &get_widget(builder, "si_label_left"); spin_labels[SPIN_X1] = &get_widget(builder, "si_label_right"); @@ -248,7 +249,7 @@ void SingleExport::setupSpinButtons() } template -void SingleExport::setupSpinButton(Gtk::SpinButton *sb, double val, double min, double max, double step, double page, +void SingleExport::setupSpinButton(UI::Widget::SpinButton *sb, double val, double min, double max, double step, double page, int digits, bool sensitive, void (SingleExport::*cb)(T), T param) { if (sb) { @@ -257,8 +258,6 @@ void SingleExport::setupSpinButton(Gtk::SpinButton *sb, double val, double min, sb->set_range(min, max); sb->set_value(val); sb->set_sensitive(sensitive); - sb->set_width_chars(0); - sb->set_max_width_chars(0); if (cb) { auto signal = sb->signal_value_changed().connect(sigc::bind(sigc::mem_fun(*this, cb), param)); // add signals to list to block all easily diff --git a/src/ui/dialog/export-single.h b/src/ui/dialog/export-single.h index aa1be2e50fcb9290c90ea673c1694219f286072c..c7d45adbb6d0560a6ccbe1acccbd468c8397d88f 100644 --- a/src/ui/dialog/export-single.h +++ b/src/ui/dialog/export-single.h @@ -26,7 +26,6 @@ class Label; class ProgressBar; class ToggleButton; class ScrolledWindow; -class SpinButton; } // namespace Gtk class InkscapeApplication; @@ -43,6 +42,7 @@ class Preferences; namespace UI { namespace Widget { +class SpinButton; class UnitMenu; class ColorPicker; } // namespace Widget @@ -100,7 +100,7 @@ private: bool setupDone = false; // To prevent setup() call add connections again. - std::map spin_buttons; + std::map spin_buttons; std::map spin_labels; std::map selection_buttons; @@ -153,7 +153,7 @@ private: // change range and callbacks to spinbuttons template - void setupSpinButton(Gtk::SpinButton *sb, double val, double min, double max, double step, double page, int digits, + void setupSpinButton(UI::Widget::SpinButton *sb, double val, double min, double max, double step, double page, int digits, bool sensitive, void (SingleExport::*cb)(T), T param); void setDefaultSelectionMode(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 3b49bec3baf50b30e3e3784be41ee7aaba1cb8dd..4401e34c93903d836721ef32eaca0b1a97795f8c 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -139,7 +139,7 @@ class SpinButtonAttr : public Inkscape::UI::Widget::SpinButton, public AttrWidge public: SpinButtonAttr(double lower, double upper, double step_inc, double climb_rate, int digits, const SPAttr a, double def, char* tip_text) - : Inkscape::UI::Widget::SpinButton(climb_rate, digits), + : Glib::ObjectBase("SpinButtonAttr"), Inkscape::UI::Widget::SpinButton(climb_rate, digits), AttrWidget(a, def) { if (tip_text) { diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index ce361fb3fcee7621a2186c3c69d9d9cd64f3ef5a..ca264fa0cad545964ca3213eb8e19342c8236af0 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -43,6 +43,7 @@ #include "ui/tools/node-tool.h" #include "ui/util.h" #include "ui/widget/custom-tooltip.h" +#include "ui/widget/generic/spin-button.h" #include "util/optstr.h" namespace Inkscape::UI::Dialog { @@ -272,9 +273,9 @@ void align(Gtk::Widget *top, int const spinbutton_width_chars) // column 1 - align spin buttons, if any int button_width = 0; for_child_n(1, [&](Gtk::Widget* child) { - if (auto spin = dynamic_cast(child)) { + if (auto spin = dynamic_cast(child)) { // selected spinbutton size by each LPE default 7 - spin->set_width_chars(spinbutton_width_chars); + spin->property_width_chars().set_value(spinbutton_width_chars); int dummy = 0; spin->measure(Gtk::Orientation::HORIZONTAL, -1, dummy, button_width, dummy, dummy); } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index 716a687322e4fdd5255f6f3a0516fb171544d256..562651483d0856a49d2e73cb485e9c2a0796b144 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -10,11 +10,11 @@ #include #include -#include #include #include #include "live_effects/parameter/nodesatellitesarray.h" +#include "ui/widget/spinbutton.h" class SPDesktop; @@ -36,13 +36,13 @@ protected: Gtk::Box _buttonbox; Gtk::Label _fillet_chamfer_position_label; - Gtk::SpinButton _fillet_chamfer_position_numeric; + UI::Widget::SpinButton _fillet_chamfer_position_numeric; Gtk::CheckButton _fillet_chamfer_type_fillet; Gtk::CheckButton _fillet_chamfer_type_inverse_fillet; Gtk::CheckButton _fillet_chamfer_type_chamfer; Gtk::CheckButton _fillet_chamfer_type_inverse_chamfer; Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; - Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; + UI::Widget::SpinButton _fillet_chamfer_chamfer_subdivisions; Gtk::Grid _layout_table; bool _position_visible = false; diff --git a/src/ui/dialog/lpe-powerstroke-properties.h b/src/ui/dialog/lpe-powerstroke-properties.h index 1569c8f0c8e043b8cfadec348bd46b24838e8dc0..cab6163177794827621588ef653877925538b476 100644 --- a/src/ui/dialog/lpe-powerstroke-properties.h +++ b/src/ui/dialog/lpe-powerstroke-properties.h @@ -19,11 +19,11 @@ #include #include -#include #include #include #include "live_effects/parameter/powerstrokepointarray.h" +#include "ui/widget/spinbutton.h" class SPDesktop; @@ -43,9 +43,9 @@ protected: Gtk::Box _buttonbox; Gtk::Label _powerstroke_position_label; - Gtk::SpinButton _powerstroke_position_entry; + UI::Widget::SpinButton _powerstroke_position_entry; Gtk::Label _powerstroke_width_label; - Gtk::SpinButton _powerstroke_width_entry; + UI::Widget::SpinButton _powerstroke_width_entry; Gtk::Grid _layout_table; bool _position_visible = false; diff --git a/src/ui/dialog/object-attributes.cpp b/src/ui/dialog/object-attributes.cpp index 425005d0f649763acb1b32c62d9c096f4c39ef95..0d896d9891112d085a8d5849b9b8c6a02c2b8d87 100644 --- a/src/ui/dialog/object-attributes.cpp +++ b/src/ui/dialog/object-attributes.cpp @@ -293,10 +293,6 @@ std::tuple round_values(double x, double y) { return std::make_tuple(a != x || b != y, a, b); } -std::tuple round_values(Gtk::SpinButton& x, Gtk::SpinButton& y) { - return round_values(x.get_adjustment()->get_value(), y.get_adjustment()->get_value()); -} - std::tuple round_values(Widget::InkSpinButton& x, Widget::InkSpinButton& y) { return round_values(x.get_adjustment()->get_value(), y.get_adjustment()->get_value()); } diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index ca8821cbe652082762d363882cc2f18df792d02b..4e64a39916b158ea3353718fc9afbcab4e9405ab 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -365,6 +365,7 @@ TraceDialogImpl::TraceDialogImpl() , boxchild1 (get_widget (builder, "boxchild1")) , boxchild2 (get_widget (builder, "boxchild2")) { + builder->get_objects(); // instantiate all InkSpinButton instances append(bin); bin.set_child(mainBox); bin.set_expand(true); diff --git a/src/ui/toolbar/calligraphy-toolbar.cpp b/src/ui/toolbar/calligraphy-toolbar.cpp index 0686a44e49a4aa36efaeb1661a12cf5e31e52253..9762caffa31951f8f1a6a38c2bf44efc434da022 100644 --- a/src/ui/toolbar/calligraphy-toolbar.cpp +++ b/src/ui/toolbar/calligraphy-toolbar.cpp @@ -57,7 +57,7 @@ CalligraphyToolbar::CalligraphyToolbar() CalligraphyToolbar::CalligraphyToolbar(Glib::RefPtr const &builder) : Toolbar{get_widget(builder, "calligraphy-toolbar")} , _tracker{std::make_unique(Util::UNIT_TYPE_LINEAR)} - , _profile_selector_combo{get_widget(builder, "_profile_selector_combo")} + , _profile_selector_combo{get_derived_widget(builder, "_profile_selector_combo")} , _width_item{get_derived_widget(builder, "_width_item")} , _thinning_item{get_derived_widget(builder, "_thinning_item")} , _mass_item{get_derived_widget(builder, "_mass_item")} @@ -328,14 +328,14 @@ void CalligraphyToolbar::update_presets_list() if (match) { // newly added item is at the same index as the // save command, so we need to change twice for it to take effect - _profile_selector_combo.set_active(0); - _profile_selector_combo.set_active(index); + _profile_selector_combo.set_selected(0); + _profile_selector_combo.set_selected(index); return; } } // no match found - _profile_selector_combo.set_active(0); + _profile_selector_combo.set_selected(0); } void CalligraphyToolbar::tilt_state_changed() @@ -366,7 +366,7 @@ void CalligraphyToolbar::build_presets_list() void CalligraphyToolbar::change_profile() { - auto mode = _profile_selector_combo.get_active_row_number(); + auto mode = _profile_selector_combo.get_selected(); if (_presets_blocked) { return; @@ -436,7 +436,7 @@ void CalligraphyToolbar::save_profile(GtkWidget *) return; } - Glib::ustring current_profile_name = _profile_selector_combo.get_active_text(); + auto current_profile_name = _profile_selector_combo.get_string(_profile_selector_combo.get_selected()); if (current_profile_name == _("No preset")) { current_profile_name = ""; diff --git a/src/ui/toolbar/calligraphy-toolbar.h b/src/ui/toolbar/calligraphy-toolbar.h index 95e849de629cd129556fae4ec2f3c28bd88955d8..cc62363f8e4ba8cb29aef2d2b8497f40cdb4fd79 100644 --- a/src/ui/toolbar/calligraphy-toolbar.h +++ b/src/ui/toolbar/calligraphy-toolbar.h @@ -39,6 +39,7 @@ class ToggleButton; namespace Inkscape::UI { class SimplePrefPusher; namespace Widget { +class DropDownList; class SpinButton; class UnitTracker; } // namespace Widget @@ -60,7 +61,7 @@ private: std::unique_ptr _tracker; bool _presets_blocked = false; - Gtk::ComboBoxText &_profile_selector_combo; + UI::Widget::DropDownList &_profile_selector_combo; UI::Widget::SpinButton &_width_item; UI::Widget::SpinButton &_thinning_item; diff --git a/src/ui/toolbar/text-toolbar.cpp b/src/ui/toolbar/text-toolbar.cpp index d60345254d960c5e5c6f23e46f19307a2bb9f09a..4004b14b0e894af15f848706a9df6d77341575e8 100644 --- a/src/ui/toolbar/text-toolbar.cpp +++ b/src/ui/toolbar/text-toolbar.cpp @@ -307,7 +307,7 @@ TextToolbar::TextToolbar(Glib::RefPtr const &builder) _("Font Size"), tooltip, create_sizes_store(unit), - 8, // Width in characters + 5, // Width in characters 0, // Extra list width {}, // Cell layout {} // Separator diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index 448f6d87e05d25f5d59d54a54a3cf1026a95d7a9..fa15cac9535a9898e3ebc6e47d4c9824948b0182 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -58,6 +58,7 @@ #include #include "ui/widget/events/canvas-event.h" #include "ui/widget/events/debug.h" +#include "ui/widget/generic/spin-button.h" // globals for temporary switching to selector by space static bool selector_toggled = false; @@ -144,7 +145,7 @@ static Gtk::Widget* find_first_focusable_input(Gtk::Widget* container) { return (entry && entry->get_sensitive()) ? entry : nullptr; } - if (dynamic_cast(container) || dynamic_cast(container)) { + if (dynamic_cast(container) || dynamic_cast(container)) { return (container->get_focusable() && container->get_sensitive()) ? container : nullptr; } diff --git a/src/ui/util.cpp b/src/ui/util.cpp index d55c3479b81d738c4849bddecc2732466a190f10..5bc40852ac461771296ca3266f8f853d9de86eda 100644 --- a/src/ui/util.cpp +++ b/src/ui/util.cpp @@ -107,8 +107,9 @@ namespace Inkscape::UI { void set_icon_sizes(Gtk::Widget *parent, int pixel_size) { if (!parent) return; + for_each_descendant(*parent, [=](Gtk::Widget &widget) { - if (dynamic_cast(&widget)) { + if (dynamic_cast(&widget) || dynamic_cast(&widget)) { // do not descend into spinbuttons; it will impact +/- icons too return ForEachResult::_skip; } diff --git a/src/ui/widget/character-viewer.cpp b/src/ui/widget/character-viewer.cpp index d64c11d83ca85dd6f3cfa462aec18c6df2dade5a..3862ad6f5ef1fb41b97e30465562bbef8e1e24c0 100644 --- a/src/ui/widget/character-viewer.cpp +++ b/src/ui/widget/character-viewer.cpp @@ -66,6 +66,7 @@ CharacterViewer::CharacterViewer(): }); _range_selector.set_button_max_chars(20); // limit how wide dropdown can get + _range_selector.set_ellipsize_button(true); _range_selector.enable_search(); for (auto& range : Util::get_unicode_ranges()) { _range_selector.append(range.name); diff --git a/src/ui/widget/dash-selector.cpp b/src/ui/widget/dash-selector.cpp index 3188bdf4951a9918f09ea3b8db7a17a50f3c81fc..ee2770b20f713f29b8679883648f0033d3ce9ac1 100644 --- a/src/ui/widget/dash-selector.cpp +++ b/src/ui/widget/dash-selector.cpp @@ -138,7 +138,7 @@ void DashSelector::construct(bool compact) { if (compact) { auto& spinbutton = get_widget(_builder, "offset"); adjustment = spinbutton.get_adjustment(); - sp_dialog_defocus_on_enter(spinbutton); + spinbutton.setDefocusTarget(this); } else { adjustment = Gtk::Adjustment::create(0.0, 0.0, 1000.0, 0.1, 1.0, 0.0); @@ -307,6 +307,10 @@ void DashSelector::draw_text(Cairo::RefPtr const &cr, int width, cr->show_text(_("Custom")); } +void DashSelector::onDefocus() { + sp_dialog_defocus(dynamic_cast(get_root())); +} + } // namespace Inkscape::UI::Widget /* diff --git a/src/ui/widget/dash-selector.h b/src/ui/widget/dash-selector.h index f21a9a98beeea3f87b910dbc359adbaa38009afe..7a217a982e39fc49823633b6a8bdf27e65b2bd0e 100644 --- a/src/ui/widget/dash-selector.h +++ b/src/ui/widget/dash-selector.h @@ -23,6 +23,8 @@ #include #include +#include "ui/defocus-target.h" + namespace Gtk { class Builder; class DrawingArea; @@ -34,7 +36,7 @@ class SingleSelection; namespace Inkscape::UI::Widget { -class DashSelector final : public Gtk::Box { +class DashSelector final : public Gtk::Box, DefocusTarget{ public: DashSelector(bool compact = false); @@ -64,6 +66,8 @@ private: const std::vector& pattern); void draw_text(const Cairo::RefPtr& cr, int width, int height); + void onDefocus() override; + // Variables std::vector dash_pattern; // The current pattern. double offset = 0; // The current offset. diff --git a/src/ui/widget/drop-down-list.cpp b/src/ui/widget/drop-down-list.cpp index 1249f951bf1c835dd853ffa932e286c883ec44fe..f2366cd96f379215b4b53fcd6e2df5819f04d894 100644 --- a/src/ui/widget/drop-down-list.cpp +++ b/src/ui/widget/drop-down-list.cpp @@ -78,7 +78,7 @@ void DropDownList::_init() { auto dropdown_button = Gtk::SignalListItemFactory::create(); dropdown_button->signal_setup().connect([this](auto& list_item) { - list_item->set_child(*set_up_item(true)); + list_item->set_child(*set_up_item(_ellipsize_button)); }); dropdown_button->signal_bind().connect([this](const Glib::RefPtr& list_item) { auto& label = dynamic_cast(*list_item->get_child()); diff --git a/src/ui/widget/drop-down-list.h b/src/ui/widget/drop-down-list.h index 915975854a208309d9122c2c8e40ac5e33bd63b6..59c09d1bc91c661dae61c157817456ece5029f27 100644 --- a/src/ui/widget/drop-down-list.h +++ b/src/ui/widget/drop-down-list.h @@ -57,6 +57,9 @@ public: // if set, this function will be used to extract string from items stored in the model void set_to_string_func(std::function&)> callback); + // enable ellipsizing strings in the dropdown button itself + void set_ellipsize_button(bool ellipsize = true) { _ellipsize_button = ellipsize; } + private: void _init(); Glib::ustring get_item_string(const Glib::RefPtr& item); @@ -66,6 +69,7 @@ private: std::function _separator_callback; std::function&)> _to_string; int _button_max_chars = -1; + bool _ellipsize_button = false; }; } // namespace diff --git a/src/ui/widget/export-lists.cpp b/src/ui/widget/export-lists.cpp index a0241dc733a4b06bd7676c92ccccaa0fbeac4c89..8b902b891921f7ac74a6ea5d5fe1b2e1682fe5a4 100644 --- a/src/ui/widget/export-lists.cpp +++ b/src/ui/widget/export-lists.cpp @@ -16,6 +16,7 @@ #include #include +#include "spinbutton.h" #include "extension/db.h" #include "extension/output.h" #include "io/sys.h" @@ -175,9 +176,6 @@ void ExportList::setup() add_button->signal_clicked().connect(sigc::mem_fun(*this, &ExportList::append_row)); add_button->set_hexpand(true); add_button->set_visible(true); - - this->set_row_spacing(5); - this->set_column_spacing(2); } void ExportList::removeExtension(std::string &filename) @@ -202,7 +200,7 @@ void ExportList::append_row() suffix->set_visible(true); auto const extension = Gtk::make_managed(); - auto const dpi_sb = Gtk::make_managed(); + auto const dpi_sb = Gtk::make_managed(); extension->setup(); extension->set_visible(true); @@ -222,8 +220,6 @@ void ExportList::append_row() dpi_sb->set_value(default_dpi); dpi_sb->set_sensitive(true); dpi_sb->set_width_chars(6); - dpi_sb->set_max_width_chars(6); - dpi_sb->set_visible(true); this->attach(*dpi_sb, _dpi_col, current_row, 1, 1); auto const pIcon = Gtk::manage(sp_get_icon_image("window-close", Gtk::IconSize::NORMAL)); @@ -275,7 +271,7 @@ Inkscape::Extension::Output *ExportList::getExtension(int row) double ExportList::get_dpi(int row) { double dpi = default_dpi; - auto spin_sb = dynamic_cast(this->get_child_at(_dpi_col, row + 1)); + auto spin_sb = dynamic_cast(this->get_child_at(_dpi_col, row + 1)); if (spin_sb == nullptr) { return dpi; } diff --git a/src/ui/widget/font-variations.cpp b/src/ui/widget/font-variations.cpp index d63100b630f8737499cd44b37ebc72fabf9b1508..f5c843b3f47cc0da60ca56fb69c74fafb9320f8e 100644 --- a/src/ui/widget/font-variations.cpp +++ b/src/ui/widget/font-variations.cpp @@ -39,9 +39,7 @@ #include "ui/util.h" -namespace Inkscape { -namespace UI { -namespace Widget { +namespace Inkscape::UI::Widget { std::pair get_axis_name(const std::string& tag, const Glib::ustring& abbr) { // Transformed axis names; @@ -56,7 +54,7 @@ std::pair get_axis_name(const std::string& tag, co // which describes how it alters the opaque stroke forms of glyphs typically in the X dimension {"XOPQ", std::make_pair(C_("Variable font axis", "X opaque"), _("Alter the opaque stroke forms of glyphs in the X dimension"))}, // TRANSLATORS: “Parametric Thin Stroke”, YOPQ, is a reference to its logical name, “Y Opaque”, - // which describes how it alters the opaque stroke forms of glyphs typically in the Y dimension + // which describes how it alters the opaque stroke forms of glyphs typically in the Y dimension {"YOPQ", std::make_pair(C_("Variable font axis", "Y opaque"), _("Alter the opaque stroke forms of glyphs in the Y dimension"))}, // TRANSLATORS: “Parametric Counter Width”, XTRA, is a reference to its logical name, “X-Transparent,” // which describes how it alters a font’s transparent spaces (also known as negative shapes) @@ -108,7 +106,7 @@ std::pair get_axis_name(const std::string& tag, co {"slnt", std::make_pair(C_("Variable font axis", "Slant"), _("Controls the font file’s slant parameter for oblique styles"))}, // Italic {"ital", std::make_pair(C_("Variable font axis", "Italic"), _("Turns on the font’s italic forms"))}, - // TRANSLATORS: Weight controls the font file’s weight parameter. + // TRANSLATORS: Weight controls the font file’s weight parameter. {"wght", std::make_pair(C_("Variable font axis", "Weight"), _("Controls the font file’s weight parameter"))}, // TRANSLATORS: Width controls the font file’s width parameter. {"wdth", std::make_pair(C_("Variable font axis", "Width"), _("Controls the font file’s width parameter"))}, @@ -147,7 +145,7 @@ std::pair get_axis_name(const std::string& tag, co FontVariationAxis::FontVariationAxis(Glib::ustring name_, OTVarAxis const &axis, Glib::ustring label_, Glib::ustring tooltip) : Gtk::Box(Gtk::Orientation::HORIZONTAL) - , name(std::move(name_)) + , name(std::move(name_)) { // std::cout << "FontVariationAxis::FontVariationAxis:: " // << " name: " << name @@ -163,7 +161,7 @@ FontVariationAxis::FontVariationAxis(Glib::ustring name_, OTVarAxis const &axis, label->set_xalign(0.0f); // left-align append(*label); - edit = Gtk::make_managed(); + edit = Gtk::make_managed(); edit->set_max_width_chars(5); edit->set_valign(Gtk::Align::CENTER); edit->set_margin_top(2); @@ -365,15 +363,13 @@ bool FontVariations::variations_present() const { Glib::RefPtr FontVariations::get_size_group(int index) { switch (index) { - case 0: return _size_group; - case 1: return _size_group_edit; - default: return Glib::RefPtr(); + case 0: return _size_group; + case 1: return _size_group_edit; + default: return Glib::RefPtr(); } } -} // namespace Widget -} // namespace UI -} // namespace Inkscape +} /* Local Variables: diff --git a/src/ui/widget/font-variations.h b/src/ui/widget/font-variations.h index f58c20f1313d9da5fdb7bc3fd7894f4195a82116..f1a9ecf190f62737d20270a28555657e40cc985f 100644 --- a/src/ui/widget/font-variations.h +++ b/src/ui/widget/font-variations.h @@ -18,15 +18,12 @@ #include #include +#include "spinbutton.h" #include "libnrtype/OpenTypeUtil.h" - #include "style.h" #include "ui/operation-blocker.h" -namespace Inkscape { -namespace UI { -namespace Widget { - +namespace Inkscape::UI::Widget { /** * A widget for a single axis: Label and Slider @@ -41,7 +38,7 @@ public: int get_precision() { return precision; } Gtk::Scale* get_scale() { return scale; } double get_def() { return def; } - Gtk::SpinButton* get_editbox() { return edit; } + SpinButton* get_editbox() { return edit; } void set_value(double value); private: @@ -49,7 +46,7 @@ private: Glib::ustring name; Gtk::Label* label; Gtk::Scale* scale; - Gtk::SpinButton* edit = nullptr; + SpinButton* edit = nullptr; int precision; double def = 0.0; // Default value @@ -113,10 +110,8 @@ private: OperationBlocker _update; }; - -} // namespace Widget -} // namespace UI -} // namespace Inkscape + +} #endif // INKSCAPE_UI_WIDGET_FONT_VARIATIONS_H diff --git a/src/ui/widget/generic/spin-button.cpp b/src/ui/widget/generic/spin-button.cpp index 73b2436895eaeeaf7f92028a6ca4f1fe4316e5cf..055afda30530748067b211dc9aef30254c7ff6b9 100644 --- a/src/ui/widget/generic/spin-button.cpp +++ b/src/ui/widget/generic/spin-button.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,13 @@ void InkSpinButton::construct() { // ------------- CONTROLLERS ------------- + // mouse clicks to open context menu + _click_value = Gtk::GestureClick::create(); + _click_value->set_button(); // all buttons + _click_value->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); // before GTK's popup handler + _click_value->signal_pressed().connect([this](auto n, auto x, auto y) { on_value_clicked(); }); + add_controller(_click_value); + // This is a mouse movement. Shows/hides +/- buttons. // Shows/hides +/- buttons. _motion = Gtk::EventControllerMotion::create(); @@ -193,7 +201,7 @@ void InkSpinButton::construct() { _key_entry = Gtk::EventControllerKey::create(); _key_entry->set_propagation_phase(Gtk::PropagationPhase::CAPTURE); - _key_entry->signal_key_pressed().connect(sigc::mem_fun(*this, &InkSpinButton::on_key_pressed), false); // Before default handler. + _key_entry->signal_key_pressed().connect([this](auto keyval, auto keycode, auto modifiers){ return on_key_pressed(keyval, modifiers); }, false); // Before default handler. _entry.add_controller(_key_entry); // GTK4 @@ -201,15 +209,25 @@ void InkSpinButton::construct() { _entry.signal_activate().connect([this] { on_activate(); }); - // Value (button) NOT USED, Click handled by zero length drag. - // m_value->signal_clicked().connect(sigc::mem_fun(*this, &SpinButton::on_value_clicked)); - _minus.set_visible(); auto m = _minus.measure(Gtk::Orientation::HORIZONTAL); _button_width = m.sizes.natural; m = _entry.measure(Gtk::Orientation::VERTICAL); _entry_height = m.sizes.natural; _baseline = m.baselines.natural; + { + auto layout = create_pango_layout("9"); + int text_width = 0; + int text_height = 0; + layout->get_pixel_size(text_width, text_height); + _text_width_min = text_width; + layout = create_pango_layout("12345.678"); + layout->get_pixel_size(text_width, text_height); + _text_width_wide = text_width; + if (_text_width_wide <= _text_width_min) { + _text_width_wide = _text_width_min + 1; + } + } set_value(_num_value); set_step(_step_value); @@ -246,12 +264,17 @@ void InkSpinButton::construct() { property_value().signal_changed().connect([this]{ set_value(_num_value); }); property_prefix().signal_changed().connect([this]{ update(false); }); property_suffix().signal_changed().connect([this]{ update(false); }); + property_width_chars().signal_changed().connect([this] { set_width_chars(_width_chars.get_value()); }); // if the adjustment property has been set, it takes precedence over min/max values and step if (auto adj = _adjust.get_value()) { _adjustment = adj; } _connection = _adjustment->signal_value_changed().connect([this]{ update(); }); + + if (auto width = _width_chars.get_value()) { + set_width_chars(width); + } update(); } @@ -270,7 +293,9 @@ void InkSpinButton::construct() { _icon_name(*this, "icon", {}), \ _label_text(*this, "label", {}), \ _prefix(*this, "prefix", {}), \ - _suffix(*this, "suffix", {}) + _suffix(*this, "suffix", {}), \ + _width_chars(*this, "width-chars", 0), \ + _climb_rate(*this, "climb-rate", 0.0) #define CALL_CONSTRUCTORS \ Glib::ObjectBase("InkSpinButton"), \ @@ -341,8 +366,19 @@ void InkSpinButton::measure_vfunc(Gtk::Orientation orientation, int for_size, in auto btn = _enable_arrows ? _button_width : 0; // always reserve space for inc/dec buttons and label, whichever is greater natural = std::max(get_left_padding() + text_width, btn + text_width + btn); - // allow spin button to shrink if pushed - minimum = natural / 2; + // allow spin button to shrink if pushed; + // if it is wide, then we let it go down to 0.5 its normal size + // if it is narrow, then we let it shrink less + // if it is very narrow (one digit), we keep natural size + auto shrink_factor = 1.0; // 100% size - no shrinking + if (text_width > _text_width_min) { + double range = _text_width_wide - _text_width_min; + auto excess = text_width - _text_width_min; + // calc shrink amount in proportion to the size of the button; + // let it shrink, but to no less than to 50% of natural size + shrink_factor = std::max(0.5, 1.0 - (excess / range) * 0.5); + } + minimum = static_cast(std::ceil(natural * shrink_factor)); } else { minimum_baseline = natural_baseline = _baseline; @@ -462,6 +498,10 @@ void InkSpinButton::set_step(double step_increment) { _adjustment->set_step_increment(step_increment); } +void InkSpinButton::set_page_step(double page_increment) { + _adjustment->set_page_increment(page_increment); +} + void InkSpinButton::set_prefix(const std::string& prefix, bool add_space) { if (add_space && !prefix.empty()) { _prefix.set_value(prefix + " "); @@ -747,6 +787,10 @@ void InkSpinButton::exit_edit() { _mask.show(); } +bool InkSpinButton::edit_pending() const { + return _entry.get_visible(); +} + void InkSpinButton::cancel_editing() { update(false); // take the current recorder value and update text/display exit_edit(); @@ -833,9 +877,10 @@ double InkSpinButton::get_value() const { return _adjustment->get_value() / _fmt_scaling_factor; } -void InkSpinButton::change_value(double inc, Gdk::ModifierType state) { +void InkSpinButton::change_value(double inc, Gdk::ModifierType state, bool page) { double scale = get_accel_factor(state); - auto value = _adjustment->get_value() + _adjustment->get_step_increment() * scale * inc; + double step = page ? _adjustment->get_page_increment() : _adjustment->get_step_increment(); + auto value = _adjustment->get_value() + step * scale * inc; set_new_value(value); } @@ -854,31 +899,73 @@ double InkSpinButton::wrap_around(double value) { // ------------------ KEY ------------------ -bool InkSpinButton::on_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state) { - switch (keyval) { - case GDK_KEY_Escape: // Cancel - // Esc pressed - cancel editing - cancel_editing(); - defocus(); - return false; // allow Esc to be handled by dialog too +bool InkSpinButton::on_key_pressed(guint keyval, Gdk::ModifierType state) { + state &= Gtk::Accelerator::get_default_mod_mask(); + + // Note: + // event->triggers_context_menu() doesn't work with key messages + + switch (keyval) { + case GDK_KEY_Escape: // Cancel + // Esc pressed - cancel editing + if (edit_pending() && state == Gdk::ModifierType::NO_MODIFIER_MASK) { + cancel_editing(); + defocus(); + return true; + } + // allow Esc to be handled by dialog too + break; + + // signal "activate" uses this key, so we may not see it + case GDK_KEY_Return: + case GDK_KEY_KP_Enter: +#ifdef __APPLE__ + // ctrl+return is a macOS context menu shortcut + if (Controller::has_flag(state, Gdk::ModifierType::CONTROL_MASK)) { + return _context_menu_call ? _context_menu_call() : false; + } +#endif + if (edit_pending() && state == Gdk::ModifierType::NO_MODIFIER_MASK) { + commit_entry(); + defocus(); + return true; + } + break; + + case GDK_KEY_Up: + case GDK_KEY_KP_Up: + change_value(1, state); + return true; - // signal "activate" uses this key, so we won't see it: - // case GDK_KEY_Return: - // break; + case GDK_KEY_Down: + case GDK_KEY_KP_Down: + change_value(-1, state); + return true; - case GDK_KEY_Up: - change_value(1, state); - return true; + case GDK_KEY_Page_Up: + change_value(1, state, true); + return true; - case GDK_KEY_Down: - change_value(-1, state); - return true; + case GDK_KEY_Page_Down: + change_value(-1, state, true); + return true; - default: - break; - } +#ifndef __APPLE__ + case GDK_KEY_F10: + if (Controller::has_flag(state, Gdk::ModifierType::SHIFT_MASK)) { + return _context_menu_call ? _context_menu_call() : false; + } + break; +#endif - return false; + case GDK_KEY_Menu: + return _context_menu_call ? _context_menu_call() : false; + + default: + break; + } + + return false; } // ------------------ CLICK ------------------ @@ -897,12 +984,24 @@ void InkSpinButton::on_pressed_minus(int n_press, double x, double y) { start_spinning(-inc, state, _click_minus); } +void InkSpinButton::on_value_clicked() { + if (!_context_menu_call) return; + + auto event = _click_value->get_current_event(); + if (event->triggers_context_menu()) { + if (_context_menu_call()) { + _click_value->set_state(Gtk::EventSequenceState::CLAIMED); + } + } +} + void InkSpinButton::on_activate() { bool ok = commit_entry(); if (ok && _enter_exit_edit) { set_focusable(true); defocus(); exit_edit(); + _signal_activate.emit(); } } @@ -939,6 +1038,11 @@ int InkSpinButton::get_left_padding() const { return _icon_width > 0 ? 2 * icon_margin + _icon_width : _label_width; } +void InkSpinButton::set_width_chars(int width) { + std::string pattern(std::clamp(width, 0, 50), '9'); + set_min_size(pattern); +} + void InkSpinButton::set_drag_sensitivity(double distance) { _drag_full_travel = distance; } @@ -956,7 +1060,7 @@ void InkSpinButton::set_label(const std::string& label) { } } -sigc::signal InkSpinButton::signal_value_changed() const { +sigc::signal& InkSpinButton::signal_value_changed() { return _signal_value_changed; } @@ -1007,6 +1111,14 @@ void InkSpinButton::set_transformers(std::function input, std::f update(false); // apply transformer } +sigc::signal & InkSpinButton::signal_activate() { + return _signal_activate; +} + +void InkSpinButton::set_activates_default(bool setting) { + _entry.set_activates_default(setting); +} + // a fade-out mask for overflowing numbers void InkSpinButton::FadeOut::snapshot_vfunc(const Glib::RefPtr& snapshot) { auto rect = Gdk::Graphene::Rect(0, 0, get_width(), get_height()); diff --git a/src/ui/widget/generic/spin-button.h b/src/ui/widget/generic/spin-button.h index aa33905118500da3abf6934e3123b4a0d57d9071..2c5b9d03c65a694119c875909a462ef600514b2a 100644 --- a/src/ui/widget/generic/spin-button.h +++ b/src/ui/widget/generic/spin-button.h @@ -47,6 +47,8 @@ public: void set_range(double min, double max); // Set the step increment of the spin button void set_step(double step_increment); + // Set the page increment of the spin button + void set_page_step(double page_increment); // Set a new value; it will be rescaled if scaling is set void set_value(double new_value); // Get the current value; it will be rescaled if scaling is set @@ -72,7 +74,7 @@ public: // Specify the label to show inside spin button void set_label(const std::string& label); // Signal fired when numerical value changes - sigc::signal signal_value_changed() const; + sigc::signal& signal_value_changed(); // Base spin button's min size on the pattern provided; ex: "99.99" void set_min_size(const std::string& pattern); // Set a callback function that parses text and returns "double" value; it may throw std::exception on failure @@ -89,6 +91,12 @@ public: // - input transformer takes value as input by the user and transforms it to the internal domain // - output transformer takes internal value and transforms is to the presentation layer void set_transformers(std::function input, std::function output); + // Signal emitted when the user finished editing by pressing Enter + sigc::signal& signal_activate(); + // Set callback invoked when the user tries to open contextual menu + void set_context_menu_callback(const std::function& callback) { _context_menu_call = callback; } + // Should pressing enter/return activate the default widget + void set_activates_default(bool setting = true); private: void construct(); @@ -139,11 +147,13 @@ private: Glib::RefPtr _click_minus; void on_pressed_minus(int n_press, double x, double y); + Glib::RefPtr _click_value; + void on_value_clicked(); + Glib::RefPtr _focus; Glib::RefPtr _key_entry; - bool on_key_pressed(guint keyval, guint keycode, Gdk::ModifierType state); // "pressed" vs GTK3 "press" - // void on_key_released(guint keyval, guint keycode, Gdk::ModifierType state); + bool on_key_pressed(guint keyval, Gdk::ModifierType state); void on_activate(); // "activate" fires on pressing Enter in an entry widget @@ -151,17 +161,19 @@ private: void on_editing_done(); void enter_edit(); void exit_edit(); + bool edit_pending() const; void cancel_editing(); bool defocus(); void show_arrows(bool on = true); void show_label_icon(bool on = true); bool commit_entry(); - void change_value(double inc, Gdk::ModifierType state); + void change_value(double inc, Gdk::ModifierType state, bool page = false); double wrap_around(double value); std::string format(double value, bool with_prefix_suffix, bool with_markup, bool trim_zeros, bool limit_size) const; void start_spinning(double steps, Gdk::ModifierType state, Glib::RefPtr& gesture); void stop_spinning(); int get_left_padding() const; + void set_width_chars(int width); // ---------------- DATA ------------------ double _initial_value = 0.0; // Value of adjustment at the start of drag. @@ -171,7 +183,9 @@ private: bool _trim_zeros = true; // hide insignificant zeros in decimal fraction double _fmt_scaling_factor = 1.0; // multiplier for value formatting sigc::connection _connection; - int _button_width = 0; // width of increment/decrement button + int _button_width = 0; // width of increment/decrement button + int _text_width_min = 0; // width of a single digit + int _text_width_wide = 0; // width of a wide "12345.678" string int _entry_height = 0; // natural height of Gtk::Entry int _baseline = 0; int _label_width = 0; @@ -190,6 +204,8 @@ private: bool _mouse_entered = false; // flag to keep track of motion_enter/leave std::function _output_transformer; std::function _input_transformer; + std::function _context_menu_call; + sigc::signal _signal_activate; // ----------- PROPERTIES ------------ Glib::Property> _adjust; @@ -199,6 +215,7 @@ private: Glib::Property _max_value; Glib::Property _step_value; Glib::Property _scaling_factor; + Glib::Property _climb_rate; Glib::Property _has_frame; Glib::Property _show_arrows; Glib::Property _enter_exit; @@ -207,6 +224,7 @@ private: Glib::Property _label_text; Glib::Property _prefix; Glib::Property _suffix; + Glib::Property _width_chars; public: Glib::PropertyProxy> property_adjustment() { return _adjust.get_proxy(); } @@ -224,6 +242,7 @@ public: Glib::PropertyProxy property_show_arrows() { return _show_arrows.get_proxy(); } Glib::PropertyProxy property_enter_exit() { return _enter_exit.get_proxy(); } Glib::PropertyProxy property_wrap_around() { return _wrap_around.get_proxy(); } + Glib::PropertyProxy property_width_chars() { return _width_chars.get_proxy(); } }; } // namespace Inkscape::UI::Widget diff --git a/src/ui/widget/page-properties.cpp b/src/ui/widget/page-properties.cpp index bf88f5ee295f57aea213194893bff25fca49a6e0..b300117ef86e6efb88b4bc6a0bf945ee59b9b574 100644 --- a/src/ui/widget/page-properties.cpp +++ b/src/ui/widget/page-properties.cpp @@ -210,11 +210,11 @@ public: _linked_viewbox_scale.set_from_icon_name(s_linked); // report page size changes - _page_width .signal_value_changed().connect([this](){ set_page_size_linked(true); }); - _page_height.signal_value_changed().connect([this](){ set_page_size_linked(false); }); + _page_width .signal_value_changed().connect([this](auto){ set_page_size_linked(true); }); + _page_height.signal_value_changed().connect([this](auto){ set_page_size_linked(false); }); // enforce uniform scale thru viewbox - _viewbox_width. signal_value_changed().connect([this](){ set_viewbox_size_linked(true); }); - _viewbox_height.signal_value_changed().connect([this](){ set_viewbox_size_linked(false); }); + _viewbox_width. signal_value_changed().connect([this](auto){ set_viewbox_size_linked(true); }); + _viewbox_height.signal_value_changed().connect([this](auto){ set_viewbox_size_linked(false); }); _landscape.signal_toggled().connect([this](){ if (_landscape.get_active()) swap_width_height(); }); _portrait .signal_toggled().connect([this](){ if (_portrait .get_active()) swap_width_height(); }); @@ -225,14 +225,14 @@ public: auto b2 = &pair.second; if (dim == Dimension::Scale) { // uniform scale: report the same x and y - b1->signal_value_changed().connect([=, this](){ - // Report the dimention differently if locked + b1->signal_value_changed().connect([=, this](auto){ + // Report the dimension differently if locked fire_value_changed(*b1, *b1, nullptr, _locked_content_scale ? Dimension::ScaleContent : Dimension::Scale); }); } else { - b1->signal_value_changed().connect([=, this](){ fire_value_changed(*b1, *b2, nullptr, dim); }); - b2->signal_value_changed().connect([=, this](){ fire_value_changed(*b1, *b2, nullptr, dim); }); + b1->signal_value_changed().connect([=, this](auto){ fire_value_changed(*b1, *b2, nullptr, dim); }); + b2->signal_value_changed().connect([=, this](auto){ fire_value_changed(*b1, *b2, nullptr, dim); }); } } @@ -288,7 +288,7 @@ private: set_page_size(true); } - void changed_linked_value(bool width_changing, Gtk::SpinButton& wedit, Gtk::SpinButton& hedit) { + void changed_linked_value(bool width_changing, MathSpinButton& wedit, MathSpinButton& hedit) { if (_size_ratio > 0) { auto scoped(_update.block()); if (width_changing) { @@ -470,7 +470,7 @@ private: } } - void fire_value_changed(Gtk::SpinButton& b1, Gtk::SpinButton& b2, const Util::Unit* unit, Dimension dim) { + void fire_value_changed(MathSpinButton& b1, MathSpinButton& b2, const Util::Unit* unit, Dimension dim) { if (!_update.pending()) { _signal_dimension_changed.emit(b1.get_value(), b2.get_value(), unit, dim); } @@ -517,7 +517,7 @@ private: } } - typedef std::pair spin_pair; + typedef std::pair spin_pair; spin_pair get_dimension(Dimension dimension) { switch (dimension) { case Dimension::PageSize: return spin_pair(_page_width, _page_height); diff --git a/src/ui/widget/point.cpp b/src/ui/widget/point.cpp index 8546a76dfe4df0507b012c83f2a597ba68244a5d..c8efeee97c5014b1af54144775cca625502080e1 100644 --- a/src/ui/widget/point.cpp +++ b/src/ui/widget/point.cpp @@ -141,12 +141,12 @@ void Point::clearProgrammatically() ywidget.setProgrammatically = false; } -Glib::SignalProxy Point::signal_x_value_changed() +sigc::signal& Point::signal_x_value_changed() { return xwidget.signal_value_changed(); } -Glib::SignalProxy Point::signal_y_value_changed() +sigc::signal& Point::signal_y_value_changed() { return ywidget.signal_value_changed(); } diff --git a/src/ui/widget/point.h b/src/ui/widget/point.h index 872481b5545328666d32a63214d61eb0b39e10eb..026cd17f013bbc491fd9003e21325adea5adbd62 100644 --- a/src/ui/widget/point.h +++ b/src/ui/widget/point.h @@ -155,8 +155,8 @@ public: /** * Signal raised when the spin button's value changes. */ - Glib::SignalProxy signal_x_value_changed(); - Glib::SignalProxy signal_y_value_changed(); + sigc::signal& signal_x_value_changed(); + sigc::signal& signal_y_value_changed(); /** * Check 'setProgrammatically' of both scalar widgets. False if value is changed by user by clicking the widget. diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index 443beac31b2c19b22146ef6afb10bdaf4891d8c5..37084802cf7910ca5b92a494c2375fdd16995759 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -86,6 +86,7 @@ public: class PrefSpinButton : public SpinButton { public: + PrefSpinButton() : Glib::ObjectBase("PrefSpinButton") {} void init(Glib::ustring const &prefs_path, double lower, double upper, double step_increment, double page_increment, double default_value, bool is_int, bool is_percent); diff --git a/src/ui/widget/scalar-unit.cpp b/src/ui/widget/scalar-unit.cpp index af1c917db5fde50a690236f1683492cfa56f6f46..2d057280664716ead277826af6ba9402000945b1 100644 --- a/src/ui/widget/scalar-unit.cpp +++ b/src/ui/widget/scalar-unit.cpp @@ -138,13 +138,15 @@ void ScalarUnit::grabFocusAndSelectEntry() { auto &spinButton = getSpinButton(); spinButton.grab_focus(); - spinButton.select_region(0, 20); + //TODO: + // spinButton.select_region(0, 20); } void ScalarUnit::setAlignment(double xalign) { xalign = std::clamp(xalign,0.0,1.0); - getSpinButton().set_alignment(xalign); + g_message("spinbtn alignment: not supported"); + // getSpinButton().set_alignment(xalign); } void ScalarUnit::setHundredPercent(double number) diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index ac79986ca1a1e0470e54e72ec080dbb8667553fd..d3eaf97f52082d334ab419e9950027d02e47052c 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -97,26 +97,27 @@ void Scalar::setDigits(unsigned digits) void Scalar::setNoLeadingZeros() { - if (getDigits()) { - auto &spin_button = getSpinButton(); - spin_button.set_numeric(false); - spin_button.signal_output().connect(sigc::mem_fun(*this, &Scalar::setNoLeadingZerosOutput), false); - } + // if (getDigits()) { + // auto &spin_button = getSpinButton(); + // spin_button.set_numeric(false); + // spin_button.signal_output().connect(sigc::mem_fun(*this, &Scalar::setNoLeadingZerosOutput), false); + // } } bool Scalar::setNoLeadingZerosOutput() { - auto &spin_button = getSpinButton(); - double digits = std::pow(10.0, spin_button.get_digits()); - double val = std::round(spin_button.get_value() * digits) / digits; - spin_button.set_text(Glib::ustring::format(val)); + // auto &spin_button = getSpinButton(); + // double digits = std::pow(10.0, spin_button.get_digits()); + // double val = std::round(spin_button.get_value() * digits) / digits; + // spin_button.set_text(Glib::ustring::format(val)); return true; } void Scalar::setWidthChars(gint width_chars) { - getSpinButton().property_width_chars() = width_chars; + //TODO: set size, if need be + // getSpinButton().property_width_chars() = width_chars; } void Scalar::setIncrements(double step, double /*page*/) @@ -145,7 +146,7 @@ void Scalar::setWidthChars(unsigned chars) void Scalar::update() { - getSpinButton().update(); + // getSpinButton().update(); } void Scalar::addSlider() @@ -155,7 +156,7 @@ void Scalar::addSlider() UI::pack_start(*this, *scale); } -Glib::SignalProxy Scalar::signal_value_changed() +sigc::signal& Scalar::signal_value_changed() { return getSpinButton().signal_value_changed(); } diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h index ac7063883ec8ddde62075c1e60c1da464186e5e7..f032ef8325d076ff7cd4178cd7f501d4dd276417 100644 --- a/src/ui/widget/scalar.h +++ b/src/ui/widget/scalar.h @@ -169,7 +169,7 @@ public: /** * Signal raised when the spin button's value changes. */ - Glib::SignalProxy signal_value_changed(); + sigc::signal& signal_value_changed(); /** * true if the value was set by setValue, not changed by the user; diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp index 1cefd7a4c3e496648524cd2b419ebf306b2a8ad2..1edd62e3dd3c503aa3470140c72a41f526ca644f 100644 --- a/src/ui/widget/spinbutton.cpp +++ b/src/ui/widget/spinbutton.cpp @@ -17,7 +17,6 @@ #include "scroll-utils.h" #include "ui/controller.h" -#include "ui/defocus-target.h" #include "ui/tools/tool-base.h" #include "ui/util.h" #include "unit-menu.h" @@ -27,24 +26,17 @@ namespace Inkscape::UI::Widget { -MathSpinButton::MathSpinButton(BaseObjectType *cobject, const Glib::RefPtr &refGlade) - : Gtk::SpinButton(cobject) +MathSpinButton::MathSpinButton(BaseObjectType *cobject, const Glib::RefPtr &refGlade) : + Glib::ObjectBase("MathSpinButtonWrapper"), InkSpinButton(cobject) { - signal_input().connect(sigc::mem_fun(*this, &MathSpinButton::on_input), true); + set_evaluator_function([this](auto& text) { return on_input(text); }); } -int MathSpinButton::on_input(double &newvalue) -{ - try { - newvalue = Util::ExpressionEvaluator{::get_text(*this)}.evaluate().value; - } catch (Inkscape::Util::EvaluatorException const &e) { - g_message ("%s", e.what()); - return false; - } - return true; +double MathSpinButton::on_input(const Glib::ustring& text) { + return Util::ExpressionEvaluator{text.c_str()}.evaluate().value; } -void SpinButton::_construct() +void SpinButton::_construct(BaseObjectType* cobject) { auto const key = Gtk::EventControllerKey::create(); key->signal_key_pressed().connect([this, &key = *key](auto &&...args) { return on_key_pressed(key, args...); }, true); @@ -58,41 +50,39 @@ void SpinButton::_construct() }); add_controller(focus); - UI::on_popup_menu(*this, sigc::mem_fun(*this, &SpinButton::on_popup_menu)); + set_context_menu_callback([this]{ return on_popup_menu({}); }); + + set_evaluator_function([this](auto& text) { return on_input(text); }); - signal_input().connect(sigc::mem_fun(*this, &SpinButton::on_input), true); + InkSpinButton::signal_value_changed().connect([this](auto) { + _signal_value_changed.emit(); + }); signal_destroy().connect([this] { _unparentChildren(); }); } -int SpinButton::on_input(double &newvalue) -{ - if (_dont_evaluate) return false; - - try { - Inkscape::Util::EvaluatorQuantity result; - if (_unit_menu || _unit_tracker) { - Unit const *unit = nullptr; - if (_unit_menu) { - unit = _unit_menu->getUnit(); - } else { - unit = _unit_tracker->getActiveUnit(); - } - result = Util::ExpressionEvaluator{::get_text(*this), unit}.evaluate(); - // check if output dimension corresponds to input unit - if (result.dimension != (unit->isAbsolute() ? 1 : 0) ) { - throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.",""); - } +double SpinButton::on_input(const Glib::ustring& text) { + auto value = std::stod(text); + if (_dont_evaluate) return value; + + Inkscape::Util::EvaluatorQuantity result; + if (_unit_menu || _unit_tracker) { + Unit const *unit = nullptr; + if (_unit_menu) { + unit = _unit_menu->getUnit(); } else { - result = Util::ExpressionEvaluator{::get_text(*this)}.evaluate(); + unit = _unit_tracker->getActiveUnit(); } - newvalue = result.value; - } catch (Inkscape::Util::EvaluatorException const &e) { - g_message ("%s", e.what()); - return false; + result = Util::ExpressionEvaluator{text.c_str(), unit}.evaluate(); + // check if output dimension corresponds to input unit + if (result.dimension != (unit->isAbsolute() ? 1 : 0) ) { + throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.",""); + } + } else { + result = Util::ExpressionEvaluator{text.c_str()}.evaluate(); } - return true; + return result.value; } bool SpinButton::on_key_pressed(Gtk::EventControllerKey const &controller, @@ -116,16 +106,6 @@ bool SpinButton::on_key_pressed(Gtk::EventControllerKey const &controller, } switch (Inkscape::UI::Tools::get_latin_keyval(controller, keyval, keycode, state)) { - case GDK_KEY_Escape: // defocus - undo(); - defocus(); - return true; - - case GDK_KEY_Return: // defocus - case GDK_KEY_KP_Enter: - defocus(); - break; - case GDK_KEY_z: case GDK_KEY_Z: if (Controller::has_flag(state, Gdk::ModifierType::CONTROL_MASK)) { @@ -236,19 +216,6 @@ SpinButton::~SpinButton() _unparentChildren(); } -void SpinButton::defocus() -{ - // clear selection, which would otherwise persist - select_region(0, 0); - - // defocus spinbutton by moving focus to the canvas - if (_defocus_target) { - _defocus_target->onDefocus(); - } else if (auto widget = get_scrollable_ancestor(*this)) { - widget->grab_focus(); - } -} - void SpinButton::set_custom_numeric_menu_data(NumericMenuData &&custom_menu_data) { _custom_popup = true; @@ -259,6 +226,48 @@ void SpinButton::set_increment(double delta) { _increment = delta; } +void SpinButton::set_increments(double step, double page) { + set_step(step); + set_page_step(page); +} + +void SpinButton::get_increments(double &step, double &page) const { + auto& spin = const_cast(*this); + step = spin.get_adjustment()->get_step_increment(); + page = spin.get_adjustment()->get_page_increment(); +} + +void SpinButton::get_range(double &min, double &max) const { + auto& spin = const_cast(*this); + auto adj = spin.get_adjustment(); + min = adj->get_lower(); + max = adj->get_upper(); +} + +void SpinButton::set_range(double min, double max) { + auto adj = get_adjustment(); + adj->set_lower(min); + adj->set_upper(max); +} + +void SpinButton::set_width_chars(int chars) { + property_width_chars().set_value(chars); +} + +void SpinButton::set_max_width_chars(int chars) { + //TODO if needed +} + +Glib::ustring SpinButton::get_text() const { + //TODO: remove + return {}; +} + +int SpinButton::get_value_as_int() const { + //TODO: round the value? + return static_cast(get_value()); +} + } // namespace Inkscape::UI::Widget /* diff --git a/src/ui/widget/spinbutton.h b/src/ui/widget/spinbutton.h index ea8999645966ff281c1523cf6ba52639290e9efc..363244c405708bbcc4228e37c6ec3c7345b6cace 100644 --- a/src/ui/widget/spinbutton.h +++ b/src/ui/widget/spinbutton.h @@ -13,6 +13,8 @@ #include +#include "generic/bin.h" +#include "generic/spin-button.h" #include "ui/popup-menu.h" #include "ui/widget/generic/popover-menu.h" @@ -21,8 +23,6 @@ class Builder; class EventControllerKey; } // namespace Gtk -namespace Inkscape::UI { class DefocusTarget; } - namespace Inkscape::UI::Widget { class UnitMenu; @@ -31,13 +31,13 @@ class UnitTracker; /** * A spin button for use with builders. */ -class MathSpinButton : public Gtk::SpinButton +class MathSpinButton : public InkSpinButton { public: MathSpinButton(BaseObjectType *cobject, const Glib::RefPtr &refGlade); private: - int on_input(double &newvalue); + double on_input(const Glib::ustring& text); }; /** @@ -46,19 +46,33 @@ private: * * Calling "set_numeric()" effectively disables the expression parsing. If no unit menu is linked, all unitlike characters are ignored. */ -class SpinButton : public Gtk::SpinButton +class SpinButton : public InkSpinButton { public: using NumericMenuData = std::map; - // We canʼt inherit ctors as if we declare SpinButton(), inherited ctors donʼt call it. Really! - template - SpinButton(Args &&...args) - : Gtk::SpinButton(std::forward(args)...) - { _construct(); } // Do the non-templated stuff - SpinButton(BaseObjectType *cobject, Glib::RefPtr const &) - : Gtk::SpinButton(cobject) - { _construct(); } + SpinButton(BaseObjectType *cobject, Glib::RefPtr const & b): + Glib::ObjectBase("SpinButtonWrapper"), InkSpinButton(cobject, b) + { _construct(cobject); } + + SpinButton(BaseObjectType *cobject): + Glib::ObjectBase("SpinButtonWrapper"), InkSpinButton(cobject) + { _construct(cobject); } + + explicit SpinButton(double climb_rate = 0.0, guint digits = 0): + Glib::ObjectBase("SpinButtonWrapper") + { + _construct(); + set_digits(digits); + } + + explicit SpinButton(const Glib::RefPtr& adjustment, double climb_rate = 0.0, guint digits = 0): + Glib::ObjectBase("SpinButtonWrapper") + { + _construct(); + set_adjustment(adjustment); + set_digits(digits); + } ~SpinButton() override; @@ -72,16 +86,22 @@ public: inline bool get_zeroable() const { return _zeroable; } inline bool get_oneable() const { return _oneable; } - void defocus(); - // set key up/down increment to override spin button adjustment step setting void set_increment(double delta); + void set_increments(double step, double page); + void get_increments(double& step, double& page) const; + void get_range(double& min, double& max) const; + void set_range(double min, double max); + void set_width_chars(int chars); + void set_max_width_chars(int chars); + Glib::ustring get_text() const; + int get_value_as_int() const; + sigc::signal& signal_value_changed() { return _signal_value_changed; } private: UnitMenu *_unit_menu = nullptr; ///< Linked unit menu for unit conversion in entered expressions. UnitTracker *_unit_tracker = nullptr; ///< Linked unit tracker for unit conversion in entered expressions. double _on_focus_in_value = 0.; - Inkscape::UI::DefocusTarget *_defocus_target = nullptr; ///< Widget that should be informed when the spinbutton defocuses bool _zeroable = false; ///< Reset-value should be zero bool _oneable = false; ///< Reset-value should be one bool _dont_evaluate = false; ///< Don't attempt to evaluate expressions @@ -89,8 +109,9 @@ private: bool _custom_popup = false; double _increment = 0.0; // if > 0, key up/down will increment/decrement current value by this amount std::unique_ptr _popover_menu; + sigc::signal _signal_value_changed; - void _construct(); + void _construct(BaseObjectType* cobject = nullptr); /** * This callback function should try to convert the entered text to a number and write it to newvalue. @@ -99,7 +120,7 @@ private: * @retval false No conversion done, continue with default handler. * @retval true Conversion successful, don't call default handler. */ - int on_input(double &newvalue); + double on_input(const Glib::ustring& text); /** * Handle specific keypress events, like Ctrl+Z. @@ -122,9 +143,6 @@ private: void _unparentChildren(); public: - inline void setDefocusTarget(decltype(_defocus_target) target) { _defocus_target = target; } - inline void set_dont_evaluate(bool flag) { _dont_evaluate = flag; } - void set_custom_numeric_menu_data(NumericMenuData &&custom_menu_data); }; diff --git a/src/ui/widget/textpath-popover.cpp b/src/ui/widget/textpath-popover.cpp index b602f54b1e63969538efb89c771c0e4d8a59b343..d88758069543425bbe7def96f3b673fb1e715f3c 100644 --- a/src/ui/widget/textpath-popover.cpp +++ b/src/ui/widget/textpath-popover.cpp @@ -21,6 +21,7 @@ #include "document-undo.h" #include "object/sp-shape.h" #include "preferences.h" +#include "spinbutton.h" #include "ui/builder-utils.h" #include "ui/icon-names.h" @@ -31,7 +32,7 @@ TextpathPopover::TextpathPopover(SPText *text, SPTextPath *textpath, SPDesktop * , _text(text) , _textpath(textpath) , _builder(create_builder("textpath-popover-box.ui")) - , _start_offset_sb(get_widget(_builder, "start-offset-sb")) + , _start_offset_sb(get_derived_widget(_builder, "start-offset-sb")) , _side_left_btn(get_widget(_builder, "side-left-btn")) , _side_right_btn(get_widget(_builder, "side-right-btn")) { diff --git a/src/ui/widget/textpath-popover.h b/src/ui/widget/textpath-popover.h index 052b52a8d34c9e3758609e4953b4e6a3727ce5a8..8e129bfd5861c96bd1e4850bf9c399f039f89b00 100644 --- a/src/ui/widget/textpath-popover.h +++ b/src/ui/widget/textpath-popover.h @@ -28,6 +28,7 @@ class ToggleButton; } // namespace Gtk namespace Inkscape::UI::Widget { +class SpinButton; class TextpathPopover final : public Gtk::Popover { @@ -45,7 +46,7 @@ private: // ************* Widgets ************* // Glib::RefPtr _builder; - Gtk::SpinButton &_start_offset_sb; + SpinButton &_start_offset_sb; Gtk::ToggleButton &_side_left_btn; Gtk::ToggleButton &_side_right_btn;