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.
34 * <title>HildonNumberEditor example</title>
36 * number_editor = hildon_number_editor_new (-250, 500);
37 * hildon_number_editor_set_range (number_editor, 0, 100);
42 #undef HILDON_DISABLE_DEPRECATED
52 #include <gdk/gdkkeysyms.h>
54 #include "hildon-number-editor.h"
55 #include "hildon-marshalers.h"
56 #include "hildon-defines.h"
57 #include "hildon-enum-types.h"
58 #include "hildon-banner.h"
59 #include "hildon-number-editor-private.h"
60 #include "hildon-private.h"
62 #define _(String) dgettext("hildon-libs", String)
64 /*Pixel spec defines*/
65 #define NUMBER_EDITOR_HEIGHT 30
67 /* Size of plus and minus buttons */
68 #define BUTTON_HEIGHT 30
70 #define BUTTON_WIDTH 30
73 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
76 hildon_number_editor_init (HildonNumberEditor *editor);
79 hildon_number_editor_entry_focusout (GtkWidget *widget,
84 hildon_number_editor_entry_changed (GtkWidget *widget,
88 hildon_number_editor_size_request (GtkWidget *widget,
89 GtkRequisition *requisition);
92 set_widget_allocation (GtkWidget *widget,
94 const GtkAllocation *allocation);
97 hildon_number_editor_size_allocate (GtkWidget *widget,
98 GtkAllocation *allocation);
101 hildon_number_editor_focus (GtkWidget *widget,
102 GtkDirectionType direction);
105 hildon_number_editor_entry_keypress (GtkWidget *widget,
110 hildon_number_editor_button_pressed (GtkWidget *widget,
111 GdkEventButton *event,
115 hildon_number_editor_entry_button_released (GtkWidget *widget,
116 GdkEventButton *event,
119 hildon_number_editor_button_released (GtkWidget *widget,
121 HildonNumberEditor *editor);
123 do_mouse_timeout (HildonNumberEditor *editor);
126 change_numbers (HildonNumberEditor *editor,
130 hildon_number_editor_forall (GtkContainer *container,
131 gboolean include_internals,
132 GtkCallback callback,
133 gpointer callback_data);
136 hildon_number_editor_destroy (GtkObject *self);
139 hildon_number_editor_start_timer (HildonNumberEditor *editor);
142 hildon_number_editor_finalize (GObject *self);
145 hildon_number_editor_range_error (HildonNumberEditor *editor,
146 HildonNumberEditorErrorType type);
149 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
152 hildon_number_editor_validate_value (HildonNumberEditor *editor,
153 gboolean allow_intermediate);
156 hildon_number_editor_set_property (GObject * object,
158 const GValue * value,
162 hildon_number_editor_get_property (GObject *object,
178 static GtkContainerClass* parent_class;
180 static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
183 * hildon_number_editor_get_type:
185 * Returns GType for HildonNumberEditor.
187 * Returns: HildonNumberEditor type
190 hildon_number_editor_get_type (void)
192 static GType editor_type = 0;
196 static const GTypeInfo editor_info =
198 sizeof (HildonNumberEditorClass),
199 NULL, /* base_init */
200 NULL, /* base_finalize */
201 (GClassInitFunc) hildon_number_editor_class_init,
202 NULL, /* class_finalize */
203 NULL, /* class_data */
204 sizeof (HildonNumberEditor),
206 (GInstanceInitFunc) hildon_number_editor_init,
208 editor_type = g_type_register_static (GTK_TYPE_CONTAINER,
209 "HildonNumberEditor",
216 hildon_number_editor_class_init (HildonNumberEditorClass *editor_class)
218 GtkContainerClass *container_class = GTK_CONTAINER_CLASS (editor_class);
219 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (editor_class);
220 GObjectClass *gobject_class = G_OBJECT_CLASS (editor_class);
222 g_type_class_add_private (editor_class,
223 sizeof (HildonNumberEditorPrivate));
225 parent_class = g_type_class_peek_parent (editor_class);
227 widget_class->size_request = hildon_number_editor_size_request;
228 widget_class->size_allocate = hildon_number_editor_size_allocate;
229 widget_class->focus = hildon_number_editor_focus;
231 editor_class->range_error = hildon_number_editor_range_error;
233 /* Because we derived our widget from GtkContainer, we should override
235 container_class->forall = hildon_number_editor_forall;
236 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
237 gobject_class->finalize = hildon_number_editor_finalize;
238 gobject_class->set_property = hildon_number_editor_set_property;
239 gobject_class->get_property = hildon_number_editor_get_property;
242 * HildonNumberEditor:value:
244 * The current value of the number editor.
246 g_object_class_install_property (gobject_class, PROP_VALUE,
247 g_param_spec_int ("value",
249 "The current value of number editor",
252 0, G_PARAM_READWRITE));
254 HildonNumberEditor_signal[RANGE_ERROR] =
255 g_signal_new ("range_error", HILDON_TYPE_NUMBER_EDITOR,
256 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
257 (HildonNumberEditorClass, range_error),
258 g_signal_accumulator_true_handled, NULL,
259 _hildon_marshal_BOOLEAN__ENUM,
260 G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
264 hildon_number_editor_forall (GtkContainer *container,
265 gboolean include_internals,
266 GtkCallback callback,
267 gpointer callback_data)
269 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (container);
271 g_assert (callback != NULL);
274 if (! include_internals)
277 /* Enumerate child widgets */
278 (*callback) (priv->minus, callback_data);
279 (*callback) (priv->num_entry, callback_data);
280 (*callback) (priv->plus, callback_data);
284 hildon_number_editor_destroy (GtkObject *self)
286 HildonNumberEditorPrivate *priv;
288 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
291 /* Free child widgets */
294 gtk_widget_unparent (priv->minus);
299 gtk_widget_unparent (priv->num_entry);
300 priv->num_entry = NULL;
304 gtk_widget_unparent (priv->plus);
308 if (GTK_OBJECT_CLASS (parent_class)->destroy)
309 GTK_OBJECT_CLASS (parent_class)->destroy(self);
313 hildon_number_editor_stop_repeat_timer (HildonNumberEditorPrivate *priv)
315 g_assert (priv != NULL);
317 if (priv->button_event_id)
319 g_source_remove (priv->button_event_id);
320 priv->button_event_id = 0;
325 hildon_number_editor_finalize (GObject *self)
327 HildonNumberEditorPrivate *priv;
329 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (self);
333 hildon_number_editor_stop_repeat_timer (priv);
335 if (priv->select_all_idle_id)
336 g_source_remove (priv->select_all_idle_id);
338 /* Call parent class finalize, if have one */
339 if (G_OBJECT_CLASS (parent_class)->finalize)
340 G_OBJECT_CLASS (parent_class)->finalize(self);
344 hildon_number_editor_init (HildonNumberEditor *editor)
346 HildonNumberEditorPrivate *priv;
348 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
351 GTK_WIDGET_SET_FLAGS (GTK_WIDGET (editor), GTK_NO_WINDOW);
353 /* Create child widgets */
354 priv->num_entry = gtk_entry_new ();
355 priv->minus = gtk_button_new ();
356 priv->plus = gtk_button_new ();
358 gtk_widget_set_name (priv->minus, "ne-minus-button");
359 gtk_widget_set_name (priv->plus, "ne-plus-button" );
360 gtk_widget_set_size_request (priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT);
361 gtk_widget_set_size_request (priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT);
362 gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
364 GTK_WIDGET_UNSET_FLAGS (priv->minus, GTK_CAN_FOCUS);
365 GTK_WIDGET_UNSET_FLAGS (priv->plus, GTK_CAN_FOCUS);
367 priv->button_event_id = 0;
368 priv->select_all_idle_id = 0;
370 gtk_widget_set_parent (priv->minus, GTK_WIDGET (editor));
371 gtk_widget_set_parent (priv->num_entry, GTK_WIDGET (editor));
372 gtk_widget_set_parent (priv->plus, GTK_WIDGET (editor));
374 /* Connect child widget signals */
375 g_signal_connect (GTK_OBJECT (priv->num_entry), "changed",
376 G_CALLBACK (hildon_number_editor_entry_changed),
379 g_signal_connect (GTK_OBJECT (priv->num_entry), "focus-out-event",
380 G_CALLBACK (hildon_number_editor_entry_focusout),
383 g_signal_connect (GTK_OBJECT (priv->num_entry), "key-press-event",
384 G_CALLBACK (hildon_number_editor_entry_keypress),
387 g_signal_connect (GTK_OBJECT (priv->num_entry), "button-release-event",
388 G_CALLBACK (hildon_number_editor_entry_button_released),
391 g_signal_connect (GTK_OBJECT (priv->minus), "button-press-event",
392 G_CALLBACK (hildon_number_editor_button_pressed),
395 g_signal_connect (GTK_OBJECT (priv->plus), "button-press-event",
396 G_CALLBACK (hildon_number_editor_button_pressed),
399 g_signal_connect (GTK_OBJECT (priv->minus), "button-release-event",
400 G_CALLBACK (hildon_number_editor_button_released),
403 g_signal_connect (GTK_OBJECT (priv->plus), "button-release-event",
404 G_CALLBACK (hildon_number_editor_button_released),
407 g_signal_connect (GTK_OBJECT (priv->minus), "leave-notify-event",
408 G_CALLBACK(hildon_number_editor_button_released),
411 g_signal_connect (GTK_OBJECT (priv->plus), "leave-notify-event",
412 G_CALLBACK (hildon_number_editor_button_released),
416 g_object_set (G_OBJECT (priv->num_entry),
417 "hildon-input-mode", HILDON_GTK_INPUT_MODE_NUMERIC, NULL);
420 gtk_widget_show (priv->num_entry);
421 gtk_widget_show (priv->minus);
422 gtk_widget_show (priv->plus);
424 hildon_number_editor_set_range (editor, G_MININT, G_MAXINT);
428 hildon_number_editor_entry_button_released (GtkWidget *widget,
429 GdkEventButton *event,
432 gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
437 hildon_number_editor_button_released (GtkWidget *widget,
439 HildonNumberEditor *editor)
441 HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
444 hildon_number_editor_stop_repeat_timer (priv);
448 /* Format given number to editor field, no checks performed, all signals
449 are sent normally. */
451 hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv,
454 /* FIXME: That looks REALLY bad */
457 /* Update text in entry to new value */
458 g_snprintf (buffer, sizeof (buffer), "%d", value);
459 gtk_entry_set_text (GTK_ENTRY (priv->num_entry), buffer);
463 hildon_number_editor_button_pressed (GtkWidget *widget,
464 GdkEventButton *event,
467 /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
468 /* Need to fetch current value from entry and increment or decrement
471 HildonNumberEditor *editor;
472 HildonNumberEditorPrivate *priv;
473 GtkSettings *settings;
476 g_assert (HILDON_IS_NUMBER_EDITOR (data));
478 editor = HILDON_NUMBER_EDITOR (data);
479 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
482 settings = gtk_settings_get_default ();
483 g_object_get (settings, "gtk-timeout-initial", &timeout, NULL);
485 /* Save type of button pressed */
486 if (GTK_BUTTON (widget) == GTK_BUTTON (priv->plus))
487 priv->button_type = 1;
489 priv->button_type = -1;
491 /* Start repetition timer */
492 if (! priv->button_event_id)
494 change_numbers (editor, priv->button_type);
495 priv->button_event_id = g_timeout_add (timeout,
496 (GSourceFunc) hildon_number_editor_start_timer,
504 hildon_number_editor_start_timer (HildonNumberEditor *editor)
506 HildonNumberEditorPrivate *priv;
507 GtkSettings *settings;
510 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
511 settings = gtk_settings_get_default ();
512 g_object_get (settings, "gtk-timeout-repeat", &timeout, NULL);
515 priv->button_event_id = g_timeout_add (timeout,
516 (GSourceFunc) do_mouse_timeout,
523 do_mouse_timeout (HildonNumberEditor *editor)
525 HildonNumberEditorPrivate *priv;
526 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
528 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
531 GDK_THREADS_ENTER ();
533 /* Update value based on button held */
534 change_numbers (editor, priv->button_type);
536 GDK_THREADS_LEAVE ();
541 /* Changes the current number value by the amount of update
542 and verifies the result. */
544 change_numbers (HildonNumberEditor *editor,
547 HildonNumberEditorPrivate *priv;
550 g_assert (HILDON_IS_NUMBER_EDITOR (editor));
552 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
555 current_value = hildon_number_editor_get_value (editor);
557 /* We need to rerun validation by hand, since validation
558 done in "changed" callback allows intermediate values */
559 hildon_number_editor_real_set_value (priv, current_value + update);
560 hildon_number_editor_validate_value (editor, FALSE);
561 g_object_notify (G_OBJECT (editor), "value");
565 add_select_all_idle (HildonNumberEditorPrivate *priv)
569 if (! priv->select_all_idle_id)
571 priv->select_all_idle_id =
572 g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
577 hildon_number_editor_validate_value (HildonNumberEditor *editor,
578 gboolean allow_intermediate)
580 HildonNumberEditorPrivate *priv;
581 gint error_code, fixup_value;
587 g_assert (HILDON_IS_NUMBER_EDITOR(editor));
589 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
592 text = gtk_entry_get_text (GTK_ENTRY (priv->num_entry));
594 fixup_value = priv->default_val;
598 /* Try to convert entry text to number */
599 value = strtol (text, &tail, 10);
601 /* Check if conversion succeeded */
604 /* Check if value is in allowed range. This is tricky in those
605 cases when user is editing a value.
606 For example: Range = [100, 500] and user have just inputted "4".
607 This should not lead into error message. Otherwise value is
608 resetted back to "100" and next "4" press will reset it back
610 if (allow_intermediate)
612 /* We now have the following error cases:
613 * If inputted value as above maximum and
614 maximum is either positive or then maximum
615 negative and value is positive.
616 * If inputted value is below minimum and minimum
617 is negative or minumum positive and value
619 In all other cases situation can be fixed just by
620 adding new numbers to the string.
622 if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
624 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
625 fixup_value = priv->end;
627 else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
629 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
630 fixup_value = priv->start;
635 if (value > priv->end) {
636 error_code = HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED;
637 fixup_value = priv->end;
639 else if (value < priv->start) {
640 error_code = HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED;
641 fixup_value = priv->start;
645 /* The only valid case when conversion can fail is when we
646 have plain '-', intermediate forms are allowed AND
647 minimum bound is negative */
648 else if (! allow_intermediate || strcmp (text, "-") != 0 || priv->start >= 0)
649 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
651 else if (! allow_intermediate)
652 error_code = HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE;
654 if (error_code != -1)
656 /* If entry is empty and intermediate forms are nor allowed,
658 /* Change to default value */
659 hildon_number_editor_set_value (editor, fixup_value);
660 g_signal_emit (editor, HildonNumberEditor_signal[RANGE_ERROR], 0, error_code, &r);
661 add_select_all_idle (priv);
666 hildon_number_editor_entry_changed (GtkWidget *widget,
669 g_assert (HILDON_IS_NUMBER_EDITOR (data));
670 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR (data), TRUE);
671 g_object_notify (G_OBJECT (data), "value");
675 hildon_number_editor_size_request (GtkWidget *widget,
676 GtkRequisition *requisition)
678 HildonNumberEditor *editor;
679 HildonNumberEditorPrivate *priv;
682 editor = HILDON_NUMBER_EDITOR (widget);
683 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
686 /* Requested size is size of all child widgets plus border space */
687 gtk_widget_size_request (priv->minus, &req);
688 requisition->width = req.width;
690 gtk_widget_size_request (priv->num_entry, &req);
691 requisition->width += req.width;
693 gtk_widget_size_request (priv->plus, &req);
694 requisition->width += req.width;
696 requisition->width += HILDON_MARGIN_DEFAULT * 2;
698 /* FIXME: XXX Height is fixed */
699 requisition->height = NUMBER_EDITOR_HEIGHT;
702 /* Update alloc->width so widget fits, update alloc->x to point to free space */
704 set_widget_allocation (GtkWidget *widget,
705 GtkAllocation *alloc,
706 const GtkAllocation *allocation)
708 GtkRequisition child_requisition;
710 gtk_widget_get_child_requisition (widget, &child_requisition);
712 /* Fit to widget width */
713 if (allocation->width + allocation->x > alloc->x + child_requisition.width)
714 alloc->width = child_requisition.width;
717 alloc->width = allocation->width - (alloc->x - allocation->x);
718 if (alloc->width < 0)
722 gtk_widget_size_allocate (widget, alloc);
723 /* Update x position */
724 alloc->x += alloc->width;
728 hildon_number_editor_size_allocate (GtkWidget *widget,
729 GtkAllocation *allocation)
731 HildonNumberEditor *editor;
732 HildonNumberEditorPrivate *priv;
735 editor = HILDON_NUMBER_EDITOR (widget);
736 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
739 widget->allocation = *allocation;
741 /* Add upper border */
742 alloc.y = widget->allocation.y + widget->style->ythickness;
745 if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
747 alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
748 alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
751 alloc.height = widget->allocation.height - widget->style->ythickness * 2;
753 if (alloc.height < 0)
756 /* Add left border */
757 alloc.x = allocation->x + widget->style->xthickness;
759 /* Allocate positions for widgets (left-to-right) */
760 set_widget_allocation(priv->minus, &alloc, &widget->allocation);
761 alloc.x += HILDON_MARGIN_DEFAULT;
763 set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
764 alloc.x += HILDON_MARGIN_DEFAULT;
766 set_widget_allocation(priv->plus, &alloc, &widget->allocation);
770 hildon_number_editor_focus (GtkWidget *widget,
771 GtkDirectionType direction)
774 GtkDirectionType effective_direction;
776 g_assert (HILDON_IS_NUMBER_EDITOR (widget));
778 retval = hildon_private_composite_focus (widget, direction, &effective_direction);
781 return GTK_WIDGET_CLASS (parent_class)->focus (widget, effective_direction);
787 hildon_number_editor_entry_focusout (GtkWidget *widget,
788 GdkEventFocus *event,
791 g_assert (HILDON_IS_NUMBER_EDITOR(data));
793 hildon_number_editor_validate_value (HILDON_NUMBER_EDITOR(data), FALSE);
798 hildon_number_editor_entry_keypress (GtkWidget *widget,
802 GtkEditable *editable;
805 g_assert (HILDON_IS_NUMBER_EDITOR (data));
807 editable = GTK_EDITABLE (widget);
808 cursor_pos = gtk_editable_get_position (editable);
810 switch (event->keyval)
813 /* If the cursor is on the left, try to decrement */
814 if (cursor_pos == 0) {
815 change_numbers (HILDON_NUMBER_EDITOR (data), -1);
821 /* If the cursor is on the right, try to increment */
822 if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text (GTK_ENTRY (widget)), -1))
824 change_numbers (HILDON_NUMBER_EDITOR (data), 1);
825 gtk_editable_set_position(editable, cursor_pos);
838 hildon_number_editor_range_error (HildonNumberEditor *editor,
839 HildonNumberEditorErrorType type)
843 gchar *err_msg = NULL;
844 HildonNumberEditorPrivate *priv;
846 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
852 /* Construct error message */
855 case HILDON_NUMBER_EDITOR_ERROR_MAXIMUM_VALUE_EXCEED:
856 err_msg = g_strdup_printf (_("ckct_ib_maximum_value"), max, max);
859 case HILDON_NUMBER_EDITOR_ERROR_MINIMUM_VALUE_EXCEED:
860 err_msg = g_strdup_printf (_("ckct_ib_minimum_value"), min, min);
863 case HILDON_NUMBER_EDITOR_ERROR_ERRONEOUS_VALUE:
865 g_strdup_printf (_("ckct_ib_set_a_value_within_range"), min, max);
869 /* Infoprint error */
872 hildon_banner_show_information (GTK_WIDGET (GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET(editor),
873 GTK_TYPE_WINDOW))), NULL, err_msg);
881 * hildon_number_editor_new:
882 * @min: minimum accepted value
883 * @max: maximum accepted value
885 * Creates new number editor
887 * Returns: a new #HildonNumberEditor widget
890 hildon_number_editor_new (gint min,
893 HildonNumberEditor *editor = g_object_new (HILDON_TYPE_NUMBER_EDITOR, NULL);
895 /* Set user inputted range to editor */
896 hildon_number_editor_set_range (editor, min, max);
898 return GTK_WIDGET (editor);
902 * hildon_number_editor_set_range:
903 * @editor: a #HildonNumberEditor widget
904 * @min: minimum accepted value
905 * @max: maximum accepted value
907 * Sets accepted number range for editor
910 hildon_number_editor_set_range (HildonNumberEditor *editor,
914 HildonNumberEditorPrivate *priv;
915 gchar buffer_min[32], buffer_max[32];
918 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
920 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
923 /* Set preferences */
924 priv->start = MIN (min, max);
925 priv->end = MAX (min, max);
927 /* Find maximum allowed length of value */
928 g_snprintf (buffer_min, sizeof (buffer_min), "%d", min);
929 g_snprintf (buffer_max, sizeof (buffer_max), "%d", max);
930 a = strlen (buffer_min);
931 b = strlen (buffer_max);
933 /* Set maximum size of entry */
934 gtk_entry_set_width_chars (GTK_ENTRY (priv->num_entry), MAX (a, b));
935 hildon_number_editor_set_value (editor, priv->start);
939 * hildon_number_editor_get_value:
940 * @editor: pointer to #HildonNumberEditor
942 * Returns: current NumberEditor value
945 hildon_number_editor_get_value (HildonNumberEditor *editor)
947 HildonNumberEditorPrivate *priv;
949 g_return_val_if_fail (HILDON_IS_NUMBER_EDITOR (editor), 0);
951 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
954 return atoi (gtk_entry_get_text (GTK_ENTRY (priv->num_entry)));
958 * hildon_number_editor_set_value:
959 * @editor: pointer to #HildonNumberEditor
960 * @value: numeric value for number editor
962 * Sets numeric value for number editor
965 hildon_number_editor_set_value (HildonNumberEditor *editor,
968 HildonNumberEditorPrivate *priv;
970 g_return_if_fail (HILDON_IS_NUMBER_EDITOR (editor));
972 priv = HILDON_NUMBER_EDITOR_GET_PRIVATE (editor);
975 g_return_if_fail (value <= priv->end);
976 g_return_if_fail (value >= priv->start);
978 priv->default_val = value;
979 hildon_number_editor_real_set_value (priv, value);
980 g_object_notify (G_OBJECT(editor), "value");
983 /* When calling gtk_entry_set_text, the entry widget does things that can
984 * cause the whole widget to redraw. This redrawing is delayed and if any
985 * selections are made right after calling the gtk_entry_set_text the
986 * setting of the selection might seem to have no effect.
988 * If the selection is delayed with a lower priority than the redrawing,
989 * the selection should stick. Calling this function with g_idle_add should
993 hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
995 GDK_THREADS_ENTER ();
996 gtk_editable_select_region (GTK_EDITABLE (priv->num_entry), 0, -1);
997 priv->select_all_idle_id = 0;
998 GDK_THREADS_LEAVE ();
1003 hildon_number_editor_set_property (GObject *object,
1005 const GValue *value,
1008 HildonNumberEditor *editor;
1010 editor = HILDON_NUMBER_EDITOR (object);
1015 hildon_number_editor_set_value (editor, g_value_get_int (value));
1019 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
1025 hildon_number_editor_get_property (GObject *object,
1030 HildonNumberEditor *editor;
1032 editor = HILDON_NUMBER_EDITOR (object);
1037 g_value_set_int(value, hildon_number_editor_get_value (editor));
1041 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);