2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
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
11 * the License, or (at your option) any later version.
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 * <title>HildonNumberEditor example</title>
36 * number_editor = hildon_number_editor_new (-250, 500);
37 * hildon_number_editor_set_range (number_editor, 0, 100);
46 #include "hildon-number-editor.h"
47 #include <gdk/gdkkeysyms.h>
52 #include "hildon-marshalers.h"
53 #include "hildon-private.h"
54 #include "hildon-defines.h"
55 #include "hildon-enum-types.h"
56 #include "hildon-banner.h"
58 #include "hildon-number-editor-private.h"
60 #define _(String) dgettext("hildon-libs", String)
62 /*Pixel spec defines*/
63 #define NUMBER_EDITOR_HEIGHT 30
65 /* Size of plus and minus buttons */
66 #define BUTTON_HEIGHT 30
68 #define BUTTON_WIDTH 30
71 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
74 hildon_number_editor_init (HildonNumberEditor *editor);
77 hildon_number_editor_entry_focusout (GtkWidget *widget,
82 hildon_number_editor_entry_changed (GtkWidget *widget,
86 hildon_number_editor_size_request (GtkWidget *widget,
87 GtkRequisition *requisition);
90 set_widget_allocation (GtkWidget *widget,
92 const GtkAllocation *allocation);
95 hildon_number_editor_size_allocate (GtkWidget *widget,
96 GtkAllocation *allocation);
99 hildon_number_editor_entry_keypress (GtkWidget *widget,
104 hildon_number_editor_button_pressed (GtkWidget *widget,
105 GdkEventButton *event,
109 hildon_number_editor_entry_button_released (GtkWidget *widget,
110 GdkEventButton *event,
113 hildon_number_editor_button_released (GtkWidget *widget,
115 HildonNumberEditor *editor);
117 do_mouse_timeout (HildonNumberEditor *editor);
120 change_numbers (HildonNumberEditor *editor,
124 hildon_number_editor_forall (GtkContainer *container,
125 gboolean include_internals,
126 GtkCallback callback,
127 gpointer callback_data);
130 hildon_number_editor_destroy (GtkObject *self);
133 hildon_number_editor_start_timer (HildonNumberEditor *editor);
136 hildon_number_editor_finalize (GObject *self);
139 hildon_number_editor_range_error (HildonNumberEditor *editor,
140 HildonNumberEditorErrorType type);
143 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
146 hildon_number_editor_validate_value (HildonNumberEditor *editor,
147 gboolean allow_intermediate);
150 hildon_number_editor_set_property (GObject * object,
152 const GValue * value,
156 hildon_number_editor_get_property (GObject *object,
172 static GtkContainerClass* parent_class;
174 static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
177 * hildon_number_editor_get_type:
179 * Returns GType for HildonNumberEditor.
181 * Returns: HildonNumberEditor type
184 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_private_composite_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;
236 * HildonNumberEditor:value:
238 * The current value of the number editor.
240 g_object_class_install_property (gobject_class, PROP_VALUE,
241 g_param_spec_int ("value",
243 "The current value of number editor",
246 0, G_PARAM_READWRITE));
248 HildonNumberEditor_signal[RANGE_ERROR] =
249 g_signal_new ("range_error", HILDON_TYPE_NUMBER_EDITOR,
250 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
251 (HildonNumberEditorClass, range_error),
252 g_signal_accumulator_true_handled, NULL,
253 _hildon_marshal_BOOLEAN__ENUM,
254 G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
258 hildon_number_editor_forall (GtkContainer *container,
259 gboolean include_internals,
260 GtkCallback callback,
261 gpointer callback_data)
263 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (container);
265 g_assert (callback != NULL);
268 if (! include_internals)
271 /* Enumerate child widgets */
272 (*callback) (priv->minus, callback_data);
273 (*callback) (priv->num_entry, callback_data);
274 (*callback) (priv->plus, callback_data);
278 hildon_number_editor_destroy (GtkObject *self)
280 HildonNumberEditorPrivate *priv;
282 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
285 /* Free child widgets */
288 gtk_widget_unparent (priv->minus);
293 gtk_widget_unparent (priv->num_entry);
294 priv->num_entry = NULL;
298 gtk_widget_unparent (priv->plus);
302 if (GTK_OBJECT_CLASS (parent_class)->destroy)
303 GTK_OBJECT_CLASS (parent_class)->destroy(self);
307 hildon_number_editor_stop_repeat_timer (HildonNumberEditorPrivate *priv)
309 g_assert (priv != NULL);
311 if (priv->button_event_id)
313 g_source_remove (priv->button_event_id);
314 priv->button_event_id = 0;
319 hildon_number_editor_finalize (GObject *self)
321 HildonNumberEditorPrivate *priv;
323 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
327 hildon_number_editor_stop_repeat_timer (priv);
329 if (priv->select_all_idle_id)
330 g_source_remove (priv->select_all_idle_id);
332 /* Call parent class finalize, if have one */
333 if (G_OBJECT_CLASS (parent_class)->finalize)
334 G_OBJECT_CLASS (parent_class)->finalize(self);
338 hildon_number_editor_init (HildonNumberEditor *editor)
340 HildonNumberEditorPrivate *priv;
342 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
345 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (editor), GTK_NO_WINDOW);
347 /* Create child widgets */
348 priv->num_entry = gtk_entry_new ();
349 priv->minus = gtk_button_new ();
350 priv->plus = gtk_button_new ();
352 gtk_widget_set_name (priv->minus, "ne-minus-button");
353 gtk_widget_set_name (priv->plus, "ne-plus-button" );
354 gtk_widget_set_size_request (priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT);
355 gtk_widget_set_size_request (priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT);
356 gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
358 GTK_WIDGET_UNSET_FLAGS (priv->minus, GTK_CAN_FOCUS);
359 GTK_WIDGET_UNSET_FLAGS (priv->plus, GTK_CAN_FOCUS);
361 priv->button_event_id = 0;
362 priv->select_all_idle_id = 0;
364 gtk_widget_set_parent (priv->minus, GTK_WIDGET (editor));
365 gtk_widget_set_parent (priv->num_entry, GTK_WIDGET (editor));
366 gtk_widget_set_parent (priv->plus, GTK_WIDGET (editor));
368 /* Connect child widget signals */
369 g_signal_connect (GTK_OBJECT (priv->num_entry), "changed",
370 G_CALLBACK (hildon_number_editor_entry_changed),
373 g_signal_connect (GTK_OBJECT (priv->num_entry), "focus-out-event",
374 G_CALLBACK (hildon_number_editor_entry_focusout),
377 g_signal_connect (GTK_OBJECT (priv->num_entry), "key-press-event",
378 G_CALLBACK (hildon_number_editor_entry_keypress),
381 g_signal_connect (GTK_OBJECT (priv->num_entry), "button-release-event",
382 G_CALLBACK (hildon_number_editor_entry_button_released),
385 g_signal_connect (GTK_OBJECT (priv->minus), "button-press-event",
386 G_CALLBACK (hildon_number_editor_button_pressed),
389 g_signal_connect (GTK_OBJECT (priv->plus), "button-press-event",
390 G_CALLBACK (hildon_number_editor_button_pressed),
393 g_signal_connect (GTK_OBJECT (priv->minus), "button-release-event",
394 G_CALLBACK (hildon_number_editor_button_released),
397 g_signal_connect (GTK_OBJECT (priv->plus), "button-release-event",
398 G_CALLBACK (hildon_number_editor_button_released),
401 g_signal_connect (GTK_OBJECT (priv->minus), "leave-notify-event",
402 G_CALLBACK(hildon_number_editor_button_released),
405 g_signal_connect (GTK_OBJECT (priv->plus), "leave-notify-event",
406 G_CALLBACK (hildon_number_editor_button_released),
410 g_object_set (G_OBJECT (priv->num_entry),
411 "hildon-input-mode", HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
414 gtk_widget_show (priv->num_entry);
415 gtk_widget_show (priv->minus);
416 gtk_widget_show (priv->plus);
418 hildon_number_editor_set_range (editor, G_MININT, G_MAXINT);
422 hildon_number_editor_entry_button_released (GtkWidget *widget,
423 GdkEventButton *event,
426 gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
431 hildon_number_editor_button_released (GtkWidget *widget,
433 HildonNumberEditor *editor)
435 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
438 hildon_number_editor_stop_repeat_timer (priv);
442 /* Format given number to editor field, no checks performed, all signals
443 are sent normally. */
445 hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv,
448 /* FIXME: That looks REALLY bad */
451 /* Update text in entry to new value */
452 g_snprintf (buffer, sizeof (buffer), "%d", value);
453 gtk_entry_set_text (GTK_ENTRY (priv->num_entry), buffer);
457 hildon_number_editor_button_pressed (GtkWidget *widget,
458 GdkEventButton *event,
461 /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
462 /* Need to fetch current value from entry and increment or decrement
465 HildonNumberEditor *editor;
466 HildonNumberEditorPrivate *priv;
467 GtkSettings *settings;
470 g_assert (HILDON_IS_NUMBER_EDITOR (data));
472 editor = HILDON_NUMBER_EDITOR (data);
473 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
476 settings = gtk_settings_get_default ();
477 g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
479 /* Save type of button pressed */
480 if (GTK_BUTTON (widget) == GTK_BUTTON (priv->plus))
481 priv->button_type = 1;
483 priv->button_type = -1;
485 /* Start repetition timer */
486 if (! priv->button_event_id)
488 change_numbers (editor, priv->button_type);
489 priv->button_event_id = g_timeout_add (timeout,
490 (GSourceFunc) hildon_number_editor_start_timer,
498 hildon_number_editor_start_timer (HildonNumberEditor *editor)
500 HildonNumberEditorPrivate *priv;
501 GtkSettings *settings;
504 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
505 settings = gtk_settings_get_default ();
506 g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
509 priv->button_event_id = g_timeout_add (timeout,
510 (GSourceFunc) do_mouse_timeout,
517 do_mouse_timeout (HildonNumberEditor *editor)
519 HildonNumberEditorPrivate *priv;
520 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
522 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
525 GDK_THREADS_ENTER ();
527 /* Update value based on button held */
528 change_numbers (editor, priv->button_type);
530 GDK_THREADS_LEAVE ();
535 /* Changes the current number value by the amount of update
536 and verifies the result. */
538 change_numbers (HildonNumberEditor *editor,
541 HildonNumberEditorPrivate *priv;
544 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
546 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
549 current_value = hildon_number_editor_get_value (editor);
551 /* We need to rerun validation by hand, since validation
552 done in "changed" callback allows intermediate values */
553 hildon_number_editor_real_set_value (priv, current_value + update);
554 hildon_number_editor_validate_value (editor, FALSE);
555 g_object_notify (G_OBJECT (editor), "value");
559 add_select_all_idle (HildonNumberEditorPrivate *priv)
563 if (! priv->select_all_idle_id)
565 priv->select_all_idle_id =
566 g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
571 hildon_number_editor_validate_value (HildonNumberEditor *editor,
572 gboolean allow_intermediate)
574 HildonNumberEditorPrivate *priv;
575 gint error_code, fixup_value;
581 g_assert (HILDON_IS_NUMBER_EDITOR(editor));
583 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
586 text = gtk_entry_get_text (GTK_ENTRY (priv->num_entry));
588 fixup_value = priv->default_val;
592 /* Try to convert entry text to number */
593 value = strtol (text, &tail, 10);
595 /* Check if conversion succeeded */
598 /* Check if value is in allowed range. This is tricky in those
599 cases when user is editing a value.
600 For example: Range = [100, 500] and user have just inputted "4".
601 This should not lead into error message. Otherwise value is
602 resetted back to "100" and next "4" press will reset it back
604 if (allow_intermediate)
606 /* We now have the following error cases:
607 * If inputted value as above maximum and
608 maximum is either positive or then maximum
609 negative and value is positive.
610 * If inputted value is below minimum and minimum
611 is negative or minumum positive and value
613 In all other cases situation can be fixed just by
614 adding new numbers to the string.
616 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
618 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
619 fixup_value = priv->end;
621 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
623 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
624 fixup_value = priv->start;
629 if (value > priv->end) {
630 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
631 fixup_value = priv->end;
633 else if (value < priv->start) {
634 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
635 fixup_value = priv->start;
639 /* The only valid case when conversion can fail is when we
640 have plain '-', intermediate forms are allowed AND
641 minimum bound is negative */
642 else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0)
643 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
645 else if (! allow_intermediate)
646 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
648 if (error_code != -1)
650 /* If entry is empty and intermediate forms are nor allowed,
652 /* Change to default value */
653 hildon_number_editor_set_value (editor, fixup_value);
654 g_signal_emit (editor, HildonNumberEditor_signal[RANGE_ERROR], 0, error_code, &r);
655 add_select_all_idle (priv);
660 hildon_number_editor_entry_changed (GtkWidget *widget,
663 g_assert (HILDON_IS_NUMBER_EDITOR (data));
664 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR (data), TRUE);
665 g_object_notify (G_OBJECT (data), "value");
669 hildon_number_editor_size_request (GtkWidget *widget,
670 GtkRequisition *requisition)
672 HildonNumberEditor *editor;
673 HildonNumberEditorPrivate *priv;
676 editor = HILDON_NUMBER_EDITOR (widget);
677 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
680 /* Requested size is size of all child widgets plus border space */
681 gtk_widget_size_request (priv->minus, &req);
682 requisition->width = req.width;
684 gtk_widget_size_request (priv->num_entry, &req);
685 requisition->width += req.width;
687 gtk_widget_size_request (priv->plus, &req);
688 requisition->width += req.width;
690 requisition->width += HILDON_MARGIN_DEFAULT * 2;
692 /* FIXME: XXX Height is fixed */
693 requisition->height = NUMBER_EDITOR_HEIGHT;
696 /* Update alloc->width so widget fits, update alloc->x to point to free space */
698 set_widget_allocation (GtkWidget *widget,
699 GtkAllocation *alloc,
700 const GtkAllocation *allocation)
702 GtkRequisition child_requisition;
704 gtk_widget_get_child_requisition (widget, &child_requisition);
706 /* Fit to widget width */
707 if (allocation->width + allocation->x > alloc->x + child_requisition.width)
708 alloc->width = child_requisition.width;
711 alloc->width = allocation->width - (alloc->x - allocation->x);
712 if (alloc->width < 0)
716 gtk_widget_size_allocate (widget, alloc);
717 /* Update x position */
718 alloc->x += alloc->width;
722 hildon_number_editor_size_allocate (GtkWidget *widget,
723 GtkAllocation *allocation)
725 HildonNumberEditor *editor;
726 HildonNumberEditorPrivate *priv;
729 editor = HILDON_NUMBER_EDITOR (widget);
730 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
733 widget->allocation = *allocation;
735 /* Add upper border */
736 alloc.y = widget->allocation.y + widget->style->ythickness;
739 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
741 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
742 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
745 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
747 if (alloc.height < 0)
750 /* Add left border */
751 alloc.x = allocation->x + widget->style->xthickness;
753 /* Allocate positions for widgets (left-to-right) */
754 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
755 alloc.x += HILDON_MARGIN_DEFAULT;
757 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
758 alloc.x += HILDON_MARGIN_DEFAULT;
760 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
764 hildon_number_editor_entry_focusout (GtkWidget *widget,
765 GdkEventFocus *event,
768 g_assert (HILDON_IS_NUMBER_EDITOR(data));
770 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR(data), FALSE);
775 hildon_number_editor_entry_keypress (GtkWidget *widget,
779 GtkEditable *editable;
782 g_assert (HILDON_IS_NUMBER_EDITOR (data));
784 editable = GTK_EDITABLE (widget);
785 cursor_pos = gtk_editable_get_position (editable);
787 switch (event->keyval)
790 /* If the cursor is on the left, try to decrement */
791 if (cursor_pos == 0) {
792 change_numbers (HILDON_NUMBER_EDITOR (data), -1);
798 /* If the cursor is on the right, try to increment */
799 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (widget)), -1))
801 change_numbers (HILDON_NUMBER_EDITOR (data), 1);
802 gtk_editable_set_position(editable, cursor_pos);
815 hildon_number_editor_range_error (HildonNumberEditor *editor,
816 HildonNumberEditorErrorType type)
820 gchar *err_msg = NULL;
821 HildonNumberEditorPrivate *priv;
823 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
829 /* Construct error message */
832 case HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED:
833 err_msg = g_strdup_printf (_("ckct_ib_maximum_value"), max, max);
836 case HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED:
837 err_msg = g_strdup_printf (_("ckct_ib_minimum_value"), min, min);
840 case HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE:
842 g_strdup_printf (_("ckct_ib_set_a_value_within_range"), min, max);
846 /* Infoprint error */
849 hildon_banner_show_information (GTK_WIDGET (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(editor),
850 GTK_TYPE_WINDOW))), NULL, err_msg);
858 * hildon_number_editor_new:
859 * @min: minimum accepted value
860 * @max: maximum accepted value
862 * Creates new number editor
864 * Returns: a new #HildonNumberEditor widget
867 hildon_number_editor_new (gint min,
870 HildonNumberEditor *editor = g_object_new (HILDON_TYPE_NUMBER_EDITOR, NULL);
872 /* Set user inputted range to editor */
873 hildon_number_editor_set_range (editor, min, max);
875 return GTK_WIDGET (editor);
879 * hildon_number_editor_set_range:
880 * @editor: a #HildonNumberEditor widget
881 * @min: minimum accepted value
882 * @max: maximum accepted value
884 * Sets accepted number range for editor
887 hildon_number_editor_set_range (HildonNumberEditor *editor,
891 HildonNumberEditorPrivate *priv;
892 gchar buffer_min[32], buffer_max[32];
895 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
897 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
900 /* Set preferences */
901 priv->start = MIN (min, max);
902 priv->end = MAX (min, max);
904 /* Find maximum allowed length of value */
905 g_snprintf (buffer_min, sizeof (buffer_min), "%d", min);
906 g_snprintf (buffer_max, sizeof (buffer_max), "%d", max);
907 a = strlen (buffer_min);
908 b = strlen (buffer_max);
910 /* Set maximum size of entry */
911 gtk_entry_set_width_chars (GTK_ENTRY (priv->num_entry), MAX (a, b));
912 hildon_number_editor_set_value (editor, priv->start);
916 * hildon_number_editor_get_value:
917 * @editor: pointer to #HildonNumberEditor
919 * Returns: current NumberEditor value
922 hildon_number_editor_get_value (HildonNumberEditor *editor)
924 HildonNumberEditorPrivate *priv;
926 g_return_val_if_fail (HILDON_IS_NUMBER_EDITOR (editor), 0);
928 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
931 return atoi (gtk_entry_get_text (GTK_ENTRY (priv->num_entry)));
935 * hildon_number_editor_set_value:
936 * @editor: pointer to #HildonNumberEditor
937 * @value: numeric value for number editor
939 * Sets numeric value for number editor
942 hildon_number_editor_set_value (HildonNumberEditor *editor,
945 HildonNumberEditorPrivate *priv;
947 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
949 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
952 g_return_if_fail (value <= priv->end);
953 g_return_if_fail (value >= priv->start);
955 priv->default_val = value;
956 hildon_number_editor_real_set_value (priv, value);
957 g_object_notify (G_OBJECT(editor), "value");
960 /* When calling gtk_entry_set_text, the entry widget does things that can
961 * cause the whole widget to redraw. This redrawing is delayed and if any
962 * selections are made right after calling the gtk_entry_set_text the
963 * setting of the selection might seem to have no effect.
965 * If the selection is delayed with a lower priority than the redrawing,
966 * the selection should stick. Calling this function with g_idle_add should
970 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
972 GDK_THREADS_ENTER ();
973 gtk_editable_select_region (GTK_EDITABLE (priv->num_entry), 0, -1);
974 priv->select_all_idle_id = 0;
975 GDK_THREADS_LEAVE ();
980 hildon_number_editor_set_property (GObject *object,
985 HildonNumberEditor *editor;
987 editor = HILDON_NUMBER_EDITOR (object);
992 hildon_number_editor_set_value (editor, g_value_get_int (value));
996 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1002 hildon_number_editor_get_property (GObject *object,
1007 HildonNumberEditor *editor;
1009 editor = HILDON_NUMBER_EDITOR (object);
1014 g_value_set_int(value, hildon_number_editor_get_value (editor));
1018 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);