2 * This file is a part of hildon
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Rodrigo Novo <rodrigo.novo@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.
35 * #HildonNumberEditor has been deprecated since Hildon 2.2
36 * See <link linkend="hildon-migrating-number-widgets">Migrating Number Widgets</link>
37 * section to know how to migrate this deprecated widget.
42 * <title>HildonNumberEditor example</title>
44 * number_editor = hildon_number_editor_new (-250, 500);
45 * hildon_number_editor_set_range (number_editor, 0, 100);
50 #undef HILDON_DISABLE_DEPRECATED
60 #include <gdk/gdkkeysyms.h>
62 #include "hildon-number-editor.h"
63 #include "hildon-marshalers.h"
64 #include "hildon-defines.h"
65 #include "hildon-enum-types.h"
66 #include "hildon-banner.h"
67 #include "hildon-number-editor-private.h"
68 #include "hildon-private.h"
70 #define _(String) dgettext("hildon-libs", String)
72 /*Pixel spec defines*/
73 #define NUMBER_EDITOR_HEIGHT 30
75 /* Size of plus and minus buttons */
76 #define BUTTON_HEIGHT 30
78 #define BUTTON_WIDTH 30
81 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
84 hildon_number_editor_init (HildonNumberEditor *editor);
87 hildon_number_editor_entry_focusout (GtkWidget *widget,
92 hildon_number_editor_entry_changed (GtkWidget *widget,
96 hildon_number_editor_size_request (GtkWidget *widget,
97 GtkRequisition *requisition);
100 set_widget_allocation (GtkWidget *widget,
101 GtkAllocation *alloc,
102 const GtkAllocation *allocation);
105 hildon_number_editor_size_allocate (GtkWidget *widget,
106 GtkAllocation *allocation);
109 hildon_number_editor_focus (GtkWidget *widget,
110 GtkDirectionType direction);
113 hildon_number_editor_entry_keypress (GtkWidget *widget,
118 hildon_number_editor_button_pressed (GtkWidget *widget,
119 GdkEventButton *event,
123 hildon_number_editor_entry_button_released (GtkWidget *widget,
124 GdkEventButton *event,
127 hildon_number_editor_button_released (GtkWidget *widget,
129 HildonNumberEditor *editor);
131 do_mouse_timeout (HildonNumberEditor *editor);
134 change_numbers (HildonNumberEditor *editor,
138 hildon_number_editor_forall (GtkContainer *container,
139 gboolean include_internals,
140 GtkCallback callback,
141 gpointer callback_data);
144 hildon_number_editor_destroy (GtkObject *self);
147 hildon_number_editor_start_timer (HildonNumberEditor *editor);
150 hildon_number_editor_finalize (GObject *self);
153 hildon_number_editor_range_error (HildonNumberEditor *editor,
154 HildonNumberEditorErrorType type);
157 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
160 hildon_number_editor_validate_value (HildonNumberEditor *editor,
161 gboolean allow_intermediate);
164 hildon_number_editor_set_property (GObject * object,
166 const GValue * value,
170 hildon_number_editor_get_property (GObject *object,
186 static GtkContainerClass* parent_class;
188 static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
191 * hildon_number_editor_get_type:
193 * Returns GType for HildonNumberEditor.
195 * Returns: HildonNumberEditor type
198 hildon_number_editor_get_type (void)
200 static GType editor_type = 0;
204 static const GTypeInfo editor_info =
206 sizeof (HildonNumberEditorClass),
207 NULL, /* base_init */
208 NULL, /* base_finalize */
209 (GClassInitFunc) hildon_number_editor_class_init,
210 NULL, /* class_finalize */
211 NULL, /* class_data */
212 sizeof (HildonNumberEditor),
214 (GInstanceInitFunc) hildon_number_editor_init,
216 editor_type = g_type_register_static (GTK_TYPE_CONTAINER,
217 "HildonNumberEditor",
224 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class)
226 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (editor_class);
227 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (editor_class);
228 GObjectClass *gobject_class = G_OBJECT_CLASS (editor_class);
230 g_type_class_add_private (editor_class,
231 sizeof (HildonNumberEditorPrivate));
233 parent_class = g_type_class_peek_parent (editor_class);
235 widget_class->size_request = hildon_number_editor_size_request;
236 widget_class->size_allocate = hildon_number_editor_size_allocate;
237 widget_class->focus = hildon_number_editor_focus;
239 editor_class->range_error = hildon_number_editor_range_error;
241 /* Because we derived our widget from GtkContainer, we should override
243 container_class->forall = hildon_number_editor_forall;
244 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
245 gobject_class->finalize = hildon_number_editor_finalize;
246 gobject_class->set_property = hildon_number_editor_set_property;
247 gobject_class->get_property = hildon_number_editor_get_property;
250 * HildonNumberEditor:value:
252 * The current value of the number editor.
254 g_object_class_install_property (gobject_class, PROP_VALUE,
255 g_param_spec_int ("value",
257 "The current value of number editor",
260 0, G_PARAM_READWRITE));
262 HildonNumberEditor_signal[RANGE_ERROR] =
263 g_signal_new ("range_error", HILDON_TYPE_NUMBER_EDITOR,
264 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
265 (HildonNumberEditorClass, range_error),
266 g_signal_accumulator_true_handled, NULL,
267 _hildon_marshal_BOOLEAN__ENUM,
268 G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
272 hildon_number_editor_forall (GtkContainer *container,
273 gboolean include_internals,
274 GtkCallback callback,
275 gpointer callback_data)
277 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (container);
279 g_assert (callback != NULL);
282 if (! include_internals)
285 /* Enumerate child widgets */
286 (*callback) (priv->minus, callback_data);
287 (*callback) (priv->num_entry, callback_data);
288 (*callback) (priv->plus, callback_data);
292 hildon_number_editor_destroy (GtkObject *self)
294 HildonNumberEditorPrivate *priv;
296 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
299 /* Free child widgets */
302 gtk_widget_unparent (priv->minus);
307 gtk_widget_unparent (priv->num_entry);
308 priv->num_entry = NULL;
312 gtk_widget_unparent (priv->plus);
316 if (GTK_OBJECT_CLASS (parent_class)->destroy)
317 GTK_OBJECT_CLASS (parent_class)->destroy(self);
321 hildon_number_editor_stop_repeat_timer (HildonNumberEditorPrivate *priv)
323 g_assert (priv != NULL);
325 if (priv->button_event_id)
327 g_source_remove (priv->button_event_id);
328 priv->button_event_id = 0;
333 hildon_number_editor_finalize (GObject *self)
335 HildonNumberEditorPrivate *priv;
337 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
341 hildon_number_editor_stop_repeat_timer (priv);
343 if (priv->select_all_idle_id)
344 g_source_remove (priv->select_all_idle_id);
346 /* Call parent class finalize, if have one */
347 if (G_OBJECT_CLASS (parent_class)->finalize)
348 G_OBJECT_CLASS (parent_class)->finalize(self);
352 hildon_number_editor_init (HildonNumberEditor *editor)
354 HildonNumberEditorPrivate *priv;
356 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
359 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (editor), GTK_NO_WINDOW);
361 /* Create child widgets */
362 priv->num_entry = gtk_entry_new ();
363 priv->minus = gtk_button_new ();
364 priv->plus = gtk_button_new ();
366 gtk_widget_set_name (priv->minus, "ne-minus-button");
367 gtk_widget_set_name (priv->plus, "ne-plus-button" );
368 gtk_widget_set_size_request (priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT);
369 gtk_widget_set_size_request (priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT);
370 gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
372 GTK_WIDGET_UNSET_FLAGS (priv->minus, GTK_CAN_FOCUS);
373 GTK_WIDGET_UNSET_FLAGS (priv->plus, GTK_CAN_FOCUS);
375 priv->button_event_id = 0;
376 priv->select_all_idle_id = 0;
378 gtk_widget_set_parent (priv->minus, GTK_WIDGET (editor));
379 gtk_widget_set_parent (priv->num_entry, GTK_WIDGET (editor));
380 gtk_widget_set_parent (priv->plus, GTK_WIDGET (editor));
382 /* Connect child widget signals */
383 g_signal_connect (GTK_OBJECT (priv->num_entry), "changed",
384 G_CALLBACK (hildon_number_editor_entry_changed),
387 g_signal_connect (GTK_OBJECT (priv->num_entry), "focus-out-event",
388 G_CALLBACK (hildon_number_editor_entry_focusout),
391 g_signal_connect (GTK_OBJECT (priv->num_entry), "key-press-event",
392 G_CALLBACK (hildon_number_editor_entry_keypress),
395 g_signal_connect (GTK_OBJECT (priv->num_entry), "button-release-event",
396 G_CALLBACK (hildon_number_editor_entry_button_released),
399 g_signal_connect (GTK_OBJECT (priv->minus), "button-press-event",
400 G_CALLBACK (hildon_number_editor_button_pressed),
403 g_signal_connect (GTK_OBJECT (priv->plus), "button-press-event",
404 G_CALLBACK (hildon_number_editor_button_pressed),
407 g_signal_connect (GTK_OBJECT (priv->minus), "button-release-event",
408 G_CALLBACK (hildon_number_editor_button_released),
411 g_signal_connect (GTK_OBJECT (priv->plus), "button-release-event",
412 G_CALLBACK (hildon_number_editor_button_released),
415 g_signal_connect (GTK_OBJECT (priv->minus), "leave-notify-event",
416 G_CALLBACK(hildon_number_editor_button_released),
419 g_signal_connect (GTK_OBJECT (priv->plus), "leave-notify-event",
420 G_CALLBACK (hildon_number_editor_button_released),
424 g_object_set (G_OBJECT (priv->num_entry),
425 "hildon-input-mode", HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
428 gtk_widget_show (priv->num_entry);
429 gtk_widget_show (priv->minus);
430 gtk_widget_show (priv->plus);
432 hildon_number_editor_set_range (editor, G_MININT, G_MAXINT);
436 hildon_number_editor_entry_button_released (GtkWidget *widget,
437 GdkEventButton *event,
440 gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
445 hildon_number_editor_button_released (GtkWidget *widget,
447 HildonNumberEditor *editor)
449 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
452 hildon_number_editor_stop_repeat_timer (priv);
456 /* Format given number to editor field, no checks performed, all signals
457 are sent normally. */
459 hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv,
464 /* Update text in entry to new value */
465 buffer = g_strdup_printf ("%d", value);
466 gtk_entry_set_text (GTK_ENTRY (priv->num_entry), buffer);
471 hildon_number_editor_button_pressed (GtkWidget *widget,
472 GdkEventButton *event,
475 /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
476 /* Need to fetch current value from entry and increment or decrement
479 HildonNumberEditor *editor;
480 HildonNumberEditorPrivate *priv;
481 GtkSettings *settings;
484 g_assert (HILDON_IS_NUMBER_EDITOR (data));
486 editor = HILDON_NUMBER_EDITOR (data);
487 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
490 settings = gtk_settings_get_default ();
491 g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
493 /* Save type of button pressed */
494 if (GTK_BUTTON (widget) == GTK_BUTTON (priv->plus))
495 priv->button_type = 1;
497 priv->button_type = -1;
499 /* Start repetition timer */
500 if (! priv->button_event_id)
502 change_numbers (editor, priv->button_type);
503 priv->button_event_id = gdk_threads_add_timeout (timeout,
504 (GSourceFunc) hildon_number_editor_start_timer,
512 hildon_number_editor_start_timer (HildonNumberEditor *editor)
514 HildonNumberEditorPrivate *priv;
515 GtkSettings *settings;
518 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
519 settings = gtk_settings_get_default ();
520 g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
523 priv->button_event_id = gdk_threads_add_timeout (timeout,
524 (GSourceFunc) do_mouse_timeout,
531 do_mouse_timeout (HildonNumberEditor *editor)
533 HildonNumberEditorPrivate *priv;
534 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
536 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
539 /* Update value based on button held */
540 change_numbers (editor, priv->button_type);
545 /* Changes the current number value by the amount of update
546 and verifies the result. */
548 change_numbers (HildonNumberEditor *editor,
551 HildonNumberEditorPrivate *priv;
554 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
556 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
559 current_value = hildon_number_editor_get_value (editor);
561 /* We need to rerun validation by hand, since validation
562 done in "changed" callback allows intermediate values */
563 hildon_number_editor_real_set_value (priv, current_value + update);
564 hildon_number_editor_validate_value (editor, FALSE);
565 g_object_notify (G_OBJECT (editor), "value");
569 add_select_all_idle (HildonNumberEditorPrivate *priv)
573 if (! priv->select_all_idle_id)
575 priv->select_all_idle_id =
576 gdk_threads_add_idle ((GSourceFunc) hildon_number_editor_select_all, priv);
581 hildon_number_editor_validate_value (HildonNumberEditor *editor,
582 gboolean allow_intermediate)
584 HildonNumberEditorPrivate *priv;
585 gint error_code, fixup_value;
591 g_assert (HILDON_IS_NUMBER_EDITOR(editor));
593 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
596 text = gtk_entry_get_text (GTK_ENTRY (priv->num_entry));
598 fixup_value = priv->default_val;
602 /* Try to convert entry text to number */
603 value = strtol (text, &tail, 10);
605 /* Check if conversion succeeded */
608 /* Check if value is in allowed range. This is tricky in those
609 cases when user is editing a value.
610 For example: Range = [100, 500] and user have just inputted "4".
611 This should not lead into error message. Otherwise value is
612 resetted back to "100" and next "4" press will reset it back
614 if (allow_intermediate)
616 /* We now have the following error cases:
617 * If inputted value as above maximum and
618 maximum is either positive or then maximum
619 negative and value is positive.
620 * If inputted value is below minimum and minimum
621 is negative or minumum positive and value
623 In all other cases situation can be fixed just by
624 adding new numbers to the string.
626 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
628 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
629 fixup_value = priv->end;
631 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
633 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
634 fixup_value = priv->start;
639 if (value > priv->end) {
640 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
641 fixup_value = priv->end;
643 else if (value < priv->start) {
644 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
645 fixup_value = priv->start;
649 /* The only valid case when conversion can fail is when we
650 have plain '-', intermediate forms are allowed AND
651 minimum bound is negative */
652 else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0)
653 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
655 else if (! allow_intermediate)
656 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
658 if (error_code != -1)
660 /* If entry is empty and intermediate forms are nor allowed,
662 /* Change to default value */
663 hildon_number_editor_set_value (editor, fixup_value);
664 g_signal_emit (editor, HildonNumberEditor_signal[RANGE_ERROR], 0, error_code, &r);
665 add_select_all_idle (priv);
670 hildon_number_editor_entry_changed (GtkWidget *widget,
673 g_assert (HILDON_IS_NUMBER_EDITOR (data));
674 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR (data), TRUE);
675 g_object_notify (G_OBJECT (data), "value");
679 hildon_number_editor_size_request (GtkWidget *widget,
680 GtkRequisition *requisition)
682 HildonNumberEditor *editor;
683 HildonNumberEditorPrivate *priv;
686 editor = HILDON_NUMBER_EDITOR (widget);
687 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
690 /* Requested size is size of all child widgets plus border space */
691 gtk_widget_size_request (priv->minus, &req);
692 requisition->width = req.width;
694 gtk_widget_size_request (priv->num_entry, &req);
695 requisition->width += req.width;
697 gtk_widget_size_request (priv->plus, &req);
698 requisition->width += req.width;
700 requisition->width += HILDON_MARGIN_DEFAULT * 2;
702 /* FIXME: XXX Height is fixed */
703 requisition->height = NUMBER_EDITOR_HEIGHT;
706 /* Update alloc->width so widget fits, update alloc->x to point to free space */
708 set_widget_allocation (GtkWidget *widget,
709 GtkAllocation *alloc,
710 const GtkAllocation *allocation)
712 GtkRequisition child_requisition;
714 gtk_widget_get_child_requisition (widget, &child_requisition);
716 /* Fit to widget width */
717 if (allocation->width + allocation->x > alloc->x + child_requisition.width)
718 alloc->width = child_requisition.width;
721 alloc->width = allocation->width - (alloc->x - allocation->x);
722 if (alloc->width < 0)
726 gtk_widget_size_allocate (widget, alloc);
727 /* Update x position */
728 alloc->x += alloc->width;
732 hildon_number_editor_size_allocate (GtkWidget *widget,
733 GtkAllocation *allocation)
735 HildonNumberEditor *editor;
736 HildonNumberEditorPrivate *priv;
739 editor = HILDON_NUMBER_EDITOR (widget);
740 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
743 widget->allocation = *allocation;
745 /* Add upper border */
746 alloc.y = widget->allocation.y + widget->style->ythickness;
749 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
751 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
752 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
755 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
757 if (alloc.height < 0)
760 /* Add left border */
761 alloc.x = allocation->x + widget->style->xthickness;
763 /* Allocate positions for widgets (left-to-right) */
764 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
765 alloc.x += HILDON_MARGIN_DEFAULT;
767 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
768 alloc.x += HILDON_MARGIN_DEFAULT;
770 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
774 hildon_number_editor_focus (GtkWidget *widget,
775 GtkDirectionType direction)
778 GtkDirectionType effective_direction;
780 g_assert (HILDON_IS_NUMBER_EDITOR (widget));
782 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
785 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
791 hildon_number_editor_entry_focusout (GtkWidget *widget,
792 GdkEventFocus *event,
795 g_assert (HILDON_IS_NUMBER_EDITOR(data));
797 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR(data), FALSE);
802 hildon_number_editor_entry_keypress (GtkWidget *widget,
806 GtkEditable *editable;
809 g_assert (HILDON_IS_NUMBER_EDITOR (data));
811 editable = GTK_EDITABLE (widget);
812 cursor_pos = gtk_editable_get_position (editable);
814 switch (event->keyval)
817 /* If the cursor is on the left, try to decrement */
818 if (cursor_pos == 0) {
819 change_numbers (HILDON_NUMBER_EDITOR (data), -1);
825 /* If the cursor is on the right, try to increment */
826 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (widget)), -1))
828 change_numbers (HILDON_NUMBER_EDITOR (data), 1);
829 gtk_editable_set_position(editable, cursor_pos);
842 hildon_number_editor_range_error (HildonNumberEditor *editor,
843 HildonNumberEditorErrorType type)
847 gchar *err_msg = NULL;
848 HildonNumberEditorPrivate *priv;
850 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
856 /* Construct error message */
859 case HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED:
860 err_msg = g_strdup_printf (_("ckct_ib_maximum_value"), max, max);
863 case HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED:
864 err_msg = g_strdup_printf (_("ckct_ib_minimum_value"), min, min);
867 case HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE:
869 g_strdup_printf (_("ckct_ib_set_a_value_within_range"), min, max);
873 /* Infoprint error */
876 hildon_banner_show_information (GTK_WIDGET (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(editor),
877 GTK_TYPE_WINDOW))), NULL, err_msg);
885 * hildon_number_editor_new:
886 * @min: minimum accepted value
887 * @max: maximum accepted value
889 * Creates new number editor
891 * Returns: a new #HildonNumberEditor widget
894 hildon_number_editor_new (gint min,
897 HildonNumberEditor *editor = g_object_new (HILDON_TYPE_NUMBER_EDITOR, NULL);
899 /* Set user inputted range to editor */
900 hildon_number_editor_set_range (editor, min, max);
902 return GTK_WIDGET (editor);
906 * hildon_number_editor_set_range:
907 * @editor: a #HildonNumberEditor widget
908 * @min: minimum accepted value
909 * @max: maximum accepted value
911 * Sets accepted number range for editor
914 hildon_number_editor_set_range (HildonNumberEditor *editor,
918 HildonNumberEditorPrivate *priv;
919 gchar buffer_min[32], buffer_max[32];
922 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
924 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
927 /* Set preferences */
928 priv->start = MIN (min, max);
929 priv->end = MAX (min, max);
931 /* Find maximum allowed length of value */
932 g_snprintf (buffer_min, sizeof (buffer_min), "%d", min);
933 g_snprintf (buffer_max, sizeof (buffer_max), "%d", max);
934 a = strlen (buffer_min);
935 b = strlen (buffer_max);
937 /* Set maximum size of entry */
938 gtk_entry_set_width_chars (GTK_ENTRY (priv->num_entry), MAX (a, b));
939 hildon_number_editor_set_value (editor, priv->start);
943 * hildon_number_editor_get_value:
944 * @editor: a #HildonNumberEditor
946 * Gets the current value of the number editor.
948 * Returns: the current value
951 hildon_number_editor_get_value (HildonNumberEditor *editor)
953 HildonNumberEditorPrivate *priv;
955 g_return_val_if_fail (HILDON_IS_NUMBER_EDITOR (editor), 0);
957 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
960 return atoi (gtk_entry_get_text (GTK_ENTRY (priv->num_entry)));
964 * hildon_number_editor_set_value:
965 * @editor: a #HildonNumberEditor
966 * @value: numeric value for number editor
968 * Sets numeric value for number editor
971 hildon_number_editor_set_value (HildonNumberEditor *editor,
974 HildonNumberEditorPrivate *priv;
976 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
978 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
981 g_return_if_fail (value <= priv->end);
982 g_return_if_fail (value >= priv->start);
984 priv->default_val = value;
985 hildon_number_editor_real_set_value (priv, value);
986 g_object_notify (G_OBJECT(editor), "value");
989 /* When calling gtk_entry_set_text, the entry widget does things that can
990 * cause the whole widget to redraw. This redrawing is delayed and if any
991 * selections are made right after calling the gtk_entry_set_text the
992 * setting of the selection might seem to have no effect.
994 * If the selection is delayed with a lower priority than the redrawing,
995 * the selection should stick. Calling this function with g_idle_add should
999 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
1001 gtk_editable_select_region (GTK_EDITABLE (priv->num_entry), 0, -1);
1002 priv->select_all_idle_id = 0;
1007 hildon_number_editor_set_property (GObject *object,
1009 const GValue *value,
1012 HildonNumberEditor *editor;
1014 editor = HILDON_NUMBER_EDITOR (object);
1019 hildon_number_editor_set_value (editor, g_value_get_int (value));
1023 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1029 hildon_number_editor_get_property (GObject *object,
1034 HildonNumberEditor *editor;
1036 editor = HILDON_NUMBER_EDITOR (object);
1041 g_value_set_int(value, hildon_number_editor_get_value (editor));
1045 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);