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
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-input-mode-hint.h"
55 #include "hildon-defines.h"
56 #include "hildon-enum-types.h"
57 #include "hildon-banner.h"
59 #include "hildon-number-editor-private.h"
61 #define _(String) dgettext("hildon-libs", String)
63 /*Pixel spec defines*/
64 #define NUMBER_EDITOR_HEIGHT 30
66 /* Size of plus and minus buttons */
67 #define BUTTON_HEIGHT 30
69 #define BUTTON_WIDTH 30
72 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
75 hildon_number_editor_init (HildonNumberEditor *editor);
78 hildon_number_editor_entry_focusout (GtkWidget *widget,
83 hildon_number_editor_entry_changed (GtkWidget *widget,
87 hildon_number_editor_size_request (GtkWidget *widget,
88 GtkRequisition *requisition);
91 set_widget_allocation (GtkWidget *widget,
93 const GtkAllocation *allocation);
96 hildon_number_editor_size_allocate (GtkWidget *widget,
97 GtkAllocation *allocation);
100 hildon_number_editor_entry_keypress (GtkWidget *widget,
105 hildon_number_editor_button_pressed (GtkWidget *widget,
106 GdkEventButton *event,
110 hildon_number_editor_entry_button_released (GtkWidget *widget,
111 GdkEventButton *event,
114 hildon_number_editor_button_released (GtkWidget *widget,
116 HildonNumberEditor *editor);
118 do_mouse_timeout (HildonNumberEditor *editor);
121 change_numbers (HildonNumberEditor *editor,
125 hildon_number_editor_forall (GtkContainer *container,
126 gboolean include_internals,
127 GtkCallback callback,
128 gpointer callback_data);
131 hildon_number_editor_destroy (GtkObject *self);
134 hildon_number_editor_start_timer (HildonNumberEditor *editor);
137 hildon_number_editor_finalize (GObject *self);
140 hildon_number_editor_range_error (HildonNumberEditor *editor,
141 HildonNumberEditorErrorType type);
144 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
147 hildon_number_editor_validate_value (HildonNumberEditor *editor,
148 gboolean allow_intermediate);
151 hildon_number_editor_set_property (GObject * object,
153 const GValue * value,
157 hildon_number_editor_get_property (GObject *object,
173 static GtkContainerClass* parent_class;
175 static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
178 * hildon_number_editor_get_type:
180 * Returns GType for HildonNumberEditor.
182 * Returns: HildonNumberEditor type
185 hildon_number_editor_get_type (void)
187 static GType editor_type = 0;
191 static const GTypeInfo editor_info =
193 sizeof (HildonNumberEditorClass),
194 NULL, /* base_init */
195 NULL, /* base_finalize */
196 (GClassInitFunc) hildon_number_editor_class_init,
197 NULL, /* class_finalize */
198 NULL, /* class_data */
199 sizeof (HildonNumberEditor),
201 (GInstanceInitFunc) hildon_number_editor_init,
203 editor_type = g_type_register_static (GTK_TYPE_CONTAINER,
204 "HildonNumberEditor",
211 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class)
213 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (editor_class);
214 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (editor_class);
215 GObjectClass *gobject_class = G_OBJECT_CLASS (editor_class);
217 g_type_class_add_private (editor_class,
218 sizeof (HildonNumberEditorPrivate));
220 parent_class = g_type_class_peek_parent (editor_class);
222 widget_class->size_request = hildon_number_editor_size_request;
223 widget_class->size_allocate = hildon_number_editor_size_allocate;
224 widget_class->focus = hildon_private_composite_focus;
226 editor_class->range_error = hildon_number_editor_range_error;
228 /* Because we derived our widget from GtkContainer, we should override
230 container_class->forall = hildon_number_editor_forall;
231 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
232 gobject_class->finalize = hildon_number_editor_finalize;
233 gobject_class->set_property = hildon_number_editor_set_property;
234 gobject_class->get_property = hildon_number_editor_get_property;
237 * HildonNumberEditor:value:
239 * The current value of the number editor.
241 g_object_class_install_property (gobject_class, PROP_VALUE,
242 g_param_spec_int ("value",
244 "The current value of number editor",
247 0, G_PARAM_READWRITE));
249 HildonNumberEditor_signal[RANGE_ERROR] =
250 g_signal_new ("range_error", HILDON_TYPE_NUMBER_EDITOR,
251 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
252 (HildonNumberEditorClass, range_error),
253 g_signal_accumulator_true_handled, NULL,
254 _hildon_marshal_BOOLEAN__ENUM,
255 G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
259 hildon_number_editor_forall (GtkContainer *container,
260 gboolean include_internals,
261 GtkCallback callback,
262 gpointer callback_data)
264 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (container);
266 g_assert (callback != NULL);
269 if (! include_internals)
272 /* Enumerate child widgets */
273 (*callback) (priv->minus, callback_data);
274 (*callback) (priv->num_entry, callback_data);
275 (*callback) (priv->plus, callback_data);
279 hildon_number_editor_destroy (GtkObject *self)
281 HildonNumberEditorPrivate *priv;
283 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
286 /* Free child widgets */
289 gtk_widget_unparent (priv->minus);
294 gtk_widget_unparent (priv->num_entry);
295 priv->num_entry = NULL;
299 gtk_widget_unparent (priv->plus);
303 if (GTK_OBJECT_CLASS (parent_class)->destroy)
304 GTK_OBJECT_CLASS (parent_class)->destroy(self);
308 hildon_number_editor_stop_repeat_timer (HildonNumberEditorPrivate *priv)
310 g_assert (priv != NULL);
312 if (priv->button_event_id)
314 g_source_remove (priv->button_event_id);
315 priv->button_event_id = 0;
320 hildon_number_editor_finalize (GObject *self)
322 HildonNumberEditorPrivate *priv;
324 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
328 hildon_number_editor_stop_repeat_timer (priv);
330 if (priv->select_all_idle_id)
331 g_source_remove (priv->select_all_idle_id);
333 /* Call parent class finalize, if have one */
334 if (G_OBJECT_CLASS (parent_class)->finalize)
335 G_OBJECT_CLASS (parent_class)->finalize(self);
339 hildon_number_editor_init (HildonNumberEditor *editor)
341 HildonNumberEditorPrivate *priv;
343 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
346 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (editor), GTK_NO_WINDOW);
348 /* Create child widgets */
349 priv->num_entry = gtk_entry_new ();
350 priv->minus = gtk_button_new ();
351 priv->plus = gtk_button_new ();
353 gtk_widget_set_name (priv->minus, "ne-minus-button");
354 gtk_widget_set_name (priv->plus, "ne-plus-button" );
355 gtk_widget_set_size_request (priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT);
356 gtk_widget_set_size_request (priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT);
357 gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
359 GTK_WIDGET_UNSET_FLAGS (priv->minus, GTK_CAN_FOCUS);
360 GTK_WIDGET_UNSET_FLAGS (priv->plus, GTK_CAN_FOCUS);
362 priv->button_event_id = 0;
363 priv->select_all_idle_id = 0;
365 gtk_widget_set_parent (priv->minus, GTK_WIDGET (editor));
366 gtk_widget_set_parent (priv->num_entry, GTK_WIDGET (editor));
367 gtk_widget_set_parent (priv->plus, GTK_WIDGET (editor));
369 /* Connect child widget signals */
370 g_signal_connect (GTK_OBJECT (priv->num_entry), "changed",
371 G_CALLBACK (hildon_number_editor_entry_changed),
374 g_signal_connect (GTK_OBJECT (priv->num_entry), "focus-out-event",
375 G_CALLBACK (hildon_number_editor_entry_focusout),
378 g_signal_connect (GTK_OBJECT (priv->num_entry), "key-press-event",
379 G_CALLBACK (hildon_number_editor_entry_keypress),
382 g_signal_connect (GTK_OBJECT (priv->num_entry), "button-release-event",
383 G_CALLBACK (hildon_number_editor_entry_button_released),
386 g_signal_connect (GTK_OBJECT (priv->minus), "button-press-event",
387 G_CALLBACK (hildon_number_editor_button_pressed),
390 g_signal_connect (GTK_OBJECT (priv->plus), "button-press-event",
391 G_CALLBACK (hildon_number_editor_button_pressed),
394 g_signal_connect (GTK_OBJECT (priv->minus), "button-release-event",
395 G_CALLBACK (hildon_number_editor_button_released),
398 g_signal_connect (GTK_OBJECT (priv->plus), "button-release-event",
399 G_CALLBACK (hildon_number_editor_button_released),
402 g_signal_connect (GTK_OBJECT (priv->minus), "leave-notify-event",
403 G_CALLBACK(hildon_number_editor_button_released),
406 g_signal_connect (GTK_OBJECT (priv->plus), "leave-notify-event",
407 G_CALLBACK (hildon_number_editor_button_released),
410 g_object_set (G_OBJECT (priv->num_entry),
411 "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
413 gtk_widget_show (priv->num_entry);
414 gtk_widget_show (priv->minus);
415 gtk_widget_show (priv->plus);
417 hildon_number_editor_set_range (editor, G_MININT, G_MAXINT);
421 hildon_number_editor_entry_button_released (GtkWidget *widget,
422 GdkEventButton *event,
425 gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
430 hildon_number_editor_button_released (GtkWidget *widget,
432 HildonNumberEditor *editor)
434 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
437 hildon_number_editor_stop_repeat_timer (priv);
441 /* Format given number to editor field, no checks performed, all signals
442 are sent normally. */
444 hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv,
447 /* FIXME: That looks REALLY bad */
450 /* Update text in entry to new value */
451 g_snprintf (buffer, sizeof (buffer), "%d", value);
452 gtk_entry_set_text (GTK_ENTRY (priv->num_entry), buffer);
456 hildon_number_editor_button_pressed (GtkWidget *widget,
457 GdkEventButton *event,
460 /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
461 /* Need to fetch current value from entry and increment or decrement
464 HildonNumberEditor *editor;
465 HildonNumberEditorPrivate *priv;
466 GtkSettings *settings;
469 g_assert (HILDON_IS_NUMBER_EDITOR (data));
471 editor = HILDON_NUMBER_EDITOR (data);
472 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
475 settings = gtk_settings_get_default ();
476 g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
478 /* Save type of button pressed */
479 if (GTK_BUTTON (widget) == GTK_BUTTON (priv->plus))
480 priv->button_type = 1;
482 priv->button_type = -1;
484 /* Start repetition timer */
485 if (! priv->button_event_id)
487 change_numbers (editor, priv->button_type);
488 priv->button_event_id = g_timeout_add (timeout,
489 (GSourceFunc) hildon_number_editor_start_timer,
497 hildon_number_editor_start_timer (HildonNumberEditor *editor)
499 HildonNumberEditorPrivate *priv;
500 GtkSettings *settings;
503 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
504 settings = gtk_settings_get_default ();
505 g_object_get (settings, "gtk-timeout-update", &timeout, NULL);
507 priv->button_event_id = g_timeout_add (timeout,
508 (GSourceFunc) do_mouse_timeout,
515 do_mouse_timeout (HildonNumberEditor *editor)
517 HildonNumberEditorPrivate *priv;
518 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
520 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
523 GDK_THREADS_ENTER ();
525 /* Update value based on button held */
526 change_numbers (editor, priv->button_type);
528 GDK_THREADS_LEAVE ();
533 /* Changes the current number value by the amount of update
534 and verifies the result. */
536 change_numbers (HildonNumberEditor *editor,
539 HildonNumberEditorPrivate *priv;
542 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
544 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
547 current_value = hildon_number_editor_get_value (editor);
549 /* We need to rerun validation by hand, since validation
550 done in "changed" callback allows intermediate values */
551 hildon_number_editor_real_set_value (priv, current_value + update);
552 hildon_number_editor_validate_value (editor, FALSE);
553 g_object_notify (G_OBJECT (editor), "value");
557 add_select_all_idle (HildonNumberEditorPrivate *priv)
561 if (! priv->select_all_idle_id)
563 priv->select_all_idle_id =
564 g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
569 hildon_number_editor_validate_value (HildonNumberEditor *editor,
570 gboolean allow_intermediate)
572 HildonNumberEditorPrivate *priv;
573 gint error_code, fixup_value;
579 g_assert (HILDON_IS_NUMBER_EDITOR(editor));
581 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
584 text = gtk_entry_get_text (GTK_ENTRY (priv->num_entry));
586 fixup_value = priv->default_val;
590 /* Try to convert entry text to number */
591 value = strtol (text, &tail, 10);
593 /* Check if conversion succeeded */
596 /* Check if value is in allowed range. This is tricky in those
597 cases when user is editing a value.
598 For example: Range = [100, 500] and user have just inputted "4".
599 This should not lead into error message. Otherwise value is
600 resetted back to "100" and next "4" press will reset it back
602 if (allow_intermediate)
604 /* We now have the following error cases:
605 * If inputted value as above maximum and
606 maximum is either positive or then maximum
607 negative and value is positive.
608 * If inputted value is below minimum and minimum
609 is negative or minumum positive and value
611 In all other cases situation can be fixed just by
612 adding new numbers to the string.
614 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
616 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
617 fixup_value = priv->end;
619 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
621 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
622 fixup_value = priv->start;
627 if (value > priv->end) {
628 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
629 fixup_value = priv->end;
631 else if (value < priv->start) {
632 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
633 fixup_value = priv->start;
637 /* The only valid case when conversion can fail is when we
638 have plain '-', intermediate forms are allowed AND
639 minimum bound is negative */
640 else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0)
641 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
643 else if (! allow_intermediate)
644 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
646 if (error_code != -1)
648 /* If entry is empty and intermediate forms are nor allowed,
650 /* Change to default value */
651 hildon_number_editor_set_value (editor, fixup_value);
652 g_signal_emit (editor, HildonNumberEditor_signal[RANGE_ERROR], 0, error_code, &r);
653 add_select_all_idle (priv);
658 hildon_number_editor_entry_changed (GtkWidget *widget,
661 g_assert (HILDON_IS_NUMBER_EDITOR (data));
662 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR (data), TRUE);
663 g_object_notify (G_OBJECT (data), "value");
667 hildon_number_editor_size_request (GtkWidget *widget,
668 GtkRequisition *requisition)
670 HildonNumberEditor *editor;
671 HildonNumberEditorPrivate *priv;
674 editor = HILDON_NUMBER_EDITOR (widget);
675 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
678 /* Requested size is size of all child widgets plus border space */
679 gtk_widget_size_request (priv->minus, &req);
680 requisition->width = req.width;
682 gtk_widget_size_request (priv->num_entry, &req);
683 requisition->width += req.width;
685 gtk_widget_size_request (priv->plus, &req);
686 requisition->width += req.width;
688 requisition->width += HILDON_MARGIN_DEFAULT * 2;
690 /* FIXME: XXX Height is fixed */
691 requisition->height = NUMBER_EDITOR_HEIGHT;
694 /* Update alloc->width so widget fits, update alloc->x to point to free space */
696 set_widget_allocation (GtkWidget *widget,
697 GtkAllocation *alloc,
698 const GtkAllocation *allocation)
700 GtkRequisition child_requisition;
702 gtk_widget_get_child_requisition (widget, &child_requisition);
704 /* Fit to widget width */
705 if (allocation->width + allocation->x > alloc->x + child_requisition.width)
706 alloc->width = child_requisition.width;
709 alloc->width = allocation->width - (alloc->x - allocation->x);
710 if (alloc->width < 0)
714 gtk_widget_size_allocate (widget, alloc);
715 /* Update x position */
716 alloc->x += alloc->width;
720 hildon_number_editor_size_allocate (GtkWidget *widget,
721 GtkAllocation *allocation)
723 HildonNumberEditor *editor;
724 HildonNumberEditorPrivate *priv;
727 editor = HILDON_NUMBER_EDITOR (widget);
728 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
731 widget->allocation = *allocation;
733 /* Add upper border */
734 alloc.y = widget->allocation.y + widget->style->ythickness;
737 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
739 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
740 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
743 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
745 if (alloc.height < 0)
748 /* Add left border */
749 alloc.x = allocation->x + widget->style->xthickness;
751 /* Allocate positions for widgets (left-to-right) */
752 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
753 alloc.x += HILDON_MARGIN_DEFAULT;
755 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
756 alloc.x += HILDON_MARGIN_DEFAULT;
758 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
762 hildon_number_editor_entry_focusout (GtkWidget *widget,
763 GdkEventFocus *event,
766 g_assert (HILDON_IS_NUMBER_EDITOR(data));
768 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR(data), FALSE);
773 hildon_number_editor_entry_keypress (GtkWidget *widget,
777 GtkEditable *editable;
780 g_assert (HILDON_IS_NUMBER_EDITOR (data));
782 editable = GTK_EDITABLE (widget);
783 cursor_pos = gtk_editable_get_position (editable);
785 switch (event->keyval)
788 /* If the cursor is on the left, try to decrement */
789 if (cursor_pos == 0) {
790 change_numbers (HILDON_NUMBER_EDITOR (data), -1);
796 /* If the cursor is on the right, try to increment */
797 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (widget)), -1))
799 change_numbers (HILDON_NUMBER_EDITOR (data), 1);
800 gtk_editable_set_position(editable, cursor_pos);
813 hildon_number_editor_range_error (HildonNumberEditor *editor,
814 HildonNumberEditorErrorType type)
818 gchar *err_msg = NULL;
819 HildonNumberEditorPrivate *priv;
821 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
827 /* Construct error message */
830 case HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED:
831 err_msg = g_strdup_printf (_("ckct_ib_maximum_value"), max, max);
834 case HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED:
835 err_msg = g_strdup_printf (_("ckct_ib_minimum_value"), min, min);
838 case HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE:
840 g_strdup_printf (_("ckct_ib_set_a_value_within_range"), min, max);
844 /* Infoprint error */
847 hildon_banner_show_information (GTK_WIDGET (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(editor),
848 GTK_TYPE_WINDOW))), NULL, err_msg);
856 * hildon_number_editor_new:
857 * @min: minimum accepted value
858 * @max: maximum accepted value
860 * Creates new number editor
862 * Returns: a new #HildonNumberEditor widget
865 hildon_number_editor_new (gint min,
868 HildonNumberEditor *editor = g_object_new (HILDON_TYPE_NUMBER_EDITOR, NULL);
870 /* Set user inputted range to editor */
871 hildon_number_editor_set_range (editor, min, max);
873 return GTK_WIDGET (editor);
877 * hildon_number_editor_set_range:
878 * @editor: a #HildonNumberEditor widget
879 * @min: minimum accepted value
880 * @max: maximum accepted value
882 * Sets accepted number range for editor
885 hildon_number_editor_set_range (HildonNumberEditor *editor,
889 HildonNumberEditorPrivate *priv;
890 gchar buffer_min[32], buffer_max[32];
893 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
895 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
898 /* Set preferences */
899 priv->start = MIN (min, max);
900 priv->end = MAX (min, max);
902 /* Find maximum allowed length of value */
903 g_snprintf (buffer_min, sizeof (buffer_min), "%d", min);
904 g_snprintf (buffer_max, sizeof (buffer_max), "%d", max);
905 a = strlen (buffer_min);
906 b = strlen (buffer_max);
908 /* Set maximum size of entry */
909 gtk_entry_set_width_chars (GTK_ENTRY (priv->num_entry), MAX (a, b));
910 hildon_number_editor_set_value (editor, priv->start);
914 * hildon_number_editor_get_value:
915 * @editor: pointer to #HildonNumberEditor
917 * Returns: current NumberEditor value
920 hildon_number_editor_get_value (HildonNumberEditor *editor)
922 HildonNumberEditorPrivate *priv;
924 g_return_val_if_fail (HILDON_IS_NUMBER_EDITOR (editor), 0);
926 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
929 return atoi (gtk_entry_get_text (GTK_ENTRY (priv->num_entry)));
933 * hildon_number_editor_set_value:
934 * @editor: pointer to #HildonNumberEditor
935 * @value: numeric value for number editor
937 * Sets numeric value for number editor
940 hildon_number_editor_set_value (HildonNumberEditor *editor,
943 HildonNumberEditorPrivate *priv;
945 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
947 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
950 g_return_if_fail (value <= priv->end);
951 g_return_if_fail (value >= priv->start);
953 priv->default_val = value;
954 hildon_number_editor_real_set_value (priv, value);
955 g_object_notify (G_OBJECT(editor), "value");
958 /* When calling gtk_entry_set_text, the entry widget does things that can
959 * cause the whole widget to redraw. This redrawing is delayed and if any
960 * selections are made right after calling the gtk_entry_set_text the
961 * setting of the selection might seem to have no effect.
963 * If the selection is delayed with a lower priority than the redrawing,
964 * the selection should stick. Calling this function with g_idle_add should
968 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
970 GDK_THREADS_ENTER ();
971 gtk_editable_select_region (GTK_EDITABLE (priv->num_entry), 0, -1);
972 priv->select_all_idle_id = 0;
973 GDK_THREADS_LEAVE ();
978 hildon_number_editor_set_property (GObject *object,
983 HildonNumberEditor *editor;
985 editor = HILDON_NUMBER_EDITOR (object);
990 hildon_number_editor_set_value (editor, g_value_get_int (value));
994 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1000 hildon_number_editor_get_property (GObject *object,
1005 HildonNumberEditor *editor;
1007 editor = HILDON_NUMBER_EDITOR (object);
1012 g_value_set_int(value, hildon_number_editor_get_value (editor));
1016 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);