2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; version 2.1 of
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * SECTION:hildon-number-editor
27 * @short_description: A widget used to enter a number within a pre-defined range
29 * HildonNumberEditor is used to enter a number from a specific range.
30 * There are two buttons to scroll the value in number field.
31 * Manual input is also possible.
34 #include <gdk/gdkkeysyms.h>
41 #include "hildon-number-editor.h"
42 #include "hildon-marshalers.h"
43 #include <hildon-widgets/gtk-infoprint.h>
44 #include "hildon-composite-widget.h"
45 #include <hildon-widgets/hildon-input-mode-hint.h>
46 #include <hildon-widgets/hildon-defines.h>
47 #include "hildon-libs-enum-types.h"
54 #define _(String) dgettext(PACKAGE, String)
56 /*Pixel spec defines*/
57 #define NUMBER_EDITOR_HEIGHT 30
59 /* Size of plus and minus buttons */
60 #define BUTTON_HEIGHT 30
61 #define BUTTON_WIDTH 30
63 #define HILDON_NUMBER_EDITOR_GET_PRIVATE(obj) \
64 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_NUMBER_EDITOR, \
65 HildonNumberEditorPrivate));
67 typedef struct _HildonNumberEditorPrivate HildonNumberEditorPrivate;
70 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
73 hildon_number_editor_init (HildonNumberEditor *editor);
76 hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
80 hildon_number_editor_entry_changed (GtkWidget *widget, gpointer data);
83 hildon_number_editor_size_request (GtkWidget *widget,
84 GtkRequisition *requisition);
87 set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
88 const GtkAllocation *allocation);
91 hildon_number_editor_size_allocate (GtkWidget *widget,
92 GtkAllocation *allocation);
95 hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
99 hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
103 hildon_number_editor_entry_button_released (GtkWidget *widget,
104 GdkEventButton *event,
107 hildon_number_editor_button_released (GtkWidget *widget,
109 HildonNumberEditor *editor);
111 do_mouse_timeout (HildonNumberEditor *editor);
114 change_numbers (HildonNumberEditor *editor, gint update);
117 hildon_number_editor_forall (GtkContainer *container, gboolean include_internals,
118 GtkCallback callback, gpointer callback_data);
121 hildon_number_editor_destroy (GtkObject *self);
124 hildon_number_editor_start_timer (HildonNumberEditor *editor);
127 hildon_number_editor_finalize (GObject *self);
130 hildon_number_editor_range_error(HildonNumberEditor *editor,
131 HildonNumberEditorErrorType type);
134 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
137 hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate);
139 static void hildon_number_editor_set_property(GObject * object,
141 const GValue * value,
144 static void hildon_number_editor_get_property(GObject * object,
146 GValue * value, GParamSpec * pspec);
155 /* Property indices */
161 static GtkContainerClass *parent_class;
163 static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
165 struct _HildonNumberEditorPrivate
168 GtkWidget *num_entry;
172 gint start; /* Minimum */
173 gint end; /* Maximum */
175 gint button_type; /* Type of button pressed: 1 = plus, -1 = minus */
178 guint button_event_id; /* Repeat change when button is held */
179 guint select_all_idle_id; /* Selection repaint hack
180 see hildon_number_editor_select_all */
184 GType hildon_number_editor_get_type(void)
186 static GType editor_type = 0;
190 static const GTypeInfo editor_info =
192 sizeof(HildonNumberEditorClass),
193 NULL, /* base_init */
194 NULL, /* base_finalize */
195 (GClassInitFunc) hildon_number_editor_class_init,
196 NULL, /* class_finalize */
197 NULL, /* class_data */
198 sizeof(HildonNumberEditor),
200 (GInstanceInitFunc) hildon_number_editor_init,
202 editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
203 "HildonNumberEditor",
210 hildon_number_editor_class_init(HildonNumberEditorClass * editor_class)
212 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
213 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
214 GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
216 g_type_class_add_private(editor_class,
217 sizeof(HildonNumberEditorPrivate));
219 parent_class = g_type_class_peek_parent(editor_class);
221 widget_class->size_request = hildon_number_editor_size_request;
222 widget_class->size_allocate = hildon_number_editor_size_allocate;
223 widget_class->focus = hildon_composite_widget_focus;
225 editor_class->range_error = hildon_number_editor_range_error;
227 /* Because we derived our widget from GtkContainer, we should override
229 container_class->forall = hildon_number_editor_forall;
230 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
231 gobject_class->finalize = hildon_number_editor_finalize;
232 gobject_class->set_property = hildon_number_editor_set_property;
233 gobject_class->get_property = hildon_number_editor_get_property;
235 g_object_class_install_property(gobject_class, PROP_VALUE,
236 g_param_spec_int("value",
238 "The current value of number editor",
241 0, G_PARAM_READWRITE));
243 HildonNumberEditor_signal[RANGE_ERROR] =
244 g_signal_new("range_error", HILDON_TYPE_NUMBER_EDITOR,
245 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
246 (HildonNumberEditorClass, range_error),
247 g_signal_accumulator_true_handled, NULL,
248 _hildon_marshal_BOOLEAN__ENUM,
249 G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
253 hildon_number_editor_forall(GtkContainer *container, gboolean include_internals,
254 GtkCallback callback, gpointer callback_data)
256 HildonNumberEditorPrivate *priv =
257 HILDON_NUMBER_EDITOR_GET_PRIVATE(container);
259 g_assert(callback != NULL);
261 if (!include_internals)
264 /* Enumerate child widgets */
265 (*callback) (priv->minus, callback_data);
266 (*callback) (priv->num_entry, callback_data);
267 (*callback) (priv->plus, callback_data);
271 hildon_number_editor_destroy(GtkObject *self)
273 HildonNumberEditorPrivate *priv;
275 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
277 /* Free child widgets */
280 gtk_widget_unparent(priv->minus);
285 gtk_widget_unparent(priv->num_entry);
286 priv->num_entry = NULL;
290 gtk_widget_unparent(priv->plus);
294 if (GTK_OBJECT_CLASS(parent_class)->destroy)
295 GTK_OBJECT_CLASS(parent_class)->destroy(self);
299 hildon_number_editor_stop_repeat_timer(HildonNumberEditorPrivate *priv)
301 if (priv->button_event_id)
303 g_source_remove(priv->button_event_id);
304 priv->button_event_id = 0;
309 hildon_number_editor_finalize (GObject *self)
311 HildonNumberEditorPrivate *priv;
313 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
316 hildon_number_editor_stop_repeat_timer(priv);
318 if (priv->select_all_idle_id)
319 g_source_remove (priv->select_all_idle_id);
321 /* Call parent class finalize, if have one */
322 if (G_OBJECT_CLASS (parent_class)->finalize)
323 G_OBJECT_CLASS (parent_class)->finalize(self);
327 hildon_number_editor_init (HildonNumberEditor *editor)
329 HildonNumberEditorPrivate *priv;
331 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
332 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(editor), GTK_NO_WINDOW);
334 /* Create child widgets */
335 priv->num_entry = gtk_entry_new();
336 priv->minus = gtk_button_new();
337 priv->plus = gtk_button_new();
339 gtk_widget_set_name( priv->minus, "minus-button" );
340 gtk_widget_set_name( priv->plus, "plus-button" );
341 gtk_widget_set_size_request( priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT );
342 gtk_widget_set_size_request( priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT );
343 gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
345 GTK_WIDGET_UNSET_FLAGS( priv->minus, GTK_CAN_FOCUS );
346 GTK_WIDGET_UNSET_FLAGS( priv->plus, GTK_CAN_FOCUS );
348 priv->button_event_id = 0;
349 priv->select_all_idle_id = 0;
351 gtk_widget_set_parent(priv->minus, GTK_WIDGET(editor));
352 gtk_widget_set_parent(priv->num_entry, GTK_WIDGET(editor));
353 gtk_widget_set_parent(priv->plus, GTK_WIDGET(editor));
355 /* Connect child widget signals */
356 g_signal_connect(GTK_OBJECT(priv->num_entry), "changed",
357 G_CALLBACK(hildon_number_editor_entry_changed),
360 g_signal_connect(GTK_OBJECT(priv->num_entry), "focus-out-event",
361 G_CALLBACK(hildon_number_editor_entry_focusout),
364 g_signal_connect(GTK_OBJECT(priv->num_entry), "key-press-event",
365 G_CALLBACK(hildon_number_editor_entry_keypress),
368 g_signal_connect(GTK_OBJECT(priv->num_entry), "button-release-event",
369 G_CALLBACK(hildon_number_editor_entry_button_released),
372 g_signal_connect(GTK_OBJECT(priv->minus), "button-press-event",
373 G_CALLBACK(hildon_number_editor_button_pressed),
376 g_signal_connect(GTK_OBJECT(priv->plus), "button-press-event",
377 G_CALLBACK(hildon_number_editor_button_pressed),
380 g_signal_connect(GTK_OBJECT(priv->minus), "button-release-event",
381 G_CALLBACK(hildon_number_editor_button_released),
384 g_signal_connect(GTK_OBJECT(priv->plus), "button-release-event",
385 G_CALLBACK(hildon_number_editor_button_released),
388 g_signal_connect(GTK_OBJECT(priv->minus), "leave-notify-event",
389 G_CALLBACK(hildon_number_editor_button_released),
392 g_signal_connect(GTK_OBJECT(priv->plus), "leave-notify-event",
393 G_CALLBACK(hildon_number_editor_button_released),
396 g_object_set( G_OBJECT(priv->num_entry),
397 "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
399 gtk_widget_show(priv->num_entry);
400 gtk_widget_show(priv->minus);
401 gtk_widget_show(priv->plus);
403 hildon_number_editor_set_range(editor, G_MININT, G_MAXINT);
407 hildon_number_editor_entry_button_released (GtkWidget *widget,
408 GdkEventButton *event,
411 gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
416 hildon_number_editor_button_released (GtkWidget *widget, GdkEvent *event,
417 HildonNumberEditor *editor)
419 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
420 hildon_number_editor_stop_repeat_timer(priv);
424 /* Format given number to editor field, no checks performed, all signals
425 are sent normally. */
427 hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv, gint value)
431 /* Update text in entry to new value */
432 g_snprintf(buffer, sizeof(buffer), "%d", value);
433 gtk_entry_set_text(GTK_ENTRY(priv->num_entry), buffer);
437 hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
440 /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
441 /* Need to fetch current value from entry and increment or decrement
443 HildonNumberEditor *editor;
444 HildonNumberEditorPrivate *priv;
445 GtkSettings *settings;
448 g_assert(HILDON_IS_NUMBER_EDITOR(data));
450 editor = HILDON_NUMBER_EDITOR(data);
451 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
452 settings = gtk_settings_get_default();
453 g_object_get(settings, "gtk-initial-timeout", &timeout, NULL);
455 /* Save type of button pressed */
456 if (GTK_BUTTON(widget) == GTK_BUTTON(priv->plus))
457 priv->button_type = 1;
459 priv->button_type = -1;
461 /* Start repetition timer */
462 if (!priv->button_event_id)
464 do_mouse_timeout(editor);
465 priv->button_event_id = g_timeout_add (timeout,
466 (GSourceFunc) hildon_number_editor_start_timer,
474 hildon_number_editor_start_timer (HildonNumberEditor *editor)
476 HildonNumberEditorPrivate *priv;
477 GtkSettings *settings;
480 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
481 settings = gtk_settings_get_default();
482 g_object_get(settings, "gtk-update-timeout", &timeout, NULL);
484 priv->button_event_id = g_timeout_add(timeout,
485 (GSourceFunc) do_mouse_timeout,
491 do_mouse_timeout (HildonNumberEditor *editor)
493 HildonNumberEditorPrivate *priv;
495 GDK_THREADS_ENTER ();
497 g_assert(HILDON_IS_NUMBER_EDITOR(editor));
499 /* Update value based on button held */
500 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
501 change_numbers(editor, priv->button_type);
503 GDK_THREADS_LEAVE ();
508 /* Changes the current number value by the amount of update
509 and verifies the result. */
511 change_numbers (HildonNumberEditor *editor, gint update)
513 HildonNumberEditorPrivate *priv;
516 g_assert(HILDON_IS_NUMBER_EDITOR(editor));
518 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
519 current_value = hildon_number_editor_get_value(editor);
521 /* We need to rerun validation by hand, since validation
522 done in "changed" callback allows intermediate values */
523 hildon_number_editor_real_set_value(priv, current_value + update);
524 hildon_number_editor_validate_value(editor, FALSE);
528 add_select_all_idle (HildonNumberEditorPrivate *priv)
530 if (!priv->select_all_idle_id)
532 priv->select_all_idle_id =
533 g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
538 hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate)
540 HildonNumberEditorPrivate *priv;
541 gint error_code, fixup_value;
547 g_assert(HILDON_IS_NUMBER_EDITOR(editor));
549 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
550 text = gtk_entry_get_text(GTK_ENTRY(priv->num_entry));
552 fixup_value = priv->default_val;
556 /* Try to convert entry text to number */
557 value = strtol(text, &tail, 10);
559 /* Check if conversion succeeded */
562 /* Check if value is in allowed range. This is tricky in those
563 cases when user is editing a value.
564 For example: Range = [100, 500] and user have just inputted "4".
565 This should not lead into error message. Otherwise value is
566 resetted back to "100" and next "4" press will reset it back
568 if (allow_intermediate)
570 /* We now have the following error cases:
571 * If inputted value as above maximum and
572 maximum is either positive or then maximum
573 negative and value is positive.
574 * If inputted value is below minimum and minimum
575 is negative or minumum positive and value
577 In all other cases situation can be fixed just by
578 adding new numbers to the string.
580 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
582 error_code = MAXIMUM_VALUE_EXCEED;
583 fixup_value = priv->end;
585 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value < 0)))
587 error_code = MINIMUM_VALUE_EXCEED;
588 fixup_value = priv->start;
593 if (value > priv->end) {
594 error_code = MAXIMUM_VALUE_EXCEED;
595 fixup_value = priv->end;
597 else if (value < priv->start) {
598 error_code = MINIMUM_VALUE_EXCEED;
599 fixup_value = priv->start;
603 /* The only valid case when conversion can fail is when we
604 have plain '-', intermediate forms are allowed AND
605 minimum bound is negative */
606 else if (!allow_intermediate || strcmp(text, "-") != 0 || priv->start >= 0)
607 error_code = ERRONEOUS_VALUE;
609 else if (!allow_intermediate)
610 error_code = ERRONEOUS_VALUE;
612 if (error_code != -1)
614 /* If entry is empty and intermediate forms are nor allowed,
616 /* Change to default value */
617 hildon_number_editor_set_value(editor, fixup_value);
618 g_signal_emit(editor, HildonNumberEditor_signal[RANGE_ERROR],
620 add_select_all_idle(priv);
625 hildon_number_editor_entry_changed(GtkWidget *widget, gpointer data)
627 g_assert(HILDON_IS_NUMBER_EDITOR(data));
628 hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), TRUE);
632 hildon_number_editor_size_request (GtkWidget *widget,
633 GtkRequisition *requisition)
635 HildonNumberEditor *editor;
636 HildonNumberEditorPrivate *priv;
639 editor = HILDON_NUMBER_EDITOR(widget);
640 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
642 /* Requested size is size of all child widgets plus border space */
643 gtk_widget_size_request(priv->minus, &req);
644 requisition->width = req.width;
646 gtk_widget_size_request(priv->num_entry, &req);
647 requisition->width += req.width;
649 gtk_widget_size_request(priv->plus, &req);
650 requisition->width += req.width;
652 requisition->width += HILDON_MARGIN_DEFAULT * 2;
654 /* FIXME: XXX Height is fixed */
655 requisition->height = NUMBER_EDITOR_HEIGHT;
658 /* Update @alloc->width so widget fits, update @alloc->x to point to free space */
660 set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
661 const GtkAllocation *allocation)
663 GtkRequisition child_requisition;
665 gtk_widget_get_child_requisition(widget, &child_requisition);
667 /* Fit to widget width */
668 if (allocation->width + allocation->x >
669 alloc->x + child_requisition.width)
670 alloc->width = child_requisition.width;
673 alloc->width = allocation->width - (alloc->x - allocation->x);
674 if (alloc->width < 0)
678 gtk_widget_size_allocate(widget, alloc);
679 /* Update x position */
680 alloc->x += alloc->width;
684 hildon_number_editor_size_allocate (GtkWidget *widget,
685 GtkAllocation *allocation)
687 HildonNumberEditor *editor;
688 HildonNumberEditorPrivate *priv;
691 editor = HILDON_NUMBER_EDITOR(widget);
692 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
694 widget->allocation = *allocation;
696 /* Add upper border */
697 alloc.y = widget->allocation.y + widget->style->ythickness;
700 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
702 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
703 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
706 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
708 if (alloc.height < 0)
711 /* Add left border */
712 alloc.x = allocation->x + widget->style->xthickness;
714 /* Allocate positions for widgets (left-to-right) */
715 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
716 alloc.x += HILDON_MARGIN_DEFAULT;
718 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
719 alloc.x += HILDON_MARGIN_DEFAULT;
721 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
725 hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
728 g_assert(HILDON_IS_NUMBER_EDITOR(data));
729 hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), FALSE);
734 hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
737 GtkEditable *editable;
740 g_assert(HILDON_IS_NUMBER_EDITOR(data));
742 editable = GTK_EDITABLE(widget);
743 cursor_pos = gtk_editable_get_position(editable);
745 switch (event->keyval)
748 /* If the cursor is on the left, try to decrement */
749 if (cursor_pos == 0) {
750 change_numbers(HILDON_NUMBER_EDITOR(data), -1);
756 /* If the cursor is on the right, try to increment */
757 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1))
759 change_numbers(HILDON_NUMBER_EDITOR(data), 1);
760 gtk_editable_set_position(editable, cursor_pos);
773 hildon_number_editor_range_error(HildonNumberEditor *editor,
774 HildonNumberEditorErrorType type)
778 gchar *err_msg = NULL;
779 HildonNumberEditorPrivate *priv;
781 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
785 /* Construct error message */
788 case MAXIMUM_VALUE_EXCEED:
789 err_msg = g_strdup_printf(_("ckct_ib_maximum_value"), max, max);
791 case MINIMUM_VALUE_EXCEED:
792 err_msg = g_strdup_printf(_("ckct_ib_minimum_value"), min, min);
794 case ERRONEOUS_VALUE:
796 g_strdup_printf(_("ckct_ib_set_a_value_within_range"), min, max);
800 /* Infoprint error */
803 gtk_infoprint(GTK_WINDOW(gtk_widget_get_ancestor(GTK_WIDGET(editor),
804 GTK_TYPE_WINDOW)), err_msg);
813 * hildon_number_editor_new:
814 * @min: minimum accepted value
815 * @max: maximum accepted value
817 * Creates new number editor
819 * Returns: a new #HildonNumberEditor widget
822 hildon_number_editor_new (gint min, gint max)
824 HildonNumberEditor *editor =
825 g_object_new(HILDON_TYPE_NUMBER_EDITOR, NULL);
827 /* Set user inputted range to editor */
828 hildon_number_editor_set_range(editor, min, max);
830 return GTK_WIDGET(editor);
834 * hildon_number_editor_set_range:
835 * @editor: a #HildonNumberEditor widget
836 * @min: minimum accepted value
837 * @max: maximum accepted value
839 * Sets accepted number range for editor
842 hildon_number_editor_set_range (HildonNumberEditor *editor, gint min, gint max)
844 HildonNumberEditorPrivate *priv;
845 gchar buffer_min[32], buffer_max[32];
848 g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
850 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
852 /* Set preferences */
853 priv->start = MIN(min, max);
854 priv->end = MAX(min, max);
856 /* Find maximum allowed length of value */
857 g_snprintf(buffer_min, sizeof(buffer_min), "%d", min);
858 g_snprintf(buffer_max, sizeof(buffer_max), "%d", max);
859 a = strlen(buffer_min);
860 b = strlen(buffer_max);
862 /* Set maximum size of entry */
863 gtk_entry_set_width_chars(GTK_ENTRY(priv->num_entry), MAX(a, b));
864 hildon_number_editor_set_value(editor, priv->start);
868 * hildon_number_editor_get_value:
869 * @editor: pointer to #HildonNumberEditor
871 * Returns: current NumberEditor value
874 hildon_number_editor_get_value (HildonNumberEditor *editor)
876 HildonNumberEditorPrivate *priv;
878 g_return_val_if_fail(HILDON_IS_NUMBER_EDITOR(editor), 0);
880 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
881 return atoi(gtk_entry_get_text(GTK_ENTRY(priv->num_entry)));
885 * hildon_number_editor_set_value:
886 * @editor: pointer to #HildonNumberEditor
887 * @value: numeric value for number editor
889 * Sets numeric value for number editor
892 hildon_number_editor_set_value (HildonNumberEditor *editor, gint value)
894 HildonNumberEditorPrivate *priv;
896 g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
898 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
900 g_return_if_fail(value <= priv->end);
901 g_return_if_fail(value >= priv->start);
903 priv->default_val = value;
904 hildon_number_editor_real_set_value(priv, value);
905 g_object_notify (G_OBJECT(editor), "value");
908 /* When calling gtk_entry_set_text, the entry widget does things that can
909 * cause the whole widget to redraw. This redrawing is delayed and if any
910 * selections are made right after calling the gtk_entry_set_text the
911 * setting of the selection might seem to have no effect.
913 * If the selection is delayed with a lower priority than the redrawing,
914 * the selection should stick. Calling this function with g_idle_add should
918 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
920 GDK_THREADS_ENTER ();
921 gtk_editable_select_region(GTK_EDITABLE(priv->num_entry), 0, -1);
922 priv->select_all_idle_id = 0;
923 GDK_THREADS_LEAVE ();
928 hildon_number_editor_set_property(GObject * object,
930 const GValue * value, GParamSpec * pspec)
932 HildonNumberEditor *editor;
934 editor = HILDON_NUMBER_EDITOR(object);
938 hildon_number_editor_set_value(editor, g_value_get_int(value));
941 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
947 hildon_number_editor_get_property(GObject * object,
948 guint prop_id, GValue * value, GParamSpec * pspec)
950 HildonNumberEditor *editor;
952 editor = HILDON_NUMBER_EDITOR(object);
956 g_value_set_int(value, hildon_number_editor_get_value(editor));
959 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);