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 = g_timeout_add (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 = g_timeout_add (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 GDK_THREADS_ENTER ();
541 /* Update value based on button held */
542 change_numbers (editor, priv->button_type);
544 GDK_THREADS_LEAVE ();
549 /* Changes the current number value by the amount of update
550 and verifies the result. */
552 change_numbers (HildonNumberEditor *editor,
555 HildonNumberEditorPrivate *priv;
558 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
560 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
563 current_value = hildon_number_editor_get_value (editor);
565 /* We need to rerun validation by hand, since validation
566 done in "changed" callback allows intermediate values */
567 hildon_number_editor_real_set_value (priv, current_value + update);
568 hildon_number_editor_validate_value (editor, FALSE);
569 g_object_notify (G_OBJECT (editor), "value");
573 add_select_all_idle (HildonNumberEditorPrivate *priv)
577 if (! priv->select_all_idle_id)
579 priv->select_all_idle_id =
580 g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
585 hildon_number_editor_validate_value (HildonNumberEditor *editor,
586 gboolean allow_intermediate)
588 HildonNumberEditorPrivate *priv;
589 gint error_code, fixup_value;
595 g_assert (HILDON_IS_NUMBER_EDITOR(editor));
597 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
600 text = gtk_entry_get_text (GTK_ENTRY (priv->num_entry));
602 fixup_value = priv->default_val;
606 /* Try to convert entry text to number */
607 value = strtol (text, &tail, 10);
609 /* Check if conversion succeeded */
612 /* Check if value is in allowed range. This is tricky in those
613 cases when user is editing a value.
614 For example: Range = [100, 500] and user have just inputted "4".
615 This should not lead into error message. Otherwise value is
616 resetted back to "100" and next "4" press will reset it back
618 if (allow_intermediate)
620 /* We now have the following error cases:
621 * If inputted value as above maximum and
622 maximum is either positive or then maximum
623 negative and value is positive.
624 * If inputted value is below minimum and minimum
625 is negative or minumum positive and value
627 In all other cases situation can be fixed just by
628 adding new numbers to the string.
630 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
632 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
633 fixup_value = priv->end;
635 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
637 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
638 fixup_value = priv->start;
643 if (value > priv->end) {
644 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
645 fixup_value = priv->end;
647 else if (value < priv->start) {
648 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
649 fixup_value = priv->start;
653 /* The only valid case when conversion can fail is when we
654 have plain '-', intermediate forms are allowed AND
655 minimum bound is negative */
656 else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0)
657 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
659 else if (! allow_intermediate)
660 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
662 if (error_code != -1)
664 /* If entry is empty and intermediate forms are nor allowed,
666 /* Change to default value */
667 hildon_number_editor_set_value (editor, fixup_value);
668 g_signal_emit (editor, HildonNumberEditor_signal[RANGE_ERROR], 0, error_code, &r);
669 add_select_all_idle (priv);
674 hildon_number_editor_entry_changed (GtkWidget *widget,
677 g_assert (HILDON_IS_NUMBER_EDITOR (data));
678 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR (data), TRUE);
679 g_object_notify (G_OBJECT (data), "value");
683 hildon_number_editor_size_request (GtkWidget *widget,
684 GtkRequisition *requisition)
686 HildonNumberEditor *editor;
687 HildonNumberEditorPrivate *priv;
690 editor = HILDON_NUMBER_EDITOR (widget);
691 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
694 /* Requested size is size of all child widgets plus border space */
695 gtk_widget_size_request (priv->minus, &req);
696 requisition->width = req.width;
698 gtk_widget_size_request (priv->num_entry, &req);
699 requisition->width += req.width;
701 gtk_widget_size_request (priv->plus, &req);
702 requisition->width += req.width;
704 requisition->width += HILDON_MARGIN_DEFAULT * 2;
706 /* FIXME: XXX Height is fixed */
707 requisition->height = NUMBER_EDITOR_HEIGHT;
710 /* Update alloc->width so widget fits, update alloc->x to point to free space */
712 set_widget_allocation (GtkWidget *widget,
713 GtkAllocation *alloc,
714 const GtkAllocation *allocation)
716 GtkRequisition child_requisition;
718 gtk_widget_get_child_requisition (widget, &child_requisition);
720 /* Fit to widget width */
721 if (allocation->width + allocation->x > alloc->x + child_requisition.width)
722 alloc->width = child_requisition.width;
725 alloc->width = allocation->width - (alloc->x - allocation->x);
726 if (alloc->width < 0)
730 gtk_widget_size_allocate (widget, alloc);
731 /* Update x position */
732 alloc->x += alloc->width;
736 hildon_number_editor_size_allocate (GtkWidget *widget,
737 GtkAllocation *allocation)
739 HildonNumberEditor *editor;
740 HildonNumberEditorPrivate *priv;
743 editor = HILDON_NUMBER_EDITOR (widget);
744 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
747 widget->allocation = *allocation;
749 /* Add upper border */
750 alloc.y = widget->allocation.y + widget->style->ythickness;
753 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
755 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
756 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
759 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
761 if (alloc.height < 0)
764 /* Add left border */
765 alloc.x = allocation->x + widget->style->xthickness;
767 /* Allocate positions for widgets (left-to-right) */
768 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
769 alloc.x += HILDON_MARGIN_DEFAULT;
771 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
772 alloc.x += HILDON_MARGIN_DEFAULT;
774 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
778 hildon_number_editor_focus (GtkWidget *widget,
779 GtkDirectionType direction)
782 GtkDirectionType effective_direction;
784 g_assert (HILDON_IS_NUMBER_EDITOR (widget));
786 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
789 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
795 hildon_number_editor_entry_focusout (GtkWidget *widget,
796 GdkEventFocus *event,
799 g_assert (HILDON_IS_NUMBER_EDITOR(data));
801 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR(data), FALSE);
806 hildon_number_editor_entry_keypress (GtkWidget *widget,
810 GtkEditable *editable;
813 g_assert (HILDON_IS_NUMBER_EDITOR (data));
815 editable = GTK_EDITABLE (widget);
816 cursor_pos = gtk_editable_get_position (editable);
818 switch (event->keyval)
821 /* If the cursor is on the left, try to decrement */
822 if (cursor_pos == 0) {
823 change_numbers (HILDON_NUMBER_EDITOR (data), -1);
829 /* If the cursor is on the right, try to increment */
830 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (widget)), -1))
832 change_numbers (HILDON_NUMBER_EDITOR (data), 1);
833 gtk_editable_set_position(editable, cursor_pos);
846 hildon_number_editor_range_error (HildonNumberEditor *editor,
847 HildonNumberEditorErrorType type)
851 gchar *err_msg = NULL;
852 HildonNumberEditorPrivate *priv;
854 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
860 /* Construct error message */
863 case HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED:
864 err_msg = g_strdup_printf (_("ckct_ib_maximum_value"), max, max);
867 case HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED:
868 err_msg = g_strdup_printf (_("ckct_ib_minimum_value"), min, min);
871 case HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE:
873 g_strdup_printf (_("ckct_ib_set_a_value_within_range"), min, max);
877 /* Infoprint error */
880 hildon_banner_show_information (GTK_WIDGET (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(editor),
881 GTK_TYPE_WINDOW))), NULL, err_msg);
889 * hildon_number_editor_new:
890 * @min: minimum accepted value
891 * @max: maximum accepted value
893 * Creates new number editor
895 * Returns: a new #HildonNumberEditor widget
898 hildon_number_editor_new (gint min,
901 HildonNumberEditor *editor = g_object_new (HILDON_TYPE_NUMBER_EDITOR, NULL);
903 /* Set user inputted range to editor */
904 hildon_number_editor_set_range (editor, min, max);
906 return GTK_WIDGET (editor);
910 * hildon_number_editor_set_range:
911 * @editor: a #HildonNumberEditor widget
912 * @min: minimum accepted value
913 * @max: maximum accepted value
915 * Sets accepted number range for editor
918 hildon_number_editor_set_range (HildonNumberEditor *editor,
922 HildonNumberEditorPrivate *priv;
923 gchar buffer_min[32], buffer_max[32];
926 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
928 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
931 /* Set preferences */
932 priv->start = MIN (min, max);
933 priv->end = MAX (min, max);
935 /* Find maximum allowed length of value */
936 g_snprintf (buffer_min, sizeof (buffer_min), "%d", min);
937 g_snprintf (buffer_max, sizeof (buffer_max), "%d", max);
938 a = strlen (buffer_min);
939 b = strlen (buffer_max);
941 /* Set maximum size of entry */
942 gtk_entry_set_width_chars (GTK_ENTRY (priv->num_entry), MAX (a, b));
943 hildon_number_editor_set_value (editor, priv->start);
947 * hildon_number_editor_get_value:
948 * @editor: pointer to #HildonNumberEditor
950 * Returns: current NumberEditor value
953 hildon_number_editor_get_value (HildonNumberEditor *editor)
955 HildonNumberEditorPrivate *priv;
957 g_return_val_if_fail (HILDON_IS_NUMBER_EDITOR (editor), 0);
959 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
962 return atoi (gtk_entry_get_text (GTK_ENTRY (priv->num_entry)));
966 * hildon_number_editor_set_value:
967 * @editor: pointer to #HildonNumberEditor
968 * @value: numeric value for number editor
970 * Sets numeric value for number editor
973 hildon_number_editor_set_value (HildonNumberEditor *editor,
976 HildonNumberEditorPrivate *priv;
978 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
980 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
983 g_return_if_fail (value <= priv->end);
984 g_return_if_fail (value >= priv->start);
986 priv->default_val = value;
987 hildon_number_editor_real_set_value (priv, value);
988 g_object_notify (G_OBJECT(editor), "value");
991 /* When calling gtk_entry_set_text, the entry widget does things that can
992 * cause the whole widget to redraw. This redrawing is delayed and if any
993 * selections are made right after calling the gtk_entry_set_text the
994 * setting of the selection might seem to have no effect.
996 * If the selection is delayed with a lower priority than the redrawing,
997 * the selection should stick. Calling this function with g_idle_add should
1001 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
1003 GDK_THREADS_ENTER ();
1004 gtk_editable_select_region (GTK_EDITABLE (priv->num_entry), 0, -1);
1005 priv->select_all_idle_id = 0;
1006 GDK_THREADS_LEAVE ();
1011 hildon_number_editor_set_property (GObject *object,
1013 const GValue *value,
1016 HildonNumberEditor *editor;
1018 editor = HILDON_NUMBER_EDITOR (object);
1023 hildon_number_editor_set_value (editor, g_value_get_int (value));
1027 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1033 hildon_number_editor_get_property (GObject *object,
1038 HildonNumberEditor *editor;
1040 editor = HILDON_NUMBER_EDITOR (object);
1045 g_value_set_int(value, hildon_number_editor_get_value (editor));
1049 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);