From cba60dd473848d5e980894dd4a48fdeb9890a8ac Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 9 Apr 2011 01:19:48 +0200 Subject: add a subclassed spinbutton class. this numeric entry box accepts both ',' and '.' as the decimal point when in numeric mode. (bzr r10150) --- src/ui/widget/spinbutton.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/ui/widget/spinbutton.cpp (limited to 'src/ui/widget/spinbutton.cpp') diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp new file mode 100644 index 000000000..55c2d877f --- /dev/null +++ b/src/ui/widget/spinbutton.cpp @@ -0,0 +1,60 @@ +/** + * \brief SpinButton widget, that allows entry of both '.' and ',' for the decimal, even when in numeric mode. + */ +/* + * Author: + * Johan B. C. Engelen + * + * Copyright (C) 2011 Author + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "spinbutton.h" + +#include + +namespace Inkscape { +namespace UI { +namespace Widget { + +void +SpinButton::on_insert_text(const Glib::ustring& text, int* position) +{ + Glib::ustring newtext = text; + + // if in numeric mode: replace '.' or ',' with the locale's decimal point + if (get_numeric()) { + size_t found = newtext.find('.'); + if (found != Glib::ustring::npos) { + newtext.replace(found, 1, localeconv()->decimal_point); + } else { + found = newtext.find(','); + if (found != Glib::ustring::npos) { + newtext.replace(found, 1, localeconv()->decimal_point); + } + } + } + + // call parent function with replaced text: + Gtk::SpinButton::on_insert_text(newtext, position); +} + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3 From fe875852760883dd20b6a57b57be50de83e37fc2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 14 Apr 2011 00:04:49 +0200 Subject: add expression evaluator for spinbox input boxes. also knows a little about units. needs more work to fully integrate it in all of inkscape spinboxes also needs documentation rework (bzr r10162) --- src/ui/widget/spinbutton.cpp | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'src/ui/widget/spinbutton.cpp') diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp index 55c2d877f..22bc30bb2 100644 --- a/src/ui/widget/spinbutton.cpp +++ b/src/ui/widget/spinbutton.cpp @@ -16,32 +16,39 @@ #include "spinbutton.h" -#include +#include "unit-menu.h" +#include "util/expression-evaluator.h" namespace Inkscape { namespace UI { namespace Widget { -void -SpinButton::on_insert_text(const Glib::ustring& text, int* position) +/** + * This callback function should try to convert the entered text to a number and write it to newvalue. + * It calls a method to evaluate the (potential) mathematical expression. + * + * @retval false No conversion done, continue with default handler. + * @retval true Conversion successful, don't call default handler. + */ +int +SpinButton::on_input(double* newvalue) { - Glib::ustring newtext = text; - - // if in numeric mode: replace '.' or ',' with the locale's decimal point - if (get_numeric()) { - size_t found = newtext.find('.'); - if (found != Glib::ustring::npos) { - newtext.replace(found, 1, localeconv()->decimal_point); - } else { - found = newtext.find(','); - if (found != Glib::ustring::npos) { - newtext.replace(found, 1, localeconv()->decimal_point); - } + try { + Inkscape::Util::GimpEevlQuantity result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), _unit_menu ? &_unit_menu->getUnit() : NULL); + // check if output dimension corresponds to input unit + if (_unit_menu && result.dimension != (_unit_menu->getUnit().isAbsolute() ? 1 : 0) ) { + throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.",""); } + + *newvalue = result.value; + } + catch(Inkscape::Util::EvaluatorException &e) { + g_message ("%s", e.what()); + + return false; } - // call parent function with replaced text: - Gtk::SpinButton::on_insert_text(newtext, position); + return true; } } // namespace Widget -- cgit v1.2.3 From ba0656ed825139624f4726c2e9d4389e2a8c2f37 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 15 Apr 2011 21:38:27 +0200 Subject: add undo to SpinButton (bzr r10167) --- src/ui/widget/spinbutton.cpp | 70 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) (limited to 'src/ui/widget/spinbutton.cpp') diff --git a/src/ui/widget/spinbutton.cpp b/src/ui/widget/spinbutton.cpp index 22bc30bb2..32090f96c 100644 --- a/src/ui/widget/spinbutton.cpp +++ b/src/ui/widget/spinbutton.cpp @@ -18,11 +18,20 @@ #include "unit-menu.h" #include "util/expression-evaluator.h" +#include "event-context.h" namespace Inkscape { namespace UI { namespace Widget { + +void +SpinButton::connect_signals() { + signal_input().connect(sigc::mem_fun(*this, &SpinButton::on_input)); + signal_focus_in_event().connect(sigc::mem_fun(*this, &SpinButton::on_my_focus_in_event)); + signal_key_press_event().connect(sigc::mem_fun(*this, &SpinButton::on_my_key_press_event)); +}; + /** * This callback function should try to convert the entered text to a number and write it to newvalue. * It calls a method to evaluate the (potential) mathematical expression. @@ -34,10 +43,16 @@ int SpinButton::on_input(double* newvalue) { try { - Inkscape::Util::GimpEevlQuantity result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), _unit_menu ? &_unit_menu->getUnit() : NULL); - // check if output dimension corresponds to input unit - if (_unit_menu && result.dimension != (_unit_menu->getUnit().isAbsolute() ? 1 : 0) ) { - throw Inkscape::Util::EvaluatorException("Input dimensions do not match with parameter dimensions.",""); + Inkscape::Util::GimpEevlQuantity result; + if (_unit_menu) { + Unit unit = _unit_menu->getUnit(); + result = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), &unit); + // 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 = Inkscape::Util::gimp_eevl_evaluate (get_text().c_str(), NULL); } *newvalue = result.value; @@ -51,6 +66,53 @@ SpinButton::on_input(double* newvalue) return true; } +/** When focus is obtained, save the value to enable undo later. + * @retval false continue with default handler. + * @retval true don't call default handler. +*/ +bool +SpinButton::on_my_focus_in_event(GdkEventFocus* /*event*/) +{ + on_focus_in_value = get_value(); + return false; // do not consume the event +} + +/** Handle specific keypress events, like Ctrl+Z + * @retval false continue with default handler. + * @retval true don't call default handler. +*/ +bool +SpinButton::on_my_key_press_event(GdkEventKey* event) +{ + switch (get_group0_keyval (event)) { + case GDK_Escape: + undo(); + return true; // I consumed the event + break; + case GDK_z: + case GDK_Z: + if (event->state & GDK_CONTROL_MASK) { + undo(); + return true; // I consumed the event + } + break; + default: + break; + } + + return false; // do not consume the event +} + +/** + * Undo the editing, by resetting the value upon when the spinbutton got focus. + */ +void +SpinButton::undo() +{ + set_value(on_focus_in_value); +} + + } // namespace Widget } // namespace UI } // namespace Inkscape -- cgit v1.2.3