1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Author: 4 * Johan B. C. Engelen 5 * 6 * Copyright (C) 2011 Author 7 * 8 * Released under GNU GPL v2+, read the file 'COPYING' for more information. 9 */ 10 11 #ifndef INKSCAPE_UI_WIDGET_SPINBUTTON_H 12 #define INKSCAPE_UI_WIDGET_SPINBUTTON_H 13 14 #include <gtkmm/spinbutton.h> 15 16 #include "scrollprotected.h" 17 18 namespace Inkscape { 19 namespace UI { 20 namespace Widget { 21 22 class UnitMenu; 23 class UnitTracker; 24 25 /** 26 * SpinButton widget, that allows entry of simple math expressions (also units, when linked with UnitMenu), 27 * and allows entry of both '.' and ',' for the decimal, even when in numeric mode. 28 * 29 * Calling "set_numeric()" effectively disables the expression parsing. If no unit menu is linked, all unitlike characters are ignored. 30 */ 31 class SpinButton : public ScrollProtected<Gtk::SpinButton> 32 { 33 using parent_type = ScrollProtected<Gtk::SpinButton>; 34 35 public: 36 using parent_type::parent_type; 37 setUnitMenu(UnitMenu * unit_menu)38 void setUnitMenu(UnitMenu* unit_menu) { _unit_menu = unit_menu; }; 39 addUnitTracker(UnitTracker * ut)40 void addUnitTracker(UnitTracker* ut) { _unit_tracker = ut; }; 41 42 // TODO: Might be better to just have a default value and a reset() method? 43 inline void set_zeroable(const bool zeroable = true) { _zeroable = zeroable; } 44 inline void set_oneable(const bool oneable = true) { _oneable = oneable; } 45 get_zeroable()46 inline bool get_zeroable() const { return _zeroable; } get_oneable()47 inline bool get_oneable() const { return _oneable; } 48 49 void defocus(); 50 51 protected: 52 UnitMenu *_unit_menu = nullptr; ///< Linked unit menu for unit conversion in entered expressions. 53 UnitTracker *_unit_tracker = nullptr; ///< Linked unit tracker for unit conversion in entered expressions. 54 double _on_focus_in_value = 0.; 55 Gtk::Widget *_defocus_widget = nullptr; ///< Widget that should grab focus when the spinbutton defocuses 56 57 bool _zeroable = false; ///< Reset-value should be zero 58 bool _oneable = false; ///< Reset-value should be one 59 60 bool _stay = false; ///< Whether to ignore defocusing 61 bool _dont_evaluate = false; ///< Don't attempt to evaluate expressions 62 63 /** 64 * This callback function should try to convert the entered text to a number and write it to newvalue. 65 * It calls a method to evaluate the (potential) mathematical expression. 66 * 67 * @retval false No conversion done, continue with default handler. 68 * @retval true Conversion successful, don't call default handler. 69 */ 70 int on_input(double* newvalue) override; 71 72 /** 73 * When focus is obtained, save the value to enable undo later. 74 * @retval false continue with default handler. 75 * @retval true don't call default handler. 76 */ 77 bool on_focus_in_event(GdkEventFocus *) override; 78 79 /** 80 * Handle specific keypress events, like Ctrl+Z. 81 * 82 * @retval false continue with default handler. 83 * @retval true don't call default handler. 84 */ 85 bool on_key_press_event(GdkEventKey *) override; 86 87 /** 88 * Undo the editing, by resetting the value upon when the spinbutton got focus. 89 */ 90 void undo(); 91 92 public: set_defocus_widget(const decltype (_defocus_widget)widget)93 inline void set_defocus_widget(const decltype(_defocus_widget) widget) { _defocus_widget = widget; } set_dont_evaluate(bool flag)94 inline void set_dont_evaluate(bool flag) { _dont_evaluate = flag; } 95 }; 96 97 } // namespace Widget 98 } // namespace UI 99 } // namespace Inkscape 100 101 #endif // INKSCAPE_UI_WIDGET_SPINBUTTON_H 102 103 /* 104 Local Variables: 105 mode:c++ 106 c-file-style:"stroustrup" 107 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) 108 indent-tabs-mode:nil 109 fill-column:99 110 End: 111 */ 112 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : 113