2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@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; either 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-range-editor
27 * @short_description: A widget is used to ask bounds of a range
29 * HidlonRangeEditor allows entering a pair of integers, e.g. the lower
30 * and higher bounds of a range. A minimum and maximum can also be set
34 #include <gtk/gtkbox.h>
35 #include <gtk/gtklabel.h>
36 #include <gtk/gtksignal.h>
37 #include <gtk/gtkentry.h>
38 #include <gdk/gdkkeysyms.h>
39 #include <glib/gprintf.h>
42 #include <hildon-widgets/hildon-input-mode-hint.h>
44 #include "hildon-range-editor.h"
51 #define _(string) dgettext(PACKAGE, string)
53 /* Alignment in entry box ( 0 = left, 1 = right ) */
54 #define DEFAULT_ALIGNMENT 1
55 /* Amount of padding to add to each side of the separator */
56 #define DEFAULT_PADDING 3
58 #define DEFAULT_START -999
59 #define DEFAULT_END 999
60 #define DEFAULT_LENGTH 4
62 #define HILDON_RANGE_EDITOR_GET_PRIVATE(obj) \
63 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
64 HILDON_TYPE_RANGE_EDITOR, HildonRangeEditorPrivate));
66 typedef struct _HildonRangeEditorPrivate HildonRangeEditorPrivate;
68 /* Property indices */
78 static GtkContainerClass *parent_class = NULL;
82 hildon_range_editor_class_init (HildonRangeEditorClass *editor_class);
84 hildon_range_editor_init (HildonRangeEditor *editor);
86 hildon_range_editor_forall (GtkContainer *container,
87 gboolean include_internals, GtkCallback callback,
88 gpointer callback_data);
90 hildon_range_editor_destroy (GtkObject *self);
92 /*size and font functions */
94 hildon_range_editor_size_request (GtkWidget *widget,
95 GtkRequisition *requisition);
97 hildon_range_editor_size_allocate (GtkWidget *widget,
98 GtkAllocation *allocation);
100 hildon_range_editor_entry_focus_in (GtkEditable *editable,
101 GdkEventFocus *event,
102 HildonRangeEditor *editor);
104 hildon_range_editor_entry_focus_out (GtkEditable *editable,
105 GdkEventFocus *event,
106 HildonRangeEditor *editor);
108 hildon_range_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
109 HildonRangeEditor *editor);
111 hildon_range_editor_released (GtkEditable *editable, GdkEventButton *event,
112 HildonRangeEditor *editor);
114 hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
115 HildonRangeEditor *editor);
117 static void hildon_range_editor_set_property( GObject *object, guint param_id,
118 const GValue *value, GParamSpec *pspec );
119 static void hildon_range_editor_get_property( GObject *object, guint param_id,
120 GValue *value, GParamSpec *pspec );
121 static void hildon_range_editor_entry_changed(GtkWidget *widget,
122 HildonRangeEditor *editor);
125 struct _HildonRangeEditorPrivate
127 GtkWidget *start_entry; /* Entry for lower value */
128 GtkWidget *end_entry; /* Entry for higher value */
132 gint range_limits_start; /* Minimum value allowed for range start/end */
133 gint range_limits_end; /* Maximum value allowed for range start/end */
135 gboolean bp; /* Button pressed, don't overwrite selection */
138 /* Private functions */
140 hildon_range_editor_class_init (HildonRangeEditorClass *editor_class)
142 GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
143 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
144 GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
146 parent_class = g_type_class_peek_parent(editor_class);
148 g_type_class_add_private(editor_class,
149 sizeof(HildonRangeEditorPrivate));
151 gobject_class->set_property = hildon_range_editor_set_property;
152 gobject_class->get_property = hildon_range_editor_get_property;
153 widget_class->size_request = hildon_range_editor_size_request;
154 widget_class->size_allocate = hildon_range_editor_size_allocate;
156 container_class->forall = hildon_range_editor_forall;
157 GTK_OBJECT_CLASS(editor_class)->destroy = hildon_range_editor_destroy;
159 gtk_widget_class_install_style_property(widget_class,
160 g_param_spec_int("hildon_range_editor_entry_alignment",
161 "Hildon RangeEditor entry alignment",
162 "Hildon RangeEditor entry alignment", 0, 1,
166 gtk_widget_class_install_style_property(widget_class,
167 g_param_spec_int("hildon_range_editor_separator_padding",
168 "Hildon RangeEditor separator padding",
169 "Hildon RangeEditor separaror padding",
175 * HildonRangeEditor:min:
177 * Minimum value in a range.
180 g_object_class_install_property( gobject_class, PROP_MIN,
181 g_param_spec_int("min",
183 "Minimum value in a range",
185 DEFAULT_START, G_PARAM_CONSTRUCT |
186 G_PARAM_READABLE | G_PARAM_WRITABLE) );
189 * HildonRangeEditor:max:
191 * Maximum value in a range.
194 g_object_class_install_property( gobject_class, PROP_MAX,
195 g_param_spec_int("max",
197 "Maximum value in a range",
199 DEFAULT_END, G_PARAM_CONSTRUCT |
200 G_PARAM_READABLE | G_PARAM_WRITABLE) );
203 * HildonRangeEditor:lower:
205 * Current value in the entry presenting lower end of selected range.
208 g_object_class_install_property( gobject_class, PROP_LOWER,
209 g_param_spec_int("lower",
210 "Current lower value",
211 "Current value in the entry presenting lower end of selected range",
213 DEFAULT_START, G_PARAM_CONSTRUCT |
214 G_PARAM_READABLE | G_PARAM_WRITABLE) );
217 * HildonRangeEditor:higher:
219 * Current value in the entry presenting higher end of selected range.
222 g_object_class_install_property( gobject_class, PROP_HIGHER,
223 g_param_spec_int("higher",
224 "Current higher value",
225 "Current value in the entry presenting higher end of selected range",
227 DEFAULT_END, G_PARAM_CONSTRUCT |
228 G_PARAM_READABLE | G_PARAM_WRITABLE) );
231 * HildonRangeEditor:separator:
233 * Separator string to separate range editor entries.
236 g_object_class_install_property( gobject_class, PROP_SEPARATOR,
237 g_param_spec_string("separator",
239 "Separator string to separate entries",
240 _("ckct_wi_range_separator"),
242 G_PARAM_READABLE | G_PARAM_WRITABLE) );
246 hildon_range_editor_init (HildonRangeEditor *editor)
248 HildonRangeEditorPrivate *priv;
250 gint range_editor_entry_alignment;
251 gint range_editor_separator_padding;
253 priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
255 GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
257 gtk_widget_push_composite_child();
259 priv->start_entry = gtk_entry_new();
260 priv->end_entry = gtk_entry_new();
261 priv->label = gtk_label_new(_("ckct_wi_range_separator"));
264 /* Get values from gtkrc (or use defaults) */
265 /* FIXME: This is broken, styles are not yet attached */
266 gtk_widget_style_get(GTK_WIDGET(editor),
267 "hildon_range_editor_entry_alignment",
268 &range_editor_entry_alignment,
269 "hildon_range_editor_separator_padding",
270 &range_editor_separator_padding, NULL);
272 /* Add padding to separator */
273 gtk_misc_set_padding (GTK_MISC(priv->label),
274 range_editor_separator_padding, 0);
276 /* Align the text to right in entry box */
277 gtk_entry_set_alignment(GTK_ENTRY(priv->start_entry),
278 range_editor_entry_alignment);
279 gtk_entry_set_alignment(GTK_ENTRY(priv->end_entry),
280 range_editor_entry_alignment);
282 gtk_widget_set_composite_name(priv->start_entry, "start_entry");
283 gtk_widget_set_composite_name(priv->end_entry, "end_entry");
284 gtk_widget_set_composite_name(priv->label, "separator_label");
285 gtk_widget_set_parent(priv->start_entry, GTK_WIDGET(editor));
286 gtk_widget_set_parent(priv->end_entry, GTK_WIDGET(editor));
287 gtk_widget_set_parent(priv->label, GTK_WIDGET(editor));
289 g_signal_connect(G_OBJECT(priv->start_entry), "button-release-event",
290 G_CALLBACK(hildon_range_editor_released), editor);
291 g_signal_connect(G_OBJECT(priv->end_entry), "button-release-event",
292 G_CALLBACK(hildon_range_editor_released), editor);
294 g_signal_connect(G_OBJECT(priv->start_entry), "button-press-event",
295 G_CALLBACK(hildon_range_editor_press), editor);
296 g_signal_connect(G_OBJECT(priv->end_entry), "button-press-event",
297 G_CALLBACK(hildon_range_editor_press), editor);
299 g_signal_connect(G_OBJECT(priv->start_entry), "key-press-event",
300 G_CALLBACK(hildon_range_editor_entry_keypress), editor);
301 g_signal_connect(G_OBJECT(priv->end_entry), "key-press-event",
302 G_CALLBACK(hildon_range_editor_entry_keypress), editor);
304 g_signal_connect(G_OBJECT(priv->start_entry), "focus-in-event",
305 G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
306 g_signal_connect(G_OBJECT(priv->end_entry), "focus-in-event",
307 G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
309 g_signal_connect(G_OBJECT(priv->start_entry), "focus-out-event",
310 G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
311 g_signal_connect(G_OBJECT(priv->end_entry), "focus-out-event",
312 G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
313 g_signal_connect(priv->start_entry, "changed",
314 G_CALLBACK(hildon_range_editor_entry_changed), editor);
315 g_signal_connect(priv->end_entry, "changed",
316 G_CALLBACK(hildon_range_editor_entry_changed), editor);
318 g_object_set( G_OBJECT(priv->start_entry),
319 "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
320 g_object_set( G_OBJECT(priv->end_entry),
321 "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
323 gtk_widget_show(priv->start_entry);
324 gtk_widget_show(priv->end_entry);
325 gtk_widget_show(priv->label);
327 gtk_widget_pop_composite_child();
330 static void hildon_range_editor_set_property (GObject *object, guint param_id,
331 const GValue *value, GParamSpec *pspec)
333 HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
337 hildon_range_editor_set_lower (editor, g_value_get_int (value));
341 hildon_range_editor_set_higher (editor, g_value_get_int (value));
345 hildon_range_editor_set_min (editor, g_value_get_int (value));
349 hildon_range_editor_set_max (editor, g_value_get_int (value));
353 hildon_range_editor_set_separator (editor,
354 g_value_get_string (value));
358 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
363 static void hildon_range_editor_get_property( GObject *object, guint param_id,
364 GValue *value, GParamSpec *pspec )
366 HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
370 g_value_set_int (value, hildon_range_editor_get_lower (editor));
374 g_value_set_int (value, hildon_range_editor_get_higher (editor));
378 g_value_set_int (value, hildon_range_editor_get_min (editor));
382 g_value_set_int (value, hildon_range_editor_get_max (editor));
386 g_value_set_string (value, hildon_range_editor_get_separator (editor));
390 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
396 hildon_range_editor_entry_validate(HildonRangeEditor *editor,
397 GtkWidget *edited_entry, gboolean allow_intermediate)
399 HildonRangeEditorPrivate *priv;
402 gint min, max, fixup;
405 gboolean error = FALSE;
407 g_assert(HILDON_IS_RANGE_EDITOR(editor));
408 g_assert(GTK_IS_ENTRY(edited_entry));
410 priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
412 /* Find the valid range for the modified component */
413 if (edited_entry == priv->start_entry) {
414 min = hildon_range_editor_get_min(editor);
415 max = hildon_range_editor_get_higher(editor);
417 min = hildon_range_editor_get_lower(editor);
418 max = hildon_range_editor_get_max(editor);
421 text = gtk_entry_get_text(edited_entry);
425 /* Try to convert entry text to number */
426 value = strtol(text, &tail, 10);
428 /* Check if conversion succeeded */
431 /* Check if value is in allowed range. This is tricky in those
432 cases when user is editing a value.
433 For example: Range = [100, 500] and user have just inputted "4".
434 This should not lead into error message. Otherwise value is
435 resetted back to "100" and next "4" press will reset it back
437 if (allow_intermediate)
439 /* We now have the following error cases:
440 * If inputted value as above maximum and
441 maximum is either positive or then maximum
442 negative and value is positive.
443 * If inputted value is below minimum and minimum
444 is negative or minumum positive and value
446 In all other cases situation can be fixed just by
447 adding new numbers to the string.
449 if (value > max && (max >= 0 || (max < 0 && value >= 0)))
453 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
455 else if (value < min && (min < 0 || (min >= 0 && value < 0)))
459 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
467 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
469 else if (value < min) {
472 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
477 if (edited_entry == priv->start_entry)
478 hildon_range_editor_set_lower(editor, fixup);
480 hildon_range_editor_set_higher(editor, fixup);
483 /* The only valid case when conversion can fail is when we
484 have plain '-', intermediate forms are allowed AND
485 minimum bound is negative */
486 else if (!allow_intermediate || strcmp(text, "-") != 0 || min >= 0) {
488 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
491 else if (!allow_intermediate) {
493 g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
498 hildon_banner_show_information(edited_entry, NULL, buffer);
499 gtk_widget_grab_focus(edited_entry);
504 hildon_range_editor_entry_focus_in (GtkEditable *editable,
505 GdkEventFocus *event,
506 HildonRangeEditor *editor)
508 HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
514 if (GTK_WIDGET(editable) == priv->start_entry)
515 gtk_editable_select_region(editable, -1, 0);
517 gtk_editable_select_region(editable, 0, -1);
521 /* Gets and sets the current range. This has two usefull side effects:
522 * Values are now sorted to the correct order
523 * Out of range values are clamped to range */
524 static void hildon_range_editor_apply_current_range(HildonRangeEditor *editor)
526 g_assert(HILDON_IS_RANGE_EDITOR(editor));
528 hildon_range_editor_set_range(editor,
529 hildon_range_editor_get_lower(editor),
530 hildon_range_editor_get_higher(editor));
533 static void hildon_range_editor_entry_changed(GtkWidget *widget, HildonRangeEditor *editor)
535 g_assert(HILDON_IS_RANGE_EDITOR(editor));
536 hildon_range_editor_entry_validate(editor, widget, TRUE);
540 hildon_range_editor_entry_focus_out (GtkEditable *editable,
541 GdkEventFocus *event,
542 HildonRangeEditor *editor)
544 g_assert(HILDON_IS_RANGE_EDITOR(editor));
545 hildon_range_editor_entry_validate(editor, GTK_WIDGET(editable), FALSE);
550 hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
551 HildonRangeEditor *editor)
553 HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
559 hildon_range_editor_forall (GtkContainer *container,
560 gboolean include_internals,
561 GtkCallback callback, gpointer callback_data)
563 HildonRangeEditorPrivate *priv;
565 g_assert(HILDON_IS_RANGE_EDITOR(container));
566 g_assert(callback != NULL);
568 priv = HILDON_RANGE_EDITOR_GET_PRIVATE(container);
570 if (!include_internals)
573 (*callback) (priv->start_entry, callback_data);
574 (*callback) (priv->end_entry, callback_data);
575 (*callback) (priv->label, callback_data);
579 hildon_range_editor_destroy(GtkObject *self)
581 HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(self);
583 if (priv->start_entry)
585 gtk_widget_unparent(priv->start_entry);
586 priv->start_entry = NULL;
590 gtk_widget_unparent(priv->end_entry);
591 priv->end_entry = NULL;
595 gtk_widget_unparent(priv->label);
599 if (GTK_OBJECT_CLASS(parent_class)->destroy)
600 GTK_OBJECT_CLASS(parent_class)->destroy(self);
605 hildon_range_editor_size_request(GtkWidget *widget,
606 GtkRequisition *requisition)
608 HildonRangeEditorPrivate *priv = NULL;
609 GtkRequisition lab_req, mreq;
611 priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
613 gtk_entry_get_width_chars(GTK_ENTRY(priv->end_entry));
615 gtk_widget_size_request(priv->start_entry, &mreq);
616 gtk_widget_size_request(priv->end_entry, &mreq);
617 gtk_widget_size_request(priv->label, &lab_req);
619 /* Width for entries and separator label and border */
620 requisition->width = mreq.width * 2 + lab_req.width +
621 widget->style->xthickness * 2;
622 /* Add vertical border */
623 requisition->height = mreq.height + widget->style->ythickness * 2;
624 /* Fit label height */
625 requisition->height = MAX (requisition->height, lab_req.height);
629 hildon_range_editor_size_allocate(GtkWidget *widget,
630 GtkAllocation *allocation)
632 HildonRangeEditorPrivate *priv;
633 GtkAllocation child1_allocation, child2_allocation, child3_allocation;
635 priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
637 widget->allocation = *allocation;
639 /* Allocate entries, left-to-right */
640 if (priv->start_entry && GTK_WIDGET_VISIBLE(priv->start_entry))
642 GtkRequisition child_requisition;
644 gtk_widget_get_child_requisition(priv->start_entry,
647 child1_allocation.x = allocation->x;
648 child1_allocation.y = allocation->y;
650 child1_allocation.width = child_requisition.width;
651 child1_allocation.height = allocation->height;
653 gtk_widget_size_allocate(priv->start_entry, &child1_allocation);
656 if (priv->label && GTK_WIDGET_VISIBLE(priv->label))
658 GtkRequisition child_requisition;
660 gtk_widget_get_child_requisition(priv->label, &child_requisition);
662 child2_allocation.x = child1_allocation.x + child1_allocation.width;
663 child2_allocation.y = allocation->y;
665 child2_allocation.width = child_requisition.width + 4;
666 child2_allocation.height = allocation->height;
668 gtk_widget_size_allocate (priv->label, &child2_allocation);
671 if (priv->end_entry && GTK_WIDGET_VISIBLE(priv->end_entry))
673 GtkRequisition child_requisition;
675 gtk_widget_get_child_requisition (priv->end_entry, &child_requisition);
677 child3_allocation.x = child2_allocation.x + child2_allocation.width;
678 child3_allocation.y = allocation->y;
680 child3_allocation.width = child_requisition.width;
681 child3_allocation.height = allocation->height;
683 gtk_widget_size_allocate(priv->end_entry, &child3_allocation);
687 /* Button released inside entries */
689 hildon_range_editor_released(GtkEditable *editable, GdkEventButton *event,
690 HildonRangeEditor *editor)
692 HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
693 if (GTK_WIDGET(editable) == priv->start_entry)
694 gtk_editable_select_region(editable, -1, 0);
696 gtk_editable_select_region(editable, 0, -1);
701 hildon_range_editor_entry_keypress(GtkWidget *widget, GdkEventKey *event,
702 HildonRangeEditor *editor)
707 g_assert(HILDON_IS_RANGE_EDITOR(editor));
709 text = gtk_entry_get_text(GTK_ENTRY(widget));
710 cursor_pos = gtk_editable_get_position(GTK_EDITABLE(widget));
712 switch (event->keyval)
715 /* If we are on the first character and press left,
716 try to move to previous field */
717 if (cursor_pos == 0) {
718 (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_LEFT);
724 /* If the cursor is on the right, try to move to the next field */
725 if (cursor_pos >= g_utf8_strlen(text, -1)) {
726 (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_RIGHT);
738 static void hildon_range_editor_refresh_widths(HildonRangeEditorPrivate *priv)
740 gchar start_range[32], end_range[32];
743 /* Calculate length of entry so extremes would fit */
744 g_snprintf(start_range, sizeof(start_range), "%d", priv->range_limits_start);
745 g_snprintf(end_range, sizeof(end_range), "%d", priv->range_limits_end);
746 length = MAX(g_utf8_strlen(start_range, -1), g_utf8_strlen(end_range, -1));
748 gtk_entry_set_width_chars(GTK_ENTRY(priv->start_entry), length);
749 gtk_entry_set_max_length(GTK_ENTRY(priv->start_entry), length);
750 gtk_entry_set_width_chars(GTK_ENTRY (priv->end_entry), length);
751 gtk_entry_set_max_length(GTK_ENTRY (priv->end_entry), length);
754 /* Public functions */
757 * hildon_range_editor_get_type:
759 * Initializes, and returns the type of a hildon range editor.
761 * @Returns : GType of #HildonRangeEditor
765 hildon_range_editor_get_type (void)
767 static GType editor_type = 0;
771 static const GTypeInfo editor_info =
773 sizeof(HildonRangeEditorClass),
774 NULL, /* base_init */
775 NULL, /* base_finalize */
776 (GClassInitFunc) hildon_range_editor_class_init,
777 NULL, /* class_finalize */
778 NULL, /* class_data */
779 sizeof(HildonRangeEditor),
781 (GInstanceInitFunc) hildon_range_editor_init,
783 editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
791 * hildon_range_editor_new:
793 * HildonRangeEditor contains two GtkEntrys that accept numbers and minus.
795 * Returns: pointer to a new @HildonRangeEditor widget
798 hildon_range_editor_new (void)
800 return GTK_WIDGET(g_object_new(HILDON_TYPE_RANGE_EDITOR, NULL));
805 * hildon_range_editor_new_with_separator:
806 * @separator: a string that is shown between the numbers
808 * HildonRangeEditor contains two Gtk entries that accept numbers.
809 * A separator is displayed between two entries.
810 * CHECKME: Use '-' as a separator in the case of null separator?
812 * Returns: pointer to a new @HildonRangeEditor widget
815 hildon_range_editor_new_with_separator (const gchar *separator)
817 return GTK_WIDGET (g_object_new (HILDON_TYPE_RANGE_EDITOR,
818 "separator", separator, NULL));
823 * hildon_range_editor_set_range:
824 * @editor: the #HildonRangeEditor widget
825 * @start: range's start value
826 * @end: range's end value
828 * Sets a range to the editor. (The current value)
830 * Sets the range of the @HildonRangeEditor widget.
833 hildon_range_editor_set_range (HildonRangeEditor *editor, gint start, gint end)
835 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
837 /* Make sure that the start/end appear in the correct order */
838 hildon_range_editor_set_lower (editor, MIN(start, end));
839 hildon_range_editor_set_higher (editor, MAX(start, end));
844 * hildon_range_editor_get_range:
845 * @editor: the #HildonRangeEditor widget
846 * @start: ranges start value
847 * @end: ranges end value
849 * Gets the range of the @HildonRangeEditor widget.
852 hildon_range_editor_get_range (HildonRangeEditor *editor, gint *start,
855 HildonRangeEditorPrivate *priv;
857 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor) && start && end);
858 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
860 *start = hildon_range_editor_get_lower (editor);
861 *end = hildon_range_editor_get_higher (editor);
866 * hildon_range_editor_set_limits:
867 * @editor: the #HildonRangeEditor widget
868 * @start: minimum acceptable value (default: no limit)
869 * @end: maximum acceptable value (default: no limit)
871 * Sets the range of the @HildonRangeEditor widget.
874 hildon_range_editor_set_limits (HildonRangeEditor *editor, gint start,
877 /* FIXME: Setting start/end as separate steps can modify
878 the inputted range unneedlesly */
879 hildon_range_editor_set_min (editor, start);
880 hildon_range_editor_set_max (editor, end);
884 hildon_range_editor_set_lower (HildonRangeEditor *editor, gint value)
886 HildonRangeEditorPrivate *priv;
889 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
890 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
892 g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
893 priv->range_limits_start, priv->range_limits_end));
895 /* Update entry text with new value */
896 gtk_entry_set_text (GTK_ENTRY (priv->start_entry), buffer);
897 g_object_notify (G_OBJECT (editor), "lower");
901 hildon_range_editor_set_higher (HildonRangeEditor *editor, gint value)
903 HildonRangeEditorPrivate *priv;
906 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
907 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
909 g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
910 priv->range_limits_start, priv->range_limits_end));
912 /* Update entry text with new value */
913 gtk_entry_set_text (GTK_ENTRY (priv->end_entry), buffer);
914 g_object_notify (G_OBJECT (editor), "higher");
918 hildon_range_editor_get_lower (HildonRangeEditor *editor)
920 HildonRangeEditorPrivate *priv;
921 g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
922 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
923 return atoi(gtk_entry_get_text(GTK_ENTRY(priv->start_entry)));
927 hildon_range_editor_get_higher (HildonRangeEditor *editor)
929 HildonRangeEditorPrivate *priv;
930 g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
931 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
932 return atoi(gtk_entry_get_text(GTK_ENTRY (priv->end_entry)));
936 hildon_range_editor_set_min (HildonRangeEditor *editor, gint value)
938 HildonRangeEditorPrivate *priv;
940 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
942 /* We can cause many properties to change */
943 g_object_freeze_notify(G_OBJECT(editor));
944 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
945 priv->range_limits_start = value;
947 if (priv->range_limits_end < value)
948 hildon_range_editor_set_max (editor, value);
949 /* Setting maximum applies widths and range in this case */
951 hildon_range_editor_refresh_widths(priv);
952 hildon_range_editor_apply_current_range(editor);
955 g_object_notify (G_OBJECT (editor), "min");
956 g_object_thaw_notify(G_OBJECT(editor));
960 hildon_range_editor_set_max (HildonRangeEditor *editor, gint value)
962 HildonRangeEditorPrivate *priv;
964 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
966 /* We can cause many properties to change */
967 g_object_freeze_notify(G_OBJECT(editor));
968 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
969 priv->range_limits_end = value;
971 if (priv->range_limits_start > value)
972 hildon_range_editor_set_min (editor, value);
973 /* Setting minimum applies widths and range in this case */
975 hildon_range_editor_refresh_widths(priv);
976 hildon_range_editor_apply_current_range(editor);
979 g_object_notify (G_OBJECT (editor), "max");
980 g_object_thaw_notify(G_OBJECT(editor));
984 hildon_range_editor_get_min (HildonRangeEditor *editor)
986 HildonRangeEditorPrivate *priv;
987 g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
988 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
990 return priv->range_limits_start;
994 hildon_range_editor_get_max (HildonRangeEditor *editor)
996 HildonRangeEditorPrivate *priv;
997 g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
998 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
1000 return priv->range_limits_end;
1004 hildon_range_editor_set_separator (HildonRangeEditor *editor,
1005 const gchar *separator)
1007 HildonRangeEditorPrivate *priv;
1008 g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
1009 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
1011 gtk_label_set_text (GTK_LABEL (priv->label), separator);
1012 g_object_notify (G_OBJECT(editor), "separator");
1016 hildon_range_editor_get_separator (HildonRangeEditor *editor)
1018 HildonRangeEditorPrivate *priv;
1019 g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), NULL);
1020 priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
1022 return gtk_label_get_text (GTK_LABEL (priv->label));