* ./: hildon-widgets => src . hildon-widgets-plugins => plugins.
Changing dir names etc.
+2006-11-14 Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+
+ * ./: hildon-widgets => src . hildon-widgets-plugins => plugins.
+ Changing dir names etc.
+
2006-11-08 Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
* hildon-widgets/hildon-libs.c:
-SUBDIRS = hildon-widgets hildon-widgets-plugins timer doc po
+SUBDIRS = src plugins timer doc po
+
EXTRA_DIST = \
debian/changelog \
debian/control \
AC_HEADER_STDC
-#PKG_CHECK_MODULES(OUTO, outo >= 0.1.1)
-#AC_SUBST(OUTO_CFLAGS)
-
CFLAGS="$CFLAGS -std=c99 -Wall -pedantic -Wmissing-prototypes -Wmissing-declarations"
# -Werror disabled due to the flaw in glib-2.0
# See http://bugzilla.gnome.org/show_bug.cgi?id=310175 and
AM_CONDITIONAL(HAVE_DOXYGEN, [test "$DOXYGEN_FOUND" = "yes"])
localedir=${datadir}/locale
-#outomoduledir=${libdir}/outo
AC_SUBST(localedir)
-#AC_SUBST(outomoduledir)
-
-
# Disable rebuild of glib-mkenum -generated source code:
AC_ARG_ENABLE(rebuilds, [ --disable-rebuilds disable all source autogeneration rules],,enable_rebuilds=yes)
AC_OUTPUT(Makefile \
- hildon-widgets/Makefile \
- hildon-widgets-plugins/Makefile \
+ src/Makefile \
+ plugins/Makefile \
timer/Makefile \
po/Makefile \
po/porules.mk \
+++ /dev/null
-MAINTAINERCLEANFILES = Makefile.in
-
-INCLUDES = $(GTK_CFLAGS) $(GCONF_CFLAGS) -DLOCALEDIR=\"$(localedir)\" \
- -I$(srcdir)/..
-
-LDFLAGS = -module -avoid-version
-LIBADD = -L$(srcdir)/../hildon-widgets/.libs -lhildonwidgets $(GTK_LIBS)
-
-pluginwidgetdir = $(libdir)/hildon-widgets
-pluginwidget_LTLIBRARIES = hildoncolorchooser_hsv.la \
- hildoncolorchooserdialog_hsv.la
-
-hildoncolorchooser_hsv_la_SOURCES = hildon-color-chooser-hsv.c
-
-hildoncolorchooserdialog_hsv_la_SOURCES = hildon-color-chooser-dialog-hsv.c
-hildoncolorchooserdialog_hsv_la_LIBADD = $(GCONF_LIBS)
-
-install-exec-local: installdirs
- @echo "Creating default symlink for color chooser..."
- @ln -f -s 'hildoncolorchooser_hsv.so' '$(DESTDIR)/$(libdir)/hildon-widgets/hildoncolorchooser_default.so'
- @echo "Creating default symlink for color chooser dialog..."
- @ln -f -s 'hildoncolorchooserdialog_hsv.so' '$(DESTDIR)/$(libdir)/hildon-widgets/hildoncolorchooserdialog_default.so'
-
-
-
-
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#include <memory.h>
-#include <string.h>
-
-#include <libintl.h>
-
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <gtk/gtk.h>
-
-#include <gconf/gconf-client.h>
-
-
-#include <hildon-widgets/hildon-color-chooser-dialog.h>
-#include <hildon-widgets/hildon-color-chooser.h>
-
-#include <hildon-widgets/hildon-plugin-widget.h>
-
-#include <hildon-widgets/hildon-defines.h>
-
-#include <hildon-widgets/hildon-banner.h>
-
-
-#define _(String) dgettext("hildon-libs", String)
-
-
-const char *parent_name = "HildonColorChooserDialog";
-const char *plugin_name = "HSV color chooser dialog";
-
-GType export_type(void);
-
-
-static HildonPluginWidgetInfo *chooser_plugin = NULL;
-
-static HildonColorChooserDialogClass *parent_klass = NULL;
-
-
-/* darkened EGA palette to be used as predefined colors if style doesn't
- define anything else (darker colors are darkened 0x8000 -> 0x6666) */
-static GdkColor hardcoded_colors[16] = {{0, 0x0000, 0x0000, 0x0000},
- {0, 0x6666, 0x6666, 0x6666},
- {0, 0x6666, 0x0000, 0x0000},
- {0, 0x0000, 0x6666, 0x0000},
- {0, 0x0000, 0x0000, 0x6666},
- {0, 0x6666, 0x6666, 0x0000},
- {0, 0x6666, 0x0000, 0x6666},
- {0, 0x0000, 0x6666, 0x6666},
- {0, 0xffff, 0xffff, 0xffff},
- {0, 0xc000, 0xc000, 0xc000},
- {0, 0xffff, 0x0000, 0x0000},
- {0, 0x0000, 0xffff, 0x0000},
- {0, 0x0000, 0x0000, 0xffff},
- {0, 0xffff, 0xffff, 0x0000},
- {0, 0xffff, 0x0000, 0xffff},
- {0, 0x0000, 0xffff, 0xffff}};
-
-
-typedef struct {
- GtkBorder radio_sizes;
- GtkBorder cont_sizes;
- GtkBorder num_buttons;
- GtkBorder last_num_buttons;
-
- GdkColor default_color;
-} HildonColorChooserStyleInfo;
-
-
-typedef struct _HildonColorChooserDialogHSV HildonColorChooserDialogHSV;
-typedef struct _HildonColorChooserDialogHSVClass HildonColorChooserDialogHSVClass;
-
-
-struct _HildonColorChooserDialogHSV {
- HildonColorChooserDialog parent;
-
- GtkWidget *hbox;
- GtkWidget *vbox;
-
- GtkWidget *align_custom, *align_defined;
- GtkWidget *area_custom, *area_defined;
- GtkWidget *separator;
-
- GtkWidget *chooser;
-
- GdkColor *colors_custom, *colors_defined;
- GdkGC **gc_array;
-
- gint selected;
-
- HildonColorChooserStyleInfo style_info;
-
-
- gint has_style;
-
- GdkColor pending_color;
-
-
- struct {
- GConfClient *client;
- } gconf_data;
-};
-
-struct _HildonColorChooserDialogHSVClass {
- HildonColorChooserDialogClass parent_klass;
-};
-
-
-#define HILDON_COLOR_CHOOSER_DIALOG_HSV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), export_type(), HildonColorChooserDialogHSV))
-#define HILDON_COLOR_CHOOSER_DIALOG_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), export_type(), HildonColorChooserDialogHSVClass))
-
-
-GtkType export_type(void);
-
-
-static void hildon_color_chooser_dialog_hsv_init(HildonColorChooserDialogHSV *object);
-static void hildon_color_chooser_dialog_hsv_class_init(HildonColorChooserDialogHSVClass *klass);
-
-static void hildon_color_chooser_dialog_hsv_size_request(GtkWidget *widget, GtkRequisition *req);
-static void hildon_color_chooser_dialog_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
-
-static void hildon_color_chooser_dialog_hsv_realize(GtkWidget *widget);
-static void hildon_color_chooser_dialog_hsv_unrealize(GtkWidget *widget);
-
-static void hildon_color_chooser_dialog_hsv_style_set(GtkWidget *widget, GtkStyle *previous_style);
-
-static void hildon_color_chooser_dialog_hsv_show(GtkWidget *widget);
-static void hildon_color_chooser_dialog_hsv_show_all(GtkWidget *widget);
-
-static gboolean hildon_color_chooser_dialog_hsv_key_press_event(GtkWidget *widget, GdkEventKey *event);
-static gboolean hildon_color_chooser_dialog_hsv_key_release_event(GtkWidget *widget, GdkEventKey *event);
-
-
-static void hildon_color_chooser_dialog_hsv_destroy(GtkObject *object);
-
-
-static void hildon_color_chooser_dialog_hsv_set_color(HildonColorChooserDialog *dialog, GdkColor *color);
-
-
-static gboolean hildon_color_chooser_dialog_hsv_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data);
-
-static gboolean hildon_color_chooser_dialog_hsv_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data);
-
-
-static void hildon_color_chooser_dialog_hsv_chooser_color_changed(HildonColorChooser *chooser, GdkColor *color, gpointer data);
-
-static void hildon_color_chooser_dialog_hsv_chooser_insensitive_press(GtkWidget *widget, gpointer data);
-
-
-static void hildon_color_chooser_dialog_hsv_refresh_style_info(HildonColorChooserDialogHSV *dialog);
-
-static void hildon_color_chooser_dialog_hsv_set_color_num(HildonColorChooserDialogHSV *dialog, gint num);
-
-static void hildon_color_chooser_dialog_hsv_ascii_hex_to_color(gchar *s, GdkColor *color);
-static void hildon_color_chooser_dialog_hsv_color_to_ascii_hex(gchar *s, GdkColor *color);
-
-
-GType export_type()
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info =
- {
- sizeof (HildonColorChooserDialogHSVClass),
- NULL,
- NULL,
- (GClassInitFunc) hildon_color_chooser_dialog_hsv_class_init,
- NULL,
- NULL,
- sizeof (HildonColorChooserDialogHSV),
- 0,
- (GInstanceInitFunc) hildon_color_chooser_dialog_hsv_init,
- NULL
- };
-
- dialog_type = g_type_register_static (HILDON_TYPE_COLOR_CHOOSER_DIALOG, "HildonColorChooserDialogHSV", &dialog_info, 0);
- }
-
- return dialog_type;
-}
-
-
-static void hildon_color_chooser_dialog_hsv_init(HildonColorChooserDialogHSV *object)
-{
- if(!chooser_plugin) {
- chooser_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER, "hsv");
- }
-
-
- gtk_dialog_set_has_separator(GTK_DIALOG(object), FALSE);
-
- gtk_window_set_title(GTK_WINDOW(object), _("ecdg_ti_colour_selector"));
-
-
- object->chooser = hildon_plugin_info_construct_widget(chooser_plugin);
-
- object->hbox = gtk_hbox_new(FALSE, 0);
- object->vbox = gtk_vbox_new(FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(object->hbox), object->chooser, TRUE, TRUE, 0);
- gtk_box_pack_end(GTK_BOX(object->hbox), object->vbox, FALSE, FALSE, 0);
-
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(object)->vbox), object->hbox, TRUE, TRUE, 0);
-
-
- object->align_custom = gtk_alignment_new(0.5, 1.0, 0.0, 0.0);
- object->align_defined = gtk_alignment_new(0.5, 1.0, 0.0, 0.0);
-
- object->area_custom = gtk_drawing_area_new();
- object->area_defined = gtk_drawing_area_new();
-
-
- gtk_container_add(GTK_CONTAINER(object->align_custom), object->area_custom);
- gtk_container_add(GTK_CONTAINER(object->align_defined), object->area_defined);
-
-
- object->separator = gtk_hseparator_new();
-
-
- gtk_box_pack_start(GTK_BOX(object->vbox), object->align_defined, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(object->vbox), object->separator, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(object->vbox), object->align_custom, FALSE, FALSE, 0);
-
-
- gtk_dialog_add_button(GTK_DIALOG(object), _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
- gtk_dialog_add_button(GTK_DIALOG(object), _("ecdg_bd_colour_selector_cancel"), GTK_RESPONSE_CANCEL);
- gtk_dialog_set_default_response (GTK_DIALOG (object), GTK_RESPONSE_OK);
-
-
- g_signal_connect(G_OBJECT(object->chooser), "insensitive-press", G_CALLBACK(hildon_color_chooser_dialog_hsv_chooser_insensitive_press), object);
-
-
- g_signal_connect(G_OBJECT(object->area_custom), "expose-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_expose), object);
- g_signal_connect(G_OBJECT(object->area_defined), "expose-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_expose), object);
-
- g_signal_connect(G_OBJECT(object->area_custom), "button-press-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_button_press), object);
- g_signal_connect(G_OBJECT(object->area_defined), "button-press-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_button_press), object);
-
- gtk_widget_add_events(object->area_custom, GDK_BUTTON_PRESS_MASK);
- gtk_widget_add_events(object->area_defined, GDK_BUTTON_PRESS_MASK);
-
-
- object->selected = 0;
-
-
- g_signal_connect(G_OBJECT(object->chooser), "color-changed", G_CALLBACK(hildon_color_chooser_dialog_hsv_chooser_color_changed), object);
-
-
- object->gconf_data.client = gconf_client_get_default();
-
-
- memset(&object->style_info, 0, sizeof(HildonColorChooserStyleInfo));
-
-
- object->colors_custom = NULL;
- object->colors_defined = NULL;
-
- object->gc_array = NULL;
-
-
- object->has_style = 0;
-}
-
-static void hildon_color_chooser_dialog_hsv_class_init(HildonColorChooserDialogHSVClass *klass)
-{
- GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS(klass);
- GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
- HildonColorChooserDialogClass *dialog_klass = HILDON_COLOR_CHOOSER_DIALOG_CLASS(klass);
- gchar tmp[32];
- gint i;
-
-
- widget_klass->size_request = hildon_color_chooser_dialog_hsv_size_request;
- widget_klass->size_allocate = hildon_color_chooser_dialog_hsv_size_allocate;
-
- widget_klass->realize = hildon_color_chooser_dialog_hsv_realize;
- widget_klass->unrealize = hildon_color_chooser_dialog_hsv_unrealize;
-
- widget_klass->style_set = hildon_color_chooser_dialog_hsv_style_set;
-
- widget_klass->show = hildon_color_chooser_dialog_hsv_show;
- widget_klass->show_all = hildon_color_chooser_dialog_hsv_show_all;
-
- widget_klass->key_press_event = hildon_color_chooser_dialog_hsv_key_press_event;
- widget_klass->key_release_event = hildon_color_chooser_dialog_hsv_key_release_event;
-
-
- object_klass->destroy = hildon_color_chooser_dialog_hsv_destroy;
-
-
- dialog_klass->set_color = hildon_color_chooser_dialog_hsv_set_color;
-
-
- parent_klass = g_type_class_peek_parent(klass);
-
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("container_sizes",
- "Container sizes",
- "Container specific sizes",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("radio_sizes",
- "Color radio sizes",
- "Color radio specific sizes",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("num_buttons",
- "Number of buttons",
- "Number of color store buttons",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("default_color", "Default color",
- "Default color for nonpainted custom colors",
- GDK_TYPE_COLOR,
- G_PARAM_READABLE));
-
-
- for(i = 0; i < 32; i++) {
- memset(tmp, 0, 32);
- g_snprintf(tmp, 32, "defined_color%d", i);
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed(tmp, "Defined color",
- "Pre-defined colors for the dialog",
- GDK_TYPE_COLOR,
- G_PARAM_READABLE));
- }
-}
-
-
-static void hildon_color_chooser_dialog_hsv_size_request(GtkWidget *widget, GtkRequisition *req)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
-
-
- gtk_container_set_border_width(GTK_CONTAINER(dialog->hbox), dialog->style_info.cont_sizes.left);
-
- gtk_box_set_spacing(GTK_BOX(dialog->hbox), dialog->style_info.cont_sizes.right);
- gtk_box_set_spacing(GTK_BOX(dialog->vbox), dialog->style_info.cont_sizes.top);
- gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(widget)->vbox), dialog->style_info.cont_sizes.bottom);
-
-
- gtk_widget_set_size_request(dialog->area_custom,
- (dialog->style_info.radio_sizes.left + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.top) +
- (dialog->style_info.num_buttons.top-1)*dialog->style_info.radio_sizes.top,
- (dialog->style_info.radio_sizes.right + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.bottom) +
- (dialog->style_info.num_buttons.bottom-1)*dialog->style_info.radio_sizes.top);
- gtk_widget_set_size_request(dialog->area_defined,
- (dialog->style_info.radio_sizes.left + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.left) +
- (dialog->style_info.num_buttons.left-1)*dialog->style_info.radio_sizes.top,
- (dialog->style_info.radio_sizes.right + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.right) +
- (dialog->style_info.num_buttons.right-1)*dialog->style_info.radio_sizes.top);
-
-
- GTK_WIDGET_CLASS(parent_klass)->size_request(widget, req);
-}
-
-static void hildon_color_chooser_dialog_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
- GdkRectangle rect;
- int i, tmp, tmp2;
-
-
- GTK_WIDGET_CLASS(parent_klass)->size_allocate(widget, alloc);
-
-
- if(GTK_WIDGET_REALIZED(widget)) {
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
- tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- rect.x = ((i % dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.y = ((i / dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.width = dialog->style_info.radio_sizes.left;
- rect.height = dialog->style_info.radio_sizes.right;
-
- gdk_gc_set_clip_rectangle(dialog->gc_array[i], &rect);
- }
-
- for(i = 0; i < tmp2; i++) {
- rect.x = ((i % dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.y = ((i / dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.width = dialog->style_info.radio_sizes.left;
- rect.height = dialog->style_info.radio_sizes.right;
-
- gdk_gc_set_clip_rectangle(dialog->gc_array[i + tmp], &rect);
- }
- }
-}
-
-
-static void hildon_color_chooser_dialog_hsv_realize(GtkWidget *widget)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
- GdkRectangle rect;
- int i, tmp, tmp2;
-
-
- GTK_WIDGET_CLASS(parent_klass)->realize(widget);
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
- (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- dialog->gc_array[i] = gdk_gc_new(widget->window);
- }
-
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
- tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- gdk_gc_set_rgb_fg_color(dialog->gc_array[i], &dialog->colors_defined[i]);
-
- rect.x = ((i % dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.y = ((i / dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.width = dialog->style_info.radio_sizes.left;
- rect.height = dialog->style_info.radio_sizes.right;
-
- gdk_gc_set_clip_rectangle(dialog->gc_array[i], &rect);
- }
-
- for(i = 0; i < tmp2; i++) {
- gdk_gc_set_rgb_fg_color(dialog->gc_array[i + tmp], &dialog->colors_custom[i]);
-
- rect.x = ((i % dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.y = ((i / dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
- 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
- rect.width = dialog->style_info.radio_sizes.left;
- rect.height = dialog->style_info.radio_sizes.right;
-
- gdk_gc_set_clip_rectangle(dialog->gc_array[i + tmp], &rect);
- }
-}
-
-static void hildon_color_chooser_dialog_hsv_unrealize(GtkWidget *widget)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
- int i, tmp;
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
- (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- g_object_unref(dialog->gc_array[i]);
- }
-
-
- GTK_WIDGET_CLASS(parent_klass)->unrealize(widget);
-}
-
-
-static void hildon_color_chooser_dialog_hsv_style_set(GtkWidget *widget, GtkStyle *previous_style)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
- GdkColor *tmpcolor;
- gchar tmp[32], key[128], *val;
- int i, tmpn, setcolor = 0;
-
-
- if(!dialog->has_style)
- setcolor = 1;
-
- dialog->has_style = 1;
-
-
- gtk_widget_style_get(widget, "default_color", &tmpcolor, NULL);
- if(tmpcolor) {
- dialog->style_info.default_color = *tmpcolor;
- } else {
- dialog->style_info.default_color.red = 0x0000;
- dialog->style_info.default_color.green = 0x0000;
- dialog->style_info.default_color.blue = 0x0000;
- dialog->style_info.default_color.pixel = 0x00000000;
- }
-
-
- hildon_color_chooser_dialog_hsv_refresh_style_info(dialog);
-
-
- if(memcmp(&dialog->style_info.num_buttons, &dialog->style_info.last_num_buttons, sizeof(GtkBorder))) {
- if(dialog->colors_custom) {
- g_free(dialog->colors_custom);
- } if(dialog->colors_defined) {
- g_free(dialog->colors_defined);
- } if(dialog->gc_array) {
- if(GTK_WIDGET_REALIZED(widget)) {
- tmpn = (dialog->style_info.last_num_buttons.left * dialog->style_info.last_num_buttons.right) +
- (dialog->style_info.last_num_buttons.top * dialog->style_info.last_num_buttons.bottom);
-
- for(i = 0; i < tmpn; i++) {
- g_object_unref(dialog->gc_array[i]);
- }
- }
-
- g_free(dialog->gc_array);
- }
-
- dialog->colors_custom = (GdkColor *)g_malloc0(sizeof(GdkColor) * (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom));
- dialog->colors_defined = (GdkColor *)g_malloc0(sizeof(GdkColor) * (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right));
-
-
- tmpn = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
- (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
- dialog->gc_array = (GdkGC **)g_malloc0(sizeof(GdkGC *) * tmpn);
-
-
- if(dialog->gconf_data.client) {
- for(i = 0; i < (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom); i++) {
- memset(key, 0, 128);
- g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
- val = gconf_client_get_string(dialog->gconf_data.client, key, NULL);
- if(val) {
- hildon_color_chooser_dialog_hsv_ascii_hex_to_color(val, &dialog->colors_custom[i]);
- g_free(val);
- } else {
- dialog->colors_custom[i] = dialog->style_info.default_color;
- }
- }
- } else {
- for(i = 0; i < (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom); i++) {
- dialog->colors_custom[i] = dialog->style_info.default_color;
- }
- }
- }
-
-
- tmpn = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
-
- hildon_color_chooser_set_color(HILDON_COLOR_CHOOSER(dialog->chooser),
- (dialog->selected < tmpn) ? &dialog->colors_defined[dialog->selected] : &dialog->colors_custom[dialog->selected - tmpn]);
-
-
- for(i = 0; i < (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right); i++) {
- memset(tmp, 0, 32);
- g_snprintf(tmp, 32, "defined_color%d", i);
-
- gtk_widget_style_get(widget, tmp, &tmpcolor, NULL);
-
- if(tmpcolor) {
- dialog->colors_defined[i] = *tmpcolor;
- } else {
- if(i < 16) {
- dialog->colors_defined[i] = hardcoded_colors[i];
- } else { /* fallback to prevent segfault */
- dialog->colors_defined[i].red = 0x0000;
- dialog->colors_defined[i].green = 0x0000;
- dialog->colors_defined[i].blue = 0x0000;
- dialog->colors_defined[i].pixel = 0x00000000;
- }
- }
- }
-
-
- if(GTK_WIDGET_REALIZED(widget)) {
- for(i = 0; i < (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right); i++) {
- gdk_gc_set_rgb_fg_color(dialog->gc_array[i], &dialog->colors_defined[i]);
- }
- }
-
-
- if(setcolor)
- hildon_color_chooser_dialog_hsv_set_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &dialog->pending_color);
-
-
- gtk_widget_queue_resize(widget);
-
-
- GTK_WIDGET_CLASS(parent_klass)->style_set(widget, previous_style);
-}
-
-
-static void hildon_color_chooser_dialog_hsv_show(GtkWidget *widget)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
-
-
- gtk_widget_show(dialog->hbox);
- gtk_widget_show(dialog->vbox);
-
- gtk_widget_show(dialog->chooser);
-
- gtk_widget_show(dialog->align_custom);
- gtk_widget_show(dialog->align_defined);
-
- gtk_widget_show(dialog->separator);
-
- gtk_widget_show(dialog->area_custom);
- gtk_widget_show(dialog->area_defined);
-
-
- GTK_WIDGET_CLASS(parent_klass)->show(widget);
-}
-
-static void hildon_color_chooser_dialog_hsv_show_all(GtkWidget *widget)
-{
- hildon_color_chooser_dialog_hsv_show(widget);
-}
-
-
-static gboolean hildon_color_chooser_dialog_hsv_key_press_event(GtkWidget *widget, GdkEventKey *event)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
- int tmp, tot, sel;
-
-
- if(event->keyval == HILDON_HARDKEY_UP || event->keyval == HILDON_HARDKEY_DOWN ||
- event->keyval == HILDON_HARDKEY_LEFT || event->keyval == HILDON_HARDKEY_RIGHT) {
- tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
- tot = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) + tmp;
-
- switch(event->keyval) {
- case HILDON_HARDKEY_UP:
- if(dialog->selected >= dialog->style_info.num_buttons.top) {
- if(dialog->selected - dialog->style_info.num_buttons.left >= tmp) {
- sel = dialog->selected - dialog->style_info.num_buttons.left;
- } else {
- sel = dialog->selected - dialog->style_info.num_buttons.top;
- }
-
- hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
- }
- break;
- case HILDON_HARDKEY_DOWN:
- if(dialog->selected < tot - dialog->style_info.num_buttons.left) {
- if(dialog->selected < tmp) {
- sel = dialog->selected + dialog->style_info.num_buttons.top;
- } else {
- sel = dialog->selected + dialog->style_info.num_buttons.left;
- }
-
- hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
- }
- break;
- case HILDON_HARDKEY_LEFT:
- if((dialog->selected < tmp ? (dialog->selected % dialog->style_info.num_buttons.top) : ((dialog->selected - tmp) % dialog->style_info.num_buttons.left)) > 0) {
- sel = dialog->selected - 1;
-
- hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
- }
- break;
- case HILDON_HARDKEY_RIGHT:
- if((dialog->selected < tmp) ? (dialog->selected % dialog->style_info.num_buttons.top < dialog->style_info.num_buttons.top - 1) :
- ((dialog->selected - tmp) % dialog->style_info.num_buttons.left < dialog->style_info.num_buttons.left - 1)) {
- sel = dialog->selected + 1;
-
- hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
- }
- break;
- default:
- break;
- }
-
- return FALSE;
- }
-
- return GTK_WIDGET_CLASS(parent_klass)->key_press_event(widget, event);
-}
-
-static gboolean hildon_color_chooser_dialog_hsv_key_release_event(GtkWidget *widget, GdkEventKey *event)
-{
- if(event->keyval == HILDON_HARDKEY_UP || event->keyval == HILDON_HARDKEY_DOWN ||
- event->keyval == HILDON_HARDKEY_LEFT || event->keyval == HILDON_HARDKEY_RIGHT) {
- return FALSE;
- }
-
- return GTK_WIDGET_CLASS(parent_klass)->key_press_event(widget, event);
-}
-
-
-static void hildon_color_chooser_dialog_hsv_destroy(GtkObject *object)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(object);
- gchar key[128], color[13];
- int i, tmp;
-
-
- if(dialog->gconf_data.client) {
- memset(color, 0, 13);
-
- tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- memset(key, 0, 128);
- g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
- hildon_color_chooser_dialog_hsv_color_to_ascii_hex(color, &dialog->colors_custom[i]);
- gconf_client_set_string(dialog->gconf_data.client, key, color, NULL);
- }
-
- g_object_unref(dialog->gconf_data.client);
- dialog->gconf_data.client = NULL;
- }
-
-
- if(dialog->gc_array) {
- g_free(dialog->gc_array);
- dialog->gc_array = NULL;
- } if(dialog->colors_defined) {
- g_free(dialog->colors_defined);
- dialog->colors_defined = NULL;
- } if(dialog->colors_custom) {
- g_free(dialog->colors_custom);
- dialog->colors_custom = NULL;
- }
-
-
- GTK_OBJECT_CLASS(parent_klass)->destroy(object);
-}
-
-
-static void hildon_color_chooser_dialog_hsv_set_color(HildonColorChooserDialog *dialog, GdkColor *color)
-{
- HildonColorChooserDialogHSV *dialog_hsv = HILDON_COLOR_CHOOSER_DIALOG_HSV(dialog);
- int i, found = -1, tmp, tmp2;
-
-
- if(!dialog_hsv->has_style) {
- dialog_hsv->pending_color = *color;
- return;
- }
-
-
- tmp = (dialog_hsv->style_info.num_buttons.left * dialog_hsv->style_info.num_buttons.right);
- tmp2 = (dialog_hsv->style_info.num_buttons.top * dialog_hsv->style_info.num_buttons.bottom);
-
- for(i = 0; i < tmp; i++) {
- if(dialog_hsv->colors_defined[i].red == color->red &&
- dialog_hsv->colors_defined[i].green == color->green &&
- dialog_hsv->colors_defined[i].blue == color->blue) {
- found = i;
- break;
- }
- }
-
- if(found == -1) {
- for(i = 0; i < tmp2; i++) {
- if(dialog_hsv->colors_custom[i].red == color->red &&
- dialog_hsv->colors_custom[i].green == color->green &&
- dialog_hsv->colors_custom[i].blue == color->blue) {
- found = i + tmp;
- break;
- }
- }
- }
-
-
- if(found == -1) {
- dialog_hsv->colors_custom[tmp2-1] = *color;
- if(GTK_WIDGET_REALIZED(GTK_WIDGET(dialog))) {
- gdk_gc_set_rgb_fg_color(dialog_hsv->gc_array[tmp2-1], color);
- }
- hildon_color_chooser_dialog_hsv_set_color_num(dialog_hsv, tmp2-1);
- } else {
- hildon_color_chooser_dialog_hsv_set_color_num(dialog_hsv, found);
- }
-}
-
-
-static gboolean hildon_color_chooser_dialog_hsv_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
- int i, num_selected, tot_w, tot_h, spacing, brd, x, y;
- GdkGC **start_gc;
- int tmp, w, h;
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
-
- if(widget == dialog->area_custom) {
- num_selected = dialog->selected - tmp;
- start_gc = dialog->gc_array + tmp;
- tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
- w = dialog->style_info.num_buttons.top; h = dialog->style_info.num_buttons.bottom;
- } else { /* widget == dialog->area_defined */
- num_selected = dialog->selected;
- start_gc = dialog->gc_array;
- w = dialog->style_info.num_buttons.left; h = dialog->style_info.num_buttons.right;
- }
-
- spacing = dialog->style_info.radio_sizes.top;
- brd = dialog->style_info.radio_sizes.bottom;
- tot_w = dialog->style_info.radio_sizes.left + 2*brd;
- tot_h = dialog->style_info.radio_sizes.right + 2*brd;
-
-
- for(i = 0; i < tmp; i++) {
- x = ((i % w) * (tot_w + spacing));
- y = ((i / w) * (tot_h + spacing));
-
- gdk_draw_rectangle(widget->window,
- widget->style->black_gc,
- TRUE,
- (i == num_selected) ? x : x + 2,
- (i == num_selected) ? y : y + 2,
- (i == num_selected) ? tot_w : tot_w - 4,
- (i == num_selected) ? tot_h : tot_h - 4);
-
- gdk_draw_rectangle(widget->window,
- widget->style->white_gc,
- TRUE,
- x + 3,
- y + 3,
- tot_w - 6,
- tot_h - 6);
-
- gdk_draw_rectangle(widget->window,
- start_gc [i],
- TRUE,
- x + 3 + 1,
- y + 3 + 1,
- tot_w - 6 - 2,
- tot_h - 6 - 2);
-
-// gtk_paint_box(gtk_widget_get_style(GTK_WIDGET(dialog)), widget->window, (i == num_selected) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL,
-// (i == num_selected) ? GTK_SHADOW_IN : GTK_SHADOW_OUT, &event->area, GTK_WIDGET(dialog), "color-radio", x, y, tot_w, tot_h);
- //}
-
- //gdk_draw_rectangle(widget->window, start_gc[i], TRUE, event->area.x, event->area.y, event->area.width, event->area.height);
- }
-
-
- return FALSE;
-}
-
-
-static gboolean hildon_color_chooser_dialog_hsv_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
- int i, hskip, vskip, brd, selection = -1;
- int x, y, tmp, tmp2, w;
-
-
- x = event->x;
- y = event->y;
-
-
- brd = dialog->style_info.radio_sizes.bottom;
- hskip = dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top + 2*brd;
- vskip = dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top + 2*brd;
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
- tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
-
-
- if(widget == dialog->area_defined) {
- w = dialog->style_info.num_buttons.left;
-
- for(i = 0; i < tmp; i++) {
- if(x >= hskip*(i % w) + brd && x < hskip*(i % w) + brd + dialog->style_info.radio_sizes.left &&
- y >= vskip*(i / w) + brd && y < hskip*(i / w) + brd + dialog->style_info.radio_sizes.right) {
- selection = i;
- break;
- }
- }
- } else {
- w = dialog->style_info.num_buttons.top;
- for(i = 0; i < tmp2; i++) {
- if(x >= hskip*(i % w) + brd && x < hskip*(i % w) + brd + dialog->style_info.radio_sizes.left &&
- y >= vskip*(i / w) + brd && y < hskip*(i / w) + brd + dialog->style_info.radio_sizes.right) {
- selection = i + tmp;
- break;
- }
- }
- }
-
-
- if(selection != -1) {
- hildon_color_chooser_dialog_hsv_set_color_num(dialog, selection);
- }
-
-
- return FALSE;
-}
-
-
-static void hildon_color_chooser_dialog_hsv_chooser_color_changed(HildonColorChooser *chooser, GdkColor *color, gpointer data)
-{
- HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
- HildonColorChooserDialog *dia = HILDON_COLOR_CHOOSER_DIALOG(data);
- char key[128], color_str[13];
- int tmp;
-
-
- dia->color = *color;
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
-
-
- if(dialog->selected >= tmp) {
- dialog->colors_custom[dialog->selected - tmp] = *color;
-
- gdk_gc_set_rgb_fg_color(dialog->gc_array[dialog->selected], &dialog->colors_custom[dialog->selected - tmp]);
-
- gtk_widget_queue_draw(dialog->area_custom);
-
-
- if(dialog->gconf_data.client) {
- memset(key, 0, 128);
- memset(color_str, 0, 13);
- g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", dialog->selected - tmp);
- hildon_color_chooser_dialog_hsv_color_to_ascii_hex(color_str, &dialog->colors_custom[dialog->selected - tmp]);
- gconf_client_set_string(dialog->gconf_data.client, key, color_str, NULL);
- }
- }
-}
-
-
-static void hildon_color_chooser_dialog_hsv_chooser_insensitive_press(GtkWidget *widget, gpointer data)
-{
- hildon_banner_show_information(widget, NULL, _("ecdg_ib_colour_selector_predefined"));
-}
-
- /* function has size defaults */
-static void hildon_color_chooser_dialog_hsv_refresh_style_info(HildonColorChooserDialogHSV *dialog)
-{
- GtkBorder *tmp1, *tmp2, *tmp3;
-
-
- gtk_widget_style_get(GTK_WIDGET(dialog), "container_sizes", &tmp1,
- "radio_sizes", &tmp2, "num_buttons", &tmp3, NULL);
-
-
- dialog->style_info.last_num_buttons = dialog->style_info.num_buttons;
-
-
- if(tmp1) {
- dialog->style_info.cont_sizes = *tmp1;
- g_free(tmp1);
- } else {
- dialog->style_info.cont_sizes.left = 0;
- dialog->style_info.cont_sizes.right = 8;
- dialog->style_info.cont_sizes.top = 4;
- dialog->style_info.cont_sizes.bottom = 0;
- }
-
- if(tmp2) {
- dialog->style_info.radio_sizes = *tmp2;
- g_free(tmp2);
- } else {
- dialog->style_info.radio_sizes.left = 16;
- dialog->style_info.radio_sizes.right = 16;
- dialog->style_info.radio_sizes.top = 4;
- dialog->style_info.radio_sizes.bottom = 2;
- }
-
- if(tmp3) {
- dialog->style_info.num_buttons = *tmp3;
- g_free(tmp3);
- } else {
- dialog->style_info.num_buttons.left = 8;
- dialog->style_info.num_buttons.right = 2;
- dialog->style_info.num_buttons.top = 8;
- dialog->style_info.num_buttons.bottom = 2;
- }
-}
-
-
-static void hildon_color_chooser_dialog_hsv_set_color_num(HildonColorChooserDialogHSV *dialog, gint num)
-{
- HildonColorChooserDialog *dia = HILDON_COLOR_CHOOSER_DIALOG(dialog);
- int tmp;
-
-
- tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
-
-
- if(num < tmp) {
- gtk_widget_set_sensitive(dialog->chooser, FALSE);
- } else {
- gtk_widget_set_sensitive(dialog->chooser, TRUE);
- }
-
-
- dialog->selected = num;
-
- gtk_widget_queue_draw(dialog->area_custom);
- gtk_widget_queue_draw(dialog->area_defined);
-
- dia->color = (num < tmp) ? dialog->colors_defined[num] : dialog->colors_custom[num - tmp];
-
- hildon_color_chooser_set_color(HILDON_COLOR_CHOOSER(dialog->chooser), (num < tmp) ? &dialog->colors_defined[num] : &dialog->colors_custom[num - tmp]);
-}
-
-
-static void hildon_color_chooser_dialog_hsv_ascii_hex_to_color(gchar *s, GdkColor *color)
-{
- int vals[12], i;
-
-
- for(i = 0; i < 12; i++) {
- if(s[i] >= '0' && s[i] <= '9') {
- vals[i] = s[i] - 0x30;
- } else if(s[i] >= 'a' && s[i] <= 'f') {
- vals[i] = s[i] - 0x57;
- } else {
- vals[i] = 0;
- }
- }
-
-
- color->red = (vals[0] << 12) | (vals[1] << 8) | (vals[2 ] << 4) | (vals[3 ] );
- color->green = (vals[4] << 12) | (vals[5] << 8) | (vals[6 ] << 4) | (vals[7 ] );
- color->blue = (vals[8] << 12) | (vals[9] << 8) | (vals[10] << 4) | (vals[11] );
-}
-
-static void hildon_color_chooser_dialog_hsv_color_to_ascii_hex(gchar *s, GdkColor *color)
-{
- g_snprintf(s, 13, "%x%x%x%x%x%x%x%x%x%x%x%x",
- (color->red >> 12) & 0xf, (color->red >> 8) & 0xf,
- (color->red >> 4) & 0xf, (color->red ) & 0xf,
- (color->green >> 12) & 0xf, (color->green >> 8) & 0xf,
- (color->green >> 4) & 0xf, (color->green ) & 0xf,
- (color->blue >> 12) & 0xf, (color->blue >> 8) & 0xf,
- (color->blue >> 4) & 0xf, (color->blue ) & 0xf);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <gtk/gtk.h>
-
-#include <hildon-widgets/hildon-color-chooser.h>
-
-
-const char *parent_name = "HildonColorChooser";
-const char *plugin_name = "HSV color chooser";
-
-GType export_type(void);
-
-
-typedef struct {
- HildonColorChooser parent;
-
- GtkAllocation hba;
- GtkAllocation spa;
-
- unsigned short currhue;
- unsigned short currsat;
- unsigned short currval;
-
- int mousestate;
- gboolean mousein;
-
-
- GdkWindow *event_window;
-
- GdkPixbuf *dimmed_plane;
- GdkPixbuf *dimmed_bar;
-
- struct {
- unsigned short last_expose_hue;
-
- GTimeVal last_expose_time;
-
- int expose_queued;
- } expose_info;
-} HildonColorChooserHSV;
-
-typedef struct {
- HildonColorChooserClass parent;
-} HildonColorChooserHSVClass;
-
-
-#define HILDON_COLOR_CHOOSER_HSV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), export_type(), HildonColorChooserHSV))
-#define HILDON_COLOR_CHOOSER_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), export_type(), HildonColorChooserHSVClass))
-
-
-static HildonColorChooserClass *parent_class = NULL;
-
-
- /* "crosshair" is hardcoded for now */
-static gchar crosshair[64] = { 0, 0, 0, 2, 2, 0, 0, 0,
- 0, 2, 2, 3, 3, 2, 2, 0,
- 0, 2, 3, 0, 0, 3, 2, 0,
- 2, 3, 0, 0, 0, 0, 3, 2,
- 2, 3, 0, 0, 0, 0, 3, 2,
- 0, 2, 3, 0, 0, 3, 2, 0,
- 0, 2, 2, 3, 3, 2, 2, 0,
- 0, 0, 0, 2, 2, 0, 0, 0};
-
-
-static void hildon_color_chooser_hsv_init(HildonColorChooserHSV *sel);
-static void hildon_color_chooser_hsv_class_init(HildonColorChooserHSVClass *klass);
-
-static void hildon_color_chooser_hsv_dispose(HildonColorChooserHSV *sel);
-
-static void hildon_color_chooser_hsv_size_request(GtkWidget *widget, GtkRequisition *req);
-static void hildon_color_chooser_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
-
-static void hildon_color_chooser_hsv_realize(GtkWidget *widget);
-
-static void hildon_color_chooser_hsv_map(GtkWidget *widget);
-static void hildon_color_chooser_hsv_unmap(GtkWidget *widget);
-
-static gboolean hildon_color_chooser_hsv_expose(GtkWidget *widget, GdkEventExpose *event);
-
-static gboolean hildon_color_chooser_button_press(GtkWidget *widget, GdkEventButton *event);
-static gboolean hildon_color_chooser_button_release(GtkWidget *widget, GdkEventButton *event);
-static gboolean hildon_color_chooser_pointer_motion(GtkWidget *widget, GdkEventMotion *event);
-
-static void hildon_color_chooser_hsv_set_color(HildonColorChooser *sel, GdkColor *color);
-
-
-static void internal_get_border(GtkWidget *w, char *name, GtkBorder *b);
-static void _internal_init_borders(GtkWidget *w, GtkBorder *inner, GtkBorder *outer);
-
-static void internal_invoke_color_changed(HildonColorChooserHSV *sel);
-
-
-inline void inline_clip_to_alloc(void *s, GtkAllocation *a);
-
-inline void inline_sub_times(GTimeVal *result, GTimeVal *greater, GTimeVal *lesser);
-
-inline void inline_limited_expose(HildonColorChooserHSV *sel);
-
-inline void inline_draw_hue_bar(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh);
-inline void inline_draw_hue_bar_dimmed(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh);
-
-inline void inline_draw_sv_plane(HildonColorChooserHSV *sel, int x, int y, int w, int h);
-inline void inline_draw_sv_plane_dimmed(HildonColorChooserHSV *sel, int x, int y, int w, int h);
-
-inline void inline_draw_crosshair(unsigned char *buf, int x, int y, int w, int h);
-
-
-inline void inline_h2rgb(unsigned short hue, unsigned long *rgb);
-
-
-static gboolean hildon_color_chooser_hsv_expose_timer(gpointer data);
-
-
-GType export_type()
-{
- static GType chooser_type = 0;
-
- if (!chooser_type) {
- static const GTypeInfo chooser_info =
- {
- sizeof (HildonColorChooserHSVClass),
- NULL,
- NULL,
- (GClassInitFunc) hildon_color_chooser_hsv_class_init,
- NULL,
- NULL,
- sizeof (HildonColorChooserHSV),
- 0,
- (GInstanceInitFunc) hildon_color_chooser_hsv_init,
- NULL
- };
-
- chooser_type = g_type_register_static (HILDON_TYPE_COLOR_CHOOSER,
- "HildonColorChooserHSV",
- &chooser_info, 0);
- }
-
- return chooser_type;
-}
-
-static void hildon_color_chooser_hsv_init(HildonColorChooserHSV *sel)
-{
- GTK_WIDGET_SET_FLAGS (sel, GTK_NO_WINDOW);
-
-
- sel->currhue = 0;
- sel->currsat = 0;
- sel->currval = 0;
-
- sel->mousestate = 0;
- sel->mousein = FALSE;
-
-
- g_get_current_time(&sel->expose_info.last_expose_time);
-
- sel->expose_info.last_expose_hue = sel->currhue;
- sel->expose_info.expose_queued = 0;
-
- sel->dimmed_plane = NULL;
- sel->dimmed_bar = NULL;
-}
-
-static void hildon_color_chooser_hsv_class_init(HildonColorChooserHSVClass *klass)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- GObjectClass *object_class = G_OBJECT_CLASS(klass);
-
- HildonColorChooserClass *selection_class = HILDON_COLOR_CHOOSER_CLASS(klass);
-
-
- parent_class = g_type_class_peek_parent(klass);
-
-
- object_class->dispose = (gpointer) hildon_color_chooser_hsv_dispose;
-
- widget_class->size_request = hildon_color_chooser_hsv_size_request;
- widget_class->size_allocate = hildon_color_chooser_hsv_size_allocate;
-
- widget_class->realize = hildon_color_chooser_hsv_realize;
-
- widget_class->map = hildon_color_chooser_hsv_map;
- widget_class->unmap = hildon_color_chooser_hsv_unmap;
-
- widget_class->expose_event = hildon_color_chooser_hsv_expose;
-
- widget_class->button_press_event = hildon_color_chooser_button_press;
- widget_class->button_release_event = hildon_color_chooser_button_release;
- widget_class->motion_notify_event = hildon_color_chooser_pointer_motion;
-
-
- selection_class->set_color = hildon_color_chooser_hsv_set_color;
-
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_boxed("inner_size",
- "Inner sizes",
- "Sizes of SV plane, H bar and spacing",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_boxed("graphic_border",
- "Graphical borders",
- "Size of graphical border",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-}
-
-
-static void hildon_color_chooser_hsv_dispose(HildonColorChooserHSV *sel)
-{
- if (sel->dimmed_bar != NULL) {
- g_object_unref (sel->dimmed_bar);
- sel->dimmed_bar = NULL;
- }
-
- if (sel->dimmed_plane != NULL) {
- g_object_unref (sel->dimmed_plane);
- sel->dimmed_plane = NULL;
- }
-
- G_OBJECT_CLASS(parent_class)->dispose(sel);
-}
-
-static void hildon_color_chooser_hsv_size_request(GtkWidget *widget, GtkRequisition *req)
-{
- GtkBorder inner, outer;
-
-
- _internal_init_borders(widget, &inner, &outer);
-
-
- req->width = inner.left + inner.top + inner.bottom + outer.left + outer.right;
- req->height = inner.right + outer.top + outer.bottom;
-}
-
-static void hildon_color_chooser_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- GtkBorder outer, inner;
-
-
- widget->allocation = *alloc;
-
-
- _internal_init_borders(widget, &inner, &outer);
-
-
- sel->hba.height = alloc->height - outer.top - outer.bottom;
- sel->hba.y = alloc->y + outer.top;
- sel->hba.width = inner.top;
- sel->hba.x = alloc->x + alloc->width - outer.right - inner.top;
-
- sel->spa.x = alloc->x + outer.left;
- sel->spa.y = alloc->y + outer.top;
- sel->spa.height = alloc->height - outer.top - outer.bottom;
- sel->spa.width = alloc->width - outer.left - outer.right - inner.top - inner.bottom;
-
- if(GTK_WIDGET_REALIZED(widget)) {
- gdk_window_move_resize(sel->event_window, widget->allocation.x, widget->allocation.y, widget->allocation.width, widget->allocation.height);
- }
-}
-
-
-static void hildon_color_chooser_hsv_realize(GtkWidget *widget)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- GdkWindowAttr attributes;
- gint attributes_mask;
-
- attributes.x = widget->allocation.x;
- attributes.y = widget->allocation.y;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
- attributes.wclass = GDK_INPUT_ONLY;
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK |
- GDK_BUTTON1_MOTION_MASK;
- attributes.visual = gtk_widget_get_visual(widget);
- attributes.colormap = gtk_widget_get_colormap(widget);
-
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_WMCLASS;
- sel->event_window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
-
-
- gdk_window_set_user_data(sel->event_window, widget);
-
-
- widget->window = gtk_widget_get_parent_window(widget);
-
-
- widget->style = gtk_style_attach(widget->style, widget->window);
-
-
- GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-}
-
-
-static void hildon_color_chooser_hsv_map(GtkWidget *widget)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
-
-
- GTK_WIDGET_CLASS(parent_class)->map(widget);
-
- if(sel->event_window) {
- gdk_window_show(sel->event_window);
- }
-}
-
-static void hildon_color_chooser_hsv_unmap(GtkWidget *widget)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
-
-
- if(sel->event_window) {
- gdk_window_hide(sel->event_window);
- }
-
- GTK_WIDGET_CLASS(parent_class)->unmap(widget);
-}
-
-
-inline void inline_clip_to_alloc(void *s, GtkAllocation *a)
-{
- struct {
- int x, y, w, h;
- } *area = s;
-
-
- if(area->x < a->x) {
- area->w -= a->x - area->x;
- area->x = a->x;
- } if(area->y < a->y) {
- area->h -= a->y - area->y;
- area->y = a->y;
- }
- if(area->x + area->w > a->x + a->width) area->w = a->width - (area->x - a->x);
- if(area->y + area->h > a->y + a->height) area->h = a->height - (area->y - a->y);
-}
-
-static gboolean hildon_color_chooser_hsv_expose(GtkWidget *widget, GdkEventExpose *event)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- GtkBorder graphical_border;
- struct {
- int x, y, w, h;
- } area;
-
-
- if(!GTK_WIDGET_REALIZED(widget)) {
- return FALSE;
- }
-
-
- internal_get_border(widget, "graphic_border", &graphical_border);
-
-
- if(event->area.width || event->area.height) {
- gdk_draw_rectangle(widget->window,
- widget->style->black_gc,
- FALSE,
- sel->hba.x - 2,
- sel->hba.y - 2,
- sel->hba.width + 3,
- sel->hba.height + 3);
-
- gdk_draw_rectangle(widget->window,
- widget->style->black_gc,
- FALSE,
- sel->spa.x - 2,
- sel->spa.y - 2,
- sel->spa.width + 3,
- sel->spa.height + 3);
- }
-
- if(sel->expose_info.expose_queued) {
- if(GTK_WIDGET_SENSITIVE(widget)) {
- inline_draw_hue_bar(widget, sel->hba.x, sel->hba.y, sel->hba.width, sel->hba.height, sel->hba.y, sel->hba.height);
-
- inline_draw_sv_plane(sel, sel->spa.x, sel->spa.y, sel->spa.width, sel->spa.height);
- } else {
- inline_draw_hue_bar_dimmed(widget, sel->hba.x, sel->hba.y, sel->hba.width, sel->hba.height, sel->hba.y, sel->hba.height);
-
- inline_draw_sv_plane_dimmed(sel, sel->spa.x, sel->spa.y, sel->spa.width, sel->spa.height);
- }
-
-
- sel->expose_info.expose_queued = 0;
-
- g_get_current_time(&sel->expose_info.last_expose_time);
- } else {
- /* clip hue bar region */
- area.x = event->area.x;
- area.y = event->area.y;
- area.w = event->area.width;
- area.h = event->area.height;
-
- inline_clip_to_alloc(&area, &sel->hba);
-
- if(GTK_WIDGET_SENSITIVE(widget)) {
- inline_draw_hue_bar(widget, area.x, area.y, area.w, area.h, sel->hba.y, sel->hba.height);
- } else {
- inline_draw_hue_bar_dimmed(widget, area.x, area.y, area.w, area.h, sel->hba.y, sel->hba.height);
- }
-
-
- area.x = event->area.x;
- area.y = event->area.y;
- area.w = event->area.width;
- area.h = event->area.height;
-
- inline_clip_to_alloc(&area, &sel->spa);
-
- if(GTK_WIDGET_SENSITIVE(widget)) {
- inline_draw_sv_plane(sel, area.x, area.y, area.w, area.h);
- } else {
- inline_draw_sv_plane_dimmed(sel, area.x, area.y, area.w, area.h);
- }
- }
-
-
- return FALSE;
-}
-
-
-inline void inline_sub_times(GTimeVal *result, GTimeVal *greater, GTimeVal *lesser)
-{
- result->tv_sec = greater->tv_sec - lesser->tv_sec;
- result->tv_usec = greater->tv_usec - lesser->tv_usec;
-
- if(result->tv_usec < 0) {
- result->tv_sec--;
- result->tv_usec += 1000000;
- }
-}
-
-#define EXPOSE_INTERVAL 50000
-inline void inline_limited_expose(HildonColorChooserHSV *sel)
-{
- GTimeVal curr_time, result;
- GdkEventExpose event;
-
-
- if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sel))) {
- return;
- }
-
-
- if(sel->currhue == sel->expose_info.last_expose_hue) {
- return; /* no need to redraw */
- }
-
-
- sel->expose_info.last_expose_hue = sel->currhue;
-
-
- g_get_current_time(&curr_time);
-
- inline_sub_times(&result, &curr_time, &sel->expose_info.last_expose_time);
-
- if(result.tv_sec != 0 || result.tv_usec >= EXPOSE_INTERVAL) {
- sel->expose_info.expose_queued = 1;
-
-#if 1
- event.type = GDK_EXPOSE;
- event.area.width = 0;
- event.area.height = 0;
- event.window = GTK_WIDGET(sel)->window;
-
- gtk_widget_send_expose(GTK_WIDGET(sel), (GdkEvent *)&event);
-#else
- gtk_widget_queue_draw(GTK_WIDGET(sel));
-#endif
- } else if(!sel->expose_info.expose_queued) {
- sel->expose_info.expose_queued = 1;
-
-
- g_timeout_add((EXPOSE_INTERVAL - result.tv_usec)/1000, hildon_color_chooser_hsv_expose_timer, sel);
- }
-}
-
-static gboolean hildon_color_chooser_button_press(GtkWidget *widget, GdkEventButton *event)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- int x, y, tmp;
-
-
- x = (int)event->x + widget->allocation.x;
- y = (int)event->y + widget->allocation.y;
-
-
- if(x >= sel->spa.x && x <= sel->spa.x + sel->spa.width &&
- y >= sel->spa.y && y <= sel->spa.y + sel->spa.height) {
- tmp = y - sel->spa.y;
- sel->currsat = tmp * 0xffff / sel->spa.height;
- tmp = x - sel->spa.x;
- sel->currval = tmp * 0xffff / sel->spa.width;
-
- internal_invoke_color_changed(sel);
- gtk_widget_queue_draw(widget);
-
- sel->mousestate = 1;
- sel->mousein = TRUE;
-
- gtk_grab_add(widget);
- } else if(x >= sel->hba.x && x <= sel->hba.x + sel->hba.width &&
- y >= sel->hba.y && y <= sel->hba.y + sel->hba.height) {
- tmp = y - sel->hba.y;
- sel->currhue = tmp * 0xffff / sel->hba.height;
-
- internal_invoke_color_changed(sel);
- inline_limited_expose(sel);
-
- sel->mousestate = 2;
- sel->mousein = TRUE;
-
- gtk_grab_add(widget);
- }
-
-
- return FALSE;
-}
-
-static gboolean hildon_color_chooser_button_release(GtkWidget *widget, GdkEventButton *event)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
-
-
- if(sel->mousestate) {
- gtk_grab_remove(widget);
- }
-
-
- sel->mousestate = 0;
- sel->mousein = FALSE;
-
-
- return FALSE;
-}
-
-static gboolean hildon_color_chooser_pointer_motion(GtkWidget *widget, GdkEventMotion *event)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- GdkModifierType mods;
- gint x, y, tmp;
-
-
- if (event->is_hint || (event->window != widget->window))
- gdk_window_get_pointer (widget->window, &x, &y, &mods);
-
-
- if(sel->mousestate == 1) {
- if(x >= sel->spa.x && x <= sel->spa.x + sel->spa.width &&
- y >= sel->spa.y && y <= sel->spa.y + sel->spa.height) {
- sel->currsat = (((long)(y - sel->spa.y)) * 0xffff)/sel->spa.height;
- sel->currval = (((long)(x - sel->spa.x)) * 0xffff)/sel->spa.width;
-
- internal_invoke_color_changed(sel);
- gtk_widget_queue_draw(widget);
- } else if(sel->mousein == TRUE) {
- }
- } else if(sel->mousestate == 2) {
- if(x >= sel->hba.x && x <= sel->hba.x + sel->hba.width &&
- y >= sel->hba.y && y <= sel->hba.y + sel->hba.height) {
- tmp = y - sel->hba.y;
- tmp *= 0xffff;
- tmp /= sel->hba.height;
-
- if(tmp != sel->currhue) {
- sel->currhue = tmp;
-
- internal_invoke_color_changed(sel);
- inline_limited_expose(sel);
- }
- } else if(sel->mousein == TRUE) {
- }
- }
-
- return FALSE;
-}
-
-
-static void internal_get_border(GtkWidget *w, char *name, GtkBorder *b)
-{
- GtkBorder *tb;
-
- gtk_widget_style_get(w, name, &tb, NULL);
-
- if(tb) {
- *b = *tb;
- g_free(tb);
- } else {
- b->left = 0;
- b->right = 0;
- b->top = 0;
- b->bottom = 0;
- }
-}
-
-
-static void _internal_init_borders(GtkWidget *w, GtkBorder *inner, GtkBorder *outer)
-{
- GtkBorder *tb;
-
-
- internal_get_border(w, "outer_border", outer);
-
-
- gtk_widget_style_get(w, "inner_size", &tb, NULL);
-
- if(tb) {
- *inner = *tb;
- g_free(tb);
- } else {
- inner->left = 64;
- inner->right = 64;
- inner->top = 12;
- inner->bottom = 2;
- }
-
- if(inner->left < 2) inner->left = 2;
- if(inner->right < 2) inner->right = 2;
- if(inner->top < 2) inner->top = 2;
-}
-
- /* calculate RGB color & emit signal */
-static void internal_invoke_color_changed(HildonColorChooserHSV *sel)
-{
- HildonColorChooser *parent_sel = HILDON_COLOR_CHOOSER(sel);
- GdkVisual *system_visual = gdk_visual_get_system();
- unsigned long rgb[3], rgb2[3];
-
-
- inline_h2rgb(sel->currhue, rgb);
-
- rgb2[0] = 0xffffff - rgb[0];
- rgb2[1] = 0xffffff - rgb[1];
- rgb2[2] = 0xffffff - rgb[2];
-
-
- parent_sel->color.red = ((rgb[0] >> 8) + ((rgb2[0] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
- parent_sel->color.green = ((rgb[1] >> 8) + ((rgb2[1] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
- parent_sel->color.blue = ((rgb[2] >> 8) + ((rgb2[2] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
-
- parent_sel->color.pixel = ((parent_sel->color.red >> (16 - system_visual->red_prec)) << system_visual->red_shift) |
- ((parent_sel->color.green >> (16 - system_visual->green_prec)) << system_visual->green_shift) |
- ((parent_sel->color.blue >> (16 - system_visual->blue_prec)) << system_visual->blue_shift);
-
-
- hildon_color_chooser_emit_color_changed(HILDON_COLOR_CHOOSER(sel));
-}
-
- /* do the RGB -> HSV conversion here, not so time critical */
-static void hildon_color_chooser_hsv_set_color(HildonColorChooser *sel, GdkColor *color)
-{
- HildonColorChooserHSV *sel_hsv = HILDON_COLOR_CHOOSER_HSV(sel);
- unsigned short hue, sat, val;
- unsigned long min, max;
- signed long tmp, diff;
-
- /* ugly nesting */
- min = MIN(MIN(color->red, color->green), color->blue);
- max = MAX(MAX(color->red, color->green), color->blue);
- diff = max - min;
-
-
- val = max;
-
- if(val > 0 && diff != 0) {
- sat = (diff * 0x0000ffff) / max;
-
- if(color->red == max) {
- tmp = (signed)color->green - (signed)color->blue;
- tmp *= 10922;
- tmp /= diff;
- if(tmp < 0) {
- tmp += 65532;
- }
- hue = tmp;
- } else if(color->green == max) {
- hue = (((signed long)color->blue - (signed long)color->red)*10922 / diff) + 21844;
- } else {
- hue = (((signed long)color->red - (signed long)color->green)*10922 / diff) + 43688;
- }
- } else {
- hue = 0;
- sat = 0;
- }
-
-
- sel_hsv->currhue = hue;
- sel_hsv->currsat = sat;
- sel_hsv->currval = val;
-
-
- inline_limited_expose(sel_hsv);
-}
-
-
-#define FULL_COLOR 0x00ffffff
-inline void inline_h2rgb(unsigned short hue, unsigned long *rgb)
-{
- unsigned short hue_rotation, hue_value;
-
- hue_rotation = hue / 10922;
- hue_value = hue % 10922;
-
-
- switch(hue_rotation) {
- case 0:
- case 6:
- rgb[0] = FULL_COLOR;
- rgb[1] = hue_value * 6*256;
- rgb[2] = 0;
- break;
- case 1:
- rgb[0] = FULL_COLOR - (hue_value * 6*256);
- rgb[1] = FULL_COLOR;
- rgb[2] = 0;
- break;
- case 2:
- rgb[0] = 0;
- rgb[1] = FULL_COLOR;
- rgb[2] = hue_value * 6*256;
- break;
- case 3:
- rgb[0] = 0;
- rgb[1] = FULL_COLOR - (hue_value * 6*256);
- rgb[2] = FULL_COLOR;
- break;
- case 4:
- rgb[0] = hue_value * 6*256;
- rgb[1] = 0;
- rgb[2] = FULL_COLOR;
- break;
- case 5:
- rgb[0] = FULL_COLOR;
- rgb[1] = 0;
- rgb[2] = FULL_COLOR - (hue_value * 6*256);
- break;
- default:
- rgb[0] = 0;
- rgb[1] = 0;
- rgb[2] = 0;
- break;
- }
-}
-
-#define FULL_COLOR8 0xff
-static void intern_h2rgb8(unsigned short hue, unsigned char *rgb)
-{
- unsigned short hue_rotation, hue_value;
-
- hue >>= 8;
- hue_rotation = hue / 42;
- hue_value = hue % 42;
-
-
- switch(hue_rotation) {
- case 0:
- case 6:
- rgb[0] = FULL_COLOR8;
- rgb[1] = hue_value * 6;
- rgb[2] = 0;
- break;
- case 1:
- rgb[0] = FULL_COLOR8 - (hue_value * 6);
- rgb[1] = FULL_COLOR8;
- rgb[2] = 0;
- break;
- case 2:
- rgb[0] = 0;
- rgb[1] = FULL_COLOR8;
- rgb[2] = hue_value * 6;
- break;
- case 3:
- rgb[0] = 0;
- rgb[1] = FULL_COLOR8 - (hue_value * 6);
- rgb[2] = FULL_COLOR8;
- break;
- case 4:
- rgb[0] = hue_value * 6;
- rgb[1] = 0;
- rgb[2] = FULL_COLOR8;
- break;
- case 5:
- rgb[0] = FULL_COLOR8;
- rgb[1] = 0;
- rgb[2] = FULL_COLOR8 - (hue_value * 6);
- break;
- default:
- rgb[0] = 0;
- rgb[1] = 0;
- rgb[2] = 0;
- break;
- }
-}
-
-
- /* optimization: do not ask hue for each round but have bilinear vectors */
- /* rethink: benefits from handling data 8 bit? (no shift round) */
-inline void inline_draw_hue_bar(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
- unsigned short hvec, hcurr;
- unsigned char *buf, *ptr, tmp[3];
- int i, j, tmpy;
-
-
- if(w <= 0 || h <= 0) {
- return;
- }
-
- buf = (unsigned char *)g_malloc(w*h*3);
-
- hvec = 65535/sh;
- hcurr = hvec * (y - sy);
-
- ptr = buf;
-
-
- for(i = 0; i < h; i++) {
- intern_h2rgb8(hcurr, tmp);
-
- for(j = 0; j < w; j++) {
- ptr[0] = tmp[0];
- ptr[1] = tmp[1];
- ptr[2] = tmp[2];
- ptr += 3;
- }
-
- hcurr += hvec;
- }
-
-
- gdk_draw_rgb_image(widget->parent->window, widget->style->fg_gc[0], x, y, w, h, GDK_RGB_DITHER_NONE, buf, w*3);
-
- tmpy = sel->hba.y + (sel->currhue * sel->hba.height / 0xffff);
- gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy, sel->hba.x + sel->hba.width - 1, tmpy);
-
- if((((sel->currhue * sel->hba.height) & 0xffff) > 0x8000) && (tmpy < (sel->hba.y + sel->hba.height))) {
- gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy+1, sel->hba.x + sel->hba.width - 1, tmpy+1);
- } else if(tmpy > sel->hba.y) {
- gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy-1, sel->hba.x + sel->hba.width - 1, tmpy-1);
- }
-
-
- g_free(buf);
-}
-
-inline void inline_draw_hue_bar_dimmed(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
-
-
- if(w <= 0 || h <= 0) {
- return;
- }
-
- /* We need to create (and cache) the pixbuf if we don't
- * have it yet */
- if (sel->dimmed_bar == NULL) {
- int i, j;
- unsigned short hvec, hcurr, avg;
- unsigned char *buf, *ptr, tmp[3];
- buf = (unsigned char *)g_malloc(w*h*3);
-
- hvec = 65535/sh;
- hcurr = hvec * (y - sy);
-
- ptr = buf;
-
-
- for(i = 0; i < h; i++) {
- intern_h2rgb8(hcurr, tmp);
-
- for(j = 0; j < w; j++) {
- avg = ((unsigned short)tmp[0]*3 + (unsigned short)tmp[1]*2 + (unsigned short)tmp[2])/6;
- ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- ptr += 3;
- }
-
- hcurr += hvec;
- }
-
- sel->dimmed_bar = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, g_free, buf);
- }
-
- gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], sel->dimmed_bar, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
-}
-
-
-inline void inline_draw_crosshair(unsigned char *buf, int x, int y, int w, int h)
-{
- int i, j, sx, sy;
-
- /* bad "clipping", clip the loop to save cpu */
- for(i = 0; i < 8; i++) {
- for(j = 0; j < 8; j++) {
- sx = j + x; sy = i + y;
-
- if(sx >= 0 && sx < w && sy >= 0 && sy < h) {
- if(crosshair[j + 8*i]) {
- if(crosshair[j + 8*i] & 0x1) {
- buf[(sx)*3+(sy)*w*3+0] = 255;
- buf[(sx)*3+(sy)*w*3+1] = 255;
- buf[(sx)*3+(sy)*w*3+2] = 255;
- } else {
- buf[(sx)*3+(sy)*w*3+0] = 0;
- buf[(sx)*3+(sy)*w*3+1] = 0;
- buf[(sx)*3+(sy)*w*3+2] = 0;
- }
- }
- }
- }
- }
-}
-
-
-inline void inline_draw_sv_plane(HildonColorChooserHSV *sel, int x, int y, int w, int h)
-{
- GtkWidget *widget = GTK_WIDGET(sel);
- unsigned char *buf, *ptr;
- unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
- signed long rgby[3];
- int tmp = sel->spa.width*sel->spa.height, i, j;
-
-
- if(w <= 0 || h <= 0) {
- return;
- }
-
-
- buf = (unsigned char *)g_malloc(w*h*3);
-
- ptr = buf;
-
-
- inline_h2rgb(sel->currhue, rgbtmp);
-
- rgby[0] = rgbtmp[0] - rgbx[0];
- rgby[1] = rgbtmp[1] - rgbx[1];
- rgby[2] = rgbtmp[2] - rgbx[2];
-
- rgbx[0] /= sel->spa.width;
- rgbx[1] /= sel->spa.width;
- rgbx[2] /= sel->spa.width;
-
- rgby[0] /= tmp;
- rgby[1] /= tmp;
- rgby[2] /= tmp;
-
-
- rgbx[0] += (y - sel->spa.y)*rgby[0];
- rgbx[1] += (y - sel->spa.y)*rgby[1];
- rgbx[2] += (y - sel->spa.y)*rgby[2];
-
-
- for(i = 0; i < h; i++) {
- rgbtmp[0] = rgbx[0] * (x - sel->spa.x);
- rgbtmp[1] = rgbx[1] * (x - sel->spa.x);
- rgbtmp[2] = rgbx[2] * (x - sel->spa.x);
-
- for(j = 0; j < w; j++) {
- ptr[0] = rgbtmp[0] >> 16;
- ptr[1] = rgbtmp[1] >> 16;
- ptr[2] = rgbtmp[2] >> 16;
- rgbtmp[0] += rgbx[0];
- rgbtmp[1] += rgbx[1];
- rgbtmp[2] += rgbx[2];
- ptr += 3;
- }
-
- rgbx[0] += rgby[0];
- rgbx[1] += rgby[1];
- rgbx[2] += rgby[2];
- }
-
-
- inline_draw_crosshair(buf, (sel->spa.width * sel->currval / 0xffff) - x + sel->spa.x - 4, (sel->spa.height * sel->currsat / 0xffff) - y + sel->spa.y - 4, w, h);
-
-
- gdk_draw_rgb_image(widget->parent->window, widget->style->fg_gc[0], x, y, w, h, GDK_RGB_DITHER_NONE, buf, w*3);
-
-
- g_free(buf);
-}
-
-inline void inline_draw_sv_plane_dimmed(HildonColorChooserHSV *sel, int x, int y, int w, int h)
-{
- GtkWidget *widget = GTK_WIDGET(sel);
-
- if(w <= 0 || h <= 0) {
- return;
- }
-
- /* We need to create (and cache) the pixbuf if we don't
- * have it yet */
- if (sel->dimmed_plane == NULL) {
- unsigned char *buf, *ptr;
- unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
- unsigned long avg;
- signed long rgby[3];
- int tmp = sel->spa.width*sel->spa.height, i, j;
-
- buf = (unsigned char *)g_malloc(w*h*3);
-
- ptr = buf;
-
- /* possibe optimization: as we are drawing grayscale plane, there might
- be some simpler algorithm to do this*/
- rgbtmp[0] = 0x00ffffff;
- rgbtmp[1] = 0x00000000;
- rgbtmp[2] = 0x00000000;
-
- rgby[0] = rgbtmp[0] - rgbx[0];
- rgby[1] = rgbtmp[1] - rgbx[1];
- rgby[2] = rgbtmp[2] - rgbx[2];
-
- rgbx[0] /= sel->spa.width;
- rgbx[1] /= sel->spa.width;
- rgbx[2] /= sel->spa.width;
-
- rgby[0] /= tmp;
- rgby[1] /= tmp;
- rgby[2] /= tmp;
-
- rgbx[0] += (y - sel->spa.y)*rgby[0];
- rgbx[1] += (y - sel->spa.y)*rgby[1];
- rgbx[2] += (y - sel->spa.y)*rgby[2];
-
- for(i = 0; i < h; i++) {
- rgbtmp[0] = rgbx[0] * (x - sel->spa.x);
- rgbtmp[1] = rgbx[1] * (x - sel->spa.x);
- rgbtmp[2] = rgbx[2] * (x - sel->spa.x);
-
- for(j = 0; j < w; j++) {
- avg = (rgbtmp[0] + rgbtmp[1] + rgbtmp[2])/3;
- avg >>= 16;
- ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
- rgbtmp[0] += rgbx[0];
- rgbtmp[1] += rgbx[1];
- rgbtmp[2] += rgbx[2];
- ptr += 3;
- }
-
- rgbx[0] += rgby[0];
- rgbx[1] += rgby[1];
- rgbx[2] += rgby[2];
- }
-
- sel->dimmed_plane = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, g_free, buf);
- }
-
- gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], sel->dimmed_plane, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
-}
-
-
-static gboolean hildon_color_chooser_hsv_expose_timer(gpointer data)
-{
- HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(data);
-
-
- if(sel->expose_info.expose_queued) {
- gtk_widget_queue_draw(GTK_WIDGET(data));
- }
-
-
- return FALSE;
-}
+++ /dev/null
-INCLUDES = $(GTK_CFLAGS) $(GCONF_CFLAGS) \
- $(ESD_CFLAGS) $(LIBMB_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/..
-
-lib_LTLIBRARIES = libhildonwidgets.la
-
-MAINTAINERCLEANFILES = \
- Makefile.in hildon-libs-enum-types.c hildon-libs-enum-types.h
-
-EXTRA_DIST = hildon-marshalers.list
-
-libhildonwidgets_la_LDFLAGS = -version-info 5:0:5
-
-libhildonwidgets_la_LIBADD = $(GTK_LIBS) $(GCONF_LIBS) \
- $(ESD_LIBS) $(LIBMB_LIBS)
-
-libhildonwidgets_la_SOURCES = \
- hildon-marshalers.c \
- hildon-marshalers.h \
- hildon-composite-widget.c \
- hildon-composite-widget.h \
- hildon-controlbar.c \
- hildon-controlbar.h \
- hildon-seekbar.c \
- hildon-seekbar.h \
- hildon-color-selector.c \
- hildon-color-selector.h \
- hildon-note.c \
- hildon-note.h \
- hildon-volumebar.c \
- hildon-volumebar.h \
- hildon-volumebar-range.c \
- hildon-volumebar-range.h \
- hildon-volumebar-private.h \
- hildon-hvolumebar.c \
- hildon-hvolumebar.h \
- hildon-vvolumebar.c \
- hildon-vvolumebar.h \
- hildon-dialoghelp.c \
- hildon-dialoghelp.h \
- hildon-calendar-popup.c \
- hildon-calendar-popup.h \
- hildon-date-editor.c \
- hildon-date-editor.h \
- hildon-time-editor.c \
- hildon-time-editor.h \
- hildon-private.h \
- hildon-time-picker.c \
- hildon-time-picker.h \
- hildon-weekday-picker.c \
- hildon-weekday-picker.h \
- hildon-telephone-editor.c \
- hildon-telephone-editor.h \
- hildon-number-editor.c \
- hildon-number-editor.h \
- hildon-range-editor.c \
- hildon-range-editor.h \
- hildon-get-password-dialog.c \
- hildon-get-password-dialog.h \
- hildon-set-password-dialog.c \
- hildon-set-password-dialog.h \
- hildon-sort-dialog.c \
- hildon-sort-dialog.h \
- hildon-add-home-dialog.c \
- hildon-add-home-dialog.h \
- hildon-font-selection-dialog.c \
- hildon-font-selection-dialog.h \
- hildon-grid.c \
- hildon-grid.h \
- hildon-grid-item.c \
- hildon-grid-item.h \
- hildon-grid-item-private.h \
- hildon-file-handling-note.c \
- hildon-file-handling-note.h \
- hildon-name-password-dialog.c \
- hildon-name-password-dialog.h \
- hildon-scroll-area.c \
- hildon-scroll-area.h \
- hildon-wizard-dialog.c \
- hildon-wizard-dialog.h \
- hildon-color-popup.c \
- hildon-color-popup.h \
- hildon-color-button.c \
- hildon-color-button.h \
- hildon-system-sound.c \
- hildon-system-sound.h \
- hildon-app.c \
- hildon-app.h \
- hildon-defines.c \
- hildon-defines.h \
- hildon-appview.c \
- hildon-appview.h \
- hildon-find-toolbar.c \
- hildon-find-toolbar.h \
- gtk-infoprint.c \
- gtk-infoprint.h \
- hildon-banner.c \
- hildon-banner.h \
- hildon-input-mode-hint.h \
- hildon-app-private.h \
- hildon-caption.c \
- hildon-caption.h \
- hildon-window.c \
- hildon-window.h \
- hildon-window-private.h \
- hildon-program.c \
- hildon-program.h \
- hildon-code-dialog.c \
- hildon-code-dialog.h \
- hildon-plugin-widget.c \
- hildon-plugin-widget.h \
- hildon-color-chooser.c \
- hildon-color-chooser.h \
- hildon-color-chooser-dialog.c \
- hildon-color-chooser-dialog.h \
- hildon-color-chooser-button.c \
- hildon-color-chooser-button.h \
- $(hildonlibs_built_headers) \
- $(hildonlibs_built_cfiles)
-
-
-hildon-marshalers.h: hildon-marshalers.list
- glib-genmarshal --prefix _hildon_marshal --header \
- hildon-marshalers.list >hildon-marshalers.h
-
-hildon-marshalers.c: hildon-marshalers.list hildon-marshalers.h
- echo '#include <hildon-widgets/hildon-marshalers.h>' >hildon-marshalers.c
- glib-genmarshal --prefix _hildon_marshal --body \
- hildon-marshalers.list >>hildon-marshalers.c
-
-hildonwidgetsincludeinstdir=$(includedir)/hildon-widgets
-hildonwidgetsincludeinst_DATA = \
- hildon-controlbar.h \
- hildon-note.h \
- hildon-seekbar.h \
- hildon-color-selector.h \
- hildon-volumebar.h \
- hildon-hvolumebar.h \
- hildon-vvolumebar.h \
- hildon-dialoghelp.h \
- hildon-calendar-popup.h \
- hildon-date-editor.h \
- hildon-time-editor.h \
- hildon-time-picker.h \
- hildon-weekday-picker.h \
- hildon-telephone-editor.h \
- hildon-number-editor.h \
- hildon-range-editor.h \
- hildon-get-password-dialog.h \
- hildon-set-password-dialog.h \
- hildon-sort-dialog.h \
- hildon-add-home-dialog.h \
- hildon-font-selection-dialog.h \
- hildon-grid.h \
- hildon-grid-item.h \
- hildon-file-handling-note.h \
- hildon-name-password-dialog.h \
- hildon-scroll-area.h \
- hildon-wizard-dialog.h \
- hildon-color-popup.h \
- hildon-color-button.h \
- hildon-system-sound.h \
- hildon-app.h \
- hildon-defines.h \
- hildon-appview.h \
- hildon-find-toolbar.h \
- gtk-infoprint.h \
- hildon-banner.h \
- hildon-input-mode-hint.h \
- hildon-app-private.h \
- hildon-caption.h \
- hildon-window.h \
- hildon-program.h \
- hildon-window-private.h \
- hildon-code-dialog.h \
- hildon-plugin-widget.h \
- hildon-color-chooser.h \
- hildon-color-chooser-dialog.h \
- hildon-color-chooser-button.h
-
-headers_to_scan_for_enums = $(hildonwidgetsincludeinst_DATA)
-
-# Generate the enums source code, with glib-mkenums:
-# This is based on the same Makefile.am stuff in pango:
-hildonlibs_built_headers = hildon-libs-enum-types.h
-hildonlibs_built_cfiles = hildon-libs-enum-types.c
-
-# Don't build the library until we have built the header that it needs:
-$(OBJECTS) $(libhildonwidgets_la_OBJECTS): $(hildonlibs_built_headers)
-
-hildon-libs-enum-types.h: @REBUILD@ $(headers_to_scan_for_enums) Makefile
- (cd $(srcdir) && glib-mkenums \
- --fhead "#ifndef __HILDON_LIBS_ENUM_TYPES_H__\n#define __HILDON_LIBS_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
- --fprod "/* enumerations from \"@filename@\" */\n" \
- --vhead "GType @enum_name@_get_type (void);\n#define HILDON_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
- --ftail "G_END_DECLS\n\n#endif /* __HILDON_LIBS_ENUM_TYPES_H__ */" \
- $(headers_to_scan_for_enums)) > $@
-
-#FIXME: This would be shorter if there was a hildon-libs.h file:
-hildon-libs-enum-types.c: @REBUILD@ $(headers_to_scan_for_enums) Makefile
- (cd $(srcdir) && glib-mkenums \
- --fhead "#include <hildon-widgets/hildon-app.h>\n" \
- --fhead "#include <hildon-widgets/hildon-input-mode-hint.h>\n" \
- --fhead "#include <hildon-widgets/hildon-caption.h>\n" \
- --fhead "#include <hildon-widgets/hildon-date-editor.h>\n" \
- --fhead "#include <hildon-widgets/hildon-time-editor.h>\n" \
- --fhead "#include <hildon-widgets/hildon-number-editor.h>\n" \
- --fhead "#include <hildon-widgets/hildon-telephone-editor.h>\n" \
- --fhead "#include <hildon-widgets/hildon-note.h>\n" \
- --fhead "#include <hildon-widgets/hildon-grid.h>\n" \
- --fhead '#include "hildon-libs-enum-types.h"\n' \
- --fhead "#include <glib-object.h>" \
- --fprod "\n/* enumerations from \"@filename@\" */" \
- --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
- --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
- --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
- $(headers_to_scan_for_enums)) > $@
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:gtk-infoprint
- * @short_description: deprecated widget. Use #HildonBanner instead
- *
- * This widget is deprecated. Use #HildonBanner instead
- */
-
-#include "gtk-infoprint.h"
-#include "hildon-banner.h"
-
-/* This is a helper function that searches the banner for
- given window. This is needed to provide backwards
- compatibility. */
-static GtkWidget *find_banner_for_parent(GtkWindow *parent)
-{
- GList *toplevels, *iter;
- GtkWidget *result = NULL;
- gboolean is_timed;
-
- toplevels = gtk_window_list_toplevels();
- for (iter = toplevels; iter; iter = iter->next)
- if (HILDON_IS_BANNER(iter->data) &&
- gtk_window_get_transient_for(GTK_WINDOW(iter->data)) == parent)
- {
- g_object_get(iter->data, "is-timed", &is_timed, NULL);
-
- /* We do not want to touch timed infoprints */
- if (!is_timed) {
- result = iter->data;
- break;
- }
- }
-
- g_list_free(toplevels);
- return result;
-}
-
-/**************************************************/
-/** Public **/
-/**************************************************/
-
-/**
- * gtk_infoprint:
- * @parent: The transient window for the infoprint.
- * @text: The text in infoprint
- *
- * Opens a new infoprint with @text content.
- *
- * If parent is %NULL, the infoprint is a system infoprint.
- * Normally you should use your application window
- * or dialog as a transient parent and avoid passing %NULL.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void gtk_infoprint(GtkWindow * parent, const gchar * text)
-{
- hildon_banner_show_information((GtkWidget *) parent, NULL, text);
-}
-
-/**
- * gtk_infoprint_with_icon_stock:
- * @parent: The transient window for the infoprint.
- * @text: The text in infoprint
- * @stock_id: The stock id of the custom icon
- *
- * Opens a new infoprint with @text content.
- * With this function you can also set a custom icon
- * by giving a stock id as last parameter.
- *
- * If parent is %NULL, the infoprint is a system infoprint.
- * Normally you should use your application window
- * or dialog as a transient parent and avoid passing %NULL.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void
-gtk_infoprint_with_icon_stock(GtkWindow * parent,
- const gchar * text, const gchar * stock_id)
-{
- hildon_banner_show_information((GtkWidget *) parent, NULL, text);
-}
-
-/**
- * gtk_infoprint_with_icon_name:
- * @parent: The transient window for the infoprint.
- * @text: The text in infoprint
- * @icon_name: The name of the icon
- *
- * Opens a new infoprint with @text content.
- * With this function you can also set a custom icon
- * by giving a icon name as last parameter.
- *
- * If parent is %NULL, the infoprint is a system infoprint.
- * Normally you should use your application window
- * or dialog as a transient parent and avoid passing %NULL.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void
-gtk_infoprint_with_icon_name(GtkWindow * parent,
- const gchar * text, const gchar * icon_name)
-{
- hildon_banner_show_information((GtkWidget *) parent, icon_name, text);
-}
-
-/**
- * gtk_infoprintf:
- * @parent: The transient window for the infoprint.
- * @format: Format of the text.
- * @Varargs: List of parameters.
- *
- * Opens a new infoprint with @text printf-style formatting
- * string and comma-separated list of parameters.
- *
- * If parent is %NULL, the infoprint is a system infoprint.
- * This version of infoprint allow you to make printf-like formatting
- * easily.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...)
-{
- gchar *message;
- va_list args;
-
- va_start(args, format);
- message = g_strdup_vprintf(format, args);
- va_end(args);
-
- gtk_infoprint(parent, message);
-
- g_free(message);
-}
-
-/**
- * gtk_infoprint_temporarily_disable_wrap:
- *
- * Will disable wrapping for the next shown infoprint. This only
- * affects next infoprint shown in this application.
- *
- * Currently it does nothing.
- *
- * Deprecated:
- */
-void gtk_infoprint_temporarily_disable_wrap(void)
-{
-}
-
-/**
- * gtk_confirmation_banner:
- * @parent: The transient window for the confirmation banner.
- * @text: The text in confirmation banner
- * @stock_id: The stock id of the custom icon
- *
- * Opens a new confirmation banner with @text content.
- * With this function you can also set a custom icon
- * by giving a stock id as last parameter.
- *
- * If parent is %NULL, the banner is a system banner.
- * Normally you should use your application window
- * or dialog as a transient parent and avoid passing %NULL.
- *
- * This function is otherwise similar to
- * gtk_infoprint_with_icon_stock except in always restricts
- * the text to one line and the font is emphasized.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void
-gtk_confirmation_banner(GtkWindow * parent, const gchar * text,
- const gchar * stock_id)
-{
- gchar *s;
- s = g_strdup_printf("<b>%s</b>", text);
-
- hildon_banner_show_information_with_markup((GtkWidget *) parent, NULL, s);
-
- g_free(s);
-}
-
-/**
- * gtk_confirmation_banner_with_icon_name:
- * @parent: The transient window for the confirmation banner.
- * @text: The text in confirmation banner
- * @icon_name: The name of the custom icon in icon theme
- *
- * Opens a new confirmation banner with @text content.
- * With this function you can also set a custom icon
- * by giving a icon theme's icon name as last parameter.
- *
- * If parent is %NULL, the banner is a system banner.
- * Normally you should use your application window
- * or dialog as a transient parent and avoid passing %NULL.
- *
- * This function is otherwise similar to
- * gtk_infoprint_with_icon_name except in always restricts
- * the text to one line and the font is emphasized.
- *
- * Deprecated: Use #hildon_banner_show_information instead.
- */
-void
-gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text,
- const gchar * icon_name)
-{
- gchar *s;
- s = g_strdup_printf("<b>%s</b>", text);
-
- hildon_banner_show_information_with_markup((GtkWidget *) parent, icon_name, s);
-
- g_free(s);
-}
-
-/**
- * gtk_banner_show_animation:
- * @parent: #GtkWindow
- * @text: #const gchar *
- *
- * The @text is the text shown in banner.
- * Creates a new banner with the animation.
- *
- * Deprecated: Use #hildon_banner_show_animation instead.
- */
-void gtk_banner_show_animation(GtkWindow * parent, const gchar * text)
-{
- (void) hildon_banner_show_animation((GtkWidget *) parent, NULL, text);
-}
-
-/**
- * gtk_banner_show_bar
- * @parent: #GtkWindow
- * @text: #const gchar *
- *
- * The @text is the text shown in banner.
- * Creates a new banner with the progressbar.
- *
- * Deprecated: Use #hildon_banner_show_progress instead.
- */
-void gtk_banner_show_bar(GtkWindow * parent, const gchar * text)
-{
- (void) hildon_banner_show_progress((GtkWidget *) parent, NULL, text);
-}
-
-/**
- * gtk_banner_set_text
- * @parent: #GtkWindow
- * @text: #const gchar *
- *
- * The @text is the text shown in banner.
- * Sets the banner text.
- *
- * Deprecated: Use #hildon_banner_set_text instead.
- */
-void gtk_banner_set_text(GtkWindow * parent, const gchar * text)
-{
- GtkWidget *banner;
-
- g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
-
- banner = find_banner_for_parent(parent);
- if (banner)
- hildon_banner_set_text(HILDON_BANNER(banner), text);
-}
-
-/**
- * gtk_banner_set_fraction:
- * @parent: #GtkWindow
- * @fraction: #gdouble
- *
- * The fraction is the completion of progressbar,
- * the scale is from 0.0 to 1.0.
- * Sets the amount of fraction the progressbar has.
- *
- * Deprecated: Use #hildon_banner_set_fraction instead.
- */
-void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction)
-{
- GtkWidget *banner;
-
- g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
-
- banner = find_banner_for_parent(parent);
- if (banner)
- hildon_banner_set_fraction(HILDON_BANNER(banner), fraction);
-}
-
-/**
- * gtk_banner_close:
- * @parent: #GtkWindow
- *
- * Destroys the banner
- *
- * Deprecated:
- */
-void gtk_banner_close(GtkWindow * parent)
-{
- GtkWidget *banner;
-
- g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
-
- banner = find_banner_for_parent(parent);
- if (banner)
- gtk_widget_destroy(banner);
-}
-
-/**
- * gtk_banner_temporarily_disable_wrap
- *
- * Will disable wrapping for the next shown banner. This only
- * affects next banner shown in this application.
- *
- * Currently it does nothing.
- *
- * Deprecated:
- **/
-void gtk_banner_temporarily_disable_wrap(void)
-{
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __GTK_INFOPRINT_H__
-#define __GTK_INFOPRINT_H__
-
-#include <gtk/gtkwindow.h>
-
-G_BEGIN_DECLS void gtk_infoprint(GtkWindow * parent, const gchar * text);
-void gtk_infoprint_with_icon_stock(GtkWindow * parent, const gchar * text,
- const gchar * stock_id);
-void gtk_infoprint_with_icon_name(GtkWindow * parent, const gchar * text,
- const gchar * icon_name);
-
-void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...);
-void gtk_infoprint_temporarily_disable_wrap(void);
-
-void gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text,
- const gchar * icon_name);
-void gtk_confirmation_banner(GtkWindow * parent, const gchar * text,
- const gchar * stock_id);
-
-void gtk_banner_show_animation(GtkWindow * parent, const gchar * text);
-void gtk_banner_show_bar(GtkWindow * parent, const gchar * text);
-void gtk_banner_set_text(GtkWindow * parent, const gchar * text);
-void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction);
-void gtk_banner_close(GtkWindow * parent);
-void gtk_banner_temporarily_disable_wrap(void);
-
-G_END_DECLS
-#endif /* __GTK_INFOPRINT_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-
-#include "hildon-add-home-dialog.h"
-#include <hildon-widgets/hildon-caption.h>
-
-#define _(String) dgettext(PACKAGE, String)
-#define MAX_ERR_MSG 256
-#define HILDON_ADD_HOME_DIALOG_WIDTH 370
-#define HILDON_ADD_HOME_DIALOG_HEIGHT 100
-#define HILDON_MAX_TITLE_LENGTH 256
-#define HILDON_HOME_MAX_SHORTCUT_LEN 255
-
-#define HILDON_ADD_HOME_DIALOG_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_ADD_HOME_DIALOG, \
- HildonAddHomeDialogPrivate));
-
-typedef struct _HildonAddHomeDialogPrivate HildonAddHomeDialogPrivate;
-
-static GtkDialogClass *parent_class;
-
-static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog);
-static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name);
-static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* name);
-static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename);
-
-static void
-hildon_add_home_dialog_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-static void
-hildon_add_home_dialog_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void
-hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * class);
-static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog);
-
-/* private struct */
-
-struct _HildonAddHomeDialogPrivate {
- GtkWidget *desc_label;
- GtkWidget *name_entry; /* Used when isrename */
- GtkWidget *name_label; /* Used when !isrename */
- GtkWidget *caption_name_entry; /* Used when isrename */
- GtkWidget *new_name_entry;
- GtkWidget *caption_new_name_entry;
- GtkSizeGroup *size_group;
- GtkWidget *okButton;
- GtkWidget *cancelButton;
- gboolean isrename;
-};
-
-enum
-{
- PROP_0,
-
- PROP_NAME,
- PROP_NEW_NAME,
-};
-
-/* Private functions */
-
-static void
-hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * klass)
-{
- GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
- parent_class = g_type_class_peek_parent(klass);
-
- gobject_class->set_property = hildon_add_home_dialog_set_property;
- gobject_class->get_property = hildon_add_home_dialog_get_property;
-
- /**
- * HildonAddHomeDialog:name
- *
- * The name
- */
- g_object_class_install_property(gobject_class,
- PROP_NAME,
- g_param_spec_string ("name",
- ("Name"),
- ("The name."),
- NULL,
- G_PARAM_READWRITE));
-
- /**
- * HildonAddHomeDialog:new_name
- *
- * The new name
- */
- g_object_class_install_property(gobject_class,
- PROP_NEW_NAME,
- g_param_spec_string ("new_name",
- ("New Name"),
- ("The new name."),
- NULL,
- G_PARAM_READWRITE));
-
- g_type_class_add_private(klass, sizeof(HildonAddHomeDialogPrivate));
-}
-
-static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog)
-{
- HildonAddHomeDialogPrivate *priv;
-
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
- priv->name_entry = NULL;
- priv->name_label = NULL;
- priv->caption_name_entry = NULL;
- priv->new_name_entry = NULL;
- priv->isrename = FALSE;
-
- priv->okButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
- "addtoHome_button_ok",
- GTK_RESPONSE_OK);
- priv->cancelButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
- "addtoHome_button_cancel",
- GTK_RESPONSE_CANCEL);
-
- gtk_window_resize(GTK_WINDOW(dialog),
- HILDON_ADD_HOME_DIALOG_WIDTH,
- HILDON_ADD_HOME_DIALOG_HEIGHT);
-
- gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
- gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
-
- priv->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
-
- /* add description text (only shown when isrename==true */
- priv->desc_label = gtk_label_new(_("ckdg_ib_link_exists"));
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->desc_label, FALSE, FALSE, 0);
-
- /* We don't use the hildon_caption_new() C convenience function, because it demands a non-NULL child widget (via gtk_container_add()). */
- priv->caption_name_entry = GTK_WIDGET( g_object_new( HILDON_TYPE_CAPTION, "size_group", priv->size_group, "label", "addtoHome_editor_caption", "status", HILDON_CAPTION_OPTIONAL, NULL) );
- gtk_widget_show(priv->caption_name_entry);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), priv->caption_name_entry,
- FALSE, FALSE, 0);
-
-
- gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
-}
-
-/* Public functions */
-
-GType hildon_add_home_dialog_get_type(void)
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonAddHomeDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_add_home_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonAddHomeDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_add_home_dialog_init
- };
-
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonAddHomeDialog",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-static void
-hildon_add_home_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
- HildonAddHomeDialogPrivate *priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- switch(prop_id)
- {
- case PROP_NAME:
- {
- const gchar* name = NULL;
- if(priv->isrename && priv->name_label)
- name = gtk_entry_get_text(GTK_ENTRY(priv->name_label));
- else if(!(priv->isrename) && priv->name_entry)
- name = gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
-
- g_value_set_string (value, name);
- break;
- }
- case PROP_NEW_NAME:
- {
- const gchar* new_name = NULL;
- if(priv->isrename && priv->new_name_entry)
- new_name = gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
-
- g_value_set_string (value, new_name);
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_add_home_dialog_set_window_title (HildonAddHomeDialog * dialog)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- /* Set up the window title */
- if (priv->isrename)
- gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_rename_link"));
- else
- gtk_window_set_title(GTK_WINDOW(dialog), "addtoHome_dialog_title");
-}
-
-
-static void
-hildon_add_home_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
- HildonAddHomeDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id)
- {
- case PROP_NAME:
- hildon_add_home_dialog_set_old_name (dialog, g_value_get_string (value));
- break;
- case PROP_NEW_NAME:
- hildon_add_home_dialog_set_new_name (dialog, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * hildon_add_home_dialog_new:
- * @parent: parent window for the dialog
- * @name: name to show in the entry (or label, if @new_name is not NULL)
- * @new_name: name to show in the new name entry. If this is not NULL
- * the widget acts as a RenameShortcutDialog.
- *
- * Creates a new Add to Home dialog or Rename Shortcut dialog.
- *
- * Returns: the new dialog.
- */
-GtkWidget *hildon_add_home_dialog_new(GtkWindow * parent,
- const gchar * name,
- const gchar * new_name)
-{
- HildonAddHomeDialog *dialog =
- HILDON_ADD_HOME_DIALOG(g_object_new
- (HILDON_TYPE_ADD_HOME_DIALOG, "name", name, "new_name", new_name, NULL));
-
- if (parent)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return GTK_WIDGET(dialog);
-}
-
-/**
- * hildon_add_home_dialog_get_name:
- * @dialog: the dialog
- *
- * Returns: the string the user has entered in the entry
- */
-const gchar *hildon_add_home_dialog_get_name(HildonAddHomeDialog * dialog)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- if (priv->isrename && priv->new_name_entry)
- return gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
- else if(priv->name_entry)
- return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
- else
- return NULL;
-}
-
-static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- if (priv->isrename && priv->name_label)
- return gtk_label_get_text(GTK_LABEL(priv->name_label));
- else if(!priv->isrename && priv->name_entry)
- return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
- else
- return NULL;
-}
-
-static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
-
- /* Set text in the widgets: */
- if (priv->isrename)
- gtk_label_set_text(GTK_LABEL(priv->name_label), name);
- else
- gtk_entry_set_text(GTK_ENTRY(priv->name_entry), name);
-}
-
-static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* new_name)
-{
- HildonAddHomeDialogPrivate *priv;
- gchar* name = NULL;
- gboolean new_isrename = FALSE;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- /* We get the old name, in case we need to set it again in a new widget. */
- name = g_strdup( hildon_add_home_dialog_get_old_name(dialog) );
- new_isrename = (new_name != NULL);
-
- hildon_add_home_dialog_create_widgets(dialog, new_isrename);
-
-
- /* Set text in the widgets: */
- if(priv->isrename)
- {
- gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), new_name);
- gtk_label_set_text(GTK_LABEL(priv->name_label), (name) ? name : "");
- }
- else
- {
- gtk_entry_set_text(GTK_ENTRY(priv->name_entry), (name) ? name : "");
- }
-
- if(name)
- g_free(name);
-}
-
-static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- /* Create and destroy widgets, depending on the mode.
- * Note that we are making a small speed sacrifice (recreating the widgets)
- * in exchange for memory (creating all widgets and just hiding the ones we don't use.)
- */
-
- if(priv->isrename && !new_isrename)
- {
- /* Remove widgets that were used for isrename mode,
- because we don't need them anymore. */
- if(priv->new_name_entry)
- {
- gtk_widget_destroy(priv->new_name_entry);
- priv->new_name_entry = NULL;
- }
-
- if(priv->caption_new_name_entry)
- {
- gtk_widget_destroy(priv->caption_new_name_entry);
- priv->caption_new_name_entry = NULL;
- }
-
- if(priv->name_label) /* A label */
- {
- gtk_widget_destroy(priv->name_label);
- priv->name_label = NULL;
- }
-
- if(priv->name_entry) /* A box with label inside */
- {
- gtk_widget_destroy(priv->name_entry);
- priv->name_entry = NULL;
- }
- }
- else if(!priv->isrename && new_isrename)
- {
- /* Remove widgets that were used only for !isrename mode,
- because we don't need them anymore. */
- if(priv->name_entry) /* An entry. */
- {
- gtk_widget_destroy(priv->name_entry);
- priv->name_entry = NULL;
- }
- }
-
- priv->isrename = new_isrename;
-
- if(priv->isrename)
- {
- /* Create widgets needed for isrename mode: */
-
- /* Create Entry (in a Caption) for the new name, and pack it into the dialog: */
- if(!priv->new_name_entry)
- {
- priv->new_name_entry = gtk_entry_new();
- gtk_widget_show(priv->new_name_entry);
- }
-
- if(!priv->caption_new_name_entry)
- {
- priv->caption_new_name_entry = hildon_caption_new(priv->size_group, _("ckdg_fi_rename_name"),
- priv->new_name_entry, NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_widget_show(priv->caption_new_name_entry);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(priv->caption_new_name_entry),
- FALSE, FALSE, 0);
- }
-
- /* add description text */
- if(priv->desc_label)
- gtk_widget_show(priv->desc_label);
-
- /* Create Label (in a Box) for the existing name: */
- if(!priv->name_entry)
- {
- priv->name_label = gtk_label_new(NULL);
- gtk_widget_show(priv->name_label);
-
- priv->name_entry = gtk_hbox_new(FALSE, 0);
- gtk_widget_show(priv->name_entry);
- gtk_box_pack_start(GTK_BOX(priv->name_entry), priv->name_label, FALSE, FALSE,
- 0);
- gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
- }
- }
- else
- {
- if(priv->desc_label)
- gtk_widget_hide(priv->desc_label);
-
- /* Create widgets needed for !isrename mode: */
- if(!priv->name_entry)
- {
- priv->name_entry = gtk_entry_new();
- gtk_widget_show(priv->name_entry);
- gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
- }
- }
-
- hildon_add_home_dialog_set_window_title(dialog);
-
- priv->isrename = new_isrename;
-}
-
-void hildon_add_home_dialog_set_name(HildonAddHomeDialog * dialog, const gchar* name)
-{
- HildonAddHomeDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
- priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
-
- hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
-
- /* Set text in the widgets: */
- if (priv->isrename)
- gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), name);
- else
- gtk_label_set_text(GTK_LABEL(priv->name_entry), name);
-}
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_ADD_HOME_DIALOG_H__
-#define __HILDON_ADD_HOME_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_ADD_HOME_DIALOG \
- ( hildon_add_home_dialog_get_type() )
-#define HILDON_ADD_HOME_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_ADD_HOME_DIALOG, HildonAddHomeDialog))
-#define HILDON_ADD_HOME_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_ADD_HOME_DIALOG, \
- HildonAddHomeDialogClass))
-#define HILDON_IS_ADD_HOME_DIALOG(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_ADD_HOME_DIALOG))
-#define HILDON_IS_ADD_HOME_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_ADD_HOME_DIALOG))
-typedef struct _HildonAddHomeDialog HildonAddHomeDialog;
-typedef struct _HildonAddHomeDialogClass HildonAddHomeDialogClass;
-
-struct _HildonAddHomeDialog {
- GtkDialog parent;
-};
-
-struct _HildonAddHomeDialogClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_add_home_dialog_get_type(void);
-
-GtkWidget *hildon_add_home_dialog_new(GtkWindow * parent,
- const gchar * name,
- const gchar * new_name);
-const gchar *hildon_add_home_dialog_get_name(HildonAddHomeDialog * dialog);
-
-G_END_DECLS
-#endif /* __HILDON_ADD_HOME_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef HILDON_APP_PRIVATE_H
-#define HILDON_APP_PRIVATE_H
-
-G_BEGIN_DECLS
-
-enum {
- TOPMOST_STATUS_ACQUIRE,
- TOPMOST_STATUS_LOSE,
- SWITCH_TO,
- IM_CLOSE,
- CLIPBOARD_COPY,
- CLIPBOARD_CUT,
- CLIPBOARD_PASTE,
-
- HILDON_APP_LAST_SIGNAL
-};
-
-struct _HildonAppPrivate {
- GList *children;
- gchar *title;
-#ifndef HILDON_DISABLE_DEPRECATED
- HildonZoomLevel zoom;
-#endif
-
- /* Used to keep track of menu key press/release */
- gint lastmenuclick;
-
- gulong curr_view_id;
- gulong view_id_counter;
- GSList *view_ids;
- gboolean scroll_control;
-
- guint twoparttitle: 1;
- guint is_topmost: 1;
- gboolean killable;
- gboolean autoregistration;
-
- guint escape_timeout;
- guint key_snooper;
-
- GtkUIManager *uim;
-
- guint active_menu_id;
-};
-
-typedef struct {
- gpointer view_ptr;
- unsigned long view_id;
-} view_item;
-
-G_END_DECLS
-
-#endif /* HILDON_APP_PRIVATE_H */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-app
- * @short_description: A base widget to present application. Deprecated, use #HildonProgram instead.
- * @see_also: #HildonAppView
- *
- * #HildonApp is the base for any hildon application.
- * It controls basic looks and functionality of an application, like a title.
- *
- * This widget is deprecated use #HildonProgram instead.
- */
-
-#include <gdk/gdk.h>
-#include "hildon-app.h"
-#include "hildon-app-private.h"
-#include "hildon-appview.h"
-#include "gtk-infoprint.h"
-
-#include <gdk/gdkevents.h>
-#include <gdk/gdkkeysyms.h>
-#include <X11/Xatom.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkeditable.h>
-#include <gtk/gtktextview.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtkuimanager.h>
-#include <gtk/gtkactiongroup.h>
-#include <gtk/gtkdialog.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkcombobox.h>
-
-#include <libintl.h>
-#include <string.h>
-
-#include <libmb/mbutil.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define TITLE_DELIMITER " - "
-
-/*
- * 'Magic' values for the titlebar menu area limits
- */
-#define MENUAREA_LEFT_LIMIT 80
-#define MENUAREA_RIGHT_LIMIT MENUAREA_LEFT_LIMIT + 307
-#define MENUAREA_TOP_LIMIT 0
-#define MENUAREA_BOTTOM_LIMIT 39
-
-#define KILLABLE "CANKILL"
-
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_APP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_APP, HildonAppPrivate));
-
-static GtkWindowClass *parent_class;
-static guint app_signals[HILDON_APP_LAST_SIGNAL] = { 0 };
-
-typedef struct _HildonAppPrivate HildonAppPrivate;
-
-static gboolean
-hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent);
-static gboolean
-hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent);
-static gboolean
-hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app);
-static GdkFilterReturn
-hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data);
-static void
-hildon_app_construct_title (HildonApp *self);
-static void
-hildon_app_finalize (GObject *obj_self);
-static void
-hildon_app_destroy (GtkObject *obj);
-static void
-hildon_app_init (HildonApp *self);
-static void
-hildon_app_class_init (HildonAppClass *app_class);
-static void
-hildon_app_real_topmost_status_acquire (HildonApp *self);
-static void
-hildon_app_real_topmost_status_lose (HildonApp *self);
-static void
-hildon_app_real_switch_to (HildonApp *self);
-static gboolean
-hildon_app_button (GtkWidget *widget, GdkEventButton *event);
-static GdkWindow *
-find_window (GdkWindow *window, gint by, gint co);
-static void
-hildon_app_clipboard_copy(HildonApp *self, GtkWidget *widget);
-static void
-hildon_app_clipboard_cut(HildonApp *self, GtkWidget *widget);
-static void
-hildon_app_clipboard_paste(HildonApp *self, GtkWidget *widget);
-static gboolean hildon_app_escape_timeout(gpointer data);
-
-static void hildon_app_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec);
-static void hildon_app_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec);
-
-static void hildon_app_add (GtkContainer *container, GtkWidget *child);
-static void hildon_app_remove (GtkContainer *container, GtkWidget *child);
-static void hildon_app_forall (GtkContainer *container, gboolean include_internals,
- GtkCallback callback, gpointer callback_data);
-
-enum {
- PROP_0,
- PROP_SCROLL_CONTROL,
- /* FIXME: Zoom is deprecated, should be removed */
- PROP_ZOOM,
- PROP_TWO_PART_TITLE,
- PROP_APP_TITLE,
- PROP_KILLABLE,
- PROP_AUTOREGISTRATION,
- PROP_APPVIEW,
- PROP_UI_MANAGER
-};
-
-static gpointer find_view(HildonApp *self, unsigned long view_id);
-
-/* FIXME: Zoom level is deprecated, should be removed */
-/**
- * hildon_zoom_level_get_type:
- *
- * Initialises, and returns the type of a hildon zoom level
- *
- * Returns: GType of #HildonZoomLevel
- */
-
-GType
-hildon_zoom_level_get_type (void)
-{
- static GType etype = 0;
- if (etype == 0) {
- static const GEnumValue values[] = {
- { HILDON_ZOOM_SMALL, "HILDON_ZOOM_SMALL", "small" },
- { HILDON_ZOOM_MEDIUM, "HILDON_ZOOM_MEDIUM", "medium" },
- { HILDON_ZOOM_LARGE, "HILDON_ZOOM_LARGE", "large" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static ("HildonZoomLevel", values);
- }
- return etype;
-}
-
-GType hildon_app_get_type(void)
-{
- static GType app_type = 0;
-
- if (!app_type)
- {
- static const GTypeInfo app_info =
- {
- sizeof(HildonAppClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_app_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonApp),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_app_init,
- };
- app_type = g_type_register_static(GTK_TYPE_WINDOW,
- "HildonApp", &app_info, 0);
- }
- return app_type;
-}
-
-/*
- * Sets or delete a custom property into the XServer, according
- * to the boolean value of HildonAppPrivate::killable
- */
-static void hildon_app_apply_killable(HildonApp *self)
-{
- HildonAppPrivate *priv;
- Atom killability_atom = XInternAtom (GDK_DISPLAY(),
- "_HILDON_APP_KILLABLE", False);
- priv = HILDON_APP_GET_PRIVATE (self);
-
- g_assert (HILDON_IS_APP (self) );
- g_assert(GTK_WIDGET_REALIZED(self));
-
- if (priv->killable)
- {
- /* Set the atom to specific value, because perhaps in the future,
- there may be other possible values? */
- XChangeProperty(GDK_DISPLAY(),
- GDK_WINDOW_XID(GTK_WIDGET(self)->window),
- killability_atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *)KILLABLE,
- strlen(KILLABLE));
- }
- else
- {
- XDeleteProperty(GDK_DISPLAY(),
- GDK_WINDOW_XID(GTK_WIDGET(self)->window),
- killability_atom);
- }
-}
-
-/*
- * Updates the _NET_CLIENT_LIST property into the XServer.
- * It is the list of the views associated to the HildonApp.
- * It will be used by the Task Navigator in order to be able to show a list
- * of all the views, and let the user switch and navigate them.
- */
-static void hildon_app_apply_client_list(HildonApp *self)
-{
- HildonAppPrivate *priv;
- Window *win_array;
- GSList *list_ptr;
- int loopctr = 0;
- Atom clientlist;
-
- g_assert (HILDON_IS_APP (self) );
- g_assert(GTK_WIDGET_REALIZED(self));
-
- /* Get the client list handle */
- clientlist = XInternAtom (GDK_DISPLAY(),
- "_NET_CLIENT_LIST", False);
-
- /* Allocate a new array for window IDs */
- priv = HILDON_APP_GET_PRIVATE(self);
- win_array = g_new(Window, g_slist_length(priv->view_ids));
-
- /* Fill the contents of the window array with current view IDs */
- for (list_ptr = priv->view_ids; list_ptr; list_ptr = list_ptr->next)
- {
- win_array[loopctr] =
- (unsigned long)(((view_item *)(list_ptr->data))->view_id);
- loopctr++;
- }
-
- /* Update the details of current view IDs to our X property */
- XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window),
- clientlist, XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)win_array,
- g_slist_length(priv->view_ids));
-
- XFlush(GDK_DISPLAY());
- g_free(win_array);
-}
-
-/*
- * Performs the standard gtk realize function.
- */
-static void hildon_app_realize(GtkWidget *widget)
-{
- HildonApp *self;
- HildonAppPrivate *priv;
- GdkWindow *window;
- Atom *old_atoms, *new_atoms;
- gint atom_count;
- Display *disp;
-
- g_assert(widget != NULL);
-
- self = HILDON_APP(widget);
- priv = HILDON_APP_GET_PRIVATE(self);
-
- /*
- * Of course we need to realize the parent.
- * parent_class got already initialised in the hildon_app_init function
- */
- GTK_WIDGET_CLASS(parent_class)->realize(widget);
-
- /* some initialisation code */
- hildon_app_apply_killable(self);
- hildon_app_construct_title(self);
- hildon_app_apply_client_list(self);
- hildon_app_notify_view_changed(self, hildon_app_get_appview(self));
- window = widget->window;
- disp = GDK_WINDOW_XDISPLAY(window);
-
- /* Install a key snooper for the Home button - so that it works everywhere */
- priv->key_snooper = gtk_key_snooper_install
- ((GtkKeySnoopFunc) hildon_app_key_snooper, widget);
-
- /* Get the list of Atoms for the WM_PROTOCOLS property... */
- XGetWMProtocols(disp, GDK_WINDOW_XID(window), &old_atoms, &atom_count);
- new_atoms = g_new(Atom, atom_count + 1);
-
- memcpy(new_atoms, old_atoms, sizeof(Atom) * atom_count);
-
- /* ... creates a new Atom... */
- new_atoms[atom_count++] =
- XInternAtom(disp, "_NET_WM_CONTEXT_CUSTOM", False);
-
- /* ... and finally update the property within the XServer */
- XSetWMProtocols(disp, GDK_WINDOW_XID(window), new_atoms, atom_count);
-
- XFree(old_atoms);
- g_free(new_atoms);
-
- /* Add the GDK_SUBSTRUCTURE_MASK (receive events about window configuration
- * changes of child windows) to the window.
- */
- gdk_window_set_events(window, gdk_window_get_events(window) | GDK_SUBSTRUCTURE_MASK);
-}
-
-/*
- * Performs the standard gtk unrealize function.
- */
-static void hildon_app_unrealize(GtkWidget *widget)
-{
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(widget);
-
- if (priv->key_snooper)
- {
- /* removing the snooper that handles MENU key presses */
- gtk_key_snooper_remove(priv->key_snooper);
- priv->key_snooper = 0;
- }
-
- gdk_window_remove_filter(NULL, hildon_app_event_filter, widget);
- GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
-}
-
-/*
- * Class initialisation.
- */
-static void hildon_app_class_init (HildonAppClass *app_class)
-{
- /* get convenience variables */
- GObjectClass *object_class = G_OBJECT_CLASS(app_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS (app_class);
- GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS(app_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(app_class);
-
- /* set the global parent_class here */
- parent_class = g_type_class_peek_parent(app_class);
-
- g_type_class_add_private(app_class, sizeof(HildonAppPrivate));
-
- /* now the object stuff */
- object_class->finalize = hildon_app_finalize;
- object_class->set_property = hildon_app_set_property;
- object_class->get_property = hildon_app_get_property;
-
- gtkobject_class->destroy = hildon_app_destroy;
-
- widget_class->key_press_event = hildon_app_key_press;
- widget_class->key_release_event = hildon_app_key_release;
- widget_class->button_press_event = hildon_app_button;
- widget_class->button_release_event = hildon_app_button;
- widget_class->realize = hildon_app_realize;
- widget_class->unrealize = hildon_app_unrealize;
-
- container_class->add = hildon_app_add;
- container_class->remove = hildon_app_remove;
- container_class->forall = hildon_app_forall;
-
- app_class->topmost_status_acquire =
- hildon_app_real_topmost_status_acquire;
- app_class->topmost_status_lose = hildon_app_real_topmost_status_lose;
- app_class->switch_to = hildon_app_real_switch_to;
-
- /* create the signals */
- app_signals[TOPMOST_STATUS_ACQUIRE] =
- g_signal_new("topmost_status_acquire",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass,
- topmost_status_acquire), NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- app_signals[TOPMOST_STATUS_LOSE] =
- g_signal_new("topmost_status_lose",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, topmost_status_lose),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- app_signals[SWITCH_TO] =
- g_signal_new("switch_to",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, switch_to),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- app_signals[IM_CLOSE] =
- g_signal_new("im_close",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, im_close),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- app_signals[CLIPBOARD_COPY] =
- g_signal_new("clipboard_copy",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, clipboard_copy),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GTK_TYPE_WIDGET);
- app_signals[CLIPBOARD_CUT] =
- g_signal_new("clipboard_cut",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, clipboard_cut),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GTK_TYPE_WIDGET);
- app_signals[CLIPBOARD_PASTE] =
- g_signal_new("clipboard_paste",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppClass, clipboard_paste),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GTK_TYPE_WIDGET);
-
- /* properties */
- g_object_class_install_property(object_class, PROP_SCROLL_CONTROL,
- g_param_spec_boolean("scroll-control",
- "Scroll control",
- "Set the scroll control ON/OFF",
- TRUE, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_TWO_PART_TITLE,
- g_param_spec_boolean("two-part-title",
- "Two part title",
- "Use two part title or not",
- FALSE, G_PARAM_READWRITE));
-#ifndef HILDON_DISABLE_DEPRECATED
- g_object_class_install_property(object_class, PROP_ZOOM,
- g_param_spec_enum ("zoom",
- "Zoom level",
- "Set the zoom level",
- HILDON_TYPE_ZOOM_LEVEL,
- HILDON_ZOOM_MEDIUM,
- G_PARAM_READWRITE));
-#endif
- g_object_class_install_property(object_class, PROP_APP_TITLE,
- g_param_spec_string ("app-title",
- "Application title",
- "Set the application title",
- "",
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_KILLABLE,
- g_param_spec_boolean("killable",
- "Killable",
- "Whether the application is killable or not",
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class, PROP_AUTOREGISTRATION,
- g_param_spec_boolean("autoregistration",
- "Autoregistration",
- "Whether the application views should be registered automatically",
- TRUE,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class, PROP_APPVIEW,
- g_param_spec_object("appview",
- "Appplication View",
- "The currently active application view",
- HILDON_TYPE_APPVIEW,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class, PROP_UI_MANAGER,
- g_param_spec_object("ui-manager",
- "UIManager",
- "The associated GtkUIManager for this app",
- GTK_TYPE_UI_MANAGER,
- G_PARAM_READWRITE));
-}
-
-/*
- * Performs the standard gtk finalize function, freeing allocated
- * memory and propagating the finalization to the parent.
- */
-static void
-hildon_app_finalize (GObject *obj)
-{
- HildonAppPrivate *priv = NULL;
-
- g_assert (obj != NULL);
-
- priv = HILDON_APP_GET_PRIVATE (obj);
-
- g_free (priv->title);
-
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(obj);
-
- /* FIXME: This is legacy code, but cannot be removed
- without changing functionality */
- gtk_main_quit ();
-}
-
-/*
- * Removes the long escape ("cancel" hw key) press timeout.
- */
-static void
-hildon_app_remove_timeout(HildonAppPrivate *priv)
-{
- g_assert(priv != NULL);
-
- if (priv->escape_timeout > 0)
- {
- g_source_remove (priv->escape_timeout);
- priv->escape_timeout = 0;
- }
-}
-
-/*
- * Frees all the resources and propagates the destroy call to the parent.
- */
-static void
-hildon_app_destroy (GtkObject *obj)
-{
- HildonAppPrivate *priv = NULL;
-
- g_assert (obj != NULL);
-
- priv = HILDON_APP_GET_PRIVATE (obj);
-
- /* Just in case a GDK_Escape key was pressed shortly before the propagation
- * of this event, it is safer to remove the timeout that will generate a
- * GDK_DELETE key press. We are destroying the app, so we're not interested
- * anymore in processing key presses.
- */
- hildon_app_remove_timeout(priv);
-
- if (priv->uim != NULL)
- {
- g_object_unref (G_OBJECT (priv->uim));
- priv->uim = NULL;
- }
-
- /* Free all the views */
- if (priv->view_ids)
- {
- g_slist_foreach (priv->view_ids, (GFunc)g_free, NULL);
- g_slist_free (priv->view_ids);
- priv->view_ids = NULL;
- }
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- GTK_OBJECT_CLASS (parent_class)->destroy(obj);
-}
-
-/*
- * Overrides gtk_container_forall, calling the callback function for each of
- * the children of HildonAppPrivate.
- */
-static void hildon_app_forall (GtkContainer *container, gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonAppPrivate *priv = NULL;
-
- g_return_if_fail (container != NULL);
- g_return_if_fail (callback != NULL);
-
- priv = HILDON_APP_GET_PRIVATE (container);
-
- /* Note! we only have user added children, no internals */
- g_list_foreach (priv->children, (GFunc)callback, callback_data);
-}
-
-/*
- * An accessor to set private properties of HildonAppPrivate.
- */
-static void hildon_app_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_SCROLL_CONTROL:
- priv->scroll_control = g_value_get_boolean(value);
- break;
-#ifndef HILDON_DISABLE_DEPRECATED
- case PROP_ZOOM:
- hildon_app_set_zoom( HILDON_APP (object), g_value_get_enum (value) );
- break;
-#endif
- case PROP_TWO_PART_TITLE:
- hildon_app_set_two_part_title( HILDON_APP (object),
- g_value_get_boolean (value) );
- break;
- case PROP_APP_TITLE:
- hildon_app_set_title( HILDON_APP (object), g_value_get_string (value));
- break;
- case PROP_KILLABLE:
- hildon_app_set_killable( HILDON_APP (object),
- g_value_get_boolean (value));
- break;
- case PROP_AUTOREGISTRATION:
- hildon_app_set_autoregistration( HILDON_APP (object),
- g_value_get_boolean (value));
- break;
- case PROP_APPVIEW:
- hildon_app_set_appview( HILDON_APP (object),
- HILDON_APPVIEW (g_value_get_object (value)));
- break;
- case PROP_UI_MANAGER:
- hildon_app_set_ui_manager( HILDON_APP (object),
- GTK_UI_MANAGER (g_value_get_object (value)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-/*
- * An accessor to get private properties of HildonAppPrivate.
- */
-static void hildon_app_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_SCROLL_CONTROL:
- g_value_set_boolean( value, priv->scroll_control );
- break;
-#ifndef HILDON_DISABLE_DEPRECATED
- case PROP_ZOOM:
- g_value_set_enum( value, priv->zoom);
- break;
-#endif
- case PROP_TWO_PART_TITLE:
- g_value_set_boolean( value, priv->twoparttitle);
- break;
- case PROP_APP_TITLE:
- g_value_set_string (value, priv->title);
- break;
- case PROP_KILLABLE:
- g_value_set_boolean (value, priv->killable);
- break;
- case PROP_AUTOREGISTRATION:
- g_value_set_boolean (value, priv->autoregistration);
- break;
- case PROP_APPVIEW:
- g_value_set_object (value, hildon_app_get_appview (HILDON_APP (object)));
- break;
- case PROP_UI_MANAGER:
- g_value_set_object (value, hildon_app_get_ui_manager (HILDON_APP (object)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-/*
- * Adds a child widget to HildonApp.
- */
-static void hildon_app_add (GtkContainer *container, GtkWidget *child)
-{
- HildonApp *app = NULL;
- HildonAppPrivate *priv = NULL;
-
- g_return_if_fail (container != NULL);
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- app = HILDON_APP (container);
- priv = HILDON_APP_GET_PRIVATE (app);
-
- /* Check if child is already added here */
- if (g_list_find (priv->children, child) != NULL)
- return;
-
- priv->children = g_list_append (priv->children, child);
- GTK_BIN (container)->child = child;
- gtk_widget_set_parent (child, GTK_WIDGET (app));
-
- /* If the default direction (RTL/LTR) is different from the real
- default, change it This happens if the locale has been changed
- but this appview was orphaned and thus never got to know about
- it. "default_direction" could be RTL, but the widget direction
- of the view might still be LTR. Thats what we're fixing here. */
-
- /* FIXME: This is legacy stuff */
- if (gtk_widget_get_default_direction () !=
- gtk_widget_get_direction (GTK_WIDGET (child)))
- {
- gtk_widget_set_direction (GTK_WIDGET (child),
- gtk_widget_get_default_direction ());
- }
-
- if (HILDON_IS_APPVIEW (child))
- {
- g_signal_connect_swapped (G_OBJECT (child), "title_change",
- G_CALLBACK (hildon_app_construct_title), app);
- if (priv->autoregistration)
- hildon_app_register_view (app, child);
- }
-}
-
-/*
- * Removes a child widget from HildonApp.
- */
-static void hildon_app_remove (GtkContainer *container, GtkWidget *child)
-{
- HildonAppPrivate *priv;
- GtkBin *bin;
- HildonApp *app;
-
- g_return_if_fail (container != NULL);
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- priv = HILDON_APP_GET_PRIVATE (container);
- bin = GTK_BIN (container);
- app = HILDON_APP (bin);
-
- /* Make sure that child is found in the list */
- if (g_list_find (priv->children, child) == NULL)
- return;
-
- priv->children = g_list_remove (priv->children, child);
-
- if (HILDON_IS_APPVIEW (child))
- {
- /* FIXME: This is a compilation workaround for gcc > 3.3, since glib-2 API is buggy.
- * see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
-
-G_GNUC_EXTENSION
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (child),
- (gpointer)hildon_app_construct_title, app);
-
- if (priv->autoregistration)
- hildon_app_unregister_view (app, HILDON_APPVIEW (child));
- }
-
- /* If that was our visible child, we need to recalculate size.
- We could chain up to parent as well... */
- gtk_widget_unparent (child);
-
- if (bin->child == child)
- {
- bin->child = NULL;
- gtk_widget_queue_resize (GTK_WIDGET (bin));
- }
-}
-
-
-/*
- * Long escape keypress handler.
- * Long press of the escape key means "close this window", so we fake a delete-event
- * for our GdkWindow to make it act the same as if the user had closed the window the
- * usual way. This allows any application code to gracefully exit.
- *
- * It returns FALSE in order to get called only once.
- */
-static gboolean
-hildon_app_escape_timeout(gpointer app)
-{
- HildonAppPrivate *priv;
- GdkEvent *event;
-
- GDK_THREADS_ENTER ();
-
- g_assert(GTK_WIDGET_REALIZED(app));
-
- priv = HILDON_APP_GET_PRIVATE(app);
-
- /* Send fake event, simulation a situation that user
- pressed 'x' from the corner */
- event = gdk_event_new(GDK_DELETE);
- ((GdkEventAny *)event)->window = GTK_WIDGET(app)->window;
- gtk_main_do_event(event);
- gdk_event_free(event);
-
- priv->escape_timeout = 0;
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
-/*
- * Looks for the visible window to whom the point of coordinates (co,by)
- * belongs. Search recursively all the children of the window.
- *
- * This functionality is only needed for scrollbar remote control.
- */
-static GdkWindow *find_window (GdkWindow *window, gint by, gint co)
-{
- GdkWindow *child;
- GList *children = gdk_window_peek_children (window);
-
- /* If the window has no children, then the coordinates must match it */
- if (!children)
- return window;
-
- if (!(child = (GdkWindow *)children->data))
- return window;
-
- do
- {
- /* It makes sense to process a child window only if it's visible and it's
- * capable to get the GDK_BUTTON_PRESS_MASK event. */
- if (gdk_window_is_visible (child) &&
- gdk_window_get_events (child) & GDK_BUTTON_PRESS_MASK)
- {
- gint x, width, y, height;
-
- gdk_window_get_geometry (child, &x, &y, &width, &height, NULL);
- /* This checks that the the point of coordinates (co,by) is in the rectangle
- * made by (x,y,x+width,y+height). If so, then we spotted which child of the
- * original window is in the point (co,by). We can now recursively search
- * its own children.
- */
- if (x < co && x + width > co && y < by && y + height > by)
- return find_window (child, by, co);
- }
-
- /* If the window has no more children, then it's the one we're looking for */
- if (!(children = g_list_next (children)))
- return window;
-
- } while ( (child = children->data));
-
- return NULL;
-}
-
-/*
- * This is the callback function that gets called on a mouse button press
- * event. If the press is happens in a "sensitive border" area in the right side of
- * the window, the event is translated to the left edge of that border (which
- * usually will contain a scrollbar).
- *
- * This functionality is used for right-hand side scroll control feature (dragging on the
- * right edge of the window controls the rightmost scrollbar if present).
- */
-static gboolean
-hildon_app_button (GtkWidget *widget, GdkEventButton *event)
-{
- HildonAppPrivate *priv = NULL;
-
- /* FIXME: This is an estimate, but the AppView does not expose the
- width of it's borders so we default to something */
- gint sensitive_border = 31;
-
- if (!GTK_WIDGET_REALIZED(widget))
- {
- return FALSE;
- }
-
- priv = HILDON_APP_GET_PRIVATE (widget);
-
- if (!priv->scroll_control)
- {
- return FALSE;
- }
-
- /* We can easily get the location of the vertical scrollbar and get the exact
- * area for the scroll_control *if* the setup is such that the HildonAppview
- * contains a GtkScrolledWindow, so we check for it before defaulting to
- * the previous guess. More complex situations are not feasible to autodetect.
- * Applications should provide the GtkAdjustment to be changed for this to work
- * flawlessly.
- */
- if (HILDON_IS_APPVIEW(GTK_BIN(widget)->child))
- {
- GtkBin *avbin = GTK_BIN(GTK_BIN(widget)->child);
- if (GTK_IS_SCROLLED_WINDOW(avbin->child))
- {
- GtkScrolledWindow *win;
- win = GTK_SCROLLED_WINDOW(avbin->child);
-
- if (GTK_WIDGET_VISIBLE(win->vscrollbar))
- {
- /* Calculate the distance between the AppView's right border and
- * the scrollbars center
- */
- sensitive_border = (GTK_WIDGET(avbin)->allocation.x +
- GTK_WIDGET(avbin)->allocation.width) -
- (win->vscrollbar->allocation.x +
- win->vscrollbar->allocation.width / 2);
- }
- }
- }
-
- /* If the press event comes to the sensitive area, we send a fake event to the
- * area we think the scrollbar is in to make it think the button press happened on it
- */
- if (event->x > widget->allocation.width - sensitive_border)
- {
- GdkWindow *window = NULL;
- gint co = widget->allocation.width - sensitive_border;
-
- /* We now need to know in which window the _modified_ coordinates are */
- if ((window = find_window (widget->window, event->y, co)))
- {
- GdkEventButton nevent;
-
- if (window == widget->window)
- return FALSE;
-
- /* Build a new event and associate the proper window to it */
- nevent = *event;
- nevent.x = 8;
- nevent.window = window;
- g_object_ref (nevent.window);
- gtk_main_do_event ((GdkEvent*)&nevent);
- }
- }
- return FALSE;
-}
-
-/*
- * Performs the initialisation of the widget.
- */
-static void
-hildon_app_init (HildonApp *self)
-{
- HildonAppPrivate *priv;
-
- priv = HILDON_APP_GET_PRIVATE(self);
-
- /* init private */
- priv->title = g_strdup("");
-#ifndef HILDON_DISABLE_DEPRECATED
- priv->zoom = HILDON_ZOOM_MEDIUM;
-#endif
- priv->twoparttitle = FALSE;
- priv->lastmenuclick = 0;
- priv->is_topmost = FALSE;
- priv->curr_view_id = 0;
- priv->view_id_counter = 1;
- priv->view_ids = NULL;
- priv->killable = FALSE;
- priv->autoregistration = TRUE;
- priv->scroll_control = TRUE;
- priv->uim = NULL;
- priv->active_menu_id = 0;
-
- /* grab the events here since HildonApp isn't necessarily ever shown */
- gdk_window_set_events(gdk_get_default_root_window(),
- gdk_window_get_events(gdk_get_default_root_window()) |
- GDK_PROPERTY_CHANGE_MASK);
-
- /* For some reason, the titlebar menu has problems with the grab
- (bugzilla bug 1527). This is part of somewhat ugly fix for it to
- get it to work until a more satisfactory solution is found */
- gdk_window_add_filter(NULL, hildon_app_event_filter, self);
-
- gtk_widget_set_events (GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_POINTER_MOTION_MASK);
-}
-
-/*public functions */
-
-/**
- * hildon_app_new:
- *
- * Creates a new #HildonApp
- *
- * Returns: pointer to a new #HildonApp structure
- */
-GtkWidget *
-hildon_app_new (void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_APP, NULL));
-}
-
-/**
- * hildon_app_new_with_appview:
- * @appview : a #HildonAppView
- *
- * Creates an app, and sets it's initial appview.
- *
- * Returns: pointer to a new #HildonApp structure
- */
-GtkWidget *
-hildon_app_new_with_appview (HildonAppView *appview)
-{
- GtkWidget *app;
-
- g_return_val_if_fail (HILDON_IS_APPVIEW (appview), NULL);
-
- app = hildon_app_new ();
-
- hildon_app_set_appview(HILDON_APP(app), appview);
-
- return app;
-}
-
-/**
- * hildon_app_get_appview:
- * @self : a #HildonApp
- *
- * Gets the currently shown appview.
- *
- * Returns: the currently shown appview in this HildonApp.
- * If no appview is currently set for this HildonApp,
- * returns NULL.
- */
-HildonAppView *
-hildon_app_get_appview (HildonApp *self)
-{
- GtkBin *bin;
-
- g_return_val_if_fail (HILDON_IS_APP (self), NULL);
- bin = GTK_BIN (self);
- if (HILDON_IS_APPVIEW (bin->child))
- {
- return HILDON_APPVIEW (bin->child);
- }
-
- return NULL;
-}
-
-/**
- * hildon_app_set_appview:
- * @self : a #HildonApp
- * @appview : a #HildonAppView
- *
- * Sets (switches to) appview.
- */
-void
-hildon_app_set_appview (HildonApp *app, HildonAppView *view)
-{
- HildonAppPrivate *priv;
- GtkBin *bin;
- GtkWidget *widget; /*(view to be set)*/
- gchar *menu_ui;
-
- g_return_if_fail (HILDON_IS_APP (app));
- g_return_if_fail (HILDON_IS_APPVIEW (view));
-
- bin = GTK_BIN (app);
- priv = HILDON_APP_GET_PRIVATE (app);
- widget = GTK_WIDGET (view);
-
- if (widget == bin->child)
- return;
-
- /* Make old appview dissapear */
- if (bin->child)
- {
- gtk_widget_hide (bin->child);
- g_signal_emit_by_name (bin->child, "switched_from", NULL);
-
- if (priv->active_menu_id > 0)
- {
- if (priv->uim != NULL)
- {
- gtk_ui_manager_remove_ui (priv->uim,
- priv->active_menu_id);
- }
- priv->active_menu_id = 0;
- }
-
- bin->child = NULL;
- }
-
- /* Ensure that new view is in our child list */
- if (!g_list_find (priv->children, widget))
- gtk_container_add (GTK_CONTAINER (app), widget);
-
- bin->child = widget;
-
- gtk_widget_show (widget);
-
- /* UI manager support, merge menu for activated view */
- g_object_get (G_OBJECT (view),
- "menu-ui", &menu_ui,
- NULL);
-
- if (menu_ui && priv->uim)
- {
-
- priv->active_menu_id =
- gtk_ui_manager_add_ui_from_string (priv->uim, menu_ui, -1, NULL);
-
- gtk_ui_manager_ensure_update (priv->uim);
-
- }
-
- g_free (menu_ui);
-
- g_signal_emit_by_name (widget, "switched_to", NULL);
-
- /* Inform task navigator about changed view */
- hildon_app_notify_view_changed (app, view);
-
- /* Update title to show currently activated view */
- hildon_app_construct_title (app);
- gtk_widget_child_focus (widget, GTK_DIR_TAB_FORWARD);
-}
-
-/**
- * hildon_app_set_title:
- * @self : a #HildonApp
- * @newtitle : the new title assigned to the application
- *
- * Sets title of the application.
- */
-void
-hildon_app_set_title (HildonApp *self, const gchar *newtitle)
-{
- HildonAppPrivate *priv;
- gchar *oldstr;
-
- g_return_if_fail(HILDON_IS_APP(self));
-
- priv = HILDON_APP_GET_PRIVATE(self);
- oldstr = priv->title;
-
- if (newtitle)
- {
- priv->title = g_strdup(newtitle);
- g_strstrip(priv->title);
- }
- else
- priv->title = g_strdup("");
-
- if (oldstr)
- g_free(oldstr);
-
- hildon_app_construct_title(self);
-}
-
-/**
- * hildon_app_get_title:
- * @self : a #HildonApp
- *
- * Gets the title of the application.
- *
- * Returns: the title currently assigned to the application. This
- * value is not to be freed or modified by the calling application
- */
-const gchar *
-hildon_app_get_title (HildonApp *self)
-{
- HildonAppPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_APP(self), NULL);
- priv = HILDON_APP_GET_PRIVATE(self);
- return priv->title;
-}
-
-/* FIXME: Zoom is deprecated, remove */
-/**
- * hildon_app_set_zoom:
- * @self : a #HildonApp
- * @newzoom: the zoom level of type #HildonZoomLevel to be assigned to an
- * application
- *
- * Sets the zoom level. Warning! This function is deprecated and
- * should not be used. It's lecacy stuff from ancient specs.
- */
-void
-hildon_app_set_zoom (HildonApp *self, HildonZoomLevel newzoom)
-{
- HildonAppPrivate *priv;
-
- g_return_if_fail(HILDON_IS_APP(self));
-
- priv = HILDON_APP_GET_PRIVATE(self);
-
- if (newzoom != priv->zoom)
- {
- if (newzoom < HILDON_ZOOM_SMALL)
- {
- newzoom = HILDON_ZOOM_SMALL;
- gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_min_zoom_level_reached"));
- }
- else if (newzoom > HILDON_ZOOM_LARGE) {
- newzoom = HILDON_ZOOM_LARGE;
- gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_max_zoom_level_reached"));
- }
- priv->zoom = newzoom;
- }
-}
-
-/**
- * hildon_app_get_zoom:
- * @self : a #HildonApp
- *
- * Gets the zoom level. Warning! This function is deprecated and
- * should not be used. It's lecacy stuff from ancient specifications.
- *
- * Returns: the zoom level of the Hildon application. The
- * returned zoom level is of type #HildonZoomLevel.
- */
-HildonZoomLevel
-hildon_app_get_zoom (HildonApp *self)
-{
- HildonAppPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_APP(self), HILDON_ZOOM_MEDIUM);
- priv = HILDON_APP_GET_PRIVATE(self);
- return priv->zoom;
-}
-
-/**
- * hildon_app_get_default_font:
- * @self : a #HildonApp
- *
- * Gets default font. Warning! This function is deprecated and should
- * not be used. It's legacy stuff from ancient version of specification.
- *
- * Returns: pointer to PangoFontDescription for the default,
- * normal size font
- */
-PangoFontDescription *
-hildon_app_get_default_font (HildonApp *self)
-{
- PangoFontDescription *font_desc = NULL;
- GtkStyle *fontstyle = NULL;
-
- g_return_val_if_fail(HILDON_IS_APP(self), NULL);
-
- fontstyle =
- gtk_rc_get_style_by_paths (gtk_widget_get_settings
- (GTK_WIDGET(self)), NULL, NULL,
- gtk_widget_get_type());
-
- if (!fontstyle)
- {
- g_print("WARNING : default font not found. "
- "Defaulting to swissa 19\n");
- font_desc = pango_font_description_from_string("swissa 19");
-
- }
- else
- font_desc = pango_font_description_copy(fontstyle->font_desc);
-
- return font_desc;
-}
-
-/**
- * hildon_app_get_zoom_font:
- * @self : a #HildonApp
- *
- * Gets the description of the default font. Warning! This function
- * is deprecated and should not be used. It's legacy stuff from
- * ancient specs.
- *
- * Returns: pointer to PangoFontDescription for the default,
- * normal size font
- */
-PangoFontDescription *
-hildon_app_get_zoom_font (HildonApp *self)
-{
- HildonAppPrivate *priv;
- PangoFontDescription *font_desc = NULL;
- gchar *style_name = 0;
- GtkStyle *fontstyle = NULL;
-
- g_return_val_if_fail(HILDON_IS_APP(self), NULL);
-
- priv = HILDON_APP_GET_PRIVATE(self);
- if (priv->zoom == HILDON_ZOOM_SMALL)
- style_name = g_strdup("hildon-zoom-small");
- else if (priv->zoom == HILDON_ZOOM_MEDIUM)
- style_name = g_strdup("hildon-zoom-medium");
- else if (priv->zoom == HILDON_ZOOM_LARGE)
- style_name = g_strdup("hildon-zoom-large");
- else
- {
- g_warning("Invalid Zoom Value\n");
- style_name = g_strdup("");
- }
-
- fontstyle =
- gtk_rc_get_style_by_paths (gtk_widget_get_settings
- (GTK_WIDGET(self)), style_name, NULL,
- G_TYPE_NONE);
- g_free (style_name);
-
- if (!fontstyle)
- {
- g_print("WARNING : theme specific zoomed font not found. "
- "Defaulting to preset zoom-specific fonts\n");
- if (priv->zoom == HILDON_ZOOM_SMALL)
- font_desc = pango_font_description_from_string("swissa 16");
- else if (priv->zoom == HILDON_ZOOM_MEDIUM)
- font_desc = pango_font_description_from_string("swissa 19");
- else if (priv->zoom == HILDON_ZOOM_LARGE)
- font_desc = pango_font_description_from_string("swissa 23");
- }
- else
- font_desc = pango_font_description_copy(fontstyle->font_desc);
-
- return font_desc;
-}
-
- /* FIXME: Zoom is deprecated, remove the code above */
-
-/**
- * hildon_app_set_two_part_title:
- * @self : a #HildonApp
- * @istwoparttitle : a gboolean indicating wheter to activate
- * a title that has both the application title and application
- * view title separated by a triangle
- *
- * Sets the two part title.
- */
-void
-hildon_app_set_two_part_title (HildonApp *self, gboolean istwoparttitle)
-{
- HildonAppPrivate *priv;
- g_return_if_fail(HILDON_IS_APP(self));
- priv = HILDON_APP_GET_PRIVATE(self);
-
- if (istwoparttitle != priv->twoparttitle)
- {
- priv->twoparttitle = istwoparttitle;
- hildon_app_construct_title(self);
- }
-}
-
-/**
- * hildon_app_get_two_part_title:
- * @self : a #HildonApp
- *
- * Gets the 'twopart' represention of the title inside #HildonApp.
- *
- * Returns: a boolean indicating wheter title shown has both
- * application, and application view title separated by a triangle.
- */
-gboolean
-hildon_app_get_two_part_title (HildonApp *self)
-{
- HildonAppPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_APP(self), FALSE);
- priv = HILDON_APP_GET_PRIVATE(self);
- return priv->twoparttitle;
-}
-
-
-/* private functions */
-
-
-/*
- * Handles the key press of the Escape, Increase and Decrease keys. Other keys
- * are handled by the parent GtkWidgetClass.
- */
-static gboolean
-hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent)
-{
- HildonApp *app = HILDON_APP (widget);
- HildonAppView *appview;
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app);
-
- if (HILDON_IS_APPVIEW(GTK_BIN (app)->child))
- {
- appview = HILDON_APPVIEW (GTK_BIN (app)->child);
- }
- else
- {
- return FALSE;
- }
-
- if (keyevent->keyval == GDK_Escape && priv->escape_timeout == 0)
- {
- /* Call hildon_app_escape_timeout every 1500ms until it returns FALSE
- * and store the relative GSource id. Since hildon_app_escape_timeout
- * can only return FALSE, the call will occurr only once.
- */
- priv->escape_timeout = g_timeout_add(1500, hildon_app_escape_timeout, app);
- }
-
- /* FIXME: Handling +/- keys here is not usefull. Applications
- can equally easily handle the keypress themselves. */
- else if (HILDON_KEYEVENT_IS_INCREASE_KEY (keyevent))
- {
- _hildon_appview_increase_button_state_changed (appview,
- keyevent->type);
- }
- else if (HILDON_KEYEVENT_IS_DECREASE_KEY (keyevent))
- {
- _hildon_appview_decrease_button_state_changed (appview,
- keyevent->type);
- }
-
- /* Activate default bindings and let the widget with focus to handle key */
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, keyevent);
-}
-
-/*
- * Handles the key release event for the Escape, Toolbar and Fullscreen keys.
- */
-static gboolean
-hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent)
-{
- HildonApp *app = HILDON_APP (widget);
- HildonAppView *appview;
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app);
-
- if (HILDON_IS_APPVIEW(GTK_BIN (app)->child))
- {
- appview = HILDON_APPVIEW (GTK_BIN (app)->child);
- }
- else
- {
- return FALSE;
- }
-
- if (keyevent->keyval == GDK_Escape)
- {
- /*
- * This will prevent the hildon_app_escape_timeout from being called.
- * See hildon_app_escape_timeout and hildon_app_remove_timeout for more.
- */
- hildon_app_remove_timeout(priv);
- }
- else if (HILDON_KEYEVENT_IS_TOOLBAR_KEY (keyevent))
- {
- g_signal_emit_by_name(G_OBJECT(appview),
- "toolbar-toggle-request");
- }
- else if (HILDON_KEYEVENT_IS_FULLSCREEN_KEY (keyevent))
- {
- /* Emit the fullscreen_state_change directly, it'll save one step */
- if (hildon_appview_get_fullscreen_key_allowed (appview))
- {
- gboolean fullscreen;
-
- fullscreen = hildon_appview_get_fullscreen(appview);
- g_signal_emit_by_name(G_OBJECT(appview),
- "fullscreen_state_change",
- !fullscreen);
- }
- }
-
- /* FIXME: Should the event be marked as handled if any of the three
- above cases took an action */
-
- /* Activate default bindings and let the widget with focus to handle key */
- return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, keyevent);
-}
-
-/*
- * Handles the MENU key presses.
- */
-static gboolean
-hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app)
-{
- /* FIXME: Using normal keypress handler would be better choise. All
- keyevents come to window anyway, so we would get the same
- keys in that way as well, but we wouldn't need to struggle
- with grabs (modal dialogs etc). */
-
- /* Menu key handling is done here */
- if ( HILDON_KEYEVENT_IS_MENU_KEY (keyevent) ) {
- HildonAppView *appview;
- HildonAppPrivate *priv;
- GtkWidget *toplevel;
- GtkWidget *focus = NULL;
-
- /* Don't act on modal dialogs */
- toplevel = gtk_widget_get_toplevel (widget);
- focus = gtk_window_get_focus(GTK_WINDOW(app));
-
- /* Don't act when comboboxes are active, if a togglebutton
- (combobox) has the focus and it is active, we deactivate the
- combobox and do nothing */
- if (GTK_IS_TOGGLE_BUTTON (focus))
- {
- GtkWidget *parent = gtk_widget_get_parent (focus);
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (focus)) &&
- GTK_IS_COMBO_BOX (parent))
- {
- gtk_combo_box_popdown (GTK_COMBO_BOX (parent));
- return TRUE;
- }
- }
-
- /* Don't act when a GtkWindow of a combobox is selected, this
- can happen in some applications that change the properties of
- the widget focus attribute, WARNING: we are using the name of
- the hildon combobox widget to identify the window
- (gtkcombobox.c, HILDON_COMBO_BOX_POPUP), if it changes we
- must change this name */
- if (GTK_IS_WINDOW (widget) &&
- !g_ascii_strcasecmp("hildon-combobox-window", gtk_widget_get_name (widget)))
- {
- return TRUE;
- }
-
- if (GTK_IS_DIALOG (toplevel)
- && gtk_window_get_modal (GTK_WINDOW (toplevel)))
- {
- return TRUE;
- }
-
- appview = HILDON_APPVIEW (GTK_BIN(app)->child);
- priv = HILDON_APP_GET_PRIVATE(app);
-
- if ( keyevent->type == GDK_KEY_PRESS ) {
- /* Toggle menu on press, avoid key repeat */
- if ( priv->lastmenuclick == 0 ){
- priv->lastmenuclick = 1;
- if (_hildon_appview_toggle_menu(appview,
- gtk_get_current_event_time()))
- {
- return TRUE;
- }
- }
- } else if ( keyevent->type == GDK_KEY_RELEASE ) {
- /* We got release, so next press is really a new press,
- not a repeat */
- if ( priv->lastmenuclick == 1 ) {
- priv->lastmenuclick = 0;
- }
-
- } else {
- /* Unknown key event */
- return FALSE;
- }
-
- /* don't stop the key event so that it reaches GTK where it
- closes all existing menus that might be open */
- return FALSE;
- }
-
- return FALSE;
-}
-
-/*
- * Returns the message_type of the Atom registered with a certain name.
- */
-static int
-xclient_message_type_check(XClientMessageEvent *cm, const gchar *name)
-{
- return cm->message_type == XInternAtom(GDK_DISPLAY(), name, FALSE);
-}
-
-/*
- * Returns the GtkWidget associated to a certain Window.
- */
-static GtkWidget *
-hildon_app_xwindow_lookup_widget(Window xwindow)
-{
- GdkWindow *window;
- gpointer widget;
-
- window = gdk_xid_table_lookup(xwindow);
- if (window == NULL)
- return NULL;
-
- gdk_window_get_user_data(window, &widget);
- return widget;
-}
-
-/*
- * Let's search a actual main window using tranciency hints.
- * Note that there can be several levels of menus/dialogs above
- * the actual main window.
- */
-static Window get_active_main_window(Window window)
-{
- Window parent_window;
- gint limit = 0;
-
- gdk_error_trap_push ();
-
- while (XGetTransientForHint(GDK_DISPLAY(), window, &parent_window))
- {
- /* The limit > TRANSIENCY_MAXITER ensures that we can't be stuck
- here forever if we have circular transiencies for some reason.
- Use of _MB_CURRENT_APP_WINDOW might be more elegant... */
-
- if (!parent_window || parent_window == GDK_ROOT_WINDOW() ||
- parent_window == window || limit > TRANSIENCY_MAXITER)
- {
- break;
- }
-
- limit++;
- window = parent_window;
- }
-
- gdk_flush ();
-
- if (gdk_error_trap_pop ())
- return 0;
-
- return window;
-}
-
-/*
- * Filters every GDK event first.
- */
-static GdkFilterReturn
-hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
-{
- gint x,y;
- HildonApp *app = data;
- HildonAppPrivate *priv;
- HildonAppView *appview = NULL;
-
- XAnyEvent *eventti = xevent;
-
- if (HILDON_IS_APPVIEW (GTK_BIN (app)->child))
- {
- appview = HILDON_APPVIEW (GTK_BIN (app)->child);
- }
-
- g_return_val_if_fail (app, GDK_FILTER_CONTINUE);
- g_return_val_if_fail (HILDON_IS_APP(app), GDK_FILTER_CONTINUE);
-
- priv = HILDON_APP_GET_PRIVATE(app);
- if (eventti->type == ClientMessage)
- {
- XClientMessageEvent *cm = xevent;
-
- /* Check if a message indicating a click on titlebar has been
- received. Don't open it if mouse is grabbed (eg. modal dialog
- was just opened).
- _MB_GRAB_TRANSFER is emitted by MatchBox, and signals that a button
- has just been released. */
- if (xclient_message_type_check(cm, "_MB_GRAB_TRANSFER") &&
- HILDON_IS_APPVIEW(appview) &&
- gtk_grab_get_current() == NULL &&
- !_hildon_appview_menu_visible(appview))
- {
- _hildon_appview_toggle_menu(appview, cm->data.l[0]);
- return GDK_FILTER_REMOVE;
- }
- /* IM_CLOSE is input method specific hack that is really questionable */
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLOSE"))
- {
- g_signal_emit_by_name(app, "im_close", NULL);
- return GDK_FILTER_REMOVE;
- }
- /* Task user changed the view through task navigator? */
- else if (xclient_message_type_check(cm, "_NET_ACTIVE_WINDOW"))
- {
- unsigned long view_id = cm->window;
- gpointer view_ptr = find_view(app, view_id);
-
- /* When getting a _NET_ACTIVE_WINDOW signal from the WM we need
- * to bring the application to the front */
- if (!priv->is_topmost)
- g_signal_emit_by_name (G_OBJECT(app), "topmost_status_acquire");
-
- if (HILDON_IS_APPVIEW(view_ptr))
- /* Sets the current view to the "window" that the _NET_ACTIVE_WINDOW
- * specified */
- hildon_app_set_appview(app, (HILDON_APPVIEW(view_ptr)));
- else
- /* there was no view, so we have to switch to an actual application */
- g_signal_emit_by_name (G_OBJECT(app), "switch_to", view_ptr);
-
- /* FIXME: This is a hack. This was once just gtk_window_present, but
- was changed into this at some day!! */
- if (GTK_WIDGET(app)->window)
- {
- mb_util_window_activate(GDK_DISPLAY(),
- GDK_WINDOW_XID(GTK_WIDGET(app)->window));
- }
- }
- /* FIXME: IM hack */
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_COPY"))
- {
- Window xwindow = cm->data.l[0];
- GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
-
- g_signal_emit_by_name (G_OBJECT(app), "clipboard_copy", widget);
- }
- /* FIXME: IM hack */
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_CUT"))
- {
- Window xwindow = cm->data.l[0];
- GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
-
- g_signal_emit_by_name (G_OBJECT(app), "clipboard_cut", widget);
- }
- /* FIXME: IM hack */
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_PASTE"))
- {
- Window xwindow = cm->data.l[0];
- GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
-
- g_signal_emit_by_name (G_OBJECT(app), "clipboard_paste", widget);
- }
- }
-
- if (eventti->type == ButtonPress)
- {
-
- /* FIXME: This is mysterious bugfix related to problems to open the
- application menu (bugzilla N#3204) */
- XButtonEvent *bev = (XButtonEvent *)xevent;
-
- if (HILDON_IS_APPVIEW(appview) &&
- _hildon_appview_menu_visible(appview) &&
- !hildon_appview_get_fullscreen(appview))
- {
- x = bev->x_root;
- y = bev->y_root;
- if ( (x >= MENUAREA_LEFT_LIMIT) && (x <= MENUAREA_RIGHT_LIMIT) &&
- (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT))
- {
- _hildon_appview_toggle_menu(appview, bev->time);
- return GDK_FILTER_CONTINUE;
- }
- }
- }
-
- /* FIXME: as above */
- if (eventti->type == ButtonRelease)
- {
- if (HILDON_IS_APPVIEW(appview) &&
- _hildon_appview_menu_visible(appview) &&
- !hildon_appview_get_fullscreen(appview))
- {
- XButtonEvent *bev = (XButtonEvent *)xevent;
- x = bev->x_root;
- y = bev->y_root;
- if ( (x >= MENUAREA_LEFT_LIMIT) && (x < MENUAREA_RIGHT_LIMIT) &&
- (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT))
- {
- return GDK_FILTER_REMOVE;
- }
- }
- return GDK_FILTER_CONTINUE;
- }
-
- /* Application stacking order changed */
- if (eventti->type == PropertyNotify)
- {
- Atom active_app_atom =
- XInternAtom (GDK_DISPLAY(), "_MB_CURRENT_APP_WINDOW", False);
- XPropertyEvent *prop = xevent;
-
- if ((prop->atom == active_app_atom)
- && (prop->window == GDK_ROOT_WINDOW()))
- {
- Atom realtype;
- int format;
- int status;
- unsigned long n;
- unsigned long extra;
- Window my_window;
- union
- {
- Window *win;
- unsigned char *char_pointer;
- } win;
-
- win.win = NULL;
-
- status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
- active_app_atom, 0L, 16L,
- 0, XA_WINDOW, &realtype, &format,
- &n, &extra, &win.char_pointer);
- if (!(status == Success && realtype == XA_WINDOW && format == 32
- && n == 1 && win.win != NULL))
- {
- if (win.win != NULL)
- XFree(win.char_pointer);
- return GDK_FILTER_CONTINUE;
- }
-
- my_window = GDK_WINDOW_XID(GTK_WIDGET(app)->window);
-
- /* Are we the topmost one? */
- if (win.win[0] == my_window ||
- get_active_main_window(win.win[0]) == my_window)
- {
- if (!priv->is_topmost)
- g_signal_emit_by_name (G_OBJECT(app),
- "topmost_status_acquire");
- }
- else if (priv->is_topmost)
- {
- GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(app));
-
- /* FIXME: IM hack, IM-module should do this in response to
- topmost_status_lose (emission hook?) */
- if (GTK_IS_ENTRY(focus))
- gtk_im_context_focus_out(GTK_ENTRY(focus)->im_context);
- if (GTK_IS_TEXT_VIEW(focus))
- gtk_im_context_focus_out(GTK_TEXT_VIEW(focus)->im_context);
-
- g_signal_emit_by_name (app, "topmost_status_lose");
- }
-
- if (win.win != NULL)
- XFree(win.char_pointer);
- }
- }
-
- return GDK_FILTER_CONTINUE;
- }
-
-/*
- * Sets the GTK Window title to the application's title, or
- * combined appview/app title, if two part title is asked.
- */
-static void
-hildon_app_construct_title (HildonApp *self)
-{
- g_return_if_fail (HILDON_IS_APP (self));
-
- if (GTK_WIDGET_REALIZED(self))
- {
- HildonAppPrivate *priv;
- GdkAtom subname;
- gchar *concatenated_title = NULL;
- HildonAppView *appview;
-
- priv = HILDON_APP_GET_PRIVATE (self);
- appview = hildon_app_get_appview(self);
-
- /* FIXME: The subname property is legacy stuff no longer supported by
- Matchbox. However, it is still set for the convenience of
- the Task Navigator. */
- subname = gdk_atom_intern("_MB_WIN_SUB_NAME", FALSE);
-
- if (!appview || !hildon_app_get_two_part_title(self) ||
- g_utf8_strlen(hildon_appview_get_title(appview), -1) < 1 )
- {
- /* Set an invisible dummy value if there is no appview title */
- gdk_property_change (GTK_WIDGET(self)->window, subname,
- gdk_atom_intern ("UTF8_STRING", FALSE),
- 8, GDK_PROP_MODE_REPLACE, (guchar *) " \0", 1);
- gtk_window_set_title (GTK_WINDOW(self), priv->title);
- }
- else
- {
- gdk_property_change (GTK_WIDGET(self)->window, subname,
- gdk_atom_intern ("UTF8_STRING", FALSE),
- 8, GDK_PROP_MODE_REPLACE,
- (guchar *)hildon_appview_get_title(appview),
- strlen(hildon_appview_get_title (appview)));
- concatenated_title = g_strjoin(TITLE_DELIMITER, priv->title,
- hildon_appview_get_title(appview), NULL);
- /* priv->title should always be non-null, but check anyway */
- if (concatenated_title != NULL)
- {
- gtk_window_set_title (GTK_WINDOW(self), concatenated_title);
- g_free(concatenated_title);
- }
- }
- }
-}
-
-/*
- * Callback function to the topmost_status_acquire signal emitted by
- * hildon_app_event_filter function. See it for more details.
- */
-void
-hildon_app_real_topmost_status_acquire (HildonApp *self)
-{
- HildonAppPrivate *priv;
- g_return_if_fail (HILDON_IS_APP (self));
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* FIXME: What is the logic not to update topmost status now? */
- if (!GTK_BIN (self)->child)
- return;
-
- priv->is_topmost = TRUE;
-}
-
-/*
- * Callback function to the topmost_status_lose signal emitted by
- * hildon_app_event_filter function. See it for more details.
- */
-void
-hildon_app_real_topmost_status_lose (HildonApp *self)
-{
- HildonAppPrivate *priv;
- g_return_if_fail (HILDON_IS_APP (self));
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* FIXME: What is the logic not to update topmost status now? */
- if (!GTK_BIN (self)->child)
- return;
-
- priv->is_topmost = FALSE;
-}
-
-void
-hildon_app_real_switch_to (HildonApp *self)
-{
- g_return_if_fail (HILDON_IS_APP (self));
- /* Do we have to do anything here? */
-}
-
-
-/**
- * hildon_app_set_autoregistration
- * @self : a #HildonApp
- * @auto_reg : whether the (app)view autoregistration should be active
- *
- * Controls the autoregistration/unregistration of (app)views.
- */
-
-void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg)
-{
- HildonAppPrivate *priv;
- g_return_if_fail (HILDON_IS_APP (self));
-
- priv = HILDON_APP_GET_PRIVATE (self);
- priv->autoregistration = auto_reg;
-}
-
-
-/**
- * hildon_app_register_view:
- * @self : a #HildonApp
- * @view_ptr : pointer to the view instance to be registered
- *
- * Registers a new view. For appviews, this can be done automatically
- * if autoregistration is set.
- */
-
-void hildon_app_register_view(HildonApp *self, gpointer view_ptr)
-{
- HildonAppPrivate *priv;
- view_item *view_item_inst;
-
- g_return_if_fail (HILDON_IS_APP (self) || view_ptr != NULL);
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- if (hildon_app_find_view_id(self, view_ptr) == 0)
- {
- /* The pointer to the view was unique, so add it to the list */
- view_item_inst = g_malloc(sizeof(view_item));
- view_item_inst->view_id = priv->view_id_counter;
- view_item_inst->view_ptr = view_ptr;
-
- priv->view_id_counter++;
-
- priv->view_ids =
- g_slist_append(priv->view_ids, view_item_inst);
-
- /* Update the list of views */
- if (GTK_WIDGET_REALIZED(self))
- hildon_app_apply_client_list(self);
- }
-}
-
-
-/**
- * hildon_app_register_view_with_id:
- * @self : a #HildonApp
- * @view_ptr : pointer to the view instance to be registered
- * @view_id : the ID of the view
- *
- * Registers a new view. Allows the application to specify any ID.
- *
- * Returns: TRUE if the view registration succeeded, FALSE otherwise.
- * The probable cause of failure is that view with that ID
- * already existed.
- */
-
-gboolean hildon_app_register_view_with_id(HildonApp *self,
- gpointer view_ptr,
- unsigned long view_id)
-{
- view_item *view_item_inst;
- HildonAppPrivate *priv;
- GSList *list_ptr = NULL;
-
- g_return_val_if_fail (HILDON_IS_APP (self), FALSE);
- g_return_val_if_fail (view_ptr, FALSE);
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- list_ptr = priv->view_ids;
-
- /* Check that the view is not already registered */
- while (list_ptr)
- {
- if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr
- && (unsigned long)((view_item *)list_ptr->data)->view_id == view_id)
- {
- return FALSE;
- }
- list_ptr = list_ptr->next;
- }
-
- /* The pointer to the view was unique, so add it to the list */
- view_item_inst = g_malloc(sizeof(view_item));
- view_item_inst->view_id = view_id;
- view_item_inst->view_ptr = view_ptr;
-
- priv->view_ids =
- g_slist_append(priv->view_ids, view_item_inst);
-
- priv->view_id_counter++;
-
- /* Finally, update the _NET_CLIENT_LIST property */
- if (GTK_WIDGET_REALIZED(self))
- hildon_app_apply_client_list(self);
-
- return TRUE;
-}
-
-/**
- * hildon_app_unregister_view:
- * @self : a #HildonApp
- * @view_ptr : pointer to the view instance to be unregistered
- *
- * Unregisters a view from HildonApp. Done usually when a view is
- * destroyed. For appviews, this is can be automatically
- * if autoregistration is set.
- */
-void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr)
-{
- HildonAppPrivate *priv = NULL;
- GSList *list_ptr = NULL;
-
- g_return_if_fail (HILDON_IS_APP (self));
- g_return_if_fail (view_ptr != NULL);
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* Search the view from the list */
- list_ptr = priv->view_ids;
-
- while (list_ptr)
- {
- if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr)
- {
- /* Found the view, kick it off */
- g_free (list_ptr->data);
- priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr);
- break;
- }
- list_ptr = list_ptr->next;
- }
-
- if (GTK_WIDGET_REALIZED(self))
- hildon_app_apply_client_list(self);
-}
-
-
-/**
- * hildon_app_unregister_view_with_id:
- * @self: a #HildonApp
- * @view_id: the ID of the view that should be unregistered
- *
- * Unregisters a view with specified ID, if it exists.
- */
-void hildon_app_unregister_view_with_id(HildonApp *self,
- unsigned long view_id)
-{
- HildonAppPrivate *priv;
- GSList *list_ptr = NULL;
-
- g_return_if_fail (HILDON_IS_APP (self));
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* Search the view from the list */
- list_ptr = priv->view_ids;
-
- while (list_ptr)
- {
- if ( (unsigned long)((view_item *)list_ptr->data)->view_id == view_id)
- {
- /* Found view with given id, kick it off */
- g_free (list_ptr->data);
- priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr);
- break;
- }
- list_ptr = list_ptr->next;
- }
-
- /* Update client list to reflect new situation. If we are not
- realized, then nobody knows about us anyway... */
- if (GTK_WIDGET_REALIZED(self))
- hildon_app_apply_client_list(self);
-}
-
-
-/**
- * hildon_app_notify_view_changed:
- * @self : a #HildonApp
- * @view_ptr : pointer to the view that is switched to
- *
- * Updates the X property that contains the currently active view
- */
-void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr)
-{
- g_return_if_fail (HILDON_IS_APP (self));
- g_return_if_fail (view_ptr != NULL);
-
- /* We need GdkWindow before we can send X messages */
- if (GTK_WIDGET_REALIZED(self))
- {
- gulong id = hildon_app_find_view_id(self, view_ptr);
- Atom active_view = XInternAtom (GDK_DISPLAY(),
- "_NET_ACTIVE_WINDOW", False);
-
- if (id) {
- /* Set _NET_ACTIVE_WINDOW for our own toplevel to contain view id */
- XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window),
- active_view, XA_WINDOW, 32, PropModeReplace,
- (unsigned char *)&id, 1);
- XFlush(GDK_DISPLAY());
- }
- }
-}
-
-
-/**
- * hildon_app_find_view_id:
- * @self : a #HildonApp
- * @view_ptr : pointer to the view whose ID we want to acquire
- *
- * Returns: the ID of the view, or 0 if not found
- *
- * Allows mapping of view pointer to its view ID. If NULL is passed
- * as the view pointer, returns the ID of the current view.
- */
-unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr)
-{
- HildonAppPrivate *priv;
- GSList *iter;
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* If no view is given, find the ID for the currently visible view */
- if (!view_ptr)
- view_ptr = GTK_BIN (self)->child;
- if (!view_ptr)
- return 0;
-
- /* Iterate through list and search for given view pointer */
- for (iter = priv->view_ids; iter; iter = iter->next)
- {
- if ( (gpointer)((view_item *)iter->data)->view_ptr == view_ptr)
- return (unsigned long)((view_item *)iter->data)->view_id;
- }
-
- return 0;
-}
-
-/**
- * hildon_app_set_killable:
- * @self : a #HildonApp
- * @killability : truth value indicating whether the app can be killed
- *
- * Updates information about whether the application can be killed or not by
- * Task Navigator (i.e. whether its statesave is up to date)
- */
-void hildon_app_set_killable(HildonApp *self, gboolean killability)
-{
- HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (self);
- g_return_if_fail (HILDON_IS_APP (self) );
-
- if (killability != priv->killable)
- {
- priv->killable = killability;
-
- /* If we have a window, then we can actually set this
- property. Otherwise we wait until we are realized */
- if (GTK_WIDGET_REALIZED(self))
- hildon_app_apply_killable(self);
- }
-}
-
-
-/**
- * hildon_app_set_ui_manager:
- * @self : #HildonApp
- * @uim : #GtkUIManager to be set
- *
- * Sets the #GtkUIManager assigned to the #HildonApp.
- * If @uim is NULL, unsets the current ui manager.
- * The @HildonApp holds a reference to the ui manager until
- * the @HildonApp is destroyed or unset.
- */
-void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim)
-{
- HildonAppPrivate *priv;
-
- g_return_if_fail(self && HILDON_IS_APP(self));
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* Release old ui-manager object if such exists */
- if (priv->uim != NULL)
- {
- g_object_unref (G_OBJECT (priv->uim));
- }
-
- priv->uim = uim;
-
- /* If we got new ui-manager (it's perfectly valid not
- to give one), acquire reference to it */
- if (priv->uim != NULL)
- {
- g_object_ref (G_OBJECT (uim));
- }
-
- g_object_notify (G_OBJECT(self), "ui-manager");
-}
-
-/**
- * hildon_app_get_ui_manager:
- * @self : #HildonApp
- *
- * Gets the #GtkUIManager assigned to the #HildonApp.
- *
- * Returns: the #GtkUIManager assigned to this application
- * or null if no manager is assigned
- */
-GtkUIManager *hildon_app_get_ui_manager(HildonApp *self)
-{
- HildonAppPrivate *priv;
-
- g_return_val_if_fail(self && HILDON_IS_APP(self), NULL);
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- return (priv->uim);
-}
-
-/*
- * Search for a view with the given id within HildonApp.
- * Returns a pointer to the found view, or NULL if not found.
- */
-static gpointer find_view(HildonApp *self, unsigned long view_id)
-{
- HildonAppPrivate *priv;
- GSList *iter;
-
- priv = HILDON_APP_GET_PRIVATE (self);
-
- /* Iterate through the list of view ids and search given id */
- for (iter = priv->view_ids; iter; iter = iter->next)
- {
- if ( (unsigned long)((view_item *)iter->data)->view_id == view_id)
- return (gpointer)((view_item *)iter->data)->view_ptr;
- }
-
- return NULL;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_APP_H__
-#define __HILDON_APP_H__
-
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkuimanager.h>
-#include "hildon-appview.h"
-
-G_BEGIN_DECLS
-/**
- * HildonApp:
- *
- * Contains only private data not to be touched by outsiders.
- */
-typedef struct _HildonApp HildonApp;
-typedef struct _HildonAppClass HildonAppClass;
-
-#define HILDON_TYPE_APP ( hildon_app_get_type() )
-
-#define HILDON_APP(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_APP, \
- HildonApp))
-
-#define HILDON_APP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
- HILDON_TYPE_APP, HildonAppClass))
-
-#define HILDON_IS_APP(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APP))
-
-#define HILDON_IS_APP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
- HILDON_TYPE_APP))
-
-
-struct _HildonApp {
- GtkWindow parent;
-};
-
-struct _HildonAppClass {
- GtkWindowClass parent_class;
- void (*topmost_status_acquire) (HildonApp *self);
- void (*topmost_status_lose) (HildonApp *self);
- void (*switch_to) (HildonApp *self); /* FIXME: Possible browser hack?? */
- void (*im_close) (HildonApp *self);
- void (*clipboard_copy) (HildonApp *self, GtkWidget *widget);
- void (*clipboard_cut) (HildonApp *self, GtkWidget *widget);
- void (*clipboard_paste) (HildonApp *self, GtkWidget *widget);
-};
-
-#ifndef HILDON_DISABLE_DEPRECATED
-/* Make these values >0 so that we can detect when someone sets SMALL-1
- * zoom level (enum seems to be unsigned int)
- */
-
-/**
- * HildonZoomLevel:
- * @HILDON_ZOOM_SMALL: Smallest font.
- * @HILDON_ZOOM_MEDIUM: Middle size font.
- * @HILDON_ZOOM_LARGE: Largest font.
- *
- * The Hildon zoom levels. Small meaning small font. Large meaning
- * large font. These font are specified in the gtkrc files.
- * This enum is deprecated and should not be used. It's just
- * lecagy stuff from ancient specs.
- */
-typedef enum /*< skip >*/
-{
- HILDON_ZOOM_SMALL = 1,
- HILDON_ZOOM_MEDIUM = 2,
- HILDON_ZOOM_LARGE = 3
-} HildonZoomLevel;
-
-#define HILDON_TYPE_ZOOM_LEVEL (hildon_zoom_level_get_type ())
-
-GType hildon_zoom_level_get_type (void);
-#endif /* deprecated */
-
-
-/* You should use the correct ones from hildon-defines.h
- *
- * FIXME: These should be removed when API changes are allowed,
- * they are not used in hildon code anymore (but might be in external).
- */
-#define HILDON_MENU_KEY GDK_F4
-#define HILDON_HOME_KEY GDK_F5
-#define HILDON_TOOLBAR_KEY GDK_T
-#define HILDON_FULLSCREEN_KEY GDK_F6
-#define HILDON_INCREASE_KEY GDK_F7
-#define HILDON_DECREASE_KEY GDK_F8
-#define HILDON_TOOLBAR_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK)
-
-#define HILDON_KEYEVENT_IS_MENU_KEY(keyevent) (keyevent->keyval == HILDON_MENU_KEY)
-#define HILDON_KEYEVENT_IS_HOME_KEY(keyevent) (keyevent->keyval == HILDON_HOME_KEY)
-#define HILDON_KEYEVENT_IS_TOOLBAR_KEY(keyevent) ((keyevent->keyval == HILDON_TOOLBAR_KEY) && \
- (keyevent->state == HILDON_TOOLBAR_MODIFIERS))
-#define HILDON_KEYEVENT_IS_FULLSCREEN_KEY(keyevent) (keyevent->keyval == HILDON_FULLSCREEN_KEY)
-#define HILDON_KEYEVENT_IS_INCREASE_KEY(keyevent) (keyevent->keyval == HILDON_INCREASE_KEY)
-#define HILDON_KEYEVENT_IS_DECREASE_KEY(keyevent) (keyevent->keyval == HILDON_DECREASE_KEY)
-
-#define TRANSIENCY_MAXITER 50
-
-GType hildon_app_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_app_new(void);
-GtkWidget *hildon_app_new_with_appview(HildonAppView * appview);
-void hildon_app_set_appview(HildonApp * self, HildonAppView * appview);
-HildonAppView *hildon_app_get_appview(HildonApp * self);
-void hildon_app_set_title(HildonApp * self, const gchar * newtitle);
-const gchar *hildon_app_get_title(HildonApp * self);
-
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_app_set_zoom(HildonApp * self, HildonZoomLevel newzoom);
-HildonZoomLevel hildon_app_get_zoom(HildonApp * self);
-PangoFontDescription *hildon_app_get_default_font(HildonApp * self);
-PangoFontDescription *hildon_app_get_zoom_font(HildonApp * self);
-#endif
-
-void hildon_app_set_two_part_title(HildonApp * self,
- gboolean istwoparttitle);
-gboolean hildon_app_get_two_part_title(HildonApp * self);
-
-void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg);
-void hildon_app_register_view(HildonApp *self, gpointer view_ptr);
-gboolean hildon_app_register_view_with_id(HildonApp *self,
- gpointer view_ptr,
- unsigned long view_id);
-void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr);
-void hildon_app_unregister_view_with_id(HildonApp *self,
- unsigned long view_id);
-unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr);
-void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr);
-
-void hildon_app_set_killable(HildonApp *self, gboolean killability);
-
-void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim);
-GtkUIManager *hildon_app_get_ui_manager(HildonApp *self);
-
-G_END_DECLS
-#endif /* __HILDON_APP_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-appview
- * @short_description: A widget which present one view of an application
- * @see_also: #HildonApp
- *
- * #HildonAppView is a widget which presents one view of an application.
- * Application can have many different views and the appview helps to organize.
- * It has automatic fullscreen and menu handling. It also helps to handle
- * components like a toolbar.
- */
-
-#include <memory.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include "hildon-app.h"
-#include <hildon-appview.h>
-#include <hildon-find-toolbar.h>
-
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkimcontext.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkcheckmenuitem.h>
-#include <gtk/gtkmenushell.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkprogressbar.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkiconfactory.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk/gdk.h>
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-
-#include <libintl.h>
-#define _(String) gettext(String)
-
-enum {
- PROP_0,
- PROP_CONNECTED_ADJUSTMENT,
- PROP_FULLSCREEN_KEY_ALLOWED,
- PROP_FULLSCREEN,
- PROP_TITLE,
- PROP_MENU_UI
-};
-
-/*The size of screen*/
-#define WINDOW_HEIGHT 480
-#define WINDOW_WIDTH 800
-
-#define NAVIGATOR_HEIGHT WINDOW_HEIGHT
-
-#define APPVIEW_HEIGHT 396
-#define APPVIEW_WIDTH 672
-
-#define TOOLBAR_HEIGHT 40
-#define TOOLBAR_UP 9
-#define TOOLBAR_DOWN 9
-#define TOOLBAR_MIDDLE 10
-#define TOOLBAR_RIGHT 24
-#define TOOLBAR_LEFT 24
-#define TOOLBAR_WIDTH APPVIEW_WIDTH
-
-#define WORKAREA_ATOM "_NET_WORKAREA"
-
-/* Non atom defines */
-#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
-#define _NET_WM_STATE_ADD 1 /* add/set property */
-
-/*Margins
- * These margins are set to be 5pixels smaller than in the specs
- * Inner things are allocation that extra space
- * */
-/*
-#define MARGIN_TOOLBAR_TOP 2
-#define MARGIN_TOOLBAR_BOTTOM 6
-#define MARGIN_TOOLBAR_LEFT 22
-#define MARGIN_TOOLBAR_RIGHT 23
-*/
-#define MARGIN_APPVIEW_TOP 0
-#define MARGIN_APPVIEW_BOTTOM 24
-#define MARGIN_APPVIEW_LEFT 24
-#define MARGIN_APPVIEW_RIGHT 24
-
-
-#define HILDON_APPVIEW_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
- HILDON_TYPE_APPVIEW, HildonAppViewPrivate))
-
-/*Progressbar*/
-#define DEFAULT_WIDTH 20
-#define DEFAULT_HEIGHT 28
-#define BANNER_WIDTH DEFAULT_WIDTH
-#define BANNER_HEIGHT DEFAULT_HEIGHT
-
-static GtkBinClass *parent_class;
-
-static void hildon_appview_init(HildonAppView * self);
-static void hildon_appview_class_init(HildonAppViewClass * appview_class);
-
-static void hildon_appview_menupopupfunc(GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget);
-static void hildon_appview_menupopupfuncfull(GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget);
-static gboolean hildon_appview_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static void hildon_appview_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void hildon_appview_show_all(GtkWidget *widget);
-
-static void hildon_appview_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static void hildon_appview_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void hildon_appview_finalize(GObject * obj_self);
-static void hildon_appview_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec);
-static void hildon_appview_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec);
-static void hildon_appview_destroy(GtkObject *obj);
-static void hildon_appview_real_fullscreen_state_change(HildonAppView *
- self,
- gboolean
- fullscreen);
-static void hildon_appview_switched_to(HildonAppView * self);
-static void get_client_area(GtkWidget * widget,
- GtkAllocation * allocation);
-
-typedef void (*HildonAppViewSignal) (HildonAppView *, gint, gpointer);
-
-/* signals */
-enum {
- TOOLBAR_CHANGED,
- TOOLBAR_TOGGLE_REQUEST,
- FULLSCREEN_STATE_CHANGE,
- TITLE_CHANGE,
- SWITCHED_TO,
- SWITCHED_FROM,
- INCREASE_BUTTON_EVENT,
- DECREASE_BUTTON_EVENT,
- HILDON_APPVIEW_LAST_SIGNAL
-};
-
-static guint appview_signals[HILDON_APPVIEW_LAST_SIGNAL] = { 0 };
-
-enum {
- WIN_TYPE = 0,
- WIN_TYPE_MESSAGE,
- MAX_WIN_MESSAGES
-};
-
-struct _HildonAppViewPrivate {
- GtkWidget *menu;
- gchar *title;
-
- GtkAllocation allocation;
-
- guint fullscreen : 1;
- guint fullscreenshortcutallowed : 1;
-
- /* For future expansion.
- * We might use the below variables for disabling keyrepeat if we need it someday. */
- guint increase_button_pressed_down : 1;
- guint decrease_button_pressed_down : 1;
- gint visible_toolbars;
- GtkAdjustment * connected_adjustment;
-
- gchar *menu_ui;
-};
-
-/* FIXME: Extremely old Legacy code. I wonder why we need
- a custom marshaller in the first place. */
-static void hildon_appview_signal_marshal(GClosure * closure,
- GValue * return_value,
- guint n_param_values,
- const GValue * param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- register HildonAppViewSignal callback;
- register GCClosure *cc = (GCClosure *) closure;
- register gpointer data1, data2;
-
- g_assert(n_param_values == 2);
-
- if (G_CCLOSURE_SWAP_DATA(closure)) {
- data1 = closure->data;
- data2 = g_value_peek_pointer(param_values + 0);
- } else {
- data1 = g_value_peek_pointer(param_values + 0);
- data2 = closure->data;
- }
-
- callback =
- /* FIXME: This is a compilation workaround for gcc > 3.3 since glib is buggy */
- /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
-
-#ifdef __GNUC__
- __extension__
-#endif
- (HildonAppViewSignal) (marshal_data !=
- NULL ? marshal_data : cc->callback);
-
- callback((HildonAppView *) data1,
- (gint) g_value_get_int(param_values + 1), data2);
-}
-
-GType hildon_appview_get_type(void)
-{
- static GType appview_type = 0;
-
- if (!appview_type) {
- static const GTypeInfo appview_info = {
- sizeof(HildonAppViewClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_appview_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonAppView),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_appview_init,
- };
- appview_type = g_type_register_static(GTK_TYPE_BIN,
- "HildonAppView",
- &appview_info, 0);
- }
- return appview_type;
-}
-
-/*
- * Class initialisation.
- */
-static void hildon_appview_class_init(HildonAppViewClass * appview_class)
-{
- /* Get convenience variables */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(appview_class);
- GObjectClass *object_class = G_OBJECT_CLASS(appview_class);
- GtkContainerClass *container_class =
- GTK_CONTAINER_CLASS(appview_class);
-
- /* Set the global parent_class here */
- parent_class = g_type_class_peek_parent(appview_class);
-
- object_class->set_property = hildon_appview_set_property;
- object_class->get_property = hildon_appview_get_property;
-
- /* Set the widgets virtual functions */
- widget_class->size_allocate = hildon_appview_size_allocate;
- widget_class->size_request = hildon_appview_size_request;
- widget_class->expose_event = hildon_appview_expose;
- widget_class->show_all = hildon_appview_show_all;
- /* widget_class->realize = hildon_appview_realize; */
-
- /* now the object stuff */
- object_class->finalize = hildon_appview_finalize;
-
- /* To the container */
- container_class->forall = hildon_appview_forall;
-
- /* gtkobject stuff*/
- GTK_OBJECT_CLASS(appview_class)->destroy = hildon_appview_destroy;
-
- /* And own virtual functions */
- appview_class->fullscreen_state_change =
- hildon_appview_real_fullscreen_state_change;
- appview_class->switched_to = hildon_appview_switched_to;
-
- g_type_class_add_private(appview_class,
- sizeof(struct _HildonAppViewPrivate));
-
- /* New signals */
- appview_signals[TOOLBAR_CHANGED] =
- g_signal_new("toolbar-changed",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, toolbar_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- appview_signals[TOOLBAR_TOGGLE_REQUEST] =
- g_signal_new("toolbar-toggle-request",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass,
- toolbar_toggle_request), NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- appview_signals[FULLSCREEN_STATE_CHANGE] =
- g_signal_new("fullscreen_state_change",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass,
- fullscreen_state_change), NULL, NULL,
- hildon_appview_signal_marshal, G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- appview_signals[TITLE_CHANGE] =
- g_signal_new("title_change",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, title_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- appview_signals[SWITCHED_TO] =
- g_signal_new("switched_to",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, switched_to),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- appview_signals[SWITCHED_FROM] =
- g_signal_new("switched_from",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, switched_from),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- appview_signals[INCREASE_BUTTON_EVENT] =
- g_signal_new("increase_button_event",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, increase_button_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- appview_signals[DECREASE_BUTTON_EVENT] =
- g_signal_new("decrease_button_event",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonAppViewClass, decrease_button_event),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- /* New properties */
- g_object_class_install_property(object_class, PROP_CONNECTED_ADJUSTMENT,
- g_param_spec_object("connected-adjustment",
- "Connected GtkAdjustment",
- "The GtkAdjustment. The increase and decrease hardware buttons are mapped to this.",
- GTK_TYPE_ADJUSTMENT,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_FULLSCREEN_KEY_ALLOWED,
- g_param_spec_boolean("fullscreen-key-allowed",
- "Fullscreen key allowed",
- "Whether the fullscreen key is allowed or not",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_FULLSCREEN,
- g_param_spec_boolean("fullscreen",
- "Fullscreen",
- "Whether the appview should be fullscreen or not",
- FALSE,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class, PROP_TITLE,
- g_param_spec_string("title",
- "Title",
- "Appview title",
- NULL,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class, PROP_MENU_UI,
- g_param_spec_string("menu-ui",
- "Menu UI string",
- "UI string for application view menu",
- NULL,
- G_PARAM_READWRITE));
- widget_class = (GtkWidgetClass*) appview_class;
-}
-
-/*
- * Performs the initialisation of the widget.
- */
-static void hildon_appview_init(HildonAppView * self)
-{
- HildonAppViewPrivate *priv = self->priv =
- HILDON_APPVIEW_GET_PRIVATE(self);
-
- /* the vbox is used to handle both the view's main body and how many
- * toolbars as the user wants */
-
- self->vbox = gtk_vbox_new(TRUE, TOOLBAR_MIDDLE);
- /* TOOLBAR_MIDDLE is here properly used, as originally meant. In order to
- * be free to use whatever distance between toolbars, it's crucial to mind
- * that the relevant gtkrc file must contain the following border property
- * for the "toolbar-frame-middle" property: border = {24, 24, 5, 4}
- */
-
- gtk_widget_set_parent(self->vbox, GTK_WIDGET(self));
- priv->menu = NULL;
- priv->visible_toolbars = 0;
-
- priv->title = g_strdup("");
-
- priv->fullscreen = FALSE;
- priv->fullscreenshortcutallowed = FALSE;
- priv->increase_button_pressed_down = FALSE;
- priv->decrease_button_pressed_down = FALSE;
-
- priv->connected_adjustment = NULL;
-}
-
-/*
- * Performs the standard gtk finalize function, freeing allocated
- * memory and propagating the finalization to the parent.
- */
-static void hildon_appview_finalize(GObject * obj_self)
-{
- HildonAppView *self;
- g_assert(HILDON_APPVIEW(obj_self));
- self = HILDON_APPVIEW(obj_self);
-
- if (self->priv->menu_ui)
- g_free (self->priv->menu_ui);
-
- if (self->priv->connected_adjustment != NULL)
- g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
- (gpointer) &self->priv->connected_adjustment);
-
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(obj_self);
-
- g_free(self->priv->title);
-}
-
-/*
- * An accessor to set private properties of HildonAppView.
- */
-static void hildon_appview_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonAppView *appview = HILDON_APPVIEW (object);
-
- switch (property_id) {
- case PROP_CONNECTED_ADJUSTMENT:
- hildon_appview_set_connected_adjustment (appview, g_value_get_object (value));
- break;
-
- case PROP_FULLSCREEN_KEY_ALLOWED:
- hildon_appview_set_fullscreen_key_allowed (appview, g_value_get_boolean (value));
- break;
-
- case PROP_FULLSCREEN:
- hildon_appview_set_fullscreen (appview, g_value_get_boolean (value));
- break;
-
- case PROP_TITLE:
- hildon_appview_set_title (appview, g_value_get_string (value));
- break;
-
- case PROP_MENU_UI:
- hildon_appview_set_menu_ui (appview, g_value_get_string (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-/*
- * An accessor to get private properties of HildonAppView.
- */
-static void hildon_appview_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(object);
-
- switch (property_id) {
- case PROP_CONNECTED_ADJUSTMENT:
- g_value_set_object (value, priv->connected_adjustment);
- break;
-
- case PROP_FULLSCREEN_KEY_ALLOWED:
- g_value_set_boolean (value, priv->fullscreenshortcutallowed);
- break;
-
- case PROP_FULLSCREEN:
- g_value_set_boolean (value, priv->fullscreen);
- break;
-
- case PROP_TITLE:
- g_value_set_string (value, priv->title);
- break;
-
- case PROP_MENU_UI:
- g_value_set_string (value, priv->menu_ui);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-/*
- * Used when the HildonAppView is exposed, this function gets a GtkBoxChild
- * as first argument, and a pointer to a gint as second argument. If such
- * GtkBoxChild is visible, the function increments the gint. It is used
- * in a loop, to compute the number of visible toolbars.
- */
-static void visible_toolbar(gpointer child, gpointer number_of_visible_toolbars)
-{
- if(GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
- (*((gint *)number_of_visible_toolbars))++;
-}
-
-/*
- * Used in the paint_toolbar function to discover how many toolbars are
- * above the find toolbar. It's called in a loop that iterates through
- * all the children of the GtkVBox of the HildonAppView.
- */
-static void find_findtoolbar_index(gpointer child, gpointer number_of_visible_toolbars)
-{
- gint *pass_bundle = (gint *)number_of_visible_toolbars;
-
- if(((GtkBoxChild *)child)->widget->allocation.y < pass_bundle[0]
- && GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
- pass_bundle[1]++;
-}
-
-/*
- * Used in the paint_toolbar function, it's get a GtkBoxChild as first argument
- * and a pointer to a GtkWidget as the second one, which will be addressed to
- * the find toolbar widget, if it is contained in the given GtkBoxChild.
- */
-static void find_findtoolbar(gpointer child, gpointer widget)
-{
- if(HILDON_IS_FIND_TOOLBAR(((GtkBoxChild *)child)->widget)
- && GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
- (*((GtkWidget **)widget)) = ((GtkBoxChild *)child)->widget;
-}
-
-/*
- * Paints all the toolbar children of the GtkVBox of the HildonAppView.
- */
-static void paint_toolbar(GtkWidget *widget, GtkBox *box,
- GdkEventExpose * event,
- gboolean fullscreen)
-{
- gint toolbar_num = 0;
- gint ftb_index = 0;
- gint count;
- GtkWidget *findtoolbar = NULL;
- gchar toolbar_mode[40];
-
- /* Iterate through all the children of the vbox of the HildonAppView.
- * The visible_toolbar function increments toolbar_num if the toolbar
- * is visible. After this loop, toobar_num will contain the number
- * of the visible toolbars. */
- g_list_foreach(box->children, visible_toolbar,
- (gpointer) &toolbar_num);
- if(toolbar_num <= 0)
- return;
-
- /* Loop through all the children of the GtkVBox of the HildonAppView.
- * The find_findtoolbar function will assign a pointer to the find toolbar
- * to "findtoolbar" argument. If the findtoolbar is not found, i.e. it
- * isn't in the GtkVBox, then the "findtoolbar" argument will stay NULL */
- g_list_foreach(box->children, find_findtoolbar,
- (gpointer) &findtoolbar);
- if(findtoolbar != NULL){
- gint pass_bundle[2];
-
- /* an array for convient data passing
- * the first member contains the y allocation
- * of the find toolbar, and the second allocation
- * contains the index(how many toolbars are above
- * find toolbar) */
- pass_bundle[0] = findtoolbar->allocation.y;
- pass_bundle[1] = ftb_index;
-
- /* computes how many toolbars are above the find toolbar, and the
- * value is stored in pass_bundle[1] */
- g_list_foreach(box->children, find_findtoolbar_index,
- (gpointer) pass_bundle);
- ftb_index = pass_bundle[1];
- }
- /*upper border*/
- sprintf(toolbar_mode, "toolbar%sframe-top",
- fullscreen ? "-fullscreen-" : "-");
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y -TOOLBAR_UP,
- widget->allocation.width, TOOLBAR_UP);
-
- /*top most toolbar painting*/
- if(findtoolbar != NULL && ftb_index == 0 )
- {
- sprintf(toolbar_mode, "findtoolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y,
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }else{
- sprintf(toolbar_mode, "toolbar%s",
- fullscreen ? "-fullscreen" : "");
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y,
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- /*multi toolbar painting*/
- for(count = 0; count < toolbar_num - 1; count++)
- {
- sprintf(toolbar_mode, "toolbar%sframe-middle",
- fullscreen ? "-fullscreen-" : "-");
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * TOOLBAR_HEIGHT +
- count * TOOLBAR_MIDDLE,
- widget->allocation.width,
- TOOLBAR_MIDDLE);
-
- if(findtoolbar != NULL && count + 1 == ftb_index){
- sprintf(toolbar_mode, "findtoolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }else{
- sprintf(toolbar_mode, "toolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- }
- sprintf(toolbar_mode, "toolbar%sframe-bottom",
- fullscreen ? "-fullscreen-" : "-");
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- GTK_WIDGET(box)->allocation.height,
- widget->allocation.width, TOOLBAR_DOWN);
-}
-
-/*
- * Callback function to an expose event.
- */
-static gboolean hildon_appview_expose(GtkWidget * widget,
- GdkEventExpose * event)
-{
- gint toolbar_num = 0;
- GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox);
-
- if(GTK_WIDGET_VISIBLE(box) && box->children != NULL)
- {
- HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(widget);
-
- /* Iterate through all the children of the vbox of the HildonAppView.
- * The visible_toolbar function increments toolbar_num if the toolbar
- * is visible. After this loop, toobar_num will contain the number
- * of the visible toolbars. */
- g_list_foreach(box->children, visible_toolbar,
- (gpointer) &toolbar_num);
-
- if( priv->visible_toolbars != toolbar_num)
- {
- /* If the code reaches this block, it means that a toolbar as
- * been added or removed since last time the view was drawn.
- * Let's then compute the new height of the toolbars areas */
- gint y_pos = 0;
- /* the height difference */
- gint change = (priv->visible_toolbars - toolbar_num) *
- (TOOLBAR_HEIGHT+TOOLBAR_MIDDLE+TOOLBAR_UP);
- if( change < 0 )
- change = TOOLBAR_MIDDLE + TOOLBAR_UP;
- /* the new y-coordinate for the toolbars area */
- y_pos = HILDON_APPVIEW(widget)->vbox->allocation.y - change;
-
- gtk_widget_queue_draw_area(widget, 0, y_pos, widget->allocation.width,
- change + HILDON_APPVIEW(widget)->vbox->allocation.height +
- TOOLBAR_DOWN);
- priv->visible_toolbars = toolbar_num;
- }
- }
-
-
- if (HILDON_APPVIEW(widget)->priv->fullscreen)
- {
- if (toolbar_num > 0)
- paint_toolbar(widget, box, event, TRUE);
- }
- else
- {
- gint appview_height_decrement = 0;
- if (toolbar_num > 0)
- {
- appview_height_decrement = toolbar_num * TOOLBAR_HEIGHT +
- (toolbar_num - 1) * TOOLBAR_MIDDLE
- + TOOLBAR_UP + TOOLBAR_DOWN;
-
- paint_toolbar(widget, box, event, FALSE);
- }
- else
- {
- appview_height_decrement = MARGIN_APPVIEW_BOTTOM;
-
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, "bottom-border",
- widget->allocation.x,
- widget->allocation.y +
- (widget->allocation.height - MARGIN_APPVIEW_BOTTOM),
- widget->allocation.width, MARGIN_APPVIEW_BOTTOM);
- }
- gtk_paint_box( widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area,
- widget, "left-border", widget->allocation.x,
- widget->allocation.y, MARGIN_APPVIEW_LEFT,
- widget->allocation.height - appview_height_decrement );
- gtk_paint_box( widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area,
- widget, "right-border",
- (widget->allocation.x +
- widget->allocation.width) -
- MARGIN_APPVIEW_RIGHT, widget->allocation.y,
- MARGIN_APPVIEW_RIGHT,
- widget->allocation.height - appview_height_decrement );
- }
-
- GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
-
- return FALSE;
-}
-
-/*
- * Responds to the usual size_request signal.
- */
-static void hildon_appview_size_request(GtkWidget * widget,
- GtkRequisition * requisition)
-{
- HildonAppViewPrivate *priv = HILDON_APPVIEW(widget)->priv;
- GtkWidget *child = GTK_BIN(widget)->child;
-
- /* forward the size_request to the eventual child of the main container */
- if (child)
- gtk_widget_size_request(child, requisition);
-
- /* forward the size_request to the eventual vbox (which may contain
- * toolbars) */
- if (HILDON_APPVIEW(widget)->vbox != NULL)
- gtk_widget_size_request(HILDON_APPVIEW(widget)->vbox, requisition);
-
- /* express the size_request for the view */
- if (priv->fullscreen) {
- requisition->height = WINDOW_HEIGHT;
- requisition->width = WINDOW_WIDTH;
- } else {
- requisition->height = APPVIEW_HEIGHT;
- requisition->width = APPVIEW_WIDTH;
- }
-}
-
-/*
- * Computes size and position for the children of the view.
- */
-static void hildon_appview_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- GtkAllocation box_allocation;
- GtkAllocation alloc = *allocation;
- gint border_width = GTK_CONTAINER(widget)->border_width;
- GtkBin *bin = GTK_BIN(widget);
- GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox);
- gboolean at_least_one_visible_toolbar = FALSE;
-
- if(!GTK_IS_WIDGET(bin->child)) return;
-
- widget->allocation = *allocation;
-
- if (bin->child != NULL && GTK_IS_WIDGET(bin->child)) {
- if (HILDON_APPVIEW(widget)->priv->fullscreen) {
- alloc.x += border_width;
- alloc.y += border_width;
- alloc.width -= (border_width * 2);
- alloc.height -= (border_width * 2);
- } else {
- alloc.x += border_width + MARGIN_APPVIEW_LEFT;
- alloc.y += border_width + MARGIN_APPVIEW_TOP;
- alloc.width -= (border_width * 2) + (MARGIN_APPVIEW_LEFT +
- MARGIN_APPVIEW_RIGHT);
- alloc.height -= (border_width * 2) + MARGIN_APPVIEW_TOP;
- }
- }
-
- if (box->children != NULL) {
- gint length = 0;
- gint box_height = 0;
- /* Iterate through all the children of the vbox of the HildonAppView.
- * The visible_toolbar function increments toolbar_num if the toolbar
- * is visible. After this loop, toobar_num will contain the number
- * of the visible toolbars. */
- g_list_foreach(box->children, visible_toolbar,
- (gpointer) &length);
- if(length > 0){
- box_height = length * TOOLBAR_HEIGHT +
- (length - 1) * TOOLBAR_MIDDLE;
-
- if(bin->child != NULL) {
- alloc.height = alloc.height - box_height - TOOLBAR_UP
- - TOOLBAR_DOWN;
- at_least_one_visible_toolbar = TRUE;
- }
-
- box_allocation.y = allocation->height - box_height - TOOLBAR_DOWN;
- box_allocation.height = box_height;
- box_allocation.x = allocation->x + TOOLBAR_LEFT;
- box_allocation.width = allocation->width - TOOLBAR_LEFT -
- TOOLBAR_RIGHT;
- gtk_widget_size_allocate(GTK_WIDGET(box), &box_allocation);
- }
- }
-
- /* The bottom skin graphics is visible only when there are no toolbars */
- if ((HILDON_APPVIEW(widget)->priv->fullscreen == FALSE) &&
- (at_least_one_visible_toolbar == FALSE))
- alloc.height -= MARGIN_APPVIEW_BOTTOM;
-
- gtk_widget_size_allocate(GTK_WIDGET(bin->child), &alloc);
-}
-
-/*
- * Overrides gtk_container_forall, calling the callback function for each of
- * the children of HildonAppPrivate.
- */
-static void hildon_appview_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- HildonAppView *self = HILDON_APPVIEW(container);
-
- g_assert(callback != NULL);
-
- GTK_CONTAINER_CLASS(parent_class)->forall(container, include_internals,
- callback, callback_data);
- if(include_internals && self->vbox != NULL)
- (* callback)(GTK_WIDGET(self->vbox), callback_data);
-}
-
-/**
- * Shows all the widgets in the container.
- */
-static void hildon_appview_show_all(GtkWidget *widget)
-{
- HildonAppView *self = HILDON_APPVIEW(widget);
-
- /* Toolbar items */
- gtk_widget_show_all(self->vbox);
-
- /* Parent handless stuff inside appview */
- GTK_WIDGET_CLASS(parent_class)->show_all(widget);
-}
-
-/*
- * Frees all the resources and propagates the destroy call to the parent.
- */
-static void hildon_appview_destroy(GtkObject *obj)
-{
- HildonAppView *self = HILDON_APPVIEW(obj);
-
- if(self->vbox != NULL){
- gtk_widget_unparent(self->vbox);
- self->vbox = NULL;
- }
-
- GTK_OBJECT_CLASS(parent_class)->destroy(obj);
-}
-
-/*******************/
-/* Signals */
-/*******************/
-
-/*Signal - When is changed to this appview, this is called*/
-static void hildon_appview_switched_to(HildonAppView * self)
-{
- GtkWidget *parent;
-
- g_assert(self && HILDON_IS_APPVIEW(self));
-
- parent = gtk_widget_get_parent(GTK_WIDGET(self));
- hildon_appview_set_fullscreen( self, self->priv->fullscreen );
-}
-
-/*Signal - When the fullscreen state is changed, this is called*/
-static void hildon_appview_real_fullscreen_state_change(HildonAppView *
- self,
- gboolean
- fullscreen)
-{
- HildonAppViewPrivate *priv;
- g_assert(self && HILDON_IS_APPVIEW(self));
- priv = self->priv;
-
- /* Ensure that state is really changed */
- if( priv->fullscreen == fullscreen )
- return;
-
- if( fullscreen )
- gtk_window_fullscreen( GTK_WINDOW(
- gtk_widget_get_parent(GTK_WIDGET(self))) );
- else
- gtk_window_unfullscreen( GTK_WINDOW(
- gtk_widget_get_parent(GTK_WIDGET(self))) );
-
- priv->fullscreen = fullscreen;
-}
-
-/*******************/
-/* General */
-/*******************/
-
-
-/*
- * queries a window for the root window coordinates and size of its
- * client area (i.e. minus the title borders etc.)
- */
-static void get_client_area(GtkWidget * widget, GtkAllocation * allocation)
-{
- GdkWindow *window = widget->window;
-
- if (window)
- gdk_window_get_origin(window, &allocation->x, &allocation->y);
- else
- memset( allocation, 0, sizeof(GtkAllocation) );
-}
-
-/*The menu popuping needs a menu popup-function*/
-static void hildon_appview_menupopupfunc( GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in, GtkWidget *widget )
-{
- GtkAllocation client_area = { 0, 0, 0, 0 };
-
- get_client_area( GTK_WIDGET(widget), &client_area );
-
- gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
- "vertical-offset", y, NULL);
-
- *x += client_area.x;
- *y += client_area.y;
-
-}
-
-/* Similar to above, but used in fullscreen mode */
-static void hildon_appview_menupopupfuncfull( GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget )
-{
- gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
- "vertical-offset", y, NULL);
-
- *x = MAX (0, *x);
- *y = MAX (0, *y);
-}
-
-/*******************/
-/*public functions*/
-/*******************/
-
-
-/**
- * hildon_appview_new:
- * @title:the application view title of the new @HildonAppView
- *
- * Use this function to create a new application view. The title will
- * be set only if two-part-title is enabled on the @HildonApp.
- *
- * Returns: A #HildonAppView.
- **/
-GtkWidget *hildon_appview_new(const gchar * title)
-{
- HildonAppView *newappview = g_object_new(HILDON_TYPE_APPVIEW, NULL);
-
- hildon_appview_set_title(newappview, title);
- return GTK_WIDGET(newappview);
-}
-
-/**
- * hildon_appview_add_with_scrollbar
- * @self : a @HildonAppView
- * @child : a @GtkWidget
- *
- * Adds the @child to the @self(HildonAppView) and creates a vertical
- * scrollbar to it. Similar as adding first a #GtkScrolledWindow
- * and then the @child to it.
- */
-void hildon_appview_add_with_scrollbar(HildonAppView * self,
- GtkWidget * child)
-{
- GtkScrolledWindow *scrolledw;
-
- g_return_if_fail(HILDON_IS_APPVIEW(self));
- g_return_if_fail(GTK_IS_WIDGET(child));
- g_return_if_fail(child->parent == NULL);
-
- scrolledw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
- gtk_scrolled_window_set_policy(scrolledw, GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(scrolledw, GTK_SHADOW_NONE);
-
- /* Check whether child widget supports adjustments */
- if (GTK_WIDGET_GET_CLASS (child)->set_scroll_adjustments_signal)
- gtk_container_add(GTK_CONTAINER(scrolledw), child);
- else
- {
- if( GTK_IS_CONTAINER(child) )
- gtk_container_set_focus_vadjustment( GTK_CONTAINER(child),
- gtk_scrolled_window_get_vadjustment(scrolledw) );
- gtk_scrolled_window_add_with_viewport(scrolledw, child);
- }
-
- gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(scrolledw));
-}
-
-/**
- * hildon_appview_get_title:
- * @self : a #HildonAppView
- *
- * Gets the title of given #HildonAppView.
- *
- * Returns: the title of the application view
- */
-const gchar *hildon_appview_get_title(HildonAppView * self)
-{
- g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), "");
- return self->priv->title;
-}
-
-/**
- * hildon_appview_set_title:
- * @self : a #HildonAppView
- * @newname : the new title of the application view.
- *
- * Sets an title of an application view. The title is visible only if
- * two-part-title is enabled on the #HildonApp.
- *
- */
-void hildon_appview_set_title(HildonAppView * self, const gchar * newname)
-{
- gchar *oldtitle;
-
- g_return_if_fail(self && HILDON_IS_APPVIEW(self));
- oldtitle = self->priv->title;
-
- if (newname != NULL)
- self->priv->title = g_strdup(newname);
- else
- self->priv->title = g_strdup("");
-
- g_free(oldtitle);
- g_signal_emit_by_name(G_OBJECT(self), "title_change");
-}
-
-/**
- * hildon_appview_set_toolbar:
- * @self: a #HildonAppView
- * @toolbar: a #GtkToolbar
- *
- * Sets the #GtkToolbar to given #HildonAppView. This is, however, not a
- * recommended way to set your toolbars. When you have multi toolbars, calling
- * this function more than once will just replace the bottom most toolbar.
- * There is a #GtkVBox in #HildonAppView's public structure, the programmer
- * is responsible to pack his toolbars in the #GtkVBox, and #HildonAppView will
- * take care of putting them at the right place.
- *
- */
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_appview_set_toolbar(HildonAppView * self, GtkToolbar * toolbar)
-{
- GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox);
- g_return_if_fail(self && HILDON_IS_APPVIEW(self));
- if(toolbar != NULL)/*for failure checking*/
- g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
-
- /*if it is NULL, it unsets the last one,
- * if it is not null, it unsets the last one anyway*/
- if(box->children != NULL){
- GtkWidget *last_widget;
-
- last_widget = ((GtkBoxChild *)g_list_last
- (box->children)->data)->widget;
- gtk_container_remove(GTK_CONTAINER(box),
- last_widget);
- }
-
- gtk_box_pack_end(box, GTK_WIDGET(toolbar), TRUE, TRUE, 0);
- gtk_widget_queue_resize(GTK_WIDGET(self));
- /*deprecated signal*/
- g_signal_emit_by_name(G_OBJECT(self), "toolbar-changed");
-}
-#endif
-/**
- * hildon_appview_get_toolbar:
- * @self: a #HildonAppView
- *
- * This function will only
- * return the last widget that has been packed into the #GtkVBox in the public
- * structure. Note this does not, however, mean that it is the bottom most
- * toolbar.
- *
- * Return value: the #GtkToolbar assigned to this application view.
- **/
-#ifndef HILDON_DISABLE_DEPRECATED
-GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self)
-{
- GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox);
- g_return_val_if_fail(self != NULL && HILDON_IS_APPVIEW(self), FALSE);
- if(box != NULL && box->children != NULL)
- return GTK_TOOLBAR(((GtkBoxChild*)
- g_list_last(box->children)->data)->widget);
- else
- return NULL;
-}
-#endif
-/**
- * hildon_appview_set_fullscreen:
- * @self: a #HildonAppView
- * @fullscreen: the new state of fullscreen mode. TRUE means fullscreen
- * will be set. FALSE the opposite.
- *
- * Set the fullscreen state of given #HildonAppView class.
- */
-void hildon_appview_set_fullscreen(HildonAppView * self,
- gboolean fullscreen)
-{
- g_return_if_fail(self && HILDON_IS_APPVIEW(self));
- g_signal_emit_by_name(G_OBJECT(self), "fullscreen_state_change",
- fullscreen);
-}
-
-/**
- * hildon_appview_get_fullscreen:
- * @self: a #HildonAppView
- *
- * Gets the current state of fullscreen mode.
- *
- * Returns: the current state of fullscreen mode
- */
-gboolean hildon_appview_get_fullscreen(HildonAppView * self)
-{
- g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
- return self->priv->fullscreen;
-}
-
-/**
- * hildon_appview_get_fullscreen_key_allowed:
- * @self: a #HildonAppView
- *
- * Check if fullscreening with a shortcut is allowed for given
- * #HildonAppView.
- *
- * Returns: wheter it's possible to swith fullscreen on/off with
- * a shortcut key
- */
-gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self)
-{
- g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
- return self->priv->fullscreenshortcutallowed;
-}
-
-/**
- * hildon_appview_set_fullscreen_key_allowed:
- * @self: a #HildonAppView
- * @allow: wheter it's possible to swith fullscreen on/off with
- * a shortcut key
- *
- * Sets given #HildonAppView whether to allow toggling fullscreen mode
- * with a shortcut key.
- */
-void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self,
- gboolean allow)
-{
- g_return_if_fail(self && HILDON_IS_APPVIEW(self));
- self->priv->fullscreenshortcutallowed = allow;
-}
-
-/**
- * hildon_appview_get_menu:
- * @self : #HildonAppView
- *
- * Gets the #GtMenu assigned to the #HildonAppview.
- *
- * Returns: the #GtkMenu assigned to this application view
- */
-GtkMenu *hildon_appview_get_menu(HildonAppView * self)
-{
- g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), NULL);
-
- if (self->priv->menu == NULL) {
- /* Create hildonlike menu */
-
- GtkUIManager *uim;
- GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));
-
- /* Try to get appview menu from ui manager */
- if (parent && HILDON_IS_APP (parent))
- {
- uim = hildon_app_get_ui_manager (HILDON_APP (parent));
- if (uim)
- {
- self->priv->menu =
- gtk_ui_manager_get_widget (uim, "/HildonApp");
- }
- }
-
-
- if (self->priv->menu == NULL)
- {
- /* Fall back to oldskool menus */
- self->priv->menu = GTK_WIDGET (g_object_new (GTK_TYPE_MENU, NULL));
- }
-
- gtk_widget_set_name(GTK_WIDGET(self->priv->menu),
- "menu_force_with_corners");
- gtk_widget_show_all (self->priv->menu);
- }
-
- return GTK_MENU(self->priv->menu);
-}
-
-/**
- * _hildon_appview_toggle_menu:
- * @self : a #HildonAppView
- * @button_event_time :
- *
- * This function should be only called from @HildonApp.
- * Should be renamed to popup menu. Just the first parameter is used.
- *
- * Returns: Whether or not something was done (whether or not we had
- * a menu)
- */
-gboolean _hildon_appview_toggle_menu(HildonAppView * self,
- Time button_event_time)
-{
- GList *children;
-
- g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
-
- if (!self->priv->menu)
- return FALSE;
-
- if (GTK_WIDGET_VISIBLE(self->priv->menu)) {
- gtk_menu_popdown(GTK_MENU(self->priv->menu));
- gtk_menu_shell_deactivate(GTK_MENU_SHELL(self->priv->menu));
- return TRUE;
- }
-
- /* Avoid opening an empty menu */
- children = gtk_container_get_children(
- GTK_CONTAINER(hildon_appview_get_menu(self)));
- if (children != NULL) {
- GtkWidget *menu;
-
- g_list_free(children);
- menu = GTK_WIDGET(hildon_appview_get_menu(self));
- if (self->priv->fullscreen) {
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
- (GtkMenuPositionFunc)
- hildon_appview_menupopupfuncfull,
- self, 0, button_event_time);
- } else {
- gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
- (GtkMenuPositionFunc)
- hildon_appview_menupopupfunc,
- self, 0, button_event_time);
- }
- gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), TRUE);
- return TRUE;
- }
- return FALSE;
-
-}
-
-/**
- * _hildon_appview_menu_visible
- * @self: a #HildonAppView
- *
- * Checks whether the titlebar menu is currently visible
- * Returns: TRUE if the menu is visible, FALSE if not
- */
-
-gboolean _hildon_appview_menu_visible(HildonAppView * self)
-{
- g_return_val_if_fail (HILDON_IS_APPVIEW (self), FALSE);
-
- return GTK_WIDGET_VISIBLE(GTK_WIDGET(hildon_appview_get_menu(self)));
-}
-
-/**
- * hildon_appview_set_connected_adjustment
- * @self : #HildonAppView
- * @adjustment : a new #GtkAdjustment set to reach to increase
- * / decrease hardware keys or NULL to unset
- *
- * Sets a #GtkAdjustment which will change when increase/decrease buttons
- * are pressed.
- */
-void hildon_appview_set_connected_adjustment (HildonAppView * self,
- GtkAdjustment * adjustment)
-{
- g_return_if_fail (HILDON_IS_APPVIEW (self));
-
- /* Disconnect old adjustment */
- if (self->priv->connected_adjustment != NULL)
- g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
- (gpointer) &self->priv->connected_adjustment);
-
- /* Start using the new one */
- self->priv->connected_adjustment = adjustment;
- if (self->priv->connected_adjustment != NULL)
- g_object_add_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
- (gpointer) &self->priv->connected_adjustment);
-}
-
-/**
- * hildon_appview_get_connected_adjustment
- * @self : a #HildonAppView
- *
- * Retrieves the #GtkAdjustment which is connected to this application view
- * and is changed with increase / decrease hardware buttons.
- *
- * Returns: currently connectd #GtkAdjustment assigned to this
- * application view or NULL if it's not set
- */
-GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self)
-{
- g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL);
-
- return self->priv->connected_adjustment;
-}
-
-
-/**
- * hildon_appview_set_menu_ui
- * @self : a #HildonAppView
- * @ui_string : a #GtkUIManager ui description string
- *
- * Sets the ui description (xml) from which the UIManager creates menus
- * (see @GtkUIManager for details on how to use it)
- */
-void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string)
-{
- g_return_if_fail (HILDON_IS_APPVIEW (self));
-
- if (ui_string)
- {
- if (self->priv->menu_ui)
- g_free (self->priv->menu_ui);
-
- self->priv->menu_ui = g_strdup (ui_string);
-
- /* FIXME: We should update the menu here, preferrably by a
- * hildon_app_ensure_menu_update() which re-installs the menu ui
- * and calls gtk_ui_manager_ensure_update()
- */
- }
- else
- {
- /* Reset the UI */
- if (self->priv->menu_ui)
- {
- g_free (self->priv->menu_ui);
- self->priv->menu_ui = NULL;
- }
- }
-
- g_object_notify (G_OBJECT(self), "menu-ui");
-}
-
-/**
- * hildon_appview_get_menu_ui
- * @self : a #HildonAppView
- *
- * Sets the ui description (xml) from which the UIManager creates menus
- * (see #GtkUIManager for details on how to use it)
- *
- * Returns: currently set ui description
- */
-const gchar *hildon_appview_get_menu_ui(HildonAppView *self)
-{
- g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL);
-
- return (self->priv->menu_ui);
-
-}
-
-/* Called when '+' hardkey is pressed/released */
-void _hildon_appview_increase_button_state_changed (HildonAppView * self,
- guint newkeytype)
-{
- self->priv->increase_button_pressed_down = newkeytype;
-
- /* Transform '+' press into adjustment update (usually scrollbar move) */
- if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS))
- {
- gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) + self->priv->connected_adjustment->step_increment,
- self->priv->connected_adjustment->lower,
- self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size);
- gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue);
- }
-
- g_signal_emit (G_OBJECT (self), appview_signals[INCREASE_BUTTON_EVENT], 0, newkeytype);
-}
-
-/* Called when '-' hardkey is pressed/released */
-void _hildon_appview_decrease_button_state_changed (HildonAppView * self,
- guint newkeytype)
-{
- self->priv->decrease_button_pressed_down = newkeytype;
-
- /* Transform '-' press into adjustment update (usually scrollbar move) */
- if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS))
- {
- gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) - self->priv->connected_adjustment->step_increment,
- self->priv->connected_adjustment->lower,
- self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size);
- gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue);
- }
-
- g_signal_emit (G_OBJECT (self), appview_signals[DECREASE_BUTTON_EVENT], 0, newkeytype);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_APPVIEW_H__
-#define __HILDON_APPVIEW_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtkbin.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtktoolbar.h>
-#include <gdk/gdkx.h>
-
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_APPVIEW ( hildon_appview_get_type() )
-#define HILDON_APPVIEW(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_APPVIEW, HildonAppView))
-#define HILDON_APPVIEW_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_APPVIEW, HildonAppViewClass))
-#define HILDON_IS_APPVIEW(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APPVIEW))
-#define HILDON_IS_APPVIEW_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_APPVIEW))
-typedef struct _HildonAppView HildonAppView;
-typedef struct _HildonAppViewClass HildonAppViewClass;
-
-/**
- * HildonAppViewPrivate:
- *
- * This structure contains just internal data. It should not
- * be accessed directly.
- */
-typedef struct _HildonAppViewPrivate HildonAppViewPrivate;
-
-struct _HildonAppView {
- GtkBin parent;
-
- /*public*/
- GtkWidget *vbox;
-
- /*private*/
- HildonAppViewPrivate *priv;
-};
-
-struct _HildonAppViewClass {
- GtkBinClass parent_class;
- void (*toolbar_changed) (HildonAppView * self);
- void (*toolbar_toggle_request) (HildonAppView * self);
- void (*fullscreen_state_change) (HildonAppView * self,
- gboolean is_fullscreen);
- void (*title_change) (HildonAppView * self);
- void (*switched_to) (HildonAppView * self);
- void (*switched_from) (HildonAppView * self);
- void (*increase_button_event) (HildonAppView * self,
- guint newkeytype);
- void (*decrease_button_event) (HildonAppView * self,
- guint newkeytype);
-};
-
-
-GType hildon_appview_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_appview_new(const gchar * title);
-void hildon_appview_add_with_scrollbar(HildonAppView * self,
- GtkWidget * child);
-void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self,
- gboolean allow);
-gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self);
-
-gboolean hildon_appview_get_fullscreen(HildonAppView * self);
-void hildon_appview_set_fullscreen(HildonAppView * self,
- gboolean fullscreen);
-GtkMenu *hildon_appview_get_menu(HildonAppView * self);
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_appview_set_toolbar(HildonAppView * self,
- GtkToolbar * toolbar);
-GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self);
-#endif
-void hildon_appview_set_title(HildonAppView * self, const gchar * newname);
-const gchar *hildon_appview_get_title(HildonAppView * self);
-
-gboolean _hildon_appview_toggle_menu(HildonAppView * self,
- Time button_event_time);
-gboolean _hildon_appview_menu_visible(HildonAppView * self);
-
-void hildon_appview_set_connected_adjustment (HildonAppView * self,
- GtkAdjustment * adjustment);
-GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self);
-
-void _hildon_appview_increase_button_state_changed (HildonAppView * self,
- guint newkeytype);
-void _hildon_appview_decrease_button_state_changed (HildonAppView * self,
- guint newkeytype);
-
-void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string);
-const gchar *hildon_appview_get_menu_ui(HildonAppView *self);
-
-G_END_DECLS
-#endif /* HILDON_APPVIEW_H */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkicontheme.h>
-#include <string.h>
-#include <X11/X.h>
-#include <X11/Xatom.h>
-
-#include "hildon-defines.h"
-#include "hildon-banner.h"
-
-/* position relative to the screen */
-#define HILDON_BANNER_WINDOW_X 30
-#define HILDON_BANNER_WINDOW_Y 73
-#define HILDON_BANNER_WINDOW_FULLSCREEN_Y 20
-
-/* max widths */
-#define HILDON_BANNER_PROGRESS_WIDTH 104
-#define HILDON_BANNER_LABEL_MAX_TIMED 375
-#define HILDON_BANNER_LABEL_MAX_PROGRESS 375 /*265*/
-
-/* default timeout */
-#define HILDON_BANNER_TIMEOUT 3000
-
-/* default icons */
-#define HILDON_BANNER_DEFAULT_ICON "qgn_note_infoprint"
-#define HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION "qgn_indi_pball_a"
-
-enum {
- PROP_PARENT_WINDOW = 1,
- PROP_IS_TIMED
-};
-
-struct _HildonBannerPrivate
-{
- GtkWidget *main_item;
- GtkWidget *label;
- GtkWidget *layout;
- guint timeout_id;
- gboolean is_timed;
-};
-
-static GtkWidget *global_timed_banner = NULL;
-
-G_DEFINE_TYPE(HildonBanner, hildon_banner, GTK_TYPE_WINDOW)
-
-/* copy/paste from old infoprint implementation: Use matchbox
- properties to find the topmost application window */
-static Window get_current_app_window(void)
-{
- unsigned long n;
- unsigned long extra;
- int format;
- int status;
-
- Atom atom_current_app_window = gdk_x11_get_xatom_by_name ("_MB_CURRENT_APP_WINDOW");
- Atom realType;
- Window win_result = None;
- guchar *data_return = NULL;
-
- status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
- atom_current_app_window, 0L, 16L,
- 0, XA_WINDOW, &realType, &format,
- &n, &extra,
- &data_return);
-
- if ( status == Success && realType == XA_WINDOW
- && format == 32 && n == 1 && data_return != NULL )
- {
- win_result = ((Window*) data_return)[0];
- }
-
- if ( data_return )
- XFree(data_return);
-
- return win_result;
-}
-
-/* Checks if a window is in fullscreen state or not. This
- information is needed when banners are positioned on screen.
- copy/paste from old infoprint implementation. */
-static gboolean check_fullscreen_state( Window window )
-{
- unsigned long n;
- unsigned long extra;
- int format, status, i;
- guchar *data_return = NULL;
-
- Atom realType;
- Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
- Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN");
-
- if ( window == None )
- return FALSE;
-
- /* in some cases XGetWindowProperty seems to generate BadWindow,
- so at the moment this function does not always work perfectly */
- gdk_error_trap_push();
- status = XGetWindowProperty(GDK_DISPLAY(), window,
- atom_window_state, 0L, 1000000L,
- 0, XA_ATOM, &realType, &format,
- &n, &extra, &data_return);
- gdk_flush();
- if (gdk_error_trap_pop())
- return FALSE;
-
- if (status == Success && realType == XA_ATOM && format == 32 && n > 0)
- {
- for(i=0; i < n; i++)
- if ( ((Atom*)data_return)[i] &&
- ((Atom*)data_return)[i] == atom_fullscreen)
- {
- if (data_return) XFree(data_return);
- return TRUE;
- }
- }
-
- if (data_return)
- XFree(data_return);
-
- return FALSE;
-}
-
-static GQuark hildon_banner_timed_quark(void)
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY(quark == 0))
- quark = g_quark_from_static_string("hildon-banner-timed");
-
- return quark;
-}
-
-/* Set the label name to make the correct rc-style attached into it */
-static void hildon_banner_bind_label_style(HildonBanner *self,
- const gchar *name)
-{
- GtkWidget *label = self->priv->label;
-
- /* Too bad that we cannot really reset the widget name */
- gtk_widget_set_name(label, name ? name : g_type_name(GTK_WIDGET_TYPE(label)));
-}
-
-/* In timeout function we automatically destroy timed banners */
-static gboolean hildon_banner_timeout(gpointer data)
-{
- GtkWidget *widget;
- GdkEvent *event;
- gboolean continue_timeout = FALSE;
-
- GDK_THREADS_ENTER ();
-
- g_assert(HILDON_IS_BANNER(data));
-
- widget = GTK_WIDGET(data);
- g_object_ref(widget);
-
- /* If the banner is currently visible (it normally should),
- we simulate clicking the close button of the window.
- This allows applications to reuse the banner by prevent
- closing it etc */
- if (GTK_WIDGET_DRAWABLE(widget))
- {
- event = gdk_event_new (GDK_DELETE);
- event->any.window = g_object_ref(widget->window);
- event->any.send_event = FALSE;
- continue_timeout = gtk_widget_event (widget, event);
- gdk_event_free(event);
- }
-
- if (!continue_timeout)
- gtk_widget_destroy (widget);
-
- g_object_unref(widget);
-
- GDK_THREADS_LEAVE ();
-
- return continue_timeout;
-}
-
-static gboolean hildon_banner_clear_timeout(HildonBanner *self)
-{
- g_assert(HILDON_IS_BANNER(self));
-
- if (self->priv->timeout_id != 0) {
- g_source_remove(self->priv->timeout_id);
- self->priv->timeout_id = 0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void hildon_banner_ensure_timeout(HildonBanner *self)
-{
- g_assert(HILDON_IS_BANNER(self));
-
- if (self->priv->timeout_id == 0 && self->priv->is_timed)
- self->priv->timeout_id = g_timeout_add(HILDON_BANNER_TIMEOUT,
- hildon_banner_timeout, self);
-}
-
-static void hildon_banner_set_property(GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkWidget *window;
- GdkGeometry geom;
- HildonBannerPrivate *priv = HILDON_BANNER(object)->priv;
-
- switch (prop_id) {
- case PROP_IS_TIMED:
- priv->is_timed = g_value_get_boolean(value);
-
- /* Timed and progress notifications have different
- pixel size values for text.
- We force to use requisition size for timed banners
- in order to avoid resize problems when reusing the
- window (see bug #24339) */
- geom.max_width = priv->is_timed ? -1
- : HILDON_BANNER_LABEL_MAX_PROGRESS;
- geom.max_height = -1;
- gtk_window_set_geometry_hints(GTK_WINDOW(object),
- priv->label, &geom, GDK_HINT_MAX_SIZE);
- break;
-
- case PROP_PARENT_WINDOW:
- window = g_value_get_object(value);
-
- gtk_window_set_transient_for(GTK_WINDOW(object), (GtkWindow *) window);
-
- if (window)
- gtk_window_set_destroy_with_parent(GTK_WINDOW(object), TRUE);
-
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void hildon_banner_get_property(GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HildonBanner *self = HILDON_BANNER(object);
-
- switch (prop_id)
- {
- case PROP_IS_TIMED:
- g_value_set_boolean(value, self->priv->is_timed);
- break;
-
- case PROP_PARENT_WINDOW:
- g_value_set_object(value, gtk_window_get_transient_for(GTK_WINDOW(object)));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void hildon_banner_destroy(GtkObject *object)
-{
- HildonBanner *self;
- GObject *parent_window;
-
- g_assert(HILDON_IS_BANNER(object));
- self = HILDON_BANNER(object);
-
- /* Drop possible global pointer. That can hold reference to us */
- if ((gpointer) object == (gpointer) global_timed_banner) {
- global_timed_banner = NULL;
- g_object_unref(object);
- }
-
- /* Remove the data from parent window for timed banners. Those hold reference */
- if (self->priv->is_timed &&
- (parent_window = (GObject *) gtk_window_get_transient_for(
- GTK_WINDOW(object))) != NULL)
- g_object_set_qdata(parent_window, hildon_banner_timed_quark(), NULL);
-
- (void) hildon_banner_clear_timeout(self);
-
- if (GTK_OBJECT_CLASS(hildon_banner_parent_class)->destroy)
- GTK_OBJECT_CLASS(hildon_banner_parent_class)->destroy(object);
-}
-
-/* Search a previous banner instance */
-static GObject *hildon_banner_real_get_instance(GObject *window, gboolean timed)
-{
- g_assert(window == NULL || GTK_IS_WINDOW(window));
-
- if (timed) {
- /* If we have a parent window, the previous instance is stored there */
- if (window)
- return g_object_get_qdata(window, hildon_banner_timed_quark());
-
- /* System notification instance is stored into global pointer */
- return (GObject *) global_timed_banner;
- }
-
- /* Non-timed banners are normal (non-singleton) objects */
- return NULL;
-}
-
-/* By overriding constructor we force timed banners to be
- singletons for each window */
-static GObject* hildon_banner_constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- GObject *banner, *window = NULL;
- gboolean timed = FALSE;
- guint i;
-
- /* Search banner type information from parameters in order
- to locate the possible previous banner instance. */
- for (i = 0; i < n_construct_params; i++)
- {
- if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
- window = g_value_get_object(construct_params[i].value);
- else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
- timed = g_value_get_boolean(construct_params[i].value);
- }
-
- /* Try to get a previous instance if such exists */
- banner = hildon_banner_real_get_instance(window, timed);
- if (!banner)
- {
- /* We have to create a new banner */
- banner = G_OBJECT_CLASS(hildon_banner_parent_class)->constructor(
- type, n_construct_params, construct_params);
-
- /* Store the newly created singleton instance either into parent
- window data or into global variables. */
- if (timed) {
- if (window) {
- g_object_set_qdata_full(G_OBJECT(window), hildon_banner_timed_quark(),
- g_object_ref(banner), g_object_unref);
- } else {
- g_assert(global_timed_banner == NULL);
- global_timed_banner = g_object_ref(banner);
- }
- }
- }
- else {
- /* FIXME: This is a hack! We have to manually freeze
- notifications. This is normally done by g_object_init, but we
- are not going to call that. g_object_newv will otherwise give
- a critical like this:
-
- GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
- assertion `nqueue->freeze_count > 0' failed */
-
- g_object_freeze_notify(banner);
- }
-
- /* We restart possible timeouts for each new timed banner request */
- if (timed && hildon_banner_clear_timeout(HILDON_BANNER(banner)))
- hildon_banner_ensure_timeout(HILDON_BANNER(banner));
-
- return banner;
-}
-
-/* We start the timer for timed notifications after the window appears on screen */
-static gboolean hildon_banner_map_event(GtkWidget *widget, GdkEventAny *event)
-{
- gboolean result = FALSE;
-
- if (GTK_WIDGET_CLASS(hildon_banner_parent_class)->map_event)
- result = GTK_WIDGET_CLASS(hildon_banner_parent_class)->map_event(widget, event);
-
- hildon_banner_ensure_timeout(HILDON_BANNER(widget));
-
- return result;
-}
-
-
-/* force to wrap truncated label by setting explicit size request
- * see N#27000 and G#329646 */
-static void force_to_wrap_truncated(HildonBanner *banner){
- GtkLabel *label;
- PangoLayout *layout;
- int width_text, width_max;
- int width = -1;
-
- label = GTK_LABEL(banner->priv->label);
-
- layout = gtk_label_get_layout(label);
- width_text = PANGO_PIXELS(pango_layout_get_width(layout));
- /* = width to which the lines of the PangoLayout should be wrapped */
-
- width_max = banner->priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
- : HILDON_BANNER_LABEL_MAX_PROGRESS;
-
- if(width_text >= width_max){
- /* explicitly request maximum size to force wrapping */
- PangoRectangle logical;
-
- pango_layout_set_width (layout, width_max * PANGO_SCALE);
- pango_layout_get_extents (layout, NULL, &logical);
-
- width = PANGO_PIXELS (logical.width);
- }
-
- /* use fixed width when wrapping or natural one otherwise */
- gtk_widget_set_size_request (GTK_WIDGET (label),
- width, -1);
-}
-
-
-static void hildon_banner_check_position(GtkWidget *widget)
-{
- gint x, y;
- GtkRequisition req;
-
- force_to_wrap_truncated(HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
-
- gtk_widget_size_request(widget, &req);
-
- if (req.width == 0)
- {
- return;
- }
-
- x = gdk_screen_width() - HILDON_BANNER_WINDOW_X - req.width;
- y = check_fullscreen_state(get_current_app_window()) ?
- HILDON_BANNER_WINDOW_FULLSCREEN_Y : HILDON_BANNER_WINDOW_Y;
-
- gtk_window_move(GTK_WINDOW(widget), x, y);
-}
-
-static void hildon_banner_realize(GtkWidget *widget)
-{
- /* We let the parent to init widget->window before we need it */
- if (GTK_WIDGET_CLASS(hildon_banner_parent_class)->realize)
- GTK_WIDGET_CLASS(hildon_banner_parent_class)->realize(widget);
-
- /* We use special hint to turn the banner into information notification. */
- gdk_window_set_type_hint(widget->window, GDK_WINDOW_TYPE_HINT_MESSAGE);
-
- hildon_banner_check_position(widget);
-}
-
-static void hildon_banner_class_init(HildonBannerClass *klass)
-{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = G_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
-
- /* Append private structure to class. This is more elegant than
- on g_new based approach */
- g_type_class_add_private(klass, sizeof(HildonBannerPrivate));
-
- /* Override virtual methods */
- object_class->constructor = hildon_banner_constructor;
- object_class->set_property = hildon_banner_set_property;
- object_class->get_property = hildon_banner_get_property;
- GTK_OBJECT_CLASS(klass)->destroy = hildon_banner_destroy;
- widget_class->map_event = hildon_banner_map_event;
- widget_class->realize = hildon_banner_realize;
-
- /* Install properties.
- We need construct properties for singleton purposes */
- g_object_class_install_property(object_class, PROP_PARENT_WINDOW,
- g_param_spec_object("parent-window",
- "Parent window",
- "The window for which the banner will be singleton",
- GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property(object_class, PROP_IS_TIMED,
- g_param_spec_boolean("is-timed",
- "Is timed",
- "Whether or not the notification goes away automatically "
- "after the specified time has passed",
- FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-static void hildon_banner_init(HildonBanner *self)
-{
- HildonBannerPrivate *priv;
-
- /* Make private data available through cached pointer */
- self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
- HILDON_TYPE_BANNER,
- HildonBannerPrivate);
-
- /* Initialize the common layout inside banner */
- self->priv->layout = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
-
- priv->label = g_object_new(GTK_TYPE_LABEL, NULL);
- gtk_label_set_line_wrap(GTK_LABEL(priv->label), TRUE);
-
- gtk_container_set_border_width(GTK_CONTAINER(self->priv->layout), HILDON_MARGIN_DEFAULT);
- gtk_container_add(GTK_CONTAINER(self), self->priv->layout);
- gtk_box_pack_start(GTK_BOX(self->priv->layout), priv->label, TRUE, TRUE, 0);
-
- gtk_window_set_accept_focus(GTK_WINDOW(self), FALSE);
-}
-
-/* Makes sure that icon/progress item contains the desired type
- of item. If possible, tries to avoid creating a new widget but
- reuses the existing one */
-static void hildon_banner_ensure_child(HildonBanner *self,
- GtkWidget *user_widget,
- guint pos,
- GType type,
- const gchar *first_property, ...)
-{
- GtkWidget *widget;
- va_list args;
-
- g_assert(HILDON_IS_BANNER(self));
- g_assert(user_widget == NULL || GTK_IS_WIDGET(user_widget));
-
- widget = self->priv->main_item;
- va_start(args, first_property);
-
- /* Reuse existing widget if possible */
- if (!user_widget && G_TYPE_CHECK_INSTANCE_TYPE(widget, type))
- {
- g_object_set_valist(G_OBJECT(widget), first_property, args);
- }
- else
- {
- /* We have to abandon old content widget */
- if (widget)
- gtk_container_remove(GTK_CONTAINER(self->priv->layout), widget);
-
- /* Use user provided widget or create a new one */
- self->priv->main_item = widget = user_widget ?
- user_widget : GTK_WIDGET(g_object_new_valist(type, first_property, args));
- gtk_box_pack_start(GTK_BOX(self->priv->layout), widget, TRUE, TRUE, 0);
- }
-
- /* We make sure that the widget exists in desired position. Different
- banners place this child widget to different places */
- gtk_box_reorder_child(GTK_BOX(self->priv->layout), widget, pos);
- va_end(args);
-}
-
-/* Creates a new banner instance or uses an existing one */
-static HildonBanner *hildon_banner_get_instance_for_widget(GtkWidget *widget, gboolean timed)
-{
- GtkWidget *window;
-
- g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
- window = widget ? gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW) : NULL;
- return g_object_new(HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
-}
-
-
-
-
-
-/* Public functions **************************************************************/
-
-/**
- * hildon_banner_show_information:
- * @widget: the #GtkWidget that wants to display banner
- * @icon_name: the name of icon to use. Can be %NULL for default icon.
- * @text: Text to display
- *
- * This function creates and displays an information banner that
- * automatically goes away after certain time period. For each window
- * in your application there can only be one timed banner, so if you
- * spawn a new banner before the earlier one has timed out, the
- * previous one will be replaced.
- *
- * Since: 0.12.2
- */
-void hildon_banner_show_information(GtkWidget *widget,
- const gchar *icon_name,
- const gchar *text)
-{
- HildonBanner *banner;
-
- g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
- g_return_if_fail(icon_name == NULL || icon_name[0] != 0);
- g_return_if_fail(text != NULL);
-
- /* Prepare banner */
- banner = hildon_banner_get_instance_for_widget(widget, TRUE);
- hildon_banner_ensure_child(banner, NULL, 0, GTK_TYPE_IMAGE,
- "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
- "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
- "yalign", 0.0,
- NULL);
- hildon_banner_set_text(banner, text);
- hildon_banner_bind_label_style(banner, NULL);
-
- /* Show the banner, since caller cannot do that */
- gtk_widget_show_all(GTK_WIDGET(banner));
-}
-
-/**
- * hildon_banner_show_information_with_markup:
- * @widget: the #GtkWidget that wants to display banner
- * @icon_name: the name of icon to use. Can be %NULL for default icon.
- * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
- *
- * This function creates and displays an information banner that
- * automatically goes away after certain time period. For each window
- * in your application there can only be one timed banner, so if you
- * spawn a new banner before the earlier one has timed out, the
- * previous one will be replaced.
- *
- * Since: 0.12.8
- */
-void hildon_banner_show_information_with_markup(GtkWidget *widget,
- const gchar *icon_name, const gchar *markup)
-{
- HildonBanner *banner;
-
- g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
- g_return_if_fail(icon_name == NULL || icon_name[0] != 0);
- g_return_if_fail(markup != NULL);
-
- /* Prepare banner */
- banner = hildon_banner_get_instance_for_widget(widget, TRUE);
-
- hildon_banner_ensure_child(banner, NULL, 0, GTK_TYPE_IMAGE,
- "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
- "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
- "yalign", 0.0,
- NULL);
- hildon_banner_set_markup(banner, markup);
- hildon_banner_bind_label_style(banner, NULL);
-
- /* Show the banner, since caller cannot do that */
- gtk_widget_show_all(GTK_WIDGET(banner));
-}
-
-/**
- * hildon_banner_show_animation:
- * @widget: the #GtkWidget that wants to display banner
- * @animation_name: The progress animation to use. You usually can just
- * pass %NULL for the default animation.
- * @text: the text to display.
- *
- * Shows an animated progress notification. It's recommended not to try
- * to show more than one progress notification at a time, since
- * they will appear on top of each other. You can use progress
- * notifications with timed banners. In this case the banners are
- * located so that you can somehow see both.
- *
- * Please note that banners are destroyed automatically once the
- * window they are attached to is closed. The pointer that you
- * receive with this function do not contain additional references,
- * so it can become invalid without warning (this is true for
- * all toplevel windows in gtk). To make sure that the banner do not disapear
- * automatically, you can separately ref the return value (this
- * doesn't prevent the banner from disappearing, but the object it just
- * not finalized). In this case you have to call both #gtk_widget_destroy
- * followed by #g_object_unref (in this order).
- *
- * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
- * once you are ready with the banner.
- *
- * Since: 0.12.2
- */
-GtkWidget *hildon_banner_show_animation(GtkWidget *widget,
- const gchar *animation_name, const gchar *text)
-{
- HildonBanner *banner;
- GtkIconTheme *theme;
- GtkIconInfo *info;
- GtkWidget *image_widget;
- const gchar *filename;
-
- g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
- g_return_val_if_fail(animation_name == NULL || animation_name[0] != 0, NULL);
- g_return_val_if_fail(text != NULL, NULL);
-
- /* Find out which animation to use */
- theme = gtk_icon_theme_get_default();
- info = gtk_icon_theme_lookup_icon(theme, animation_name ? /* TODO: consider using: gtk_icon_theme_load_icon() */
- animation_name : HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION,
- HILDON_ICON_SIZE_NOTE, 0);
-
- /* Try to load animation. One could try to optimize this
- to avoid loading the default animation during each call */
- if (info) {
- filename = gtk_icon_info_get_filename(info);
- image_widget = gtk_image_new_from_file(filename);
- gtk_icon_info_free(info);
- } else {
- g_warning("icon theme lookup for icon failed!");
- image_widget = NULL;
- }
-
- /* Prepare banner */
- banner = hildon_banner_get_instance_for_widget(widget, FALSE);
- hildon_banner_ensure_child(banner, image_widget, 0,
- GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
- hildon_banner_set_text(banner, text);
- hildon_banner_bind_label_style(banner, NULL);
-
- /* And show it */
- gtk_widget_show_all(GTK_WIDGET(banner));
-
- return GTK_WIDGET(banner);
-}
-
-/**
- * hildon_banner_show_progress:
- * @widget: the #GtkWidget that wants to display banner
- * @bar: Progressbar to use. You usually can just pass %NULL, unless
- * you want somehow customized progress bar.
- * @text: text to display.
- *
- * Shows progress notification. See #hildon_banner_show_animation
- * for more information.
- *
- * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
- * once you are ready with the banner.
- *
- * Since: 0.12.2
- */
-GtkWidget *hildon_banner_show_progress(GtkWidget *widget,
- GtkProgressBar *bar, const gchar *text)
-{
- HildonBanner *banner;
-
- g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
- g_return_val_if_fail(bar == NULL || GTK_IS_PROGRESS_BAR(bar), NULL);
- g_return_val_if_fail(text != NULL, NULL);
-
- /* Prepare banner */
- banner = hildon_banner_get_instance_for_widget(widget, FALSE);
- hildon_banner_ensure_child(banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
- gtk_widget_set_size_request(banner->priv->main_item,
- HILDON_BANNER_PROGRESS_WIDTH, -1);
- hildon_banner_set_text(banner, text);
- hildon_banner_bind_label_style(banner, NULL);
-
- /* Show the banner */
- gtk_widget_show_all(GTK_WIDGET(banner));
-
- return GTK_WIDGET(banner);
-}
-
-/**
- * hildon_banner_set_text:
- * @self: a #HildonBanner widget
- * @text: a new text to display in banner
- *
- * Sets the text that is displayed in the banner.
- *
- * Since: 0.12.2
- */
-void hildon_banner_set_text(HildonBanner *self, const gchar *text)
-{
- GtkLabel *label;
-
- g_return_if_fail(HILDON_IS_BANNER(self));
-
- label = GTK_LABEL(self->priv->label);
- gtk_label_set_text(label, text);
-
- hildon_banner_check_position(GTK_WIDGET(self));
-}
-
-/**
- * hildon_banner_set_markup:
- * @self: a #HildonBanner widget
- * @markup: a new text with Pango markup to display in the banner
- *
- * Sets the text with markup that is displayed in the banner.
- *
- * Since: 0.12.8
- */
-void hildon_banner_set_markup(HildonBanner *self, const gchar *markup)
-{
- GtkLabel *label;
-
- g_return_if_fail(HILDON_IS_BANNER(self));
-
- label = GTK_LABEL(self->priv->label);
- gtk_label_set_markup(label, markup);
-
- hildon_banner_check_position(GTK_WIDGET(self));
-}
-
-/**
- * hildon_banner_set_fraction:
- * @self: a #HildonBanner widget
- * @fraction: #gdouble
- *
- * The fraction is the completion of progressbar,
- * the scale is from 0.0 to 1.0.
- * Sets the amount of fraction the progressbar has.
- *
- * Since: 0.12.2
- */
-void hildon_banner_set_fraction(HildonBanner *self, gdouble fraction)
-{
- g_return_if_fail(HILDON_IS_BANNER(self));
- g_return_if_fail(GTK_IS_PROGRESS_BAR(self->priv->main_item));
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(self->priv->main_item), fraction);
-}
-
-
-
-
-
-/**
- * Deprecated: really, do NOT use.
- */
-void _hildon_gtk_label_set_text_n_lines(GtkLabel *label, const gchar *text, gint max_lines)
-{
-/* Forces the wrapping of text into several lines and ellipsizes the rest.
- Similar to combination of gtk_label_set_wrap and pango ellipzation.
- We cannot just use those directly, since ellipzation always wins wrapping.
-
- This means that we have to:
- * First wrap the text
- * Insert forced linebreaks into text
- * Truncate the result
-
- NOTE! This will not work with pango markup!
-
- FIXME: luc: DO NOT TRUNCATE the text. Use as many lines as needed.
- Lenth of the text is under applications' responsibility.
- Widget does not have to enforce this.
-*/
- PangoLayout *layout;
- PangoLayoutLine *line;
- GtkRequisition req;
- GString *wrapped_text;
- gchar *line_data;
- gint lines, i;
-
- g_return_if_fail(GTK_IS_LABEL(label));
- g_return_if_fail(max_lines >= 1);
-
- /* Setup the label to contain the new data */
- gtk_label_set_text(label, text);
- gtk_label_set_line_wrap(label, TRUE);
- gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_NONE);
-
- /* We really want to recalculate the size, not use some old values */
- gtk_widget_size_request(GTK_WIDGET(label), &req);
- layout = gtk_label_get_layout(label);
- lines = pango_layout_get_line_count(layout);
-
- /* Now collect the wrapped text. */
- wrapped_text = g_string_new(NULL);
-
- for (i = 0; i < lines; i++)
- {
- /* Append the next line into wrapping buffer, but
- avoid adding extra whitespaces at the end, since those
- can cause other lines to be ellipsized as well. */
- line = pango_layout_get_line(layout, i);
- line_data = g_strndup(pango_layout_get_text(layout) + line->start_index,
- line->length);
- g_strchomp(line_data);
- g_string_append(wrapped_text, line_data);
-
- /* Append forced linebreaks, until we have the desired
- amount of lines. After that we put the rest to the
- last line to make ellipzation to happen */
- if (i < lines - 1)
- {
- if (i < max_lines - 1)
- g_string_append_c(wrapped_text, '\n');
- else
- g_string_append_c(wrapped_text, ' ');
- }
-
- g_free(line_data);
- }
-
- /* Now update the label to use wrapped text. Use builtin
- ellipzation as well. */
- gtk_widget_set_size_request(GTK_WIDGET(label), req.width, -1);
- gtk_label_set_text(label, wrapped_text->str);
- gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END);
- gtk_label_set_line_wrap(label, FALSE);
-
- g_string_free(wrapped_text, TRUE);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_BANNER_H__
-#define __HILDON_BANNER_H__
-
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkprogressbar.h>
-#include <gtk/gtklabel.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_BANNER (hildon_banner_get_type())
-
-#define HILDON_BANNER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HILDON_TYPE_BANNER, HildonBanner))
-#define HILDON_IS_BANNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HILDON_TYPE_BANNER))
-
-typedef struct _HildonBanner HildonBanner;
-typedef struct _HildonBannerClass HildonBannerClass;
-typedef struct _HildonBannerPrivate HildonBannerPrivate;
-
-struct _HildonBanner
-{
- GtkWindow parent;
- HildonBannerPrivate *priv;
-};
-
-struct _HildonBannerClass
-{
- GtkWindowClass parent_class;
-};
-
-GType hildon_banner_get_type (void) G_GNUC_CONST;
-
-void hildon_banner_show_information (GtkWidget *widget,
- const gchar *icon_name,
- const gchar *text);
-
-void hildon_banner_show_information_with_markup (GtkWidget *widget,
- const gchar *icon_name,
- const gchar *markup);
-
-GtkWidget *hildon_banner_show_animation (GtkWidget *widget,
- const gchar *animation_name,
- const gchar *text);
-
-GtkWidget *hildon_banner_show_progress (GtkWidget *widget,
- GtkProgressBar *bar,
- const gchar *text);
-
-void hildon_banner_set_text (HildonBanner *self,
- const gchar *text);
-
-void hildon_banner_set_markup (HildonBanner *self,
- const gchar *markup);
-
-void hildon_banner_set_fraction (HildonBanner *self,
- gdouble fraction);
-
-
-
-/* For internal use of hildon libraries only */
-void _hildon_gtk_label_set_text_n_lines(GtkLabel *label, const gchar *text, gint max_lines);
-
-G_END_DECLS
-
-#endif /* __HILDON_BANNER_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-calendar-popup
- * @shortdesc: CalendarPopup allows choosing a date from a popup calendar.
- * @longdesc: The Calendar popup is a dialog that contains a GtkCalendar
- * widget. The pop-up is cancelled by pressing the ESC key.
- * </para><para>
- *
- * @seealso: #HildonDateEditor, #HildonTimeEditor
- *
- * HildonCalendarPopup is a dialog which contains a GtkCalendar. It
- * also contains arrow buttons for changing the month/year. If an
- * entered date is invalid, an information message will be shown.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <gtk/gtkcalendar.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <langinfo.h>
-#include <time.h>
-#include <libintl.h>
-#include <hildon-widgets/hildon-calendar-popup.h>
-
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_CALENDAR_POPUP_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE\
- ((obj), HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopupPrivate));
-
-static GtkDialog *parent_class;
-
-typedef struct _HildonCalendarPopupPrivate HildonCalendarPopupPrivate;
-
-static void init_dmy(guint year, guint month, guint day, guint * d,
- guint * m, guint * y);
-
-static void
-hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class);
-
-static void hildon_calendar_popup_init(HildonCalendarPopup * cal);
-
-static void hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup);
-
-static gboolean hildon_key_pressed(GtkWidget * widget, GdkEventKey * event,
- gpointer cal_popup);
-
-static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec);
-static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec);
-
-enum {
- PROP_0,
- PROP_DAY,
- PROP_MONTH,
- PROP_YEAR,
- PROP_MIN_YEAR,
- PROP_MAX_YEAR
-};
-
-struct _HildonCalendarPopupPrivate {
- GtkWidget *cal;
-};
-
-GType hildon_calendar_popup_get_type(void)
-{
- static GType popup_type = 0;
-
- if (!popup_type) {
- static const GTypeInfo popup_info = {
- sizeof(HildonCalendarPopupClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_calendar_popup_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonCalendarPopup),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_calendar_popup_init,
- };
- popup_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonCalendarPopup",
- &popup_info, 0);
- }
-
- return popup_type;
-}
-
-/**
- * hildon_calendar_popup_new:
- * @parent: parent window for dialog
- * @year: initial year
- * @month: initial month
- * @day: initial day
- *
- * This function returns a new HildonCalendarPopup. The initially
- * selected date is specified by the parameters (year, month, day).
- * If the specified date is invalid, the current date is used.
- *
- * Returns: new @HildonCalendarPopup widget
- */
-GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
- guint month, guint day)
-{
- HildonCalendarPopup *cal = NULL;
-
- /* Create new HildonCalendarPopup */
- cal = HILDON_CALENDAR_POPUP(g_object_new(HILDON_TYPE_CALENDAR_POPUP,
- "year", year, "month", month, "day", day,
- NULL));
-
- if (parent) {
- gtk_window_set_transient_for(GTK_WINDOW(cal), parent);
- }
-
- return GTK_WIDGET(cal);
-}
-
-/**
- * hildon_calendar_popup_set_date:
- * @cal: the @HildonCalendarPopup widget
- * @year: year
- * @month: month
- * @day: day
- *
- * activates a new date on the calendar popup.
- **/
-void
-hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
- guint year, guint month, guint day)
-{
- guint dtmp, mtmp, ytmp = 0;
- HildonCalendarPopupPrivate *priv;
-
- g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
-
- priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
-
- /* Choose current date if the date is invalid:
- */
- init_dmy(year, month, day, &dtmp, &mtmp, &ytmp);
-
- /* Remove all visual markers */
- gtk_calendar_clear_marks(GTK_CALENDAR(priv->cal));
-
- /* Set a new date */
- gtk_calendar_select_month(GTK_CALENDAR(priv->cal), mtmp - 1, ytmp);
- gtk_calendar_select_day(GTK_CALENDAR(priv->cal), dtmp);
-}
-
-/**
- * hildon_calendar_popup_get_date:
- * @cal: the @HildonCalendarPopup widget
- * @year: year
- * @month: month
- * @day: day
- *
- * Gets the currently selected year, month, and day.
- */
-void
-hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
- guint * year, guint * month, guint * day)
-{
- HildonCalendarPopupPrivate *priv;
-
- g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
-
- priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
- gtk_calendar_get_date(GTK_CALENDAR(priv->cal), year, month, day);
- *month = *month + 1;
-
- if (!g_date_valid_dmy(*day, *month, *year)) {
- *day = g_date_get_days_in_month(*month, *year);
- }
-}
-
-static void
-hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(cal_class);
- parent_class = g_type_class_peek_parent(cal_class);
-
- object_class->set_property = hildon_calendar_popup_set_property;
- object_class->get_property = hildon_calendar_popup_get_property;
-
- g_type_class_add_private(cal_class,
- sizeof(HildonCalendarPopupPrivate));
-
- /* Install new properties for the GObject_class */
- g_object_class_install_property(object_class, PROP_MIN_YEAR,
- g_param_spec_uint("min-year",
- "Minimum valid year",
- "Minimum valid year",
- 1, 2100,
- 1970,
- G_PARAM_WRITABLE));
-
- g_object_class_install_property(object_class, PROP_MAX_YEAR,
- g_param_spec_uint("max-year",
- "Maximum valid year",
- "Maximum valid year",
- 1, 2100,
- 2037,
- G_PARAM_WRITABLE));
-
- g_object_class_install_property(object_class, PROP_DAY,
- g_param_spec_int ("day",
- "Day",
- "currently selected day",
- G_MININT,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_MONTH,
- g_param_spec_int ("month",
- "Month",
- "currently selected month",
- G_MININT,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_YEAR,
- g_param_spec_int ("year",
- "Year",
- "the currently selected year",
- G_MININT,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE));
-
-}
-
-static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
-{
- HildonCalendarPopupPrivate *priv;
- static int set_domain = 1;
-
- priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
-
- /* set the domain directory for different language */
- if (set_domain) {
- (void) bindtextdomain(PACKAGE, LOCALEDIR);
- set_domain = 0;
- }
-
- priv->cal = gtk_calendar_new();
-
- /* dialog options and packing */
- gtk_calendar_set_display_options(GTK_CALENDAR(priv->cal),
- GTK_CALENDAR_SHOW_HEADING |
- GTK_CALENDAR_SHOW_DAY_NAMES |
- GTK_CALENDAR_SHOW_WEEK_NUMBERS);
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cal)->vbox), priv->cal,
- TRUE, TRUE, 0);
- gtk_dialog_set_has_separator(GTK_DIALOG(cal), FALSE);
- gtk_dialog_add_button(GTK_DIALOG(cal), _("ecdg_bd_calendar_popout_done"),
- GTK_RESPONSE_OK);
- gtk_widget_show(priv->cal);
-
- /* Connect signals */
- g_signal_connect(G_OBJECT(priv->cal), "key-press-event",
- G_CALLBACK(hildon_key_pressed), cal);
-
- g_signal_connect(G_OBJECT(priv->cal), "selected_date",
- G_CALLBACK(hildon_calendar_selected_date), cal);
-
- /* set decorations, needs realizing first*/
- gtk_widget_realize(GTK_WIDGET(cal));
- gdk_window_set_decorations(GTK_WIDGET(cal)->window, GDK_DECOR_BORDER);
-
-}
-
-
-/*
- * Signal handler for key-press-event. Closes the dialog for some
- * special keys.
- */
-static gboolean
-hildon_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer cal_popup)
-{
- g_assert(HILDON_IS_CALENDAR_POPUP(cal_popup));
-
- /* Handle Return key press as OK response */
- if (event->keyval == GDK_Return)
- {
- gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
- return TRUE;
- }
-
- /* Handle Esc key press as CANCEL response */
- if ((event->keyval == GDK_Escape))
- {
- gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_CANCEL);
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/*
- * Validates the given date or initializes it with the current date
- */
-static void
-init_dmy(guint year, guint month, guint day, guint *d, guint *m, guint *y)
-{
- GDate date;
-
- /* Initialize the date with a valid selected date */
- if (g_date_valid_dmy(day, month, year)) {
- *d = day;
- *m = month;
- *y = year;
- } else {
-
- /* If selected date is invalid initialize the date with current date */
- g_date_clear(&date, 1);
- g_date_set_time(&date, time(NULL));
-
- *d = g_date_get_day(&date);
- *m = g_date_get_month(&date);
- *y = g_date_get_year(&date);
- }
-}
-
-/*
- * Exits the dialog when "selected_date" signal is emmited. The
- * "selected_date" signal is a Hildon addition to GtkCalendar and is
- * emitted on button-release.
- */
-static void
-hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup)
-{
- g_assert(GTK_IS_WIDGET (self));
- g_assert(HILDON_IS_CALENDAR_POPUP (cal_popup));
-
- gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
-}
-
-
-static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonCalendarPopup *popup = HILDON_CALENDAR_POPUP (object);
- HildonCalendarPopupPrivate *priv =
- HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
-
- switch (property_id) {
- case PROP_DAY:
- {
- guint year, month, day = 0;
- hildon_calendar_popup_get_date(popup, &year, &month, &day);
-
- /*Verifies that the date is valid: */
- hildon_calendar_popup_set_date(popup, year, month, g_value_get_int(value));
- break;
- }
- case PROP_MONTH:
- {
- guint year, month, day = 0;
- hildon_calendar_popup_get_date(popup, &year, &month, &day);
-
- /*Verifies that the date is valid: */
- hildon_calendar_popup_set_date(popup, year, g_value_get_int(value), day);
- break;
- }
- case PROP_YEAR:
- {
- guint year, month, day = 0;
- hildon_calendar_popup_get_date(popup, &year, &month, &day);
-
- /*Verifies that the date is valid: */
- hildon_calendar_popup_set_date(popup, g_value_get_int(value), month, day);
- break;
- }
- case PROP_MIN_YEAR:
- g_object_set_property(G_OBJECT(priv->cal), "min-year", value);
- break;
- case PROP_MAX_YEAR:
- g_object_set_property(G_OBJECT(priv->cal), "max-year", value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonCalendarPopupPrivate *priv =
- HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
-
- switch (property_id) {
- case PROP_DAY:
- g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
- break;
- case PROP_MONTH:
- g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
- break;
- case PROP_YEAR:
- g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_CALENDAR_POPUP_H__
-#define __HILDON_CALENDAR_POPUP_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-/**
- * HILDON_TYPE_CALENDAR_POPUP:
- *
- * Macro for getting type of calendar popup.
- * Since: 0.12.10
- */
-#define HILDON_TYPE_CALENDAR_POPUP ( hildon_calendar_popup_get_type() )
-
-/**
- * HILDON_CALENDAR_POPUP_TYPE:
- *
- * Deprecated: use #HILDON_TYPE_CALENDAR_POPUP instead
- */
-#define HILDON_CALENDAR_POPUP_TYPE HILDON_TYPE_CALENDAR_POPUP
-
-#define HILDON_CALENDAR_POPUP(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopup))
-#define HILDON_CALENDAR_POPUP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopupClass))
-#define HILDON_IS_CALENDAR_POPUP(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_CALENDAR_POPUP))
-#define HILDON_IS_CALENDAR_POPUP_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CALENDAR_POPUP))
-
-/**
- * HildonCalendarPopup:
- *
- * Internal struct for calendar popup.
- */
-typedef struct _HildonCalendarPopup HildonCalendarPopup;
-typedef struct _HildonCalendarPopupClass HildonCalendarPopupClass;
-
-/* Note: CalendarPopup is no longer derived from GtkWindow
- but from GtkDialog */
-
-struct _HildonCalendarPopup {
- GtkDialog par;
-};
-
-struct _HildonCalendarPopupClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_calendar_popup_get_type(void) G_GNUC_CONST;
-
-GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
- guint month, guint day);
-
-void hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
- guint year, guint month, guint day);
-
-void hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
- guint * year, guint * month,
- guint * day);
-
-G_END_DECLS
-#endif /* __HILDON_CALENDAR_POPUP_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-caption
- * @short_description: A single-child container widget that precedes the
- * contained widget with a field label and an optional icon
- *
- * #HildonCaption is a single-child container widget that precedes the
- * contained widget with a field label and an optional icon. It allows
- * grouping of several controls together. When a captioned widget has focus,
- * both widget and caption label are displayed with active focus.
- */
-
-#include <gtk/gtkhbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkcombo.h>
-#include <gtk/gtkcombobox.h>
-#include <gtk/gtkcomboboxentry.h>
-#include <gtk/gtkoptionmenu.h>
-#include <gtk/gtkmarshal.h>
-#include <gtk/gtkalignment.h>
-#include <stdio.h>
-#include <string.h>
-#include "hildon-caption.h"
-#include "hildon-defines.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_CAPTION_SPACING 6
-
-#define HILDON_CAPTION_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_CAPTION, HildonCaptionPrivate));
-
-/*our parent class*/
-static GtkEventBox *parent_class = NULL;
-
-typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
-
-enum
-{
- PROP_NONE,
- PROP_LABEL,
- PROP_ICON,
- PROP_STATUS,
- PROP_SEPARATOR,
- PROP_SIZE_GROUP,
- PROP_ICON_POSITION,
-};
-
-enum
-{
- CHILD_PROP_NONE,
- CHILD_PROP_EXPAND
-};
-
-static void hildon_caption_class_init ( HildonCaptionClass *caption_class );
-static void hildon_caption_init ( HildonCaption *caption );
-static void hildon_caption_size_request ( GtkWidget *widget, GtkRequisition *requisition );
-static void hildon_caption_size_allocate( GtkWidget *widget, GtkAllocation *allocation );
-
-static void hildon_caption_forall( GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback, gpointer data );
-static void hildon_caption_hierarchy_changed( GtkWidget *widget,
- GtkWidget *previous_toplevel);
-static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
- GtkWidget *caption );
-static void hildon_caption_activate( GtkWidget *widget );
-
-static void hildon_caption_set_property( GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec );
-static void hildon_caption_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec );
-static gboolean hildon_caption_expose( GtkWidget *widget,
- GdkEventExpose *event );
-static void hildon_caption_destroy( GtkObject *self );
-static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
-
-static void
-hildon_caption_set_label_text( HildonCaptionPrivate *priv );
-
-static void hildon_caption_set_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void hildon_caption_get_child_property (GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-struct _HildonCaptionPrivate
-{
- GtkWidget *caption_area;
- GtkWidget *label;
- GtkWidget *icon;
- GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
- GtkSizeGroup *group;
- gchar *text;
- gchar *separator;
- guint is_focused : 1;
- guint expand : 1;
- HildonCaptionStatus status;
- HildonCaptionIconPosition icon_position;
-};
-
-/* Register optional/mandatory type enumeration */
-/* FIXME: mandatory icon was removed. The mandatory/optional logic
- remains, it should most probably be removed as well. This imply APi
- change, especially hildon_caption_new() */
-GType
-hildon_caption_status_get_type (void)
-{
- static GType etype = 0;
- if (etype == 0) {
- static const GEnumValue values[] = {
- { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" },
- { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static ("HildonCaptionStatus", values);
- }
- return etype;
-}
-
-GType
-hildon_caption_icon_position_get_type (void)
-{
- static GType etype = 0;
- if (etype == 0) {
- static const GEnumValue values[] = {
- { HILDON_CAPTION_POSITION_LEFT, "HILDON_CAPTION_POSITION_LEFT", "left" },
- { HILDON_CAPTION_POSITION_RIGHT, "HILDON_CAPTION_POSITION_RIGHT", "right" },
- { 0, NULL, NULL }
- };
- etype = g_enum_register_static ("HildonCaptionIconPosition", values);
- }
- return etype;
-}
-
-/**
- * hildon_caption_get_type:
- *
- * Initialises, and returns the type of a hildon caption.
- *
- * @Returns: GType of #HildonCaption
- */
-GType hildon_caption_get_type (void)
-{
- static GType caption_type = 0;
-
- if (!caption_type)
- {
- static const GTypeInfo caption_info = {
- sizeof(HildonCaptionClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_caption_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonCaption),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_caption_init,
- };
- caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
- "HildonCaption", &caption_info, 0 );
- }
- return caption_type;
-}
-
-/*
- * Initialises the caption class.
- */
-static void hildon_caption_class_init( HildonCaptionClass *caption_class )
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
- GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
-
- parent_class = g_type_class_peek_parent( caption_class );
-
- g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
-
- /* Override virtual functions */
- gobject_class->get_property = hildon_caption_get_property;
- gobject_class->set_property = hildon_caption_set_property;
-
- caption_class->activate = hildon_caption_activate;
-
- GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
-
- container_class->forall = hildon_caption_forall;
- container_class->set_child_property = hildon_caption_set_child_property;
- container_class->get_child_property = hildon_caption_get_child_property;
-
- widget_class->expose_event = hildon_caption_expose;
- widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
- widget_class->size_request = hildon_caption_size_request;
- widget_class->size_allocate = hildon_caption_size_allocate;
- widget_class->button_press_event = hildon_caption_button_press;
-
- /* Create new signals and properties */
- widget_class->activate_signal = g_signal_new( "activate",
- G_OBJECT_CLASS_TYPE(
- gobject_class),
- G_SIGNAL_RUN_FIRST |
- G_SIGNAL_ACTION,
- G_STRUCT_OFFSET( HildonCaptionClass,
- activate), NULL, NULL,
- gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /**
- * HildonCaption:label:
- *
- * Caption label.
- */
- g_object_class_install_property( gobject_class, PROP_LABEL,
- g_param_spec_string("label",
- "Current label", "Caption label",
- NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonCaption:icon:
- *
- * The icon shown on the caption area.
- */
- g_object_class_install_property( gobject_class, PROP_ICON,
- g_param_spec_object("icon",
- "Current icon",
- "The icon shown on the caption area",
- GTK_TYPE_WIDGET, G_PARAM_READABLE |
- G_PARAM_WRITABLE) );
- /**
- * HildonCaption:status:
- *
- * Mandatory or optional status.
- */
- g_object_class_install_property( gobject_class, PROP_STATUS,
- g_param_spec_enum("status",
- "Current status",
- "Mandatory or optional status",
- HILDON_TYPE_CAPTION_STATUS,
- HILDON_CAPTION_OPTIONAL,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
- /**
- * HildonCaption:icon-position:
- *
- * If the icon is positioned on the left or right side.
- *
- * Since: 0.14.5
- */
- g_object_class_install_property( gobject_class, PROP_ICON_POSITION,
- g_param_spec_enum("icon-position",
- "Icon position",
- "If the icon is on the left or right side",
- HILDON_TYPE_CAPTION_ICON_POSITION,
- HILDON_CAPTION_POSITION_RIGHT,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonCaption:size_group:
- *
- * Current size group the caption is in.
- */
- g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
- g_param_spec_object("size_group",
- "Current size group",
- "Current size group the caption is in",
- GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
- G_PARAM_WRITABLE) );
-
- /**
- * HildonCaption:separator:
- *
- * The current separator.
- */
- g_object_class_install_property( gobject_class, PROP_SEPARATOR,
- g_param_spec_string("separator",
- "Current separator", "Current separator",
- _("ecdg_ti_caption_separator"),
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /* Create child properties. These are related to
- child <-> parent relationship, not to either of objects itself */
- gtk_container_class_install_child_property (container_class,
- CHILD_PROP_EXPAND,
- g_param_spec_boolean ("expand",
- "Same as GtkBox expand.",
- "Same as GtkBox expand. Wheter the child should be expanded or not.",
- FALSE,
- G_PARAM_READWRITE));
-}
-
-/* Destroy can be called multiple times, remember to set pointers to NULL */
-static void hildon_caption_destroy( GtkObject *self )
-{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
-
- /* Free our internal child */
- if( priv->caption_area )
- {
- gtk_widget_unparent( priv->caption_area );
- priv->caption_area = NULL;
- }
-
- /* Free user provided strings */
- if( priv->text )
- {
- g_free( priv->text );
- priv->text = NULL;
- }
- if( priv->separator )
- {
- g_free( priv->separator );
- priv->separator = NULL;
- }
-
- /* Parent classes destroy takes care of user packed contents */
- if( GTK_OBJECT_CLASS(parent_class)->destroy )
- GTK_OBJECT_CLASS(parent_class)->destroy( self );
-}
-
-/* Parent, eventbox will run allocate also for the child which may be
- * owning a window too. This window is then moved and resized
- * and we do not want to do that (it causes flickering).
- */
-static gboolean hildon_caption_expose( GtkWidget *widget,
- GdkEventExpose *event )
-{
- HildonCaptionPrivate *priv = NULL;
- GtkRequisition req;
- GtkAllocation alloc;
- gfloat align;
-
- g_assert( HILDON_IS_CAPTION(widget) );
- priv = HILDON_CAPTION_GET_PRIVATE(widget);
-
- if( !GTK_WIDGET_DRAWABLE(widget) )
- return FALSE;
-
- GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
-
- /* If our child control is focused, we draw nice looking focus
- graphics for the caption */
- if ( priv->is_focused && priv->text )
- {
- /* Determine focus box dimensions */
- gtk_widget_get_child_requisition( priv->caption_area, &req );
- align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
-
- alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
- alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
-
- alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
- alloc.y = priv->caption_area->allocation.y +
- MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
-
- /* Paint the focus box */
- gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
- GTK_SHADOW_OUT, NULL, widget, "selection",
- alloc.x, alloc.y, alloc.width, alloc.height );
-
- /* Paint caption contents on top of the focus box */
- GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
- priv->caption_area, event);
- }
-
- return FALSE;
-}
-
-static void hildon_caption_set_property( GObject *object, guint param_id,
- const GValue *value,
- GParamSpec *pspec )
-{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
-
- switch( param_id )
- {
- case PROP_ICON_POSITION:
-
- hildon_caption_set_icon_position (HILDON_CAPTION (object),
- g_value_get_enum (value));
-
- break;
-
- case PROP_LABEL:
- /* Free old label string */
- if( priv->text )
- {
- g_free( priv->text );
- priv->text = NULL;
- }
-
- /* Update label */
- priv->text = g_value_dup_string(value);
- hildon_caption_set_label_text( priv );
- break;
-
- case PROP_ICON:
- /* Remove old icon */
- if( priv->icon )
- gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
-
- /* Pack and display new icon */
- priv->icon = g_value_get_object( value );
- if( priv->icon )
- {
- gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
- gtk_widget_show_all( priv->caption_area );
- }
- break;
-
- case PROP_STATUS:
- priv->status = g_value_get_enum( value );
- break;
-
- case PROP_SIZE_GROUP:
- /* Detach from previous size group */
- if( priv->group )
- gtk_size_group_remove_widget( priv->group, priv->caption_area );
-
- priv->group = g_value_get_object( value );
-
- /* Attach to new size group */
- if( priv->group )
- gtk_size_group_add_widget( priv->group, priv->caption_area );
- gtk_widget_queue_draw( GTK_WIDGET(object) );
- break;
-
- case PROP_SEPARATOR:
-
- /* Free old separator */
- if( priv->separator )
- {
- g_free( priv->separator );
- priv->separator = NULL;
- }
-
- priv->separator = g_value_dup_string(value);
- hildon_caption_set_label_text( priv );
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_caption_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec )
-{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
-
- switch (param_id)
- {
- case PROP_LABEL:
- g_value_set_string( value, priv->text );
- break;
- case PROP_ICON:
- g_value_set_object( value, priv->icon );
- break;
- case PROP_STATUS:
- g_value_set_enum( value, priv->status );
- break;
- case PROP_ICON_POSITION:
- g_value_set_enum( value, priv->icon_position);
- break;
- case PROP_SIZE_GROUP:
- g_value_set_object( value, priv->group );
- break;
- case PROP_SEPARATOR:
- g_value_set_string( value, priv->separator );
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_caption_set_child_property( GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec )
-{
- switch (property_id)
- {
- case CHILD_PROP_EXPAND:
- hildon_caption_set_child_expand( HILDON_CAPTION(container),
- g_value_get_boolean(value) );
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
- break;
- }
-}
-
-static void hildon_caption_get_child_property( GtkContainer *container,
- GtkWidget *child,
- guint property_id,
- GValue *value,
- GParamSpec *pspec )
-{
- switch (property_id)
- {
- case CHILD_PROP_EXPAND:
- g_value_set_boolean( value, hildon_caption_get_child_expand(
- HILDON_CAPTION(container)) );
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
- break;
- }
-}
-
-/* We want to activate out child control on button press */
-static gboolean hildon_caption_button_press( GtkWidget *widget,
- GdkEventButton *event )
-{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
- GtkWidget *child = GTK_BIN(widget)->child;
-
- /* nothing to do */
- if (priv->is_focused == TRUE)
- return;
-
- /* If child can take focus, we simply grab focus to it */
- if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
- GTK_WIDGET_IS_SENSITIVE(child))
- {
- /* Only if container can be focusable we must set is_focused to TRUE */
- if (GTK_IS_CONTAINER(child))
- {
- if (gtk_widget_child_focus (child,
- GTK_DIR_TAB_FORWARD))
- priv->is_focused = TRUE;
- }
- else
- {
- priv->is_focused = TRUE;
- gtk_widget_grab_focus (GTK_BIN (widget)->child);
- }
- }
-
- return FALSE;
-}
-
-static void hildon_caption_init( HildonCaption *caption )
-{
- HildonCaptionPrivate *priv = NULL;
-
- /* Initialize startup state */
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
- priv->status = HILDON_CAPTION_OPTIONAL;
- priv->icon = NULL;
- priv->group = NULL;
- priv->is_focused = FALSE;
- priv->text = NULL;
-
- priv->separator = g_strdup(_("ecdg_ti_caption_separator"));
-
- gtk_widget_push_composite_child();
-
- /* Create caption text */
- priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
- priv->label = gtk_label_new( NULL );
- priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
- priv->icon_position = HILDON_CAPTION_POSITION_RIGHT;
-
- /* We want to receive button presses for child widget activation */
- gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
- gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
-
- /* Pack text label caption layout */
- gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
- gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
- gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
-
-
- gtk_widget_pop_composite_child();
-
- hildon_caption_set_child_expand( caption, TRUE );
-
- gtk_widget_show_all( priv->caption_area );
-}
-
-static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
- GtkWidget *caption )
-{
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- /* check if ancestor gone */
- if (!widget)
- {
- return;
- }
-
- /* Try to find caption among the ancestors of widget */
- if (gtk_widget_is_ancestor(widget, caption))
- {
- priv->is_focused = TRUE;
- gtk_widget_queue_draw( caption );
- return;
- }
-
- if( priv->is_focused == TRUE )
- {
- /* Caption wasn't found, so cannot focus */
- priv->is_focused = FALSE;
- gtk_widget_queue_draw( caption );
- }
-}
-
-/* We need to connect/disconnect signal handlers to toplevel window
- in which we reside. Ww want to update connected signals if our
- parent changes */
-static void hildon_caption_hierarchy_changed( GtkWidget *widget,
- GtkWidget *previous_toplevel)
-{
- GtkWidget *current_ancestor;
- HildonCaptionPrivate *priv;
-
- priv = HILDON_CAPTION_GET_PRIVATE(widget);
-
- if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
- GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
- previous_toplevel );
-
- /* If we already were inside a window, remove old handler */
- if (previous_toplevel) {
- /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
- /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
-#ifdef __GNUC__
- __extension__
-#endif
- g_signal_handlers_disconnect_by_func
- (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
- }
- current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
-
- /* Install new handler for focus movement */
- if (current_ancestor)
- g_signal_connect( current_ancestor, "set-focus",
- G_CALLBACK(hildon_caption_set_focus), widget );
-}
-
-static void hildon_caption_size_request( GtkWidget *widget,
- GtkRequisition *requisition )
-{
- GtkRequisition req;
- HildonCaptionPrivate *priv = NULL;
- g_return_if_fail( HILDON_IS_CAPTION(widget) );
- priv = HILDON_CAPTION_GET_PRIVATE(widget);
-
- /* Use the same size requisition for the main box of the caption */
- gtk_widget_size_request( priv->caption_area, &req );
-
- if( GTK_WIDGET_CLASS(parent_class)->size_request )
- GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
-
- requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
-
- if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
- requisition->height = req.height + (2 * widget->style->ythickness);
-}
-
-/* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
-static void hildon_caption_size_allocate( GtkWidget *widget,
- GtkAllocation *allocation )
-{
- GtkAllocation allocA;
- GtkAllocation allocB;
- GtkRequisition req;
- GtkWidget *child = NULL;
- HildonCaptionPrivate *priv = NULL;
-
- g_assert( HILDON_IS_CAPTION(widget) );
- priv = HILDON_CAPTION_GET_PRIVATE(widget);
-
- /* Position the caption to its allocated location */
- if( GTK_WIDGET_REALIZED(widget) )
- gdk_window_move_resize (widget->window,
- allocation->x + GTK_CONTAINER (widget)->border_width,
- allocation->y + GTK_CONTAINER (widget)->border_width,
- MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
- MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
-
- child = GTK_BIN(widget)->child;
-
- widget->allocation = *allocation;
- gtk_widget_get_child_requisition( priv->caption_area, &req );
-
- allocA.height = allocB.height = allocation->height;
- allocA.width = allocB.width = allocation->width;
- allocA.x = allocB.x = allocB.y = allocA.y = 0;
-
- /* Center the captioned widget */
- if( allocA.width > req.width + HILDON_CAPTION_SPACING )
- {
- allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
- allocB.width = req.width;
- }
-
- /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
- allocB.x = HILDON_CAPTION_SPACING;
-
- /* Leave room for the other drawable parts of the caption control */
- allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
-
- /* Give the child at least its minimum requisition, unless it is expandable */
- if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
- {
- GtkRequisition child_req;
- gtk_widget_get_child_requisition( child, &child_req );
- allocA.width = MIN( allocA.width, child_req.width );
- allocA.height = MIN( allocA.height, child_req.height );
- }
-
- /* Ensure there are no negative dimensions */
- if( allocA.width < 0 )
- {
- allocB.width = req.width + allocA.width;
- allocA.width = 0;
- allocB.width = MAX (allocB.width, 0);
- }
-
- allocA.height = MAX (allocA.height, 0);
- allocB.height = MAX (allocB.height, 0);
-
- if (child && GTK_WIDGET_VISIBLE(child) )
- gtk_widget_size_allocate( child, &allocA );
-
- gtk_widget_size_allocate( priv->caption_area, &allocB );
-}
-
-static void hildon_caption_forall( GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback, gpointer data )
-{
- HildonCaptionPrivate *priv = NULL;
-
- g_assert( HILDON_IS_CAPTION(container) );
- g_assert( callback != NULL );
-
- priv = HILDON_CAPTION_GET_PRIVATE(container);
-
- /* Execute callback for the child widgets */
- if( GTK_CONTAINER_CLASS(parent_class)->forall )
- GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
- callback, data );
-
- if( include_internals )
- /* Execute callback for the parent box as well */
- (*callback)( priv->caption_area, data );
-}
-
-
-/**
- * hildon_caption_set_sizegroup:
- * @caption : a #HildonCaption
- * @new_group : a #GtkSizeGroup
- *
- * Sets a #GtkSizeGroup of a given captioned control.
- *
- * Deprecated: use g_object_set, property :size-group
- */
-void hildon_caption_set_sizegroup( const HildonCaption *self,
- GtkSizeGroup *group )
-{
- g_object_set( G_OBJECT(self), "size_group", group, NULL );
-}
-
-/**
- * hildon_caption_get_sizegroup:
- * @caption : a #HildonCaption
- *
- * Query given captioned control for the #GtkSizeGroup assigned to it.
- *
- * @Returns : a #GtkSizeGroup
- *
- * Deprecated: Use g_object_get, property :size-group
- */
-GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
- priv = HILDON_CAPTION_GET_PRIVATE(self);
- return priv->group;
-}
-
-/**
- * hildon_caption_new:
- * @group : a #GtkSizeGroup for controlling the size of related captions,
- * Can be NULL
- * @value : the caption text to accompany the text entry. The widget makes
- * a copy of this text.
- * @control : the control that is to be captioned
- * @icon : an icon to accompany the label - can be NULL in which case no
- * icon is displayed
- * @flag : indicates whether this captioned control is mandatory or
- * optional
- *
- * Creates a new instance of hildon_caption widget, with a specific
- * control and image.
- * Note: Clicking on a focused caption will trigger the activate signal.
- * The default behaviour for the caption's activate signal is to call
- * gtk_widget_activate on it's control.
- *
- * @Returns : a #GtkWidget pointer of Caption
- */
-GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
- GtkWidget *child, GtkWidget *icon,
- HildonCaptionStatus flag)
-{
- GtkWidget *widget;
- g_return_val_if_fail( GTK_IS_WIDGET(child), NULL );
-
- widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
- "child" /* From GtkContainer */, child, "size_group", group, "icon", icon, "status", flag,
- NULL );
-
- return widget;
-}
-
-/**
- * hildon_caption_is_mandatory:
- * @caption : a #HildonCaption
- *
- * Query #HildonCaption whether this captioned control is a mandatory one.
- *
- * @Returns : is this captioned control a mandatory one?
- */
-
-gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return priv->status == HILDON_CAPTION_MANDATORY;
-}
-
-/**
- * hildon_caption_set_icon_position:
- * @caption : a #HildonCaption
- * @pos : one of the values from #HildonCaptionIconPosition
- *
- * Sets #HildonCaption icon position.
- *
- * Since: 0.14.5
- */
-
-void hildon_caption_set_icon_position( HildonCaption *caption,
- HildonCaptionIconPosition pos )
-{
- g_return_if_fail (HILDON_IS_CAPTION (caption));
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- g_return_if_fail (priv->caption_area != NULL);
- int order = (pos == HILDON_CAPTION_POSITION_LEFT) ? -1 : 0;
- gtk_box_reorder_child (GTK_BOX (priv->caption_area), priv->icon_align, order);
-
- priv->icon_position = pos;
-}
-
-/**
- * hildon_caption_get_icon_position:
- * @caption : a #HildonCaption
- *
- * Gets #HildonCaption icon position.
- *
- * @Returns : one of the values from #HildonCaptionIconPosition.
- *
- * Since: 0.14.5
- */
-
-HildonCaptionIconPosition hildon_caption_get_icon_position( const HildonCaption *caption )
-{
- g_return_if_fail (HILDON_IS_CAPTION (caption));
- HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return priv->icon_position;
-}
-
-/**
- * hildon_caption_set_status:
- * @caption : a #HildonCaption
- * @flag : one of the values from #HildonCaptionStatus
- *
- * Sets #HildonCaption status.
- */
-
-void hildon_caption_set_status( HildonCaption *caption,
- HildonCaptionStatus flag )
-{
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
-
- g_object_set( G_OBJECT(caption), "status", flag, NULL );
-}
-
-/**
- * hildon_caption_get_status:
- * @caption : a #HildonCaption
- *
- * Gets #HildonCaption status.
- *
- * @Returns : one of the values from #HildonCaptionStatus
- */
-
-HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return priv->status;
-}
-
-/**
- * hildon_caption_set_icon_image:
- * @caption : a #HildonCaption
- * @icon : the #GtkImage to use as the icon.
- * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
- *
- * Sets the icon to be used by this hildon_caption widget.
- */
-
-void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
-{
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
-
- g_object_set( G_OBJECT(caption), "icon", icon, NULL );
-}
-
-/**
- * hildon_caption_get_icon_image:
- * @caption : a #HildonCaption
- *
- * Gets icon of #HildonCaption
- *
- * @Returns : the #GtkImage that is being used as the icon by the
- * hildon_caption, or NULL if no icon is in use
- */
-
-GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return priv->icon;
-}
-
-/**
- * hildon_caption_set_label:
- * @caption : a #HildonCaption
- * @label : the text to use
- *
- * Sets the label text that appears before the control.
- * Separator character is added to the end of the label string. By default
- * the separator is ":".
- */
-
-void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
-{
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
-
- g_object_set( G_OBJECT(caption), "label", label, NULL );
-}
-
-/**
- * hildon_caption_get_label:
- * @caption : a #HildonCaption
- *
- * Gets label of #HildonCaption
- *
- * @Returns : the text currently being used as the label of the caption
- * control. The string is owned by the label and the caller should never
- * free or modify this value.
- */
-
-gchar *hildon_caption_get_label( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
-}
-
-/**
- * hildon_caption_set_separator:
- * @caption : a #HildonCaption
- * @separator : the separator to use
- *
- * Sets the separator character that appears after the label.
- * The default seaparator character is ":"
- * separately.
- */
-
-void hildon_caption_set_separator( HildonCaption *caption,
- const gchar *separator )
-{
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
-
- g_object_set( G_OBJECT(caption), "separator", separator, NULL );
-}
-
-/**
- * hildon_caption_get_separator:
- * @caption : a #HildonCaption
- *
- * Gets separator string of #HildonCaption
- *
- * @Returns : the text currently being used as the separator of the caption
- * control. The string is owned by the caption control and the caller should
- * never free or modify this value.
- */
-
-gchar *hildon_caption_get_separator( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv;
- g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- return priv->separator;
-}
-
-
-/**
- * hildon_caption_get_control:
- * @caption : a #HildonCaption
- *
- * Gets caption's control.
- *
- * @Returns : a #GtkWidget
- *
- * Deprecated: use gtk_bin_get_child instead
- */
-GtkWidget *hildon_caption_get_control( const HildonCaption *caption )
-{
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
- return GTK_BIN(caption)->child;
-}
-
-/*activates the child control
- *We have this signal so that if needed an application can
- *know when we've been activated (useful for captions with
- *multiple children
- */
-/* FIXME: There never are multiple children. Possibly activate
- signal could be removed entirely? (does anyone use it?) */
-static void hildon_caption_activate( GtkWidget *widget )
-{
- HildonCaptionPrivate *priv;
- GtkWidget *child = GTK_BIN(widget)->child;
- priv = HILDON_CAPTION_GET_PRIVATE(widget);
-
- gtk_widget_grab_focus( child );
-}
-
-/**
- * hildon_caption_set_child_expand:
- * @caption : a #HildonCaption
- * @expand : gboolean to determine is the child expandable
- *
- * Sets child expandability.
- */
-void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand )
-{
- HildonCaptionPrivate *priv = NULL;
- GtkWidget *child = NULL;
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
-
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
-
- /* Did the setting really change? */
- if( priv->expand == expand )
- return;
-
- priv->expand = expand;
- child = GTK_BIN(caption)->child;
-
- /* We do not have a child, nothing to do */
- if( !GTK_IS_WIDGET(child) )
- return;
-
- if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) )
- gtk_widget_queue_resize( child );
-
- gtk_widget_child_notify( child, "expand" );
-}
-
-/**
- * hildon_caption_get_child_expand:
- * @caption : a #HildonCaption
- *
- * Gets childs expandability.
- *
- * @Returns : wheter the child is expandable or not.
- */
-gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
-{
- HildonCaptionPrivate *priv = NULL;
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
- return priv->expand;
-}
-
-/**
- * hildon_caption_set_control:
- * @caption : a #HildonCaption
- * @control : the control to use. Control should not be NULL.
- *
- * Sets the control of the caption.
- * The old control will be destroyed, unless the caller has added a
- * reference to it.
- * Function unparents the old control (if there is one) and adds the new
- * control.
- *
- * Deprecated: use gtk_container_add
- */
-void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control )
-{
- GtkWidget *child = NULL;
- g_return_if_fail( HILDON_IS_CAPTION(caption) );
- child = GTK_BIN(caption)->child;
-
- if( child )
- gtk_container_remove( GTK_CONTAINER(caption), child );
-
- if( control )
- {
- gtk_container_add( GTK_CONTAINER(caption), control );
- child = control;
- }
- else
- child = NULL;
-}
-
-static void
-hildon_caption_set_label_text( HildonCaptionPrivate *priv )
-{
- gchar *tmp = NULL;
- g_assert ( priv != NULL );
-
- if ( priv->text )
- {
- if( priv->separator )
- {
- /* Don't duplicate the separator, if the string already contains one */
- if (g_str_has_suffix(priv->text, priv->separator))
- {
- gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
- }
- else
- {
- /* Append separator and set text */
- tmp = g_strconcat( priv->text, priv->separator, NULL );
- gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
- g_free( tmp );
- }
- }
- else
- {
- gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
- }
- }
- else
- {
- /* Clear the label */
- gtk_label_set_text( GTK_LABEL( priv->label ), "" );
- }
-
-}
-
-/**
- * hildon_caption_set_label_alignment:
- * @caption: a #HildonCaption widget
- * @alignment: new vertical alignment
- *
- * Sets the vertical alignment to be used for the
- * text part of the caption. Applications need to
- * align the child control themselves.
- *
- * Since: 0.12.0
- */
-void hildon_caption_set_label_alignment(HildonCaption *caption,
- gfloat alignment)
-{
- HildonCaptionPrivate *priv;
-
- g_return_if_fail(HILDON_IS_CAPTION(caption));
-
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
- g_object_set(priv->label, "yalign", alignment, NULL);
- g_object_set(priv->icon_align, "yalign", alignment, NULL);
-
-}
-
-/**
- * hildon_caption_get_label_alignment:
- * @caption: a #HildonCaption widget
- *
- * Gets current vertical alignment for the text part.
- *
- * Returns: vertical alignment
- *
- * Since: 0.12.0
- */
-gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
-{
- HildonCaptionPrivate *priv;
- gfloat result;
-
- g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
- priv = HILDON_CAPTION_GET_PRIVATE(caption);
- g_object_get(priv->label, "yalign", &result, NULL);
-
- return result;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_CAPTION_H__
-#define __HILDON_CAPTION_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtkeventbox.h>
-#include <gtk/gtksizegroup.h>
-
-G_BEGIN_DECLS
-
-
-#define HILDON_TYPE_CAPTION ( hildon_caption_get_type() )
-#define HILDON_CAPTION(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_CAPTION, HildonCaption))
-#define HILDON_CAPTION_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_CAPTION, HildonCaptionClass))
-#define HILDON_IS_CAPTION(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_CAPTION))
-#define HILDON_IS_CAPTION_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CAPTION))
-
-
-/**
- * HildonCaptionStatus:
- * @HILDON_CAPTION_OPTIONAL: Optional.
- * @HILDON_CAPTION_MANDATORY: Mandatory.
- *
- * Keys to set the #HildonCaption to be optional or mandatory.
- */
-typedef enum /*< skip >*/
-{
- HILDON_CAPTION_OPTIONAL = 0,
- HILDON_CAPTION_MANDATORY
-} HildonCaptionStatus;
-
-/**
- * HildonCaptionIconPosition:
- * @HILDON_CAPTION_POSITION_LEFT: Show the icon on the left side.
- * @HILDON_CAPTION_POSITION_RIGHT: Show the icon on the right side.
- *
- * Keys to set the icon placement in #HildonCaption.
- *
- * Since: 0.14.5
- */
-typedef enum /*< skip >*/
-{
- HILDON_CAPTION_POSITION_LEFT = 0,
- HILDON_CAPTION_POSITION_RIGHT
-} HildonCaptionIconPosition;
-
-#define HILDON_TYPE_CAPTION_STATUS (hildon_caption_status_get_type ())
-
-#define HILDON_TYPE_CAPTION_ICON_POSITION (hildon_caption_icon_position_get_type ())
-
-GType hildon_caption_status_get_type (void) G_GNUC_CONST;
-
-GType hildon_caption_icon_position_get_type (void) G_GNUC_CONST;
-
-/**
- * HildonCaption:
- *
- * Contains only private data.
- */
-typedef struct _HildonCaption HildonCaption;
-typedef struct _HildonCaptionClass HildonCaptionClass;
-
-
-struct _HildonCaption
-{
- GtkEventBox event_box;
-};
-
-
-struct _HildonCaptionClass
-{
- GtkEventBoxClass parent_class;
- void (*activate) (HildonCaption *widget);
-};
-
-
-GType hildon_caption_get_type (void) G_GNUC_CONST;
-
-GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
- GtkWidget *control, GtkWidget *icon,
- HildonCaptionStatus flag );
-#ifndef HILDON_DISABLE_DEPRECATED
-GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *caption );
-
-void hildon_caption_set_sizegroup( const HildonCaption *caption,
- GtkSizeGroup *new_group );
-#endif
-
-gboolean hildon_caption_is_mandatory( const HildonCaption *caption );
-
-void hildon_caption_set_status( HildonCaption *caption,
- HildonCaptionStatus flag );
-
-HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption );
-
-void hildon_caption_set_icon_position( HildonCaption *caption,
- HildonCaptionIconPosition pos );
-
-HildonCaptionIconPosition hildon_caption_get_icon_position( const HildonCaption *caption );
-
-void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon );
-
-GtkWidget *hildon_caption_get_icon_image(const HildonCaption *caption);
-
-void hildon_caption_set_label( HildonCaption *caption, const gchar *label );
-
-gchar *hildon_caption_get_label( const HildonCaption *caption );
-
-void hildon_caption_set_separator( HildonCaption *caption,
- const gchar *separator );
-
-gchar *hildon_caption_get_separator( const HildonCaption *caption );
-
-void hildon_caption_set_label_alignment(HildonCaption *caption,
- gfloat alignment);
-gfloat hildon_caption_get_label_alignment(HildonCaption *caption);
-
-#ifndef HILDON_DISABLE_DEPRECATED
-GtkWidget *hildon_caption_get_control( const HildonCaption *caption );
-
-void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control );
-#endif
-
-void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand );
-gboolean hildon_caption_get_child_expand( const HildonCaption *caption );
-
-G_END_DECLS
-#endif /* __HILDON_CAPTION_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#include "hildon-code-dialog.h"
-#include "hildon-defines.h"
-#include "hildon-banner.h"
-
-#include <gdk/gdkkeysyms.h>
-
-#include<gtk/gtkbutton.h>
-#include<gtk/gtkentry.h>
-#include<gtk/gtkicontheme.h>
-#include<gtk/gtktable.h>
-#include<gtk/gtkvbox.h>
-#include<gtk/gtkbbox.h>
-#include<gtk/gtklabel.h>
-#include<gtk/gtkalignment.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-
-#define HEIGHT (38-HILDON_MARGIN_DEFAULT)
-#define WIDTH (60-HILDON_MARGIN_DEFAULT)
-#define BACKSPACE_ICON "qgn_calculator_backspace"
-
-#define _(String) dgettext(PACKAGE, String)
-#define c_(String) dgettext("hildon-common-strings", String)
-#define DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
-#define DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
-#define DEVICELOCK_TITLE _("secu_application_title")
-#define DEVICELOCK_MAX_CHAR_REACHED c_("ckdg_ib_maximum_characters_reached")
-
-
-
-#define MAX_PINCODE_LEN (10)
-
-
-
-static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class);
-static void hildon_code_dialog_init (HildonCodeDialog *self);
-static void hildon_code_dialog_finalize (GObject *self);
-static void hildon_code_dialog_button_clicked (GtkButton *buttonm,
- gpointer user_data);
-static void hildon_code_dialog_insert_text (GtkEditable *editable,
- gchar *new_text,
- gint new_text_length,
- gint *position,
- gpointer user_data);
-
-static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data);
-
-
-GtkDialogClass *parent_class;
-
-struct _HildonCodeDialogPrivate
-{
- GtkWidget *entry;
- GtkWidget *buttons[5][3];
- GtkWidget *help_text;
-};
-
-GType hildon_code_dialog_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- {
- static const GTypeInfo info =
- {
- sizeof(HildonCodeDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_code_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonCodeDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_code_dialog_init
- };
- type = g_type_register_static (GTK_TYPE_DIALOG,
- "HildonCodeDialog", &info, 0);
- }
- return type;
-}
-
-static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class)
-{
- /* Get convenience variables */
- GObjectClass *object_class = G_OBJECT_CLASS (cd_class);
-
- parent_class = GTK_DIALOG_CLASS (g_type_class_peek_parent (cd_class));
-
- object_class->finalize = hildon_code_dialog_finalize;
-
-}
-
-static void hildon_code_dialog_init (HildonCodeDialog *dialog)
-{
- HildonCodeDialogPrivate *priv;
- gint i, x, y;
- GtkWidget *dialog_vbox1 = NULL;
- GtkWidget *table = NULL;
- GtkWidget *alignment = NULL;
- GtkWidget *vbox1 = NULL;
- GtkWidget *image1 = NULL;
- GtkWidget *dialog_action_area1 = NULL;
- GdkGeometry hints;
- GtkWidget *okButton;
- GtkWidget *cancelButton;
-
- priv = dialog->priv = (HildonCodeDialogPrivate*) g_malloc0
- (sizeof (HildonCodeDialogPrivate));
-
- const gchar* numstrs[10] = {
- "0","1","2","3","4","5","6","7","8","9"
- };
-
- GdkPixbuf* pixbuf = NULL;
- GtkIconTheme* icon_theme = NULL;
- GtkIconInfo *icon_info = NULL;
- gint base_size=0;
-
- /* Set default title */
- gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
-
- gtk_window_set_type_hint(GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
-
- hints.min_width = -1;
- hints.min_height = -1;
- hints.max_width = -1;
- hints.max_height = -1;
-
- gtk_window_set_geometry_hints(GTK_WINDOW(dialog), GTK_WIDGET(dialog),
- &hints,
- GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
-
- table = gtk_table_new (4, 3, FALSE);
- gtk_table_set_row_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
- gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
-
- dialog_vbox1 = GTK_DIALOG (dialog)->vbox;
- vbox1 = gtk_vbox_new (FALSE, 0);
- gtk_box_set_spacing (GTK_BOX(vbox1),HILDON_MARGIN_DOUBLE);
-
- priv->help_text= gtk_label_new ("");
- alignment=gtk_alignment_new(0.5,0,1,1);
- gtk_container_add(GTK_CONTAINER(alignment),priv->help_text);
-
- priv->entry = gtk_entry_new ();
-
- GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(priv->entry),GTK_CAN_FOCUS);
- gtk_entry_set_invisible_char (GTK_ENTRY(priv->entry), g_utf8_get_char ("*"));
- gtk_entry_set_alignment (GTK_ENTRY(priv->entry),1.0);
-
- gtk_editable_set_editable (GTK_EDITABLE(priv->entry),FALSE);
- gtk_entry_set_visibility (GTK_ENTRY(priv->entry), FALSE);
-
- gtk_box_pack_start (GTK_BOX (vbox1),alignment,TRUE,FALSE,0);
- gtk_box_pack_start (GTK_BOX (vbox1),priv->entry,TRUE,FALSE,0);
- gtk_box_pack_start (GTK_BOX (vbox1),table,FALSE,TRUE,0);
-
- gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1,FALSE,TRUE,0);
-
-
- for(i=1;i<=3;i++) {
- priv->buttons[0][i-1] = gtk_button_new_with_mnemonic(numstrs[i]);
- gtk_widget_set_size_request(priv->buttons[0][i-1],WIDTH,HEIGHT);
- gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[0][i-1],
- i-1,i,0,1);
- }
-
- for(i=4;i<=6;i++) {
- priv->buttons[1][i-4] = gtk_button_new_with_mnemonic (numstrs[i]);
- gtk_widget_set_size_request(priv->buttons[1][i-4],WIDTH,HEIGHT);
- gtk_table_attach_defaults(GTK_TABLE(table),priv->buttons[1][i-4],
- i-4,i-3,1,2);
- }
-
- for(i=7;i<=9;i++) {
- priv->buttons[2][i-7] = gtk_button_new_with_mnemonic (numstrs[i]);
- gtk_widget_set_size_request(priv->buttons[2][i-7], WIDTH,HEIGHT);
- gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[2][i-7],
- i-7,i-6,2,3);
- }
-
- priv->buttons[3][0] = priv->buttons[3][1] =
- gtk_button_new_with_mnemonic (numstrs[0]);
- gtk_widget_set_size_request (priv->buttons[3][0], WIDTH,HEIGHT);
- gtk_table_attach (GTK_TABLE(table), priv->buttons[3][0],
- 0,2,3,4, (GtkAttachOptions) (GTK_FILL),
- (GtkAttachOptions) (0), 0, 0);
-
- priv->buttons[3][2] = gtk_button_new ();
- gtk_widget_set_size_request(priv->buttons[3][2], WIDTH,HEIGHT);
- gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[3][2],
- 2,3,3,4);
-
- icon_theme = gtk_icon_theme_get_default ();
-
- icon_info = gtk_icon_theme_lookup_icon(icon_theme, BACKSPACE_ICON, 1,
- GTK_ICON_LOOKUP_NO_SVG);
- base_size = gtk_icon_info_get_base_size(icon_info);
- gtk_icon_info_free(icon_info);
- icon_info = NULL;
- pixbuf = gtk_icon_theme_load_icon (icon_theme,
- BACKSPACE_ICON, base_size,
- GTK_ICON_LOOKUP_NO_SVG,
- NULL);
- image1 = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (G_OBJECT(pixbuf));
- gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
- dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
- gtk_button_box_set_layout (GTK_BUTTON_BOX(dialog_action_area1),
- GTK_BUTTONBOX_END);
-
- okButton = gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_OK,
- GTK_RESPONSE_OK);
- cancelButton =
- gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_CANCEL,
- GTK_RESPONSE_CANCEL);
-
- gtk_widget_set_sensitive (okButton, FALSE);
-
- priv->buttons[4][0] = priv->buttons[4][1] = okButton;
- priv->buttons[4][2] = cancelButton;
-
- /*
- Connect signals.
- */
- g_signal_connect (G_OBJECT(priv->entry), "insert_text",
- G_CALLBACK (hildon_code_dialog_insert_text), dialog);
-
- gtk_entry_set_max_length(GTK_ENTRY(priv->entry),MAX_PINCODE_LEN);
-
- for (x=0; x<3; x++)
- {
- for (y=0; y<3 ;y++)
- {
- g_signal_connect (G_OBJECT (priv->buttons[x][y]), "clicked",
- G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
- g_signal_connect (G_OBJECT (priv->buttons[x][y]), "key-press-event",
- G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
- }
- }
-
- g_signal_connect (G_OBJECT (priv->buttons[3][0]), "clicked",
- G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
- g_signal_connect (G_OBJECT (priv->buttons[3][0]), "key-press-event",
- G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
-
- g_signal_connect (G_OBJECT (priv->buttons[3][2]), "clicked",
- G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
- g_signal_connect (G_OBJECT (priv->buttons[3][2]), "key-press-event",
- G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
-
- g_signal_connect (G_OBJECT (okButton), "key-press-event",
- G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
-
- g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
- G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
-
-}
-
-static void hildon_code_dialog_finalize (GObject *self)
-{
- HildonCodeDialog *dialog = HILDON_CODE_DIALOG (self);
-
- fprintf( stderr, "called destroy\n" );
-
- g_free (dialog->priv);
-
- G_OBJECT_CLASS (parent_class)->finalize (self);
-}
-
-/* Signal handlers */
-void hildon_code_dialog_button_clicked (GtkButton *button, gpointer user_data)
-{
- HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
- HildonCodeDialogPrivate *priv = dialog->priv;
- const char *number = gtk_button_get_label (button);
-
- if (number && *number )
- {
- gtk_entry_append_text (GTK_ENTRY (priv->entry), number);
- }
- else
- {
- /* Backspace */
- gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
- gchar *pos;
-
- pos = text;
-
- while (*pos != '\0')
- {
- pos ++;
- }
-
- pos = g_utf8_find_prev_char (text, pos);
-
- if (pos)
- {
- *pos=0;
- }
-
- gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
-
- if (*text == 0)
- {
- gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
- }
-
- g_free (text);
- }
-
-}
-
-static void hildon_code_dialog_insert_text (GtkEditable *editable,
- gchar *new_text,
- gint new_text_length,
- gint *position,
- gpointer user_data)
-{
- HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
- HildonCodeDialogPrivate *priv = dialog->priv;
- gchar * text = g_strdup(gtk_entry_get_text (GTK_ENTRY (priv->entry)));
- glong length = g_utf8_strlen (text, -1);
- g_free (text);
-
- if (length == MAX_PINCODE_LEN)
- {
- hildon_banner_show_information (dialog,
- NULL,
- DEVICELOCK_MAX_CHAR_REACHED);
- }
-
- else if (!length)
- {
- /* make the Ok button sensitive */
- gtk_widget_set_sensitive(priv->buttons[4][0], TRUE);
- }
-}
-
-static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
- GdkEventKey *event,
- gpointer user_data)
-{
- HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
- HildonCodeDialogPrivate *priv = dialog->priv;
- GtkWidget *new_widget = widget;
- gint x, y;
-
- for (x = 0; x < 5; x++)
- {
- for (y = 0; y < 3; y++)
- {
- if (priv->buttons[x][y] == widget)
- goto found;
- }
- }
- return FALSE;
-
-found:
-
- while (new_widget == widget)
- {
- switch (event->keyval)
- {
- case GDK_Up:
- x = (x+4)%5;
- break;
-
- case GDK_Down:
- x = (x+1)%5;
- break;
-
- case GDK_Left:
- y = (y+2)%3;
- break;
-
- case GDK_Right:
- y = (y+1)%3;
- break;
-
- default:
- return FALSE;
- }
-
- new_widget = priv->buttons[x][y];
- }
-
- gtk_widget_grab_focus (new_widget);
-
- return TRUE;
-}
-
-/* Public methods */
-
-/**
- * hildon_code_dialog_new:
- *
- * Use this function to create a new HildonCodeDialog.
- *
- * Return value: A @HildonCodeDialog.
- **/
-GtkWidget *hildon_code_dialog_new()
-{
- HildonCodeDialog *dialog = g_object_new (HILDON_TYPE_CODE_DIALOG, NULL);
-
- return GTK_WIDGET (dialog);
-}
-
-/**
- * hildon_code_dialog_get_code:
- * @dialog: The #HildonCodeDialog from which to get the entered code
- *
- * Use this function to access the code entered by the user.
- *
- * Return value: The entered code.
- **/
-const gchar *hildon_code_dialog_get_code (HildonCodeDialog *dialog)
-{
- g_return_val_if_fail (HILDON_IS_CODE_DIALOG (dialog), NULL);
- return gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
-}
-
-/**
- * hildon_code_dialog_clear_clode:
- * @dialog: The #HildonCodeDialog whose entry should be cleared:
- *
- * Use this function to clear the user entered code.
- **/
-void hildon_code_dialog_clear_code (HildonCodeDialog *dialog)
-{
- g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
- gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
- gtk_widget_set_sensitive (dialog->priv->buttons[4][0], FALSE);
-}
-
-/**
- * hildon_code_dialog_set_help_text:
- * @dialog: The #HildonCodeDialog whose entry should be cleared:
- * @text: The text to use in the help label.
- *
- * Use this function to set the text that will be displayd in the
- * help label
- **/
-void hildon_code_dialog_set_help_text (HildonCodeDialog *dialog,
- const gchar *text)
-{
- g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
- gtk_label_set_text (GTK_LABEL (dialog->priv->help_text), text);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_CODE_DIALOG_H__
-#define __HILDON_CODE_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-
-#define HILDON_TYPE_CODE_DIALOG ( hildon_code_dialog_get_type() )
-#define HILDON_CODE_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_CODE_DIALOG, HildonCodeDialog))
-#define HILDON_CODE_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_CODE_DIALOG, HildonCodeDialogClass))
-#define HILDON_IS_CODE_DIALOG(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_CODE_DIALOG))
-#define HILDON_IS_CODE_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CODE_DIALOG))
-
-
-typedef struct _HildonCodeDialogPrivate HildonCodeDialogPrivate;
-typedef struct _HildonCodeDialog HildonCodeDialog;
-typedef struct _HildonCodeDialogClass HildonCodeDialogClass;
-
-
-struct _HildonCodeDialog
-{
- GtkDialog parent;
-
- HildonCodeDialogPrivate *priv;
-};
-
-struct _HildonCodeDialogClass
-{
- GtkDialogClass parent_class;
-};
-
-
-GType hildon_code_dialog_get_type (void);
-GtkWidget *hildon_code_dialog_new(void);
-const gchar *hildon_code_dialog_get_code (HildonCodeDialog *dialog);
-void hildon_code_dialog_clear_code (HildonCodeDialog *dialog);
-void hildon_code_dialog_set_help_text (HildonCodeDialog *dialog,
- const gchar *text);
-
-
-G_END_DECLS
-#endif /* __HILDON_CODE_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-color-button
- * @short_description: A widget to open HildonColorChooserDialog
- * @see_also: #HildonColorChooserDialog, #HildonColorPopup
- *
- * HildonColorButton is a widget to open a HildonColorChooserDialog.
- * The selected color is shown in the button.
- * The selected color is a property of the button.
- * The property name is "color" and its type is GtkColor.
- */
-#include <config.h>
-
-#include <gtk/gtkbutton.h>
-#include <gtk/gtkalignment.h>
-#include <gtk/gtkdrawingarea.h>
-#include <gtk/gtksignal.h>
-#include <gdk/gdkkeysyms.h>
-#include <hildon-widgets/hildon-defines.h>
-
-#include "hildon-color-button.h"
-#include "hildon-color-chooser-dialog.h"
-
-#define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
- ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
-
-#define COLOR_FILLED_HEIGHT 22
-#define COLOR_FILLED_WIDTH 22
-
-#define COLOR_BUTTON_WIDTH 52
-#define COLOR_BUTTON_HEIGHT 48
-
-/* the outer border color */
-#define OUTER_BORDER_RED 0
-#define OUTER_BORDER_BLUE 0
-#define OUTER_BORDER_GREEN 0
-#define OUTER_BORDER_THICKNESS 1
-
-/* the inner border color */
-#define INNER_BORDER_RED 65535
-#define INNER_BORDER_BLUE 65535
-#define INNER_BORDER_GREEN 65535
-#define INNER_BORDER_THICKNESS 2
-
-struct _HildonColorButtonPrivate
-{
- GtkWidget *dialog;
-
- GdkColor color;
- GdkGC *gc;
-};
-
-enum
-{
- PROP_NONE,
- PROP_COLOR
-};
-
-static void
-hildon_color_button_class_init(HildonColorButtonClass *klass);
-static void
-hildon_color_button_init(HildonColorButton *color_button);
-
-static void
-hildon_color_button_finalize(GObject *object);
-static void
-hildon_color_button_set_property(GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec);
-static void
-hildon_color_button_get_property(GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec);
-static void
-hildon_color_button_realize(GtkWidget *widget);
-static void
-hildon_color_button_unrealize(GtkWidget *widget);
-static void
-hildon_color_button_clicked(GtkButton *button);
-static gboolean
-hildon_color_button_key_pressed(GtkWidget * button,
- GdkEventKey * event,
- gpointer data);
-static gint
-hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
- HildonColorButton *cb);
-
-static gboolean
-hildon_color_button_mnemonic_activate( GtkWidget *widget,
- gboolean group_cycling );
-
-static void
-draw_grid (GdkDrawable *drawable, GdkGC *gc,
- int x, int y,
- gint w, gint h);
-
-static gpointer parent_class = NULL;
-
-GType
-hildon_color_button_get_type(void)
-{
- static GType color_button_type = 0;
-
- if (!color_button_type)
- {
- static const GTypeInfo color_button_info =
- {
- sizeof (HildonColorButtonClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_color_button_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (HildonColorButton),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_color_button_init,
- };
-
- color_button_type =
- g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
- &color_button_info, 0);
- }
-
- return color_button_type;
-}
-
-static void
-hildon_color_button_class_init(HildonColorButtonClass *klass)
-{
- GObjectClass *gobject_class;
- GtkButtonClass *button_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- button_class = GTK_BUTTON_CLASS (klass);
- widget_class = GTK_WIDGET_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->get_property = hildon_color_button_get_property;
- gobject_class->set_property = hildon_color_button_set_property;
- gobject_class->finalize = hildon_color_button_finalize;
- widget_class->realize = hildon_color_button_realize;
- widget_class->unrealize = hildon_color_button_unrealize;
- button_class->clicked = hildon_color_button_clicked;
- widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
-
- /**
- * HildonColorButton:color:
- *
- * The selected color.
- */
- g_object_class_install_property (gobject_class, PROP_COLOR,
- g_param_spec_boxed ("color",
- "Current Color",
- "The selected color",
- GDK_TYPE_COLOR,
- G_PARAM_READWRITE));
-
- g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
-}
-
-/* Draw a dotted grid over the specified area to make it look
- * insensitive. Actually, we should generate that pixbuf once and
- * just render it over later... */
-static void
-draw_grid (GdkDrawable *drawable, GdkGC *gc,
- int x, int y,
- gint w, gint h)
-{
- int currentx;
- int currenty;
- for (currenty = y; currenty <= h; currenty++)
- for (currentx = ((currenty % 2 == 0) ? x : x + 1); currentx <= w; currentx += 2)
- gdk_draw_point (drawable, gc, currentx, currenty);
-}
-
-/* Handle exposure events for the color picker's drawing area */
-static gint
-hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
- HildonColorButton *cb)
-{
- GdkColor outer_border, inner_border;
-
- /* Create the outer border color */
- outer_border.pixel = 0;
- outer_border.red = OUTER_BORDER_RED;
- outer_border.blue = OUTER_BORDER_BLUE;
- outer_border.green = OUTER_BORDER_GREEN;
-
- /* Create the inner border color */
- inner_border.pixel = 0;
- inner_border.red = INNER_BORDER_RED;
- inner_border.blue = INNER_BORDER_BLUE;
- inner_border.green = INNER_BORDER_GREEN;
-
- /* serve the outer border color to the Graphic Context */
- gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
- /* draw the outer border as a filled rectangle */
- gdk_draw_rectangle(widget->window,
- (GTK_WIDGET_IS_SENSITIVE (widget)) ? cb->priv->gc : widget->style->bg_gc [GTK_STATE_INSENSITIVE],
- TRUE,
- 0,
- 0,
- widget->allocation.width,
- widget->allocation.height);
-
- /* serve the inner border color to the Graphic Context */
- gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
- /* draw the inner border as a filled rectangle */
- gdk_draw_rectangle(widget->window,
- cb->priv->gc,
- TRUE,
- OUTER_BORDER_THICKNESS,
- OUTER_BORDER_THICKNESS,
- widget->allocation.width - (OUTER_BORDER_THICKNESS * 2),
- widget->allocation.height - (OUTER_BORDER_THICKNESS * 2));
-
- /* serve the actual color to the Graphic Context */
- gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
- /* draw the actual rectangle */
- gdk_draw_rectangle(widget->window,
- cb->priv->gc,
- TRUE,
- INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
- INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
- widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
- widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
-
- if (! GTK_WIDGET_IS_SENSITIVE (widget)) {
- draw_grid (GDK_DRAWABLE (widget->window), widget->style->bg_gc [GTK_STATE_INSENSITIVE],
- INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
- INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
- widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2,
- widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2);
- }
-
- return FALSE;
-}
-
-static void
-hildon_color_button_init(HildonColorButton *cb)
-{
- GtkWidget *align;
- GtkWidget *drawing_area;
-
- cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
-
- cb->priv->dialog = NULL;
- cb->priv->gc = NULL;
-
- gtk_widget_push_composite_child();
-
- /* create widgets and pixbuf */
- align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
-
- drawing_area = gtk_drawing_area_new(); /*composite widget*/
-
- /* setting minimum sizes */
- gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
- COLOR_BUTTON_HEIGHT);
- gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
- COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
-
- /* Connect the callback function for exposure event */
- g_signal_connect(drawing_area, "expose-event",
- G_CALLBACK(hildon_color_field_expose_event), cb);
-
- /* Connect to callback function for key press event */
- g_signal_connect(G_OBJECT(cb), "key-press-event",
- G_CALLBACK(hildon_color_button_key_pressed), cb);
-
- /* packing */
- gtk_container_add(GTK_CONTAINER(align), drawing_area);
- gtk_container_add(GTK_CONTAINER(cb), align);
-
- gtk_widget_show_all(align);
-
- gtk_widget_pop_composite_child();
-}
-
-/* Free memory used by HildonColorButton */
-static void
-hildon_color_button_finalize(GObject *object)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
-
- if (cb->priv->dialog)
- {
- gtk_widget_destroy(cb->priv->dialog);
- cb->priv->dialog = NULL;
- }
-
- if( G_OBJECT_CLASS(parent_class)->finalize )
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-static void
-hildon_color_button_realize(GtkWidget *widget)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
-
- GTK_WIDGET_CLASS(parent_class)->realize(widget);
-
- cb->priv->gc = gdk_gc_new(widget->window);
-}
-
-static void
-hildon_color_button_unrealize(GtkWidget *widget)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
-
- g_object_unref(cb->priv->gc);
- cb->priv->gc = NULL;
-
- GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
-}
-
-/* Make the widget sensitive with the keyboard event */
-static gboolean
-hildon_color_button_mnemonic_activate( GtkWidget *widget,
- gboolean group_cycling )
-{
- gtk_widget_grab_focus( widget );
- return TRUE;
-}
-
-/* Popup a color selector dialog on button click */
-static void
-hildon_color_button_clicked(GtkButton *button)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
- HildonColorChooserDialog *cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
-
- /* Popup the color selector dialog */
- if (!cs_dialog)
- {
- /* The dialog hasn't been created yet, do it. */
- GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
- cb->priv->dialog = hildon_color_chooser_dialog_new(GTK_WINDOW(parent));
- cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
- if (parent)
- gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
- }
-
- /* Set the initial color for the color selector dialog */
- hildon_color_chooser_dialog_set_color(cs_dialog, &cb->priv->color);
-
- /* Update the color for color button if selection was made */
- if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
- {
- hildon_color_chooser_dialog_get_color(cs_dialog, &cb->priv->color);
- hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
- &(cb->priv->color) );
- }
-
- gtk_widget_hide(GTK_WIDGET(cs_dialog));
-}
-
-/* Popup a color selector dialog on hardkey Select press */
-static gboolean
-hildon_color_button_key_pressed(GtkWidget * button,
- GdkEventKey * event,
- gpointer data)
-{
- g_return_val_if_fail (HILDON_IS_COLOR_BUTTON(button), FALSE);
-
- if (event->keyval == HILDON_HARDKEY_SELECT)
- {
- hildon_color_button_clicked(GTK_BUTTON(button));
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Set_property function for HildonColorButtonClass initialization */
-static void
-hildon_color_button_set_property(GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
-
- switch (param_id)
- {
- case PROP_COLOR:
- cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
- gtk_widget_queue_draw(GTK_WIDGET(cb));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-/* Get_property function for HildonColorButtonClass initialization */
-static void
-hildon_color_button_get_property(GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec)
-{
- HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
-
- switch (param_id)
- {
- case PROP_COLOR:
- g_value_set_boxed(value, &cb->priv->color);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-/**
- * hildon_color_button_new:
- *
- * Creates a new color button. This returns a widget in the form of a
- * small button containing a swatch representing the selected color.
- * When the button is clicked, a color-selection dialog will open,
- * allowing the user to select a color. The swatch will be updated to
- * reflect the new color when the user finishes.
- *
- * Returns: a new color button
- */
-GtkWidget *
-hildon_color_button_new(void)
-{
- return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
-}
-
-/**
- * hildon_color_button_new_with_color:
- * @color: a #GdkColor for the initial color
- *
- * Creates a new color button with @color as the initial color.
- *
- * Returns: a new color button
- */
-GtkWidget *
-hildon_color_button_new_with_color(const GdkColor *color)
-{
- return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
-}
-
-/**
- * hildon_color_button_set_color:
- * @button: a #HildonColorButton
- * @color: a color to be set
- *
- * Sets the color selected by the button.
- */
-void
-hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
-{
- g_object_set( G_OBJECT(button), "color", color, NULL );
-}
-
-/**
- * hildon_color_button_get_color:
- * @button: a #HildonColorButton
- *
- * Returns: the color selected by the button
- */
-GdkColor *
-hildon_color_button_get_color( HildonColorButton *button )
-{
- GdkColor *color = NULL;
- g_object_get( G_OBJECT(button), "color", &color, NULL );
- return color;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_COLOR_BUTTON_H__
-#define __HILDON_COLOR_BUTTON_H__
-
-#include <gtk/gtkbutton.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_COLOR_BUTTON (hildon_color_button_get_type ())
-#define HILDON_COLOR_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButton))
-#define HILDON_COLOR_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_BUTTON, HildonColorButtonClass))
-#define HILDON_IS_COLOR_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_BUTTON))
-#define HILDON_IS_COLOR_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_COLOR_BUTTON))
-#define HILDON_COLOR_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonClass))
-
-typedef struct _HildonColorButton HildonColorButton;
-typedef struct _HildonColorButtonClass HildonColorButtonClass;
-typedef struct _HildonColorButtonPrivate HildonColorButtonPrivate;
-
-struct _HildonColorButton
-{
- GtkButton button;
- HildonColorButtonPrivate *priv;
-};
-
-struct _HildonColorButtonClass
-{
- GtkButtonClass parent_class;
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-
-GType
-hildon_color_button_get_type( void ) G_GNUC_CONST;
-
-GtkWidget *
-hildon_color_button_new( void );
-
-GtkWidget *
-hildon_color_button_new_with_color( const GdkColor *color );
-
-GdkColor *
-hildon_color_button_get_color( HildonColorButton *button );
-
-void
-hildon_color_button_set_color( HildonColorButton *button, GdkColor *color );
-
-G_END_DECLS
-
-#endif /* __HILDON_COLOR_BUTTON_H__ */
-
-
-
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#include <gtk/gtk.h>
-
-
-#include "hildon-color-chooser-button.h"
-
-#include "hildon-color-chooser-dialog.h"
-
-
-enum {
- COLOR_CHANGED,
- LAST_SIGNAL
-};
-
-
-static guint color_chooser_button_signals[LAST_SIGNAL] = { 0 };
-
-
-static GtkButtonClass *parent_klass = NULL;
-
-
-static void hildon_color_chooser_button_init(HildonColorChooserButton *object);
-static void hildon_color_chooser_button_class_init(HildonColorChooserButtonClass *klass);
-
-
-static void hildon_color_chooser_button_size_request(GtkWidget *widget, GtkRequisition *req);
-static void hildon_color_chooser_button_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
-
-static void hildon_color_chooser_button_realize(GtkWidget *widget);
-static void hildon_color_chooser_button_unrealize(GtkWidget *widget);
-
-static void hildon_color_chooser_button_style_set(GtkWidget *widget, GtkStyle *previous_style);
-
-static void hildon_color_chooser_button_show(GtkWidget *widget);
-static void hildon_color_chooser_button_show_all(GtkWidget *widget);
-
-static void hildon_color_chooser_button_virtual_set_color(HildonColorChooserButton *button, GdkColor *color);
-static void hildon_color_chooser_button_virtual_color_changed(HildonColorChooserButton *button, GdkColor *color);
-
-static void hildon_color_chooser_button_clicked(GtkButton *button);
-
-
-static gboolean hildon_color_chooser_button_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data);
-
-
-static void hildon_color_chooser_button_helper_get_style_info(HildonColorChooserButton *button);
-
-
-GtkType hildon_color_chooser_button_get_type ()
-{
- static GtkType button_type = 0;
-
- if (!button_type)
- {
- static const GtkTypeInfo button_info =
- {
- "HildonColorChooserButton",
- sizeof (HildonColorChooserButton),
- sizeof (HildonColorChooserButtonClass),
- (GtkClassInitFunc) hildon_color_chooser_button_class_init,
- (GtkObjectInitFunc) hildon_color_chooser_button_init,
- /* reserved_1 */ NULL,
- /* reserved_1 */ NULL,
- (GtkClassInitFunc) NULL
- };
-
- button_type = gtk_type_unique (GTK_TYPE_BUTTON, &button_info);
- }
-
- return button_type;
-}
-
-
- /* initializer functions */
-static void hildon_color_chooser_button_init(HildonColorChooserButton *object)
-{
- object->color.red = 0x0000;
- object->color.green = 0x0000;
- object->color.blue = 0x0000;
- object->color.pixel = 0x00000000;
-
-
- object->area = gtk_drawing_area_new();
-
- gtk_container_add(GTK_CONTAINER(object), object->area);
-
-
- g_signal_connect(G_OBJECT(object->area), "expose-event",
- G_CALLBACK(hildon_color_chooser_button_area_expose), object);
-}
-
-static void hildon_color_chooser_button_class_init(HildonColorChooserButtonClass *klass)
-{
- GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS(klass);
- GtkButtonClass *button_klass = GTK_BUTTON_CLASS(klass);
- GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
-
-
- parent_klass = g_type_class_peek_parent(klass);
-
-
- klass->set_color = hildon_color_chooser_button_virtual_set_color;
- klass->color_changed = hildon_color_chooser_button_virtual_color_changed;
-
-
- button_klass->clicked = hildon_color_chooser_button_clicked;
-
-
- widget_klass->size_request = hildon_color_chooser_button_size_request;
- widget_klass->size_allocate = hildon_color_chooser_button_size_allocate;
-
- widget_klass->realize = hildon_color_chooser_button_realize;
- widget_klass->unrealize = hildon_color_chooser_button_unrealize;
-
- widget_klass->style_set = hildon_color_chooser_button_style_set;
-
- widget_klass->show = hildon_color_chooser_button_show;
- widget_klass->show_all = hildon_color_chooser_button_show_all;
-
-
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("outer_border",
- "Outer border",
- "Size of the outer border",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("inner_border",
- "Inner border",
- "Size of the inner border",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
- gtk_widget_class_install_style_property(widget_klass,
- g_param_spec_boxed("minimum_size",
- "minimum_size",
- "Minimum size of the color area",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
-
- color_chooser_button_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_klass),
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserButtonClass, color_changed),
- NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
-}
-
-
- /* virtual widget functions */
-static void hildon_color_chooser_button_size_request(GtkWidget *widget, GtkRequisition *req)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
-
-
- req->width = button->style_info.outer.left + button->style_info.min.left + button->style_info.outer.right;
- req->height = button->style_info.outer.top + button->style_info.min.right + button->style_info.outer.bottom;
-}
-
-static void hildon_color_chooser_button_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
- GtkAllocation child_alloc;
- GdkRectangle clip_rect;
-
-
- GTK_WIDGET_CLASS(parent_klass)->size_allocate(widget, alloc);
- child_alloc = *alloc;
-
-
- child_alloc.x += button->style_info.outer.left;
- child_alloc.y += button->style_info.outer.top;
-
- child_alloc.width -= (button->style_info.outer.left + button->style_info.outer.right);
- child_alloc.height -= (button->style_info.outer.top + button->style_info.outer.bottom);
-
-
- gtk_widget_size_allocate(button->area, &child_alloc);
-
-
- if(GTK_WIDGET_REALIZED(widget)) {
- clip_rect.x = button->style_info.inner.left;
- clip_rect.y = button->style_info.inner.top;
- clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
- clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
-
- gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
- }
-}
-
-
-static void hildon_color_chooser_button_realize(GtkWidget *widget)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
- GdkRectangle clip_rect;
-
-
- GTK_WIDGET_CLASS(parent_klass)->realize(widget);
-
-
- button->color_gc = gdk_gc_new(widget->window);
- gdk_gc_set_rgb_fg_color(button->color_gc, &button->color);
-
-
- clip_rect.x = button->style_info.inner.left;
- clip_rect.y = button->style_info.inner.top;
- clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
- clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
-
- gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
-}
-
-static void hildon_color_chooser_button_unrealize(GtkWidget *widget)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
-
-
- g_object_unref(button->color_gc);
- button->color_gc = NULL;
-
-
- GTK_WIDGET_CLASS(parent_klass)->unrealize(widget);
-}
-
-
-static void hildon_color_chooser_button_style_set(GtkWidget *widget, GtkStyle *previous_style)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
- GdkRectangle clip_rect;
-
-
- hildon_color_chooser_button_helper_get_style_info(button);
-
-
- if(GTK_WIDGET_REALIZED(widget)) {
- clip_rect.x = button->style_info.inner.left;
- clip_rect.y = button->style_info.inner.top;
- clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
- clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
-
- gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
- }
-}
-
-
-static void hildon_color_chooser_button_show(GtkWidget *widget)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
-
-
- gtk_widget_show(button->area);
-
- GTK_WIDGET_CLASS(parent_klass)->show(widget);
-}
-
-static void hildon_color_chooser_button_show_all(GtkWidget *widget)
-{
- hildon_color_chooser_button_show(widget);
-}
-
-
-static void hildon_color_chooser_button_virtual_set_color(HildonColorChooserButton *button, GdkColor *color)
-{
- button->color = *color;
-
- if(GTK_WIDGET_REALIZED(button)) {
- gdk_gc_set_rgb_fg_color(button->color_gc, &button->color);
-
- gtk_widget_queue_draw(button->area);
- }
-
-
- g_signal_emit(button, color_chooser_button_signals[COLOR_CHANGED], 0, &button->color);
-}
-
-static void hildon_color_chooser_button_virtual_color_changed(HildonColorChooserButton *button, GdkColor *color)
-{
-}
-
-
-static void hildon_color_chooser_button_clicked(GtkButton *button)
-{
- HildonColorChooserButton *color_button = HILDON_COLOR_CHOOSER_BUTTON(button);
- GtkWidget *dialog;
- GdkColor color;
- gint result = 0;
-
-
- dialog = hildon_color_chooser_dialog_new();
- gtk_widget_realize(dialog);
- hildon_color_chooser_dialog_set_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &color_button->color);
- gtk_widget_show(dialog);
-
-
- result = gtk_dialog_run(GTK_DIALOG(dialog));
-
-
- if(result == GTK_RESPONSE_OK) {
- hildon_color_chooser_dialog_get_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &color);
- hildon_color_chooser_button_virtual_set_color(color_button, &color);
- }
-
-
-/*g_object_unref(G_OBJECT(dialog));*/
- gtk_widget_destroy(dialog);
-}
-
-
- /* signal handlers */
-static gboolean hildon_color_chooser_button_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
- HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(data);
- GtkWidget *button_widget = GTK_WIDGET(data);
-
-
- if(button->style_info.inner.left > 0 || button->style_info.inner.right > 0 ||
- button->style_info.inner.top > 0 || button->style_info.inner.bottom > 0) {
- gtk_paint_box(gtk_widget_get_style(button_widget), widget->window, GTK_WIDGET_STATE(button_widget), GTK_SHADOW_NONE,
- &event->area, button_widget, "color-button", 0, 0, widget->allocation.width, widget->allocation.height);
- }
-
-
- gdk_draw_rectangle(widget->window, button->color_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height);
-
-
- return FALSE;
-}
-
-
- /* additional use-only-here functions */
-static void hildon_color_chooser_button_helper_get_style_info(HildonColorChooserButton *button)
-{
- GtkBorder *in, *out, *min;
-
- gtk_widget_style_get(GTK_WIDGET(button), "inner_border", &in,
- "outer_border", &out,
- "minimum_size", &min, NULL);
-
-
- if(in) {
- button->style_info.inner = *in;
- g_free(in);
- } else {
- button->style_info.inner.left = 0;
- button->style_info.inner.right = 0;
- button->style_info.inner.top = 0;
- button->style_info.inner.bottom = 0;
- }
-
- if(out) {
- button->style_info.outer = *out;
- g_free(out);
- } else {
- button->style_info.outer.left = 4;
- button->style_info.outer.right = 4;
- button->style_info.outer.top = 4;
- button->style_info.outer.bottom = 4;
- }
-
- if(min) {
- button->style_info.min = *min;
- g_free(min);
- } else {
- button->style_info.min.left = 8;
- button->style_info.min.right = 8;
- button->style_info.min.top = 0;
- button->style_info.min.bottom = 0;
- }
-}
-
-
- /* public API */
-GtkWidget *hildon_color_chooser_button_new()
-{
- return gtk_type_new(HILDON_TYPE_COLOR_CHOOSER_BUTTON);
-}
-
-
-void hildon_color_chooser_button_set_color(HildonColorChooserButton *button, GdkColor *color)
-{
- HILDON_COLOR_CHOOSER_BUTTON_CLASS(G_OBJECT_GET_CLASS(button))->set_color(button, color);
-}
-
-void hildon_color_chooser_button_get_color(HildonColorChooserButton *button, GdkColor *color)
-{
- *color = button->color;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_COLOR_CHOOSER_BUTTON_H__
-#define __HILDON_COLOR_CHOOSER_BUTTON_H__
-
-
-#include <gdk/gdkcolor.h>
-
-#include <gtk/gtkwidget.h>
-
-
-#define HILDON_TYPE_COLOR_CHOOSER_BUTTON (hildon_color_chooser_button_get_type())
-
-#define HILDON_COLOR_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER_BUTTON, HildonColorChooserButton))
-#define HILDON_COLOR_CHOOSER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER_BUTTON, HildonColorChooserButtonClass))
-#define HILDON_IS_COLOR_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER_BUTTON))
-
-
-typedef struct HildonColorChooserButton_ HildonColorChooserButton;
-typedef struct HildonColorChooserButtonClass_ HildonColorChooserButtonClass;
-
-
-struct HildonColorChooserButton_
-{
- GtkButton parent;
-
- GdkColor color;
-
- GtkWidget *area;
-
- GdkGC *color_gc;
-
-
- struct {
- GtkBorder outer;
- GtkBorder inner;
- GtkBorder min;
- } style_info;
-};
-
-struct HildonColorChooserButtonClass_
-{
- GtkButtonClass parent;
-
- void (*color_changed) (HildonColorChooserButton *button, GdkColor *color);
-
- void (*set_color) (HildonColorChooserButton *, GdkColor *);
-};
-
-
-GtkType hildon_color_chooser_button_get_type();
-GtkWidget *hildon_color_chooser_button_new();
-
-void hildon_color_chooser_button_set_color(HildonColorChooserButton *button, GdkColor *color);
-void hildon_color_chooser_button_get_color(HildonColorChooserButton *button, GdkColor *color);
-
-
-#endif /* __HILDON_COLOR_CHOOSER_BUTTON_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-/**
- * SECTION:hildon-color-chooser-dialog
- * @short_description: A dialog to choose a color.
- * @see_also: #HildonColorButton, #HildonColorChooser
- *
- * HildonColorChooserDialog is a widget widget to choose a color.
- */
-#include <gtk/gtk.h>
-
-
-#include "hildon-color-chooser-dialog.h"
-
-#include "hildon-plugin-widget.h"
-
-
-enum {
- COLOR_CHANGED,
- LAST_SIGNAL
-};
-
-
-static HildonPluginWidgetInfo *global_plugin = NULL;
-
-
-static guint color_chooser_dialog_signals[LAST_SIGNAL] = { 0 };
-
-
-static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object);
-static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass);
-
-
-GtkType hildon_color_chooser_dialog_get_type ()
-{
- static GtkType chooser_type = 0;
-
- if (!chooser_type)
- {
- static const GtkTypeInfo chooser_info =
- {
- "HildonColorChooserDialog",
- sizeof (HildonColorChooserDialog),
- sizeof (HildonColorChooserDialogClass),
- (GtkClassInitFunc) hildon_color_chooser_dialog_class_init,
- (GtkObjectInitFunc) hildon_color_chooser_dialog_init,
- /* reserved_1 */ NULL,
- /* reserved_1 */ NULL,
- (GtkClassInitFunc) NULL
- };
-
- chooser_type = gtk_type_unique (GTK_TYPE_DIALOG, &chooser_info);
- }
-
- return chooser_type;
-}
-
-
-static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object)
-{
- int i;
-
-
- object->color.red = 0x0000;
- object->color.green = 0x0000;
- object->color.blue = 0x0000;
- object->color.pixel = 0x00000000;
-
-
- for(i = 0; i < 32; i++) {
- object->reserved[i] = 0;
- }
-}
-
-static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass)
-{
- GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
- int i;
-
-
- for(i = 0; i < 32; i++) {
- klass->reserved[i] = 0;
- }
-
- klass->set_color = 0;
-
-
- color_chooser_dialog_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_klass),
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserDialogClass, color_changed),
- NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
-}
-
-/**
- * hildon_color_chooser_dialog_new:
- *
- * Creates a new color chooser dialog. The dialog is created through
- * HildonPluginWidget API and is loaded from plugin. The initially selected
- * color can be anything, so it's recommended to call
- * hildon_color_chooser_dialog_set_color () after creating the widget.
- *
- * Returns: a new color chooser dialog
- */
-GtkWidget *hildon_color_chooser_dialog_new()
-{
- if(!global_plugin) {
- global_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER_DIALOG, NULL);
- g_return_val_if_fail (global_plugin != NULL, NULL);
- }
-
- return hildon_plugin_info_construct_widget(global_plugin);
-}
-
-/**
- * hildon_color_chooser_dialog_set_color:
- * @chooser: a #HildonColorChooserDialog
- * @color: a color to be set
- *
- * Sets the color selected in the dialog.
- */
-void hildon_color_chooser_dialog_set_color(HildonColorChooserDialog *chooser, GdkColor *color)
-{
- HildonColorChooserDialogClass *klass = HILDON_COLOR_CHOOSER_DIALOG_CLASS(G_OBJECT_GET_CLASS(chooser));
-
-
- chooser->color = *color;
-
- if(klass->set_color) {
- klass->set_color(chooser, color);
- }
-}
-
-/**
- * hildon_color_chooser_dialog_get_color:
- * @chooser: a #HildonColorChooserDialog
- * @color: a pointer to #GdkColor to be filled by the function
- *
- * Gets the color selected in the dialog.
- */
-void hildon_color_chooser_dialog_get_color(HildonColorChooserDialog *chooser, GdkColor *color)
-{
- *color = chooser->color;
-}
-
-
-void hildon_color_chooser_dialog_emit_color_changed(HildonColorChooserDialog *chooser)
-{
- g_signal_emit(chooser, color_chooser_dialog_signals[COLOR_CHANGED], 0, &chooser->color);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_COLOR_CHOOSER_DIALOG_H__
-#define __HILDON_COLOR_CHOOSER_DIALOG_H__
-
-
-#include <gdk/gdkcolor.h>
-
-#include <gtk/gtkdialog.h>
-
-
-#define HILDON_TYPE_COLOR_CHOOSER_DIALOG (hildon_color_chooser_dialog_get_type())
-
-#define HILDON_COLOR_CHOOSER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER_DIALOG, HildonColorChooserDialog))
-#define HILDON_COLOR_CHOOSER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER_DIALOG, HildonColorChooserDialogClass))
-#define HILDON_IS_COLOR_CHOOSER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER_DIALOG))
-
-
-typedef struct HildonColorChooserDialog_ HildonColorChooserDialog;
-typedef struct HildonColorChooserDialogClass_ HildonColorChooserDialogClass;
-
-
-struct HildonColorChooserDialog_ {
- GtkDialog parent;
-
- GdkColor color;
-
- guint32 reserved[32];
-};
-
-struct HildonColorChooserDialogClass_ {
- GtkDialogClass parent_class;
-
- gboolean (*color_changed) (HildonColorChooserDialog *chooser, GdkColor *color);
-
- void (*set_color) (HildonColorChooserDialog *, GdkColor *);
-
- void (*reserved[32]) (void *);
-};
-
-
-GtkType hildon_color_chooser_dialog_get_type();
-
-GtkWidget *hildon_color_chooser_dialog_new();
-
-void hildon_color_chooser_dialog_set_color(HildonColorChooserDialog *chooser, GdkColor *color);
-void hildon_color_chooser_dialog_get_color(HildonColorChooserDialog *chooser, GdkColor *color);
-
-void hildon_color_chooser_dialog_emit_color_changed(HildonColorChooserDialog *chooser);
-
-
-#endif /* __HILDON_COLOR_CHOOSER_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-/**
- * SECTION:hildon-color-chooser
- * @short_description: A widget to choose a color.
- * @see_also: #HildonColorChooserDialog, #HildonColorButton
- *
- * HildonColorChooser is a widget to choose a color.
- */
-#include <gtk/gtk.h>
-
-
-#include "hildon-color-chooser.h"
-
-#include "hildon-plugin-widget.h"
-
-
-enum {
- COLOR_CHANGED,
- LAST_SIGNAL
-};
-
-
-static HildonPluginWidgetInfo *global_plugin = NULL;
-
-
-static guint color_chooser_signals[LAST_SIGNAL] = { 0 };
-
-
-static void hildon_color_chooser_init(HildonColorChooser *sel);
-static void hildon_color_chooser_class_init(HildonColorChooserClass *klass);
-
-
-GtkType hildon_color_chooser_get_type ()
-{
- static GtkType chooser_type = 0;
-
- if (!chooser_type)
- {
- static const GtkTypeInfo chooser_info =
- {
- "HildonColorChooser",
- sizeof (HildonColorChooser),
- sizeof (HildonColorChooserClass),
- (GtkClassInitFunc) hildon_color_chooser_class_init,
- (GtkObjectInitFunc) hildon_color_chooser_init,
- /* reserved_1 */ NULL,
- /* reserved_1 */ NULL,
- (GtkClassInitFunc) NULL
- };
-
- chooser_type = gtk_type_unique (GTK_TYPE_WIDGET, &chooser_info);
- }
-
- return chooser_type;
-}
-
-
-static void hildon_color_chooser_init(HildonColorChooser *sel)
-{
- sel->color.red = 0x0000;
- sel->color.green = 0x0000;
- sel->color.blue = 0x0000;
- sel->color.pixel = 0x00000000;
-}
-
-static void hildon_color_chooser_class_init(HildonColorChooserClass *klass)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);
-
- klass->set_color = NULL;
-
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_boxed("outer_border",
- "Outer border",
- "Size of outer border",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
- color_chooser_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserClass, color_changed),
- NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
-}
-
-/**
- * hildon_color_chooser_new:
- *
- * Creates a new color chooser widget. The dialog is created through
- * HildonPluginWidget API and is loaded from plugin. The initially selected
- * color can be anything, so it's recommended to call
- * hildon_color_chooser_dialog_set_color () after creating the widget.
- *
- * Returns: a new color chooser widget
- */
-GtkWidget *hildon_color_chooser_new()
-{
- if(!global_plugin) {
- global_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER, NULL);
- }
-
-
- return hildon_plugin_info_construct_widget(global_plugin);
-}
-
-/**
- * hildon_color_chooser_set_color:
- * @chooser: a #HildonColorChooser
- * @color: a color to be set
- *
- * Sets the color selected in the widget.
- */
-void hildon_color_chooser_set_color(HildonColorChooser *chooser, GdkColor *color)
-{
- HildonColorChooserClass *klass = HILDON_COLOR_CHOOSER_CLASS(G_OBJECT_GET_CLASS(chooser));
-
-
- chooser->color = *color;
-
- if(klass->set_color) {
- klass->set_color(chooser, color);
- }
-}
-
-/**
- * hildon_color_chooser_get_color:
- * @chooser: a #HildonColorChooser
- * @color: a pointer to #GdkColor to be filled by the function
- *
- * Gets the color selected in the widget.
- */
-void hildon_color_chooser_get_color(HildonColorChooser *chooser, GdkColor *color)
-{
- *color = chooser->color;
-}
-
-
-void hildon_color_chooser_emit_color_changed(HildonColorChooser *chooser)
-{
- g_signal_emit(chooser, color_chooser_signals[COLOR_CHANGED], 0, &chooser->color);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_COLOR_CHOOSER_H__
-#define __HILDON_COLOR_CHOOSER_H__
-
-
-#include <gdk/gdkcolor.h>
-
-#include <gtk/gtkwidget.h>
-
-
-#define HILDON_TYPE_COLOR_CHOOSER (hildon_color_chooser_get_type())
-
-#define HILDON_COLOR_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER, HildonColorChooser))
-#define HILDON_COLOR_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER, HildonColorChooserClass))
-#define HILDON_IS_COLOR_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER))
-
-
-typedef struct HildonColorChooser_ HildonColorChooser;
-typedef struct HildonColorChooserClass_ HildonColorChooserClass;
-
-
-struct HildonColorChooser_
-{
- GtkWidget parent;
-
- GdkColor color;
-};
-
-struct HildonColorChooserClass_
-{
- GtkWidgetClass parent;
-
- void (*color_changed) (HildonColorChooser *selection, GdkColor *color);
-
- void (*set_color) (HildonColorChooser *, GdkColor *);
-};
-
-
-GtkType hildon_color_chooser_get_type(void);
-GtkWidget *hildon_color_chooser_new(void);
-
-void hildon_color_chooser_set_color(HildonColorChooser *chooser, GdkColor *color);
-void hildon_color_chooser_get_color(HildonColorChooser *chooser, GdkColor *color);
-
-void hildon_color_chooser_emit_color_changed(HildonColorChooser *chooser);
-
-
-#endif /* __HILDON_COLOR_CHOOSER_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-color-popup
- * @short_description: A popup dialog for editing a color and showing the
- * edited result
- * @see_also: #HildonColorButton, #HildonColorSelector
- *
- * #HildonColorPopup is only used inside #HildonColorButton. It is a
- * popup dialog for editing a color. The color can be changed using
- * three control bars that are used to adjust the red, green and blue
- * color channels. The display is updated in real time when the bars are
- * moved.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtkbox.h>
-#include <gtk/gtktable.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkdrawingarea.h>
-
-#include "hildon-color-selector.h"
-#include "hildon-color-popup.h"
-#include "hildon-controlbar.h"
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-/* Pixel sizes */
-#define HILDON_COLOR_PALETTE_SIZE 120
-#define HILDON_COLOR_CONTROLBAR_MAX 31
-#define HILDON_COLOR_CONTROLBAR_MIN 0
-#define HILDON_COLOR_LABELS_LEFT_PAD 35
-#define HILDON_COLOR_PALETTE_POS_PAD 45
-#define HILDON_COLOR_BAR_WIDTH 449
-#define HILDON_COLOR_COL_SPACING 18
-
-/*
- * Private function prototype definitions
- */
-
-static gboolean
-hildon_popup_palette_expose (GtkWidget * widget,
- GdkEventExpose * event,
- gpointer data);
-/**
- * hildon_color_popup_new:
- * @parent: the parent window of the dialog
- * @initial_color: a #GdkColor with the initial values to be used
- * @popup_data: a #HildonColorPopup
- *
- * This function creates a new popup dialog with three controlbars
- * (red, green, blue) and a drawing area with the current color.
- *
- * Used as normal GtkDialog (run with gtk_dialog_run() and read
- * stardard responses (GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL).
- *
- * Returns: the newly created popup dialog
- */
-
-GtkWidget *
-hildon_color_popup_new(GtkWindow *parent, const GdkColor *initial_color,
- HildonColorPopup *popup_data)
-{
- GtkWidget *popup;
- GtkTable *layout;
- GtkWidget *area;
- GtkWidget *l_red, *l_green, *l_blue;
-
- /* Create control bars for HildonColorPopup */
- popup_data->ctrlbar_red = hildon_controlbar_new ();
- popup_data->ctrlbar_green = hildon_controlbar_new ();
- popup_data->ctrlbar_blue = hildon_controlbar_new ();
- area = gtk_drawing_area_new();
- layout = GTK_TABLE(gtk_table_new(12, 2, FALSE));
-
- /* Set widgets' size */
- gtk_widget_set_size_request (area,
- HILDON_COLOR_PALETTE_SIZE,
- HILDON_COLOR_PALETTE_SIZE);
- gtk_widget_set_size_request(popup_data->ctrlbar_red,
- HILDON_COLOR_BAR_WIDTH, -1);
- gtk_widget_set_size_request(popup_data->ctrlbar_green,
- HILDON_COLOR_BAR_WIDTH, -1);
- gtk_widget_set_size_request(popup_data->ctrlbar_blue,
- HILDON_COLOR_BAR_WIDTH, -1);
-
- /* Create labels for three kinds of color */
- l_red = gtk_label_new(_("ecdg_fi_5bit_colour_selector_red"));
- l_green = gtk_label_new(_("ecdg_fi_5bit_colour_selector_green"));
- l_blue = gtk_label_new(_("ecdg_fi_5bit_colour_selector_blue"));
-
- /* Position the labels to start about the same label as the controlbars */
- gtk_misc_set_alignment(GTK_MISC(l_red), 0.08f, 0.5f);
- gtk_misc_set_alignment(GTK_MISC(l_green), 0.08f, 0.5f);
- gtk_misc_set_alignment(GTK_MISC(l_blue), 0.08f, 0.5f);
-
- /* Add labels and control bars to the layout table */
- gtk_table_set_col_spacing(layout, 0, HILDON_COLOR_COL_SPACING);
- gtk_table_attach_defaults(layout, l_red, 0, 1, 0, 2);
- gtk_table_attach_defaults(layout, popup_data->ctrlbar_red, 0, 1, 2, 4);
- gtk_table_attach_defaults(layout, l_green, 0, 1, 4, 6);
- gtk_table_attach_defaults(layout, popup_data->ctrlbar_green, 0, 1, 6, 8);
- gtk_table_attach_defaults(layout, l_blue, 0, 1, 8, 10);
- gtk_table_attach_defaults(layout, popup_data->ctrlbar_blue, 0, 1, 10, 12);
- gtk_table_attach(layout, area, 1, 2, 3, 11, GTK_SHRINK, GTK_SHRINK, 0, 0);
-
- /* Give the maximum and minimum limits for each control bar */
- hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_red),
- HILDON_COLOR_CONTROLBAR_MIN,
- HILDON_COLOR_CONTROLBAR_MAX);
- hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_green),
- HILDON_COLOR_CONTROLBAR_MIN,
- HILDON_COLOR_CONTROLBAR_MAX);
- hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_blue),
- HILDON_COLOR_CONTROLBAR_MIN,
- HILDON_COLOR_CONTROLBAR_MAX);
-
- /* Give the initial values for each control bar */
- hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_red),
- (initial_color->red >> 11)&0x1F);
- hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_green),
- (initial_color->green >> 11)&0x1F);
- hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_blue),
- (initial_color->blue >> 11)&0x1F);
-
- /* Register controlbar callbacks */
- g_signal_connect_swapped(popup_data->ctrlbar_red, "value-changed",
- G_CALLBACK(gtk_widget_queue_draw), area);
- g_signal_connect_swapped(popup_data->ctrlbar_green, "value-changed",
- G_CALLBACK(gtk_widget_queue_draw), area);
- g_signal_connect_swapped(popup_data->ctrlbar_blue, "value-changed",
- G_CALLBACK(gtk_widget_queue_draw), area);
-
- /* Attach expose_event callback function to drawing area */
- g_signal_connect (area, "expose_event",
- G_CALLBACK(hildon_popup_palette_expose),
- popup_data);
-
- /* Create popup dialog */
- popup = gtk_dialog_new_with_buttons (_("ecdg_ti_5bit_colour_selector"),
- GTK_WINDOW(parent),
- GTK_DIALOG_DESTROY_WITH_PARENT |
- GTK_DIALOG_NO_SEPARATOR,
- _("ecdg_bd_5bit_colour_selector_ok"), GTK_RESPONSE_OK,
- _("ecdg_bd_5bit_colour_selector_cancel"),
- GTK_RESPONSE_CANCEL,
- NULL);
-
- /* Select-key shouldn't do anything unless dialog's button is focused */
- gtk_dialog_set_default_response(GTK_DIALOG(popup), GTK_RESPONSE_NONE);
-
- /* Add layout table to the Vbox of the popup dialog */
- gtk_box_pack_start (GTK_BOX(GTK_DIALOG(popup)->vbox),
- GTK_WIDGET(layout), TRUE, TRUE, 0);
-
- /* Show thw Vbox of the popup dialog */
- gtk_widget_show_all(GTK_DIALOG(popup)->vbox);
-
- return popup;
-}
-
-/**
- * hildon_color_popup_set_color_from_sliders:
- * @color: a pointer to #GdkColor to which the new values will be put
- * @popup_data: a #HildonColorPopup
- *
- * Sets the values in the given #GdkColor to the values of the
- * controlbars.
- */
-
-void
-hildon_color_popup_set_color_from_sliders(GdkColor *color,
- HildonColorPopup *popup_data)
-{
- color->pixel = 0;
- color->red = hildon_controlbar_get_value (
- HILDON_CONTROLBAR(popup_data->ctrlbar_red)) << 11;
- color->green = hildon_controlbar_get_value (
- HILDON_CONTROLBAR(popup_data->ctrlbar_green)) << 11;
- color->blue = hildon_controlbar_get_value (
- HILDON_CONTROLBAR(popup_data->ctrlbar_blue)) << 11;
-}
-
-/* expose_event callback function */
-static gboolean
-hildon_popup_palette_expose (GtkWidget * widget,
- GdkEventExpose *event, gpointer data)
-{
- if (GTK_WIDGET_DRAWABLE(widget))
- {
- GdkColor color;
- GdkGC * gc = gdk_gc_new (widget->window);
-
- /* Get the current color value */
- hildon_color_popup_set_color_from_sliders(&color, data);
- gdk_gc_set_rgb_fg_color(gc, &color);
-
- /* draw the color area */
- gdk_draw_rectangle( widget->window, gc, TRUE /* filled */,
- 1, 1, widget->allocation.width - 2,
- widget->allocation.height - 2);
-
- color.pixel = color.red = color.green = color.blue = 0;
- gdk_gc_set_rgb_fg_color(gc, &color);
-
- /* Draw frames on color box */
- gdk_draw_rectangle( widget->window, gc, FALSE,
- 0, 0, widget->allocation.width - 1,
- widget->allocation.height - 1);
-
- /* Free memory used by the graphics contexts */
- g_object_unref(gc);
- }
-
- return TRUE;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_COLOR_POPUP_H__
-#define __HILDON_COLOR_POPUP_H__
-
-#include <gtk/gtkcontainer.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-typedef struct
-{
- GtkWidget *ctrlbar_red;
- GtkWidget *ctrlbar_green;
- GtkWidget *ctrlbar_blue;
-
-} HildonColorPopup;
-
-GtkWidget *hildon_color_popup_new(GtkWindow *parent,
- const GdkColor *initial_color,
- HildonColorPopup *popupdata);
-
-void hildon_color_popup_set_color_from_sliders(GdkColor *color,
- HildonColorPopup *popupdata);
-
-
-G_END_DECLS
-
-#endif /* __HILDON_COLOR_POPUP_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-color-selector
- * @short_description: A widget for selecting a color
- * @see_also: #HildonColorButton, #HildonColorPopup
- *
- * #HildonColorSelector allows selection of a color from a standard
- * 16-color palette or a palette of 8 user-customizable colors.
- * The user-customizable colors can be modified through HildonColorPopup.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtktable.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkdrawingarea.h>
-#include <gtk/gtkbutton.h>
-#include <gdk/gdkkeysyms.h>
-#include <gconf/gconf-client.h>
-
-#include "hildon-color-selector.h"
-#include "hildon-color-popup.h"
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-/* Color amounts */
-#define HILDON_BASE_COLOR_NUM 16
-#define HILDON_CUSTOM_COLOR_NUM 8
-#define HILDON_TOTAL_COLOR_NUM (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM)
-#define BLACKIND 0
-#define GREYIND 6
-#define WHITEIND 9
-
-#define SELECTION_BORDER_COLOR_NAME "ImageBorderColor"
-#define FOCUS_BORDER_COLOR "#8080FF"
-#define FOCUS_BORDER_WIDTH 2
-
-/* Pixel sizes */
-#define HILDON_COLOR_SELECTOR_BOX_W 26
-#define HILDON_COLOR_SELECTOR_BOX_H 26
-#define HILDON_COLOR_SELECTOR_BORDER_WIDTH 1
-#define HILDON_COLOR_SELECTOR_PADDING_WIDTH 1
-
-#define HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH \
- ( HILDON_COLOR_SELECTOR_BOX_W \
- + HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 \
- + HILDON_COLOR_SELECTOR_PADDING_WIDTH * 2 )
-
-#define HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT \
- ( HILDON_COLOR_SELECTOR_BOX_H \
- + HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 \
- + HILDON_COLOR_SELECTOR_PADDING_WIDTH * 2 )
-
-#define HILDON_COLOR_SELECTOR_COLS 8
-#define HILDON_COLOR_SELECTOR_ROWS 3
-
-/* gconf definitions */
-#define HILDON_COLOR_GCONF_PATH "/system/osso/af/color_selector"
-#define HILDON_COLOR_GCONF_KEYS "/system/osso/af/color_selector/custom_colors"
-
-/* Pointer parent class */
-static GtkDialogClass *parent_class;
-
-struct _HildonColorSelectorPriv
-{
- GConfClient *client;
- GtkWidget *drawing_area;
- GtkWidget *modify_button;
- gint selected_index;
- gint focused_index;
- guint notify_id;
- /* one extra place for the modified base color */
- GdkColor color[HILDON_TOTAL_COLOR_NUM + 1];
-};
-
-enum
-{
- PROP_NONE,
- PROP_COLOR
-};
-
-/*
- * Private function prototype definitions
- */
-static void
-hildon_color_selector_class_init (HildonColorSelectorClass * selector_class);
-
-static void
-hildon_color_selector_init (HildonColorSelector * selector);
-
-static gboolean
-hildon_color_selector_expose (GtkWidget * widget,
- GdkEventExpose * event,
- gpointer data);
-
-static gboolean key_pressed (GtkWidget * widget,
- GdkEventKey * event);
-
-static gboolean color_pressed (GtkWidget * widget,
- GdkEventButton * event,
- gpointer user_data);
-
-static void select_color_index (HildonColorSelector *selector,
- gint idx,
- gboolean motion);
-
-static void select_color (HildonColorSelector * selector,
- int event_x,
- int event_y,
- gboolean motion);
-
-static gboolean color_moved (GtkWidget * widget,
- GdkEventMotion * event,
- gpointer data);
-
-static void
-modify_button_clicked (GtkWidget * button,
- HildonColorSelector * selector);
-
-static void modify_focused(HildonColorSelector * colselector);
-
-static void
-hildon_color_selector_set_property(GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-static void
-hildon_color_selector_get_property(GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-
-GType
-hildon_color_selector_get_type(void)
-{
- static GType selector_type = 0;
-
- if (!selector_type)
- {
- static const GTypeInfo selector_info =
- {
- sizeof(HildonColorSelectorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_color_selector_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonColorSelector),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_color_selector_init,
- };
-
- selector_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonColorSelector",
- &selector_info, 0);
- }
- return selector_type;
-}
-
-static void
-hildon_color_selector_destroy(GtkObject *obj)
-{
- HildonColorSelectorPriv *priv = HILDON_COLOR_SELECTOR(obj)->priv;
-
- if (priv->client)
- {
- gconf_client_notify_remove(priv->client, priv->notify_id);
- g_object_unref(priv->client);
- priv->client = NULL;
- }
-
- GTK_OBJECT_CLASS(parent_class)->destroy(obj);
-}
-
-static void
-hildon_color_selector_class_init(HildonColorSelectorClass * selector_class)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(selector_class);
- GObjectClass *gobject_class = G_OBJECT_CLASS (selector_class);
-
- parent_class = g_type_class_peek_parent(selector_class);
-
- widget_class->key_press_event = key_pressed;
-
- g_type_class_add_private(selector_class,
- sizeof(HildonColorSelectorPriv));
-
- GTK_OBJECT_CLASS(selector_class)->destroy = hildon_color_selector_destroy;
-
- gobject_class->get_property = hildon_color_selector_get_property;
- gobject_class->set_property = hildon_color_selector_set_property;
-
- /**
- * HildonColorSelector:color:
- *
- * The selected color.
- */
- g_object_class_install_property (gobject_class, PROP_COLOR,
- g_param_spec_boxed ("color",
- "Current Color",
- "The selected color",
- GDK_TYPE_COLOR,
- G_PARAM_READWRITE));
-}
-
-
-/**
- * hildon_color_selector_new:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application
- *
- * Creates a new #HildonColorSelector dialog with 3x8 layout of
- * base colors and 'OK', 'More..' and 'Cancel' buttons.
- *
- * Returns: new #HildonColorSelector
- **/
-GtkWidget *hildon_color_selector_new(GtkWindow * parent)
-{
- GtkWidget *dialog = g_object_new(HILDON_TYPE_COLOR_SELECTOR, NULL);
-
- g_return_val_if_fail(dialog, NULL);
-
- if (parent)
- {
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
- }
-
- return dialog;
-}
-
-static void
-hildon_color_selector_set_custom_colors(
- HildonColorSelector *selector,
- GConfValue *value)
-{
- GSList *list;
- gint i;
-
- g_assert(HILDON_IS_COLOR_SELECTOR(selector));
-
- /* We have to be really careful. At least gconftool's
- stress test may generate unexpected value setups */
- if (value == NULL
- || value->type != GCONF_VALUE_LIST
- || gconf_value_get_list_type(value) != GCONF_VALUE_STRING)
- list = NULL;
- else
- list = gconf_value_get_list(value);
-
- /* Use list to fill in the selector's color property */
- for ( i = 0; i < HILDON_CUSTOM_COLOR_NUM; ++i)
- {
- const gchar *color_string = NULL;
-
- if (list) {
- color_string = gconf_value_get_string(list->data);
- list = list->next;
- } else {
- color_string = "#FFFFFF";
- }
-
-/* g_print("custom_color: %s\n", color_string); */
-
- selector->priv->color[i].pixel = 0;
- gdk_color_parse (color_string,
- &(selector->priv->color[HILDON_BASE_COLOR_NUM+i]));
- }
-}
-
-static void
-gconf_notify_func(GConfClient *client,
- guint cnxn_id,
- GConfEntry *entry,
- gpointer data)
-{
- hildon_color_selector_set_custom_colors(HILDON_COLOR_SELECTOR(data),
- gconf_entry_get_value(entry));
- gtk_widget_queue_draw(GTK_WIDGET(data));
-}
-
-static void
-hildon_color_selector_init(HildonColorSelector * selector)
-{
- guint i;
- GtkWidget *hbox;
- GConfValue *value;
-
- /* 16 standard Windows colors */
- const char base_colours[][HILDON_BASE_COLOR_NUM] = {
- "#000000", "#FFFFFF", "#FF0000", "#660000", "#0000FF", "#000066",
- "#FF33FF", "#660066", "#33CC33", "#006600", "#FFCC00", "#CC9900",
- "#999999", "#666666", "#00CCCC", "#006666"
- };
-
- selector->priv =
- G_TYPE_INSTANCE_GET_PRIVATE(selector,
- HILDON_TYPE_COLOR_SELECTOR,
- HildonColorSelectorPriv);
-
- /* ***********test GConf*********** */
- selector->priv->client = gconf_client_get_default ();
- gconf_client_set_error_handling (selector->priv->client,
- GCONF_CLIENT_HANDLE_UNRETURNED);
-
- /* Add our directory to the list of directories the GConfClient will
- watch. */
- gconf_client_add_dir (selector->priv->client, HILDON_COLOR_GCONF_PATH,
- GCONF_CLIENT_PRELOAD_NONE,
- NULL);
-
- /* Use the value directed by GConfValue to set the color */
- value = gconf_client_get(selector->priv->client,
- HILDON_COLOR_GCONF_KEYS, NULL);
-
- hildon_color_selector_set_custom_colors(selector, value);
-
- if (value) {
- gconf_value_free(value);
- }
-
- /* Listen to changes to our key. */
- selector->priv->notify_id = gconf_client_notify_add (selector->priv->client,
- HILDON_COLOR_GCONF_KEYS, gconf_notify_func, selector, NULL, NULL);
-
- /* ************************************ */
-
- selector->priv->selected_index = GREYIND;
- selector->priv->focused_index = GREYIND;
-
- /* init base colors for color boxes */
- for (i = 0; i < HILDON_BASE_COLOR_NUM; ++i)
- {
- selector->priv->color[i].pixel = 0;
- gdk_color_parse (base_colours[i], &(selector->priv->color[i]));
- }
-
- gtk_dialog_set_has_separator(GTK_DIALOG(selector), FALSE);
-
- /* create drawing area */
- hbox = gtk_hbox_new(TRUE, 0);
- selector->priv->drawing_area = gtk_drawing_area_new();
-
- /* receive focus from dialog buttons */
- GTK_WIDGET_SET_FLAGS (selector->priv->drawing_area, GTK_CAN_FOCUS);
-
- gtk_widget_add_events (selector->priv->drawing_area,
- GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
-
- /* Arrange size of the drawing area. */
- gtk_widget_set_size_request (selector->priv->drawing_area,
- (HILDON_COLOR_SELECTOR_COLS *
- HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH),
- (HILDON_COLOR_SELECTOR_ROWS *
- HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT));
-
- gtk_box_pack_start (GTK_BOX(GTK_DIALOG(selector)->vbox),
- hbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX(hbox), selector->priv->drawing_area,
- FALSE, FALSE, 0);
-
- /* Register callback functions for the drawing area */
- g_signal_connect (selector->priv->drawing_area, "expose_event",
- G_CALLBACK(hildon_color_selector_expose), selector);
- g_signal_connect (selector->priv->drawing_area, "button_press_event",
- G_CALLBACK(color_pressed), selector);
- g_signal_connect (selector->priv->drawing_area, "motion-notify-event",
- G_CALLBACK(color_moved), selector);
-
- gtk_dialog_add_button (GTK_DIALOG(selector),
- _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
-
- selector->priv->modify_button =
- gtk_button_new_with_label(_("ecdg_bd_colour_selector_modify"));
- gtk_widget_set_sensitive(selector->priv->modify_button, FALSE);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selector)->action_area),
- selector->priv->modify_button, FALSE, TRUE, 0);
-
- g_signal_connect(selector->priv->modify_button, "clicked",
- G_CALLBACK(modify_button_clicked), selector);
-
- gtk_dialog_add_button (GTK_DIALOG(selector),
- _("ecdg_bd_colour_selector_cancel"),
- GTK_RESPONSE_CANCEL);
-
- gtk_dialog_set_default_response (GTK_DIALOG(selector), GTK_RESPONSE_OK);
-
- gtk_window_set_title ( GTK_WINDOW(selector),
- _("ecdg_ti_colour_selector") );
- gtk_widget_show_all (GTK_DIALOG(selector)->vbox);
-}
-
-static gboolean
-hildon_color_selector_expose(GtkWidget * widget,
- GdkEventExpose * event,
- gpointer data)
-{
- HildonColorSelector *selector;
- GdkColor color;
- GdkGC *gc, *gc_focus;
- gint x, y, idx;
-
- g_return_val_if_fail (GTK_IS_WIDGET(widget), FALSE);
- g_return_val_if_fail (event, FALSE);
- g_return_val_if_fail (HILDON_IS_COLOR_SELECTOR(data), FALSE);
-
- if (!GTK_WIDGET_DRAWABLE(widget))
- return FALSE;
-
- selector = HILDON_COLOR_SELECTOR(data);
- gc = gdk_gc_new (widget->window);
-
- gc_focus = gdk_gc_new(widget->window);
- gdk_gc_set_line_attributes(gc_focus, FOCUS_BORDER_WIDTH,
- GDK_LINE_SOLID, GDK_CAP_BUTT,
- GDK_JOIN_MITER);
-
- /* draw the color boxes and a focus for one of them */
- for (y = 0, idx = 0; y < HILDON_COLOR_SELECTOR_ROWS; ++y)
- {
- for (x = 0; x < HILDON_COLOR_SELECTOR_COLS; ++x, ++idx)
- {
- gint xpos = x * HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH;
- gint ypos = y * HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT;
-
- /* frames on color box */
- gdk_draw_rectangle(widget->window, widget->style->black_gc, FALSE,
- xpos + HILDON_COLOR_SELECTOR_PADDING_WIDTH,
- ypos + HILDON_COLOR_SELECTOR_PADDING_WIDTH,
- HILDON_COLOR_SELECTOR_BOX_W +
- HILDON_COLOR_SELECTOR_PADDING_WIDTH,
- HILDON_COLOR_SELECTOR_BOX_H +
- HILDON_COLOR_SELECTOR_PADDING_WIDTH);
-
- /* color box */
- gdk_gc_set_rgb_fg_color(gc, &(selector->priv->color[idx]));
- gdk_draw_rectangle(widget->window, gc,
- TRUE, /* filled */
- xpos + HILDON_COLOR_SELECTOR_PADDING_WIDTH +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH,
- ypos + HILDON_COLOR_SELECTOR_PADDING_WIDTH +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH,
- HILDON_COLOR_SELECTOR_BOX_W,
- HILDON_COLOR_SELECTOR_BOX_H);
-
- /* focus around the selected and focused color box */
- if (idx == selector->priv->selected_index)
- {
- /* selected color box */
- if (!gtk_style_lookup_logical_color(widget->style,
- SELECTION_BORDER_COLOR_NAME, &color))
- {
- /* set default color if color looking up fails */
- color.red = color.green = color.blue = 0;
- }
-
- gdk_gc_set_rgb_fg_color(gc_focus, &color);
- gdk_draw_rectangle(widget->window, gc_focus, FALSE,
- xpos + 1-(FOCUS_BORDER_WIDTH % 2),
- ypos + 1-(FOCUS_BORDER_WIDTH % 2),
- HILDON_COLOR_SELECTOR_BOX_W +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
- (FOCUS_BORDER_WIDTH % 2),
- HILDON_COLOR_SELECTOR_BOX_H +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
- (FOCUS_BORDER_WIDTH % 2));
- }
- else if (idx == selector->priv->focused_index)
- {
- /* focused color box.
- There's only zero or one so allocate GC in here. */
- gdk_color_parse(FOCUS_BORDER_COLOR, &color);
-
- gdk_gc_set_rgb_fg_color(gc_focus, &color);
- gdk_draw_rectangle(widget->window, gc_focus, FALSE,
- xpos + 1-(FOCUS_BORDER_WIDTH % 2),
- ypos + 1-(FOCUS_BORDER_WIDTH % 2),
- HILDON_COLOR_SELECTOR_BOX_W +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
- (FOCUS_BORDER_WIDTH % 2),
- HILDON_COLOR_SELECTOR_BOX_H +
- HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
- (FOCUS_BORDER_WIDTH % 2));
- }
- }
- }
-
- g_object_unref(gc);
- g_object_unref(gc_focus);
- return TRUE;
-}
-
-/**
- * hildon_color_selector_get_color:
- * @selector: a #HildonColorSelector
- *
- * Returns: the currently selected #GdkColor. The returned pointer must
- * not be freed.
- */
-G_CONST_RETURN GdkColor *hildon_color_selector_get_color(HildonColorSelector * selector)
-{
- g_return_val_if_fail(HILDON_IS_COLOR_SELECTOR(selector), NULL);
- return &(selector->priv->color[selector->priv->selected_index]);
-}
-
-/**
- * hildon_color_selector_set_color:
- * @selector: #HildonColorSelector
- * @color: #Gdkcolor to set
- *
- * Selects the color specified. Does nothing if the color does not
- * exist among the standard colors.
- */
-void hildon_color_selector_set_color(HildonColorSelector * selector,
- GdkColor * color)
-{
- gint i;
-
- g_return_if_fail(HILDON_IS_COLOR_SELECTOR(selector));
- g_return_if_fail(color);
-
- /* Select the specified color */
- for (i = 0;
- i < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM);
- ++i)
- {
- if (selector->priv->color[i].red == color->red &&
- selector->priv->color[i].green == color->green &&
- selector->priv->color[i].blue == color->blue)
- {
- selector->priv->selected_index = i;
- selector->priv->focused_index = i;
-
- /* The modify button is active if the color index is bigger than
- * the number of base colours.
- */
- gtk_widget_set_sensitive(selector->priv->modify_button,
- selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
- gtk_widget_queue_draw(selector->priv->drawing_area);
- break;
- }
- }
-
- /* Notify the color selector that the color has changed */
- g_object_notify (G_OBJECT (selector), "color");
-}
-
-static gboolean
-color_pressed(GtkWidget * widget, GdkEventButton * event,
- gpointer user_data)
-{
- select_color(HILDON_COLOR_SELECTOR(user_data), event->x, event->y, FALSE);
- return TRUE;
-}
-
-/* Handle key press of right, left, up, down and return */
-static gboolean key_pressed(GtkWidget * widget,
- GdkEventKey * event)
-{
- HildonColorSelector *selector;
- gint index;
-
- g_assert(widget);
-
- selector = HILDON_COLOR_SELECTOR(widget);
- index = selector->priv->focused_index;
-
- /* if dialog buttons has the focus */
- if (GTK_WIDGET_HAS_FOCUS(selector->priv->drawing_area) == FALSE)
- return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
-
- /* Since wrapping is not allowed,
- * move only if the next index is a valid one.
- */
- switch (event->keyval) {
- case GDK_KP_Right:
- case GDK_Right:
- if (index == (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1)
- || index == (HILDON_CUSTOM_COLOR_NUM - 1)
- || index == (2*HILDON_CUSTOM_COLOR_NUM - 1))
- {
- return TRUE;
- }
- index++;
- break;
- case GDK_KP_Left:
- case GDK_Left:
- if (index == 0
- || index == (HILDON_CUSTOM_COLOR_NUM)
- || index == (2*HILDON_CUSTOM_COLOR_NUM))
- {
- return TRUE;
- }
- index--;
- break;
- case GDK_KP_Up:
- case GDK_Up:
- if (index > (HILDON_COLOR_SELECTOR_COLS - 1))
- {
- index -= HILDON_COLOR_SELECTOR_COLS;
- }
- else
- {
- return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
- }
- break;
- case GDK_KP_Down:
- case GDK_Down:
- if (index < (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM))
- {
- index += HILDON_COLOR_SELECTOR_COLS;
- }
- else
- {
- return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
- }
- break;
- case GDK_KP_Enter:
- case GDK_Return:
- if (index < HILDON_BASE_COLOR_NUM)
- select_color_index(selector, selector->priv->focused_index, FALSE);
- else
- modify_focused(selector);
- default:
- return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
- }
-
- if (index < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM))
- {
- selector->priv->focused_index = index;
- }
- else
- {
- selector->priv->focused_index =
- HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1;
- }
- /* The modify button is active if the color index is bigger than
- * the number of base colours.
- */
- gtk_widget_set_sensitive(selector->priv->modify_button,
- selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
-
- gtk_widget_queue_draw(selector->priv->drawing_area);
-
- return TRUE;
-}
-
-static void
-select_color_index(HildonColorSelector * selector, gint idx, gboolean motion)
-{
- /* If a custom colour is selected, open a popup to modify the colour */
- if (!motion &&
- selector->priv->focused_index >= HILDON_BASE_COLOR_NUM &&
- selector->priv->focused_index == idx)
- modify_focused(selector);
-
- selector->priv->focused_index = selector->priv->selected_index = idx;
- gtk_widget_set_sensitive(selector->priv->modify_button,
- selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
-
- gtk_widget_queue_draw(selector->priv->drawing_area);
-}
-
-static void
-select_color(HildonColorSelector * selector, gint event_x, gint event_y,
- gboolean motion)
-{
- gint x, y;
-
- g_assert(HILDON_IS_COLOR_SELECTOR(selector));
-
- /* Get the selection coordinates */
- x = event_x / HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH;
- y = event_y / HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT;
-
- /* Get the row and column numbers for the selected color */
- if (x > (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1))
- {
- x = HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1;
- }
- else if (x < 0)
- {
- x = 0;
- }
- if (y > (HILDON_COLOR_SELECTOR_ROWS - 1))
- {
- y = HILDON_COLOR_SELECTOR_ROWS - 1;
- }
- else if (y < 0)
- {
- y = 0;
- }
-
- select_color_index(selector, (x + y * HILDON_COLOR_SELECTOR_COLS), motion);
-}
-
-static gboolean
-color_moved(GtkWidget * widget, GdkEventMotion * event, gpointer data)
-{
- if ( event->state &
- (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK) )
- {
- select_color(HILDON_COLOR_SELECTOR(data), event->x, event->y, TRUE);
- return TRUE;
- }
- return FALSE;
-}
-
-static void
-modify_button_clicked(GtkWidget * button, HildonColorSelector * selector)
-{
- modify_focused (selector);
-}
-
-static void
-modify_focused(HildonColorSelector * colselector)
-{
- HildonColorPopup popupdata;
- GtkWidget *popup;
-
- /* Create a HildonColorPopup dialog */
- popup = hildon_color_popup_new(GTK_WINDOW(colselector),
- hildon_color_selector_get_color(colselector), &popupdata);
-
- if ( gtk_dialog_run(GTK_DIALOG(popup) ) == GTK_RESPONSE_OK)
- {
- GdkColor *color;
-
- /* We cannot modify a base color */
- if (colselector->priv->focused_index < HILDON_BASE_COLOR_NUM)
- {
- colselector->priv->color[HILDON_TOTAL_COLOR_NUM] =
- colselector->priv->color[colselector->priv->focused_index];
- colselector->priv->focused_index = HILDON_TOTAL_COLOR_NUM;
- }
-
- /* Update the focused color with the color selected in color popup */
- color = &(colselector->priv->color[colselector->priv->focused_index]);
- hildon_color_popup_set_color_from_sliders(color, &popupdata);
-
- /* If we modified a base color we just accept the dialog */
- if( colselector->priv->focused_index >= HILDON_TOTAL_COLOR_NUM)
- {
- gtk_dialog_response(GTK_DIALOG(colselector), GTK_RESPONSE_OK);
- }
- else /* If we mofied custom colors we have to save to gconf */
- {
- GConfValue *value;
- GSList * list;
- gint i;
-
- value = gconf_value_new(GCONF_VALUE_LIST);
- gconf_value_set_list_type(value, GCONF_VALUE_STRING);
- list = NULL;
-
- for ( i = HILDON_BASE_COLOR_NUM; i < HILDON_TOTAL_COLOR_NUM; i++)
- {
- GConfValue *item;
- char buffer[32];
-
- g_snprintf(buffer, sizeof(buffer), "#%.2X%.2X%.2X",
- (colselector->priv->color[i].red>>8)&0xFF,
- (colselector->priv->color[i].green>>8)&0xFF,
- (colselector->priv->color[i].blue>>8)&0xFF );
-
- item = gconf_value_new(GCONF_VALUE_STRING);
- gconf_value_set_string(item, buffer);
- list = g_slist_append (list, item);
- }
-
- gconf_value_set_list_nocopy(value, list);
-
- /* gconf client handles the possible error */
- gconf_client_set(colselector->priv->client,
- HILDON_COLOR_GCONF_KEYS, value, NULL);
-
- gconf_value_free(value);
- }
- }
-
- gtk_widget_destroy (popup);
- gtk_window_present (GTK_WINDOW(colselector));
-}
-
-static void
-hildon_color_selector_set_property(GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- HildonColorSelector *selector = HILDON_COLOR_SELECTOR(object);
-
- switch (param_id)
- {
- case PROP_COLOR:
- hildon_color_selector_set_color(selector, (GdkColor*)g_value_get_boxed(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void
-hildon_color_selector_get_property(GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec)
-{
- HildonColorSelector *selector = HILDON_COLOR_SELECTOR(object);
-
- switch (param_id)
- {
- case PROP_COLOR:
- g_value_set_boxed(value, (gconstpointer)hildon_color_selector_get_color(selector));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_COLOR_SELECTOR_H__
-#define __HILDON_COLOR_SELECTOR_H__
-
-#include <gtk/gtkcontainer.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_COLOR_SELECTOR \
- ( hildon_color_selector_get_type() )
-#define HILDON_COLOR_SELECTOR(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_COLOR_SELECTOR, HildonColorSelector))
-#define HILDON_COLOR_SELECTOR_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_SELECTOR,\
- HildonColorSelectorClass))
-#define HILDON_IS_COLOR_SELECTOR(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_COLOR_SELECTOR))
-#define HILDON_IS_COLOR_SELECTOR_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_COLOR_SELECTOR_CLASS))
- GType hildon_color_selector_get_type(void);
-
-typedef struct _HildonColorSelector HildonColorSelector;
-typedef struct _HildonColorSelectorClass HildonColorSelectorClass;
-
-/**
- * HildonColorSelectorPriv:
- *
- * Internal struct for color selector.
- */
-typedef struct _HildonColorSelectorPriv HildonColorSelectorPriv;
-
-struct _HildonColorSelector {
- GtkDialog parent;
- HildonColorSelectorPriv *priv;
-};
-
-struct _HildonColorSelectorClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_color_selector_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_color_selector_new(GtkWindow * parent);
-G_CONST_RETURN GdkColor *hildon_color_selector_get_color(HildonColorSelector * selector);
-void hildon_color_selector_set_color(HildonColorSelector * selector,
- GdkColor * color);
-
-G_END_DECLS
-#endif /* __HILDON_COLOR_SELECTOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkwindow.h>
-#include "hildon-composite-widget.h"
-#include "hildon-date-editor.h"
-#include "hildon-time-editor.h"
-
-/* This function is a private function of hildon-libs. It hadles focus
- * changing for composite hildon widgets: HildonDateEditor,
- * HildonNumberEditor, HildonTimeEditor, HildonWeekdayPicker.
- * Its purpose is to focus the first widget (from left) inside the container
- * regardless of where the focus is coming from.
- */
-gboolean
-hildon_composite_widget_focus (GtkWidget *widget, GtkDirectionType direction)
-{
- GtkWidget *toplevel = NULL;
- GtkWidget *focus_widget = NULL;
-
- /* Get the topmost parent widget */
- toplevel = gtk_widget_get_toplevel (widget);
- if (!GTK_IS_WINDOW(toplevel))
- return GTK_WIDGET_CLASS (g_type_class_peek_parent (
- GTK_WIDGET_GET_CLASS (widget)))->focus (widget, direction);
- /* Get focus widget in the topmost parent widget */
- focus_widget = GTK_WINDOW (toplevel)->focus_widget;
-
- if (!GTK_IS_WIDGET (focus_widget))
- return TRUE;
-
- if (!gtk_widget_is_ancestor (focus_widget, widget))
- {
- gtk_widget_grab_focus (widget);
- }
- else
- {
- /* Containers grab_focus grabs the focus to the correct widget */
- switch (direction) {
- case GTK_DIR_UP:
- case GTK_DIR_DOWN:
- if (HILDON_IS_DATE_EDITOR(widget) || HILDON_IS_TIME_EDITOR(widget))
- return FALSE;
- else
- return GTK_WIDGET_CLASS (g_type_class_peek_parent
- (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
- break;
-
- default:
- return GTK_WIDGET_CLASS (g_type_class_peek_parent
- (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
- break;
- }
- }
-
- return TRUE;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file
- *
- * Hildon composite widget includes all features which were not fitting into
- * the any current class. A new, separate widget was not created because of the
- * amount of current features is low. Need for this kind of class was not known
- * when the building of the class hierarchy began. When a new feature is added,
- * need for a new class should be re-considered. To make this decision one
- * should really consider all the common features which are needed in the
- * hildon composite widgets. Class position (for hildon-composite-widget)
- * in the class hierarchy is between GtkContainer and any composite widget.
- *
- */
-
-#ifndef __HILDON_COMPOSITE_WIDGET__
-#define __HILDON_COMPOSITE_WIDGET__
-
-
-G_BEGIN_DECLS
-
-
-gboolean
-hildon_composite_widget_focus( GtkWidget *widget, GtkDirectionType direction );
-
-
-G_END_DECLS
-
-
-#endif /*__HILDON_COMPOSITE_WIDGET__*/
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-controlbar
- * @short_description: A widget that allows increasing or decreasing
- * a value within a pre-defined range
- *
- * #HildonControlbar is a horizontally positioned range widget that is
- * visually divided into blocks and supports setting a minimum and
- * maximum value for the range.
- */
-
-
-#include <math.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include "hildon-controlbar.h"
-
-#include <libintl.h>
-#define _(string) dgettext(PACKAGE, string)
-
-#define HILDON_CONTROLBAR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
- HILDON_TYPE_CONTROLBAR, HildonControlbarPrivate));
-
-#define DEFAULT_WIDTH 234
-#define DEFAULT_HEIGHT 30
-#define DEFAULT_BORDER_WIDTH 2
-
-#define HILDON_CONTROLBAR_STEP_INCREMENT 1
-#define HILDON_CONTROLBAR_PAGE_INCREMENT 1
-#define HILDON_CONTROLBAR_PAGE_SIZE 0
-#define HILDON_CONTROLBAR_UPPER_VALUE 10
-#define HILDON_CONTROLBAR_LOWER_VALUE 0.0
-#define HILDON_CONTROLBAR_INITIAL_VALUE 0
-
-static GtkScaleClass *parent_class;
-
-typedef struct _HildonControlbarPrivate HildonControlbarPrivate;
-
-enum
-{
- PROP_MIN = 1,
- PROP_MAX,
- PROP_VALUE
-};
-
-enum
-{
- END_REACHED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-static void
-hildon_controlbar_class_init(HildonControlbarClass * controlbar_class);
-static void hildon_controlbar_init(HildonControlbar * controlbar);
-static GObject *
-hildon_controlbar_constructor(GType type, guint n_construct_properties,
- GObjectConstructParam *construct_properties);
-
-static gint hildon_controlbar_button_press_event(GtkWidget * widget,
- GdkEventButton * event);
-static gint hildon_controlbar_button_release_event(GtkWidget * widget,
- GdkEventButton * event);
-static gint
-hildon_controlbar_expose_event(GtkWidget * widget, GdkEventExpose * event);
-static void
-hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req);
-static void
-hildon_controlbar_paint(HildonControlbar * self, GdkRectangle * area);
-static gboolean
-hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event);
-
-static void hildon_controlbar_set_property( GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec );
-static void hildon_controlbar_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec );
-
-static void
-hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range );
-
-/*
- * Purpose of this function is to prevent Up and Down keys from
- * changing the widget's value (like Left and Right). Instead they
- * are used for changing focus to other widgtes.
- */
-static gboolean
-hildon_controlbar_change_value( GtkRange *range, GtkScrollType scroll,
- gdouble new_value, gpointer data );
-
-GType hildon_controlbar_get_type(void)
-{
- static GType controlbar_type = 0;
-
- if (!controlbar_type) {
- static const GTypeInfo controlbar_info = {
- sizeof(HildonControlbarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_controlbar_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonControlbar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_controlbar_init,
- };
- controlbar_type = g_type_register_static(GTK_TYPE_SCALE,
- "HildonControlbar",
- &controlbar_info, 0);
- }
- return controlbar_type;
-}
-
-struct _HildonControlbarPrivate {
- gboolean button_press;
- gint old_value;
-};
-
-static void
-hildon_controlbar_class_init(HildonControlbarClass * controlbar_class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(controlbar_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(controlbar_class);
-
- parent_class = g_type_class_peek_parent(controlbar_class);
-
- g_type_class_add_private(controlbar_class,
- sizeof(HildonControlbarPrivate));
-
- gobject_class->get_property = hildon_controlbar_get_property;
- gobject_class->set_property = hildon_controlbar_set_property;
- widget_class->size_request = hildon_controlbar_size_request;
- widget_class->button_press_event = hildon_controlbar_button_press_event;
- widget_class->button_release_event = hildon_controlbar_button_release_event;
- widget_class->expose_event = hildon_controlbar_expose_event;
- widget_class->key_press_event = hildon_controlbar_keypress;
- G_OBJECT_CLASS(controlbar_class)->constructor = hildon_controlbar_constructor;
- controlbar_class->end_reached = NULL;
-
- /**
- * HildonControlbar:min:
- *
- * Controlbar minimum value.
- */
- g_object_class_install_property( gobject_class, PROP_MIN,
- g_param_spec_int("min",
- "Minimum value",
- "Smallest possible value",
- G_MININT, G_MAXINT,
- HILDON_CONTROLBAR_LOWER_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonControlbar:max:
- *
- * Controlbar maximum value.
- */
- g_object_class_install_property( gobject_class, PROP_MAX,
- g_param_spec_int("max",
- "Maximum value",
- "Greatest possible value",
- G_MININT, G_MAXINT,
- HILDON_CONTROLBAR_UPPER_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonControlbar:value:
- *
- * Controlbar value.
- */
- g_object_class_install_property( gobject_class, PROP_VALUE,
- g_param_spec_int("value",
- "Current value",
- "Current value",
- G_MININT, G_MAXINT,
- HILDON_CONTROLBAR_INITIAL_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("inner_border_width",
- "Inner border width",
- "The border spacing between the controlbar border and controlbar blocks.",
- 0, G_MAXINT,
- DEFAULT_BORDER_WIDTH,
- G_PARAM_READABLE));
-
- signals[END_REACHED] =
- g_signal_new("end-reached",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET(HildonControlbarClass, end_reached),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
- G_TYPE_BOOLEAN);
-}
-
-static void hildon_controlbar_init(HildonControlbar * controlbar)
-{
- GtkRange *range;
- HildonControlbarPrivate *priv;
-
- /* Initialize the private property */
- priv = HILDON_CONTROLBAR_GET_PRIVATE(controlbar);
- priv->button_press = FALSE;
- priv->old_value = 0;
- range = GTK_RANGE(controlbar);
-
- range->has_stepper_a = TRUE;
- range->has_stepper_d = TRUE;
- range->round_digits = -1;
-
- gtk_widget_set_size_request( GTK_WIDGET(controlbar), DEFAULT_WIDTH,
- DEFAULT_HEIGHT );
- g_signal_connect( range, "change-value",
- G_CALLBACK(hildon_controlbar_change_value), NULL );
-}
-
-static GObject *hildon_controlbar_constructor(GType type,
- guint n_construct_properties, GObjectConstructParam *construct_properties)
-{
- GObject *obj;
- GtkAdjustment *adj;
-
- obj = G_OBJECT_CLASS(parent_class)->constructor(type,
- n_construct_properties, construct_properties);
-
- gtk_scale_set_draw_value (GTK_SCALE (obj), FALSE);
-
- /* Initialize the GtkAdjustment of the controlbar*/
- adj = GTK_RANGE(obj)->adjustment;
- adj->step_increment = HILDON_CONTROLBAR_STEP_INCREMENT;
- adj->page_increment = HILDON_CONTROLBAR_PAGE_INCREMENT;
- adj->page_size = HILDON_CONTROLBAR_PAGE_SIZE;
-
- g_signal_connect( adj, "value-changed",
- G_CALLBACK(hildon_controlbar_value_changed), obj );
- return obj;
-}
-
-static void hildon_controlbar_set_property (GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- HildonControlbar *controlbar = HILDON_CONTROLBAR(object);
- switch (param_id)
- {
- case PROP_MIN:
- hildon_controlbar_set_min (controlbar, g_value_get_int(value));
- break;
-
- case PROP_MAX:
- hildon_controlbar_set_max (controlbar, g_value_get_int(value));
- break;
-
- case PROP_VALUE:
- hildon_controlbar_set_value (controlbar, g_value_get_int(value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_controlbar_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec )
-{
- HildonControlbar *controlbar = HILDON_CONTROLBAR(object);
- switch (param_id)
- {
- case PROP_MIN:
- g_value_set_int (value, hildon_controlbar_get_min (controlbar));
- break;
-
- case PROP_MAX:
- g_value_set_int (value, hildon_controlbar_get_max (controlbar));
- break;
-
- case PROP_VALUE:
- g_value_set_int (value, hildon_controlbar_get_value (controlbar));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-
-static void
-hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range )
-{
- HildonControlbarPrivate *priv = HILDON_CONTROLBAR_GET_PRIVATE(range);
-
- /* Change the controlbar value if the adjusted value is large enough
- * otherwise, keep the old value
- */
- if( ABS(ceil(adj->value) - priv->old_value) >= 1 )
- {
- priv->old_value = ceil(adj->value);
- adj->value = priv->old_value;
- }
- else
- g_signal_stop_emission_by_name( adj, "value-changed" );
- gtk_adjustment_set_value( adj, priv->old_value );
-}
-
-/**
- * hildon_controlbar_new:
- *
- * Creates a new #HildonControlbar widget.
- *
- * Returns: a #GtkWidget pointer of newly created control bar
- * widget
- */
-GtkWidget *hildon_controlbar_new(void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_CONTROLBAR, NULL));
-}
-
-/* This function prevents Up and Down keys from changing the
- * widget's value (like Left and Right).
- * Instead they are used for changing focus to other widgtes.
- */
-static gboolean
-hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event)
-{
- if (event->keyval == GDK_Up || event->keyval == GDK_Down)
- return FALSE;
- return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget, event));
-}
-
-static void
-hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req)
-{
- if (GTK_WIDGET_CLASS(parent_class)->size_request)
- GTK_WIDGET_CLASS(parent_class)->size_request(self, req);
-
- req->width = DEFAULT_WIDTH;
- req->height = DEFAULT_HEIGHT;
-}
-
-/**
- * hildon_controlbar_set_value:
- * @self: pointer to #HildonControlbar
- * @value: value in range of >= 0 && < G_MAX_INT
- *
- * Change the current value of the control bar to the specified value.
- */
-void hildon_controlbar_set_value(HildonControlbar * self, gint value)
-{
- GtkAdjustment *adj;
- g_return_if_fail (HILDON_IS_CONTROLBAR (self));
- adj = GTK_RANGE(self)->adjustment;
-
- g_return_if_fail(value >= 0);
-
- if (value >= adj->upper)
- value = adj->upper;
- else if (value <= adj->lower)
- value = adj->lower;
-
- adj->value = value;
- gtk_adjustment_value_changed(adj);
-
- g_object_notify (G_OBJECT(self), "value");
-}
-
-/**
- * hildon_controlbar_get_value:
- * @self: pointer to #HildonControlbar
- *
- * Returns: current value as gint
- */
-gint hildon_controlbar_get_value(HildonControlbar * self)
-{
- GtkAdjustment *adj;
- g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0);
- adj = GTK_RANGE(self)->adjustment;
-
- return (gint) ceil(adj->value);
-}
-
-/**
- * hildon_controlbar_set_max:
- * @self: pointer to #HildonControlbar
- * @max: maximum value to set. The value needs to be greater than 0.
- *
- * Set the control bar's maximum to the given value.
- *
- * If the new maximum is smaller than current value, the value will be
- * adjusted so that it equals the new maximum.
- */
-void hildon_controlbar_set_max(HildonControlbar * self, gint max)
-{
- GtkAdjustment *adj;
- g_return_if_fail (HILDON_IS_CONTROLBAR (self));
- adj = GTK_RANGE(self)->adjustment;
-
- if (max < adj->lower)
- max = adj->lower;
-
- if (adj->value > max)
- hildon_controlbar_set_value (self, max);
-
- adj->upper = max;
- gtk_adjustment_changed(adj);
-
- g_object_notify (G_OBJECT(self), "max");
-}
-
-/**
- * hildon_controlbar_set_min:
- * @self: pointer to #HildonControlbar
- * @min: minimum value to set. The value needs to be greater than or
- * equal to 0.
- *
- * Set the control bar's minimum to the given value.
- *
- * If the new minimum is smaller than current value, the value will be
- * adjusted so that it equals the new minimum.
- */
-void hildon_controlbar_set_min(HildonControlbar * self, gint min)
-{
- GtkAdjustment *adj;
- g_return_if_fail (HILDON_IS_CONTROLBAR (self));
- adj = GTK_RANGE(self)->adjustment;
-
- if (min > adj->upper)
- min = adj->upper;
-
- if (adj->value < min)
- hildon_controlbar_set_value (self, min);
-
- adj->lower = min;
- gtk_adjustment_changed(adj);
- g_object_notify (G_OBJECT(self), "min");
-}
-
-/**
- * hildon_controlbar_set_range:
- * @self: pointer to #HildonControlbar
- * @max: maximum value to set. The value needs to be greater than 0.
- * @min: Minimum value to set. The value needs to be greater than or
- * equal to 0.
- *
- * Set the controlbars range to the given value
- *
- * If the new maximum is smaller than current value, the value will be
- * adjusted so that it equals the new maximum.
- *
- * If the new minimum is smaller than current value, the value will be
- * adjusted so that it equals the new minimum.
- */
-void hildon_controlbar_set_range(HildonControlbar * self, gint min,
- gint max)
-{
- g_return_if_fail (HILDON_IS_CONTROLBAR (self));
-
- if (min > max)
- min = max;
- /* We need to set max first here, because when min is set before
- * max is set, it would end up 0, because max can't be bigger than 0.
- */
- hildon_controlbar_set_max (self, max);
- hildon_controlbar_set_min (self, min);
-}
-
-/**
- * hildon_controlbar_get_max:
- * @self: a pointer to #HildonControlbar
- *
- * Returns: maximum value of control bar
- */
-gint hildon_controlbar_get_max(HildonControlbar * self)
-{
- GtkAdjustment *adj;
- g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0);
- adj = GTK_RANGE(self)->adjustment;
-
- return (gint) adj->upper;
-}
-
-/**
- * hildon_controlbar_get_min:
- * @self: a pointer to #HildonControlbar
- *
- * Returns: minimum value of controlbar
- */
-gint hildon_controlbar_get_min(HildonControlbar * self)
-{
- GtkAdjustment *adj = GTK_RANGE(self)->adjustment;
- return (gint) adj->lower;
-}
-
-/*
- * Event handler for button press
- * Need to change button1 to button2 before passing this event to
- * parent handler. (see specs)
- * Also updates button_press variable so that we can draw hilites
- * correctly
- */
-static gint hildon_controlbar_button_press_event(GtkWidget * widget,
- GdkEventButton * event)
-{
- HildonControlbar *self;
- HildonControlbarPrivate *priv;
- gboolean result = FALSE;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(event, FALSE);
-
- self = HILDON_CONTROLBAR(widget);
- priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
-
- priv->button_press = TRUE;
- event->button = event->button == 1 ? 2 : event->button;
-
- /* Ugh dirty hack. We manipulate the mouse event location to
- compensate for centering the widget in case it is taller than the
- default height. */
- if (widget->allocation.height > DEFAULT_HEIGHT) {
- gint difference = widget->allocation.height - DEFAULT_HEIGHT;
-
- if (difference & 1)
- difference += 1;
- difference = difference / 2;
-
- event->y -= difference;
- }
-
-
- /* call the parent handler */
- if (GTK_WIDGET_CLASS(parent_class)->button_press_event)
- result =
- GTK_WIDGET_CLASS(parent_class)->button_press_event(widget, event);
-
- return result;
-}
-
-/*
- * Purpose of this function is to prevent Up and Down keys from
- * changing the widget's value (like Left and Right). Instead they
- * are used for changing focus to other widgtes.
- */
-static gboolean
-hildon_controlbar_change_value( GtkRange *range,
- GtkScrollType scroll,
- gdouble new_value,
- gpointer data )
-{
- HildonControlbarPrivate *priv;
- GtkAdjustment *adj = range->adjustment;
-
- priv = HILDON_CONTROLBAR_GET_PRIVATE(range);
-
- /* Emit a signal when upper or lower limit is reached */
- switch (scroll)
- {
- case GTK_SCROLL_STEP_FORWARD :
- case GTK_SCROLL_PAGE_FORWARD :
- if( adj->value == priv->old_value )
- if( adj->value == adj->upper )
- g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, TRUE );
- break;
-
- case GTK_SCROLL_STEP_BACKWARD :
- case GTK_SCROLL_PAGE_BACKWARD :
- if( adj->value == priv->old_value )
- if( adj->value == adj->lower )
- g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, FALSE );
- break;
-
- default:
- break;
- }
-return FALSE;
-}
-
-/*
- * Event handler for button release
- * Need to change button1 to button2 before passing this event to
- * parent handler. (see specs)
- * Also updates button_press variable so that we can draw hilites
- * correctly
- */
-static gint hildon_controlbar_button_release_event(GtkWidget * widget,
- GdkEventButton * event)
-{
- HildonControlbar *self;
- HildonControlbarPrivate *priv;
- gboolean result = FALSE;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(event, FALSE);
-
- self = HILDON_CONTROLBAR(widget);
- priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
-
- priv->button_press = FALSE;
- event->button = event->button == 1 ? 2 : event->button;
-
- /* call the parent handler */
- if (GTK_WIDGET_CLASS(parent_class)->button_release_event)
- result =
- GTK_WIDGET_CLASS(parent_class)->button_release_event(widget, event);
- return result;
-}
-
-/*
- * Event handler for expose event
- */
-static gint hildon_controlbar_expose_event(GtkWidget * widget,
- GdkEventExpose * event)
-{
- HildonControlbar *self = NULL;
-
- gboolean result = FALSE;
- gint old_height = -1;
- gint old_y = -1;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(event, FALSE);
- g_return_val_if_fail(HILDON_IS_CONTROLBAR(widget), FALSE);
-
- self = HILDON_CONTROLBAR(widget);
-
- old_height = widget->allocation.height;
- old_y = widget->allocation.y;
-
- if (widget->allocation.height > DEFAULT_HEIGHT) {
- int difference = widget->allocation.height - DEFAULT_HEIGHT;
-
- if (difference & 1)
- difference += 1;
- difference = difference / 2;
-
- widget->allocation.y += difference;
- widget->allocation.height = DEFAULT_HEIGHT;
- }
-
- /* call the parent handler */
- if (GTK_WIDGET_CLASS(parent_class)->expose_event)
- result = GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
- hildon_controlbar_paint(self, &event->area);
-
- widget->allocation.height = old_height;
- widget->allocation.y = old_y;
-
- return TRUE;
-}
-
-/*
- * Paint method.
- * This is where all the work is actually done...
- */
-static void hildon_controlbar_paint(HildonControlbar * self,
- GdkRectangle * area)
-{
- HildonControlbarPrivate *priv;
- GtkWidget *widget = GTK_WIDGET(self);
- GtkAdjustment *ctrlbar = GTK_RANGE(self)->adjustment;
- gint x = widget->allocation.x;
- gint y = widget->allocation.y;
- gint h = widget->allocation.height;
- gint w = widget->allocation.width;
- gint max = 0;
- gint stepper_size = 0;
- gint stepper_spacing = 0;
- gint inner_border_width = 0;
- gint block_area = 0, block_width = 0, block_x = 0, block_max = 0, block_height,block_y;
- /* Number of blocks on the controlbar */
- guint block_count = 0;
- /* Number of displayed active blocks */
- guint block_act = 0;
- /* Minimum no. of blocks visible */
- guint block_min = 0;
- gint separatingpixels = 2;
- gint block_remains = 0;
- gint i, start_x, end_x, current_width;
- GtkStateType state = GTK_STATE_NORMAL;
-
- g_return_if_fail(area);
-
- priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
- if (GTK_WIDGET_SENSITIVE(self) == FALSE)
- state = GTK_STATE_INSENSITIVE;
-
- gtk_widget_style_get(GTK_WIDGET(self),
- "stepper-size", &stepper_size,
- "stepper-spacing", &stepper_spacing,
- "inner_border_width", &inner_border_width, NULL);
- g_object_get(G_OBJECT(self), "minimum_visible_bars", &block_min, NULL);
-
- block_area = (w - 2 * stepper_size - 2 * stepper_spacing - 2 * inner_border_width);
- if (block_area <= 0)
- return;
-
- block_max = ctrlbar->upper - ctrlbar->lower + block_min;
- block_act = priv->old_value - GTK_RANGE(self)->adjustment->lower + block_min;
-
- /* We check border width and maximum value and adjust
- * separating pixels for block width here. If the block size would
- * become too small, we make the separators smaller. Graceful fallback.
- */
- max = ctrlbar->upper;
- if( ctrlbar->upper == 0 )
- {
- separatingpixels = 3;
- }
- else if ((block_area - ((max - 1) * 3)) / max >= 4) {
- separatingpixels = 3;
- } else if ((block_area - ((max - 1) * 2)) / max >= 4) {
- separatingpixels = 2;
- } else if ((block_area - ((max - 1) * 1)) / max >= 4) {
- separatingpixels = 1;
- } else
- separatingpixels = 0;
-
- if( block_max == 0 )
- {
- /* If block max is 0 then we dim the whole control. */
- state = GTK_STATE_INSENSITIVE;
- block_width = block_area;
- block_remains = 0;
- block_max = 1;
- }
- else
- {
- block_width =
- (block_area - (separatingpixels * (block_max - 1))) / block_max;
- block_remains =
- (block_area - (separatingpixels * (block_max - 1))) % block_max;
- }
-
- block_x = x + stepper_size + stepper_spacing + inner_border_width;
- block_y = y + inner_border_width;
- block_height = h - 2 * inner_border_width;
-
- block_count = ctrlbar->value - ctrlbar->lower + block_min;
-
- /* Without this there is vertical block corruption when block_height =
- 1. This should work from 0 up to whatever */
-
- if (block_height < 2)
- block_height = 2;
-
- /*
- * Changed the drawing of the blocks completely,
- * because of "do-not-resize-when-changing-max"-specs.
- * Now the code calculates from the block_remains when
- * it should add one pixel to the block and when not.
- */
-
- for (i = 1; i <= block_max; i++) {
-
- /* Here we calculate whether we add one pixel to current_width or
- not. */
- start_x = block_width * (i - 1) + ((i - 1) * block_remains) / block_max;
- end_x = block_width * i + (i * block_remains) / block_max;
- current_width = end_x - start_x;
-
- gtk_paint_box(widget->style, widget->window, state,
- (i <= block_count) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
- NULL, widget, "hildon_block",
- block_x, block_y, current_width,
- block_height);
-
- /* We keep the block_x separate because of the
- 'separatingpixels' */
- block_x += current_width + separatingpixels;
- }
-
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_CONTROLBAR_H__
-#define __HILDON_CONTROLBAR_H__
-
-#include <gtk/gtkscale.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_CONTROLBAR ( hildon_controlbar_get_type() )
-#define HILDON_CONTROLBAR(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_CONTROLBAR, HildonControlbar))
-#define HILDON_CONTROLBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_CONTROLBAR, HildonControlbarClass))
-#define HILDON_IS_CONTROLBAR(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_CONTROLBAR))
-#define HILDON_IS_CONTROLBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_CONTROLBAR))
-
-/**
- * HildonControlbar:
- *
- * Contains gboolean variable named 'button_press' whether a button
- * has been pressed.
- */
-typedef struct _HildonControlbar HildonControlbar;
-typedef struct _HildonControlbarClass HildonControlbarClass;
-
-struct _HildonControlbar {
- GtkScale scale;
-};
-
-struct _HildonControlbarClass {
- GtkScaleClass parent_class;
- void (*end_reached) (HildonControlbar *controlbar, gboolean end);
-};
-
-GType hildon_controlbar_get_type(void);
-GtkWidget *hildon_controlbar_new(void);
-void hildon_controlbar_set_value(HildonControlbar * self, gint value);
-gint hildon_controlbar_get_value(HildonControlbar * self);
-gint hildon_controlbar_get_max(HildonControlbar * self);
-gint hildon_controlbar_get_min(HildonControlbar * self);
-void hildon_controlbar_set_max(HildonControlbar * self, gint max);
-void hildon_controlbar_set_min(HildonControlbar * self, gint min);
-void hildon_controlbar_set_range(HildonControlbar * self, gint min,
- gint max);
-
-G_END_DECLS
-#endif /* __HILDON_CONTROLBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-date-editor
- * @short_description: A widget which queries a date from user or opens
- * a HildonCalendarPopup
- * @see_also: #HildonCalendarPopup, #HildonTimeEditor
- *
- * HildonDateEditor is a widget with three entry fields (day, month,
- * year) and an icon (button): clicking on the icon opens up a
- * HildonCalendarPopup.
- */
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <hildon-widgets/hildon-date-editor.h>
-#include <hildon-widgets/hildon-calendar-popup.h>
-#include <hildon-widgets/gtk-infoprint.h>
-#include <hildon-widgets/hildon-defines.h>
-#include <hildon-widgets/hildon-input-mode-hint.h>
-#include "hildon-composite-widget.h"
-#include "hildon-marshalers.h"
-#include "hildon-libs-enum-types.h"
-
-#ifdef HAVE_CONFIG_H
-#include<config.h>
-#endif
-
-#include<libintl.h>
-#define _(string) dgettext(PACKAGE, string)
-
-#define ENTRY_BORDERS 11
-#define DATE_EDITOR_HEIGHT 30
-
-#define DAY_ENTRY_WIDTH 2
-#define MONTH_ENTRY_WIDTH 2
-#define YEAR_ENTRY_WIDTH 4
-
-#define DEFAULT_MIN_YEAR 1970
-#define DEFAULT_MAX_YEAR 2037
-
-#define HILDON_DATE_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE((obj),\
- HILDON_TYPE_DATE_EDITOR, HildonDateEditorPrivate));
-
-static GtkContainerClass *parent_class;
-
-typedef struct _HildonDateEditorPrivate HildonDateEditorPrivate;
-
-static void
-hildon_date_editor_class_init(HildonDateEditorClass * editor_class);
-
-static void hildon_date_editor_init(HildonDateEditor * editor);
-
-static gboolean
-hildon_date_editor_icon_press(GtkWidget * widget,
- gpointer data);
-
-static gboolean
-hildon_date_editor_released(GtkWidget * widget,
- gpointer data);
-
-static gboolean
-hildon_date_editor_keypress(GtkWidget * widget, GdkEventKey * event,
- gpointer data);
-
-static gboolean
-hildon_date_editor_keyrelease(GtkWidget * widget, GdkEventKey * event,
- gpointer data);
-static gboolean
-hildon_date_editor_clicked(GtkWidget * widget, gpointer data);
-static gint
-hildon_date_editor_entry_validate(GtkWidget *widget, gpointer data);
-
-static void
-hildon_date_editor_entry_changed(GtkEditable *widget, gpointer data);
-
-static gboolean
-hildon_date_editor_entry_focus_out(GtkWidget * widget, GdkEventFocus * event,
- gpointer data);
-
-static gboolean hildon_date_editor_date_error(HildonDateEditor *editor,
- HildonDateEditorErrorType type);
-
-static gboolean hildon_date_editor_entry_focusin(GtkWidget * widget,
- GdkEventFocus * event,
- gpointer data);
-static void hildon_date_editor_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec );
-static void hildon_date_editor_set_property (GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec);
-static void
-hildon_child_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback, gpointer callback_data);
-
-static void hildon_date_editor_destroy(GtkObject * self);
-
-static void
-hildon_date_editor_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-
-static void
-hildon_date_editor_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-
-static gboolean
-_hildon_date_editor_entry_select_all(GtkWidget *widget);
-
-/* Property indices */
-enum
-{
- PROP_DAY = 1,
- PROP_MONTH,
- PROP_YEAR,
- PROP_MIN_YEAR,
- PROP_MAX_YEAR
-};
-
-struct _HildonDateEditorPrivate {
- /* Cache of values in the entries, used in setting only parts of the date */
- guint year; /* current year in the entry */
- guint month; /* current month in the entry */
- guint day; /* current day in the entry */
-
- gboolean calendar_icon_pressed;
-
- GtkWidget *frame; /* borders around the date */
- GtkWidget *d_button_image; /* icon */
- GtkWidget *d_box_date; /* hbox for date */
-
- GtkWidget *d_entry; /* GtkEntry for day */
- GtkWidget *m_entry; /* GtkEntry for month */
- GtkWidget *y_entry; /* GtkEntry for year */
-
- GList *delims; /* List of delimeters between the fields (and possible at the ends) */
- GtkWidget *calendar_icon;
-
- gboolean skip_validation; /* don't validate date at all */
-
- gint min_year; /* minimum year allowed */
- gint max_year; /* maximum year allowed */
-};
-
-enum {
- DATE_ERROR,
- LAST_SIGNAL
-};
-
-static guint date_editor_signals[LAST_SIGNAL] = { 0 };
-
-GType hildon_date_editor_get_type(void)
-{
- static GType editor_type = 0;
-
- if (!editor_type) {
- static const GTypeInfo editor_info = {
- sizeof(HildonDateEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_date_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonDateEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_date_editor_init,
- };
- editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonDateEditor",
- &editor_info, 0);
- }
- return editor_type;
-}
-
-static void
-hildon_date_editor_class_init(HildonDateEditorClass * editor_class)
-{
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
- GObjectClass *gobject_class = G_OBJECT_CLASS (editor_class);
-
- parent_class = g_type_class_peek_parent(editor_class);
-
- g_type_class_add_private(editor_class,
- sizeof(HildonDateEditorPrivate));
-
- gobject_class->set_property = hildon_date_editor_set_property;
- gobject_class->get_property = hildon_date_editor_get_property;
- widget_class->size_request = hildon_date_editor_size_request;
- widget_class->size_allocate = hildon_date_editor_size_allocate;
- widget_class->focus = hildon_composite_widget_focus;
-
- container_class->forall = hildon_child_forall;
- GTK_OBJECT_CLASS(editor_class)->destroy = hildon_date_editor_destroy;
-
- editor_class->date_error = hildon_date_editor_date_error;
-
- date_editor_signals[DATE_ERROR] =
- g_signal_new("date-error",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(HildonDateEditorClass, date_error),
- g_signal_accumulator_true_handled, NULL,
- _hildon_marshal_BOOLEAN__ENUM,
- G_TYPE_BOOLEAN, 1, HILDON_TYPE_DATE_EDITOR_ERROR_TYPE);
-
- /**
- * HildonDateEditor:year:
- *
- * Current year.
- */
- g_object_class_install_property( gobject_class, PROP_YEAR,
- g_param_spec_uint("year",
- "Current year",
- "Current year",
- 1, 2100,
- 2005,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonDateEditor:month:
- *
- * Current month.
- */
- g_object_class_install_property( gobject_class, PROP_MONTH,
- g_param_spec_uint("month",
- "Current month",
- "Current month",
- 1, 12,
- 1,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonDateEditor:day:
- *
- * Current day.
- */
- g_object_class_install_property( gobject_class, PROP_DAY,
- g_param_spec_uint("day",
- "Current day",
- "Current day",
- 1, 31,
- 1,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonDateEditor:min-year:
- *
- * Minimum valid year.
- */
- g_object_class_install_property( gobject_class, PROP_MIN_YEAR,
- g_param_spec_uint("min-year",
- "Minimum valid year",
- "Minimum valid year",
- 1, 2100,
- DEFAULT_MIN_YEAR,
- G_PARAM_READWRITE) );
-
- /**
- * HildonDateEditor:max-year:
- *
- * Maximum valid year.
- */
- g_object_class_install_property( gobject_class, PROP_MAX_YEAR,
- g_param_spec_uint("max-year",
- "Maximum valid year",
- "Maximum valid year",
- 1, 2100,
- DEFAULT_MAX_YEAR,
- G_PARAM_READWRITE) );
-}
-
-/* Forces setting of the icon to certain state. Used initially
- and from the actual setter function */
-static void
-real_set_calendar_icon_state(HildonDateEditorPrivate *priv,
- gboolean pressed)
-{
- gtk_image_set_from_icon_name(GTK_IMAGE(priv->calendar_icon),
- pressed ? "qgn_widg_datedit_pr" : "qgn_widg_datedit",
- HILDON_ICON_SIZE_WIDG);
-
- priv->calendar_icon_pressed = pressed;
-}
-
-/* Sets the icon to given state (normal/pressed). Returns
- info if the state actually changed. */
-static gboolean
-hildon_date_editor_set_calendar_icon_state(HildonDateEditor *editor,
- gboolean pressed)
-{
- HildonDateEditorPrivate *priv;
-
- g_assert(HILDON_IS_DATE_EDITOR(editor));
-
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
- if (pressed != priv->calendar_icon_pressed) {
- real_set_calendar_icon_state(priv, pressed);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Packing day, month and year entries depend on locale settings
- We find out the order and all separators by converting a known
- date to default format and inspecting the result string */
-static void apply_locale_field_order(HildonDateEditorPrivate *priv)
-{
- GDate locale_test_date;
- GtkWidget *delim;
- gchar buffer[256];
- gchar *iter, *delim_text;
-
- g_date_set_dmy(&locale_test_date, 1, 2, 1970);
- (void) g_date_strftime(buffer, sizeof(buffer), "%x", &locale_test_date);
- iter = buffer;
-
- while (*iter)
- {
- gchar *endp;
- unsigned long value;
-
- /* Try to convert the current location into number. */
- value = strtoul(iter, &endp, 10);
-
- /* If the conversion didn't progress or the detected value was
- unknown (we used a fixed date, you remember), we treat
- current position as a literal */
- switch (value)
- {
- case 1:
- gtk_box_pack_start(GTK_BOX(priv->d_box_date),
- priv->d_entry, FALSE, FALSE, 0);
- break;
- case 2:
- gtk_box_pack_start(GTK_BOX(priv->d_box_date),
- priv->m_entry, FALSE, FALSE, 0);
- break;
- case 70: /* %x format uses only 2 numbers for some locales */
- case 1970:
- gtk_box_pack_start(GTK_BOX(priv->d_box_date),
- priv->y_entry, FALSE, FALSE, 0);
- break;
- default:
- /* All non-number characters starting from current position
- form the delimeter */
- for (endp = iter; *endp; endp++)
- if (g_ascii_isdigit(*endp))
- break;
-
- /* Now endp points one place past the delimeter text */
- delim_text = g_strndup(iter, endp - iter);
- delim = gtk_label_new(delim_text);
- gtk_box_pack_start(GTK_BOX(priv->d_box_date),
- delim, FALSE, FALSE, 0);
- priv->delims = g_list_append(priv->delims, delim);
- g_free(delim_text);
-
- break;
- };
-
- iter = endp;
- }
-}
-
-static void hildon_date_editor_init(HildonDateEditor * editor)
-{
- HildonDateEditorPrivate *priv;
- GDate cur_date;
-
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(editor), GTK_NO_WINDOW);
-
- gtk_widget_push_composite_child();
-
- /* initialize values */
- g_date_clear(&cur_date, 1);
- g_date_set_time(&cur_date, time(NULL));
-
- priv->day = g_date_get_day(&cur_date);
- priv->month = g_date_get_month(&cur_date);
- priv->year = g_date_get_year(&cur_date);
- priv->min_year = DEFAULT_MIN_YEAR;
- priv->max_year = DEFAULT_MAX_YEAR;
-
- /* make widgets */
- priv->frame = gtk_frame_new(NULL);
- gtk_container_set_border_width(GTK_CONTAINER(priv->frame), 0);
-
- priv->d_entry = gtk_entry_new();
- priv->m_entry = gtk_entry_new();
- priv->y_entry = gtk_entry_new();
-
- g_object_set (G_OBJECT(priv->d_entry), "input-mode",
- HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
- g_object_set (G_OBJECT(priv->m_entry), "input-mode",
- HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
- g_object_set (G_OBJECT(priv->y_entry), "input-mode",
- HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
-
- /* set entry look */
- gtk_entry_set_width_chars(GTK_ENTRY(priv->d_entry), DAY_ENTRY_WIDTH);
- gtk_entry_set_width_chars(GTK_ENTRY(priv->m_entry), MONTH_ENTRY_WIDTH);
- gtk_entry_set_width_chars(GTK_ENTRY(priv->y_entry), YEAR_ENTRY_WIDTH);
-
- gtk_entry_set_max_length(GTK_ENTRY(priv->d_entry), DAY_ENTRY_WIDTH);
- gtk_entry_set_max_length(GTK_ENTRY(priv->m_entry), MONTH_ENTRY_WIDTH);
- gtk_entry_set_max_length(GTK_ENTRY(priv->y_entry), YEAR_ENTRY_WIDTH);
-
- gtk_entry_set_has_frame(GTK_ENTRY(priv->d_entry), FALSE);
- gtk_entry_set_has_frame(GTK_ENTRY(priv->m_entry), FALSE);
- gtk_entry_set_has_frame(GTK_ENTRY(priv->y_entry), FALSE);
-
- gtk_widget_set_composite_name(priv->d_entry, "day_entry");
- gtk_widget_set_composite_name(priv->m_entry, "month_entry");
- gtk_widget_set_composite_name(priv->y_entry, "year_entry");
-
- priv->d_box_date = gtk_hbox_new(FALSE, 0);
-
- priv->d_button_image = gtk_button_new();
- priv->calendar_icon = gtk_image_new();
- real_set_calendar_icon_state(priv, FALSE);
- GTK_WIDGET_UNSET_FLAGS(priv->d_button_image, GTK_CAN_FOCUS | GTK_CAN_DEFAULT);
-
- apply_locale_field_order(priv);
-
- gtk_container_add(GTK_CONTAINER(priv->frame), priv->d_box_date);
- gtk_container_add(GTK_CONTAINER(priv->d_button_image), priv->calendar_icon);
- gtk_button_set_relief(GTK_BUTTON(priv->d_button_image), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click(GTK_BUTTON(priv->d_button_image), FALSE);
-
- gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->d_button_image, GTK_WIDGET(editor));
- gtk_widget_show_all(priv->frame);
- gtk_widget_show_all(priv->d_button_image);
-
- /* image button signal connects */
- g_signal_connect(GTK_OBJECT(priv->d_button_image), "pressed",
- G_CALLBACK(hildon_date_editor_icon_press), editor);
- g_signal_connect(GTK_OBJECT(priv->d_button_image), "released",
- G_CALLBACK(hildon_date_editor_released), editor);
- g_signal_connect(GTK_OBJECT(priv->d_button_image), "clicked",
- G_CALLBACK(hildon_date_editor_clicked), editor);
- g_signal_connect(GTK_OBJECT(priv->d_button_image), "key_press_event",
- G_CALLBACK(hildon_date_editor_keypress), editor);
-
- /* entry signal connects */
- g_signal_connect(GTK_OBJECT(priv->d_entry), "focus-in-event",
- G_CALLBACK(hildon_date_editor_entry_focusin), editor);
-
- g_signal_connect(GTK_OBJECT(priv->m_entry), "focus-in-event",
- G_CALLBACK(hildon_date_editor_entry_focusin), editor);
-
- g_signal_connect(GTK_OBJECT(priv->y_entry), "focus-in-event",
- G_CALLBACK(hildon_date_editor_entry_focusin), editor);
-
- g_signal_connect(GTK_OBJECT(priv->d_entry), "focus-out-event",
- G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
-
- g_signal_connect(GTK_OBJECT(priv->m_entry), "focus-out-event",
- G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
-
- g_signal_connect(GTK_OBJECT(priv->y_entry), "focus-out-event",
- G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
-
- g_signal_connect(GTK_OBJECT(priv->d_entry), "key-press-event",
- G_CALLBACK(hildon_date_editor_keypress), editor);
-
- g_signal_connect(GTK_OBJECT(priv->m_entry), "key-press-event",
- G_CALLBACK(hildon_date_editor_keypress), editor);
-
- g_signal_connect(GTK_OBJECT(priv->y_entry), "key-press-event",
- G_CALLBACK(hildon_date_editor_keypress), editor);
-
- g_signal_connect(GTK_OBJECT(priv->d_entry), "key-release-event",
- G_CALLBACK(hildon_date_editor_keyrelease), editor);
-
- g_signal_connect(GTK_OBJECT(priv->m_entry), "key-release-event",
- G_CALLBACK(hildon_date_editor_keyrelease), editor);
-
- g_signal_connect(GTK_OBJECT(priv->y_entry), "key-release-event",
- G_CALLBACK(hildon_date_editor_keyrelease), editor);
-
- hildon_date_editor_set_date(editor, priv->year, priv->month, priv->day);
-
- g_signal_connect(GTK_OBJECT(priv->d_entry), "changed",
- G_CALLBACK(hildon_date_editor_entry_changed), editor);
-
- g_signal_connect(GTK_OBJECT(priv->m_entry), "changed",
- G_CALLBACK(hildon_date_editor_entry_changed), editor);
-
- g_signal_connect(GTK_OBJECT(priv->y_entry), "changed",
- G_CALLBACK(hildon_date_editor_entry_changed), editor);
-
- gtk_widget_pop_composite_child();
-}
-
-static void hildon_date_editor_set_property (GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- HildonDateEditor *editor = HILDON_DATE_EDITOR(object);
- HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
- gint val;
-
- switch (param_id)
- {
- case PROP_YEAR:
- hildon_date_editor_set_year (editor, g_value_get_uint(value));
- break;
-
- case PROP_MONTH:
- hildon_date_editor_set_month (editor, g_value_get_uint(value));
- break;
-
- case PROP_DAY:
- hildon_date_editor_set_day (editor, g_value_get_uint(value));
- break;
-
- case PROP_MIN_YEAR:
- val = g_value_get_uint(value);
- if (val <= priv->max_year)
- {
- priv->min_year = val;
- /* Clamp current year */
- if (hildon_date_editor_get_year (editor) < priv->min_year)
- hildon_date_editor_set_year (editor, priv->min_year);
- }
- else
- g_warning("min-year cannot be greater than max-year");
- break;
-
- case PROP_MAX_YEAR:
- val = g_value_get_uint(value);
- if (val >= priv->min_year)
- {
- priv->max_year = val;
- /* Clamp current year */
- if (hildon_date_editor_get_year (editor) > priv->max_year)
- hildon_date_editor_set_year (editor, priv->max_year);
- }
- else
- g_warning("max-year cannot be less than min-year");
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_date_editor_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec )
-{
- HildonDateEditor *editor = HILDON_DATE_EDITOR(object);
- HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- switch (param_id)
- {
- case PROP_YEAR:
- g_value_set_uint (value, hildon_date_editor_get_year (editor));
- break;
-
- case PROP_MONTH:
- g_value_set_uint (value, hildon_date_editor_get_month (editor));
- break;
-
- case PROP_DAY:
- g_value_set_uint (value, hildon_date_editor_get_day (editor));
- break;
-
- case PROP_MIN_YEAR:
- g_value_set_uint (value, priv->min_year);
- break;
-
- case PROP_MAX_YEAR:
- g_value_set_uint (value, priv->max_year);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_child_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- HildonDateEditor *editor;
- HildonDateEditorPrivate *priv;
-
- g_assert(HILDON_IS_DATE_EDITOR(container));
- g_assert(callback);
-
- editor = HILDON_DATE_EDITOR(container);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- if (include_internals) {
- (*callback) (priv->frame, callback_data);
- (*callback) (priv->d_button_image, callback_data);
- }
-}
-
-static void hildon_date_editor_destroy(GtkObject * self)
-{
- HildonDateEditorPrivate *priv;
-
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(self);
-
- if (priv->frame) {
- gtk_widget_unparent(priv->frame);
- priv->frame = NULL;
- }
- if (priv->d_button_image) {
- gtk_widget_unparent(priv->d_button_image);
- priv->d_button_image = NULL;
- }
- if (priv->delims) {
- g_list_free(priv->delims);
- priv->delims = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-/**
- * hildon_date_editor_new:
- *
- * Creates a new date editor. The current system date
- * is shown in the editor.
- *
- * Returns: pointer to a new @HildonDateEditor widget.
- */
-GtkWidget *hildon_date_editor_new(void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_DATE_EDITOR, NULL));
-}
-
-/**
- * hildon_date_editor_set_date:
- * @date: the @HildonDateEditor widget
- * @year: year
- * @month: month
- * @day: day
- *
- * Sets the date shown in the editor.
- */
-void hildon_date_editor_set_date(HildonDateEditor * editor,
- guint year, guint month, guint day)
-{
- HildonDateEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_DATE_EDITOR(editor));
-
- /* This function cannot be implemented by calling
- component setters, since applying the individual
- values one by one can make the date temporarily
- invalid (depending on what the previous values were),
- which in turn causes that the desired date
- is not set (even though it's valid). We must set all the
- components at one go and not try to do any validation etc
- there in between. */
-
- g_return_if_fail(HILDON_IS_DATE_EDITOR(editor));
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- if (g_date_valid_dmy(day, month, year))
- {
- GDate date;
- gchar buffer[256];
-
- priv->year = year;
- priv->month = month;
- priv->day = day;
-
- g_date_set_dmy(&date, day, month, year);
-
- /* We apply the new values, but do not want automatic focus move
- etc to take place */
- g_snprintf(buffer, sizeof(buffer), "%04d", year);
- g_signal_handlers_block_by_func(priv->y_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->y_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->y_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_date_strftime(buffer, sizeof(buffer), "%m", &date);
- g_signal_handlers_block_by_func(priv->m_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->m_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->m_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_date_strftime(buffer, sizeof(buffer), "%d", &date);
- g_signal_handlers_block_by_func(priv->d_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->d_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->d_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_object_notify(G_OBJECT(editor), "year");
- g_object_notify(G_OBJECT(editor), "month");
- g_object_notify(G_OBJECT(editor), "day");
- }
-}
-
-/**
- * hildon_date_editor_get_date:
- * @date: the @HildonDateEditor widget
- * @year: year
- * @month: month
- * @day: day
- *
- * Returns: the year, month, and day currently on the
- * date editor.
- */
-void hildon_date_editor_get_date(HildonDateEditor * date,
- guint * year, guint * month, guint * day)
-{
- HildonDateEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_DATE_EDITOR(date));
- g_return_if_fail(year);
- g_return_if_fail(month);
- g_return_if_fail(day);
-
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(date);
-
- /* FIXME: The role of priv->{day,month,year} members vs. entry contents
- is unclear. They do not neccesarily match and still the texts are
- used as return values and members for some internal validation!!
- At least a partly reason is to allow empty text to become
- 0 return value, while members are restricted to valid ranges?!
- However, if we change the current way, we are likely to break
- some applications if they rely on some specific way how this
- widget currently handles empty values and temporarily invalid values.
-
- The key issue is this: What should the _get methods return while
- user is editing a field and the result is incomplete. The
- partial result? The last good result? If we return partial result
- we also need a way to inform if the date is not valid. Current
- implementation is some kind of hybrid of these two...
-
- for example:
- hildon_date_editor_set_day(editor, hildon_date_editor_get_day(editor));
-
- easily fails, since set_day tries to force validity while get_day
- doesn't do that.
-
- Proposal: Always return the same values that are shown in the
- fields. We add a separate flag (Or use GDate) to
- indicate if the current date is valid. This would allow
- setters to make the date invalid as well.
- */
- *year = /*priv->year;*/
- (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->y_entry)));
- *month = /*priv->month;*/
- (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->m_entry)));
- *day = /*priv->day;*/
- (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->d_entry)));
-}
-
-/* icon button press event */
-static gboolean hildon_date_editor_icon_press(GtkWidget * widget,
- gpointer data)
-{
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(HILDON_IS_DATE_EDITOR(data));
-
- hildon_date_editor_set_calendar_icon_state(HILDON_DATE_EDITOR(data), TRUE);
-
- return FALSE;
-}
-
-static gboolean hildon_date_editor_entry_focusin(GtkWidget * widget,
- GdkEventFocus * event,
- gpointer data)
-{
- g_idle_add((GSourceFunc)
- _hildon_date_editor_entry_select_all, GTK_ENTRY(widget));
-
- return FALSE;
-}
-
-
-static void popup_calendar_dialog(HildonDateEditor *ed)
-{
- guint y = 0, m = 0, d = 0;
- GtkWidget *popup;
- GtkWidget *parent;
- guint result;
- GValue val = {0, };
-
- hildon_date_editor_get_date(ed, &y, &m, &d);
-
- parent = gtk_widget_get_ancestor(GTK_WIDGET(ed), GTK_TYPE_WINDOW);
- popup = hildon_calendar_popup_new(GTK_WINDOW(parent), y, m, d);
-
- g_value_init(&val, G_TYPE_INT);
- /* Set max/min year in calendar popup to date editor values */
- g_object_get_property(G_OBJECT(ed), "min-year", &val);
- g_object_set_property(G_OBJECT(popup), "min-year", &val);
- g_object_get_property(G_OBJECT(ed), "max-year", &val);
- g_object_set_property(G_OBJECT(popup), "max-year", &val);
-
- /* Pop up calendar */
- result = gtk_dialog_run(GTK_DIALOG(popup));
- switch (result) {
- case GTK_RESPONSE_OK:
- case GTK_RESPONSE_ACCEPT:
- hildon_calendar_popup_get_date(HILDON_CALENDAR_POPUP(popup), &y,
- &m, &d);
- hildon_date_editor_set_date(ed, y, m, d);
- }
-
- gtk_widget_destroy(popup);
-}
-
-/* button released */
-static gboolean hildon_date_editor_released(GtkWidget * widget,
- gpointer data)
-{
- HildonDateEditor *ed;
-
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(HILDON_IS_DATE_EDITOR(data));
-
- ed = HILDON_DATE_EDITOR(data);
-
- /* restores the icon state. The clicked cycle raises the dialog */
- hildon_date_editor_set_calendar_icon_state(ed, FALSE);
-
- return FALSE;
-}
-
-/* button released */
-static gboolean hildon_date_editor_clicked(GtkWidget * widget,
- gpointer data)
-{
- HildonDateEditor *ed;
-
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(HILDON_IS_DATE_EDITOR(data));
-
- ed = HILDON_DATE_EDITOR(data);
-
- /* restores the non-clicked button state and raises the dialog */
- hildon_date_editor_set_calendar_icon_state(ed, FALSE);
- popup_calendar_dialog(ed);
-
- return FALSE;
-}
-
-/* This is called whenever some editor filed loses the focus and
- when the all of the fields are filled.
- Earlier this was called whenever an entry changed */
-/* FIXME: Validation on focus_out is broken by concept */
-static gint
-hildon_date_editor_entry_validate(GtkWidget *widget, gpointer data)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
- gint d, m, y, max_days;
- gboolean r; /* temp return values for signals */
- const gchar *text;
- gint error_code = NO_ERROR;
-
- g_assert(HILDON_IS_DATE_EDITOR(data));
- g_assert(GTK_IS_ENTRY(widget));
-
- ed = HILDON_DATE_EDITOR(data);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
-
- if (priv->skip_validation)
- return error_code;
-
- /*check if the calling entry is empty*/
- text = gtk_entry_get_text(GTK_ENTRY(widget));
- if(text == NULL || text[0] == 0)
- {
- if (widget == priv->d_entry)
- g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_DAY, &r);
- else if(widget == priv->m_entry)
- g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_MONTH, &r);
- else
- g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_YEAR, &r);
-
- /* restore empty entry to safe value */
- hildon_date_editor_set_date (ed, priv->year, priv->month, priv->day);
- return error_code;
- }
-
- /* Ok, we now check validity. Some fields can be empty */
- text = gtk_entry_get_text(GTK_ENTRY(priv->d_entry));
- if (text == NULL || text[0] == 0) return error_code;
- d = atoi(text);
- text = gtk_entry_get_text(GTK_ENTRY(priv->m_entry));
- if (text == NULL || text[0] == 0) return error_code;
- m = atoi(text);
- text = gtk_entry_get_text(GTK_ENTRY(priv->y_entry));
- if (text == NULL || text[0] == 0) return error_code;
- y = atoi(text);
-
- /* Did it actually change? */
- if (d != priv->day || m != priv->month || y != priv->year)
- {
- /* We could/should use hildon_date_editor_set_year and such functions
- * to set the date, instead of use gtk_entry_set_text, and then change
- * the priv member but hildon_date_editor_set_year and such functions
- * check if the date is valid, we do want to do date validation check
- * here according to spec */
-
- /* Validate month */
- if(widget == priv->m_entry) {
- if(m < 1) {
- error_code = MIN_MONTH;
- m = 1;
- }
- else if (m > 12) {
- error_code = MAX_MONTH;
- m = 12;
- }
- }
-
- /* Validate year */
- if(widget == priv->y_entry) {
- if (y < priv->min_year) {
- error_code = MIN_YEAR;
- y = priv->min_year;
- }
- else if (y > priv->max_year) {
- error_code = MAX_YEAR;
- y = priv->max_year;
- }
- }
-
- /* Validate day. We have to do this in every case, since
- changing month or year can make the day number to be invalid */
- max_days = g_date_get_days_in_month(m,y);
- if(d < 1) {
- error_code = MIN_DAY;
- d = 1;
- }
- else if (d > max_days) {
- if (d > 31) {
- error_code = MAX_DAY;
- d = max_days;
- }
- else { /* the date does not exist (is invalid) */
- error_code = INVALID_DATE;
- /* check what was changed and restore previous value */
- if ( widget == priv->y_entry )
- y = priv->year;
- else if ( widget == priv->m_entry )
- m = priv->month;
- else
- d = priv->day;
- }
- }
-
- if (error_code != NO_ERROR)
- {
- g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, error_code, &r);
-
- g_idle_add ((GSourceFunc)
- _hildon_date_editor_entry_select_all,
- widget);
- }
- }
-
- /* Fix and reformat the date after error signal is processed.
- reformatting can be needed even in a such case that numerical
- values of the date components are the same as earlier. */
- hildon_date_editor_set_date(ed, y, m, d);
- return error_code;
-}
-
-/* When entry becomes full, we move the focus to the next field.
- If we are on the last field, the whole contents are validated. */
-static void
-hildon_date_editor_entry_changed(GtkEditable *ed, gpointer data)
-{
- GtkEntry *entry;
- gint error_code;
- HildonDateEditorPrivate *priv;
-
- g_assert(GTK_IS_ENTRY(ed));
- g_assert(HILDON_IS_DATE_EDITOR(data));
-
- entry = GTK_ENTRY(ed);
-
- /* If day entry is full, move to next entry or validate */
- if (g_utf8_strlen(gtk_entry_get_text(entry), -1) == gtk_entry_get_max_length(entry))
- {
- error_code = hildon_date_editor_entry_validate(GTK_WIDGET(entry), data);
- if (error_code == NO_ERROR)
- {
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(HILDON_DATE_EDITOR(data));
- priv->skip_validation = TRUE;
- gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_RIGHT);
- }
- }
-}
-
-static gboolean hildon_date_editor_keyrelease(GtkWidget * widget,
- GdkEventKey * event,
- gpointer data)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
-
- g_return_val_if_fail(data, FALSE);
- g_return_val_if_fail(widget, FALSE);
-
- ed = HILDON_DATE_EDITOR(data);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
-
- if (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return ||
- event->keyval == GDK_ISO_Enter) {
- if (hildon_date_editor_set_calendar_icon_state(ed, FALSE))
- {
- popup_calendar_dialog(ed);
- return TRUE;
- }
- } else if (event->keyval == GDK_Escape)
- priv->skip_validation = FALSE;
-
- return FALSE;
-}
-
-/* keyboard handling */
-static gboolean hildon_date_editor_keypress(GtkWidget * widget,
- GdkEventKey * event,
- gpointer data)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
- gint pos;
- gboolean r;
-
- g_assert(HILDON_IS_DATE_EDITOR(data));
- g_assert(GTK_IS_ENTRY(widget));
-
- ed = HILDON_DATE_EDITOR(data);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
- pos = gtk_editable_get_position(GTK_EDITABLE(widget));
-
- /* Show error message in case the key pressed is not allowed
- (only digits and control characters are allowed )*/
- if (!g_unichar_isdigit(event->keyval) && !(event->keyval & 0xF000)) {
- g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, INVALID_CHAR, &r);
- return TRUE;
- }
-
- switch (event->keyval) {
- case GDK_Left:
- if (pos == 0) {
- (void) gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_LEFT);
- return TRUE;
- }
- break;
- case GDK_Right:
- if (pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1)) {
- (void) gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_RIGHT);
- return TRUE;
- }
- break;
- case GDK_Return:
- case GDK_ISO_Enter:
- /* Ignore return value, since we want to handle event at all times.
- otherwise vkb would popup when the keyrepeat starts. */
- (void) hildon_date_editor_set_calendar_icon_state(ed, TRUE);
- return TRUE;
-
- case GDK_Escape:
- priv->skip_validation = TRUE;
- break;
- default:
- break;
- }
-
- return FALSE;
-}
-
-static gboolean hildon_date_editor_entry_focus_out(GtkWidget * widget,
- GdkEventFocus * event,
- gpointer data)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
-
- g_assert(HILDON_IS_DATE_EDITOR(data));
-
- ed = HILDON_DATE_EDITOR(data);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
-
- hildon_date_editor_entry_validate(widget, data);
- priv->skip_validation = FALSE;
-
- return FALSE;
-}
-
-static gboolean
-hildon_date_editor_date_error(HildonDateEditor *editor,
- HildonDateEditorErrorType type)
-{
- HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- switch(type)
- {
- case MAX_DAY:
- gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), 31);
- break;
- case MAX_MONTH:
- gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), 12);
- break;
- case MAX_YEAR:
- gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), priv->max_year);
- break;
- case MIN_DAY:
- case MIN_MONTH:
- gtk_infoprintf(NULL, _("ckct_ib_minimum_value"), 1);
- break;
- case MIN_YEAR:
- gtk_infoprintf(NULL, _("ckct_ib_minimum_value"), priv->min_year);
- break;
- case EMPTY_DAY:
- gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"), 1, 31);
- break;
- case EMPTY_MONTH:
- gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"), 1, 12);
- break;
- case EMPTY_YEAR:
- gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"),
- priv->min_year, priv->max_year);
- break;
- case INVALID_CHAR:
- gtk_infoprint(NULL, _("ckct_ib_illegal_character"));
- break;
- case INVALID_DATE:
- gtk_infoprint(NULL, _("ckct_ib_date_does_not_exist"));
- break;
- default:
- /*default error message ?*/
- break;
- }
- return TRUE;
-}
-
-static void hildon_date_editor_size_request(GtkWidget * widget,
- GtkRequisition * requisition)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
- GtkRequisition f_req, img_req;
-
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(requisition != NULL);
-
- ed = HILDON_DATE_EDITOR(widget);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
-
- /* Our own children affect our size */
- gtk_widget_size_request(priv->frame, &f_req);
- gtk_widget_size_request(priv->d_button_image, &img_req);
-
- /* calculate our size */
- requisition->width = f_req.width + img_req.width + HILDON_MARGIN_DEFAULT;
-
- /* FIXME: Fixed size is bad! We should use the maximum of our children, but
- doing so would break current pixel specifications, since
- the text entry by itself is already 30px tall + then frame takes
- something */
- requisition->height = DATE_EDITOR_HEIGHT;
-}
-
-static void hildon_date_editor_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonDateEditor *ed;
- HildonDateEditorPrivate *priv;
- GtkAllocation f_alloc, img_alloc;
- GtkRequisition req;
- GtkRequisition max_req;
- GList *iter;
-
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(allocation != NULL);
-
- ed = HILDON_DATE_EDITOR(widget);
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
-
- widget->allocation = *allocation;
-
- gtk_widget_get_child_requisition(widget, &max_req);
-
- /* Center vertically */
- f_alloc.y = img_alloc.y = allocation->y +
- MAX(allocation->height - max_req.height, 0) / 2;
-
- /* Center horizontally */
- f_alloc.x = img_alloc.x = allocation->x +
- MAX(allocation->width - max_req.width, 0) / 2;
-
- /* allocate frame */
- if (GTK_WIDGET_VISIBLE(priv->frame)) {
- gtk_widget_get_child_requisition(priv->frame, &req);
-
- f_alloc.width = req.width;
- f_alloc.height = max_req.height;
- gtk_widget_size_allocate(priv->frame, &f_alloc);
- }
-
- /* allocate icon */
- if (GTK_WIDGET_VISIBLE(priv->d_button_image)) {
- gtk_widget_get_child_requisition(priv->d_button_image,
- &req);
-
- img_alloc.x += f_alloc.width + HILDON_MARGIN_DEFAULT;
- img_alloc.width = req.width;
- img_alloc.height = max_req.height;
- gtk_widget_size_allocate(priv->d_button_image, &img_alloc);
- }
-
- /* FIXME: We really should not alloc delimeters by hand (since they
- are not our own children, but we need to force to appear
- higher. This ugly hack is needed to compensate the forced
- height in size_request. */
- for (iter = priv->delims; iter; iter = iter->next)
- {
- GtkWidget *delim;
- GtkAllocation alloc;
-
- delim = GTK_WIDGET(iter->data);
- alloc = delim->allocation;
- alloc.height = max_req.height;
- alloc.y = priv->d_entry->allocation.y - 2;
-
- gtk_widget_size_allocate(delim, &alloc);
- }
-}
-
-/**
- * hildon_date_editor_set_year:
- * @editor: the @HildonDateEditor widget
- * @year: year
- *
- * Sets the year shown in the editor.
- *
- * Returns: TRUE if the year is valid
- */
-gboolean hildon_date_editor_set_year(HildonDateEditor *editor, guint year)
-{
- HildonDateEditorPrivate *priv;
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- if (g_date_valid_dmy(priv->day, priv->month, year))
- {
- gchar buffer[256];
- priv->year = year;
-
- g_snprintf(buffer, sizeof(buffer), "%04d", year);
-
- /* We apply the new day, but do not want automatic focus move
- etc to take place */
- g_signal_handlers_block_by_func(priv->y_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->y_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->y_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_object_notify(G_OBJECT(editor), "year");
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * hildon_date_editor_set_month:
- * @editor: the @HildonDateEditor widget
- * @month: month
- *
- * Sets the month shown in the editor.
- *
- * Returns: TRUE if the month is valid
- */
-gboolean hildon_date_editor_set_month(HildonDateEditor *editor, guint month)
-{
- HildonDateEditorPrivate *priv;
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- if (g_date_valid_dmy(priv->day, month, priv->year))
- {
- GDate date;
- gchar buffer[256];
-
- priv->month = month;
- g_date_set_dmy(&date, priv->day, month, priv->year);
- g_date_strftime(buffer, sizeof(buffer), "%m", &date);
-
- /* We apply the new day, but do not want automatic focus move
- etc to take place */
- g_signal_handlers_block_by_func(priv->m_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->m_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->m_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_object_notify(G_OBJECT(editor), "month");
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * hildon_date_editor_set_day:
- * @editor: the @HildonDateEditor widget
- * @day: day
- *
- * Sets the day shown in the editor.
- *
- * Returns: TRUE if the day is valid
- */
-gboolean hildon_date_editor_set_day(HildonDateEditor *editor, guint day)
-{
- HildonDateEditorPrivate *priv;
-
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
-
- if (g_date_valid_dmy(day, priv->month, priv->year))
- {
- GDate date;
- gchar buffer[256];
-
- priv->day = day;
- g_date_set_dmy(&date, day, priv->month, priv->year);
- g_date_strftime(buffer, sizeof(buffer), "%d", &date);
-
- /* We apply the new day, but do not want automatic focus move
- etc to take place */
- g_signal_handlers_block_by_func(priv->d_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
- gtk_entry_set_text(GTK_ENTRY(priv->d_entry), buffer);
- g_signal_handlers_unblock_by_func(priv->d_entry,
- (gpointer) hildon_date_editor_entry_changed, editor);
-
- g_object_notify(G_OBJECT(editor), "day");
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * hildon_date_editor_get_year:
- * @editor: the @HildonDateEditor widget
- *
- * Returns: the current year shown in the editor.
- */
-guint hildon_date_editor_get_year(HildonDateEditor *editor)
-{
- HildonDateEditorPrivate *priv;
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
- return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->y_entry)));
-}
-
-/**
- * hildon_date_editor_get_month:
- * @editor: the @HildonDateEditor widget
- *
- * Gets the month shown in the editor.
- *
- * Returns: the current month shown in the editor.
- */
-
-guint hildon_date_editor_get_month(HildonDateEditor *editor)
-{
- HildonDateEditorPrivate *priv;
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
- return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->m_entry)));
-}
-
-/**
- * hildon_date_editor_get_day:
- * @editor: the @HildonDateEditor widget
- *
- * Gets the day shown in the editor.
- *
- * Returns: the current day shown in the editor
- */
-
-guint hildon_date_editor_get_day(HildonDateEditor *editor)
-{
- HildonDateEditorPrivate *priv;
- g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
- priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
- return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->d_entry)));
-}
-
-/* Idle callback */
-static gboolean
-_hildon_date_editor_entry_select_all (GtkWidget *widget)
-{
- GDK_THREADS_ENTER ();
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- GDK_THREADS_LEAVE ();
- return FALSE;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_DATE_EDITOR_H__
-#define __HILDON_DATE_EDITOR_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-/**
- * HILDON_TYPE_DATE_EDITOR:
- *
- * Macro for getting type of date editor.
- * Since: 0.12.10
- */
-#define HILDON_TYPE_DATE_EDITOR ( hildon_date_editor_get_type() )
-
-
-/**
- * HILDON_DATE_EDITOR_TYPE:
- *
- * Deprecated: use #HILDON_TYPE_DATE_EDITOR instead
- */
-#define HILDON_DATE_EDITOR_TYPE HILDON_TYPE_DATE_EDITOR
-
-#define HILDON_DATE_EDITOR(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_DATE_EDITOR, HildonDateEditor))
-#define HILDON_DATE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_DATE_EDITOR, HildonDateEditorClass))
-#define HILDON_IS_DATE_EDITOR(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_DATE_EDITOR))
-#define HILDON_IS_DATE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_DATE_EDITOR))
-
-/**
- * HildonDateEditor:
- *
- * Internal struct for date editor.
- */
-typedef struct _HildonDateEditor HildonDateEditor;
-typedef struct _HildonDateEditorClass HildonDateEditorClass;
-
-typedef enum
-{
- NO_ERROR = -1,
- MAX_DAY,
- MAX_MONTH,
- MAX_YEAR,
- MIN_DAY,
- MIN_MONTH,
- MIN_YEAR,
- EMPTY_DAY,
- EMPTY_MONTH,
- EMPTY_YEAR,
- INVALID_DATE,
- INVALID_CHAR
-
-}HildonDateEditorErrorType;
-
-struct _HildonDateEditor {
- GtkContainer par;
-};
-
-struct _HildonDateEditorClass {
- GtkContainerClass parent_class;
-
- gboolean (*date_error) (HildonDateEditor *editor,
- HildonDateEditorErrorType type);
-};
-
-GType hildon_date_editor_get_type(void) G_GNUC_CONST;
-
-GtkWidget *hildon_date_editor_new(void);
-
-void hildon_date_editor_set_date(HildonDateEditor * date,
- guint year, guint month, guint day);
-
-void hildon_date_editor_get_date(HildonDateEditor * date,
- guint * year, guint * month, guint * day);
-
-gboolean hildon_date_editor_set_year(HildonDateEditor *editor, guint year);
-gboolean hildon_date_editor_set_month(HildonDateEditor *editor, guint month);
-gboolean hildon_date_editor_set_day(HildonDateEditor *editor, guint day);
-
-guint hildon_date_editor_get_year(HildonDateEditor *editor);
-guint hildon_date_editor_get_month(HildonDateEditor *editor);
-guint hildon_date_editor_get_day(HildonDateEditor *editor);
-
-G_END_DECLS
-#endif /* __HILDON_DATE_EDITOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-defines
- * @short_description: Not a widget, just a helper
- *
- */
-
-#include <gtk/gtk.h>
-#include "hildon-defines.h"
-
-const HildonIconSizes *hildoniconsizes = NULL;
-static HildonIconSizes iis; /* hildon internal icon sizes */
-
-/**
- * hildon_icon_sizes_init:
- *
- * Initializes the icon sizes. This is automatically
- * called when the icon sizes have not been initialized
- * and one is requested.
- **/
-void hildon_icon_sizes_init (void)
-{
- if (hildoniconsizes != NULL)
- return;
-
- hildoniconsizes = &iis;
-
- iis.icon_size_list = gtk_icon_size_register ("hildon_icon_size_list", 64, 64);
- iis.icon_size_small = gtk_icon_size_register ("*icon_size_small", 26, 26);
- iis.icon_size_toolbar = gtk_icon_size_register ("icon_size_toolbar", 26, 26);
- iis.icon_size_widg = gtk_icon_size_register ("icon_size_widg", 26, 26);
- iis.icon_size_widg_wizard = gtk_icon_size_register ("icon_size_widg_wizard", 50, 50);
- iis.icon_size_grid = gtk_icon_size_register ("icon_size_grid", 64, 64);
- iis.icon_size_big_note = gtk_icon_size_register ("icon_size_big_note", 50, 50);
- iis.icon_size_note = gtk_icon_size_register ("icon_size_note", 26, 26);
- iis.icon_size_statusbar = gtk_icon_size_register ("icon_size_statusbar", 40, 40);
- iis.icon_size_indi_video_player_pre_roll = gtk_icon_size_register ("icon_size_indi_video_player_pre_roll", 64, 64);
- iis.icon_size_indi_key_pad_lock = gtk_icon_size_register ("icon_size_indi_key_pad_lock", 50, 50);
- iis.icon_size_indi_copy = gtk_icon_size_register ("icon_size_indi_copy", 64, 64);
- iis.icon_size_indi_delete = gtk_icon_size_register ("icon_size_indi_delete", 64, 64);
- iis.icon_size_indi_process = gtk_icon_size_register ("icon_size_indi_process", 64, 64);
- iis.icon_size_indi_progressball = gtk_icon_size_register ("icon_size_indi_progressball", 64, 64);
- iis.icon_size_indi_send = gtk_icon_size_register ("icon_size_indi_send", 64, 64);
- iis.icon_size_indi_offmode_charging = gtk_icon_size_register ("icon_size_indi_offmode_charging", 50, 50);
- iis.icon_size_indi_tap_and_hold = gtk_icon_size_register ("icon_size_indi_tap_and_hold", 34, 34);
- iis.icon_size_indi_send_receive = gtk_icon_size_register ("icon_size_indi_send_receive", 64, 64);
- iis.icon_size_indi_wlan_strength = gtk_icon_size_register ("icon_size_indi_wlan_strength", 64, 64);
-
- iis.image_size_indi_nokia_logo = gtk_icon_size_register ("image_size_indi_nokia_logo", 64, 64);
- iis.image_size_indi_startup_failed = gtk_icon_size_register ("image_size_indi_startup_failed", 64, 64);
- iis.image_size_indi_startup_nokia_logo = gtk_icon_size_register ("image_size_indi_startup_nokia_logo", 64, 64);
- iis.image_size_indi_nokia_hands = gtk_icon_size_register ("image_size_indi_nokia_hands", 64, 64);
-}
-
-typedef struct _HildonLogicalData HildonLogicalData;
-
-struct _HildonLogicalData
-{
- GtkRcFlags rcflags;
- GtkStateType state;
- gchar *logicalcolorstring;
- gchar *logicalfontstring;
-};
-
-
-static void hildon_change_style_recursive_from_ld (GtkWidget *widget, GtkStyle *prev_style, HildonLogicalData *ld)
-{
- /* Change the style for child widgets */
- if (GTK_IS_CONTAINER (widget)) {
- GSList *iterator = gtk_container_get_children (GTK_CONTAINER (widget));
- for (iterator; iterator; iterator = g_list_next (iterator))
- hildon_change_style_recursive_from_ld (iterator->data, prev_style, ld);
- }
-
- /* gtk_widget_modify_*() emit "style_set" signals, so if we got here from
- "style_set" signal, we need to block this function from being called
- again or we get into inifinite loop.
-
- FIXME: Compiling with gcc > 3.3 and -pedantic won't allow
- conversion between function and object pointers. GLib API however
- requires an object pointer for a function, so we have to work
- around this.
- See http://bugzilla.gnome.org/show_bug.cgi?id=310175
- */
- G_GNUC_EXTENSION
- g_signal_handlers_block_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
- g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)),
- 0, NULL,
- (gpointer) hildon_change_style_recursive_from_ld,
- NULL);
-
- if (ld->logicalcolorstring != NULL)
- {
- /* Changing logical color */
- GdkColor color;
- gtk_widget_ensure_style (widget);
- if (gtk_style_lookup_logical_color (widget->style, ld->logicalcolorstring, &color) == TRUE)
- switch (ld->rcflags)
- {
- case GTK_RC_FG:
- gtk_widget_modify_fg (widget, ld->state, &color);
- break;
- case GTK_RC_BG:
- gtk_widget_modify_bg (widget, ld->state, &color);
- break;
- case GTK_RC_TEXT:
- gtk_widget_modify_text (widget, ld->state, &color);
- break;
- case GTK_RC_BASE:
- gtk_widget_modify_base (widget, ld->state, &color);
- break;
- } else
- {
- g_warning ("Failed to lookup '%s' color!", ld->logicalcolorstring);
- }
- }
-
- if (ld->logicalfontstring != NULL)
- {
- /* Changing logical font */
- GtkStyle *fontstyle = gtk_rc_get_style_by_paths (gtk_settings_get_default (), ld->logicalfontstring, NULL, G_TYPE_NONE);
- if (fontstyle != NULL)
- {
- PangoFontDescription *fontdesc = fontstyle->font_desc;
-
- if (fontdesc != NULL)
- gtk_widget_modify_font (widget, fontdesc);
- }
- }
-
-
- /* FIXME: Compilation workaround for gcc > 3.3 + -pedantic again */
- G_GNUC_EXTENSION
- g_signal_handlers_unblock_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
- g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)),
- 0, NULL,
- (gpointer) hildon_change_style_recursive_from_ld,
- NULL);
-}
-
-static void hildon_logical_data_free (HildonLogicalData *ld)
-{
- g_return_if_fail (ld != NULL);
-
- if (ld->logicalcolorstring)
- g_free(ld->logicalcolorstring);
-
- if (ld->logicalfontstring)
- g_free(ld->logicalfontstring);
-
- g_free(ld);
-}
-
-/**
- * hildon_gtk_widget_set_logical_font:
- * @widget : A @GtkWidget to assign this logical font for.
- * @logicalfontname : A gchar* with the logical font name to assign to the widget with an "osso-" -prefix.
- *
- * This function assigns a defined logical font to the @widget and all its child widgets.
- * It also connects to the "style_set" signal which will retrieve & assign the new font for the given logical name each time the theme is changed.
- * The returned signal id can be used to disconnect the signal.
- * The previous signal (obtained by calling this function) is disconnected automatically and should not be used.
- *
- * Return value : The signal id that is triggered every time theme is changed. 0 if font set failed.
- **/
-gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, const gchar *logicalfontname)
-{
- HildonLogicalData *ld;
- gulong signum = 0;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- g_return_val_if_fail (logicalfontname != NULL, 0);
-
- ld = g_malloc (sizeof (HildonLogicalData));
-
- ld->rcflags = 0;
- ld->state = 0;
- ld->logicalcolorstring = NULL;
- ld->logicalfontstring = g_strdup(logicalfontname);
-
- /* Disconnects the previously connected signals. That calls the closure notify
- * and effectively disposes the allocated data (hildon_logical_data_free) */
- g_signal_handlers_disconnect_matched (G_OBJECT (widget), G_SIGNAL_MATCH_FUNC,
- 0, NULL, NULL,
- G_CALLBACK (hildon_change_style_recursive_from_ld), NULL);
-
- /* Change the font now */
- hildon_change_style_recursive_from_ld (widget, NULL, ld);
-
- /* Connect to "style_set" so that the font gets changed whenever theme changes. */
- signum = g_signal_connect_data (G_OBJECT (widget), "style_set",
- G_CALLBACK (hildon_change_style_recursive_from_ld),
- ld, (GClosureNotify) hildon_logical_data_free, 0);
-
- return signum;
-}
-
-/**
- * hildon_gtk_widget_set_logical_color:
- * @widget : A @GtkWidget to assign this logical font for.
- * @rcflags : @GtkRcFlags enumeration defining whether to assign to FG, BG, TEXT or BASE style.
- * @state : @GtkStateType indicating to which state to assign the logical color
- * @logicalcolorname : A gchar* with the logical font name to assign to the widget.
- *
- * This function assigns a defined logical color to the @widget and all it's child widgets.
- * It also connects to the "style_set" signal which will retrieve & assign the new color for the given logical name each time the theme is changed.
- * The returned signal id can be used to disconnect the signal.
- * The previous signal (obtained by calling this function) is disconnected automatically and should not be used.
- *
- * Example : If the style you want to modify is bg[NORMAL] then set rcflags to GTK_RC_BG and state to GTK_STATE_NORMAL.
- *
- * Return value : The signal id that is triggered every time theme is changed. 0 if color set failed.
- **/
-gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags,
- GtkStateType state, const gchar *logicalcolorname)
-{
- HildonLogicalData *ld;
- gulong signum = 0;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
- g_return_val_if_fail (logicalcolorname != NULL, 0);
-
- ld = g_malloc (sizeof (HildonLogicalData));
-
- ld->rcflags = rcflags;
- ld->state = state;
- ld->logicalcolorstring = g_strdup(logicalcolorname);
- ld->logicalfontstring = NULL;
-
- /* Disconnects the previously connected signals. That calls the closure notify
- * and effectively disposes the allocated data (hildon_logical_data_free) */
- g_signal_handlers_disconnect_matched (G_OBJECT (widget), G_SIGNAL_MATCH_FUNC,
- 0, NULL, NULL,
- G_CALLBACK (hildon_change_style_recursive_from_ld), NULL);
-
- /* Change the colors now */
- hildon_change_style_recursive_from_ld (widget, NULL, ld);
-
- /* Connect to "style_set" so that the colors gets changed whenever theme */
- signum = g_signal_connect_data (G_OBJECT (widget), "style_set",
- G_CALLBACK (hildon_change_style_recursive_from_ld),
- ld, (GClosureNotify) hildon_logical_data_free, 0);
-
- return signum;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_DEFINES_H__
-#define __HILDON_DEFINES_H__
-
-#include <gtk/gtkwindow.h>
-#include <gdk/gdkkeysyms.h>
-#include "hildon-appview.h"
-
-G_BEGIN_DECLS
-
-void hildon_icon_sizes_init (void);
-
-typedef struct _HildonIconSizes HildonIconSizes;
-
-struct _HildonIconSizes
-{
- GtkIconSize icon_size_list;
- GtkIconSize icon_size_small;
- GtkIconSize icon_size_toolbar;
- GtkIconSize icon_size_widg;
- GtkIconSize icon_size_widg_wizard;
- GtkIconSize icon_size_grid;
- GtkIconSize icon_size_big_note;
- GtkIconSize icon_size_note;
- GtkIconSize icon_size_statusbar;
- GtkIconSize icon_size_indi_video_player_pre_roll;
- GtkIconSize icon_size_indi_key_pad_lock;
- GtkIconSize icon_size_indi_copy;
- GtkIconSize icon_size_indi_delete;
- GtkIconSize icon_size_indi_process;
- GtkIconSize icon_size_indi_progressball;
- GtkIconSize icon_size_indi_send;
- GtkIconSize icon_size_indi_offmode_charging;
- GtkIconSize icon_size_indi_tap_and_hold;
- GtkIconSize icon_size_indi_send_receive;
- GtkIconSize icon_size_indi_wlan_strength;
- GtkIconSize image_size_indi_nokia_logo;
- GtkIconSize image_size_indi_startup_failed;
- GtkIconSize image_size_indi_startup_nokia_logo;
- GtkIconSize image_size_indi_nokia_hands;
-};
-
-extern const HildonIconSizes *hildoniconsizes;
-
-#define HILDON_ICON_SIZE_CHECK_AND_GET(iconvar) (!hildoniconsizes ? hildon_icon_sizes_init (), hildoniconsizes->iconvar : hildoniconsizes->iconvar)
-
-#define HILDON_ICON_SIZE_LIST HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_list)
-#define HILDON_ICON_SIZE_SMALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_small)
-#define HILDON_ICON_SIZE_TOOLBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_toolbar)
-#define HILDON_ICON_SIZE_WIDG HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg)
-#define HILDON_ICON_SIZE_WIDG_WIZARD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg_wizard)
-#define HILDON_ICON_SIZE_GRID HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_grid)
-#define HILDON_ICON_SIZE_BIG_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_big_note)
-#define HILDON_ICON_SIZE_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_note)
-#define HILDON_ICON_SIZE_STATUSBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_statusbar)
-#define HILDON_ICON_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_video_player_pre_roll)
-#define HILDON_ICON_SIZE_INDI_COPY HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_copy)
-#define HILDON_ICON_SIZE_INDI_DELETE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_delete)
-#define HILDON_ICON_SIZE_INDI_PROCESS HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_process)
-#define HILDON_ICON_SIZE_INDI_PROGRESSBALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_progressball)
-#define HILDON_ICON_SIZE_INDI_SEND HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send)
-#define HILDON_ICON_SIZE_INDI_OFFMODE_CHARGING HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_offmode)
-#define HILDON_ICON_SIZE_INDI_TAP_AND_HOLD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_tap_and_hold)
-#define HILDON_ICON_SIZE_INDI_SEND_RECEIVE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send_receive)
-#define HILDON_ICON_SIZE_INDI_WLAN_STRENGTH HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_wlan_strength)
-
-#define HILDON_IMAGE_SIZE_INDI_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_logo)
-#define HILDON_IMAGE_SIZE_INDI_STARTUP_FAILED HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_failed)
-#define HILDON_IMAGE_SIZE_INDI_STARTUP_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_logo)
-#define HILDON_IMAGE_SIZE_INDI_NOKIA_HAND HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_hands)
-
-#define HILDON_ICON_PIXEL_SIZE_LIST 64
-#define HILDON_ICON_PIXEL_SIZE_SMALL 26
-#define HILDON_ICON_PIXEL_SIZE_TOOLBAR 26
-#define HILDON_ICON_PIXEL_SIZE_WIDG 26
-#define HILDON_ICON_PIXEL_SIZE_WIDG_WIZARD 50
-#define HILDON_ICON_PIXEL_SIZE_GRID 64
-#define HILDON_ICON_PIXEL_SIZE_BIG_NOTE 50
-#define HILDON_ICON_PIXEL_SIZE_NOTE 26
-#define HILDON_ICON_PIXEL_SIZE_STATUSBAR 40
-#define HILDON_ICON_PIXEL_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_KEY_PAD_LOCK 50
-#define HILDON_ICON_PIXEL_SIZE_INDI_COPY 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_DELETE 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_PROCESS 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_PROGRESSBALL 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_SEND 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_OFFMODE_CHARGING 50
-#define HILDON_ICON_PIXEL_SIZE_INDI_TAP_AND_HOLD 34
-#define HILDON_ICON_PIXEL_SIZE_INDI_SEND_RECEIVE 64
-#define HILDON_ICON_PIXEL_SIZE_INDI_WLAN_STRENGTH 64
-
-#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_LOGO 64
-#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_FAILED 64
-#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_NOKIA_LOGO 64
-#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_HANDS 64
-
-#define HILDON_MARGIN_HALF 3
-#define HILDON_MARGIN_DEFAULT 6
-#define HILDON_MARGIN_DOUBLE 12
-#define HILDON_MARGIN_TRIPLE 18
-
-#define HILDON_HARDKEY_UP GDK_Up
-#define HILDON_HARDKEY_LEFT GDK_Left
-#define HILDON_HARDKEY_RIGHT GDK_Right
-#define HILDON_HARDKEY_DOWN GDK_Down
-#define HILDON_HARDKEY_SELECT GDK_Return
-#define HILDON_HARDKEY_MENU GDK_F4
-#define HILDON_HARDKEY_HOME GDK_F5
-#define HILDON_HARDKEY_ESC GDK_Escape
-#define HILDON_HARDKEY_FULLSCREEN GDK_F6
-#define HILDON_HARDKEY_INCREASE GDK_F7
-#define HILDON_HARDKEY_DECREASE GDK_F8
-
-gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, const gchar *logicalfontname);
-gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags,
- GtkStateType state, const gchar *logicalcolorname);
-
-G_END_DECLS
-#endif /* HILDON_DEFINES_H */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-dialoghelp
- * @short_description: A helper which contains a button in a normal dialog to
- * open a help if required
- *
- * #HildonDialoghelp is a helper that provides an API for enabling or
- * disabling a help button in the titlebar area of normal dialogs that
- * are derived from GtkDialog.
- */
-
-#include <stdlib.h>
-#include <gdk/gdkx.h>
-#include "hildon-dialoghelp.h"
-
-static guint help_signal = 0;
-
-static GdkFilterReturn
-handle_xevent(GdkXEvent * xevent, GdkEvent * event, gpointer dialog)
-{
- XAnyEvent *eventti = xevent;
-
- if (eventti->type == ClientMessage) {
- Atom help_atom, wm_atom;
- Display *disp;
- XClientMessageEvent *cm;
-
- disp = GDK_DISPLAY();
- cm = xevent;
-
- help_atom = XInternAtom(disp, "_NET_WM_CONTEXT_HELP", True);
- wm_atom = XInternAtom(disp, "WM_PROTOCOLS", True);
-
- if (cm->message_type == wm_atom && cm->data.l[0] == help_atom) {
- /* XClientMessageEvent *cm = xevent; */
- g_signal_emit(G_OBJECT(dialog), help_signal, 0);
- }
-
- return GDK_FILTER_REMOVE; /* Event handled, don't process
- further */
- }
-
- return GDK_FILTER_CONTINUE; /* Event not handled */
-}
-
-/**
- * gtk_dialog_help_enable:
- * @dialog: The dialog for which help is to be enabled.
- *
- * Enables context help button for a given dialog. The signal "help" can be
- * connected to handler by normal GTK methods. Note that this function
- * has to be called before the dialog is shown.
- *
- * The "help" signal itself has no other parameters than the dialog where
- * it is connected to, ie.:
- * void user_function(GtkDialog *dialog, gpointer user_data);
- */
-void gtk_dialog_help_enable(GtkDialog * dialog)
-{
- GdkWindow *window;
- GdkDisplay *display;
- Atom *protocols;
- Atom *list;
- Atom helpatom;
- int amount = 0;
- int n = 0;
- int i = 0;
- int help_enabled = 0;
-
- /* Create help signal if it didn't exist */
- if (help_signal == 0) {
- help_signal = g_signal_new("help", GTK_TYPE_DIALOG,
- G_SIGNAL_ACTION, (guint) - 1, NULL,
- NULL, g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- }
-
- g_return_if_fail(GTK_IS_DIALOG(dialog));
-
- gtk_widget_realize(GTK_WIDGET(dialog));
- window = GTK_WIDGET(dialog)->window;
- display = gdk_drawable_get_display (window);
-
- /* Create a list of atoms stored in GdkWindow */
- XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
- &list, &amount);
-
- protocols = (Atom *) malloc ((amount+1) * sizeof (Atom));
- helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
-
- /* Enable the dialoghelp if help_atom is in the atoms' list */
- for (i=0; i<amount; i++)
- {
- protocols[n++] = list[i];
- if (list[i] == helpatom)
- {
- help_enabled = 1;
- }
- }
- XFree (list);
-
- /* Add the help_atom to the atoms' list if it was not in it */
- if (!help_enabled)
- {
- protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
- }
-
- /* Replace the protocol property of the GdkWindow with the new atoms' list */
- XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
- free (protocols);
-
- /* Add a callback function as event filter */
- gdk_window_add_filter(window, handle_xevent, dialog);
-}
-
-
-/**
- * gtk_dialog_help_disable:
- * @dialog: The dialog for which help is to be disabled.
- *
- * Disables context help button for the given dialog.
- **/
-void gtk_dialog_help_disable(GtkDialog * dialog)
-{
- GdkWindow *window=NULL;
- GdkDisplay *display;
- Atom *protocols;
- Atom *list;
- Atom helpatom;
- int amount = 0;
- int n = 0;
- int i = 0;
-
- g_return_if_fail(GTK_IS_DIALOG(dialog));
-
- gtk_widget_realize(GTK_WIDGET(dialog));
- window = GTK_WIDGET(dialog)->window;
- display = gdk_drawable_get_display (window);
-
- /* Create a list of atoms stored in GdkWindow */
- XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
- &list, &amount);
-
- helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
- protocols = (Atom *) malloc (amount * sizeof (Atom));
-
- /* Remove the help_atom if it is in the atoms' list */
- for (i=0; i<amount; i++)
- {
- if (list[i] != helpatom)
- {
- protocols[n++] = list[i];
- }
- }
- XFree (list);
-
- /* Replace the protocol property of the GdkWindow with the new atoms' list */
- XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
- free (protocols);
-
- /* Remove the event filter */
- gdk_window_remove_filter(window, handle_xevent, dialog);
-}
-
-
-
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_DIALOG_HELP_H__
-#define __HILDON_DIALOG_HELP_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-void gtk_dialog_help_enable (GtkDialog * dialog);
-void gtk_dialog_help_disable (GtkDialog * dialog);
-
-G_END_DECLS
-
-#endif /* __HILDON_DIALOG_HELP_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-file-handling-note
- * @short_description: Displaying the notification when a move
- * operation is in progress.
- * @see_also: #HildonFileHandlingNote
- *
- * This is the notification displayed when a move operation is in
- * progress. The notification uses a progress bar to indicate the
- * progress of the operation. For operation containing multiple items, a
- * separe progress bar is shown for each item. The notification has a
- * single button, which allows users to stop the move operation.
- */
-
-#include "hildon-note.h"
-#include "hildon-file-handling-note.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <gtk/gtk.h>
-#include <libintl.h>
-#include <glib.h>
-#include <glib-object.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-/* Note types */
-#define MOVING_TYPE 0
-#define DELETING_TYPE 1
-#define OPENING_TYPE 2
-#define SAVING_TYPE 3
-
-/*#define _(String) dgettext(PACKAGE, String)*/
-#define _(String) dgettext("hildon-fm", String) /* FIXME: this file should be moved to hildon-fm */
-
-#define HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(obj)\
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_FILE_HANDLING_NOTE, HildonFileHandlingNotePrivate));
-
-typedef struct _HildonFileHandlingNotePrivate
- HildonFileHandlingNotePrivate;
-
-struct _HildonFileHandlingNotePrivate {
- guint note_type;
-};
-
-
-static HildonNote *parent_class;
-
-
-/* standard forbids empty source file, therefore the ifdef must be
- placed here. */
-
-static void
-hildon_file_handling_note_class_init(HildonFileHandlingNoteClass * class);
-
-static void hildon_file_handling_note_init(HildonFileHandlingNote *
- dialog);
-
-static void hildon_file_handling_note_finalize(GObject * obj_self);
-
-
-
-
-GType hildon_file_handling_note_get_type()
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonFileHandlingNoteClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_file_handling_note_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonFileHandlingNote),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_file_handling_note_init
- };
-
- dialog_type = g_type_register_static(HILDON_TYPE_NOTE,
- "HildonFileHandlingNote",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-static void
-hildon_file_handling_note_class_init(HildonFileHandlingNoteClass * class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(class);
-
- parent_class = g_type_class_peek_parent(class);
- g_type_class_add_private(class, sizeof(HildonFileHandlingNotePrivate));
- object_class->finalize = hildon_file_handling_note_finalize;
-}
-
-static void hildon_file_handling_note_init(HildonFileHandlingNote * dialog)
-{
- HildonFileHandlingNotePrivate *priv;
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(dialog);
- priv->note_type = OPENING_TYPE;
-}
-
-static void hildon_file_handling_note_finalize(GObject * obj_self)
-{
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(obj_self);
-}
-
-/**
- * hildon_file_handling_note_set_counter_and_name:
- * @note: the #HildonFileHandlingNote widget
- * @current: progress, current item being processed
- * @maximum: maximum value for counter (number of items)
- * @name: filename
- *
- * This function sets current counter value, maximum
- * counter value and filename for dialog
- *
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-void hildon_file_handling_note_set_counter_and_name(HildonFileHandlingNote
- * note, guint current,
- guint maximum,
- const gchar * name)
-{
- gchar str[255];
- HildonNote *p_note = HILDON_NOTE(note);
- HildonFileHandlingNotePrivate *priv;
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(note);
-
- if (priv->note_type == MOVING_TYPE) {
- if (maximum == 1)
- {
- g_snprintf(str, 255, _("sfil_nw_moving_file"), name);
- hildon_note_set_button_text(p_note, _("sfil_bd_moving_file"));
- } else {
- g_snprintf(str, 255, _("docm_nw_moving_files"),
- current, maximum, name);
- hildon_note_set_button_text(p_note, _("docm_bd_moving_files"));
- }
- } else if (priv->note_type == SAVING_TYPE) {
- if (maximum == 1)
- {
- g_snprintf(str, 255, _("docm_nw_saving_file"), name);
- hildon_note_set_button_text(p_note, _("docm_bd_saving_file"));
- } else {
- g_snprintf(str, 255, _("docm_nw_saving_files"),
- current, maximum, name);
- hildon_note_set_button_text(p_note, _("docm_bd_saving_files"));
- }
- } else if (priv->note_type == OPENING_TYPE) {
- if (maximum == 1)
- {
- g_snprintf(str, 255, _("docm_nw_opening_file"), name);
- hildon_note_set_button_text(p_note, _("docm_bd_opening_file"));
- } else {
- g_snprintf(str, 255, _("docm_nw_opening_files"),
- current, maximum, name);
- hildon_note_set_button_text(p_note, _("docm_bd_opening_files"));
- }
- } else if (priv->note_type == DELETING_TYPE) {
- if (maximum == 1)
- {
- g_snprintf(str, 255, _("docm_nw_deleting_file"), name);
- hildon_note_set_button_text(p_note, _("docm_bd_deleting_file"));
- } else {
- g_snprintf(str, 255, _("docm_nw_deleting_files"),
- current, maximum, name);
- hildon_note_set_button_text(p_note, _("docm_bd_deleting_files"));
- }
- }
-
- g_object_set(p_note, "description", str, NULL);
-}
-
-/**
- * hildon_file_handling_note_set_name:
- * @note: the @HildonFileHandlingNote widget
- * @name: filename
- *
- * This function sets the filename for dialog
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-void hildon_file_handling_note_set_name(HildonFileHandlingNote * note,
- const gchar * name)
-{
- gchar str[255];
- HildonNote *p_note = HILDON_NOTE(note);
- HildonFileHandlingNotePrivate *priv =
- HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(note);
-
- if (priv->note_type == MOVING_TYPE) {
- g_snprintf(str, 255, _("sfil_nw_moving_file"), name);
- } else if (priv->note_type == SAVING_TYPE) {
- g_snprintf(str, 255, _("docm_nw_saving_file"), name);
- } else if (priv->note_type == OPENING_TYPE) {
- g_snprintf(str, 255, _("docm_nw_opening_file"), name);
- } else if (priv->note_type == DELETING_TYPE) {
- g_snprintf(str, 255, _("docm_nw_deleting_file"), name);
- }
-
- g_object_set(p_note, "description", str, NULL);
-}
-
-/**
- * hildon_file_handling_note_set_fraction:
- * @note: the @HildonFileHandlingNote widget
- * @frac: value for progress bar
-
- * This function sets fraction value for
- * progress bar.
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-void hildon_file_handling_note_set_fraction(HildonFileHandlingNote * note,
- gfloat frac)
-{
- GtkWidget *progbar;
-
- g_object_get(note, "progressbar", &progbar, NULL);
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progbar), frac);
-}
-
-/**
- * hildon_file_handling_note_new_moving:
- * @parent: parent GtkWindow
- *
- * This function creates new dialog
- * which is "moving" type.
- *
- * Returns: a new #HildonFileHandlingNote
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-GtkWidget *hildon_file_handling_note_new_moving(GtkWindow * parent)
-{
- GtkWidget *progbar;
- HildonFileHandlingNote *file_note;
- HildonFileHandlingNotePrivate *priv;
-
- progbar = gtk_progress_bar_new();
-
- file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
- "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
- "description", _("sfil_nw_moving_file"),
- "progressbar", progbar, NULL);
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
- priv->note_type = MOVING_TYPE;
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
-
- return GTK_WIDGET(file_note);
-}
-
-/**
- * hildon_file_handling_note_new_deleting:
- * @parent: parent GtkWindow
- *
- * This function creates new dialog
- * which is "deleting" type.
- *
- * Returns: a new #HildonFileHandlingNote
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-GtkWidget *hildon_file_handling_note_new_deleting(GtkWindow * parent)
-{
- GtkWidget *progbar;
- HildonFileHandlingNote *file_note;
- HildonFileHandlingNotePrivate *priv;
-
- progbar = gtk_progress_bar_new();
-
- file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
- "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
- "description", _("docm_nw_deleting_file"),
- "progressbar", progbar, NULL);
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
- priv->note_type = DELETING_TYPE;
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
-
- return GTK_WIDGET(file_note);
-}
-
-/**
- * hildon_file_handling_note_new_opening:
- * @parent: parent GtkWindow
- *
- * This function creates new dialog
- * which is "opening" type
- *
- * Returns: a new #HildonFileHandlingNote
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-GtkWidget *hildon_file_handling_note_new_opening(GtkWindow * parent)
-{
- GtkWidget *progbar;
- HildonFileHandlingNote *file_note;
- HildonFileHandlingNotePrivate *priv;
-
- progbar = gtk_progress_bar_new();
-
- file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
- "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
- "description", _("docm_nw_opening_file"),
- "progressbar", progbar, NULL);
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
- priv->note_type = OPENING_TYPE;
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
-
- return GTK_WIDGET(file_note);
-}
-
-/**
- * hildon_file_handling_note_new_saving:
- * @parent: parent GtkWindow
- *
- * This function creates new dialog
- * which is "saving" type.
- *
- * Returns: a new #HildonFileHandlingNote
- * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
- */
-GtkWidget *hildon_file_handling_note_new_saving(GtkWindow * parent)
-{
- GtkWidget *progbar;
- HildonFileHandlingNote *file_note;
- HildonFileHandlingNotePrivate *priv;
-
- progbar = gtk_progress_bar_new();
-
- file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
- "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
- "description", _("docm_nw_saving_file"),
- "progressbar", progbar, NULL);
-
- priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
- priv->note_type = SAVING_TYPE;
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
-
- return GTK_WIDGET(file_note);
-}
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_FILE_HANDLING_NOTE_H__
-#define __HILDON_FILE_HANDLING_NOTE_H__
-
-
-#ifndef HILDON_DISABLE_DEPRECATED
-
-#include "hildon-note.h"
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_FILE_HANDLING_NOTE \
- ( hildon_file_handling_note_get_type() )
-#define HILDON_FILE_HANDLING_NOTE(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_FILE_HANDLING_NOTE,\
- HildonFileHandlingNote))
-#define HILDON_FILE_HANDLING_NOTE_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_FILE_HANDLING_NOTE,\
- HildonFileHandlingNoteClass))
-#define HILDON_IS_FILE_HANDLING_NOTE(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_FILE_HANDLING_NOTE))
-#define HILDON_IS_FILE_HANDLING_NOTE_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_FILE_HANDLING_NOTE))
-typedef struct _HildonFileHandlingNote HildonFileHandlingNote;
-typedef struct _HildonFileHandlingNoteClass HildonFileHandlingNoteClass;
-
-struct _HildonFileHandlingNote {
- HildonNote parent;
-};
-
-struct _HildonFileHandlingNoteClass {
- HildonNoteClass parent_class;
-};
-
-/* Note creation functions */
-GtkWidget *hildon_file_handling_note_new_moving(GtkWindow * parent);
-GtkWidget *hildon_file_handling_note_new_deleting(GtkWindow * parent);
-GtkWidget *hildon_file_handling_note_new_opening(GtkWindow * parent);
-GtkWidget *hildon_file_handling_note_new_saving(GtkWindow * parent);
-
-/* Function for progressbar status setting */
-void hildon_file_handling_note_set_fraction(HildonFileHandlingNote * note,
- gfloat frac);
-void hildon_file_handling_note_set_counter_and_name(HildonFileHandlingNote
- * note, guint current,
- guint maximum,
- const gchar * name);
-void hildon_file_handling_note_set_name(HildonFileHandlingNote * note,
- const gchar * name);
-
-GType hildon_file_handling_note_get_type(void);
-
-G_END_DECLS
-#endif /* HILDON_DISABLE_DEPRECATED */
-
-#endif /* __HILDON_FILE_HANDLING_NOTE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-find-toolbar
- * @short_description: A special toolbar to be used with HildonAppView
- * @see_also: #HildonAppView
- *
- * HildonFindToolbar is a predefined toolbar for text searching purpose.
- * It contains a GtkListStore which has the text items that the user has
- * searched. But once the application is terminated, or HildonFindToolbar
- * is trashed. Programmer is responsible for getting the GtkListStore through
- * property "list", if he/she wants to use the information in the future.
- * And through the same property, programmer is able to set the GtkListStore.
- * Note, once the search button is pressed, string in the GtkComboxEntry is
- * automatically added to the existing model, unless it is empty.
- */
-
-#include "hildon-find-toolbar.h"
-#include "hildon-defines.h"
-#include <gdk/gdkkeysyms.h>
-
-#include <gtk/gtklabel.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtktoolbutton.h>
-#include <gtk/gtktoolitem.h>
-#include <gtk/gtkcomboboxentry.h>
-#include <gtk/gtkseparatortoolitem.h>
-#include <string.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-/*same define as gtkentry.c as entry will further handle this*/
-#define MAX_SIZE G_MAXUSHORT
-#define FIND_LABEL_XPADDING 6
-#define FIND_LABEL_YPADDING 0
-
-enum
-{
- SEARCH = 0,
- CLOSE,
- INVALID_INPUT,
- HISTORY_APPEND,
-
- LAST_SIGNAL
-};
-
-enum
-{
- PROP_LABEL = 1,
- PROP_PREFIX,
- PROP_LIST,
- PROP_COLUMN,
- PROP_MAX,
- PROP_HISTORY_LIMIT
-};
-
-struct _HildonFindToolbarPrivate
-{
- GtkWidget* label;
- GtkComboBoxEntry* entry_combo_box;
- GtkToolItem* find_button;
- GtkToolItem* separator;
- GtkToolItem* close_button;
-
- gint history_limit;
-};
-static guint HildonFindToolbar_signal[LAST_SIGNAL] = {0};
-
-G_DEFINE_TYPE(HildonFindToolbar, hildon_find_toolbar, GTK_TYPE_TOOLBAR)
-
-static GtkTreeModel *
-hildon_find_toolbar_get_list_model(HildonFindToolbarPrivate *priv)
-{
- GtkTreeModel *filter_model =
- gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box));
-
- return filter_model == NULL ? NULL :
- gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(filter_model));
-}
-
-static GtkEntry *
-hildon_find_toolbar_get_entry(HildonFindToolbarPrivate *priv)
-{
- return GTK_ENTRY(gtk_bin_get_child(GTK_BIN(priv->entry_combo_box)));
-}
-
-static gboolean
-hildon_find_toolbar_filter(GtkTreeModel *model,
- GtkTreeIter *iter,
- gpointer self)
-{
- GtkTreePath *path;
- const gint *indices;
- gint n;
- gint limit;
- gint total;
-
- total = gtk_tree_model_iter_n_children(model, NULL);
- g_object_get(self, "history_limit", &limit, NULL);
- path = gtk_tree_model_get_path(model, iter);
- indices = gtk_tree_path_get_indices (path);
-
- /* set the row's index, list store has only one level */
- n = indices[0];
- gtk_tree_path_free(path);
-
- /*if the row is among the latest "history_limit" additions of the
- * model, then we show it */
- if( (total - limit <= n) && (n < total) )
- return TRUE;
- else
- return FALSE;
-}
-
-static void
-hildon_find_toolbar_apply_filter(HildonFindToolbar *self, GtkTreeModel *model)
-{
- GtkTreeModel *filter;
- HildonFindToolbarPrivate *priv = self->priv;
-
- /* Create a filter for the given model. Its only purpose is to hide
- the oldest entries so only "history_limit" entries are visible. */
- filter = gtk_tree_model_filter_new(model, NULL);
-
- gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
- hildon_find_toolbar_filter,
- self, NULL);
- gtk_combo_box_set_model(GTK_COMBO_BOX(priv->entry_combo_box), filter);
-
- /* ComboBox keeps the only needed reference to the filter */
- g_object_unref(filter);
-}
-
-static void
-hildon_find_toolbar_get_property(GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(object)->priv;
- const gchar *string;
- gint c_n, max_len;
-
- switch (prop_id)
- {
- case PROP_LABEL:
- string = gtk_label_get_text(GTK_LABEL(priv->label));
- g_value_set_string(value, string);
- break;
- case PROP_PREFIX:
- string = gtk_entry_get_text(hildon_find_toolbar_get_entry(priv));
- g_value_set_string(value, string);
- break;
- case PROP_LIST:
- g_value_set_object(value, hildon_find_toolbar_get_list_model(priv));
- break;
- case PROP_COLUMN:
- c_n = gtk_combo_box_entry_get_text_column(priv->entry_combo_box);
- g_value_set_int(value, c_n);
- break;
- case PROP_MAX:
- max_len = gtk_entry_get_max_length(hildon_find_toolbar_get_entry(priv));
- g_value_set_int(value, max_len);
- break;
- case PROP_HISTORY_LIMIT:
- g_value_set_int(value, priv->history_limit);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_find_toolbar_set_property(GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HildonFindToolbar *self = HILDON_FIND_TOOLBAR(object);
- HildonFindToolbarPrivate *priv = self->priv;
- GtkTreeModel *model;
- const gchar *string;
-
- switch (prop_id)
- {
- case PROP_LABEL:
- string = g_value_get_string(value);
- gtk_label_set_text(GTK_LABEL(priv->label), string);
- break;
- case PROP_PREFIX:
- string = g_value_get_string(value);
- gtk_entry_set_text(hildon_find_toolbar_get_entry(priv), string);
- break;
- case PROP_LIST:
- model = GTK_TREE_MODEL(g_value_get_object(value));
- hildon_find_toolbar_apply_filter(self, model);
- break;
- case PROP_COLUMN:
- gtk_combo_box_entry_set_text_column(priv->entry_combo_box,
- g_value_get_int(value));
- break;
- case PROP_MAX:
- gtk_entry_set_max_length(hildon_find_toolbar_get_entry(priv),
- g_value_get_int(value));
- break;
- case PROP_HISTORY_LIMIT:
- priv->history_limit = g_value_get_int(value);
-
- /* Re-apply the history limit to the model. */
- model = hildon_find_toolbar_get_list_model(priv);
- if (model != NULL)
- {
- /* Note that refilter function doesn't update the status of the
- combobox popup arrow, so we'll just recreate the filter. */
- hildon_find_toolbar_apply_filter(self, model);
-
- if (gtk_combo_box_entry_get_text_column(priv->entry_combo_box) == -1)
- {
- /* FIXME: This is only for backwards compatibility, although
- probably nothing actually relies on it. The behavior was only
- an accidental side effect of original code */
- gtk_combo_box_entry_set_text_column(priv->entry_combo_box, 0);
- }
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-hildon_find_toolbar_find_string(HildonFindToolbar *self,
- GtkTreeIter *iter,
- gint column,
- const gchar *string)
-{
- GtkTreeModel *model = NULL;
- gchar *old_string;
-
- model = hildon_find_toolbar_get_list_model(self->priv);
-
- if (gtk_tree_model_get_iter_first(model, iter))
- {
- do {
- gtk_tree_model_get(model, iter, column, &old_string, -1);
- if (old_string != NULL && strcmp(string, old_string) == 0)
- {
- /* Found it */
- return TRUE;
- }
- } while (gtk_tree_model_iter_next(model, iter));
- }
-
- return FALSE;
-}
-
-static gboolean
-hildon_find_toolbar_history_append(HildonFindToolbar *self,
- gpointer data)
-{
- HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(self)->priv;
- gchar *string;
- gint column = 0;
- GtkTreeModel *model = NULL;
- GtkListStore *list = NULL;
- GtkTreeIter iter;
- gboolean self_create = FALSE;
-
- g_object_get(self, "prefix", &string, NULL);
-
- if (*string == '\0')
- {
- /* empty prefix, ignore */
- g_free(string);
- return TRUE;
- }
-
-
- /* If list store is set, get it */
- model = hildon_find_toolbar_get_list_model(priv);
- if(model != NULL)
- {
- list = GTK_LIST_STORE(model);
- g_object_get(self, "column", &column, NULL);
-
- if (column < 0)
- {
- /* Column number is -1 if "column" property hasn't been set but
- "list" property is. */
- g_free(string);
- return TRUE;
- }
-
- /* Latest string is always the first one in list. If the string
- already exists, remove it so there are no duplicates in list. */
- if (hildon_find_toolbar_find_string(self, &iter, column, string))
- gtk_list_store_remove(list, &iter);
- }
- else
- {
- /* No list store set. Create our own. */
- list = gtk_list_store_new(1, G_TYPE_STRING);
- model = GTK_TREE_MODEL(list);
- self_create = TRUE;
- }
-
- /* Add the string to first in list */
- gtk_list_store_append(list, &iter);
- gtk_list_store_set(list, &iter, column, string, -1);
-
- if(self_create)
- {
- /* Add the created list to ComboBoxEntry */
- hildon_find_toolbar_apply_filter(self, model);
- /* ComboBoxEntry keeps the only needed reference to this list */
- g_object_unref(list);
-
- /* Set the column only after ComboBoxEntry's model is set
- in hildon_find_toolbar_apply_filter() */
- g_object_set(self, "column", 0, NULL);
- }
- else
- {
- /* Refilter to get the oldest entry hidden from history */
- gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(
- gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box))));
- }
-
- g_free(string);
-
- return TRUE;
-}
-
-static void
-hildon_find_toolbar_emit_search(GtkButton *button, gpointer self)
-{
- gboolean rb;
-
- /* Clicked search button. Perform search and add search prefix to history */
- g_signal_emit_by_name(self, "search", NULL);
- g_signal_emit_by_name(self, "history_append", &rb, NULL);
-}
-
-static void
-hildon_find_toolbar_emit_close(GtkButton *button, gpointer self)
-{
- HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(self)->priv;
- GtkWidget *entry = gtk_bin_get_child(GTK_BIN(priv->entry_combo_box));
- if (GTK_WIDGET_HAS_FOCUS(entry))
- {
- hildon_gtk_im_context_hide(GTK_ENTRY(entry)->im_context);
- }
- /* Clicked close button */
- g_signal_emit_by_name(self, "close", NULL);
-}
-
-static void
-hildon_find_toolbar_emit_invalid_input(GtkEntry *entry,
- GtkInvalidInputType type,
- gpointer self)
-{
- if(type == GTK_INVALID_INPUT_MAX_CHARS_REACHED)
- g_signal_emit_by_name(self, "invalid_input", NULL);
-}
-
-static void
-hildon_find_toolbar_entry_activate (GtkWidget *widget,
- gpointer user_data)
-{
- GtkWidget *find_toolbar = GTK_WIDGET(user_data);
- gboolean rb;
-
- /* NB#40936 stop focus from moving to next widget */
- g_signal_stop_emission_by_name (widget, "activate");
-
- g_signal_emit_by_name(find_toolbar, "search", NULL);
- g_signal_emit_by_name(find_toolbar, "history_append", &rb, NULL);
-}
-
-static void
-hildon_find_toolbar_class_init(HildonFindToolbarClass *klass)
-{
- GObjectClass *object_class;
-
- g_type_class_add_private(klass, sizeof(HildonFindToolbarPrivate));
-
- object_class = G_OBJECT_CLASS(klass);
-
- object_class->get_property = hildon_find_toolbar_get_property;
- object_class->set_property = hildon_find_toolbar_set_property;
-
- klass->history_append = hildon_find_toolbar_history_append;
-
- g_object_class_install_property(object_class, PROP_LABEL,
- g_param_spec_string("label",
- "Label", "Displayed name for"
- " find-toolbar",
- _("ecdg_ti_find_toolbar_label"),
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(object_class, PROP_PREFIX,
- g_param_spec_string("prefix",
- "Prefix", "Search string", NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_LIST,
- g_param_spec_object("list",
- "List"," GtkListStore model where "
- "history list is kept",
- GTK_TYPE_LIST_STORE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_COLUMN,
- g_param_spec_int("column",
- "Column", "Column number in GtkListStore "
- "where history list strings are kept",
- 0, G_MAXINT,
- 0, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_MAX,
- g_param_spec_int("max_characters",
- "Maximum number of characters",
- "Maximum number of characters "
- "in search string",
- 0, MAX_SIZE,
- 0, G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(object_class, PROP_HISTORY_LIMIT,
- g_param_spec_int("history_limit",
- "Maximum number of history items",
- "Maximum number of history items "
- "in search combobox",
- 0, G_MAXINT,
- 5, G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- /**
- * HildonFindToolbar::search:
- * @toolbar: the toolbar which received the signal
- *
- * Gets emitted when the find button is pressed.
- */
- HildonFindToolbar_signal[SEARCH] =
- g_signal_new(
- "search", HILDON_TYPE_FIND_TOOLBAR,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
- (HildonFindToolbarClass, search),
- NULL, NULL, gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /**
- * HildonFindToolbar::close:
- * @toolbar: the toolbar which received the signal
- *
- * Gets emitted when the close button is pressed.
- */
- HildonFindToolbar_signal[CLOSE] =
- g_signal_new(
- "close", HILDON_TYPE_FIND_TOOLBAR,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
- (HildonFindToolbarClass, close),
- NULL, NULL, gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /**
- * HildonFindToolbar::invalid-input:
- * @toolbar: the toolbar which received the signal
- *
- * Gets emitted when the maximum search prefix length is reached and
- * user tries to type more.
- */
- HildonFindToolbar_signal[INVALID_INPUT] =
- g_signal_new(
- "invalid_input", HILDON_TYPE_FIND_TOOLBAR,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
- (HildonFindToolbarClass, invalid_input),
- NULL, NULL, gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- /**
- * HildonFindToolbar::history-append:
- * @toolbar: the toolbar which received the signal
- *
- * Gets emitted when the current search prefix should be added to history.
- */
- HildonFindToolbar_signal[HISTORY_APPEND] =
- g_signal_new(
- "history_append", HILDON_TYPE_FIND_TOOLBAR,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
- (HildonFindToolbarClass, history_append),
- g_signal_accumulator_true_handled, NULL,
- gtk_marshal_BOOLEAN__VOID,
- G_TYPE_BOOLEAN, 0);
-}
-
-static void
-hildon_find_toolbar_init(HildonFindToolbar *self)
-{
- GtkToolItem *label_container;
- GtkToolItem *entry_combo_box_container;
-
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
- HILDON_TYPE_FIND_TOOLBAR,
- HildonFindToolbarPrivate);
-
- /* Create the label */
- self->priv->label = gtk_label_new(_("ecdg_ti_find_toolbar_label"));
-
- gtk_misc_set_padding (GTK_MISC(self->priv->label), FIND_LABEL_XPADDING,
- FIND_LABEL_YPADDING);
-
- label_container = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(label_container),
- self->priv->label);
- gtk_widget_show_all(GTK_WIDGET(label_container));
- gtk_toolbar_insert (GTK_TOOLBAR(self), label_container, -1);
-
- /* ComboBoxEntry for search prefix string / history list */
- self->priv->entry_combo_box = GTK_COMBO_BOX_ENTRY(gtk_combo_box_entry_new());
- g_signal_connect(hildon_find_toolbar_get_entry(self->priv),
- "invalid_input",
- G_CALLBACK(hildon_find_toolbar_emit_invalid_input), self);
- entry_combo_box_container = gtk_tool_item_new();
- gtk_tool_item_set_expand(entry_combo_box_container, TRUE);
- gtk_container_add(GTK_CONTAINER(entry_combo_box_container),
- GTK_WIDGET(self->priv->entry_combo_box));
- gtk_widget_show_all(GTK_WIDGET(entry_combo_box_container));
- gtk_toolbar_insert (GTK_TOOLBAR(self), entry_combo_box_container, -1);
- g_signal_connect(hildon_find_toolbar_get_entry(self->priv),
- "activate",
- G_CALLBACK(hildon_find_toolbar_entry_activate), self);
-
- /* Find button */
- self->priv->find_button = gtk_tool_button_new (
- gtk_image_new_from_icon_name ("qgn_toolb_browser_gobutton",
- HILDON_ICON_SIZE_TOOLBAR),
- "Find");
- g_signal_connect(self->priv->find_button, "clicked",
- G_CALLBACK(hildon_find_toolbar_emit_search), self);
- gtk_widget_show_all(GTK_WIDGET(self->priv->find_button));
- gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->find_button, -1);
- if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->find_button)->child) )
- GTK_WIDGET_UNSET_FLAGS(
- GTK_BIN(self->priv->find_button)->child, GTK_CAN_FOCUS);
-
- /* Separator */
- self->priv->separator = gtk_separator_tool_item_new();
- gtk_widget_show(GTK_WIDGET(self->priv->separator));
- gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->separator, -1);
-
- /* Close button */
- self->priv->close_button = gtk_tool_button_new (
- gtk_image_new_from_icon_name ("qgn_toolb_gene_close",
- HILDON_ICON_SIZE_TOOLBAR),
- "Close");
- g_signal_connect(self->priv->close_button, "clicked",
- G_CALLBACK(hildon_find_toolbar_emit_close), self);
- gtk_widget_show_all(GTK_WIDGET(self->priv->close_button));
- gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->close_button, -1);
- if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->close_button)->child) )
- GTK_WIDGET_UNSET_FLAGS(
- GTK_BIN(self->priv->close_button)->child, GTK_CAN_FOCUS);
-}
-
-/*Public functions*/
-
-/**
- * hildon_find_toolbar_new:
- * @label: label for the find_toolbar, NULL to set the label to
- * default "Find"
- *
- * Returns a new HildonFindToolbar.
- *
- * Returns: a new HildonFindToolbar
- */
-
-GtkWidget *
-hildon_find_toolbar_new(const gchar *label)
-{
- GtkWidget *findtoolbar;
-
- findtoolbar = GTK_WIDGET(g_object_new(HILDON_TYPE_FIND_TOOLBAR, NULL));
- if(label != NULL)
- g_object_set(findtoolbar, "label", label, NULL);
-
- return findtoolbar;
-}
-
-/**
- * hildon_find_toolbar_new_with_model
- * @label: label for the find_toolbar, NULL to set the label to
- * default "Find"
- * @model: a @GtkListStore
- * @column: indicating which column the search histry list will
- * retreive string from
- *
- * Returns a new HildonFindToolbar, with a model.
- *
- * Returns: a new #HildonFindToolbar
- */
-GtkWidget *
-hildon_find_toolbar_new_with_model(const gchar *label,
- GtkListStore *model,
- gint column)
-{
- GtkWidget *findtoolbar;
-
- findtoolbar = hildon_find_toolbar_new(label);
- g_object_set(findtoolbar, "list", model,
- "column", column, NULL);
-
- return findtoolbar;
-}
-
-/**
- * hildon_find_toolbar_highlight_entry
- * @ftb: find Toolbar whose entry is to be highlighted
- * @get_focus: if user passes TRUE to this value, then the text in
- * the entry will not only get highlighted, but also get focused.
- *
- */
-void
-hildon_find_toolbar_highlight_entry(HildonFindToolbar *ftb,
- gboolean get_focus)
-{
- GtkEntry *entry = NULL;
-
- g_return_if_fail(HILDON_IS_FIND_TOOLBAR(ftb));
-
- entry = hildon_find_toolbar_get_entry(ftb->priv);
-
- gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
-
- if(get_focus)
- gtk_widget_grab_focus(GTK_WIDGET(entry));
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_FIND_TOOLBAR_H__
-#define __HILDON_FIND_TOOLBAR_H__
-
-#include <gtk/gtktoolbar.h>
-#include <gtk/gtkliststore.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_FIND_TOOLBAR (hildon_find_toolbar_get_type())
-#define HILDON_FIND_TOOLBAR(object) \
- (G_TYPE_CHECK_INSTANCE_CAST((object), HILDON_TYPE_FIND_TOOLBAR, \
- HildonFindToolbar))
-#define HILDON_FIND_TOOLBARClass(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR, \
- HildonFindToolbarClass))
-#define HILDON_IS_FIND_TOOLBAR(object) \
- (G_TYPE_CHECK_INSTANCE_TYPE((object), HILDON_TYPE_FIND_TOOLBAR))
-#define HILDON_IS_FIND_TOOLBAR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR))
-#define HILDON_FIND_TOOLBAR_GET_CLASS(object) \
- (G_TYPE_INSTANCE_GET_CLASS((object), HILDON_TYPE_FIND_TOOLBAR, \
- HildonFindToolbarClass))
-
-typedef struct _HildonFindToolbar HildonFindToolbar;
-typedef struct _HildonFindToolbarClass HildonFindToolbarClass;
-typedef struct _HildonFindToolbarPrivate HildonFindToolbarPrivate;
-
-struct _HildonFindToolbar
-{
- GtkToolbar parent;
-
- HildonFindToolbarPrivate *priv;
-};
-
-struct _HildonFindToolbarClass
-{
- GtkToolbarClass parent_class;
-
- void (*search) (HildonFindToolbar *toolbar);
- void (*close) (HildonFindToolbar *toolbar);
- void (*invalid_input) (HildonFindToolbar *toolbar);
- gboolean (*history_append) (HildonFindToolbar *tooblar);
-};
-
-GType hildon_find_toolbar_get_type (void) G_GNUC_CONST;
-GtkWidget* hildon_find_toolbar_new (const gchar *label);
-GtkWidget* hildon_find_toolbar_new_with_model (const gchar *label,
- GtkListStore*
- model,
- gint column);
-void hildon_find_toolbar_highlight_entry (HildonFindToolbar *ftb,
- gboolean get_focus);
-
-G_END_DECLS
-
-#endif /* __HILDON_FIND_TOOLBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-font-selection-dialog
- * @short_description: A widget used to allow users to select a font
- * with certain properties
- *
- * Font selection can be made using this widget. Users can select font name,
- * size, style, etc. Users can also preview text in the selected font.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtkstock.h>
-#include <gtk/gtkcombobox.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtkcheckbutton.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkliststore.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtk.h>
-#include <glib.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "hildon-font-selection-dialog.h"
-#include <hildon-widgets/hildon-caption.h>
-#include <hildon-widgets/hildon-color-selector.h>
-#include <hildon-widgets/hildon-color-button.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-#define SUPERSCRIPT_RISE 3333
-#define SUBSCRIPT_LOW -3333
-#define ON_BIT 0x01
-#define OFF_BIT 0x02
-
-/*
- * These are what we use as the standard font sizes, for the size list.
- */
-static const guint16 font_sizes[] =
-{
- 6, 8, 10, 12, 16, 24, 32
-};
-
-#define HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(obj) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_FONT_SELECTION_DIALOG, \
- HildonFontSelectionDialogPrivate))
-
-/*None of designed api function works, so now it all comes down to
- *use properties to achieve what we are supposed to achieve*/
-enum
-{
- PROP_FAMILY = 1,
- PROP_FAMILY_SET,
- PROP_SIZE,
- PROP_SIZE_SET,
- PROP_COLOR,
- PROP_COLOR_SET,
- PROP_BOLD,
- PROP_BOLD_SET,
- PROP_ITALIC,
- PROP_ITALIC_SET,
- PROP_UNDERLINE,
- PROP_UNDERLINE_SET,
- PROP_STRIKETHROUGH,
- PROP_STRIKETHROUGH_SET,
- PROP_POSITION,
- PROP_POSITION_SET,
- PROP_PREVIEW_TEXT,
- PROP_FONT_SCALING
-};
-
-typedef struct
-_HildonFontSelectionDialogPrivate HildonFontSelectionDialogPrivate;
-
-struct _HildonFontSelectionDialogPrivate
-{
- GtkNotebook *notebook;
-
- gchar *preview_text;
-
- /*Tab one*/
- GtkWidget *cbx_font_type;
- GtkWidget *cbx_font_size;
- GtkWidget *font_color_button;
-
- /*Tab two*/
- GtkWidget *chk_bold;
- GtkWidget *chk_italic;
- GtkWidget *chk_underline;
-
- /*Tab three*/
- GtkWidget *chk_strikethrough;
- GtkWidget *cbx_positioning;
-
- /*Every family*/
- PangoFontFamily **families;
- gint n_families;
-
- /*color_set is used to show whether the color is inconsistent
- * The handler id is used to block the signal emission
- * when we change the color setting*/
-
- gboolean color_set;
-
- /* font_scaling is the scaling factor applied to font
- * scale in the preview dialog */
-
- gdouble font_scaling;
- gulong color_modified_signal_handler;
-};
-
-/*combo box active row indicator -2--inconsistent, -1--undefined
- * please make sure that you use settings_init settings_apply
- * and settings_destroy, dont even try to touch this structure
- * without using the three above interface functions, of course
- * if you know what you are doing, do as you please ;-)*/
-typedef struct
-{
- HildonFontSelectionDialog
- *fsd; /*pointer to our font selection dialog*/
-
- gint family; /*combo box indicator*/
- gint size; /*combo box indicator*/
- GdkColor *color; /*free after read the setting*/
- gboolean color_inconsist;
- gint weight; /*bit mask*/
- gint style; /*bit mask*/
- gint underline; /*bit mask*/
- gint strikethrough; /*bit mask*/
- gint position; /*combo box indicator*/
-
-}HildonFontSelectionDialogSettings;
-
-static gboolean
- hildon_font_selection_dialog_preview_key_press
- (GtkWidget * widget,
- GdkEventKey * event,
- gpointer unused);
-
-/*Some tools from gtk_font_selection*/
-static int cmp_families (const void *a, const void *b);
-
-static void hildon_font_selection_dialog_show_preview
- (HildonFontSelectionDialog
- *fontsel);
-
-static PangoAttrList*
- hildon_font_selection_dialog_create_attrlist
- (HildonFontSelectionDialog
- *fontsel, guint start_index,
- guint len);
-
-static void hildon_font_selection_dialog_show_available_positionings
- (HildonFontSelectionDialogPrivate
- *priv);
-
-static void hildon_font_selection_dialog_show_available_fonts
- (HildonFontSelectionDialog
- *fontsel);
-
-static void hildon_font_selection_dialog_show_available_sizes
- (HildonFontSelectionDialogPrivate
- *priv);
-
-static void hildon_font_selection_dialog_class_init
- (HildonFontSelectionDialogClass
- *klass);
-
-static void hildon_font_selection_dialog_init
- (HildonFontSelectionDialog
- *fontseldiag);
-
-static void hildon_font_selection_dialog_finalize
- (GObject * object);
-
-static void hildon_font_selection_dialog_construct_notebook
- (HildonFontSelectionDialog
- *fontsel);
-
-static void color_modified_cb (HildonColorButton *button,
- GParamSpec *pspec,
- gpointer fsd_priv);
-
-static void check_tags (gpointer data,
- gpointer user_data);
-
-static void settings_init (HildonFontSelectionDialogSettings
- *setttings,
- HildonFontSelectionDialog
- *fsd);
-
-static void settings_apply (HildonFontSelectionDialogSettings
- *setttings);
-
-static void settings_destroy (HildonFontSelectionDialogSettings
- *setttings);
-
-static void bit_mask_toggle (gint mask, GtkToggleButton*
- button, GObject *object,
- const gchar *prop,
- const gchar *prop_set);
-
-static void combo_active (gint active, GtkComboBox *box,
- GObject *object,
- const gchar *prop,
- const gchar *prop_set);
-
-static void add_preview_text_attr (PangoAttrList *list,
- PangoAttribute *attr,
- guint start,
- guint len);
-
-static void toggle_clicked (GtkButton *button,
- gpointer unused);
-
-
-
-static GtkDialogClass *font_selection_dialog_parent_class = NULL;
-
-GType hildon_font_selection_dialog_get_type(void)
-{
- static GType font_selection_dialog_type = 0;
-
- if (!font_selection_dialog_type) {
- static const GTypeInfo fontsel_diag_info = {
- sizeof(HildonFontSelectionDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_font_selection_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonFontSelectionDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_font_selection_dialog_init,
- };
-
- font_selection_dialog_type =
- g_type_register_static(GTK_TYPE_DIALOG,
- "HildonFontSelectionDialog",
- &fontsel_diag_info, 0);
- }
-
- return font_selection_dialog_type;
-}
-
-static void
-hildon_font_selection_dialog_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- gint i;
- GdkColor *color = NULL;
-
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
- HILDON_FONT_SELECTION_DIALOG(object));
-
-
- switch (prop_id)
- {
- case PROP_FAMILY:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
- if(i >= 0 && i < priv->n_families)
- g_value_set_string(value,
- pango_font_family_get_name(priv->families[i]));
- else
- g_value_set_string(value, "Sans");
- break;
-
- case PROP_FAMILY_SET:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
- if(i >= 0 && i < priv->n_families)
- g_value_set_boolean(value, TRUE);
- else
- g_value_set_boolean(value, FALSE);
- break;
-
- case PROP_SIZE:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
- if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
- g_value_set_int(value, font_sizes[i]);
- else
- g_value_set_int(value, 16);
- break;
-
- case PROP_SIZE_SET:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
- if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
- g_value_set_boolean(value, TRUE);
- else
- g_value_set_boolean(value, FALSE);
- break;
-
- case PROP_COLOR:
- color = hildon_color_button_get_color
- (HILDON_COLOR_BUTTON(priv->font_color_button));
- g_value_set_boxed(value, (gconstpointer) color);
- if(color != NULL)
- gdk_color_free(color);
- break;
-
- case PROP_COLOR_SET:
- g_value_set_boolean(value, priv->color_set);
- break;
-
- case PROP_BOLD:
- g_value_set_boolean(value,
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->chk_bold)));
- break;
-
- case PROP_BOLD_SET:
- g_value_set_boolean(value,
- !gtk_toggle_button_get_inconsistent
- (GTK_TOGGLE_BUTTON(priv->chk_bold)));
- break;
-
- case PROP_ITALIC:
- g_value_set_boolean(value,
- gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(priv->chk_italic)));
- break;
-
- case PROP_ITALIC_SET:
- g_value_set_boolean(value,
- !gtk_toggle_button_get_inconsistent
- (GTK_TOGGLE_BUTTON(priv->chk_italic)));
- break;
-
- case PROP_UNDERLINE:
- g_value_set_boolean(value,
- gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(priv->chk_underline)));
- break;
-
- case PROP_UNDERLINE_SET:
- g_value_set_boolean(value,
- !gtk_toggle_button_get_inconsistent
- (GTK_TOGGLE_BUTTON(priv->chk_underline)));
- break;
-
- case PROP_STRIKETHROUGH:
- g_value_set_boolean(value,
- gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
- break;
-
- case PROP_STRIKETHROUGH_SET:
- g_value_set_boolean(value,
- !gtk_toggle_button_get_inconsistent
- (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
- break;
-
- case PROP_POSITION:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
- if(i == 1)/*super*/
- g_value_set_int(value, 1);
- else if(i == 2)/*sub*/
- g_value_set_int(value, -1);
- else
- g_value_set_int(value, 0);
- break;
-
- case PROP_FONT_SCALING:
- g_value_set_double(value, priv->font_scaling);
- break;
-
- case PROP_POSITION_SET:
- i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
- if(i >= 0 && i < 3)
- g_value_set_boolean(value, TRUE);
- else
- g_value_set_boolean(value, FALSE);
- break;
-
- case PROP_PREVIEW_TEXT:
- g_value_set_string(value,
- hildon_font_selection_dialog_get_preview_text(
- HILDON_FONT_SELECTION_DIALOG(object)));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_font_selection_dialog_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- gint i, size;
- const gchar *str;
- gboolean b;
- GdkColor *color = NULL;
- GdkColor black;
-
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
- HILDON_FONT_SELECTION_DIALOG(object));
- black.red = black.green = black.blue = 0;
-
- switch (prop_id)
- {
- case PROP_FAMILY:
- str = g_value_get_string(value);
- for(i = 0; i < priv->n_families; i++)
- {
- if(strcmp(str, pango_font_family_get_name(priv->families[i]))
- == 0)
- {
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), i);
- break;
- }
- }
- break;
-
- case PROP_FAMILY_SET:
- b = g_value_get_boolean(value);
- if(!b)
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), -1);
- break;
-
- case PROP_SIZE:
- size = g_value_get_int(value);
- for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
- {
- if(size == font_sizes[i])
- {
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), i);
- break;
- }
- }
- break;
-
- case PROP_SIZE_SET:
- b = g_value_get_boolean(value);
- if(!b)
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), -1);
- break;
-
- case PROP_COLOR:
- color = (GdkColor *) g_value_get_boxed(value);
- if(color != NULL)
- hildon_color_button_set_color(HILDON_COLOR_BUTTON
- (priv->font_color_button),
- color);
- else
- hildon_color_button_set_color(HILDON_COLOR_BUTTON
- (priv->font_color_button),
- &black);
- break;
-
- case PROP_COLOR_SET:
- priv->color_set = g_value_get_boolean(value);
- if(!priv->color_set)
- {
- /*set color to black, but block our signal handler*/
- g_signal_handler_block((gpointer) priv->font_color_button,
- priv->color_modified_signal_handler);
-
- hildon_color_button_set_color(HILDON_COLOR_BUTTON
- (priv->font_color_button),
- &black);
-
- g_signal_handler_unblock((gpointer) priv->font_color_button,
- priv->color_modified_signal_handler);
- }
- break;
-
- case PROP_BOLD:
- /*this call will make sure that we dont get extra clicked signal*/
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
- FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_bold),
- g_value_get_boolean(value));
- break;
-
- case PROP_BOLD_SET:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
- !g_value_get_boolean(value));
- break;
-
- case PROP_ITALIC:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
- FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
- g_value_get_boolean(value));
- break;
-
- case PROP_ITALIC_SET:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
- !g_value_get_boolean(value));
- break;
-
- case PROP_UNDERLINE:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
- (priv->chk_underline),
- FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
- g_value_get_boolean(value));
- break;
-
- case PROP_UNDERLINE_SET:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
- !g_value_get_boolean(value));
- break;
-
- case PROP_STRIKETHROUGH:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
- (priv->chk_strikethrough),
- FALSE);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
- g_value_get_boolean(value));
- break;
-
- case PROP_STRIKETHROUGH_SET:
- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
- (priv->chk_strikethrough),
- !g_value_get_boolean(value));
- break;
-
- case PROP_POSITION:
- i = g_value_get_int(value);
- if( i == 1 )
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
- else if(i == -1)
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
- else
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
- break;
-
- case PROP_FONT_SCALING:
- priv->font_scaling = g_value_get_double(value);
- break;
-
- case PROP_POSITION_SET:
- b = g_value_get_boolean(value);
- if(!b)
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
- break;
-
- case PROP_PREVIEW_TEXT:
- hildon_font_selection_dialog_set_preview_text(
- HILDON_FONT_SELECTION_DIALOG(object),
- g_value_get_string(value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_font_selection_dialog_class_init(HildonFontSelectionDialogClass *
- klass)
-{
- GObjectClass *gobject_class;
-
- font_selection_dialog_parent_class = g_type_class_peek_parent(klass);
- gobject_class = G_OBJECT_CLASS(klass);
- gobject_class->finalize = hildon_font_selection_dialog_finalize;
- gobject_class->get_property = hildon_font_selection_dialog_get_property;
- gobject_class->set_property = hildon_font_selection_dialog_set_property;
-
- /* Install property to the class */
- g_object_class_install_property(gobject_class, PROP_FAMILY,
- g_param_spec_string("family",
- "Font family", "String defines"
- " the font family", "Sans",
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_FAMILY_SET,
- g_param_spec_boolean ("family-set",
- "family inconsistent state",
- "Whether the family property"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_SIZE,
- g_param_spec_int ("size",
- "Font size",
- "Font size in Pt",
- 6, 32, 16,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_SIZE_SET,
- g_param_spec_boolean ("size-set",
- "size inconsistent state",
- "Whether the size property"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_COLOR,
- g_param_spec_boxed ("color",
- "text color",
- "gdk color for the text",
- GDK_TYPE_COLOR,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_COLOR_SET,
- g_param_spec_boolean ("color-set",
- "color inconsistent state",
- "Whether the color property"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_BOLD,
- g_param_spec_boolean ("bold",
- "text weight",
- "Whether the text is bold",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_BOLD_SET,
- g_param_spec_boolean ("bold-set",
- "bold inconsistent state",
- "Whether the bold"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_ITALIC,
- g_param_spec_boolean ("italic",
- "text style",
- "Whether the text is italic",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_ITALIC_SET,
- g_param_spec_boolean ("italic-set",
- "italic inconsistent state",
- "Whether the italic"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_UNDERLINE,
- g_param_spec_boolean ("underline",
- "text underline",
- "Whether the text is underlined",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_UNDERLINE_SET,
- g_param_spec_boolean ("underline-set",
- "underline inconsistent state",
- "Whether the underline"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH,
- g_param_spec_boolean ("strikethrough",
- "strikethroughed text",
- "Whether the text is strikethroughed",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH_SET,
- g_param_spec_boolean ("strikethrough-set",
- "strikethrough inconsistent state",
- "Whether the strikethrough"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_POSITION,
- g_param_spec_int ("position",
- "Font position",
- "Font position super or subscript",
- -1, 1, 0,
- G_PARAM_READWRITE));
-
- /* FIXME This was introduced in 0.14.1. We don't have documentation for
- * properties anyways, but once it's there it needs to be marked as
- * Since: 0.14.1 */
- g_object_class_install_property(gobject_class, PROP_FONT_SCALING,
- g_param_spec_double ("font-scaling",
- "Font scaling",
- "Font scaling for the preview dialog",
- 0, 10, 1,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_POSITION_SET,
- g_param_spec_boolean ("position-set",
- "position inconsistent state",
- "Whether the position"
- " is inconsistent", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- g_object_class_install_property(gobject_class, PROP_PREVIEW_TEXT,
- g_param_spec_string("preview-text",
- "Preview Text",
- "the text in preview dialog, which does"
- "not include the reference text",
- "",
- G_PARAM_READWRITE));
-
-
- g_type_class_add_private(klass,
- sizeof(struct _HildonFontSelectionDialogPrivate));
-}
-
-
-static void
-hildon_font_selection_dialog_init(HildonFontSelectionDialog *fontseldiag)
-{
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontseldiag);
- GtkWidget *preview_button;
-
- priv->notebook = GTK_NOTEBOOK(gtk_notebook_new());
-
- hildon_font_selection_dialog_construct_notebook(fontseldiag);
-
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->vbox),
- GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
-
- /* Add dialog buttons */
- gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
- _("ecdg_bd_font_dialog_ok"),
- GTK_RESPONSE_OK);
-
- preview_button = gtk_button_new_with_label(_("ecdg_bd_font_dialog_preview"));
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->action_area),
- preview_button, FALSE, TRUE, 0);
- g_signal_connect_swapped(preview_button, "clicked",
- G_CALLBACK
- (hildon_font_selection_dialog_show_preview),
- fontseldiag);
- gtk_widget_show(preview_button);
-
- gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
- _("ecdg_bd_font_dialog_cancel"),
- GTK_RESPONSE_CANCEL);
-
- /*Set default preview text*/
- priv->preview_text = g_strdup(_("ecdg_fi_preview_font_preview_text"));
-
- gtk_window_set_title(GTK_WINDOW(fontseldiag), _("ecdg_ti_font"));
- /*here is the line to make sure that notebook has the default focus*/
- gtk_container_set_focus_child(GTK_CONTAINER(GTK_DIALOG(fontseldiag)->vbox),
- GTK_WIDGET(priv->notebook));
-}
-
-static void
-hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog
- *fontsel)
-{
- gint i;
- GtkWidget *vbox_tab[3];
- GtkWidget *font_color_box;
- GtkWidget *caption_control;
- GtkSizeGroup *group;
-
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
-
- for (i = 0; i < 3; i++)
- vbox_tab[i] = gtk_vbox_new(TRUE, 0);
-
- group =
- GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
-
- /* Build the first page of the GtkNotebook: font style */
- priv->cbx_font_type = gtk_combo_box_new_text();
- hildon_font_selection_dialog_show_available_fonts(fontsel);
- caption_control = hildon_caption_new(group,
- _("ecdg_fi_font_font"),
- priv->cbx_font_type,
- NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
- FALSE, FALSE, 0);
-
- priv->cbx_font_size = gtk_combo_box_new_text();
- hildon_font_selection_dialog_show_available_sizes(priv);
- caption_control = hildon_caption_new(group,
- _("ecdg_fi_font_size"),
- priv->cbx_font_size,
- NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
- FALSE, FALSE, 0);
-
- font_color_box = gtk_hbox_new(FALSE, 0);
- priv->font_color_button = hildon_color_button_new();
- priv->color_set = FALSE;
- priv->font_scaling = 1.0;
- priv->color_modified_signal_handler =
- g_signal_connect(G_OBJECT(priv->font_color_button), "notify::color",
- G_CALLBACK(color_modified_cb), (gpointer) priv);
- gtk_box_pack_start(GTK_BOX(font_color_box),
- priv->font_color_button, FALSE, FALSE, 0);
-
- caption_control =
- hildon_caption_new(group, _("ecdg_fi_font_colour_selector"),
- font_color_box,
- NULL, HILDON_CAPTION_OPTIONAL);
-
- gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
- FALSE, FALSE, 0);
-
- /* Build the second page of the GtkNotebook: font formatting */
- priv->chk_bold = gtk_check_button_new();
- caption_control = hildon_caption_new(group,
- _("ecdg_fi_font_bold"),
- priv->chk_bold,
- NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
- FALSE, FALSE, 0);
- g_signal_connect(G_OBJECT(priv->chk_bold), "clicked",
- G_CALLBACK(toggle_clicked), NULL);
-
- priv->chk_italic = gtk_check_button_new();
- caption_control =
- hildon_caption_new(group, _("ecdg_fi_font_italic"),
- priv->chk_italic,
- NULL, HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
- FALSE, FALSE, 0);
- g_signal_connect(G_OBJECT(priv->chk_italic), "clicked",
- G_CALLBACK(toggle_clicked), NULL);
-
- priv->chk_underline = gtk_check_button_new();
- caption_control =
- hildon_caption_new(group, _("ecdg_fi_font_underline"),
- priv->chk_underline, NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
- FALSE, FALSE, 0);
- g_signal_connect(G_OBJECT(priv->chk_underline), "clicked",
- G_CALLBACK(toggle_clicked), NULL);
-
- /* Build the third page of the GtkNotebook: other font properties */
- priv->chk_strikethrough = gtk_check_button_new();
- caption_control =
- hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
- priv->chk_strikethrough, NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
- FALSE, FALSE, 0);
- g_signal_connect(G_OBJECT(priv->chk_strikethrough), "clicked",
- G_CALLBACK(toggle_clicked), NULL);
-
- priv->cbx_positioning = gtk_combo_box_new_text();
- hildon_font_selection_dialog_show_available_positionings(priv);
- caption_control =
- hildon_caption_new(group, _("ecdg_fi_font_special"),
- priv->cbx_positioning, NULL,
- HILDON_CAPTION_OPTIONAL);
- gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
- FALSE, FALSE, 0);
-
- /* Populate notebook */
- gtk_notebook_insert_page(priv->notebook, vbox_tab[0], NULL, 0);
- gtk_notebook_insert_page(priv->notebook, vbox_tab[1], NULL, 1);
- gtk_notebook_insert_page(priv->notebook, vbox_tab[2], NULL, 2);
- gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[0],
- _("ecdg_ti_font_dialog_style"));
- gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[1],
- _("ecdg_ti_font_dialog_format"));
- gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[2],
- _("ecdg_ti_font_dialog_other"));
-
- gtk_widget_show_all(GTK_WIDGET(priv->notebook));
-}
-
-static void
-color_modified_cb(HildonColorButton *button,
- GParamSpec *pspec,
- gpointer fsd_priv)
-{
- HildonFontSelectionDialogPrivate *priv =
- (HildonFontSelectionDialogPrivate *) fsd_priv;
-
- priv->color_set = TRUE;
-}
-
-static void
-hildon_font_selection_dialog_finalize(GObject * object)
-{
- HildonFontSelectionDialogPrivate *priv;
- HildonFontSelectionDialog *fontsel;
-
- g_assert(HILDON_IS_FONT_SELECTION_DIALOG(object));
- fontsel = HILDON_FONT_SELECTION_DIALOG(object);
-
- priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
-
- g_free(priv->preview_text);
- g_free(priv->families);
-
- if (G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize)
- G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize(object);
-}
-
-static int
-cmp_families(const void *a, const void *b)
-{
- const char *a_name =
- pango_font_family_get_name(*(PangoFontFamily **) a);
- const char *b_name =
- pango_font_family_get_name(*(PangoFontFamily **) b);
-
- return g_utf8_collate(a_name, b_name);
-}
-
-/* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
- * was pressed */
-static gboolean
-hildon_font_selection_dialog_preview_key_press(GtkWidget * widget,
- GdkEventKey * event,
- gpointer unused)
-{
- g_assert(widget);
- g_assert(event);
-
- if (event->keyval == GDK_Escape)
- {
- gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-add_preview_text_attr(PangoAttrList *list, PangoAttribute *attr,
- guint start, guint len)
-{
- attr->start_index = start;
- attr->end_index = start + len;
- pango_attr_list_insert(list, attr);
-}
-
-static PangoAttrList*
-hildon_font_selection_dialog_create_attrlist(HildonFontSelectionDialog *
- fontsel, guint start_index, guint len)
-{
- PangoAttrList *list;
- PangoAttribute *attr;
- gint size, position;
- gboolean family_set, size_set, color_set, bold, bold_set,
- italic, italic_set, underline, underline_set,
- strikethrough, strikethrough_set, position_set;
- GdkColor *color = NULL;
- gchar *family = NULL;
- gdouble font_scaling = 1.0;
-
- list = pango_attr_list_new();
-
- g_object_get(G_OBJECT(fontsel),
- "family", &family, "family-set", &family_set,
- "size", &size, "size-set", &size_set,
- "color", &color, "color-set", &color_set,
- "bold", &bold, "bold-set", &bold_set,
- "italic", &italic, "italic-set", &italic_set,
- "underline", &underline, "underline-set", &underline_set,
- "strikethrough", &strikethrough, "strikethrough-set",
- &strikethrough_set, "position", &position,
- "position-set", &position_set,
- "font-scaling", &font_scaling,
- NULL);
-
- /*family*/
- if(family_set)
- {
- attr = pango_attr_family_new(family);
- add_preview_text_attr(list, attr, start_index, len);
- }
- g_free(family);
-
- /*size*/
- if(size_set)
- {
- attr = pango_attr_size_new(size * PANGO_SCALE);
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*color*/
- if(color_set)
- {
- attr = pango_attr_foreground_new(color->red, color->green, color->blue);
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- if(color != NULL)
- gdk_color_free(color);
-
- /*weight*/
- if(bold_set)
- {
- if(bold)
- attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
- else
- attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
-
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*style*/
- if(italic_set)
- {
- if(italic)
- attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
- else
- attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
-
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*underline*/
- if(underline_set)
- {
- if(underline)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
- else
- attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
-
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*strikethrough*/
- if(strikethrough_set)
- {
- if(strikethrough)
- attr = pango_attr_strikethrough_new(TRUE);
- else
- attr = pango_attr_strikethrough_new(FALSE);
-
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*position*/
- if(position_set)
- {
- switch(position)
- {
- case 1: /*super*/
- attr = pango_attr_rise_new(SUPERSCRIPT_RISE);
- break;
- case -1: /*sub*/
- attr = pango_attr_rise_new(SUBSCRIPT_LOW);
- break;
- default: /*normal*/
- attr = pango_attr_rise_new(0);
- break;
- }
-
- add_preview_text_attr(list, attr, start_index, len);
- }
-
- /*font scaling for preview*/
- if(font_scaling)
- {
- attr = pango_attr_scale_new(font_scaling);
- add_preview_text_attr(list, attr, 0, len + start_index);
- }
-
- return list;
-}
-
-static void
-hildon_font_selection_dialog_show_preview(HildonFontSelectionDialog *
- fontsel)
-{
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
- gint size;
- gboolean family_set, size_set;
- PangoAttribute *attr;
- PangoAttrList *list;
- GtkWidget *preview_dialog;
- GtkWidget *preview_label;
- gchar *str = NULL;
- gboolean position_set = FALSE;
- gint position = 0;
- gboolean show_ref = FALSE;
-
- g_object_get(G_OBJECT(fontsel), "position-set", &position_set, NULL);
- if (position_set) {
- g_object_get(G_OBJECT(fontsel), "position", &position, NULL);
- if (position == 1 || position == -1)
- show_ref = TRUE;
- }
-
- /*Preview dialog init*/
- preview_dialog=
- gtk_dialog_new_with_buttons(_("ecdg_ti_preview_font"), NULL,
- GTK_DIALOG_MODAL |
- GTK_DIALOG_DESTROY_WITH_PARENT |
- GTK_DIALOG_NO_SEPARATOR,
- _("ecdg_bd_font_dialog_ok"),
- GTK_RESPONSE_ACCEPT,
- NULL);
-
- str = (show_ref) ? g_strconcat(_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
- g_strdup (priv->preview_text);
-
- preview_label = gtk_label_new(str);
- gtk_label_set_line_wrap(GTK_LABEL(preview_label), TRUE);
-
- g_free(str);
- str = NULL;
-
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(preview_dialog)->vbox),
- preview_label);
-
-
- /* set keypress handler (ESC hardkey) */
- g_signal_connect(G_OBJECT(preview_dialog), "key-press-event",
- G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
- NULL);
-
-
- /*Set the font*/
- list = (show_ref) ? hildon_font_selection_dialog_create_attrlist(fontsel,
- strlen(_("ecdg_fi_preview_font_preview_reference")),
- strlen(priv->preview_text)) :
- hildon_font_selection_dialog_create_attrlist(fontsel,
- 0,
- strlen(priv->preview_text));
-
- g_object_get(G_OBJECT(fontsel), "family", &str, "family-set",
- &family_set, "size", &size, "size-set", &size_set,
- NULL);
-
- /* FIXME: This is a slightly ugly hack to force the width of the window so that
- * the whole text fits with various font sizes. It's being done in such a way,
- * because of some GtkLabel wrapping issues and other mysterious bugs related to
- * truncating ellipsizing. Needs a rethink in future. (MDK) */
-
- gint dialog_width = (size_set && size > 24) ? 600 : 500;
- gtk_window_set_default_size (GTK_WINDOW(preview_dialog), dialog_width, -1);
-
- /*make reference text to have the same fontface and size*/
- if(family_set)
- {
- attr = pango_attr_family_new(str);
- add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
- }
- g_free(str);
-
- /*size*/
- if(size_set)
- {
- attr = pango_attr_size_new(size * PANGO_SCALE);
- add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
- }
-
- gtk_label_set_attributes(GTK_LABEL(preview_label), list);
- pango_attr_list_unref(list);
-
- /*And show the dialog*/
- gtk_window_set_transient_for(GTK_WINDOW(preview_dialog),
- GTK_WINDOW(fontsel));
-
- gtk_widget_show_all(preview_dialog);
- gtk_dialog_run(GTK_DIALOG(preview_dialog));
- gtk_widget_destroy(preview_dialog);
-}
-
-
-static gboolean is_internal_font(const gchar * name){
- return strcmp(name, "DeviceSymbols") == 0
- || strcmp(name, "Nokia Smiley" ) == 0
- || strcmp(name, "NewCourier" ) == 0
- || strcmp(name, "NewTimes" ) == 0
- || strcmp(name, "SwissA" ) == 0
- || strcmp(name, "Nokia Sans" ) == 0
- || strcmp(name, "Nokia Sans Cn") == 0;
-}
-
-static void filter_out_internal_fonts(PangoFontFamily **families, int *n_families){
- int i;
- int n; /* counts valid fonts */
- const gchar * name = NULL;
-
- for(i = 0, n = 0; i < *n_families; i++){
-
- name = pango_font_family_get_name(families[i]);
-
- if(!is_internal_font(name)){
-
- if(i!=n){ /* there are filtered out families */
- families[n] = families[i]; /* shift the current family */
- }
-
- n++; /* count one more valid */
- }
- }/* foreach font family */
-
- *n_families = n;
-}
-
-
-static void
-hildon_font_selection_dialog_show_available_fonts(HildonFontSelectionDialog
- *fontsel)
-
-{
- gint i;
-
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
-
- pango_context_list_families(gtk_widget_get_pango_context
- (GTK_WIDGET(fontsel)), &priv->families,
- &priv->n_families);
-
- filter_out_internal_fonts(priv->families, &priv->n_families);
-
- qsort(priv->families, priv->n_families, sizeof(PangoFontFamily *),
- cmp_families);
-
-
- for (i = 0; i < priv->n_families; i++)
- {
- const gchar *name = pango_font_family_get_name(priv->families[i]);
-
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_type),
- name);
- }
-}
-
-
-static void
-hildon_font_selection_dialog_show_available_positionings
- (HildonFontSelectionDialogPrivate
- *priv)
-{
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
- _("ecdg_va_font_printpos_1"));
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
- _("ecdg_va_font_printpos_2"));
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
- _("ecdg_va_font_printpos_3"));
-}
-
-/*Loads the sizes from a pre-allocated table*/
-static void
-hildon_font_selection_dialog_show_available_sizes
- (HildonFontSelectionDialogPrivate
- *priv)
-{
- gchar *size_str;
- gint i;
-
- for (i = 0; i < G_N_ELEMENTS(font_sizes); i++)
- {
- size_str = g_strdup_printf ("%i%s",
- font_sizes[i],
- _("ecdg_va_font_size_trailer"));
-
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_size),
- size_str);
- g_free (size_str);
- }
-}
-
-/* WARNING: This function is called only from deprecated API */
-static
-void check_tags(gpointer data, gpointer user_data)
-{
- gchar *font_family;
- GdkColor *fore_color = NULL;
- gint p_size, p_weight, p_style, p_underline, p_rise;
- gboolean b_st, ff_s, size_s, fgc_s, w_s, ss_s, u_s, sth_s, r_s;
-
- GtkTextTag *tag = (GtkTextTag*) data;
- HildonFontSelectionDialogSettings *settings =
- (HildonFontSelectionDialogSettings *) user_data;
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
-
- /*get all the properties*/
- g_object_get(G_OBJECT(tag),
- "family", &font_family, "family-set", &ff_s,
- "size", &p_size, "size-set", &size_s,
- "foreground-gdk", &fore_color, "foreground-set", &fgc_s,
- "weight", &p_weight, "weight-set", &w_s,
- "style", &p_style, "style-set", &ss_s,
- "underline", &p_underline, "underline-set", &u_s,
- "strikethrough", &b_st, "strikethrough-set", &sth_s,
- "rise", &p_rise, "rise-set", & r_s,
- NULL);
-
- /* Check that the given values are valid.
- * If not, set the combobox row indicator to 'inconsistent' */
- if(ff_s)
- {
- gint new_f = -1;
- gint i;
-
- for(i = 0; i < priv->n_families; i++)
- {
- if(strcmp(font_family,
- pango_font_family_get_name(priv->families[i])) == 0)
- {
- new_f = i;
- break;
- }
- }
-
- if(settings->family == -1)
- settings->family = new_f;
- else if(settings->family != -2 &&
- settings->family != new_f)
- settings->family = -2;/*inconsist*/
-
- g_free(font_family);
- }
-
- if(size_s)
- {
- gint new_size = -1;
- gint i;
-
- for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
- {
- if(p_size == font_sizes[i] * PANGO_SCALE)
- {
- new_size = i;
- break;
- }
- }
-
- if(settings->size == -1)
- settings->size = new_size;
- else if(settings->size != -2 &&
- settings->size != new_size)
- settings->size = -2;/*inconsist*/
- }
-
- if(fgc_s && settings->color == NULL
- && !settings->color_inconsist)
- settings->color = fore_color;
- else if(fore_color != NULL)
- {
- if(!gdk_color_equal(fore_color, settings->color)
- && fgc_s)
- settings->color_inconsist = TRUE;
-
- gdk_color_free(fore_color);
- }
-
- if(w_s)
- settings->weight |= p_weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
-
- if(ss_s)
- settings->style |= p_style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT;
-
- if(u_s)
- settings->underline |=
- p_underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
-
- if(sth_s)
- settings->strikethrough |= b_st ? ON_BIT : OFF_BIT;
-
- if(r_s)
- {
- gint new_rs = -1;
-
- if(p_rise == 0)
- new_rs = 0;/*normal*/
- else if (p_rise > 0)
- new_rs = 1;/*super*/
- else
- new_rs = 2;/*sub*/
-
- if(settings->position == -1)
- settings->position = new_rs;
- else if(settings->position != -2 &&
- settings->position != new_rs)
- settings->position = -2;/*inconsist*/
- }
-}
-
-/* WARNING: This function is called only from deprecated API */
-static
-void check_attrs(gpointer data, gpointer user_data)
-{
- PangoAttribute *attr = (PangoAttribute *) data;
- HildonFontSelectionDialogSettings *settings =
- (HildonFontSelectionDialogSettings *) user_data;
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
-
- gchar *family;
- GdkColor color;
- gint i;
- gint size, weight, style, underline, strikethrough, rise;
- gint new_f = -1, new_size = -1, new_rise = -1;
-
- /* Check that the given values are valid.
- * If not, set the combobox row indicator to 'inconsistent' */
- switch(attr->klass->type)
- {
- case PANGO_ATTR_FAMILY:
- family = ((PangoAttrString *) attr)->value;
-
- for(i = 0; i < priv->n_families; i++)
- {
- if(strcmp(family,
- pango_font_family_get_name(priv->families[i])) == 0)
- {
- new_f = i;
- break;
- }
- }
-
- if(settings->family == -1)
- settings->family = new_f;
- else if(settings->family != -2 &&
- settings->family != new_f)
- settings->family = -2;/*inconsist*/
-
- break;
- case PANGO_ATTR_SIZE:
- size = ((PangoAttrInt *) attr)->value;
-
- for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
- {
- if(size == font_sizes[i] * PANGO_SCALE)
- {
- new_size = i;
- break;
- }
- }
-
- if(settings->size == -1)
- settings->size = new_size;
- else if(settings->size != -2 &&
- settings->size != new_size)
- settings->size = -2;/*inconsist*/
-
- break;
- case PANGO_ATTR_FOREGROUND:
- color.red = ((PangoAttrColor *) attr)->color.red;
- color.green = ((PangoAttrColor *) attr)->color.green;
- color.blue = ((PangoAttrColor *) attr)->color.blue;
-
- if(!settings->color_inconsist && settings->color == NULL)
- settings->color = gdk_color_copy(&color);
- else if(settings->color != NULL &&
- !gdk_color_equal(&color, settings->color))
- settings->color_inconsist = TRUE;
-
- break;
- case PANGO_ATTR_WEIGHT:
- weight = ((PangoAttrInt *) attr)->value;
-
- settings->weight |= weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
-
- break;
- case PANGO_ATTR_STYLE:
- style = ((PangoAttrInt *) attr)->value;
-
- settings->style |= style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT;
-
- break;
- case PANGO_ATTR_UNDERLINE:
- underline = ((PangoAttrInt *) attr)->value;
-
- settings->underline |=
- underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
-
- break;
- case PANGO_ATTR_STRIKETHROUGH:
- strikethrough = ((PangoAttrInt *) attr)->value;
-
- settings->strikethrough |= strikethrough ? ON_BIT : OFF_BIT;
-
- break;
- case PANGO_ATTR_RISE:
- rise = ((PangoAttrInt *) attr)->value;
-
- if(rise == 0)
- new_rise = 0;/*normal*/
- else if (rise > 0)
- new_rise = 1;/*super*/
- else
- new_rise = 2;/*sub*/
-
- if(settings->position == -1)
- settings->position = new_rise;
- else if(settings->position != -2 &&
- settings->position != new_rise)
- settings->position = -2;/*inconsist*/
-
- break;
- default:
- break;
- }
-
- pango_attribute_destroy(attr);
-}
-
-/* WARNING: This function is called only from deprecated API */
-static void
-settings_init(HildonFontSelectionDialogSettings *settings,
- HildonFontSelectionDialog *fsd)
-{
- settings->fsd = fsd;
- settings->family = -1;
- settings->size = -1;
- settings->color = NULL;
- settings->color_inconsist = FALSE;
- settings->weight = 0;
- settings->style = 0;
- settings->underline = 0;
- settings->strikethrough = 0;
- settings->position = -1;
-}
-
-/* WARNING: This function is called only from deprecated API */
-static void
-bit_mask_toggle(gint mask, GtkToggleButton *button,
- GObject *object, const gchar *prop,
- const gchar *prop_set)
-{
-
- if(mask == 3)
- gtk_toggle_button_set_inconsistent(button, TRUE);
- else
- {
- gtk_toggle_button_set_inconsistent(button, FALSE);
-
- if(mask == 1)
- gtk_toggle_button_set_active(button, TRUE);
- else
- gtk_toggle_button_set_active(button, FALSE);
-
- g_object_notify(object, prop);
- }
-
- g_object_notify(object, prop_set);
-}
-
-/* WARNING: This function is called only from deprecated API */
-static void
-combo_active(gint active, GtkComboBox *box,
- GObject *object, const gchar *prop, const gchar *prop_set)
-{
- /*probaly not the best function, but we need all these
- * parameters to keep things together*/
-
-
- if(active >= 0)
- {
- gtk_combo_box_set_active(box, active);
- g_object_notify(object, prop);
- }
- else
- gtk_combo_box_set_active(box, -1);
-
- g_object_notify(object, prop_set);
-}
-
-/* WARNING: This function is called only from deprecated API */
-static void
-settings_apply(HildonFontSelectionDialogSettings *settings)
-{
-
- HildonFontSelectionDialogPrivate *priv =
- HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
-
- /*family*/
- combo_active(settings->family, GTK_COMBO_BOX(priv->cbx_font_type),
- G_OBJECT(settings->fsd), "family", "family-set");
-
- /*size*/
- combo_active(settings->size, GTK_COMBO_BOX(priv->cbx_font_size),
- G_OBJECT(settings->fsd), "size", "size-set");
-
- /*block our signal handler indicating color has been changed by
- * the user before set the color, and unblock it after setting
- * is done*/
-
- if(settings->color == NULL || settings->color_inconsist)
- {
- GdkColor black;
-
- black.red = black.green = black.blue = 0;
- g_signal_handler_block((gpointer) priv->font_color_button,
- priv->color_modified_signal_handler);
-
- g_object_set(G_OBJECT(settings->fsd), "color", &black, "color-set",
- FALSE, NULL);
-
- g_signal_handler_unblock((gpointer) priv->font_color_button,
- priv->color_modified_signal_handler);
- }
- else
- g_object_set(G_OBJECT(settings->fsd), "color", settings->color, NULL);
-
- /*weight*/
- bit_mask_toggle(settings->weight, GTK_TOGGLE_BUTTON(priv->chk_bold),
- G_OBJECT(settings->fsd), "bold", "bold-set");
-
- /*style*/
- bit_mask_toggle(settings->style, GTK_TOGGLE_BUTTON(priv->chk_italic),
- G_OBJECT(settings->fsd), "italic", "italic-set");
-
- /*underline*/
- bit_mask_toggle(settings->underline,
- GTK_TOGGLE_BUTTON(priv->chk_underline),
- G_OBJECT(settings->fsd), "underline", "underline-set");
-
- /*strikethrough*/
- bit_mask_toggle(settings->strikethrough,
- GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
- G_OBJECT(settings->fsd), "strikethrough",
- "strikethrough-set");
-
- /*position*/
- combo_active(settings->position, GTK_COMBO_BOX(priv->cbx_positioning),
- G_OBJECT(settings->fsd), "position", "position-set");
-}
-
-static void
-settings_destroy(HildonFontSelectionDialogSettings *settings)
-{
- if(settings->color != NULL)
- gdk_color_free(settings->color);
-}
-
-static void
-toggle_clicked(GtkButton *button, gpointer unused)
-{
- GtkToggleButton *t_b = GTK_TOGGLE_BUTTON(button);
-
- /*we have to remove the inconsistent state ourselves*/
- if(gtk_toggle_button_get_inconsistent(t_b))
- {
- gtk_toggle_button_set_inconsistent(t_b, FALSE);
- gtk_toggle_button_set_active(t_b, FALSE);
- }
-}
-
-/*******************/
-/*Public functions*/
-/*******************/
-
-/**
- * hildon_font_selection_dialog_new:
- * @parent: the parent window
- * @title: the title of font selection dialog
- *
- * If NULL is passed for title, then default title
- * "Font" will be used.
- *
- * Returns: a new #HildonFontSelectionDialog
- */
-GtkWidget *
-hildon_font_selection_dialog_new(GtkWindow * parent,
- const gchar * title)
-{
- HildonFontSelectionDialog *fontseldiag;
-
- fontseldiag = g_object_new(HILDON_TYPE_FONT_SELECTION_DIALOG,
- "has-separator", FALSE, NULL);
-
- if (title)
- gtk_window_set_title(GTK_WINDOW(fontseldiag), title);
-
- if (parent)
- gtk_window_set_transient_for(GTK_WINDOW(fontseldiag), parent);
-
- return GTK_WIDGET(fontseldiag);
-}
-
-/**
- * hildon_font_selection_dialog_get_preview_text:
- * @fsd: the font selection dialog
- *
- * Gets the text in preview dialog, which does not include the
- * reference text. The returned string must be freed by the user.
- *
- * Returns: a string pointer
- */
-gchar *
-hildon_font_selection_dialog_get_preview_text(HildonFontSelectionDialog * fsd)
-{
- HildonFontSelectionDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
- priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
- return g_strdup(priv->preview_text);
-}
-
-/**
- * hildon_font_selection_dialog_set_preview_text:
- * @fsd: the font selection dialog
- * @text: the text to be displayed in the preview dialog
- *
- * The default preview text is
- * "The quick brown fox jumped over the lazy dogs"
- */
-void
-hildon_font_selection_dialog_set_preview_text(HildonFontSelectionDialog *
- fsd, const gchar * text)
-{
- HildonFontSelectionDialogPrivate *priv = NULL;
-
- g_return_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd));
- g_return_if_fail(text);
-
- priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
-
- g_free(priv->preview_text);
- priv->preview_text = g_strdup(text);
- g_object_notify (G_OBJECT (fsd), "preview-text");
-}
-
-/**
- * hildon_font_selection_dialog_get_text_tag:
- * @fsd: the font selection dialog
- *
- * Get the #GtkTextTag for selections. This function
- * is deprecated. The best way to use
- * the text tags is to reuse them as much as possible.
- * The recommended way is to get the properties of the font
- * selection dialog on GTK_RESPONSE_OK, and according to
- * these properties use the tags that you have pre-created.
- *
- * Returns: a #GtkTextTag having corresponding properties
- * set
- */
-GtkTextTag *
-hildon_font_selection_dialog_get_text_tag (HildonFontSelectionDialog *fsd)
-{
- GtkTextTag *tag;
- gint size, position;
- gboolean family_set, size_set, color_set, bold, bold_set,
- italic, italic_set, underline, underline_set,
- strikethrough, strikethrough_set, position_set;
- GdkColor *color = NULL;
- gchar *family = NULL;
-
- tag = gtk_text_tag_new(NULL);
-
- g_object_get(G_OBJECT(fsd),
- "family", &family, "family-set", &family_set,
- "size", &size, "size-set", &size_set,
- "color", &color, "color-set", &color_set,
- "bold", &bold, "bold-set", &bold_set,
- "italic", &italic, "italic-set", &italic_set,
- "underline", &underline, "underline-set", &underline_set,
- "strikethrough", &strikethrough, "strikethrough-set",
- &strikethrough_set, "position", &position,
- "position-set", &position_set, NULL);
- /*family*/
- if(family_set)
- g_object_set(G_OBJECT(tag), "family",
- family, "family-set", TRUE, NULL);
- else
- g_object_set(G_OBJECT(tag), "family-set", FALSE, NULL);
-
- g_free(family);
-
- /*size*/
- if(size_set)
- g_object_set(G_OBJECT(tag), "size", size * PANGO_SCALE,
- "size-set", TRUE, NULL);
- else
- g_object_set(G_OBJECT(tag), "size-set", FALSE, NULL);
-
- /*color*/
- if(color_set)
- g_object_set(G_OBJECT(tag), "foreground-gdk", color,
- "foreground-set", TRUE ,NULL);
- else
- g_object_set(G_OBJECT(tag), "foreground-set", FALSE, NULL);
-
- if(color != NULL)
- gdk_color_free(color);
-
- /*weight*/
- if(bold_set)
- {
- if(bold)
- g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, NULL);
- else
- g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_NORMAL, NULL);
-
- g_object_set(G_OBJECT(tag), "weight-set", TRUE, NULL);
- }
- else
- g_object_set(G_OBJECT(tag), "weight-set", FALSE, NULL);
-
- /*style*/
- if(italic_set)
- {
- if(italic)
- g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
- else
- g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
-
- g_object_set(G_OBJECT(tag), "style-set", TRUE, NULL);
- }
- else
- g_object_set(G_OBJECT(tag), "style-set", FALSE, NULL);
-
- /*underline*/
- if(underline_set)
- {
- if(underline)
- g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_SINGLE, NULL);
- else
- g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_NONE, NULL);
-
- g_object_set(G_OBJECT(tag), "underline-set", TRUE, NULL);
- }
- else
- g_object_set(G_OBJECT(tag), "underline-set", FALSE, NULL);
-
- /*strikethrough*/
- if(strikethrough_set)
- {
- if(strikethrough)
- g_object_set(G_OBJECT(tag), "strikethrough", TRUE, NULL);
- else
- g_object_set(G_OBJECT(tag), "strikethrough", FALSE, NULL);
-
- g_object_set(G_OBJECT(tag), "strikethrough-set", TRUE, NULL);
- }
- else
- g_object_set(G_OBJECT(tag), "strikethrough-set", FALSE, NULL);
-
- /*position*/
- if(position_set)
- {
- switch(position)
- {
- case 1: /*super*/
- g_object_set(G_OBJECT(tag), "rise", SUPERSCRIPT_RISE, NULL);
- break;
- case -1: /*sub*/
- g_object_set(G_OBJECT(tag), "rise", SUBSCRIPT_LOW, NULL);
- break;
- case 0: /*normal*/
- g_object_set(G_OBJECT(tag), "rise", 0, NULL);
- break;
- }
- g_object_set(G_OBJECT(tag), "rise-set", TRUE, NULL);
- }
- else
- g_object_set(G_OBJECT(tag), "rise-set", FALSE, NULL);
-
- return tag;
-}
-
-/**
- * hildon_font_selection_dialog_set_buffer:
- * @fsd: the font selection dialog
- * @buffer: a #GtkTextBuffer containing the text to which the selections will
- * be applied. Applying is responsibility of application.
- *
- * This is deprecated. GtkTextBuffer is not enough
- * to get the attributes of currently selected text. Please
- * inspect the attributes yourself, and set the properties of
- * font selection dialog to reflect your inspection.
- */
-void
-hildon_font_selection_dialog_set_buffer (HildonFontSelectionDialog *fsd,
- GtkTextBuffer *buffer)
-{
- GtkTextIter begin, end, iter;
- HildonFontSelectionDialogSettings settings;
-
- gtk_text_buffer_get_selection_bounds(buffer, &begin, &end);
-
- settings_init(&settings, fsd);
-
- iter = begin;
-
- /* Keep original settings if the selection includes nothing */
- if(gtk_text_iter_compare(&iter, &end) == 0)
- {
- GSList *slist;
-
- slist = gtk_text_iter_get_tags(&iter);
- g_slist_foreach(slist, check_tags, (gpointer) &settings);
- g_slist_free(slist);
- }
-
- /* Apply the user settings to the selected text */
- while(gtk_text_iter_compare(&iter, &end) < 0)
- {
- GSList *slist;
-
- slist = gtk_text_iter_get_tags(&iter);
- g_slist_foreach(slist, check_tags, (gpointer) &settings);
- g_slist_free(slist);
-
- if(!gtk_text_iter_forward_cursor_position(&iter))
- break;
- }
-
- settings_apply(&settings);
- settings_destroy(&settings);
-}
-
-/**
- * hildon_font_selection_dialog_get_font:
- * @fsd: the font selection dialog
- *
- * This is deprecated. @PangoAttrList needs
- * starting index, and end index on construction.
- *
- * Returns: pointer to @PangoAttrList
- */
-PangoAttrList
-*hildon_font_selection_dialog_get_font(HildonFontSelectionDialog * fsd)
-{
- HildonFontSelectionDialogPrivate *priv
- = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
-
- g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
- /*an approve of none working api, should have ask for start_index,
- * and length in bytes of the string, currently using preview_text
- * length, KLUDGE!*/
-
- return hildon_font_selection_dialog_create_attrlist(fsd,
- 0, strlen(priv->preview_text));
-}
-
-/**
- * hildon_font_selection_dialog_set_font:
- * @fsd: the font selection dialog
- * @list: the pango attribute list
- *
- * This is a deprecated.
- *
- * Sets the font to the dialog.
- */
-void
-hildon_font_selection_dialog_set_font(HildonFontSelectionDialog * fsd,
- PangoAttrList * list)
-{
- PangoAttrIterator *iter;
- HildonFontSelectionDialogSettings settings;
-
- iter = pango_attr_list_get_iterator(list);
-
- settings_init(&settings, fsd);
-
- while(iter != NULL)
- {
- GSList *slist;
-
- slist = pango_attr_iterator_get_attrs(iter);
- g_slist_foreach(slist, check_attrs, (gpointer) &settings);
- g_slist_free(slist);
-
- if(!pango_attr_iterator_next(iter))
- break;
- }
-
- pango_attr_iterator_destroy(iter);
-
- settings_apply(&settings);
- settings_destroy(&settings);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_FONT_SELECTION_DIALOG_H__
-#define __HILDON_FONT_SELECTION_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-#include <gtk/gtktextbuffer.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_FONT_SELECTION_DIALOG \
- (hildon_font_selection_dialog_get_type ())
-#define HILDON_FONT_SELECTION_DIALOG(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
- HILDON_TYPE_FONT_SELECTION_DIALOG, HildonFontSelectionDialog))
-#define HILDON_FONT_SELECTION_DIALOG_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_FONT_SELECTION_DIALOG,\
- HildonFontSelectionDialogClass))
-#define HILDON_IS_FONT_SELECTION_DIALOG(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
- HILDON_TYPE_FONT_SELECTION_DIALOG))
-#define HILDON_IS_FONT_SELECTION_DIALOG_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_FONT_SELECTION_DIALOG))
-#define HILDON_FONT_SELECTION_DIALOG_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj),\
- HILDON_TYPE_FONT_SELECTION_DIALOG,\
- HildonFontSelectionDialogClass))
-
-typedef struct _HildonFontSelectionDialog HildonFontSelectionDialog;
-typedef struct _HildonFontSelectionDialogClass HildonFontSelectionDialogClass;
-
-struct _HildonFontSelectionDialog
-{
- GtkDialog parent;
-};
-
-struct _HildonFontSelectionDialogClass
-{
- GtkDialogClass parent_class;
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-#ifndef HILDON_DISABLE_DEPRECATED
-PangoAttrList* hildon_font_selection_dialog_get_font(HildonFontSelectionDialog *fsd);
-
-void hildon_font_selection_dialog_set_font(HildonFontSelectionDialog *fsd,
- PangoAttrList *list);
-#endif
-
-
-GType hildon_font_selection_dialog_get_type (void) G_GNUC_CONST;
-
-GtkWidget* hildon_font_selection_dialog_new (GtkWindow *parent,
- const gchar *title);
-
-
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_font_selection_dialog_set_buffer (HildonFontSelectionDialog *fsd,
- GtkTextBuffer *buffer);
-
-GtkTextTag* hildon_font_selection_dialog_get_text_tag (HildonFontSelectionDialog *fsd);
-#endif
-
-
-gchar* hildon_font_selection_dialog_get_preview_text (HildonFontSelectionDialog *fsd);
-
-void hildon_font_selection_dialog_set_preview_text (HildonFontSelectionDialog *fsd,
- const gchar * text);
-
-G_END_DECLS
-
-#endif /* __HILDON_FONT_SELECTION_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-get-password-dialog
- * @short_description: A widget used to get a password
- * @see_also: #HildonSetPasswordDialog
- *
- * HildonGetPasswordDialog prompts the user for a password. It allows
- * inputting password, with an optional configurable label eg. for
- * showing the domain. The maximum length of the password can be set.
- */
-
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <gtk/gtk.h>
-
-#include "gtk-infoprint.h"
-#include "hildon-input-mode-hint.h"
-
-#include <hildon-widgets/hildon-caption.h>
-#include <hildon-widgets/hildon-get-password-dialog.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-static GtkDialogClass * parent_class;
-
-typedef struct _HildonGetPasswordDialogPrivate
- HildonGetPasswordDialogPrivate;
-
-struct _HildonGetPasswordDialogPrivate {
- GtkButton *okButton;
- GtkButton *cancelButton;
-
- GtkLabel *domainLabel;
- HildonCaption *passwordEntry;
- gboolean get_old;
-};
-
-
-#define HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_GET_PASSWORD_DIALOG, HildonGetPasswordDialogPrivate));
-
-static void
-hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass *
- class);
-static void hildon_get_password_dialog_init(HildonGetPasswordDialog *
- widget);
-static void hildon_get_password_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_get_password_get_property(GObject * object,
- guint prop_id, GValue * value,
- GParamSpec * pspec);
-static void create_contents(HildonGetPasswordDialog *dialog);
-static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason,
- gpointer unused);
-
-enum{
- PROP_NONE = 0,
- PROP_DOMAIN,
- PROP_PASSWORD,
- PROP_NUMBERS_ONLY,
- PROP_CAPTION_LABEL,
- PROP_MAX_CHARS,
- PROP_GET_OLD
-};
-
-/* Private functions */
-static void
-hildon_get_password_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
- HildonGetPasswordDialogPrivate *priv;
-
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id) {
- case PROP_DOMAIN:
- /* Set label text representing password domain */
- gtk_label_set_text(priv->domainLabel, g_value_get_string(value));
- break;
- case PROP_PASSWORD:
- gtk_entry_set_text(GTK_ENTRY
- (hildon_caption_get_control (priv->passwordEntry)),
- g_value_get_string(value));
- break;
- case PROP_NUMBERS_ONLY:
- /* Set input mode for the password entry */
- g_object_set(G_OBJECT(hildon_caption_get_control(priv->passwordEntry)),
- "input-mode",
- (g_value_get_boolean(value)
- ? HILDON_INPUT_MODE_HINT_NUMERIC
- : HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL),
- NULL);
- break;
- case PROP_CAPTION_LABEL:
- hildon_get_password_dialog_set_caption(dialog, g_value_get_string(value));
- break;
- case PROP_MAX_CHARS:
- hildon_get_password_dialog_set_max_characters(dialog,
- g_value_get_int(value));
- break;
- case PROP_GET_OLD:
- priv->get_old = g_value_get_boolean(value);
- create_contents(dialog);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_get_password_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
- HildonGetPasswordDialogPrivate *priv;
- const gchar *string;
- gint max_length;
- gint input_mode;
-
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id) {
- case PROP_DOMAIN:
- string = gtk_label_get_text(priv->domainLabel);
- g_value_set_string(value, string);
- break;
- case PROP_PASSWORD:
- string = gtk_entry_get_text(GTK_ENTRY (hildon_caption_get_control(priv->passwordEntry)));
- g_value_set_string(value, string);
- break;
- case PROP_NUMBERS_ONLY:
- /* This property is set if and only if the input mode
- of the password entry has been set to numeric only */
- g_object_get(G_OBJECT(hildon_caption_get_control(priv->passwordEntry)),
- "input-mode", &input_mode, NULL);
- g_value_set_boolean(value,
- (input_mode == HILDON_INPUT_MODE_HINT_NUMERIC));
- break;
- case PROP_CAPTION_LABEL:
- string = hildon_caption_get_label(priv->passwordEntry);
- g_value_set_string(value, string);
- break;
- case PROP_MAX_CHARS:
- max_length = gtk_entry_get_max_length(
- GTK_ENTRY (hildon_caption_get_control (priv->passwordEntry)));
- g_value_set_int(value, max_length);
- break;
- case PROP_GET_OLD:
- g_value_set_boolean(value, priv->get_old);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass * class)
-{
-
- GObjectClass *object_class = G_OBJECT_CLASS(class);
-
- parent_class = g_type_class_peek_parent(class);
-
- /* Override virtual functions */
- object_class->set_property = hildon_get_password_set_property;
- object_class->get_property = hildon_get_password_get_property;
-
- /* Install new properties */
- g_object_class_install_property
- (object_class,
- PROP_DOMAIN,
- g_param_spec_string ("domain",
- "Domain",
- "Set domain(content) for optional label.",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property
- (object_class,
- PROP_PASSWORD,
- g_param_spec_string ("password",
- "Password",
- "Set content for password entry",
- "DEFAULT",
- G_PARAM_READWRITE));
-
- g_object_class_install_property
- (object_class,
- PROP_NUMBERS_ONLY,
- g_param_spec_boolean ("numbers_only",
- "NumbersOnly",
- "Set entry to accept only numeric values",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property
- (object_class,
- PROP_CAPTION_LABEL,
- g_param_spec_string ("caption-label",
- "Caption Label",
- "The text to be set as the caption label",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property
- (object_class,
- PROP_MAX_CHARS,
- g_param_spec_int ("max-characters",
- "Maximum Characters",
- "The maximum number of characters the password"
- " dialog accepts",
- G_MININT,
- G_MAXINT,
- 0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property
- (object_class,
- PROP_GET_OLD,
- g_param_spec_boolean ("get-old",
- "Get Old Password",
- "TRUE if dialog is a get old password dialog, "
- "FALSE if dialog is a get password dialog",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /* Install private structure */
- g_type_class_add_private(class,
- sizeof(HildonGetPasswordDialogPrivate));
-}
-
-static void
-hildon_get_password_dialog_init(HildonGetPasswordDialog * dialog)
-{
- /* Set initial properties for the dialog; the actual contents are
- created once the 'get-old' property is set with g_object_new */
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-}
-
-static void
-create_contents(HildonGetPasswordDialog *dialog)
-{
- HildonGetPasswordDialogPrivate *priv;
- GtkSizeGroup * group;
- GtkWidget *control;
-
- /* Cache private pointer for faster member access */
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Sizegroup for captions */
- group = GTK_SIZE_GROUP(gtk_size_group_new
- (GTK_SIZE_GROUP_HORIZONTAL));
-
- /* Dialog title */
- gtk_window_set_title(GTK_WINDOW(dialog),
- priv->get_old
- ? _(HILDON_GET_PASSWORD_DIALOG_TITLE)
- : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_TITLE));
-
- /* Optional password domain label */
- priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
-
- /* Create buttons */
- priv->okButton =
- GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
- (priv->get_old
- ? _(HILDON_GET_PASSWORD_DIALOG_OK)
- : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_OK)),
-
- GTK_RESPONSE_OK));
- priv->cancelButton =
- GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
- (priv->get_old
- ? _(HILDON_GET_PASSWORD_DIALOG_CANCEL)
- : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_CANCEL)),
- GTK_RESPONSE_CANCEL));
-
- /* Create password text entry */
- control = gtk_entry_new();
- gtk_entry_set_width_chars (GTK_ENTRY (control), 20);
-
- g_object_set (control, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
- gtk_entry_set_visibility(GTK_ENTRY(control), FALSE);
- priv->passwordEntry = HILDON_CAPTION
- (hildon_caption_new(group,
- (priv->get_old
- ? _(HILDON_GET_PASSWORD_DIALOG_PASSWORD)
- : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_PASSWORD)),
- control, NULL,
- HILDON_CAPTION_OPTIONAL));
- hildon_caption_set_separator(HILDON_CAPTION(priv->passwordEntry), "");
-
- /* Do the basic layout */
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(priv->passwordEntry), FALSE, FALSE, 0);
- gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
-
- /* Ensure group is freed when all its contents have been removed */
- g_object_unref(group);
-}
-
-
-/* Public functions */
-
-/**
- * hildon_get_password_dialog_get_type:
- *
- * Returns GType for HildonGetPasswordDialog as produced by
- * g_type_register_static().
- *
- * Returns: HildonGetPasswordDialog type
- */
-GType hildon_get_password_dialog_get_type(void)
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonGetPasswordDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_get_password_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonGetPasswordDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_get_password_dialog_init
- };
-
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonGetPasswordDialog",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-/**
- * hildon_get_password_dialog_new:
- * @parent: parent window; can be NULL
- * @get_old: FALSE creates a new get password dialog and
- * TRUE creates a new get old password dialog. That is,
- * if the password to be obtained is the old password,
- * this parameter is specified TRUE.
- *
- * Construct a new HildonGetPasswordDialog.
- *
- * Returns: a new #GtkWidget of type HildonGetPasswordDialog
- */
-GtkWidget *hildon_get_password_dialog_new(GtkWindow * parent,
- gboolean get_old)
-{
- HildonGetPasswordDialog *dialog = g_object_new
- (HILDON_TYPE_GET_PASSWORD_DIALOG,
- "get-old", get_old, NULL);
-
- if (parent != NULL) {
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
- }
-
- return GTK_WIDGET(dialog);
-}
-
-/**
- * hildon_get_password_dialog_new_with_default:
- * @parent: parent window; can be NULL
- * @password: a default password to be shown in password field
- * @get_old: FALSE creates a new get password dialog and
- * TRUE creates a new get old password dialog.That is,
- * if the password to be obtained is the old password,
- * this parameter is specified TRUE.
- *
- *
- * Same as #hildon_get_password_dialog_new but with a default password
- * in password field.
- *
- * Returns: a new #GtkWidget of type HildonGetPasswordDialog
- */
-GtkWidget *hildon_get_password_dialog_new_with_default (GtkWindow * parent,
- const gchar *password,
- gboolean get_old)
-{
- GtkWidget *dialog;
-
- dialog = hildon_get_password_dialog_new(parent, get_old);
- if(password != NULL)
- g_object_set(G_OBJECT(dialog), "password", password, NULL);
-
- return GTK_WIDGET(dialog);
-}
-
-/**
- * hildon_get_password_dialog_get_password:
- * @dialog: pointer to HildonSetPasswordDialog
- *
- * Gets the currently inputted password.
- *
- * Returns: current password ( if the dialog is successfully
- * accepted with 'OK' )
- */
-const gchar
- *hildon_get_password_dialog_get_password(HildonGetPasswordDialog *
- dialog)
-{
- GtkEntry *entry1;
- gchar *text1;
-
- HildonGetPasswordDialogPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog), NULL);
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Retrieve the password entry widget */
- entry1 = GTK_ENTRY (hildon_caption_get_control(priv->passwordEntry));
- text1 = GTK_ENTRY(entry1)->text;
-
- return text1;
-}
-
-/**
- * hildon_get_password_dialog_set_domain(GtkWidget *dialog,
- * @dialog: the dialog
- * @domain: the domain or some other descriptive text to be set
- *
- * Sets the optional descriptive text.
- */
-
-void hildon_get_password_dialog_set_domain(HildonGetPasswordDialog *dialog,
- const gchar *domain)
-{
- HildonGetPasswordDialogPrivate *priv;
-
- g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
-
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- gtk_label_set_text(priv->domainLabel, domain);
-
-}
-
-/**
- * hildon_get_password_dialog_set_title:
- * @dialog: the dialog
- * @new_title: the text to be set as the dialog title
- *
- * Sets the dialog title.
- *
- * DEPRECATED! use gtk_window_set_title instead.
- */
-void hildon_get_password_dialog_set_title(HildonGetPasswordDialog *dialog,
- const gchar *new_title)
-
-{
- /* FIXME: This method is completely useless, should be deprecated/removed */
- g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
- g_return_if_fail (new_title !=NULL);
- gtk_window_set_title(GTK_WINDOW(dialog),
- new_title);
-}
-
-/**
- * hildon_get_password_dialog_set_caption:
- * @dialog: the dialog
- * @new_caption: the text to be set as the caption label
- *
- * Sets the password entry field's neigbouring label.
- */
-
-void hildon_get_password_dialog_set_caption(HildonGetPasswordDialog *dialog,
- const gchar *new_caption)
-{
-
-
- HildonGetPasswordDialogPrivate *priv;
-
- g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
- g_return_if_fail (new_caption != NULL);
-
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- hildon_caption_set_label(priv->passwordEntry, new_caption);
-
-}
-
-/**
- * hildon_get_password_dialog_set_max_characters:
- * @dialog: the dialog
- * @max_characters: the maximum number of characters the password dialog
- * accepts
- * @new_caption: the text to be set as the caption label
- *
- * sets the maximum number of characters allowed as the password
- */
-
-void hildon_get_password_dialog_set_max_characters (HildonGetPasswordDialog *dialog, gint max_characters )
-{
- HildonGetPasswordDialogPrivate *priv;
-
- g_return_if_fail (max_characters > 0);
- g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
-
- priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Apply the given length to password entry */
- gtk_entry_set_max_length(GTK_ENTRY
- (hildon_caption_get_control
- (priv->passwordEntry)),
- max_characters);
-
- /* Connect callback to show error banner if the limit is exceeded */
- g_signal_connect(GTK_ENTRY
- (hildon_caption_get_control
- (priv->passwordEntry)),
- "invalid_input",
- G_CALLBACK(_invalid_input),
- NULL
- );
-}
-
-static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason,
- gpointer unused)
-{
- if (reason==GTK_INVALID_INPUT_MAX_CHARS_REACHED) {
- gtk_infoprint(GTK_WINDOW(widget), _(HILDON_GET_PASSWORD_DIALOG_MAX_CHARS));
- }
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_GET_PASSWORD_DIALOG_H__
-#define __HILDON_GET_PASSWORD_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_GET_PASSWORD_DIALOG ( hildon_get_password_dialog_get_type() )
-
-#define HILDON_GET_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_GET_PASSWORD_DIALOG,\
- HildonGetPasswordDialog))
-
-#define HILDON_GET_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_GET_PASSWORD_DIALOG, \
- HildonGetPasswordDialogClass))
-
-#define HILDON_IS_GET_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_GET_PASSWORD_DIALOG))
-
-#define HILDON_IS_GET_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_GET_PASSWORD_DIALOG))
-
-
-#define HILDON_GET_PASSWORD_DIALOG_TITLE "ecdg_ti_get_old_password"
-#define HILDON_GET_PASSWORD_DIALOG_PASSWORD "ecdg_fi_get_old_pwd_enter_pwd"
-#define HILDON_GET_PASSWORD_DIALOG_OK "ecdg_bd_get_old_password_dialog_ok"
-#define HILDON_GET_PASSWORD_DIALOG_CANCEL "ecdg_bd_get_old_password_dialog_cancel"
-
-#define HILDON_GET_PASSWORD_VERIFY_DIALOG_TITLE "ecdg_ti_verify_password"
-#define HILDON_GET_PASSWORD_VERIFY_DIALOG_PASSWORD "ecdg_fi_verify_pwd_enter_pwd"
-#define HILDON_GET_PASSWORD_VERIFY_DIALOG_OK "ecdg_bd_verify_password_dialog_ok"
-#define HILDON_GET_PASSWORD_VERIFY_DIALOG_CANCEL "ecdg_bd_verify_password_dialog_cancel"
-
-#define HILDON_GET_PASSWORD_DIALOG_MAX_CHARS "ckdg_ib_maximum_characters_reached"
-
-typedef struct _HildonGetPasswordDialog HildonGetPasswordDialog;
-typedef struct _HildonGetPasswordDialogClass HildonGetPasswordDialogClass;
-
-struct _HildonGetPasswordDialog {
- GtkDialog parent;
-};
-
-struct _HildonGetPasswordDialogClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_get_password_dialog_get_type(void) G_GNUC_CONST;
-
-GtkWidget *hildon_get_password_dialog_new (GtkWindow *parent,
- gboolean get_old);
-
-GtkWidget *hildon_get_password_dialog_new_with_default (GtkWindow *parent,
- const gchar *password,
- gboolean get_old);
-
-void hildon_get_password_dialog_set_domain (HildonGetPasswordDialog *dialog,
- const gchar *domain);
-
-void hildon_get_password_dialog_set_caption (HildonGetPasswordDialog *dialog,
- const gchar *new_caption);
-
-void hildon_get_password_dialog_set_max_characters(HildonGetPasswordDialog *dialog,
- gint max_characters);
-
-const gchar * hildon_get_password_dialog_get_password(HildonGetPasswordDialog * dialog);
-
-
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_get_password_dialog_set_title (HildonGetPasswordDialog *dialog,
- const gchar *new_title);
-#endif /* HILDON_DISABLE_DEPRECATED */
-
-G_END_DECLS
-#endif /* __HILDON_GET_PASSWORD_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file hildon-grid-item-private.h
- *
- * This file is a private header file for he implementation of
- * HildonGridItem. HildonGridItem is an item mainly used in HildonGrid. It
- * has an icon, emblem and a label. This private header file exists so that
- * grid can call semi-public functions of an item.
- */
-
-#ifndef __HILDON_GRID_ITEM_PRIVATE_H__
-#define __HILDON_GRID_ITEM_PRIVATE_H__
-
-#include <hildon-widgets/hildon-grid-item.h>
-
-G_BEGIN_DECLS
-
-
-void _hildon_grid_item_set_label(HildonGridItem *item,
- const gchar *label);
-
-void _hildon_grid_item_set_emblem_size(HildonGridItem *item,
- const gint emblem_size);
-void _hildon_grid_item_set_label_pos(HildonGridItem *item,
- HildonGridPositionType label_pos);
-
-void _hildon_grid_item_set_icon_size(HildonGridItem *item,
- HildonGridItemIconSizeType icon_size);
-
-void _hildon_grid_item_set_focus_margin(HildonGridItem *item,
- const gint focus_margin);
-void _hildon_grid_item_set_label_height(HildonGridItem *item,
- const gint label_height);
-void _hildon_grid_item_set_label_icon_margin(HildonGridItem *item,
- const gint label_icon_margin);
-void _hildon_grid_item_set_icon_width(HildonGridItem *item,
- const gint icon_width);
-void _hildon_grid_item_set_icon_height(HildonGridItem *item,
- const gint icon_height);
-void _hildon_grid_item_set_label_height(HildonGridItem *item,
- const gint label_height);
-
-void _hildon_grid_item_done_updating_settings(HildonGridItem *item);
-
-
-G_END_DECLS
-
-#endif /* __HILDON_GRID_ITEM_PRIVATE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-grid-item
- * @short_description: Creating grid items used by #HildonGrid
- * @see_also: #HildonGrid
- *
- * HildonGridItem is used to create grid items used by #HildonGrid. The
- * grid item consists of an icon and a label. Based on the displaying
- * mode employed by #HildonGrid, the label is justified to the right or
- * the bottom.
- */
-
-/*
- * TODO:
- * - play with libtool to get _-functions private but accesable from grid
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtklabel.h>
-#include <gtk/gtkicontheme.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkmisc.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkenums.h>
-#include <pango/pango.h>
-
-#include "hildon-grid-item-private.h"
-#include <hildon-widgets/hildon-grid-item.h>
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_GRID_ITEM_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_GRID_ITEM, \
- HildonGridItemPrivate))
-
-typedef struct _HildonGridItemPrivate HildonGridItemPrivate;
-
-
-/* Default icon. */
-#define DEFAULT_ICON_BASENAME "qgn_list_gene_unknown_file"
-#define HILDON_GRID_ICON_SIZE 26
-#define HILDON_GRID_EMBLEM_SIZE 16
-
-/* Use some alpha-thing for emblems. */
-#define USE_DIRTY_ALPHA
-
-struct _HildonGridItemPrivate {
- gchar *icon_basename;
- gint icon_size;
- GtkWidget *icon;
-
- gchar *emblem_basename;
- gint emblem_size;
-
- GtkWidget *label; /* TODO use pango! */
- HildonGridPositionType label_pos;
-
- gint focus_margin;
- gint label_height;
- gint label_icon_margin;
- gint column_margin;
- gint icon_width;
- gint icon_height;
- gint row_height;
-
- gint pending_icon_size;
- gint pending_emblem_size;
- HildonGridPositionType pending_label_pos;
- gint pending_focus_margin;
- gint pending_label_height;
- gint pending_label_icon_margin;
- gint pending_icon_width;
- gint pending_icon_height;
-
- gboolean selected;
-};
-
-enum{
- PROP_NONE = 0,
- PROP_EMBLEM_TYPE,
- PROP_ICON_BASENAME
-};
-
-/* Prototypes. */
-static void hildon_grid_item_class_init(HildonGridItemClass * klass);
-static void hildon_grid_item_init(HildonGridItem * item);
-static gboolean hildon_grid_item_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static void hildon_grid_item_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void hildon_grid_item_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static void hildon_grid_item_forall(GtkContainer * container,
- gboolean include_int,
- GtkCallback callback,
- gpointer callback_data);
-static void hildon_grid_item_remove(GtkContainer * container,
- GtkWidget * child);
-
-static void hildon_grid_item_finalize(GObject * object);
-
-static void update_icon(HildonGridItem * item);
-static void set_label_justify(HildonGridItem * item);
-
-static void hildon_grid_item_set_icon_size(HildonGridItem *item,
- HildonGridItemIconSizeType icon_size);
-
-static void hildon_grid_item_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-
-static void hildon_grid_item_get_property(GObject * object,
- guint prop_id, GValue * value,
- GParamSpec * pspec);
-
-
-static GtkContainerClass *parent_class = NULL;
-
-/* Private functions */
-static void
-hildon_grid_item_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonGridItem *item = HILDON_GRID_ITEM(object);
- HildonGridItemPrivate *priv;
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- switch (prop_id) {
- case PROP_EMBLEM_TYPE:
- hildon_grid_item_set_emblem_type(item, g_value_get_string(value));
- break;
- case PROP_ICON_BASENAME:
- if(priv->icon_basename)
- g_free(priv->icon_basename);
-
- priv->icon_basename = g_strdup(g_value_get_string(value));
- update_icon(item);
-
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_grid_item_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonGridItem *item = HILDON_GRID_ITEM(object);
- HildonGridItemPrivate *priv;
- const gchar *string;
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- switch (prop_id) {
- case PROP_EMBLEM_TYPE:
- string = hildon_grid_item_get_emblem_type(item);
- g_value_set_string(value, string);
- break;
- case PROP_ICON_BASENAME:
- g_value_set_string(value, priv->icon_basename);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-
-GType
-hildon_grid_item_get_type(void)
-{
- static GType grid_item_type = 0;
-
- if (!grid_item_type) {
- static const GTypeInfo grid_item_info = {
- sizeof(HildonGridItemClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_grid_item_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonGridItem),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_grid_item_init,
- };
- grid_item_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonGridItem",
- &grid_item_info, 0);
- }
-
- return grid_item_type;
-}
-
-static void
-hildon_grid_item_class_init(HildonGridItemClass *klass)
-{
- GtkWidgetClass *widget_class;
- GtkContainerClass *container_class;
- GObjectClass *gobject_class;
-
- widget_class = GTK_WIDGET_CLASS(klass);
- gobject_class = G_OBJECT_CLASS(klass);
- container_class = GTK_CONTAINER_CLASS(klass);
-
- parent_class = g_type_class_peek_parent(klass);
-
- g_type_class_add_private(klass, sizeof(HildonGridItemPrivate));
-
- gobject_class->finalize = hildon_grid_item_finalize;
-
- widget_class->expose_event = hildon_grid_item_expose;
- widget_class->size_request = hildon_grid_item_size_request;
- widget_class->size_allocate = hildon_grid_item_size_allocate;
-
- container_class->forall = hildon_grid_item_forall;
- container_class->remove = hildon_grid_item_remove;
-
- gobject_class->set_property = hildon_grid_item_set_property;
- gobject_class->get_property = hildon_grid_item_get_property;
-
- g_object_class_install_property
- (gobject_class,
- PROP_EMBLEM_TYPE,
- g_param_spec_string ("emblem-type",
- "Emblem Type",
- "The emblem's basename",
- NULL,
- G_PARAM_WRITABLE));
-
- g_object_class_install_property
- (gobject_class,
- PROP_ICON_BASENAME,
- g_param_spec_string ("icon-basename",
- "Icon Basename",
- "The icon's basename",
- NULL,
- G_PARAM_WRITABLE));
-
-}
-
-static void
-hildon_grid_item_init(HildonGridItem *item)
-{
- HildonGridItemPrivate *priv;
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- priv->icon_basename = NULL;
- priv->pending_icon_size = priv->icon_size = HILDON_GRID_ICON_SIZE;
- priv->icon = NULL;
-
- priv->emblem_basename = NULL;
- priv->pending_emblem_size = priv->emblem_size = HILDON_GRID_EMBLEM_SIZE;
-
- priv->label = NULL;
- priv->pending_label_pos = priv->label_pos =
- HILDON_GRID_ITEM_LABEL_POS_BOTTOM;
-
- priv->selected = FALSE;
-
- priv->pending_focus_margin = priv->focus_margin = 6;
- priv->pending_label_height = priv->label_height = 30;
- priv->pending_label_icon_margin = priv->label_icon_margin = 6;
- priv->pending_icon_width = priv->icon_width = 64;
- priv->pending_icon_height = priv->icon_height = 54;
- priv->pending_label_height = priv->label_height = 30;
-
-
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(item), GTK_CAN_FOCUS);
-
- priv->label = gtk_label_new(NULL);
- gtk_widget_set_name(priv->label, "hildon-grid-item-label");
- gtk_widget_set_parent(priv->label, GTK_WIDGET(item));
-
- update_icon(item);
- set_label_justify(item);
-
- gtk_widget_show(priv->label);
-}
-
-/**
- * hildon_grid_item_new:
- * @icon_basename: icon base name
- *
- * Creates a new #HildonGridItem.
- *
- * Returns: a new #HildonGridItem
- */
-GtkWidget *
-hildon_grid_item_new(const gchar *icon_basename)
-{
- HildonGridItem *item;
-
- item = g_object_new(HILDON_TYPE_GRID_ITEM, "icon-basename", icon_basename, NULL);
-
- return GTK_WIDGET(item);
-}
-
-/**
- * hildon_grid_item_new_with_label:
- * @icon_basename: icon base name
- * @label: text label for icon
- *
- * Creates a new #HildonGridItem with a specified label for the icon.
- *
- * Returns: a new #HildonGridItem
- */
-GtkWidget *
-hildon_grid_item_new_with_label(const gchar *icon_basename,
- const gchar *label)
-{
- HildonGridItem *item;
-
- item = g_object_new(HILDON_TYPE_GRID_ITEM, "icon-basename", icon_basename, NULL);
-
- hildon_grid_item_set_label(item, label);
-
- return GTK_WIDGET(item);
-}
-
-
-static void
-update_icon(HildonGridItem *item)
-{
- GtkIconTheme *icon_theme;
- GdkPixbuf *icon;
- GdkPixbuf *emblem_icon;
- HildonGridItemPrivate *priv;
- GError *error;
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- if (priv->icon != NULL) {
- if (GTK_WIDGET_VISIBLE(priv->icon))
- gtk_widget_hide(priv->icon);
- gtk_widget_unparent(priv->icon);
- }
-
- icon_theme = gtk_icon_theme_get_default();
-
- /* Load icon. Fall to default if loading fails. */
- icon = NULL;
- if (priv->icon_basename)
- {
- error = NULL;
- icon = gtk_icon_theme_load_icon(icon_theme,
- priv->icon_basename,
- priv->icon_size, 0, &error);
- if (icon == NULL) {
- g_warning("Couldn't load icon \"%s\": %s", priv->icon_basename,
- error->message);
- g_error_free(error);
- }
- }
-
- if (icon == NULL) {
- error = NULL;
- icon = gtk_icon_theme_load_icon(icon_theme,
- DEFAULT_ICON_BASENAME,
- priv->icon_size, 0, &error);
- if (icon == NULL) {
- g_warning("Couldn't load default icon: %s!\n", error->message);
- g_error_free(error);
- }
- }
- priv->icon_width = gdk_pixbuf_get_width(icon);
- priv->icon_height = gdk_pixbuf_get_height(icon);
-
-
- /* Load and merge emblem if one is specified. */
- if (priv->emblem_basename != NULL) {
- error = NULL;
- emblem_icon = gtk_icon_theme_load_icon(icon_theme,
- priv->emblem_basename,
- priv->emblem_size,
- 0, &error);
- if (emblem_icon == NULL) {
- g_warning("Couldn't load emblem \"%s\": %s",
- priv->emblem_basename, error->message);
- g_error_free(error);
- } else {
- gint icon_height;
- gint width, height, y;
-
-#ifdef USE_DIRTY_ALPHA
- GdkPixbuf *tmp;
-#endif
-
- icon_height = gdk_pixbuf_get_height(icon);
- width = MIN(gdk_pixbuf_get_width(emblem_icon),
- gdk_pixbuf_get_width(icon));
- height = MIN(gdk_pixbuf_get_height(emblem_icon), icon_height);
- y = icon_height - height;
-#ifndef USE_DIRTY_ALPHA
- gdk_pixbuf_copy_area(emblem_icon, 0, 0, width, height,
- icon, 0, y);
-#else
- /*
- * Using composite to copy emblem to lower left corner creates
- * some garbage on top of emblem. This way it can be avoided.
- */
- tmp = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE,
- 8, width, icon_height);
- gdk_pixbuf_fill(tmp, 0x00000000);
- gdk_pixbuf_copy_area(emblem_icon, 0, 0, width, height,
- tmp, 0, y);
- gdk_pixbuf_composite(tmp, icon,
- 0, 0, width, icon_height,
- 0.0, 0.0, 1.0, 1.0,
- GDK_INTERP_NEAREST, 255);
- g_object_unref(tmp);
-#endif /* ifndef else USE_DIRTY_ALPHA */
- g_object_unref(emblem_icon);
- }
- }
-
- priv->icon = gtk_image_new_from_pixbuf(icon);
- g_object_unref(icon);
-
- gtk_widget_set_parent(priv->icon, GTK_WIDGET(item));
- gtk_widget_show(priv->icon);
-
- gtk_widget_queue_draw(priv->icon);
-}
-
-void
-hildon_grid_item_set_label(HildonGridItem *item, const gchar *label)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- if (label == NULL)
- label = "";
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (strcmp (gtk_label_get_label (GTK_LABEL (priv->label)), label) == 0)
- return;
- gtk_label_set_label(GTK_LABEL(priv->label), label);
-}
-
-static void
-hildon_grid_item_set_icon_size(HildonGridItem *item,
- HildonGridItemIconSizeType icon_size)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_icon_size == icon_size) {
- return;
- }
- priv->pending_icon_size = icon_size;
-}
-
-
-void
-_hildon_grid_item_set_label_pos(HildonGridItem *item,
- HildonGridPositionType label_pos)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_label_pos == label_pos) {
- return;
- }
- priv->pending_label_pos = label_pos;
-}
-
-
-void
-_hildon_grid_item_set_emblem_size(HildonGridItem *item, gint emblem_size)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_emblem_size == emblem_size) {
- return;
- }
- priv->pending_emblem_size = emblem_size;
-}
-
-
-void
-_hildon_grid_item_set_focus_margin(HildonGridItem *item,
- const gint focus_margin)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_focus_margin == focus_margin) {
- return;
- }
- priv->pending_focus_margin = focus_margin;
-}
-
-
-void
-_hildon_grid_item_set_label_height(HildonGridItem *item,
- const gint label_height)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_label_height == label_height) {
- return;
- }
- priv->pending_label_height = label_height;
-}
-
-
-void
-_hildon_grid_item_set_label_icon_margin(HildonGridItem *item,
- const gint label_icon_margin)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_label_icon_margin == label_icon_margin) {
- return;
- }
- priv->pending_label_icon_margin = label_icon_margin;
-}
-
-
-void
-_hildon_grid_item_set_icon_height(HildonGridItem *item,
- const gint icon_height)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_icon_height == icon_height) {
- return;
- }
- priv->pending_icon_height = icon_height;
-}
-
-
-void
-_hildon_grid_item_set_icon_width(HildonGridItem *item,
- const gint icon_width)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- hildon_grid_item_set_icon_size(item, icon_width);
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- if (priv->pending_icon_width == icon_width) {
- return;
- }
- priv->pending_icon_width = icon_width;
-}
-
-
-static void
-set_label_justify(HildonGridItem *item)
-{
- HildonGridItemPrivate *priv;
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- if (priv->label != NULL) {
- switch (priv->label_pos) {
- case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
- gtk_misc_set_alignment(GTK_MISC(priv->label), 0.5, 0.5);
- break;
-
- case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
- gtk_misc_set_alignment(GTK_MISC(priv->label), 0.0, 0.5);
- break;
-
- default:
- g_warning("Invalid position!");
- break;
- }
- }
-}
-
-static void
-hildon_grid_item_remove(GtkContainer *container, GtkWidget *child)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
-
- item = HILDON_GRID_ITEM(container);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- g_return_if_fail(GTK_IS_WIDGET(child));
- g_return_if_fail(child == priv->label || child == priv->icon);
-
- if (child == priv->label) {
- gtk_widget_unparent(child);
- priv->label = NULL;
- } else if (child == priv->icon) {
- gtk_widget_unparent(child);
- priv->icon = NULL;
- }
-}
-
-static gboolean
-hildon_grid_item_expose(GtkWidget *widget, GdkEventExpose *event)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(HILDON_IS_GRID_ITEM(widget), FALSE);
- g_return_val_if_fail(event, FALSE);
-
- item = HILDON_GRID_ITEM(widget);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- if (priv->label == NULL && priv->icon == NULL) {
- return FALSE;
- }
- if (GTK_WIDGET_HAS_FOCUS(GTK_WIDGET(item))) {
- GdkRectangle clip;
- GtkWidget *focused;
-
- if (priv->label != NULL) {
- focused = priv->label;
- } else {
- focused = priv->icon;
- }
-
- /* Determine the coordinates and size of clip */
- switch (priv->label_pos) {
- case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
- clip.x = focused->allocation.x - priv->focus_margin;
- clip.y = focused->allocation.y;
- clip.width = focused->allocation.width + priv->focus_margin * 2;
- clip.height = focused->allocation.height;
- if (clip.x < widget->allocation.x ||
- clip.width > widget->allocation.width) {
- clip.x = widget->allocation.x;
- clip.width = widget->allocation.width;
- }
- if (clip.y + clip.height >
- widget->allocation.y + widget->allocation.height) {
- clip.height = widget->allocation.y +
- widget->allocation.height - clip.y;
- }
- break;
-
- case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
- clip.x = widget->allocation.x;
- clip.y = widget->allocation.y;
- clip.width = widget->allocation.width;
- clip.height = widget->allocation.height;
- break;
- }
-
- /* Build painting box for the exposure event */
- gtk_paint_box(focused->style,
- gtk_widget_get_toplevel(focused)->window,
- GTK_STATE_SELECTED,
- GTK_SHADOW_NONE,
- &clip, focused, "selected",
- clip.x, clip.y, clip.width, clip.height);
- }
-
- /*
- * Items are not exposed unless they are visible.
- * -> No need to "optimize" by checking if they need exposing.
- */
- gtk_container_propagate_expose(GTK_CONTAINER(widget),
- priv->icon, event);
- gtk_container_propagate_expose(GTK_CONTAINER(widget),
- priv->label, event);
- return TRUE;
-}
-
-
-static void
-hildon_grid_item_size_request(GtkWidget *widget, GtkRequisition *requisition)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
- GtkRequisition label_req;
- gint label_margin;
-
- item = HILDON_GRID_ITEM(widget);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- label_margin = priv->focus_margin;
-
- gtk_widget_size_request(priv->icon, requisition);
- gtk_widget_size_request(priv->label, &label_req);
-
- switch (priv->label_pos) {
- case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
- requisition->width = MAX(requisition->width, label_req.width);
- requisition->height += label_req.height + label_margin;
- break;
-
- case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
- requisition->width += label_req.width + label_margin;
- requisition->height = MAX(requisition->height, label_req.height);
- break;
- default:
- g_warning("bad position");
- return;
- break;
- }
-}
-
-static void
-hildon_grid_item_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
- GtkRequisition l_req;
- GtkAllocation i_alloc, l_alloc;
-
- g_return_if_fail(widget);
- g_return_if_fail(allocation);
-
- item = HILDON_GRID_ITEM(widget);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
- widget->allocation = *allocation;
-
- /* If creating label and icon failed, don't show a thing... */
- if (priv->label == NULL && priv->icon == NULL) {
- return;
- }
- if (priv->label != NULL) {
- gtk_widget_get_child_requisition(priv->label, &l_req);
- } else {
- l_req.width = l_req.height = 0;
- }
-
- /* Determine icon and label allocation based on label position */
- switch (priv->label_pos) {
- case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
- i_alloc.x = (allocation->width - priv->icon_width) / 2 +
- allocation->x;
- if (priv->label != NULL) {
- i_alloc.y = allocation->y + (allocation->height -
- priv->label_height -
- priv->label_icon_margin -
- priv->icon_height) / 2;
- } else {
- i_alloc.y = (allocation->height - priv->icon_height) / 2 +
- allocation->y;
- }
-
- if (priv->label != NULL) {
- l_alloc.x = allocation->x + priv->focus_margin;
- l_alloc.y = i_alloc.y + priv->icon_height +
- priv->label_icon_margin;
- l_alloc.width = allocation->width - priv->focus_margin * 2;
- l_alloc.height = priv->label_height;
- }
- break;
-
- case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
- i_alloc.x = allocation->x + priv->focus_margin;
- i_alloc.y = allocation->y +
- (priv->label_height - priv->icon_height) / 2;
-
- if (priv->label != NULL) {
- l_alloc.x = allocation->x + priv->focus_margin +
- priv->icon_width + priv->label_icon_margin;
- l_alloc.y = allocation->y;
- l_alloc.width = allocation->width - priv->focus_margin * 2 -
- priv->label_icon_margin - priv->icon_width;
- l_alloc.height = priv->label_height;
- }
- break;
- default:
- g_warning("bad label position");
- return;
- break;
- }
-
- if (i_alloc.y < allocation->y) {
- i_alloc.height -= i_alloc.height - allocation->height;
- i_alloc.y = allocation->y;
- }
- if (i_alloc.y + i_alloc.height > allocation->y + allocation->height) {
- i_alloc.height-= i_alloc.y + i_alloc.height -
- allocation->y - allocation->height;
- }
-
-
- i_alloc.width = priv->icon_width;
- i_alloc.height = priv->icon_height;
-
- if (priv->label != NULL) {
- gtk_widget_size_allocate(priv->label, &l_alloc);
- }
- if (priv->icon != NULL) {
- gtk_widget_size_allocate(priv->icon, &i_alloc);
- }
-}
-
-static void
-hildon_grid_item_forall(GtkContainer *container,
- gboolean include_int,
- GtkCallback callback,
- gpointer callback_data)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(container);
- g_return_if_fail(callback);
-
- item = HILDON_GRID_ITEM(container);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- /* Connect callback functions to the item */
- if (priv->icon != NULL) {
- (*callback) (priv->icon, callback_data);
- }
- if (priv->label != NULL) {
- (*callback) (priv->label, callback_data);
- }
-}
-
-static void
-hildon_grid_item_finalize(GObject *object)
-{
- HildonGridItem *item;
- HildonGridItemPrivate *priv;
-
- item = HILDON_GRID_ITEM(object);
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- g_free(priv->icon_basename);
- if (priv->emblem_basename != NULL) {
- g_free(priv->emblem_basename);
- }
-
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-#if 0
-static int hildon_time_get_font_width(GtkWidget * widget)
-{
- PangoContext *context;
- PangoFontMetrics *metrics;
- gint digit_width;
-
- context = gtk_widget_get_pango_context(widget);
- metrics = pango_context_get_metrics(context,
- widget->style->font_desc,
- pango_context_get_language
- (context));
-
- digit_width = pango_font_metrics_get_approximate_digit_width(metrics);
- digit_width = PANGO_PIXELS(digit_width);
-
- pango_font_metrics_unref(metrics);
-
- return digit_width;
-}
-#endif
-
-
-/**
- * hildon_grid_item_set_emblem_type:
- * @item: #HildonGridItem
- * @emblem_basename: emblem's basename
- *
- * Sets item emblem type.
- */
-void
-hildon_grid_item_set_emblem_type(HildonGridItem *item,
- const gchar *emblem_basename)
-{
- HildonGridItemPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
-
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- if (priv->emblem_basename != NULL) {
- g_free(priv->emblem_basename);
- }
-
- priv->emblem_basename = g_strdup(emblem_basename);
-
- update_icon(item);
-
- g_object_notify (G_OBJECT (item), "emblem-type");
-}
-
-/**
- * hildon_grid_item_get_emblem_type:
- * @item: #HildonGridItem
- *
- * Returns: emblem's basename. Must not be changed or freed.
- */
-const gchar *
-hildon_grid_item_get_emblem_type(HildonGridItem *item)
-{
- g_return_val_if_fail(HILDON_IS_GRID_ITEM(item), NULL);
-
- return HILDON_GRID_ITEM_GET_PRIVATE(item)->emblem_basename;
-}
-
-
-
-void
-_hildon_grid_item_done_updating_settings(HildonGridItem *item)
-{
- gboolean need_update_icon;
- gboolean need_resize;
-
- HildonGridItemPrivate *priv;
- g_return_if_fail(HILDON_IS_GRID_ITEM(item));
- priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
-
- need_update_icon = need_resize = FALSE;
-
- if (priv->pending_icon_size != priv->icon_size) {
- if (priv->pending_icon_size > 0) {
- priv->icon_size = priv->pending_icon_size;
- } else {
- priv->icon_size = 1;
- }
- need_update_icon = TRUE;
- }
- if (priv->pending_emblem_size != priv->emblem_size) {
- priv->emblem_size = priv->pending_emblem_size;
- need_update_icon = TRUE;
- }
- if (priv->pending_label_pos != priv->label_pos) {
- priv->label_pos = priv->pending_label_pos;
- /* No refresh here, grid will do it. */
- set_label_justify(item);
- }
- /*
- * grid will take care of this
- *
- if (priv->pending_focus_margin != priv->focus_margin) {
- priv->focus_margin = priv->pending_focus_margin;
- need_resize = TRUE;
- }
- if (priv->pending_label_height != priv->label_height) {
- priv->label_height = priv->pending_label_height;
- need_resize = TRUE;
- }
- if (priv->pending_label_icon_margin != priv->label_icon_margin) {
- priv->label_icon_margin = priv->pending_label_icon_margin;
- need_resize = TRUE;
- }
- if (priv->pending_icon_height != priv->icon_height) {
- priv->icon_height = priv->pending_icon_height;
- need_resize = TRUE;
- }
- if (priv->pending_icon_width != priv->icon_width) {
- priv->icon_width = priv->pending_icon_width;
- need_resize = TRUE;
- }
- */
-
- if (need_update_icon == TRUE) {
- update_icon(HILDON_GRID_ITEM(item));
- }
- /*
- if (need_resize == TRUE) {
- gtk_widget_queue_resize(GTK_WIDGET(item));
- }
- */
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file hildon-grid-item.h
- *
- * This file is a header file for he implementation of HildonGridItem.
- * HildonGridItem is an item mainly used in HildonGrid. It has an icon,
- * emblem and a label.
- */
-
-#ifndef __HILDON_GRID_ITEM_H__
-#define __HILDON_GRID_ITEM_H__
-
-#include <gtk/gtkcontainer.h>
-#include <gtk/gtkitem.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_GRID_ITEM (hildon_grid_item_get_type ())
-#define HILDON_GRID_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- HILDON_TYPE_GRID_ITEM, \
- HildonGridItem))
-#define HILDON_GRID_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_GRID_ITEM, \
- HildonGridItemClass))
-#define HILDON_IS_GRID_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- HILDON_TYPE_GRID_ITEM))
-#define HILDON_IS_GRID_ITEM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_GRID_ITEM))
-#define HILDON_GRID_ITEM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- HILDON_TYPE_GRID_ITEM, HildonGridItemClass))
-
-typedef enum {
- HILDON_GRID_ITEM_LABEL_POS_BOTTOM = 1,
- HILDON_GRID_ITEM_LABEL_POS_RIGHT
-} HildonGridPositionType;
-
-typedef enum {
- HILDON_GRID_ITEM_ICON_27x27 = 1,
- HILDON_GRID_ITEM_ICON_128x128
-} HildonGridItemIconSizeType;
-
-
-typedef struct _HildonGridItem HildonGridItem;
-typedef struct _HildonGridItemClass HildonGridItemClass;
-
-
-struct _HildonGridItem {
- GtkContainer parent;
-};
-
-struct _HildonGridItemClass {
- GtkContainerClass parent_class;
-};
-
-
-
-GType hildon_grid_item_get_type(void);
-GtkWidget *hildon_grid_item_new(const gchar * icon_basename);
-GtkWidget *hildon_grid_item_new_with_label(const gchar * icon_basename,
- const gchar * label);
-
-void hildon_grid_item_set_emblem_type(HildonGridItem * item,
- const gchar * emblem_basename);
-const gchar *hildon_grid_item_get_emblem_type(HildonGridItem * item);
-void hildon_grid_item_set_label(HildonGridItem *item, const gchar *label);
-
-
-G_END_DECLS
-#endif /* __HILDON_GRID_ITEM_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-grid
- * @short_description: Being used where ever a number of single tap
- * activatable items need to be presented (e.g. Control Panel applets)
- * @see_also: #HildonGridItem
- *
- * HildonGrid is a set of application-defineable items that are presented in a
- * table. There are two modes for the form of the table; large icon mode
- * and small icon mode.
- *
- * In large icon mode, the Grid View items are presented with a large
- * icon and a label under it. In small icon mode, the items are
- * presented with a small icon and a label on the right side of the
- * icon.
- *
- * The label has a solid background as wide as the maximum text width.
- * This allows the text to have focus as well as be legible when
- * displayed upon a black or dark background image. Long names are
- * truncated with an ellipsis ("...") appended.
- */
-
-/*
- * TODO
- * - there must be a predefined place for the "no items" -label...
- * - performance :-)
- * - dimmed items & scrolling by scrollbar
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtklabel.h>
-#include <gtk/gtkrange.h>
-#include <gtk/gtkvscrollbar.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkenums.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "hildon-grid-item-private.h"
-#include "hildon-marshalers.h"
-#include "hildon-app.h"
-#include <hildon-widgets/hildon-grid.h>
-#include <hildon-widgets/hildon-grid-item.h>
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_GRID_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_GRID, \
- HildonGridPrivate))
-
-
-#define DEFAULT_STYLE "largeicons-home"
-
-#define DEFAULT_N_COLUMNS 3
-#define GRID_LABEL_POS_PAD 16
-
-#define DRAG_SENSITIVITY 6
-
-
-enum {
- ACTIVATE_CHILD,
- POPUP_CONTEXT,
- LAST_SIGNAL
-};
-
-enum {
- PROP_0,
- PROP_EMPTY_LABEL,
- PROP_STYLE,
- PROP_SCROLLBAR_POS
-};
-
-
-typedef struct _HildonGridChild HildonGridChild;
-typedef struct _HildonGridPrivate HildonGridPrivate;
-
-
-struct _HildonGridChild {
- GtkWidget *widget;
-};
-
-
-struct _HildonGridPrivate {
- GList *children;
- GtkWidget *scrollbar;
- gint old_sb_pos;
- GdkWindow *event_window;
-
- gchar *style;
- gint emblem_size;
- GtkWidget *empty_label;
-
- gint item_width;
- gint item_height;
- gint h_margin;
- gint v_margin;
- gint focus_margin;
- gint icon_label_margin;
- gint icon_width;
- gint num_columns;
- HildonGridPositionType label_pos;
- gint label_height;
-
- gint focus_index;
- guint click_x;
- guint click_y;
-
- /* Handy variables outsize _allocate. */
- gint area_height;
- gint area_rows;
- gint scrollbar_width;
-
- gint first_index;
- GdkEventType last_button_event;
- gint old_item_height;
-};
-
-
-
-/* Prototypes. */
-static void hildon_grid_class_init(HildonGridClass * klass);
-static void hildon_grid_init(HildonGrid * grid);
-static void hildon_grid_realize(GtkWidget * widget);
-static void hildon_grid_unrealize(GtkWidget * widget);
-static void hildon_grid_map(GtkWidget * widget);
-static void hildon_grid_unmap(GtkWidget * widget);
-static gboolean hildon_grid_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static void hildon_grid_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void hildon_grid_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static void hildon_grid_add(GtkContainer * container, GtkWidget * widget);
-static void hildon_grid_remove(GtkContainer * container,
- GtkWidget * widget);
-static void hildon_grid_set_focus_child(GtkContainer * container,
- GtkWidget * widget);
-static void hildon_grid_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void hildon_grid_tap_and_hold_setup(GtkWidget * widget,
- GtkWidget * menu,
- GtkCallback func,
- GtkWidgetTapAndHoldFlags flags);
-
-static GType hildon_grid_child_type(GtkContainer * container);
-
-
-static void hildon_grid_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_grid_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static void hildon_grid_set_empty_label(HildonGrid *grid,
- const gchar *empty_label);
-static const gchar *hildon_grid_get_empty_label(HildonGrid * grid);
-static void hildon_grid_set_num_columns(HildonGrid *grid, gint num_cols);
-static void hildon_grid_set_label_pos(HildonGrid *grid,
- HildonGridPositionType label_pos);
-static void hildon_grid_set_focus_margin(HildonGrid *grid,
- gint focus_margin);
-static void hildon_grid_set_icon_label_margin(HildonGrid *grid,
- gint icon_label_margin);
-static void hildon_grid_set_icon_width(HildonGrid *grid, gint icon_width);
-static void hildon_grid_set_emblem_size(HildonGrid *grid, gint emblem_size);
-static void hildon_grid_set_label_height(HildonGrid *grid,
- gint label_height);
-static void hildon_grid_destroy(GtkObject * self);
-static void hildon_grid_finalize(GObject * object);
-
-/* Signal handlers. */
-static gboolean hildon_grid_button_pressed(GtkWidget * widget,
- GdkEventButton * event);
-static gboolean hildon_grid_button_released(GtkWidget * widget,
- GdkEventButton * event);
-static gboolean hildon_grid_key_pressed(GtkWidget * widget,
- GdkEventKey * event);
-static gboolean hildon_grid_scrollbar_moved(GtkWidget * widget,
- gpointer data);
-static gboolean hildon_grid_state_changed(GtkWidget * widget,
- GtkStateType state,
- gpointer data);
-
-/* Other internal functions. */
-static void get_style_properties(HildonGrid * grid);
-static gint get_child_index(HildonGridPrivate * priv, GtkWidget * child);
-static gint get_child_index_by_coord(HildonGridPrivate * priv,
- gint x, gint y);
-static GtkWidget *get_child_by_index(HildonGridPrivate * priv, gint index);
-
-static gboolean jump_scrollbar_to_focused(HildonGrid * grid);
-static gboolean adjust_scrollbar_height(HildonGrid * grid);
-static gboolean update_contents(HildonGrid * grid);
-static void set_focus(HildonGrid * grid,
- GtkWidget * widget, gboolean refresh_view);
-
-static GtkContainerClass *parent_class = NULL;
-static guint grid_signals[LAST_SIGNAL] = { 0 };
-
-
-GType hildon_grid_get_type(void)
-{
- static GType grid_type = 0;
-
- if (!grid_type) {
- static const GTypeInfo grid_info = {
- sizeof(HildonGridClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_grid_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonGrid),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_grid_init,
- };
- grid_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonGrid", &grid_info, 0);
- }
-
- return grid_type;
-}
-
-
-
-static void hildon_grid_class_init(HildonGridClass * klass)
-{
- GObjectClass *gobject_class;
- GtkWidgetClass *widget_class;
- GtkContainerClass *container_class;
-
- widget_class = GTK_WIDGET_CLASS(klass);
- container_class = GTK_CONTAINER_CLASS(klass);
- gobject_class = G_OBJECT_CLASS(klass);
-
- parent_class = g_type_class_peek_parent(klass);
-
- g_type_class_add_private(klass, sizeof(HildonGridPrivate));
-
- GTK_OBJECT_CLASS(klass)->destroy = hildon_grid_destroy;
- gobject_class->finalize = hildon_grid_finalize;
- gobject_class->set_property = hildon_grid_set_property;
- gobject_class->get_property = hildon_grid_get_property;
-
- widget_class->realize = hildon_grid_realize;
- widget_class->unrealize = hildon_grid_unrealize;
- widget_class->map = hildon_grid_map;
- widget_class->unmap = hildon_grid_unmap;
- widget_class->expose_event = hildon_grid_expose;
- widget_class->size_request = hildon_grid_size_request;
- widget_class->size_allocate = hildon_grid_size_allocate;
- widget_class->tap_and_hold_setup = hildon_grid_tap_and_hold_setup;
- widget_class->key_press_event = hildon_grid_key_pressed;
- widget_class->button_press_event = hildon_grid_button_pressed;
- widget_class->button_release_event = hildon_grid_button_released;
-
- container_class->add = hildon_grid_add;
- container_class->remove = hildon_grid_remove;
- container_class->forall = hildon_grid_forall;
- container_class->child_type = hildon_grid_child_type;
- container_class->set_focus_child = hildon_grid_set_focus_child;
-
- /* Install properties to the class */
- g_object_class_install_property(gobject_class, PROP_EMPTY_LABEL,
- g_param_spec_string("empty_label",
- "Empty label",
- "Label to show when grid has no items",
- _("ckct_wi_grid_no_items"), G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_STYLE,
- g_param_spec_string("style",
- "Style",
- "Widget's Style. Setting style sets widget size, "
- "spacing, label position, number of columns, "
- "and icon sizeLabel to show when grid has no items",
- DEFAULT_STYLE, G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_SCROLLBAR_POS,
- g_param_spec_int("scrollbar-position",
- "Scrollbar Position",
- "View (scrollbar) position.",
- G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("item_width",
- "Item width",
- "Total width of an item (obsolete)",
- 1, G_MAXINT, 212, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("item_height",
- "Item height",
- "Total height of an item",
- 1, G_MAXINT, 96, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("item_hspacing",
- "Item horizontal spacing",
- "Margin between two columns and labels",
- 0, G_MAXINT, 12, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("item_vspacing",
- "Item vertical spacing",
- "Icon on right: Margin between rows / Icon at bottom: Vertical margin betweeb label and icon",
- 0, G_MAXINT, 6, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("label_hspacing",
- "Focus margin",
- "Margin between focus edge and item edge",
- 0, G_MAXINT, 6, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("label_vspacing",
- "Vertical label spacing",
- "Vertical margin between item and label",
- 0, G_MAXINT, 6, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("label_height",
- "Label height",
- "Height of icon label",
- 1, G_MAXINT, 30, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("n_columns",
- "Columns",
- "Number of columns",
- 0, G_MAXINT, DEFAULT_N_COLUMNS, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("label_pos",
- "Label position",
- "Position of label related to the icon",
- 1, 2, 1, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("icon_size",
- "Icon size",
- "Size of the icon in pixels (width)",
- 1, G_MAXINT, 64, G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_uint("emblem_size",
- "Emblem size",
- "Size of the emblem in pixels",
- 1, G_MAXINT, 25, G_PARAM_READABLE));
-
- /**
- * HildonGrid::activate-child:
- *
- * Emitted when a child (@HildonGridItem) is activated either by
- * tapping on it or by pressing enter.
- */
- grid_signals[ACTIVATE_CHILD] =
- g_signal_new("activate-child",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET(HildonGridClass, activate_child),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, HILDON_TYPE_GRID_ITEM);
-
- /**
- * HildonGrid::popup-context-menu:
- *
- * Emitted when popup-menu is supposed to open. Used for tap-and-hold.
- */
- grid_signals[POPUP_CONTEXT] =
- g_signal_new("popup-context-menu",
- G_OBJECT_CLASS_TYPE(gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(HildonGridClass, popup_context_menu),
- NULL, NULL,
- _hildon_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, HILDON_TYPE_GRID_ITEM);
-}
-
-
-
-/*
- * hildon_grid_set_empty_label:
- * @grid: #HildonGrid
- * @empty_label: New label
- *
- * Sets empty label.
- */
-static void
-hildon_grid_set_empty_label(HildonGrid * grid, const gchar * empty_label)
-{
- /* No need to worry about update -- label receives a signal for it. */
- gtk_label_set_label(GTK_LABEL(HILDON_GRID_GET_PRIVATE
- (grid)->empty_label),
- empty_label == NULL ? "" : empty_label);
-}
-
-/*
- * _hildon_grid_get_empty_label:
- * @grid: #HildonGrid
- *
- * Returns: empty label. Label must not be modified nor freed.
- */
-static const gchar *
-hildon_grid_get_empty_label(HildonGrid * grid)
-{
- return gtk_label_get_label(GTK_LABEL(HILDON_GRID_GET_PRIVATE
- (grid)->empty_label));
-}
-
-/*
- * hildon_grid_set_num_columns:
- * @grid: #HildonGrid
- * @columns: Number of columns
- *
- * Sets number of columns.
- */
-static void
-hildon_grid_set_num_columns(HildonGrid * grid, gint columns)
-{
- HildonGridPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID(grid));
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (priv->num_columns == columns) {
- return;
- }
-
- if (columns != 0)
- priv->num_columns = columns;
- else
- priv->num_columns = DEFAULT_N_COLUMNS;
-
- /* Update estimated row-count for jump_scrollbar... */
- priv->area_rows = MAX(priv->area_height / priv->num_columns, 1);
-
- /* Size could have changed. Scroll view so there's something to show. */
- adjust_scrollbar_height(grid);
- jump_scrollbar_to_focused(grid);
- gtk_widget_queue_resize(GTK_WIDGET(grid));
-}
-
-/*
- * hildon_grid_set_label_pos:
- * @grid: #HildonGrid
- * @label_pos: Label position
- *
- * Sets icon label position.
- */
-static void
-hildon_grid_set_label_pos(HildonGrid * grid,
- HildonGridPositionType label_pos)
-{
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (label_pos == priv->label_pos)
- return;
-
- /* gtknotebook doesn't check if we use valid values -- why should
- we?-) */
-
- priv->label_pos = label_pos;
-
- /* Set label position to each HildonGridItem */
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- _hildon_grid_item_set_label_pos(HILDON_GRID_ITEM(child),
- label_pos);
- }
-}
-
-/*
- * hildon_grid_set_focus_margin:
- * @grid: #HildonGrid
- * @focus_margin: Focus margin
- *
- * Sets margin between icon edge and label edge
- */
-static void
-hildon_grid_set_focus_margin(HildonGrid *grid, gint focus_margin)
-{
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- if (focus_margin == priv->focus_margin)
- return;
-
- priv->focus_margin = focus_margin;
-
- /* Update children. */
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- _hildon_grid_item_set_focus_margin(HILDON_GRID_ITEM(child),
- priv->focus_margin);
- }
-}
-
-
-/*
- * hildon_grid_set_icon_label_margin:
- * @grid: #HildonGrid
- * @hspacing: Vertical spacing
- *
- * Sets vertical spacing for label.
- * XXX
- */
-static void
-hildon_grid_set_icon_label_margin(HildonGrid *grid, gint icon_label_margin)
-{
- HildonGridPrivate *priv;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- if (icon_label_margin == priv->icon_label_margin)
- return;
-
- priv->icon_label_margin = icon_label_margin;
-}
-
-
-/*
- * hildon_grid_set_icon_width:
- * @grid: #HildonGrid
- * @icon_size: Icon size (width)
- *
- * Sets icon size (in pixels).
- */
-static void
-hildon_grid_set_icon_width(HildonGrid * grid, gint icon_width)
-{
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (icon_width == priv->icon_width)
- return;
-
- priv->icon_width = icon_width;
-
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- _hildon_grid_item_set_icon_width(HILDON_GRID_ITEM(child),
- icon_width);
- }
-}
-
-
-/*
- * hildon_grid_set_emblem_size:
- * @grid: #HildonGrid
- * @emblem_size: Emblem size
- *
- * Sets emblem size (in pixels).
- */
-static void
-hildon_grid_set_emblem_size(HildonGrid *grid, gint emblem_size)
-{
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (emblem_size == priv->emblem_size)
- return;
-
- priv->emblem_size = emblem_size;
-
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- _hildon_grid_item_set_emblem_size(HILDON_GRID_ITEM(child),
- emblem_size);
- }
-}
-
-
-static void
-hildon_grid_set_label_height(HildonGrid *grid,
- gint label_height)
-{
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (label_height == priv->label_height)
- return;
-
- priv->label_height = label_height;
-
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- _hildon_grid_item_set_label_height(HILDON_GRID_ITEM(child),
- label_height);
- }
-}
-
-
-static GType hildon_grid_child_type(GtkContainer * container)
-{
- return GTK_TYPE_WIDGET;
-}
-
-static void hildon_grid_init(HildonGrid * grid)
-{
- HildonGridPrivate *priv;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- GTK_CONTAINER(grid)->focus_child = NULL;
- priv->focus_index = -1;
-
- priv->scrollbar = gtk_vscrollbar_new(NULL);
- priv->empty_label = gtk_label_new(_("ckct_wi_grid_no_items"));
- priv->style = NULL;
-
- priv->area_height = 1;
- priv->area_rows = 1;
- priv->children = NULL;
-
- priv->first_index = 0;
- priv->click_x = 0;
- priv->click_y = 0;
-
- priv->item_height = 96;
- priv->h_margin = 12;
- priv->v_margin = 6;
- priv->focus_margin = 6;
- priv->icon_label_margin = 6;
- priv->icon_width = 64;
- priv->label_pos = HILDON_GRID_ITEM_LABEL_POS_BOTTOM;
-
- priv->old_sb_pos = -1;
- priv->old_item_height = -1;
-
- gtk_widget_set_parent(priv->scrollbar, GTK_WIDGET(grid));
- gtk_widget_set_parent(priv->empty_label, GTK_WIDGET(grid));
-
- priv->last_button_event = GDK_NOTHING;
-
- GTK_WIDGET_SET_FLAGS(grid, GTK_NO_WINDOW);
-
- /* Signal for scrollbar. */
- g_signal_connect(G_OBJECT(priv->scrollbar), "value-changed",
- G_CALLBACK(hildon_grid_scrollbar_moved), grid);
-
- /* Signal for key press. */
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(grid), GTK_CAN_FOCUS);
- gtk_widget_set_events(GTK_WIDGET(grid), GDK_KEY_PRESS_MASK);
-
- GTK_WIDGET_UNSET_FLAGS(priv->scrollbar, GTK_CAN_FOCUS);
- hildon_grid_set_style(grid, DEFAULT_STYLE);
-}
-
-/**
- * hildon_grid_new:
- *
- * Creates a new #HildonGrid.
- *
- * Returns: a new #HildonGrid
- */
-GtkWidget *hildon_grid_new(void)
-{
-
- HildonGrid *grid;
-
- grid = g_object_new(HILDON_TYPE_GRID, NULL);
-
- return GTK_WIDGET(grid);
-}
-
-
-static void hildon_grid_realize(GtkWidget * widget)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GdkWindowAttr attr;
- gint attr_mask;
-
-
- GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- /* Create GdkWindow for catching events. */
- attr.x = widget->allocation.x;
- attr.y = widget->allocation.y;
- attr.width = widget->allocation.width - priv->scrollbar_width;
- attr.height = widget->allocation.height;
- attr.window_type = GDK_WINDOW_CHILD;
- attr.event_mask = gtk_widget_get_events(widget)
- | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
-
- widget->window = gtk_widget_get_parent_window(widget);
- g_object_ref(widget->window);
-
- attr.wclass = GDK_INPUT_ONLY;
- attr_mask = GDK_WA_X | GDK_WA_Y;
-
- priv->event_window = gdk_window_new(widget->window, &attr, attr_mask);
- gdk_window_set_user_data(priv->event_window, widget);
-
- widget->style = gtk_style_attach(widget->style, widget->window);
-
- gtk_style_set_background(widget->style,
- widget->window, GTK_STATE_NORMAL);
-}
-
-
-static void hildon_grid_unrealize(GtkWidget * widget)
-{
- HildonGridPrivate *priv;
-
- priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(widget));
-
- if (priv->event_window != NULL) {
- gdk_window_set_user_data(priv->event_window, NULL);
- gdk_window_destroy(priv->event_window);
- priv->event_window = NULL;
- }
-
- if (GTK_WIDGET_CLASS(parent_class)->unrealize) {
- (*GTK_WIDGET_CLASS(parent_class)->unrealize) (widget);
- }
-}
-
-
-
-static void hildon_grid_map(GtkWidget * widget)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
-
- g_return_if_fail(HILDON_IS_GRID(widget));
-
- if (!GTK_WIDGET_VISIBLE(widget))
- return;
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- (*GTK_WIDGET_CLASS(parent_class)->map) (widget);
-
- /* We shouldn't really need the following...*/
- if (priv->scrollbar != NULL && GTK_WIDGET_VISIBLE(priv->scrollbar)) {
- if (!GTK_WIDGET_MAPPED(priv->scrollbar)) {
- gtk_widget_map(priv->scrollbar);
- }
- }
-
- if (priv->empty_label != NULL &&
- GTK_WIDGET_VISIBLE(priv->empty_label)) {
- if (!GTK_WIDGET_MAPPED(priv->empty_label)) {
- gtk_widget_map(priv->empty_label);
- }
- }
-
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- if (GTK_WIDGET_VISIBLE(child)) {
- if (!GTK_WIDGET_MAPPED(child)) {
- gtk_widget_map(child);
- }
- }
- }
- /* END OF don't really need */
-
- /* Also make event window visible. */
- gdk_window_show(priv->event_window);
-}
-
-
-
-static void hildon_grid_unmap(GtkWidget * widget)
-{
- HildonGridPrivate *priv;
-
- priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(widget));
-
- if (priv->event_window != NULL) {
- gdk_window_hide(priv->event_window);
- }
-
- (*GTK_WIDGET_CLASS(parent_class)->unmap) (widget);
-}
-
-
-
-static gboolean
-hildon_grid_expose(GtkWidget * widget, GdkEventExpose * event)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GtkContainer *container;
- GList *list;
- gint child_no;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(HILDON_IS_GRID(widget), FALSE);
- g_return_val_if_fail(event, FALSE);
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
- container = GTK_CONTAINER(grid);
-
- /* If grid has no children,
- * propagate the expose event to the label is one exists */
- if (priv->children == NULL || g_list_length(priv->children) == 0) {
- if (priv->empty_label != NULL) {
- gtk_container_propagate_expose(container,
- priv->empty_label, event);
- }
- return FALSE;
- }
-
- /* Only expose visible children. */
-
- /* Jump over invisible. */
- for (list = priv->children, child_no = 0;
- list != NULL && child_no < priv->first_index;
- list = list->next, child_no++) {
- ; /* Nothing here. */
- }
-
- for (; list != NULL && child_no < priv->first_index +
- priv->num_columns * priv->area_rows; list = list->next) {
- gtk_container_propagate_expose(container,
- ((HildonGridChild *) list->data)
- ->widget, event);
- }
-
- /* Keep focused item focused. */
- if (container->focus_child != NULL
- && !GTK_WIDGET_HAS_FOCUS(container->focus_child)) {
- set_focus(grid, container->focus_child, FALSE);
- }
- if (priv->scrollbar_width > 0 && priv->scrollbar != NULL) {
- gtk_container_propagate_expose(container, priv->scrollbar, event);
- }
-
- return FALSE;
-}
-
-
-static void
-hildon_grid_size_request(GtkWidget * widget, GtkRequisition * requisition)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
- GtkRequisition req;
-
- g_return_if_fail(widget);
- g_return_if_fail(requisition);
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- /* Want as big as possible. */
- requisition->width = 0x7fff; /* Largest possible gint16 */
- requisition->height = 0x7fff; /* Largest possible gint16 */
-
- if (priv->children == NULL) {
- if (priv->empty_label != NULL &&
- GTK_WIDGET_VISIBLE(priv->empty_label)) {
- gtk_widget_size_request(priv->empty_label, &req);
- }
- }
-
- if (priv->scrollbar != NULL && GTK_WIDGET_VISIBLE(priv->scrollbar)) {
- gtk_widget_size_request(priv->scrollbar, &req);
- }
-
- for (list = priv->children; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- gtk_widget_size_request(child, &req);
- }
-}
-
-/*
- * hildon_grid_size_allocate:
- *
- * Supposingly called when size of grid changes and after view have moved so
- * that items need to be relocated.
- */
-static void
-hildon_grid_size_allocate(GtkWidget * widget, GtkAllocation * allocation)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *child;
- gint child_no;
- gint y_offset;
- gint row_margin;
-
- GtkAllocation alloc;
- GtkRequisition req;
-
- g_return_if_fail(widget);
- g_return_if_fail(allocation);
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
- widget->allocation = *allocation;
-
- get_style_properties(grid);
-
- /* First of all, make sure GdkWindow is over our widget. */
- if (priv->event_window != NULL) {
- gdk_window_move_resize(priv->event_window,
- widget->allocation.x,
- widget->allocation.y,
- widget->allocation.width -
- priv->scrollbar_width,
- widget->allocation.height);
- }
- /* Show the label if there are no items. */
- if (priv->children == NULL) {
- /*
- * We probably don't need this as scrollbar should be hidden when
- * removing items, but one can never be too sure...
- */
- if (priv->scrollbar != NULL &&
- GTK_WIDGET_VISIBLE(priv->scrollbar)) {
- priv->scrollbar_width = 0;
- gtk_widget_hide(priv->scrollbar);
- }
-
- /* Show label if creating one actually worked. */
- if (priv->empty_label != NULL) {
- gtk_widget_get_child_requisition(priv->empty_label, &req);
-
- /* ...for sure we must have a position for the label here... */
- alloc.x = allocation->x + GRID_LABEL_POS_PAD;
- alloc.y = allocation->y + GRID_LABEL_POS_PAD;
- alloc.width = MIN(req.width, allocation->width -
- GRID_LABEL_POS_PAD);
- alloc.height = MIN(req.height, allocation->height -
- GRID_LABEL_POS_PAD);
-
- /* Make sure we don't use negative values. */
- if (alloc.width < 0) {
- alloc.width = 0;
- }
- if (alloc.height < 0) {
- alloc.height = 0;
- }
-
- gtk_widget_size_allocate(priv->empty_label, &alloc);
-
- if (!GTK_WIDGET_VISIBLE(priv->empty_label)) {
- gtk_widget_show(priv->empty_label);
- }
- }
-
- return;
- }
-
- /* As we have some items, hide label if it was visible. */
- if (priv->empty_label != NULL &&
- GTK_WIDGET_VISIBLE(priv->empty_label)) {
- gtk_widget_hide(priv->empty_label);
- }
-
- priv->area_height = allocation->height;
- priv->area_rows = allocation->height / priv->item_height;
-
- /* Adjust/show/hide scrollbar. */
- adjust_scrollbar_height(grid);
- if (priv->old_item_height != priv->item_height) {
- priv->old_item_height = priv->item_height;
- jump_scrollbar_to_focused(grid);
- }
-
- /* Update item width. */
- if (priv->num_columns == 1) {
- priv->item_width = allocation->width - priv->scrollbar_width -
- priv->h_margin - priv->scrollbar_width;
- } else {
- priv->item_width = (allocation->width - priv->scrollbar_width) /
- priv->num_columns;
- }
-
- priv->first_index =
- (int) gtk_range_get_value(GTK_RANGE(priv->scrollbar)) /
- priv->item_height * priv->num_columns;
-
- /* Hide items before visible ones. */
- for (list = priv->children, child_no = 0;
- list != NULL && child_no < priv->first_index;
- list = list->next, child_no++) {
- child = ((HildonGridChild *) list->data)->widget;
-
- if (GTK_WIDGET_VISIBLE(child)) {
- gtk_widget_hide(child);
- }
- }
-
- /* Allocate visible items. */
- alloc.width = priv->item_width - priv->h_margin;
- switch (priv->label_pos) {
- case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
- row_margin = priv->icon_label_margin;
- break;
- case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
- row_margin = priv->v_margin;
- break;
- default:
- row_margin = 0;
- break;
- }
- alloc.height = priv->item_height - row_margin;
-
- for (y_offset = priv->first_index / priv->num_columns * priv->item_height;
- list != NULL && child_no < priv->first_index +
- priv->area_rows * priv->num_columns;
- list = list->next, child_no++) {
- child = ((HildonGridChild *) list->data)->widget;
-
- if (!GTK_WIDGET_VISIBLE(child)) {
- gtk_widget_show(child);
- }
-
- /* Don't update icons which are not visible... */
- alloc.y = (child_no / priv->num_columns) * priv->item_height +
- allocation->y - y_offset + row_margin;
- alloc.x = (child_no % priv->num_columns) * priv->item_width +
- allocation->x;
-
- _hildon_grid_item_done_updating_settings(HILDON_GRID_ITEM(child));
- gtk_widget_size_allocate(child, &alloc);
- }
-
- /* Hide items after visible items. */
- for (; list != NULL; list = list->next) {
- child = ((HildonGridChild *) list->data)->widget;
-
- if (GTK_WIDGET_VISIBLE(child)) {
- gtk_widget_hide(child);
- }
- }
-}
-
-
-
-/**
- * hildon_grid_add:
- * @container: container (#HildonGrid) to add HildonGridItem into
- * @widget: #GtkWidget (#HildonGridItem) to add
- *
- * Adds a new HildonGridItem into HildonGrid.
- */
-static void hildon_grid_add(GtkContainer * container, GtkWidget * widget)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- HildonGridChild *child;
-
-
- g_return_if_fail(HILDON_IS_GRID(container));
- g_return_if_fail(HILDON_IS_GRID_ITEM(widget));
-
- grid = HILDON_GRID(container);
- priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(grid));
- GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW);
-
- child = g_new(HildonGridChild, 1);
- if (child == NULL) {
- g_critical("no memory for child - not adding");
- return;
- }
- child->widget = widget;
-
- _hildon_grid_item_set_label_pos (HILDON_GRID_ITEM(widget), priv->label_pos);
- _hildon_grid_item_set_focus_margin(HILDON_GRID_ITEM(widget), priv->focus_margin);
- _hildon_grid_item_set_icon_width (HILDON_GRID_ITEM(widget), priv->icon_width);
- _hildon_grid_item_set_emblem_size (HILDON_GRID_ITEM(widget), priv->emblem_size);
-
- /* Add the new item to the grid */
- priv->children = g_list_append(priv->children, child);
- gtk_widget_set_parent(widget, GTK_WIDGET(grid));
-
- /* Property changes (child's set_sensitive) */
- g_signal_connect_after(G_OBJECT(widget), "state-changed",
- G_CALLBACK(hildon_grid_state_changed), grid);
-
- /* Matches both empty grid and all-dimmed grid. */
- if (GTK_CONTAINER(grid)->focus_child == NULL)
- set_focus(grid, widget, TRUE);
-
- /*
- * If item was added in visible area, relocate items. Otherwise update
- * scrollbar and see if items need relocating.
- */
- if (g_list_length(priv->children) < priv->first_index +
- priv->area_rows * priv->num_columns) {
- gtk_widget_queue_resize(GTK_WIDGET(grid));
- } else {
- gboolean updated;
-
- updated = adjust_scrollbar_height(grid);
- /* Basically this other test is useless -- shouldn't need to jump.
- */
- updated |= jump_scrollbar_to_focused(grid);
-
- if (updated) {
- gtk_widget_queue_resize(GTK_WIDGET(grid));
- }
- }
-}
-
-/**
- * hildon_grid_remove:
- * @container: container (#HildonGrid) to remove #HildonGridItem from
- * @widget: widget (#HildonGridItem) to be removed
- *
- * Removes HildonGridItem from HildonGrid.
- */
-static void
-hildon_grid_remove(GtkContainer * container, GtkWidget * widget)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- HildonGridChild *child;
- GtkWidget *child_widget;
- GList *list;
- gint index, old_index;
- gboolean deleted;
- gboolean updated;
-
- g_return_if_fail(HILDON_IS_GRID(container));
- g_return_if_fail(HILDON_IS_GRID_ITEM(widget));
-
- grid = HILDON_GRID(container);
- priv = HILDON_GRID_GET_PRIVATE(container);
-
- old_index = priv->focus_index;
- updated = GTK_WIDGET_VISIBLE(widget);
-
- for (list = priv->children, index = 0, deleted = FALSE;
- list != NULL; list = list->next, index++) {
- child = (HildonGridChild *) list->data;
- child_widget = child->widget;
-
- /* Remove the Item if it is found in the grid */
- if (child_widget == widget) {
- gtk_widget_unparent(child_widget);
- priv->children = g_list_remove_link(priv->children, list);
- g_list_free(list);
- g_free(child);
-
- deleted = TRUE;
-
- break;
- }
- }
-
- /* Emit warning if the item is not found */
- if (!deleted) {
- g_warning("tried to remove unexisting item");
- return;
- }
-
- /* Move focus somewhere. */
- if (old_index == index) {
- if (old_index == g_list_length(priv->children)) {
- if (index == 0) {
- set_focus(grid, NULL, TRUE);
- } else {
- set_focus(grid,
- get_child_by_index(priv, old_index - 1), TRUE);
- }
- } else {
- set_focus(grid, get_child_by_index(priv, old_index), TRUE);
- }
- } else {
- set_focus(grid, GTK_CONTAINER(grid)->focus_child, TRUE);
- }
-
- updated |= adjust_scrollbar_height(grid);
- updated |= jump_scrollbar_to_focused(grid);
-
- if (updated) {
- gtk_widget_queue_resize(GTK_WIDGET(grid));
- }
-}
-
-/**
- * hildon_grid_set_focus_child:
- * @container: HildonGrid
- * @widget: HildonGridItem
- *
- * Sets focus.
- */
-static void
-hildon_grid_set_focus_child(GtkContainer * container, GtkWidget * widget)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID(container));
- g_return_if_fail(HILDON_IS_GRID_ITEM(widget) || widget == NULL);
-
- grid = HILDON_GRID(container);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- if (GTK_CONTAINER(grid)->focus_child == widget || widget == NULL)
- return;
-
- set_focus(grid, widget, TRUE);
-}
-
-
-
-static void
-set_focus(HildonGrid * grid, GtkWidget * widget, gboolean refresh_view)
-{
- HildonGridPrivate *priv;
- GtkContainer *container;
- gboolean view_updated;
-
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- container = GTK_CONTAINER(grid);
-
- /* If widget is NULL -> unfocus */
- if (widget == NULL && container->focus_child != NULL)
- GTK_WIDGET_UNSET_FLAGS(container->focus_child, GTK_HAS_FOCUS);
-
- GTK_CONTAINER(grid)->focus_child = widget;
- if (widget == NULL) {
- priv->focus_index = -1;
- return;
- }
-
- /* Get the child index which the user wanted to focus */
- priv->focus_index = get_child_index(priv, widget);
-
- gtk_widget_grab_focus(widget);
-
- if (refresh_view) {
- view_updated = jump_scrollbar_to_focused(grid);
- } else {
- view_updated = FALSE;
- }
-
- if (view_updated) {
- hildon_grid_size_allocate(GTK_WIDGET(grid),
- >K_WIDGET(grid)->allocation);
- }
-}
-
-static void
-hildon_grid_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GList *list;
-
- g_return_if_fail(container);
- g_return_if_fail(callback);
-
- grid = HILDON_GRID(container);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- /* Connect callback functions */
- if (include_internals) {
- if (priv->scrollbar != NULL) {
- (*callback) (priv->scrollbar, callback_data);
- }
- if (priv->empty_label != NULL) {
- (*callback) (priv->empty_label, callback_data);
- }
- }
-
- for (list = priv->children; list != NULL; list = list->next) {
- (*callback) (((HildonGridChild *) list->data)->widget,
- callback_data);
- }
-}
-
-static void hildon_grid_destroy(GtkObject * self)
-{
- HildonGridPrivate *priv;
-
- g_return_if_fail(self != NULL);
- g_return_if_fail(HILDON_IS_GRID(self));
-
- priv = HILDON_GRID_GET_PRIVATE(self);
-
- if (GTK_WIDGET(self)->window != NULL) {
- g_object_unref(G_OBJECT(GTK_WIDGET(self)->window));
- }
-
- gtk_container_forall(GTK_CONTAINER(self),
- (GtkCallback) gtk_object_ref, NULL);
- gtk_container_forall(GTK_CONTAINER(self),
- (GtkCallback) gtk_widget_unparent, NULL);
-
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-static void hildon_grid_finalize(GObject * object)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
-
- grid = HILDON_GRID(object);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- gtk_container_forall(GTK_CONTAINER(object),
- (GtkCallback) gtk_object_unref, NULL);
-
- if (priv->style != NULL) {
- g_free(priv->style);
- }
- if (G_OBJECT_CLASS(parent_class)->finalize) {
- G_OBJECT_CLASS(parent_class)->finalize(object);
- }
-}
-
-/*
- * hildon_grid_key_pressed:
- * @widget: Widget where we get the signal from
- * @event: EventKey
- * @data: #HildonGrid
- *
- * Handle user key press (keyboard navigation).
- *
- * And here's how it works if some items are dimmed (moving to right):
- * . . . . . . # . . 2 # . . # . .
- * . 1 # 2 . 1 # # 1 # # # 1 # # #
- * . . . . . 2 . . . . 2 .
- *
- * '.' = item,
- * '#' = dimmed item,
- * '1' = starting position,
- * '2' = final position
- *
- * ...although only the first example is implemented right now.
- *
- * Return value: Signal handled
- */
-static gboolean
-hildon_grid_key_pressed(GtkWidget * widget,
- GdkEventKey * event)
-{
- GtkAdjustment *adjustment;
- GtkContainer *container;
- GtkWidget *new_focus;
- HildonGrid *grid;
- HildonGridPrivate *priv;
- gboolean shift;
- gint keyval;
- gint x, y;
- gint focus_index;
- gint child_count, child_rows;
- gint t;
- gint addition, max_add;
-
- g_return_val_if_fail(widget, FALSE);
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- /*
- * If focus was never lost, we could just see if an item is focused -
- * if not, there's nothing else to focus...
- */
-
- /* No items? */
- if (priv->children == NULL || g_list_length(priv->children) == 0)
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
-
- /* Focused item is dimmed? */
- /* If we have no focus, allow non-existing focus to move... */
- container = GTK_CONTAINER(grid);
- if (container->focus_child != NULL
- && !GTK_WIDGET_IS_SENSITIVE(container->focus_child)) {
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
- }
- /* At the moment we don't want to do anything here if alt or control
- or MODX is pressed, so return now. Shift + TAB are accepted (from
- hildon-table-grid) And right now modifiers do not make any
- difference... */
-
- /* Said somewhere that "foo = a == b" is not desirable. */
- if (event->state & GDK_SHIFT_MASK) {
- shift = TRUE;
- } else {
- shift = FALSE;
- }
-
- keyval = event->keyval;
- if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL) {
- switch (event->keyval) {
- case GDK_Left:
- keyval = GDK_Right;
- break;
- case GDK_KP_Left:
- keyval = GDK_KP_Right;
- break;
- case GDK_Right:
- keyval = GDK_Left;
- break;
- case GDK_KP_Right:
- keyval = GDK_KP_Left;
- break;
- }
- }
-
- child_count = g_list_length(priv->children);
- child_rows = (child_count - 1) / priv->num_columns + 1;
-
- if (priv->focus_index != -1) {
- x = priv->focus_index % priv->num_columns;
- y = priv->focus_index / priv->num_columns;
- } else {
- x = y = 0;
- }
-
- switch (keyval) {
- case GDK_KP_Page_Up:
- case GDK_Page_Up:
- if (priv->first_index == 0) {
- if (priv->focus_index == 0) {
- return TRUE;
- }
- set_focus(grid, get_child_by_index(priv, 0), TRUE);
- return TRUE;
- }
-
- t = MAX(priv->first_index / priv->num_columns - priv->area_rows, 0);
- adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
- adjustment->value = (gdouble) (t * priv->item_height);
- gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
- gtk_widget_queue_draw(priv->scrollbar);
- update_contents(grid);
-
- /* Want to update now. */
- hildon_grid_size_allocate(GTK_WIDGET(grid),
- >K_WIDGET(grid)->allocation);
-
- return TRUE;
- break;
-
- case GDK_KP_Page_Down:
- case GDK_Page_Down:
- if (priv->first_index / priv->num_columns ==
- child_rows - priv->area_rows) {
- if (priv->focus_index == child_count - 1) {
- return TRUE;
- }
- set_focus(grid, get_child_by_index(priv, child_count - 1),
- TRUE);
- return TRUE;
- }
-
- t = MIN(priv->first_index / priv->num_columns +
- priv->area_rows, child_rows - priv->area_rows);
- adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
- adjustment->value = (gdouble) (t * priv->item_height);
- gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
- gtk_widget_queue_draw(priv->scrollbar);
- update_contents(grid);
-
- /* Want to update now. */
- hildon_grid_size_allocate(GTK_WIDGET(grid),
- >K_WIDGET(grid)->allocation);
-
- return TRUE;
- break;
-
- case GDK_KP_Up:
- case GDK_Up:
- if (y <= 0) {
- return TRUE;
- }
- addition = -priv->num_columns;
- max_add = y;
- y--;
- break;
-
- case GDK_KP_Down:
- case GDK_Down:
- if (y >= (child_count - 1) / priv->num_columns) {
- return TRUE;
- }
- t = child_count % priv->num_columns;
- if (t == 0) {
- t = priv->num_columns;
- }
- if (y == (child_count - 1) / priv->num_columns - 1 && x >= t) {
- x = t - 1;
- }
- y++;
- addition = priv->num_columns;
- max_add = child_rows - y;
- break;
-
- case GDK_KP_Left:
- case GDK_Left:
- if (x <= 0) {
- return TRUE;
- }
- addition = -1;
- max_add = x;
- x--;
- break;
-
- case GDK_KP_Right:
- case GDK_Right:
- if (x >= priv->num_columns - 1) {
- return TRUE;
- }
- if (y == 0 && x >= child_count - 1) {
- return TRUE;
- }
- x++;
- addition = 1;
- max_add = priv->num_columns - x;
- if (y * priv->num_columns + x == child_count) {
- y--;
- }
- break;
- case GDK_KP_Enter:
- case GDK_Return:
- hildon_grid_activate_child(grid,
- HILDON_GRID_ITEM
- (GTK_CONTAINER(grid)->focus_child));
- return TRUE;
- break;
- default:
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
- break;
- }
-
- focus_index = y * priv->num_columns + x;
- new_focus = get_child_by_index(priv, focus_index);
-
- while (new_focus != NULL &&
- focus_index < child_count && !GTK_WIDGET_SENSITIVE(new_focus)) {
- max_add--;
-
- if (max_add == 0) {
- return TRUE;
- }
- focus_index += addition;
- new_focus = get_child_by_index(priv, focus_index);
- }
-
- if (new_focus != NULL) {
- set_focus(grid, new_focus, TRUE);
- }
- return TRUE;
-}
-
-
-/*
- * hildon_grid_button_pressed:
- * @widget: Widget where signal is coming from
- * @event: #EventButton
- * @data: #HildonGrid
- *
- * Handle mouse button press.
- *
- * Return value: Signal handled
- */
-static gboolean
-hildon_grid_button_pressed(GtkWidget * widget,
- GdkEventButton * event)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GtkWidget *child;
- int child_no;
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
-/* Watch out for double/triple click press events */
-
- if (event->type == GDK_2BUTTON_PRESS ||
- event->type == GDK_3BUTTON_PRESS) {
- priv->last_button_event = event->type;
- return FALSE;
- }
-
- priv->last_button_event = event->type;
-
- if (event->type != GDK_BUTTON_PRESS)
- return FALSE;
-
-
- child_no = get_child_index_by_coord(priv, event->x, event->y);
-
- if (child_no == -1 || child_no >= g_list_length(priv->children))
- return FALSE;
-
- child = get_child_by_index(priv, child_no);
- if (!GTK_WIDGET_IS_SENSITIVE(child))
- return FALSE;
-
- priv->click_x = event->x;
- priv->click_y = event->y;
-
- return FALSE;
-}
-
-/*
- * hildon_grid_button_released:
- * @widget: Widget the signal is coming from
- * @event: #EventButton
- * @data: #HildonGrid
- *
- * Handle mouse button release.
- *
- * Return value: Signal handled
- */
-static gboolean
-hildon_grid_button_released(GtkWidget * widget,
- GdkEventButton * event)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GtkWidget *child;
- int child_no;
- gboolean already_selected;
-
- grid = HILDON_GRID(widget);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- /* In case of double/triple click, silently ignore the release event */
-
- if (priv->last_button_event == GDK_2BUTTON_PRESS ||
- priv->last_button_event == GDK_3BUTTON_PRESS) {
- priv->last_button_event = event->type;
- return FALSE;
- }
-
- child_no = get_child_index_by_coord(priv, event->x, event->y);
-
- if (child_no == -1 || child_no >= g_list_length(priv->children)) {
- return FALSE;
- }
- child = get_child_by_index(priv, child_no);
- if (!GTK_WIDGET_IS_SENSITIVE(child)) {
- return FALSE;
- }
- if (abs(priv->click_x - event->x) >= DRAG_SENSITIVITY
- && abs(priv->click_y - event->y) >= DRAG_SENSITIVITY) {
- return FALSE;
- }
-
- /* Check if this element was already selected */
- already_selected = (priv->focus_index == child_no);
-
- set_focus(grid, child, TRUE);
- priv->last_button_event = event->type;
-
- /* If this is not the first click in this element, activate it */
- if (already_selected)
- hildon_grid_activate_child(grid, HILDON_GRID_ITEM(child));
-
- return FALSE;
-}
-
-/*
- * hildon_grid_scrollbar_moved:
- * @widget: Widget which sent the signal
- * @data: #HildonGrid
- *
- * Update HildonGrid contents when scrollbar is moved.
- *
- * Return value: Signal handeld
- */
-static gboolean
-hildon_grid_scrollbar_moved(GtkWidget * widget, gpointer data)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- gboolean updated = FALSE;
-
- grid = HILDON_GRID(data);
- priv = HILDON_GRID_GET_PRIVATE(grid);
- updated = update_contents(grid);
-
- /*
- * If grid changes focus while dragging scrollbar and pointer leaves
- * scrollbar, focus is moved to prev_focus... This prevents that.
- */
- gtk_window_set_prev_focus_widget(GTK_WINDOW
- (gtk_widget_get_toplevel(widget)),
- GTK_CONTAINER(grid)->focus_child);
-
- if (updated)
- /* Don't just queue it, let's do it now! */
- hildon_grid_size_allocate(GTK_WIDGET(grid),
- >K_WIDGET(grid)->allocation);
-
- return TRUE;
-}
-
-
-/*
- * update_contents:
- * @grid: #HildonGrid
- *
- * Update the view if scrollbar has moved so that first visible row
- * should've changed. Returns true if location actually changed.
- *
- * Return value: Content changed
- */
-static gboolean update_contents(HildonGrid * grid)
-{
- HildonGridPrivate *priv;
- gint new_row;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- new_row = (int) gtk_range_get_value(GTK_RANGE(priv->scrollbar))
- / priv->item_height;
-
- if (new_row != priv->old_sb_pos) {
- priv->old_sb_pos = new_row;
- priv->first_index = new_row * priv->num_columns;
-
- return TRUE;
- }
- return FALSE;
-}
-
-/*
- * jump_scrollbar_to_focused:
- * @grid: #HildonGrid
- *
- * Moves scrollbar position so that focused item will be shown
- * in visible area.
- * Returns TRUE if visible position of widgets have changed.
- *
- * Return value: Content changed
- */
-static gboolean jump_scrollbar_to_focused(HildonGrid * grid)
-{
- HildonGridPrivate *priv;
- GtkAdjustment *adjustment;
- gint child_count;
- gint empty_grids;
- gint new_row;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- /* If we don't have scrollbar, let the focus be broken, too. */
- g_return_val_if_fail(priv->scrollbar != NULL, FALSE);
-
- /* Make sure "first widget" is something sensible. */
- priv->first_index = priv->first_index -
- priv->first_index % priv->num_columns;
-
- child_count = g_list_length(priv->children);
- empty_grids = priv->num_columns * priv->area_rows - child_count +
- priv->first_index;
-
- /* Determine the position of the new row */
- if (priv->focus_index < priv->first_index) {
- new_row = priv->focus_index / priv->num_columns;
- } else if (priv->focus_index >= priv->first_index +
- priv->area_rows * priv->num_columns) {
- gint last_top_row;
- new_row = priv->focus_index / priv->num_columns -
- priv->area_rows + 1;
- last_top_row = child_count / priv->num_columns - priv->area_rows + 1;
- if (child_count % priv->num_columns != 0) {
- last_top_row++;
- }
- if (new_row > last_top_row) {
- new_row = last_top_row;
- }
- } else if (empty_grids >= priv->num_columns) {
- new_row = ((child_count - 1) / priv->num_columns + 1)
- - priv->area_rows;
- if (new_row < 0) {
- new_row = 0;
- }
- } else {
- return FALSE;
- }
-
- /* Move scrollbar accordingly. */
- adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
- adjustment->value = (gdouble) (new_row * priv->item_height);
- gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
- priv->first_index = new_row * priv->num_columns;
- priv->old_sb_pos = new_row;
-
- gtk_widget_queue_draw(priv->scrollbar);
-
- return TRUE;
-}
-
-
-/*
- * adjust_scrollbar_height:
- * @grid: HildonGridPrivate
- *
- * Return value: View should change
- *
- * Adjust scrollbar according the #HildonGrid contents.
- * Show/hide scrollbar if
- * appropriate. Also sets priv->first_index.
- */
-static gboolean adjust_scrollbar_height(HildonGrid * grid)
-{
- HildonGridPrivate *priv;
- GtkRequisition req;
- GtkAdjustment *adj;
- GtkAllocation alloc;
- GtkAllocation *gridalloc;
- gint old_upper;
- gint need_rows;
- gint need_pixels;
- gboolean updated;
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- g_return_val_if_fail(priv->scrollbar != NULL, FALSE);
-
- updated = FALSE;
- gridalloc = >K_WIDGET(grid)->allocation;
-
- /* See if we need scrollbar at all. */
- if (priv->num_columns == 0) {
- priv->num_columns = DEFAULT_N_COLUMNS;
- } else {
- priv->num_columns = MAX(1, priv->num_columns);
- }
-
- if (g_list_length(priv->children) != 0) {
- need_rows = (g_list_length(priv->children) - 1) /
- priv->num_columns + 1;
- } else {
- need_rows = 0;
- }
-
- if (need_rows <= priv->area_rows) {
- updated = priv->first_index != 0;
- priv->scrollbar_width = 0;
-
- priv->first_index = 0;
- if (GTK_WIDGET_VISIBLE(priv->scrollbar)) {
- GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET (grid));
- if (HILDON_IS_APP (parent))
- g_object_set (parent, "scroll-control", FALSE, NULL);
- gtk_widget_hide(priv->scrollbar);
- updated = TRUE;
- }
-
- return updated;
- }
-
- /* All right then, we need scrollbar. Place scrollbar on the screen. */
- gtk_widget_get_child_requisition(priv->scrollbar, &req);
- priv->scrollbar_width = req.width;
-
- alloc.width = req.width;
- alloc.height = gridalloc->height;
- alloc.x = gridalloc->width - req.width + gridalloc->x;
- alloc.y = gridalloc->y;
- gtk_widget_size_allocate(priv->scrollbar, &alloc);
-
- if (!GTK_WIDGET_VISIBLE(priv->scrollbar)) {
- GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET (grid));
- if (HILDON_IS_APP (parent))
- g_object_set (parent, "scroll-control", TRUE, NULL);
- gtk_widget_show(priv->scrollbar);
- updated = TRUE;
- }
-
-
- need_pixels = need_rows * priv->item_height;
-
- /* Once we know how much space we need, update the scrollbar. */
- adj = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
- old_upper = (int) adj->upper;
- adj->lower = 0.0;
- adj->upper = (gdouble) need_pixels;
- adj->step_increment = (gdouble) priv->item_height;
- adj->page_increment = (gdouble) (priv->area_rows * priv->item_height);
- adj->page_size =
- (gdouble) (priv->area_height - priv->area_height % priv->item_height);
-
- /* Also update position if needed to show focused item. */
-
- gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adj);
-
- /* Then set first_index. */
- priv->first_index = (int) adj->value / priv->item_height *
- priv->num_columns;
-
- /* Finally, ask Gtk to redraw the scrollbar. */
- if (old_upper != (int) adj->upper) {
- gtk_widget_queue_draw(priv->scrollbar);
- }
- return updated;
-}
-
-/*
- * get_child_index_by_coord:
- * @priv: HildonGridPrivate
- * @x: X-coordinate
- * @y: Y-coordinate
- *
- * Returns index of child at given coordinates, -1 if no child.
- *
- * Return value: Index
- */
-static gint
-get_child_index_by_coord(HildonGridPrivate * priv, gint x, gint y)
-{
- int xgap, ygap;
- int t;
-
- if (priv->item_width==0 || priv->item_height==0) {
- return -1;
- }
-
- xgap = x % priv->item_width;
- ygap = y % priv->item_height;
-
- if (xgap > priv->item_width - priv->h_margin) { /*FIXME*/
- return -1;
- }
-
- /* Event may come from outside of the grid. Skipping those events */
- if (x >= priv->item_width * priv->num_columns)
- return -1;
-
- t = y / priv->item_height * priv->num_columns +
- x / priv->item_width + priv->first_index;
-
- if (t >= priv->first_index + priv->area_rows * priv->num_columns ||
- t >= g_list_length(priv->children) || t < 0) {
- return -1;
- }
- return t;
-}
-
-/*
- * get_child_by_index:
- * @priv: HildonGridPrivate
- * @index: Index of child
- *
- * Returns child that is #th in HildonGrid or NULL if child was not found
- * among the children.
- *
- * Return value: GtkWidget
- */
-static GtkWidget *get_child_by_index(HildonGridPrivate * priv, gint index)
-{
- GList *list;
- int i = 0;
-
- if (index >= g_list_length(priv->children) || index < 0) {
- return NULL;
- }
- for (list = priv->children, i = 0; list != NULL;
- list = list->next, i++) {
- if (index == i) {
- return ((HildonGridChild *) list->data)->widget;
- }
- }
-
- g_warning("no such child");
- return NULL;
-}
-
-/*
- * get_child_index:
- * @priv: HildonGridPrivate
- * @child: #GtkWidget to look for
- *
- * Returns index of a child or -1 if child was not found among the
- * children.
- *
- * Return value: Index
- */
-static gint get_child_index(HildonGridPrivate * priv, GtkWidget * child)
-{
- GList *list;
- gint index;
-
- if (child == NULL)
- return -1;
-
- for (list = priv->children, index = 0;
- list != NULL; list = list->next, index++) {
- if (((HildonGridChild *) list->data)->widget == child) {
- return index;
- }
- }
-
- g_warning("no such child");
- return -1;
-}
-
-
-/**
- * hildon_grid_activate_child:
- * @grid: #HildonGrid
- * @item: #HildonGridItem
- *
- * Sends a signal to indicate that this HildonGridItem is activated.
- */
-void hildon_grid_activate_child(HildonGrid * grid, HildonGridItem * item)
-{
- g_return_if_fail(HILDON_IS_GRID(grid));
-
- g_signal_emit(grid, grid_signals[ACTIVATE_CHILD], 0, item);
-}
-
-
-
-/**
- * hildon_grid_set_style:
- * @grid: #HildonGrid
- * @style_name: style name
- *
- * Sets style. Setting style sets widget size, spacing, label position,
- * number of columns, and icon size.
- */
-void hildon_grid_set_style(HildonGrid * grid, const gchar * style_name)
-{
- HildonGridPrivate *priv;
-
- g_return_if_fail(HILDON_IS_GRID(grid));
-
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- if (priv->style != NULL) {
- g_free((gpointer) priv->style);
- }
- if (style_name != NULL) {
- priv->style = g_strdup(style_name);
- } else {
- priv->style = NULL;
- }
-
- gtk_widget_set_name(GTK_WIDGET(grid), style_name);
- get_style_properties(grid);
-
- gtk_widget_queue_resize(GTK_WIDGET(grid));
-}
-
-/**
- * hildon_grid_get_style:
- * @grid: #HildonGrid
- *
- * Returns the name of style currently used in HildonGrid.
- *
- * Returns: style name
- */
-const gchar *hildon_grid_get_style(HildonGrid * grid)
-{
- g_return_val_if_fail(HILDON_IS_GRID(grid), NULL);
-
- return gtk_widget_get_name(GTK_WIDGET(grid));
-}
-
-/*
- * get_style_properties:
- * @grid: #HildonGrid
- *
- * Gets widget size and other properties from gtkrc. If some properties
- * have changed, notify children of this, too.
- */
-static void get_style_properties(HildonGrid * grid)
-{
- GList *iter;
- gint num_columns;
- HildonGridPositionType label_pos;
- gint emblem_size;
-
- gint h_margin, v_margin;
- gint item_height;
- gint icon_width;
- gint focus_margin, icon_label_margin;
- gint label_height;
-
- HildonGridPrivate *priv;
- g_return_if_fail(HILDON_IS_GRID(grid));
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
- gtk_widget_style_get(GTK_WIDGET(grid),
- "item_hspacing", &h_margin,
- "item_vspacing", &v_margin,
- "item_height", &item_height,
- "icon_size", &icon_width,
- "n_columns", &num_columns,
- "label_pos", &label_pos,
- "label_hspacing", &focus_margin,
- "label_vspacing", &icon_label_margin,
- "emblem_size", &emblem_size,
- "label_height", &label_height,
- NULL);
-
- hildon_grid_set_icon_width(grid, icon_width);
- hildon_grid_set_num_columns(grid, num_columns);
- hildon_grid_set_label_pos(grid, label_pos);
- hildon_grid_set_focus_margin(grid, focus_margin);
- hildon_grid_set_icon_label_margin(grid, icon_label_margin);
- hildon_grid_set_emblem_size(grid, emblem_size);
- hildon_grid_set_label_height(grid, label_height);
-
- priv->h_margin = h_margin;
- priv->v_margin = v_margin;
- priv->item_height = item_height;
-
- iter = NULL;
- /*
- for (iter = priv->children; iter != NULL; iter = iter->next) {
- HildonGridItem *child;
- child = HILDON_GRID_ITEM(((HildonGridChild *) iter->data)->widget);
- _hildon_grid_item_done_updating_settings(child);
- }
- */
-}
-
-
-
-/**
- * hildon_grid_set_scrollbar_pos:
- * @grid: #HildonGrid
- * @scrollbar_pos: new position (in pixels)
- *
- * Sets view (scrollbar) to specified position.
- */
-void hildon_grid_set_scrollbar_pos(HildonGrid * grid, gint scrollbar_pos)
-{
- HildonGridPrivate *priv;
- GtkAdjustment *adjustment;
-
- g_return_if_fail(HILDON_IS_GRID(grid));
-
- priv = HILDON_GRID_GET_PRIVATE(grid);
- adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
- adjustment->value = (gdouble) scrollbar_pos;
-
- gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
-
- g_object_notify (G_OBJECT (grid), "scrollbar-position");
-
- /* If grid isn't drawable, updating anything could mess up focus. */
- if (!GTK_WIDGET_DRAWABLE(GTK_WIDGET(grid)))
- return;
-
- update_contents(grid);
-}
-
-/**
- * hildon_grid_get_scrollbar_pos:
- * @grid: #HildonGrid
- *
- * Returns: position of scrollbar (in pixels).
- */
-gint hildon_grid_get_scrollbar_pos(HildonGrid * grid)
-{
- GtkAdjustment *adjustment;
-
- g_return_val_if_fail(HILDON_IS_GRID(grid), -1);
-
- adjustment = gtk_range_get_adjustment(GTK_RANGE
- (HILDON_GRID_GET_PRIVATE
- (grid)->scrollbar));
- return (int) adjustment->value;
-}
-
-static void
-hildon_grid_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonGrid *grid;
-
- grid = HILDON_GRID(object);
-
- switch (prop_id) {
- case PROP_EMPTY_LABEL:
- hildon_grid_set_empty_label(grid, g_value_get_string(value));
- break;
-
- case PROP_STYLE:
- hildon_grid_set_style(grid, g_value_get_string(value));
- break;
-
- case PROP_SCROLLBAR_POS:
- hildon_grid_set_scrollbar_pos(grid, g_value_get_int(value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_grid_get_property(GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- HildonGrid *grid;
-
- grid = HILDON_GRID(object);
-
- switch (prop_id) {
- case PROP_EMPTY_LABEL:
- g_value_set_string(value, hildon_grid_get_empty_label(grid));
- break;
-
- case PROP_STYLE:
- g_value_set_string(value, hildon_grid_get_style(grid));
- break;
-
- case PROP_SCROLLBAR_POS:
- g_value_set_int(value, hildon_grid_get_scrollbar_pos(grid));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-hildon_grid_state_changed(GtkWidget * widget,
- GtkStateType state, gpointer data)
-{
- HildonGrid *grid;
- HildonGridPrivate *priv;
- GList *list;
- GtkWidget *current;
- GtkWidget *prev_focusable, *next_focusable;
- gboolean found_old;
-
- g_return_val_if_fail(HILDON_IS_GRID(data), FALSE);
- g_return_val_if_fail(HILDON_IS_GRID_ITEM(widget), FALSE);
-
- grid = HILDON_GRID(data);
- priv = HILDON_GRID_GET_PRIVATE(grid);
-
-
- if (GTK_WIDGET_IS_SENSITIVE(widget))
- return FALSE;
-
- prev_focusable = next_focusable = NULL;
- found_old = FALSE;
-
- for (list = priv->children; list != NULL; list = list->next) {
- current = ((HildonGridChild *) list->data)->widget;
-
- if (GTK_WIDGET_IS_SENSITIVE(current)) {
- if (found_old) {
- next_focusable = current;
- break;
- } else {
- prev_focusable = current;
- }
- } else if (current == widget) {
- found_old = TRUE;
- }
- }
-
- if (next_focusable == NULL) {
- next_focusable = prev_focusable;
- }
-
- gtk_container_set_focus_child(GTK_CONTAINER(grid), next_focusable);
-
- return FALSE;
-}
-
-
-
-static void
-hildon_grid_tap_and_hold_setup(GtkWidget * widget,
- GtkWidget * menu,
- GtkCallback func,
- GtkWidgetTapAndHoldFlags flags)
-{
- g_return_if_fail(HILDON_IS_GRID(widget) && GTK_IS_MENU(menu));
-
- parent_class->parent_class.tap_and_hold_setup
- (widget, menu, func, flags | GTK_TAP_AND_HOLD_NO_INTERNALS);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file hildon-grid.h
- *
- * This file is a header file for hildon-grid.c, the implementation of
- * #HildonGrid. #HildonGrid is used in views like Home and Control Panel
- * which have single-tap activated items.
- */
-
-#ifndef __HILDON_GRID_H__
-#define __HILDON_GRID_H__
-
-#include <gtk/gtkcontainer.h>
-#include <hildon-widgets/hildon-grid-item.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_GRID (hildon_grid_get_type ())
-#define HILDON_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- HILDON_TYPE_GRID, \
- HildonGrid))
-#define HILDON_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
- HILDON_TYPE_GRID, \
- HildonGridClass))
-#define HILDON_IS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- HILDON_TYPE_GRID))
-#define HILDON_IS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- HILDON_TYPE_GRID))
-#define HILDON_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- HILDON_TYPE_GRID, \
- HildonGridClass))
-typedef struct _HildonGrid HildonGrid;
-typedef struct _HildonGridClass HildonGridClass;
-
-
-
-struct _HildonGrid {
- GtkContainer parent;
-};
-
-struct _HildonGridClass {
- GtkContainerClass parent_class;
-
- void (*activate_child) (HildonGrid * grid, HildonGridItem * item);
- void (*popup_context_menu) (HildonGrid * grid, HildonGridItem * item);
-};
-
-GType hildon_grid_get_type(void);
-GtkWidget *hildon_grid_new(void);
-
-/*
- * Use GtkContainer API:
- *
- * void gtk_container_set_focus_child (GtkContainer *container,
- * GtkWidget *child);
- *
- * GTK_CONTAINER (grid)->focus_child can be used to get focused child.
- */
-
-void hildon_grid_set_style(HildonGrid * grid, const gchar * style_name);
-const gchar *hildon_grid_get_style(HildonGrid * grid);
-
-void hildon_grid_set_scrollbar_pos(HildonGrid * grid, gint scrollbar_pos);
-gint hildon_grid_get_scrollbar_pos(HildonGrid * grid);
-
-
-/*
- * We are going to use gtk_container_add/remove, so these are internal.
- * If GridView is not visible, it won't update the view, so it should be
- * hidden when doing massive modifications.
- *
- *
- * Use GtkContainer API:
- *
- * void gtk_container_add (GtkContainer *container,
- * GtkWidget *widget);
- *
- * void gtk_container_remove (GtkContainer *container,
- * GtkWidget *widget);
- */
-
-void hildon_grid_activate_child(HildonGrid * grid, HildonGridItem * item);
-
-G_END_DECLS
-#endif /* __HILDON_GRID_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-hvolumebar
- * @short_description: A widget that displays a horizontal volume bar
- * @see_also: #HildonVVolumebar, #HildonVolumebar
- *
- * The #HildonHVolumebar widget displays a horizontal volume bar that allows
- * increasing or decreasing volume within a pre-defined range, and includes
- * a mute icon which users can click to mute the sound.
- */
-
-
-/* Horizontal volumebar subclass */
-
-#include <gtk/gtktoolbar.h>
-#include "hildon-hvolumebar.h"
-#include "hildon-volumebar.h"
-#include "hildon-volumebar-range.h"
-#include "hildon-volumebar-private.h"
-
-/* Defines for normal version of HVolumebar */
-/* Toggle button */
-#define DEFAULT_TBUTTON_WIDTH 26
-#define DEFAULT_TBUTTON_HEIGHT 26
-/* Volume bar */
-#define MINIMUM_BAR_WIDTH 147
-#define DEFAULT_BAR_HEIGHT 58
-#define DEFAULT_ENDING_SIZE 20
-
-/* Gap to leave for mute button */
-#define VERTICAL_MUTE_GAP 16
-#define HORIZONTAL_MUTE_GAP 6
-
-/* Sizes inside a toolbar */
-/* Toggle button */
-#define TOOL_DEFAULT_TBUTTON_WIDTH 26
-#define TOOL_DEFAULT_TBUTTON_HEIGHT 26
-/* Volumebar */
-#define TOOL_MINIMUM_BAR_WIDTH 121
-#define TOOL_DEFAULT_BAR_HEIGHT 40
-#define TOOL_DEFAULT_ENDING_SIZE 0
-#define TOOL_VERTICAL_MUTE_GAP ((TOOL_DEFAULT_BAR_HEIGHT - TOOL_DEFAULT_TBUTTON_HEIGHT) / 2)
-
-static HildonVolumebarClass *parent_class;
-static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass);
-static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar);
-
-static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static void hildon_hvolumebar_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void hildon_hvolumebar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static void hildon_hvolumebar_map(GtkWidget * widget);
-
-
-GType hildon_hvolumebar_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(HildonHVolumebarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_hvolumebar_class_init, /* class_init */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonHVolumebar),
- 0,
- (GInstanceInitFunc) hildon_hvolumebar_init,
- };
- type = g_type_register_static(HILDON_TYPE_VOLUMEBAR,
- "HildonHVolumebar", &info, 0);
- }
- return type;
-}
-
-
-static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass)
-{
- GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
-
- parent_class = g_type_class_peek_parent(klass);
-
- volumebar_class->size_request = hildon_hvolumebar_size_request;
- volumebar_class->size_allocate = hildon_hvolumebar_size_allocate;
- volumebar_class->map = hildon_hvolumebar_map;
- volumebar_class->expose_event = hildon_hvolumebar_expose;
-}
-
-
-static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(hvolumebar);
-
- priv->volumebar =
- HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
- (GTK_ORIENTATION_HORIZONTAL));
-
- GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(hvolumebar), GTK_CAN_FOCUS);
-
- gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(hvolumebar));
- gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(hvolumebar));
-
- gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
-
- /* Signals */
- g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
- G_CALLBACK(hildon_volumebar_level_change),
- hvolumebar);
- g_signal_connect_swapped(priv->tbutton, "toggled",
- G_CALLBACK(_hildon_volumebar_mute_toggled), hvolumebar);
-
- gtk_widget_show(GTK_WIDGET(priv->volumebar));
-}
-
-/**
- * hildon_hvolumebar_new:
- *
- * Creates a new #HildonHVolumebar widget.
- *
- * Returns: a new #HildonHVolumebar
- */
-GtkWidget *hildon_hvolumebar_new(void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_HVOLUMEBAR, NULL));
-}
-
-static void hildon_hvolumebar_map(GtkWidget * widget)
-{
- HildonVolumebarPrivate *priv;
- GtkWidget *parent;
-
- g_assert(HILDON_IS_HVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
- parent = gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_TOOLBAR);
-
- /* Check if the volumebar is in a toolbar */
- if (parent)
- priv->is_toolbar = TRUE;
-
- GTK_WIDGET_CLASS(parent_class)->map(widget);
-}
-
-static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
- GdkEventExpose * event)
-{
- HildonVolumebarPrivate *priv;
-
- g_assert(HILDON_IS_HVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
-
- if (GTK_WIDGET_DRAWABLE(widget)) {
- /* Paint background */
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(priv->volumebar), GTK_SHADOW_OUT,
- NULL, widget, "background",
- widget->allocation.x,
- widget->allocation.y,
- widget->allocation.width,
- widget->allocation.height);
-
- /* The contents of the widget can paint themselves */
- (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
- }
-
- return FALSE;
-}
-
-static void
-hildon_hvolumebar_size_request(GtkWidget * widget,
- GtkRequisition * requisition)
-{
- HildonVolumebarPrivate *priv;
-
- g_assert(HILDON_IS_HVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
-
- /* Volumebar has different dimensions in toolbar */
- requisition->width = (priv->is_toolbar
- ? TOOL_MINIMUM_BAR_WIDTH
- : MINIMUM_BAR_WIDTH);
- requisition->height = (priv->is_toolbar
- ? TOOL_DEFAULT_BAR_HEIGHT
- : DEFAULT_BAR_HEIGHT);
-}
-
-static void
-hildon_hvolumebar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonVolumebarPrivate *priv;
- GtkAllocation button_allocation, range_allocation;
-
- g_assert(HILDON_IS_HVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- button_allocation.x = 0;
- button_allocation.width = 0;
-
- /* Center the widget vertically */
- if (priv->is_toolbar && allocation->height > TOOL_DEFAULT_BAR_HEIGHT) {
- allocation->y += (allocation->height - TOOL_DEFAULT_BAR_HEIGHT) / 2;
- allocation->height = TOOL_DEFAULT_BAR_HEIGHT;
- }
- if (!priv->is_toolbar && allocation->height > DEFAULT_BAR_HEIGHT) {
- allocation->y += (allocation->height - DEFAULT_BAR_HEIGHT) / 2;
- allocation->height = DEFAULT_BAR_HEIGHT;
- }
-
- GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
-
- if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
-
- /* Allocate space for the mute button */
- if (priv->is_toolbar) {
- button_allocation.x = allocation->x;
- button_allocation.y = allocation->y + TOOL_VERTICAL_MUTE_GAP;
- button_allocation.width = TOOL_DEFAULT_TBUTTON_WIDTH;
- button_allocation.height = TOOL_DEFAULT_TBUTTON_HEIGHT;
- } else {
- button_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
- button_allocation.y = allocation->y + VERTICAL_MUTE_GAP;
- button_allocation.width = DEFAULT_TBUTTON_WIDTH;
- button_allocation.height = DEFAULT_TBUTTON_HEIGHT;
- }
- gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
- &button_allocation);
- }
- if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
-
- /* Allocate space for the slider */
- range_allocation.y = allocation->y;
-
- if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
- {
- /* Leave room for the mute button */
- range_allocation.x = button_allocation.x
- + button_allocation.width
- + HORIZONTAL_MUTE_GAP;
-
- if (priv->is_toolbar)
- {
- /* In toolbar with mute button */
- range_allocation.width = MAX(0,
- allocation->width
- - 2 * TOOL_DEFAULT_ENDING_SIZE
- - TOOL_DEFAULT_TBUTTON_WIDTH
- - HORIZONTAL_MUTE_GAP);
-
- range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
-
- }
-
- else
- {
- /* Standalone with mute button */
- range_allocation.width = MAX(0,
- allocation->width
- - 2 * DEFAULT_ENDING_SIZE
- - DEFAULT_TBUTTON_WIDTH
- - HORIZONTAL_MUTE_GAP);
-
- range_allocation.height = DEFAULT_BAR_HEIGHT;
- }
-
- }
-
- else
- {
- if (priv->is_toolbar)
- {
- /* In toolbar without mute button */
- range_allocation.x = allocation->x;
-
- range_allocation.width = MAX(0,
- allocation->width
- - 2 * TOOL_DEFAULT_ENDING_SIZE );
-
- range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
-
- }
-
- else
- {
- /* Standalone without mute button */
- range_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
-
- range_allocation.width = MAX(0,
- allocation->width
- - 2 * DEFAULT_ENDING_SIZE );
-
- range_allocation.height = DEFAULT_BAR_HEIGHT;
- }
- }
-
- gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),
- &range_allocation);
- }
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_HVOLUMEBAR_H__
-#define __HILDON_HVOLUMEBAR_H__
-
-#include <hildon-widgets/hildon-volumebar.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_HVOLUMEBAR ( hildon_hvolumebar_get_type() )
-#define HILDON_HVOLUMEBAR(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_HVOLUMEBAR, HildonHVolumebar))
-#define HILDON_HVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_HVOLUMEBAR, HildonHVolumebarClass))
-#define HILDON_IS_HVOLUMEBAR(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_HVOLUMEBAR))
-#define HILDON_IS_HVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_HVOLUMEBAR))
-
-typedef struct _HildonHVolumebar HildonHVolumebar;
-typedef struct _HildonHVolumebarClass HildonHVolumebarClass;
-
-struct _HildonHVolumebar {
- /* This is our parent class */
- HildonVolumebar volumebar;
-};
-
-struct _HildonHVolumebarClass {
- HildonVolumebarClass parent_class;
-};
-
-GType hildon_hvolumebar_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_hvolumebar_new(void);
-
-G_END_DECLS
-#endif /* __HILDON_HVOLUMEBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_INPUT_MODE_HINT_H__
-#define __HILDON_INPUT_MODE_HINT_H__
-
-G_BEGIN_DECLS
-
-/* Hildon wrapper for setting the input mode in a GtkEntry
- * Usage: g_object_set(G_OBJECT(entry), HILDON_INPUT_MODE_HINT, HILDON_INPUT_MODE_HINT_HEXA, NULL);
- */
-#define HILDON_INPUT_MODE_HINT "input-mode"
-
-/* Hildon wrapper for setting the autocapitalization in text widgets.
- * Usage: g_object_set(G_OBJECT(entry), HILDON_AUTOCAP, FALSE, NULL);
- */
-#define HILDON_AUTOCAP "autocap"
-
-/**
- * HildonInputModeHint:
- * @HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL: accept all characters.
- * @HILDON_INPUT_MODE_HINT_NUMERIC: accept only NUMERIC characters.
- * @HILDON_INPUT_MODE_HINT_ALPHA: accept only ALPHA characters
- * @HILDON_INPUT_MODE_HINT_NUMERICSPECIAL: accept only NUMERIC and SPECIAL
- * @HILDON_INPUT_MODE_HINT_ALPHASPECIAL: accept only ALPHA and SPECIAL
- * @HILDON_INPUT_MODE_HINT_ALPHANUMERIC: accept only ALPHA and NUMERIC
- * @HILDON_INPUT_MODE_HINT_HEXA: accept only HEXA
- * @HILDON_INPUT_MODE_HINT_HEXASPECIAL: accept only HEXA and SPECIAL
- * @HILDON_INPUT_MODE_HINT_TELE: accept only TELEPHONE
- * @HILDON_INPUT_MODE_HINT_TELESPECIAL: accept only TELEPHONE and SPECIAL
- *
- * Keys to set the mode in a GtkEntry widget into ALPHANUMERIC or NUMERIC mode. Note that this is only a hint; it only shows VKB with specified layout. Use it by calling 'g_object_set(G_OBJECT(entry), "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL);'.
- */
-typedef enum {
- HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL = 0,
- HILDON_INPUT_MODE_HINT_NUMERIC,
- HILDON_INPUT_MODE_HINT_ALPHA,
- HILDON_INPUT_MODE_HINT_NUMERICSPECIAL,
- HILDON_INPUT_MODE_HINT_ALPHASPECIAL,
- HILDON_INPUT_MODE_HINT_ALPHANUMERIC,
- HILDON_INPUT_MODE_HINT_HEXA,
- HILDON_INPUT_MODE_HINT_HEXASPECIAL,
- HILDON_INPUT_MODE_HINT_TELE,
- HILDON_INPUT_MODE_HINT_TELESPECIAL
-
-} HildonInputModeHint;
-
-G_END_DECLS
-#endif /* __HILDON_INPUT_MODE_HINT_H__ */
+++ /dev/null
-#include <hildon-widgets/hildon-marshalers.h>
-
-#include <glib-object.h>
-
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v) g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v) g_value_get_int (v)
-#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-#define g_marshal_value_peek_long(v) g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-#define g_marshal_value_peek_float(v) g_value_get_float (v)
-#define g_marshal_value_peek_double(v) g_value_get_double (v)
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v) g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v) g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- * Do not access GValues directly in your code. Instead, use the
- * g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
-#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* BOOLEAN:ENUM (hildon-marshalers.list:26) */
-void
-_hildon_marshal_BOOLEAN__ENUM (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__ENUM) (gpointer data1,
- gint arg_1,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__ENUM callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 2);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__ENUM) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_enum (param_values + 1),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* BOOLEAN:INT,INT,INT (hildon-marshalers.list:27) */
-void
-_hildon_marshal_BOOLEAN__INT_INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gint arg_3,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__INT_INT_INT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
-
- v_return = callback (data1,
- g_marshal_value_peek_int (param_values + 1),
- g_marshal_value_peek_int (param_values + 2),
- g_marshal_value_peek_int (param_values + 3),
- data2);
-
- g_value_set_boolean (return_value, v_return);
-}
-
-/* VOID:OBJECT (hildon-marshalers.list:28) */
-
+++ /dev/null
-
-#ifndef ___HILDON_MARSHALERS_H__
-#define ___HILDON_MARSHALERS_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* BOOLEAN:ENUM (hildon-marshalers.list:26) */
-extern void _hildon_marshal_BOOLEAN__ENUM (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* BOOLEAN:INT,INT,INT (hildon-marshalers.list:27) */
-extern void _hildon_marshal_BOOLEAN__INT_INT_INT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:OBJECT (hildon-marshalers.list:28) */
-#define _hildon_marshal_VOID__OBJECT g_cclosure_marshal_VOID__OBJECT
-
-G_END_DECLS
-
-#endif /* __HILDON_MARSHALERS_H__ */
-
+++ /dev/null
-# A copy of gtkmarshalers.list header for convenience
-#
-# see glib-genmarshal(1) for a detailed description of the file format,
-# possible parameter types are:
-# VOID indicates no return type, or no extra
-# parameters. if VOID is used as the parameter
-# list, no additional parameters may be present.
-# BOOLEAN for boolean types (gboolean)
-# CHAR for signed char types (gchar)
-# UCHAR for unsigned char types (guchar)
-# INT for signed integer types (gint)
-# UINT for unsigned integer types (guint)
-# LONG for signed long integer types (glong)
-# ULONG for unsigned long integer types (gulong)
-# ENUM for enumeration types (gint)
-# FLAGS for flag enumeration types (guint)
-# FLOAT for single-precision float types (gfloat)
-# DOUBLE for double-precision float types (gdouble)
-# STRING for string types (gchar*)
-# BOXED for boxed (anonymous but reference counted) types (GBoxed*)
-# POINTER for anonymous pointer types (gpointer)
-# OBJECT for GObject or derived types (GObject*)
-# NONE deprecated alias for VOID
-# BOOL deprecated alias for BOOLEAN
-
-BOOLEAN:ENUM
-BOOLEAN:INT,INT,INT
-VOID:OBJECT
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-name-password-dialog
- * @short_description: A widget which allows a user to enter an username
- * and a password
- * @see_also: #HildonGetPasswordDialog, #HildonSetPasswordDialog
- *
- * #HildonNamePasswordDialog is used to enter a username and password
- * when accessing a password protected function. The widget performs no
- * input checking and is used only for retrieving a user name and a
- * password.
- */
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <hildon-name-password-dialog.h>
-#include <hildon-widgets/hildon-caption.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-static GtkDialogClass *parent_class;
-
-typedef struct _HildonNamePasswordDialogPrivate
- HildonNamePasswordDialogPrivate;
-
-struct _HildonNamePasswordDialogPrivate {
- GtkButton *okButton;
- GtkButton *closeButton;
-
- GtkLabel *domainLabel;
- GtkEntry *nameEntry;
- GtkEntry *passwordEntry;
-};
-
-/* Macro to access the private data of the object instance */
-#define HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_NAME_PASSWORD_DIALOG,\
- HildonNamePasswordDialogPrivate))
-
-enum{
- PROP_NONE = 0,
- PROP_CONTENT,
- PROP_USERNAME,
- PROP_PASSWORD
-};
-
-static void
-hildon_name_password_dialog_class_init(HildonNamePasswordDialogClass *class);
-static void hildon_name_password_dialog_init(HildonNamePasswordDialog *widget);
-static void hildon_name_password_dialog_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_name_password_dialog_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-
-static void
-hildon_name_password_dialog_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonNamePasswordDialog *dialog = NULL;
- HildonNamePasswordDialogPrivate *priv = NULL;
-
- dialog = HILDON_NAME_PASSWORD_DIALOG(object);
- priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id) {
- case PROP_CONTENT:
- /* Set the password domain text */
- hildon_name_password_dialog_set_domain(dialog, g_value_get_string(value));
- break;
- case PROP_USERNAME:
- /* Set the current username displayed in the dialog */
- gtk_entry_set_text(priv->nameEntry, g_value_get_string(value));
- break;
- case PROP_PASSWORD:
- /* Set the currently entered password */
- gtk_entry_set_text(priv->passwordEntry, g_value_get_string(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_name_password_dialog_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonNamePasswordDialog *dialog = NULL;
- HildonNamePasswordDialogPrivate *priv = NULL;
-
- dialog = HILDON_NAME_PASSWORD_DIALOG(object);
- priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id) {
- case PROP_CONTENT:
- g_value_set_string(value, gtk_label_get_text(priv->domainLabel));
- break;
- case PROP_USERNAME:
- g_value_set_string(value, hildon_name_password_dialog_get_name(dialog));
- break;
- case PROP_PASSWORD:
- g_value_set_string(value, hildon_name_password_dialog_get_password(dialog));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_name_password_dialog_class_init(HildonNamePasswordDialogClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(class);
-
- parent_class = g_type_class_peek_parent(class);
-
- /* Override virtual functions */
- object_class->set_property = hildon_name_password_dialog_set_property;
- object_class->get_property = hildon_name_password_dialog_get_property;
-
- /* Install new properties */
- g_object_class_install_property(object_class,
- PROP_CONTENT,
- g_param_spec_string ("content",
- "Content",
- "Set content for content label.",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class,
- PROP_USERNAME,
- g_param_spec_string ("username",
- "Username",
- "Set content for name entry.",
- "DEFAULT",
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class,
- PROP_PASSWORD,
- g_param_spec_string ("password",
- "Password",
- "Set content for password entry",
- "DEFAULT",
- G_PARAM_READWRITE));
-
- /* Install private data structure */
- g_type_class_add_private(class,
- sizeof(HildonNamePasswordDialogPrivate));
-}
-
-static void
-hildon_name_password_dialog_init(HildonNamePasswordDialog * dialog)
-{
- /* Access private structure */
- HildonNamePasswordDialogPrivate *priv =
- HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Size group for captions */
- GtkSizeGroup *group =
- GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
- HildonCaption *caption;
-
- /* Initialize dialog */
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
- gtk_window_set_title(GTK_WINDOW(dialog), _(HILDON_NAME_PASSWORD_DIALOG_TITLE));
-
- /* Optional domain name label */
- priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
-
- /* Create buttons */
- priv->okButton =
- GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
- _(HILDON_NAME_PASSWORD_DIALOG_OK),
- GTK_RESPONSE_OK));
- priv->closeButton =
- GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
- _(HILDON_NAME_PASSWORD_DIALOG_CANCEL),
- GTK_RESPONSE_CANCEL));
-
- /* Setup user name entry */
- priv->nameEntry = GTK_ENTRY(gtk_entry_new());
- g_object_set (priv->nameEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
- gtk_entry_set_visibility(GTK_ENTRY(priv->nameEntry), FALSE);
- caption = HILDON_CAPTION(hildon_caption_new
- (group,
- _(HILDON_NAME_PASSWORD_DIALOG_NAME ),
- GTK_WIDGET(priv->nameEntry), NULL,
- HILDON_CAPTION_OPTIONAL));
- hildon_caption_set_separator(caption, "");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(caption), FALSE, FALSE, 0);
-
- /* Setup password entry */
- priv->passwordEntry = GTK_ENTRY(gtk_entry_new());
- g_object_set (priv->passwordEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
- gtk_entry_set_visibility(GTK_ENTRY(priv->passwordEntry), FALSE);
- caption =
- HILDON_CAPTION(hildon_caption_new(group,
- _(HILDON_NAME_PASSWORD_DIALOG_PASSWORD),
- GTK_WIDGET(priv->passwordEntry),
- NULL,
- HILDON_CAPTION_OPTIONAL));
- hildon_caption_set_separator(caption, "");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(caption), FALSE, FALSE, 0);
-
- gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
- gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
- /* Ensure group is freed when all its contents have been removed */
- g_object_unref(group);
-}
-
-GType hildon_name_password_dialog_get_type(void)
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonNamePasswordDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_name_password_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonNamePasswordDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_name_password_dialog_init
- };
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonNamePasswordDialog",
- &dialog_info, 0);
- }
-
- return dialog_type;
-}
-
-/**
- * hildon_name_password_dialog_new:
- * @parent: the parent window of the dialog
- *
- * Creates a new #HildonNamePasswordDialog widget with Ok and Close
- * buttons.
- *
- * Returns: the newly created #HildonNamePasswordDialog
- */
-GtkWidget *hildon_name_password_dialog_new(GtkWindow * parent)
-{
- GtkWidget *self = g_object_new(HILDON_TYPE_NAME_PASSWORD_DIALOG,NULL);
-
- if (parent)
- gtk_window_set_transient_for(GTK_WINDOW(self), parent);
-
- return self;
-}
-
-/**
- * hildon_name_password_dialog_new_with_default:
- * @parent: the parent window of the dialog
- * @name: default username, NULL if unset
- * @password: default password, NULL if unset
- *
- * Same as #hildon_name_password_dialog_new, but with a
- * default name and password.
- *
- * Returns: the newly created #HildonNamePasswordDialog
- */
-GtkWidget *hildon_name_password_dialog_new_with_default(GtkWindow *parent,
- const gchar *name,
- const gchar *password)
-{
- GtkWidget *self = hildon_name_password_dialog_new(parent);
-
- if(name != NULL)
- g_object_set(G_OBJECT(self), "username", name, NULL);
- if(password != NULL)
- g_object_set(G_OBJECT(self), "password", password, NULL);
-
- return self;
-}
-
-/**
- * hildon_name_password_dialog_get_name:
- * @dialog: the dialog
- *
- * Gets the text that's in the name entry.
- *
- * Returns: a pointer to the name string.
- */
-const gchar *hildon_name_password_dialog_get_name(HildonNamePasswordDialog
- * dialog)
-{
- HildonNamePasswordDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog), NULL);
-
- priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- return gtk_entry_get_text(priv->nameEntry);
-}
-
-/**
- * hildon_name_password_dialog_get_password:
- * @dialog: the dialog
- *
- * Gets the text that's in the password entry.
- *
- * Returns: a pointer to the password string
- */
-const gchar *hildon_name_password_dialog_get_password(HildonNamePasswordDialog
- * dialog)
-{
- HildonNamePasswordDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog), NULL);
-
- priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- return gtk_entry_get_text(priv->passwordEntry);
-}
-
-/**
- * hildon_name_password_dialog_set_domain(GtkWidget *dialog,
- * @dialog: the dialog
- * @domain: the domain or some other descriptive text to be set
- *
- * sets the optional descriptive text
- */
-
-void hildon_name_password_dialog_set_domain(HildonNamePasswordDialog *dialog,
- const gchar *domain)
-{
- HildonNamePasswordDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog));
-
- priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- gtk_label_set_text(priv->domainLabel, domain);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_NAME_PASSWORD_DIALOG_H__
-#define __HILDON_NAME_PASSWORD_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_NAME_PASSWORD_DIALOG \
- ( hildon_name_password_dialog_get_type() )
-#define HILDON_NAME_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_NAME_PASSWORD_DIALOG,\
- HildonNamePasswordDialog))
-#define HILDON_NAME_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NAME_PASSWORD_DIALOG, \
- HildonNamePasswordDialogClass))
-#define HILDON_IS_NAME_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_NAME_PASSWORD_DIALOG))
-#define HILDON_IS_NAME_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NAME_PASSWORD_DIALOG))
-
-#define HILDON_NAME_PASSWORD_DIALOG_TITLE "frw_ti_get_user_name_and_pwd"
-#define HILDON_NAME_PASSWORD_DIALOG_NAME \
- "frw_ti_get_user_name_and_pwd_enter_user_name"
-#define HILDON_NAME_PASSWORD_DIALOG_PASSWORD \
- "frw_ti_get_user_name_and_pwd_enter_pwd"
-#define HILDON_NAME_PASSWORD_DIALOG_OK "frw_bd_get_user_name_and_pwd_ok"
-#define HILDON_NAME_PASSWORD_DIALOG_CANCEL \
- "frw_bd_get_user_name_and_pwd_cancel"
-
-
-typedef struct _HildonNamePasswordDialog HildonNamePasswordDialog;
-typedef struct _HildonNamePasswordDialogClass
- HildonNamePasswordDialogClass;
-
-struct _HildonNamePasswordDialog {
- GtkDialog parent;
-};
-
-struct _HildonNamePasswordDialogClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_name_password_dialog_get_type(void) G_GNUC_CONST;
-
-GtkWidget *hildon_name_password_dialog_new(GtkWindow * parent);
-
-GtkWidget *hildon_name_password_dialog_new_with_default(GtkWindow *parent,
- const gchar *name,
- const gchar *pass);
-
-
-const gchar *hildon_name_password_dialog_get_name(HildonNamePasswordDialog
- * dialog);
-
-const gchar *hildon_name_password_dialog_get_password(HildonNamePasswordDialog
- * dialog);
-
-void hildon_name_password_dialog_set_domain(HildonNamePasswordDialog *dialog,
- const gchar *domain);
-
-G_END_DECLS
-#endif /* __HILDON_NAME_PASSWORD_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-note
- * @short_description: A widget to ask confirmation from the user
- *
- * Notes are used to for confirmation (OK/Cancel/etc.) from the user.
- * A simple note contains an information text and an OK button to be
- * pressed. Additional features such as progress bars or animation can
- * also be included.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "hildon-note.h"
-#include <gtk/gtklabel.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkalignment.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkbutton.h>
-#include <libintl.h>
-#include <hildon-widgets/hildon-defines.h>
-#include <hildon-widgets/hildon-system-sound.h>
-#include <hildon-widgets/hildon-banner.h> /* for _hildon_gtk_label_set_text_n_lines */
-
-#include <stdio.h>
-#include <string.h>
-
-/* FIXME: Can these be included from somewhere? */
-#define CONFIRMATION_SOUND_PATH "/usr/share/sounds/ui-confirmation_note.wav"
-#define INFORMATION_SOUND_PATH "/usr/share/sounds/ui-information_note.wav"
-#define HILDON_NOTE_CONFIRMATION_ICON "qgn_note_confirm"
-#define HILDON_NOTE_INFORMATION_ICON "qgn_note_info"
-
-#define _(String) dgettext(PACKAGE, String)
-
-static GtkDialogClass *parent_class;
-
-#define HILDON_NOTE_GET_PRIVATE(obj)\
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_NOTE, HildonNotePrivate));
-
-typedef struct _HildonNotePrivate HildonNotePrivate;
-
-static void hildon_note_class_init(HildonNoteClass * class);
-static void hildon_note_init(HildonNote * dialog);
-
-static void hildon_note_rebuild(HildonNote *note);
-static void hildon_note_finalize(GObject * obj_self);
-static void hildon_note_realize (GtkWidget *widget);
-
-static void hildon_note_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_note_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-static gboolean
-sound_handling(GtkWidget * widget, GdkEventExpose *event, gpointer data);
-
-struct _HildonNotePrivate {
- GtkWidget *okButton;
- GtkWidget *cancelButton;
- GtkWidget *label;
- GtkWidget *box;
- GtkWidget *icon;
-
- HildonNoteType note_n;
- GtkWidget *progressbar;
- gulong sound_signal_handler;
-
- gchar *original_description;
-};
-
-enum {
- PROP_NONE = 0,
- PROP_HILDON_NOTE_TYPE,
- PROP_HILDON_NOTE_DESCRIPTION,
- PROP_HILDON_NOTE_ICON,
- PROP_HILDON_NOTE_PROGRESSBAR,
- PROP_HILDON_NOTE_STOCK_ICON
-};
-
-static void
-hildon_note_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonNote *note = HILDON_NOTE(object);
- HildonNotePrivate *priv;
- GtkWidget *widget;
-
- priv = HILDON_NOTE_GET_PRIVATE(note);
-
- switch (prop_id) {
- case PROP_HILDON_NOTE_TYPE:
- priv->note_n = g_value_get_enum(value);
- hildon_note_rebuild(note);
- break;
- case PROP_HILDON_NOTE_DESCRIPTION:
- g_free(priv->original_description);
- priv->original_description = g_value_dup_string(value);
-
- _hildon_gtk_label_set_text_n_lines(GTK_LABEL(priv->label),
- priv->original_description,
- priv->note_n == HILDON_NOTE_PROGRESSBAR_TYPE ? 1 : 5);
-
- break;
- case PROP_HILDON_NOTE_ICON:
- gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
- g_value_get_string(value), HILDON_ICON_SIZE_BIG_NOTE);
- break;
- case PROP_HILDON_NOTE_STOCK_ICON:
- gtk_image_set_from_stock(GTK_IMAGE(priv->icon),
- g_value_get_string(value), HILDON_ICON_SIZE_BIG_NOTE);
- break;
- case PROP_HILDON_NOTE_PROGRESSBAR:
- widget = g_value_get_object(value);
- if (widget != priv->progressbar)
- {
- if (priv->progressbar)
- g_object_unref(priv->progressbar);
-
- priv->progressbar = widget;
-
- if (widget)
- {
- g_object_ref(widget);
- gtk_object_sink(GTK_OBJECT(widget));
- }
-
- hildon_note_rebuild(note);
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_note_get_property(GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- HildonNote *note = HILDON_NOTE(object);
- HildonNotePrivate *priv;
-
- priv = HILDON_NOTE_GET_PRIVATE(note);
-
- switch (prop_id) {
- case PROP_HILDON_NOTE_TYPE:
- g_value_set_enum(value, priv->note_n);
- break;
- case PROP_HILDON_NOTE_DESCRIPTION:
- g_value_set_string(value, priv->original_description);
- break;
- case PROP_HILDON_NOTE_ICON:
- g_object_get_property(G_OBJECT(priv->icon), "icon-name", value);
- break;
- case PROP_HILDON_NOTE_STOCK_ICON:
- g_object_get_property(G_OBJECT(priv->icon), "stock", value);
- break;
- case PROP_HILDON_NOTE_PROGRESSBAR:
- g_value_set_object(value, priv->progressbar);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-GType hildon_note_type_get_type (void)
-{
- static GType notetype = 0;
- if (notetype == 0) {
- static const GEnumValue values[] = {
- { HILDON_NOTE_CONFIRMATION_TYPE, "HILDON_NOTE_CONFIRMATION_TYPE", "confirmation" },
- { HILDON_NOTE_CONFIRMATION_BUTTON_TYPE, "HILDON_NOTE_CONFIRMATION_BUTTON_TYPE", "confirmation-button" },
- { HILDON_NOTE_INFORMATION_TYPE, "HILDON_NOTE_INFORMATION_TYPE", "note-information" },
- { HILDON_NOTE_INFORMATION_THEME_TYPE, "HILDON_NOTE_INFORMATION_THEME_TYPE", "note-information-theme" },
- { HILDON_NOTE_PROGRESSBAR_TYPE, "HILDON_NOTE_PROGRESSBAR_TYPE", "note-progressbar" },
- { 0, NULL, NULL }
- };
- notetype = g_enum_register_static ("HildonNoteType", values);
- }
- return notetype;
-}
-
-
-GType hildon_note_get_type()
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonNoteClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_note_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonNote),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_note_init
- };
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonNote",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-static void hildon_note_class_init(HildonNoteClass * class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class);
-
- /* set the global parent_class */
- parent_class = g_type_class_peek_parent(class);
-
- g_type_class_add_private(class, sizeof(HildonNotePrivate));
-
- object_class->finalize = hildon_note_finalize;
- object_class->set_property = hildon_note_set_property;
- object_class->get_property = hildon_note_get_property;
- widget_class->realize = hildon_note_realize;
-
- g_object_class_install_property(object_class,
- PROP_HILDON_NOTE_TYPE,
- g_param_spec_enum("note_type",
- "note type",
- "The type of the note dialog",
- hildon_note_type_get_type(),
- HILDON_NOTE_CONFIRMATION_TYPE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
- /**
- * HildonNote:description:
- *
- * Description for note.
- */
- g_object_class_install_property(object_class,
- PROP_HILDON_NOTE_DESCRIPTION,
- g_param_spec_string("description",
- "note description",
- "The text that appears in the note dialog",
- "",
- G_PARAM_READWRITE));
-
- /**
- * HildonNote:icon:
- *
- * Icon for note.
- */
- g_object_class_install_property(object_class,
- PROP_HILDON_NOTE_ICON,
- g_param_spec_string("icon",
- "note icon",
- "The name of the icon that appears in the note dialog",
- "",
- G_PARAM_READWRITE));
-
- /**
- * HildonNote:stock-icon:
- *
- * Stock icon for note.
- */
- g_object_class_install_property(object_class,
- PROP_HILDON_NOTE_STOCK_ICON,
- g_param_spec_string("stock-icon",
- "Stock note icon",
- "The stock name of the icon that appears in the note dialog",
- "",
- G_PARAM_READWRITE));
-
- /**
- * HildonNote:progressbar:
- *
- * Progressbar for note.
- */
- g_object_class_install_property(object_class,
- PROP_HILDON_NOTE_PROGRESSBAR,
- g_param_spec_object("progressbar",
- "Progressbar widget",
- "The progressbar that appears in the note dialog",
- GTK_TYPE_PROGRESS_BAR,
- G_PARAM_READWRITE));
-}
-
-static void hildon_note_init(HildonNote * dialog)
-{
- HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(dialog);
-
- priv->label = gtk_label_new(NULL);
- priv->icon = gtk_image_new();
-
- /* Acquire real references to our internal children, since
- they are not nessecarily packed into container in each
- layout */
- g_object_ref(priv->label);
- g_object_ref(priv->icon);
- gtk_object_sink(GTK_OBJECT(priv->label));
- gtk_object_sink(GTK_OBJECT(priv->icon));
-
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
-}
-
-
-static void hildon_note_finalize(GObject * obj_self)
-{
- HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(obj_self);
-
- /* Free internal data */
- g_object_unref(priv->label);
- g_object_unref(priv->icon);
- if (priv->progressbar)
- g_object_unref(priv->progressbar);
-
- g_free(priv->original_description);
-
- G_OBJECT_CLASS(parent_class)->finalize(obj_self);
-}
-
-static void
-hildon_note_realize (GtkWidget *widget)
-{
- HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(widget);
-
- /* Make widget->window accessible */
- GTK_WIDGET_CLASS (parent_class)->realize (widget);
-
- /* Border only, no titlebar */
- gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER);
-
- /* Because ESD is synchronous, we wish to play sound after the
- note is already on screen to avoid blocking its appearance */
- if (priv->sound_signal_handler == 0)
- priv->sound_signal_handler = g_signal_connect_after(widget,
- "expose-event", G_CALLBACK(sound_handling), NULL);
-}
-
-/* Helper function for removing a widget from it's container.
- we own a separate reference to each object we try to unpack,
- so extra referencing is not needed. */
-static void unpack_widget(GtkWidget *widget)
-{
- g_assert(widget == NULL || GTK_IS_WIDGET(widget));
-
- if (widget && widget->parent)
- gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
-}
-
-static void
-hildon_note_rebuild(HildonNote *note)
-{
- GtkDialog *dialog;
- HildonNotePrivate *priv;
- gboolean IsHorizontal = TRUE;
-
- g_assert(HILDON_IS_NOTE(note));
-
- priv = HILDON_NOTE_GET_PRIVATE (note);
- dialog = GTK_DIALOG(note);
-
- /* Reuse exiting content widgets for new layout */
- unpack_widget(priv->label);
- unpack_widget(priv->icon);
- unpack_widget(priv->progressbar);
-
- /* Destroy old layout and buttons */
- if (priv->box) {
- gtk_widget_destroy(priv->box);
- priv->box = NULL;
- }
- if (priv->okButton) {
- gtk_widget_destroy(priv->okButton);
- priv->okButton = NULL;
- }
- if (priv->cancelButton) {
- gtk_widget_destroy(priv->cancelButton);
- priv->cancelButton = NULL;
- }
-
- /* Add needed buttons and images for each note type */
- switch (priv->note_n)
- {
- case HILDON_NOTE_CONFIRMATION_TYPE:
- priv->okButton = gtk_dialog_add_button(dialog,
- _("ecdg_bd_confirmation_note_ok"), GTK_RESPONSE_OK);
- priv->cancelButton = gtk_dialog_add_button(dialog,
- _("ecdg_bd_confirmation_note_cancel"), GTK_RESPONSE_CANCEL);
-
- /* Fall through */
- case HILDON_NOTE_CONFIRMATION_BUTTON_TYPE:
- gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
- HILDON_NOTE_CONFIRMATION_ICON,
- HILDON_ICON_SIZE_BIG_NOTE);
- break;
-
- case HILDON_NOTE_INFORMATION_THEME_TYPE:
- case HILDON_NOTE_INFORMATION_TYPE:
- /* Add clickable OK button (cancel really,
- but doesn't matter since this is info) */
- priv->cancelButton = gtk_dialog_add_button(dialog,
- _("ecdg_bd_information_note_ok"), GTK_RESPONSE_CANCEL);
- gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
- HILDON_NOTE_INFORMATION_ICON,
- HILDON_ICON_SIZE_BIG_NOTE);
- break;
-
- case HILDON_NOTE_PROGRESSBAR_TYPE:
- priv->cancelButton = gtk_dialog_add_button(dialog,
- _("ecdg_bd_cancel_note_cancel"), GTK_RESPONSE_CANCEL);
- IsHorizontal = FALSE;
- break;
-
- default:
- break;
- }
-
- if (IsHorizontal) {
- /* Pack item with label horizontally */
- priv->box = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
- gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
-
- if (priv->icon) {
- GtkWidget *alignment = gtk_alignment_new(0, 0, 0, 0);
-
- gtk_box_pack_start(GTK_BOX(priv->box), alignment, FALSE, FALSE, 0);
- gtk_container_add(GTK_CONTAINER(alignment), priv->icon);
- }
- gtk_box_pack_start(GTK_BOX(priv->box), priv->label, TRUE, TRUE, 0);
-
- } else {
- /* Pack item with label vertically */
- priv->box = gtk_vbox_new(FALSE, HILDON_MARGIN_DOUBLE);
- gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
- gtk_box_pack_start(GTK_BOX(priv->box), priv->label, TRUE, TRUE, 0);
-
- if (priv->progressbar)
- gtk_box_pack_start(GTK_BOX(priv->box), priv->progressbar, FALSE, FALSE, 0);
- }
-
- gtk_widget_show_all(priv->box);
-}
-
-/**
- * hildon_note_new_confirmation_add_buttons:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly.
- * In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @Varargs: arguments pairs for new buttons(label and return value).
- * Terminate the list with %NULL value.
- *
- * Create a new confirmation note with custom buttons. Confirmation
- * note has a text and any number of buttons. It's important to note
- * that even though the name of the function might suggest, the
- * default ok/cancel buttons are not appended but you have to provide
- * all of the buttons.
- *
- * FIXME: This doc seems to be wrong, the two buttons aren't added so
- * it would only contain the "additional" buttons? However, changing
- * this would break those applications that rely on current behaviour.
- *
- * Returns: A #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_confirmation_add_buttons(GtkWindow *parent,
- const gchar *description,
- ...)
-{
- va_list args;
- char *message;
- int value;
-
- g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
-
- GtkWidget *conf_note =
- g_object_new(HILDON_TYPE_NOTE,
- "note_type", HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
- "description", description,
- "icon", HILDON_NOTE_CONFIRMATION_ICON,
- NULL);
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(conf_note), parent);
-
- /* Add the buttons from varargs */
- va_start(args, description);
-
- while (TRUE) {
- message = va_arg(args, char *);
-
- if (!message) {
- break;
- }
- value = va_arg(args, int);
-
- gtk_dialog_add_button(GTK_DIALOG(conf_note), message, value);
- }
-
- va_end(args);
-
- return conf_note;
-}
-
-
-/**
- * hildon_note_new_confirmation:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- *
- * Create a new confirmation note. Confirmation note has text (description)
- * that you specify, two buttons and a default confirmation stock icon.
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_confirmation(GtkWindow * parent,
- const gchar * description)
-{
- return hildon_note_new_confirmation_with_icon_name
- (parent, description, HILDON_NOTE_CONFIRMATION_ICON);
-}
-
-
-/**
- * hildon_note_new_confirmation_with_icon_stock:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @stock_id: icon to be displayed. If NULL, default icon is used.
- *
- * Create a new confirmation note. Confirmation note has text (description)
- * that you specify, two buttons and an icon.
- *
- * Deprecated: this function is broken, and really should not be used by anyone!
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_confirmation_with_icon_stock(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- stock_id)
-{
- GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
- "note_type",
- HILDON_NOTE_CONFIRMATION_TYPE,
- "description", description, "stock-icon",
- stock_id, NULL);
-
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return dialog;
-}
-
-/**
- * hildon_note_new_confirmation_with_icon_name:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @icon_name: icon to be displayed. If NULL, default icon is used.
- *
- * Create a new confirmation note. Confirmation note has text(description)
- * that you specify, two buttons and an icon.
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_confirmation_with_icon_name(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- icon_name)
-{
- GtkWidget *dialog = NULL;
-
- g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
-
- dialog = g_object_new(HILDON_TYPE_NOTE,
- "note_type",
- HILDON_NOTE_CONFIRMATION_TYPE,
- "description", description, "icon",
- icon_name, NULL);
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return dialog;
-}
-
-/**
- * hildon_note_new_information:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- *
- * Create a new information note. Information note has a text(description)
- * that you specify, an OK button and an icon.
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_information(GtkWindow * parent,
- const gchar * description)
-{
- return hildon_note_new_information_with_icon_name
- (parent, description, HILDON_NOTE_INFORMATION_ICON);
-}
-
-/**
- * hildon_note_new_information_with_icon_stock:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @stock_id: icon to be displayed. If NULL, default icon is used.
- *
- * Create a new information note. Information note has text(description)
- * that you specify, an OK button and a default stock note icon.
- *
- * Note! This function is broken and deprecated and should not be
- * used by anybody. Since the platform doesn't use stock icons,
- * use #hildon_note_new_information_with_icon_name instead.
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_information_with_icon_stock(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- stock_id)
-{
- GtkWidget *dialog = NULL;
-
- g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
-
- dialog = g_object_new(HILDON_TYPE_NOTE,
- "note_type",
- HILDON_NOTE_INFORMATION_TYPE,
- "description", description,
- "icon", stock_id, NULL);
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return dialog;
-}
-
-/**
- * hildon_note_new_information_with_icon_name:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @icon_name: icon to be displayed. If NULL, default icon is used.
- *
- * Create a new information note. Information note has text(description)
- * that you specify, an OK button and an icon.
- *
- * Returns: a #GtkWidget pointer of the note
- */
-GtkWidget *hildon_note_new_information_with_icon_name(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- icon_name)
-{
- GtkWidget *dialog = NULL;
-
- g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
-
- dialog = g_object_new(HILDON_TYPE_NOTE,
- "note_type",
- HILDON_NOTE_INFORMATION_THEME_TYPE,
- "description", description,
- "icon", icon_name, NULL);
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return dialog;
-}
-
-/**
- * hildon_note_new_information_with_icon_theme:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the message to confirm
- * @icon: #GtkIconTheme icon to be displayed
- *
- * This function is deprecated. Use
- * #hildon_note_new_information_with_icon_name instead.
- *
- * Create a new information note. Information note has text(description)
- * that you specify, an OK button and an icon.
- *
- * Returns: a #GtkWidget pointer of the note.
- */
-GtkWidget *hildon_note_new_information_with_icon_theme(GtkWindow *parent,
- const gchar *description,
- const gchar *icon)
-{
- return hildon_note_new_information_with_icon_name(parent, description, icon);
-}
-
-/**
- * hildon_note_new_cancel_with_progress_bar:
- * @parent: the parent window. The X window ID of the parent window
- * has to be the same as the X window ID of the application. This is
- * important so that the window manager could handle the windows
- * correctly. In GTK the X window ID can be checked using
- * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
- * @description: the action to cancel
- * @progressbar: a pointer to #GtkProgressBar to be filled with the
- * progressbar assigned to this note. Use this to set the fraction of
- * progressbar done. This parameter can be %NULL as well, in which
- * case plain text cancel note appears.
- *
- * Create a new cancel note with a progress bar. Cancel note has
- * text(description) that you specify, a Cancel button and a progress bar.
- *
- * Returns: a #GtkDialog. Use this to get rid of this note when you
- * no longer need it.
- */
-GtkWidget *hildon_note_new_cancel_with_progress_bar(GtkWindow * parent,
- const gchar *
- description,
- GtkProgressBar *
- progressbar)
-{
- GtkWidget *dialog = NULL;
-
- g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
-
- dialog = g_object_new(HILDON_TYPE_NOTE,
- "note_type",
- HILDON_NOTE_PROGRESSBAR_TYPE,
- "description", description,
- "progressbar",
- progressbar, NULL);
- if (parent != NULL)
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
-
- return dialog;
-}
-
-
-/**
- * hildon_note_set_button_text:
- * @note: a #HildonNote
- * @text: sets the button text and if there is two buttons in dialog,
- * the button texts will be <text>, "Cancel".
- *
- * Sets the button text to be used by the hildon_note widget.
- */
-void hildon_note_set_button_text(HildonNote * note, const gchar * text)
-{
- HildonNotePrivate *priv;
-
- g_return_if_fail(HILDON_IS_NOTE(note));
-
- priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
- if (priv->okButton) {
- gtk_button_set_label(GTK_BUTTON(priv->okButton), text);
- gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
- _("ecdg_bd_confirmation_note_cancel"));
- } else {
- gtk_button_set_label(GTK_BUTTON(priv->cancelButton), text);
- }
-}
-
-/**
- * hildon_note_set_button_texts:
- * @note: a #HildonNote
- * @textOk: the new text of the default OK button
- * @textCancel: the new text of the default cancel button
- *
- * Sets the button texts to be used by this hildon_note widget.
- */
-void hildon_note_set_button_texts(HildonNote * note,
- const gchar * textOk,
- const gchar * textCancel)
-{
- HildonNotePrivate *priv;
-
- g_return_if_fail(HILDON_IS_NOTE(note));
-
- priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
- if (priv->okButton) {
- gtk_button_set_label(GTK_BUTTON(priv->okButton), textOk);
- gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
- textCancel);
- } else {
- gtk_button_set_label(GTK_BUTTON(priv->cancelButton), textCancel);
- }
-}
-
-/* We play a system sound when the note comes visible */
-static gboolean
-sound_handling(GtkWidget * widget, GdkEventExpose *event, gpointer data)
-{
- HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(widget);
- g_signal_handler_disconnect(widget, priv->sound_signal_handler);
- priv->sound_signal_handler = 0;
-
- switch (priv->note_n)
- {
- case HILDON_NOTE_INFORMATION_TYPE:
- case HILDON_NOTE_INFORMATION_THEME_TYPE:
- hildon_play_system_sound(INFORMATION_SOUND_PATH);
- break;
- case HILDON_NOTE_CONFIRMATION_TYPE:
- case HILDON_NOTE_CONFIRMATION_BUTTON_TYPE:
- hildon_play_system_sound(CONFIRMATION_SOUND_PATH);
- break;
- default:
- break;
- };
-
- return FALSE;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_NOTE_H__
-#define __HILDON_NOTE_H__
-
-#include <gtk/gtkdialog.h>
-#include <gtk/gtkprogressbar.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_NOTE ( hildon_note_get_type() )
-#define HILDON_NOTE(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_NOTE, HildonNote))
-#define HILDON_NOTE_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NOTE, HildonNoteClass))
-#define HILDON_IS_NOTE(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_NOTE))
-#define HILDON_IS_NOTE_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NOTE))
-
-typedef struct _HildonNote HildonNote;
-typedef struct _HildonNoteClass HildonNoteClass;
-
-typedef enum /*< skip >*/
-{
- HILDON_NOTE_CONFIRMATION_TYPE = 0,
- HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
- HILDON_NOTE_INFORMATION_TYPE,
- HILDON_NOTE_INFORMATION_THEME_TYPE,
- HILDON_NOTE_PROGRESSBAR_TYPE
-} HildonNoteType;
-
-struct _HildonNote {
- GtkDialog parent;
-};
-
-struct _HildonNoteClass {
- GtkDialogClass parent_class;
-};
-
-GtkWidget *hildon_note_new_confirmation(GtkWindow * parent,
- const gchar * description);
-
-GtkWidget *hildon_note_new_confirmation_add_buttons(GtkWindow * parent,
- const gchar *
- description, ...);
-#ifndef HILDON_DISABLE_DEPRECATED
-GtkWidget *hildon_note_new_confirmation_with_icon_stock(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- stock_id);
-#endif /* HILDON_DISABLE_DEPRECATED */
-
-GtkWidget *hildon_note_new_confirmation_with_icon_name(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- icon_name);
-
-
-GtkWidget *hildon_note_new_cancel_with_progress_bar(GtkWindow * parent,
- const gchar *
- description,
- GtkProgressBar *
- progressbar);
-
-GtkWidget *hildon_note_new_information(GtkWindow * parent,
- const gchar * description);
-
-GtkWidget *hildon_note_new_information_with_icon_name(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- icon_name);
-#ifndef HILDON_DISABLE_DEPRECATED
-GtkWidget *hildon_note_new_information_with_icon_stock(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- stock_id);
-
-GtkWidget *hildon_note_new_information_with_icon_theme(GtkWindow * parent,
- const gchar *
- description,
- const gchar *
- icon);
-#endif /* HILDON_DISABLE_DEPRECATED */
-
-void hildon_note_set_button_text(HildonNote * note, const gchar * text);
-
-void hildon_note_set_button_texts(HildonNote * note, const gchar * textOk,
- const gchar * textCancel);
-
-GType hildon_note_get_type(void) G_GNUC_CONST;
-GType hildon_note_type_get_type(void) G_GNUC_CONST;
-
-G_END_DECLS
-#endif /* __HILDON_NOTE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-number-editor
- * @short_description: A widget used to enter a number within a pre-defined range
- *
- * HildonNumberEditor is used to enter a number from a specific range.
- * There are two buttons to scroll the value in number field.
- * Manual input is also possible.
- */
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "hildon-number-editor.h"
-#include "hildon-marshalers.h"
-#include <hildon-widgets/gtk-infoprint.h>
-#include "hildon-composite-widget.h"
-#include <hildon-widgets/hildon-input-mode-hint.h>
-#include <hildon-widgets/hildon-defines.h>
-#include "hildon-libs-enum-types.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-
-/*Pixel spec defines*/
-#define NUMBER_EDITOR_HEIGHT 30
-
-/* Size of plus and minus buttons */
-#define BUTTON_HEIGHT 30
-#define BUTTON_WIDTH 30
-
-#define HILDON_NUMBER_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_NUMBER_EDITOR, \
- HildonNumberEditorPrivate));
-
-typedef struct _HildonNumberEditorPrivate HildonNumberEditorPrivate;
-
-static void
-hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
-
-static void
-hildon_number_editor_init (HildonNumberEditor *editor);
-
-static gboolean
-hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
- gpointer data);
-
-static void
-hildon_number_editor_entry_changed (GtkWidget *widget, gpointer data);
-
-static void
-hildon_number_editor_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-
-static void
-set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
- const GtkAllocation *allocation);
-
-static void
-hildon_number_editor_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-
-static gboolean
-hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
- gpointer data);
-
-static gboolean
-hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
- gpointer data);
-
-static gboolean
-hildon_number_editor_entry_button_released (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data);
-static gboolean
-hildon_number_editor_button_released (GtkWidget *widget,
- GdkEvent *event,
- HildonNumberEditor *editor);
-static gboolean
-do_mouse_timeout (HildonNumberEditor *editor);
-
-static void
-change_numbers (HildonNumberEditor *editor, gint update);
-
-static void
-hildon_number_editor_forall (GtkContainer *container, gboolean include_internals,
- GtkCallback callback, gpointer callback_data);
-
-static void
-hildon_number_editor_destroy (GtkObject *self);
-
-static gboolean
-hildon_number_editor_start_timer (HildonNumberEditor *editor);
-
-static void
-hildon_number_editor_finalize (GObject *self);
-
-static gboolean
-hildon_number_editor_range_error(HildonNumberEditor *editor,
- HildonNumberEditorErrorType type);
-
-static gboolean
-hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
-
-static void
-hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate);
-
-static void hildon_number_editor_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-
-static void hildon_number_editor_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-/* Signal indices */
-enum
-{
- RANGE_ERROR,
- LAST_SIGNAL
-};
-
-/* Property indices */
-enum {
- PROP_0,
- PROP_VALUE
-};
-
-static GtkContainerClass *parent_class;
-
-static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
-
-struct _HildonNumberEditorPrivate
-{
- /* Child widgets */
- GtkWidget *num_entry;
- GtkWidget *plus;
- GtkWidget *minus;
-
- gint start; /* Minimum */
- gint end; /* Maximum */
- gint default_val;
- gint button_type; /* Type of button pressed: 1 = plus, -1 = minus */
-
- /* Timer IDs */
- guint button_event_id; /* Repeat change when button is held */
- guint select_all_idle_id; /* Selection repaint hack
- see hildon_number_editor_select_all */
-};
-
-
-GType hildon_number_editor_get_type(void)
-{
- static GType editor_type = 0;
-
- if (!editor_type)
- {
- static const GTypeInfo editor_info =
- {
- sizeof(HildonNumberEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_number_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonNumberEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_number_editor_init,
- };
- editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonNumberEditor",
- &editor_info, 0);
- }
- return editor_type;
-}
-
-static void
-hildon_number_editor_class_init(HildonNumberEditorClass * editor_class)
-{
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
- GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
-
- g_type_class_add_private(editor_class,
- sizeof(HildonNumberEditorPrivate));
-
- parent_class = g_type_class_peek_parent(editor_class);
-
- widget_class->size_request = hildon_number_editor_size_request;
- widget_class->size_allocate = hildon_number_editor_size_allocate;
- widget_class->focus = hildon_composite_widget_focus;
-
- editor_class->range_error = hildon_number_editor_range_error;
-
- /* Because we derived our widget from GtkContainer, we should override
- forall method */
- container_class->forall = hildon_number_editor_forall;
- GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
- gobject_class->finalize = hildon_number_editor_finalize;
- gobject_class->set_property = hildon_number_editor_set_property;
- gobject_class->get_property = hildon_number_editor_get_property;
-
- g_object_class_install_property(gobject_class, PROP_VALUE,
- g_param_spec_int("value",
- "Value",
- "The current value of number editor",
- G_MININT,
- G_MAXINT,
- 0, G_PARAM_READWRITE));
-
- HildonNumberEditor_signal[RANGE_ERROR] =
- g_signal_new("range_error", HILDON_TYPE_NUMBER_EDITOR,
- G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
- (HildonNumberEditorClass, range_error),
- g_signal_accumulator_true_handled, NULL,
- _hildon_marshal_BOOLEAN__ENUM,
- G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
-}
-
-static void
-hildon_number_editor_forall(GtkContainer *container, gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonNumberEditorPrivate *priv =
- HILDON_NUMBER_EDITOR_GET_PRIVATE(container);
-
- g_assert(callback != NULL);
-
- if (!include_internals)
- return;
-
- /* Enumerate child widgets */
- (*callback) (priv->minus, callback_data);
- (*callback) (priv->num_entry, callback_data);
- (*callback) (priv->plus, callback_data);
-}
-
-static void
-hildon_number_editor_destroy(GtkObject *self)
-{
- HildonNumberEditorPrivate *priv;
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
-
- /* Free child widgets */
- if (priv->minus)
- {
- gtk_widget_unparent(priv->minus);
- priv->minus = NULL;
- }
- if (priv->num_entry)
- {
- gtk_widget_unparent(priv->num_entry);
- priv->num_entry = NULL;
- }
- if (priv->plus)
- {
- gtk_widget_unparent(priv->plus);
- priv->plus = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-static void
-hildon_number_editor_stop_repeat_timer(HildonNumberEditorPrivate *priv)
-{
- if (priv->button_event_id)
- {
- g_source_remove(priv->button_event_id);
- priv->button_event_id = 0;
- }
-}
-
-static void
-hildon_number_editor_finalize (GObject *self)
-{
- HildonNumberEditorPrivate *priv;
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
-
- /* Free timers */
- hildon_number_editor_stop_repeat_timer(priv);
-
- if (priv->select_all_idle_id)
- g_source_remove (priv->select_all_idle_id);
-
- /* Call parent class finalize, if have one */
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize(self);
-}
-
-static void
-hildon_number_editor_init (HildonNumberEditor *editor)
-{
- HildonNumberEditorPrivate *priv;
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(editor), GTK_NO_WINDOW);
-
- /* Create child widgets */
- priv->num_entry = gtk_entry_new();
- priv->minus = gtk_button_new();
- priv->plus = gtk_button_new();
-
- gtk_widget_set_name( priv->minus, "ne-minus-button" );
- gtk_widget_set_name( priv->plus, "ne-plus-button" );
- gtk_widget_set_size_request( priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT );
- gtk_widget_set_size_request( priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT );
- gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
-
- GTK_WIDGET_UNSET_FLAGS( priv->minus, GTK_CAN_FOCUS );
- GTK_WIDGET_UNSET_FLAGS( priv->plus, GTK_CAN_FOCUS );
-
- priv->button_event_id = 0;
- priv->select_all_idle_id = 0;
-
- gtk_widget_set_parent(priv->minus, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->num_entry, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->plus, GTK_WIDGET(editor));
-
- /* Connect child widget signals */
- g_signal_connect(GTK_OBJECT(priv->num_entry), "changed",
- G_CALLBACK(hildon_number_editor_entry_changed),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->num_entry), "focus-out-event",
- G_CALLBACK(hildon_number_editor_entry_focusout),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->num_entry), "key-press-event",
- G_CALLBACK(hildon_number_editor_entry_keypress),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->num_entry), "button-release-event",
- G_CALLBACK(hildon_number_editor_entry_button_released),
- NULL);
-
- g_signal_connect(GTK_OBJECT(priv->minus), "button-press-event",
- G_CALLBACK(hildon_number_editor_button_pressed),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->plus), "button-press-event",
- G_CALLBACK(hildon_number_editor_button_pressed),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->minus), "button-release-event",
- G_CALLBACK(hildon_number_editor_button_released),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->plus), "button-release-event",
- G_CALLBACK(hildon_number_editor_button_released),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->minus), "leave-notify-event",
- G_CALLBACK(hildon_number_editor_button_released),
- editor);
-
- g_signal_connect(GTK_OBJECT(priv->plus), "leave-notify-event",
- G_CALLBACK(hildon_number_editor_button_released),
- editor);
-
- g_object_set( G_OBJECT(priv->num_entry),
- "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
-
- gtk_widget_show(priv->num_entry);
- gtk_widget_show(priv->minus);
- gtk_widget_show(priv->plus);
-
- hildon_number_editor_set_range(editor, G_MININT, G_MAXINT);
-}
-
-static gboolean
-hildon_number_editor_entry_button_released (GtkWidget *widget,
- GdkEventButton *event,
- gpointer data)
-{
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- return FALSE;
-}
-
-static gboolean
-hildon_number_editor_button_released (GtkWidget *widget, GdkEvent *event,
- HildonNumberEditor *editor)
-{
- HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- hildon_number_editor_stop_repeat_timer(priv);
- return FALSE;
-}
-
-/* Format given number to editor field, no checks performed, all signals
- are sent normally. */
-static void
-hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv, gint value)
-{
- gchar buffer[32];
-
- /* Update text in entry to new value */
- g_snprintf(buffer, sizeof(buffer), "%d", value);
- gtk_entry_set_text(GTK_ENTRY(priv->num_entry), buffer);
-}
-
-static gboolean
-hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
- gpointer data)
-{
- /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
- /* Need to fetch current value from entry and increment or decrement
- it */
- HildonNumberEditor *editor;
- HildonNumberEditorPrivate *priv;
- GtkSettings *settings;
- guint timeout;
-
- g_assert(HILDON_IS_NUMBER_EDITOR(data));
-
- editor = HILDON_NUMBER_EDITOR(data);
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- settings = gtk_settings_get_default();
- g_object_get(settings, "gtk-initial-timeout", &timeout, NULL);
-
- /* Save type of button pressed */
- if (GTK_BUTTON(widget) == GTK_BUTTON(priv->plus))
- priv->button_type = 1;
- else
- priv->button_type = -1;
-
- /* Start repetition timer */
- if (!priv->button_event_id)
- {
- do_mouse_timeout(editor);
- priv->button_event_id = g_timeout_add (timeout,
- (GSourceFunc) hildon_number_editor_start_timer,
- editor);
- }
-
- return FALSE;
-}
-
-static gboolean
-hildon_number_editor_start_timer (HildonNumberEditor *editor)
-{
- HildonNumberEditorPrivate *priv;
- GtkSettings *settings;
- guint timeout;
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- settings = gtk_settings_get_default();
- g_object_get(settings, "gtk-update-timeout", &timeout, NULL);
-
- priv->button_event_id = g_timeout_add(timeout,
- (GSourceFunc) do_mouse_timeout,
- editor);
- return FALSE;
-}
-
-static gboolean
-do_mouse_timeout (HildonNumberEditor *editor)
-{
- HildonNumberEditorPrivate *priv;
-
- GDK_THREADS_ENTER ();
-
- g_assert(HILDON_IS_NUMBER_EDITOR(editor));
-
- /* Update value based on button held */
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- change_numbers(editor, priv->button_type);
-
- GDK_THREADS_LEAVE ();
-
- return TRUE;
-}
-
-/* Changes the current number value by the amount of update
- and verifies the result. */
-static void
-change_numbers (HildonNumberEditor *editor, gint update)
-{
- HildonNumberEditorPrivate *priv;
- gint current_value;
-
- g_assert(HILDON_IS_NUMBER_EDITOR(editor));
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- current_value = hildon_number_editor_get_value(editor);
-
- /* We need to rerun validation by hand, since validation
- done in "changed" callback allows intermediate values */
- hildon_number_editor_real_set_value(priv, current_value + update);
- hildon_number_editor_validate_value(editor, FALSE);
- g_object_notify (G_OBJECT(editor), "value");
-}
-
-static void
-add_select_all_idle (HildonNumberEditorPrivate *priv)
-{
- if (!priv->select_all_idle_id)
- {
- priv->select_all_idle_id =
- g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
- }
-}
-
-static void
-hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate)
-{
- HildonNumberEditorPrivate *priv;
- gint error_code, fixup_value;
- const gchar *text;
- long value;
- gchar *tail;
- gboolean r;
-
- g_assert(HILDON_IS_NUMBER_EDITOR(editor));
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- text = gtk_entry_get_text(GTK_ENTRY(priv->num_entry));
- error_code = -1;
- fixup_value = priv->default_val;
-
- if (text && text[0])
- {
- /* Try to convert entry text to number */
- value = strtol(text, &tail, 10);
-
- /* Check if conversion succeeded */
- if (tail[0] == 0)
- {
- /* Check if value is in allowed range. This is tricky in those
- cases when user is editing a value.
- For example: Range = [100, 500] and user have just inputted "4".
- This should not lead into error message. Otherwise value is
- resetted back to "100" and next "4" press will reset it back
- and so on. */
- if (allow_intermediate)
- {
- /* We now have the following error cases:
- * If inputted value as above maximum and
- maximum is either positive or then maximum
- negative and value is positive.
- * If inputted value is below minimum and minimum
- is negative or minumum positive and value
- negative or zero.
- In all other cases situation can be fixed just by
- adding new numbers to the string.
- */
- if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
- {
- error_code = MAXIMUM_VALUE_EXCEED;
- fixup_value = priv->end;
- }
- else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
- {
- error_code = MINIMUM_VALUE_EXCEED;
- fixup_value = priv->start;
- }
- }
- else
- {
- if (value > priv->end) {
- error_code = MAXIMUM_VALUE_EXCEED;
- fixup_value = priv->end;
- }
- else if (value < priv->start) {
- error_code = MINIMUM_VALUE_EXCEED;
- fixup_value = priv->start;
- }
- }
- }
- /* The only valid case when conversion can fail is when we
- have plain '-', intermediate forms are allowed AND
- minimum bound is negative */
- else if (!allow_intermediate || strcmp(text, "-") != 0 || priv->start >= 0)
- error_code = ERRONEOUS_VALUE;
- }
- else if (!allow_intermediate)
- error_code = ERRONEOUS_VALUE;
-
- if (error_code != -1)
- {
- /* If entry is empty and intermediate forms are nor allowed,
- emit error signal */
- /* Change to default value */
- hildon_number_editor_set_value(editor, fixup_value);
- g_signal_emit(editor, HildonNumberEditor_signal[RANGE_ERROR],
- 0, error_code, &r);
- add_select_all_idle(priv);
- }
-}
-
-static void
-hildon_number_editor_entry_changed(GtkWidget *widget, gpointer data)
-{
- g_assert(HILDON_IS_NUMBER_EDITOR(data));
- hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), TRUE);
- g_object_notify (G_OBJECT(data), "value");
-}
-
-static void
-hildon_number_editor_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- HildonNumberEditor *editor;
- HildonNumberEditorPrivate *priv;
- GtkRequisition req;
-
- editor = HILDON_NUMBER_EDITOR(widget);
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
-
- /* Requested size is size of all child widgets plus border space */
- gtk_widget_size_request(priv->minus, &req);
- requisition->width = req.width;
-
- gtk_widget_size_request(priv->num_entry, &req);
- requisition->width += req.width;
-
- gtk_widget_size_request(priv->plus, &req);
- requisition->width += req.width;
-
- requisition->width += HILDON_MARGIN_DEFAULT * 2;
-
- /* FIXME: XXX Height is fixed */
- requisition->height = NUMBER_EDITOR_HEIGHT;
-}
-
-/* Update @alloc->width so widget fits, update @alloc->x to point to free space */
-static void
-set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
- const GtkAllocation *allocation)
-{
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition(widget, &child_requisition);
-
- /* Fit to widget width */
- if (allocation->width + allocation->x >
- alloc->x + child_requisition.width)
- alloc->width = child_requisition.width;
- else
- {
- alloc->width = allocation->width - (alloc->x - allocation->x);
- if (alloc->width < 0)
- alloc->width = 0;
- }
-
- gtk_widget_size_allocate(widget, alloc);
- /* Update x position */
- alloc->x += alloc->width;
-}
-
-static void
-hildon_number_editor_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- HildonNumberEditor *editor;
- HildonNumberEditorPrivate *priv;
- GtkAllocation alloc;
-
- editor = HILDON_NUMBER_EDITOR(widget);
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
-
- widget->allocation = *allocation;
-
- /* Add upper border */
- alloc.y = widget->allocation.y + widget->style->ythickness;
-
- /* Fix height */
- if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
- {
- alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
- alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
- }
- else
- alloc.height = widget->allocation.height - widget->style->ythickness * 2;
-
- if (alloc.height < 0)
- alloc.height = 0;
-
- /* Add left border */
- alloc.x = allocation->x + widget->style->xthickness;
-
- /* Allocate positions for widgets (left-to-right) */
- set_widget_allocation(priv->minus, &alloc, &widget->allocation);
- alloc.x += HILDON_MARGIN_DEFAULT;
-
- set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
- alloc.x += HILDON_MARGIN_DEFAULT;
-
- set_widget_allocation(priv->plus, &alloc, &widget->allocation);
-}
-
-static gboolean
-hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
- gpointer data)
-{
- g_assert(HILDON_IS_NUMBER_EDITOR(data));
- hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), FALSE);
- return FALSE;
-}
-
-static gboolean
-hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
- gpointer data)
-{
- GtkEditable *editable;
- gint cursor_pos;
-
- g_assert(HILDON_IS_NUMBER_EDITOR(data));
-
- editable = GTK_EDITABLE(widget);
- cursor_pos = gtk_editable_get_position(editable);
-
- switch (event->keyval)
- {
- case GDK_Left:
- /* If the cursor is on the left, try to decrement */
- if (cursor_pos == 0) {
- change_numbers(HILDON_NUMBER_EDITOR(data), -1);
- return TRUE;
- }
- break;
-
- case GDK_Right:
- /* If the cursor is on the right, try to increment */
- if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1))
- {
- change_numbers(HILDON_NUMBER_EDITOR(data), 1);
- gtk_editable_set_position(editable, cursor_pos);
- return TRUE;
- }
- break;
-
- default:
- break;
- };
-
- return FALSE;
-}
-
-static gboolean
-hildon_number_editor_range_error(HildonNumberEditor *editor,
- HildonNumberEditorErrorType type)
-{
-
- gint min, max;
- gchar *err_msg = NULL;
- HildonNumberEditorPrivate *priv;
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- min = priv->start;
- max = priv->end;
-
- /* Construct error message */
- switch (type)
- {
- case MAXIMUM_VALUE_EXCEED:
- err_msg = g_strdup_printf(_("ckct_ib_maximum_value"), max, max);
- break;
- case MINIMUM_VALUE_EXCEED:
- err_msg = g_strdup_printf(_("ckct_ib_minimum_value"), min, min);
- break;
- case ERRONEOUS_VALUE:
- err_msg =
- g_strdup_printf(_("ckct_ib_set_a_value_within_range"), min, max);
- break;
- }
-
- /* Infoprint error */
- if (err_msg)
- {
- gtk_infoprint(GTK_WINDOW(gtk_widget_get_ancestor(GTK_WIDGET(editor),
- GTK_TYPE_WINDOW)), err_msg);
- g_free(err_msg);
- }
-
- return TRUE;
-}
-
-
-/**
- * hildon_number_editor_new:
- * @min: minimum accepted value
- * @max: maximum accepted value
- *
- * Creates new number editor
- *
- * Returns: a new #HildonNumberEditor widget
- */
-GtkWidget *
-hildon_number_editor_new (gint min, gint max)
-{
- HildonNumberEditor *editor =
- g_object_new(HILDON_TYPE_NUMBER_EDITOR, NULL);
-
- /* Set user inputted range to editor */
- hildon_number_editor_set_range(editor, min, max);
-
- return GTK_WIDGET(editor);
-}
-
-/**
- * hildon_number_editor_set_range:
- * @editor: a #HildonNumberEditor widget
- * @min: minimum accepted value
- * @max: maximum accepted value
- *
- * Sets accepted number range for editor
- */
-void
-hildon_number_editor_set_range (HildonNumberEditor *editor, gint min, gint max)
-{
- HildonNumberEditorPrivate *priv;
- gchar buffer_min[32], buffer_max[32];
- gint a, b;
-
- g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
-
- /* Set preferences */
- priv->start = MIN(min, max);
- priv->end = MAX(min, max);
-
- /* Find maximum allowed length of value */
- g_snprintf(buffer_min, sizeof(buffer_min), "%d", min);
- g_snprintf(buffer_max, sizeof(buffer_max), "%d", max);
- a = strlen(buffer_min);
- b = strlen(buffer_max);
-
- /* Set maximum size of entry */
- gtk_entry_set_width_chars(GTK_ENTRY(priv->num_entry), MAX(a, b));
- hildon_number_editor_set_value(editor, priv->start);
-}
-
-/**
- * hildon_number_editor_get_value:
- * @editor: pointer to #HildonNumberEditor
- *
- * Returns: current NumberEditor value
- */
-gint
-hildon_number_editor_get_value (HildonNumberEditor *editor)
-{
- HildonNumberEditorPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_NUMBER_EDITOR(editor), 0);
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
- return atoi(gtk_entry_get_text(GTK_ENTRY(priv->num_entry)));
-}
-
-/**
- * hildon_number_editor_set_value:
- * @editor: pointer to #HildonNumberEditor
- * @value: numeric value for number editor
- *
- * Sets numeric value for number editor
- */
-void
-hildon_number_editor_set_value (HildonNumberEditor *editor, gint value)
-{
- HildonNumberEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
-
- priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
-
- g_return_if_fail(value <= priv->end);
- g_return_if_fail(value >= priv->start);
-
- priv->default_val = value;
- hildon_number_editor_real_set_value(priv, value);
- g_object_notify (G_OBJECT(editor), "value");
-}
-
-/* When calling gtk_entry_set_text, the entry widget does things that can
- * cause the whole widget to redraw. This redrawing is delayed and if any
- * selections are made right after calling the gtk_entry_set_text the
- * setting of the selection might seem to have no effect.
- *
- * If the selection is delayed with a lower priority than the redrawing,
- * the selection should stick. Calling this function with g_idle_add should
- * do it.
- */
-static gboolean
-hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
-{
- GDK_THREADS_ENTER ();
- gtk_editable_select_region(GTK_EDITABLE(priv->num_entry), 0, -1);
- priv->select_all_idle_id = 0;
- GDK_THREADS_LEAVE ();
- return FALSE;
-}
-
-static void
-hildon_number_editor_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonNumberEditor *editor;
-
- editor = HILDON_NUMBER_EDITOR(object);
-
- switch (prop_id) {
- case PROP_VALUE:
- hildon_number_editor_set_value(editor, g_value_get_int(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_number_editor_get_property(GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- HildonNumberEditor *editor;
-
- editor = HILDON_NUMBER_EDITOR(object);
-
- switch (prop_id) {
- case PROP_VALUE:
- g_value_set_int(value, hildon_number_editor_get_value(editor));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_NUMBER_EDITOR_H__
-#define __HILDON_NUMBER_EDITOR_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-
-
-
-#define HILDON_TYPE_NUMBER_EDITOR ( hildon_number_editor_get_type() )
-
-#define HILDON_NUMBER_EDITOR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_NUMBER_EDITOR, HildonNumberEditor))
-#define HILDON_NUMBER_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NUMBER_EDITOR, HildonNumberEditorClass))
-#define HILDON_IS_NUMBER_EDITOR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_NUMBER_EDITOR))
-#define HILDON_IS_NUMBER_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NUMBER_EDITOR))
-
-typedef struct _HildonNumberEditor HildonNumberEditor;
-typedef struct _HildonNumberEditorClass HildonNumberEditorClass;
-
-
-struct _HildonNumberEditor
-{
- GtkContainer parent;
-};
-
-
-typedef enum
-{
- MAXIMUM_VALUE_EXCEED,
- MINIMUM_VALUE_EXCEED,
- ERRONEOUS_VALUE
-
-} HildonNumberEditorErrorType;
-
-
-struct _HildonNumberEditorClass
-{
- GtkContainerClass parent_class;
-
- gboolean (*range_error) (HildonNumberEditor *editor, HildonNumberEditorErrorType type);
-};
-
-
-GType hildon_number_editor_get_type (void) G_GNUC_CONST;
-
-GtkWidget* hildon_number_editor_new (gint min, gint max);
-
-void hildon_number_editor_set_range (HildonNumberEditor *editor,
- gint min,
- gint max);
-
-gint hildon_number_editor_get_value (HildonNumberEditor *editor);
-void hildon_number_editor_set_value (HildonNumberEditor *editor, gint value);
-
-
-G_END_DECLS
-#endif /* __HILDON_NUMBER_EDITOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-plugin-widget
- * @short_description: A simple interface to load plugin based widgets. Not
- * compatible with GObject.
- *
- * #HildonPluginWidgetInfo is a struct containing information about loaded
- * module which contains code for a widget.
- */
-
-
-#include <stdio.h>
-#include <memory.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-
-#include "hildon-plugin-widget.h"
-
-
-#ifndef PLUGIN_DIR
-#define PLUGIN_DIR "/usr/lib/hildon-widgets"
-#endif
-
-
-struct HildonPluginWidgetInfo_ {
- GType base_type;
-
- gchar *filename;
-
- GModule *module;
- int refcount;
-
- GType (*get_type) ();
-};
-
-
-static gchar *hildon_plugin_filename(GType base_type, const gchar *name);
-
- /* WARNING: works properly only with ASCII */
-static gchar *ascii_decapitalize_without_dashes(gchar *source);
-
-static gchar *hildon_plugin_default_name(gchar *typename);
-
-/**
- * hildon_plugin_info_initialize:
- * @base_type: a #GType representing parent type of object that will be
- * loaded.
- * @name: Name of child. To load default (or #GtkSettings defined), NULL
- * should be passed as name. To load specific child type, decapitalized name
- * should be passed here.
- *
- * Creates a new #HildonPluginWidgetInfo structure and opens a module.
- *
- * The naming of child widgets (or objects) doesn't matter, but for plugins
- * the file names should be type
- * <decapitalized-parent-type-name-with-dashes>-<pluginname>.so where the
- * decapitalized type name would be for example for #GtkWidget gtk-widget.
- *
- * The name comes from name argument or from #GtkSettings where the variable
- * storing it is with name <ParentTypeName>-plugin, for #GtkWidget this would
- * be "GtkWidget-plugin". If nothing is defined in #GtkSettings, name
- * "default" is assumed. For this case there should be symlink to some child
- * type plugin named <parent-type-name>-default.so
- *
- * Returns: a #HildonPluginWidgetInfo struct pointer upon success, NULL if
- * failed.
- */
-HildonPluginWidgetInfo *hildon_plugin_info_initialize(GType base_type, const gchar *name)
-{
- HildonPluginWidgetInfo *ret;
- GModule *module;
- gchar *filename;
-
-
- if(!base_type) {
- return NULL;
- }
-
-
- filename = hildon_plugin_filename(base_type, name);
- g_return_val_if_fail (filename != NULL, NULL);
-
-
- module = g_module_open(filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
- if(!module) {
- g_warning ("Failed to load plugin for '%s' (filename: '%s')", name, filename);
- g_free(filename);
- return NULL;
- }
-
-
- ret = (HildonPluginWidgetInfo *)g_malloc0(sizeof(HildonPluginWidgetInfo) + strlen(filename) + 1);
- ret->filename = (gchar *)ret + sizeof(HildonPluginWidgetInfo);
-
- ret->base_type = base_type;
-
- ret->module = module;
-
- g_module_symbol(module, "export_type", (void **)&ret->get_type);
-
- memcpy(ret->filename, filename, strlen(filename));
-
-
- g_free(filename);
-
-
- return ret;
-}
-
-/**
- * hildon_plugin_info_construct_widget:
- * @info: pointer to a #HildonPluginWidgetInfo struct.
- *
- * Creates instance of loaded type from module stored in
- * #HildonPluginWidgetInfo struct. Designed for loading types inherited from
- * GtkWidget, but could be basically any GTK+ type.
- *
- * Returns: a GtkWidget pointer to instance of loaded type.
- */
-GtkWidget *hildon_plugin_info_construct_widget(HildonPluginWidgetInfo *info)
-{
- g_return_val_if_fail (info != NULL, NULL);
- info->refcount++;
-
-
- return GTK_WIDGET(g_type_create_instance(info->get_type()));
-}
-
-/**
- * hildon_plugin_info_kill:
- * @info: a pointer to a #HildonPluginWidgetInfo struct that should be
- * destroyed.
- *
- * Frees the plugin information structure and unloads the module.
- */
-void hildon_plugin_info_kill(HildonPluginWidgetInfo *info)
-{
- if(!info) {
- return;
- }
-
-
- g_module_close(info->module);
-
-
- g_free(info);
-}
-
-
-static gchar *hildon_plugin_filename(GType base_type, const gchar *name)
-{
- gchar *ret, *name2, *plgbuf;
- gchar *typename = (gchar *)g_type_name(base_type);
- int retsize;
-
-
- plgbuf = ascii_decapitalize_without_dashes(typename);
-
-
- if(name) {
- name2 = g_strdup(name);
- } else {
- name2 = hildon_plugin_default_name(typename);
- }
-
-
- retsize = strlen(PLUGIN_DIR) + strlen(plgbuf) + strlen(name2) + 6;
- ret = (gchar *)g_malloc0(retsize);
- g_snprintf(ret, retsize, "%s/%s_%s.so", PLUGIN_DIR, plgbuf, name2);
-
-
- g_free(name2);
- g_free(plgbuf);
-
-
- return ret;
-}
-
- /* possible speedup: pre-allocate more memory and ditch the first loop */
-static gchar *ascii_decapitalize_without_dashes(gchar *source)
-{
- gchar *ptr, *ret = g_strdup (source);
-
-
- for(ptr = ret; *ptr; ptr++) {
- if(*ptr >= 'A' && *ptr <= 'Z') {
- *ptr += 0x20;
- }
- }
-
-
- return ret;
-}
-
-
-static gchar *hildon_plugin_default_name(gchar *typename)
-{
- GtkSettings *settings;
- gchar *ret, *val, *tmp;
- int tmplen;
-
-
- tmplen = strlen(typename) + strlen("-plugin") + 1;
- tmp = (gchar *)g_malloc0(tmplen);
- g_snprintf(tmp, tmplen, "%s-plugin", typename);
-
-
- gtk_settings_install_property(g_param_spec_string(tmp,
- tmp,
- "Plugin for this pecific widget",
- NULL,
- G_PARAM_READWRITE));
-
- settings = gtk_settings_get_default();
-
- g_object_get(G_OBJECT(settings), tmp, &val, NULL);
-
- g_free(tmp);
-
-
- if(val) {
- ret = (gchar *)g_malloc0(strlen(val)+1);
- memcpy(ret, val, strlen(val));
- g_free(val);
- } else {
- ret = (gchar *)g_malloc0(strlen("default")+1);
-
-
- g_snprintf(ret, strlen("default")+1, "default");
- }
-
-
- return ret;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_PLUGIN_WIDGET_H__
-#define __HILDON_PLUGIN_WIDGET_H__
-
-
-#include <glib-object.h>
-
-#include <gtk/gtkwidget.h>
-
-
-/**
- * HildonPluginWidgetInfo:
- *
- * Contains information about the loaded module which has some widget
- * inherited from some non-plugin widget. The struct should be considered
- * private and should not be used directly.
- */
-typedef struct HildonPluginWidgetInfo_ HildonPluginWidgetInfo;
-
-
-HildonPluginWidgetInfo *hildon_plugin_info_initialize(GType base_type, const gchar *name);
-
-
-GtkWidget *hildon_plugin_info_construct_widget(HildonPluginWidgetInfo *info);
-
-
-void hildon_plugin_info_kill(HildonPluginWidgetInfo *info);
-
-
-
-#endif /* __HILDON_PLUGIN_WIDGET_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_PRIVATE_H__
-#define __HILDON_PRIVATE_H__
-
-#include <gtk/gtklabel.h>
-
-G_BEGIN_DECLS
-
-void
-_hildon_time_editor_get_time_separators(GtkLabel *hm_sep_label,
- GtkLabel *ms_sep_label);
-
-G_END_DECLS
-#endif /* __HILDON_PRIVATE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file hildon-program.c
- *
- * This file implements the HildonProgram object
- *
- */
-
-#include "hildon-program.h"
-#include "hildon-window-private.h"
-
-/*FIXME*/
-#include <X11/Xatom.h>
-
-
-#define HILDON_PROGRAM_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_PROGRAM, HildonProgramPriv));
-
-
-typedef struct _HildonProgramPriv HildonProgramPriv;
-
-struct _HildonProgramPriv
-{
- gboolean killable;
- gboolean is_topmost;
- GdkWindow *group_leader;
- guint window_count;
- GtkWidget *common_menu;
- GtkWidget *common_toolbar;
- GSList *windows;
- Window window_group;
- gchar *name;
-};
-
-static void
-hildon_program_init (HildonProgram *self);
-
-static void
-hildon_program_finalize (GObject *self);
-
-static void
-hildon_program_class_init (HildonProgramClass *self);
-
-static void
-hildon_program_get_property(GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec);
-static void
-hildon_program_set_property (GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec);
-
-enum
-{
- PROP_0,
- PROP_IS_TOPMOST,
- PROP_KILLABLE
-};
-
-
-GType
-hildon_program_get_type (void)
-{
- static GType program_type = 0;
-
- if (!program_type)
- {
- static const GTypeInfo program_info =
- {
- sizeof(HildonProgramClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_program_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonProgram),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_program_init,
- };
- program_type = g_type_register_static(G_TYPE_OBJECT,
- "HildonProgram", &program_info, 0);
- }
- return program_type;
-}
-
-static void
-hildon_program_init (HildonProgram *self)
-{
- HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- priv->killable = FALSE;
- priv->window_count = 0;
- priv->is_topmost = FALSE;
- priv->window_group = GDK_WINDOW_XID (gdk_display_get_default_group
- (gdk_display_get_default()));
- priv->common_toolbar = NULL;
- priv->name = NULL;
-}
-
-static void
-hildon_program_finalize (GObject *self)
-{
- HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (HILDON_PROGRAM (self));
-
- if (priv->common_toolbar)
- {
- g_object_unref (priv->common_toolbar);
- priv->common_toolbar = NULL;
- }
-
- if (priv->common_menu)
- {
- g_object_unref (priv->common_menu);
- priv->common_menu = NULL;
- }
-
- g_free (priv->name);
-
-}
-
-static void
-hildon_program_class_init (HildonProgramClass *self)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(self);
-
- g_type_class_add_private (self, sizeof(HildonProgramPriv));
-
- /* Set up object virtual functions */
- object_class->finalize = hildon_program_finalize;
- object_class->set_property = hildon_program_set_property;
- object_class->get_property = hildon_program_get_property;
-
- /* Install properties */
- g_object_class_install_property (object_class, PROP_IS_TOPMOST,
- g_param_spec_boolean ("is-topmost",
- "Is top-most",
- "Whether one of the program's window or dialog currently "
- "is activated by window manager",
- FALSE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (object_class, PROP_KILLABLE,
- g_param_spec_boolean ("can-hibernate",
- "Can hibernate",
- "Whether the program should be set to hibernate by the Task "
- "Navigator in low memory situation",
- FALSE,
- G_PARAM_READWRITE));
- return;
-}
-
-
-static void
-hildon_program_set_property (GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- switch (property_id){
- case PROP_KILLABLE:
- hildon_program_set_can_hibernate (HILDON_PROGRAM (object),
- g_value_get_boolean (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-
-}
-
-static void
-hildon_program_get_property (GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (object);
-
- switch (property_id)
- {
- case PROP_KILLABLE:
- g_value_set_boolean (value, priv->killable);
- break;
- case PROP_IS_TOPMOST:
- g_value_set_boolean (value, priv->is_topmost);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-
-}
-
-/* Utilities */
-static gint
-hildon_program_window_list_compare (gconstpointer window_a,
- gconstpointer window_b)
-{
- g_return_val_if_fail (1, HILDON_IS_WINDOW(window_a) &&
- HILDON_IS_WINDOW(window_b));
-
- return window_a != window_b;
-}
-
-/*
- * foreach function, checks if a window is topmost and acts consequently
- */
-static void
-hildon_program_window_list_is_is_topmost (gpointer data, gpointer window_id_)
-{
- if (data && HILDON_IS_WINDOW (data))
- {
- HildonWindow *window = HILDON_WINDOW (data);
- Window window_id = * (Window*)window_id_;
-
- hildon_window_update_topmost (window, window_id);
- }
-}
-
-/*
- * Check the _MB_CURRENT_APP_WINDOW on the root window, and update
- * the top_most status accordingly
- */
-static void
-hildon_program_update_top_most (HildonProgram *program)
-{
- XWMHints *wm_hints;
- Window active_window;
- HildonProgramPriv *priv;
-
- priv = HILDON_PROGRAM_GET_PRIVATE (program);
-
- active_window = hildon_window_get_active_window();
-
- if (active_window)
- {
- wm_hints = XGetWMHints (GDK_DISPLAY (), active_window);
-
- if (wm_hints)
- {
-
- if (wm_hints->window_group == priv->window_group)
- {
- if (!priv->is_topmost)
- {
- priv->is_topmost = TRUE;
- g_object_notify (G_OBJECT (program), "is-topmost");
- }
- }
- else if (priv->is_topmost)
- {
- priv->is_topmost = FALSE;
- g_object_notify (G_OBJECT (program), "is-topmost");
- }
- }
- XFree (wm_hints);
- }
-
- /* Check each window if it was is_topmost */
- g_slist_foreach (priv->windows,
- (GFunc)hildon_program_window_list_is_is_topmost, &active_window);
-}
-
-
-/* Event filter */
-
-/*
- * We keep track of the _MB_CURRENT_APP_WINDOW property on the root window,
- * to detect when a window belonging to this program was is_topmost. This
- * is based on the window group WM hint.
- */
-static GdkFilterReturn
-hildon_program_root_window_event_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- XAnyEvent *eventti = xevent;
- HildonProgram *program = HILDON_PROGRAM (data);
- Atom active_app_atom =
- XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
-
- if (eventti->type == PropertyNotify)
- {
- XPropertyEvent *pevent = xevent;
-
- if (pevent->atom == active_app_atom)
- {
- hildon_program_update_top_most (program);
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-
-/**
- * hildon_program_common_toolbar_topmost_window:
- * @window: A @HildonWindow to be informed about its new common toolbar
- * @data: Not used, it is here just to respect the API
- *
- * Checks if the window is the topmost window of the program and in
- * that case forces the window to take the common toolbar.
- **/
-static void
-hildon_program_common_toolbar_topmost_window (gpointer window, gpointer data)
-{
- if (HILDON_IS_WINDOW (window) &&
- hildon_window_get_is_topmost (HILDON_WINDOW (window)))
- {
- hildon_window_take_common_toolbar (HILDON_WINDOW (window));
- }
-}
-
-/* Public methods */
-
-/**
- * hildon_program_get_instance:
- *
- * Return value: Returns the #HildonProgram for the current process.
- * The object is created on the first call.
- **/
-HildonProgram *
-hildon_program_get_instance ()
-{
- static HildonProgram *program = NULL;
-
- if (!program)
- {
- program = g_object_new (HILDON_TYPE_PROGRAM, NULL);
- }
-
- return program;
-}
-
-/**
- * hildon_program_add_window:
- * @program: The @HildonProgram to which the window should be registered
- * @window: A @HildonWindow to be added
- *
- * Registers a @HildonWindow as belonging to a given @HildonProgram. This
- * allows to apply program-wide settings as all the registered windows,
- * such as hildon_program_set_common_menu() and
- * hildon_pogram_set_common_toolbar()
- **/
-void
-hildon_program_add_window (HildonProgram *self, HildonWindow *window)
-{
- HildonProgramPriv *priv;
-
- g_return_if_fail (self && HILDON_IS_PROGRAM (self));
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- if (g_slist_find_custom (priv->windows, window,
- hildon_program_window_list_compare) )
- {
- /* We already have that window */
- return;
- }
-
- if (!priv->window_count)
- {
- hildon_program_update_top_most (self);
-
- /* Now that we have a window we should start keeping track of
- * the root window */
- gdk_window_set_events (gdk_get_default_root_window (),
- gdk_window_get_events (gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK);
- gdk_window_add_filter (gdk_get_default_root_window (),
- hildon_program_root_window_event_filter, self );
- }
-
- hildon_window_set_can_hibernate_property (window, &priv->killable);
-
- hildon_window_set_program (window, G_OBJECT (self));
-
- priv->windows = g_slist_append (priv->windows, window);
- priv->window_count ++;
-}
-
-/**
- * hildon_program_remove_window:
- * @self: The #HildonProgram to which the window should be unregistered
- * @window: The @HildonWindow to unregister
- *
- * Used to unregister a window from the program. Subsequent calls to
- * hildon_program_set_common_menu() and hildon_pogram_set_common_toolbar()
- * will not affect the window
- **/
-void
-hildon_program_remove_window (HildonProgram *self, HildonWindow *window)
-{
- HildonProgramPriv *priv;
-
- g_return_if_fail (self && HILDON_IS_PROGRAM (self));
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- hildon_window_unset_program (window);
-
- priv->windows = g_slist_remove (priv->windows, window);
-
- priv->window_count --;
-
- if (!priv->window_count)
- {
- gdk_window_remove_filter (gdk_get_default_root_window(),
- hildon_program_root_window_event_filter,
- self);
- }
-}
-
-/**
- * hildon_program_set_can_hibernate:
- * @self: The #HildonProgram which can hibernate or not
- * @can_hibernate: whether or not the #HildonProgram can hibernate
- *
- * Used to set whether or not the Hildon task navigator should
- * be able to set the program to hibernation in case of low memory
- **/
-void
-hildon_program_set_can_hibernate (HildonProgram *self, gboolean killable)
-{
- HildonProgramPriv *priv;
-
- g_return_if_fail (self && HILDON_IS_PROGRAM (self));
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- if (priv->killable != killable)
- {
- g_slist_foreach (priv->windows,
- (GFunc)hildon_window_set_can_hibernate_property, &killable);
- }
-
- priv->killable = killable;
-
-}
-
-/**
- * hildon_program_get_can_hibernate:
- * @self: The #HildonProgram which can hibernate or not
- *
- * Return value: Whether or not this #HildonProgram is set to be
- * support hibernation from the Hildon task navigator
- **/
-gboolean
-hildon_program_get_can_hibernate (HildonProgram *self)
-{
- HildonProgramPriv *priv;
-
- g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- return priv->killable;
-
-}
-
-/**
- * hildon_program_set_common_menu:
- * @self: The #HildonProgram in which the common menu should be used
- * @menu: A GtkMenu to use as common menu for the program
- *
- * Sets a GtkMenu that will appear in all the @HildonWindow registered
- * to the #HildonProgram. Only one common GtkMenu can be set, further
- * call will detach the previous common GtkMenu. A @HildonWindow
- * can use it's own GtkMenu with @hildon_window_set_menu
- **/
-void
-hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu)
-{
- HildonProgramPriv *priv;
-
- g_return_if_fail (self && HILDON_IS_PROGRAM (self));
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- if (priv->common_menu)
- {
- if (GTK_WIDGET_VISIBLE (priv->common_menu))
- {
- gtk_menu_popdown (GTK_MENU(priv->common_menu));
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->common_menu));
- }
-
- if (gtk_menu_get_attach_widget (GTK_MENU (priv->common_menu)))
- {
- gtk_menu_detach (GTK_MENU (priv->common_menu));
- }
- else
- {
- g_object_unref (priv->common_menu);
- }
- }
-
- priv->common_menu = GTK_WIDGET (menu);
-
- if (priv->common_menu)
- {
- g_object_ref (menu);
- gtk_object_sink (GTK_OBJECT (menu));
- gtk_widget_show_all (GTK_WIDGET (menu));
- }
-}
-
-/**
- * hildon_program_get_common_menu:
- * @self: The #HildonProgram from which to retrieve the common menu
- *
- * Return value: the GtkMenu that was set as common menu for this
- * #HildonProgram, or NULL of no common menu was set.
- **/
-GtkMenu *
-hildon_program_get_common_menu (HildonProgram *self)
-{
- HildonProgramPriv *priv;
-
- g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- return GTK_MENU (priv->common_menu);
-}
-
-/**
- * hildon_program_set_common_toolbar:
- * @self: The #HildonProgram in which the common toolbar should be used
- * @toolbar: A GtkToolbar to use as common toolbar for the program
- *
- * Sets a GtkToolbar that will appear in all the @HildonWindow registered
- * to the #HildonProgram. Only one common GtkToolbar can be set, further
- * call will detach the previous common GtkToolbar. A @HildonWindow
- * can use its own GtkToolbar with @hildon_window_set_toolbar. Both
- * #HildonProgram and @HildonWindow specific toolbars will be shown
- **/
-void
-hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar)
-{
- HildonProgramPriv *priv;
-
- g_return_if_fail (self && HILDON_IS_PROGRAM (self));
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- if (priv->common_toolbar)
- {
- if (priv->common_toolbar->parent)
- {
- gtk_container_remove (GTK_CONTAINER (priv->common_toolbar->parent),
- priv->common_toolbar);
- }
-
- g_object_unref (priv->common_toolbar);
- }
-
- priv->common_toolbar = GTK_WIDGET (toolbar);
-
- if (priv->common_toolbar)
- {
- g_object_ref (priv->common_toolbar);
- gtk_object_sink (GTK_OBJECT (priv->common_toolbar) );
- }
-
- /* if the program is the topmost we have to update the common
- toolbar right now for the topmost window */
- if (priv->is_topmost)
- {
- g_slist_foreach (priv->windows,
- (GFunc) hildon_program_common_toolbar_topmost_window, NULL);
- }
-}
-
-/**
- * hildon_program_get_common_toolbar:
- * @self: The #HildonProgram from which to retrieve the common toolbar
- *
- * Return value: the GtkToolbar that was set as common toolbar for this
- * #HildonProgram, or NULL of no common menu was set.
- **/
-GtkToolbar *
-hildon_program_get_common_toolbar (HildonProgram *self)
-{
- HildonProgramPriv *priv;
-
- g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- return priv->common_toolbar ? GTK_TOOLBAR (priv->common_toolbar) : NULL;
-}
-
-/**
- * hildon_program_get_is_topmost:
- * @self: A #HildonWindow
- *
- * Return value: Whether or not one of the program's window or dialog is
- * currenltly activated by the window manager.
- **/
-gboolean
-hildon_program_get_is_topmost (HildonProgram *self)
-{
- HildonProgramPriv *priv;
-
- g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
-
- priv = HILDON_PROGRAM_GET_PRIVATE (self);
-
- return priv->is_topmost;
-}
-
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_PROGRAM_H__
-#define __HILDON_PROGRAM_H__
-
-#include<glib-object.h>
-#include"hildon-window.h"
-
-G_BEGIN_DECLS
-typedef struct _HildonProgram HildonProgram;
-typedef struct _HildonProgramClass HildonProgramClass;
-
-#define HILDON_TYPE_PROGRAM (hildon_program_get_type())
-#define HILDON_PROGRAM(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, \
- HILDON_TYPE_PROGRAM, \
- HildonProgram))
-#define HILDON_IS_PROGRAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, \
- HILDON_TYPE_PROGRAM))
-
-/* deprecated */
-#define hildon_program_new hildon_program_get_instance
-
-
-
-struct _HildonProgram
-{
- GObject parent;
-};
-
-struct _HildonProgramClass
-{
- GObjectClass parent;
-
- /* Padding for future extension */
- void (*_hildon_reserved1)(void);
- void (*_hildon_reserved2)(void);
- void (*_hildon_reserved3)(void);
- void (*_hildon_reserved4)(void);
-
-};
-
-GType
-hildon_program_get_type (void);
-
-/* Public methods */
-
-HildonProgram *
-hildon_program_get_instance (void);
-
-void
-hildon_program_add_window (HildonProgram *self, HildonWindow *window);
-
-void
-hildon_program_remove_window (HildonProgram *self, HildonWindow *window);
-
-void
-hildon_program_set_can_hibernate (HildonProgram *self, gboolean killable);
-
-gboolean
-hildon_program_get_can_hibernate (HildonProgram *self);
-
-void
-hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu);
-
-GtkMenu *
-hildon_program_get_common_menu (HildonProgram *self);
-
-void
-hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar);
-
-GtkToolbar *
-hildon_program_get_common_toolbar (HildonProgram *self);
-
-gboolean
-hildon_program_get_is_topmost (HildonProgram *self);
-
-G_END_DECLS
-#endif /* __HILDON_PROGRAM_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-range-editor
- * @short_description: A widget is used to ask bounds of a range
- *
- * HidlonRangeEditor allows entering a pair of integers, e.g. the lower
- * and higher bounds of a range. A minimum and maximum can also be set
- * for the bounds.
- */
-
-#include <gtk/gtkbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkentry.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gprintf.h>
-#include <string.h>
-#include <stdlib.h>
-#include <hildon-widgets/hildon-input-mode-hint.h>
-
-#include "hildon-range-editor.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#define _(string) dgettext(PACKAGE, string)
-
-/* Alignment in entry box ( 0 = left, 1 = right ) */
-#define DEFAULT_ALIGNMENT 1
-/* Amount of padding to add to each side of the separator */
-#define DEFAULT_PADDING 3
-
-#define DEFAULT_START -999
-#define DEFAULT_END 999
-#define DEFAULT_LENGTH 4
-
-#define HILDON_RANGE_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_RANGE_EDITOR, HildonRangeEditorPrivate));
-
-typedef struct _HildonRangeEditorPrivate HildonRangeEditorPrivate;
-
-/* Property indices */
-enum
-{
- PROP_LOWER = 1,
- PROP_HIGHER,
- PROP_MIN,
- PROP_MAX,
- PROP_SEPARATOR
-};
-
-static GtkContainerClass *parent_class = NULL;
-
-/*Init functions*/
-static void
-hildon_range_editor_class_init (HildonRangeEditorClass *editor_class);
-static void
-hildon_range_editor_init (HildonRangeEditor *editor);
-static void
-hildon_range_editor_forall (GtkContainer *container,
- gboolean include_internals, GtkCallback callback,
- gpointer callback_data);
-static void
-hildon_range_editor_destroy (GtkObject *self);
-
-/*size and font functions */
-static void
-hildon_range_editor_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void
-hildon_range_editor_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gboolean
-hildon_range_editor_entry_focus_in (GtkEditable *editable,
- GdkEventFocus *event,
- HildonRangeEditor *editor);
-static gboolean
-hildon_range_editor_entry_focus_out (GtkEditable *editable,
- GdkEventFocus *event,
- HildonRangeEditor *editor);
-static gboolean
-hildon_range_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
- HildonRangeEditor *editor);
-static gboolean
-hildon_range_editor_released (GtkEditable *editable, GdkEventButton *event,
- HildonRangeEditor *editor);
-static gboolean
-hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
- HildonRangeEditor *editor);
-
-static void hildon_range_editor_set_property( GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec );
-static void hildon_range_editor_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec );
-static void hildon_range_editor_entry_changed(GtkWidget *widget,
- HildonRangeEditor *editor);
-
-/* Private struct */
-struct _HildonRangeEditorPrivate
-{
- GtkWidget *start_entry; /* Entry for lower value */
- GtkWidget *end_entry; /* Entry for higher value */
-
- GtkWidget *label;
-
- gint range_limits_start; /* Minimum value allowed for range start/end */
- gint range_limits_end; /* Maximum value allowed for range start/end */
-
- gboolean bp; /* Button pressed, don't overwrite selection */
-};
-
-/* Private functions */
-static void
-hildon_range_editor_class_init (HildonRangeEditorClass *editor_class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
-
- parent_class = g_type_class_peek_parent(editor_class);
-
- g_type_class_add_private(editor_class,
- sizeof(HildonRangeEditorPrivate));
-
- gobject_class->set_property = hildon_range_editor_set_property;
- gobject_class->get_property = hildon_range_editor_get_property;
- widget_class->size_request = hildon_range_editor_size_request;
- widget_class->size_allocate = hildon_range_editor_size_allocate;
-
- container_class->forall = hildon_range_editor_forall;
- GTK_OBJECT_CLASS(editor_class)->destroy = hildon_range_editor_destroy;
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_int("hildon_range_editor_entry_alignment",
- "Hildon RangeEditor entry alignment",
- "Hildon RangeEditor entry alignment", 0, 1,
- DEFAULT_ALIGNMENT,
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property(widget_class,
- g_param_spec_int("hildon_range_editor_separator_padding",
- "Hildon RangeEditor separator padding",
- "Hildon RangeEditor separaror padding",
- G_MININT, G_MAXINT,
- DEFAULT_PADDING,
- G_PARAM_READABLE));
-
- /**
- * HildonRangeEditor:min:
- *
- * Minimum value in a range.
- * Default: -999
- */
- g_object_class_install_property( gobject_class, PROP_MIN,
- g_param_spec_int("min",
- "Minimum value",
- "Minimum value in a range",
- G_MININT, G_MAXINT,
- DEFAULT_START, G_PARAM_CONSTRUCT |
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonRangeEditor:max:
- *
- * Maximum value in a range.
- * Default: 999
- */
- g_object_class_install_property( gobject_class, PROP_MAX,
- g_param_spec_int("max",
- "Maximum value",
- "Maximum value in a range",
- G_MININT, G_MAXINT,
- DEFAULT_END, G_PARAM_CONSTRUCT |
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonRangeEditor:lower:
- *
- * Current value in the entry presenting lower end of selected range.
- * Default: -999
- */
- g_object_class_install_property( gobject_class, PROP_LOWER,
- g_param_spec_int("lower",
- "Current lower value",
- "Current value in the entry presenting lower end of selected range",
- G_MININT, G_MAXINT,
- DEFAULT_START, G_PARAM_CONSTRUCT |
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonRangeEditor:higher:
- *
- * Current value in the entry presenting higher end of selected range.
- * Default: 999
- */
- g_object_class_install_property( gobject_class, PROP_HIGHER,
- g_param_spec_int("higher",
- "Current higher value",
- "Current value in the entry presenting higher end of selected range",
- G_MININT, G_MAXINT,
- DEFAULT_END, G_PARAM_CONSTRUCT |
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonRangeEditor:separator:
- *
- * Separator string to separate range editor entries.
- * Default: "-"
- */
- g_object_class_install_property( gobject_class, PROP_SEPARATOR,
- g_param_spec_string("separator",
- "Separator",
- "Separator string to separate entries",
- _("ckct_wi_range_separator"),
- G_PARAM_CONSTRUCT |
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-}
-
-static void
-hildon_range_editor_init (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
-
- gint range_editor_entry_alignment;
- gint range_editor_separator_padding;
-
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
-
- GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
-
- gtk_widget_push_composite_child();
-
- priv->start_entry = gtk_entry_new();
- priv->end_entry = gtk_entry_new();
- priv->label = gtk_label_new(_("ckct_wi_range_separator"));
- priv->bp = FALSE;
-
- /* Get values from gtkrc (or use defaults) */
- /* FIXME: This is broken, styles are not yet attached */
- gtk_widget_style_get(GTK_WIDGET(editor),
- "hildon_range_editor_entry_alignment",
- &range_editor_entry_alignment,
- "hildon_range_editor_separator_padding",
- &range_editor_separator_padding, NULL);
-
- /* Add padding to separator */
- gtk_misc_set_padding (GTK_MISC(priv->label),
- range_editor_separator_padding, 0);
-
- /* Align the text to right in entry box */
- gtk_entry_set_alignment(GTK_ENTRY(priv->start_entry),
- range_editor_entry_alignment);
- gtk_entry_set_alignment(GTK_ENTRY(priv->end_entry),
- range_editor_entry_alignment);
-
- gtk_widget_set_composite_name(priv->start_entry, "start_entry");
- gtk_widget_set_composite_name(priv->end_entry, "end_entry");
- gtk_widget_set_composite_name(priv->label, "separator_label");
- gtk_widget_set_parent(priv->start_entry, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->end_entry, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->label, GTK_WIDGET(editor));
-
- g_signal_connect(G_OBJECT(priv->start_entry), "button-release-event",
- G_CALLBACK(hildon_range_editor_released), editor);
- g_signal_connect(G_OBJECT(priv->end_entry), "button-release-event",
- G_CALLBACK(hildon_range_editor_released), editor);
-
- g_signal_connect(G_OBJECT(priv->start_entry), "button-press-event",
- G_CALLBACK(hildon_range_editor_press), editor);
- g_signal_connect(G_OBJECT(priv->end_entry), "button-press-event",
- G_CALLBACK(hildon_range_editor_press), editor);
-
- g_signal_connect(G_OBJECT(priv->start_entry), "key-press-event",
- G_CALLBACK(hildon_range_editor_entry_keypress), editor);
- g_signal_connect(G_OBJECT(priv->end_entry), "key-press-event",
- G_CALLBACK(hildon_range_editor_entry_keypress), editor);
-
- g_signal_connect(G_OBJECT(priv->start_entry), "focus-in-event",
- G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
- g_signal_connect(G_OBJECT(priv->end_entry), "focus-in-event",
- G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
-
- g_signal_connect(G_OBJECT(priv->start_entry), "focus-out-event",
- G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
- g_signal_connect(G_OBJECT(priv->end_entry), "focus-out-event",
- G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
- g_signal_connect(priv->start_entry, "changed",
- G_CALLBACK(hildon_range_editor_entry_changed), editor);
- g_signal_connect(priv->end_entry, "changed",
- G_CALLBACK(hildon_range_editor_entry_changed), editor);
-
- g_object_set( G_OBJECT(priv->start_entry),
- "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
- g_object_set( G_OBJECT(priv->end_entry),
- "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
-
- gtk_widget_show(priv->start_entry);
- gtk_widget_show(priv->end_entry);
- gtk_widget_show(priv->label);
-
- gtk_widget_pop_composite_child();
-}
-
-static void hildon_range_editor_set_property (GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec)
-{
- HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
- switch (param_id)
- {
- case PROP_LOWER:
- hildon_range_editor_set_lower (editor, g_value_get_int (value));
- break;
-
- case PROP_HIGHER:
- hildon_range_editor_set_higher (editor, g_value_get_int (value));
- break;
-
- case PROP_MIN:
- hildon_range_editor_set_min (editor, g_value_get_int (value));
- break;
-
- case PROP_MAX:
- hildon_range_editor_set_max (editor, g_value_get_int (value));
- break;
-
- case PROP_SEPARATOR:
- hildon_range_editor_set_separator (editor,
- g_value_get_string (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_range_editor_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec )
-{
- HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
- switch (param_id)
- {
- case PROP_LOWER:
- g_value_set_int (value, hildon_range_editor_get_lower (editor));
- break;
-
- case PROP_HIGHER:
- g_value_set_int (value, hildon_range_editor_get_higher (editor));
- break;
-
- case PROP_MIN:
- g_value_set_int (value, hildon_range_editor_get_min (editor));
- break;
-
- case PROP_MAX:
- g_value_set_int (value, hildon_range_editor_get_max (editor));
- break;
-
- case PROP_SEPARATOR:
- g_value_set_string (value, hildon_range_editor_get_separator (editor));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void
-hildon_range_editor_entry_validate(HildonRangeEditor *editor,
- GtkWidget *edited_entry, gboolean allow_intermediate)
-{
- HildonRangeEditorPrivate *priv;
- const gchar *text;
- long value;
- gint min, max, fixup;
- gchar *tail;
- gchar buffer[256];
- gboolean error = FALSE;
-
- g_assert(HILDON_IS_RANGE_EDITOR(editor));
- g_assert(GTK_IS_ENTRY(edited_entry));
-
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
-
- /* Find the valid range for the modified component */
- if (edited_entry == priv->start_entry) {
- min = hildon_range_editor_get_min(editor);
- max = hildon_range_editor_get_higher(editor);
- } else {
- min = hildon_range_editor_get_lower(editor);
- max = hildon_range_editor_get_max(editor);
- }
-
- text = gtk_entry_get_text(edited_entry);
-
- if (text && text[0])
- {
- /* Try to convert entry text to number */
- value = strtol(text, &tail, 10);
-
- /* Check if conversion succeeded */
- if (tail[0] == 0)
- {
- /* Check if value is in allowed range. This is tricky in those
- cases when user is editing a value.
- For example: Range = [100, 500] and user have just inputted "4".
- This should not lead into error message. Otherwise value is
- resetted back to "100" and next "4" press will reset it back
- and so on. */
- if (allow_intermediate)
- {
- /* We now have the following error cases:
- * If inputted value as above maximum and
- maximum is either positive or then maximum
- negative and value is positive.
- * If inputted value is below minimum and minimum
- is negative or minumum positive and value
- negative.
- In all other cases situation can be fixed just by
- adding new numbers to the string.
- */
- if (value > max && (max >= 0 || (max < 0 && value >= 0)))
- {
- error = TRUE;
- fixup = max;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
- }
- else if (value < min && (min < 0 || (min >= 0 && value < 0)))
- {
- error = TRUE;
- fixup = min;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
- }
- }
- else
- {
- if (value > max) {
- error = TRUE;
- fixup = max;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
- }
- else if (value < min) {
- error = TRUE;
- fixup = min;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
- }
- }
-
- if (error) {
- if (edited_entry == priv->start_entry)
- hildon_range_editor_set_lower(editor, fixup);
- else
- hildon_range_editor_set_higher(editor, fixup);
- }
- }
- /* The only valid case when conversion can fail is when we
- have plain '-', intermediate forms are allowed AND
- minimum bound is negative */
- else if (!allow_intermediate || strcmp(text, "-") != 0 || min >= 0) {
- error = TRUE;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
- }
- }
- else if (!allow_intermediate) {
- error = TRUE;
- g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
- }
-
- if (error)
- {
- hildon_banner_show_information(edited_entry, NULL, buffer);
- gtk_widget_grab_focus(edited_entry);
- }
-}
-
-static gboolean
-hildon_range_editor_entry_focus_in (GtkEditable *editable,
- GdkEventFocus *event,
- HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
- if(priv->bp)
- {
- priv->bp = FALSE;
- return FALSE;
- }
- if (GTK_WIDGET(editable) == priv->start_entry)
- gtk_editable_select_region(editable, -1, 0);
- else
- gtk_editable_select_region(editable, 0, -1);
- return FALSE;
-}
-
-/* Gets and sets the current range. This has two usefull side effects:
- * Values are now sorted to the correct order
- * Out of range values are clamped to range */
-static void hildon_range_editor_apply_current_range(HildonRangeEditor *editor)
-{
- g_assert(HILDON_IS_RANGE_EDITOR(editor));
-
- hildon_range_editor_set_range(editor,
- hildon_range_editor_get_lower(editor),
- hildon_range_editor_get_higher(editor));
-}
-
-static void hildon_range_editor_entry_changed(GtkWidget *widget, HildonRangeEditor *editor)
-{
- g_assert(HILDON_IS_RANGE_EDITOR(editor));
- hildon_range_editor_entry_validate(editor, widget, TRUE);
-}
-
-static gboolean
-hildon_range_editor_entry_focus_out (GtkEditable *editable,
- GdkEventFocus *event,
- HildonRangeEditor *editor)
-{
- g_assert(HILDON_IS_RANGE_EDITOR(editor));
- hildon_range_editor_entry_validate(editor, GTK_WIDGET(editable), FALSE);
- return FALSE;
-}
-
-static gboolean
-hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
- HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
- priv->bp = TRUE;
- return FALSE;
-}
-
-static void
-hildon_range_editor_forall (GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonRangeEditorPrivate *priv;
-
- g_assert(HILDON_IS_RANGE_EDITOR(container));
- g_assert(callback != NULL);
-
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE(container);
-
- if (!include_internals)
- return;
-
- (*callback) (priv->start_entry, callback_data);
- (*callback) (priv->end_entry, callback_data);
- (*callback) (priv->label, callback_data);
-}
-
-static void
-hildon_range_editor_destroy(GtkObject *self)
-{
- HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(self);
-
- if (priv->start_entry)
- {
- gtk_widget_unparent(priv->start_entry);
- priv->start_entry = NULL;
- }
- if (priv->end_entry)
- {
- gtk_widget_unparent(priv->end_entry);
- priv->end_entry = NULL;
- }
- if (priv->label)
- {
- gtk_widget_unparent(priv->label);
- priv->label = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-
-static void
-hildon_range_editor_size_request(GtkWidget *widget,
- GtkRequisition *requisition)
-{
- HildonRangeEditorPrivate *priv = NULL;
- GtkRequisition lab_req, mreq;
-
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
-
- gtk_entry_get_width_chars(GTK_ENTRY(priv->end_entry));
-
- gtk_widget_size_request(priv->start_entry, &mreq);
- gtk_widget_size_request(priv->end_entry, &mreq);
- gtk_widget_size_request(priv->label, &lab_req);
-
- /* Width for entries and separator label and border */
- requisition->width = mreq.width * 2 + lab_req.width +
- widget->style->xthickness * 2;
- /* Add vertical border */
- requisition->height = mreq.height + widget->style->ythickness * 2;
- /* Fit label height */
- requisition->height = MAX (requisition->height, lab_req.height);
-}
-
-static void
-hildon_range_editor_size_allocate(GtkWidget *widget,
- GtkAllocation *allocation)
-{
- HildonRangeEditorPrivate *priv;
- GtkAllocation child1_allocation, child2_allocation, child3_allocation;
-
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
-
- widget->allocation = *allocation;
-
- /* Allocate entries, left-to-right */
- if (priv->start_entry && GTK_WIDGET_VISIBLE(priv->start_entry))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition(priv->start_entry,
- &child_requisition);
-
- child1_allocation.x = allocation->x;
- child1_allocation.y = allocation->y;
-
- child1_allocation.width = child_requisition.width;
- child1_allocation.height = allocation->height;
-
- gtk_widget_size_allocate(priv->start_entry, &child1_allocation);
- }
-
- if (priv->label && GTK_WIDGET_VISIBLE(priv->label))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition(priv->label, &child_requisition);
-
- child2_allocation.x = child1_allocation.x + child1_allocation.width;
- child2_allocation.y = allocation->y;
- /* Add spacing */
- child2_allocation.width = child_requisition.width + 4;
- child2_allocation.height = allocation->height;
-
- gtk_widget_size_allocate (priv->label, &child2_allocation);
- }
-
- if (priv->end_entry && GTK_WIDGET_VISIBLE(priv->end_entry))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_get_child_requisition (priv->end_entry, &child_requisition);
-
- child3_allocation.x = child2_allocation.x + child2_allocation.width;
- child3_allocation.y = allocation->y;
-
- child3_allocation.width = child_requisition.width;
- child3_allocation.height = allocation->height;
-
- gtk_widget_size_allocate(priv->end_entry, &child3_allocation);
- }
-}
-
-/* Button released inside entries */
-static gboolean
-hildon_range_editor_released(GtkEditable *editable, GdkEventButton *event,
- HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
- if (GTK_WIDGET(editable) == priv->start_entry)
- gtk_editable_select_region(editable, -1, 0);
- else
- gtk_editable_select_region(editable, 0, -1);
- return FALSE;
-}
-
-static gboolean
-hildon_range_editor_entry_keypress(GtkWidget *widget, GdkEventKey *event,
- HildonRangeEditor *editor)
-{
- const gchar *text;
- gint cursor_pos;
-
- g_assert(HILDON_IS_RANGE_EDITOR(editor));
-
- text = gtk_entry_get_text(GTK_ENTRY(widget));
- cursor_pos = gtk_editable_get_position(GTK_EDITABLE(widget));
-
- switch (event->keyval)
- {
- case GDK_Left:
- /* If we are on the first character and press left,
- try to move to previous field */
- if (cursor_pos == 0) {
- (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_LEFT);
- return TRUE;
- }
- break;
-
- case GDK_Right:
- /* If the cursor is on the right, try to move to the next field */
- if (cursor_pos >= g_utf8_strlen(text, -1)) {
- (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_RIGHT);
- return TRUE;
- }
- break;
-
- default:
- break;
- };
-
- return FALSE;
-}
-
-static void hildon_range_editor_refresh_widths(HildonRangeEditorPrivate *priv)
-{
- gchar start_range[32], end_range[32];
- gint length;
-
- /* Calculate length of entry so extremes would fit */
- g_snprintf(start_range, sizeof(start_range), "%d", priv->range_limits_start);
- g_snprintf(end_range, sizeof(end_range), "%d", priv->range_limits_end);
- length = MAX(g_utf8_strlen(start_range, -1), g_utf8_strlen(end_range, -1));
-
- gtk_entry_set_width_chars(GTK_ENTRY(priv->start_entry), length);
- gtk_entry_set_max_length(GTK_ENTRY(priv->start_entry), length);
- gtk_entry_set_width_chars(GTK_ENTRY (priv->end_entry), length);
- gtk_entry_set_max_length(GTK_ENTRY (priv->end_entry), length);
-}
-
-/* Public functions */
-
-/**
- * hildon_range_editor_get_type:
- *
- * Initializes, and returns the type of a hildon range editor.
- *
- * @Returns : GType of #HildonRangeEditor
- *
- */
-GType
-hildon_range_editor_get_type (void)
-{
- static GType editor_type = 0;
-
- if (!editor_type)
- {
- static const GTypeInfo editor_info =
- {
- sizeof(HildonRangeEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_range_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonRangeEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_range_editor_init,
- };
- editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonRangeEditor",
- &editor_info, 0);
- }
- return editor_type;
-}
-
-/**
- * hildon_range_editor_new:
- *
- * HildonRangeEditor contains two GtkEntrys that accept numbers and minus.
- *
- * Returns: pointer to a new @HildonRangeEditor widget
- */
-GtkWidget *
-hildon_range_editor_new (void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_RANGE_EDITOR, NULL));
-}
-
-
-/**
- * hildon_range_editor_new_with_separator:
- * @separator: a string that is shown between the numbers
- *
- * HildonRangeEditor contains two Gtk entries that accept numbers.
- * A separator is displayed between two entries.
- * CHECKME: Use '-' as a separator in the case of null separator?
- *
- * Returns: pointer to a new @HildonRangeEditor widget
- */
-GtkWidget *
-hildon_range_editor_new_with_separator (const gchar *separator)
-{
- return GTK_WIDGET (g_object_new (HILDON_TYPE_RANGE_EDITOR,
- "separator", separator, NULL));
-}
-
-
-/**
- * hildon_range_editor_set_range:
- * @editor: the #HildonRangeEditor widget
- * @start: range's start value
- * @end: range's end value
- *
- * Sets a range to the editor. (The current value)
- *
- * Sets the range of the @HildonRangeEditor widget.
- */
-void
-hildon_range_editor_set_range (HildonRangeEditor *editor, gint start, gint end)
-{
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
-
- /* Make sure that the start/end appear in the correct order */
- hildon_range_editor_set_lower (editor, MIN(start, end));
- hildon_range_editor_set_higher (editor, MAX(start, end));
-}
-
-
-/**
- * hildon_range_editor_get_range:
- * @editor: the #HildonRangeEditor widget
- * @start: ranges start value
- * @end: ranges end value
- *
- * Gets the range of the @HildonRangeEditor widget.
- */
-void
-hildon_range_editor_get_range (HildonRangeEditor *editor, gint *start,
- gint *end)
-{
- HildonRangeEditorPrivate *priv;
-
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor) && start && end);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- *start = hildon_range_editor_get_lower (editor);
- *end = hildon_range_editor_get_higher (editor);
-}
-
-
-/**
- * hildon_range_editor_set_limits:
- * @editor: the #HildonRangeEditor widget
- * @start: minimum acceptable value (default: no limit)
- * @end: maximum acceptable value (default: no limit)
- *
- * Sets the range of the @HildonRangeEditor widget.
- */
-void
-hildon_range_editor_set_limits (HildonRangeEditor *editor, gint start,
- gint end)
-{
- /* FIXME: Setting start/end as separate steps can modify
- the inputted range unneedlesly */
- hildon_range_editor_set_min (editor, start);
- hildon_range_editor_set_max (editor, end);
-}
-
-void
-hildon_range_editor_set_lower (HildonRangeEditor *editor, gint value)
-{
- HildonRangeEditorPrivate *priv;
- gchar buffer[32];
-
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
- priv->range_limits_start, priv->range_limits_end));
-
- /* Update entry text with new value */
- gtk_entry_set_text (GTK_ENTRY (priv->start_entry), buffer);
- g_object_notify (G_OBJECT (editor), "lower");
-}
-
-void
-hildon_range_editor_set_higher (HildonRangeEditor *editor, gint value)
-{
- HildonRangeEditorPrivate *priv;
- gchar buffer[32];
-
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
- priv->range_limits_start, priv->range_limits_end));
-
- /* Update entry text with new value */
- gtk_entry_set_text (GTK_ENTRY (priv->end_entry), buffer);
- g_object_notify (G_OBJECT (editor), "higher");
-}
-
-gint
-hildon_range_editor_get_lower (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
- g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
- return atoi(gtk_entry_get_text(GTK_ENTRY(priv->start_entry)));
-}
-
-gint
-hildon_range_editor_get_higher (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
- g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
- return atoi(gtk_entry_get_text(GTK_ENTRY (priv->end_entry)));
-}
-
-void
-hildon_range_editor_set_min (HildonRangeEditor *editor, gint value)
-{
- HildonRangeEditorPrivate *priv;
-
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
-
- /* We can cause many properties to change */
- g_object_freeze_notify(G_OBJECT(editor));
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
- priv->range_limits_start = value;
-
- if (priv->range_limits_end < value)
- hildon_range_editor_set_max (editor, value);
- /* Setting maximum applies widths and range in this case */
- else {
- hildon_range_editor_refresh_widths(priv);
- hildon_range_editor_apply_current_range(editor);
- }
-
- g_object_notify (G_OBJECT (editor), "min");
- g_object_thaw_notify(G_OBJECT(editor));
-}
-
-void
-hildon_range_editor_set_max (HildonRangeEditor *editor, gint value)
-{
- HildonRangeEditorPrivate *priv;
-
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
-
- /* We can cause many properties to change */
- g_object_freeze_notify(G_OBJECT(editor));
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
- priv->range_limits_end = value;
-
- if (priv->range_limits_start > value)
- hildon_range_editor_set_min (editor, value);
- /* Setting minimum applies widths and range in this case */
- else {
- hildon_range_editor_refresh_widths(priv);
- hildon_range_editor_apply_current_range(editor);
- }
-
- g_object_notify (G_OBJECT (editor), "max");
- g_object_thaw_notify(G_OBJECT(editor));
-}
-
-gint
-hildon_range_editor_get_min (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
- g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- return priv->range_limits_start;
-}
-
-gint
-hildon_range_editor_get_max (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
- g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- return priv->range_limits_end;
-}
-
-void
-hildon_range_editor_set_separator (HildonRangeEditor *editor,
- const gchar *separator)
-{
- HildonRangeEditorPrivate *priv;
- g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- gtk_label_set_text (GTK_LABEL (priv->label), separator);
- g_object_notify (G_OBJECT(editor), "separator");
-}
-
-const gchar *
-hildon_range_editor_get_separator (HildonRangeEditor *editor)
-{
- HildonRangeEditorPrivate *priv;
- g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), NULL);
- priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
-
- return gtk_label_get_text (GTK_LABEL (priv->label));
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_RANGE_EDITOR_H__
-#define __HILDON_RANGE_EDITOR_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-/**
- * HILDON_TYPE_RANGE_EDITOR
- *
- * Macro for getting type of range editor.
- * Since: 0.12.10
- */
-#define HILDON_TYPE_RANGE_EDITOR (hildon_range_editor_get_type())
-
-/**
- * HILDON_RANGE_EDITOR_TYPE
- *
- * Deprecated: use #HILDON_TYPE_RANGE_EDITOR instead
- */
-#define HILDON_RANGE_EDITOR_TYPE HILDON_TYPE_RANGE_EDITOR
-
-#define HILDON_RANGE_EDITOR(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_RANGE_EDITOR, HildonRangeEditor))
-#define HILDON_RANGE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_RANGE_EDITOR, HildonRangeEditorClass))
-#define HILDON_IS_RANGE_EDITOR(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_RANGE_EDITOR))
-#define HILDON_IS_RANGE_EDITOR_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_RANGE_EDITOR))
-/**
- * HildonRangeEditor:
- *
- * Internal struct for range editor.
- */
-typedef struct _HildonRangeEditor HildonRangeEditor;
-typedef struct _HildonRangeEditorClass HildonRangeEditorClass;
-
-
-struct _HildonRangeEditor {
- GtkContainer parent;
-};
-
-struct _HildonRangeEditorClass {
- GtkContainerClass parent_class;
-};
-
-GType hildon_range_editor_get_type(void) G_GNUC_CONST;
-
-GtkWidget *hildon_range_editor_new_with_separator(const gchar * separator);
-GtkWidget *hildon_range_editor_new(void);
-
-void hildon_range_editor_set_range(HildonRangeEditor * editor,
- gint start, gint end);
-void hildon_range_editor_get_range(HildonRangeEditor * editor,
- gint * start, gint * end);
-void hildon_range_editor_set_limits(HildonRangeEditor * editor,
- gint start, gint end);
-
-void hildon_range_editor_set_lower (HildonRangeEditor *editor, gint value);
-void hildon_range_editor_set_higher (HildonRangeEditor *editor, gint value);
-gint hildon_range_editor_get_lower (HildonRangeEditor *editor);
-gint hildon_range_editor_get_higher (HildonRangeEditor *editor);
-void hildon_range_editor_set_min (HildonRangeEditor *editor, gint value);
-void hildon_range_editor_set_max (HildonRangeEditor *editor, gint value);
-gint hildon_range_editor_get_min (HildonRangeEditor *editor);
-gint hildon_range_editor_get_max (HildonRangeEditor *editor);
-void hildon_range_editor_set_separator (HildonRangeEditor *editor,
- const gchar *separator);
-const gchar *hildon_range_editor_get_separator (HildonRangeEditor *editor);
-
-G_END_DECLS
-#endif /* __HILDON_RANGE_EDITOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-scroll-area
- * @short_description: A helper to create Maemo specific views,
- * which are using scrollable area
- *
- * #GtkScrollArea combines a large widget that needs scrolling (like a
- * text editor or a tree view) and other widgets that wouldn't fit one
- * the screen normally without scrolling (like entries, toolbars etc.)
- * into one scrollable area.
- */
-
-#include "hildon-scroll-area.h"
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtkfixed.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkwidget.h>
-#include <string.h>
-
-typedef struct
- {
- GtkWidget *fixed;
-
- /* Scrolled windows */
- GtkWidget *swouter;
- GtkWidget *swinner;
-
- /* Widget that's being contained */
- GtkWidget *child;
-
- /* Vertical adjustment for scrolled windows */
- GtkAdjustment *outadj;
- GtkAdjustment *inadj;
-
- } HildonScrollArea;
-
-
-static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
- HildonScrollArea *sc);
-static void hildon_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
- HildonScrollArea *sc);
-static void hildon_scroll_area_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation,
- HildonScrollArea *sc);
-static void hildon_scroll_area_child_requisition (GtkWidget *widget,
- GtkRequisition *req,
- HildonScrollArea *sc);
-static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
- GtkAllocation *allocation,
- HildonScrollArea *sc);
-
-static int calculate_size (GtkWidget *widget);
-
-/**
- * hildon_scroll_area_new:
- * @sw: #GtkWidget - #GtkScrolledWindow
- * @child: #GtkWidget - child to be place inside the sw
- *
- * This is not a widget. It's a helper function to create
- * hildon-specific scrolling methods.
- * A common situation where the scroll area should be used
- * might be following. A view containing @GtkTreeView based widget,
- * (or any similar widget which has built-in @GtkScrolledWindow support)
- * and eg. couple buttons. Normaly @GtkScrolledWindow can not handle
- * the situation so that the @GtkTreeView built-in support
- * would work. The scroll area is connecting this built-in system to
- * the scrolled window and also noticing the buttons. To use, one should
- * create a box to which pack the buttons and the scroll area.
- * The scroll area then contains the problematic widget eg. the @GtkTreeView.
- * Then the box should be placed in the @GtkScrolledWindow.
- * The function is currently assuming that the newly created scroll area
- * hierarchy is not modified in anyway. Or if it is, it may lead to
- * unwanted problems. Also assumed, that the @child will be packed
- * to the @sw.
- *
- * Returns: a @GtkFixed
- */
-GtkWidget *hildon_scroll_area_new (GtkWidget *sw, GtkWidget *child)
-{
- GtkWidget *swi;
- GtkWidget *fixed;
- HildonScrollArea *sc;
-
- g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (sw)
- && GTK_IS_WIDGET (child), NULL);
-
- swi = gtk_scrolled_window_new (NULL, NULL);
- fixed = gtk_fixed_new ();
- sc = g_malloc (sizeof (HildonScrollArea));
- memset (sc, 0, sizeof (HildonScrollArea));
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swi),
- GTK_POLICY_NEVER, GTK_POLICY_NEVER);
-
- gtk_container_add (GTK_CONTAINER (swi), child);
- gtk_fixed_put (GTK_FIXED (fixed), swi, 0, 0);
-
- sc->fixed = fixed;
- sc->swouter = sw;
- sc->swinner = swi;
- sc->child = child;
- sc->outadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw));
- sc->inadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (swi));
-
- g_signal_connect_after (G_OBJECT (child), "size-request",
- G_CALLBACK (hildon_scroll_area_child_requisition), sc);
-
- g_signal_connect_after (G_OBJECT (sc->outadj), "value_changed",
- G_CALLBACK (hildon_scroll_area_outer_value_changed), sc);
- g_signal_connect_after (G_OBJECT (sc->inadj), "value_changed",
- G_CALLBACK (hildon_scroll_area_inner_value_changed), sc);
-
- g_signal_connect_after (G_OBJECT (sw), "size-allocate",
- G_CALLBACK (hildon_scroll_area_size_allocate), sc);
- g_signal_connect (G_OBJECT (sc->fixed), "size-allocate",
- G_CALLBACK (hildon_scroll_area_fixed_allocate), sc);
- g_signal_connect_swapped (G_OBJECT (sw), "destroy",
- G_CALLBACK (g_free), sc);
-
- gtk_widget_show_all (sw);
- return fixed;
-}
-
-static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
- GtkAllocation *allocation,
- HildonScrollArea *sc)
-{
- gtk_widget_set_size_request (sc->swinner, -1,
- MIN (sc->outadj->page_size, allocation->height));
-}
-
-
-static int calculate_size (GtkWidget *widget)
-{
- int size = 0;
-
- if (GTK_IS_TEXT_VIEW (widget))
- return 0;
-
- if (GTK_IS_CONTAINER (widget)) {
- GList *children = gtk_container_get_children (GTK_CONTAINER (widget));
- while (children != NULL) {
- GtkWidget *wid = GTK_WIDGET (children->data);
- gint sz = calculate_size (wid);
- if ((GTK_WIDGET_VISIBLE (wid))) {
- size += sz;
- }
-
- children = g_list_next (children);
- }
- } else {
- size = widget->allocation.height;
- }
-
- return size;
-}
-
-static void hildon_scroll_area_child_requisition (GtkWidget *widget,
- GtkRequisition *req,
- HildonScrollArea *sc)
-{
- /* Limit height to fixed height */
- gint new_req = MAX (req->height, sc->fixed->allocation.height);
- gint adjust_factor = calculate_size (sc->swouter) * 0.7;
-
- adjust_factor = MAX (0, adjust_factor - sc->outadj->value);
- new_req = MIN (sc->outadj->page_size - adjust_factor, new_req);
-
- gtk_widget_set_size_request (sc->fixed, -1, req->height);
- /* Request inner scrolled window at most page size */
- gtk_widget_set_size_request (sc->swinner, -1, new_req);
-}
-
-static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
- HildonScrollArea *sc)
-{
- GtkRequisition req;
- gtk_widget_size_request (sc->child, &req);
-
- /* Update inner adjustment position based on outer one, update fixed position */
- if ((sc->outadj->value + sc->outadj->page_size) > sc->fixed->allocation.y
- && sc->outadj->value < (sc->fixed->allocation.y + req.height))
- {
- gdouble new_pos = 0;
-
- new_pos = MAX (sc->outadj->value - sc->fixed->allocation.y, 0);
- new_pos = MIN (new_pos, req.height - sc->inadj->page_size);
- new_pos = MAX (new_pos, 0);
-
- gtk_fixed_move (GTK_FIXED (sc->fixed), sc->swinner, 0, new_pos);
- gtk_adjustment_set_value (sc->inadj, new_pos);
- }
-}
-
-static void hildon_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
- HildonScrollArea *sc)
-{
- /* Update outer adjustment based on inner adjustment position */
- if (sc->outadj->value != sc->fixed->allocation.y + adjustment->value)
- gtk_adjustment_set_value (sc->outadj,
- sc->fixed->allocation.y + adjustment->value);
-}
-
-__inline__ static gint calculate_width (HildonScrollArea *sc)
-{
- GtkScrolledWindow *scwin = GTK_SCROLLED_WINDOW (sc->swouter);
- return (scwin->hscrollbar_visible * scwin->hscrollbar->allocation.width);
-}
-
-static void hildon_scroll_area_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation,
- HildonScrollArea *sc)
-{
- gtk_widget_set_size_request (sc->fixed, calculate_width (sc), sc->fixed->allocation.height);
- gtk_widget_set_size_request (sc->child, sc->fixed->allocation.width, -1);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * The reason why this is not made as a widget:
- * We can not create a widget which could return the correct child.
- * (ie. by gtk_bin_get_child)
- */
-
-#ifndef __HILDON_SCROLL_AREA_H__
-#define __HILDON_SCROLL_AREA_H__
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
- GtkWidget * hildon_scroll_area_new(GtkWidget * sw, GtkWidget * child);
-
-G_END_DECLS
-#endif /* __HILDON_SCROLL_AREA_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-seekbar
- * @short_description: A widget used to identify a place from a content
- *
- * HildonSeekbar allows seeking in media with a range widget. It
- * supports for setting or getting the length (total time) of the media,
- * the position within it and the fraction (maximum position in a
- * stream/the amount currently downloaded). The position is clamped
- * between zero and the total time, or zero and the fraction in case of
- * a stream.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <libintl.h>
-#include <stdio.h>
-#include <math.h>
-
-#include <gtk/gtklabel.h>
-#include <gtk/gtkframe.h>
-#include <gtk/gtkalignment.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtktoolbar.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "hildon-seekbar.h"
-
-#define HILDON_SEEKBAR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_SEEKBAR, HildonSeekbarPrivate));
-
-typedef struct _HildonSeekbarPrivate HildonSeekbarPrivate;
-
-/* our parent class */
-static GtkScaleClass *parent_class = NULL;
-
-/* Init functions */
-static void hildon_seekbar_class_init(HildonSeekbarClass * seekbar_class);
-static void hildon_seekbar_init(HildonSeekbar * seekbar);
-
-/* property functions */
-static void hildon_seekbar_set_property(GObject * object, guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-
-static void hildon_seekbar_get_property(GObject * object, guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-
-/* virtual functions */
-static void hildon_seekbar_size_request(GtkWidget * widget,
- GtkRequisition * event);
-static void hildon_seekbar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static gboolean hildon_seekbar_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static gboolean hildon_seekbar_button_press_event(GtkWidget * widget,
- GdkEventButton * event);
-static gboolean hildon_seekbar_button_release_event(GtkWidget * widget,
- GdkEventButton * event);
-static gboolean hildon_seekbar_keypress(GtkWidget * widget,
- GdkEventKey * event);
-
-
-#define MINIMUM_WIDTH 115
-#define DEFAULT_HEIGHT 58
-
-/* Toolbar width and height defines */
-#define TOOL_MINIMUM_WIDTH 75
-#define TOOL_DEFAULT_HEIGHT 40
-
-#define DEFAULT_DISPLAYC_BORDER 10
-#define BUFFER_SIZE 32
-#define EXTRA_SIDE_BORDER 20
-#define TOOL_EXTRA_SIDE_BORDER 0
-
-/* the number of steps it takes to move from left to right */
-#define NUM_STEPS 20
-
-#define SECONDS_PER_MINUTE 60
-
-/* the number of digits precision for the internal range.
- * note, this needs to be enough so that the step size for
- * small total_times doesn't get rounded off. Currently set to 3
- * this is because for the smallest total time ( i.e 1 ) and the current
- * num steps ( 20 ) is: 1/20 = 0.05. 0.05 is 2 digits, and we
- * add one for safety */
-#define MAX_ROUND_DIGITS 3
-
-/*
- * FIXME HildonSeekbar introduced major changes in GtkRange mostly related
- * to stream_indicator. These changes should be minimized.
- */
-
-/* Property indices */
-enum {
- PROP_TOTAL_TIME = 1,
- PROP_POSITION,
- PROP_FRACTION
-};
-
-/* private variables */
-struct _HildonSeekbarPrivate {
- gboolean is_toolbar; /* TRUE if this widget is inside a toolbar */
- guint fraction; /* This is the amount of time that has progressed from
- the beginning. It should be an integer between the
- minimum and maximum values of the corresponding
- adjustment, ie. adjument->lower and ->upper.. */
-};
-
-/**
- * Initialises, and returns the type of a hildon seekbar.
- */
-GType hildon_seekbar_get_type(void)
-{
- static GType seekbar_type = 0;
-
- if (!seekbar_type) {
- static const GTypeInfo seekbar_info = {
- sizeof(HildonSeekbarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_seekbar_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonSeekbar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_seekbar_init,
- };
- seekbar_type = g_type_register_static(GTK_TYPE_SCALE,
- "HildonSeekbar",
- &seekbar_info, 0);
- }
- return seekbar_type;
-}
-
-/**
- * Initialises the seekbar class.
- */
-static void hildon_seekbar_class_init(HildonSeekbarClass * seekbar_class)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(seekbar_class);
- GObjectClass *object_class = G_OBJECT_CLASS(seekbar_class);
-
- parent_class = g_type_class_peek_parent(seekbar_class);
-
- g_type_class_add_private(seekbar_class, sizeof(HildonSeekbarPrivate));
-
- widget_class->size_request = hildon_seekbar_size_request;
- widget_class->size_allocate = hildon_seekbar_size_allocate;
- widget_class->expose_event = hildon_seekbar_expose;
- widget_class->button_press_event = hildon_seekbar_button_press_event;
- widget_class->button_release_event =
- hildon_seekbar_button_release_event;
- widget_class->key_press_event = hildon_seekbar_keypress;
-
- object_class->set_property = hildon_seekbar_set_property;
- object_class->get_property = hildon_seekbar_get_property;
-
- g_object_class_install_property(object_class, PROP_TOTAL_TIME,
- g_param_spec_double("total_time",
- "total time",
- "Total playing time of this media file",
- 0, /* min value */
- G_MAXDOUBLE, /* max value */
- 0, /* default */
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_POSITION,
- g_param_spec_double("position",
- "position",
- "Current position in this media file",
- 0, /* min value */
- G_MAXDOUBLE, /* max value */
- 0, /* default */
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_FRACTION,
- g_param_spec_double("fraction",
- "Fraction",
- "current fraction related to the"
- "progress indicator",
- 0, /* min value */
- G_MAXDOUBLE, /* max value */
- 0, /* default */
- G_PARAM_READWRITE));
-}
-
-
-static void hildon_seekbar_init(HildonSeekbar * seekbar)
-{
- HildonSeekbarPrivate *priv;
- GtkRange *range = GTK_RANGE(seekbar);
-
- priv = HILDON_SEEKBAR_GET_PRIVATE(seekbar);
-
- /* Initialize range widget */
- range->orientation = GTK_ORIENTATION_HORIZONTAL;
- range->flippable = TRUE;
- range->has_stepper_a = TRUE;
- range->has_stepper_d = TRUE;
- range->round_digits = MAX_ROUND_DIGITS;
-
- gtk_scale_set_draw_value (GTK_SCALE (seekbar), FALSE);
-}
-
-/*
- * Purpose of this function is to prevent Up and Down keys from
- * changing the widget's value (like Left and Right). Instead they
- * are used for changing focus to other widgtes.
- */
-static gboolean hildon_seekbar_keypress(GtkWidget * widget,
- GdkEventKey * event)
-{
- if (event->keyval == GDK_Up || event->keyval == GDK_Down)
- return FALSE;
- return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget,
- event));
-}
-
-static void
-hildon_seekbar_set_property(GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonSeekbar *seekbar = HILDON_SEEKBAR(object);
-
- switch (prop_id) {
- case PROP_TOTAL_TIME:
- hildon_seekbar_set_total_time(seekbar, g_value_get_double(value));
- break;
- case PROP_POSITION:
- hildon_seekbar_set_position(seekbar, g_value_get_double(value));
- break;
- case PROP_FRACTION:
- hildon_seekbar_set_fraction(seekbar, g_value_get_double(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/* handle getting of seekbar properties */
-static void
-hildon_seekbar_get_property(GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec)
-{
- GtkRange *range = GTK_RANGE(object);
-
- switch (prop_id) {
- case PROP_TOTAL_TIME:
- g_value_set_double(value, range->adjustment->upper);
- break;
- case PROP_POSITION:
- g_value_set_double(value, range->adjustment->value);
- break;
- case PROP_FRACTION:
- g_value_set_double(value,
- hildon_seekbar_get_fraction(HILDON_SEEKBAR(object)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * hildon_seekbar_new:
- *
- * Create a new #HildonSeekbar widget.
- *
- * Returns: a #GtkWidget pointer of #HildonSeekbar widget
- */
-GtkWidget *hildon_seekbar_new(void)
-{
- return g_object_new(HILDON_TYPE_SEEKBAR, NULL);
-}
-
-/**
- * hildon_seekbar_get_total_time:
- * @seekbar: pointer to #HildonSeekbar widget
- *
- * Returns: total playing time of media in seconds.
- */
-gint hildon_seekbar_get_total_time(HildonSeekbar *seekbar)
-{
- GtkWidget *widget;
- widget = GTK_WIDGET (seekbar);
- g_return_val_if_fail(HILDON_IS_SEEKBAR(seekbar), 0);
- g_return_val_if_fail(GTK_RANGE(widget)->adjustment, 0);
- return GTK_RANGE(widget)->adjustment->upper;
-}
-
-/**
- * hildon_seekbar_set_total_time:
- * @seekbar: pointer to #HildonSeekbar widget
- * @time: integer greater than zero
- *
- * Set total playing time of media in seconds.
- */
-void hildon_seekbar_set_total_time(HildonSeekbar *seekbar, gint time)
-{
- GtkAdjustment *adj;
- GtkWidget *widget;
- gboolean value_changed = FALSE;
-
- g_return_if_fail(HILDON_IS_SEEKBAR(seekbar));
- widget = GTK_WIDGET (seekbar);
-
- if (time <= 0) {
- return;
- }
-
- g_return_if_fail(GTK_RANGE(widget)->adjustment);
-
- adj = GTK_RANGE(widget)->adjustment;
- adj->upper = time;
-
- /* Clamp position to total time */
- if (adj->value > time) {
- adj->value = time;
- value_changed = TRUE;
- }
-
- /* Calculate new step value */
- adj->step_increment = adj->upper / NUM_STEPS;
- adj->page_increment = adj->step_increment;
-
- gtk_adjustment_changed(adj);
-
- /* Update range widget position/fraction */
- if (value_changed) {
- gtk_adjustment_value_changed(adj);
- hildon_seekbar_set_fraction(seekbar,
- MIN(hildon_seekbar_get_fraction(seekbar),
- time));
-
- g_object_freeze_notify (G_OBJECT(seekbar));
-
- hildon_seekbar_set_position(seekbar,
- MIN(hildon_seekbar_get_position(seekbar),
- time));
-
- g_object_notify(G_OBJECT (seekbar), "total-time");
-
- g_object_thaw_notify (G_OBJECT(seekbar));
- }
-}
-
-/**
- * hildon_seekbar_get_fraction:
- * @seekbar: pointer to #HildonSeekbar widget
- *
- * Get current fraction value of the rage.
- *
- * Returns: current fraction
- */
-guint hildon_seekbar_get_fraction( HildonSeekbar *seekbar )
-{
- g_return_val_if_fail( HILDON_IS_SEEKBAR( seekbar ), 0 );
-
- return osso_gtk_range_get_stream_position (GTK_RANGE(seekbar));
-}
-
-/**
- * hildon_seekbar_set_fraction:
- * @seekbar: pointer to #HildonSeekbar widget
- * @fraction: the new position of the progress indicator
- *
- * Set current fraction value of the range.
- * It should be between the minimal and maximal values of the range in seekbar.
- */
-void hildon_seekbar_set_fraction( HildonSeekbar *seekbar, guint fraction )
-{
- GtkRange *range = NULL;
- g_return_if_fail( HILDON_IS_SEEKBAR( seekbar ) );
-
- range = GTK_RANGE(GTK_WIDGET(seekbar));
-
- g_return_if_fail(fraction <= range->adjustment->upper &&
- fraction >= range->adjustment->lower);
-
- /* Set to show stream indicator. */
- g_object_set (G_OBJECT (seekbar), "stream_indicator", TRUE, NULL);
-
- fraction = CLAMP(fraction, range->adjustment->lower,
- range->adjustment->upper);
-
- /* Update stream position of range widget */
- osso_gtk_range_set_stream_position( range, fraction );
-
- if (fraction < hildon_seekbar_get_position(seekbar))
- hildon_seekbar_set_position(seekbar, fraction);
-
- g_object_notify (G_OBJECT (seekbar), "fraction");
-}
-
-/**
- * hildon_seekbar_get_position:
- * @seekbar: pointer to #HildonSeekbar widget
- *
- * Get current position in stream in seconds.
- *
- * Returns: current position in stream in seconds
- */
-gint hildon_seekbar_get_position(HildonSeekbar *seekbar)
-{
- g_return_val_if_fail(HILDON_IS_SEEKBAR(seekbar), 0);
- g_return_val_if_fail(GTK_RANGE(seekbar)->adjustment, 0);
-
- return GTK_RANGE(seekbar)->adjustment->value;
-}
-
-/**
- * hildon_seekbar_set_position:
- * @seekbar: pointer to #HildonSeekbar widget
- * @time: time within range of >= 0 && < G_MAXINT
- *
- * Set current position in stream in seconds.
- */
-void hildon_seekbar_set_position(HildonSeekbar *seekbar, gint time)
-{
- GtkRange *range;
- GtkAdjustment *adj;
- gint value;
-
- g_return_if_fail(time >= 0);
- g_return_if_fail(HILDON_IS_SEEKBAR(seekbar));
- range = GTK_RANGE(seekbar);
- adj = range->adjustment;
- g_return_if_fail(adj);
-
- /* only change value if it is a different int. this allows us to have
- smooth scrolls for small total_times */
- value = floor(adj->value);
- if (time != value) {
- value = (time < adj->upper) ? time : adj->upper;
- if (value <= osso_gtk_range_get_stream_position (range)) {
- adj->value = value;
- gtk_adjustment_value_changed(adj);
-
- g_object_notify(G_OBJECT(seekbar), "position");
- }
- }
-}
-
-static void hildon_seekbar_size_request(GtkWidget * widget,
- GtkRequisition * req)
-{
- HildonSeekbar *self = NULL;
- HildonSeekbarPrivate *priv = NULL;
- GtkWidget *parent = NULL;
-
- self = HILDON_SEEKBAR(widget);
- priv = HILDON_SEEKBAR_GET_PRIVATE(self);
-
- parent = gtk_widget_get_ancestor(GTK_WIDGET(self), GTK_TYPE_TOOLBAR);
-
- priv->is_toolbar = parent ? TRUE : FALSE;
-
- if (GTK_WIDGET_CLASS(parent_class)->size_request)
- GTK_WIDGET_CLASS(parent_class)->size_request(widget, req);
-
- /* Request minimum size, depending on whether the widget is in a
- * toolbar or not */
- req->width = priv->is_toolbar ? TOOL_MINIMUM_WIDTH : MINIMUM_WIDTH;
- req->height = priv->is_toolbar ? TOOL_DEFAULT_HEIGHT : DEFAULT_HEIGHT;
-}
-
-static void hildon_seekbar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonSeekbarPrivate *priv;
-
- priv = HILDON_SEEKBAR_GET_PRIVATE(HILDON_SEEKBAR(widget));
-
- if (priv->is_toolbar == TRUE)
- {
- /* Center vertically */
- if (allocation->height > TOOL_DEFAULT_HEIGHT)
- {
- allocation->y +=
- (allocation->height - TOOL_DEFAULT_HEIGHT) / 2;
- allocation->height = TOOL_DEFAULT_HEIGHT;
- }
- /* Add space for border */
- allocation->x += TOOL_EXTRA_SIDE_BORDER;
- allocation->width -= 2 * TOOL_EXTRA_SIDE_BORDER;
- }
- else
- {
- /* Center vertically */
- if (allocation->height > DEFAULT_HEIGHT)
- {
- allocation->y += (allocation->height - DEFAULT_HEIGHT) / 2;
- allocation->height = DEFAULT_HEIGHT;
- }
-
- /* Add space for border */
- allocation->x += EXTRA_SIDE_BORDER;
- allocation->width -= 2 * EXTRA_SIDE_BORDER;
- }
-
- if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
- GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
-}
-
-static gboolean hildon_seekbar_expose(GtkWidget * widget,
- GdkEventExpose * event)
-{
- HildonSeekbarPrivate *priv;
- gint extra_side_borders = 0;
-
- priv = HILDON_SEEKBAR_GET_PRIVATE(HILDON_SEEKBAR(widget));
-
- extra_side_borders = priv->is_toolbar ? TOOL_EXTRA_SIDE_BORDER :
- EXTRA_SIDE_BORDER;
-
- if (GTK_WIDGET_DRAWABLE(widget)) {
- /* Paint border */
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- NULL, widget, "seekbar",
- widget->allocation.x - extra_side_borders,
- widget->allocation.y,
- widget->allocation.width + 2 * extra_side_borders,
- widget->allocation.height);
-
- (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
- }
-
- return FALSE;
-}
-
-/*
- * Event handler for button press. Changes button1 to button2.
- */
-static gboolean
-hildon_seekbar_button_press_event(GtkWidget * widget,
- GdkEventButton * event)
-{
- gint result = FALSE;
-
- /* We change here the button id because we want to use button2
- * functionality for button1: jump to mouse position
- * instead of slowly incrementing to it */
- if (event->button == 1) event->button = 2;
-
- /* call the parent handler */
- if (GTK_WIDGET_CLASS(parent_class)->button_press_event)
- result = GTK_WIDGET_CLASS(parent_class)->button_press_event(widget,
- event);
-
- return result;
-}
-/*
- * Event handler for button release. Changes button1 to button2.
- */
-static gboolean
-hildon_seekbar_button_release_event(GtkWidget * widget,
- GdkEventButton * event)
-{
- gboolean result = FALSE;
-
- /* We change here the button id because we want to use button2
- * functionality for button1: jump to mouse position
- * instead of slowly incrementing to it */
- event->button = event->button == 1 ? 2 : event->button;
-
- /* call the parent handler */
- if (GTK_WIDGET_CLASS(parent_class)->button_release_event)
- result = GTK_WIDGET_CLASS(parent_class)->button_release_event(widget,
- event);
- return result;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_SEEKBAR_H__
-#define __HILDON_SEEKBAR_H__
-
-#include <gtk/gtkscale.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_SEEKBAR ( hildon_seekbar_get_type() )
-#define HILDON_SEEKBAR(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_SEEKBAR, HildonSeekbar))
-#define HILDON_SEEKBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_SEEKBAR, HildonSeekbarClass))
-#define HILDON_IS_SEEKBAR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_SEEKBAR))
-#define HILDON_IS_SEEKBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_SEEKBAR))
-/**
- * HildonSeekbar:
- *
- * Contains only private data.
- */
-typedef struct _HildonSeekbar HildonSeekbar;
-typedef struct _HildonSeekbarClass HildonSeekbarClass;
-
-struct _HildonSeekbar {
- GtkScale scale;
-};
-
-struct _HildonSeekbarClass {
- GtkScaleClass parent_class;
-};
-
-GType hildon_seekbar_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_seekbar_new(void);
-gint hildon_seekbar_get_total_time(HildonSeekbar *seekbar);
-void hildon_seekbar_set_total_time(HildonSeekbar *seekbar, gint time);
-gint hildon_seekbar_get_position(HildonSeekbar *seekbar);
-void hildon_seekbar_set_position(HildonSeekbar *seekbar, gint time);
-void hildon_seekbar_set_fraction(HildonSeekbar *seekbar, guint fraction);
-guint hildon_seekbar_get_fraction(HildonSeekbar *seekbar);
-
-G_END_DECLS
-#endif /* __HILDON_SEEKBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-set-password-dialog
- * @short_description: A dialog used to set, change or remove a password
- * @see_also: #HildonGetPasswordDialog
- *
- * HildonSetPasswordDialog allows setting and changing a password.
- *
- * In Change mode: Dialog is used to change or remove an existing
- * password. Unselecting the check box dims the password fields below
- * it. If the dialog is accepted with 'OK' while the check box is
- * unselected, a Confirmation Note is shown. If the Confirmation Note
- * Dialog is accepted with 'Remove', the password protection is removed.
- *
- * In Set mode: Set Password Dialog is used to define a password, or
- * change a password that cannot be removed.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <glib.h>
-
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include <hildon-widgets/hildon-caption.h>
-#include <hildon-widgets/gtk-infoprint.h>
-#include <hildon-widgets/hildon-set-password-dialog.h>
-#include <hildon-widgets/hildon-note.h>
-#include <hildon-widgets/hildon-defines.h>
-
-#include <libintl.h>
-#define _(String) dgettext(PACKAGE, String)
-#define c_(String) dgettext("hildon-common-strings", String)
-
-static GtkDialogClass *parent_class;
-
-#define HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(obj)\
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_SET_PASSWORD_DIALOG, HildonSetPasswordDialogPrivate));
-
-typedef struct
-_HildonSetPasswordDialogPrivate HildonSetPasswordDialogPrivate;
-
-static void
-hildon_set_password_dialog_class_init(HildonSetPasswordDialogClass *
- class);
-static void hildon_set_password_dialog_init(HildonSetPasswordDialog *
- dialog);
-static void hildon_checkbox_toggled(GtkWidget * widget, gpointer dialog);
-
-static void
-hildon_set_password_response_change(GtkDialog * d, gint arg1, gpointer unused);
-static void
-hildon_set_password_response_set(GtkDialog * d, gint arg1, gpointer unused);
-
-static void create_contents(HildonSetPasswordDialog *dialog);
-static void hildon_set_password_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_set_password_get_property(GObject * object,
- guint prop_id, GValue * value,
- GParamSpec * pspec);
-
-/* Private struct */
-struct _HildonSetPasswordDialogPrivate {
- GtkWidget *checkboxCaption;
- GtkWidget *checkbox;
-
- GtkLabel *domainLabel;
-
- GtkWidget *pwd1stEntry;
- GtkWidget *pwd1stCaption;
- gchar *pwd1stCaption_string;
-
- GtkWidget *pwd2ndEntry;
- GtkWidget *pwd2ndCaption;
- gchar *pwd2ndCaption_string;
-
- GtkWidget *okButton;
- GtkWidget *cancelButton;
-
- gboolean protection;
-};
-
-enum {
- PROP_NONE = 0,
- PROP_DOMAIN,
- PROP_PASSWORD,
- PROP_HILDON_PASSWORD_DIALOG
-};
-
-/* Private functions */
-static void
-hildon_set_password_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonSetPasswordDialog *dialog = HILDON_SET_PASSWORD_DIALOG(object);
- HildonSetPasswordDialogPrivate *priv;
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- switch (prop_id) {
- case PROP_DOMAIN:
- /* Update domain label to display new value */
- gtk_label_set_text(priv->domainLabel, g_value_get_string(value));
- break;
- case PROP_PASSWORD:
- /* Update password entry to display new value */
- gtk_entry_set_text(GTK_ENTRY(priv->pwd1stEntry), g_value_get_string(value));
- break;
- case PROP_HILDON_PASSWORD_DIALOG:
- /* Note this is a G_PARAM_CONSTRUCT_ONLY type property */
- priv->protection = g_value_get_boolean(value);
-
- /* We now have the necessary information to populate the dialog */
- create_contents(dialog);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_set_password_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec)
-{
- HildonSetPasswordDialogPrivate *priv = NULL;
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(object);
-
- switch (prop_id) {
- case PROP_DOMAIN:
- g_value_set_string(value, gtk_label_get_text(priv->domainLabel));
- break;
- case PROP_PASSWORD:
- g_value_set_string(value,
- gtk_entry_get_text(GTK_ENTRY(priv->pwd1stEntry)));
- break;
- case PROP_HILDON_PASSWORD_DIALOG:
- g_value_set_boolean(value, priv->protection);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-
-static void
-create_contents(HildonSetPasswordDialog *dialog)
-{
- HildonSetPasswordDialogPrivate *priv = NULL;
-
- GtkSizeGroup *group;
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- priv->checkbox = NULL;
-
- /* Size group for labels */
- group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
-
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
-
- /* Setup and pack domain label */
- priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
- gtk_widget_show(GTK_WIDGET(priv->domainLabel));
-
- if (priv->protection == TRUE) {
- /* Use Change Password Dialog strings */
- priv->pwd1stCaption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD);
- priv->pwd2ndCaption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD);
-
- /* Setup checkbox to enable/disable password protection */
- priv->checkbox = gtk_check_button_new();
- gtk_widget_show(priv->checkbox);
- priv->checkboxCaption = hildon_caption_new
- (group,
- _(HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL),
- priv->checkbox,
- NULL, HILDON_CAPTION_OPTIONAL);
- hildon_caption_set_separator(HILDON_CAPTION(priv->checkboxCaption), "");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->checkboxCaption, TRUE, TRUE, 0);
- gtk_widget_show(priv->checkboxCaption);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->checkbox),
- TRUE);
- gtk_signal_connect(GTK_OBJECT(priv->checkbox), "toggled",
- G_CALLBACK(hildon_checkbox_toggled), dialog);
-
- /* Setup appropriate response handler */
- g_signal_connect(G_OBJECT(dialog), "response",
- G_CALLBACK(hildon_set_password_response_change),
- NULL);
- } else {
- /* Use Set Password Dialog strings */
- priv->pwd1stCaption_string = _(HILDON_SET_PASSWORD_DIALOG_PASSWORD);
- priv->pwd2ndCaption_string = _(HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD);
-
- /* Setup appropriate response handler */
- g_signal_connect(G_OBJECT(dialog), "response",
- G_CALLBACK(hildon_set_password_response_set),
- NULL);
- }
-
- /* Create the password field */
- priv->pwd1stEntry = gtk_entry_new();
- g_object_set (priv->pwd1stEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
- gtk_entry_set_visibility(GTK_ENTRY(priv->pwd1stEntry), FALSE);
- gtk_widget_show(priv->pwd1stEntry);
- priv->pwd1stCaption = hildon_caption_new(group,
- priv->pwd1stCaption_string,
- priv->pwd1stEntry,
- NULL, HILDON_CAPTION_OPTIONAL);
- hildon_caption_set_separator(HILDON_CAPTION(priv->pwd1stCaption), "");
- gtk_entry_set_visibility(GTK_ENTRY(priv->pwd1stEntry), FALSE);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->pwd1stCaption, TRUE, TRUE, 0);
- gtk_widget_show(priv->pwd1stCaption);
-
- /* Create the password verify field */
- priv->pwd2ndEntry = gtk_entry_new();
- g_object_set (priv->pwd2ndEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
- gtk_widget_show(priv->pwd2ndEntry);
- priv->pwd2ndCaption = hildon_caption_new(group,
- priv->pwd2ndCaption_string,
- priv->pwd2ndEntry,
- NULL, HILDON_CAPTION_OPTIONAL);
- hildon_caption_set_separator(HILDON_CAPTION(priv->pwd2ndCaption), "");
- gtk_entry_set_visibility(GTK_ENTRY(priv->pwd2ndEntry), FALSE);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->pwd2ndCaption, TRUE, TRUE, 0);
- gtk_widget_show(priv->pwd2ndCaption);
-
- /* Set dialog title */
- gtk_window_set_title(GTK_WINDOW(dialog),
- _(priv->protection
- ? HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE
- : HILDON_SET_PASSWORD_DIALOG_TITLE));
-
- /* Create the OK/CANCEL buttons */
- priv->okButton = gtk_dialog_add_button
- (GTK_DIALOG(dialog), _(priv->protection
- ? HILDON_SET_MODIFY_PASSWORD_DIALOG_OK
- : HILDON_SET_PASSWORD_DIALOG_OK),
- GTK_RESPONSE_OK);
- priv->cancelButton = gtk_dialog_add_button
- (GTK_DIALOG(dialog), _(priv->protection
- ? HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL
- : HILDON_SET_PASSWORD_DIALOG_CANCEL),
- GTK_RESPONSE_CANCEL);
-
- gtk_widget_show(priv->okButton);
- gtk_widget_show(priv->cancelButton);
-
- /* Ensure group is freed when all its contents have been removed */
- g_object_unref(group);
-}
-
-static void
-hildon_set_password_dialog_class_init(HildonSetPasswordDialogClass * class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(class);
-
- parent_class = g_type_class_peek_parent(class);
-
- /* Override virtual methods */
- object_class->set_property = hildon_set_password_set_property;
- object_class->get_property = hildon_set_password_get_property;
-
- /* Install new properties */
- g_object_class_install_property(object_class,
- PROP_DOMAIN,
- g_param_spec_string ("domain",
- "Domain",
- "Set Domain (content) for domain label.",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class,
- PROP_HILDON_PASSWORD_DIALOG,
- g_param_spec_boolean ("modify_protection",
- "Password type",
- "Set type to dialog",
- TRUE,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class,
- PROP_PASSWORD,
- g_param_spec_string ("password",
- "Password content",
- "Set content to dialog",
- "DEFAULT",
- G_PARAM_READWRITE));
-
- /* Install private structure */
- g_type_class_add_private(class,
- sizeof(HildonSetPasswordDialogPrivate));
-}
-
-static void
-hildon_set_password_dialog_init(HildonSetPasswordDialog * dialog)
-{
- /* Most of the initializations are done in create_contents()
- after the 'modify_protection' property has been set */
-
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
-}
-
-
-/* We come here when response button is clicked and dialog
- is used to change existing password. */
-static void
-hildon_set_password_response_change(GtkDialog * dialog, gint arg1,
- gpointer unused)
-{
- GtkEntry *pwd1stEntry;
- GtkEntry *pwd2ndEntry;
- gchar *text1;
- gchar *text2;
- HildonNote *note;
- gint i;
- HildonSetPasswordDialogPrivate *priv;
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Password and verification */
- pwd1stEntry = GTK_ENTRY(gtk_bin_get_child
- (GTK_BIN(priv->pwd1stCaption)));
- pwd2ndEntry = GTK_ENTRY(gtk_bin_get_child
- (GTK_BIN(priv->pwd2ndCaption)));
- text1 = GTK_ENTRY(pwd1stEntry)->text;
- text2 = GTK_ENTRY(pwd2ndEntry)->text;
-
- /* User accepted the dialog */
- if (arg1 == GTK_RESPONSE_OK){
- /* Is the checkbox marked, so password protection is still in use? */
- if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbox))){
- /* Yes, Something is given as password as well? */
- if (text1[0] != '\0') {
- if (strcmp (text1, text2) == 0) {
- /* Passwords match, so accept change password */
- priv->protection = TRUE;
- } else if (text2[0] == '\0') {
- /* Second field is empty, so show error, but don't clear fields */
- g_signal_stop_emission_by_name(G_OBJECT(dialog),
- "response");
- gtk_infoprint (NULL,
- c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_widget_grab_focus(GTK_WIDGET(pwd2ndEntry));
- } else {
- /* Error: Passwords don't match, so start over */
- g_signal_stop_emission_by_name(G_OBJECT(dialog),
- "response");
- gtk_entry_set_text(pwd1stEntry, "");
- gtk_entry_set_text(pwd2ndEntry, "");
- gtk_infoprint (NULL,
- c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
- }
- } else {
- /* No, the password is empty */
- g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
- if (text2[0] == '\0') {
- /* Error: Both fields are empty */
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
- } else {
- /* Error: Second field doesn't match
- the empty first field, so start over */
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_entry_set_text(pwd2ndEntry, "");
- }
- gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
- }
- } else {
- /* No, user wants to remove password protection.
- Confirm remove password protection */
- note = HILDON_NOTE(hildon_note_new_confirmation
- (GTK_WINDOW(dialog),
- c_(HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION
- )));
-
- hildon_note_set_button_texts
- (HILDON_NOTE(note),
- c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE),
- c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL));
-
- /* Display confirmation note */
- i = gtk_dialog_run(GTK_DIALOG(note));
-
- gtk_widget_destroy(GTK_WIDGET(note));
-
- if (i == GTK_RESPONSE_OK)
- /* Remove password protection */
- priv->protection = FALSE;
- else {
- /* Remove password protection cancelled */
- priv->protection = TRUE;
- g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
- }
- }
-
- } else {
- /* Watch out for fading boolean values */
- priv->protection = TRUE;
- }
-}
-
-/* We come here when response button is clicked and dialog
- is used to set new password. */
-static void
-hildon_set_password_response_set(GtkDialog * dialog, gint arg1,
- gpointer unused)
-{
- GtkEntry *pwd1stEntry;
- GtkEntry *pwd2ndEntry;
- gchar *text1;
- gchar *text2;
-
- HildonSetPasswordDialogPrivate *priv;
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- /* Password and confirmation */
- pwd1stEntry = GTK_ENTRY(gtk_bin_get_child
- (GTK_BIN(priv->pwd1stCaption)));
- pwd2ndEntry = GTK_ENTRY(gtk_bin_get_child
- (GTK_BIN(priv->pwd2ndCaption)));
- text1 = GTK_ENTRY(pwd1stEntry)->text;
- text2 = GTK_ENTRY(pwd2ndEntry)->text;
-
- if (arg1 == GTK_RESPONSE_OK) {
- /* User provided something for password? */
- if (text1[0] != '\0') {
- if (strcmp (text1, text2) == 0) {
- /* Passwords match, so accept set password */
- priv->protection = TRUE;
- } else if (text2[0] == '\0') {
- /* Second field is empty, so show error,
- but don't clear the fields */
- g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_widget_grab_focus (GTK_WIDGET (priv->pwd2ndEntry));
- } else {
- /* Error: Passwords don't match, so start over */
- g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
- gtk_entry_set_text(pwd1stEntry, "");
- gtk_entry_set_text(pwd2ndEntry, "");
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_widget_grab_focus(GTK_WIDGET(priv->pwd1stEntry));
- }
- } else {
- /* First field is empty */
- g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
- if (text2[0] == '\0') {
- /* Error: Both fields are empty */
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
- } else {
- /* Error: Second field doesn't match
- the empty first field, so start over */
- gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
- gtk_entry_set_text(pwd2ndEntry, "");
- }
- gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
- }
- } else {
- /* Watch out for fading boolean values */
- priv->protection = FALSE;
- }
-}
-
-static void hildon_checkbox_toggled(GtkWidget * widget, gpointer dialog)
-{
- HildonSetPasswordDialogPrivate *priv =
- HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- gboolean active;
-
- /* If the user enabled/disabled the password protection feature
- we enable/disable password entries accordingly */
- active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- gtk_widget_set_sensitive(GTK_WIDGET(priv->pwd1stEntry), active);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->pwd2ndEntry), active);
-}
-
-/* Public functions */
-
-/**
- * hildon_set_password_dialog_get_type:
- *
- * Returns GType for HildonPasswordDialog as produced by
- * g_type_register_static().
- *
- * Returns: HildonSetPasswordDialog type
- */
-GType hildon_set_password_dialog_get_type(void)
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonSetPasswordDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_set_password_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonSetPasswordDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_set_password_dialog_init
- };
-
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonSetPasswordDialog",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-/**
- * hildon_set_password_dialog_new:
- * @parent: parent window; can be NULL
- * @modify_protection: TRUE creates a new change password dialog and FALSE
- * creates a new set password dialog
- *
- * Constructs a new HildonSetPasswordDialog.
- *
- * Returns: a new #GtkWidget of type HildonSetPasswordDialog
- */
-
-GtkWidget *hildon_set_password_dialog_new(GtkWindow * parent,
- gboolean modify_protection)
-{
- return hildon_set_password_dialog_new_with_default(parent, "",
- modify_protection);
-}
-
-/**
- * hildon_set_password_dialog_new_with_default:
- * @parent: parent window; can be NULL
- * @password: a default password to be shown in password field
- * @modify_protection: TRUE creates a new change password dialog and FALSE
- * creates a new set password dialog
- *
- * Same as #hildon_set_password_dialog_new, but with a default password
- * in password field.
- *
- * Returns: a new #GtkWidget of type HildonSetPasswordDialog
- */
-
-GtkWidget *hildon_set_password_dialog_new_with_default
- (GtkWindow *parent,
- const gchar *password,
- gboolean modify_protection)
-{
- GtkWidget *dialog = g_object_new(HILDON_TYPE_SET_PASSWORD_DIALOG,
- "modify_protection", modify_protection,
- "password", password, NULL);
-
- if (parent != NULL) {
- gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
- }
-
- return dialog;
-}
-
-/**
- * hildon_set_password_dialog_get_password:
- * @dialog: pointer to HildonSetPasswordDialog
- *
- * Returns current password.
- *
- * Returns: changed password ( if the dialog is successfully
- * accepted with 'OK' ( and when the check box is 'ON' ( in Change Password
- * Dialog ))
- */
-const gchar
- *hildon_set_password_dialog_get_password(HildonSetPasswordDialog *
- dialog)
-{
- HildonSetPasswordDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog), NULL);
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- return GTK_ENTRY(priv->pwd1stEntry)->text;
-}
-
-/**
- * hildon_set_password_dialog_get_protected:
- * @dialog: pointer to HildonSetPasswordDialog
- *
- * Returns the protection mode.
- *
- * Returns: password protection mode ( TRUE when the protection is
- * 'ON' and FALSE when the protection is 'OFF' )
- */
-gboolean
-hildon_set_password_dialog_get_protected(HildonSetPasswordDialog * dialog)
-{
- HildonSetPasswordDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog), FALSE);
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
-
- return priv->protection;
-}
-
-/**
- * hildon_set_password_dialog_set_domain(GtkWidget *dialog,
- * @dialog: the dialog
- * @domain: the domain or some other descriptive text to be set
- *
- * Sets the optional descriptive text.
- */
-
-void hildon_set_password_dialog_set_domain(HildonSetPasswordDialog *dialog,
- const gchar *domain)
-{
- HildonSetPasswordDialogPrivate *priv = NULL;
-
- g_return_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog));
-
- priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
- gtk_label_set_text(priv->domainLabel, domain);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_SET_PASSWORD_DIALOG_H__
-#define __HILDON_SET_PASSWORD_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-
-#define HILDON_TYPE_SET_PASSWORD_DIALOG \
- ( hildon_set_password_dialog_get_type() )
-#define HILDON_SET_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_SET_PASSWORD_DIALOG,\
- HildonSetPasswordDialog))
-#define HILDON_SET_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_SET_PASSWORD_DIALOG, \
- HildonSetPasswordDialogClass))
-#define HILDON_IS_SET_PASSWORD_DIALOG(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_SET_PASSWORD_DIALOG))
-#define HILDON_IS_SET_PASSWORD_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_SET_PASSWORD_DIALOG))
-
-
-
-#define HILDON_SET_PASSWORD_DIALOG_TITLE "ecdg_ti_set_password"
-#define HILDON_SET_PASSWORD_DIALOG_PASSWORD "ecdg_fi_set_passwd_enter_pwd"
-#define HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD "ecdg_fi_set_passwd_confirm"
-#define HILDON_SET_PASSWORD_DIALOG_OK "ecdg_bd_set_password_dialog_ok"
-#define HILDON_SET_PASSWORD_DIALOG_CANCEL "ecdg_bd_set_password_dialog_cancel"
-
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE "ckdg_ti_dialog_c_passwd_change_password"
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL "ckdg_fi_dialog_c_passwd_pwd_protect"
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD "ckdg_fi_dialog_c_passwd_new_pwd"
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD "ckdg_fi_dialog_c_passwd_ver_pwd"
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_OK "ckdg_bd_change_password_dialog_ok"
-#define HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL "ckdg_bd_change_password_dialog_cancel"
-
-#define HILDON_SET_PASSWORD_DIALOG_MISMATCH "ecdg_ib_passwords_do_not_match"
-#define HILDON_SET_PASSWORD_DIALOG_EMPTY "ecdg_ib_password_is_empty"
-#define HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION "ckdg_nc_dialog_c_passwd_remove_pwd"
-
-#define HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE "ckdg_bd_dialog_c_passwd_remove_button"
-#define HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL "ckdg_bd_dialog_c_passwd_cancel_button"
-
-
-
-typedef struct _HildonSetPasswordDialog HildonSetPasswordDialog;
-typedef struct _HildonSetPasswordDialogClass HildonSetPasswordDialogClass;
-
-struct _HildonSetPasswordDialog {
- GtkDialog parent;
-};
-
-struct _HildonSetPasswordDialogClass {
- GtkDialogClass parent_class;
-};
-
-
-
-GtkWidget * hildon_set_password_dialog_new (GtkWindow *parent,
- gboolean modify_protection);
-
-GtkWidget * hildon_set_password_dialog_new_with_default (GtkWindow *parent,
- const gchar *password,
- gboolean modify_protection);
-
-GType hildon_set_password_dialog_get_type (void) G_GNUC_CONST;
-
-const gchar *hildon_set_password_dialog_get_password (HildonSetPasswordDialog *dialog);
-
-gboolean hildon_set_password_dialog_get_protected (HildonSetPasswordDialog *dialog);
-
-void hildon_set_password_dialog_set_domain (HildonSetPasswordDialog *dialog,
- const gchar *domain);
-
-
-G_END_DECLS
-
-#endif /* __HILDON_SET_PASSWORD_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-sort-dialog
- * @short_description: A widget for defining the sorting order of items
- *
- * HildonSortDialog is used to define an order (ascending/descending)
- * and a field by which items are sorted in a list. The combo boxes
- * display the current value when the dialog is opened.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <libintl.h>
-#include <gtk/gtkcombobox.h>
-#include <gtk/gtkbox.h>
-#include <hildon-widgets/hildon-caption.h>
-#include "hildon-sort-dialog.h"
-
-
-#define _(String) dgettext(PACKAGE, String)
-
-static GtkDialogClass *parent_class;
-
-#define HILDON_SORT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \
- ((obj), HILDON_TYPE_SORT_DIALOG, HildonSortDialogPrivate));
-
-typedef struct _HildonSortDialogPrivate HildonSortDialogPrivate;
-
-static void hildon_sort_dialog_class_init(HildonSortDialogClass * class);
-static void hildon_sort_dialog_init(HildonSortDialog * widget);
-static void hildon_sort_dialog_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_sort_dialog_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec);
-static void reconstruct_combo (HildonSortDialog * dialog,
- gboolean remove,
- gboolean reversed);
-static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog,
- const gchar * sort_key,
- gboolean sorting);
-static void sort_key_changed(GtkWidget * widget,
- HildonSortDialog * dialog);
-static void hildon_sort_dialog_finalize(GObject * object);
-
-enum {
- PROP_0,
- PROP_SORT_KEY,
- PROP_SORT_ORDER
-};
-
-/* private data */
-struct _HildonSortDialogPrivate {
- /* Sort category widgets */
- GtkWidget *combo_key;
- GtkWidget *caption_key;
-
- /* Sort order widgets */
- GtkWidget *combo_order;
- GtkWidget *caption_order;
-
- /* Index value counter */
- gint index_counter;
-
- /* If the current order displayed is reversed */
- gboolean reversed;
-
- /* An array for each key representing if a key should be reverse-sorted */
- gboolean *key_reversed;
-};
-
-/* Private functions */
-
-static void sort_key_changed(GtkWidget * widget, HildonSortDialog * dialog)
-{
- g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
-
- HildonSortDialogPrivate *priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
-
- gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
-
- if (priv->key_reversed [index] != priv->reversed) {
- reconstruct_combo (dialog, TRUE, priv->key_reversed [index]);
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
- }
-
- priv->reversed = priv->key_reversed [index];
-}
-
-/*
- * Initialises the sort dialog class.
- */
-static void hildon_sort_dialog_class_init(HildonSortDialogClass * class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(class);
- parent_class = g_type_class_peek_parent(class);
- g_type_class_add_private(class, sizeof(HildonSortDialogPrivate));
-
- gobject_class->set_property = hildon_sort_dialog_set_property;
- gobject_class->get_property = hildon_sort_dialog_get_property;
- gobject_class->finalize = (gpointer) hildon_sort_dialog_finalize;
-
- g_object_class_install_property(gobject_class, PROP_SORT_KEY,
- g_param_spec_int("sort-key",
- "Sort Key",
- "The currently active sort key",
- G_MININT,
- G_MAXINT,
- 0, G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class, PROP_SORT_ORDER,
- g_param_spec_enum("sort-order",
- "Sort Order",
- "The current sorting order",
- GTK_TYPE_SORT_TYPE,
- GTK_SORT_ASCENDING,
- G_PARAM_READWRITE));
-}
-
-static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog, const gchar * sort_key, gboolean sorting)
-{
- HildonSortDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
- gboolean *new_array = g_malloc (sizeof (gboolean) * (priv->index_counter + 1));
-
- /* Rewrite the old values */
- int i = 0;
- for (i = 0; i < priv->index_counter; i++)
- new_array [i] = priv->key_reversed [i];
-
- new_array [priv->index_counter] = sorting;
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_key), sort_key);
-
- /* Free the old one and reassign */
- if (priv->key_reversed != NULL)
- g_free (priv->key_reversed);
- priv->key_reversed = new_array;
-
- return priv->index_counter++;
-}
-
-static void reconstruct_combo (HildonSortDialog * dialog, gboolean remove, gboolean reversed)
-{
- HildonSortDialogPrivate *priv;
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
-
- if (remove) {
- gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 1);
- gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 0);
- }
-
- if (reversed) {
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
- } else {
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
- gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
- }
-}
-
-static void hildon_sort_dialog_init(HildonSortDialog * dialog)
-{
- HildonSortDialogPrivate *priv;
- GtkSizeGroup *group;
-
- g_assert(HILDON_IS_SORT_DIALOG(dialog));
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
-
- priv->index_counter = 0;
- priv->reversed = FALSE;
- priv->key_reversed = NULL;
-
- group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
-
- gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
- gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
- gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_sort"));
-
- /* Tab one */
- priv->combo_key = gtk_combo_box_new_text();
- priv->caption_key = hildon_caption_new(group, _("ckdg_fi_sort_field"), priv->combo_key,
- NULL, HILDON_CAPTION_OPTIONAL);
- hildon_caption_set_separator(HILDON_CAPTION(priv->caption_key), "");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->caption_key, FALSE, FALSE, 0);
-
- /* Tab two */
- priv->combo_order = gtk_combo_box_new_text();
- reconstruct_combo (dialog, FALSE, FALSE);
-
- priv->caption_order = hildon_caption_new(group, _("ckdg_fi_sort_order"),
- priv->combo_order,
- NULL, HILDON_CAPTION_OPTIONAL);
- hildon_caption_set_separator(HILDON_CAPTION(priv->caption_order), "");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
- priv->caption_order, FALSE, FALSE, 0);
-
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_key), 0);
- gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
- g_signal_connect (G_OBJECT (priv->combo_key), "changed", (gpointer) sort_key_changed, dialog);
-
- /* Create the OK/CANCEL buttons */
- (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
- _("ckdg_bd_sort_dialog_ok"),
- GTK_RESPONSE_OK);
- (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
- _("ckdg_bd_sort_dialog_cancel"),
- GTK_RESPONSE_CANCEL);
- /* FIXME: Hardcoded sizes are bad */
- gtk_window_resize(GTK_WINDOW(dialog), 370, 100);
- gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
-
- g_object_unref(group); /* Captions now own their references to sizegroup */
-}
-
-/* Public functions */
-
-/**
- * hildon_sort_dialog_get_type:
- *
- * Returns GType for HildonSortDialog as produced by
- * g_type_register_static().
- *
- * Returns: HildonSortDialog type
- */
-GType hildon_sort_dialog_get_type()
-{
- static GType dialog_type = 0;
-
- if (!dialog_type) {
- static const GTypeInfo dialog_info = {
- sizeof(HildonSortDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_sort_dialog_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonSortDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_sort_dialog_init
- };
-
- dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
- "HildonSortDialog",
- &dialog_info, 0);
- }
- return dialog_type;
-}
-
-/**
- * hildon_sort_dialog_new:
- * @parent: widget to be transient for, or NULL if none
- *
- * HildonSortDialog contains two HildonCaptions with combo boxes.
- *
- * Returns: pointer to a new @HildonSortDialog widget
- */
-GtkWidget *hildon_sort_dialog_new(GtkWindow * parent)
-{
- GtkWidget *sort_dialog = g_object_new(HILDON_TYPE_SORT_DIALOG, NULL);
-
- if (parent)
- gtk_window_set_transient_for(GTK_WINDOW(sort_dialog), parent);
-
- return sort_dialog;
-}
-
-/**
- * hildon_sort_dialog_get_sort_key:
- * @dialog: the #HildonSortDialog widget
- *
- * Gets index to currently active sort key.
- *
- * Returns: an integer which is the index value of the "Sort by"
- * field
- */
-gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog)
-{
- GtkWidget *combo_key;
- HildonSortDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
-
- combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
-
- return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_key));
-}
-
-/**
- * hildon_sort_dialog_get_sort_order:
- * @dialog: the #HildonSortDialog widget
- *
- * Gets current sorting order from "Sort order" field.
- *
- * Returns: current sorting order as #GtkSortType
- */
-GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog)
-{
- GtkWidget *combo_order;
- HildonSortDialogPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), 0);
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
- combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
-
- gint sort_order = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_order));
-
- if (priv->reversed)
- return (sort_order == 0) ? 1 : 0;
- else
- return sort_order;
-}
-
-/**
- * hildon_sort_dialog_set_sort_key:
- * @dialog: the #HildonSortDialog widget
- * @key: combo box's index value
- *
- * Sets the index value of the #HildonSortDialog widget.
- */
-void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key)
-{
- GtkWidget *combo_key;
- HildonSortDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
- combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_key), key);
-
- g_object_notify (G_OBJECT (dialog), "sort-key");
-}
-
-/**
- * hildon_sort_dialog_set_sort_order:
- * @dialog: the #HildonSortDialog widget
- * @order: combo box's index value
- *
- * Sets the index value of the #HildonSortDialog widget.
- */
-void
-hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
- GtkSortType order)
-{
- GtkWidget *combo_order;
- HildonSortDialogPrivate *priv;
-
- g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
- combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
-
- if (priv->reversed)
- order = (order == 0) ? 1 : 0;
-
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_order), order);
-
- g_object_notify (G_OBJECT (dialog), "sort-order");
-}
-
-/**
- * hildon_sort_dialog_add_sort_key:
- * @dialog: the #HildonSortDialog widget
- * @sort_key: combo box's index value
- *
- * Adds a new sort key and returns the respective index in
- * sort key combobox.
- *
- * Returns: an integer which is the index of the added combo box's
- * item
- */
-gint
-hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
- const gchar * sort_key)
-{
- return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, FALSE);
-}
-
-/**
- * hildon_sort_dialog_add_sort_key_reversed:
- * @dialog: the #HildonSortDialog widget
- * @sort_key: combo box's index value
- *
- * Adds a new sort key and returns the respective index in
- * sort key combobox. The default sort order for this key is reversed (Descending first).
- *
- * Returns: an integer which is the index of the added combo box's
- * item
- *
- * Since: 0.14.1
- */
-gint
-hildon_sort_dialog_add_sort_key_reversed(HildonSortDialog * dialog,
- const gchar * sort_key)
-{
- return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, TRUE);
-}
-
-static void
-hildon_sort_dialog_set_property(GObject * object,
- guint prop_id,
- const GValue * value, GParamSpec * pspec)
-{
- HildonSortDialog *dialog;
-
- dialog = HILDON_SORT_DIALOG(object);
-
- switch (prop_id) {
- case PROP_SORT_KEY:
- hildon_sort_dialog_set_sort_key(dialog, g_value_get_int(value));
- break;
- case PROP_SORT_ORDER:
- hildon_sort_dialog_set_sort_order(dialog, g_value_get_enum(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_sort_dialog_get_property(GObject * object,
- guint prop_id, GValue * value, GParamSpec * pspec)
-{
- HildonSortDialog *dialog;
-
- dialog = HILDON_SORT_DIALOG(object);
-
- switch (prop_id) {
- case PROP_SORT_KEY:
- g_value_set_int(value, hildon_sort_dialog_get_sort_key(dialog));
- break;
- case PROP_SORT_ORDER:
- g_value_set_enum(value, hildon_sort_dialog_get_sort_order(dialog));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_sort_dialog_finalize(GObject * object)
-{
- HildonSortDialogPrivate *priv;
- HildonSortDialog *dialog;
-
- g_return_if_fail (HILDON_IS_SORT_DIALOG (object));
- dialog = HILDON_SORT_DIALOG(object);
-
- priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
- if (priv != NULL && priv->key_reversed != NULL)
- g_free(priv->key_reversed);
-
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_SORT_DIALOG_H__
-#define __HILDON_SORT_DIALOG_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-#define HILDON_TYPE_SORT_DIALOG \
- ( hildon_sort_dialog_get_type() )
-#define HILDON_SORT_DIALOG(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_SORT_DIALOG, HildonSortDialog))
-#define HILDON_SORT_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_SORT_DIALOG, \
- HildonSortDialogClass))
-#define HILDON_IS_SORT_DIALOG(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_SORT_DIALOG))
-#define HILDON_IS_SORT_DIALOG_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_SORT_DIALOG))
-typedef struct _HildonSortDialog HildonSortDialog;
-typedef struct _HildonSortDialogClass HildonSortDialogClass;
-
-
-
-struct _HildonSortDialog {
- GtkDialog parent;
-};
-
-struct _HildonSortDialogClass {
- GtkDialogClass parent_class;
-};
-
-GType hildon_sort_dialog_get_type(void) G_GNUC_CONST;
-
-
-GtkWidget *hildon_sort_dialog_new(GtkWindow * parent);
-gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog);
-GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog);
-void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key);
-void hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
- GtkSortType order);
-gint hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
- const gchar * sort_key);
-
-G_END_DECLS
-#endif /* __HILDON_SORT_DIALOG_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-system-sound
- * @short_description: An esd-based utility function for playing a sound
- *
- * HildonSystemSound is an esd-based utility function for playing a sound
- * from the system sounds directory with volume taken from GConf.
- */
-
-#include <gconf/gconf-client.h>
-#include <esd.h>
-#include "hildon-system-sound.h"
-
-#define ALARM_GCONF_PATH "/apps/osso/sound/system_alert_volume"
-
-/**
- * hildon_play_system_sound:
- * @sample: sound file to play
- *
- * Plays the given sample using esd sound daemon.
- * Volume level is received from gconf.
- */
-void hildon_play_system_sound(const gchar *sample)
-{
- GConfClient *client;
- GConfValue *value;
- gint volume, scale, sock, sample_id;
-
- client = gconf_client_get_default();
- value = gconf_client_get(client, ALARM_GCONF_PATH, NULL);
-
- /* We want error cases to match full volume, not silence, so
- we do not want to use gconf_client_get_int */
- if (!value || value->type != GCONF_VALUE_INT)
- volume = 2;
- else
- volume = gconf_value_get_int(value);
-
- if (value)
- gconf_value_free(value);
- g_object_unref(client);
-
- switch (volume)
- {
- case 0:
- return;
- case 1:
- scale = 0x80;
- break;
- case 2:
- default:
- scale = 0xff;
- break;
- };
-
- sock = esd_open_sound(NULL);
- if (sock <= 0)
- return;
-
- sample_id = esd_file_cache(sock, g_get_prgname(), sample);
- if (sample_id < 0) {
- close(sock);
- return;
- }
-
- esd_set_default_sample_pan(sock, sample_id, scale, scale);
- esd_sample_play(sock, sample_id);
- esd_sample_free(sock, sample_id);
- close(sock);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_SYSTEM_SOUND_H__
-#define __HILDON_SYSTEM_SOUND_H__
-
-G_BEGIN_DECLS
-
-void hildon_play_system_sound(const gchar *sample);
-
-G_END_DECLS
-#endif /* __HILDON_SYSTEM_SOUND_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-telephone-editor.c
- * @short_description: A widget which allows users to enter telephone numbers
- *
- * A single-line editor which allows user to enter a telephone number.
- * There are two modes to choose from (coerce/free format).
- * Coerce format has three fields which are placed horizontally.
- * The fields are: country code, area code and number. When nothing is
- * entered in the fields, assisting text is displayed. Tapping on the
- * field highlights the field and allows users to input numbers.
- *
- * The widget is used where a user should enter a phone number. Free format
- * should be used wherever possible as it enables the user to enter the
- * phone number in the format she likes. Free format also supports DTMF
- * strings as a part of the phone number. The format can not be changed
- * at runtime.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <libintl.h>
-#include <string.h>
-#include "hildon-telephone-editor.h"
-#include "hildon-composite-widget.h"
-
-#define _(String) gettext (String)
-#define HILDON_TELEPHONE_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TELEPHONE_EDITOR_TYPE, HildonTelephoneEditorPriv));
-
-#define AREA_LEN 4
-#define COUNTRY_LEN 7
-#define NUMBER_LEN 10
-
-#define AREA_STR "Area"
-#define COUNTRY_STR "Country"
-#define NUMBER_STR "Number"
-
-typedef struct _HildonTelephoneEditorPriv HildonTelephoneEditorPriv;
-
-enum {
- PROP_0,
- PROP_COUNTRY_STR,
- PROP_AREA_STR,
- PROP_NUMBER_STR,
- PROP_SHOW_BORDER,
- PROP_SHOW_PLUS,
- PROP_FORMAT
-};
-
-/*< private >*/
-struct _HildonTelephoneEditorPriv {
- HildonTelephoneEditorFormat format; /* format of the editor */
-
- gboolean edited_country; /* is the country edited */
- gboolean edited_area; /* is the area edited */
- gboolean edited_number; /* is the number edited */
-
- gboolean editable_country; /* is the country editable */
- gboolean editable_area; /* is the area editable */
- gboolean editable_number; /* is the number editable */
-
- gboolean show_plus; /* show '+' sign in country */
- gboolean show_border; /* show border around the widget */
-
- GtkWidget *frame; /* frame for border lines */
- GtkWidget *plus; /* + in front of country code */
- GtkWidget *plus_event; /* event box for the + -label */
- GtkWidget *country; /* country code */
- GtkWidget *area; /* area code */
- GtkWidget *number; /* telephone number */
-
- gint j;
-};
-
-
-static GtkContainerClass *parent_class;
-
-static void
-hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
- editor_class);
-
-static void
-hildon_telephone_editor_init(HildonTelephoneEditor * editor);
-
-static void
-hildon_telephone_editor_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void
-hildon_telephone_editor_destroy(GtkObject * self);
-
-static void
-hildon_telephone_editor_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-
-static void
-hildon_telephone_editor_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-
-static gboolean
-hildon_telephone_editor_button_release(GtkWidget * widget,
- GdkEventButton * event,
- gpointer data);
-static void
-hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
- gboolean edited,
- gboolean move_left);
-static gboolean
-hildon_telephone_editor_entry_keypress(GtkWidget * widget,
- GdkEventKey * event, gpointer data);
-
-static gboolean
-hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
- gboolean group_cycling);
-
-static void
-hildon_telephone_editor_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void
-hildon_telephone_editor_get_property(GObject * object,
- guint prop_id,
- GValue * value, GParamSpec * pspec);
-
-GType hildon_telephone_editor_get_type(void)
-{
- static GType editor_type = 0;
-
- if (!editor_type) {
- static const GTypeInfo editor_info = {
- sizeof(HildonTelephoneEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_telephone_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonTelephoneEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_telephone_editor_init,
- };
- editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonTelephoneEditor",
- &editor_info, 0);
- }
- return editor_type;
-}
-
-static void
-hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
- editor_class)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
- GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
-
- parent_class = g_type_class_peek_parent(editor_class);
-
- g_type_class_add_private(editor_class, sizeof(HildonTelephoneEditorPriv));
-
- widget_class->size_request = hildon_telephone_editor_size_request;
- widget_class->size_allocate = hildon_telephone_editor_size_allocate;
- container_class->forall = hildon_telephone_editor_forall;
- widget_class->mnemonic_activate = hildon_telephone_editor_mnemonic_activate;
- widget_class->focus = hildon_composite_widget_focus;
- object_class->set_property = hildon_telephone_editor_set_property;
- object_class->get_property = hildon_telephone_editor_get_property;
-
- GTK_OBJECT_CLASS(editor_class)->destroy = hildon_telephone_editor_destroy;
-
- /* Install properties */
- g_object_class_install_property(object_class, PROP_COUNTRY_STR,
- g_param_spec_string("country",
- ("Country string"),
- ("Country string"),
- COUNTRY_STR, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_AREA_STR,
- g_param_spec_string("area",
- ("Area string"),
- ("Area string"),
- AREA_STR, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_NUMBER_STR,
- g_param_spec_string("number",
- ("Number string"),
- ("Number string"),
- NUMBER_STR, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_SHOW_BORDER,
- g_param_spec_boolean ("show-border",
- "Show Border",
- "Wether to show the border around the widget",
- TRUE, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_SHOW_PLUS,
- g_param_spec_boolean ("show-plus",
- "Show Plus",
- "Wether to show the plus sign in front of"
- " coerce format's country field",
- TRUE, G_PARAM_READWRITE));
-
- g_object_class_install_property(object_class, PROP_FORMAT,
- g_param_spec_int("set-format",
- ("Format"),
- ("Sets telephoneditor format"),
- HILDON_TELEPHONE_EDITOR_FORMAT_FREE,
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA,
- 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
-}
-
-static void
-hildon_telephone_editor_init(HildonTelephoneEditor * editor)
-{
- HildonTelephoneEditorPriv *priv;
- gboolean use_frames = FALSE; /* in entries, for debug purposes */
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- priv->frame = gtk_frame_new(NULL);
- priv->plus = gtk_label_new("+");
- priv->plus_event = gtk_event_box_new();
- priv->country = gtk_entry_new();
- priv->area = gtk_entry_new();
- priv->number = gtk_entry_new();
- priv->edited_country = FALSE;
- priv->edited_area = FALSE;
- priv->edited_number = FALSE;
- priv->show_plus = TRUE;
- priv->show_border = TRUE;
- priv->editable_country = TRUE;
- priv->editable_area = TRUE;
- priv->editable_number = TRUE;
-
- gtk_container_add(GTK_CONTAINER(priv->plus_event), priv->plus);
-
- gtk_entry_set_has_frame(GTK_ENTRY(priv->country), use_frames);
- gtk_entry_set_has_frame(GTK_ENTRY(priv->area), use_frames);
- gtk_entry_set_has_frame(GTK_ENTRY(priv->number), use_frames);
-
- gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
- gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
-
- hildon_telephone_editor_set_widths(editor, COUNTRY_LEN, AREA_LEN,
- NUMBER_LEN);
-
- /* set signals for country entry */
- gtk_signal_connect(GTK_OBJECT(priv->country), "button_release_event",
- G_CALLBACK(hildon_telephone_editor_button_release),
- editor);
-
- gtk_signal_connect(GTK_OBJECT(priv->country), "key-press-event",
- G_CALLBACK(hildon_telephone_editor_entry_keypress),
- editor);
-
- /* set signals for plus label */
- gtk_signal_connect(GTK_OBJECT(priv->plus_event), "button_press_event",
- G_CALLBACK(hildon_telephone_editor_button_release),
- editor);
-
- /* set signals for area entry */
- gtk_signal_connect(GTK_OBJECT(priv->area), "button_release_event",
- G_CALLBACK(hildon_telephone_editor_button_release),
- editor);
-
- gtk_signal_connect(GTK_OBJECT(priv->area), "key-press-event",
- G_CALLBACK(hildon_telephone_editor_entry_keypress),
- editor);
-
- /* set signals for number entry */
- gtk_signal_connect(GTK_OBJECT(priv->number), "button_release_event",
- G_CALLBACK(hildon_telephone_editor_button_release),
- editor);
-
- gtk_signal_connect(GTK_OBJECT(priv->number), "key-press-event",
- G_CALLBACK(hildon_telephone_editor_entry_keypress),
- editor);
-
- GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
-
- gtk_widget_show(priv->number);
- gtk_widget_show(priv->area);
- gtk_widget_show(priv->country);
- gtk_widget_show_all(priv->frame);
- gtk_widget_show_all(priv->plus_event);
-}
-
-/**
- * hildon_telephone_editor_new:
- * @format: format of the editor
- *
- * Creates a new #HildonTelephoneEditor. The editor can be in a free
- * format where the user can type in country code, area code and the
- * phone number and can type in other characters than just digits. In
- * coerse format the editor has fields where the user can input only
- * digits. See #HildonTelephoneEditorFormat for the different coerse
- * formats.
- *
- * Returns: new #HildonTelephoneEditor
- */
-GtkWidget *
-hildon_telephone_editor_new(HildonTelephoneEditorFormat format)
-{
-
- HildonTelephoneEditor *editor;
-
- editor =
- g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
- "set-country", _(COUNTRY_STR), "set-area",
- _(AREA_STR), "set-number", _(NUMBER_STR), NULL);
-
- return GTK_WIDGET(editor);
-}
-
-/**
- * hildon_telephone_editor_new_with_strings:
- * @format: format of the editor
- * @country: default text for the country field
- * @area: default text for the area field
- * @number: default text for the number field
- *
- * Creates a new #HildonTelephoneEditor. See hildon_telephone_editor_new
- * for details.
- *
- * Returns: new #HildonTelephoneEditor
- */
-GtkWidget *
-hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
- format,
- const gchar * country,
- const gchar * area,
- const gchar * number)
-{
- HildonTelephoneEditor *editor;
-
- editor =
- g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
- "set-country", country, "set-area", area,
- "set-number", number, NULL);
-
- return GTK_WIDGET(editor);
-}
-
-static void
-hildon_telephone_editor_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
-
- editor = HILDON_TELEPHONE_EDITOR (object);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
-
- switch (prop_id) {
- case PROP_COUNTRY_STR:
- g_value_set_string(value,
- hildon_telephone_editor_get_country(editor));
- break;
- case PROP_AREA_STR:
- g_value_set_string(value,
- hildon_telephone_editor_get_area(editor));
- break;
- case PROP_NUMBER_STR:
- g_value_set_string(value,
- hildon_telephone_editor_get_number(editor));
- break;
- case PROP_SHOW_BORDER:
- g_value_set_boolean(value,
- hildon_telephone_editor_get_show_border(editor));
- break;
- case PROP_SHOW_PLUS:
- g_value_set_boolean(value,
- hildon_telephone_editor_get_show_plus(editor));
- break;
- case PROP_FORMAT:
- g_value_set_int(value, priv->format);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_telephone_editor_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
-
- editor = HILDON_TELEPHONE_EDITOR (object);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
-
- switch (prop_id) {
- case PROP_COUNTRY_STR:
- hildon_telephone_editor_set_country(editor,
- _(g_value_get_string(value)));
- break;
- case PROP_AREA_STR:
- hildon_telephone_editor_set_area(editor,
- _(g_value_get_string(value)));
- break;
- case PROP_NUMBER_STR:
- hildon_telephone_editor_set_number(editor,
- _(g_value_get_string(value)));
- break;
- case PROP_SHOW_BORDER:
- hildon_telephone_editor_set_show_border(
- editor, g_value_get_boolean(value));
- break;
- case PROP_SHOW_PLUS:
- hildon_telephone_editor_set_show_plus(
- editor, g_value_get_boolean(value));
- break;
- case PROP_FORMAT:
- priv->format = g_value_get_int(value);
- if (priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- gtk_entry_set_text(GTK_ENTRY(priv->number), _(NUMBER_STR));
-
- /* set proper fields according to selected format */
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- gtk_widget_set_parent(priv->area, GTK_WIDGET(object));
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- gtk_widget_set_parent(priv->country, GTK_WIDGET(object));
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
- break;
- default:
- g_assert_not_reached();
- }
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
- gboolean group_cycling)
-{
- HildonTelephoneEditorPriv *priv;
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(widget);
-
- if (!GTK_CONTAINER(widget)->focus_child)
- {
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- {
- gtk_widget_grab_focus(priv->number);
-
- if (priv->editable_number && !priv->edited_number)
- gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
- }
- else
- {
- if (priv->editable_country)
- {
- gtk_widget_grab_focus(priv->country);
- if (!priv->edited_country)
- gtk_editable_select_region(GTK_EDITABLE(priv->country), 0, -1);
- }
- else if ((priv->editable_area) && (priv->format !=
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY))
- {
- gtk_widget_grab_focus(priv->area);
- if (!priv->edited_area)
- gtk_editable_select_region(GTK_EDITABLE(priv->area), 0, -1);
- }
- else if ((priv->editable_number) && (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE))
- {
- gtk_widget_grab_focus(priv->number);
- if (!priv->edited_number)
- gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
- }
- else
- gtk_widget_grab_focus(priv->country);
- }
- }
- return TRUE;
-}
-
-static void
-hildon_telephone_editor_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
-
- editor = HILDON_TELEPHONE_EDITOR(container);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- g_return_if_fail(container);
- g_return_if_fail(callback);
-
- if (!include_internals)
- return;
-
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- (*callback) (priv->number, callback_data);
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- (*callback) (priv->area, callback_data);
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- (*callback) (priv->country, callback_data);
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- (*callback) (priv->number, callback_data);
- break;
- default:
- g_return_if_reached();
- }
-
- if (priv->show_plus)
- (*callback) (priv->plus_event, callback_data);
-
- if (priv->show_border)
- (*callback) (priv->frame, callback_data);
-
-}
-
-static void
-hildon_telephone_editor_destroy(GtkObject * self)
-{
- HildonTelephoneEditorPriv *priv;
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(self);
-
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- if (priv->number) {
- gtk_widget_unparent(priv->number);
- priv->number = NULL;
- }
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- if (priv->area) {
- gtk_widget_unparent(priv->area);
- priv->area = NULL;
- }
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- if (priv->country) {
- gtk_widget_unparent(priv->country);
- priv->country = NULL;
- }
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- if (priv->number) {
- gtk_widget_unparent(priv->number);
- priv->number = NULL;
- }
- break;
- default:
- g_return_if_reached();
- }
-
- if (priv->plus_event) {
- gtk_widget_unparent(priv->plus_event);
- priv->plus_event = NULL;
- }
- if (priv->frame) {
- gtk_widget_unparent(priv->frame);
- priv->frame = NULL;
- }
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-static void
-hildon_telephone_editor_size_request(GtkWidget *widget,
- GtkRequisition *requisition)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
- GtkRequisition req;
-
- g_return_if_fail(requisition);
-
- editor = HILDON_TELEPHONE_EDITOR(widget);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- if (priv->show_border)
- gtk_widget_size_request(priv->frame, requisition);
-
- requisition->width = 0;
- requisition->height = 0;
-
- switch (priv->format)
- {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- gtk_widget_size_request(priv->number, &req);
- requisition->width += req.width;
- if (requisition->height < req.height)
- requisition->height = req.height;
-
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- gtk_widget_size_request(priv->area, &req);
- requisition->width += req.width;
- if (requisition->height < req.height)
- requisition->height = req.height;
-
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- gtk_widget_size_request(priv->country, &req);
- requisition->width += req.width;
- if (requisition->height < req.height)
- requisition->height = req.height;
-
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- gtk_widget_size_request(priv->number, &req);
- requisition->width += req.width;
- if (requisition->height < req.height)
- requisition->height = req.height;
-
- break;
- default:
- g_return_if_reached();
- }
-
- if (priv->show_plus)
- {
- gtk_widget_size_request(priv->plus_event, &req);
- requisition->width += req.width;
- if (requisition->height < req.height)
- requisition->height = req.height;
- }
-
- requisition->width += GTK_CONTAINER(priv->frame)->border_width * 2;
- requisition->height += GTK_CONTAINER(priv->frame)->border_width * 2;
-}
-
-static void
-hildon_telephone_editor_size_allocate(GtkWidget *widget,
- GtkAllocation *allocation)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
- gint header_x = 6, frame_w = 12;
- GtkAllocation alloc, country_alloc, area_alloc, number_alloc;
- GtkRequisition requisition, country_requisition, area_requisition,
- number_requisition;
-
- g_return_if_fail(widget);
- g_return_if_fail(allocation);
-
- if (allocation->height < 0 )
- allocation->height = 0;
-
- widget->allocation = *allocation;
-
- header_x += allocation->x;
- editor = HILDON_TELEPHONE_EDITOR(widget);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
-
- if (priv->show_plus &&
- priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE) {
- gtk_widget_get_child_requisition(priv->plus_event, &requisition);
-
- alloc.x = header_x;
- alloc.y = allocation->y + 1;
- alloc.width = requisition.width;
- alloc.height = requisition.height;
-
- header_x += alloc.width;
- gtk_widget_size_allocate(priv->plus_event, &alloc);
- frame_w += alloc.width;
- }
-
- gtk_widget_get_child_requisition(priv->number, &number_requisition);
-
- number_alloc.width = number_requisition.width;
-
- number_alloc.height = allocation->height - 4 -
- GTK_CONTAINER(priv->frame)->border_width * 2;
-
- /* get sizes */
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- gtk_widget_get_child_requisition(priv->area, &area_requisition);
-
- area_alloc.width = area_requisition.width;
- area_alloc.height = number_alloc.height;
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- gtk_widget_get_child_requisition(priv->country, &country_requisition);
-
- country_alloc.width = country_requisition.width;
- country_alloc.height = number_alloc.height;
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- break;
- default:
- g_return_if_reached();
- }
-
-
- /* allocate in coerce formats */
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- number_alloc.x = header_x + country_alloc.width + area_alloc.width;
- number_alloc.y = allocation->y + 1;
-
- gtk_widget_size_allocate(priv->number, &number_alloc);
- frame_w += number_alloc.width;
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- area_alloc.x = header_x + country_alloc.width;
- area_alloc.y = allocation->y + 1;
-
- gtk_widget_size_allocate(priv->area, &area_alloc);
- frame_w += area_alloc.width;
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- country_alloc.x = header_x;
- country_alloc.y = allocation->y + 1;
-
- gtk_widget_size_allocate(priv->country, &country_alloc);
- frame_w += country_alloc.width;
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- number_alloc.x = header_x;
- number_alloc.y = allocation->y + 1;
-
- gtk_widget_size_allocate(priv->number, &number_alloc);
- frame_w += number_alloc.width;
- break;
- default:
- g_return_if_reached();
- }
-
- if (priv->show_border)
- {
- alloc.x = allocation->x;
- alloc.y = allocation->y;
-
- alloc.width = frame_w - 4;
-
- alloc.height = allocation->height;
- gtk_widget_size_allocate( GTK_WIDGET(priv->frame), &alloc );
- }
-}
-
-static gboolean
-hildon_telephone_editor_button_release(GtkWidget * widget,
- GdkEventButton * event, gpointer data)
-{
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- return FALSE;
-}
-
-static void
-hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
- gboolean edited,
- gboolean move_left)
-{
- /* full coerse mode, wrap to field */
- gtk_widget_grab_focus(widget);
-
- if (move_left)
- gtk_editable_set_position(GTK_EDITABLE(widget), -1);
- else
- gtk_editable_set_position(GTK_EDITABLE(widget), 0);
- /* new field not yet edited, select all */
- if (!edited)
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
-}
-
-static gboolean
-hildon_telephone_editor_entry_keypress(GtkWidget * widget,
- GdkEventKey * event, gpointer data)
-{
- HildonTelephoneEditor *editor;
- HildonTelephoneEditorPriv *priv;
- gint pos, width;
- gint cpos, start, end;
-
- g_return_val_if_fail(widget, FALSE);
- g_return_val_if_fail(event, FALSE);
- g_return_val_if_fail(data, FALSE);
-
- editor = HILDON_TELEPHONE_EDITOR(data);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
- cpos = gtk_editable_get_position(GTK_EDITABLE(widget));
- gtk_editable_get_selection_bounds(GTK_EDITABLE(widget), &start, &end);
-
- if( event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
- event->keyval == GDK_Down || event->keyval == GDK_KP_Down )
- return FALSE;
-
- /* Wrap around should not happen; that's why following code */
- switch (priv->format) {
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
- if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
- (widget == priv->country) && ((cpos == 0) ||
- ((start == 0 && end == strlen(GTK_ENTRY(priv->country)->text)))))
- ||
- ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
- && (widget == priv->number)
- && (cpos >= strlen(GTK_ENTRY(priv->number)->text))))
- return TRUE;
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
- if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
- (widget == priv->country) && ((cpos == 0) ||
- ((start == 0
- && end ==
- strlen(GTK_ENTRY
- (priv->country)->
- text)))))
- ||
- ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
- && (widget == priv->area)
- && (cpos >= strlen(GTK_ENTRY(priv->area)->text))))
- return TRUE;
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
- break;
- case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
- break;
- }
-
- /* valid key pressed */
- if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left ||
- event->keyval == GDK_Right || event->keyval == GDK_KP_Right ||
- event->keyval == GDK_BackSpace || event->keyval == GDK_Delete ||
- event->keyval == GDK_KP_Delete ||
- (event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
- (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
- (event->keyval == GDK_slash || event->keyval == GDK_space ||
- event->keyval == GDK_parenleft || event->keyval == GDK_parenright
- || event->keyval == GDK_period || event->keyval == GDK_hyphen
- || event->keyval == GDK_plus || event->keyval == GDK_asterisk
- || event->keyval == GDK_KP_Multiply
- || event->keyval == GDK_KP_Add || event->keyval == GDK_numbersign
- || event->keyval == GDK_question || event->keyval == GDK_KP_Subtract
- || event->keyval == GDK_minus)))
- {
- if ((event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
- (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
- (event->keyval == GDK_slash || event->keyval == GDK_space ||
- event->keyval == GDK_parenleft ||
- event->keyval == GDK_parenright ||
- event->keyval == GDK_period || event->keyval == GDK_hyphen ||
- event->keyval == GDK_plus || event->keyval == GDK_asterisk ||
- event->keyval == GDK_KP_Add ||
- event->keyval == GDK_KP_Multiply ||
- event->keyval == GDK_numbersign ||
- event->keyval == GDK_question ||
- event->keyval == GDK_KP_Subtract ||
- event->keyval == GDK_minus)))
- {
- if (widget == priv->country)
- priv->edited_country = TRUE;
- if (widget == priv->area)
- priv->edited_area = TRUE;
- if (widget == priv->number)
- priv->edited_number = TRUE;
- }
-
- pos = gtk_editable_get_position(GTK_EDITABLE(widget));
-
- /* going left */
- if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) {
- /* not yet on the left edge and the widget is edited */
- if (pos != 0 &&
- ((widget == priv->country && priv->edited_country == TRUE)
- || (widget == priv->area && priv->edited_area == TRUE)
- || (widget == priv->number
- && priv->edited_number == TRUE)))
- return FALSE;
-
- /* left edge of number field */
- if (widget == priv->number) {
- /* Stop signal handler, if only number field exists */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return TRUE;
- else {
- /* Grab the focus to the area field, if it is editable
- */
- if (priv->editable_area) {
- hildon_telephone_editor_focus_dest_entry
- (priv->area, priv->edited_area, TRUE);
- }
- /* Grab the focus to the country field, if it is
- editable */
- else if (priv->editable_country) {
- hildon_telephone_editor_focus_dest_entry
- (priv->country, priv->edited_country, TRUE);
- } else
- return TRUE;
- }
- }
-
- /* left edge of area field */
- if (widget == priv->area) { /* grab the focus to the country
- field, if it is editable */
- if (priv->editable_country) {
- hildon_telephone_editor_focus_dest_entry
- (priv->country, priv->edited_country, TRUE);
- } else
- return TRUE;
- }
-
- /* left edge of country field, let's wrap */
- if (widget == priv->country) {
- /* Stop the signal handler, if only country field exists */
- if (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
- return TRUE;
- /* wrap to area, if in AREA mode */
- else if (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
- hildon_telephone_editor_focus_dest_entry
- (priv->area, priv->edited_area, TRUE);
- }
-
- else {
- hildon_telephone_editor_focus_dest_entry
- (priv->number, priv->edited_number, TRUE);
- }
- }
- }
- /* going right */
- else if (event->keyval == GDK_Right || event->keyval == GDK_KP_Right) {
- width = g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1);
-
- /* not yet on the rigth edge and the widget is edited */
- if (pos != width &&
- ((widget == priv->country && priv->edited_country == TRUE)
- || (widget == priv->area && priv->edited_area == TRUE)
- || (widget == priv->number
- && priv->edited_number == TRUE)))
- return FALSE;
-
- /* rigth edge of number field */
- if (widget == priv->number) {
- /* Stop signal handler, if only number field exists */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return TRUE;
- else {
- hildon_telephone_editor_focus_dest_entry
- (priv->country, priv->edited_country, FALSE);
- }
- }
-
- /* rigth edge of area field */
- if (widget == priv->area) {
- /* area mode, wrap to country field */
- if (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
- hildon_telephone_editor_focus_dest_entry
- (priv->country, priv->edited_country, FALSE);
- }
- /* grab the focus to the number field, if it is editable */
- else if (priv->editable_number) {
- hildon_telephone_editor_focus_dest_entry
- (priv->number, priv->edited_number, FALSE);
- } else
- return TRUE;
- }
-
- /* rigth edge of country field */
- if (widget == priv->country) {
- /* wrap around, if only country field exists */
- if (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
- return TRUE;
-
- /* area mode, move to area field */
- else if (priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA ||
- priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) {
- /* grab the focus to the area field, if it is editable
- */
- if (priv->editable_area) {
- hildon_telephone_editor_focus_dest_entry
- (priv->area, priv->edited_area, FALSE);
- }
- /* grab the focus to the area field, if it is editable
- */
- else if ((priv->format ==
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) &&
- priv->editable_number) {
- hildon_telephone_editor_focus_dest_entry
- (priv->number, priv->edited_number, FALSE);
- } else
- return TRUE;
- }
-
- else {
- hildon_telephone_editor_focus_dest_entry
- (priv->number, priv->edited_number, FALSE);
- }
- }
- }
- return FALSE;
- }
- return TRUE;
-}
-
-/**
- * hildon_telephone_editor_set_editable:
- * @hte: #HildonTelephoneEditor
- * @country: set the editable status of the country field in coarce format
- * @area: set the editable status of the area field in coarce format
- * @number: set the editable status of the number field in coarce format
- *
- * Specify wheter the fields in coerse format are editable or
- * not. This function is ignored if the editor is in free mode. The
- * number or area and number parameters are ignored if the editor is
- * in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY formats,
- * respectively.
- */
-void
-hildon_telephone_editor_set_editable(HildonTelephoneEditor * editor,
- gboolean country,
- gboolean area, gboolean number)
-{
- HildonTelephoneEditorPriv *priv;
-
- g_return_if_fail(editor);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- priv->editable_country = country;
- priv->editable_area = area;
- priv->editable_number = number;
-
- if (priv->country)
- {
- gtk_editable_set_editable(GTK_EDITABLE(priv->country), country);
- gtk_widget_set_sensitive(GTK_WIDGET(priv->plus), country);
- }
-
- if (priv->area)
- gtk_editable_set_editable(GTK_EDITABLE(priv->area), area);
-
- if (priv->number)
- gtk_editable_set_editable(GTK_EDITABLE(priv->number), number);
-}
-
-/**
- * hildon_telephone_editor_set_widths:
- * @hte: #HildonTelephoneEditor
- * @country: width (characters) of the country field in coarce mode
- * @area: width (characters) of the area field in coarce mode
- * @number: width (characters) of the number field in coarce mode
- *
- * Set widths of the fields in coecse format. Country and area parameters
- * are ignored, if the editor is in free mode. The number or area and number
- * parameters are ignored if the editor is in
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode, respectively.
- */
-void
-hildon_telephone_editor_set_widths(HildonTelephoneEditor * editor,
- guint country,
- guint area, guint number)
-{
- HildonTelephoneEditorPriv *priv;
-
- g_return_if_fail(editor);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- if (priv->country) {
- /*gtk_entry_set_max_length(GTK_ENTRY(priv->country), country);*/
- gtk_entry_set_width_chars(GTK_ENTRY(priv->country), country);
- }
-
- if (priv->area) {
- /*gtk_entry_set_max_length(GTK_ENTRY(priv->area), area);*/
- gtk_entry_set_width_chars(GTK_ENTRY(priv->area), area);
- }
-
- if (priv->number) {
- /*gtk_entry_set_max_length(GTK_ENTRY(priv->number), number);*/
- gtk_entry_set_width_chars(GTK_ENTRY(priv->number), number);
- }
-
-}
-
-/**
- * hildon_telephone_editor_set_show_plus:
- * @hte: #HildonTelephoneEditor
- * @show: show the plus sign
- *
- * Show or hide the plus sign in front of coerce format's country field.
- */
-void
-hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * editor,
- gboolean show)
-{
- HildonTelephoneEditorPriv *priv;
-
- g_return_if_fail(editor);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* do nothing in FREE format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return;
-
- if (show && !priv->show_plus) {
- priv->show_plus = TRUE;
- gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
- gtk_widget_show(priv->plus_event);
- } else if (!show && priv->show_plus) {
- gtk_widget_hide(priv->plus_event);
- gtk_widget_unparent(priv->plus_event);
- priv->show_plus = FALSE;
- }
-}
-
-/**
- * hildon_telephone_editor_get_show_plus:
- * @hte: #HildonTelephoneEditor
- *
- * Get the visibility status of the plus sign in
- * front of coerce format's country field.
- *
- * Returns: gboolean
- */
-gboolean
-hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
- editor)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_val_if_fail(editor, FALSE);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* no plus in FREE format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return FALSE;
- return priv->show_plus;
-}
-
-/**
- * hildon_telephone_editor_set_show_border:
- * @hte: #HildonTelephoneEditor
- * @show: show the border
- *
- * Show or hide the border around the widget
- */
-void
-hildon_telephone_editor_set_show_border(HildonTelephoneEditor *
- editor, gboolean show)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_if_fail(editor);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- if (show && !priv->show_border) {
- priv->show_border = TRUE;
- gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
- gtk_widget_show(priv->frame);
- } else if (!show && priv->show_border) {
- gtk_widget_hide(priv->frame);
- gtk_widget_unparent(priv->frame);
- priv->show_border = FALSE;
- }
-}
-
-/**
- * hildon_telephone_editor_get_show_border:
- * @hte: #HildonTelephoneEditor
- *
- * Get the visibility status of the border around the widget.
- *
- * Returns: gboolean
- */
-gboolean
-hildon_telephone_editor_get_show_border(HildonTelephoneEditor * editor)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_val_if_fail(editor, FALSE);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- return priv->show_border;
-}
-
-/**
- * hildon_telephone_editor_get_country:
- * @hte: #HildonTelephoneEditor
- *
- * Get text in the country field in coarse format. This function must
- * not be called if in free mode.
- *
- * Returns: pointer to the text in the country field. It must not
- * be changed or freed.
- */
-const gchar *
-hildon_telephone_editor_get_country(HildonTelephoneEditor *
- editor)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_val_if_fail(editor, NULL);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* return NULL if in FREE format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return NULL;
-
- return gtk_entry_get_text(GTK_ENTRY(priv->country));
-}
-
-/**
- * hildon_telephone_editor_set_country:
- * @hte: #HildonTelephoneEditor
- * @country: text to be set in country field
- *
- * Set text in the country field in coarse format. This function must
- * not be called if in free mode.
- */
-void
-hildon_telephone_editor_set_country(HildonTelephoneEditor * editor,
- const gchar * country)
-{
- HildonTelephoneEditorPriv *priv;
- const gchar *p;
- gunichar u;
-
- g_return_if_fail(editor);
- g_return_if_fail(country);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* do nothing in FREE format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return;
-
- if (!priv->country)
- return;
-
- p = country;
- g_return_if_fail(g_utf8_validate(p, -1, NULL));
-
- /* allow only digits */
- do {
- u = g_utf8_get_char(p);
- if (!g_unichar_isdigit(*p))
- return;
-
- p = g_utf8_next_char(p);
- } while (*p);
-
- gtk_entry_set_text(GTK_ENTRY(priv->country), country);
-}
-
-/**
- * hildon_telephone_editor_get_area:
- * @hte: #HildonTelephoneEditor
- *
- * Get text in the area field in coarse format. This function must not
- * be called if in free mode or in
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
- *
- * Returns: pointer to the text in the area field. It must not be
- * changed or freed.
- */
-const gchar *
-hildon_telephone_editor_get_area(HildonTelephoneEditor *
- editor)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_val_if_fail(editor, NULL);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* return NULL if in FREE format or if in COERCE_COUNTRY format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return NULL;
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
- return NULL;
-
- return gtk_entry_get_text(GTK_ENTRY(priv->area));
-}
-
-/**
- * hildon_telephone_editor_set_area:
- * @hte: #HildonTelephoneEditor
- * @area: text to be set in area field
- *
- * Set text in the area field in coarse format. This function must not
- * be called if in free mode or in
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
- */
-void
-hildon_telephone_editor_set_area(HildonTelephoneEditor * editor,
- const gchar * area)
-{
- HildonTelephoneEditorPriv *priv;
- const gchar *p;
- gunichar u;
-
- g_return_if_fail(editor);
- g_return_if_fail(area);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- /* do nothing in FREE format */
- if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
- return;
-
- if (!priv->area)
- return;
-
- p = area;
- g_return_if_fail(g_utf8_validate(p, -1, NULL));
-
- /* allow only digits */
- do {
- u = g_utf8_get_char(p);
- if (!g_unichar_isdigit(u))
- return;
-
- p = g_utf8_next_char(p);
- } while (*p);
-
- gtk_entry_set_text(GTK_ENTRY(priv->area), area);
-}
-
-/**
- * hildon_telephone_editor_get_number:
- * @hte: #HildonTelephoneEditor
- *
- * Get text in the number field in all formats. In free mode, this
- * functions returns the whole phone number. In coarce mode, it returns
- * only the number field. This function must not be called if
- * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
- *
- * Returns: pointer to text in the number field. It must not be
- * changed or freed.
- */
-const gchar *
-hildon_telephone_editor_get_number(HildonTelephoneEditor *
- editor)
-{
- HildonTelephoneEditorPriv *priv;
- g_return_val_if_fail(editor, NULL);
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- return gtk_entry_get_text(GTK_ENTRY(priv->number));
-}
-
-/**
- * hildon_telephone_editor_set_number:
- * @hte: #HildonTelephoneEditor
- * @number: text to be set to number field
- *
- * Set text in the number field in all formats. In free mode this
- * functions sets the whole phone number. In coerce mode, it sets
- * only the number field. This function must not be called if
- * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERSE_AREA or
- * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
- */
-void
-hildon_telephone_editor_set_number(HildonTelephoneEditor * editor,
- const gchar * number)
-{
- HildonTelephoneEditorPriv *priv;
- const gchar *p;
- gunichar u;
-
- g_return_if_fail(editor);
- g_return_if_fail(number);
-
- priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
-
- if (!priv->number)
- return;
-
- p = number;
- g_return_if_fail(g_utf8_validate(p, -1, NULL));
-
- /* allow only digits in coerce format or some other in free format */
- do {
- u = g_utf8_get_char(p);
- if (g_unichar_isdigit(u) ||
- (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
- (u == '+' ||
- u == 'p' ||
- u == 'w' ||
- u == '(' ||
- u == ')' ||
- u == '/' ||
- u == ' ' ||
- u == '.' || u == '-' || u == '*' || u == '#' || u == '?')))
- p = g_utf8_next_char(p);
- else
- return;
-
- } while (*p);
-
- gtk_entry_set_text(GTK_ENTRY(priv->number), number);
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_TELEPHONE_EDITOR_H__
-#define __HILDON_TELEPHONE_EDITOR_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-/**
- * HILDON_TELEPHONE_EDITOR_TYPE:
- *
- * Macro for getting type of telephone editor.
- */
-#define HILDON_TELEPHONE_EDITOR_TYPE \
- ( hildon_telephone_editor_get_type() )
-#define HILDON_TELEPHONE_EDITOR(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TELEPHONE_EDITOR_TYPE, \
- HildonTelephoneEditor))
-#define HILDON_TELEPHONE_EDITOR_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), HILDON_TELEPHONE_EDITOR_TYPE, \
- HildonTelephoneEditorClass))
-#define HILDON_IS_TELEPHONE_EDITOR(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TELEPHONE_EDITOR_TYPE))
-#define HILDON_IS_TELEPHONE_EDITOR_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TELEPHONE_EDITOR_TYPE))
-/**
- * HildonTelephoneEditorFormat:
- * @HILDON_TELEPHONE_EDITOR_FORMAT_FREE: Free format.
- * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE: Coerce format, three fields.
- * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY: Coerce format, only
- * country field.
- * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA: Coerce format, country
- * and area fields.
- *
- * Define all possible format modes for the HildonTelephoneEditor.
- *
- */
- typedef enum {
- HILDON_TELEPHONE_EDITOR_FORMAT_FREE = 0,
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE,
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY,
- HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA
-} HildonTelephoneEditorFormat;
-
-
-/**
- * HildonTelephoneEditor:
- *
- * Internal struct for telephone editor.
- */
-typedef struct _HildonTelephoneEditor HildonTelephoneEditor;
-typedef struct _HildonTelephoneEditorClass HildonTelephoneEditorClass;
-
-/*< private >*/
-struct _HildonTelephoneEditor {
- GtkContainer parent;
-};
-
-struct _HildonTelephoneEditorClass {
- GtkContainerClass parent_class;
-};
-
-GType hildon_telephone_editor_get_type(void);
-
-GtkWidget *hildon_telephone_editor_new(HildonTelephoneEditorFormat format);
-GtkWidget
- *hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
- format,
- const gchar * country,
- const gchar * area,
- const gchar * number);
-void hildon_telephone_editor_set_editable(HildonTelephoneEditor * hte,
- gboolean country, gboolean area,
- gboolean number);
-
-void hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * hte,
- gboolean show);
-
-gboolean hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
- hte);
-
-void hildon_telephone_editor_set_show_border(HildonTelephoneEditor * hte,
- gboolean show);
-
-gboolean hildon_telephone_editor_get_show_border(HildonTelephoneEditor *
- hte);
-
-
-void hildon_telephone_editor_set_widths(HildonTelephoneEditor * hte,
- guint country,
- guint area, guint number);
-
-const gchar *hildon_telephone_editor_get_country(HildonTelephoneEditor *
- hte);
-
-void hildon_telephone_editor_set_country(HildonTelephoneEditor * hte,
- const gchar * country);
-
-const gchar *hildon_telephone_editor_get_area(HildonTelephoneEditor * hte);
-
-void hildon_telephone_editor_set_area(HildonTelephoneEditor * hte,
- const gchar * area);
-
-const gchar *hildon_telephone_editor_get_number(HildonTelephoneEditor *
- hte);
-
-void hildon_telephone_editor_set_number(HildonTelephoneEditor * hte,
- const gchar * number);
-
-G_END_DECLS
-#endif /* __HILDON_TELEPHONE_EDITOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-time-editor
- * @short_description: A widget used to enter time or duration in hours, minutes,
- * and optional seconds
- * @see_also: #HildonTimePicker
- *
- * HildonTimeEditor is used to edit time or duration. Time mode is
- * restricted to normal 24 hour cycle, but Duration mode can select any
- * amount of time up to 99 hours. It consists of entries for hours,
- * minutes and seconds, and pm/am indicator as well as a button which
- * popups a #HildonTimePicker dialog.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtkbutton.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkframe.h>
-#include <gdk/gdkkeysyms.h>
-
-#include <string.h>
-#include <time.h>
-#include <stdlib.h>
-#include <langinfo.h>
-#include <libintl.h>
-
-#include <hildon-widgets/hildon-defines.h>
-#include <hildon-widgets/hildon-time-editor.h>
-#include <hildon-widgets/hildon-time-picker.h>
-#include <hildon-widgets/hildon-banner.h>
-#include <hildon-widgets/hildon-input-mode-hint.h>
-#include <hildon-widgets/hildon-private.h>
-#include "hildon-composite-widget.h"
-#include "hildon-marshalers.h"
-#include "hildon-libs-enum-types.h"
-
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_TIME_EDITOR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_TIME_EDITOR, HildonTimeEditorPrivate));
-
-#define TICKS(h,m,s) ((h) * 3600 + (m) * 60 + (s))
-
-#define TIME_EDITOR_HEIGHT 30
-#define ICON_PRESSED 4
-#define ICON_NAME "qgn_widg_timedit"
-#define ICON_SIZE "timepicker-size"
-#define MIN_DURATION 0
-#define MAX_DURATION TICKS(99, 59, 59)
-
-/* Default values for properties */
-#define HILDON_TIME_EDITOR_TICKS_VALUE 0
-#define HILDON_TIME_EDITOR_DURATION_MODE FALSE
-#define HILDON_TIME_EDITOR_DURATION_LOWER_VALUE 0
-#define HILDON_TIME_EDITOR_DURATION_UPPER_VALUE TICKS(99, 59, 59)
-
-#define HOURS_MAX_24 23
-#define HOURS_MAX_12 12
-#define HOURS_MIN_24 0
-#define HOURS_MIN_12 1
-#define MINUTES_MAX 59
-#define SECONDS_MAX 59
-#define MINUTES_MIN 0
-#define SECONDS_MIN 0
-
-static GtkContainerClass *parent_class;
-
-typedef struct _HildonTimeEditorPrivate HildonTimeEditorPrivate;
-
-enum
-{
- PROP_TICKS = 1,
- PROP_DURATION_MODE,
- PROP_DURATION_MIN,
- PROP_DURATION_MAX,
- PROP_SHOW_SECONDS,
- PROP_SHOW_HOURS
-};
-
-/* Indices for h/m/s entries in priv->entries */
-enum {
- ENTRY_HOURS,
- ENTRY_MINS,
- ENTRY_SECS,
-
- ENTRY_COUNT
-};
-
-/* Signals */
-enum {
- TIME_ERROR,
- LAST_SIGNAL
-};
-
-/* Error codes categories */
-enum {
- MAX_VALUE,
- MIN_VALUE,
- WITHIN_RANGE,
- NUM_ERROR_CODES
-};
-
-static guint time_editor_signals[LAST_SIGNAL] = { 0 };
-static guint hour_errors[NUM_ERROR_CODES] = { MAX_HOURS, MIN_HOURS, EMPTY_HOURS };
-static guint min_errors[NUM_ERROR_CODES] = { MAX_MINS, MIN_MINS, EMPTY_MINS };
-static guint sec_errors[NUM_ERROR_CODES] = { MAX_SECS, MIN_SECS, EMPTY_SECS };
-
-struct _HildonTimeEditorPrivate {
- guint ticks; /* Current duration in seconds */
-
- gchar *am_symbol;
- gchar *pm_symbol;
-
- GtkWidget *iconbutton; /* button for icon */
-
- GtkWidget *frame; /* frame around the entries */
- GtkWidget *entries[ENTRY_COUNT]; /* h, m, s entries */
- GtkWidget *hm_label; /* between hour and minute */
- GtkWidget *sec_label; /* between minute and second */
- GtkWidget *ampm_label; /* label for showing am or pm */
-
- GtkWidget *error_widget; /* field to highlight in idle */
- GtkWidget *ampm_button; /* am/pm change button */
-
-
- gboolean duration_mode; /* In HildonDurationEditor mode */
- gboolean show_seconds; /* show seconds */
- gboolean show_hours; /* show hours */
-
- gboolean ampm_pos_after; /* is am/pm shown after others */
- gboolean clock_24h; /* whether to show a 24h clock */
- gboolean am; /* TRUE == am, FALSE == pm */
-
- guint duration_min; /* duration editor ranges */
- guint duration_max; /* duration editor ranges */
-
- guint highlight_idle;
- gboolean skipper; /* FIXME (MDK): To prevent us from looping inside the validation events.
- When set to TRUE further validations (that can happen from-inside other validations)
- are being skipped. Nasty hack to cope with a bad design. */
-};
-
-/***
- * Widget functions
- */
-
-static void hildon_time_editor_class_init (HildonTimeEditorClass *editor_class);
-static void hildon_time_editor_init (HildonTimeEditor *editor);
-
-static void hildon_time_editor_finalize (GObject *obj_self);
-
-static void hildon_time_editor_set_property(GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void hildon_time_editor_get_property(GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void hildon_time_editor_forall(GtkContainer *container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-
-static void hildon_time_editor_destroy(GtkObject * self);
-
-/***
- * Signal handlers
- */
-
-static gboolean hildon_time_editor_entry_focusout(GtkWidget *widget,
- GdkEventFocus *event,
- gpointer data);
-
-static gboolean hildon_time_editor_entry_focusin(GtkWidget *widget,
- GdkEventFocus *event,
- gpointer data);
-
-static gboolean hildon_time_editor_time_error(HildonTimeEditor *editor,
- HildonTimeEditorErrorType type);
-
-static gboolean hildon_time_editor_ampm_clicked(GtkWidget *widget,
- gpointer data);
-
-static gboolean hildon_time_editor_icon_clicked(GtkWidget *widget,
- gpointer data);
-
-static void hildon_time_editor_size_request(GtkWidget *widget,
- GtkRequisition *requisition);
-
-static void hildon_time_editor_size_allocate(GtkWidget *widget,
- GtkAllocation *allocation);
-
-static gboolean hildon_time_editor_entry_keypress(GtkWidget *widget,
- GdkEventKey *event,
- gpointer data);
-
-/***
- * Internal functions
- */
-
-static gboolean hildon_time_editor_check_locale(HildonTimeEditor * editor);
-
-static
-void hildon_time_editor_tap_and_hold_setup(GtkWidget * widget,
- GtkWidget * menu,
- GtkCallback func,
- GtkWidgetTapAndHoldFlags flags);
-static void
-hildon_time_editor_validate (HildonTimeEditor *editor, gboolean allow_intermediate);
-
-static void hildon_time_editor_set_to_current_time (HildonTimeEditor * editor);
-
-static gboolean
-_hildon_time_editor_entry_select_all(GtkWidget *widget);
-
-
-/***
- * Utility functions
- */
-
-static void convert_to_12h (guint *h, gboolean *am);
-static void convert_to_24h (guint *h, gboolean am);
-
-static void ticks_to_time (guint ticks,
- guint *hours,
- guint *minutes,
- guint *seconds);
-
-static void
-hildon_time_editor_inserted_text (GtkEditable * editable,
- gchar * new_text,
- gint new_text_length,
- gint * position,
- gpointer user_data);
-
-GType hildon_time_editor_get_type(void)
-{
- static GType editor_type = 0;
-
- if (!editor_type) {
- static const GTypeInfo editor_info = {
- sizeof(HildonTimeEditorClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_time_editor_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonTimeEditor),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_time_editor_init,
- };
- editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonTimeEditor",
- &editor_info, 0);
- }
- return editor_type;
-}
-
-static void hildon_time_editor_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data)
-{
- HildonTimeEditor *editor;
- HildonTimeEditorPrivate *priv;
-
- g_assert(HILDON_IS_TIME_EDITOR(container));
- g_assert(callback != NULL);
-
- editor = HILDON_TIME_EDITOR(container);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if (!include_internals)
- return;
-
- /* widget that are always shown */
- (*callback) (priv->iconbutton, callback_data);
- (*callback) (priv->frame, callback_data);
-}
-
-static void hildon_time_editor_destroy(GtkObject * self)
-{
- HildonTimeEditorPrivate *priv;
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(self);
-
- if (priv->iconbutton) {
- gtk_widget_unparent(priv->iconbutton);
- priv->iconbutton = NULL;
- }
- if (priv->frame) {
- gtk_widget_unparent(priv->frame);
- priv->frame = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-
-}
-
-static void
-hildon_time_editor_class_init(HildonTimeEditorClass * editor_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
-
- parent_class = g_type_class_peek_parent(editor_class);
-
- g_type_class_add_private(editor_class,
- sizeof(HildonTimeEditorPrivate));
-
- object_class->get_property = hildon_time_editor_get_property;
- object_class->set_property = hildon_time_editor_set_property;
- widget_class->size_request = hildon_time_editor_size_request;
- widget_class->size_allocate = hildon_time_editor_size_allocate;
- widget_class->tap_and_hold_setup =
- hildon_time_editor_tap_and_hold_setup;
- widget_class->focus = hildon_composite_widget_focus;
-
- container_class->forall = hildon_time_editor_forall;
- GTK_OBJECT_CLASS(editor_class)->destroy = hildon_time_editor_destroy;
-
- object_class->finalize = hildon_time_editor_finalize;
-
- editor_class->time_error = hildon_time_editor_time_error;
-
- time_editor_signals[TIME_ERROR] =
- g_signal_new("time-error",
- G_OBJECT_CLASS_TYPE(object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(HildonTimeEditorClass, time_error),
- g_signal_accumulator_true_handled, NULL,
- _hildon_marshal_BOOLEAN__ENUM,
- G_TYPE_BOOLEAN, 1, HILDON_TYPE_TIME_EDITOR_ERROR_TYPE);
-
- /**
- * HildonTimeEditor:ticks:
- *
- * If editor is in duration mode, contains the duration seconds.
- * If not, contains seconds since midnight.
- */
- g_object_class_install_property( object_class, PROP_TICKS,
- g_param_spec_uint("ticks",
- "Duration value",
- "Current value of duration",
- 0, G_MAXUINT,
- HILDON_TIME_EDITOR_TICKS_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonTimeEditor:show_seconds:
- *
- * Controls whether seconds are shown in the editor
- */
- g_object_class_install_property( object_class, PROP_SHOW_SECONDS,
- g_param_spec_boolean("show_seconds",
- "Show seconds property",
- "Controls whether the seconds are shown in the editor",
- FALSE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonTimeEditor:show_hours:
- *
- * Controls whether hours are shown in the editor
- */
- g_object_class_install_property( object_class, PROP_SHOW_HOURS,
- g_param_spec_boolean("show_hours",
- "Show hours field",
- "Controls whether the hours field is shown in the editor",
- TRUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonTimeEditor:duration_mode:
- *
- * Controls whether the TimeEditor is in duration mode
- */
- g_object_class_install_property( object_class, PROP_DURATION_MODE,
- g_param_spec_boolean("duration_mode",
- "Duration mode",
- "Controls whether the TimeEditor is in duration mode",
- HILDON_TIME_EDITOR_DURATION_MODE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonTimeEditor:duration_min:
- *
- * Minimum allowed duration value.
- */
- g_object_class_install_property( object_class, PROP_DURATION_MIN,
- g_param_spec_uint("duration_min",
- "Minumum duration value",
- "Smallest possible duration value",
- MIN_DURATION, MAX_DURATION,
- HILDON_TIME_EDITOR_DURATION_LOWER_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- /**
- * HildonTimeEditor:duration_max:
- *
- * Maximum allowed duration value.
- */
- g_object_class_install_property( object_class, PROP_DURATION_MAX,
- g_param_spec_uint("duration_max",
- "Maximum duration value",
- "Largest possible duration value",
- 0, G_MAXUINT,
- HILDON_TIME_EDITOR_DURATION_UPPER_VALUE,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-}
-
-static
-void hildon_time_editor_tap_and_hold_setup(GtkWidget * widget,
- GtkWidget * menu,
- GtkCallback func,
- GtkWidgetTapAndHoldFlags flags)
-{
- HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(widget);
- gint i;
-
- /* Forward this tap_and_hold_setup signal to all our child widgets */
- for (i = 0; i < ENTRY_COUNT; i++)
- {
- gtk_widget_tap_and_hold_setup(priv->entries[i], menu, func,
- GTK_TAP_AND_HOLD_NO_SIGNALS);
- }
- gtk_widget_tap_and_hold_setup(priv->ampm_button, menu, func,
- GTK_TAP_AND_HOLD_NO_SIGNALS);
- gtk_widget_tap_and_hold_setup(priv->iconbutton, menu, func,
- GTK_TAP_AND_HOLD_NONE);
-}
-
-static void hildon_time_editor_entry_changed(GtkWidget *widget, gpointer data)
-{
- g_assert(HILDON_IS_TIME_EDITOR(data));
- hildon_time_editor_validate(HILDON_TIME_EDITOR(data), TRUE);
-}
-
-static void hildon_time_editor_init(HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
- GtkWidget *hbox, *icon;
- gint i;
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- gtk_widget_push_composite_child();
-
- /* Setup defaults and create widgets */
- priv->ticks = 0;
- priv->show_seconds = FALSE;
- priv->show_hours = TRUE;
- priv->ampm_pos_after = TRUE;
- priv->clock_24h = TRUE;
- priv->duration_mode = FALSE;
- priv->iconbutton = gtk_button_new();
- priv->ampm_label = gtk_label_new(NULL);
- priv->hm_label = gtk_label_new(NULL);
- priv->sec_label = gtk_label_new(NULL);
- priv->frame = gtk_frame_new(NULL);
- priv->ampm_button = gtk_button_new();
- priv->skipper = FALSE;
-
- icon = gtk_image_new_from_icon_name(ICON_NAME, HILDON_ICON_SIZE_WIDG);
- hbox = gtk_hbox_new(FALSE, 0);
-
- GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
- GTK_WIDGET_UNSET_FLAGS(priv->iconbutton, GTK_CAN_FOCUS | GTK_CAN_DEFAULT);
-
- gtk_container_set_border_width(GTK_CONTAINER(priv->frame), 0);
-
- gtk_container_add(GTK_CONTAINER(priv->iconbutton), icon);
- gtk_container_add(GTK_CONTAINER(priv->ampm_button), priv->ampm_label);
- gtk_button_set_relief(GTK_BUTTON(priv->ampm_button), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click(GTK_BUTTON(priv->ampm_button), FALSE);
-
- /* Create hour, minute and second entries */
- for (i = 0; i < ENTRY_COUNT; i++)
- {
- priv->entries[i] = gtk_entry_new();
-
- /* No frames for entries, so that they all appear to be inside one long entry */
- gtk_entry_set_has_frame(GTK_ENTRY(priv->entries[i]), FALSE);
-
- /* Set the entries to accept only numeric characters */
- g_object_set (priv->entries[i], "input-mode",
- HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
-
- /* The entry fields all take exactly two characters */
- gtk_entry_set_max_length (GTK_ENTRY(priv->entries[i]), 2);
- gtk_entry_set_width_chars (GTK_ENTRY(priv->entries[i]), 2);
-
- g_signal_connect(priv->entries[i], "focus-in-event",
- G_CALLBACK(hildon_time_editor_entry_focusin), editor);
- g_signal_connect(priv->entries[i], "focus-out-event",
- G_CALLBACK(hildon_time_editor_entry_focusout), editor);
- g_signal_connect(priv->entries[i], "key-press-event",
- G_CALLBACK(hildon_time_editor_entry_keypress), editor);
- g_signal_connect(priv->entries[i], "changed",
- G_CALLBACK(hildon_time_editor_entry_changed), editor);
-
- /* inserted signal sets time */
- g_signal_connect_after (G_OBJECT(priv->entries[i]), "insert_text",
- G_CALLBACK (hildon_time_editor_inserted_text),
- editor);
- }
-
- /* clicked signal for am/pm label */
- g_signal_connect(G_OBJECT(priv->ampm_button), "clicked",
- G_CALLBACK(hildon_time_editor_ampm_clicked), editor);
-
- /* clicked signal for icon */
- g_signal_connect(G_OBJECT(priv->iconbutton), "clicked",
- G_CALLBACK(hildon_time_editor_icon_clicked), editor);
-
- /* Set ourself as the parent of all the widgets we created */
- gtk_widget_set_parent(priv->iconbutton, GTK_WIDGET(editor));
- gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_HOURS], FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), priv->hm_label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_MINS], FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), priv->sec_label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_SECS], FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), priv->ampm_button, FALSE, FALSE, 0);
- gtk_misc_set_padding(GTK_MISC(priv->ampm_label), 0, 0);
-
- gtk_container_add(GTK_CONTAINER(priv->frame), hbox);
-
- /* Show created widgets */
- gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
- gtk_widget_show_all(priv->frame);
- gtk_widget_show_all(priv->iconbutton);
-
- /* Update AM/PM and time separators settings from locale */
- if (!hildon_time_editor_check_locale(editor)) {
- /* Using 12h clock */
- priv->clock_24h = FALSE;
- } else {
- gtk_widget_hide(priv->ampm_button);
- }
-
- if (!priv->show_seconds) {
- gtk_widget_hide(priv->sec_label);
- gtk_widget_hide(priv->entries[ENTRY_SECS]);
- }
-
- /* set the default time to current time. */
- hildon_time_editor_set_to_current_time (editor);
-
- gtk_widget_pop_composite_child();
-}
-
-static void hildon_time_editor_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HildonTimeEditor *time_editor = HILDON_TIME_EDITOR(object);
- switch (param_id)
- {
- case PROP_TICKS:
- hildon_time_editor_set_ticks (time_editor, g_value_get_uint(value));
- break;
-
- case PROP_SHOW_SECONDS:
- hildon_time_editor_set_show_seconds (time_editor, g_value_get_boolean(value));
- break;
-
- case PROP_SHOW_HOURS:
- hildon_time_editor_set_show_hours (time_editor, g_value_get_boolean(value));
- break;
-
- case PROP_DURATION_MODE:
- hildon_time_editor_set_duration_mode (time_editor, g_value_get_boolean(value));
- break;
-
- case PROP_DURATION_MIN:
- hildon_time_editor_set_duration_min (time_editor, g_value_get_uint(value));
- break;
-
- case PROP_DURATION_MAX:
- hildon_time_editor_set_duration_max (time_editor, g_value_get_uint(value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void hildon_time_editor_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HildonTimeEditor *time_editor = HILDON_TIME_EDITOR(object);
- switch (param_id)
- {
-
- case PROP_TICKS:
- g_value_set_uint (value, hildon_time_editor_get_ticks (time_editor));
- break;
-
- case PROP_SHOW_SECONDS:
- g_value_set_boolean (value, hildon_time_editor_get_show_seconds (time_editor));
- break;
-
- case PROP_SHOW_HOURS:
- g_value_set_boolean (value, hildon_time_editor_get_show_hours (time_editor));
- break;
-
- case PROP_DURATION_MODE:
- g_value_set_boolean (value, hildon_time_editor_get_duration_mode (time_editor));
- break;
-
- case PROP_DURATION_MIN:
- g_value_set_uint (value, hildon_time_editor_get_duration_min (time_editor));
- break;
-
- case PROP_DURATION_MAX:
- g_value_set_uint (value, hildon_time_editor_get_duration_max (time_editor));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-/**
- * hildon_time_editor_new:
- *
- * This function creates a new time editor.
- *
- * Returns: pointer to a new #HildonTimeEditor widget
- */
-
-GtkWidget *hildon_time_editor_new(void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_TIME_EDITOR, NULL));
-}
-
-static void hildon_time_editor_finalize(GObject * obj_self)
-{
- HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(obj_self);
-
- g_free(priv->am_symbol);
- g_free(priv->pm_symbol);
-
- if (priv->highlight_idle)
- g_source_remove(priv->highlight_idle);
-
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(obj_self);
-}
-
-/**
- * _hildon_time_editor_get_time_separators:
- * @editor: the #HildonTimeEditor
- * @hm_sep_label: the label that will show the hour:minutes separator
- * @ms_sep_label: the label that will show the minutes:seconds separator
- *
- * Gets hour-minute separator and minute-second separator from current
- * locale and sets then to the labels we set as parameters. Both
- * parameters can be NULL if you just want to assing one separator.
- *
- */
-void
-_hildon_time_editor_get_time_separators(GtkLabel *hm_sep_label,
- GtkLabel *ms_sep_label)
-{
- gchar buffer[256];
- gchar *separator;
- GDate locale_test_date;
- gchar *iter, *endp = NULL;
-
- /* Get localized time string */
- g_date_set_dmy(&locale_test_date, 1, 2, 1970);
- (void) g_date_strftime(buffer, sizeof(buffer), "%X", &locale_test_date);
-
- if (hm_sep_label != NULL)
- {
- /* Find h-m separator */
- iter = buffer;
- while (*iter && g_ascii_isdigit(*iter)) iter++;
-
- /* Extract h-m separator*/
- endp = iter;
- while (*endp && !g_ascii_isdigit(*endp)) endp++;
- separator = g_strndup(iter, endp - iter);
- gtk_label_set_label(hm_sep_label, separator);
- g_free(separator);
- }
-
- if (ms_sep_label != NULL)
- {
- /* Find m-s separator */
- iter = endp;
- while (*iter && g_ascii_isdigit(*iter)) iter++;
-
- /* Extract m-s separator*/
- endp = iter;
- while (*endp && !g_ascii_isdigit(*endp)) endp++;
- separator = g_strndup(iter, endp - iter);
- gtk_label_set_label(ms_sep_label, separator);
- g_free(separator);
- }
-
-}
-
-/* Convert ticks to H:M:S. Ticks = seconds since 00:00:00. */
-static void ticks_to_time (guint ticks,
- guint *hours,
- guint *minutes,
- guint *seconds)
-{
- guint left;
-
- *hours = ticks / 3600;
- left = ticks % 3600;
- *minutes = left / 60;
- *seconds = left % 60;
-}
-
-/**
- * hildon_time_editor_set_ticks:
- * @editor: the #HildonTimeEditor widget
- * @ticks: the duration to set, in seconds
- *
- * Sets the current duration in seconds. This means seconds from
- * midnight, if not in duration mode. In case of any errors, it tries
- * to fix it.
- */
-
-void hildon_time_editor_set_ticks (HildonTimeEditor * editor,
- guint ticks)
-{
- HildonTimeEditorPrivate *priv;
- guint i, h, m, s;
- gchar str[3];
-
- g_assert(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* Validate ticks. If it's too low or too high, set it to
- min/max value for the current mode. */
- if (priv->duration_mode)
- priv->ticks = CLAMP(ticks, priv->duration_min, priv->duration_max);
- else {
- /* Check that ticks value is valid. We only need to check that hours
- don't exceed 23. */
- ticks_to_time (ticks, &h, &m, &s);
- if (h > HOURS_MAX_24)
- ticks = TICKS(HOURS_MAX_24, m, s);
-
- priv->ticks = ticks;
- }
-
- /* Get the time in H:M:S. */
- ticks_to_time (priv->ticks, &h, &m, &s);
-
- if (!priv->clock_24h && !priv->duration_mode)
- {
- /* Convert 24h H:M:S values to 12h mode, and update AM/PM state */
- convert_to_12h (&h, &priv->am);
- }
-
- /* Set H:M:S values to entries. We do not want to invoke validation
- callbacks (since they can cause new call to this function), so we
- block signals while setting values. */
- for (i = 0; i < ENTRY_COUNT; i++)
- {
- g_signal_handlers_block_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_changed, editor);
-
- g_signal_handlers_block_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_inserted_text, editor);
-
- g_signal_handlers_block_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_focusout, editor);
-
- }
-
- g_snprintf(str, sizeof(str), "%02u", h);
- gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_HOURS]), str);
-
- g_snprintf(str, sizeof(str), "%02u", m);
- gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_MINS]), str);
-
- g_snprintf(str, sizeof(str), "%02u", s);
- gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_SECS]), str);
-
- for (i = 0; i < ENTRY_COUNT; i++)
- {
- g_signal_handlers_unblock_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_changed, editor);
-
- g_signal_handlers_unblock_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_inserted_text, editor);
-
- g_signal_handlers_unblock_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_focusout, editor);
-
- }
-
- /* Update AM/PM label in case we're in 12h mode */
- gtk_label_set_label(GTK_LABEL(priv->ampm_label),
- priv->am ? priv->am_symbol : priv->pm_symbol);
-
- g_object_notify (G_OBJECT (editor), "ticks");
-}
-
-static void
-hildon_time_editor_set_to_current_time (HildonTimeEditor * editor)
-{
- time_t now;
- const struct tm *tm;
-
- now = time(NULL);
- tm = localtime(&now);
-
- if (tm != NULL)
- hildon_time_editor_set_time(editor, tm->tm_hour, tm->tm_min, tm->tm_sec);
-}
-
-/**
- * hildon_time_editor_get_ticks:
- * @editor: the #HildonTimeEditor widget
- *
- * This function returns the current duration, in seconds.
- * This means seconds from midnight, if not in duration mode.
- *
- * Returns: current duration in seconds
- */
-
-guint hildon_time_editor_get_ticks (HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail(editor, 0);
- g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- return (priv->ticks);
-}
-
-/**
- * hildon_time_editor_set_show_seconds:
- * @editor: the #HildonTimeEditor
- * @show_seconds: enable or disable showing of seconds
- *
- * This function shows or hides the seconds field.
- */
-
-void hildon_time_editor_set_show_seconds (HildonTimeEditor * editor,
- gboolean show_seconds)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if (show_seconds != priv->show_seconds) {
- priv->show_seconds = show_seconds;
-
- /* show/hide seconds field and its ':' label if the value changed. */
- if (show_seconds) {
- gtk_widget_show(priv->entries[ENTRY_SECS]);
- gtk_widget_show(priv->sec_label);
- } else {
- gtk_widget_hide(priv->entries[ENTRY_SECS]);
- gtk_widget_hide(priv->sec_label);
- }
-
- g_object_notify (G_OBJECT (editor), "show_seconds");
- }
-}
-
-/**
- * hildon_time_editor_get_show_seconds:
- * @editor: the #HildonTimeEditor widget
- *
- * This function returns a boolean indicating the visibility of
- * seconds in the #HildonTimeEditor
- *
- * Returns: TRUE if the seconds are visible
- */
-
-gboolean hildon_time_editor_get_show_seconds (HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- return (priv->show_seconds);
-}
-
-/**
- * hildon_time_editor_set_duration_mode:
- * @editor: the #HildonTimeEditor
- * @duration_mode: enable or disable duration editor mode
- *
- * This function sets the duration editor mode in which the maximum hours
- * is 99.
- */
-
-void hildon_time_editor_set_duration_mode (HildonTimeEditor * editor,
- gboolean duration_mode)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if (duration_mode != priv->duration_mode) {
- priv->duration_mode = duration_mode;
-
- if (duration_mode) {
- /* FIXME: Why do we reset the duration range here?
- Would change API, so won't touch this for now. */
- hildon_time_editor_set_duration_range(editor, MIN_DURATION,
- MAX_DURATION);
- /* There's no AM/PM label or time picker icon in duration mode.
- Make sure they're hidden. */
- gtk_widget_hide(GTK_WIDGET(priv->ampm_label));
- gtk_widget_hide(GTK_WIDGET(priv->ampm_button));
- gtk_widget_hide(GTK_WIDGET(priv->iconbutton));
- /* Duration mode has seconds by default. */
- hildon_time_editor_set_show_seconds(editor, TRUE);
- } else {
- /* Make sure AM/PM label and time picker icons are visible if needed */
- if (!priv->clock_24h)
- gtk_widget_show(GTK_WIDGET(priv->ampm_label));
-
- gtk_widget_show(GTK_WIDGET(priv->ampm_button));
- gtk_widget_show(GTK_WIDGET(priv->iconbutton));
-
- /* Reset the ticks to current time. Anything set in duration mode
- * is bound to be invalid or useless in time mode.
- */
- hildon_time_editor_set_to_current_time (editor);
- }
-
- g_object_notify (G_OBJECT (editor), "duration_mode");
- }
-}
-
-/**
- * hildon_time_editor_get_duration_mode:
- * @editor: the #HildonTimeEditor widget
- *
- * This function returns a boolean indicating whether the #HildonTimeEditor
- * is in the duration mode.
- *
- * Returns: TRUE if the #HildonTimeEditor is in duration mode
- */
-
-gboolean hildon_time_editor_get_duration_mode (HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- return (priv->duration_mode);
-}
-
-/**
- * hildon_time_editor_set_duration_min:
- * @editor: the #HildonTimeEditor widget
- * @duration_min: mimimum allowed duration
- *
- * Sets the minimum allowed duration for the duration mode.
- * Note: Has no effect in time mode
- */
-
-void hildon_time_editor_set_duration_min (HildonTimeEditor * editor,
- guint duration_min)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
- g_return_if_fail(duration_min >= MIN_DURATION);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if( !priv->duration_mode )
- return;
-
- priv->duration_min = duration_min;
-
- /* Clamp the current value to the minimum if necessary */
- if (priv->ticks < duration_min)
- {
- hildon_time_editor_set_ticks (editor, duration_min);
- }
-
- g_object_notify (G_OBJECT (editor), "duration_min");
-}
-
-/**
- * hildon_time_editor_get_duration_min:
- * @editor: the #HildonTimeEditor widget
- *
- * This function returns the smallest duration the #HildonTimeEditor
- * allows in the duration mode.
- *
- * Returns: minimum allowed duration in seconds
- */
-
-guint hildon_time_editor_get_duration_min (HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if( !priv->duration_mode )
- return (0);
-
- return (priv->duration_min);
-}
-
-/**
- * hildon_time_editor_set_duration_max:
- * @editor: the #HildonTimeEditor widget
- * @duration_max: maximum allowed duration in seconds
- *
- * Sets the maximum allowed duration in seconds for the duration mode.
- * Note: Has no effect in time mode
- */
-
-void hildon_time_editor_set_duration_max (HildonTimeEditor * editor,
- guint duration_max)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
- g_return_if_fail(duration_max <= MAX_DURATION);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if( !priv->duration_mode )
- return;
-
- priv->duration_max = duration_max;
-
- /* Clamp the current value to the maximum if necessary */
- if (priv->ticks > duration_max)
- {
- hildon_time_editor_set_ticks (editor, duration_max);
- }
-
- g_object_notify (G_OBJECT (editor), "duration_max");
-}
-
-/**
- * hildon_time_editor_get_duration_max:
- * @editor: the #HildonTimeEditor widget
- *
- * This function returns the longest duration the #HildonTimeEditor
- * allows in the duration mode.
- *
- * Returns: maximum allowed duration in seconds
- */
-
-guint hildon_time_editor_get_duration_max (HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if( !priv->duration_mode )
- return (0);
-
- return (priv->duration_max);
-}
-
-
-/**
- * hildon_time_editor_set_time:
- * @editor: the #HildonTimeEditor widget
- * @hours: hours
- * @minutes: minutes
- * @seconds: seconds
- *
- * This function sets the time on an existing time editor. If the
- * time specified by the arguments is invalid, it's fixed.
- * The time is assumed to be in 24h format.
- */
-
-void hildon_time_editor_set_time(HildonTimeEditor * editor, guint hours,
- guint minutes, guint seconds)
-{
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- hildon_time_editor_set_ticks (editor, TICKS(hours, minutes, seconds));
-}
-
-/**
- * hildon_time_editor_get_time:
- * @editor: the #HildonTimeEditor widget
- * @hours: hours
- * @minutes: minutes
- * @seconds: seconds
- *
- * Gets the time of the #HildonTimeEditor widget. The time returned is
- * always in 24h format.
- */
-
-void hildon_time_editor_get_time(HildonTimeEditor * editor,
- guint * hours,
- guint * minutes, guint * seconds)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- ticks_to_time (hildon_time_editor_get_ticks (editor),
- hours, minutes, seconds);
-}
-
-/**
- * hildon_time_editor_set_duration_range:
- * @editor: the #HildonTimeEditor widget
- * @min_seconds: minimum allowed time in seconds
- * @max_seconds: maximum allowed time in seconds
- *
- * Sets the duration editor time range of the #HildonTimeEditor widget.
- */
-
-void hildon_time_editor_set_duration_range(HildonTimeEditor * editor,
- guint min_seconds,
- guint max_seconds)
-{
- HildonTimeEditorPrivate *priv;
- guint tmp;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
- /* Swap values if reversed */
- if (min_seconds > max_seconds)
- {
- tmp = max_seconds;
- max_seconds = min_seconds;
- min_seconds = tmp;
- }
-
- hildon_time_editor_set_duration_max (editor, max_seconds);
- hildon_time_editor_set_duration_min (editor, min_seconds);
-
- if (priv->duration_mode) {
- /* Set minimum allowed value for duration editor.
- FIXME: Shouldn't it be changed only if it's not in range?
- Would change API, so won't touch this for now. */
- hildon_time_editor_set_ticks(editor, min_seconds);
- }
-}
-
-/**
- * hildon_time_editor_get_duration_range:
- * @editor: the #HildonTimeEditor widget
- * @min_seconds: pointer to guint
- * @max_seconds: pointer to guint
- *
- * Gets the duration editor time range of the #HildonTimeEditor widget.
- */
-
-void hildon_time_editor_get_duration_range(HildonTimeEditor * editor,
- guint * min_seconds,
- guint * max_seconds)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- *min_seconds = priv->duration_min;
- *max_seconds = priv->duration_max;
-}
-
-static gboolean hildon_time_editor_check_locale(HildonTimeEditor * editor)
-{
- HildonTimeEditorPrivate *priv;
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* Update time separator symbols */
- _hildon_time_editor_get_time_separators(GTK_LABEL(priv->hm_label), GTK_LABEL(priv->sec_label));
-
- /* Get AM/PM symbols. */
- priv->am_symbol = g_strdup(nl_langinfo(AM_STR));
- priv->pm_symbol = g_strdup(nl_langinfo(PM_STR));
-
- if (priv->am_symbol[0] == '\0')
- return TRUE;
- else {
- /* 12h clock mode. Check if AM/PM should be before or after time.
- %p is the AM/PM string, so we assume that if the format string
- begins with %p it's in the beginning, and in any other case it's
- in the end (although that's not necessarily the case). */
- if (strncmp(nl_langinfo(T_FMT_AMPM), "%p", 2) == 0)
- priv->ampm_pos_after = FALSE;
- return FALSE;
- }
-}
-
-static gboolean hildon_time_editor_entry_focusin(GtkWidget * widget,
- GdkEventFocus * event,
- gpointer data)
-{
- g_idle_add((GSourceFunc) _hildon_time_editor_entry_select_all,
- GTK_ENTRY(widget));
-
- return FALSE;
-}
-
-static gboolean
-hildon_time_editor_time_error(HildonTimeEditor *editor,
- HildonTimeEditorErrorType type)
-{
- return TRUE;
-}
-
-/* Returns negative if we didn't get value,
- * and should stop further validation
- */
-static gint validated_conversion(HildonTimeEditorPrivate *priv,
- GtkWidget *field,
- gint min,
- gint max,
- gint def_value,
- gboolean allow_intermediate,
- guint *error_code,
- GString *error_string)
-{
- const gchar *text;
- gchar *tail;
- long value;
-
- text = gtk_entry_get_text(GTK_ENTRY(field));
-
- if (text && text[0])
- {
- /* Try to convert entry text to number */
- value = strtol(text, &tail, 10);
-
- /* Check if conversion succeeded */
- if ((tail[0] == 0) && !(text[0] == '-'))
- {
- if (value > max) {
- g_string_printf(error_string, _("ckct_ib_maximum_value"), max);
- priv->error_widget = field;
- *error_code = MAX_VALUE;
- return max;
- }
- if (value < min && !allow_intermediate) {
- g_string_printf(error_string, _("ckct_ib_minimum_value"), min);
- priv->error_widget = field;
- *error_code = MIN_VALUE;
- return min;
- }
-
- return value;
- }
- /* We'll handle failed conversions soon */
- else
- {
- if ((tail[0] == '-') || (text[0] == '-'))
- {
- g_string_printf(error_string, _("ckct_ib_minimum_value"), min);
- priv->error_widget = field;
- *error_code = MIN_VALUE;
- return min;
- }
- }
- }
- else if (allow_intermediate)
- return -1; /* Empty field while user is still editing. No error, but
- cannot validate either... */
- else /* Empty field: show error and set value to minimum allowed */
- {
- g_string_printf(error_string, _("ckct_ib_set_a_value_within_range"), min, max);
- priv->error_widget = field;
- *error_code = WITHIN_RANGE;
- return def_value;
- }
-
- /* Empty field and not allowed intermediated OR failed conversion */
- g_string_printf(error_string, _("ckct_ib_set_a_value_within_range"), min, max);
- priv->error_widget = field;
- *error_code = WITHIN_RANGE;
- return -1;
-}
-
-static void
-hildon_time_editor_real_validate(HildonTimeEditor *editor,
- gboolean allow_intermediate, GString *error_string)
-{
- HildonTimeEditorPrivate *priv;
- guint h, m, s, ticks;
- guint error_code;
- guint max_hours, min_hours, def_hours;
- guint max_minutes, min_minutes, def_minutes;
- guint max_seconds, min_seconds, def_seconds;
- gboolean r;
-
- g_assert(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* Find limits for field based validation. */
- if (priv->duration_mode)
- {
- ticks_to_time(priv->duration_min, &min_hours, &min_minutes, &min_seconds);
- ticks_to_time(priv->duration_max, &max_hours, &max_minutes, &max_seconds);
- } else {
- if (priv->clock_24h) {
- max_hours = HOURS_MAX_24;
- min_hours = HOURS_MIN_24;
- } else {
- max_hours = HOURS_MAX_12;
- min_hours = HOURS_MIN_12;
- }
- }
-
- hildon_time_editor_get_time(editor, &def_hours, &def_minutes, &def_seconds);
-
- /* Get time components from fields and validate them... */
- if (priv->show_hours) {
- h = validated_conversion(priv, priv->entries[ENTRY_HOURS], min_hours, max_hours, def_hours,
- allow_intermediate, &error_code, error_string);
- if (priv->error_widget == priv->entries[ENTRY_HOURS])
- g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, hour_errors[error_code], &r);
- if ((gint) h < 0) return;
- }
- else h = 0;
- m = validated_conversion(priv, priv->entries[ENTRY_MINS], MINUTES_MIN, MINUTES_MAX, def_minutes,
- allow_intermediate, &error_code, error_string);
- if (priv->error_widget == priv->entries[ENTRY_MINS])
- g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, min_errors[error_code], &r);
- if ((gint) m < 0) return;
- if (priv->show_seconds) {
- s = validated_conversion(priv, priv->entries[ENTRY_SECS], SECONDS_MIN, SECONDS_MAX, def_seconds,
- allow_intermediate, &error_code, error_string);
- if (priv->error_widget == priv->entries[ENTRY_SECS])
- g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, sec_errors[error_code], &r);
- if ((gint) s < 0) return;
- }
- else s = 0;
-
- /* Ok, we now do separate check that tick count is valid for duration mode */
- if (priv->duration_mode)
- {
- ticks = TICKS(h, m, s);
-
- if (ticks < priv->duration_min && !allow_intermediate)
- {
- g_string_printf(error_string,
- _("ckct_ib_min_allowed_duration_hts"),
- min_hours, min_minutes, min_seconds);
- hildon_time_editor_set_ticks (editor, priv->duration_min);
- priv->error_widget = priv->show_hours ? priv->entries[ENTRY_HOURS] : priv->entries[ENTRY_MINS];
- g_signal_emit (editor, time_editor_signals[TIME_ERROR], 0, MIN_DUR, &r);
- return;
- }
- else if (ticks > priv->duration_max)
- {
- g_string_printf(error_string,
- _("ckct_ib_max_allowed_duration_hts"),
- max_hours, max_minutes, max_seconds);
- hildon_time_editor_set_ticks (editor, priv->duration_max);
- priv->error_widget = priv->show_hours ? priv->entries[ENTRY_HOURS] : priv->entries[ENTRY_MINS];
- g_signal_emit (editor, time_editor_signals[TIME_ERROR], 0, MAX_DUR, &r);
- return;
- }
- }
- else if (!priv->clock_24h)
- convert_to_24h (&h, priv->am);
-
- /* The only case when we do not want to refresh the
- time display, is when the user is editing a value
- (unless the value was out of bounds and we have to fix it) */
- if (!allow_intermediate || priv->error_widget)
- hildon_time_editor_set_time (editor, h, m, s);
-}
-
-/* Setting text to entries causes entry to recompute itself
- in idle callback, which remove selection. Because of this
- we need to do selection in idle as well. */
-static gboolean highlight_callback(gpointer data)
-{
- HildonTimeEditorPrivate *priv;
- GtkWidget *widget;
- gint i;
-
- g_assert(HILDON_IS_TIME_EDITOR(data));
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(data);
-
- GDK_THREADS_ENTER ();
-
- widget = priv->error_widget;
- priv->error_widget = NULL;
-
- if (GTK_IS_WIDGET(widget) == FALSE)
- goto Done;
-
- /* Avoid revalidation because it will issue the date_error signal
- twice when there is an empty field. We must block the signal
- for all the entries because we do not know where the focus
- comes from */
- for (i = 0; i < ENTRY_COUNT; i++)
- g_signal_handlers_block_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_focusout, data);
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- gtk_widget_grab_focus(widget);
- for (i = 0; i < ENTRY_COUNT; i++)
- g_signal_handlers_unblock_by_func(priv->entries[i],
- (gpointer) hildon_time_editor_entry_focusout, data);
-
-Done:
- priv->highlight_idle = 0;
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
-/* Update ticks from current H:M:S entries. If they're invalid, show an
- infoprint and update the fields unless they're empty. */
-static void
-hildon_time_editor_validate (HildonTimeEditor *editor, gboolean allow_intermediate)
-{
- HildonTimeEditorPrivate *priv;
- GString *error_message;
-
- g_assert(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* if there is already an error we do nothing until it will be managed by the idle */
- if (priv->highlight_idle == 0 && priv->skipper == FALSE)
- {
- priv->skipper = TRUE;
- error_message = g_string_new(NULL);
- hildon_time_editor_real_validate(editor,
- allow_intermediate, error_message);
-
- if (priv->error_widget)
- {
- hildon_banner_show_information(priv->error_widget, NULL,
- error_message->str);
-
- priv->highlight_idle = g_idle_add(highlight_callback, editor);
- }
-
- priv->skipper = FALSE;
- g_string_free(error_message, TRUE);
- }
-}
-
-/* on inserted text, if entry has two digits, jumps to the next field. */
-static void
-hildon_time_editor_inserted_text (GtkEditable * editable,
- gchar * new_text,
- gint new_text_length,
- gint * position,
- gpointer user_data)
-{
- HildonTimeEditor *editor;
- GtkEntry *entry;
- gchar *value;
- HildonTimeEditorPrivate *priv;
-
- entry = GTK_ENTRY(editable);
- editor = HILDON_TIME_EDITOR(user_data);
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* if there is already an error we don't have to do anything */
- if (!priv->error_widget)
- {
-
- value = (gchar *) gtk_entry_get_text(entry);
-
- if (strlen(value) == 2)
- {
- if (GTK_WIDGET(editable) == priv->entries[ENTRY_HOURS])
- {
- /* We already checked the input in changed signal, but
- * now we will re-check it again in focus-out we
- * intermediate flag set to FALSE */
- gtk_widget_grab_focus(priv->entries[ENTRY_MINS]);
- *position = -1;
- }
- else if (GTK_WIDGET(editable) == priv->entries[ENTRY_MINS] &&
- GTK_WIDGET_VISIBLE (priv->entries[ENTRY_SECS]))
- {
- /* See above */
- gtk_widget_grab_focus(priv->entries[ENTRY_SECS]);
- *position = -1;
- }
- }
- }
-}
-
-static gboolean hildon_time_editor_entry_focusout(GtkWidget * widget,
- GdkEventFocus * event,
- gpointer data)
-{
- g_assert(HILDON_IS_TIME_EDITOR(data));
-
- /* Validate the given time and update ticks. */
- hildon_time_editor_validate(HILDON_TIME_EDITOR(data), FALSE);
-
- return FALSE;
-}
-
-static gboolean
-hildon_time_editor_ampm_clicked(GtkWidget * widget,
- gpointer data)
-{
- HildonTimeEditor *editor;
- HildonTimeEditorPrivate *priv;
-
- g_assert(GTK_IS_WIDGET(widget));
- g_assert(HILDON_IS_TIME_EDITOR(data));
-
- editor = HILDON_TIME_EDITOR(data);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* First validate the given time and update ticks. */
- hildon_time_editor_validate (editor, FALSE);
-
- /* Apply the AM/PM change by moving the current time by 12 hours */
- if (priv->am) {
- /* 00:00 .. 11:59 -> 12:00 .. 23:59 */
- hildon_time_editor_set_ticks (editor, priv->ticks + 12*3600);
- } else {
- /* 12:00 .. 23:59 -> 00:00 .. 11:59 */
- hildon_time_editor_set_ticks (editor, priv->ticks - 12*3600);
- }
- return FALSE;
-}
-
-static gboolean
-hildon_time_editor_icon_clicked(GtkWidget * widget, gpointer data)
-{
- HildonTimeEditor *editor;
- GtkWidget *picker;
- GtkWidget *parent;
- guint h, m, s, result;
- HildonTimeEditorPrivate *priv;
-
- g_assert(HILDON_IS_TIME_EDITOR(data));
-
- editor = HILDON_TIME_EDITOR(data);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* icon is passive in duration editor mode */
- if (hildon_time_editor_get_duration_mode(editor))
- return FALSE;
-
- /* Validate and do not launch if broken */
- hildon_time_editor_validate(HILDON_TIME_EDITOR(data), FALSE);
- if (priv->error_widget != NULL)
- return FALSE;
-
- /* Launch HildonTimePicker dialog */
- parent = gtk_widget_get_ancestor(GTK_WIDGET(editor), GTK_TYPE_WINDOW);
- picker = hildon_time_picker_new(GTK_WINDOW(parent));
-
- hildon_time_editor_get_time(editor, &h, &m, &s);
- hildon_time_picker_set_time(HILDON_TIME_PICKER(picker), h, m);
-
- result = gtk_dialog_run(GTK_DIALOG(picker));
- switch (result) {
- case GTK_RESPONSE_OK:
- case GTK_RESPONSE_ACCEPT:
- /* Use the selected time */
- hildon_time_picker_get_time(HILDON_TIME_PICKER(picker), &h, &m);
- hildon_time_editor_set_time(editor, h, m, 0);
- break;
- default:
- break;
- }
-
- gtk_widget_destroy(picker);
- return FALSE;
-}
-
-static void hildon_time_editor_size_request(GtkWidget * widget,
- GtkRequisition * requisition)
-{
- HildonTimeEditor *editor;
- HildonTimeEditorPrivate *priv;
- GtkRequisition req;
-
- editor = HILDON_TIME_EDITOR(widget);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- /* Get frame's size */
- gtk_widget_size_request(priv->frame, requisition);
-
- if (GTK_WIDGET_VISIBLE(priv->iconbutton))
- {
- gtk_widget_size_request(priv->iconbutton, &req);
- /* Reserve space for icon */
- requisition->width += req.width + ICON_PRESSED +
- HILDON_MARGIN_DEFAULT;
- }
-
- /* FIXME: It's evil to use hardcoded TIME_EDITOR_HEIGHT. For now we'll
- want to force this since themes might have varying thickness values
- which cause the height to change. */
- requisition->height = TIME_EDITOR_HEIGHT;
-}
-
-static void hildon_time_editor_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(widget);
- GtkAllocation alloc;
- GtkRequisition req, max_req;
-
- widget->allocation = *allocation;
- gtk_widget_get_child_requisition(widget, &max_req);
-
- /* Center horizontally */
- alloc.x = allocation->x + MAX(allocation->width - max_req.width, 0) / 2;
- /* Center vertically */
- alloc.y = allocation->y + MAX(allocation->height - max_req.height, 0) / 2;
-
- /* allocate frame */
- gtk_widget_get_child_requisition(priv->frame, &req);
-
- alloc.width = req.width;
- alloc.height = max_req.height;
- gtk_widget_size_allocate(priv->frame, &alloc);
-
- /* allocate icon */
- if (GTK_WIDGET_VISIBLE(priv->iconbutton)) {
- gtk_widget_get_child_requisition(priv->iconbutton, &req);
-
- alloc.x += alloc.width + HILDON_MARGIN_DEFAULT;
- alloc.width = req.width;
- gtk_widget_size_allocate(priv->iconbutton, &alloc);
- }
-
- /* FIXME: ugly way to move labels up. They just don't seem move up
- otherwise. This is likely because we force the editor to be
- smaller than it otherwise would be. */
- alloc = priv->ampm_label->allocation;
- alloc.y = allocation->y - 2;
- alloc.height = max_req.height + 2;
- gtk_widget_size_allocate(priv->ampm_label, &alloc);
-
- alloc = priv->hm_label->allocation;
- alloc.y = allocation->y - 2;
- alloc.height = max_req.height + 2;
- gtk_widget_size_allocate(priv->hm_label, &alloc);
-
- alloc = priv->sec_label->allocation;
- alloc.y = allocation->y - 2;
- alloc.height = max_req.height + 2;
- gtk_widget_size_allocate(priv->sec_label, &alloc);
-}
-
-static gboolean hildon_time_editor_entry_keypress(GtkWidget * widget,
- GdkEventKey * event,
- gpointer data)
-{
- HildonTimeEditor *editor;
- HildonTimeEditorPrivate *priv;
- gint cursor_pos;
- gboolean r;
-
- g_assert(GTK_IS_ENTRY(widget));
- g_assert(event != NULL);
- g_assert(HILDON_IS_TIME_EDITOR(data));
-
- editor = HILDON_TIME_EDITOR(data);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
- cursor_pos = gtk_editable_get_position(GTK_EDITABLE(widget));
-
- /* Show error message in case the key pressed is not allowed
- (only digits and control characters are allowed )*/
- if (!g_unichar_isdigit(event->keyval) && !(event->keyval & 0xF000)) {
- g_signal_emit(editor, time_editor_signals[TIME_ERROR], 0, INVALID_CHAR, &r);
- hildon_banner_show_information(widget, NULL, _("ckct_ib_illegal_character"));
- return TRUE;
- }
-
- switch (event->keyval)
- {
- case GDK_Return:
- /* Return key popups up time picker dialog. Visually it looks as if
- the time picker icon was clicked. Before opening the time picker
- the fields are first validated and fixed. */
- hildon_time_editor_validate (editor, FALSE);
- hildon_gtk_button_set_depressed(GTK_BUTTON(priv->iconbutton), TRUE);
- hildon_time_editor_icon_clicked(widget, data);
- hildon_gtk_button_set_depressed(GTK_BUTTON(priv->iconbutton), FALSE);
- return TRUE;
-
- case GDK_Left:
- /* left arrow pressed in the entry. If we are on first position, try to
- move to the previous field. */
- if (cursor_pos == 0) {
- (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_LEFT);
- return TRUE;
- }
- break;
-
- case GDK_Right:
- /* right arrow pressed in the entry. If we are on last position, try to
- move to the next field. */
- if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1)) {
- (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_RIGHT);
- return TRUE;
- }
- break;
-
- default:
- break;
- };
-
- return FALSE;
-}
-
-/***
- * Utility functions
- */
-
-static void
-convert_to_12h (guint *h, gboolean *am)
-{
- g_assert(0 <= *h && *h < 24);
-
- /* 00:00 to 00:59 add 12 hours */
- /* 01:00 to 11:59 straight to am */
- /* 12:00 to 12:59 straight to pm */
- /* 13:00 to 23:59 subtract 12 hours */
-
- if ( *h == 0 ) { *am = TRUE; *h += 12;}
- else if ( 1 <= *h && *h < 12 ) { *am = TRUE; }
- else if ( 12 <= *h && *h < 13 ) { *am = FALSE; }
- else { *am = FALSE; *h -= 12;}
-}
-
-static void
-convert_to_24h (guint *h, gboolean am)
-{
- if (*h == 12 && am) /* 12 midnight - 12:59 AM subtract 12 hours */
- {
- *h -= 12;
- }
- else if (!am && 1 <= *h && *h < 12) /* 1:00 PM - 11:59 AM add 12 hours */
- {
- *h += 12;
- }
-}
-
-/**
- * hildon_time_editor_set_show_hours:
- * @editor: The #HildonTimeEditor.
- * @enable: Enable or disable showing of hours.
- *
- * This function shows or hides the hours field.
- *
- * Since: 0.12.4
- **/
-void hildon_time_editor_set_show_hours(HildonTimeEditor * editor,
- gboolean show_hours)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
-
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- if (show_hours != priv->show_hours) {
- priv->show_hours = show_hours;
-
- /* show/hide hours field and its ':' label if the value changed. */
- if (show_hours) {
- gtk_widget_show(priv->entries[ENTRY_HOURS]);
- gtk_widget_show(priv->hm_label);
- } else {
- gtk_widget_hide(priv->entries[ENTRY_HOURS]);
- gtk_widget_hide(priv->hm_label);
- }
-
- g_object_notify (G_OBJECT (editor), "show_hours");
- }
-}
-
-/**
- * hildon_time_editor_get_show_hours:
- * @self: the @HildonTimeEditor widget.
- *
- * This function returns a boolean indicating the visibility of
- * hours in the @HildonTimeEditor
- *
- * Return value: TRUE if hours are visible.
- *
- * Since: 0.12.4-1
- **/
-gboolean hildon_time_editor_get_show_hours(HildonTimeEditor *editor)
-{
- HildonTimeEditorPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
- priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
-
- return priv->show_hours;
-}
-
-/***
- * Deprecated functions
- */
-
-/**
- * hildon_time_editor_show_seconds:
- * @editor: the #HildonTimeEditor
- * @enable: enable or disable showing of seconds
- *
- * This function is deprecated,
- * use #hildon_time_editor_set_show_seconds instead.
- */
-void hildon_time_editor_show_seconds(HildonTimeEditor * editor,
- gboolean enable)
-{
- hildon_time_editor_set_show_seconds (editor, enable);
-}
-/**
- * hildon_time_editor_enable_duration_mode:
- * @editor: the #HildonTimeEditor
- * @enable: enable or disable duration editor mode
- *
- * This function is deprecated,
- * use #hildon_time_editor_set_duration_mode instead.
- */
-void hildon_time_editor_enable_duration_mode(HildonTimeEditor * editor,
- gboolean enable)
-{
- hildon_time_editor_set_duration_mode (editor, enable);
-}
-
-/* Idle callback */
-static gboolean
-_hildon_time_editor_entry_select_all (GtkWidget *widget)
-{
- GDK_THREADS_ENTER ();
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- GDK_THREADS_LEAVE ();
- return FALSE;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_TIME_EDITOR_H__
-#define __HILDON_TIME_EDITOR_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_TIME_EDITOR (hildon_time_editor_get_type())
-
-#define HILDON_TIME_EDITOR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_TIME_EDITOR, HildonTimeEditor))
-#define HILDON_TIME_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_TIME_EDITOR, HildonTimeEditorClass))
-
-#define HILDON_IS_TIME_EDITOR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_TIME_EDITOR))
-#define HILDON_IS_TIME_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_TIME_EDITOR))
-
-
-typedef enum
-{
- NO_TIME_ERROR = -1,
- MAX_HOURS,
- MAX_MINS,
- MAX_SECS,
- MIN_HOURS,
- MIN_MINS,
- MIN_SECS,
- EMPTY_HOURS,
- EMPTY_MINS,
- EMPTY_SECS,
- MIN_DUR,
- MAX_DUR,
- INVALID_TIME,
- INVALID_CHAR
-} HildonTimeEditorErrorType;
-
-typedef struct _HildonTimeEditor HildonTimeEditor;
-typedef struct _HildonTimeEditorClass HildonTimeEditorClass;
-
-struct _HildonTimeEditor {
- GtkContainer parent;
-};
-
-struct _HildonTimeEditorClass {
- GtkContainerClass parent_class;
-
- gboolean (*time_error) (HildonTimeEditor *editor,
- HildonTimeEditorErrorType type);
-};
-
-GType hildon_time_editor_get_type(void) G_GNUC_CONST;
-GtkWidget *hildon_time_editor_new(void);
-
-
-void hildon_time_editor_set_time (HildonTimeEditor * editor,
- guint hours,
- guint minutes,
- guint seconds);
-
-void hildon_time_editor_get_time (HildonTimeEditor * editor,
- guint * hours,
- guint * minutes,
- guint * seconds);
-
-#ifndef HILDON_DISABLE_DEPRECATED
-void hildon_time_editor_show_seconds (HildonTimeEditor * editor, gboolean enable);
-void hildon_time_editor_enable_duration_mode (HildonTimeEditor * editor, gboolean enable);
-#endif /* HILDON_DISABLE_DEPRECATED */
-
-
-void hildon_time_editor_set_duration_range (HildonTimeEditor * editor,
- guint min_seconds,
- guint max_seconds);
-
-void hildon_time_editor_get_duration_range (HildonTimeEditor * editor,
- guint * min_seconds,
- guint * max_seconds);
-
-void hildon_time_editor_set_ticks (HildonTimeEditor * editor, guint ticks);
-guint hildon_time_editor_get_ticks (HildonTimeEditor * editor);
-
-void hildon_time_editor_set_show_seconds (HildonTimeEditor * editor, gboolean show_seconds);
-gboolean hildon_time_editor_get_show_seconds (HildonTimeEditor * editor);
-
-void hildon_time_editor_set_show_hours (HildonTimeEditor * editor, gboolean show_hours);
-gboolean hildon_time_editor_get_show_hours (HildonTimeEditor * editor);
-
-void hildon_time_editor_set_duration_mode (HildonTimeEditor * editor, gboolean duration_mode);
-gboolean hildon_time_editor_get_duration_mode (HildonTimeEditor * editor);
-
-void hildon_time_editor_set_duration_min (HildonTimeEditor * editor, guint duration_min);
-guint hildon_time_editor_get_duration_min (HildonTimeEditor * editor);
-
-void hildon_time_editor_set_duration_max (HildonTimeEditor * editor, guint duration_max);
-guint hildon_time_editor_get_duration_max (HildonTimeEditor * editor);
-
-
-G_END_DECLS
-#endif /* __HILDON_TIME_EDITOR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-time-picker
- * @short_description: A dialog popup widget which lets the user set the time
- * @see_also: #HildonTimeEditor
- *
- * #HildonTimePicker is a dialog popup widget which lets the user set the time,
- * using up/down arrows on hours and minutes. There are two arrows for minutes,
- * so that minutes can be added also in 10 min increments.This widget is mainly
- * used as a part of #HildonTimeEditor implementation.
- */
-
-#include "hildon-time-picker.h"
-#include <hildon-widgets/hildon-defines.h>
-#include <hildon-widgets/hildon-private.h>
-#include <hildon-widgets/gtk-infoprint.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk/gdk.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <langinfo.h>
-#include <libintl.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _(String) dgettext(PACKAGE, String)
-
-#define HILDON_TIME_PICKER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_TIME_PICKER, HildonTimePickerPrivate))
-
-#define DEFAULT_HOURS 1
-#define DEFAULT_MINUTES 1
-#define DEFAULT_ARROW_WIDTH 26
-#define DEFAULT_ARROW_HEIGHT 26
-
-#define MINS_IN_1H (60)
-#define MINS_IN_24H (MINS_IN_1H * 24)
-#define MINS_IN_12H (MINS_IN_1H * 12)
-
-#define HILDON_TIME_PICKER_LABEL_X_PADDING 0
-#define HILDON_TIME_PICKER_LABEL_Y_PADDING 1
-
-
-/* Indices for grouped labels in priv->widgets */
-enum
-{
- WIDGET_GROUP_HOURS,
- WIDGET_GROUP_10_MINUTES,
- WIDGET_GROUP_1_MINUTES,
- WIDGET_GROUP_AMPM,
-
- WIDGET_GROUP_COUNT
-};
-
-/* Indices for up/down buttons in group->buttons */
-enum
-{
- BUTTON_UP,
- BUTTON_DOWN,
-
- BUTTON_COUNT
-};
-
-typedef struct
-{
- GtkWidget *frame;
- GtkWidget *eventbox;
- GtkLabel *label;
-
- /* buttons are used for hours and minutes, but not for am/pm */
- GtkWidget *buttons[BUTTON_COUNT];
-
-} HildonTimePickerWidgetGroup;
-
-static GtkDialogClass *parent_class;
-
-struct _HildonTimePickerPrivate
-{
- HildonTimePickerWidgetGroup widgets[WIDGET_GROUP_COUNT];
-
- gchar *am_symbol;
- gchar *pm_symbol;
-
- guint key_repeat;
- guint minutes; /* time in minutes since midnight */
- gint mul; /* for key repeat handling */
- guint timer_id;
-
- guint show_ampm : 1; /* 12 hour clock, show AM/PM */
- guint ampm_left : 1;
- guint button_press : 1;
- guint start_key_repeat : 1;
-};
-
-enum
-{
- PROP_MINUTES = 1
-};
-
-
-static const gint button_multipliers[WIDGET_GROUP_COUNT][2] =
-{
- { MINS_IN_1H, -MINS_IN_1H },
- { 10, -10 },
- { 1, -1 },
- { 0, 0 }
-};
-
-static void
-hildon_time_picker_class_init( HildonTimePickerClass *klass );
-
-static void
-hildon_time_picker_init( HildonTimePicker *picker );
-
-static gboolean
-hildon_time_picker_key_repeat_timeout( gpointer tpicker );
-
-static void
-hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes );
-
-static gboolean
-hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker );
-
-static gboolean
-hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker );
-static gboolean
-hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker );
-
-static void
-hildon_time_picker_finalize( GObject *object );
-
-static void
-hildon_time_picker_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec );
-
-static void
-hildon_time_picker_set_property( GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec );
-
-static gboolean
-hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
- gpointer unused );
-
-static gboolean
-hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
- gpointer unused );
-
-static gboolean
-hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
- HildonTimePicker *picker );
-
-static gboolean
-hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
- HildonTimePicker *picker );
-
-static gboolean
-hildon_time_picker_event_box_button_press( GtkWidget *widget, GdkEventKey *event,
- gpointer unused );
-
-static void
-hildon_time_picker_map( GtkWidget *widget );
-
-static void
-frame_size_request (GtkWidget *widget, GtkRequisition *requistion);
-
-GType hildon_time_picker_get_type( void )
-{
- static GType picker_type = 0;
-
- if( !picker_type )
- {
- static const GTypeInfo picker_info =
- {
- sizeof(HildonTimePickerClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc)hildon_time_picker_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonTimePicker),
- 0, /* n_preallocs */
- (GInstanceInitFunc)hildon_time_picker_init,
- };
- picker_type = g_type_register_static( GTK_TYPE_DIALOG, "HildonTimePicker",
- &picker_info, 0 );
- }
- return picker_type;
-}
-
-
-static void
-hildon_time_picker_class_init( HildonTimePickerClass *klass )
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- parent_class = g_type_class_peek_parent( klass );
-
- gobject_class->finalize = hildon_time_picker_finalize;
- gobject_class->get_property = hildon_time_picker_get_property;
- gobject_class->set_property = hildon_time_picker_set_property;
- widget_class->map = hildon_time_picker_map;
-
- /**
- * HildonTimePicker:minutes:
- *
- * Currently selected time in minutes since midnight.
- */
- g_object_class_install_property( gobject_class, PROP_MINUTES,
- g_param_spec_uint("minutes",
- "Current minutes",
- "The selected time in minutes "
- "since midnight",
- 0, MINS_IN_24H, 0,
- G_PARAM_READABLE | G_PARAM_WRITABLE) );
-
- gtk_widget_class_install_style_property( widget_class,
- g_param_spec_uint("arrow-width",
- "Arrow width",
- "Increase/decrease arrows width.",
- 0, G_MAXUINT,
- DEFAULT_ARROW_WIDTH,
- G_PARAM_READABLE) );
-
- gtk_widget_class_install_style_property( widget_class,
- g_param_spec_uint("arrow-height",
- "Arrow height",
- "Increase/decrease arrows height.",
- 0, G_MAXUINT,
- DEFAULT_ARROW_HEIGHT,
- G_PARAM_READABLE) );
-
- g_type_class_add_private( klass, sizeof(HildonTimePickerPrivate) );
-}
-
-/* Okay, this is really bad. We make the requisition of the frames a bit larger
- * so that it doesn't "change" when digits are changed (see #37489). It's a
- * really bad solution to a problem, but the whole layout of the time picker is
- * on crack anyways */
-static void frame_size_request (GtkWidget *widget, GtkRequisition *requistion)
-{
- int framed = requistion->width / 10;
- requistion->width = (framed + 1) * 10;
-}
-
-static void hildon_time_picker_init( HildonTimePicker *picker )
-{
- HildonTimePickerPrivate *priv = HILDON_TIME_PICKER_GET_PRIVATE(picker);
- gint widget_group_table_column_pos[WIDGET_GROUP_COUNT];
- GtkSettings *settings = NULL;
- GtkDialog *dialog = GTK_DIALOG(picker);
- GtkTable *table = NULL;
- GtkWidget *maintocenter, *colon_label;
- const struct tm *local = NULL;
- time_t stamp;
- gint i = 0;
- GtkSizeGroup *size_group;
-
- picker->priv = priv;
-
- widget_group_table_column_pos[WIDGET_GROUP_HOURS] = 1;
- widget_group_table_column_pos[WIDGET_GROUP_10_MINUTES] = 3;
- widget_group_table_column_pos[WIDGET_GROUP_1_MINUTES] = 4;
- widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 5;
-
- /* Get AM/PM strings from locale. If they're set, the time is wanted
- in 12 hour mode. */
- priv->am_symbol = g_strdup(nl_langinfo(AM_STR));
- priv->pm_symbol = g_strdup(nl_langinfo(PM_STR));
-
- priv->show_ampm = priv->am_symbol[0] != '\0';
- if (priv->show_ampm)
- {
- /* Check if AM/PM should be before or after time.
- %p is the AM/PM string, so we assume that if the format string
- begins with %p it's in the beginning, and in any other case it's
- in the end (although that's not necessarily the case). */
- if (strncmp(nl_langinfo(T_FMT_AMPM), "%p", 2) == 0)
- {
- /* Before time. Update column position. */
- priv->ampm_left = TRUE;
- widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 0;
- }
- }
-
- gtk_widget_push_composite_child();
-
- /* Pack all our internal widgets into a table */
- table = GTK_TABLE(gtk_table_new(3, 6, FALSE));
-
- /* Put everything centered into window */
- maintocenter = gtk_alignment_new( 0.5, 0, 0, 0 );
-
- /* Create our internal widgets */
- for (i = 0; i < WIDGET_GROUP_COUNT; i++)
- {
- HildonTimePickerWidgetGroup *group = &priv->widgets[i];
- gint table_column = widget_group_table_column_pos[i];
-
- /* Create frame and attach to table. With AM/PM label we're attaching
- it later. */
- group->frame = gtk_frame_new(NULL);
- if (i != WIDGET_GROUP_AMPM)
- {
- gtk_table_attach(table, group->frame, table_column, table_column + 1,
- 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
-
-
- }
- /* FIXME: is it needed to force it to 0 here? */
- gtk_container_set_border_width(GTK_CONTAINER(group->frame), 0);
-
- /* Create eventbox inside frame */
- group->eventbox = gtk_event_box_new();
- gtk_container_add(GTK_CONTAINER(group->frame), group->eventbox);
-
- g_object_set(group->eventbox, "can-focus", TRUE, NULL);
- gtk_widget_set_events(group->eventbox,
- GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_PRESS_MASK );
-
- /* Connect signals to eventbox */
- g_signal_connect(group->eventbox, "key-release-event",
- G_CALLBACK(hildon_time_picker_event_box_key_release),
- picker);
- g_signal_connect(group->eventbox, "key-press-event",
- G_CALLBACK(hildon_time_picker_event_box_key_press),
- picker);
- g_signal_connect(group->eventbox, "focus-in-event",
- G_CALLBACK(hildon_time_picker_event_box_focus_in),
- picker);
- g_signal_connect(group->eventbox, "focus-out-event",
- G_CALLBACK(hildon_time_picker_event_box_focus_out),
- picker);
- g_signal_connect(group->eventbox, "button-press-event",
- G_CALLBACK(hildon_time_picker_event_box_button_press),
- picker);
-
- /* Create label inside eventbox */
- group->label = GTK_LABEL(gtk_label_new(NULL));
- g_signal_connect(group->frame, "size-request",
- G_CALLBACK(frame_size_request),
- NULL);
- gtk_misc_set_alignment (GTK_MISC (group->label), 0.5, 0.5);
- gtk_container_add(GTK_CONTAINER(group->eventbox), GTK_WIDGET(group->label));
-
- if (i != WIDGET_GROUP_AMPM)
- {
- gint button;
-
- /* Add some padding to hour and minute labels, and make them bigger */
- gtk_misc_set_padding(GTK_MISC(group->label),
- HILDON_TIME_PICKER_LABEL_X_PADDING,
- HILDON_TIME_PICKER_LABEL_Y_PADDING);
- gtk_widget_set_name(GTK_WIDGET(group->label), "osso-LargeFont");
-
- /* Create up and down buttons for hours and mins */
- for (button = 0; button < BUTTON_COUNT; button++)
- {
- gint table_row = button == BUTTON_UP ? 0 : 2;
-
- group->buttons[button] = gtk_button_new();
- gtk_table_attach(table, group->buttons[button],
- table_column, table_column + 1,
- table_row, table_row + 1,
- GTK_SHRINK, GTK_SHRINK, 0, 0);
- g_object_set(group->buttons[button], "can-focus", FALSE, NULL);
-
- /* Connect signals */
- g_signal_connect(group->buttons[button], "button-press-event",
- G_CALLBACK(hildon_time_picker_arrow_press), picker);
- g_signal_connect(group->buttons[button], "button-release-event",
- G_CALLBACK(hildon_time_picker_arrow_release), picker);
- }
-
- gtk_widget_set_name(group->buttons[BUTTON_UP],
- "hildon-time-picker-up");
- gtk_widget_set_name(group->buttons[BUTTON_DOWN],
- "hildon-time-picker-down");
- }
- }
-
- /* Label between hour and minutes */
- colon_label = gtk_label_new(NULL);
- _hildon_time_editor_get_time_separators(GTK_LABEL(colon_label), NULL);
-
- gtk_table_attach(table, colon_label, 2, 3, 1, 2,
- GTK_SHRINK, GTK_SHRINK, 6, 0); /* FIXME: magic */
- gtk_widget_set_name(colon_label, "osso-LargeFont" );
-
- priv->minutes = 0;
- priv->mul = 0;
- priv->key_repeat = 0;
- priv->start_key_repeat = FALSE;
- priv->timer_id = 0;
- priv->button_press = FALSE;
-
- gtk_table_set_row_spacing( table, 0, 6 );
- gtk_table_set_row_spacing( table, 1, 6 );
-
- if (priv->show_ampm)
- {
- gint table_column = widget_group_table_column_pos[WIDGET_GROUP_AMPM];
- GtkWidget *ampmtotop = NULL;
-
- /* Show the AM/PM label centered vertically */
- ampmtotop = gtk_alignment_new( 0, 0.5, 0, 0 );
- gtk_table_attach(table, ampmtotop, table_column, table_column + 1,
- 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
- gtk_container_add(GTK_CONTAINER(ampmtotop),
- priv->widgets[WIDGET_GROUP_AMPM].frame);
-
- if (table_column != 0)
- gtk_table_set_col_spacing(table, table_column - 1, 9);
-
- /* Connect AM/PM signal handlers */
- g_signal_connect(priv->widgets[WIDGET_GROUP_AMPM].eventbox,
- "button-release-event",
- G_CALLBACK(hildon_time_picker_ampm_release), picker);
- }
-
- gtk_widget_pop_composite_child();
-
- /* Get button press repeater timeout from settings (in milliseconds) */
- settings = gtk_settings_get_default();
- g_object_get( settings, "gtk-update-timeout", &priv->key_repeat, NULL );
-
- /* This dialog isn't modal */
- gtk_window_set_modal( GTK_WINDOW(dialog), FALSE );
- /* And final dialog packing */
- gtk_dialog_set_has_separator( dialog, FALSE );
- gtk_dialog_add_button( dialog, _("ecdg_bd_time_picker_close"),
- GTK_RESPONSE_OK );
-
- gtk_container_add( GTK_CONTAINER(maintocenter), GTK_WIDGET(table) );
- gtk_box_pack_start( GTK_BOX(dialog->vbox), maintocenter, TRUE, FALSE, 0 );
-
- /* Set default time to current time */
- stamp = time( NULL );
- local = localtime( &stamp );
- hildon_time_picker_set_time( picker, local->tm_hour, local->tm_min );
-
- gtk_widget_show_all( maintocenter );
-}
-
-static void
-hildon_time_picker_set_property( GObject *object, guint param_id,
- const GValue *value, GParamSpec *pspec )
-{
- HildonTimePicker *picker = HILDON_TIME_PICKER(object);
-
- switch( param_id )
- {
- case PROP_MINUTES:
- hildon_time_picker_change_time( picker, g_value_get_uint(value) );
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void
-hildon_time_picker_finalize( GObject *object )
-{
- HildonTimePicker *picker = HILDON_TIME_PICKER(object);
-
- /* Make sure the timer is stopped */
- if (picker->priv->timer_id)
- g_source_remove(picker->priv->timer_id);
-
- g_free(picker->priv->am_symbol);
- g_free(picker->priv->pm_symbol);
-
- if (G_OBJECT_CLASS(parent_class)->finalize)
- G_OBJECT_CLASS(parent_class)->finalize(object);
-}
-
-static void
-hildon_time_picker_get_property( GObject *object, guint param_id,
- GValue *value, GParamSpec *pspec )
-{
- HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(object)->priv;
-
- switch( param_id )
- {
- case PROP_MINUTES:
- g_value_set_uint( value, priv->minutes );
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
- break;
- }
-}
-
-static void
-hildon_time_picker_map( GtkWidget *widget )
-{
- guint width, height;
- gint i, button;
- HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(widget)->priv;
-
- /* Widget is now mapped. Set border for the dialog. */
- gdk_window_set_decorations( widget->window, GDK_DECOR_BORDER );
-
- /* Update hour/minute up/down buttons sizes from style properties */
- gtk_widget_style_get( widget,
- "arrow-width", &width,
- "arrow-height", &height, NULL );
- for (i = 0; i < WIDGET_GROUP_COUNT; i++)
- {
- if (priv->widgets[i].buttons[0] != NULL)
- {
- for (button = 0; button < BUTTON_COUNT; button++)
- {
- gtk_widget_set_size_request(priv->widgets[i].buttons[button],
- width, height);
- }
- }
- }
-
- GTK_WIDGET_CLASS(parent_class)->map( widget );
-}
-
-
-static gboolean
-hildon_time_picker_event_box_button_press( GtkWidget *widget,
- GdkEventKey *event, gpointer unused )
-{
- /* Clicked hour/minute field. Move focus to it. */
- gtk_widget_grab_focus( widget );
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker )
-{
- /* Clicked AM/PM label. Move focus to it and move the time by 12 hours. */
- gtk_widget_grab_focus( widget );
- hildon_time_picker_change_time( picker, picker->priv->minutes > MINS_IN_12H ?
- picker->priv->minutes - MINS_IN_12H :
- picker->priv->minutes + MINS_IN_12H );
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker )
-{
- HildonTimePickerPrivate *priv = picker->priv;
- gint i, button;
- gint newval = 0;
-
- /* Make sure we don't add repeat timer twice. Normally it shouldn't
- happen but WM can cause button release to be lost. */
- if( priv->button_press )
- return FALSE;
-
- priv->start_key_repeat = priv->button_press = TRUE;
-
- /* Find the widget which was clicked */
- priv->mul = 0;
- for (i = 0; i < WIDGET_GROUP_COUNT; i++)
- {
- for (button = 0; button < BUTTON_COUNT; button++)
- {
- if (priv->widgets[i].buttons[button] == widget)
- {
- /* Update multiplier and move the focus to the clicked field */
- priv->mul = button_multipliers[i][button];
- gtk_widget_grab_focus(priv->widgets[i].eventbox);
- break;
- }
- }
- }
- g_assert(priv->mul != 0);
-
- /* Change the time now, wrapping if needed. */
- newval = priv->minutes + priv->mul;
- if( newval < 0 )
- newval += MINS_IN_24H;
-
- hildon_time_picker_change_time( picker, newval );
-
- /* Keep changing the time as long as button is being pressed.
- The first repeat takes 3 times longer to start than the rest. */
- priv->timer_id = g_timeout_add(priv->key_repeat * 3,
- hildon_time_picker_key_repeat_timeout,
- picker);
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
- HildonTimePicker *picker )
-{
- HildonTimePickerPrivate *priv = picker->priv;
- if( priv->timer_id )
- {
- /* Stop repeat timer */
- g_source_remove( priv->timer_id );
- priv->timer_id = 0;
- }
- priv->button_press = FALSE;
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
- gpointer unused )
-{
- /* Draw the widget in selected state so focus shows clearly. */
- gtk_widget_set_state( widget, GTK_STATE_SELECTED );
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
- gpointer unused )
-{
- /* Draw the widget in normal state */
- gtk_widget_set_state( widget, GTK_STATE_NORMAL );
- return FALSE;
-}
-
-static gint
-hildon_time_picker_lookup_eventbox_group(HildonTimePicker *picker,
- GtkWidget *widget)
-{
- gint i;
-
- for (i = 0; i < WIDGET_GROUP_COUNT; i++)
- {
- if (picker->priv->widgets[i].eventbox == widget)
- return i;
- }
- return -1;
-}
-
-static gboolean
-hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
- HildonTimePicker *picker )
-{
- HildonTimePickerPrivate *priv = picker->priv;
- HildonTimePickerWidgetGroup *group;
- gint group_idx;
-
- /* If mouse button is already being pressed, ignore this keypress */
- if( priv->timer_id )
- return TRUE;
-
- group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
- group = group_idx < 0 ? NULL : &picker->priv->widgets[group_idx];
-
- /* Handle keypresses in hour/minute/AMPM fields */
- switch( event->keyval )
- {
- case GDK_Up:
- case GDK_Down:
- if (group != NULL)
- {
- gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
-
- if (group->buttons[button] != NULL)
- {
- /* Fake a button up/down press */
- hildon_time_picker_arrow_press(group->buttons[button], NULL, picker);
- gtk_widget_set_state(group->buttons[button], GTK_STATE_SELECTED);
- }
- else
- {
- /* Fake a AM/PM button release */
- g_assert(group_idx == WIDGET_GROUP_AMPM);
- hildon_time_picker_ampm_release(group->eventbox, NULL, picker);
- }
- }
- return TRUE;
-
- case GDK_Left:
- /* If we're in leftmost field, stop this keypress signal.
- Otherwise let the default key handler move focus to field in left. */
- if (priv->show_ampm && priv->ampm_left)
- {
- /* AM/PM is the leftmost field */
- if (group_idx == WIDGET_GROUP_AMPM)
- return TRUE;
- }
- else
- {
- /* Hours is the leftmost field */
- if (group_idx == WIDGET_GROUP_HOURS)
- return TRUE;
- }
- break;
-
- case GDK_Right:
- /* If we're in rightmost field, stop this keypress signal.
- Otherwise let the default key handler move focus to field in right. */
- if (priv->show_ampm && !priv->ampm_left)
- {
- /* AM/PM is the rightmost field */
- if (group_idx == WIDGET_GROUP_AMPM)
- return TRUE;
- }
- else
- {
- /* 1-minutes is the leftmost field */
- if (group_idx == WIDGET_GROUP_1_MINUTES)
- return TRUE;
- }
- break;
-
- case GDK_Escape:
- gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_CANCEL);
- return TRUE;
-
- case GDK_Return:
- gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_OK);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
- HildonTimePicker *picker )
-{
- HildonTimePickerWidgetGroup *group;
- gint group_idx;
-
- /* Fake a button release if in key-press handler we faked a button press. */
- switch( event->keyval )
- {
- case GDK_Up:
- case GDK_Down:
- group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
- if (group_idx >= 0)
- {
- gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
-
- group = &picker->priv->widgets[group_idx];
- if (group->buttons[button] != NULL)
- {
- /* Fake a button up/down press */
- gtk_widget_set_state(group->buttons[button], GTK_STATE_NORMAL);
- hildon_time_picker_arrow_release(group->buttons[button],
- NULL, picker);
- }
- }
- break;
- }
- return FALSE;
-}
-
-/* Button up/down is being pressed. Update the time. */
-static gboolean
-hildon_time_picker_key_repeat_timeout( gpointer tpicker )
-{
- HildonTimePicker *picker;
- HildonTimePickerPrivate *priv = NULL;
- gint newval = 0;
-
- GDK_THREADS_ENTER ();
-
- picker = HILDON_TIME_PICKER(tpicker);
- g_assert(picker != NULL);
-
- priv = picker->priv;
-
- /* Change the time, wrapping if needed */
- newval = priv->minutes + priv->mul;
- if( newval < 0 )
- newval += MINS_IN_24H;
-
- hildon_time_picker_change_time( picker, newval );
-
- if( priv->start_key_repeat )
- {
- /* This is the first repeat. Shorten the timeout to key_repeat
- (instead of the first time's 3*key_repeat) */
- priv->timer_id = g_timeout_add(priv->key_repeat,
- hildon_time_picker_key_repeat_timeout,
- picker);
- priv->start_key_repeat = FALSE;
-
- GDK_THREADS_LEAVE ();
- return FALSE;
- }
-
- GDK_THREADS_LEAVE ();
- return TRUE;
-}
-
-
-
-static void
-hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes )
-{
- HildonTimePickerPrivate *priv = picker->priv;
- gchar str[3] = "00";
- guint hours = 0;
- gboolean ampm = TRUE;
-
- /* If the minutes isn't in valid range, wrap them. */
- minutes %= MINS_IN_24H;
-
- if( priv->minutes == minutes )
- return;
-
- /* Minutes changed. Update widgets to show the new time. */
- priv->minutes = minutes;
-
- if (priv->show_ampm)
- {
- /* am < 12:00 <= pm */
- ampm = !((guint)(minutes / MINS_IN_12H));
- /* 12:00 - 23:59 -> 00:00 - 11:59 */
- minutes %= MINS_IN_12H;
- if( minutes < MINS_IN_1H )
- /* 00:mm is always shown as 12:mm */
- minutes += MINS_IN_12H;
-
- /* Update the AM/PM label */
- gtk_label_set_text(priv->widgets[WIDGET_GROUP_AMPM].label,
- ampm ? priv->am_symbol : priv->pm_symbol);
- }
-
- /* Update hour and minute fields */
- hours = minutes / MINS_IN_1H;
- minutes %= MINS_IN_1H;
-
- snprintf(str, sizeof(str), "%02d", hours);
- gtk_label_set_text(priv->widgets[WIDGET_GROUP_HOURS].label, str);
-
- snprintf(str, sizeof(str), "%d", minutes / 10);
- gtk_label_set_text(priv->widgets[WIDGET_GROUP_10_MINUTES].label, str);
-
- snprintf(str, sizeof(str), "%d", minutes % 10);
- gtk_label_set_text(priv->widgets[WIDGET_GROUP_1_MINUTES].label, str);
-
- g_object_notify( G_OBJECT(picker), "minutes" );
-}
-
-/**
- * hildon_time_picker_new:
- * @parent: parent window
- *
- * #HildonTimePicker shows time picker dialog. The close button is placed
- * in the dialog's action area and time picker is placed in dialogs vbox.
- * The actual time picker consists of two #GtkLabel fields - one for hours
- * and one for minutes - and an AM/PM button. A colon (:) is placed
- * between hour and minute fields.
- *
- * Returns: pointer to a new #HildonTimePicker widget.
- */
-GtkWidget *hildon_time_picker_new( GtkWindow *parent )
-{
- GtkWidget *widget = g_object_new( HILDON_TYPE_TIME_PICKER,
- "minutes", 360, NULL );
-
- if( parent )
- gtk_window_set_transient_for( GTK_WINDOW(widget), parent );
-
- return GTK_WIDGET(widget);
-}
-
-/**
- * hildon_time_picker_set_time:
- * @picker: the #HildonTimePicker widget
- * @hours: hours
- * @minutes: minutes
- *
- * Sets the time of the #HildonTimePicker widget.
- */
-void hildon_time_picker_set_time( HildonTimePicker *picker,
- guint hours, guint minutes )
-{
- g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
- hildon_time_picker_change_time( picker, hours * MINS_IN_1H + minutes );
-}
-
-/**
- * hildon_time_picker_get_time:
- * @picker: the #HildonTimePicker widget
- * @hours: hours
- * @minutes: minutes
- *
- * Gets the time of the #HildonTimePicker widget.
- */
-void hildon_time_picker_get_time( HildonTimePicker *picker,
- guint *hours, guint *minutes )
-{
- guint current;
- g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
-
- current = picker->priv->minutes;
- *hours = current / MINS_IN_1H;
- *minutes = current % MINS_IN_1H;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_TIME_PICKER_H__
-#define __HILDON_TIME_PICKER_H__
-
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-
-#define HILDON_TYPE_TIME_PICKER (hildon_time_picker_get_type())
-#define HILDON_TIME_PICKER(obj) (GTK_CHECK_CAST (obj, \
- HILDON_TYPE_TIME_PICKER, \
- HildonTimePicker))
-#define HILDON_TIME_PICKER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
- HILDON_TYPE_TIME_PICKER,\
- HildonTimePickerClass))
-#define HILDON_IS_TIME_PICKER(obj) (GTK_CHECK_TYPE (obj, \
- HILDON_TYPE_TIME_PICKER))
-#define HILDON_IS_TIME_PICKER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
- HILDON_TYPE_TIME_PICKER))
-
-
-typedef struct _HildonTimePicker HildonTimePicker;
-typedef struct _HildonTimePickerClass HildonTimePickerClass;
-typedef struct _HildonTimePickerPrivate HildonTimePickerPrivate;
-
-
-struct _HildonTimePicker
-{
- GtkDialog parent;
- HildonTimePickerPrivate *priv;
-};
-
-struct _HildonTimePickerClass
-{
- GtkDialogClass parent_class;
-};
-
-
-GType hildon_time_picker_get_type( void ) G_GNUC_CONST;
-
-GtkWidget *hildon_time_picker_new( GtkWindow *parent );
-
-void hildon_time_picker_set_time( HildonTimePicker *picker,
- guint hours, guint minutes );
-
-void hildon_time_picker_get_time( HildonTimePicker *picker,
- guint *hours, guint *minutes );
-
-
-G_END_DECLS
-#endif /* __HILDON_TIME_PICKER_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_VOLUMEBAR_PRIVATE__
-#define __HILDON_VOLUMEBAR_PRIVATE__
-
-#include <gtk/gtktogglebutton.h>
-#include <hildon-widgets/hildon-volumebar-range.h>
-
-G_BEGIN_DECLS
-#define HILDON_VOLUMEBAR_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_VOLUMEBAR, HildonVolumebarPrivate));
-
-typedef struct _HildonVolumebarPrivate HildonVolumebarPrivate;
-
-struct _HildonVolumebarPrivate {
- HildonVolumebarRange *volumebar;
- GtkToggleButton *tbutton;
- gboolean is_toolbar; /* is inside toolbar (for horizontal volumebar) */
- GdkWindow *event_window; /* input-only window to catch insensitive presses */
-};
-
-void _hildon_volumebar_mute_toggled(HildonVolumebar * self);
-
-G_END_DECLS
-#endif /* __HILDON_VOLUMEBAR_PRIVATE__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * @file hildon-volumebar-range.c
- *
- * This file contains the implementation of the HildonVolumebarRange.
- * This widget is an "workhorse" for #HildonVolumebar widget.
- * It is not designed to be used as a standalone widget.
- *
- * Purpose of this widget is to act as an "container" for GtkScale
- * widget. #HildonVolumebarRange changes some event parameters so
- * that #HildonVolumebar can meet its specifications.
- *
- * Currently #HildonVolumebarRange models range of [0..100].
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtkrange.h>
-#include <gdk/gdkkeysyms.h>
-#include "hildon-volumebar-range.h"
-
-#define VOLUMEBAR_RANGE_INITIAL_VALUE 50.0
-#define VOLUMEBAR_RANGE_MINIMUM_VALUE 0.0
-#define VOLUMEBAR_RANGE_MAXIMUM_VALUE 100.0
-#define VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE 5.0
-#define VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE 5.0
-#define VOLUMEBAR_RANGE_PAGE_SIZE_VALUE 0.0
-
-#define CHANGE_THRESHOLD 0.001
-
-static GtkScaleClass *parent_class;
-
-static void hildon_volumebar_range_class_init(HildonVolumebarRangeClass *
- volumerange_class);
-static void hildon_volumebar_range_init(HildonVolumebarRange *
- volumerange);
-static void hildon_volumebar_range_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_volumebar_range_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-static gint hildon_volumebar_range_button_press_event(GtkWidget * widget,
- GdkEventButton *
- event);
-static gint hildon_volumebar_range_button_release_event(GtkWidget * widget,
- GdkEventButton *
- event);
-static gboolean hildon_volumebar_range_keypress(GtkWidget * widget,
- GdkEventKey * event);
-
-enum {
- PROP_NONE = 0,
- PROP_LEVEL
-};
-
-GType
-hildon_volumebar_range_get_type(void)
-{
- static GType volumerange_type = 0;
-
- if (!volumerange_type) {
- static const GTypeInfo volumerange_info = {
- sizeof(HildonVolumebarRangeClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_volumebar_range_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonVolumebarRange),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_volumebar_range_init,
- };
- volumerange_type = g_type_register_static(GTK_TYPE_SCALE,
- "HildonVolumebarRange",
- &volumerange_info, 0);
- }
- return volumerange_type;
-}
-
-static void
-hildon_volumebar_range_class_init(HildonVolumebarRangeClass *
- volumerange_class)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(volumerange_class);
- GObjectClass *object_class = G_OBJECT_CLASS(volumerange_class);
-
- parent_class = g_type_class_peek_parent(volumerange_class);
-
- widget_class->button_press_event =
- hildon_volumebar_range_button_press_event;
- widget_class->button_release_event =
- hildon_volumebar_range_button_release_event;
- widget_class->key_press_event = hildon_volumebar_range_keypress;
-
- object_class->set_property = hildon_volumebar_range_set_property;
- object_class->get_property = hildon_volumebar_range_get_property;
-
- g_object_class_install_property(object_class,
- PROP_LEVEL,
- g_param_spec_double("level",
- "Level",
- "Current volume level",
- VOLUMEBAR_RANGE_MINIMUM_VALUE,
- VOLUMEBAR_RANGE_MAXIMUM_VALUE,
- VOLUMEBAR_RANGE_INITIAL_VALUE,
- G_PARAM_READWRITE));
- return;
-}
-
-static void
-hildon_volumebar_range_init(HildonVolumebarRange * volumerange)
-{
- /* stepper_a = "less", stepper_d = "more" */
- GTK_RANGE(volumerange)->has_stepper_a = TRUE;
- GTK_RANGE(volumerange)->has_stepper_d = TRUE;
-}
-
-static void
-hildon_volumebar_range_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec)
-{
- HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE(object);
-
- switch (prop_id) {
- case PROP_LEVEL:
- hildon_volumebar_range_set_level(range, g_value_get_double(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-hildon_volumebar_range_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec)
-{
- HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE(object);
-
- switch (prop_id) {
- case PROP_LEVEL:
- g_value_set_double(value, hildon_volumebar_range_get_level(range));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static
-gboolean hildon_volumebar_range_keypress(GtkWidget * widget,
- GdkEventKey * event)
-{
- /* Accept arrow keys only if they match the orientation of the widget */
- if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- if (event->keyval == GDK_Up || event->keyval == GDK_Down) {
- return FALSE;
- }
- }
- else
- {
- if (event->keyval == GDK_Left || event->keyval == GDK_Right) {
- return FALSE;
- }
- }
-
- return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget,
- event));
-}
-
-GtkWidget *
-hildon_volumebar_range_new(GtkOrientation orientation)
-{
- GtkAdjustment * adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (VOLUMEBAR_RANGE_INITIAL_VALUE,
- VOLUMEBAR_RANGE_MINIMUM_VALUE,
- VOLUMEBAR_RANGE_MAXIMUM_VALUE,
- VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE,
- VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE,
- VOLUMEBAR_RANGE_PAGE_SIZE_VALUE));
- HildonVolumebarRange *self =
- g_object_new(HILDON_TYPE_VOLUMEBAR_RANGE,
- "adjustment", adjustment,
- NULL);
-
- GTK_RANGE(self)->orientation = orientation;
-
- /* Default vertical range is upside down for purposes of this widget */
- gtk_range_set_inverted(GTK_RANGE(self),
- (orientation == GTK_ORIENTATION_VERTICAL));
-
- return GTK_WIDGET(self);
-}
-
-gdouble
-hildon_volumebar_range_get_level(HildonVolumebarRange * self)
-{
- g_return_val_if_fail(HILDON_IS_VOLUMEBAR_RANGE(self), -1.0);
-
- return gtk_adjustment_get_value(gtk_range_get_adjustment(GTK_RANGE(self)));
-}
-
-void
-hildon_volumebar_range_set_level(HildonVolumebarRange * self,
- gdouble level)
-{
- GtkAdjustment *adjustment;
-
- g_return_if_fail(HILDON_IS_VOLUMEBAR_RANGE(self));
-
- adjustment = gtk_range_get_adjustment(GTK_RANGE(self));
-
- /* Check that value has actually changed. Note that it's not safe to
- * just compare if floats are equivalent or not */
- if (ABS(gtk_adjustment_get_value(adjustment) - level) > CHANGE_THRESHOLD) {
- gtk_adjustment_set_value(adjustment, level);
- }
-}
-
-static gint
-hildon_volumebar_range_button_press_event(GtkWidget * widget,
- GdkEventButton *
- event)
-{
- gboolean result = FALSE;
-
- /* FIXME: By default, clicking left mouse button on GtkRange moves the
- slider by one step towards the click location. However, we want stylus
- taps to move the slider to the position of the tap, which by default
- is the middle button behaviour. To avoid breaking default GtkRange
- behaviour, this has been implemented by faking a middle button press. */
- event->button = (event->button == 1) ? 2 : event->button;
- if (GTK_WIDGET_CLASS(parent_class)->button_press_event) {
- result =
- GTK_WIDGET_CLASS(parent_class)->button_press_event(widget,
- event);
- }
- return result;
-}
-
-static gint
-hildon_volumebar_range_button_release_event(GtkWidget * widget,
- GdkEventButton *
- event)
-{
- gboolean result = FALSE;
-
- /* FIXME: By default, clicking left mouse button on GtkRange moves the
- slider by one step towards the click location. However, we want stylus
- taps to move the slider to the position of the tap, which by default
- is the middle button behaviour. To avoid breaking default GtkRange
- behaviour, this has been implemented by faking a middle button press. */
- event->button = event->button == 1 ? 2 : event->button;
- if (GTK_WIDGET_CLASS(parent_class)->button_release_event) {
- result =
- GTK_WIDGET_CLASS(parent_class)->button_release_event(widget,
- event);
- }
- return result;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_VOLUMEBAR_RANGE_H__
-#define __HILDON_VOLUMEBAR_RANGE_H__
-
-#include <gtk/gtkscale.h>
-
-G_BEGIN_DECLS
-
-/**
- * HILDON_VOLUMEBAR_RANGE_TYPE
- *
- * Macro for getting type of volumebar range.
- * Since: 0.12.10
- */
-#define HILDON_TYPE_VOLUMEBAR_RANGE ( hildon_volumebar_range_get_type() )
-
-/**
- * HILDON_VOLUMEBAR_RANGE_TYPE
- *
- * Deprecated: use #HILDON_VOLUMEBAR_RANGE_TYPE instead
- */
-#define HILDON_VOLUMEBAR_RANGE_TYPE HILDON_TYPE_VOLUMEBAR_RANGE
-
-
-#define HILDON_VOLUMEBAR_RANGE(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_VOLUMEBAR_RANGE, HildonVolumebarRange))
-#define HILDON_VOLUMEBAR_RANGE_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_VOLUMEBAR_RANGE, HildonVolumebarRangeClass))
-#define HILDON_IS_VOLUMEBAR_RANGE(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_VOLUMEBAR_RANGE))
-#define HILDON_IS_VOLUMEBAR_RANGE_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VOLUMEBAR_RANGE))
-
-typedef struct _HildonVolumebarRange HildonVolumebarRange;
-typedef struct _HildonVolumebarRangeClass HildonVolumebarRangeClass;
-
-struct _HildonVolumebarRange {
- GtkScale scale;
-};
-
-struct _HildonVolumebarRangeClass {
- GtkScaleClass parent_class;
-};
-
-GType hildon_volumebar_range_get_type (void) G_GNUC_CONST;
-GtkWidget * hildon_volumebar_range_new (GtkOrientation orientation);
-gdouble hildon_volumebar_range_get_level (HildonVolumebarRange *self);
-void hildon_volumebar_range_set_level (HildonVolumebarRange *self,
- gdouble level);
-
-
-G_END_DECLS
-
-#endif /* __HILDON_VOLUMEBAR_RANGE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-volumebar
- * @short_description: Base class for widgets that display a volume bar
- * @see_also: #HildonHVolumebar, #HildonVVolumebar
- *
- * #HildonVolumebar is a base class for widgets that display a volume bar that
- * allows increasing or decreasing volume within a predefined range, and muting
- * the volume when users click the mute icon.
- */
-
-#include <gtk/gtkwindow.h>
-#include <gtk/gtksignal.h>
-#include <gdk/gdkkeysyms.h>
-
-#include "hildon-volumebar.h"
-#include "hildon-volumebar-range.h"
-#include "hildon-volumebar-private.h"
-
-static GtkContainerClass *parent_class;
-
-static void
-hildon_volumebar_class_init(HildonVolumebarClass * volumebar_class);
-static void
-hildon_volumebar_init(HildonVolumebar * volumebar);
-
-static void
-hildon_child_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void
-hildon_volumebar_destroy(GtkObject * self);
-
-static void hildon_volumebar_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec);
-static void hildon_volumebar_get_property(GObject * object,
- guint prop_id,
- GValue * value,
- GParamSpec * pspec);
-
-static void mute_toggled (HildonVolumebar *self);
-
-static gboolean
-hildon_volumebar_key_press(GtkWidget * widget,
- GdkEventKey * event);
-
-static void hildon_volumebar_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static void hildon_volumebar_realize (GtkWidget *widget);
-static void hildon_volumebar_unrealize (GtkWidget *widget);
-static void hildon_volumebar_map (GtkWidget *widget);
-static void hildon_volumebar_unmap (GtkWidget *widget);
-static void hildon_volumebar_notify (GObject *self, GParamSpec *param);
-
-
-enum
-{
- MUTE_TOGGLED_SIGNAL,
- LEVEL_CHANGED_SIGNAL,
- LAST_SIGNAL
-};
-
-enum {
- PROP_NONE = 0,
- PROP_HILDON_HAS_MUTE,
- PROP_HILDON_FOCUSABLE,
- PROP_HILDON_LEVEL,
- PROP_HILDON_MUTE
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-GType
-hildon_volumebar_get_type(void)
-{
- static GType volumebar_type = 0;
-
- if (!volumebar_type) {
- static const GTypeInfo volumebar_info = {
- sizeof(HildonVolumebarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_volumebar_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonVolumebar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_volumebar_init,
- };
- volumebar_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonVolumebar",
- &volumebar_info, 0);
- }
- return volumebar_type;
-}
-
-static void
-hildon_volumebar_class_init(HildonVolumebarClass *volumebar_class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (volumebar_class);
- GtkObjectClass *object_class = GTK_OBJECT_CLASS(volumebar_class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(volumebar_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(volumebar_class);
-
- parent_class = g_type_class_peek_parent(volumebar_class);
-
- g_type_class_add_private(volumebar_class,
- sizeof(HildonVolumebarPrivate));
-
- /* Because we derived our widget from GtkContainer, we should also
- override forall method */
- volumebar_class->mute_toggled = mute_toggled;
- container_class->forall = hildon_child_forall;
- widget_class->size_allocate = hildon_volumebar_size_allocate;
- widget_class->realize = hildon_volumebar_realize;
- widget_class->unrealize = hildon_volumebar_unrealize;
- widget_class->map = hildon_volumebar_map;
- widget_class->unmap = hildon_volumebar_unmap;
- widget_class->key_press_event = hildon_volumebar_key_press;
- object_class->destroy = hildon_volumebar_destroy;
-
- signals[MUTE_TOGGLED_SIGNAL] = g_signal_new("mute_toggled",
- G_OBJECT_CLASS_TYPE
- (object_class),
- G_SIGNAL_RUN_LAST |
- G_SIGNAL_ACTION,
- G_STRUCT_OFFSET
- (HildonVolumebarClass,
- mute_toggled), NULL, NULL,
- gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[LEVEL_CHANGED_SIGNAL] = g_signal_new("level_changed",
- G_OBJECT_CLASS_TYPE
- (object_class),
- G_SIGNAL_RUN_LAST |
- G_SIGNAL_ACTION,
- G_STRUCT_OFFSET
- (HildonVolumebarClass,
- level_changed), NULL,
- NULL,
- gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- gobject_class->notify = hildon_volumebar_notify;
- gobject_class->set_property = hildon_volumebar_set_property;
- gobject_class->get_property = hildon_volumebar_get_property;
-
- /*This kind of property could be usefull in the gtkcontainer*/
- g_object_class_install_property(gobject_class,
- PROP_HILDON_FOCUSABLE,
- g_param_spec_boolean("can-focus",
- "The widget focusablility",
- "The widget focusablility. TRUE is focusable",
- TRUE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class,
- PROP_HILDON_HAS_MUTE,
- g_param_spec_boolean("has_mute",
- "Show/Hide the mute button",
- "Whether the mute button is visible. Default value: TRUE",
- TRUE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class,
- PROP_HILDON_LEVEL,
- g_param_spec_double("level",
- "Level",
- "Current volume level",
- 0.0,
- 100.0,
- 50.0,
- G_PARAM_READWRITE));
-
- g_object_class_install_property(gobject_class,
- PROP_HILDON_MUTE,
- g_param_spec_boolean("mute",
- "Mute",
- "Whether volume is muted",
- FALSE,
- G_PARAM_READWRITE));
-}
-
-static void
-hildon_volumebar_init(HildonVolumebar * volumebar)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(volumebar);
-
- /* Should set GTK_NO_WINDOW flag, because widget is derived from
- GtkContainer */
- GTK_WIDGET_SET_FLAGS(GTK_WIDGET(volumebar), GTK_NO_WINDOW);
- GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(volumebar), GTK_CAN_FOCUS);
-
- /* Initialize mute button */
- priv->tbutton = GTK_TOGGLE_BUTTON(gtk_toggle_button_new());
- g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
-}
-
-static void
-hildon_volumebar_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
- GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
-
- if (GTK_WIDGET_REALIZED (widget))
- gdk_window_move_resize (priv->event_window,
- allocation->x, allocation->y,
- allocation->width, allocation->height);
-}
-
-static void
-hildon_volumebar_realize (GtkWidget *widget)
-{
- HildonVolumebarPrivate *priv;
- GdkWindowAttr attributes;
- gint attributes_mask;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- GTK_WIDGET_CLASS(parent_class)->realize(widget);
-
- attributes.window_type = GDK_WINDOW_CHILD;
- attributes.x = widget->allocation.x;
- attributes.y = widget->allocation.y;
- attributes.width = widget->allocation.width;
- attributes.height = widget->allocation.height;
- attributes.wclass = GDK_INPUT_ONLY;
- attributes.event_mask = GDK_BUTTON_PRESS_MASK;
-
- attributes_mask = GDK_WA_X | GDK_WA_Y;
-
- priv->event_window = gdk_window_new (widget->window,
- &attributes, attributes_mask);
- gdk_window_set_user_data (priv->event_window, widget);
-}
-
-static void
-hildon_volumebar_unrealize (GtkWidget *widget)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- if (priv->event_window) {
- gdk_window_set_user_data (priv->event_window, NULL);
- gdk_window_destroy (priv->event_window);
- priv->event_window = NULL;
- }
-
- GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
-}
-
-static void
-hildon_volumebar_map (GtkWidget *widget)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- GTK_WIDGET_CLASS(parent_class)->map(widget);
-
- /* the event window must be on top of all other widget windows, so show it
- * last */
- if (!GTK_WIDGET_SENSITIVE (widget))
- gdk_window_show (priv->event_window);
-}
-
-static void hildon_volumebar_unmap (GtkWidget *widget)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- gdk_window_hide (priv->event_window);
-
- GTK_WIDGET_CLASS(parent_class)->unmap(widget);
-}
-
-static void
-hildon_child_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonVolumebarPrivate *priv;
-
- g_assert(HILDON_IS_VOLUMEBAR(container));
- g_assert(callback != NULL);
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(container);
-
- /* No external children */
- if (!include_internals)
- return;
-
- /* Execute callback for both internals */
- (*callback) (GTK_WIDGET(priv->tbutton), callback_data);
- (*callback) (GTK_WIDGET(priv->volumebar), callback_data);
-}
-
-static void
-hildon_volumebar_notify (GObject *self, GParamSpec *param)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- if (GTK_WIDGET_MAPPED (self)) {
- /* show/hide the event window on sensitivity change */
- if (g_str_equal (param->name, "sensitive")) {
- if (GTK_WIDGET_SENSITIVE (self))
- gdk_window_hide (priv->event_window);
- else
- gdk_window_show (priv->event_window);
- }
- }
-
- if (G_OBJECT_CLASS(parent_class)->notify)
- G_OBJECT_CLASS(parent_class)->notify (self, param);
-}
-
-static void
-hildon_volumebar_destroy(GtkObject * self)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- if (priv->tbutton) {
- gtk_widget_unparent(GTK_WIDGET(priv->tbutton));
- priv->tbutton = NULL;
- }
- if (priv->volumebar) {
- gtk_widget_unparent(GTK_WIDGET(priv->volumebar));
- priv->volumebar = NULL;
- }
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-}
-
-static void
-hildon_volumebar_set_property(GObject * object,
- guint prop_id,
- const GValue * value,
- GParamSpec * pspec)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(object);
-
- switch (prop_id) {
- case PROP_HILDON_HAS_MUTE:
- /* Mute button always exists, but might be hidden */
- if (g_value_get_boolean(value))
- gtk_widget_show(GTK_WIDGET(priv->tbutton));
- else
- gtk_widget_hide(GTK_WIDGET(priv->tbutton));
- break;
- case PROP_HILDON_FOCUSABLE:
- g_object_set( G_OBJECT(priv->volumebar), "can-focus",
- g_value_get_boolean(value), NULL );
- break;
- case PROP_HILDON_LEVEL:
- hildon_volumebar_set_level(HILDON_VOLUMEBAR(priv->volumebar),
- g_value_get_double(value));
- break;
- case PROP_HILDON_MUTE:
- hildon_volumebar_set_mute(HILDON_VOLUMEBAR(priv->volumebar),
- g_value_get_boolean(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-
- break;
- }
-}
-
-static void
-hildon_volumebar_get_property(GObject * object,
- guint prop_id, GValue * value,
- GParamSpec * pspec)
-{
- HildonVolumebar *vb = HILDON_VOLUMEBAR(object);
- HildonVolumebarPrivate *priv = HILDON_VOLUMEBAR_GET_PRIVATE(vb);
-
- switch (prop_id) {
- case PROP_HILDON_HAS_MUTE:
- g_value_set_boolean(value, GTK_WIDGET_VISIBLE(priv->tbutton));
- break;
- case PROP_HILDON_FOCUSABLE:
- g_value_set_boolean(value, GTK_WIDGET_CAN_FOCUS(priv->volumebar));
- break;
- case PROP_HILDON_LEVEL:
- g_value_set_double(value, hildon_volumebar_get_level(vb));
- break;
- case PROP_HILDON_MUTE:
- g_value_set_boolean(value, hildon_volumebar_get_mute(vb));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * hildon_volumebar_level_change:
- * @self: a #HildonVolumebar widget
- *
- * Emits "level_changed" signal to the given volume bar. This function
- * is mainly used by derived classes.
- */
-void
-hildon_volumebar_level_change(HildonVolumebar * self)
-{
- g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
- g_signal_emit_by_name(GTK_WIDGET(self), "level_changed");
-}
-
-/**
- * hildon_volumebar_set_level:
- * @self: volume bar to change level on
- * @level: new level
- *
- * Sets new volume level for this #HildonVolumebar.
- */
-void
-hildon_volumebar_set_level(HildonVolumebar * self, gdouble level)
-{
- HildonVolumebarPrivate *priv;
-
- g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- hildon_volumebar_range_set_level(priv->volumebar, level);
-}
-
-/**
- * hildon_volumebar_get_level:
- * @self: volume bar to query level on
- *
- * Gets the volume level of this #HildonVolumebar.
- *
- * Returns: volume level or -1 on error
- */
-gdouble
-hildon_volumebar_get_level(HildonVolumebar * self)
-{
- HildonVolumebarPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), -1);
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- return hildon_volumebar_range_get_level(priv->volumebar);
-}
-
-/**
- * hildon_volumebar_set_mute:
- * @self: volume bar to work on
- * @mute: mute ON/OFF
- *
- * Sets mute status for this #HildonVolumebar.
- */
-void
-hildon_volumebar_set_mute(HildonVolumebar * self, gboolean mute)
-{
- HildonVolumebarPrivate *priv;
- gboolean focusable = TRUE;
-
- g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- /* Slider should be insensitive when mute is on */
- gtk_widget_set_sensitive(GTK_WIDGET(priv->volumebar), !mute);
-
- focusable = GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (priv->volumebar));
-
- if (mute){
- if (focusable){
- /* Make mute button focusable since the slider isn't anymore */
- g_object_set (G_OBJECT (priv->tbutton), "can-focus", TRUE, NULL);
- gtk_widget_grab_focus (GTK_WIDGET(priv->tbutton));
- }
- }
- else
- {
- g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
-
- /* Mute off grabs focus */
- if (focusable){
- gtk_widget_grab_focus (GTK_WIDGET (self));
- }
- else{
- /* If volumebar is not focusable, focus the parent window instead */
- GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (self),
- GTK_TYPE_WINDOW);
- gtk_window_set_focus (GTK_WINDOW (win), NULL);
- }
- }
-
- /* Update mute button state and redraw */
- gtk_toggle_button_set_active(priv->tbutton, mute);
-
- gtk_widget_queue_draw (GTK_WIDGET (self));
-}
-
-/**
- * hildon_volumebar_get_mute:
- * @self: volume bar to query mute status
- *
- * Gets mute status of this #HildonVolumebar (ON/OFF).
- *
- * Returns: Mute status as #gboolean value.
- */
-gboolean
-hildon_volumebar_get_mute(HildonVolumebar * self)
-{
- HildonVolumebarPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), TRUE);
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- return gtk_toggle_button_get_active(priv->tbutton);
-}
-
-/**
- * hildon_volumebar_get_adjustment
- * @self : a #HildonVolumebar
- *
- * Gets the GtkAdjustment used in volume bar. This can be handy
- * to give to hildon_appview_set_connected_adjustment which
- * will allow changing the volume with increase / decrease
- * hardware buttons.
- *
- * This is a temporary solution until volume bar is restructured to
- * be a child class of GtkRange.
- *
- * Returns: a #GtkAdjustment used by volume bar.
- */
-GtkAdjustment *
-hildon_volumebar_get_adjustment (HildonVolumebar * self)
-{
- HildonVolumebarPrivate *priv;
-
- g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), NULL);
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
-
- return gtk_range_get_adjustment (GTK_RANGE (priv->volumebar));
-}
-
-static void
-mute_toggled (HildonVolumebar *self)
-{
- /* This looks like no-op, but it still does something meaningfull!
- set_mute also updates the ui to match new state that
- is already reported by get_mute */
- hildon_volumebar_set_mute (self, hildon_volumebar_get_mute(self));
-}
-
-static gboolean
-hildon_volumebar_key_press (GtkWidget * widget,
- GdkEventKey * event)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- /* Enter key toggles mute button (unless it is hidden) */
- if (event->keyval == GDK_Return && GTK_WIDGET_VISIBLE(priv->tbutton)) {
- gtk_toggle_button_set_active(priv->tbutton,
- !hildon_volumebar_get_mute(HILDON_VOLUMEBAR(widget)));
- return TRUE;
- }
-
- return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
-}
-
-/* Sends mute-toggled signal to widget, used as a callback in derived classes
- Just keep this "protected" in order to avoid introducing new API. */
-void
-_hildon_volumebar_mute_toggled(HildonVolumebar * self)
-{
- g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
- g_signal_emit_by_name(self, "mute_toggled");
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-#ifndef __HILDON_VOLUMEBAR_H__
-#define __HILDON_VOLUMEBAR_H__
-
-#include <gtk/gtkcontainer.h>
-#include <gtk/gtkadjustment.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_VOLUMEBAR ( hildon_volumebar_get_type() )
-#define HILDON_VOLUMEBAR(obj) (GTK_CHECK_CAST (obj,\
- HILDON_TYPE_VOLUMEBAR, HildonVolumebar))
-#define HILDON_VOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_VOLUMEBAR, HildonVolumebarClass))
-#define HILDON_IS_VOLUMEBAR(obj) (GTK_CHECK_TYPE (obj,\
- HILDON_TYPE_VOLUMEBAR))
-#define HILDON_IS_VOLUMEBAR_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VOLUMEBAR))
-
-typedef struct _HildonVolumebar HildonVolumebar;
-typedef struct _HildonVolumebarClass HildonVolumebarClass;
-
-struct _HildonVolumebar {
- GtkContainer par;
-};
-
-struct _HildonVolumebarClass {
- GtkContainerClass parent_class;
-
- /* signals */
- void (*mute_toggled) (HildonVolumebar * self);
- void (*level_changed) (HildonVolumebar * self);
-};
-
-
-GType hildon_volumebar_get_type (void) G_GNUC_CONST;
-
-double hildon_volumebar_get_level (HildonVolumebar *self);
-void hildon_volumebar_set_level (HildonVolumebar *self,
- gdouble level);
-
-gboolean hildon_volumebar_get_mute (HildonVolumebar *self);
-void hildon_volumebar_set_mute (HildonVolumebar *self,
- gboolean mute);
-
-void hildon_volumebar_level_change (HildonVolumebar *self);
-
-GtkAdjustment * hildon_volumebar_get_adjustment (HildonVolumebar *self);
-
-
-G_END_DECLS
-#endif /* __HILDON_VOLUMEBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * SECTION:hildon-vvolumebar
- * @short_description: A widget that displays a vertical volume bar
- * @see_also: #HildonVolumebar, #HildonHVolumebar
- *
- * #HildonVVolumebar is a subclass of #HildonVolumebar. It displays a
- * vertical volume bar that allows increasing or decreasing volume
- * within a predefined range, and muting when users click the mute icon.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include "hildon-vvolumebar.h"
-#include "hildon-volumebar-range.h"
-#include "hildon-volumebar-private.h"
-
-/* Volume bar */
-#define DEFAULT_BAR_WIDTH 58
-#define MINIMUM_BAR_HEIGHT 165
-/* Toggle button */
-#define DEFAULT_VERTICAL_TBUTTON_WIDTH 26
-#define DEFAULT_VERTICAL_TBUTTON_HEIGHT 26
-#define DEFAULT_ENDING_SIZE 20
-/* Gap to leave for mute button */
-#define HORIZONTAL_MUTE_GAP 16
-#define VERTICAL_MUTE_GAP 6
-
-static HildonVolumebarClass *parent_class;
-static void hildon_vvolumebar_class_init(HildonVVolumebarClass * klass);
-static void hildon_vvolumebar_init(HildonVVolumebar * vvolumebar);
-static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
- GdkEventExpose * event);
-static void hildon_vvolumebar_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void hildon_vvolumebar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-
-GType hildon_vvolumebar_get_type(void)
-{
- static GType type = 0;
-
- if (!type) {
- static const GTypeInfo info = {
- sizeof(HildonVVolumebarClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_vvolumebar_class_init, /* class_init */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonVVolumebar),
- 0,
- (GInstanceInitFunc) hildon_vvolumebar_init,
- };
- type =
- g_type_register_static(HILDON_TYPE_VOLUMEBAR,
- "HildonVVolumebar", &info, 0);
- }
- return type;
-}
-
-static void hildon_vvolumebar_class_init(HildonVVolumebarClass * klass)
-{
- GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
-
- parent_class = g_type_class_peek_parent(klass);
-
- volumebar_class->size_request = hildon_vvolumebar_size_request;
- volumebar_class->size_allocate = hildon_vvolumebar_size_allocate;
- volumebar_class->expose_event = hildon_vvolumebar_expose;
-}
-
-static void hildon_vvolumebar_init(HildonVVolumebar * vvolumebar)
-{
- HildonVolumebarPrivate *priv;
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(vvolumebar);
-
- priv->volumebar =
- HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
- (GTK_ORIENTATION_VERTICAL));
-
- GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(vvolumebar), GTK_CAN_FOCUS);
-
- gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(vvolumebar));
- gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(vvolumebar));
-
- gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
-
- /* Signals */
- g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
- G_CALLBACK(hildon_volumebar_level_change),
- vvolumebar);
- g_signal_connect_swapped(priv->tbutton, "toggled",
- G_CALLBACK(_hildon_volumebar_mute_toggled), vvolumebar);
-
- gtk_widget_show(GTK_WIDGET(priv->volumebar));
-}
-
-/**
- * hildon_vvolumebar_new:
- *
- * Creates a new #HildonVVolumebar widget.
- *
- * Returns: a new #HildonVVolumebar
- */
-GtkWidget *hildon_vvolumebar_new(void)
-{
- return GTK_WIDGET(g_object_new(HILDON_TYPE_VVOLUMEBAR, NULL));
-}
-
-static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
- GdkEventExpose * event)
-{
- HildonVolumebarPrivate *priv;
-
- g_assert(HILDON_IS_VVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
-
- if (GTK_WIDGET_DRAWABLE(widget)) {
- /* Paint background */
- gtk_paint_box(widget->style, widget->window,
- GTK_WIDGET_STATE(priv->volumebar), GTK_SHADOW_OUT,
- NULL, widget, "background",
- widget->allocation.x,
- widget->allocation.y,
- widget->allocation.width,
- widget->allocation.height);
-
- /* The contents of the widget can paint themselves */
- (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
- }
-
- return FALSE;
-}
-
-static void
-hildon_vvolumebar_size_request(GtkWidget * widget,
- GtkRequisition * requisition)
-{
- g_assert(HILDON_IS_VVOLUMEBAR(widget));
-
- requisition->height = MINIMUM_BAR_HEIGHT;
- requisition->width = DEFAULT_BAR_WIDTH;
-}
-
-static void
-hildon_vvolumebar_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonVolumebarPrivate *priv;
-
- GtkAllocation range_allocation, button_allocation;
-
- g_assert(HILDON_IS_VVOLUMEBAR(widget));
-
- priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
-
- /* Center the widget horizontally */
- if (allocation->width > DEFAULT_BAR_WIDTH) {
- allocation->x +=
- (allocation->width - DEFAULT_BAR_WIDTH) / 2;
- allocation->width = DEFAULT_BAR_WIDTH;
- }
-
- GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
-
- if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
- /* Allocate space for the slider */
- range_allocation.x = allocation->x;
- range_allocation.y = allocation->y + DEFAULT_ENDING_SIZE;
-
- range_allocation.width = DEFAULT_BAR_WIDTH;
-
- if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
- {
- /* Leave room for the mute button */
- range_allocation.height = MAX(0,
- allocation->height
- - 2 * DEFAULT_ENDING_SIZE
- - DEFAULT_VERTICAL_TBUTTON_HEIGHT
- - VERTICAL_MUTE_GAP);
- }
-
- else
- {
- range_allocation.height = MAX(0,
- allocation->height
- - 2 * DEFAULT_ENDING_SIZE);
- }
-
- gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),
- &range_allocation);
- }
-
- if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
- /* Allocate space for the mute button */
- button_allocation.x = allocation->x + HORIZONTAL_MUTE_GAP;
- button_allocation.y = allocation->y + allocation->height -
- VERTICAL_MUTE_GAP - 2 * DEFAULT_ENDING_SIZE;
- button_allocation.width = DEFAULT_VERTICAL_TBUTTON_WIDTH;
- button_allocation.height = DEFAULT_VERTICAL_TBUTTON_HEIGHT;
- gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
- &button_allocation);
- }
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_VVOLUMEBAR_H__
-#define __HILDON_VVOLUMEBAR_H__
-
-#include <hildon-widgets/hildon-volumebar.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_VVOLUMEBAR ( hildon_vvolumebar_get_type() )
-
-#define HILDON_VVOLUMEBAR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_VVOLUMEBAR, HildonVVolumebar))
-
-#define HILDON_VVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_VVOLUMEBAR, HildonVVolumebarClass))
-
-#define HILDON_IS_VVOLUMEBAR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_VVOLUMEBAR))
-
-#define HILDON_IS_VVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VVOLUMEBAR))
-
-
-typedef struct _HildonVVolumebar HildonVVolumebar;
-typedef struct _HildonVVolumebarClass HildonVVolumebarClass;
-
-struct _HildonVVolumebar {
- HildonVolumebar volumebar; /* this is our parent class */
-};
-
-struct _HildonVVolumebarClass {
- HildonVolumebarClass parent_class;
-};
-
-GType hildon_vvolumebar_get_type (void) G_GNUC_CONST;
-GtkWidget * hildon_vvolumebar_new (void);
-
-
-G_END_DECLS
-#endif /* __HILDON_VVOLUMEBAR_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-weekday-picker
- * @short_description: A widget for picking days on which a certain event
- * should take place
- * @see_also: #HildonWeekdayPicker
- *
- * #HildonWeekdayPicker supports non-mutually exclusive selection of days of
- * the week. Selected days of the week are shown with a pushed-in effect.
- *
- * #HildonWeekdayPicker is used where users are required to pick days on which
- * a certain event should take place, for example, which days a Calendar event
- * should be repeated on. It is used in Calendar in the Repeat dialog, in Tasks
- * in the Repeat dialog and in the Email set-up wizard.
- */
-
- /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
- according to locale settings first day is sunday. To get around this
- problem, we addjust GDate days numbering to be same as locale
- numbering */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <libintl.h>
-#include <langinfo.h>
-#include <time.h>
-#include <gtk/gtksignal.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtktogglebutton.h>
-#include <gtk/gtksizegroup.h>
-#include <gtk/gtkwindow.h>
-#include "hildon-weekday-picker.h"
-#include "hildon-composite-widget.h"
-
-#define HILDON_WEEKDAY_PICKER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- HILDON_TYPE_WEEKDAY_PICKER, HildonWeekdayPickerPrivate));
-
-static GtkContainerClass *parent_class;
-
-typedef struct _HildonWeekdayPickerPrivate HildonWeekdayPickerPrivate;
-
-static void
-hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class);
-static void
-hildon_weekday_picker_init(HildonWeekdayPicker * picker);
-static void
-hildon_weekday_picker_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation);
-static void
-hildon_weekday_picker_size_request(GtkWidget * widget,
- GtkRequisition * requisition);
-static void
-hildon_weekday_picker_forall(GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback, gpointer callback_data);
-static void
-hildon_weekday_picker_destroy(GtkObject * self);
-
-static void
-button_toggle(GtkToggleButton * togglebutton, gpointer wpicker);
-
-struct _HildonWeekdayPickerPrivate {
- GtkWidget *buttons[8]; /* weekday buttons in show order */
- GtkWidget *day_order_buttons[8]; /* weekday buttons in glib day order */
-};
-
-enum {
- SELECTION_CHANGED_SIGNAL,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-GType hildon_weekday_picker_get_type(void)
-{
- static GType picker_type = 0;
-
- if (!picker_type) {
- static const GTypeInfo picker_info = {
- sizeof(HildonWeekdayPickerClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_weekday_picker_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonWeekdayPicker),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_weekday_picker_init,
- };
- picker_type = g_type_register_static(GTK_TYPE_CONTAINER,
- "HildonWeekdayPicker",
- &picker_info, 0);
- }
- return picker_type;
-}
-
-static void
-hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(picker_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS(picker_class);
- GObjectClass *object_class = G_OBJECT_CLASS(picker_class);
-
- parent_class = g_type_class_peek_parent(picker_class);
-
- g_type_class_add_private(picker_class,
- sizeof(HildonWeekdayPickerPrivate));
-
- /* Override virtual methods */
- widget_class->size_request = hildon_weekday_picker_size_request;
- widget_class->size_allocate = hildon_weekday_picker_size_allocate;
- widget_class->focus = hildon_composite_widget_focus;
- container_class->forall = hildon_weekday_picker_forall;
- GTK_OBJECT_CLASS(picker_class)->destroy =
- hildon_weekday_picker_destroy;
-
- /* Create a signal for reporting user actions */
- signals[SELECTION_CHANGED_SIGNAL] = g_signal_new("selection_changed",
- G_OBJECT_CLASS_TYPE
- (object_class),
- G_SIGNAL_RUN_LAST |
- G_SIGNAL_ACTION,
- G_STRUCT_OFFSET
- (HildonWeekdayPickerClass,
- selection_changed), NULL, NULL,
- gtk_marshal_VOID__INT,
- G_TYPE_NONE, 1, G_TYPE_INT);
-}
-
-static void
-hildon_weekday_picker_init(HildonWeekdayPicker * picker)
-{
- HildonWeekdayPickerPrivate *priv;
- gint i, day;
- /* weekday indexes to be used with nl_langinfo. These are shifted
- * by one for glib compability */
- int wdays[] = {
- -1, /* 0 = invalid date */
- ABDAY_2, /* 1 = monday in glib */
- ABDAY_3, /* 2 = tuesday in glib */
- ABDAY_4, /* 3 = wednesday in glib */
- ABDAY_5, /* 4 = thursday in glib */
- ABDAY_6, /* 5 = friday in glib */
- ABDAY_7, /* 6 = saturday in glib */
- ABDAY_1 }; /* 7 = sunday in glib */
- GtkSizeGroup *sgroup;
-
- sgroup = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
-
- /* Check our first weekday */
- day = *nl_langinfo(_NL_TIME_FIRST_WEEKDAY);
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- /* Shift the days by one. This is done because GDateWeekday
- * starts with Monday(1) and langinfo's first day is Sunday */
- day--;
- if (day < 1)
- day = 7;
-
- /* Initialize and pack day buttons */
- for (i = 1; i <= 7; i++) {
- priv->buttons[i] =
- gtk_toggle_button_new_with_label(nl_langinfo(wdays[day]));
- priv->day_order_buttons[day] = priv->buttons[i];
- day++;
-
- if (day > 7)
- day = 1;
-
- g_signal_connect(GTK_WIDGET(priv->buttons[i]),
- "toggled", G_CALLBACK(button_toggle), picker);
-
- gtk_size_group_add_widget(sgroup, priv->buttons[i]);
-
- gtk_widget_set_parent(priv->buttons[i], GTK_WIDGET(picker));
- gtk_widget_show(priv->buttons[i]);
- }
-
- GTK_WIDGET_SET_FLAGS(picker, GTK_NO_WINDOW);
-
- g_object_unref( sgroup );
-}
-
-/**
- * hildon_weekday_picker_new:
- *
- * Creates a new #HildonWeekdayPicker.
- *
- * Returns: pointer to a new #HildonWeekdayPicker widget.
- */
-GtkWidget *hildon_weekday_picker_new(void)
-{
- return g_object_new(HILDON_TYPE_WEEKDAY_PICKER, NULL);
-}
-
-static void
-hildon_weekday_picker_forall(GtkContainer * container,
- gboolean include_internals, GtkCallback callback,
- gpointer callback_data)
-{
- HildonWeekdayPicker *picker;
- HildonWeekdayPickerPrivate *priv;
- gint i;
-
- g_assert(container);
- g_assert(callback);
-
- picker = HILDON_WEEKDAY_PICKER(container);
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- /* We only have internal children */
- if (!include_internals)
- return;
-
- /* Activate callback for each day button */
- for (i = 1; i <= 7; ++i) {
- (*callback) (priv->buttons[i], callback_data);
- }
-
-}
-
-static void
-hildon_weekday_picker_destroy(GtkObject * self)
-{
- HildonWeekdayPickerPrivate *priv;
- gint i;
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(self);
-
- /* Destroy internal children... */
- for (i = 1; i <= 7; ++i) {
- if (priv->buttons[i])
- {
- gtk_widget_unparent(priv->buttons[i]);
- priv->buttons[i] = NULL;
- }
- }
-
- /* ... and chain to parent. */
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(self);
-
-}
-
-static void
-hildon_weekday_picker_size_request(GtkWidget * widget,
- GtkRequisition *requisition)
-{
- HildonWeekdayPicker *picker;
- HildonWeekdayPickerPrivate *priv;
- gint i;
- GtkRequisition req;
-
- picker = HILDON_WEEKDAY_PICKER(widget);
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
- requisition->width = 0;
- requisition->height = 0;
-
- /* Request an area that is as wide as all of the buttons
- together and tall enough to hold heightest button */
- for (i = 1; i <= 7; ++i) {
- gtk_widget_size_request(priv->buttons[i], &req);
- requisition->width += req.width;
- if (req.height > requisition->height)
- requisition->height = req.height;
-
- }
-}
-
-static void
-hildon_weekday_picker_size_allocate(GtkWidget * widget,
- GtkAllocation * allocation)
-{
- HildonWeekdayPicker *picker;
- HildonWeekdayPickerPrivate *priv;
- gint i;
- GtkAllocation alloc;
- GtkRequisition child_requisition;
- gint header_x;
- guint sval;
- GtkTextDirection direction;
-
- g_assert(widget);
- g_assert(allocation);
-
- /* Check orientation */
- direction = gtk_widget_get_direction(widget);
-
- picker = HILDON_WEEKDAY_PICKER(widget);
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
- header_x = allocation->x;
- widget->allocation = *allocation;
-
- if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
- sval = 1;
- else
- sval = 7;
-
- /* Allocate day buttons side by side honouring the text direction */
- for (i = 1; i <= 7; ++i) {
- gtk_widget_get_child_requisition(priv->buttons[sval],
- &child_requisition);
-
- alloc.x = header_x;
- alloc.y = allocation->y;
- alloc.width = child_requisition.width;
- alloc.height = child_requisition.height;
- header_x += alloc.width;
- gtk_widget_size_allocate(priv->buttons[sval], &alloc);
- if (direction == GTK_TEXT_DIR_RTL)
- sval--;
- else
- sval++;
- }
-}
-
-static void
-button_toggle(GtkToggleButton * button, gpointer wpicker)
-{
- HildonWeekdayPicker *picker;
- HildonWeekdayPickerPrivate *priv;
- gint i;
-
- g_assert(button);
- g_assert(wpicker);
-
- picker = HILDON_WEEKDAY_PICKER(wpicker);
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- for (i = 1; i <= 7; ++i) {
- if (GTK_WIDGET(button) == priv->day_order_buttons[i]) {
- g_signal_emit (GTK_WIDGET(picker),
- signals[SELECTION_CHANGED_SIGNAL], 0, i);
- break;
- }
- }
-}
-
-/**
- * hildon_weekday_picker_set_day:
- * @picker: the #HildonWeekdayPicker widget
- * @day: day to be set active
- *
- * Sets specified weekday active.
- */
-void
-hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
- GDateWeekday day)
-{
- HildonWeekdayPickerPrivate *priv;
-
- g_return_if_fail(picker);
- g_return_if_fail(g_date_valid_weekday(day));
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (priv->day_order_buttons[day]), TRUE);
-}
-
-/**
- * hildon_weekday_picker_unset_day:
- * @picker: the #HildonWeekdayPicker widget
- * @day: day to be set inactive
- *
- * Sets specified weekday inactive.
- */
-void
-hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
- GDateWeekday day)
-{
- HildonWeekdayPickerPrivate *priv;
-
- g_return_if_fail(picker);
- g_return_if_fail(g_date_valid_weekday(day));
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
- (priv->day_order_buttons[day]), FALSE);
-}
-
-/**
- * hildon_weekday_picker_toggle_day:
- * @picker: the #HildonWeekdayPicker widget
- * @day: day to be toggled
- *
- * Toggles current status of the specified weekday.
- */
-void
-hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
- GDateWeekday day)
-{
- HildonWeekdayPickerPrivate *priv;
-
- g_return_if_fail(picker);
- g_return_if_fail(g_date_valid_weekday(day));
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(priv->day_order_buttons[day]),
- !gtk_toggle_button_get_active(
- GTK_TOGGLE_BUTTON(priv->day_order_buttons[day])));
-}
-
-/**
- * hildon_weekday_picker_set_all:
- * @picker: the #HildonWeekdayPicker widget
- *
- * Sets all weekdays active.
- */
-void
-hildon_weekday_picker_set_all(HildonWeekdayPicker * picker)
-{
- HildonWeekdayPickerPrivate *priv;
- gint i;
-
- g_return_if_fail(picker);
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- for (i = 1; i <= 7; i++)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
- TRUE);
-}
-
-/**
- * hildon_weekday_picker_unset_all:
- * @picker: the #HildonWeekdayPicker widget
- *
- * Sets all weekdays inactive.
- */
-void
-hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker)
-{
- HildonWeekdayPickerPrivate *priv;
- gint i;
-
- g_return_if_fail(picker);
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- for (i = 1; i <= 7; i++)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
- FALSE);
-}
-
-/**
- * hildon_weekday_picker_isset_day:
- * @picker: the #HildonWeekdayPicker widget
- * @day: day to be checked.
- *
- * Checks if the specified weekday is set active.
- *
- * Returns: TRUE if the day is set, FALSE if the day is not set
- */
-gboolean
-hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
- GDateWeekday day)
-{
- HildonWeekdayPickerPrivate *priv;
-
- g_return_val_if_fail(picker, FALSE);
- g_return_val_if_fail(g_date_valid_weekday(day), FALSE);
-
- priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
-
- return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
- priv->day_order_buttons[day]));
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_WEEKDAY_PICKER_H__
-#define __HILDON_WEEKDAY_PICKER_H__
-
-#include <gtk/gtkcontainer.h>
-
-G_BEGIN_DECLS
-/**
- * HILDON_TYPE_WEEKDAY_PICKER:
- *
- * Macro for getting type of weekday picker.
- * Since: 0.12.10
- */
-#define HILDON_TYPE_WEEKDAY_PICKER ( hildon_weekday_picker_get_type() )
-
-/**
- * HILDON_WEEKDAY_PICKER_TYPE:
- *
- * Deprecated: use #HILDON_TYPE_WEEKDAY_PICKER instead.
- */
-#define HILDON_WEEKDAY_PICKER_TYPE HILDON_TYPE_WEEKDAY_PICKER
-
-#define HILDON_WEEKDAY_PICKER(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_WEEKDAY_PICKER, \
- HildonWeekdayPicker))
-#define HILDON_WEEKDAY_PICKER_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass), \
- HILDON_TYPE_WEEKDAY_PICKER, HildonWeekdayPickerClass))
-#define HILDON_IS_WEEKDAY_PICKER(obj) \
- (GTK_CHECK_TYPE (obj, HILDON_TYPE_WEEKDAY_PICKER))
-#define HILDON_IS_WEEKDAY_PICKER_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_WEEKDAY_PICKER))
-/**
- * HildonWeekdayPicker:
- *
- * Internal struct for weekday picker.
- */
-typedef struct _HildonWeekdayPicker HildonWeekdayPicker;
-typedef struct _HildonWeekdayPickerClass HildonWeekdayPickerClass;
-
-struct _HildonWeekdayPicker {
- GtkContainer parent;
-};
-
-struct _HildonWeekdayPickerClass {
- GtkContainerClass parent_class;
-
- void (*selection_changed) (HildonWeekdayPicker * self);
-};
-
-GType hildon_weekday_picker_get_type(void) G_GNUC_CONST;
-
-/**
- * hildon_weekday_picker_new:
- *
- * Creates a new #HildonWeekdayPicker.
- *
- * Return value: New #HildonWeekdayPicker.
- **/
-GtkWidget *hildon_weekday_picker_new(void);
-
-/**
- * hildon_weekday_picker_set_day:
- * @picker: #HildonWeekdayPicker.
- * @day: #GDateWeekday.
- *
- * Select specified weekday.
- *
- **/
-void hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
- GDateWeekday day);
-
-/**
- * hildon_weekday_picker_unset_day:
- * @picker: #HildonWeekdayPicker.
- * @day: #GDateWeekday.
- *
- * Unselect specified weekday.
- *
- **/
-void hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
- GDateWeekday day);
-
-/**
- * hildon_weekday_picker_toggle_day:
- * @picker: #HildonWeekdayPicker.
- * @day: #GDateWeekday.
- *
- * Toggle current status of the specified weekday.
- *
- **/
-void hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
- GDateWeekday day);
-
-/**
- * hildon_weekday_picker_set_all:
- * @picker: #HildonWeekdayPicker.
- *
- * Select all weekdays.
- *
- **/
-void hildon_weekday_picker_set_all(HildonWeekdayPicker * picker);
-
-/**
- * hildon_weekday_picker_unset_all:
- * @picker: #HildonWeekdayPicker.
- *
- * Unselect all weekdays.
- *
- **/
-void hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker);
-
-/**
- * hildon_weekday_picker_isset_day:
- * @picker: #HildonWeekdayPicker.
- * @day: #GDateWeekday.
- *
- * Check if the specified weekday is set.
- *
- * Return value: Set/not set.
- **/
-gboolean hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
- GDateWeekday day);
-
-G_END_DECLS
-#endif /* __HILDON_WEEKDAY_PICKER_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_WINDOW_PRIVATE_H__
-#define __HILDON_WINDOW_PRIVATE_H__
-
-G_BEGIN_DECLS
-
-void
-hildon_window_set_program (HildonWindow *self, GObject *program);
-
-void
-hildon_window_unset_program (HildonWindow *self);
-
-void
-hildon_window_set_can_hibernate_property (HildonWindow *self,
- gpointer can_hibernate);
-
-void
-hildon_window_take_common_toolbar (HildonWindow *self);
-
-void
-hildon_window_update_topmost (HildonWindow *self, Window window_id);
-
-Window
-hildon_window_get_active_window (void);
-
-void
-hildon_window_update_title (HildonWindow *window);
-
-G_END_DECLS
-#endif /* __HILDON_WINDOW_PRIVATE_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#include <memory.h>
-#include <string.h>
-#include <strings.h>
-#include <stdio.h>
-#include "hildon-app.h"
-#include <hildon-window.h>
-#include "hildon-program.h"
-#include "hildon-window-private.h"
-#include <hildon-find-toolbar.h>
-
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkimcontext.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkcheckmenuitem.h>
-#include <gtk/gtkmenushell.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtktextview.h>
-#include <gtk/gtkscrolledwindow.h>
-#include <gtk/gtkmain.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk/gdk.h>
-
-#include<gtk/gtkprivate.h>
-
-#include <X11/X.h>
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
-
-#include <libintl.h>
-#define _(String) gettext(String)
-
-/*The size of screen*/
-#define WINDOW_HEIGHT 480
-#define WINDOW_WIDTH 800
-
-#define NAVIGATOR_HEIGHT WINDOW_HEIGHT
-
-#define APPVIEW_HEIGHT 396
-#define APPVIEW_WIDTH 672
-
-#define TOOLBAR_HEIGHT 40
-#define TOOLBAR_MIDDLE 10
-#define TOOLBAR_WIDTH APPVIEW_WIDTH
-
-/*FIXME*/
-#define CAN_HIBERNATE "CANKILL"
-#define CAN_HIBERNATE_LENGTH 7
-
-#define CAN_HIBERNATE_PROPERTY "_HILDON_ABLE_TO_HIBERNATE"
-
-#define TITLE_SEPARATOR " - "
-
-
-#define HILDON_WINDOW_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
- HILDON_TYPE_WINDOW, HildonWindowPrivate))
-
-static GtkWindowClass *parent_class;
-
-static void
-hildon_window_init (HildonWindow * self);
-
-static void
-hildon_window_class_init (HildonWindowClass * window_class);
-
-static void
-hildon_window_menupopupfunc (GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget);
-static void
-hildon_window_menupopupfuncfull (GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget);
-static gboolean
-hildon_window_expose (GtkWidget * widget, GdkEventExpose * event);
-static void
-hildon_window_forall (GtkContainer * container,
- gboolean include_internals,
- GtkCallback callback,
- gpointer callback_data);
-static void
-hildon_window_show_all (GtkWidget *widget);
-
-static void
-hildon_window_size_allocate (GtkWidget * widget,
- GtkAllocation * allocation);
-static void
-hildon_window_size_request (GtkWidget * widget,
- GtkRequisition * requisition);
-static void
-hildon_window_finalize (GObject * obj_self);
-static void
-hildon_window_set_property (GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec);
-static void
-hildon_window_get_property (GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec);
-static void
-hildon_window_destroy (GtkObject *obj);
-static void
-hildon_window_realize (GtkWidget *widget);
-static void
-hildon_window_unrealize (GtkWidget *widget);
-static gboolean
-hildon_window_key_press_event (GtkWidget *widget,
- GdkEventKey *event);
-static gboolean
-hildon_window_key_release_event (GtkWidget *widget,
- GdkEventKey *event);
-static gboolean
-hildon_window_window_state_event (GtkWidget *widget,
- GdkEventWindowState *event);
-
-
-static void
-hildon_window_notify (GObject *gobject, GParamSpec *param);
-
-static void
-hildon_window_is_topmost_notify (HildonWindow *window);
-
-static gboolean
-hildon_window_toggle_menu (HildonWindow * self);
-
-static gboolean
-hildon_window_escape_timeout (gpointer data);
-
-static GdkFilterReturn
-hildon_window_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data );
-
-static GdkFilterReturn
-hildon_window_root_window_event_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data );
-
-static void
-hildon_window_get_borders (HildonWindow *window);
-
-static void
-visible_toolbar (gpointer data, gpointer user_data);
-static void
-paint_toolbar (GtkWidget *widget, GtkBox *box,
- GdkEventExpose * event,
- gboolean fullscreen);
-
-typedef void (*HildonWindowSignal) (HildonWindow *, gint, gpointer);
-
-
-
-enum
-{
- PROP_0,
- PROP_IS_TOPMOST
-};
-
-enum
-{
- WIN_TYPE = 0,
- WIN_TYPE_MESSAGE,
- MAX_WIN_MESSAGES
-};
-
-struct _HildonWindowPrivate
-{
- GtkWidget *menu;
- GtkWidget *vbox;
-
- GtkBorder *borders;
- GtkBorder *toolbar_borders;
-
- GtkAllocation allocation;
-
- guint fullscreen;
- guint is_topmost;
- guint escape_timeout;
- gint visible_toolbars;
- gint previous_vbox_y;
-
- HildonProgram *program;
-};
-
-GType
-hildon_window_get_type (void)
-{
- static GType window_type = 0;
-
- if (!window_type) {
- static const GTypeInfo window_info = {
- sizeof(HildonWindowClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) hildon_window_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(HildonWindow),
- 0, /* n_preallocs */
- (GInstanceInitFunc) hildon_window_init,
- };
- window_type = g_type_register_static(GTK_TYPE_WINDOW,
- "HildonWindow",
- &window_info, 0);
- }
- return window_type;
-}
-
-/* Virtual methods */
-
-static void
-hildon_window_class_init (HildonWindowClass * window_class)
-{
- /* Get convenience variables */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (window_class);
- GObjectClass *object_class = G_OBJECT_CLASS (window_class);
- GtkContainerClass *container_class = GTK_CONTAINER_CLASS (window_class);
-
- /* Set the global parent_class here */
- parent_class = g_type_class_peek_parent (window_class);
-
- object_class->set_property = hildon_window_set_property;
- object_class->get_property = hildon_window_get_property;
- object_class->notify = hildon_window_notify;
-
- /* Set the widgets virtual functions */
- widget_class->size_allocate = hildon_window_size_allocate;
- widget_class->size_request = hildon_window_size_request;
- widget_class->expose_event = hildon_window_expose;
- widget_class->show_all = hildon_window_show_all;
- widget_class->realize = hildon_window_realize;
- widget_class->unrealize = hildon_window_unrealize;
- widget_class->key_press_event = hildon_window_key_press_event;
- widget_class->key_release_event = hildon_window_key_release_event;
- widget_class->window_state_event = hildon_window_window_state_event;
-
- /* now the object stuff */
- object_class->finalize = hildon_window_finalize;
-
- /* To the container */
- container_class->forall = hildon_window_forall;
-
- /* gtkobject stuff*/
- GTK_OBJECT_CLASS (window_class)->destroy = hildon_window_destroy;
-
- g_type_class_add_private (window_class,
- sizeof (struct _HildonWindowPrivate));
-
- /* Install properties */
- g_object_class_install_property (object_class, PROP_IS_TOPMOST,
- g_param_spec_boolean ("is-topmost",
- "Is top-most",
- "Whether the window is currently activated by the window "
- "manager",
- FALSE,
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_boxed ("borders",
- "Graphical borders",
- "Size of graphical window borders",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_boxed ("toolbar-borders",
- "Graphical toolbar borders",
- "Size of graphical toolbar borders",
- GTK_TYPE_BORDER,
- G_PARAM_READABLE));
-
- /* opera hack, install clip operation signal */
- g_signal_new ("clipboard_operation",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (HildonWindowClass, clipboard_operation),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1,
- GTK_TYPE_INT);
-}
-
-static void
-hildon_window_init (HildonWindow * self)
-{
- HildonWindowPrivate *priv = self->priv = HILDON_WINDOW_GET_PRIVATE(self);
-
- self->priv->vbox = gtk_vbox_new (TRUE, TOOLBAR_MIDDLE);
- gtk_widget_set_parent (self->priv->vbox, GTK_WIDGET(self));
- priv->menu = NULL;
- priv->visible_toolbars = 0;
- priv->is_topmost = FALSE;
- priv->borders = NULL;
- priv->toolbar_borders = NULL;
- priv->escape_timeout = 0;
-
- priv->fullscreen = FALSE;
-
- priv->program = NULL;
-
- /* We need to track the root window _MB_CURRENT_APP_WINDOW property */
- gdk_window_set_events (gdk_get_default_root_window (),
- gdk_window_get_events (gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK);
-
- gdk_window_add_filter (gdk_get_default_root_window (),
- hildon_window_root_window_event_filter, self);
-}
-
-static void
-hildon_window_finalize (GObject * obj_self)
-{
- HildonWindow *self;
- g_return_if_fail (HILDON_WINDOW (obj_self));
- self = HILDON_WINDOW (obj_self);
-
- g_free (self->priv->borders);
- g_free (self->priv->toolbar_borders);
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize (obj_self);
-
-}
-
-static void
-hildon_window_realize (GtkWidget *widget)
-{
- Atom *old_atoms, *new_atoms;
- Display *disp;
- Window window;
- gint atom_count;
- Window active_window;
-
- GTK_WIDGET_CLASS (parent_class)->realize (widget);
-
- gtk_widget_realize (GTK_WIDGET (HILDON_WINDOW (widget)->priv->vbox));
-
-
- /* catch the custom button signal from mb to display the menu */
- gdk_window_add_filter (widget->window, hildon_window_event_filter, widget );
-
- window = GDK_WINDOW_XID ( widget->window );
- disp = GDK_WINDOW_XDISPLAY ( widget->window );
-
- /* Enable custom button that is used for menu */
- XGetWMProtocols (disp, window, &old_atoms, &atom_count);
- new_atoms = g_new (Atom, atom_count + 1);
-
- memcpy (new_atoms, old_atoms, sizeof(Atom) * atom_count);
-
- new_atoms[atom_count++] =
- XInternAtom (disp, "_NET_WM_CONTEXT_CUSTOM", False);
-
- XSetWMProtocols (disp, window, new_atoms, atom_count);
-
- XFree(old_atoms);
- g_free(new_atoms);
-
- /* rely on GDK to set the window group to its default */
- gdk_window_set_group (widget->window, NULL);
-
- if (HILDON_WINDOW (widget)->priv->program)
- {
- gboolean can_hibernate = hildon_program_get_can_hibernate (
- HILDON_WINDOW (widget)->priv->program);
-
- hildon_window_set_can_hibernate_property (HILDON_WINDOW (widget),
- &can_hibernate);
- }
-
- /* Update the topmost status */
- active_window = hildon_window_get_active_window();
- hildon_window_update_topmost (HILDON_WINDOW (widget), active_window);
-
- /* Update the window title */
- hildon_window_update_title(HILDON_WINDOW (widget));
-
-}
-
-static void
-hildon_window_unrealize (GtkWidget *widget)
-{
-
- gdk_window_remove_filter (widget->window, hildon_window_event_filter,
- widget);
-
- gtk_widget_unrealize (GTK_WIDGET (HILDON_WINDOW (widget)->priv->vbox));
- GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
-}
-
-static void
-hildon_window_set_property (GObject * object, guint property_id,
- const GValue * value, GParamSpec * pspec)
-{
- /*HildonWindow *window = HILDON_WINDOW (object);*/
-
- switch (property_id) {
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-hildon_window_get_property (GObject * object, guint property_id,
- GValue * value, GParamSpec * pspec)
-{
- HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (object);
-
- switch (property_id) {
-
- case PROP_IS_TOPMOST:
- g_value_set_boolean (value, priv->is_topmost);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
- break;
- }
-}
-
-/*
- * Retrieve the graphical borders size used by the themes
- */
-static void
-hildon_window_get_borders (HildonWindow *window)
-{
-
- g_free (window->priv->borders);
- g_free (window->priv->toolbar_borders);
-
- gtk_widget_style_get (GTK_WIDGET (window), "borders",&window->priv->borders,
- "toolbar-borders", &window->priv->toolbar_borders,
- NULL);
-
- if (!window->priv->borders)
- {
- window->priv->borders = (GtkBorder *)g_malloc0 (sizeof (GtkBorder));
- }
-
- if (!window->priv->toolbar_borders)
- {
- window->priv->toolbar_borders =
- (GtkBorder *)g_malloc0 (sizeof (GtkBorder));
- }
-}
-
-static void
-visible_toolbars (gpointer data, gpointer user_data)
-{
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (((GtkBoxChild *)data)->widget)))
- (*((gint *)user_data)) ++;
-}
-
-static gboolean
-hildon_window_expose (GtkWidget * widget, GdkEventExpose * event)
-{
- HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
- GtkWidget *bx = HILDON_WINDOW(widget)->priv->vbox;
- GtkBox *box = GTK_BOX(bx);
- GtkBorder *b = HILDON_WINDOW(widget)->priv->borders;
- GtkBorder *tb = HILDON_WINDOW(widget)->priv->toolbar_borders;
- gint tb_height = 0;
- gint currently_visible_toolbars = 0;
-
- if (!priv->borders)
- {
- hildon_window_get_borders (HILDON_WINDOW (widget));
- b = HILDON_WINDOW(widget)->priv->borders;
- tb = HILDON_WINDOW(widget)->priv->toolbar_borders;
- }
-
- tb_height = bx->allocation.height + tb->top + tb->bottom;
-
- g_list_foreach (box->children, visible_toolbars,
- ¤tly_visible_toolbars);
-
- paint_toolbar (widget, box,
- event, priv->fullscreen);
-
- if (!HILDON_WINDOW (widget)->priv->fullscreen)
- {
-
- /* Draw the left and right window border */
- gint side_borders_height = widget->allocation.height - b->top;
-
- if (currently_visible_toolbars)
- side_borders_height -= tb_height;
- else
- side_borders_height -= b->bottom;
-
- if (b->left > 0)
- {
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, "left-border",
- widget->allocation.x, widget->allocation.y +
- b->top, b->left, side_borders_height);
- }
-
- if (b->right > 0)
- {
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, "right-border",
- widget->allocation.x + widget->allocation.width -
- b->right, widget->allocation.y + b->top,
- b->right, side_borders_height);
- }
-
- /* If no toolbar, draw the bottom window border */
- if (!currently_visible_toolbars && b->bottom > 0)
- {
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, "bottom-border",
- widget->allocation.x, widget->allocation.y +
- (widget->allocation.height - b->bottom),
- widget->allocation.width, b->bottom);
- }
-
- /* Draw the top border */
- if (b->top > 0)
- {
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, "top-border",
- widget->allocation.x, widget->allocation.y,
- widget->allocation.width, b->top);
- }
-
-
- }
-
- /* don't draw the window stuff as it overwrites our borders with a blank
- * rectangle. Instead start with the drawing of the GtkBin */
- GTK_WIDGET_CLASS (g_type_class_peek_parent (parent_class))->
- expose_event (widget, event);
- /*GTK_WIDGET_CLASS (parent_class))->
- expose_event (widget, event);*/
-
- return FALSE;
-
-}
-
-static void
-hildon_window_size_request (GtkWidget * widget, GtkRequisition * requisition)
-{
- HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
- GtkWidget *child = GTK_BIN (widget)->child;
- GtkRequisition req2;
- gint border_width = GTK_CONTAINER(widget)->border_width;
-
- if (!priv->borders)
- {
- hildon_window_get_borders (HILDON_WINDOW (widget));
- }
-
- if (child)
- gtk_widget_size_request (child, requisition);
-
- if (HILDON_WINDOW (widget)->priv->vbox != NULL)
- gtk_widget_size_request (HILDON_WINDOW (widget)->priv->vbox,
- &req2);
-
- requisition->height += req2.height;
- requisition->width = (requisition->width < req2.width) ?
- req2.width : requisition->width;
-
-
- requisition->width += 2 * border_width;
- requisition->height += 2 * border_width;
-
- if (!priv->fullscreen)
- {
- requisition->height += priv->borders->top;
- if (req2.height == 0)
- requisition->height += priv->borders->bottom;
- requisition->width += priv->borders->left + priv->borders->right;
- }
-}
-
-static void
-hildon_window_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
-{
- HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
- GtkAllocation box_alloc;
- GtkAllocation alloc = *allocation;
- GtkRequisition req;
- gint border_width = GTK_CONTAINER(widget)->border_width;
-
- GtkWidget *box = HILDON_WINDOW(widget)->priv->vbox;
- GtkBin *bin = GTK_BIN(widget);
- GtkBorder *b = HILDON_WINDOW (widget)->priv->borders;
- GtkBorder *tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
-
- if (!priv->borders)
- {
- hildon_window_get_borders (HILDON_WINDOW (widget));
- b = HILDON_WINDOW (widget)->priv->borders;
- tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
- }
-
- widget->allocation = *allocation;
-
- gtk_widget_get_child_requisition (box, &req);
-
- box_alloc.width = allocation->width - tb->left - tb->right;
- box_alloc.height = ( (req.height < allocation->height) ?
- req.height : allocation->height );
- box_alloc.x = allocation->x + tb->left;
- box_alloc.y = allocation->y + allocation->height - box_alloc.height - tb->bottom;
-
- if (bin->child != NULL && GTK_IS_WIDGET (bin->child)
- && GTK_WIDGET_VISIBLE (bin->child))
- {
- alloc.x += border_width;
- alloc.y += border_width;
- alloc.width -= (border_width * 2);
- alloc.height -= (border_width * 2) + box_alloc.height;
-
- if (!(HILDON_WINDOW (widget)->priv->fullscreen))
- {
- alloc.x += b->left;
- alloc.width -= (b->left + b->right);
- alloc.y += b->top;
-
- alloc.height -= b->top;
-
- if (box_alloc.height <= 0)
- alloc.height -= b->bottom;
- else
- alloc.height -= (tb->top + tb->bottom);
- }
- else
- {
- if (!(box_alloc.height <= 0))
- alloc.height -= (tb->top + tb->bottom);
- }
-
- gtk_widget_size_allocate (bin->child, &alloc);
- }
-
-
- gtk_widget_size_allocate (box, &box_alloc);
-
- if (priv->previous_vbox_y != box_alloc.y)
- {
- /* The size of the VBox has changed, we need to redraw part
- * of the window borders */
- gint draw_from_y = priv->previous_vbox_y < box_alloc.y?
- priv->previous_vbox_y - tb->top:
- box_alloc.y - tb->top;
-
- gtk_widget_queue_draw_area (widget, 0, draw_from_y,
- widget->allocation.width,
- widget->allocation.height - draw_from_y);
-
- priv->previous_vbox_y = box_alloc.y;
- }
-
-}
-
-static void
-hildon_window_forall (GtkContainer * container, gboolean include_internals,
- GtkCallback callback, gpointer callback_data)
-{
- HildonWindow *self = HILDON_WINDOW (container);
-
- g_return_if_fail (callback != NULL);
-
- GTK_CONTAINER_CLASS (parent_class)->forall (container, include_internals,
- callback, callback_data);
- if (include_internals && self->priv->vbox != NULL)
- (* callback)(GTK_WIDGET (self->priv->vbox), callback_data);
-}
-
-static void
-hildon_window_show_all (GtkWidget *widget)
-{
- HildonWindow *self = HILDON_WINDOW (widget);
-
- GTK_WIDGET_CLASS (parent_class)->show_all (widget);
- gtk_widget_show_all (self->priv->vbox);
-
-}
-
-static void
-hildon_window_destroy (GtkObject *obj)
-{
- HildonWindow *self = HILDON_WINDOW (obj);
- GList *menu_list;
-
- if (self->priv->vbox != NULL)
- {
- if (self->priv->program)
- {
- GtkWidget * common_toolbar = GTK_WIDGET (
- hildon_program_get_common_toolbar (self->priv->program));
- if (common_toolbar && common_toolbar->parent == self->priv->vbox)
- {
- gtk_container_remove (GTK_CONTAINER (self->priv->vbox),
- common_toolbar);
- }
- }
-
- gtk_widget_unparent (self->priv->vbox);
- self->priv->vbox = NULL;
-
- }
-
- menu_list = g_list_copy (gtk_menu_get_for_attach_widget (GTK_WIDGET (obj)));
-
- while (menu_list)
- {
- if (GTK_IS_MENU(menu_list->data))
- {
- if (GTK_WIDGET_VISIBLE (GTK_WIDGET (menu_list->data)))
- {
- gtk_menu_popdown (GTK_MENU (menu_list->data));
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_list->data));
- }
- gtk_menu_detach (GTK_MENU (menu_list->data));
- }
- menu_list = menu_list->next;
- }
-
- g_list_free (menu_list);
-
- if (self->priv->program)
- {
- hildon_program_remove_window (self->priv->program, self);
- }
-
- gdk_window_remove_filter (gdk_get_default_root_window(),
- hildon_window_root_window_event_filter,
- obj);
-
- gtk_widget_set_events (GTK_WIDGET(obj), 0);
-
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
-
-
-static void
-hildon_window_notify (GObject *gobject, GParamSpec *param)
-{
- HildonWindow *window = HILDON_WINDOW (gobject);
-
- if (strcmp (param->name, "title") == 0)
- {
-
- hildon_window_update_title (window);
- }
- else if (strcmp (param->name, "is-topmost"))
- {
- hildon_window_is_topmost_notify (window);
- }
-
- if (G_OBJECT_CLASS(parent_class)->notify)
- G_OBJECT_CLASS(parent_class)->notify (gobject, param);
-}
-
-/* Utilities */
-
-static void
-visible_toolbar (gpointer data, gpointer user_data)
-{
- if (GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
- (*((gint *)user_data))++;
-}
-
-static void
-find_findtoolbar_index (gpointer data, gpointer user_data)
-{
- gint *pass_bundle = (gint *)user_data;
-
- if(((GtkBoxChild *)data)->widget->allocation.y < pass_bundle[0]
- && GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
- pass_bundle[1]++;
-}
-
-static void
-find_findtoolbar (gpointer data, gpointer user_data)
-{
- if(HILDON_IS_FIND_TOOLBAR (((GtkBoxChild *)data)->widget)
- && GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
- (*((GtkWidget **)user_data)) = ((GtkBoxChild *)data)->widget;
-}
-
-static void
-paint_toolbar (GtkWidget *widget, GtkBox *box,
- GdkEventExpose * event,
- gboolean fullscreen)
-{
- gint toolbar_num = 0;
- gint ftb_index = 0;
- gint count;
- GtkWidget *findtoolbar = NULL;
- gchar toolbar_mode[40];
- GtkBorder *tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
-
- /* collect info to help on painting the boxes */
- g_list_foreach (box->children, visible_toolbar,
- (gpointer) &toolbar_num);
-
- if(toolbar_num <= 0)
- return;
-
- g_list_foreach (box->children, find_findtoolbar, (gpointer) &findtoolbar);
-
- if (findtoolbar != NULL)
- {
- gint pass_bundle[2];/* an array for convient data passing
- the first member contains the y allocation
- of the find toolbar, and the second allocation
- contains the index(how many toolbars are above
- find toolbar) */
- pass_bundle[0] = findtoolbar->allocation.y;
- pass_bundle[1] = ftb_index;
- g_list_foreach(box->children, find_findtoolbar_index,
- (gpointer) pass_bundle);
- ftb_index = pass_bundle[1];
- }
-
- /*upper border*/
- sprintf (toolbar_mode, "toolbar%sframe-top",
- fullscreen ? "-fullscreen-" : "-");
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET (box)->allocation.y - tb->top,
- widget->allocation.width, tb->top);
-
- /*top most toolbar painting*/
- if (findtoolbar != NULL && ftb_index == 0 )
- {
- sprintf (toolbar_mode, "findtoolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y,
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- else
- {
- sprintf (toolbar_mode, "toolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y,
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- /*multi toolbar painting*/
- for (count = 0; count < toolbar_num - 1; count++)
- {
- sprintf (toolbar_mode, "toolbar%sframe-middle",
- fullscreen ? "-fullscreen-" : "-");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * TOOLBAR_HEIGHT +
- count * TOOLBAR_MIDDLE,
- widget->allocation.width,
- TOOLBAR_MIDDLE);
-
- if (findtoolbar != NULL && count + 1 == ftb_index)
- {
-
- sprintf (toolbar_mode, "findtoolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- else
- {
- sprintf (toolbar_mode, "toolbar%s",
- fullscreen ? "-fullscreen" : "");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
- widget->allocation.width,
- TOOLBAR_HEIGHT);
- }
- }
- sprintf (toolbar_mode, "toolbar%sframe-bottom",
- fullscreen ? "-fullscreen-" : "-");
-
- gtk_paint_box (widget->style, widget->window,
- GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
- &event->area, widget, toolbar_mode,
- widget->allocation.x,
- GTK_WIDGET(box)->allocation.y +
- GTK_WIDGET(box)->allocation.height,
- widget->allocation.width, tb->bottom);
-
-}
-
-/*
- * Checks the root window to know which is the topped window
- */
-Window
-hildon_window_get_active_window (void)
-{
- Atom realtype;
- int format;
- int status;
- Window ret;
- unsigned long n;
- unsigned long extra;
- union
- {
- Window *win;
- unsigned char *char_pointer;
- } win;
- Atom active_app_atom =
- XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
-
- win.win = NULL;
-
- status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
- active_app_atom, 0L, 16L,
- 0, XA_WINDOW, &realtype, &format,
- &n, &extra, &win.char_pointer);
- if (!(status == Success && realtype == XA_WINDOW && format == 32
- && n == 1 && win.win != NULL))
- {
- if (win.win != NULL)
- XFree (win.char_pointer);
- return None;
- }
-
- ret = win.win[0];
-
- if (win.win != NULL)
- XFree(win.char_pointer);
-
- return ret;
-}
-
-static int
-xclient_message_type_check (XClientMessageEvent *cm, const gchar *name)
-{
- return cm->message_type == XInternAtom(GDK_DISPLAY(), name, FALSE);
-}
-
-/*****************/
-/* Event filters */
-/*****************/
-
-/*
- * Handle the window border custom button, which toggles the menu,
- * and the Hildon input method copy paste messages
- */
-static GdkFilterReturn
-hildon_window_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
-{
- XAnyEvent *eventti = xevent;
-
- if (eventti->type == ClientMessage)
- {
- XClientMessageEvent *cm = xevent;
-
- if (xclient_message_type_check (cm, "_MB_GRAB_TRANSFER"))
- {
- hildon_window_toggle_menu (HILDON_WINDOW ( data ));
- return GDK_FILTER_REMOVE;
- }
- /* opera hack clipboard client message */
- else if (xclient_message_type_check (cm, "_HILDON_IM_CLIPBOARD_COPY"))
- {
- g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
- HILDON_WINDOW_CO_COPY);
- return GDK_FILTER_REMOVE;
- }
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_CUT"))
- {
- g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
- HILDON_WINDOW_CO_CUT);
- return GDK_FILTER_REMOVE;
- }
- else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_PASTE"))
- {
- g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
- HILDON_WINDOW_CO_PASTE);
- return GDK_FILTER_REMOVE;
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-/*
- * Here we keep track of changes in the _MB_CURRENT_APP_WINDOW,
- * to know when we acquire/lose topmost status
- */
-static GdkFilterReturn
-hildon_window_root_window_event_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- XAnyEvent *eventti = xevent;
- HildonWindow *hwindow = HILDON_WINDOW (data);
-
-
- if (eventti->type == PropertyNotify)
- {
- XPropertyEvent *pevent = xevent;
- Atom active_app_atom =
- XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
-
- if (pevent->atom == active_app_atom)
- {
- Window active_window = hildon_window_get_active_window();
-
- hildon_window_update_topmost (hwindow, active_window);
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-/***************************/
-/* Signal handlers */
-/***************************/
-
-/*
- * Handle the menu hardware key here
- */
-static gboolean
-hildon_window_key_press_event (GtkWidget *widget, GdkEventKey *event)
-{
- HildonWindowPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_WINDOW (widget),FALSE);
-
- priv = HILDON_WINDOW (widget)->priv;
-
- switch (event->keyval)
- {
- case HILDON_HARDKEY_MENU:
- if (hildon_window_toggle_menu (HILDON_WINDOW (widget)))
- return TRUE;
- break;
- case HILDON_HARDKEY_ESC:
- if (!priv->escape_timeout)
- {
- priv->escape_timeout = g_timeout_add
- (HILDON_WINDOW_LONG_PRESS_TIME,
- hildon_window_escape_timeout, widget);
- }
- break;
- }
-
- return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
-
-}
-
-static gboolean
-hildon_window_key_release_event (GtkWidget *widget, GdkEventKey *event)
-{
- HildonWindowPrivate *priv;
-
- g_return_val_if_fail (HILDON_IS_WINDOW (widget),FALSE);
-
- priv = HILDON_WINDOW (widget)->priv;
-
- switch (event->keyval)
- {
- case HILDON_HARDKEY_ESC:
- if (priv->escape_timeout)
- {
- g_source_remove (priv->escape_timeout);
- priv->escape_timeout = 0;
- }
- break;
- }
-
- return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
-
-}
-
-/*
- * We keep track of the window state changes, because the drawing
- * (borders) differs whether we are in fullscreen mode or not
- */
-static gboolean
-hildon_window_window_state_event (GtkWidget *widget,
- GdkEventWindowState *event)
-{
- if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
- {
- HILDON_WINDOW (widget)->priv->fullscreen =
- event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->window_state_event)
- {
- return GTK_WIDGET_CLASS (parent_class)->window_state_event (
- widget,
- event);
- }
- else
- {
- return FALSE;
- }
-}
-
-static void
-hildon_window_title_notify (GObject *gobject,
- GParamSpec *arg1,
- gpointer user_data)
-{
- HildonWindow *window = HILDON_WINDOW (gobject);
-
- hildon_window_update_title (window);
-
-}
-
-/*******************/
-/* General */
-/*******************/
-
-/*The menu popuping needs a menu popup-function*/
-static void
-hildon_window_menupopupfunc (GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in, GtkWidget *widget)
-{
- gint window_x = 0;
- gint window_y = 0;
- GdkWindow *window = GTK_WIDGET(widget)->window;
-
- if (window)
- {
- gdk_window_get_origin (window, &window_x, &window_y);
- }
-
- gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
- "vertical-offset", y, NULL);
-
- *x += window_x;
- *y += window_y;
-
-}
-
-static void
-hildon_window_menupopupfuncfull ( GtkMenu *menu, gint *x, gint *y,
- gboolean *push_in,
- GtkWidget *widget )
-{
- gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
- "vertical-offset", y, NULL);
-
- *x = MAX (0, *x);
- *y = MAX (0, *y);
-}
-
-
-/********************/
-/* Private methods */
-/********************/
-
-
-/*
- * Takes the common toolbar when we acquire the top-most status
- */
-static void
-hildon_window_is_topmost_notify (HildonWindow *window)
-{
- if (window->priv->is_topmost)
- {
- hildon_window_take_common_toolbar (window);
- }
-
- else
- {
- /* If the window lost focus while the user started to press
- * the ESC key, we won't get the release event. We need to
- * stop the timeout*/
- if (window->priv->escape_timeout)
- {
- g_source_remove (window->priv->escape_timeout);
- window->priv->escape_timeout = 0;
- }
- }
-}
-
-/*
- * Sets the program to which the window belongs. This should only be called
- * by hildon_program_add_window
- */
-void
-hildon_window_set_program (HildonWindow *self, GObject *program)
-{
- if (self->priv->program)
- {
- g_object_unref (self->priv->program);
- }
-
- /* Now that we are bound to a program, we can rely on it to track the
- * root window */
- gdk_window_remove_filter (gdk_get_default_root_window(),
- hildon_window_root_window_event_filter,
- self);
-
- self->priv->program = HILDON_PROGRAM (program);
- g_object_ref (program);
-}
-
-/*
- * Unsets the program to which the window belongs. This should only be called
- * by hildon_program_add_window
- */
-void
-hildon_window_unset_program (HildonWindow *self)
-{
- g_return_if_fail(self && HILDON_IS_WINDOW (self));
-
- if (self->priv->program)
- {
- g_object_unref (self->priv->program);
- self->priv->program = NULL;
-
- /* We need to start tacking the root window again */
- gdk_window_set_events (gdk_get_default_root_window (),
- gdk_window_get_events (gdk_get_default_root_window ())
- | GDK_PROPERTY_CHANGE_MASK);
-
- gdk_window_add_filter (gdk_get_default_root_window (),
- hildon_window_root_window_event_filter, self );
- }
-
- self->priv->program = NULL;
-}
-
-/*
- * Sets whether or not the program to which this window belongs is
- * killable. This is used by the HildonProgram to signify to the
- * Task Navigator whether or not it can hibernate in memory-low situations
- **/
-void
-hildon_window_set_can_hibernate_property (HildonWindow *self,
- gpointer _can_hibernate)
-{
- GdkAtom killable_atom;
- gboolean can_hibernate;
-
- g_return_if_fail(self && HILDON_IS_WINDOW (self));
-
- if (!GTK_WIDGET_REALIZED ((GTK_WIDGET (self))))
- {
- return;
- }
-
- can_hibernate = * ((gboolean *)_can_hibernate);
-
- killable_atom = gdk_atom_intern (CAN_HIBERNATE_PROPERTY, FALSE);
-
- if (can_hibernate)
- {
- gdk_property_change (GTK_WIDGET (self)->window, killable_atom,
- (GdkAtom)31/* XA_STRING */, 8,
- GDK_PROP_MODE_REPLACE, (const guchar *)CAN_HIBERNATE,
- CAN_HIBERNATE_LENGTH);
- }
- else
- {
- gdk_property_delete (GTK_WIDGET (self)->window, killable_atom);
- }
-
-}
-
-/*
- * If a common toolbar was set to the program, reparent it to
- * us
- */
-void
-hildon_window_take_common_toolbar (HildonWindow *self)
-{
- g_return_if_fail(self && HILDON_IS_WINDOW (self));
-
- if (self->priv->program)
- {
- GtkWidget *common_toolbar =
- GTK_WIDGET (hildon_program_get_common_toolbar (self->priv->program));
-
- if (common_toolbar && common_toolbar->parent != self->priv->vbox)
- {
- g_object_ref (common_toolbar);
- if (common_toolbar->parent)
- {
- gtk_container_remove (GTK_CONTAINER (common_toolbar->parent),
- common_toolbar);
- }
-
- gtk_box_pack_end (GTK_BOX(self->priv->vbox), common_toolbar,
- TRUE, TRUE, 0);
- g_object_unref (common_toolbar);
-
- gtk_widget_set_size_request (common_toolbar, -1, TOOLBAR_HEIGHT);
-
- gtk_widget_show (self->priv->vbox);
-
- }
- }
-}
-
-/*
- * Compare the window that was last topped, and act consequently
- */
-void
-hildon_window_update_topmost (HildonWindow *self, Window window_id)
-{
- Window my_window;
-
- my_window = GDK_WINDOW_XID (GTK_WIDGET (self)->window);
-
- if (window_id == my_window)
- {
- if (!self->priv->is_topmost)
- {
- self->priv->is_topmost = TRUE;
- hildon_window_is_topmost_notify (self);
- g_object_notify (G_OBJECT (self), "is-topmost");
- }
- }
- else if (self->priv->is_topmost)
- {
- /* Should this go in the signal handler? */
- GtkWidget *focus = gtk_window_get_focus (GTK_WINDOW (self));
-
- if (GTK_IS_ENTRY (focus))
- gtk_im_context_focus_out (GTK_ENTRY (focus)->im_context);
- if (GTK_IS_TEXT_VIEW (focus))
- gtk_im_context_focus_out (GTK_TEXT_VIEW (focus)->im_context);
-
- self->priv->is_topmost = FALSE;
- hildon_window_is_topmost_notify (self);
- g_object_notify (G_OBJECT (self), "is-topmost");
-
- }
-}
-
-/*
- * If the application
- * was given a name (with g_set_application_name(), set
- * "ProgramName - WindowTitle" as the displayed
- * title
- */
-void
-hildon_window_update_title (HildonWindow *window)
-{
- const gchar * application_name;
- g_return_if_fail (window && HILDON_IS_WINDOW (window));
-
- if (!GTK_WIDGET_REALIZED (window))
- {
- return;
- }
-
- application_name = g_get_application_name ();
-
- if (application_name && application_name[0])
- {
- const gchar *old_title = gtk_window_get_title (GTK_WINDOW (window));
-
- if (old_title && old_title[0])
- {
- gchar *title = NULL;
-
- title = g_strjoin (TITLE_SEPARATOR, application_name,
- old_title, NULL);
-
- gdk_window_set_title (GTK_WIDGET (window)->window, title);
-
- g_free (title);
- }
-
- }
-}
-
-static void
-detach_menu_func (GtkWidget *attach_widget, GtkMenu *menu)
-{
-}
-/*
- * Toggles the display of the HildonWindow menu.
- * Returns whether or not something was done (whether or not we had a menu
- * to toggle)
- */
-static gboolean
-hildon_window_toggle_menu (HildonWindow * self)
-{
- GtkMenu *menu_to_use = NULL;
- GList *menu_children = NULL;
-
- g_return_val_if_fail (self && HILDON_IS_WINDOW (self), FALSE);
-
- /* Select which menu to use, Window specific has highest priority,
- * then program specific */
- if (self->priv->menu)
- {
- menu_to_use = GTK_MENU (self->priv->menu);
- }
- else if (self->priv->program)
- {
- menu_to_use = hildon_program_get_common_menu (self->priv->program);
- if (menu_to_use && gtk_menu_get_attach_widget (menu_to_use) !=
- GTK_WIDGET (self))
- {
- g_object_ref (menu_to_use);
- if (gtk_menu_get_attach_widget (menu_to_use))
- {
- gtk_menu_detach (menu_to_use);
- }
-
- gtk_menu_attach_to_widget (menu_to_use, GTK_WIDGET (self),
- &detach_menu_func);
- g_object_unref (menu_to_use);
- }
- }
-
- if (!menu_to_use)
- {
- return FALSE;
- }
-
-
- if (GTK_WIDGET_MAPPED (GTK_WIDGET (menu_to_use)))
- {
- gtk_menu_popdown (menu_to_use);
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_to_use));
- return TRUE;
- }
-
- /* Check if the menu has items */
- menu_children = gtk_container_get_children (GTK_CONTAINER (menu_to_use));
-
- if (menu_children)
- {
- g_list_free (menu_children);
-
- /* Apply right theming */
- gtk_widget_set_name (GTK_WIDGET (menu_to_use),
- "menu_force_with_corners");
-
- if (self->priv->fullscreen)
- {
- gtk_menu_popup (menu_to_use, NULL, NULL,
- (GtkMenuPositionFunc)
- hildon_window_menupopupfuncfull,
- self, 0,
- gtk_get_current_event_time ());
- }
- else
- {
- gtk_menu_popup (menu_to_use, NULL, NULL,
- (GtkMenuPositionFunc)
- hildon_window_menupopupfunc,
- self, 0,
- gtk_get_current_event_time ());
- }
- gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_to_use), TRUE);
- return TRUE;
- }
-
- return FALSE;
-
-}
-
-/*
- * If the ESC key was not released when the timeout expires,
- * close the window
- */
-static gboolean
-hildon_window_escape_timeout (gpointer data)
-{
- HildonWindowPrivate *priv;
- GdkEvent *event;
-
- GDK_THREADS_ENTER ();
-
- priv = HILDON_WINDOW(data)->priv;
-
- /* Send fake event, simulation a situation that user
- pressed 'x' from the corner */
- event = gdk_event_new(GDK_DELETE);
- ((GdkEventAny *)event)->window = GDK_WINDOW (g_object_ref (GTK_WIDGET(data)->window));
- gtk_main_do_event(event);
-
- /* That unrefs the window, so we're reffing it above */
- gdk_event_free(event);
-
- priv->escape_timeout = 0;
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
-
-/******************/
-/* public methods */
-/******************/
-
-
-/**
- * hildon_window_new:
- *
- * Use this function to create a new HildonWindow.
- *
- * Return value: A @HildonWindow.
- **/
-GtkWidget *
-hildon_window_new (void)
-{
- HildonWindow *newwindow = g_object_new (HILDON_TYPE_WINDOW, NULL);
-
- return GTK_WIDGET (newwindow);
-}
-
-/**
- * hildon_window_add_with_scrollbar
- * @self : A @HildonWindow
- * @child : A @GtkWidget
- *
- * Adds the @child to the HildonWindow and creates a scrollbar
- * to it. Similar as adding first a @GtkScrolledWindow and then the
- * @child to it.
- */
-void
-hildon_window_add_with_scrollbar (HildonWindow * self,
- GtkWidget * child)
-{
- GtkScrolledWindow *scrolledw;
-
- g_return_if_fail (HILDON_IS_WINDOW (self));
- g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (child->parent == NULL);
-
- scrolledw = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL));
- gtk_scrolled_window_set_policy (scrolledw, GTK_POLICY_NEVER,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (scrolledw, GTK_SHADOW_NONE);
-
- if (GTK_IS_VIEWPORT (child))
- gtk_container_add (GTK_CONTAINER (scrolledw), child);
- else
- {
- if (GTK_IS_CONTAINER (child) )
- gtk_container_set_focus_vadjustment (GTK_CONTAINER(child),
- gtk_scrolled_window_get_vadjustment (scrolledw) );
- gtk_scrolled_window_add_with_viewport (scrolledw, child);
- }
-
- gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (scrolledw));
-}
-
-/**
- * hildon_window_add_toolbar:
- * @self: A @HildonWindow
- * @toolbar: A #GtkToolbar to add to the HildonWindow
- *
- * Adds a toolbar to the window.
- **/
-void
-hildon_window_add_toolbar (HildonWindow *self, GtkToolbar *toolbar)
-{
- GtkBox *vbox;
-
- g_return_if_fail (self && HILDON_IS_WINDOW (self));
- g_return_if_fail (toolbar && GTK_IS_TOOLBAR (toolbar));
-
- vbox = GTK_BOX (self->priv->vbox);
-
- gtk_box_pack_start (vbox, GTK_WIDGET(toolbar), TRUE, TRUE, 0);
- gtk_box_reorder_child (vbox, GTK_WIDGET(toolbar), 0);
- gtk_widget_set_size_request (GTK_WIDGET (toolbar), -1, TOOLBAR_HEIGHT);
-
- gtk_widget_queue_resize (GTK_WIDGET(self));
-}
-
-/**
- * hildon_window_remove_toolbar:
- * @self: A @HildonWindow
- * @toolbar: A #GtkToolbar to remove from the HildonWindow
- *
- * Removes a toolbar from the window.
- **/
-void
-hildon_window_remove_toolbar (HildonWindow *self, GtkToolbar *toolbar)
-{
- GtkContainer *vbox = GTK_CONTAINER (self->priv->vbox);
-
- g_return_if_fail (self && HILDON_IS_WINDOW (self));
-
- gtk_container_remove (vbox, GTK_WIDGET(toolbar));
-}
-
-/**
- * hildon_window_get_menu:
- * @self : #HildonWindow
- *
- * Gets the #GtMenu assigned to the #HildonAppview.
- *
- * Return value: The #GtkMenu assigned to this application view.
- **/
-GtkMenu *
-hildon_window_get_menu (HildonWindow * self)
-{
- g_return_val_if_fail (self && HILDON_IS_WINDOW (self), NULL);
-
- return GTK_MENU (self->priv->menu);
-}
-
-
-/**
- * hildon_window_set_menu:
- * @self: A #HildonWindow
- * @menu: The #GtkMenu to be used for this #HildonWindow
- *
- * Sets the menu to be used for this window. This menu overrides
- * a program-wide menu that may have been set with
- * hildon_program_set_common_menu. Pass NULL to remove the current
- * menu.
- **/
-void
-hildon_window_set_menu (HildonWindow *self, GtkMenu *menu)
-{
- g_return_if_fail (HILDON_IS_WINDOW (self));
-
- if (self->priv->menu != NULL) {
- gtk_menu_detach (GTK_MENU (self->priv->menu));
- g_object_unref (self->priv->menu);
- }
-
- self->priv->menu = (menu != NULL) ? GTK_WIDGET (menu) : NULL;
- if (self->priv->menu != NULL) {
- gtk_widget_set_name (self->priv->menu, "menu_force_with_corners");
- gtk_menu_attach_to_widget (GTK_MENU (self->priv->menu), GTK_WIDGET (self), &detach_menu_func);
- g_object_ref (GTK_MENU (self->priv->menu));
- gtk_widget_show_all (GTK_WIDGET (self->priv->menu));
- }
-}
-
-/**
- * hildon_window_get_is_topmost:
- * @self: A #HildonWindow
- *
- * Return value: Whether or not the #HildonWindow is currenltly activated
- * by the window manager.
- **/
-gboolean
-hildon_window_get_is_topmost(HildonWindow *self){
- g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
-
- return self->priv->is_topmost;
-}
-
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-
-#ifndef __HILDON_WINDOW_H__
-#define __HILDON_WINDOW_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtktoolbar.h>
-#include <gdk/gdkx.h>
-
-#include "hildon-defines.h"
-
-G_BEGIN_DECLS
-
-#define HILDON_WINDOW_LONG_PRESS_TIME 1500 /* in ms */
-
-#define HILDON_TYPE_WINDOW ( hildon_window_get_type() )
-#define HILDON_WINDOW(obj) \
- (GTK_CHECK_CAST (obj, HILDON_TYPE_WINDOW, HildonWindow))
-#define HILDON_WINDOW_CLASS(klass) \
- (GTK_CHECK_CLASS_CAST ((klass),\
- HILDON_TYPE_WINDOW, HildonWindowClass))
-#define HILDON_IS_WINDOW(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_WINDOW))
-#define HILDON_IS_WINDOW_CLASS(klass) \
- (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_WINDOW))
-
-typedef struct _HildonWindow HildonWindow;
-typedef struct _HildonWindowClass HildonWindowClass;
-
-/**
- * HildonWindowPrivate:
- *
- * This structure contains just internal data.
- * It should not be accessed directly.
- */
-typedef struct _HildonWindowPrivate HildonWindowPrivate;
-
-struct _HildonWindow
-{
- GtkWindow parent;
-
- /*private*/
- HildonWindowPrivate *priv;
-};
-
-enum
-{
- HILDON_WINDOW_CO_COPY,
- HILDON_WINDOW_CO_CUT,
- HILDON_WINDOW_CO_PASTE
-};
-
-struct _HildonWindowClass
-{
- GtkWindowClass parent_class;
-
- /* opera hacks for clip board operation */
- void (*clipboard_operation)(HildonWindow *hwindow, int operation);
- /* Padding for future extension */
- void (*_hildon_reserved1)(void);
- void (*_hildon_reserved2)(void);
- void (*_hildon_reserved3)(void);
-};
-
-
-GType hildon_window_get_type (void);
-
-GtkWidget * hildon_window_new (void);
-
-void hildon_window_add_with_scrollbar(HildonWindow *self,
- GtkWidget *child);
-
-GtkMenu * hildon_window_get_menu (HildonWindow *self);
-void hildon_window_set_menu (HildonWindow *self,
- GtkMenu *menu);
-
-void hildon_window_add_toolbar (HildonWindow *self,
- GtkToolbar *toolbar);
-
-void hildon_window_remove_toolbar (HildonWindow *self,
- GtkToolbar *toolbar);
-
-gboolean hildon_window_get_is_topmost (HildonWindow *self);
-
-
-G_END_DECLS
-#endif /* __HILDON_WINDOW_H__ */
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- * Fixes: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/**
- * SECTION:hildon-wizard-dialog
- * @short_description: A widget to create a guided installation
- * process wizard
- *
- * #HildonWizardDialog is a widget to create a guided installation
- * process. The dialog has four standard buttons, previous, next,
- * finish, cancel, and contains several pages with optional icons.
- * Response buttons are dimmed/undimmed automatically and the standard
- * icon is shown/hidden in response to page navigation. The notebook
- * widget provided by users contains the actual wizard pages.
- */
-
-#include <gtk/gtkdialog.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtkbox.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkvbox.h>
-#include <gtk/gtkbutton.h>
-#include <hildon-widgets/hildon-defines.h>
-
-#include "hildon-wizard-dialog.h"
-
-#include <libintl.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#define _(String) dgettext(PACKAGE, String)
-
-static GtkDialogClass *parent_class;
-
-static void class_init (HildonWizardDialogClass *wizard_dialog_class);
-
-static void init (HildonWizardDialog *wizard_dialog);
-
-static void create_title (HildonWizardDialog *wizard_dialog);
-
-static void set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void finalize (GObject *object);
-
-static void response (HildonWizardDialog *wizard,
- gint response_id,
- gpointer unused);
-
-static void make_buttons_sensitive (HildonWizardDialog *wizard_dialog,
- gboolean previous,
- gboolean finish,
- gboolean next);
-
-enum {
- PROP_ZERO,
- PROP_WIZARD_NAME,
- PROP_WIZARD_NOTEBOOK,
- PROP_WIZARD_AUTOTITLE
-};
-
-struct _HildonWizardDialogPrivate {
- gchar *wizard_name;
- GtkNotebook *notebook;
- GtkBox *box;
- GtkWidget *image;
- gboolean autotitle;
-};
-
-
-GType
-hildon_wizard_dialog_get_type (void)
-{
- static GType wizard_dialog_type = 0;
-
- if (!wizard_dialog_type) {
-
- static const GTypeInfo wizard_dialog_info = {
- sizeof (HildonWizardDialogClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (HildonWizardDialog),
- 0, /* n_preallocs */
- (GInstanceInitFunc) init,
- };
-
- wizard_dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
- "HildonWizardDialog",
- &wizard_dialog_info,
- 0);
- }
-
- return wizard_dialog_type;
-}
-
-static void
-class_init (HildonWizardDialogClass *wizard_dialog_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (wizard_dialog_class);
-
- parent_class = g_type_class_peek_parent (wizard_dialog_class);
-
- g_type_class_add_private (wizard_dialog_class,
- sizeof(HildonWizardDialogPrivate));
-
- /* Override virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
-
- /**
- * HildonWizardDialog:wizard-name:
- *
- * The name of the wizard.
- */
- g_object_class_install_property (object_class, PROP_WIZARD_NAME,
- g_param_spec_string
- ("wizard-name",
- "Wizard Name",
- "The name of the HildonWizardDialog",
- NULL,
- G_PARAM_READWRITE));
-
- /**
- * HildonWizardDialog:wizard-notebook:
- *
- * The notebook object, which is used by the HildonWizardDialog.
- */
- g_object_class_install_property(object_class, PROP_WIZARD_NOTEBOOK,
- g_param_spec_object
- ("wizard-notebook",
- "Wizard Notebook",
- "GtkNotebook object to be used in the "
- "HildonWizardDialog",
- GTK_TYPE_NOTEBOOK, G_PARAM_READWRITE));
-
- /**
- * HildonWizardDialog:autotitle
- *
- * If the wizard should automatically try to change the window title when changing steps.
- * Set to FALSE if you'd like to override the default behaviour.
- *
- * Since: 0.14.5
- */
- g_object_class_install_property(object_class, PROP_WIZARD_AUTOTITLE,
- g_param_spec_boolean
- ("autotitle",
- "AutoTitle",
- "If the wizard should autotitle itself",
- TRUE,
- G_PARAM_READWRITE));
-}
-
-static void
-finalize (GObject *object)
-{
- HildonWizardDialog *dialog = HILDON_WIZARD_DIALOG (object);
- g_return_if_fail (dialog != NULL);
-
- if (dialog->priv->wizard_name != NULL)
- g_free (HILDON_WIZARD_DIALOG (object)->priv->wizard_name);
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize(object);
-}
-
-/* Disable or enable the Previous, Next and Finish buttons */
-static void
-make_buttons_sensitive (HildonWizardDialog *wizard_dialog,
- gboolean previous,
- gboolean finish,
- gboolean next)
-{
- gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
- HILDON_WIZARD_DIALOG_PREVIOUS,
- previous);
-
- gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
- HILDON_WIZARD_DIALOG_FINISH,
- finish);
-
- gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
- HILDON_WIZARD_DIALOG_NEXT,
- next);
-}
-
-static void
-init (HildonWizardDialog *wizard_dialog)
-{
- /* Initialize private structure for faster member access */
- HildonWizardDialogPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (wizard_dialog,
- HILDON_TYPE_WIZARD_DIALOG,
- HildonWizardDialogPrivate);
-
- GtkDialog *dialog = GTK_DIALOG (wizard_dialog);
-
- /* Init internal widgets */
- GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
- gtk_dialog_set_has_separator (dialog, FALSE);
- wizard_dialog->priv = priv;
- priv->box = GTK_BOX (gtk_hbox_new (FALSE, 0));
- priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard",
- HILDON_ICON_SIZE_WIDG_WIZARD);
-
- /* Default values for user provided properties */
- priv->notebook = NULL;
- priv->wizard_name = NULL;
- priv->autotitle = TRUE;
-
- /* Build wizard layout */
- gtk_box_pack_start_defaults (GTK_BOX (dialog->vbox), GTK_WIDGET (priv->box));
- gtk_box_pack_start_defaults (GTK_BOX (priv->box), GTK_WIDGET (vbox));
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0);
-
- /* Add response buttons: finish, previous, next, cancel */
- gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_finish"), HILDON_WIZARD_DIALOG_FINISH);
- gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_previous"), HILDON_WIZARD_DIALOG_PREVIOUS);
- gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_next"), HILDON_WIZARD_DIALOG_NEXT);
- gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_cancel"), HILDON_WIZARD_DIALOG_CANCEL);
-
- /* Set initial button states: previous and finish buttons are disabled */
- make_buttons_sensitive (wizard_dialog, FALSE, FALSE, TRUE);
-
- /* Show all the internal widgets */
- gtk_widget_show_all (GTK_WIDGET (dialog->vbox));
-
- /* connect to dialog's response signal */
- g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (response), NULL);
-}
-
-static void
-set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- HildonWizardDialogPrivate *priv = HILDON_WIZARD_DIALOG(object)->priv;
-
- switch (property_id) {
-
- case PROP_WIZARD_AUTOTITLE:
-
- priv->autotitle = g_value_get_boolean (value);
-
- if (priv->autotitle &&
- priv->wizard_name &&
- priv->notebook)
- create_title (HILDON_WIZARD_DIALOG (object));
- else if (priv->wizard_name)
- gtk_window_set_title (GTK_WINDOW (object), priv->wizard_name);
-
- break;
-
- case PROP_WIZARD_NAME:
-
- /* Set new wizard name. This name will appear in titlebar */
- if (priv->wizard_name)
- g_free (priv->wizard_name);
-
- gchar *str = (gchar *) g_value_get_string (value);
- g_return_if_fail (str != NULL);
-
- priv->wizard_name = g_strdup (str);
-
- /* We need notebook in order to create title, since page information
- is used in title generation */
-
- if (priv->notebook && priv->autotitle)
- create_title (HILDON_WIZARD_DIALOG (object));
-
- break;
-
- case PROP_WIZARD_NOTEBOOK: {
-
- GtkNotebook *book = GTK_NOTEBOOK (g_value_get_object (value));
- g_return_if_fail (book != NULL);
-
- priv->notebook = book;
-
- /* Set the default properties for the notebook (disable tabs,
- * and remove borders) to make it look like a nice wizard widget */
- gtk_notebook_set_show_tabs (priv->notebook, FALSE);
- gtk_notebook_set_show_border (priv->notebook, FALSE);
- gtk_box_pack_start_defaults (GTK_BOX( priv->box), GTK_WIDGET (priv->notebook));
-
- /* Show the notebook so that a gtk_widget_show on the dialog is
- * all that is required to display the dialog correctly */
- gtk_widget_show (priv->notebook);
-
- /* Update dialog title to reflect current page stats etc */
- if (priv->wizard_name && priv->autotitle)
- create_title (HILDON_WIZARD_DIALOG (object));
-
- } break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- HildonWizardDialogPrivate *priv = HILDON_WIZARD_DIALOG (object)->priv;
-
- switch (property_id) {
-
- case PROP_WIZARD_NAME:
- g_value_set_string (value, priv->wizard_name);
- break;
-
- case PROP_WIZARD_NOTEBOOK:
- g_value_set_object (value, priv->notebook);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-/*
- * Creates the title of the dialog taking into account the current
- * page of the notebook.
- */
-static void
-create_title (HildonWizardDialog *wizard_dialog)
-{
- gint pages, current;
- gchar *str = NULL;
- HildonWizardDialogPrivate *priv = wizard_dialog->priv;
- GtkNotebook *notebook = priv->notebook;
-
- if (!notebook)
- return;
-
- /* Get page information, we'll need that when creating title */
- pages = gtk_notebook_get_n_pages (notebook);
- current = gtk_notebook_get_current_page (priv->notebook);
- if (current < 0)
- current = 0;
-
- /* the welcome title on the initial page */
- if (current == 0) {
- str = g_strdup_printf (_("ecdg_ti_wizard_welcome"),
- priv->wizard_name, pages);
- } else {
- const gchar *steps = gtk_notebook_get_tab_label_text (notebook,
- gtk_notebook_get_nth_page (notebook, current));
-
- str = g_strdup_printf (_("ecdg_ti_wizard_step"),
- priv->wizard_name, current + 1, pages, steps);
- }
-
- /* Update the dialog to display the generated title */
- gtk_window_set_title (GTK_WINDOW (wizard_dialog), str);
- g_free (str);
-}
-
-/*
- * Response signal handler. This function is needed because GtkDialog's
- * handler for this signal closes the dialog and we don't want that, we
- * want to change pages and, dimm certain response buttons. Overriding the
- * virtual function would not work because that would be called after the
- * signal handler implemented by GtkDialog.
- * FIXME: There is a much saner way to do that [MDK]
- */
-static void
-response (HildonWizardDialog *wizard_dialog,
- gint response_id,
- gpointer unused)
-{
- HildonWizardDialogPrivate *priv = wizard_dialog->priv;
- GtkNotebook *notebook = priv->notebook;
- gint current = 0;
- gint last = gtk_notebook_get_n_pages (notebook) - 1;
- gboolean is_first, is_last;
-
- switch (response_id) {
-
- case HILDON_WIZARD_DIALOG_PREVIOUS:
- gtk_notebook_prev_page (notebook); /* go to previous page */
- break;
-
- case HILDON_WIZARD_DIALOG_NEXT:
- gtk_notebook_next_page (notebook); /* go to next page */
- break;
-
- case HILDON_WIZARD_DIALOG_CANCEL:
- case HILDON_WIZARD_DIALOG_FINISH:
- return;
-
- }
-
- current = gtk_notebook_get_current_page (notebook);
- is_last = current == last;
- is_first = current == 0;
-
- /* If first page, previous and finish are disabled,
- if last page, next is disabled */
- make_buttons_sensitive (wizard_dialog,
- !is_first, !is_first, !is_last);
-
- /* Don't let the dialog close */
- g_signal_stop_emission_by_name (wizard_dialog, "response");
-
- /* We show the default image on first and last pages */
- if (current == last || current == 0)
- gtk_widget_show (GTK_WIDGET(priv->image));
- else
- gtk_widget_hide (GTK_WIDGET(priv->image));
-
- /* New page number may appear in the title, update it */
- if (priv->autotitle)
- create_title (wizard_dialog);
-}
-
-/**
- * hildon_wizard_dialog_new:
- * @parent: a #GtkWindow
- * @wizard_name: the name of dialog
- * @notebook: the notebook to be shown on the dialog
- *
- * Creates a new #HildonWizardDialog.
- *
- * Returns: a new #HildonWizardDialog
- */
-GtkWidget*
-hildon_wizard_dialog_new (GtkWindow *parent,
- const char *wizard_name,
- GtkNotebook *notebook)
-{
- GtkWidget *widget;
-
- g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
-
- widget = GTK_WIDGET (g_object_new
- (HILDON_TYPE_WIZARD_DIALOG,
- "wizard-name", wizard_name,
- "wizard-notebook", notebook, NULL));
-
- if (parent)
- gtk_window_set_transient_for (GTK_WINDOW (widget), parent);
-
- return widget;
-}
+++ /dev/null
-/*
- * This file is part of hildon-libs
- *
- * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
- *
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- * Fixes: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef __HILDON_WIZARD_DIALOG_H__
-#define __HILDON_WIZARD_DIALOG_H__
-
-#include <gtk/gtkwidget.h>
-#include <gtk/gtkwindow.h>
-#include <gtk/gtknotebook.h>
-#include <gtk/gtkdialog.h>
-
-G_BEGIN_DECLS
-
-#define HILDON_TYPE_WIZARD_DIALOG (hildon_wizard_dialog_get_type())
-
-#define HILDON_WIZARD_DIALOG(obj) (GTK_CHECK_CAST ((obj), \
- HILDON_TYPE_WIZARD_DIALOG, HildonWizardDialog))
-
-#define HILDON_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
- HILDON_TYPE_WIZARD_DIALOG, HildonWizardDialogClass))
-
-#define HILDON_IS_WIZARD_DIALOG(obj) (GTK_CHECK_TYPE ((obj), \
- HILDON_TYPE_WIZARD_DIALOG))
-
-#define HILDON_IS_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
- HILDON_TYPE_WIZARD_DIALOG))
-
-typedef struct _HildonWizardDialog HildonWizardDialog;
-
-typedef struct _HildonWizardDialogClass HildonWizardDialogClass;
-
-typedef struct _HildonWizardDialogPrivate HildonWizardDialogPrivate;
-
-/* button response IDs */
-enum {
- HILDON_WIZARD_DIALOG_CANCEL = GTK_RESPONSE_CANCEL,
- HILDON_WIZARD_DIALOG_PREVIOUS = 0,
- HILDON_WIZARD_DIALOG_NEXT,
- HILDON_WIZARD_DIALOG_FINISH
-};
-
-struct _HildonWizardDialog {
- GtkDialog parent;
- HildonWizardDialogPrivate *priv;
-};
-
-struct _HildonWizardDialogClass {
- GtkDialogClass parent_class;
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-
-GType hildon_wizard_dialog_get_type (void) G_GNUC_CONST;
-
-GtkWidget* hildon_wizard_dialog_new (GtkWindow *parent,
- const char *wizard_name,
- GtkNotebook *notebook);
-
-G_END_DECLS
-
-#endif /* __HILDON_WIZARD_DIALOG_H__ */
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in
+
+INCLUDES = $(GTK_CFLAGS) $(GCONF_CFLAGS) -DLOCALEDIR=\"$(localedir)\" \
+ -I$(srcdir)/..
+
+LDFLAGS = -module -avoid-version
+LIBADD = -L$(srcdir)/../hildon-widgets/.libs -lhildonwidgets $(GTK_LIBS)
+
+pluginwidgetdir = $(libdir)/hildon-widgets
+pluginwidget_LTLIBRARIES = hildoncolorchooser_hsv.la \
+ hildoncolorchooserdialog_hsv.la
+
+hildoncolorchooser_hsv_la_SOURCES = hildon-color-chooser-hsv.c
+
+hildoncolorchooserdialog_hsv_la_SOURCES = hildon-color-chooser-dialog-hsv.c
+hildoncolorchooserdialog_hsv_la_LIBADD = $(GCONF_LIBS)
+
+install-exec-local: installdirs
+ @echo "Creating default symlink for color chooser..."
+ @ln -f -s 'hildoncolorchooser_hsv.so' '$(DESTDIR)/$(libdir)/hildon-widgets/hildoncolorchooser_default.so'
+ @echo "Creating default symlink for color chooser dialog..."
+ @ln -f -s 'hildoncolorchooserdialog_hsv.so' '$(DESTDIR)/$(libdir)/hildon-widgets/hildoncolorchooserdialog_default.so'
+
+
+
+
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#include <memory.h>
+#include <string.h>
+
+#include <libintl.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gtk/gtk.h>
+
+#include <gconf/gconf-client.h>
+
+
+#include <hildon-widgets/hildon-color-chooser-dialog.h>
+#include <hildon-widgets/hildon-color-chooser.h>
+
+#include <hildon-widgets/hildon-plugin-widget.h>
+
+#include <hildon-widgets/hildon-defines.h>
+
+#include <hildon-widgets/hildon-banner.h>
+
+
+#define _(String) dgettext("hildon-libs", String)
+
+
+const char *parent_name = "HildonColorChooserDialog";
+const char *plugin_name = "HSV color chooser dialog";
+
+GType export_type(void);
+
+
+static HildonPluginWidgetInfo *chooser_plugin = NULL;
+
+static HildonColorChooserDialogClass *parent_klass = NULL;
+
+
+/* darkened EGA palette to be used as predefined colors if style doesn't
+ define anything else (darker colors are darkened 0x8000 -> 0x6666) */
+static GdkColor hardcoded_colors[16] = {{0, 0x0000, 0x0000, 0x0000},
+ {0, 0x6666, 0x6666, 0x6666},
+ {0, 0x6666, 0x0000, 0x0000},
+ {0, 0x0000, 0x6666, 0x0000},
+ {0, 0x0000, 0x0000, 0x6666},
+ {0, 0x6666, 0x6666, 0x0000},
+ {0, 0x6666, 0x0000, 0x6666},
+ {0, 0x0000, 0x6666, 0x6666},
+ {0, 0xffff, 0xffff, 0xffff},
+ {0, 0xc000, 0xc000, 0xc000},
+ {0, 0xffff, 0x0000, 0x0000},
+ {0, 0x0000, 0xffff, 0x0000},
+ {0, 0x0000, 0x0000, 0xffff},
+ {0, 0xffff, 0xffff, 0x0000},
+ {0, 0xffff, 0x0000, 0xffff},
+ {0, 0x0000, 0xffff, 0xffff}};
+
+
+typedef struct {
+ GtkBorder radio_sizes;
+ GtkBorder cont_sizes;
+ GtkBorder num_buttons;
+ GtkBorder last_num_buttons;
+
+ GdkColor default_color;
+} HildonColorChooserStyleInfo;
+
+
+typedef struct _HildonColorChooserDialogHSV HildonColorChooserDialogHSV;
+typedef struct _HildonColorChooserDialogHSVClass HildonColorChooserDialogHSVClass;
+
+
+struct _HildonColorChooserDialogHSV {
+ HildonColorChooserDialog parent;
+
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+
+ GtkWidget *align_custom, *align_defined;
+ GtkWidget *area_custom, *area_defined;
+ GtkWidget *separator;
+
+ GtkWidget *chooser;
+
+ GdkColor *colors_custom, *colors_defined;
+ GdkGC **gc_array;
+
+ gint selected;
+
+ HildonColorChooserStyleInfo style_info;
+
+
+ gint has_style;
+
+ GdkColor pending_color;
+
+
+ struct {
+ GConfClient *client;
+ } gconf_data;
+};
+
+struct _HildonColorChooserDialogHSVClass {
+ HildonColorChooserDialogClass parent_klass;
+};
+
+
+#define HILDON_COLOR_CHOOSER_DIALOG_HSV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), export_type(), HildonColorChooserDialogHSV))
+#define HILDON_COLOR_CHOOSER_DIALOG_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), export_type(), HildonColorChooserDialogHSVClass))
+
+
+GtkType export_type(void);
+
+
+static void hildon_color_chooser_dialog_hsv_init(HildonColorChooserDialogHSV *object);
+static void hildon_color_chooser_dialog_hsv_class_init(HildonColorChooserDialogHSVClass *klass);
+
+static void hildon_color_chooser_dialog_hsv_size_request(GtkWidget *widget, GtkRequisition *req);
+static void hildon_color_chooser_dialog_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
+
+static void hildon_color_chooser_dialog_hsv_realize(GtkWidget *widget);
+static void hildon_color_chooser_dialog_hsv_unrealize(GtkWidget *widget);
+
+static void hildon_color_chooser_dialog_hsv_style_set(GtkWidget *widget, GtkStyle *previous_style);
+
+static void hildon_color_chooser_dialog_hsv_show(GtkWidget *widget);
+static void hildon_color_chooser_dialog_hsv_show_all(GtkWidget *widget);
+
+static gboolean hildon_color_chooser_dialog_hsv_key_press_event(GtkWidget *widget, GdkEventKey *event);
+static gboolean hildon_color_chooser_dialog_hsv_key_release_event(GtkWidget *widget, GdkEventKey *event);
+
+
+static void hildon_color_chooser_dialog_hsv_destroy(GtkObject *object);
+
+
+static void hildon_color_chooser_dialog_hsv_set_color(HildonColorChooserDialog *dialog, GdkColor *color);
+
+
+static gboolean hildon_color_chooser_dialog_hsv_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data);
+
+static gboolean hildon_color_chooser_dialog_hsv_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data);
+
+
+static void hildon_color_chooser_dialog_hsv_chooser_color_changed(HildonColorChooser *chooser, GdkColor *color, gpointer data);
+
+static void hildon_color_chooser_dialog_hsv_chooser_insensitive_press(GtkWidget *widget, gpointer data);
+
+
+static void hildon_color_chooser_dialog_hsv_refresh_style_info(HildonColorChooserDialogHSV *dialog);
+
+static void hildon_color_chooser_dialog_hsv_set_color_num(HildonColorChooserDialogHSV *dialog, gint num);
+
+static void hildon_color_chooser_dialog_hsv_ascii_hex_to_color(gchar *s, GdkColor *color);
+static void hildon_color_chooser_dialog_hsv_color_to_ascii_hex(gchar *s, GdkColor *color);
+
+
+GType export_type()
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info =
+ {
+ sizeof (HildonColorChooserDialogHSVClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) hildon_color_chooser_dialog_hsv_class_init,
+ NULL,
+ NULL,
+ sizeof (HildonColorChooserDialogHSV),
+ 0,
+ (GInstanceInitFunc) hildon_color_chooser_dialog_hsv_init,
+ NULL
+ };
+
+ dialog_type = g_type_register_static (HILDON_TYPE_COLOR_CHOOSER_DIALOG, "HildonColorChooserDialogHSV", &dialog_info, 0);
+ }
+
+ return dialog_type;
+}
+
+
+static void hildon_color_chooser_dialog_hsv_init(HildonColorChooserDialogHSV *object)
+{
+ if(!chooser_plugin) {
+ chooser_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER, "hsv");
+ }
+
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(object), FALSE);
+
+ gtk_window_set_title(GTK_WINDOW(object), _("ecdg_ti_colour_selector"));
+
+
+ object->chooser = hildon_plugin_info_construct_widget(chooser_plugin);
+
+ object->hbox = gtk_hbox_new(FALSE, 0);
+ object->vbox = gtk_vbox_new(FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(object->hbox), object->chooser, TRUE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(object->hbox), object->vbox, FALSE, FALSE, 0);
+
+
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(object)->vbox), object->hbox, TRUE, TRUE, 0);
+
+
+ object->align_custom = gtk_alignment_new(0.5, 1.0, 0.0, 0.0);
+ object->align_defined = gtk_alignment_new(0.5, 1.0, 0.0, 0.0);
+
+ object->area_custom = gtk_drawing_area_new();
+ object->area_defined = gtk_drawing_area_new();
+
+
+ gtk_container_add(GTK_CONTAINER(object->align_custom), object->area_custom);
+ gtk_container_add(GTK_CONTAINER(object->align_defined), object->area_defined);
+
+
+ object->separator = gtk_hseparator_new();
+
+
+ gtk_box_pack_start(GTK_BOX(object->vbox), object->align_defined, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(object->vbox), object->separator, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(object->vbox), object->align_custom, FALSE, FALSE, 0);
+
+
+ gtk_dialog_add_button(GTK_DIALOG(object), _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
+ gtk_dialog_add_button(GTK_DIALOG(object), _("ecdg_bd_colour_selector_cancel"), GTK_RESPONSE_CANCEL);
+ gtk_dialog_set_default_response (GTK_DIALOG (object), GTK_RESPONSE_OK);
+
+
+ g_signal_connect(G_OBJECT(object->chooser), "insensitive-press", G_CALLBACK(hildon_color_chooser_dialog_hsv_chooser_insensitive_press), object);
+
+
+ g_signal_connect(G_OBJECT(object->area_custom), "expose-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_expose), object);
+ g_signal_connect(G_OBJECT(object->area_defined), "expose-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_expose), object);
+
+ g_signal_connect(G_OBJECT(object->area_custom), "button-press-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_button_press), object);
+ g_signal_connect(G_OBJECT(object->area_defined), "button-press-event", G_CALLBACK(hildon_color_chooser_dialog_hsv_area_button_press), object);
+
+ gtk_widget_add_events(object->area_custom, GDK_BUTTON_PRESS_MASK);
+ gtk_widget_add_events(object->area_defined, GDK_BUTTON_PRESS_MASK);
+
+
+ object->selected = 0;
+
+
+ g_signal_connect(G_OBJECT(object->chooser), "color-changed", G_CALLBACK(hildon_color_chooser_dialog_hsv_chooser_color_changed), object);
+
+
+ object->gconf_data.client = gconf_client_get_default();
+
+
+ memset(&object->style_info, 0, sizeof(HildonColorChooserStyleInfo));
+
+
+ object->colors_custom = NULL;
+ object->colors_defined = NULL;
+
+ object->gc_array = NULL;
+
+
+ object->has_style = 0;
+}
+
+static void hildon_color_chooser_dialog_hsv_class_init(HildonColorChooserDialogHSVClass *klass)
+{
+ GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS(klass);
+ GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
+ HildonColorChooserDialogClass *dialog_klass = HILDON_COLOR_CHOOSER_DIALOG_CLASS(klass);
+ gchar tmp[32];
+ gint i;
+
+
+ widget_klass->size_request = hildon_color_chooser_dialog_hsv_size_request;
+ widget_klass->size_allocate = hildon_color_chooser_dialog_hsv_size_allocate;
+
+ widget_klass->realize = hildon_color_chooser_dialog_hsv_realize;
+ widget_klass->unrealize = hildon_color_chooser_dialog_hsv_unrealize;
+
+ widget_klass->style_set = hildon_color_chooser_dialog_hsv_style_set;
+
+ widget_klass->show = hildon_color_chooser_dialog_hsv_show;
+ widget_klass->show_all = hildon_color_chooser_dialog_hsv_show_all;
+
+ widget_klass->key_press_event = hildon_color_chooser_dialog_hsv_key_press_event;
+ widget_klass->key_release_event = hildon_color_chooser_dialog_hsv_key_release_event;
+
+
+ object_klass->destroy = hildon_color_chooser_dialog_hsv_destroy;
+
+
+ dialog_klass->set_color = hildon_color_chooser_dialog_hsv_set_color;
+
+
+ parent_klass = g_type_class_peek_parent(klass);
+
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("container_sizes",
+ "Container sizes",
+ "Container specific sizes",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("radio_sizes",
+ "Color radio sizes",
+ "Color radio specific sizes",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("num_buttons",
+ "Number of buttons",
+ "Number of color store buttons",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("default_color", "Default color",
+ "Default color for nonpainted custom colors",
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+
+
+ for(i = 0; i < 32; i++) {
+ memset(tmp, 0, 32);
+ g_snprintf(tmp, 32, "defined_color%d", i);
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed(tmp, "Defined color",
+ "Pre-defined colors for the dialog",
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+ }
+}
+
+
+static void hildon_color_chooser_dialog_hsv_size_request(GtkWidget *widget, GtkRequisition *req)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+
+
+ gtk_container_set_border_width(GTK_CONTAINER(dialog->hbox), dialog->style_info.cont_sizes.left);
+
+ gtk_box_set_spacing(GTK_BOX(dialog->hbox), dialog->style_info.cont_sizes.right);
+ gtk_box_set_spacing(GTK_BOX(dialog->vbox), dialog->style_info.cont_sizes.top);
+ gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(widget)->vbox), dialog->style_info.cont_sizes.bottom);
+
+
+ gtk_widget_set_size_request(dialog->area_custom,
+ (dialog->style_info.radio_sizes.left + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.top) +
+ (dialog->style_info.num_buttons.top-1)*dialog->style_info.radio_sizes.top,
+ (dialog->style_info.radio_sizes.right + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.bottom) +
+ (dialog->style_info.num_buttons.bottom-1)*dialog->style_info.radio_sizes.top);
+ gtk_widget_set_size_request(dialog->area_defined,
+ (dialog->style_info.radio_sizes.left + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.left) +
+ (dialog->style_info.num_buttons.left-1)*dialog->style_info.radio_sizes.top,
+ (dialog->style_info.radio_sizes.right + 2*dialog->style_info.radio_sizes.bottom)*(dialog->style_info.num_buttons.right) +
+ (dialog->style_info.num_buttons.right-1)*dialog->style_info.radio_sizes.top);
+
+
+ GTK_WIDGET_CLASS(parent_klass)->size_request(widget, req);
+}
+
+static void hildon_color_chooser_dialog_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+ GdkRectangle rect;
+ int i, tmp, tmp2;
+
+
+ GTK_WIDGET_CLASS(parent_klass)->size_allocate(widget, alloc);
+
+
+ if(GTK_WIDGET_REALIZED(widget)) {
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+ tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ rect.x = ((i % dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.y = ((i / dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.width = dialog->style_info.radio_sizes.left;
+ rect.height = dialog->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle(dialog->gc_array[i], &rect);
+ }
+
+ for(i = 0; i < tmp2; i++) {
+ rect.x = ((i % dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.y = ((i / dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.width = dialog->style_info.radio_sizes.left;
+ rect.height = dialog->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle(dialog->gc_array[i + tmp], &rect);
+ }
+ }
+}
+
+
+static void hildon_color_chooser_dialog_hsv_realize(GtkWidget *widget)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+ GdkRectangle rect;
+ int i, tmp, tmp2;
+
+
+ GTK_WIDGET_CLASS(parent_klass)->realize(widget);
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
+ (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ dialog->gc_array[i] = gdk_gc_new(widget->window);
+ }
+
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+ tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ gdk_gc_set_rgb_fg_color(dialog->gc_array[i], &dialog->colors_defined[i]);
+
+ rect.x = ((i % dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.y = ((i / dialog->style_info.num_buttons.left) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.width = dialog->style_info.radio_sizes.left;
+ rect.height = dialog->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle(dialog->gc_array[i], &rect);
+ }
+
+ for(i = 0; i < tmp2; i++) {
+ gdk_gc_set_rgb_fg_color(dialog->gc_array[i + tmp], &dialog->colors_custom[i]);
+
+ rect.x = ((i % dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.y = ((i / dialog->style_info.num_buttons.top) * (dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top +
+ 2*dialog->style_info.radio_sizes.bottom)) + dialog->style_info.radio_sizes.bottom;
+ rect.width = dialog->style_info.radio_sizes.left;
+ rect.height = dialog->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle(dialog->gc_array[i + tmp], &rect);
+ }
+}
+
+static void hildon_color_chooser_dialog_hsv_unrealize(GtkWidget *widget)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+ int i, tmp;
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
+ (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ g_object_unref(dialog->gc_array[i]);
+ }
+
+
+ GTK_WIDGET_CLASS(parent_klass)->unrealize(widget);
+}
+
+
+static void hildon_color_chooser_dialog_hsv_style_set(GtkWidget *widget, GtkStyle *previous_style)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+ GdkColor *tmpcolor;
+ gchar tmp[32], key[128], *val;
+ int i, tmpn, setcolor = 0;
+
+
+ if(!dialog->has_style)
+ setcolor = 1;
+
+ dialog->has_style = 1;
+
+
+ gtk_widget_style_get(widget, "default_color", &tmpcolor, NULL);
+ if(tmpcolor) {
+ dialog->style_info.default_color = *tmpcolor;
+ } else {
+ dialog->style_info.default_color.red = 0x0000;
+ dialog->style_info.default_color.green = 0x0000;
+ dialog->style_info.default_color.blue = 0x0000;
+ dialog->style_info.default_color.pixel = 0x00000000;
+ }
+
+
+ hildon_color_chooser_dialog_hsv_refresh_style_info(dialog);
+
+
+ if(memcmp(&dialog->style_info.num_buttons, &dialog->style_info.last_num_buttons, sizeof(GtkBorder))) {
+ if(dialog->colors_custom) {
+ g_free(dialog->colors_custom);
+ } if(dialog->colors_defined) {
+ g_free(dialog->colors_defined);
+ } if(dialog->gc_array) {
+ if(GTK_WIDGET_REALIZED(widget)) {
+ tmpn = (dialog->style_info.last_num_buttons.left * dialog->style_info.last_num_buttons.right) +
+ (dialog->style_info.last_num_buttons.top * dialog->style_info.last_num_buttons.bottom);
+
+ for(i = 0; i < tmpn; i++) {
+ g_object_unref(dialog->gc_array[i]);
+ }
+ }
+
+ g_free(dialog->gc_array);
+ }
+
+ dialog->colors_custom = (GdkColor *)g_malloc0(sizeof(GdkColor) * (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom));
+ dialog->colors_defined = (GdkColor *)g_malloc0(sizeof(GdkColor) * (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right));
+
+
+ tmpn = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) +
+ (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+ dialog->gc_array = (GdkGC **)g_malloc0(sizeof(GdkGC *) * tmpn);
+
+
+ if(dialog->gconf_data.client) {
+ for(i = 0; i < (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom); i++) {
+ memset(key, 0, 128);
+ g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
+ val = gconf_client_get_string(dialog->gconf_data.client, key, NULL);
+ if(val) {
+ hildon_color_chooser_dialog_hsv_ascii_hex_to_color(val, &dialog->colors_custom[i]);
+ g_free(val);
+ } else {
+ dialog->colors_custom[i] = dialog->style_info.default_color;
+ }
+ }
+ } else {
+ for(i = 0; i < (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom); i++) {
+ dialog->colors_custom[i] = dialog->style_info.default_color;
+ }
+ }
+ }
+
+
+ tmpn = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+
+ hildon_color_chooser_set_color(HILDON_COLOR_CHOOSER(dialog->chooser),
+ (dialog->selected < tmpn) ? &dialog->colors_defined[dialog->selected] : &dialog->colors_custom[dialog->selected - tmpn]);
+
+
+ for(i = 0; i < (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right); i++) {
+ memset(tmp, 0, 32);
+ g_snprintf(tmp, 32, "defined_color%d", i);
+
+ gtk_widget_style_get(widget, tmp, &tmpcolor, NULL);
+
+ if(tmpcolor) {
+ dialog->colors_defined[i] = *tmpcolor;
+ } else {
+ if(i < 16) {
+ dialog->colors_defined[i] = hardcoded_colors[i];
+ } else { /* fallback to prevent segfault */
+ dialog->colors_defined[i].red = 0x0000;
+ dialog->colors_defined[i].green = 0x0000;
+ dialog->colors_defined[i].blue = 0x0000;
+ dialog->colors_defined[i].pixel = 0x00000000;
+ }
+ }
+ }
+
+
+ if(GTK_WIDGET_REALIZED(widget)) {
+ for(i = 0; i < (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right); i++) {
+ gdk_gc_set_rgb_fg_color(dialog->gc_array[i], &dialog->colors_defined[i]);
+ }
+ }
+
+
+ if(setcolor)
+ hildon_color_chooser_dialog_hsv_set_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &dialog->pending_color);
+
+
+ gtk_widget_queue_resize(widget);
+
+
+ GTK_WIDGET_CLASS(parent_klass)->style_set(widget, previous_style);
+}
+
+
+static void hildon_color_chooser_dialog_hsv_show(GtkWidget *widget)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+
+
+ gtk_widget_show(dialog->hbox);
+ gtk_widget_show(dialog->vbox);
+
+ gtk_widget_show(dialog->chooser);
+
+ gtk_widget_show(dialog->align_custom);
+ gtk_widget_show(dialog->align_defined);
+
+ gtk_widget_show(dialog->separator);
+
+ gtk_widget_show(dialog->area_custom);
+ gtk_widget_show(dialog->area_defined);
+
+
+ GTK_WIDGET_CLASS(parent_klass)->show(widget);
+}
+
+static void hildon_color_chooser_dialog_hsv_show_all(GtkWidget *widget)
+{
+ hildon_color_chooser_dialog_hsv_show(widget);
+}
+
+
+static gboolean hildon_color_chooser_dialog_hsv_key_press_event(GtkWidget *widget, GdkEventKey *event)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(widget);
+ int tmp, tot, sel;
+
+
+ if(event->keyval == HILDON_HARDKEY_UP || event->keyval == HILDON_HARDKEY_DOWN ||
+ event->keyval == HILDON_HARDKEY_LEFT || event->keyval == HILDON_HARDKEY_RIGHT) {
+ tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+ tot = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right) + tmp;
+
+ switch(event->keyval) {
+ case HILDON_HARDKEY_UP:
+ if(dialog->selected >= dialog->style_info.num_buttons.top) {
+ if(dialog->selected - dialog->style_info.num_buttons.left >= tmp) {
+ sel = dialog->selected - dialog->style_info.num_buttons.left;
+ } else {
+ sel = dialog->selected - dialog->style_info.num_buttons.top;
+ }
+
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
+ }
+ break;
+ case HILDON_HARDKEY_DOWN:
+ if(dialog->selected < tot - dialog->style_info.num_buttons.left) {
+ if(dialog->selected < tmp) {
+ sel = dialog->selected + dialog->style_info.num_buttons.top;
+ } else {
+ sel = dialog->selected + dialog->style_info.num_buttons.left;
+ }
+
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
+ }
+ break;
+ case HILDON_HARDKEY_LEFT:
+ if((dialog->selected < tmp ? (dialog->selected % dialog->style_info.num_buttons.top) : ((dialog->selected - tmp) % dialog->style_info.num_buttons.left)) > 0) {
+ sel = dialog->selected - 1;
+
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
+ }
+ break;
+ case HILDON_HARDKEY_RIGHT:
+ if((dialog->selected < tmp) ? (dialog->selected % dialog->style_info.num_buttons.top < dialog->style_info.num_buttons.top - 1) :
+ ((dialog->selected - tmp) % dialog->style_info.num_buttons.left < dialog->style_info.num_buttons.left - 1)) {
+ sel = dialog->selected + 1;
+
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog, sel);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+ }
+
+ return GTK_WIDGET_CLASS(parent_klass)->key_press_event(widget, event);
+}
+
+static gboolean hildon_color_chooser_dialog_hsv_key_release_event(GtkWidget *widget, GdkEventKey *event)
+{
+ if(event->keyval == HILDON_HARDKEY_UP || event->keyval == HILDON_HARDKEY_DOWN ||
+ event->keyval == HILDON_HARDKEY_LEFT || event->keyval == HILDON_HARDKEY_RIGHT) {
+ return FALSE;
+ }
+
+ return GTK_WIDGET_CLASS(parent_klass)->key_press_event(widget, event);
+}
+
+
+static void hildon_color_chooser_dialog_hsv_destroy(GtkObject *object)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(object);
+ gchar key[128], color[13];
+ int i, tmp;
+
+
+ if(dialog->gconf_data.client) {
+ memset(color, 0, 13);
+
+ tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ memset(key, 0, 128);
+ g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
+ hildon_color_chooser_dialog_hsv_color_to_ascii_hex(color, &dialog->colors_custom[i]);
+ gconf_client_set_string(dialog->gconf_data.client, key, color, NULL);
+ }
+
+ g_object_unref(dialog->gconf_data.client);
+ dialog->gconf_data.client = NULL;
+ }
+
+
+ if(dialog->gc_array) {
+ g_free(dialog->gc_array);
+ dialog->gc_array = NULL;
+ } if(dialog->colors_defined) {
+ g_free(dialog->colors_defined);
+ dialog->colors_defined = NULL;
+ } if(dialog->colors_custom) {
+ g_free(dialog->colors_custom);
+ dialog->colors_custom = NULL;
+ }
+
+
+ GTK_OBJECT_CLASS(parent_klass)->destroy(object);
+}
+
+
+static void hildon_color_chooser_dialog_hsv_set_color(HildonColorChooserDialog *dialog, GdkColor *color)
+{
+ HildonColorChooserDialogHSV *dialog_hsv = HILDON_COLOR_CHOOSER_DIALOG_HSV(dialog);
+ int i, found = -1, tmp, tmp2;
+
+
+ if(!dialog_hsv->has_style) {
+ dialog_hsv->pending_color = *color;
+ return;
+ }
+
+
+ tmp = (dialog_hsv->style_info.num_buttons.left * dialog_hsv->style_info.num_buttons.right);
+ tmp2 = (dialog_hsv->style_info.num_buttons.top * dialog_hsv->style_info.num_buttons.bottom);
+
+ for(i = 0; i < tmp; i++) {
+ if(dialog_hsv->colors_defined[i].red == color->red &&
+ dialog_hsv->colors_defined[i].green == color->green &&
+ dialog_hsv->colors_defined[i].blue == color->blue) {
+ found = i;
+ break;
+ }
+ }
+
+ if(found == -1) {
+ for(i = 0; i < tmp2; i++) {
+ if(dialog_hsv->colors_custom[i].red == color->red &&
+ dialog_hsv->colors_custom[i].green == color->green &&
+ dialog_hsv->colors_custom[i].blue == color->blue) {
+ found = i + tmp;
+ break;
+ }
+ }
+ }
+
+
+ if(found == -1) {
+ dialog_hsv->colors_custom[tmp2-1] = *color;
+ if(GTK_WIDGET_REALIZED(GTK_WIDGET(dialog))) {
+ gdk_gc_set_rgb_fg_color(dialog_hsv->gc_array[tmp2-1], color);
+ }
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog_hsv, tmp2-1);
+ } else {
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog_hsv, found);
+ }
+}
+
+
+static gboolean hildon_color_chooser_dialog_hsv_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
+ int i, num_selected, tot_w, tot_h, spacing, brd, x, y;
+ GdkGC **start_gc;
+ int tmp, w, h;
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+
+ if(widget == dialog->area_custom) {
+ num_selected = dialog->selected - tmp;
+ start_gc = dialog->gc_array + tmp;
+ tmp = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+ w = dialog->style_info.num_buttons.top; h = dialog->style_info.num_buttons.bottom;
+ } else { /* widget == dialog->area_defined */
+ num_selected = dialog->selected;
+ start_gc = dialog->gc_array;
+ w = dialog->style_info.num_buttons.left; h = dialog->style_info.num_buttons.right;
+ }
+
+ spacing = dialog->style_info.radio_sizes.top;
+ brd = dialog->style_info.radio_sizes.bottom;
+ tot_w = dialog->style_info.radio_sizes.left + 2*brd;
+ tot_h = dialog->style_info.radio_sizes.right + 2*brd;
+
+
+ for(i = 0; i < tmp; i++) {
+ x = ((i % w) * (tot_w + spacing));
+ y = ((i / w) * (tot_h + spacing));
+
+ gdk_draw_rectangle(widget->window,
+ widget->style->black_gc,
+ TRUE,
+ (i == num_selected) ? x : x + 2,
+ (i == num_selected) ? y : y + 2,
+ (i == num_selected) ? tot_w : tot_w - 4,
+ (i == num_selected) ? tot_h : tot_h - 4);
+
+ gdk_draw_rectangle(widget->window,
+ widget->style->white_gc,
+ TRUE,
+ x + 3,
+ y + 3,
+ tot_w - 6,
+ tot_h - 6);
+
+ gdk_draw_rectangle(widget->window,
+ start_gc [i],
+ TRUE,
+ x + 3 + 1,
+ y + 3 + 1,
+ tot_w - 6 - 2,
+ tot_h - 6 - 2);
+
+// gtk_paint_box(gtk_widget_get_style(GTK_WIDGET(dialog)), widget->window, (i == num_selected) ? GTK_STATE_SELECTED : GTK_STATE_NORMAL,
+// (i == num_selected) ? GTK_SHADOW_IN : GTK_SHADOW_OUT, &event->area, GTK_WIDGET(dialog), "color-radio", x, y, tot_w, tot_h);
+ //}
+
+ //gdk_draw_rectangle(widget->window, start_gc[i], TRUE, event->area.x, event->area.y, event->area.width, event->area.height);
+ }
+
+
+ return FALSE;
+}
+
+
+static gboolean hildon_color_chooser_dialog_hsv_area_button_press(GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
+ int i, hskip, vskip, brd, selection = -1;
+ int x, y, tmp, tmp2, w;
+
+
+ x = event->x;
+ y = event->y;
+
+
+ brd = dialog->style_info.radio_sizes.bottom;
+ hskip = dialog->style_info.radio_sizes.left + dialog->style_info.radio_sizes.top + 2*brd;
+ vskip = dialog->style_info.radio_sizes.right + dialog->style_info.radio_sizes.top + 2*brd;
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+ tmp2 = (dialog->style_info.num_buttons.top * dialog->style_info.num_buttons.bottom);
+
+
+ if(widget == dialog->area_defined) {
+ w = dialog->style_info.num_buttons.left;
+
+ for(i = 0; i < tmp; i++) {
+ if(x >= hskip*(i % w) + brd && x < hskip*(i % w) + brd + dialog->style_info.radio_sizes.left &&
+ y >= vskip*(i / w) + brd && y < hskip*(i / w) + brd + dialog->style_info.radio_sizes.right) {
+ selection = i;
+ break;
+ }
+ }
+ } else {
+ w = dialog->style_info.num_buttons.top;
+ for(i = 0; i < tmp2; i++) {
+ if(x >= hskip*(i % w) + brd && x < hskip*(i % w) + brd + dialog->style_info.radio_sizes.left &&
+ y >= vskip*(i / w) + brd && y < hskip*(i / w) + brd + dialog->style_info.radio_sizes.right) {
+ selection = i + tmp;
+ break;
+ }
+ }
+ }
+
+
+ if(selection != -1) {
+ hildon_color_chooser_dialog_hsv_set_color_num(dialog, selection);
+ }
+
+
+ return FALSE;
+}
+
+
+static void hildon_color_chooser_dialog_hsv_chooser_color_changed(HildonColorChooser *chooser, GdkColor *color, gpointer data)
+{
+ HildonColorChooserDialogHSV *dialog = HILDON_COLOR_CHOOSER_DIALOG_HSV(data);
+ HildonColorChooserDialog *dia = HILDON_COLOR_CHOOSER_DIALOG(data);
+ char key[128], color_str[13];
+ int tmp;
+
+
+ dia->color = *color;
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+
+
+ if(dialog->selected >= tmp) {
+ dialog->colors_custom[dialog->selected - tmp] = *color;
+
+ gdk_gc_set_rgb_fg_color(dialog->gc_array[dialog->selected], &dialog->colors_custom[dialog->selected - tmp]);
+
+ gtk_widget_queue_draw(dialog->area_custom);
+
+
+ if(dialog->gconf_data.client) {
+ memset(key, 0, 128);
+ memset(color_str, 0, 13);
+ g_snprintf(key, 128, "/system/osso/af/color_chooser/custom_color%d", dialog->selected - tmp);
+ hildon_color_chooser_dialog_hsv_color_to_ascii_hex(color_str, &dialog->colors_custom[dialog->selected - tmp]);
+ gconf_client_set_string(dialog->gconf_data.client, key, color_str, NULL);
+ }
+ }
+}
+
+
+static void hildon_color_chooser_dialog_hsv_chooser_insensitive_press(GtkWidget *widget, gpointer data)
+{
+ hildon_banner_show_information(widget, NULL, _("ecdg_ib_colour_selector_predefined"));
+}
+
+ /* function has size defaults */
+static void hildon_color_chooser_dialog_hsv_refresh_style_info(HildonColorChooserDialogHSV *dialog)
+{
+ GtkBorder *tmp1, *tmp2, *tmp3;
+
+
+ gtk_widget_style_get(GTK_WIDGET(dialog), "container_sizes", &tmp1,
+ "radio_sizes", &tmp2, "num_buttons", &tmp3, NULL);
+
+
+ dialog->style_info.last_num_buttons = dialog->style_info.num_buttons;
+
+
+ if(tmp1) {
+ dialog->style_info.cont_sizes = *tmp1;
+ g_free(tmp1);
+ } else {
+ dialog->style_info.cont_sizes.left = 0;
+ dialog->style_info.cont_sizes.right = 8;
+ dialog->style_info.cont_sizes.top = 4;
+ dialog->style_info.cont_sizes.bottom = 0;
+ }
+
+ if(tmp2) {
+ dialog->style_info.radio_sizes = *tmp2;
+ g_free(tmp2);
+ } else {
+ dialog->style_info.radio_sizes.left = 16;
+ dialog->style_info.radio_sizes.right = 16;
+ dialog->style_info.radio_sizes.top = 4;
+ dialog->style_info.radio_sizes.bottom = 2;
+ }
+
+ if(tmp3) {
+ dialog->style_info.num_buttons = *tmp3;
+ g_free(tmp3);
+ } else {
+ dialog->style_info.num_buttons.left = 8;
+ dialog->style_info.num_buttons.right = 2;
+ dialog->style_info.num_buttons.top = 8;
+ dialog->style_info.num_buttons.bottom = 2;
+ }
+}
+
+
+static void hildon_color_chooser_dialog_hsv_set_color_num(HildonColorChooserDialogHSV *dialog, gint num)
+{
+ HildonColorChooserDialog *dia = HILDON_COLOR_CHOOSER_DIALOG(dialog);
+ int tmp;
+
+
+ tmp = (dialog->style_info.num_buttons.left * dialog->style_info.num_buttons.right);
+
+
+ if(num < tmp) {
+ gtk_widget_set_sensitive(dialog->chooser, FALSE);
+ } else {
+ gtk_widget_set_sensitive(dialog->chooser, TRUE);
+ }
+
+
+ dialog->selected = num;
+
+ gtk_widget_queue_draw(dialog->area_custom);
+ gtk_widget_queue_draw(dialog->area_defined);
+
+ dia->color = (num < tmp) ? dialog->colors_defined[num] : dialog->colors_custom[num - tmp];
+
+ hildon_color_chooser_set_color(HILDON_COLOR_CHOOSER(dialog->chooser), (num < tmp) ? &dialog->colors_defined[num] : &dialog->colors_custom[num - tmp]);
+}
+
+
+static void hildon_color_chooser_dialog_hsv_ascii_hex_to_color(gchar *s, GdkColor *color)
+{
+ int vals[12], i;
+
+
+ for(i = 0; i < 12; i++) {
+ if(s[i] >= '0' && s[i] <= '9') {
+ vals[i] = s[i] - 0x30;
+ } else if(s[i] >= 'a' && s[i] <= 'f') {
+ vals[i] = s[i] - 0x57;
+ } else {
+ vals[i] = 0;
+ }
+ }
+
+
+ color->red = (vals[0] << 12) | (vals[1] << 8) | (vals[2 ] << 4) | (vals[3 ] );
+ color->green = (vals[4] << 12) | (vals[5] << 8) | (vals[6 ] << 4) | (vals[7 ] );
+ color->blue = (vals[8] << 12) | (vals[9] << 8) | (vals[10] << 4) | (vals[11] );
+}
+
+static void hildon_color_chooser_dialog_hsv_color_to_ascii_hex(gchar *s, GdkColor *color)
+{
+ g_snprintf(s, 13, "%x%x%x%x%x%x%x%x%x%x%x%x",
+ (color->red >> 12) & 0xf, (color->red >> 8) & 0xf,
+ (color->red >> 4) & 0xf, (color->red ) & 0xf,
+ (color->green >> 12) & 0xf, (color->green >> 8) & 0xf,
+ (color->green >> 4) & 0xf, (color->green ) & 0xf,
+ (color->blue >> 12) & 0xf, (color->blue >> 8) & 0xf,
+ (color->blue >> 4) & 0xf, (color->blue ) & 0xf);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <gtk/gtk.h>
+
+#include <hildon-widgets/hildon-color-chooser.h>
+
+
+const char *parent_name = "HildonColorChooser";
+const char *plugin_name = "HSV color chooser";
+
+GType export_type(void);
+
+
+typedef struct {
+ HildonColorChooser parent;
+
+ GtkAllocation hba;
+ GtkAllocation spa;
+
+ unsigned short currhue;
+ unsigned short currsat;
+ unsigned short currval;
+
+ int mousestate;
+ gboolean mousein;
+
+
+ GdkWindow *event_window;
+
+ GdkPixbuf *dimmed_plane;
+ GdkPixbuf *dimmed_bar;
+
+ struct {
+ unsigned short last_expose_hue;
+
+ GTimeVal last_expose_time;
+
+ int expose_queued;
+ } expose_info;
+} HildonColorChooserHSV;
+
+typedef struct {
+ HildonColorChooserClass parent;
+} HildonColorChooserHSVClass;
+
+
+#define HILDON_COLOR_CHOOSER_HSV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), export_type(), HildonColorChooserHSV))
+#define HILDON_COLOR_CHOOSER_HSV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), export_type(), HildonColorChooserHSVClass))
+
+
+static HildonColorChooserClass *parent_class = NULL;
+
+
+ /* "crosshair" is hardcoded for now */
+static gchar crosshair[64] = { 0, 0, 0, 2, 2, 0, 0, 0,
+ 0, 2, 2, 3, 3, 2, 2, 0,
+ 0, 2, 3, 0, 0, 3, 2, 0,
+ 2, 3, 0, 0, 0, 0, 3, 2,
+ 2, 3, 0, 0, 0, 0, 3, 2,
+ 0, 2, 3, 0, 0, 3, 2, 0,
+ 0, 2, 2, 3, 3, 2, 2, 0,
+ 0, 0, 0, 2, 2, 0, 0, 0};
+
+
+static void hildon_color_chooser_hsv_init(HildonColorChooserHSV *sel);
+static void hildon_color_chooser_hsv_class_init(HildonColorChooserHSVClass *klass);
+
+static void hildon_color_chooser_hsv_dispose(HildonColorChooserHSV *sel);
+
+static void hildon_color_chooser_hsv_size_request(GtkWidget *widget, GtkRequisition *req);
+static void hildon_color_chooser_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
+
+static void hildon_color_chooser_hsv_realize(GtkWidget *widget);
+
+static void hildon_color_chooser_hsv_map(GtkWidget *widget);
+static void hildon_color_chooser_hsv_unmap(GtkWidget *widget);
+
+static gboolean hildon_color_chooser_hsv_expose(GtkWidget *widget, GdkEventExpose *event);
+
+static gboolean hildon_color_chooser_button_press(GtkWidget *widget, GdkEventButton *event);
+static gboolean hildon_color_chooser_button_release(GtkWidget *widget, GdkEventButton *event);
+static gboolean hildon_color_chooser_pointer_motion(GtkWidget *widget, GdkEventMotion *event);
+
+static void hildon_color_chooser_hsv_set_color(HildonColorChooser *sel, GdkColor *color);
+
+
+static void internal_get_border(GtkWidget *w, char *name, GtkBorder *b);
+static void _internal_init_borders(GtkWidget *w, GtkBorder *inner, GtkBorder *outer);
+
+static void internal_invoke_color_changed(HildonColorChooserHSV *sel);
+
+
+inline void inline_clip_to_alloc(void *s, GtkAllocation *a);
+
+inline void inline_sub_times(GTimeVal *result, GTimeVal *greater, GTimeVal *lesser);
+
+inline void inline_limited_expose(HildonColorChooserHSV *sel);
+
+inline void inline_draw_hue_bar(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh);
+inline void inline_draw_hue_bar_dimmed(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh);
+
+inline void inline_draw_sv_plane(HildonColorChooserHSV *sel, int x, int y, int w, int h);
+inline void inline_draw_sv_plane_dimmed(HildonColorChooserHSV *sel, int x, int y, int w, int h);
+
+inline void inline_draw_crosshair(unsigned char *buf, int x, int y, int w, int h);
+
+
+inline void inline_h2rgb(unsigned short hue, unsigned long *rgb);
+
+
+static gboolean hildon_color_chooser_hsv_expose_timer(gpointer data);
+
+
+GType export_type()
+{
+ static GType chooser_type = 0;
+
+ if (!chooser_type) {
+ static const GTypeInfo chooser_info =
+ {
+ sizeof (HildonColorChooserHSVClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) hildon_color_chooser_hsv_class_init,
+ NULL,
+ NULL,
+ sizeof (HildonColorChooserHSV),
+ 0,
+ (GInstanceInitFunc) hildon_color_chooser_hsv_init,
+ NULL
+ };
+
+ chooser_type = g_type_register_static (HILDON_TYPE_COLOR_CHOOSER,
+ "HildonColorChooserHSV",
+ &chooser_info, 0);
+ }
+
+ return chooser_type;
+}
+
+static void hildon_color_chooser_hsv_init(HildonColorChooserHSV *sel)
+{
+ GTK_WIDGET_SET_FLAGS (sel, GTK_NO_WINDOW);
+
+
+ sel->currhue = 0;
+ sel->currsat = 0;
+ sel->currval = 0;
+
+ sel->mousestate = 0;
+ sel->mousein = FALSE;
+
+
+ g_get_current_time(&sel->expose_info.last_expose_time);
+
+ sel->expose_info.last_expose_hue = sel->currhue;
+ sel->expose_info.expose_queued = 0;
+
+ sel->dimmed_plane = NULL;
+ sel->dimmed_bar = NULL;
+}
+
+static void hildon_color_chooser_hsv_class_init(HildonColorChooserHSVClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ HildonColorChooserClass *selection_class = HILDON_COLOR_CHOOSER_CLASS(klass);
+
+
+ parent_class = g_type_class_peek_parent(klass);
+
+
+ object_class->dispose = (gpointer) hildon_color_chooser_hsv_dispose;
+
+ widget_class->size_request = hildon_color_chooser_hsv_size_request;
+ widget_class->size_allocate = hildon_color_chooser_hsv_size_allocate;
+
+ widget_class->realize = hildon_color_chooser_hsv_realize;
+
+ widget_class->map = hildon_color_chooser_hsv_map;
+ widget_class->unmap = hildon_color_chooser_hsv_unmap;
+
+ widget_class->expose_event = hildon_color_chooser_hsv_expose;
+
+ widget_class->button_press_event = hildon_color_chooser_button_press;
+ widget_class->button_release_event = hildon_color_chooser_button_release;
+ widget_class->motion_notify_event = hildon_color_chooser_pointer_motion;
+
+
+ selection_class->set_color = hildon_color_chooser_hsv_set_color;
+
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_boxed("inner_size",
+ "Inner sizes",
+ "Sizes of SV plane, H bar and spacing",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_boxed("graphic_border",
+ "Graphical borders",
+ "Size of graphical border",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+}
+
+
+static void hildon_color_chooser_hsv_dispose(HildonColorChooserHSV *sel)
+{
+ if (sel->dimmed_bar != NULL) {
+ g_object_unref (sel->dimmed_bar);
+ sel->dimmed_bar = NULL;
+ }
+
+ if (sel->dimmed_plane != NULL) {
+ g_object_unref (sel->dimmed_plane);
+ sel->dimmed_plane = NULL;
+ }
+
+ G_OBJECT_CLASS(parent_class)->dispose(sel);
+}
+
+static void hildon_color_chooser_hsv_size_request(GtkWidget *widget, GtkRequisition *req)
+{
+ GtkBorder inner, outer;
+
+
+ _internal_init_borders(widget, &inner, &outer);
+
+
+ req->width = inner.left + inner.top + inner.bottom + outer.left + outer.right;
+ req->height = inner.right + outer.top + outer.bottom;
+}
+
+static void hildon_color_chooser_hsv_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ GtkBorder outer, inner;
+
+
+ widget->allocation = *alloc;
+
+
+ _internal_init_borders(widget, &inner, &outer);
+
+
+ sel->hba.height = alloc->height - outer.top - outer.bottom;
+ sel->hba.y = alloc->y + outer.top;
+ sel->hba.width = inner.top;
+ sel->hba.x = alloc->x + alloc->width - outer.right - inner.top;
+
+ sel->spa.x = alloc->x + outer.left;
+ sel->spa.y = alloc->y + outer.top;
+ sel->spa.height = alloc->height - outer.top - outer.bottom;
+ sel->spa.width = alloc->width - outer.left - outer.right - inner.top - inner.bottom;
+
+ if(GTK_WIDGET_REALIZED(widget)) {
+ gdk_window_move_resize(sel->event_window, widget->allocation.x, widget->allocation.y, widget->allocation.width, widget->allocation.height);
+ }
+}
+
+
+static void hildon_color_chooser_hsv_realize(GtkWidget *widget)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.event_mask = gtk_widget_get_events(widget) | GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON1_MOTION_MASK;
+ attributes.visual = gtk_widget_get_visual(widget);
+ attributes.colormap = gtk_widget_get_colormap(widget);
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_WMCLASS;
+ sel->event_window = gdk_window_new (widget->parent->window, &attributes, attributes_mask);
+
+
+ gdk_window_set_user_data(sel->event_window, widget);
+
+
+ widget->window = gtk_widget_get_parent_window(widget);
+
+
+ widget->style = gtk_style_attach(widget->style, widget->window);
+
+
+ GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+}
+
+
+static void hildon_color_chooser_hsv_map(GtkWidget *widget)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+
+
+ GTK_WIDGET_CLASS(parent_class)->map(widget);
+
+ if(sel->event_window) {
+ gdk_window_show(sel->event_window);
+ }
+}
+
+static void hildon_color_chooser_hsv_unmap(GtkWidget *widget)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+
+
+ if(sel->event_window) {
+ gdk_window_hide(sel->event_window);
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->unmap(widget);
+}
+
+
+inline void inline_clip_to_alloc(void *s, GtkAllocation *a)
+{
+ struct {
+ int x, y, w, h;
+ } *area = s;
+
+
+ if(area->x < a->x) {
+ area->w -= a->x - area->x;
+ area->x = a->x;
+ } if(area->y < a->y) {
+ area->h -= a->y - area->y;
+ area->y = a->y;
+ }
+ if(area->x + area->w > a->x + a->width) area->w = a->width - (area->x - a->x);
+ if(area->y + area->h > a->y + a->height) area->h = a->height - (area->y - a->y);
+}
+
+static gboolean hildon_color_chooser_hsv_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ GtkBorder graphical_border;
+ struct {
+ int x, y, w, h;
+ } area;
+
+
+ if(!GTK_WIDGET_REALIZED(widget)) {
+ return FALSE;
+ }
+
+
+ internal_get_border(widget, "graphic_border", &graphical_border);
+
+
+ if(event->area.width || event->area.height) {
+ gdk_draw_rectangle(widget->window,
+ widget->style->black_gc,
+ FALSE,
+ sel->hba.x - 2,
+ sel->hba.y - 2,
+ sel->hba.width + 3,
+ sel->hba.height + 3);
+
+ gdk_draw_rectangle(widget->window,
+ widget->style->black_gc,
+ FALSE,
+ sel->spa.x - 2,
+ sel->spa.y - 2,
+ sel->spa.width + 3,
+ sel->spa.height + 3);
+ }
+
+ if(sel->expose_info.expose_queued) {
+ if(GTK_WIDGET_SENSITIVE(widget)) {
+ inline_draw_hue_bar(widget, sel->hba.x, sel->hba.y, sel->hba.width, sel->hba.height, sel->hba.y, sel->hba.height);
+
+ inline_draw_sv_plane(sel, sel->spa.x, sel->spa.y, sel->spa.width, sel->spa.height);
+ } else {
+ inline_draw_hue_bar_dimmed(widget, sel->hba.x, sel->hba.y, sel->hba.width, sel->hba.height, sel->hba.y, sel->hba.height);
+
+ inline_draw_sv_plane_dimmed(sel, sel->spa.x, sel->spa.y, sel->spa.width, sel->spa.height);
+ }
+
+
+ sel->expose_info.expose_queued = 0;
+
+ g_get_current_time(&sel->expose_info.last_expose_time);
+ } else {
+ /* clip hue bar region */
+ area.x = event->area.x;
+ area.y = event->area.y;
+ area.w = event->area.width;
+ area.h = event->area.height;
+
+ inline_clip_to_alloc(&area, &sel->hba);
+
+ if(GTK_WIDGET_SENSITIVE(widget)) {
+ inline_draw_hue_bar(widget, area.x, area.y, area.w, area.h, sel->hba.y, sel->hba.height);
+ } else {
+ inline_draw_hue_bar_dimmed(widget, area.x, area.y, area.w, area.h, sel->hba.y, sel->hba.height);
+ }
+
+
+ area.x = event->area.x;
+ area.y = event->area.y;
+ area.w = event->area.width;
+ area.h = event->area.height;
+
+ inline_clip_to_alloc(&area, &sel->spa);
+
+ if(GTK_WIDGET_SENSITIVE(widget)) {
+ inline_draw_sv_plane(sel, area.x, area.y, area.w, area.h);
+ } else {
+ inline_draw_sv_plane_dimmed(sel, area.x, area.y, area.w, area.h);
+ }
+ }
+
+
+ return FALSE;
+}
+
+
+inline void inline_sub_times(GTimeVal *result, GTimeVal *greater, GTimeVal *lesser)
+{
+ result->tv_sec = greater->tv_sec - lesser->tv_sec;
+ result->tv_usec = greater->tv_usec - lesser->tv_usec;
+
+ if(result->tv_usec < 0) {
+ result->tv_sec--;
+ result->tv_usec += 1000000;
+ }
+}
+
+#define EXPOSE_INTERVAL 50000
+inline void inline_limited_expose(HildonColorChooserHSV *sel)
+{
+ GTimeVal curr_time, result;
+ GdkEventExpose event;
+
+
+ if(!GTK_WIDGET_REALIZED(GTK_WIDGET(sel))) {
+ return;
+ }
+
+
+ if(sel->currhue == sel->expose_info.last_expose_hue) {
+ return; /* no need to redraw */
+ }
+
+
+ sel->expose_info.last_expose_hue = sel->currhue;
+
+
+ g_get_current_time(&curr_time);
+
+ inline_sub_times(&result, &curr_time, &sel->expose_info.last_expose_time);
+
+ if(result.tv_sec != 0 || result.tv_usec >= EXPOSE_INTERVAL) {
+ sel->expose_info.expose_queued = 1;
+
+#if 1
+ event.type = GDK_EXPOSE;
+ event.area.width = 0;
+ event.area.height = 0;
+ event.window = GTK_WIDGET(sel)->window;
+
+ gtk_widget_send_expose(GTK_WIDGET(sel), (GdkEvent *)&event);
+#else
+ gtk_widget_queue_draw(GTK_WIDGET(sel));
+#endif
+ } else if(!sel->expose_info.expose_queued) {
+ sel->expose_info.expose_queued = 1;
+
+
+ g_timeout_add((EXPOSE_INTERVAL - result.tv_usec)/1000, hildon_color_chooser_hsv_expose_timer, sel);
+ }
+}
+
+static gboolean hildon_color_chooser_button_press(GtkWidget *widget, GdkEventButton *event)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ int x, y, tmp;
+
+
+ x = (int)event->x + widget->allocation.x;
+ y = (int)event->y + widget->allocation.y;
+
+
+ if(x >= sel->spa.x && x <= sel->spa.x + sel->spa.width &&
+ y >= sel->spa.y && y <= sel->spa.y + sel->spa.height) {
+ tmp = y - sel->spa.y;
+ sel->currsat = tmp * 0xffff / sel->spa.height;
+ tmp = x - sel->spa.x;
+ sel->currval = tmp * 0xffff / sel->spa.width;
+
+ internal_invoke_color_changed(sel);
+ gtk_widget_queue_draw(widget);
+
+ sel->mousestate = 1;
+ sel->mousein = TRUE;
+
+ gtk_grab_add(widget);
+ } else if(x >= sel->hba.x && x <= sel->hba.x + sel->hba.width &&
+ y >= sel->hba.y && y <= sel->hba.y + sel->hba.height) {
+ tmp = y - sel->hba.y;
+ sel->currhue = tmp * 0xffff / sel->hba.height;
+
+ internal_invoke_color_changed(sel);
+ inline_limited_expose(sel);
+
+ sel->mousestate = 2;
+ sel->mousein = TRUE;
+
+ gtk_grab_add(widget);
+ }
+
+
+ return FALSE;
+}
+
+static gboolean hildon_color_chooser_button_release(GtkWidget *widget, GdkEventButton *event)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+
+
+ if(sel->mousestate) {
+ gtk_grab_remove(widget);
+ }
+
+
+ sel->mousestate = 0;
+ sel->mousein = FALSE;
+
+
+ return FALSE;
+}
+
+static gboolean hildon_color_chooser_pointer_motion(GtkWidget *widget, GdkEventMotion *event)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ GdkModifierType mods;
+ gint x, y, tmp;
+
+
+ if (event->is_hint || (event->window != widget->window))
+ gdk_window_get_pointer (widget->window, &x, &y, &mods);
+
+
+ if(sel->mousestate == 1) {
+ if(x >= sel->spa.x && x <= sel->spa.x + sel->spa.width &&
+ y >= sel->spa.y && y <= sel->spa.y + sel->spa.height) {
+ sel->currsat = (((long)(y - sel->spa.y)) * 0xffff)/sel->spa.height;
+ sel->currval = (((long)(x - sel->spa.x)) * 0xffff)/sel->spa.width;
+
+ internal_invoke_color_changed(sel);
+ gtk_widget_queue_draw(widget);
+ } else if(sel->mousein == TRUE) {
+ }
+ } else if(sel->mousestate == 2) {
+ if(x >= sel->hba.x && x <= sel->hba.x + sel->hba.width &&
+ y >= sel->hba.y && y <= sel->hba.y + sel->hba.height) {
+ tmp = y - sel->hba.y;
+ tmp *= 0xffff;
+ tmp /= sel->hba.height;
+
+ if(tmp != sel->currhue) {
+ sel->currhue = tmp;
+
+ internal_invoke_color_changed(sel);
+ inline_limited_expose(sel);
+ }
+ } else if(sel->mousein == TRUE) {
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void internal_get_border(GtkWidget *w, char *name, GtkBorder *b)
+{
+ GtkBorder *tb;
+
+ gtk_widget_style_get(w, name, &tb, NULL);
+
+ if(tb) {
+ *b = *tb;
+ g_free(tb);
+ } else {
+ b->left = 0;
+ b->right = 0;
+ b->top = 0;
+ b->bottom = 0;
+ }
+}
+
+
+static void _internal_init_borders(GtkWidget *w, GtkBorder *inner, GtkBorder *outer)
+{
+ GtkBorder *tb;
+
+
+ internal_get_border(w, "outer_border", outer);
+
+
+ gtk_widget_style_get(w, "inner_size", &tb, NULL);
+
+ if(tb) {
+ *inner = *tb;
+ g_free(tb);
+ } else {
+ inner->left = 64;
+ inner->right = 64;
+ inner->top = 12;
+ inner->bottom = 2;
+ }
+
+ if(inner->left < 2) inner->left = 2;
+ if(inner->right < 2) inner->right = 2;
+ if(inner->top < 2) inner->top = 2;
+}
+
+ /* calculate RGB color & emit signal */
+static void internal_invoke_color_changed(HildonColorChooserHSV *sel)
+{
+ HildonColorChooser *parent_sel = HILDON_COLOR_CHOOSER(sel);
+ GdkVisual *system_visual = gdk_visual_get_system();
+ unsigned long rgb[3], rgb2[3];
+
+
+ inline_h2rgb(sel->currhue, rgb);
+
+ rgb2[0] = 0xffffff - rgb[0];
+ rgb2[1] = 0xffffff - rgb[1];
+ rgb2[2] = 0xffffff - rgb[2];
+
+
+ parent_sel->color.red = ((rgb[0] >> 8) + ((rgb2[0] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
+ parent_sel->color.green = ((rgb[1] >> 8) + ((rgb2[1] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
+ parent_sel->color.blue = ((rgb[2] >> 8) + ((rgb2[2] >> 8) * (0xffff - sel->currsat) / 0xffff)) * sel->currval / 0xffff;
+
+ parent_sel->color.pixel = ((parent_sel->color.red >> (16 - system_visual->red_prec)) << system_visual->red_shift) |
+ ((parent_sel->color.green >> (16 - system_visual->green_prec)) << system_visual->green_shift) |
+ ((parent_sel->color.blue >> (16 - system_visual->blue_prec)) << system_visual->blue_shift);
+
+
+ hildon_color_chooser_emit_color_changed(HILDON_COLOR_CHOOSER(sel));
+}
+
+ /* do the RGB -> HSV conversion here, not so time critical */
+static void hildon_color_chooser_hsv_set_color(HildonColorChooser *sel, GdkColor *color)
+{
+ HildonColorChooserHSV *sel_hsv = HILDON_COLOR_CHOOSER_HSV(sel);
+ unsigned short hue, sat, val;
+ unsigned long min, max;
+ signed long tmp, diff;
+
+ /* ugly nesting */
+ min = MIN(MIN(color->red, color->green), color->blue);
+ max = MAX(MAX(color->red, color->green), color->blue);
+ diff = max - min;
+
+
+ val = max;
+
+ if(val > 0 && diff != 0) {
+ sat = (diff * 0x0000ffff) / max;
+
+ if(color->red == max) {
+ tmp = (signed)color->green - (signed)color->blue;
+ tmp *= 10922;
+ tmp /= diff;
+ if(tmp < 0) {
+ tmp += 65532;
+ }
+ hue = tmp;
+ } else if(color->green == max) {
+ hue = (((signed long)color->blue - (signed long)color->red)*10922 / diff) + 21844;
+ } else {
+ hue = (((signed long)color->red - (signed long)color->green)*10922 / diff) + 43688;
+ }
+ } else {
+ hue = 0;
+ sat = 0;
+ }
+
+
+ sel_hsv->currhue = hue;
+ sel_hsv->currsat = sat;
+ sel_hsv->currval = val;
+
+
+ inline_limited_expose(sel_hsv);
+}
+
+
+#define FULL_COLOR 0x00ffffff
+inline void inline_h2rgb(unsigned short hue, unsigned long *rgb)
+{
+ unsigned short hue_rotation, hue_value;
+
+ hue_rotation = hue / 10922;
+ hue_value = hue % 10922;
+
+
+ switch(hue_rotation) {
+ case 0:
+ case 6:
+ rgb[0] = FULL_COLOR;
+ rgb[1] = hue_value * 6*256;
+ rgb[2] = 0;
+ break;
+ case 1:
+ rgb[0] = FULL_COLOR - (hue_value * 6*256);
+ rgb[1] = FULL_COLOR;
+ rgb[2] = 0;
+ break;
+ case 2:
+ rgb[0] = 0;
+ rgb[1] = FULL_COLOR;
+ rgb[2] = hue_value * 6*256;
+ break;
+ case 3:
+ rgb[0] = 0;
+ rgb[1] = FULL_COLOR - (hue_value * 6*256);
+ rgb[2] = FULL_COLOR;
+ break;
+ case 4:
+ rgb[0] = hue_value * 6*256;
+ rgb[1] = 0;
+ rgb[2] = FULL_COLOR;
+ break;
+ case 5:
+ rgb[0] = FULL_COLOR;
+ rgb[1] = 0;
+ rgb[2] = FULL_COLOR - (hue_value * 6*256);
+ break;
+ default:
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+ break;
+ }
+}
+
+#define FULL_COLOR8 0xff
+static void intern_h2rgb8(unsigned short hue, unsigned char *rgb)
+{
+ unsigned short hue_rotation, hue_value;
+
+ hue >>= 8;
+ hue_rotation = hue / 42;
+ hue_value = hue % 42;
+
+
+ switch(hue_rotation) {
+ case 0:
+ case 6:
+ rgb[0] = FULL_COLOR8;
+ rgb[1] = hue_value * 6;
+ rgb[2] = 0;
+ break;
+ case 1:
+ rgb[0] = FULL_COLOR8 - (hue_value * 6);
+ rgb[1] = FULL_COLOR8;
+ rgb[2] = 0;
+ break;
+ case 2:
+ rgb[0] = 0;
+ rgb[1] = FULL_COLOR8;
+ rgb[2] = hue_value * 6;
+ break;
+ case 3:
+ rgb[0] = 0;
+ rgb[1] = FULL_COLOR8 - (hue_value * 6);
+ rgb[2] = FULL_COLOR8;
+ break;
+ case 4:
+ rgb[0] = hue_value * 6;
+ rgb[1] = 0;
+ rgb[2] = FULL_COLOR8;
+ break;
+ case 5:
+ rgb[0] = FULL_COLOR8;
+ rgb[1] = 0;
+ rgb[2] = FULL_COLOR8 - (hue_value * 6);
+ break;
+ default:
+ rgb[0] = 0;
+ rgb[1] = 0;
+ rgb[2] = 0;
+ break;
+ }
+}
+
+
+ /* optimization: do not ask hue for each round but have bilinear vectors */
+ /* rethink: benefits from handling data 8 bit? (no shift round) */
+inline void inline_draw_hue_bar(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+ unsigned short hvec, hcurr;
+ unsigned char *buf, *ptr, tmp[3];
+ int i, j, tmpy;
+
+
+ if(w <= 0 || h <= 0) {
+ return;
+ }
+
+ buf = (unsigned char *)g_malloc(w*h*3);
+
+ hvec = 65535/sh;
+ hcurr = hvec * (y - sy);
+
+ ptr = buf;
+
+
+ for(i = 0; i < h; i++) {
+ intern_h2rgb8(hcurr, tmp);
+
+ for(j = 0; j < w; j++) {
+ ptr[0] = tmp[0];
+ ptr[1] = tmp[1];
+ ptr[2] = tmp[2];
+ ptr += 3;
+ }
+
+ hcurr += hvec;
+ }
+
+
+ gdk_draw_rgb_image(widget->parent->window, widget->style->fg_gc[0], x, y, w, h, GDK_RGB_DITHER_NONE, buf, w*3);
+
+ tmpy = sel->hba.y + (sel->currhue * sel->hba.height / 0xffff);
+ gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy, sel->hba.x + sel->hba.width - 1, tmpy);
+
+ if((((sel->currhue * sel->hba.height) & 0xffff) > 0x8000) && (tmpy < (sel->hba.y + sel->hba.height))) {
+ gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy+1, sel->hba.x + sel->hba.width - 1, tmpy+1);
+ } else if(tmpy > sel->hba.y) {
+ gdk_draw_line(widget->parent->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], sel->hba.x, tmpy-1, sel->hba.x + sel->hba.width - 1, tmpy-1);
+ }
+
+
+ g_free(buf);
+}
+
+inline void inline_draw_hue_bar_dimmed(GtkWidget *widget, int x, int y, int w, int h, int sy, int sh)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(widget);
+
+
+ if(w <= 0 || h <= 0) {
+ return;
+ }
+
+ /* We need to create (and cache) the pixbuf if we don't
+ * have it yet */
+ if (sel->dimmed_bar == NULL) {
+ int i, j;
+ unsigned short hvec, hcurr, avg;
+ unsigned char *buf, *ptr, tmp[3];
+ buf = (unsigned char *)g_malloc(w*h*3);
+
+ hvec = 65535/sh;
+ hcurr = hvec * (y - sy);
+
+ ptr = buf;
+
+
+ for(i = 0; i < h; i++) {
+ intern_h2rgb8(hcurr, tmp);
+
+ for(j = 0; j < w; j++) {
+ avg = ((unsigned short)tmp[0]*3 + (unsigned short)tmp[1]*2 + (unsigned short)tmp[2])/6;
+ ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ ptr += 3;
+ }
+
+ hcurr += hvec;
+ }
+
+ sel->dimmed_bar = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, g_free, buf);
+ }
+
+ gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], sel->dimmed_bar, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
+}
+
+
+inline void inline_draw_crosshair(unsigned char *buf, int x, int y, int w, int h)
+{
+ int i, j, sx, sy;
+
+ /* bad "clipping", clip the loop to save cpu */
+ for(i = 0; i < 8; i++) {
+ for(j = 0; j < 8; j++) {
+ sx = j + x; sy = i + y;
+
+ if(sx >= 0 && sx < w && sy >= 0 && sy < h) {
+ if(crosshair[j + 8*i]) {
+ if(crosshair[j + 8*i] & 0x1) {
+ buf[(sx)*3+(sy)*w*3+0] = 255;
+ buf[(sx)*3+(sy)*w*3+1] = 255;
+ buf[(sx)*3+(sy)*w*3+2] = 255;
+ } else {
+ buf[(sx)*3+(sy)*w*3+0] = 0;
+ buf[(sx)*3+(sy)*w*3+1] = 0;
+ buf[(sx)*3+(sy)*w*3+2] = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+inline void inline_draw_sv_plane(HildonColorChooserHSV *sel, int x, int y, int w, int h)
+{
+ GtkWidget *widget = GTK_WIDGET(sel);
+ unsigned char *buf, *ptr;
+ unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
+ signed long rgby[3];
+ int tmp = sel->spa.width*sel->spa.height, i, j;
+
+
+ if(w <= 0 || h <= 0) {
+ return;
+ }
+
+
+ buf = (unsigned char *)g_malloc(w*h*3);
+
+ ptr = buf;
+
+
+ inline_h2rgb(sel->currhue, rgbtmp);
+
+ rgby[0] = rgbtmp[0] - rgbx[0];
+ rgby[1] = rgbtmp[1] - rgbx[1];
+ rgby[2] = rgbtmp[2] - rgbx[2];
+
+ rgbx[0] /= sel->spa.width;
+ rgbx[1] /= sel->spa.width;
+ rgbx[2] /= sel->spa.width;
+
+ rgby[0] /= tmp;
+ rgby[1] /= tmp;
+ rgby[2] /= tmp;
+
+
+ rgbx[0] += (y - sel->spa.y)*rgby[0];
+ rgbx[1] += (y - sel->spa.y)*rgby[1];
+ rgbx[2] += (y - sel->spa.y)*rgby[2];
+
+
+ for(i = 0; i < h; i++) {
+ rgbtmp[0] = rgbx[0] * (x - sel->spa.x);
+ rgbtmp[1] = rgbx[1] * (x - sel->spa.x);
+ rgbtmp[2] = rgbx[2] * (x - sel->spa.x);
+
+ for(j = 0; j < w; j++) {
+ ptr[0] = rgbtmp[0] >> 16;
+ ptr[1] = rgbtmp[1] >> 16;
+ ptr[2] = rgbtmp[2] >> 16;
+ rgbtmp[0] += rgbx[0];
+ rgbtmp[1] += rgbx[1];
+ rgbtmp[2] += rgbx[2];
+ ptr += 3;
+ }
+
+ rgbx[0] += rgby[0];
+ rgbx[1] += rgby[1];
+ rgbx[2] += rgby[2];
+ }
+
+
+ inline_draw_crosshair(buf, (sel->spa.width * sel->currval / 0xffff) - x + sel->spa.x - 4, (sel->spa.height * sel->currsat / 0xffff) - y + sel->spa.y - 4, w, h);
+
+
+ gdk_draw_rgb_image(widget->parent->window, widget->style->fg_gc[0], x, y, w, h, GDK_RGB_DITHER_NONE, buf, w*3);
+
+
+ g_free(buf);
+}
+
+inline void inline_draw_sv_plane_dimmed(HildonColorChooserHSV *sel, int x, int y, int w, int h)
+{
+ GtkWidget *widget = GTK_WIDGET(sel);
+
+ if(w <= 0 || h <= 0) {
+ return;
+ }
+
+ /* We need to create (and cache) the pixbuf if we don't
+ * have it yet */
+ if (sel->dimmed_plane == NULL) {
+ unsigned char *buf, *ptr;
+ unsigned long rgbx[3] = { 0x00ffffff, 0x00ffffff, 0x00ffffff }, rgbtmp[3];
+ unsigned long avg;
+ signed long rgby[3];
+ int tmp = sel->spa.width*sel->spa.height, i, j;
+
+ buf = (unsigned char *)g_malloc(w*h*3);
+
+ ptr = buf;
+
+ /* possibe optimization: as we are drawing grayscale plane, there might
+ be some simpler algorithm to do this*/
+ rgbtmp[0] = 0x00ffffff;
+ rgbtmp[1] = 0x00000000;
+ rgbtmp[2] = 0x00000000;
+
+ rgby[0] = rgbtmp[0] - rgbx[0];
+ rgby[1] = rgbtmp[1] - rgbx[1];
+ rgby[2] = rgbtmp[2] - rgbx[2];
+
+ rgbx[0] /= sel->spa.width;
+ rgbx[1] /= sel->spa.width;
+ rgbx[2] /= sel->spa.width;
+
+ rgby[0] /= tmp;
+ rgby[1] /= tmp;
+ rgby[2] /= tmp;
+
+ rgbx[0] += (y - sel->spa.y)*rgby[0];
+ rgbx[1] += (y - sel->spa.y)*rgby[1];
+ rgbx[2] += (y - sel->spa.y)*rgby[2];
+
+ for(i = 0; i < h; i++) {
+ rgbtmp[0] = rgbx[0] * (x - sel->spa.x);
+ rgbtmp[1] = rgbx[1] * (x - sel->spa.x);
+ rgbtmp[2] = rgbx[2] * (x - sel->spa.x);
+
+ for(j = 0; j < w; j++) {
+ avg = (rgbtmp[0] + rgbtmp[1] + rgbtmp[2])/3;
+ avg >>= 16;
+ ptr[0] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ ptr[1] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ ptr[2] = ((((i % 2) + j) % 2) == 0) ? MIN ((avg * 0.7) + 180, 255) : MIN ((avg * 0.7) + 120, 255);
+ rgbtmp[0] += rgbx[0];
+ rgbtmp[1] += rgbx[1];
+ rgbtmp[2] += rgbx[2];
+ ptr += 3;
+ }
+
+ rgbx[0] += rgby[0];
+ rgbx[1] += rgby[1];
+ rgbx[2] += rgby[2];
+ }
+
+ sel->dimmed_plane = gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w * 3, g_free, buf);
+ }
+
+ gdk_draw_pixbuf (widget->parent->window, widget->style->fg_gc [0], sel->dimmed_plane, 0, 0, x, y, w, h, GDK_RGB_DITHER_NONE, 0, 0);
+}
+
+
+static gboolean hildon_color_chooser_hsv_expose_timer(gpointer data)
+{
+ HildonColorChooserHSV *sel = HILDON_COLOR_CHOOSER_HSV(data);
+
+
+ if(sel->expose_info.expose_queued) {
+ gtk_widget_queue_draw(GTK_WIDGET(data));
+ }
+
+
+ return FALSE;
+}
--- /dev/null
+INCLUDES = $(GTK_CFLAGS) $(GCONF_CFLAGS) \
+ $(ESD_CFLAGS) $(LIBMB_CFLAGS) -DLOCALEDIR=\"$(localedir)\" -I$(srcdir)/..
+
+lib_LTLIBRARIES = libhildonwidgets.la
+
+MAINTAINERCLEANFILES = \
+ Makefile.in hildon-libs-enum-types.c hildon-libs-enum-types.h
+
+EXTRA_DIST = hildon-marshalers.list
+
+libhildonwidgets_la_LDFLAGS = -version-info 5:0:5
+
+libhildonwidgets_la_LIBADD = $(GTK_LIBS) $(GCONF_LIBS) \
+ $(ESD_LIBS) $(LIBMB_LIBS)
+
+libhildonwidgets_la_SOURCES = \
+ hildon-marshalers.c \
+ hildon-marshalers.h \
+ hildon-composite-widget.c \
+ hildon-composite-widget.h \
+ hildon-controlbar.c \
+ hildon-controlbar.h \
+ hildon-seekbar.c \
+ hildon-seekbar.h \
+ hildon-color-selector.c \
+ hildon-color-selector.h \
+ hildon-note.c \
+ hildon-note.h \
+ hildon-volumebar.c \
+ hildon-volumebar.h \
+ hildon-volumebar-range.c \
+ hildon-volumebar-range.h \
+ hildon-volumebar-private.h \
+ hildon-hvolumebar.c \
+ hildon-hvolumebar.h \
+ hildon-vvolumebar.c \
+ hildon-vvolumebar.h \
+ hildon-dialoghelp.c \
+ hildon-dialoghelp.h \
+ hildon-calendar-popup.c \
+ hildon-calendar-popup.h \
+ hildon-date-editor.c \
+ hildon-date-editor.h \
+ hildon-time-editor.c \
+ hildon-time-editor.h \
+ hildon-private.h \
+ hildon-time-picker.c \
+ hildon-time-picker.h \
+ hildon-weekday-picker.c \
+ hildon-weekday-picker.h \
+ hildon-telephone-editor.c \
+ hildon-telephone-editor.h \
+ hildon-number-editor.c \
+ hildon-number-editor.h \
+ hildon-range-editor.c \
+ hildon-range-editor.h \
+ hildon-get-password-dialog.c \
+ hildon-get-password-dialog.h \
+ hildon-set-password-dialog.c \
+ hildon-set-password-dialog.h \
+ hildon-sort-dialog.c \
+ hildon-sort-dialog.h \
+ hildon-add-home-dialog.c \
+ hildon-add-home-dialog.h \
+ hildon-font-selection-dialog.c \
+ hildon-font-selection-dialog.h \
+ hildon-grid.c \
+ hildon-grid.h \
+ hildon-grid-item.c \
+ hildon-grid-item.h \
+ hildon-grid-item-private.h \
+ hildon-file-handling-note.c \
+ hildon-file-handling-note.h \
+ hildon-name-password-dialog.c \
+ hildon-name-password-dialog.h \
+ hildon-scroll-area.c \
+ hildon-scroll-area.h \
+ hildon-wizard-dialog.c \
+ hildon-wizard-dialog.h \
+ hildon-color-popup.c \
+ hildon-color-popup.h \
+ hildon-color-button.c \
+ hildon-color-button.h \
+ hildon-system-sound.c \
+ hildon-system-sound.h \
+ hildon-app.c \
+ hildon-app.h \
+ hildon-defines.c \
+ hildon-defines.h \
+ hildon-appview.c \
+ hildon-appview.h \
+ hildon-find-toolbar.c \
+ hildon-find-toolbar.h \
+ gtk-infoprint.c \
+ gtk-infoprint.h \
+ hildon-banner.c \
+ hildon-banner.h \
+ hildon-input-mode-hint.h \
+ hildon-app-private.h \
+ hildon-caption.c \
+ hildon-caption.h \
+ hildon-window.c \
+ hildon-window.h \
+ hildon-window-private.h \
+ hildon-program.c \
+ hildon-program.h \
+ hildon-code-dialog.c \
+ hildon-code-dialog.h \
+ hildon-plugin-widget.c \
+ hildon-plugin-widget.h \
+ hildon-color-chooser.c \
+ hildon-color-chooser.h \
+ hildon-color-chooser-dialog.c \
+ hildon-color-chooser-dialog.h \
+ hildon-color-chooser-button.c \
+ hildon-color-chooser-button.h \
+ $(hildonlibs_built_headers) \
+ $(hildonlibs_built_cfiles)
+
+
+hildon-marshalers.h: hildon-marshalers.list
+ glib-genmarshal --prefix _hildon_marshal --header \
+ hildon-marshalers.list >hildon-marshalers.h
+
+hildon-marshalers.c: hildon-marshalers.list hildon-marshalers.h
+ echo '#include <hildon-widgets/hildon-marshalers.h>' >hildon-marshalers.c
+ glib-genmarshal --prefix _hildon_marshal --body \
+ hildon-marshalers.list >>hildon-marshalers.c
+
+hildonwidgetsincludeinstdir=$(includedir)/hildon-widgets
+hildonwidgetsincludeinst_DATA = \
+ hildon-controlbar.h \
+ hildon-note.h \
+ hildon-seekbar.h \
+ hildon-color-selector.h \
+ hildon-volumebar.h \
+ hildon-hvolumebar.h \
+ hildon-vvolumebar.h \
+ hildon-dialoghelp.h \
+ hildon-calendar-popup.h \
+ hildon-date-editor.h \
+ hildon-time-editor.h \
+ hildon-time-picker.h \
+ hildon-weekday-picker.h \
+ hildon-telephone-editor.h \
+ hildon-number-editor.h \
+ hildon-range-editor.h \
+ hildon-get-password-dialog.h \
+ hildon-set-password-dialog.h \
+ hildon-sort-dialog.h \
+ hildon-add-home-dialog.h \
+ hildon-font-selection-dialog.h \
+ hildon-grid.h \
+ hildon-grid-item.h \
+ hildon-file-handling-note.h \
+ hildon-name-password-dialog.h \
+ hildon-scroll-area.h \
+ hildon-wizard-dialog.h \
+ hildon-color-popup.h \
+ hildon-color-button.h \
+ hildon-system-sound.h \
+ hildon-app.h \
+ hildon-defines.h \
+ hildon-appview.h \
+ hildon-find-toolbar.h \
+ gtk-infoprint.h \
+ hildon-banner.h \
+ hildon-input-mode-hint.h \
+ hildon-app-private.h \
+ hildon-caption.h \
+ hildon-window.h \
+ hildon-program.h \
+ hildon-window-private.h \
+ hildon-code-dialog.h \
+ hildon-plugin-widget.h \
+ hildon-color-chooser.h \
+ hildon-color-chooser-dialog.h \
+ hildon-color-chooser-button.h
+
+headers_to_scan_for_enums = $(hildonwidgetsincludeinst_DATA)
+
+# Generate the enums source code, with glib-mkenums:
+# This is based on the same Makefile.am stuff in pango:
+hildonlibs_built_headers = hildon-libs-enum-types.h
+hildonlibs_built_cfiles = hildon-libs-enum-types.c
+
+# Don't build the library until we have built the header that it needs:
+$(OBJECTS) $(libhildonwidgets_la_OBJECTS): $(hildonlibs_built_headers)
+
+hildon-libs-enum-types.h: @REBUILD@ $(headers_to_scan_for_enums) Makefile
+ (cd $(srcdir) && glib-mkenums \
+ --fhead "#ifndef __HILDON_LIBS_ENUM_TYPES_H__\n#define __HILDON_LIBS_ENUM_TYPES_H__\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS\n" \
+ --fprod "/* enumerations from \"@filename@\" */\n" \
+ --vhead "GType @enum_name@_get_type (void);\n#define HILDON_TYPE_@ENUMSHORT@ (@enum_name@_get_type())\n" \
+ --ftail "G_END_DECLS\n\n#endif /* __HILDON_LIBS_ENUM_TYPES_H__ */" \
+ $(headers_to_scan_for_enums)) > $@
+
+#FIXME: This would be shorter if there was a hildon-libs.h file:
+hildon-libs-enum-types.c: @REBUILD@ $(headers_to_scan_for_enums) Makefile
+ (cd $(srcdir) && glib-mkenums \
+ --fhead "#include <hildon-widgets/hildon-app.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-input-mode-hint.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-caption.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-date-editor.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-time-editor.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-number-editor.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-telephone-editor.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-note.h>\n" \
+ --fhead "#include <hildon-widgets/hildon-grid.h>\n" \
+ --fhead '#include "hildon-libs-enum-types.h"\n' \
+ --fhead "#include <glib-object.h>" \
+ --fprod "\n/* enumerations from \"@filename@\" */" \
+ --vhead "GType\n@enum_name@_get_type (void)\n{\n static GType etype = 0;\n if (etype == 0) {\n static const G@Type@Value values[] = {" \
+ --vprod " { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+ --vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
+ $(headers_to_scan_for_enums)) > $@
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:gtk-infoprint
+ * @short_description: deprecated widget. Use #HildonBanner instead
+ *
+ * This widget is deprecated. Use #HildonBanner instead
+ */
+
+#include "gtk-infoprint.h"
+#include "hildon-banner.h"
+
+/* This is a helper function that searches the banner for
+ given window. This is needed to provide backwards
+ compatibility. */
+static GtkWidget *find_banner_for_parent(GtkWindow *parent)
+{
+ GList *toplevels, *iter;
+ GtkWidget *result = NULL;
+ gboolean is_timed;
+
+ toplevels = gtk_window_list_toplevels();
+ for (iter = toplevels; iter; iter = iter->next)
+ if (HILDON_IS_BANNER(iter->data) &&
+ gtk_window_get_transient_for(GTK_WINDOW(iter->data)) == parent)
+ {
+ g_object_get(iter->data, "is-timed", &is_timed, NULL);
+
+ /* We do not want to touch timed infoprints */
+ if (!is_timed) {
+ result = iter->data;
+ break;
+ }
+ }
+
+ g_list_free(toplevels);
+ return result;
+}
+
+/**************************************************/
+/** Public **/
+/**************************************************/
+
+/**
+ * gtk_infoprint:
+ * @parent: The transient window for the infoprint.
+ * @text: The text in infoprint
+ *
+ * Opens a new infoprint with @text content.
+ *
+ * If parent is %NULL, the infoprint is a system infoprint.
+ * Normally you should use your application window
+ * or dialog as a transient parent and avoid passing %NULL.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void gtk_infoprint(GtkWindow * parent, const gchar * text)
+{
+ hildon_banner_show_information((GtkWidget *) parent, NULL, text);
+}
+
+/**
+ * gtk_infoprint_with_icon_stock:
+ * @parent: The transient window for the infoprint.
+ * @text: The text in infoprint
+ * @stock_id: The stock id of the custom icon
+ *
+ * Opens a new infoprint with @text content.
+ * With this function you can also set a custom icon
+ * by giving a stock id as last parameter.
+ *
+ * If parent is %NULL, the infoprint is a system infoprint.
+ * Normally you should use your application window
+ * or dialog as a transient parent and avoid passing %NULL.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void
+gtk_infoprint_with_icon_stock(GtkWindow * parent,
+ const gchar * text, const gchar * stock_id)
+{
+ hildon_banner_show_information((GtkWidget *) parent, NULL, text);
+}
+
+/**
+ * gtk_infoprint_with_icon_name:
+ * @parent: The transient window for the infoprint.
+ * @text: The text in infoprint
+ * @icon_name: The name of the icon
+ *
+ * Opens a new infoprint with @text content.
+ * With this function you can also set a custom icon
+ * by giving a icon name as last parameter.
+ *
+ * If parent is %NULL, the infoprint is a system infoprint.
+ * Normally you should use your application window
+ * or dialog as a transient parent and avoid passing %NULL.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void
+gtk_infoprint_with_icon_name(GtkWindow * parent,
+ const gchar * text, const gchar * icon_name)
+{
+ hildon_banner_show_information((GtkWidget *) parent, icon_name, text);
+}
+
+/**
+ * gtk_infoprintf:
+ * @parent: The transient window for the infoprint.
+ * @format: Format of the text.
+ * @Varargs: List of parameters.
+ *
+ * Opens a new infoprint with @text printf-style formatting
+ * string and comma-separated list of parameters.
+ *
+ * If parent is %NULL, the infoprint is a system infoprint.
+ * This version of infoprint allow you to make printf-like formatting
+ * easily.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...)
+{
+ gchar *message;
+ va_list args;
+
+ va_start(args, format);
+ message = g_strdup_vprintf(format, args);
+ va_end(args);
+
+ gtk_infoprint(parent, message);
+
+ g_free(message);
+}
+
+/**
+ * gtk_infoprint_temporarily_disable_wrap:
+ *
+ * Will disable wrapping for the next shown infoprint. This only
+ * affects next infoprint shown in this application.
+ *
+ * Currently it does nothing.
+ *
+ * Deprecated:
+ */
+void gtk_infoprint_temporarily_disable_wrap(void)
+{
+}
+
+/**
+ * gtk_confirmation_banner:
+ * @parent: The transient window for the confirmation banner.
+ * @text: The text in confirmation banner
+ * @stock_id: The stock id of the custom icon
+ *
+ * Opens a new confirmation banner with @text content.
+ * With this function you can also set a custom icon
+ * by giving a stock id as last parameter.
+ *
+ * If parent is %NULL, the banner is a system banner.
+ * Normally you should use your application window
+ * or dialog as a transient parent and avoid passing %NULL.
+ *
+ * This function is otherwise similar to
+ * gtk_infoprint_with_icon_stock except in always restricts
+ * the text to one line and the font is emphasized.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void
+gtk_confirmation_banner(GtkWindow * parent, const gchar * text,
+ const gchar * stock_id)
+{
+ gchar *s;
+ s = g_strdup_printf("<b>%s</b>", text);
+
+ hildon_banner_show_information_with_markup((GtkWidget *) parent, NULL, s);
+
+ g_free(s);
+}
+
+/**
+ * gtk_confirmation_banner_with_icon_name:
+ * @parent: The transient window for the confirmation banner.
+ * @text: The text in confirmation banner
+ * @icon_name: The name of the custom icon in icon theme
+ *
+ * Opens a new confirmation banner with @text content.
+ * With this function you can also set a custom icon
+ * by giving a icon theme's icon name as last parameter.
+ *
+ * If parent is %NULL, the banner is a system banner.
+ * Normally you should use your application window
+ * or dialog as a transient parent and avoid passing %NULL.
+ *
+ * This function is otherwise similar to
+ * gtk_infoprint_with_icon_name except in always restricts
+ * the text to one line and the font is emphasized.
+ *
+ * Deprecated: Use #hildon_banner_show_information instead.
+ */
+void
+gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text,
+ const gchar * icon_name)
+{
+ gchar *s;
+ s = g_strdup_printf("<b>%s</b>", text);
+
+ hildon_banner_show_information_with_markup((GtkWidget *) parent, icon_name, s);
+
+ g_free(s);
+}
+
+/**
+ * gtk_banner_show_animation:
+ * @parent: #GtkWindow
+ * @text: #const gchar *
+ *
+ * The @text is the text shown in banner.
+ * Creates a new banner with the animation.
+ *
+ * Deprecated: Use #hildon_banner_show_animation instead.
+ */
+void gtk_banner_show_animation(GtkWindow * parent, const gchar * text)
+{
+ (void) hildon_banner_show_animation((GtkWidget *) parent, NULL, text);
+}
+
+/**
+ * gtk_banner_show_bar
+ * @parent: #GtkWindow
+ * @text: #const gchar *
+ *
+ * The @text is the text shown in banner.
+ * Creates a new banner with the progressbar.
+ *
+ * Deprecated: Use #hildon_banner_show_progress instead.
+ */
+void gtk_banner_show_bar(GtkWindow * parent, const gchar * text)
+{
+ (void) hildon_banner_show_progress((GtkWidget *) parent, NULL, text);
+}
+
+/**
+ * gtk_banner_set_text
+ * @parent: #GtkWindow
+ * @text: #const gchar *
+ *
+ * The @text is the text shown in banner.
+ * Sets the banner text.
+ *
+ * Deprecated: Use #hildon_banner_set_text instead.
+ */
+void gtk_banner_set_text(GtkWindow * parent, const gchar * text)
+{
+ GtkWidget *banner;
+
+ g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
+
+ banner = find_banner_for_parent(parent);
+ if (banner)
+ hildon_banner_set_text(HILDON_BANNER(banner), text);
+}
+
+/**
+ * gtk_banner_set_fraction:
+ * @parent: #GtkWindow
+ * @fraction: #gdouble
+ *
+ * The fraction is the completion of progressbar,
+ * the scale is from 0.0 to 1.0.
+ * Sets the amount of fraction the progressbar has.
+ *
+ * Deprecated: Use #hildon_banner_set_fraction instead.
+ */
+void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction)
+{
+ GtkWidget *banner;
+
+ g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
+
+ banner = find_banner_for_parent(parent);
+ if (banner)
+ hildon_banner_set_fraction(HILDON_BANNER(banner), fraction);
+}
+
+/**
+ * gtk_banner_close:
+ * @parent: #GtkWindow
+ *
+ * Destroys the banner
+ *
+ * Deprecated:
+ */
+void gtk_banner_close(GtkWindow * parent)
+{
+ GtkWidget *banner;
+
+ g_return_if_fail(GTK_IS_WINDOW(parent) || parent == NULL);
+
+ banner = find_banner_for_parent(parent);
+ if (banner)
+ gtk_widget_destroy(banner);
+}
+
+/**
+ * gtk_banner_temporarily_disable_wrap
+ *
+ * Will disable wrapping for the next shown banner. This only
+ * affects next banner shown in this application.
+ *
+ * Currently it does nothing.
+ *
+ * Deprecated:
+ **/
+void gtk_banner_temporarily_disable_wrap(void)
+{
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __GTK_INFOPRINT_H__
+#define __GTK_INFOPRINT_H__
+
+#include <gtk/gtkwindow.h>
+
+G_BEGIN_DECLS void gtk_infoprint(GtkWindow * parent, const gchar * text);
+void gtk_infoprint_with_icon_stock(GtkWindow * parent, const gchar * text,
+ const gchar * stock_id);
+void gtk_infoprint_with_icon_name(GtkWindow * parent, const gchar * text,
+ const gchar * icon_name);
+
+void gtk_infoprintf(GtkWindow * parent, const gchar * format, ...);
+void gtk_infoprint_temporarily_disable_wrap(void);
+
+void gtk_confirmation_banner_with_icon_name(GtkWindow * parent, const gchar * text,
+ const gchar * icon_name);
+void gtk_confirmation_banner(GtkWindow * parent, const gchar * text,
+ const gchar * stock_id);
+
+void gtk_banner_show_animation(GtkWindow * parent, const gchar * text);
+void gtk_banner_show_bar(GtkWindow * parent, const gchar * text);
+void gtk_banner_set_text(GtkWindow * parent, const gchar * text);
+void gtk_banner_set_fraction(GtkWindow * parent, gdouble fraction);
+void gtk_banner_close(GtkWindow * parent);
+void gtk_banner_temporarily_disable_wrap(void);
+
+G_END_DECLS
+#endif /* __GTK_INFOPRINT_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+
+#include "hildon-add-home-dialog.h"
+#include <hildon-widgets/hildon-caption.h>
+
+#define _(String) dgettext(PACKAGE, String)
+#define MAX_ERR_MSG 256
+#define HILDON_ADD_HOME_DIALOG_WIDTH 370
+#define HILDON_ADD_HOME_DIALOG_HEIGHT 100
+#define HILDON_MAX_TITLE_LENGTH 256
+#define HILDON_HOME_MAX_SHORTCUT_LEN 255
+
+#define HILDON_ADD_HOME_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_ADD_HOME_DIALOG, \
+ HildonAddHomeDialogPrivate));
+
+typedef struct _HildonAddHomeDialogPrivate HildonAddHomeDialogPrivate;
+
+static GtkDialogClass *parent_class;
+
+static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog);
+static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name);
+static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* name);
+static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename);
+
+static void
+hildon_add_home_dialog_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+static void
+hildon_add_home_dialog_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void
+hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * class);
+static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog);
+
+/* private struct */
+
+struct _HildonAddHomeDialogPrivate {
+ GtkWidget *desc_label;
+ GtkWidget *name_entry; /* Used when isrename */
+ GtkWidget *name_label; /* Used when !isrename */
+ GtkWidget *caption_name_entry; /* Used when isrename */
+ GtkWidget *new_name_entry;
+ GtkWidget *caption_new_name_entry;
+ GtkSizeGroup *size_group;
+ GtkWidget *okButton;
+ GtkWidget *cancelButton;
+ gboolean isrename;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_NAME,
+ PROP_NEW_NAME,
+};
+
+/* Private functions */
+
+static void
+hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * klass)
+{
+ GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
+ parent_class = g_type_class_peek_parent(klass);
+
+ gobject_class->set_property = hildon_add_home_dialog_set_property;
+ gobject_class->get_property = hildon_add_home_dialog_get_property;
+
+ /**
+ * HildonAddHomeDialog:name
+ *
+ * The name
+ */
+ g_object_class_install_property(gobject_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ ("Name"),
+ ("The name."),
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * HildonAddHomeDialog:new_name
+ *
+ * The new name
+ */
+ g_object_class_install_property(gobject_class,
+ PROP_NEW_NAME,
+ g_param_spec_string ("new_name",
+ ("New Name"),
+ ("The new name."),
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private(klass, sizeof(HildonAddHomeDialogPrivate));
+}
+
+static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+ priv->name_entry = NULL;
+ priv->name_label = NULL;
+ priv->caption_name_entry = NULL;
+ priv->new_name_entry = NULL;
+ priv->isrename = FALSE;
+
+ priv->okButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ "addtoHome_button_ok",
+ GTK_RESPONSE_OK);
+ priv->cancelButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
+ "addtoHome_button_cancel",
+ GTK_RESPONSE_CANCEL);
+
+ gtk_window_resize(GTK_WINDOW(dialog),
+ HILDON_ADD_HOME_DIALOG_WIDTH,
+ HILDON_ADD_HOME_DIALOG_HEIGHT);
+
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
+
+ priv->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+
+ /* add description text (only shown when isrename==true */
+ priv->desc_label = gtk_label_new(_("ckdg_ib_link_exists"));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->desc_label, FALSE, FALSE, 0);
+
+ /* We don't use the hildon_caption_new() C convenience function, because it demands a non-NULL child widget (via gtk_container_add()). */
+ priv->caption_name_entry = GTK_WIDGET( g_object_new( HILDON_TYPE_CAPTION, "size_group", priv->size_group, "label", "addtoHome_editor_caption", "status", HILDON_CAPTION_OPTIONAL, NULL) );
+ gtk_widget_show(priv->caption_name_entry);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), priv->caption_name_entry,
+ FALSE, FALSE, 0);
+
+
+ gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
+}
+
+/* Public functions */
+
+GType hildon_add_home_dialog_get_type(void)
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonAddHomeDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_add_home_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonAddHomeDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_add_home_dialog_init
+ };
+
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonAddHomeDialog",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+static void
+hildon_add_home_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
+ HildonAddHomeDialogPrivate *priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ switch(prop_id)
+ {
+ case PROP_NAME:
+ {
+ const gchar* name = NULL;
+ if(priv->isrename && priv->name_label)
+ name = gtk_entry_get_text(GTK_ENTRY(priv->name_label));
+ else if(!(priv->isrename) && priv->name_entry)
+ name = gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
+
+ g_value_set_string (value, name);
+ break;
+ }
+ case PROP_NEW_NAME:
+ {
+ const gchar* new_name = NULL;
+ if(priv->isrename && priv->new_name_entry)
+ new_name = gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
+
+ g_value_set_string (value, new_name);
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_add_home_dialog_set_window_title (HildonAddHomeDialog * dialog)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ /* Set up the window title */
+ if (priv->isrename)
+ gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_rename_link"));
+ else
+ gtk_window_set_title(GTK_WINDOW(dialog), "addtoHome_dialog_title");
+}
+
+
+static void
+hildon_add_home_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ hildon_add_home_dialog_set_old_name (dialog, g_value_get_string (value));
+ break;
+ case PROP_NEW_NAME:
+ hildon_add_home_dialog_set_new_name (dialog, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * hildon_add_home_dialog_new:
+ * @parent: parent window for the dialog
+ * @name: name to show in the entry (or label, if @new_name is not NULL)
+ * @new_name: name to show in the new name entry. If this is not NULL
+ * the widget acts as a RenameShortcutDialog.
+ *
+ * Creates a new Add to Home dialog or Rename Shortcut dialog.
+ *
+ * Returns: the new dialog.
+ */
+GtkWidget *hildon_add_home_dialog_new(GtkWindow * parent,
+ const gchar * name,
+ const gchar * new_name)
+{
+ HildonAddHomeDialog *dialog =
+ HILDON_ADD_HOME_DIALOG(g_object_new
+ (HILDON_TYPE_ADD_HOME_DIALOG, "name", name, "new_name", new_name, NULL));
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return GTK_WIDGET(dialog);
+}
+
+/**
+ * hildon_add_home_dialog_get_name:
+ * @dialog: the dialog
+ *
+ * Returns: the string the user has entered in the entry
+ */
+const gchar *hildon_add_home_dialog_get_name(HildonAddHomeDialog * dialog)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ if (priv->isrename && priv->new_name_entry)
+ return gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
+ else if(priv->name_entry)
+ return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
+ else
+ return NULL;
+}
+
+static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ if (priv->isrename && priv->name_label)
+ return gtk_label_get_text(GTK_LABEL(priv->name_label));
+ else if(!priv->isrename && priv->name_entry)
+ return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
+ else
+ return NULL;
+}
+
+static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
+
+ /* Set text in the widgets: */
+ if (priv->isrename)
+ gtk_label_set_text(GTK_LABEL(priv->name_label), name);
+ else
+ gtk_entry_set_text(GTK_ENTRY(priv->name_entry), name);
+}
+
+static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* new_name)
+{
+ HildonAddHomeDialogPrivate *priv;
+ gchar* name = NULL;
+ gboolean new_isrename = FALSE;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ /* We get the old name, in case we need to set it again in a new widget. */
+ name = g_strdup( hildon_add_home_dialog_get_old_name(dialog) );
+ new_isrename = (new_name != NULL);
+
+ hildon_add_home_dialog_create_widgets(dialog, new_isrename);
+
+
+ /* Set text in the widgets: */
+ if(priv->isrename)
+ {
+ gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), new_name);
+ gtk_label_set_text(GTK_LABEL(priv->name_label), (name) ? name : "");
+ }
+ else
+ {
+ gtk_entry_set_text(GTK_ENTRY(priv->name_entry), (name) ? name : "");
+ }
+
+ if(name)
+ g_free(name);
+}
+
+static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ /* Create and destroy widgets, depending on the mode.
+ * Note that we are making a small speed sacrifice (recreating the widgets)
+ * in exchange for memory (creating all widgets and just hiding the ones we don't use.)
+ */
+
+ if(priv->isrename && !new_isrename)
+ {
+ /* Remove widgets that were used for isrename mode,
+ because we don't need them anymore. */
+ if(priv->new_name_entry)
+ {
+ gtk_widget_destroy(priv->new_name_entry);
+ priv->new_name_entry = NULL;
+ }
+
+ if(priv->caption_new_name_entry)
+ {
+ gtk_widget_destroy(priv->caption_new_name_entry);
+ priv->caption_new_name_entry = NULL;
+ }
+
+ if(priv->name_label) /* A label */
+ {
+ gtk_widget_destroy(priv->name_label);
+ priv->name_label = NULL;
+ }
+
+ if(priv->name_entry) /* A box with label inside */
+ {
+ gtk_widget_destroy(priv->name_entry);
+ priv->name_entry = NULL;
+ }
+ }
+ else if(!priv->isrename && new_isrename)
+ {
+ /* Remove widgets that were used only for !isrename mode,
+ because we don't need them anymore. */
+ if(priv->name_entry) /* An entry. */
+ {
+ gtk_widget_destroy(priv->name_entry);
+ priv->name_entry = NULL;
+ }
+ }
+
+ priv->isrename = new_isrename;
+
+ if(priv->isrename)
+ {
+ /* Create widgets needed for isrename mode: */
+
+ /* Create Entry (in a Caption) for the new name, and pack it into the dialog: */
+ if(!priv->new_name_entry)
+ {
+ priv->new_name_entry = gtk_entry_new();
+ gtk_widget_show(priv->new_name_entry);
+ }
+
+ if(!priv->caption_new_name_entry)
+ {
+ priv->caption_new_name_entry = hildon_caption_new(priv->size_group, _("ckdg_fi_rename_name"),
+ priv->new_name_entry, NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_widget_show(priv->caption_new_name_entry);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(priv->caption_new_name_entry),
+ FALSE, FALSE, 0);
+ }
+
+ /* add description text */
+ if(priv->desc_label)
+ gtk_widget_show(priv->desc_label);
+
+ /* Create Label (in a Box) for the existing name: */
+ if(!priv->name_entry)
+ {
+ priv->name_label = gtk_label_new(NULL);
+ gtk_widget_show(priv->name_label);
+
+ priv->name_entry = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(priv->name_entry);
+ gtk_box_pack_start(GTK_BOX(priv->name_entry), priv->name_label, FALSE, FALSE,
+ 0);
+ gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
+ }
+ }
+ else
+ {
+ if(priv->desc_label)
+ gtk_widget_hide(priv->desc_label);
+
+ /* Create widgets needed for !isrename mode: */
+ if(!priv->name_entry)
+ {
+ priv->name_entry = gtk_entry_new();
+ gtk_widget_show(priv->name_entry);
+ gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
+ }
+ }
+
+ hildon_add_home_dialog_set_window_title(dialog);
+
+ priv->isrename = new_isrename;
+}
+
+void hildon_add_home_dialog_set_name(HildonAddHomeDialog * dialog, const gchar* name)
+{
+ HildonAddHomeDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
+ priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
+
+ hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
+
+ /* Set text in the widgets: */
+ if (priv->isrename)
+ gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), name);
+ else
+ gtk_label_set_text(GTK_LABEL(priv->name_entry), name);
+}
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_ADD_HOME_DIALOG_H__
+#define __HILDON_ADD_HOME_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_ADD_HOME_DIALOG \
+ ( hildon_add_home_dialog_get_type() )
+#define HILDON_ADD_HOME_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_ADD_HOME_DIALOG, HildonAddHomeDialog))
+#define HILDON_ADD_HOME_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_ADD_HOME_DIALOG, \
+ HildonAddHomeDialogClass))
+#define HILDON_IS_ADD_HOME_DIALOG(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_ADD_HOME_DIALOG))
+#define HILDON_IS_ADD_HOME_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_ADD_HOME_DIALOG))
+typedef struct _HildonAddHomeDialog HildonAddHomeDialog;
+typedef struct _HildonAddHomeDialogClass HildonAddHomeDialogClass;
+
+struct _HildonAddHomeDialog {
+ GtkDialog parent;
+};
+
+struct _HildonAddHomeDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_add_home_dialog_get_type(void);
+
+GtkWidget *hildon_add_home_dialog_new(GtkWindow * parent,
+ const gchar * name,
+ const gchar * new_name);
+const gchar *hildon_add_home_dialog_get_name(HildonAddHomeDialog * dialog);
+
+G_END_DECLS
+#endif /* __HILDON_ADD_HOME_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef HILDON_APP_PRIVATE_H
+#define HILDON_APP_PRIVATE_H
+
+G_BEGIN_DECLS
+
+enum {
+ TOPMOST_STATUS_ACQUIRE,
+ TOPMOST_STATUS_LOSE,
+ SWITCH_TO,
+ IM_CLOSE,
+ CLIPBOARD_COPY,
+ CLIPBOARD_CUT,
+ CLIPBOARD_PASTE,
+
+ HILDON_APP_LAST_SIGNAL
+};
+
+struct _HildonAppPrivate {
+ GList *children;
+ gchar *title;
+#ifndef HILDON_DISABLE_DEPRECATED
+ HildonZoomLevel zoom;
+#endif
+
+ /* Used to keep track of menu key press/release */
+ gint lastmenuclick;
+
+ gulong curr_view_id;
+ gulong view_id_counter;
+ GSList *view_ids;
+ gboolean scroll_control;
+
+ guint twoparttitle: 1;
+ guint is_topmost: 1;
+ gboolean killable;
+ gboolean autoregistration;
+
+ guint escape_timeout;
+ guint key_snooper;
+
+ GtkUIManager *uim;
+
+ guint active_menu_id;
+};
+
+typedef struct {
+ gpointer view_ptr;
+ unsigned long view_id;
+} view_item;
+
+G_END_DECLS
+
+#endif /* HILDON_APP_PRIVATE_H */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-app
+ * @short_description: A base widget to present application. Deprecated, use #HildonProgram instead.
+ * @see_also: #HildonAppView
+ *
+ * #HildonApp is the base for any hildon application.
+ * It controls basic looks and functionality of an application, like a title.
+ *
+ * This widget is deprecated use #HildonProgram instead.
+ */
+
+#include <gdk/gdk.h>
+#include "hildon-app.h"
+#include "hildon-app-private.h"
+#include "hildon-appview.h"
+#include "gtk-infoprint.h"
+
+#include <gdk/gdkevents.h>
+#include <gdk/gdkkeysyms.h>
+#include <X11/Xatom.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkeditable.h>
+#include <gtk/gtktextview.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkuimanager.h>
+#include <gtk/gtkactiongroup.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkcombobox.h>
+
+#include <libintl.h>
+#include <string.h>
+
+#include <libmb/mbutil.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define TITLE_DELIMITER " - "
+
+/*
+ * 'Magic' values for the titlebar menu area limits
+ */
+#define MENUAREA_LEFT_LIMIT 80
+#define MENUAREA_RIGHT_LIMIT MENUAREA_LEFT_LIMIT + 307
+#define MENUAREA_TOP_LIMIT 0
+#define MENUAREA_BOTTOM_LIMIT 39
+
+#define KILLABLE "CANKILL"
+
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_APP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_APP, HildonAppPrivate));
+
+static GtkWindowClass *parent_class;
+static guint app_signals[HILDON_APP_LAST_SIGNAL] = { 0 };
+
+typedef struct _HildonAppPrivate HildonAppPrivate;
+
+static gboolean
+hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent);
+static gboolean
+hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent);
+static gboolean
+hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app);
+static GdkFilterReturn
+hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data);
+static void
+hildon_app_construct_title (HildonApp *self);
+static void
+hildon_app_finalize (GObject *obj_self);
+static void
+hildon_app_destroy (GtkObject *obj);
+static void
+hildon_app_init (HildonApp *self);
+static void
+hildon_app_class_init (HildonAppClass *app_class);
+static void
+hildon_app_real_topmost_status_acquire (HildonApp *self);
+static void
+hildon_app_real_topmost_status_lose (HildonApp *self);
+static void
+hildon_app_real_switch_to (HildonApp *self);
+static gboolean
+hildon_app_button (GtkWidget *widget, GdkEventButton *event);
+static GdkWindow *
+find_window (GdkWindow *window, gint by, gint co);
+static void
+hildon_app_clipboard_copy(HildonApp *self, GtkWidget *widget);
+static void
+hildon_app_clipboard_cut(HildonApp *self, GtkWidget *widget);
+static void
+hildon_app_clipboard_paste(HildonApp *self, GtkWidget *widget);
+static gboolean hildon_app_escape_timeout(gpointer data);
+
+static void hildon_app_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+static void hildon_app_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+
+static void hildon_app_add (GtkContainer *container, GtkWidget *child);
+static void hildon_app_remove (GtkContainer *container, GtkWidget *child);
+static void hildon_app_forall (GtkContainer *container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data);
+
+enum {
+ PROP_0,
+ PROP_SCROLL_CONTROL,
+ /* FIXME: Zoom is deprecated, should be removed */
+ PROP_ZOOM,
+ PROP_TWO_PART_TITLE,
+ PROP_APP_TITLE,
+ PROP_KILLABLE,
+ PROP_AUTOREGISTRATION,
+ PROP_APPVIEW,
+ PROP_UI_MANAGER
+};
+
+static gpointer find_view(HildonApp *self, unsigned long view_id);
+
+/* FIXME: Zoom level is deprecated, should be removed */
+/**
+ * hildon_zoom_level_get_type:
+ *
+ * Initialises, and returns the type of a hildon zoom level
+ *
+ * Returns: GType of #HildonZoomLevel
+ */
+
+GType
+hildon_zoom_level_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { HILDON_ZOOM_SMALL, "HILDON_ZOOM_SMALL", "small" },
+ { HILDON_ZOOM_MEDIUM, "HILDON_ZOOM_MEDIUM", "medium" },
+ { HILDON_ZOOM_LARGE, "HILDON_ZOOM_LARGE", "large" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("HildonZoomLevel", values);
+ }
+ return etype;
+}
+
+GType hildon_app_get_type(void)
+{
+ static GType app_type = 0;
+
+ if (!app_type)
+ {
+ static const GTypeInfo app_info =
+ {
+ sizeof(HildonAppClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_app_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonApp),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_app_init,
+ };
+ app_type = g_type_register_static(GTK_TYPE_WINDOW,
+ "HildonApp", &app_info, 0);
+ }
+ return app_type;
+}
+
+/*
+ * Sets or delete a custom property into the XServer, according
+ * to the boolean value of HildonAppPrivate::killable
+ */
+static void hildon_app_apply_killable(HildonApp *self)
+{
+ HildonAppPrivate *priv;
+ Atom killability_atom = XInternAtom (GDK_DISPLAY(),
+ "_HILDON_APP_KILLABLE", False);
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ g_assert (HILDON_IS_APP (self) );
+ g_assert(GTK_WIDGET_REALIZED(self));
+
+ if (priv->killable)
+ {
+ /* Set the atom to specific value, because perhaps in the future,
+ there may be other possible values? */
+ XChangeProperty(GDK_DISPLAY(),
+ GDK_WINDOW_XID(GTK_WIDGET(self)->window),
+ killability_atom, XA_STRING, 8,
+ PropModeReplace, (unsigned char *)KILLABLE,
+ strlen(KILLABLE));
+ }
+ else
+ {
+ XDeleteProperty(GDK_DISPLAY(),
+ GDK_WINDOW_XID(GTK_WIDGET(self)->window),
+ killability_atom);
+ }
+}
+
+/*
+ * Updates the _NET_CLIENT_LIST property into the XServer.
+ * It is the list of the views associated to the HildonApp.
+ * It will be used by the Task Navigator in order to be able to show a list
+ * of all the views, and let the user switch and navigate them.
+ */
+static void hildon_app_apply_client_list(HildonApp *self)
+{
+ HildonAppPrivate *priv;
+ Window *win_array;
+ GSList *list_ptr;
+ int loopctr = 0;
+ Atom clientlist;
+
+ g_assert (HILDON_IS_APP (self) );
+ g_assert(GTK_WIDGET_REALIZED(self));
+
+ /* Get the client list handle */
+ clientlist = XInternAtom (GDK_DISPLAY(),
+ "_NET_CLIENT_LIST", False);
+
+ /* Allocate a new array for window IDs */
+ priv = HILDON_APP_GET_PRIVATE(self);
+ win_array = g_new(Window, g_slist_length(priv->view_ids));
+
+ /* Fill the contents of the window array with current view IDs */
+ for (list_ptr = priv->view_ids; list_ptr; list_ptr = list_ptr->next)
+ {
+ win_array[loopctr] =
+ (unsigned long)(((view_item *)(list_ptr->data))->view_id);
+ loopctr++;
+ }
+
+ /* Update the details of current view IDs to our X property */
+ XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window),
+ clientlist, XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)win_array,
+ g_slist_length(priv->view_ids));
+
+ XFlush(GDK_DISPLAY());
+ g_free(win_array);
+}
+
+/*
+ * Performs the standard gtk realize function.
+ */
+static void hildon_app_realize(GtkWidget *widget)
+{
+ HildonApp *self;
+ HildonAppPrivate *priv;
+ GdkWindow *window;
+ Atom *old_atoms, *new_atoms;
+ gint atom_count;
+ Display *disp;
+
+ g_assert(widget != NULL);
+
+ self = HILDON_APP(widget);
+ priv = HILDON_APP_GET_PRIVATE(self);
+
+ /*
+ * Of course we need to realize the parent.
+ * parent_class got already initialised in the hildon_app_init function
+ */
+ GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+ /* some initialisation code */
+ hildon_app_apply_killable(self);
+ hildon_app_construct_title(self);
+ hildon_app_apply_client_list(self);
+ hildon_app_notify_view_changed(self, hildon_app_get_appview(self));
+ window = widget->window;
+ disp = GDK_WINDOW_XDISPLAY(window);
+
+ /* Install a key snooper for the Home button - so that it works everywhere */
+ priv->key_snooper = gtk_key_snooper_install
+ ((GtkKeySnoopFunc) hildon_app_key_snooper, widget);
+
+ /* Get the list of Atoms for the WM_PROTOCOLS property... */
+ XGetWMProtocols(disp, GDK_WINDOW_XID(window), &old_atoms, &atom_count);
+ new_atoms = g_new(Atom, atom_count + 1);
+
+ memcpy(new_atoms, old_atoms, sizeof(Atom) * atom_count);
+
+ /* ... creates a new Atom... */
+ new_atoms[atom_count++] =
+ XInternAtom(disp, "_NET_WM_CONTEXT_CUSTOM", False);
+
+ /* ... and finally update the property within the XServer */
+ XSetWMProtocols(disp, GDK_WINDOW_XID(window), new_atoms, atom_count);
+
+ XFree(old_atoms);
+ g_free(new_atoms);
+
+ /* Add the GDK_SUBSTRUCTURE_MASK (receive events about window configuration
+ * changes of child windows) to the window.
+ */
+ gdk_window_set_events(window, gdk_window_get_events(window) | GDK_SUBSTRUCTURE_MASK);
+}
+
+/*
+ * Performs the standard gtk unrealize function.
+ */
+static void hildon_app_unrealize(GtkWidget *widget)
+{
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(widget);
+
+ if (priv->key_snooper)
+ {
+ /* removing the snooper that handles MENU key presses */
+ gtk_key_snooper_remove(priv->key_snooper);
+ priv->key_snooper = 0;
+ }
+
+ gdk_window_remove_filter(NULL, hildon_app_event_filter, widget);
+ GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+/*
+ * Class initialisation.
+ */
+static void hildon_app_class_init (HildonAppClass *app_class)
+{
+ /* get convenience variables */
+ GObjectClass *object_class = G_OBJECT_CLASS(app_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (app_class);
+ GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS(app_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(app_class);
+
+ /* set the global parent_class here */
+ parent_class = g_type_class_peek_parent(app_class);
+
+ g_type_class_add_private(app_class, sizeof(HildonAppPrivate));
+
+ /* now the object stuff */
+ object_class->finalize = hildon_app_finalize;
+ object_class->set_property = hildon_app_set_property;
+ object_class->get_property = hildon_app_get_property;
+
+ gtkobject_class->destroy = hildon_app_destroy;
+
+ widget_class->key_press_event = hildon_app_key_press;
+ widget_class->key_release_event = hildon_app_key_release;
+ widget_class->button_press_event = hildon_app_button;
+ widget_class->button_release_event = hildon_app_button;
+ widget_class->realize = hildon_app_realize;
+ widget_class->unrealize = hildon_app_unrealize;
+
+ container_class->add = hildon_app_add;
+ container_class->remove = hildon_app_remove;
+ container_class->forall = hildon_app_forall;
+
+ app_class->topmost_status_acquire =
+ hildon_app_real_topmost_status_acquire;
+ app_class->topmost_status_lose = hildon_app_real_topmost_status_lose;
+ app_class->switch_to = hildon_app_real_switch_to;
+
+ /* create the signals */
+ app_signals[TOPMOST_STATUS_ACQUIRE] =
+ g_signal_new("topmost_status_acquire",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass,
+ topmost_status_acquire), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ app_signals[TOPMOST_STATUS_LOSE] =
+ g_signal_new("topmost_status_lose",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, topmost_status_lose),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ app_signals[SWITCH_TO] =
+ g_signal_new("switch_to",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, switch_to),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ app_signals[IM_CLOSE] =
+ g_signal_new("im_close",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, im_close),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ app_signals[CLIPBOARD_COPY] =
+ g_signal_new("clipboard_copy",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, clipboard_copy),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GTK_TYPE_WIDGET);
+ app_signals[CLIPBOARD_CUT] =
+ g_signal_new("clipboard_cut",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, clipboard_cut),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GTK_TYPE_WIDGET);
+ app_signals[CLIPBOARD_PASTE] =
+ g_signal_new("clipboard_paste",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppClass, clipboard_paste),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GTK_TYPE_WIDGET);
+
+ /* properties */
+ g_object_class_install_property(object_class, PROP_SCROLL_CONTROL,
+ g_param_spec_boolean("scroll-control",
+ "Scroll control",
+ "Set the scroll control ON/OFF",
+ TRUE, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_TWO_PART_TITLE,
+ g_param_spec_boolean("two-part-title",
+ "Two part title",
+ "Use two part title or not",
+ FALSE, G_PARAM_READWRITE));
+#ifndef HILDON_DISABLE_DEPRECATED
+ g_object_class_install_property(object_class, PROP_ZOOM,
+ g_param_spec_enum ("zoom",
+ "Zoom level",
+ "Set the zoom level",
+ HILDON_TYPE_ZOOM_LEVEL,
+ HILDON_ZOOM_MEDIUM,
+ G_PARAM_READWRITE));
+#endif
+ g_object_class_install_property(object_class, PROP_APP_TITLE,
+ g_param_spec_string ("app-title",
+ "Application title",
+ "Set the application title",
+ "",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_KILLABLE,
+ g_param_spec_boolean("killable",
+ "Killable",
+ "Whether the application is killable or not",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class, PROP_AUTOREGISTRATION,
+ g_param_spec_boolean("autoregistration",
+ "Autoregistration",
+ "Whether the application views should be registered automatically",
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class, PROP_APPVIEW,
+ g_param_spec_object("appview",
+ "Appplication View",
+ "The currently active application view",
+ HILDON_TYPE_APPVIEW,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class, PROP_UI_MANAGER,
+ g_param_spec_object("ui-manager",
+ "UIManager",
+ "The associated GtkUIManager for this app",
+ GTK_TYPE_UI_MANAGER,
+ G_PARAM_READWRITE));
+}
+
+/*
+ * Performs the standard gtk finalize function, freeing allocated
+ * memory and propagating the finalization to the parent.
+ */
+static void
+hildon_app_finalize (GObject *obj)
+{
+ HildonAppPrivate *priv = NULL;
+
+ g_assert (obj != NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (obj);
+
+ g_free (priv->title);
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
+
+ /* FIXME: This is legacy code, but cannot be removed
+ without changing functionality */
+ gtk_main_quit ();
+}
+
+/*
+ * Removes the long escape ("cancel" hw key) press timeout.
+ */
+static void
+hildon_app_remove_timeout(HildonAppPrivate *priv)
+{
+ g_assert(priv != NULL);
+
+ if (priv->escape_timeout > 0)
+ {
+ g_source_remove (priv->escape_timeout);
+ priv->escape_timeout = 0;
+ }
+}
+
+/*
+ * Frees all the resources and propagates the destroy call to the parent.
+ */
+static void
+hildon_app_destroy (GtkObject *obj)
+{
+ HildonAppPrivate *priv = NULL;
+
+ g_assert (obj != NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (obj);
+
+ /* Just in case a GDK_Escape key was pressed shortly before the propagation
+ * of this event, it is safer to remove the timeout that will generate a
+ * GDK_DELETE key press. We are destroying the app, so we're not interested
+ * anymore in processing key presses.
+ */
+ hildon_app_remove_timeout(priv);
+
+ if (priv->uim != NULL)
+ {
+ g_object_unref (G_OBJECT (priv->uim));
+ priv->uim = NULL;
+ }
+
+ /* Free all the views */
+ if (priv->view_ids)
+ {
+ g_slist_foreach (priv->view_ids, (GFunc)g_free, NULL);
+ g_slist_free (priv->view_ids);
+ priv->view_ids = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ GTK_OBJECT_CLASS (parent_class)->destroy(obj);
+}
+
+/*
+ * Overrides gtk_container_forall, calling the callback function for each of
+ * the children of HildonAppPrivate.
+ */
+static void hildon_app_forall (GtkContainer *container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonAppPrivate *priv = NULL;
+
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (callback != NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (container);
+
+ /* Note! we only have user added children, no internals */
+ g_list_foreach (priv->children, (GFunc)callback, callback_data);
+}
+
+/*
+ * An accessor to set private properties of HildonAppPrivate.
+ */
+static void hildon_app_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object);
+
+ switch (property_id) {
+ case PROP_SCROLL_CONTROL:
+ priv->scroll_control = g_value_get_boolean(value);
+ break;
+#ifndef HILDON_DISABLE_DEPRECATED
+ case PROP_ZOOM:
+ hildon_app_set_zoom( HILDON_APP (object), g_value_get_enum (value) );
+ break;
+#endif
+ case PROP_TWO_PART_TITLE:
+ hildon_app_set_two_part_title( HILDON_APP (object),
+ g_value_get_boolean (value) );
+ break;
+ case PROP_APP_TITLE:
+ hildon_app_set_title( HILDON_APP (object), g_value_get_string (value));
+ break;
+ case PROP_KILLABLE:
+ hildon_app_set_killable( HILDON_APP (object),
+ g_value_get_boolean (value));
+ break;
+ case PROP_AUTOREGISTRATION:
+ hildon_app_set_autoregistration( HILDON_APP (object),
+ g_value_get_boolean (value));
+ break;
+ case PROP_APPVIEW:
+ hildon_app_set_appview( HILDON_APP (object),
+ HILDON_APPVIEW (g_value_get_object (value)));
+ break;
+ case PROP_UI_MANAGER:
+ hildon_app_set_ui_manager( HILDON_APP (object),
+ GTK_UI_MANAGER (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * An accessor to get private properties of HildonAppPrivate.
+ */
+static void hildon_app_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(object);
+
+ switch (property_id) {
+ case PROP_SCROLL_CONTROL:
+ g_value_set_boolean( value, priv->scroll_control );
+ break;
+#ifndef HILDON_DISABLE_DEPRECATED
+ case PROP_ZOOM:
+ g_value_set_enum( value, priv->zoom);
+ break;
+#endif
+ case PROP_TWO_PART_TITLE:
+ g_value_set_boolean( value, priv->twoparttitle);
+ break;
+ case PROP_APP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+ case PROP_KILLABLE:
+ g_value_set_boolean (value, priv->killable);
+ break;
+ case PROP_AUTOREGISTRATION:
+ g_value_set_boolean (value, priv->autoregistration);
+ break;
+ case PROP_APPVIEW:
+ g_value_set_object (value, hildon_app_get_appview (HILDON_APP (object)));
+ break;
+ case PROP_UI_MANAGER:
+ g_value_set_object (value, hildon_app_get_ui_manager (HILDON_APP (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * Adds a child widget to HildonApp.
+ */
+static void hildon_app_add (GtkContainer *container, GtkWidget *child)
+{
+ HildonApp *app = NULL;
+ HildonAppPrivate *priv = NULL;
+
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ app = HILDON_APP (container);
+ priv = HILDON_APP_GET_PRIVATE (app);
+
+ /* Check if child is already added here */
+ if (g_list_find (priv->children, child) != NULL)
+ return;
+
+ priv->children = g_list_append (priv->children, child);
+ GTK_BIN (container)->child = child;
+ gtk_widget_set_parent (child, GTK_WIDGET (app));
+
+ /* If the default direction (RTL/LTR) is different from the real
+ default, change it This happens if the locale has been changed
+ but this appview was orphaned and thus never got to know about
+ it. "default_direction" could be RTL, but the widget direction
+ of the view might still be LTR. Thats what we're fixing here. */
+
+ /* FIXME: This is legacy stuff */
+ if (gtk_widget_get_default_direction () !=
+ gtk_widget_get_direction (GTK_WIDGET (child)))
+ {
+ gtk_widget_set_direction (GTK_WIDGET (child),
+ gtk_widget_get_default_direction ());
+ }
+
+ if (HILDON_IS_APPVIEW (child))
+ {
+ g_signal_connect_swapped (G_OBJECT (child), "title_change",
+ G_CALLBACK (hildon_app_construct_title), app);
+ if (priv->autoregistration)
+ hildon_app_register_view (app, child);
+ }
+}
+
+/*
+ * Removes a child widget from HildonApp.
+ */
+static void hildon_app_remove (GtkContainer *container, GtkWidget *child)
+{
+ HildonAppPrivate *priv;
+ GtkBin *bin;
+ HildonApp *app;
+
+ g_return_if_fail (container != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ priv = HILDON_APP_GET_PRIVATE (container);
+ bin = GTK_BIN (container);
+ app = HILDON_APP (bin);
+
+ /* Make sure that child is found in the list */
+ if (g_list_find (priv->children, child) == NULL)
+ return;
+
+ priv->children = g_list_remove (priv->children, child);
+
+ if (HILDON_IS_APPVIEW (child))
+ {
+ /* FIXME: This is a compilation workaround for gcc > 3.3, since glib-2 API is buggy.
+ * see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
+
+G_GNUC_EXTENSION
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (child),
+ (gpointer)hildon_app_construct_title, app);
+
+ if (priv->autoregistration)
+ hildon_app_unregister_view (app, HILDON_APPVIEW (child));
+ }
+
+ /* If that was our visible child, we need to recalculate size.
+ We could chain up to parent as well... */
+ gtk_widget_unparent (child);
+
+ if (bin->child == child)
+ {
+ bin->child = NULL;
+ gtk_widget_queue_resize (GTK_WIDGET (bin));
+ }
+}
+
+
+/*
+ * Long escape keypress handler.
+ * Long press of the escape key means "close this window", so we fake a delete-event
+ * for our GdkWindow to make it act the same as if the user had closed the window the
+ * usual way. This allows any application code to gracefully exit.
+ *
+ * It returns FALSE in order to get called only once.
+ */
+static gboolean
+hildon_app_escape_timeout(gpointer app)
+{
+ HildonAppPrivate *priv;
+ GdkEvent *event;
+
+ GDK_THREADS_ENTER ();
+
+ g_assert(GTK_WIDGET_REALIZED(app));
+
+ priv = HILDON_APP_GET_PRIVATE(app);
+
+ /* Send fake event, simulation a situation that user
+ pressed 'x' from the corner */
+ event = gdk_event_new(GDK_DELETE);
+ ((GdkEventAny *)event)->window = GTK_WIDGET(app)->window;
+ gtk_main_do_event(event);
+ gdk_event_free(event);
+
+ priv->escape_timeout = 0;
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+/*
+ * Looks for the visible window to whom the point of coordinates (co,by)
+ * belongs. Search recursively all the children of the window.
+ *
+ * This functionality is only needed for scrollbar remote control.
+ */
+static GdkWindow *find_window (GdkWindow *window, gint by, gint co)
+{
+ GdkWindow *child;
+ GList *children = gdk_window_peek_children (window);
+
+ /* If the window has no children, then the coordinates must match it */
+ if (!children)
+ return window;
+
+ if (!(child = (GdkWindow *)children->data))
+ return window;
+
+ do
+ {
+ /* It makes sense to process a child window only if it's visible and it's
+ * capable to get the GDK_BUTTON_PRESS_MASK event. */
+ if (gdk_window_is_visible (child) &&
+ gdk_window_get_events (child) & GDK_BUTTON_PRESS_MASK)
+ {
+ gint x, width, y, height;
+
+ gdk_window_get_geometry (child, &x, &y, &width, &height, NULL);
+ /* This checks that the the point of coordinates (co,by) is in the rectangle
+ * made by (x,y,x+width,y+height). If so, then we spotted which child of the
+ * original window is in the point (co,by). We can now recursively search
+ * its own children.
+ */
+ if (x < co && x + width > co && y < by && y + height > by)
+ return find_window (child, by, co);
+ }
+
+ /* If the window has no more children, then it's the one we're looking for */
+ if (!(children = g_list_next (children)))
+ return window;
+
+ } while ( (child = children->data));
+
+ return NULL;
+}
+
+/*
+ * This is the callback function that gets called on a mouse button press
+ * event. If the press is happens in a "sensitive border" area in the right side of
+ * the window, the event is translated to the left edge of that border (which
+ * usually will contain a scrollbar).
+ *
+ * This functionality is used for right-hand side scroll control feature (dragging on the
+ * right edge of the window controls the rightmost scrollbar if present).
+ */
+static gboolean
+hildon_app_button (GtkWidget *widget, GdkEventButton *event)
+{
+ HildonAppPrivate *priv = NULL;
+
+ /* FIXME: This is an estimate, but the AppView does not expose the
+ width of it's borders so we default to something */
+ gint sensitive_border = 31;
+
+ if (!GTK_WIDGET_REALIZED(widget))
+ {
+ return FALSE;
+ }
+
+ priv = HILDON_APP_GET_PRIVATE (widget);
+
+ if (!priv->scroll_control)
+ {
+ return FALSE;
+ }
+
+ /* We can easily get the location of the vertical scrollbar and get the exact
+ * area for the scroll_control *if* the setup is such that the HildonAppview
+ * contains a GtkScrolledWindow, so we check for it before defaulting to
+ * the previous guess. More complex situations are not feasible to autodetect.
+ * Applications should provide the GtkAdjustment to be changed for this to work
+ * flawlessly.
+ */
+ if (HILDON_IS_APPVIEW(GTK_BIN(widget)->child))
+ {
+ GtkBin *avbin = GTK_BIN(GTK_BIN(widget)->child);
+ if (GTK_IS_SCROLLED_WINDOW(avbin->child))
+ {
+ GtkScrolledWindow *win;
+ win = GTK_SCROLLED_WINDOW(avbin->child);
+
+ if (GTK_WIDGET_VISIBLE(win->vscrollbar))
+ {
+ /* Calculate the distance between the AppView's right border and
+ * the scrollbars center
+ */
+ sensitive_border = (GTK_WIDGET(avbin)->allocation.x +
+ GTK_WIDGET(avbin)->allocation.width) -
+ (win->vscrollbar->allocation.x +
+ win->vscrollbar->allocation.width / 2);
+ }
+ }
+ }
+
+ /* If the press event comes to the sensitive area, we send a fake event to the
+ * area we think the scrollbar is in to make it think the button press happened on it
+ */
+ if (event->x > widget->allocation.width - sensitive_border)
+ {
+ GdkWindow *window = NULL;
+ gint co = widget->allocation.width - sensitive_border;
+
+ /* We now need to know in which window the _modified_ coordinates are */
+ if ((window = find_window (widget->window, event->y, co)))
+ {
+ GdkEventButton nevent;
+
+ if (window == widget->window)
+ return FALSE;
+
+ /* Build a new event and associate the proper window to it */
+ nevent = *event;
+ nevent.x = 8;
+ nevent.window = window;
+ g_object_ref (nevent.window);
+ gtk_main_do_event ((GdkEvent*)&nevent);
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Performs the initialisation of the widget.
+ */
+static void
+hildon_app_init (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+
+ priv = HILDON_APP_GET_PRIVATE(self);
+
+ /* init private */
+ priv->title = g_strdup("");
+#ifndef HILDON_DISABLE_DEPRECATED
+ priv->zoom = HILDON_ZOOM_MEDIUM;
+#endif
+ priv->twoparttitle = FALSE;
+ priv->lastmenuclick = 0;
+ priv->is_topmost = FALSE;
+ priv->curr_view_id = 0;
+ priv->view_id_counter = 1;
+ priv->view_ids = NULL;
+ priv->killable = FALSE;
+ priv->autoregistration = TRUE;
+ priv->scroll_control = TRUE;
+ priv->uim = NULL;
+ priv->active_menu_id = 0;
+
+ /* grab the events here since HildonApp isn't necessarily ever shown */
+ gdk_window_set_events(gdk_get_default_root_window(),
+ gdk_window_get_events(gdk_get_default_root_window()) |
+ GDK_PROPERTY_CHANGE_MASK);
+
+ /* For some reason, the titlebar menu has problems with the grab
+ (bugzilla bug 1527). This is part of somewhat ugly fix for it to
+ get it to work until a more satisfactory solution is found */
+ gdk_window_add_filter(NULL, hildon_app_event_filter, self);
+
+ gtk_widget_set_events (GTK_WIDGET(self), GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK);
+}
+
+/*public functions */
+
+/**
+ * hildon_app_new:
+ *
+ * Creates a new #HildonApp
+ *
+ * Returns: pointer to a new #HildonApp structure
+ */
+GtkWidget *
+hildon_app_new (void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_APP, NULL));
+}
+
+/**
+ * hildon_app_new_with_appview:
+ * @appview : a #HildonAppView
+ *
+ * Creates an app, and sets it's initial appview.
+ *
+ * Returns: pointer to a new #HildonApp structure
+ */
+GtkWidget *
+hildon_app_new_with_appview (HildonAppView *appview)
+{
+ GtkWidget *app;
+
+ g_return_val_if_fail (HILDON_IS_APPVIEW (appview), NULL);
+
+ app = hildon_app_new ();
+
+ hildon_app_set_appview(HILDON_APP(app), appview);
+
+ return app;
+}
+
+/**
+ * hildon_app_get_appview:
+ * @self : a #HildonApp
+ *
+ * Gets the currently shown appview.
+ *
+ * Returns: the currently shown appview in this HildonApp.
+ * If no appview is currently set for this HildonApp,
+ * returns NULL.
+ */
+HildonAppView *
+hildon_app_get_appview (HildonApp *self)
+{
+ GtkBin *bin;
+
+ g_return_val_if_fail (HILDON_IS_APP (self), NULL);
+ bin = GTK_BIN (self);
+ if (HILDON_IS_APPVIEW (bin->child))
+ {
+ return HILDON_APPVIEW (bin->child);
+ }
+
+ return NULL;
+}
+
+/**
+ * hildon_app_set_appview:
+ * @self : a #HildonApp
+ * @appview : a #HildonAppView
+ *
+ * Sets (switches to) appview.
+ */
+void
+hildon_app_set_appview (HildonApp *app, HildonAppView *view)
+{
+ HildonAppPrivate *priv;
+ GtkBin *bin;
+ GtkWidget *widget; /*(view to be set)*/
+ gchar *menu_ui;
+
+ g_return_if_fail (HILDON_IS_APP (app));
+ g_return_if_fail (HILDON_IS_APPVIEW (view));
+
+ bin = GTK_BIN (app);
+ priv = HILDON_APP_GET_PRIVATE (app);
+ widget = GTK_WIDGET (view);
+
+ if (widget == bin->child)
+ return;
+
+ /* Make old appview dissapear */
+ if (bin->child)
+ {
+ gtk_widget_hide (bin->child);
+ g_signal_emit_by_name (bin->child, "switched_from", NULL);
+
+ if (priv->active_menu_id > 0)
+ {
+ if (priv->uim != NULL)
+ {
+ gtk_ui_manager_remove_ui (priv->uim,
+ priv->active_menu_id);
+ }
+ priv->active_menu_id = 0;
+ }
+
+ bin->child = NULL;
+ }
+
+ /* Ensure that new view is in our child list */
+ if (!g_list_find (priv->children, widget))
+ gtk_container_add (GTK_CONTAINER (app), widget);
+
+ bin->child = widget;
+
+ gtk_widget_show (widget);
+
+ /* UI manager support, merge menu for activated view */
+ g_object_get (G_OBJECT (view),
+ "menu-ui", &menu_ui,
+ NULL);
+
+ if (menu_ui && priv->uim)
+ {
+
+ priv->active_menu_id =
+ gtk_ui_manager_add_ui_from_string (priv->uim, menu_ui, -1, NULL);
+
+ gtk_ui_manager_ensure_update (priv->uim);
+
+ }
+
+ g_free (menu_ui);
+
+ g_signal_emit_by_name (widget, "switched_to", NULL);
+
+ /* Inform task navigator about changed view */
+ hildon_app_notify_view_changed (app, view);
+
+ /* Update title to show currently activated view */
+ hildon_app_construct_title (app);
+ gtk_widget_child_focus (widget, GTK_DIR_TAB_FORWARD);
+}
+
+/**
+ * hildon_app_set_title:
+ * @self : a #HildonApp
+ * @newtitle : the new title assigned to the application
+ *
+ * Sets title of the application.
+ */
+void
+hildon_app_set_title (HildonApp *self, const gchar *newtitle)
+{
+ HildonAppPrivate *priv;
+ gchar *oldstr;
+
+ g_return_if_fail(HILDON_IS_APP(self));
+
+ priv = HILDON_APP_GET_PRIVATE(self);
+ oldstr = priv->title;
+
+ if (newtitle)
+ {
+ priv->title = g_strdup(newtitle);
+ g_strstrip(priv->title);
+ }
+ else
+ priv->title = g_strdup("");
+
+ if (oldstr)
+ g_free(oldstr);
+
+ hildon_app_construct_title(self);
+}
+
+/**
+ * hildon_app_get_title:
+ * @self : a #HildonApp
+ *
+ * Gets the title of the application.
+ *
+ * Returns: the title currently assigned to the application. This
+ * value is not to be freed or modified by the calling application
+ */
+const gchar *
+hildon_app_get_title (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_APP(self), NULL);
+ priv = HILDON_APP_GET_PRIVATE(self);
+ return priv->title;
+}
+
+/* FIXME: Zoom is deprecated, remove */
+/**
+ * hildon_app_set_zoom:
+ * @self : a #HildonApp
+ * @newzoom: the zoom level of type #HildonZoomLevel to be assigned to an
+ * application
+ *
+ * Sets the zoom level. Warning! This function is deprecated and
+ * should not be used. It's lecacy stuff from ancient specs.
+ */
+void
+hildon_app_set_zoom (HildonApp *self, HildonZoomLevel newzoom)
+{
+ HildonAppPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_APP(self));
+
+ priv = HILDON_APP_GET_PRIVATE(self);
+
+ if (newzoom != priv->zoom)
+ {
+ if (newzoom < HILDON_ZOOM_SMALL)
+ {
+ newzoom = HILDON_ZOOM_SMALL;
+ gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_min_zoom_level_reached"));
+ }
+ else if (newzoom > HILDON_ZOOM_LARGE) {
+ newzoom = HILDON_ZOOM_LARGE;
+ gtk_infoprint(GTK_WINDOW(self), _("ckct_ib_max_zoom_level_reached"));
+ }
+ priv->zoom = newzoom;
+ }
+}
+
+/**
+ * hildon_app_get_zoom:
+ * @self : a #HildonApp
+ *
+ * Gets the zoom level. Warning! This function is deprecated and
+ * should not be used. It's lecacy stuff from ancient specifications.
+ *
+ * Returns: the zoom level of the Hildon application. The
+ * returned zoom level is of type #HildonZoomLevel.
+ */
+HildonZoomLevel
+hildon_app_get_zoom (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_APP(self), HILDON_ZOOM_MEDIUM);
+ priv = HILDON_APP_GET_PRIVATE(self);
+ return priv->zoom;
+}
+
+/**
+ * hildon_app_get_default_font:
+ * @self : a #HildonApp
+ *
+ * Gets default font. Warning! This function is deprecated and should
+ * not be used. It's legacy stuff from ancient version of specification.
+ *
+ * Returns: pointer to PangoFontDescription for the default,
+ * normal size font
+ */
+PangoFontDescription *
+hildon_app_get_default_font (HildonApp *self)
+{
+ PangoFontDescription *font_desc = NULL;
+ GtkStyle *fontstyle = NULL;
+
+ g_return_val_if_fail(HILDON_IS_APP(self), NULL);
+
+ fontstyle =
+ gtk_rc_get_style_by_paths (gtk_widget_get_settings
+ (GTK_WIDGET(self)), NULL, NULL,
+ gtk_widget_get_type());
+
+ if (!fontstyle)
+ {
+ g_print("WARNING : default font not found. "
+ "Defaulting to swissa 19\n");
+ font_desc = pango_font_description_from_string("swissa 19");
+
+ }
+ else
+ font_desc = pango_font_description_copy(fontstyle->font_desc);
+
+ return font_desc;
+}
+
+/**
+ * hildon_app_get_zoom_font:
+ * @self : a #HildonApp
+ *
+ * Gets the description of the default font. Warning! This function
+ * is deprecated and should not be used. It's legacy stuff from
+ * ancient specs.
+ *
+ * Returns: pointer to PangoFontDescription for the default,
+ * normal size font
+ */
+PangoFontDescription *
+hildon_app_get_zoom_font (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+ PangoFontDescription *font_desc = NULL;
+ gchar *style_name = 0;
+ GtkStyle *fontstyle = NULL;
+
+ g_return_val_if_fail(HILDON_IS_APP(self), NULL);
+
+ priv = HILDON_APP_GET_PRIVATE(self);
+ if (priv->zoom == HILDON_ZOOM_SMALL)
+ style_name = g_strdup("hildon-zoom-small");
+ else if (priv->zoom == HILDON_ZOOM_MEDIUM)
+ style_name = g_strdup("hildon-zoom-medium");
+ else if (priv->zoom == HILDON_ZOOM_LARGE)
+ style_name = g_strdup("hildon-zoom-large");
+ else
+ {
+ g_warning("Invalid Zoom Value\n");
+ style_name = g_strdup("");
+ }
+
+ fontstyle =
+ gtk_rc_get_style_by_paths (gtk_widget_get_settings
+ (GTK_WIDGET(self)), style_name, NULL,
+ G_TYPE_NONE);
+ g_free (style_name);
+
+ if (!fontstyle)
+ {
+ g_print("WARNING : theme specific zoomed font not found. "
+ "Defaulting to preset zoom-specific fonts\n");
+ if (priv->zoom == HILDON_ZOOM_SMALL)
+ font_desc = pango_font_description_from_string("swissa 16");
+ else if (priv->zoom == HILDON_ZOOM_MEDIUM)
+ font_desc = pango_font_description_from_string("swissa 19");
+ else if (priv->zoom == HILDON_ZOOM_LARGE)
+ font_desc = pango_font_description_from_string("swissa 23");
+ }
+ else
+ font_desc = pango_font_description_copy(fontstyle->font_desc);
+
+ return font_desc;
+}
+
+ /* FIXME: Zoom is deprecated, remove the code above */
+
+/**
+ * hildon_app_set_two_part_title:
+ * @self : a #HildonApp
+ * @istwoparttitle : a gboolean indicating wheter to activate
+ * a title that has both the application title and application
+ * view title separated by a triangle
+ *
+ * Sets the two part title.
+ */
+void
+hildon_app_set_two_part_title (HildonApp *self, gboolean istwoparttitle)
+{
+ HildonAppPrivate *priv;
+ g_return_if_fail(HILDON_IS_APP(self));
+ priv = HILDON_APP_GET_PRIVATE(self);
+
+ if (istwoparttitle != priv->twoparttitle)
+ {
+ priv->twoparttitle = istwoparttitle;
+ hildon_app_construct_title(self);
+ }
+}
+
+/**
+ * hildon_app_get_two_part_title:
+ * @self : a #HildonApp
+ *
+ * Gets the 'twopart' represention of the title inside #HildonApp.
+ *
+ * Returns: a boolean indicating wheter title shown has both
+ * application, and application view title separated by a triangle.
+ */
+gboolean
+hildon_app_get_two_part_title (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_APP(self), FALSE);
+ priv = HILDON_APP_GET_PRIVATE(self);
+ return priv->twoparttitle;
+}
+
+
+/* private functions */
+
+
+/*
+ * Handles the key press of the Escape, Increase and Decrease keys. Other keys
+ * are handled by the parent GtkWidgetClass.
+ */
+static gboolean
+hildon_app_key_press (GtkWidget *widget, GdkEventKey *keyevent)
+{
+ HildonApp *app = HILDON_APP (widget);
+ HildonAppView *appview;
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app);
+
+ if (HILDON_IS_APPVIEW(GTK_BIN (app)->child))
+ {
+ appview = HILDON_APPVIEW (GTK_BIN (app)->child);
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (keyevent->keyval == GDK_Escape && priv->escape_timeout == 0)
+ {
+ /* Call hildon_app_escape_timeout every 1500ms until it returns FALSE
+ * and store the relative GSource id. Since hildon_app_escape_timeout
+ * can only return FALSE, the call will occurr only once.
+ */
+ priv->escape_timeout = g_timeout_add(1500, hildon_app_escape_timeout, app);
+ }
+
+ /* FIXME: Handling +/- keys here is not usefull. Applications
+ can equally easily handle the keypress themselves. */
+ else if (HILDON_KEYEVENT_IS_INCREASE_KEY (keyevent))
+ {
+ _hildon_appview_increase_button_state_changed (appview,
+ keyevent->type);
+ }
+ else if (HILDON_KEYEVENT_IS_DECREASE_KEY (keyevent))
+ {
+ _hildon_appview_decrease_button_state_changed (appview,
+ keyevent->type);
+ }
+
+ /* Activate default bindings and let the widget with focus to handle key */
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, keyevent);
+}
+
+/*
+ * Handles the key release event for the Escape, Toolbar and Fullscreen keys.
+ */
+static gboolean
+hildon_app_key_release (GtkWidget *widget, GdkEventKey *keyevent)
+{
+ HildonApp *app = HILDON_APP (widget);
+ HildonAppView *appview;
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE(app);
+
+ if (HILDON_IS_APPVIEW(GTK_BIN (app)->child))
+ {
+ appview = HILDON_APPVIEW (GTK_BIN (app)->child);
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (keyevent->keyval == GDK_Escape)
+ {
+ /*
+ * This will prevent the hildon_app_escape_timeout from being called.
+ * See hildon_app_escape_timeout and hildon_app_remove_timeout for more.
+ */
+ hildon_app_remove_timeout(priv);
+ }
+ else if (HILDON_KEYEVENT_IS_TOOLBAR_KEY (keyevent))
+ {
+ g_signal_emit_by_name(G_OBJECT(appview),
+ "toolbar-toggle-request");
+ }
+ else if (HILDON_KEYEVENT_IS_FULLSCREEN_KEY (keyevent))
+ {
+ /* Emit the fullscreen_state_change directly, it'll save one step */
+ if (hildon_appview_get_fullscreen_key_allowed (appview))
+ {
+ gboolean fullscreen;
+
+ fullscreen = hildon_appview_get_fullscreen(appview);
+ g_signal_emit_by_name(G_OBJECT(appview),
+ "fullscreen_state_change",
+ !fullscreen);
+ }
+ }
+
+ /* FIXME: Should the event be marked as handled if any of the three
+ above cases took an action */
+
+ /* Activate default bindings and let the widget with focus to handle key */
+ return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, keyevent);
+}
+
+/*
+ * Handles the MENU key presses.
+ */
+static gboolean
+hildon_app_key_snooper (GtkWidget *widget, GdkEventKey *keyevent, HildonApp *app)
+{
+ /* FIXME: Using normal keypress handler would be better choise. All
+ keyevents come to window anyway, so we would get the same
+ keys in that way as well, but we wouldn't need to struggle
+ with grabs (modal dialogs etc). */
+
+ /* Menu key handling is done here */
+ if ( HILDON_KEYEVENT_IS_MENU_KEY (keyevent) ) {
+ HildonAppView *appview;
+ HildonAppPrivate *priv;
+ GtkWidget *toplevel;
+ GtkWidget *focus = NULL;
+
+ /* Don't act on modal dialogs */
+ toplevel = gtk_widget_get_toplevel (widget);
+ focus = gtk_window_get_focus(GTK_WINDOW(app));
+
+ /* Don't act when comboboxes are active, if a togglebutton
+ (combobox) has the focus and it is active, we deactivate the
+ combobox and do nothing */
+ if (GTK_IS_TOGGLE_BUTTON (focus))
+ {
+ GtkWidget *parent = gtk_widget_get_parent (focus);
+
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (focus)) &&
+ GTK_IS_COMBO_BOX (parent))
+ {
+ gtk_combo_box_popdown (GTK_COMBO_BOX (parent));
+ return TRUE;
+ }
+ }
+
+ /* Don't act when a GtkWindow of a combobox is selected, this
+ can happen in some applications that change the properties of
+ the widget focus attribute, WARNING: we are using the name of
+ the hildon combobox widget to identify the window
+ (gtkcombobox.c, HILDON_COMBO_BOX_POPUP), if it changes we
+ must change this name */
+ if (GTK_IS_WINDOW (widget) &&
+ !g_ascii_strcasecmp("hildon-combobox-window", gtk_widget_get_name (widget)))
+ {
+ return TRUE;
+ }
+
+ if (GTK_IS_DIALOG (toplevel)
+ && gtk_window_get_modal (GTK_WINDOW (toplevel)))
+ {
+ return TRUE;
+ }
+
+ appview = HILDON_APPVIEW (GTK_BIN(app)->child);
+ priv = HILDON_APP_GET_PRIVATE(app);
+
+ if ( keyevent->type == GDK_KEY_PRESS ) {
+ /* Toggle menu on press, avoid key repeat */
+ if ( priv->lastmenuclick == 0 ){
+ priv->lastmenuclick = 1;
+ if (_hildon_appview_toggle_menu(appview,
+ gtk_get_current_event_time()))
+ {
+ return TRUE;
+ }
+ }
+ } else if ( keyevent->type == GDK_KEY_RELEASE ) {
+ /* We got release, so next press is really a new press,
+ not a repeat */
+ if ( priv->lastmenuclick == 1 ) {
+ priv->lastmenuclick = 0;
+ }
+
+ } else {
+ /* Unknown key event */
+ return FALSE;
+ }
+
+ /* don't stop the key event so that it reaches GTK where it
+ closes all existing menus that might be open */
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Returns the message_type of the Atom registered with a certain name.
+ */
+static int
+xclient_message_type_check(XClientMessageEvent *cm, const gchar *name)
+{
+ return cm->message_type == XInternAtom(GDK_DISPLAY(), name, FALSE);
+}
+
+/*
+ * Returns the GtkWidget associated to a certain Window.
+ */
+static GtkWidget *
+hildon_app_xwindow_lookup_widget(Window xwindow)
+{
+ GdkWindow *window;
+ gpointer widget;
+
+ window = gdk_xid_table_lookup(xwindow);
+ if (window == NULL)
+ return NULL;
+
+ gdk_window_get_user_data(window, &widget);
+ return widget;
+}
+
+/*
+ * Let's search a actual main window using tranciency hints.
+ * Note that there can be several levels of menus/dialogs above
+ * the actual main window.
+ */
+static Window get_active_main_window(Window window)
+{
+ Window parent_window;
+ gint limit = 0;
+
+ gdk_error_trap_push ();
+
+ while (XGetTransientForHint(GDK_DISPLAY(), window, &parent_window))
+ {
+ /* The limit > TRANSIENCY_MAXITER ensures that we can't be stuck
+ here forever if we have circular transiencies for some reason.
+ Use of _MB_CURRENT_APP_WINDOW might be more elegant... */
+
+ if (!parent_window || parent_window == GDK_ROOT_WINDOW() ||
+ parent_window == window || limit > TRANSIENCY_MAXITER)
+ {
+ break;
+ }
+
+ limit++;
+ window = parent_window;
+ }
+
+ gdk_flush ();
+
+ if (gdk_error_trap_pop ())
+ return 0;
+
+ return window;
+}
+
+/*
+ * Filters every GDK event first.
+ */
+static GdkFilterReturn
+hildon_app_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ gint x,y;
+ HildonApp *app = data;
+ HildonAppPrivate *priv;
+ HildonAppView *appview = NULL;
+
+ XAnyEvent *eventti = xevent;
+
+ if (HILDON_IS_APPVIEW (GTK_BIN (app)->child))
+ {
+ appview = HILDON_APPVIEW (GTK_BIN (app)->child);
+ }
+
+ g_return_val_if_fail (app, GDK_FILTER_CONTINUE);
+ g_return_val_if_fail (HILDON_IS_APP(app), GDK_FILTER_CONTINUE);
+
+ priv = HILDON_APP_GET_PRIVATE(app);
+ if (eventti->type == ClientMessage)
+ {
+ XClientMessageEvent *cm = xevent;
+
+ /* Check if a message indicating a click on titlebar has been
+ received. Don't open it if mouse is grabbed (eg. modal dialog
+ was just opened).
+ _MB_GRAB_TRANSFER is emitted by MatchBox, and signals that a button
+ has just been released. */
+ if (xclient_message_type_check(cm, "_MB_GRAB_TRANSFER") &&
+ HILDON_IS_APPVIEW(appview) &&
+ gtk_grab_get_current() == NULL &&
+ !_hildon_appview_menu_visible(appview))
+ {
+ _hildon_appview_toggle_menu(appview, cm->data.l[0]);
+ return GDK_FILTER_REMOVE;
+ }
+ /* IM_CLOSE is input method specific hack that is really questionable */
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLOSE"))
+ {
+ g_signal_emit_by_name(app, "im_close", NULL);
+ return GDK_FILTER_REMOVE;
+ }
+ /* Task user changed the view through task navigator? */
+ else if (xclient_message_type_check(cm, "_NET_ACTIVE_WINDOW"))
+ {
+ unsigned long view_id = cm->window;
+ gpointer view_ptr = find_view(app, view_id);
+
+ /* When getting a _NET_ACTIVE_WINDOW signal from the WM we need
+ * to bring the application to the front */
+ if (!priv->is_topmost)
+ g_signal_emit_by_name (G_OBJECT(app), "topmost_status_acquire");
+
+ if (HILDON_IS_APPVIEW(view_ptr))
+ /* Sets the current view to the "window" that the _NET_ACTIVE_WINDOW
+ * specified */
+ hildon_app_set_appview(app, (HILDON_APPVIEW(view_ptr)));
+ else
+ /* there was no view, so we have to switch to an actual application */
+ g_signal_emit_by_name (G_OBJECT(app), "switch_to", view_ptr);
+
+ /* FIXME: This is a hack. This was once just gtk_window_present, but
+ was changed into this at some day!! */
+ if (GTK_WIDGET(app)->window)
+ {
+ mb_util_window_activate(GDK_DISPLAY(),
+ GDK_WINDOW_XID(GTK_WIDGET(app)->window));
+ }
+ }
+ /* FIXME: IM hack */
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_COPY"))
+ {
+ Window xwindow = cm->data.l[0];
+ GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
+
+ g_signal_emit_by_name (G_OBJECT(app), "clipboard_copy", widget);
+ }
+ /* FIXME: IM hack */
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_CUT"))
+ {
+ Window xwindow = cm->data.l[0];
+ GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
+
+ g_signal_emit_by_name (G_OBJECT(app), "clipboard_cut", widget);
+ }
+ /* FIXME: IM hack */
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_PASTE"))
+ {
+ Window xwindow = cm->data.l[0];
+ GtkWidget *widget = hildon_app_xwindow_lookup_widget(xwindow);
+
+ g_signal_emit_by_name (G_OBJECT(app), "clipboard_paste", widget);
+ }
+ }
+
+ if (eventti->type == ButtonPress)
+ {
+
+ /* FIXME: This is mysterious bugfix related to problems to open the
+ application menu (bugzilla N#3204) */
+ XButtonEvent *bev = (XButtonEvent *)xevent;
+
+ if (HILDON_IS_APPVIEW(appview) &&
+ _hildon_appview_menu_visible(appview) &&
+ !hildon_appview_get_fullscreen(appview))
+ {
+ x = bev->x_root;
+ y = bev->y_root;
+ if ( (x >= MENUAREA_LEFT_LIMIT) && (x <= MENUAREA_RIGHT_LIMIT) &&
+ (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT))
+ {
+ _hildon_appview_toggle_menu(appview, bev->time);
+ return GDK_FILTER_CONTINUE;
+ }
+ }
+ }
+
+ /* FIXME: as above */
+ if (eventti->type == ButtonRelease)
+ {
+ if (HILDON_IS_APPVIEW(appview) &&
+ _hildon_appview_menu_visible(appview) &&
+ !hildon_appview_get_fullscreen(appview))
+ {
+ XButtonEvent *bev = (XButtonEvent *)xevent;
+ x = bev->x_root;
+ y = bev->y_root;
+ if ( (x >= MENUAREA_LEFT_LIMIT) && (x < MENUAREA_RIGHT_LIMIT) &&
+ (y >= MENUAREA_TOP_LIMIT) && (y <= MENUAREA_BOTTOM_LIMIT))
+ {
+ return GDK_FILTER_REMOVE;
+ }
+ }
+ return GDK_FILTER_CONTINUE;
+ }
+
+ /* Application stacking order changed */
+ if (eventti->type == PropertyNotify)
+ {
+ Atom active_app_atom =
+ XInternAtom (GDK_DISPLAY(), "_MB_CURRENT_APP_WINDOW", False);
+ XPropertyEvent *prop = xevent;
+
+ if ((prop->atom == active_app_atom)
+ && (prop->window == GDK_ROOT_WINDOW()))
+ {
+ Atom realtype;
+ int format;
+ int status;
+ unsigned long n;
+ unsigned long extra;
+ Window my_window;
+ union
+ {
+ Window *win;
+ unsigned char *char_pointer;
+ } win;
+
+ win.win = NULL;
+
+ status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ active_app_atom, 0L, 16L,
+ 0, XA_WINDOW, &realtype, &format,
+ &n, &extra, &win.char_pointer);
+ if (!(status == Success && realtype == XA_WINDOW && format == 32
+ && n == 1 && win.win != NULL))
+ {
+ if (win.win != NULL)
+ XFree(win.char_pointer);
+ return GDK_FILTER_CONTINUE;
+ }
+
+ my_window = GDK_WINDOW_XID(GTK_WIDGET(app)->window);
+
+ /* Are we the topmost one? */
+ if (win.win[0] == my_window ||
+ get_active_main_window(win.win[0]) == my_window)
+ {
+ if (!priv->is_topmost)
+ g_signal_emit_by_name (G_OBJECT(app),
+ "topmost_status_acquire");
+ }
+ else if (priv->is_topmost)
+ {
+ GtkWidget *focus = gtk_window_get_focus(GTK_WINDOW(app));
+
+ /* FIXME: IM hack, IM-module should do this in response to
+ topmost_status_lose (emission hook?) */
+ if (GTK_IS_ENTRY(focus))
+ gtk_im_context_focus_out(GTK_ENTRY(focus)->im_context);
+ if (GTK_IS_TEXT_VIEW(focus))
+ gtk_im_context_focus_out(GTK_TEXT_VIEW(focus)->im_context);
+
+ g_signal_emit_by_name (app, "topmost_status_lose");
+ }
+
+ if (win.win != NULL)
+ XFree(win.char_pointer);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+ }
+
+/*
+ * Sets the GTK Window title to the application's title, or
+ * combined appview/app title, if two part title is asked.
+ */
+static void
+hildon_app_construct_title (HildonApp *self)
+{
+ g_return_if_fail (HILDON_IS_APP (self));
+
+ if (GTK_WIDGET_REALIZED(self))
+ {
+ HildonAppPrivate *priv;
+ GdkAtom subname;
+ gchar *concatenated_title = NULL;
+ HildonAppView *appview;
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+ appview = hildon_app_get_appview(self);
+
+ /* FIXME: The subname property is legacy stuff no longer supported by
+ Matchbox. However, it is still set for the convenience of
+ the Task Navigator. */
+ subname = gdk_atom_intern("_MB_WIN_SUB_NAME", FALSE);
+
+ if (!appview || !hildon_app_get_two_part_title(self) ||
+ g_utf8_strlen(hildon_appview_get_title(appview), -1) < 1 )
+ {
+ /* Set an invisible dummy value if there is no appview title */
+ gdk_property_change (GTK_WIDGET(self)->window, subname,
+ gdk_atom_intern ("UTF8_STRING", FALSE),
+ 8, GDK_PROP_MODE_REPLACE, (guchar *) " \0", 1);
+ gtk_window_set_title (GTK_WINDOW(self), priv->title);
+ }
+ else
+ {
+ gdk_property_change (GTK_WIDGET(self)->window, subname,
+ gdk_atom_intern ("UTF8_STRING", FALSE),
+ 8, GDK_PROP_MODE_REPLACE,
+ (guchar *)hildon_appview_get_title(appview),
+ strlen(hildon_appview_get_title (appview)));
+ concatenated_title = g_strjoin(TITLE_DELIMITER, priv->title,
+ hildon_appview_get_title(appview), NULL);
+ /* priv->title should always be non-null, but check anyway */
+ if (concatenated_title != NULL)
+ {
+ gtk_window_set_title (GTK_WINDOW(self), concatenated_title);
+ g_free(concatenated_title);
+ }
+ }
+ }
+}
+
+/*
+ * Callback function to the topmost_status_acquire signal emitted by
+ * hildon_app_event_filter function. See it for more details.
+ */
+void
+hildon_app_real_topmost_status_acquire (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+ g_return_if_fail (HILDON_IS_APP (self));
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* FIXME: What is the logic not to update topmost status now? */
+ if (!GTK_BIN (self)->child)
+ return;
+
+ priv->is_topmost = TRUE;
+}
+
+/*
+ * Callback function to the topmost_status_lose signal emitted by
+ * hildon_app_event_filter function. See it for more details.
+ */
+void
+hildon_app_real_topmost_status_lose (HildonApp *self)
+{
+ HildonAppPrivate *priv;
+ g_return_if_fail (HILDON_IS_APP (self));
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* FIXME: What is the logic not to update topmost status now? */
+ if (!GTK_BIN (self)->child)
+ return;
+
+ priv->is_topmost = FALSE;
+}
+
+void
+hildon_app_real_switch_to (HildonApp *self)
+{
+ g_return_if_fail (HILDON_IS_APP (self));
+ /* Do we have to do anything here? */
+}
+
+
+/**
+ * hildon_app_set_autoregistration
+ * @self : a #HildonApp
+ * @auto_reg : whether the (app)view autoregistration should be active
+ *
+ * Controls the autoregistration/unregistration of (app)views.
+ */
+
+void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg)
+{
+ HildonAppPrivate *priv;
+ g_return_if_fail (HILDON_IS_APP (self));
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+ priv->autoregistration = auto_reg;
+}
+
+
+/**
+ * hildon_app_register_view:
+ * @self : a #HildonApp
+ * @view_ptr : pointer to the view instance to be registered
+ *
+ * Registers a new view. For appviews, this can be done automatically
+ * if autoregistration is set.
+ */
+
+void hildon_app_register_view(HildonApp *self, gpointer view_ptr)
+{
+ HildonAppPrivate *priv;
+ view_item *view_item_inst;
+
+ g_return_if_fail (HILDON_IS_APP (self) || view_ptr != NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ if (hildon_app_find_view_id(self, view_ptr) == 0)
+ {
+ /* The pointer to the view was unique, so add it to the list */
+ view_item_inst = g_malloc(sizeof(view_item));
+ view_item_inst->view_id = priv->view_id_counter;
+ view_item_inst->view_ptr = view_ptr;
+
+ priv->view_id_counter++;
+
+ priv->view_ids =
+ g_slist_append(priv->view_ids, view_item_inst);
+
+ /* Update the list of views */
+ if (GTK_WIDGET_REALIZED(self))
+ hildon_app_apply_client_list(self);
+ }
+}
+
+
+/**
+ * hildon_app_register_view_with_id:
+ * @self : a #HildonApp
+ * @view_ptr : pointer to the view instance to be registered
+ * @view_id : the ID of the view
+ *
+ * Registers a new view. Allows the application to specify any ID.
+ *
+ * Returns: TRUE if the view registration succeeded, FALSE otherwise.
+ * The probable cause of failure is that view with that ID
+ * already existed.
+ */
+
+gboolean hildon_app_register_view_with_id(HildonApp *self,
+ gpointer view_ptr,
+ unsigned long view_id)
+{
+ view_item *view_item_inst;
+ HildonAppPrivate *priv;
+ GSList *list_ptr = NULL;
+
+ g_return_val_if_fail (HILDON_IS_APP (self), FALSE);
+ g_return_val_if_fail (view_ptr, FALSE);
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ list_ptr = priv->view_ids;
+
+ /* Check that the view is not already registered */
+ while (list_ptr)
+ {
+ if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr
+ && (unsigned long)((view_item *)list_ptr->data)->view_id == view_id)
+ {
+ return FALSE;
+ }
+ list_ptr = list_ptr->next;
+ }
+
+ /* The pointer to the view was unique, so add it to the list */
+ view_item_inst = g_malloc(sizeof(view_item));
+ view_item_inst->view_id = view_id;
+ view_item_inst->view_ptr = view_ptr;
+
+ priv->view_ids =
+ g_slist_append(priv->view_ids, view_item_inst);
+
+ priv->view_id_counter++;
+
+ /* Finally, update the _NET_CLIENT_LIST property */
+ if (GTK_WIDGET_REALIZED(self))
+ hildon_app_apply_client_list(self);
+
+ return TRUE;
+}
+
+/**
+ * hildon_app_unregister_view:
+ * @self : a #HildonApp
+ * @view_ptr : pointer to the view instance to be unregistered
+ *
+ * Unregisters a view from HildonApp. Done usually when a view is
+ * destroyed. For appviews, this is can be automatically
+ * if autoregistration is set.
+ */
+void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr)
+{
+ HildonAppPrivate *priv = NULL;
+ GSList *list_ptr = NULL;
+
+ g_return_if_fail (HILDON_IS_APP (self));
+ g_return_if_fail (view_ptr != NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* Search the view from the list */
+ list_ptr = priv->view_ids;
+
+ while (list_ptr)
+ {
+ if ( (gpointer)((view_item *)list_ptr->data)->view_ptr == view_ptr)
+ {
+ /* Found the view, kick it off */
+ g_free (list_ptr->data);
+ priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr);
+ break;
+ }
+ list_ptr = list_ptr->next;
+ }
+
+ if (GTK_WIDGET_REALIZED(self))
+ hildon_app_apply_client_list(self);
+}
+
+
+/**
+ * hildon_app_unregister_view_with_id:
+ * @self: a #HildonApp
+ * @view_id: the ID of the view that should be unregistered
+ *
+ * Unregisters a view with specified ID, if it exists.
+ */
+void hildon_app_unregister_view_with_id(HildonApp *self,
+ unsigned long view_id)
+{
+ HildonAppPrivate *priv;
+ GSList *list_ptr = NULL;
+
+ g_return_if_fail (HILDON_IS_APP (self));
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* Search the view from the list */
+ list_ptr = priv->view_ids;
+
+ while (list_ptr)
+ {
+ if ( (unsigned long)((view_item *)list_ptr->data)->view_id == view_id)
+ {
+ /* Found view with given id, kick it off */
+ g_free (list_ptr->data);
+ priv->view_ids = g_slist_delete_link(priv->view_ids, list_ptr);
+ break;
+ }
+ list_ptr = list_ptr->next;
+ }
+
+ /* Update client list to reflect new situation. If we are not
+ realized, then nobody knows about us anyway... */
+ if (GTK_WIDGET_REALIZED(self))
+ hildon_app_apply_client_list(self);
+}
+
+
+/**
+ * hildon_app_notify_view_changed:
+ * @self : a #HildonApp
+ * @view_ptr : pointer to the view that is switched to
+ *
+ * Updates the X property that contains the currently active view
+ */
+void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr)
+{
+ g_return_if_fail (HILDON_IS_APP (self));
+ g_return_if_fail (view_ptr != NULL);
+
+ /* We need GdkWindow before we can send X messages */
+ if (GTK_WIDGET_REALIZED(self))
+ {
+ gulong id = hildon_app_find_view_id(self, view_ptr);
+ Atom active_view = XInternAtom (GDK_DISPLAY(),
+ "_NET_ACTIVE_WINDOW", False);
+
+ if (id) {
+ /* Set _NET_ACTIVE_WINDOW for our own toplevel to contain view id */
+ XChangeProperty(GDK_DISPLAY(), GDK_WINDOW_XID(GTK_WIDGET(self)->window),
+ active_view, XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&id, 1);
+ XFlush(GDK_DISPLAY());
+ }
+ }
+}
+
+
+/**
+ * hildon_app_find_view_id:
+ * @self : a #HildonApp
+ * @view_ptr : pointer to the view whose ID we want to acquire
+ *
+ * Returns: the ID of the view, or 0 if not found
+ *
+ * Allows mapping of view pointer to its view ID. If NULL is passed
+ * as the view pointer, returns the ID of the current view.
+ */
+unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr)
+{
+ HildonAppPrivate *priv;
+ GSList *iter;
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* If no view is given, find the ID for the currently visible view */
+ if (!view_ptr)
+ view_ptr = GTK_BIN (self)->child;
+ if (!view_ptr)
+ return 0;
+
+ /* Iterate through list and search for given view pointer */
+ for (iter = priv->view_ids; iter; iter = iter->next)
+ {
+ if ( (gpointer)((view_item *)iter->data)->view_ptr == view_ptr)
+ return (unsigned long)((view_item *)iter->data)->view_id;
+ }
+
+ return 0;
+}
+
+/**
+ * hildon_app_set_killable:
+ * @self : a #HildonApp
+ * @killability : truth value indicating whether the app can be killed
+ *
+ * Updates information about whether the application can be killed or not by
+ * Task Navigator (i.e. whether its statesave is up to date)
+ */
+void hildon_app_set_killable(HildonApp *self, gboolean killability)
+{
+ HildonAppPrivate *priv = HILDON_APP_GET_PRIVATE (self);
+ g_return_if_fail (HILDON_IS_APP (self) );
+
+ if (killability != priv->killable)
+ {
+ priv->killable = killability;
+
+ /* If we have a window, then we can actually set this
+ property. Otherwise we wait until we are realized */
+ if (GTK_WIDGET_REALIZED(self))
+ hildon_app_apply_killable(self);
+ }
+}
+
+
+/**
+ * hildon_app_set_ui_manager:
+ * @self : #HildonApp
+ * @uim : #GtkUIManager to be set
+ *
+ * Sets the #GtkUIManager assigned to the #HildonApp.
+ * If @uim is NULL, unsets the current ui manager.
+ * The @HildonApp holds a reference to the ui manager until
+ * the @HildonApp is destroyed or unset.
+ */
+void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim)
+{
+ HildonAppPrivate *priv;
+
+ g_return_if_fail(self && HILDON_IS_APP(self));
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* Release old ui-manager object if such exists */
+ if (priv->uim != NULL)
+ {
+ g_object_unref (G_OBJECT (priv->uim));
+ }
+
+ priv->uim = uim;
+
+ /* If we got new ui-manager (it's perfectly valid not
+ to give one), acquire reference to it */
+ if (priv->uim != NULL)
+ {
+ g_object_ref (G_OBJECT (uim));
+ }
+
+ g_object_notify (G_OBJECT(self), "ui-manager");
+}
+
+/**
+ * hildon_app_get_ui_manager:
+ * @self : #HildonApp
+ *
+ * Gets the #GtkUIManager assigned to the #HildonApp.
+ *
+ * Returns: the #GtkUIManager assigned to this application
+ * or null if no manager is assigned
+ */
+GtkUIManager *hildon_app_get_ui_manager(HildonApp *self)
+{
+ HildonAppPrivate *priv;
+
+ g_return_val_if_fail(self && HILDON_IS_APP(self), NULL);
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ return (priv->uim);
+}
+
+/*
+ * Search for a view with the given id within HildonApp.
+ * Returns a pointer to the found view, or NULL if not found.
+ */
+static gpointer find_view(HildonApp *self, unsigned long view_id)
+{
+ HildonAppPrivate *priv;
+ GSList *iter;
+
+ priv = HILDON_APP_GET_PRIVATE (self);
+
+ /* Iterate through the list of view ids and search given id */
+ for (iter = priv->view_ids; iter; iter = iter->next)
+ {
+ if ( (unsigned long)((view_item *)iter->data)->view_id == view_id)
+ return (gpointer)((view_item *)iter->data)->view_ptr;
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_APP_H__
+#define __HILDON_APP_H__
+
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkuimanager.h>
+#include "hildon-appview.h"
+
+G_BEGIN_DECLS
+/**
+ * HildonApp:
+ *
+ * Contains only private data not to be touched by outsiders.
+ */
+typedef struct _HildonApp HildonApp;
+typedef struct _HildonAppClass HildonAppClass;
+
+#define HILDON_TYPE_APP ( hildon_app_get_type() )
+
+#define HILDON_APP(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_APP, \
+ HildonApp))
+
+#define HILDON_APP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
+ HILDON_TYPE_APP, HildonAppClass))
+
+#define HILDON_IS_APP(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APP))
+
+#define HILDON_IS_APP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
+ HILDON_TYPE_APP))
+
+
+struct _HildonApp {
+ GtkWindow parent;
+};
+
+struct _HildonAppClass {
+ GtkWindowClass parent_class;
+ void (*topmost_status_acquire) (HildonApp *self);
+ void (*topmost_status_lose) (HildonApp *self);
+ void (*switch_to) (HildonApp *self); /* FIXME: Possible browser hack?? */
+ void (*im_close) (HildonApp *self);
+ void (*clipboard_copy) (HildonApp *self, GtkWidget *widget);
+ void (*clipboard_cut) (HildonApp *self, GtkWidget *widget);
+ void (*clipboard_paste) (HildonApp *self, GtkWidget *widget);
+};
+
+#ifndef HILDON_DISABLE_DEPRECATED
+/* Make these values >0 so that we can detect when someone sets SMALL-1
+ * zoom level (enum seems to be unsigned int)
+ */
+
+/**
+ * HildonZoomLevel:
+ * @HILDON_ZOOM_SMALL: Smallest font.
+ * @HILDON_ZOOM_MEDIUM: Middle size font.
+ * @HILDON_ZOOM_LARGE: Largest font.
+ *
+ * The Hildon zoom levels. Small meaning small font. Large meaning
+ * large font. These font are specified in the gtkrc files.
+ * This enum is deprecated and should not be used. It's just
+ * lecagy stuff from ancient specs.
+ */
+typedef enum /*< skip >*/
+{
+ HILDON_ZOOM_SMALL = 1,
+ HILDON_ZOOM_MEDIUM = 2,
+ HILDON_ZOOM_LARGE = 3
+} HildonZoomLevel;
+
+#define HILDON_TYPE_ZOOM_LEVEL (hildon_zoom_level_get_type ())
+
+GType hildon_zoom_level_get_type (void);
+#endif /* deprecated */
+
+
+/* You should use the correct ones from hildon-defines.h
+ *
+ * FIXME: These should be removed when API changes are allowed,
+ * they are not used in hildon code anymore (but might be in external).
+ */
+#define HILDON_MENU_KEY GDK_F4
+#define HILDON_HOME_KEY GDK_F5
+#define HILDON_TOOLBAR_KEY GDK_T
+#define HILDON_FULLSCREEN_KEY GDK_F6
+#define HILDON_INCREASE_KEY GDK_F7
+#define HILDON_DECREASE_KEY GDK_F8
+#define HILDON_TOOLBAR_MODIFIERS (GDK_SHIFT_MASK | GDK_CONTROL_MASK)
+
+#define HILDON_KEYEVENT_IS_MENU_KEY(keyevent) (keyevent->keyval == HILDON_MENU_KEY)
+#define HILDON_KEYEVENT_IS_HOME_KEY(keyevent) (keyevent->keyval == HILDON_HOME_KEY)
+#define HILDON_KEYEVENT_IS_TOOLBAR_KEY(keyevent) ((keyevent->keyval == HILDON_TOOLBAR_KEY) && \
+ (keyevent->state == HILDON_TOOLBAR_MODIFIERS))
+#define HILDON_KEYEVENT_IS_FULLSCREEN_KEY(keyevent) (keyevent->keyval == HILDON_FULLSCREEN_KEY)
+#define HILDON_KEYEVENT_IS_INCREASE_KEY(keyevent) (keyevent->keyval == HILDON_INCREASE_KEY)
+#define HILDON_KEYEVENT_IS_DECREASE_KEY(keyevent) (keyevent->keyval == HILDON_DECREASE_KEY)
+
+#define TRANSIENCY_MAXITER 50
+
+GType hildon_app_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_app_new(void);
+GtkWidget *hildon_app_new_with_appview(HildonAppView * appview);
+void hildon_app_set_appview(HildonApp * self, HildonAppView * appview);
+HildonAppView *hildon_app_get_appview(HildonApp * self);
+void hildon_app_set_title(HildonApp * self, const gchar * newtitle);
+const gchar *hildon_app_get_title(HildonApp * self);
+
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_app_set_zoom(HildonApp * self, HildonZoomLevel newzoom);
+HildonZoomLevel hildon_app_get_zoom(HildonApp * self);
+PangoFontDescription *hildon_app_get_default_font(HildonApp * self);
+PangoFontDescription *hildon_app_get_zoom_font(HildonApp * self);
+#endif
+
+void hildon_app_set_two_part_title(HildonApp * self,
+ gboolean istwoparttitle);
+gboolean hildon_app_get_two_part_title(HildonApp * self);
+
+void hildon_app_set_autoregistration(HildonApp *self, gboolean auto_reg);
+void hildon_app_register_view(HildonApp *self, gpointer view_ptr);
+gboolean hildon_app_register_view_with_id(HildonApp *self,
+ gpointer view_ptr,
+ unsigned long view_id);
+void hildon_app_unregister_view(HildonApp *self, gpointer view_ptr);
+void hildon_app_unregister_view_with_id(HildonApp *self,
+ unsigned long view_id);
+unsigned long hildon_app_find_view_id(HildonApp *self, gpointer view_ptr);
+void hildon_app_notify_view_changed(HildonApp *self, gpointer view_ptr);
+
+void hildon_app_set_killable(HildonApp *self, gboolean killability);
+
+void hildon_app_set_ui_manager(HildonApp *self, GtkUIManager *uim);
+GtkUIManager *hildon_app_get_ui_manager(HildonApp *self);
+
+G_END_DECLS
+#endif /* __HILDON_APP_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-appview
+ * @short_description: A widget which present one view of an application
+ * @see_also: #HildonApp
+ *
+ * #HildonAppView is a widget which presents one view of an application.
+ * Application can have many different views and the appview helps to organize.
+ * It has automatic fullscreen and menu handling. It also helps to handle
+ * components like a toolbar.
+ */
+
+#include <memory.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include "hildon-app.h"
+#include <hildon-appview.h>
+#include <hildon-find-toolbar.h>
+
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkimcontext.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtkmenushell.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkiconfactory.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdk.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+
+#include <libintl.h>
+#define _(String) gettext(String)
+
+enum {
+ PROP_0,
+ PROP_CONNECTED_ADJUSTMENT,
+ PROP_FULLSCREEN_KEY_ALLOWED,
+ PROP_FULLSCREEN,
+ PROP_TITLE,
+ PROP_MENU_UI
+};
+
+/*The size of screen*/
+#define WINDOW_HEIGHT 480
+#define WINDOW_WIDTH 800
+
+#define NAVIGATOR_HEIGHT WINDOW_HEIGHT
+
+#define APPVIEW_HEIGHT 396
+#define APPVIEW_WIDTH 672
+
+#define TOOLBAR_HEIGHT 40
+#define TOOLBAR_UP 9
+#define TOOLBAR_DOWN 9
+#define TOOLBAR_MIDDLE 10
+#define TOOLBAR_RIGHT 24
+#define TOOLBAR_LEFT 24
+#define TOOLBAR_WIDTH APPVIEW_WIDTH
+
+#define WORKAREA_ATOM "_NET_WORKAREA"
+
+/* Non atom defines */
+#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+#define _NET_WM_STATE_ADD 1 /* add/set property */
+
+/*Margins
+ * These margins are set to be 5pixels smaller than in the specs
+ * Inner things are allocation that extra space
+ * */
+/*
+#define MARGIN_TOOLBAR_TOP 2
+#define MARGIN_TOOLBAR_BOTTOM 6
+#define MARGIN_TOOLBAR_LEFT 22
+#define MARGIN_TOOLBAR_RIGHT 23
+*/
+#define MARGIN_APPVIEW_TOP 0
+#define MARGIN_APPVIEW_BOTTOM 24
+#define MARGIN_APPVIEW_LEFT 24
+#define MARGIN_APPVIEW_RIGHT 24
+
+
+#define HILDON_APPVIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+ HILDON_TYPE_APPVIEW, HildonAppViewPrivate))
+
+/*Progressbar*/
+#define DEFAULT_WIDTH 20
+#define DEFAULT_HEIGHT 28
+#define BANNER_WIDTH DEFAULT_WIDTH
+#define BANNER_HEIGHT DEFAULT_HEIGHT
+
+static GtkBinClass *parent_class;
+
+static void hildon_appview_init(HildonAppView * self);
+static void hildon_appview_class_init(HildonAppViewClass * appview_class);
+
+static void hildon_appview_menupopupfunc(GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget);
+static void hildon_appview_menupopupfuncfull(GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget);
+static gboolean hildon_appview_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static void hildon_appview_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void hildon_appview_show_all(GtkWidget *widget);
+
+static void hildon_appview_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static void hildon_appview_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void hildon_appview_finalize(GObject * obj_self);
+static void hildon_appview_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+static void hildon_appview_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+static void hildon_appview_destroy(GtkObject *obj);
+static void hildon_appview_real_fullscreen_state_change(HildonAppView *
+ self,
+ gboolean
+ fullscreen);
+static void hildon_appview_switched_to(HildonAppView * self);
+static void get_client_area(GtkWidget * widget,
+ GtkAllocation * allocation);
+
+typedef void (*HildonAppViewSignal) (HildonAppView *, gint, gpointer);
+
+/* signals */
+enum {
+ TOOLBAR_CHANGED,
+ TOOLBAR_TOGGLE_REQUEST,
+ FULLSCREEN_STATE_CHANGE,
+ TITLE_CHANGE,
+ SWITCHED_TO,
+ SWITCHED_FROM,
+ INCREASE_BUTTON_EVENT,
+ DECREASE_BUTTON_EVENT,
+ HILDON_APPVIEW_LAST_SIGNAL
+};
+
+static guint appview_signals[HILDON_APPVIEW_LAST_SIGNAL] = { 0 };
+
+enum {
+ WIN_TYPE = 0,
+ WIN_TYPE_MESSAGE,
+ MAX_WIN_MESSAGES
+};
+
+struct _HildonAppViewPrivate {
+ GtkWidget *menu;
+ gchar *title;
+
+ GtkAllocation allocation;
+
+ guint fullscreen : 1;
+ guint fullscreenshortcutallowed : 1;
+
+ /* For future expansion.
+ * We might use the below variables for disabling keyrepeat if we need it someday. */
+ guint increase_button_pressed_down : 1;
+ guint decrease_button_pressed_down : 1;
+ gint visible_toolbars;
+ GtkAdjustment * connected_adjustment;
+
+ gchar *menu_ui;
+};
+
+/* FIXME: Extremely old Legacy code. I wonder why we need
+ a custom marshaller in the first place. */
+static void hildon_appview_signal_marshal(GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ register HildonAppViewSignal callback;
+ register GCClosure *cc = (GCClosure *) closure;
+ register gpointer data1, data2;
+
+ g_assert(n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA(closure)) {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer(param_values + 0);
+ } else {
+ data1 = g_value_peek_pointer(param_values + 0);
+ data2 = closure->data;
+ }
+
+ callback =
+ /* FIXME: This is a compilation workaround for gcc > 3.3 since glib is buggy */
+ /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
+
+#ifdef __GNUC__
+ __extension__
+#endif
+ (HildonAppViewSignal) (marshal_data !=
+ NULL ? marshal_data : cc->callback);
+
+ callback((HildonAppView *) data1,
+ (gint) g_value_get_int(param_values + 1), data2);
+}
+
+GType hildon_appview_get_type(void)
+{
+ static GType appview_type = 0;
+
+ if (!appview_type) {
+ static const GTypeInfo appview_info = {
+ sizeof(HildonAppViewClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_appview_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonAppView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_appview_init,
+ };
+ appview_type = g_type_register_static(GTK_TYPE_BIN,
+ "HildonAppView",
+ &appview_info, 0);
+ }
+ return appview_type;
+}
+
+/*
+ * Class initialisation.
+ */
+static void hildon_appview_class_init(HildonAppViewClass * appview_class)
+{
+ /* Get convenience variables */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(appview_class);
+ GObjectClass *object_class = G_OBJECT_CLASS(appview_class);
+ GtkContainerClass *container_class =
+ GTK_CONTAINER_CLASS(appview_class);
+
+ /* Set the global parent_class here */
+ parent_class = g_type_class_peek_parent(appview_class);
+
+ object_class->set_property = hildon_appview_set_property;
+ object_class->get_property = hildon_appview_get_property;
+
+ /* Set the widgets virtual functions */
+ widget_class->size_allocate = hildon_appview_size_allocate;
+ widget_class->size_request = hildon_appview_size_request;
+ widget_class->expose_event = hildon_appview_expose;
+ widget_class->show_all = hildon_appview_show_all;
+ /* widget_class->realize = hildon_appview_realize; */
+
+ /* now the object stuff */
+ object_class->finalize = hildon_appview_finalize;
+
+ /* To the container */
+ container_class->forall = hildon_appview_forall;
+
+ /* gtkobject stuff*/
+ GTK_OBJECT_CLASS(appview_class)->destroy = hildon_appview_destroy;
+
+ /* And own virtual functions */
+ appview_class->fullscreen_state_change =
+ hildon_appview_real_fullscreen_state_change;
+ appview_class->switched_to = hildon_appview_switched_to;
+
+ g_type_class_add_private(appview_class,
+ sizeof(struct _HildonAppViewPrivate));
+
+ /* New signals */
+ appview_signals[TOOLBAR_CHANGED] =
+ g_signal_new("toolbar-changed",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, toolbar_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ appview_signals[TOOLBAR_TOGGLE_REQUEST] =
+ g_signal_new("toolbar-toggle-request",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass,
+ toolbar_toggle_request), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ appview_signals[FULLSCREEN_STATE_CHANGE] =
+ g_signal_new("fullscreen_state_change",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass,
+ fullscreen_state_change), NULL, NULL,
+ hildon_appview_signal_marshal, G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ appview_signals[TITLE_CHANGE] =
+ g_signal_new("title_change",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, title_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ appview_signals[SWITCHED_TO] =
+ g_signal_new("switched_to",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, switched_to),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ appview_signals[SWITCHED_FROM] =
+ g_signal_new("switched_from",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, switched_from),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ appview_signals[INCREASE_BUTTON_EVENT] =
+ g_signal_new("increase_button_event",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, increase_button_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ appview_signals[DECREASE_BUTTON_EVENT] =
+ g_signal_new("decrease_button_event",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonAppViewClass, decrease_button_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ /* New properties */
+ g_object_class_install_property(object_class, PROP_CONNECTED_ADJUSTMENT,
+ g_param_spec_object("connected-adjustment",
+ "Connected GtkAdjustment",
+ "The GtkAdjustment. The increase and decrease hardware buttons are mapped to this.",
+ GTK_TYPE_ADJUSTMENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_FULLSCREEN_KEY_ALLOWED,
+ g_param_spec_boolean("fullscreen-key-allowed",
+ "Fullscreen key allowed",
+ "Whether the fullscreen key is allowed or not",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_FULLSCREEN,
+ g_param_spec_boolean("fullscreen",
+ "Fullscreen",
+ "Whether the appview should be fullscreen or not",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class, PROP_TITLE,
+ g_param_spec_string("title",
+ "Title",
+ "Appview title",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class, PROP_MENU_UI,
+ g_param_spec_string("menu-ui",
+ "Menu UI string",
+ "UI string for application view menu",
+ NULL,
+ G_PARAM_READWRITE));
+ widget_class = (GtkWidgetClass*) appview_class;
+}
+
+/*
+ * Performs the initialisation of the widget.
+ */
+static void hildon_appview_init(HildonAppView * self)
+{
+ HildonAppViewPrivate *priv = self->priv =
+ HILDON_APPVIEW_GET_PRIVATE(self);
+
+ /* the vbox is used to handle both the view's main body and how many
+ * toolbars as the user wants */
+
+ self->vbox = gtk_vbox_new(TRUE, TOOLBAR_MIDDLE);
+ /* TOOLBAR_MIDDLE is here properly used, as originally meant. In order to
+ * be free to use whatever distance between toolbars, it's crucial to mind
+ * that the relevant gtkrc file must contain the following border property
+ * for the "toolbar-frame-middle" property: border = {24, 24, 5, 4}
+ */
+
+ gtk_widget_set_parent(self->vbox, GTK_WIDGET(self));
+ priv->menu = NULL;
+ priv->visible_toolbars = 0;
+
+ priv->title = g_strdup("");
+
+ priv->fullscreen = FALSE;
+ priv->fullscreenshortcutallowed = FALSE;
+ priv->increase_button_pressed_down = FALSE;
+ priv->decrease_button_pressed_down = FALSE;
+
+ priv->connected_adjustment = NULL;
+}
+
+/*
+ * Performs the standard gtk finalize function, freeing allocated
+ * memory and propagating the finalization to the parent.
+ */
+static void hildon_appview_finalize(GObject * obj_self)
+{
+ HildonAppView *self;
+ g_assert(HILDON_APPVIEW(obj_self));
+ self = HILDON_APPVIEW(obj_self);
+
+ if (self->priv->menu_ui)
+ g_free (self->priv->menu_ui);
+
+ if (self->priv->connected_adjustment != NULL)
+ g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
+ (gpointer) &self->priv->connected_adjustment);
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(obj_self);
+
+ g_free(self->priv->title);
+}
+
+/*
+ * An accessor to set private properties of HildonAppView.
+ */
+static void hildon_appview_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonAppView *appview = HILDON_APPVIEW (object);
+
+ switch (property_id) {
+ case PROP_CONNECTED_ADJUSTMENT:
+ hildon_appview_set_connected_adjustment (appview, g_value_get_object (value));
+ break;
+
+ case PROP_FULLSCREEN_KEY_ALLOWED:
+ hildon_appview_set_fullscreen_key_allowed (appview, g_value_get_boolean (value));
+ break;
+
+ case PROP_FULLSCREEN:
+ hildon_appview_set_fullscreen (appview, g_value_get_boolean (value));
+ break;
+
+ case PROP_TITLE:
+ hildon_appview_set_title (appview, g_value_get_string (value));
+ break;
+
+ case PROP_MENU_UI:
+ hildon_appview_set_menu_ui (appview, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * An accessor to get private properties of HildonAppView.
+ */
+static void hildon_appview_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(object);
+
+ switch (property_id) {
+ case PROP_CONNECTED_ADJUSTMENT:
+ g_value_set_object (value, priv->connected_adjustment);
+ break;
+
+ case PROP_FULLSCREEN_KEY_ALLOWED:
+ g_value_set_boolean (value, priv->fullscreenshortcutallowed);
+ break;
+
+ case PROP_FULLSCREEN:
+ g_value_set_boolean (value, priv->fullscreen);
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+
+ case PROP_MENU_UI:
+ g_value_set_string (value, priv->menu_ui);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * Used when the HildonAppView is exposed, this function gets a GtkBoxChild
+ * as first argument, and a pointer to a gint as second argument. If such
+ * GtkBoxChild is visible, the function increments the gint. It is used
+ * in a loop, to compute the number of visible toolbars.
+ */
+static void visible_toolbar(gpointer child, gpointer number_of_visible_toolbars)
+{
+ if(GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
+ (*((gint *)number_of_visible_toolbars))++;
+}
+
+/*
+ * Used in the paint_toolbar function to discover how many toolbars are
+ * above the find toolbar. It's called in a loop that iterates through
+ * all the children of the GtkVBox of the HildonAppView.
+ */
+static void find_findtoolbar_index(gpointer child, gpointer number_of_visible_toolbars)
+{
+ gint *pass_bundle = (gint *)number_of_visible_toolbars;
+
+ if(((GtkBoxChild *)child)->widget->allocation.y < pass_bundle[0]
+ && GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
+ pass_bundle[1]++;
+}
+
+/*
+ * Used in the paint_toolbar function, it's get a GtkBoxChild as first argument
+ * and a pointer to a GtkWidget as the second one, which will be addressed to
+ * the find toolbar widget, if it is contained in the given GtkBoxChild.
+ */
+static void find_findtoolbar(gpointer child, gpointer widget)
+{
+ if(HILDON_IS_FIND_TOOLBAR(((GtkBoxChild *)child)->widget)
+ && GTK_WIDGET_VISIBLE(((GtkBoxChild *)child)->widget))
+ (*((GtkWidget **)widget)) = ((GtkBoxChild *)child)->widget;
+}
+
+/*
+ * Paints all the toolbar children of the GtkVBox of the HildonAppView.
+ */
+static void paint_toolbar(GtkWidget *widget, GtkBox *box,
+ GdkEventExpose * event,
+ gboolean fullscreen)
+{
+ gint toolbar_num = 0;
+ gint ftb_index = 0;
+ gint count;
+ GtkWidget *findtoolbar = NULL;
+ gchar toolbar_mode[40];
+
+ /* Iterate through all the children of the vbox of the HildonAppView.
+ * The visible_toolbar function increments toolbar_num if the toolbar
+ * is visible. After this loop, toobar_num will contain the number
+ * of the visible toolbars. */
+ g_list_foreach(box->children, visible_toolbar,
+ (gpointer) &toolbar_num);
+ if(toolbar_num <= 0)
+ return;
+
+ /* Loop through all the children of the GtkVBox of the HildonAppView.
+ * The find_findtoolbar function will assign a pointer to the find toolbar
+ * to "findtoolbar" argument. If the findtoolbar is not found, i.e. it
+ * isn't in the GtkVBox, then the "findtoolbar" argument will stay NULL */
+ g_list_foreach(box->children, find_findtoolbar,
+ (gpointer) &findtoolbar);
+ if(findtoolbar != NULL){
+ gint pass_bundle[2];
+
+ /* an array for convient data passing
+ * the first member contains the y allocation
+ * of the find toolbar, and the second allocation
+ * contains the index(how many toolbars are above
+ * find toolbar) */
+ pass_bundle[0] = findtoolbar->allocation.y;
+ pass_bundle[1] = ftb_index;
+
+ /* computes how many toolbars are above the find toolbar, and the
+ * value is stored in pass_bundle[1] */
+ g_list_foreach(box->children, find_findtoolbar_index,
+ (gpointer) pass_bundle);
+ ftb_index = pass_bundle[1];
+ }
+ /*upper border*/
+ sprintf(toolbar_mode, "toolbar%sframe-top",
+ fullscreen ? "-fullscreen-" : "-");
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y -TOOLBAR_UP,
+ widget->allocation.width, TOOLBAR_UP);
+
+ /*top most toolbar painting*/
+ if(findtoolbar != NULL && ftb_index == 0 )
+ {
+ sprintf(toolbar_mode, "findtoolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y,
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }else{
+ sprintf(toolbar_mode, "toolbar%s",
+ fullscreen ? "-fullscreen" : "");
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y,
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ /*multi toolbar painting*/
+ for(count = 0; count < toolbar_num - 1; count++)
+ {
+ sprintf(toolbar_mode, "toolbar%sframe-middle",
+ fullscreen ? "-fullscreen-" : "-");
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * TOOLBAR_HEIGHT +
+ count * TOOLBAR_MIDDLE,
+ widget->allocation.width,
+ TOOLBAR_MIDDLE);
+
+ if(findtoolbar != NULL && count + 1 == ftb_index){
+ sprintf(toolbar_mode, "findtoolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }else{
+ sprintf(toolbar_mode, "toolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ }
+ sprintf(toolbar_mode, "toolbar%sframe-bottom",
+ fullscreen ? "-fullscreen-" : "-");
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ GTK_WIDGET(box)->allocation.height,
+ widget->allocation.width, TOOLBAR_DOWN);
+}
+
+/*
+ * Callback function to an expose event.
+ */
+static gboolean hildon_appview_expose(GtkWidget * widget,
+ GdkEventExpose * event)
+{
+ gint toolbar_num = 0;
+ GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox);
+
+ if(GTK_WIDGET_VISIBLE(box) && box->children != NULL)
+ {
+ HildonAppViewPrivate *priv = HILDON_APPVIEW_GET_PRIVATE(widget);
+
+ /* Iterate through all the children of the vbox of the HildonAppView.
+ * The visible_toolbar function increments toolbar_num if the toolbar
+ * is visible. After this loop, toobar_num will contain the number
+ * of the visible toolbars. */
+ g_list_foreach(box->children, visible_toolbar,
+ (gpointer) &toolbar_num);
+
+ if( priv->visible_toolbars != toolbar_num)
+ {
+ /* If the code reaches this block, it means that a toolbar as
+ * been added or removed since last time the view was drawn.
+ * Let's then compute the new height of the toolbars areas */
+ gint y_pos = 0;
+ /* the height difference */
+ gint change = (priv->visible_toolbars - toolbar_num) *
+ (TOOLBAR_HEIGHT+TOOLBAR_MIDDLE+TOOLBAR_UP);
+ if( change < 0 )
+ change = TOOLBAR_MIDDLE + TOOLBAR_UP;
+ /* the new y-coordinate for the toolbars area */
+ y_pos = HILDON_APPVIEW(widget)->vbox->allocation.y - change;
+
+ gtk_widget_queue_draw_area(widget, 0, y_pos, widget->allocation.width,
+ change + HILDON_APPVIEW(widget)->vbox->allocation.height +
+ TOOLBAR_DOWN);
+ priv->visible_toolbars = toolbar_num;
+ }
+ }
+
+
+ if (HILDON_APPVIEW(widget)->priv->fullscreen)
+ {
+ if (toolbar_num > 0)
+ paint_toolbar(widget, box, event, TRUE);
+ }
+ else
+ {
+ gint appview_height_decrement = 0;
+ if (toolbar_num > 0)
+ {
+ appview_height_decrement = toolbar_num * TOOLBAR_HEIGHT +
+ (toolbar_num - 1) * TOOLBAR_MIDDLE
+ + TOOLBAR_UP + TOOLBAR_DOWN;
+
+ paint_toolbar(widget, box, event, FALSE);
+ }
+ else
+ {
+ appview_height_decrement = MARGIN_APPVIEW_BOTTOM;
+
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, "bottom-border",
+ widget->allocation.x,
+ widget->allocation.y +
+ (widget->allocation.height - MARGIN_APPVIEW_BOTTOM),
+ widget->allocation.width, MARGIN_APPVIEW_BOTTOM);
+ }
+ gtk_paint_box( widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area,
+ widget, "left-border", widget->allocation.x,
+ widget->allocation.y, MARGIN_APPVIEW_LEFT,
+ widget->allocation.height - appview_height_decrement );
+ gtk_paint_box( widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area,
+ widget, "right-border",
+ (widget->allocation.x +
+ widget->allocation.width) -
+ MARGIN_APPVIEW_RIGHT, widget->allocation.y,
+ MARGIN_APPVIEW_RIGHT,
+ widget->allocation.height - appview_height_decrement );
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
+
+ return FALSE;
+}
+
+/*
+ * Responds to the usual size_request signal.
+ */
+static void hildon_appview_size_request(GtkWidget * widget,
+ GtkRequisition * requisition)
+{
+ HildonAppViewPrivate *priv = HILDON_APPVIEW(widget)->priv;
+ GtkWidget *child = GTK_BIN(widget)->child;
+
+ /* forward the size_request to the eventual child of the main container */
+ if (child)
+ gtk_widget_size_request(child, requisition);
+
+ /* forward the size_request to the eventual vbox (which may contain
+ * toolbars) */
+ if (HILDON_APPVIEW(widget)->vbox != NULL)
+ gtk_widget_size_request(HILDON_APPVIEW(widget)->vbox, requisition);
+
+ /* express the size_request for the view */
+ if (priv->fullscreen) {
+ requisition->height = WINDOW_HEIGHT;
+ requisition->width = WINDOW_WIDTH;
+ } else {
+ requisition->height = APPVIEW_HEIGHT;
+ requisition->width = APPVIEW_WIDTH;
+ }
+}
+
+/*
+ * Computes size and position for the children of the view.
+ */
+static void hildon_appview_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ GtkAllocation box_allocation;
+ GtkAllocation alloc = *allocation;
+ gint border_width = GTK_CONTAINER(widget)->border_width;
+ GtkBin *bin = GTK_BIN(widget);
+ GtkBox *box = GTK_BOX(HILDON_APPVIEW(widget)->vbox);
+ gboolean at_least_one_visible_toolbar = FALSE;
+
+ if(!GTK_IS_WIDGET(bin->child)) return;
+
+ widget->allocation = *allocation;
+
+ if (bin->child != NULL && GTK_IS_WIDGET(bin->child)) {
+ if (HILDON_APPVIEW(widget)->priv->fullscreen) {
+ alloc.x += border_width;
+ alloc.y += border_width;
+ alloc.width -= (border_width * 2);
+ alloc.height -= (border_width * 2);
+ } else {
+ alloc.x += border_width + MARGIN_APPVIEW_LEFT;
+ alloc.y += border_width + MARGIN_APPVIEW_TOP;
+ alloc.width -= (border_width * 2) + (MARGIN_APPVIEW_LEFT +
+ MARGIN_APPVIEW_RIGHT);
+ alloc.height -= (border_width * 2) + MARGIN_APPVIEW_TOP;
+ }
+ }
+
+ if (box->children != NULL) {
+ gint length = 0;
+ gint box_height = 0;
+ /* Iterate through all the children of the vbox of the HildonAppView.
+ * The visible_toolbar function increments toolbar_num if the toolbar
+ * is visible. After this loop, toobar_num will contain the number
+ * of the visible toolbars. */
+ g_list_foreach(box->children, visible_toolbar,
+ (gpointer) &length);
+ if(length > 0){
+ box_height = length * TOOLBAR_HEIGHT +
+ (length - 1) * TOOLBAR_MIDDLE;
+
+ if(bin->child != NULL) {
+ alloc.height = alloc.height - box_height - TOOLBAR_UP
+ - TOOLBAR_DOWN;
+ at_least_one_visible_toolbar = TRUE;
+ }
+
+ box_allocation.y = allocation->height - box_height - TOOLBAR_DOWN;
+ box_allocation.height = box_height;
+ box_allocation.x = allocation->x + TOOLBAR_LEFT;
+ box_allocation.width = allocation->width - TOOLBAR_LEFT -
+ TOOLBAR_RIGHT;
+ gtk_widget_size_allocate(GTK_WIDGET(box), &box_allocation);
+ }
+ }
+
+ /* The bottom skin graphics is visible only when there are no toolbars */
+ if ((HILDON_APPVIEW(widget)->priv->fullscreen == FALSE) &&
+ (at_least_one_visible_toolbar == FALSE))
+ alloc.height -= MARGIN_APPVIEW_BOTTOM;
+
+ gtk_widget_size_allocate(GTK_WIDGET(bin->child), &alloc);
+}
+
+/*
+ * Overrides gtk_container_forall, calling the callback function for each of
+ * the children of HildonAppPrivate.
+ */
+static void hildon_appview_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonAppView *self = HILDON_APPVIEW(container);
+
+ g_assert(callback != NULL);
+
+ GTK_CONTAINER_CLASS(parent_class)->forall(container, include_internals,
+ callback, callback_data);
+ if(include_internals && self->vbox != NULL)
+ (* callback)(GTK_WIDGET(self->vbox), callback_data);
+}
+
+/**
+ * Shows all the widgets in the container.
+ */
+static void hildon_appview_show_all(GtkWidget *widget)
+{
+ HildonAppView *self = HILDON_APPVIEW(widget);
+
+ /* Toolbar items */
+ gtk_widget_show_all(self->vbox);
+
+ /* Parent handless stuff inside appview */
+ GTK_WIDGET_CLASS(parent_class)->show_all(widget);
+}
+
+/*
+ * Frees all the resources and propagates the destroy call to the parent.
+ */
+static void hildon_appview_destroy(GtkObject *obj)
+{
+ HildonAppView *self = HILDON_APPVIEW(obj);
+
+ if(self->vbox != NULL){
+ gtk_widget_unparent(self->vbox);
+ self->vbox = NULL;
+ }
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+/*******************/
+/* Signals */
+/*******************/
+
+/*Signal - When is changed to this appview, this is called*/
+static void hildon_appview_switched_to(HildonAppView * self)
+{
+ GtkWidget *parent;
+
+ g_assert(self && HILDON_IS_APPVIEW(self));
+
+ parent = gtk_widget_get_parent(GTK_WIDGET(self));
+ hildon_appview_set_fullscreen( self, self->priv->fullscreen );
+}
+
+/*Signal - When the fullscreen state is changed, this is called*/
+static void hildon_appview_real_fullscreen_state_change(HildonAppView *
+ self,
+ gboolean
+ fullscreen)
+{
+ HildonAppViewPrivate *priv;
+ g_assert(self && HILDON_IS_APPVIEW(self));
+ priv = self->priv;
+
+ /* Ensure that state is really changed */
+ if( priv->fullscreen == fullscreen )
+ return;
+
+ if( fullscreen )
+ gtk_window_fullscreen( GTK_WINDOW(
+ gtk_widget_get_parent(GTK_WIDGET(self))) );
+ else
+ gtk_window_unfullscreen( GTK_WINDOW(
+ gtk_widget_get_parent(GTK_WIDGET(self))) );
+
+ priv->fullscreen = fullscreen;
+}
+
+/*******************/
+/* General */
+/*******************/
+
+
+/*
+ * queries a window for the root window coordinates and size of its
+ * client area (i.e. minus the title borders etc.)
+ */
+static void get_client_area(GtkWidget * widget, GtkAllocation * allocation)
+{
+ GdkWindow *window = widget->window;
+
+ if (window)
+ gdk_window_get_origin(window, &allocation->x, &allocation->y);
+ else
+ memset( allocation, 0, sizeof(GtkAllocation) );
+}
+
+/*The menu popuping needs a menu popup-function*/
+static void hildon_appview_menupopupfunc( GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in, GtkWidget *widget )
+{
+ GtkAllocation client_area = { 0, 0, 0, 0 };
+
+ get_client_area( GTK_WIDGET(widget), &client_area );
+
+ gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
+ "vertical-offset", y, NULL);
+
+ *x += client_area.x;
+ *y += client_area.y;
+
+}
+
+/* Similar to above, but used in fullscreen mode */
+static void hildon_appview_menupopupfuncfull( GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget )
+{
+ gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
+ "vertical-offset", y, NULL);
+
+ *x = MAX (0, *x);
+ *y = MAX (0, *y);
+}
+
+/*******************/
+/*public functions*/
+/*******************/
+
+
+/**
+ * hildon_appview_new:
+ * @title:the application view title of the new @HildonAppView
+ *
+ * Use this function to create a new application view. The title will
+ * be set only if two-part-title is enabled on the @HildonApp.
+ *
+ * Returns: A #HildonAppView.
+ **/
+GtkWidget *hildon_appview_new(const gchar * title)
+{
+ HildonAppView *newappview = g_object_new(HILDON_TYPE_APPVIEW, NULL);
+
+ hildon_appview_set_title(newappview, title);
+ return GTK_WIDGET(newappview);
+}
+
+/**
+ * hildon_appview_add_with_scrollbar
+ * @self : a @HildonAppView
+ * @child : a @GtkWidget
+ *
+ * Adds the @child to the @self(HildonAppView) and creates a vertical
+ * scrollbar to it. Similar as adding first a #GtkScrolledWindow
+ * and then the @child to it.
+ */
+void hildon_appview_add_with_scrollbar(HildonAppView * self,
+ GtkWidget * child)
+{
+ GtkScrolledWindow *scrolledw;
+
+ g_return_if_fail(HILDON_IS_APPVIEW(self));
+ g_return_if_fail(GTK_IS_WIDGET(child));
+ g_return_if_fail(child->parent == NULL);
+
+ scrolledw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
+ gtk_scrolled_window_set_policy(scrolledw, GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(scrolledw, GTK_SHADOW_NONE);
+
+ /* Check whether child widget supports adjustments */
+ if (GTK_WIDGET_GET_CLASS (child)->set_scroll_adjustments_signal)
+ gtk_container_add(GTK_CONTAINER(scrolledw), child);
+ else
+ {
+ if( GTK_IS_CONTAINER(child) )
+ gtk_container_set_focus_vadjustment( GTK_CONTAINER(child),
+ gtk_scrolled_window_get_vadjustment(scrolledw) );
+ gtk_scrolled_window_add_with_viewport(scrolledw, child);
+ }
+
+ gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(scrolledw));
+}
+
+/**
+ * hildon_appview_get_title:
+ * @self : a #HildonAppView
+ *
+ * Gets the title of given #HildonAppView.
+ *
+ * Returns: the title of the application view
+ */
+const gchar *hildon_appview_get_title(HildonAppView * self)
+{
+ g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), "");
+ return self->priv->title;
+}
+
+/**
+ * hildon_appview_set_title:
+ * @self : a #HildonAppView
+ * @newname : the new title of the application view.
+ *
+ * Sets an title of an application view. The title is visible only if
+ * two-part-title is enabled on the #HildonApp.
+ *
+ */
+void hildon_appview_set_title(HildonAppView * self, const gchar * newname)
+{
+ gchar *oldtitle;
+
+ g_return_if_fail(self && HILDON_IS_APPVIEW(self));
+ oldtitle = self->priv->title;
+
+ if (newname != NULL)
+ self->priv->title = g_strdup(newname);
+ else
+ self->priv->title = g_strdup("");
+
+ g_free(oldtitle);
+ g_signal_emit_by_name(G_OBJECT(self), "title_change");
+}
+
+/**
+ * hildon_appview_set_toolbar:
+ * @self: a #HildonAppView
+ * @toolbar: a #GtkToolbar
+ *
+ * Sets the #GtkToolbar to given #HildonAppView. This is, however, not a
+ * recommended way to set your toolbars. When you have multi toolbars, calling
+ * this function more than once will just replace the bottom most toolbar.
+ * There is a #GtkVBox in #HildonAppView's public structure, the programmer
+ * is responsible to pack his toolbars in the #GtkVBox, and #HildonAppView will
+ * take care of putting them at the right place.
+ *
+ */
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_appview_set_toolbar(HildonAppView * self, GtkToolbar * toolbar)
+{
+ GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox);
+ g_return_if_fail(self && HILDON_IS_APPVIEW(self));
+ if(toolbar != NULL)/*for failure checking*/
+ g_return_if_fail(GTK_IS_TOOLBAR(toolbar));
+
+ /*if it is NULL, it unsets the last one,
+ * if it is not null, it unsets the last one anyway*/
+ if(box->children != NULL){
+ GtkWidget *last_widget;
+
+ last_widget = ((GtkBoxChild *)g_list_last
+ (box->children)->data)->widget;
+ gtk_container_remove(GTK_CONTAINER(box),
+ last_widget);
+ }
+
+ gtk_box_pack_end(box, GTK_WIDGET(toolbar), TRUE, TRUE, 0);
+ gtk_widget_queue_resize(GTK_WIDGET(self));
+ /*deprecated signal*/
+ g_signal_emit_by_name(G_OBJECT(self), "toolbar-changed");
+}
+#endif
+/**
+ * hildon_appview_get_toolbar:
+ * @self: a #HildonAppView
+ *
+ * This function will only
+ * return the last widget that has been packed into the #GtkVBox in the public
+ * structure. Note this does not, however, mean that it is the bottom most
+ * toolbar.
+ *
+ * Return value: the #GtkToolbar assigned to this application view.
+ **/
+#ifndef HILDON_DISABLE_DEPRECATED
+GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self)
+{
+ GtkBox *box = GTK_BOX(HILDON_APPVIEW(self)->vbox);
+ g_return_val_if_fail(self != NULL && HILDON_IS_APPVIEW(self), FALSE);
+ if(box != NULL && box->children != NULL)
+ return GTK_TOOLBAR(((GtkBoxChild*)
+ g_list_last(box->children)->data)->widget);
+ else
+ return NULL;
+}
+#endif
+/**
+ * hildon_appview_set_fullscreen:
+ * @self: a #HildonAppView
+ * @fullscreen: the new state of fullscreen mode. TRUE means fullscreen
+ * will be set. FALSE the opposite.
+ *
+ * Set the fullscreen state of given #HildonAppView class.
+ */
+void hildon_appview_set_fullscreen(HildonAppView * self,
+ gboolean fullscreen)
+{
+ g_return_if_fail(self && HILDON_IS_APPVIEW(self));
+ g_signal_emit_by_name(G_OBJECT(self), "fullscreen_state_change",
+ fullscreen);
+}
+
+/**
+ * hildon_appview_get_fullscreen:
+ * @self: a #HildonAppView
+ *
+ * Gets the current state of fullscreen mode.
+ *
+ * Returns: the current state of fullscreen mode
+ */
+gboolean hildon_appview_get_fullscreen(HildonAppView * self)
+{
+ g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
+ return self->priv->fullscreen;
+}
+
+/**
+ * hildon_appview_get_fullscreen_key_allowed:
+ * @self: a #HildonAppView
+ *
+ * Check if fullscreening with a shortcut is allowed for given
+ * #HildonAppView.
+ *
+ * Returns: wheter it's possible to swith fullscreen on/off with
+ * a shortcut key
+ */
+gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self)
+{
+ g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
+ return self->priv->fullscreenshortcutallowed;
+}
+
+/**
+ * hildon_appview_set_fullscreen_key_allowed:
+ * @self: a #HildonAppView
+ * @allow: wheter it's possible to swith fullscreen on/off with
+ * a shortcut key
+ *
+ * Sets given #HildonAppView whether to allow toggling fullscreen mode
+ * with a shortcut key.
+ */
+void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self,
+ gboolean allow)
+{
+ g_return_if_fail(self && HILDON_IS_APPVIEW(self));
+ self->priv->fullscreenshortcutallowed = allow;
+}
+
+/**
+ * hildon_appview_get_menu:
+ * @self : #HildonAppView
+ *
+ * Gets the #GtMenu assigned to the #HildonAppview.
+ *
+ * Returns: the #GtkMenu assigned to this application view
+ */
+GtkMenu *hildon_appview_get_menu(HildonAppView * self)
+{
+ g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), NULL);
+
+ if (self->priv->menu == NULL) {
+ /* Create hildonlike menu */
+
+ GtkUIManager *uim;
+ GtkWidget *parent = gtk_widget_get_parent (GTK_WIDGET (self));
+
+ /* Try to get appview menu from ui manager */
+ if (parent && HILDON_IS_APP (parent))
+ {
+ uim = hildon_app_get_ui_manager (HILDON_APP (parent));
+ if (uim)
+ {
+ self->priv->menu =
+ gtk_ui_manager_get_widget (uim, "/HildonApp");
+ }
+ }
+
+
+ if (self->priv->menu == NULL)
+ {
+ /* Fall back to oldskool menus */
+ self->priv->menu = GTK_WIDGET (g_object_new (GTK_TYPE_MENU, NULL));
+ }
+
+ gtk_widget_set_name(GTK_WIDGET(self->priv->menu),
+ "menu_force_with_corners");
+ gtk_widget_show_all (self->priv->menu);
+ }
+
+ return GTK_MENU(self->priv->menu);
+}
+
+/**
+ * _hildon_appview_toggle_menu:
+ * @self : a #HildonAppView
+ * @button_event_time :
+ *
+ * This function should be only called from @HildonApp.
+ * Should be renamed to popup menu. Just the first parameter is used.
+ *
+ * Returns: Whether or not something was done (whether or not we had
+ * a menu)
+ */
+gboolean _hildon_appview_toggle_menu(HildonAppView * self,
+ Time button_event_time)
+{
+ GList *children;
+
+ g_return_val_if_fail(self && HILDON_IS_APPVIEW(self), FALSE);
+
+ if (!self->priv->menu)
+ return FALSE;
+
+ if (GTK_WIDGET_VISIBLE(self->priv->menu)) {
+ gtk_menu_popdown(GTK_MENU(self->priv->menu));
+ gtk_menu_shell_deactivate(GTK_MENU_SHELL(self->priv->menu));
+ return TRUE;
+ }
+
+ /* Avoid opening an empty menu */
+ children = gtk_container_get_children(
+ GTK_CONTAINER(hildon_appview_get_menu(self)));
+ if (children != NULL) {
+ GtkWidget *menu;
+
+ g_list_free(children);
+ menu = GTK_WIDGET(hildon_appview_get_menu(self));
+ if (self->priv->fullscreen) {
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
+ (GtkMenuPositionFunc)
+ hildon_appview_menupopupfuncfull,
+ self, 0, button_event_time);
+ } else {
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
+ (GtkMenuPositionFunc)
+ hildon_appview_menupopupfunc,
+ self, 0, button_event_time);
+ }
+ gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), TRUE);
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+/**
+ * _hildon_appview_menu_visible
+ * @self: a #HildonAppView
+ *
+ * Checks whether the titlebar menu is currently visible
+ * Returns: TRUE if the menu is visible, FALSE if not
+ */
+
+gboolean _hildon_appview_menu_visible(HildonAppView * self)
+{
+ g_return_val_if_fail (HILDON_IS_APPVIEW (self), FALSE);
+
+ return GTK_WIDGET_VISIBLE(GTK_WIDGET(hildon_appview_get_menu(self)));
+}
+
+/**
+ * hildon_appview_set_connected_adjustment
+ * @self : #HildonAppView
+ * @adjustment : a new #GtkAdjustment set to reach to increase
+ * / decrease hardware keys or NULL to unset
+ *
+ * Sets a #GtkAdjustment which will change when increase/decrease buttons
+ * are pressed.
+ */
+void hildon_appview_set_connected_adjustment (HildonAppView * self,
+ GtkAdjustment * adjustment)
+{
+ g_return_if_fail (HILDON_IS_APPVIEW (self));
+
+ /* Disconnect old adjustment */
+ if (self->priv->connected_adjustment != NULL)
+ g_object_remove_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
+ (gpointer) &self->priv->connected_adjustment);
+
+ /* Start using the new one */
+ self->priv->connected_adjustment = adjustment;
+ if (self->priv->connected_adjustment != NULL)
+ g_object_add_weak_pointer (G_OBJECT (self->priv->connected_adjustment),
+ (gpointer) &self->priv->connected_adjustment);
+}
+
+/**
+ * hildon_appview_get_connected_adjustment
+ * @self : a #HildonAppView
+ *
+ * Retrieves the #GtkAdjustment which is connected to this application view
+ * and is changed with increase / decrease hardware buttons.
+ *
+ * Returns: currently connectd #GtkAdjustment assigned to this
+ * application view or NULL if it's not set
+ */
+GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self)
+{
+ g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL);
+
+ return self->priv->connected_adjustment;
+}
+
+
+/**
+ * hildon_appview_set_menu_ui
+ * @self : a #HildonAppView
+ * @ui_string : a #GtkUIManager ui description string
+ *
+ * Sets the ui description (xml) from which the UIManager creates menus
+ * (see @GtkUIManager for details on how to use it)
+ */
+void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string)
+{
+ g_return_if_fail (HILDON_IS_APPVIEW (self));
+
+ if (ui_string)
+ {
+ if (self->priv->menu_ui)
+ g_free (self->priv->menu_ui);
+
+ self->priv->menu_ui = g_strdup (ui_string);
+
+ /* FIXME: We should update the menu here, preferrably by a
+ * hildon_app_ensure_menu_update() which re-installs the menu ui
+ * and calls gtk_ui_manager_ensure_update()
+ */
+ }
+ else
+ {
+ /* Reset the UI */
+ if (self->priv->menu_ui)
+ {
+ g_free (self->priv->menu_ui);
+ self->priv->menu_ui = NULL;
+ }
+ }
+
+ g_object_notify (G_OBJECT(self), "menu-ui");
+}
+
+/**
+ * hildon_appview_get_menu_ui
+ * @self : a #HildonAppView
+ *
+ * Sets the ui description (xml) from which the UIManager creates menus
+ * (see #GtkUIManager for details on how to use it)
+ *
+ * Returns: currently set ui description
+ */
+const gchar *hildon_appview_get_menu_ui(HildonAppView *self)
+{
+ g_return_val_if_fail (HILDON_IS_APPVIEW (self), NULL);
+
+ return (self->priv->menu_ui);
+
+}
+
+/* Called when '+' hardkey is pressed/released */
+void _hildon_appview_increase_button_state_changed (HildonAppView * self,
+ guint newkeytype)
+{
+ self->priv->increase_button_pressed_down = newkeytype;
+
+ /* Transform '+' press into adjustment update (usually scrollbar move) */
+ if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS))
+ {
+ gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) + self->priv->connected_adjustment->step_increment,
+ self->priv->connected_adjustment->lower,
+ self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size);
+ gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue);
+ }
+
+ g_signal_emit (G_OBJECT (self), appview_signals[INCREASE_BUTTON_EVENT], 0, newkeytype);
+}
+
+/* Called when '-' hardkey is pressed/released */
+void _hildon_appview_decrease_button_state_changed (HildonAppView * self,
+ guint newkeytype)
+{
+ self->priv->decrease_button_pressed_down = newkeytype;
+
+ /* Transform '-' press into adjustment update (usually scrollbar move) */
+ if ((self->priv->connected_adjustment != NULL) && (newkeytype == GDK_KEY_PRESS))
+ {
+ gfloat clampedvalue = CLAMP (gtk_adjustment_get_value (self->priv->connected_adjustment) - self->priv->connected_adjustment->step_increment,
+ self->priv->connected_adjustment->lower,
+ self->priv->connected_adjustment->upper - self->priv->connected_adjustment->page_size);
+ gtk_adjustment_set_value (self->priv->connected_adjustment, clampedvalue);
+ }
+
+ g_signal_emit (G_OBJECT (self), appview_signals[DECREASE_BUTTON_EVENT], 0, newkeytype);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_APPVIEW_H__
+#define __HILDON_APPVIEW_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkbin.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtktoolbar.h>
+#include <gdk/gdkx.h>
+
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_APPVIEW ( hildon_appview_get_type() )
+#define HILDON_APPVIEW(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_APPVIEW, HildonAppView))
+#define HILDON_APPVIEW_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_APPVIEW, HildonAppViewClass))
+#define HILDON_IS_APPVIEW(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_APPVIEW))
+#define HILDON_IS_APPVIEW_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_APPVIEW))
+typedef struct _HildonAppView HildonAppView;
+typedef struct _HildonAppViewClass HildonAppViewClass;
+
+/**
+ * HildonAppViewPrivate:
+ *
+ * This structure contains just internal data. It should not
+ * be accessed directly.
+ */
+typedef struct _HildonAppViewPrivate HildonAppViewPrivate;
+
+struct _HildonAppView {
+ GtkBin parent;
+
+ /*public*/
+ GtkWidget *vbox;
+
+ /*private*/
+ HildonAppViewPrivate *priv;
+};
+
+struct _HildonAppViewClass {
+ GtkBinClass parent_class;
+ void (*toolbar_changed) (HildonAppView * self);
+ void (*toolbar_toggle_request) (HildonAppView * self);
+ void (*fullscreen_state_change) (HildonAppView * self,
+ gboolean is_fullscreen);
+ void (*title_change) (HildonAppView * self);
+ void (*switched_to) (HildonAppView * self);
+ void (*switched_from) (HildonAppView * self);
+ void (*increase_button_event) (HildonAppView * self,
+ guint newkeytype);
+ void (*decrease_button_event) (HildonAppView * self,
+ guint newkeytype);
+};
+
+
+GType hildon_appview_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_appview_new(const gchar * title);
+void hildon_appview_add_with_scrollbar(HildonAppView * self,
+ GtkWidget * child);
+void hildon_appview_set_fullscreen_key_allowed(HildonAppView * self,
+ gboolean allow);
+gboolean hildon_appview_get_fullscreen_key_allowed(HildonAppView * self);
+
+gboolean hildon_appview_get_fullscreen(HildonAppView * self);
+void hildon_appview_set_fullscreen(HildonAppView * self,
+ gboolean fullscreen);
+GtkMenu *hildon_appview_get_menu(HildonAppView * self);
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_appview_set_toolbar(HildonAppView * self,
+ GtkToolbar * toolbar);
+GtkToolbar *hildon_appview_get_toolbar(HildonAppView * self);
+#endif
+void hildon_appview_set_title(HildonAppView * self, const gchar * newname);
+const gchar *hildon_appview_get_title(HildonAppView * self);
+
+gboolean _hildon_appview_toggle_menu(HildonAppView * self,
+ Time button_event_time);
+gboolean _hildon_appview_menu_visible(HildonAppView * self);
+
+void hildon_appview_set_connected_adjustment (HildonAppView * self,
+ GtkAdjustment * adjustment);
+GtkAdjustment * hildon_appview_get_connected_adjustment (HildonAppView * self);
+
+void _hildon_appview_increase_button_state_changed (HildonAppView * self,
+ guint newkeytype);
+void _hildon_appview_decrease_button_state_changed (HildonAppView * self,
+ guint newkeytype);
+
+void hildon_appview_set_menu_ui(HildonAppView *self, const gchar *ui_string);
+const gchar *hildon_appview_get_menu_ui(HildonAppView *self);
+
+G_END_DECLS
+#endif /* HILDON_APPVIEW_H */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkicontheme.h>
+#include <string.h>
+#include <X11/X.h>
+#include <X11/Xatom.h>
+
+#include "hildon-defines.h"
+#include "hildon-banner.h"
+
+/* position relative to the screen */
+#define HILDON_BANNER_WINDOW_X 30
+#define HILDON_BANNER_WINDOW_Y 73
+#define HILDON_BANNER_WINDOW_FULLSCREEN_Y 20
+
+/* max widths */
+#define HILDON_BANNER_PROGRESS_WIDTH 104
+#define HILDON_BANNER_LABEL_MAX_TIMED 375
+#define HILDON_BANNER_LABEL_MAX_PROGRESS 375 /*265*/
+
+/* default timeout */
+#define HILDON_BANNER_TIMEOUT 3000
+
+/* default icons */
+#define HILDON_BANNER_DEFAULT_ICON "qgn_note_infoprint"
+#define HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION "qgn_indi_pball_a"
+
+enum {
+ PROP_PARENT_WINDOW = 1,
+ PROP_IS_TIMED
+};
+
+struct _HildonBannerPrivate
+{
+ GtkWidget *main_item;
+ GtkWidget *label;
+ GtkWidget *layout;
+ guint timeout_id;
+ gboolean is_timed;
+};
+
+static GtkWidget *global_timed_banner = NULL;
+
+G_DEFINE_TYPE(HildonBanner, hildon_banner, GTK_TYPE_WINDOW)
+
+/* copy/paste from old infoprint implementation: Use matchbox
+ properties to find the topmost application window */
+static Window get_current_app_window(void)
+{
+ unsigned long n;
+ unsigned long extra;
+ int format;
+ int status;
+
+ Atom atom_current_app_window = gdk_x11_get_xatom_by_name ("_MB_CURRENT_APP_WINDOW");
+ Atom realType;
+ Window win_result = None;
+ guchar *data_return = NULL;
+
+ status = XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ atom_current_app_window, 0L, 16L,
+ 0, XA_WINDOW, &realType, &format,
+ &n, &extra,
+ &data_return);
+
+ if ( status == Success && realType == XA_WINDOW
+ && format == 32 && n == 1 && data_return != NULL )
+ {
+ win_result = ((Window*) data_return)[0];
+ }
+
+ if ( data_return )
+ XFree(data_return);
+
+ return win_result;
+}
+
+/* Checks if a window is in fullscreen state or not. This
+ information is needed when banners are positioned on screen.
+ copy/paste from old infoprint implementation. */
+static gboolean check_fullscreen_state( Window window )
+{
+ unsigned long n;
+ unsigned long extra;
+ int format, status, i;
+ guchar *data_return = NULL;
+
+ Atom realType;
+ Atom atom_window_state = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
+ Atom atom_fullscreen = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_FULLSCREEN");
+
+ if ( window == None )
+ return FALSE;
+
+ /* in some cases XGetWindowProperty seems to generate BadWindow,
+ so at the moment this function does not always work perfectly */
+ gdk_error_trap_push();
+ status = XGetWindowProperty(GDK_DISPLAY(), window,
+ atom_window_state, 0L, 1000000L,
+ 0, XA_ATOM, &realType, &format,
+ &n, &extra, &data_return);
+ gdk_flush();
+ if (gdk_error_trap_pop())
+ return FALSE;
+
+ if (status == Success && realType == XA_ATOM && format == 32 && n > 0)
+ {
+ for(i=0; i < n; i++)
+ if ( ((Atom*)data_return)[i] &&
+ ((Atom*)data_return)[i] == atom_fullscreen)
+ {
+ if (data_return) XFree(data_return);
+ return TRUE;
+ }
+ }
+
+ if (data_return)
+ XFree(data_return);
+
+ return FALSE;
+}
+
+static GQuark hildon_banner_timed_quark(void)
+{
+ static GQuark quark = 0;
+
+ if (G_UNLIKELY(quark == 0))
+ quark = g_quark_from_static_string("hildon-banner-timed");
+
+ return quark;
+}
+
+/* Set the label name to make the correct rc-style attached into it */
+static void hildon_banner_bind_label_style(HildonBanner *self,
+ const gchar *name)
+{
+ GtkWidget *label = self->priv->label;
+
+ /* Too bad that we cannot really reset the widget name */
+ gtk_widget_set_name(label, name ? name : g_type_name(GTK_WIDGET_TYPE(label)));
+}
+
+/* In timeout function we automatically destroy timed banners */
+static gboolean hildon_banner_timeout(gpointer data)
+{
+ GtkWidget *widget;
+ GdkEvent *event;
+ gboolean continue_timeout = FALSE;
+
+ GDK_THREADS_ENTER ();
+
+ g_assert(HILDON_IS_BANNER(data));
+
+ widget = GTK_WIDGET(data);
+ g_object_ref(widget);
+
+ /* If the banner is currently visible (it normally should),
+ we simulate clicking the close button of the window.
+ This allows applications to reuse the banner by prevent
+ closing it etc */
+ if (GTK_WIDGET_DRAWABLE(widget))
+ {
+ event = gdk_event_new (GDK_DELETE);
+ event->any.window = g_object_ref(widget->window);
+ event->any.send_event = FALSE;
+ continue_timeout = gtk_widget_event (widget, event);
+ gdk_event_free(event);
+ }
+
+ if (!continue_timeout)
+ gtk_widget_destroy (widget);
+
+ g_object_unref(widget);
+
+ GDK_THREADS_LEAVE ();
+
+ return continue_timeout;
+}
+
+static gboolean hildon_banner_clear_timeout(HildonBanner *self)
+{
+ g_assert(HILDON_IS_BANNER(self));
+
+ if (self->priv->timeout_id != 0) {
+ g_source_remove(self->priv->timeout_id);
+ self->priv->timeout_id = 0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void hildon_banner_ensure_timeout(HildonBanner *self)
+{
+ g_assert(HILDON_IS_BANNER(self));
+
+ if (self->priv->timeout_id == 0 && self->priv->is_timed)
+ self->priv->timeout_id = g_timeout_add(HILDON_BANNER_TIMEOUT,
+ hildon_banner_timeout, self);
+}
+
+static void hildon_banner_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkWidget *window;
+ GdkGeometry geom;
+ HildonBannerPrivate *priv = HILDON_BANNER(object)->priv;
+
+ switch (prop_id) {
+ case PROP_IS_TIMED:
+ priv->is_timed = g_value_get_boolean(value);
+
+ /* Timed and progress notifications have different
+ pixel size values for text.
+ We force to use requisition size for timed banners
+ in order to avoid resize problems when reusing the
+ window (see bug #24339) */
+ geom.max_width = priv->is_timed ? -1
+ : HILDON_BANNER_LABEL_MAX_PROGRESS;
+ geom.max_height = -1;
+ gtk_window_set_geometry_hints(GTK_WINDOW(object),
+ priv->label, &geom, GDK_HINT_MAX_SIZE);
+ break;
+
+ case PROP_PARENT_WINDOW:
+ window = g_value_get_object(value);
+
+ gtk_window_set_transient_for(GTK_WINDOW(object), (GtkWindow *) window);
+
+ if (window)
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(object), TRUE);
+
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void hildon_banner_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonBanner *self = HILDON_BANNER(object);
+
+ switch (prop_id)
+ {
+ case PROP_IS_TIMED:
+ g_value_set_boolean(value, self->priv->is_timed);
+ break;
+
+ case PROP_PARENT_WINDOW:
+ g_value_set_object(value, gtk_window_get_transient_for(GTK_WINDOW(object)));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void hildon_banner_destroy(GtkObject *object)
+{
+ HildonBanner *self;
+ GObject *parent_window;
+
+ g_assert(HILDON_IS_BANNER(object));
+ self = HILDON_BANNER(object);
+
+ /* Drop possible global pointer. That can hold reference to us */
+ if ((gpointer) object == (gpointer) global_timed_banner) {
+ global_timed_banner = NULL;
+ g_object_unref(object);
+ }
+
+ /* Remove the data from parent window for timed banners. Those hold reference */
+ if (self->priv->is_timed &&
+ (parent_window = (GObject *) gtk_window_get_transient_for(
+ GTK_WINDOW(object))) != NULL)
+ g_object_set_qdata(parent_window, hildon_banner_timed_quark(), NULL);
+
+ (void) hildon_banner_clear_timeout(self);
+
+ if (GTK_OBJECT_CLASS(hildon_banner_parent_class)->destroy)
+ GTK_OBJECT_CLASS(hildon_banner_parent_class)->destroy(object);
+}
+
+/* Search a previous banner instance */
+static GObject *hildon_banner_real_get_instance(GObject *window, gboolean timed)
+{
+ g_assert(window == NULL || GTK_IS_WINDOW(window));
+
+ if (timed) {
+ /* If we have a parent window, the previous instance is stored there */
+ if (window)
+ return g_object_get_qdata(window, hildon_banner_timed_quark());
+
+ /* System notification instance is stored into global pointer */
+ return (GObject *) global_timed_banner;
+ }
+
+ /* Non-timed banners are normal (non-singleton) objects */
+ return NULL;
+}
+
+/* By overriding constructor we force timed banners to be
+ singletons for each window */
+static GObject* hildon_banner_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *banner, *window = NULL;
+ gboolean timed = FALSE;
+ guint i;
+
+ /* Search banner type information from parameters in order
+ to locate the possible previous banner instance. */
+ for (i = 0; i < n_construct_params; i++)
+ {
+ if (strcmp(construct_params[i].pspec->name, "parent-window") == 0)
+ window = g_value_get_object(construct_params[i].value);
+ else if (strcmp(construct_params[i].pspec->name, "is-timed") == 0)
+ timed = g_value_get_boolean(construct_params[i].value);
+ }
+
+ /* Try to get a previous instance if such exists */
+ banner = hildon_banner_real_get_instance(window, timed);
+ if (!banner)
+ {
+ /* We have to create a new banner */
+ banner = G_OBJECT_CLASS(hildon_banner_parent_class)->constructor(
+ type, n_construct_params, construct_params);
+
+ /* Store the newly created singleton instance either into parent
+ window data or into global variables. */
+ if (timed) {
+ if (window) {
+ g_object_set_qdata_full(G_OBJECT(window), hildon_banner_timed_quark(),
+ g_object_ref(banner), g_object_unref);
+ } else {
+ g_assert(global_timed_banner == NULL);
+ global_timed_banner = g_object_ref(banner);
+ }
+ }
+ }
+ else {
+ /* FIXME: This is a hack! We have to manually freeze
+ notifications. This is normally done by g_object_init, but we
+ are not going to call that. g_object_newv will otherwise give
+ a critical like this:
+
+ GLIB CRITICAL ** GLib-GObject - g_object_notify_queue_thaw:
+ assertion `nqueue->freeze_count > 0' failed */
+
+ g_object_freeze_notify(banner);
+ }
+
+ /* We restart possible timeouts for each new timed banner request */
+ if (timed && hildon_banner_clear_timeout(HILDON_BANNER(banner)))
+ hildon_banner_ensure_timeout(HILDON_BANNER(banner));
+
+ return banner;
+}
+
+/* We start the timer for timed notifications after the window appears on screen */
+static gboolean hildon_banner_map_event(GtkWidget *widget, GdkEventAny *event)
+{
+ gboolean result = FALSE;
+
+ if (GTK_WIDGET_CLASS(hildon_banner_parent_class)->map_event)
+ result = GTK_WIDGET_CLASS(hildon_banner_parent_class)->map_event(widget, event);
+
+ hildon_banner_ensure_timeout(HILDON_BANNER(widget));
+
+ return result;
+}
+
+
+/* force to wrap truncated label by setting explicit size request
+ * see N#27000 and G#329646 */
+static void force_to_wrap_truncated(HildonBanner *banner){
+ GtkLabel *label;
+ PangoLayout *layout;
+ int width_text, width_max;
+ int width = -1;
+
+ label = GTK_LABEL(banner->priv->label);
+
+ layout = gtk_label_get_layout(label);
+ width_text = PANGO_PIXELS(pango_layout_get_width(layout));
+ /* = width to which the lines of the PangoLayout should be wrapped */
+
+ width_max = banner->priv->is_timed ? HILDON_BANNER_LABEL_MAX_TIMED
+ : HILDON_BANNER_LABEL_MAX_PROGRESS;
+
+ if(width_text >= width_max){
+ /* explicitly request maximum size to force wrapping */
+ PangoRectangle logical;
+
+ pango_layout_set_width (layout, width_max * PANGO_SCALE);
+ pango_layout_get_extents (layout, NULL, &logical);
+
+ width = PANGO_PIXELS (logical.width);
+ }
+
+ /* use fixed width when wrapping or natural one otherwise */
+ gtk_widget_set_size_request (GTK_WIDGET (label),
+ width, -1);
+}
+
+
+static void hildon_banner_check_position(GtkWidget *widget)
+{
+ gint x, y;
+ GtkRequisition req;
+
+ force_to_wrap_truncated(HILDON_BANNER(widget)); /* see N#27000 and G#329646 */
+
+ gtk_widget_size_request(widget, &req);
+
+ if (req.width == 0)
+ {
+ return;
+ }
+
+ x = gdk_screen_width() - HILDON_BANNER_WINDOW_X - req.width;
+ y = check_fullscreen_state(get_current_app_window()) ?
+ HILDON_BANNER_WINDOW_FULLSCREEN_Y : HILDON_BANNER_WINDOW_Y;
+
+ gtk_window_move(GTK_WINDOW(widget), x, y);
+}
+
+static void hildon_banner_realize(GtkWidget *widget)
+{
+ /* We let the parent to init widget->window before we need it */
+ if (GTK_WIDGET_CLASS(hildon_banner_parent_class)->realize)
+ GTK_WIDGET_CLASS(hildon_banner_parent_class)->realize(widget);
+
+ /* We use special hint to turn the banner into information notification. */
+ gdk_window_set_type_hint(widget->window, GDK_WINDOW_TYPE_HINT_MESSAGE);
+
+ hildon_banner_check_position(widget);
+}
+
+static void hildon_banner_class_init(HildonBannerClass *klass)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = G_OBJECT_CLASS(klass);
+ widget_class = GTK_WIDGET_CLASS(klass);
+
+ /* Append private structure to class. This is more elegant than
+ on g_new based approach */
+ g_type_class_add_private(klass, sizeof(HildonBannerPrivate));
+
+ /* Override virtual methods */
+ object_class->constructor = hildon_banner_constructor;
+ object_class->set_property = hildon_banner_set_property;
+ object_class->get_property = hildon_banner_get_property;
+ GTK_OBJECT_CLASS(klass)->destroy = hildon_banner_destroy;
+ widget_class->map_event = hildon_banner_map_event;
+ widget_class->realize = hildon_banner_realize;
+
+ /* Install properties.
+ We need construct properties for singleton purposes */
+ g_object_class_install_property(object_class, PROP_PARENT_WINDOW,
+ g_param_spec_object("parent-window",
+ "Parent window",
+ "The window for which the banner will be singleton",
+ GTK_TYPE_WINDOW, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property(object_class, PROP_IS_TIMED,
+ g_param_spec_boolean("is-timed",
+ "Is timed",
+ "Whether or not the notification goes away automatically "
+ "after the specified time has passed",
+ FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void hildon_banner_init(HildonBanner *self)
+{
+ HildonBannerPrivate *priv;
+
+ /* Make private data available through cached pointer */
+ self->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+ HILDON_TYPE_BANNER,
+ HildonBannerPrivate);
+
+ /* Initialize the common layout inside banner */
+ self->priv->layout = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
+
+ priv->label = g_object_new(GTK_TYPE_LABEL, NULL);
+ gtk_label_set_line_wrap(GTK_LABEL(priv->label), TRUE);
+
+ gtk_container_set_border_width(GTK_CONTAINER(self->priv->layout), HILDON_MARGIN_DEFAULT);
+ gtk_container_add(GTK_CONTAINER(self), self->priv->layout);
+ gtk_box_pack_start(GTK_BOX(self->priv->layout), priv->label, TRUE, TRUE, 0);
+
+ gtk_window_set_accept_focus(GTK_WINDOW(self), FALSE);
+}
+
+/* Makes sure that icon/progress item contains the desired type
+ of item. If possible, tries to avoid creating a new widget but
+ reuses the existing one */
+static void hildon_banner_ensure_child(HildonBanner *self,
+ GtkWidget *user_widget,
+ guint pos,
+ GType type,
+ const gchar *first_property, ...)
+{
+ GtkWidget *widget;
+ va_list args;
+
+ g_assert(HILDON_IS_BANNER(self));
+ g_assert(user_widget == NULL || GTK_IS_WIDGET(user_widget));
+
+ widget = self->priv->main_item;
+ va_start(args, first_property);
+
+ /* Reuse existing widget if possible */
+ if (!user_widget && G_TYPE_CHECK_INSTANCE_TYPE(widget, type))
+ {
+ g_object_set_valist(G_OBJECT(widget), first_property, args);
+ }
+ else
+ {
+ /* We have to abandon old content widget */
+ if (widget)
+ gtk_container_remove(GTK_CONTAINER(self->priv->layout), widget);
+
+ /* Use user provided widget or create a new one */
+ self->priv->main_item = widget = user_widget ?
+ user_widget : GTK_WIDGET(g_object_new_valist(type, first_property, args));
+ gtk_box_pack_start(GTK_BOX(self->priv->layout), widget, TRUE, TRUE, 0);
+ }
+
+ /* We make sure that the widget exists in desired position. Different
+ banners place this child widget to different places */
+ gtk_box_reorder_child(GTK_BOX(self->priv->layout), widget, pos);
+ va_end(args);
+}
+
+/* Creates a new banner instance or uses an existing one */
+static HildonBanner *hildon_banner_get_instance_for_widget(GtkWidget *widget, gboolean timed)
+{
+ GtkWidget *window;
+
+ g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
+ window = widget ? gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW) : NULL;
+ return g_object_new(HILDON_TYPE_BANNER, "parent-window", window, "is-timed", timed, NULL);
+}
+
+
+
+
+
+/* Public functions **************************************************************/
+
+/**
+ * hildon_banner_show_information:
+ * @widget: the #GtkWidget that wants to display banner
+ * @icon_name: the name of icon to use. Can be %NULL for default icon.
+ * @text: Text to display
+ *
+ * This function creates and displays an information banner that
+ * automatically goes away after certain time period. For each window
+ * in your application there can only be one timed banner, so if you
+ * spawn a new banner before the earlier one has timed out, the
+ * previous one will be replaced.
+ *
+ * Since: 0.12.2
+ */
+void hildon_banner_show_information(GtkWidget *widget,
+ const gchar *icon_name,
+ const gchar *text)
+{
+ HildonBanner *banner;
+
+ g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
+ g_return_if_fail(icon_name == NULL || icon_name[0] != 0);
+ g_return_if_fail(text != NULL);
+
+ /* Prepare banner */
+ banner = hildon_banner_get_instance_for_widget(widget, TRUE);
+ hildon_banner_ensure_child(banner, NULL, 0, GTK_TYPE_IMAGE,
+ "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
+ "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
+ "yalign", 0.0,
+ NULL);
+ hildon_banner_set_text(banner, text);
+ hildon_banner_bind_label_style(banner, NULL);
+
+ /* Show the banner, since caller cannot do that */
+ gtk_widget_show_all(GTK_WIDGET(banner));
+}
+
+/**
+ * hildon_banner_show_information_with_markup:
+ * @widget: the #GtkWidget that wants to display banner
+ * @icon_name: the name of icon to use. Can be %NULL for default icon.
+ * @markup: a markup string to display (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
+ *
+ * This function creates and displays an information banner that
+ * automatically goes away after certain time period. For each window
+ * in your application there can only be one timed banner, so if you
+ * spawn a new banner before the earlier one has timed out, the
+ * previous one will be replaced.
+ *
+ * Since: 0.12.8
+ */
+void hildon_banner_show_information_with_markup(GtkWidget *widget,
+ const gchar *icon_name, const gchar *markup)
+{
+ HildonBanner *banner;
+
+ g_return_if_fail(widget == NULL || GTK_IS_WIDGET(widget));
+ g_return_if_fail(icon_name == NULL || icon_name[0] != 0);
+ g_return_if_fail(markup != NULL);
+
+ /* Prepare banner */
+ banner = hildon_banner_get_instance_for_widget(widget, TRUE);
+
+ hildon_banner_ensure_child(banner, NULL, 0, GTK_TYPE_IMAGE,
+ "pixel-size", HILDON_ICON_PIXEL_SIZE_NOTE,
+ "icon-name", icon_name ? icon_name : HILDON_BANNER_DEFAULT_ICON,
+ "yalign", 0.0,
+ NULL);
+ hildon_banner_set_markup(banner, markup);
+ hildon_banner_bind_label_style(banner, NULL);
+
+ /* Show the banner, since caller cannot do that */
+ gtk_widget_show_all(GTK_WIDGET(banner));
+}
+
+/**
+ * hildon_banner_show_animation:
+ * @widget: the #GtkWidget that wants to display banner
+ * @animation_name: The progress animation to use. You usually can just
+ * pass %NULL for the default animation.
+ * @text: the text to display.
+ *
+ * Shows an animated progress notification. It's recommended not to try
+ * to show more than one progress notification at a time, since
+ * they will appear on top of each other. You can use progress
+ * notifications with timed banners. In this case the banners are
+ * located so that you can somehow see both.
+ *
+ * Please note that banners are destroyed automatically once the
+ * window they are attached to is closed. The pointer that you
+ * receive with this function do not contain additional references,
+ * so it can become invalid without warning (this is true for
+ * all toplevel windows in gtk). To make sure that the banner do not disapear
+ * automatically, you can separately ref the return value (this
+ * doesn't prevent the banner from disappearing, but the object it just
+ * not finalized). In this case you have to call both #gtk_widget_destroy
+ * followed by #g_object_unref (in this order).
+ *
+ * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
+ * once you are ready with the banner.
+ *
+ * Since: 0.12.2
+ */
+GtkWidget *hildon_banner_show_animation(GtkWidget *widget,
+ const gchar *animation_name, const gchar *text)
+{
+ HildonBanner *banner;
+ GtkIconTheme *theme;
+ GtkIconInfo *info;
+ GtkWidget *image_widget;
+ const gchar *filename;
+
+ g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
+ g_return_val_if_fail(animation_name == NULL || animation_name[0] != 0, NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+
+ /* Find out which animation to use */
+ theme = gtk_icon_theme_get_default();
+ info = gtk_icon_theme_lookup_icon(theme, animation_name ? /* TODO: consider using: gtk_icon_theme_load_icon() */
+ animation_name : HILDON_BANNER_DEFAULT_PROGRESS_ANIMATION,
+ HILDON_ICON_SIZE_NOTE, 0);
+
+ /* Try to load animation. One could try to optimize this
+ to avoid loading the default animation during each call */
+ if (info) {
+ filename = gtk_icon_info_get_filename(info);
+ image_widget = gtk_image_new_from_file(filename);
+ gtk_icon_info_free(info);
+ } else {
+ g_warning("icon theme lookup for icon failed!");
+ image_widget = NULL;
+ }
+
+ /* Prepare banner */
+ banner = hildon_banner_get_instance_for_widget(widget, FALSE);
+ hildon_banner_ensure_child(banner, image_widget, 0,
+ GTK_TYPE_IMAGE, "yalign", 0.0, NULL);
+ hildon_banner_set_text(banner, text);
+ hildon_banner_bind_label_style(banner, NULL);
+
+ /* And show it */
+ gtk_widget_show_all(GTK_WIDGET(banner));
+
+ return GTK_WIDGET(banner);
+}
+
+/**
+ * hildon_banner_show_progress:
+ * @widget: the #GtkWidget that wants to display banner
+ * @bar: Progressbar to use. You usually can just pass %NULL, unless
+ * you want somehow customized progress bar.
+ * @text: text to display.
+ *
+ * Shows progress notification. See #hildon_banner_show_animation
+ * for more information.
+ *
+ * Returns: a #HildonBanner widget. You must call #gtk_widget_destroy
+ * once you are ready with the banner.
+ *
+ * Since: 0.12.2
+ */
+GtkWidget *hildon_banner_show_progress(GtkWidget *widget,
+ GtkProgressBar *bar, const gchar *text)
+{
+ HildonBanner *banner;
+
+ g_return_val_if_fail(widget == NULL || GTK_IS_WIDGET(widget), NULL);
+ g_return_val_if_fail(bar == NULL || GTK_IS_PROGRESS_BAR(bar), NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+
+ /* Prepare banner */
+ banner = hildon_banner_get_instance_for_widget(widget, FALSE);
+ hildon_banner_ensure_child(banner, (GtkWidget *) bar, -1, GTK_TYPE_PROGRESS_BAR, NULL);
+ gtk_widget_set_size_request(banner->priv->main_item,
+ HILDON_BANNER_PROGRESS_WIDTH, -1);
+ hildon_banner_set_text(banner, text);
+ hildon_banner_bind_label_style(banner, NULL);
+
+ /* Show the banner */
+ gtk_widget_show_all(GTK_WIDGET(banner));
+
+ return GTK_WIDGET(banner);
+}
+
+/**
+ * hildon_banner_set_text:
+ * @self: a #HildonBanner widget
+ * @text: a new text to display in banner
+ *
+ * Sets the text that is displayed in the banner.
+ *
+ * Since: 0.12.2
+ */
+void hildon_banner_set_text(HildonBanner *self, const gchar *text)
+{
+ GtkLabel *label;
+
+ g_return_if_fail(HILDON_IS_BANNER(self));
+
+ label = GTK_LABEL(self->priv->label);
+ gtk_label_set_text(label, text);
+
+ hildon_banner_check_position(GTK_WIDGET(self));
+}
+
+/**
+ * hildon_banner_set_markup:
+ * @self: a #HildonBanner widget
+ * @markup: a new text with Pango markup to display in the banner
+ *
+ * Sets the text with markup that is displayed in the banner.
+ *
+ * Since: 0.12.8
+ */
+void hildon_banner_set_markup(HildonBanner *self, const gchar *markup)
+{
+ GtkLabel *label;
+
+ g_return_if_fail(HILDON_IS_BANNER(self));
+
+ label = GTK_LABEL(self->priv->label);
+ gtk_label_set_markup(label, markup);
+
+ hildon_banner_check_position(GTK_WIDGET(self));
+}
+
+/**
+ * hildon_banner_set_fraction:
+ * @self: a #HildonBanner widget
+ * @fraction: #gdouble
+ *
+ * The fraction is the completion of progressbar,
+ * the scale is from 0.0 to 1.0.
+ * Sets the amount of fraction the progressbar has.
+ *
+ * Since: 0.12.2
+ */
+void hildon_banner_set_fraction(HildonBanner *self, gdouble fraction)
+{
+ g_return_if_fail(HILDON_IS_BANNER(self));
+ g_return_if_fail(GTK_IS_PROGRESS_BAR(self->priv->main_item));
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(self->priv->main_item), fraction);
+}
+
+
+
+
+
+/**
+ * Deprecated: really, do NOT use.
+ */
+void _hildon_gtk_label_set_text_n_lines(GtkLabel *label, const gchar *text, gint max_lines)
+{
+/* Forces the wrapping of text into several lines and ellipsizes the rest.
+ Similar to combination of gtk_label_set_wrap and pango ellipzation.
+ We cannot just use those directly, since ellipzation always wins wrapping.
+
+ This means that we have to:
+ * First wrap the text
+ * Insert forced linebreaks into text
+ * Truncate the result
+
+ NOTE! This will not work with pango markup!
+
+ FIXME: luc: DO NOT TRUNCATE the text. Use as many lines as needed.
+ Lenth of the text is under applications' responsibility.
+ Widget does not have to enforce this.
+*/
+ PangoLayout *layout;
+ PangoLayoutLine *line;
+ GtkRequisition req;
+ GString *wrapped_text;
+ gchar *line_data;
+ gint lines, i;
+
+ g_return_if_fail(GTK_IS_LABEL(label));
+ g_return_if_fail(max_lines >= 1);
+
+ /* Setup the label to contain the new data */
+ gtk_label_set_text(label, text);
+ gtk_label_set_line_wrap(label, TRUE);
+ gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_NONE);
+
+ /* We really want to recalculate the size, not use some old values */
+ gtk_widget_size_request(GTK_WIDGET(label), &req);
+ layout = gtk_label_get_layout(label);
+ lines = pango_layout_get_line_count(layout);
+
+ /* Now collect the wrapped text. */
+ wrapped_text = g_string_new(NULL);
+
+ for (i = 0; i < lines; i++)
+ {
+ /* Append the next line into wrapping buffer, but
+ avoid adding extra whitespaces at the end, since those
+ can cause other lines to be ellipsized as well. */
+ line = pango_layout_get_line(layout, i);
+ line_data = g_strndup(pango_layout_get_text(layout) + line->start_index,
+ line->length);
+ g_strchomp(line_data);
+ g_string_append(wrapped_text, line_data);
+
+ /* Append forced linebreaks, until we have the desired
+ amount of lines. After that we put the rest to the
+ last line to make ellipzation to happen */
+ if (i < lines - 1)
+ {
+ if (i < max_lines - 1)
+ g_string_append_c(wrapped_text, '\n');
+ else
+ g_string_append_c(wrapped_text, ' ');
+ }
+
+ g_free(line_data);
+ }
+
+ /* Now update the label to use wrapped text. Use builtin
+ ellipzation as well. */
+ gtk_widget_set_size_request(GTK_WIDGET(label), req.width, -1);
+ gtk_label_set_text(label, wrapped_text->str);
+ gtk_label_set_ellipsize(label, PANGO_ELLIPSIZE_END);
+ gtk_label_set_line_wrap(label, FALSE);
+
+ g_string_free(wrapped_text, TRUE);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_BANNER_H__
+#define __HILDON_BANNER_H__
+
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtklabel.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_BANNER (hildon_banner_get_type())
+
+#define HILDON_BANNER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), HILDON_TYPE_BANNER, HildonBanner))
+#define HILDON_IS_BANNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), HILDON_TYPE_BANNER))
+
+typedef struct _HildonBanner HildonBanner;
+typedef struct _HildonBannerClass HildonBannerClass;
+typedef struct _HildonBannerPrivate HildonBannerPrivate;
+
+struct _HildonBanner
+{
+ GtkWindow parent;
+ HildonBannerPrivate *priv;
+};
+
+struct _HildonBannerClass
+{
+ GtkWindowClass parent_class;
+};
+
+GType hildon_banner_get_type (void) G_GNUC_CONST;
+
+void hildon_banner_show_information (GtkWidget *widget,
+ const gchar *icon_name,
+ const gchar *text);
+
+void hildon_banner_show_information_with_markup (GtkWidget *widget,
+ const gchar *icon_name,
+ const gchar *markup);
+
+GtkWidget *hildon_banner_show_animation (GtkWidget *widget,
+ const gchar *animation_name,
+ const gchar *text);
+
+GtkWidget *hildon_banner_show_progress (GtkWidget *widget,
+ GtkProgressBar *bar,
+ const gchar *text);
+
+void hildon_banner_set_text (HildonBanner *self,
+ const gchar *text);
+
+void hildon_banner_set_markup (HildonBanner *self,
+ const gchar *markup);
+
+void hildon_banner_set_fraction (HildonBanner *self,
+ gdouble fraction);
+
+
+
+/* For internal use of hildon libraries only */
+void _hildon_gtk_label_set_text_n_lines(GtkLabel *label, const gchar *text, gint max_lines);
+
+G_END_DECLS
+
+#endif /* __HILDON_BANNER_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-calendar-popup
+ * @shortdesc: CalendarPopup allows choosing a date from a popup calendar.
+ * @longdesc: The Calendar popup is a dialog that contains a GtkCalendar
+ * widget. The pop-up is cancelled by pressing the ESC key.
+ * </para><para>
+ *
+ * @seealso: #HildonDateEditor, #HildonTimeEditor
+ *
+ * HildonCalendarPopup is a dialog which contains a GtkCalendar. It
+ * also contains arrow buttons for changing the month/year. If an
+ * entered date is invalid, an information message will be shown.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <gtk/gtkcalendar.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <langinfo.h>
+#include <time.h>
+#include <libintl.h>
+#include <hildon-widgets/hildon-calendar-popup.h>
+
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_CALENDAR_POPUP_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE\
+ ((obj), HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopupPrivate));
+
+static GtkDialog *parent_class;
+
+typedef struct _HildonCalendarPopupPrivate HildonCalendarPopupPrivate;
+
+static void init_dmy(guint year, guint month, guint day, guint * d,
+ guint * m, guint * y);
+
+static void
+hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class);
+
+static void hildon_calendar_popup_init(HildonCalendarPopup * cal);
+
+static void hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup);
+
+static gboolean hildon_key_pressed(GtkWidget * widget, GdkEventKey * event,
+ gpointer cal_popup);
+
+static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+
+enum {
+ PROP_0,
+ PROP_DAY,
+ PROP_MONTH,
+ PROP_YEAR,
+ PROP_MIN_YEAR,
+ PROP_MAX_YEAR
+};
+
+struct _HildonCalendarPopupPrivate {
+ GtkWidget *cal;
+};
+
+GType hildon_calendar_popup_get_type(void)
+{
+ static GType popup_type = 0;
+
+ if (!popup_type) {
+ static const GTypeInfo popup_info = {
+ sizeof(HildonCalendarPopupClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_calendar_popup_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonCalendarPopup),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_calendar_popup_init,
+ };
+ popup_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonCalendarPopup",
+ &popup_info, 0);
+ }
+
+ return popup_type;
+}
+
+/**
+ * hildon_calendar_popup_new:
+ * @parent: parent window for dialog
+ * @year: initial year
+ * @month: initial month
+ * @day: initial day
+ *
+ * This function returns a new HildonCalendarPopup. The initially
+ * selected date is specified by the parameters (year, month, day).
+ * If the specified date is invalid, the current date is used.
+ *
+ * Returns: new @HildonCalendarPopup widget
+ */
+GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
+ guint month, guint day)
+{
+ HildonCalendarPopup *cal = NULL;
+
+ /* Create new HildonCalendarPopup */
+ cal = HILDON_CALENDAR_POPUP(g_object_new(HILDON_TYPE_CALENDAR_POPUP,
+ "year", year, "month", month, "day", day,
+ NULL));
+
+ if (parent) {
+ gtk_window_set_transient_for(GTK_WINDOW(cal), parent);
+ }
+
+ return GTK_WIDGET(cal);
+}
+
+/**
+ * hildon_calendar_popup_set_date:
+ * @cal: the @HildonCalendarPopup widget
+ * @year: year
+ * @month: month
+ * @day: day
+ *
+ * activates a new date on the calendar popup.
+ **/
+void
+hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
+ guint year, guint month, guint day)
+{
+ guint dtmp, mtmp, ytmp = 0;
+ HildonCalendarPopupPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
+
+ priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+
+ /* Choose current date if the date is invalid:
+ */
+ init_dmy(year, month, day, &dtmp, &mtmp, &ytmp);
+
+ /* Remove all visual markers */
+ gtk_calendar_clear_marks(GTK_CALENDAR(priv->cal));
+
+ /* Set a new date */
+ gtk_calendar_select_month(GTK_CALENDAR(priv->cal), mtmp - 1, ytmp);
+ gtk_calendar_select_day(GTK_CALENDAR(priv->cal), dtmp);
+}
+
+/**
+ * hildon_calendar_popup_get_date:
+ * @cal: the @HildonCalendarPopup widget
+ * @year: year
+ * @month: month
+ * @day: day
+ *
+ * Gets the currently selected year, month, and day.
+ */
+void
+hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
+ guint * year, guint * month, guint * day)
+{
+ HildonCalendarPopupPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_CALENDAR_POPUP(cal));
+
+ priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+ gtk_calendar_get_date(GTK_CALENDAR(priv->cal), year, month, day);
+ *month = *month + 1;
+
+ if (!g_date_valid_dmy(*day, *month, *year)) {
+ *day = g_date_get_days_in_month(*month, *year);
+ }
+}
+
+static void
+hildon_calendar_popup_class_init(HildonCalendarPopupClass * cal_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(cal_class);
+ parent_class = g_type_class_peek_parent(cal_class);
+
+ object_class->set_property = hildon_calendar_popup_set_property;
+ object_class->get_property = hildon_calendar_popup_get_property;
+
+ g_type_class_add_private(cal_class,
+ sizeof(HildonCalendarPopupPrivate));
+
+ /* Install new properties for the GObject_class */
+ g_object_class_install_property(object_class, PROP_MIN_YEAR,
+ g_param_spec_uint("min-year",
+ "Minimum valid year",
+ "Minimum valid year",
+ 1, 2100,
+ 1970,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property(object_class, PROP_MAX_YEAR,
+ g_param_spec_uint("max-year",
+ "Maximum valid year",
+ "Maximum valid year",
+ 1, 2100,
+ 2037,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property(object_class, PROP_DAY,
+ g_param_spec_int ("day",
+ "Day",
+ "currently selected day",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_MONTH,
+ g_param_spec_int ("month",
+ "Month",
+ "currently selected month",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_YEAR,
+ g_param_spec_int ("year",
+ "Year",
+ "the currently selected year",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+}
+
+static void hildon_calendar_popup_init(HildonCalendarPopup * cal)
+{
+ HildonCalendarPopupPrivate *priv;
+ static int set_domain = 1;
+
+ priv = HILDON_CALENDAR_POPUP_GET_PRIVATE(cal);
+
+ /* set the domain directory for different language */
+ if (set_domain) {
+ (void) bindtextdomain(PACKAGE, LOCALEDIR);
+ set_domain = 0;
+ }
+
+ priv->cal = gtk_calendar_new();
+
+ /* dialog options and packing */
+ gtk_calendar_set_display_options(GTK_CALENDAR(priv->cal),
+ GTK_CALENDAR_SHOW_HEADING |
+ GTK_CALENDAR_SHOW_DAY_NAMES |
+ GTK_CALENDAR_SHOW_WEEK_NUMBERS);
+
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cal)->vbox), priv->cal,
+ TRUE, TRUE, 0);
+ gtk_dialog_set_has_separator(GTK_DIALOG(cal), FALSE);
+ gtk_dialog_add_button(GTK_DIALOG(cal), _("ecdg_bd_calendar_popout_done"),
+ GTK_RESPONSE_OK);
+ gtk_widget_show(priv->cal);
+
+ /* Connect signals */
+ g_signal_connect(G_OBJECT(priv->cal), "key-press-event",
+ G_CALLBACK(hildon_key_pressed), cal);
+
+ g_signal_connect(G_OBJECT(priv->cal), "selected_date",
+ G_CALLBACK(hildon_calendar_selected_date), cal);
+
+ /* set decorations, needs realizing first*/
+ gtk_widget_realize(GTK_WIDGET(cal));
+ gdk_window_set_decorations(GTK_WIDGET(cal)->window, GDK_DECOR_BORDER);
+
+}
+
+
+/*
+ * Signal handler for key-press-event. Closes the dialog for some
+ * special keys.
+ */
+static gboolean
+hildon_key_pressed(GtkWidget * widget, GdkEventKey * event, gpointer cal_popup)
+{
+ g_assert(HILDON_IS_CALENDAR_POPUP(cal_popup));
+
+ /* Handle Return key press as OK response */
+ if (event->keyval == GDK_Return)
+ {
+ gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
+ return TRUE;
+ }
+
+ /* Handle Esc key press as CANCEL response */
+ if ((event->keyval == GDK_Escape))
+ {
+ gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_CANCEL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Validates the given date or initializes it with the current date
+ */
+static void
+init_dmy(guint year, guint month, guint day, guint *d, guint *m, guint *y)
+{
+ GDate date;
+
+ /* Initialize the date with a valid selected date */
+ if (g_date_valid_dmy(day, month, year)) {
+ *d = day;
+ *m = month;
+ *y = year;
+ } else {
+
+ /* If selected date is invalid initialize the date with current date */
+ g_date_clear(&date, 1);
+ g_date_set_time(&date, time(NULL));
+
+ *d = g_date_get_day(&date);
+ *m = g_date_get_month(&date);
+ *y = g_date_get_year(&date);
+ }
+}
+
+/*
+ * Exits the dialog when "selected_date" signal is emmited. The
+ * "selected_date" signal is a Hildon addition to GtkCalendar and is
+ * emitted on button-release.
+ */
+static void
+hildon_calendar_selected_date(GtkWidget * self, gpointer cal_popup)
+{
+ g_assert(GTK_IS_WIDGET (self));
+ g_assert(HILDON_IS_CALENDAR_POPUP (cal_popup));
+
+ gtk_dialog_response(GTK_DIALOG(cal_popup), GTK_RESPONSE_OK);
+}
+
+
+static void hildon_calendar_popup_set_property(GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonCalendarPopup *popup = HILDON_CALENDAR_POPUP (object);
+ HildonCalendarPopupPrivate *priv =
+ HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
+
+ switch (property_id) {
+ case PROP_DAY:
+ {
+ guint year, month, day = 0;
+ hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+ /*Verifies that the date is valid: */
+ hildon_calendar_popup_set_date(popup, year, month, g_value_get_int(value));
+ break;
+ }
+ case PROP_MONTH:
+ {
+ guint year, month, day = 0;
+ hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+ /*Verifies that the date is valid: */
+ hildon_calendar_popup_set_date(popup, year, g_value_get_int(value), day);
+ break;
+ }
+ case PROP_YEAR:
+ {
+ guint year, month, day = 0;
+ hildon_calendar_popup_get_date(popup, &year, &month, &day);
+
+ /*Verifies that the date is valid: */
+ hildon_calendar_popup_set_date(popup, g_value_get_int(value), month, day);
+ break;
+ }
+ case PROP_MIN_YEAR:
+ g_object_set_property(G_OBJECT(priv->cal), "min-year", value);
+ break;
+ case PROP_MAX_YEAR:
+ g_object_set_property(G_OBJECT(priv->cal), "max-year", value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void hildon_calendar_popup_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonCalendarPopupPrivate *priv =
+ HILDON_CALENDAR_POPUP_GET_PRIVATE(HILDON_CALENDAR_POPUP (object));
+
+ switch (property_id) {
+ case PROP_DAY:
+ g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+ break;
+ case PROP_MONTH:
+ g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+ break;
+ case PROP_YEAR:
+ g_object_get_property(G_OBJECT(priv->cal), pspec->name, value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_CALENDAR_POPUP_H__
+#define __HILDON_CALENDAR_POPUP_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+/**
+ * HILDON_TYPE_CALENDAR_POPUP:
+ *
+ * Macro for getting type of calendar popup.
+ * Since: 0.12.10
+ */
+#define HILDON_TYPE_CALENDAR_POPUP ( hildon_calendar_popup_get_type() )
+
+/**
+ * HILDON_CALENDAR_POPUP_TYPE:
+ *
+ * Deprecated: use #HILDON_TYPE_CALENDAR_POPUP instead
+ */
+#define HILDON_CALENDAR_POPUP_TYPE HILDON_TYPE_CALENDAR_POPUP
+
+#define HILDON_CALENDAR_POPUP(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopup))
+#define HILDON_CALENDAR_POPUP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_CALENDAR_POPUP, HildonCalendarPopupClass))
+#define HILDON_IS_CALENDAR_POPUP(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_CALENDAR_POPUP))
+#define HILDON_IS_CALENDAR_POPUP_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CALENDAR_POPUP))
+
+/**
+ * HildonCalendarPopup:
+ *
+ * Internal struct for calendar popup.
+ */
+typedef struct _HildonCalendarPopup HildonCalendarPopup;
+typedef struct _HildonCalendarPopupClass HildonCalendarPopupClass;
+
+/* Note: CalendarPopup is no longer derived from GtkWindow
+ but from GtkDialog */
+
+struct _HildonCalendarPopup {
+ GtkDialog par;
+};
+
+struct _HildonCalendarPopupClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_calendar_popup_get_type(void) G_GNUC_CONST;
+
+GtkWidget *hildon_calendar_popup_new(GtkWindow * parent, guint year,
+ guint month, guint day);
+
+void hildon_calendar_popup_set_date(HildonCalendarPopup * cal,
+ guint year, guint month, guint day);
+
+void hildon_calendar_popup_get_date(HildonCalendarPopup * cal,
+ guint * year, guint * month,
+ guint * day);
+
+G_END_DECLS
+#endif /* __HILDON_CALENDAR_POPUP_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-caption
+ * @short_description: A single-child container widget that precedes the
+ * contained widget with a field label and an optional icon
+ *
+ * #HildonCaption is a single-child container widget that precedes the
+ * contained widget with a field label and an optional icon. It allows
+ * grouping of several controls together. When a captioned widget has focus,
+ * both widget and caption label are displayed with active focus.
+ */
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkcombo.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkcomboboxentry.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmarshal.h>
+#include <gtk/gtkalignment.h>
+#include <stdio.h>
+#include <string.h>
+#include "hildon-caption.h"
+#include "hildon-defines.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_CAPTION_SPACING 6
+
+#define HILDON_CAPTION_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_CAPTION, HildonCaptionPrivate));
+
+/*our parent class*/
+static GtkEventBox *parent_class = NULL;
+
+typedef struct _HildonCaptionPrivate HildonCaptionPrivate;
+
+enum
+{
+ PROP_NONE,
+ PROP_LABEL,
+ PROP_ICON,
+ PROP_STATUS,
+ PROP_SEPARATOR,
+ PROP_SIZE_GROUP,
+ PROP_ICON_POSITION,
+};
+
+enum
+{
+ CHILD_PROP_NONE,
+ CHILD_PROP_EXPAND
+};
+
+static void hildon_caption_class_init ( HildonCaptionClass *caption_class );
+static void hildon_caption_init ( HildonCaption *caption );
+static void hildon_caption_size_request ( GtkWidget *widget, GtkRequisition *requisition );
+static void hildon_caption_size_allocate( GtkWidget *widget, GtkAllocation *allocation );
+
+static void hildon_caption_forall( GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer data );
+static void hildon_caption_hierarchy_changed( GtkWidget *widget,
+ GtkWidget *previous_toplevel);
+static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
+ GtkWidget *caption );
+static void hildon_caption_activate( GtkWidget *widget );
+
+static void hildon_caption_set_property( GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec );
+static void hildon_caption_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec );
+static gboolean hildon_caption_expose( GtkWidget *widget,
+ GdkEventExpose *event );
+static void hildon_caption_destroy( GtkObject *self );
+static gboolean hildon_caption_button_press( GtkWidget *widget, GdkEventButton *event );
+
+static void
+hildon_caption_set_label_text( HildonCaptionPrivate *priv );
+
+static void hildon_caption_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void hildon_caption_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+struct _HildonCaptionPrivate
+{
+ GtkWidget *caption_area;
+ GtkWidget *label;
+ GtkWidget *icon;
+ GtkWidget *icon_align; /* Arbitrary icon widgets do not support alignment */
+ GtkSizeGroup *group;
+ gchar *text;
+ gchar *separator;
+ guint is_focused : 1;
+ guint expand : 1;
+ HildonCaptionStatus status;
+ HildonCaptionIconPosition icon_position;
+};
+
+/* Register optional/mandatory type enumeration */
+/* FIXME: mandatory icon was removed. The mandatory/optional logic
+ remains, it should most probably be removed as well. This imply APi
+ change, especially hildon_caption_new() */
+GType
+hildon_caption_status_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { HILDON_CAPTION_OPTIONAL, "HILDON_CAPTION_OPTIONAL", "optional" },
+ { HILDON_CAPTION_MANDATORY, "HILDON_CAPTION_MANDATORY", "mandatory" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("HildonCaptionStatus", values);
+ }
+ return etype;
+}
+
+GType
+hildon_caption_icon_position_get_type (void)
+{
+ static GType etype = 0;
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { HILDON_CAPTION_POSITION_LEFT, "HILDON_CAPTION_POSITION_LEFT", "left" },
+ { HILDON_CAPTION_POSITION_RIGHT, "HILDON_CAPTION_POSITION_RIGHT", "right" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static ("HildonCaptionIconPosition", values);
+ }
+ return etype;
+}
+
+/**
+ * hildon_caption_get_type:
+ *
+ * Initialises, and returns the type of a hildon caption.
+ *
+ * @Returns: GType of #HildonCaption
+ */
+GType hildon_caption_get_type (void)
+{
+ static GType caption_type = 0;
+
+ if (!caption_type)
+ {
+ static const GTypeInfo caption_info = {
+ sizeof(HildonCaptionClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_caption_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonCaption),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_caption_init,
+ };
+ caption_type = g_type_register_static( GTK_TYPE_EVENT_BOX,
+ "HildonCaption", &caption_info, 0 );
+ }
+ return caption_type;
+}
+
+/*
+ * Initialises the caption class.
+ */
+static void hildon_caption_class_init( HildonCaptionClass *caption_class )
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(caption_class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS(caption_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(caption_class);
+
+ parent_class = g_type_class_peek_parent( caption_class );
+
+ g_type_class_add_private( caption_class, sizeof(HildonCaptionPrivate) );
+
+ /* Override virtual functions */
+ gobject_class->get_property = hildon_caption_get_property;
+ gobject_class->set_property = hildon_caption_set_property;
+
+ caption_class->activate = hildon_caption_activate;
+
+ GTK_OBJECT_CLASS(caption_class)->destroy = hildon_caption_destroy;
+
+ container_class->forall = hildon_caption_forall;
+ container_class->set_child_property = hildon_caption_set_child_property;
+ container_class->get_child_property = hildon_caption_get_child_property;
+
+ widget_class->expose_event = hildon_caption_expose;
+ widget_class->hierarchy_changed = hildon_caption_hierarchy_changed;
+ widget_class->size_request = hildon_caption_size_request;
+ widget_class->size_allocate = hildon_caption_size_allocate;
+ widget_class->button_press_event = hildon_caption_button_press;
+
+ /* Create new signals and properties */
+ widget_class->activate_signal = g_signal_new( "activate",
+ G_OBJECT_CLASS_TYPE(
+ gobject_class),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET( HildonCaptionClass,
+ activate), NULL, NULL,
+ gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * HildonCaption:label:
+ *
+ * Caption label.
+ */
+ g_object_class_install_property( gobject_class, PROP_LABEL,
+ g_param_spec_string("label",
+ "Current label", "Caption label",
+ NULL, G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonCaption:icon:
+ *
+ * The icon shown on the caption area.
+ */
+ g_object_class_install_property( gobject_class, PROP_ICON,
+ g_param_spec_object("icon",
+ "Current icon",
+ "The icon shown on the caption area",
+ GTK_TYPE_WIDGET, G_PARAM_READABLE |
+ G_PARAM_WRITABLE) );
+ /**
+ * HildonCaption:status:
+ *
+ * Mandatory or optional status.
+ */
+ g_object_class_install_property( gobject_class, PROP_STATUS,
+ g_param_spec_enum("status",
+ "Current status",
+ "Mandatory or optional status",
+ HILDON_TYPE_CAPTION_STATUS,
+ HILDON_CAPTION_OPTIONAL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+ /**
+ * HildonCaption:icon-position:
+ *
+ * If the icon is positioned on the left or right side.
+ *
+ * Since: 0.14.5
+ */
+ g_object_class_install_property( gobject_class, PROP_ICON_POSITION,
+ g_param_spec_enum("icon-position",
+ "Icon position",
+ "If the icon is on the left or right side",
+ HILDON_TYPE_CAPTION_ICON_POSITION,
+ HILDON_CAPTION_POSITION_RIGHT,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonCaption:size_group:
+ *
+ * Current size group the caption is in.
+ */
+ g_object_class_install_property( gobject_class, PROP_SIZE_GROUP,
+ g_param_spec_object("size_group",
+ "Current size group",
+ "Current size group the caption is in",
+ GTK_TYPE_SIZE_GROUP, G_PARAM_READABLE |
+ G_PARAM_WRITABLE) );
+
+ /**
+ * HildonCaption:separator:
+ *
+ * The current separator.
+ */
+ g_object_class_install_property( gobject_class, PROP_SEPARATOR,
+ g_param_spec_string("separator",
+ "Current separator", "Current separator",
+ _("ecdg_ti_caption_separator"),
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /* Create child properties. These are related to
+ child <-> parent relationship, not to either of objects itself */
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_EXPAND,
+ g_param_spec_boolean ("expand",
+ "Same as GtkBox expand.",
+ "Same as GtkBox expand. Wheter the child should be expanded or not.",
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+/* Destroy can be called multiple times, remember to set pointers to NULL */
+static void hildon_caption_destroy( GtkObject *self )
+{
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(self);
+
+ /* Free our internal child */
+ if( priv->caption_area )
+ {
+ gtk_widget_unparent( priv->caption_area );
+ priv->caption_area = NULL;
+ }
+
+ /* Free user provided strings */
+ if( priv->text )
+ {
+ g_free( priv->text );
+ priv->text = NULL;
+ }
+ if( priv->separator )
+ {
+ g_free( priv->separator );
+ priv->separator = NULL;
+ }
+
+ /* Parent classes destroy takes care of user packed contents */
+ if( GTK_OBJECT_CLASS(parent_class)->destroy )
+ GTK_OBJECT_CLASS(parent_class)->destroy( self );
+}
+
+/* Parent, eventbox will run allocate also for the child which may be
+ * owning a window too. This window is then moved and resized
+ * and we do not want to do that (it causes flickering).
+ */
+static gboolean hildon_caption_expose( GtkWidget *widget,
+ GdkEventExpose *event )
+{
+ HildonCaptionPrivate *priv = NULL;
+ GtkRequisition req;
+ GtkAllocation alloc;
+ gfloat align;
+
+ g_assert( HILDON_IS_CAPTION(widget) );
+ priv = HILDON_CAPTION_GET_PRIVATE(widget);
+
+ if( !GTK_WIDGET_DRAWABLE(widget) )
+ return FALSE;
+
+ GTK_WIDGET_CLASS(parent_class)->expose_event( widget, event );
+
+ /* If our child control is focused, we draw nice looking focus
+ graphics for the caption */
+ if ( priv->is_focused && priv->text )
+ {
+ /* Determine focus box dimensions */
+ gtk_widget_get_child_requisition( priv->caption_area, &req );
+ align = hildon_caption_get_label_alignment(HILDON_CAPTION(widget));
+
+ alloc.width = priv->caption_area->allocation.width + HILDON_CAPTION_SPACING;
+ alloc.height = MIN (req.height + (2 * widget->style->ythickness), priv->caption_area->allocation.height);
+
+ alloc.x = priv->caption_area->allocation.x - HILDON_CAPTION_SPACING; /* - left margin */
+ alloc.y = priv->caption_area->allocation.y +
+ MAX(((priv->caption_area->allocation.height - alloc.height) * align), 0);
+
+ /* Paint the focus box */
+ gtk_paint_box( widget->style, widget->window, GTK_STATE_ACTIVE,
+ GTK_SHADOW_OUT, NULL, widget, "selection",
+ alloc.x, alloc.y, alloc.width, alloc.height );
+
+ /* Paint caption contents on top of the focus box */
+ GTK_WIDGET_GET_CLASS(priv->caption_area)->expose_event(
+ priv->caption_area, event);
+ }
+
+ return FALSE;
+}
+
+static void hildon_caption_set_property( GObject *object, guint param_id,
+ const GValue *value,
+ GParamSpec *pspec )
+{
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
+
+ switch( param_id )
+ {
+ case PROP_ICON_POSITION:
+
+ hildon_caption_set_icon_position (HILDON_CAPTION (object),
+ g_value_get_enum (value));
+
+ break;
+
+ case PROP_LABEL:
+ /* Free old label string */
+ if( priv->text )
+ {
+ g_free( priv->text );
+ priv->text = NULL;
+ }
+
+ /* Update label */
+ priv->text = g_value_dup_string(value);
+ hildon_caption_set_label_text( priv );
+ break;
+
+ case PROP_ICON:
+ /* Remove old icon */
+ if( priv->icon )
+ gtk_container_remove( GTK_CONTAINER(priv->icon_align), priv->icon );
+
+ /* Pack and display new icon */
+ priv->icon = g_value_get_object( value );
+ if( priv->icon )
+ {
+ gtk_container_add(GTK_CONTAINER(priv->icon_align), priv->icon);
+ gtk_widget_show_all( priv->caption_area );
+ }
+ break;
+
+ case PROP_STATUS:
+ priv->status = g_value_get_enum( value );
+ break;
+
+ case PROP_SIZE_GROUP:
+ /* Detach from previous size group */
+ if( priv->group )
+ gtk_size_group_remove_widget( priv->group, priv->caption_area );
+
+ priv->group = g_value_get_object( value );
+
+ /* Attach to new size group */
+ if( priv->group )
+ gtk_size_group_add_widget( priv->group, priv->caption_area );
+ gtk_widget_queue_draw( GTK_WIDGET(object) );
+ break;
+
+ case PROP_SEPARATOR:
+
+ /* Free old separator */
+ if( priv->separator )
+ {
+ g_free( priv->separator );
+ priv->separator = NULL;
+ }
+
+ priv->separator = g_value_dup_string(value);
+ hildon_caption_set_label_text( priv );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_caption_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec )
+{
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(object);
+
+ switch (param_id)
+ {
+ case PROP_LABEL:
+ g_value_set_string( value, priv->text );
+ break;
+ case PROP_ICON:
+ g_value_set_object( value, priv->icon );
+ break;
+ case PROP_STATUS:
+ g_value_set_enum( value, priv->status );
+ break;
+ case PROP_ICON_POSITION:
+ g_value_set_enum( value, priv->icon_position);
+ break;
+ case PROP_SIZE_GROUP:
+ g_value_set_object( value, priv->group );
+ break;
+ case PROP_SEPARATOR:
+ g_value_set_string( value, priv->separator );
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_caption_set_child_property( GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec )
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_EXPAND:
+ hildon_caption_set_child_expand( HILDON_CAPTION(container),
+ g_value_get_boolean(value) );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
+ break;
+ }
+}
+
+static void hildon_caption_get_child_property( GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec )
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_EXPAND:
+ g_value_set_boolean( value, hildon_caption_get_child_expand(
+ HILDON_CAPTION(container)) );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(container, property_id, pspec);
+ break;
+ }
+}
+
+/* We want to activate out child control on button press */
+static gboolean hildon_caption_button_press( GtkWidget *widget,
+ GdkEventButton *event )
+{
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(widget);
+ GtkWidget *child = GTK_BIN(widget)->child;
+
+ /* nothing to do */
+ if (priv->is_focused == TRUE)
+ return;
+
+ /* If child can take focus, we simply grab focus to it */
+ if ((GTK_WIDGET_CAN_FOCUS(child) || GTK_IS_CONTAINER(child)) &&
+ GTK_WIDGET_IS_SENSITIVE(child))
+ {
+ /* Only if container can be focusable we must set is_focused to TRUE */
+ if (GTK_IS_CONTAINER(child))
+ {
+ if (gtk_widget_child_focus (child,
+ GTK_DIR_TAB_FORWARD))
+ priv->is_focused = TRUE;
+ }
+ else
+ {
+ priv->is_focused = TRUE;
+ gtk_widget_grab_focus (GTK_BIN (widget)->child);
+ }
+ }
+
+ return FALSE;
+}
+
+static void hildon_caption_init( HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv = NULL;
+
+ /* Initialize startup state */
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+ priv->status = HILDON_CAPTION_OPTIONAL;
+ priv->icon = NULL;
+ priv->group = NULL;
+ priv->is_focused = FALSE;
+ priv->text = NULL;
+
+ priv->separator = g_strdup(_("ecdg_ti_caption_separator"));
+
+ gtk_widget_push_composite_child();
+
+ /* Create caption text */
+ priv->caption_area = gtk_hbox_new( FALSE, HILDON_CAPTION_SPACING );
+ priv->label = gtk_label_new( NULL );
+ priv->icon_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
+ priv->icon_position = HILDON_CAPTION_POSITION_RIGHT;
+
+ /* We want to receive button presses for child widget activation */
+ gtk_event_box_set_above_child( GTK_EVENT_BOX(caption), FALSE );
+ gtk_widget_add_events( GTK_WIDGET(caption), GDK_BUTTON_PRESS_MASK );
+
+ /* Pack text label caption layout */
+ gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->icon_align, FALSE, FALSE, 0);
+ gtk_box_pack_end( GTK_BOX(priv->caption_area), priv->label, FALSE, FALSE, 0 );
+ gtk_widget_set_parent( priv->caption_area, GTK_WIDGET(caption) );
+
+
+ gtk_widget_pop_composite_child();
+
+ hildon_caption_set_child_expand( caption, TRUE );
+
+ gtk_widget_show_all( priv->caption_area );
+}
+
+static void hildon_caption_set_focus( GtkWindow *window, GtkWidget *widget,
+ GtkWidget *caption )
+{
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ /* check if ancestor gone */
+ if (!widget)
+ {
+ return;
+ }
+
+ /* Try to find caption among the ancestors of widget */
+ if (gtk_widget_is_ancestor(widget, caption))
+ {
+ priv->is_focused = TRUE;
+ gtk_widget_queue_draw( caption );
+ return;
+ }
+
+ if( priv->is_focused == TRUE )
+ {
+ /* Caption wasn't found, so cannot focus */
+ priv->is_focused = FALSE;
+ gtk_widget_queue_draw( caption );
+ }
+}
+
+/* We need to connect/disconnect signal handlers to toplevel window
+ in which we reside. Ww want to update connected signals if our
+ parent changes */
+static void hildon_caption_hierarchy_changed( GtkWidget *widget,
+ GtkWidget *previous_toplevel)
+{
+ GtkWidget *current_ancestor;
+ HildonCaptionPrivate *priv;
+
+ priv = HILDON_CAPTION_GET_PRIVATE(widget);
+
+ if( GTK_WIDGET_CLASS(parent_class)->hierarchy_changed )
+ GTK_WIDGET_CLASS(parent_class)->hierarchy_changed( widget,
+ previous_toplevel );
+
+ /* If we already were inside a window, remove old handler */
+ if (previous_toplevel) {
+ /* This is a compilation workaround for gcc > 3.3 since glib is buggy */
+ /* see http://bugzilla.gnome.org/show_bug.cgi?id=310175 */
+#ifdef __GNUC__
+ __extension__
+#endif
+ g_signal_handlers_disconnect_by_func
+ (previous_toplevel, (gpointer) hildon_caption_set_focus, widget);
+ }
+ current_ancestor = gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW);
+
+ /* Install new handler for focus movement */
+ if (current_ancestor)
+ g_signal_connect( current_ancestor, "set-focus",
+ G_CALLBACK(hildon_caption_set_focus), widget );
+}
+
+static void hildon_caption_size_request( GtkWidget *widget,
+ GtkRequisition *requisition )
+{
+ GtkRequisition req;
+ HildonCaptionPrivate *priv = NULL;
+ g_return_if_fail( HILDON_IS_CAPTION(widget) );
+ priv = HILDON_CAPTION_GET_PRIVATE(widget);
+
+ /* Use the same size requisition for the main box of the caption */
+ gtk_widget_size_request( priv->caption_area, &req );
+
+ if( GTK_WIDGET_CLASS(parent_class)->size_request )
+ GTK_WIDGET_CLASS(parent_class)->size_request( widget, requisition );
+
+ requisition->width += req.width + HILDON_CAPTION_SPACING * 3;
+
+ if( (req.height + (2 * widget->style->ythickness)) > requisition->height )
+ requisition->height = req.height + (2 * widget->style->ythickness);
+}
+
+/* We use HILDON_CAPTION_SPACING to make it look a bit nicer */
+static void hildon_caption_size_allocate( GtkWidget *widget,
+ GtkAllocation *allocation )
+{
+ GtkAllocation allocA;
+ GtkAllocation allocB;
+ GtkRequisition req;
+ GtkWidget *child = NULL;
+ HildonCaptionPrivate *priv = NULL;
+
+ g_assert( HILDON_IS_CAPTION(widget) );
+ priv = HILDON_CAPTION_GET_PRIVATE(widget);
+
+ /* Position the caption to its allocated location */
+ if( GTK_WIDGET_REALIZED(widget) )
+ gdk_window_move_resize (widget->window,
+ allocation->x + GTK_CONTAINER (widget)->border_width,
+ allocation->y + GTK_CONTAINER (widget)->border_width,
+ MAX (allocation->width - GTK_CONTAINER (widget)->border_width * 2, 0),
+ MAX (allocation->height - GTK_CONTAINER (widget)->border_width * 2, 0));
+
+ child = GTK_BIN(widget)->child;
+
+ widget->allocation = *allocation;
+ gtk_widget_get_child_requisition( priv->caption_area, &req );
+
+ allocA.height = allocB.height = allocation->height;
+ allocA.width = allocB.width = allocation->width;
+ allocA.x = allocB.x = allocB.y = allocA.y = 0;
+
+ /* Center the captioned widget */
+ if( allocA.width > req.width + HILDON_CAPTION_SPACING )
+ {
+ allocA.x += req.width + HILDON_CAPTION_SPACING * 2;
+ allocB.width = req.width;
+ }
+
+ /* Leave at least the space of the HILDON_CAPTION_SPACING in the left */
+ allocB.x = HILDON_CAPTION_SPACING;
+
+ /* Leave room for the other drawable parts of the caption control */
+ allocA.width -= req.width + HILDON_CAPTION_SPACING * 2;
+
+ /* Give the child at least its minimum requisition, unless it is expandable */
+ if( !priv->expand && child && GTK_WIDGET_VISIBLE(child) )
+ {
+ GtkRequisition child_req;
+ gtk_widget_get_child_requisition( child, &child_req );
+ allocA.width = MIN( allocA.width, child_req.width );
+ allocA.height = MIN( allocA.height, child_req.height );
+ }
+
+ /* Ensure there are no negative dimensions */
+ if( allocA.width < 0 )
+ {
+ allocB.width = req.width + allocA.width;
+ allocA.width = 0;
+ allocB.width = MAX (allocB.width, 0);
+ }
+
+ allocA.height = MAX (allocA.height, 0);
+ allocB.height = MAX (allocB.height, 0);
+
+ if (child && GTK_WIDGET_VISIBLE(child) )
+ gtk_widget_size_allocate( child, &allocA );
+
+ gtk_widget_size_allocate( priv->caption_area, &allocB );
+}
+
+static void hildon_caption_forall( GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer data )
+{
+ HildonCaptionPrivate *priv = NULL;
+
+ g_assert( HILDON_IS_CAPTION(container) );
+ g_assert( callback != NULL );
+
+ priv = HILDON_CAPTION_GET_PRIVATE(container);
+
+ /* Execute callback for the child widgets */
+ if( GTK_CONTAINER_CLASS(parent_class)->forall )
+ GTK_CONTAINER_CLASS(parent_class)->forall( container, include_internals,
+ callback, data );
+
+ if( include_internals )
+ /* Execute callback for the parent box as well */
+ (*callback)( priv->caption_area, data );
+}
+
+
+/**
+ * hildon_caption_set_sizegroup:
+ * @caption : a #HildonCaption
+ * @new_group : a #GtkSizeGroup
+ *
+ * Sets a #GtkSizeGroup of a given captioned control.
+ *
+ * Deprecated: use g_object_set, property :size-group
+ */
+void hildon_caption_set_sizegroup( const HildonCaption *self,
+ GtkSizeGroup *group )
+{
+ g_object_set( G_OBJECT(self), "size_group", group, NULL );
+}
+
+/**
+ * hildon_caption_get_sizegroup:
+ * @caption : a #HildonCaption
+ *
+ * Query given captioned control for the #GtkSizeGroup assigned to it.
+ *
+ * @Returns : a #GtkSizeGroup
+ *
+ * Deprecated: Use g_object_get, property :size-group
+ */
+GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *self )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_CAPTION (self), NULL );
+ priv = HILDON_CAPTION_GET_PRIVATE(self);
+ return priv->group;
+}
+
+/**
+ * hildon_caption_new:
+ * @group : a #GtkSizeGroup for controlling the size of related captions,
+ * Can be NULL
+ * @value : the caption text to accompany the text entry. The widget makes
+ * a copy of this text.
+ * @control : the control that is to be captioned
+ * @icon : an icon to accompany the label - can be NULL in which case no
+ * icon is displayed
+ * @flag : indicates whether this captioned control is mandatory or
+ * optional
+ *
+ * Creates a new instance of hildon_caption widget, with a specific
+ * control and image.
+ * Note: Clicking on a focused caption will trigger the activate signal.
+ * The default behaviour for the caption's activate signal is to call
+ * gtk_widget_activate on it's control.
+ *
+ * @Returns : a #GtkWidget pointer of Caption
+ */
+GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
+ GtkWidget *child, GtkWidget *icon,
+ HildonCaptionStatus flag)
+{
+ GtkWidget *widget;
+ g_return_val_if_fail( GTK_IS_WIDGET(child), NULL );
+
+ widget = g_object_new( HILDON_TYPE_CAPTION, "label", value,
+ "child" /* From GtkContainer */, child, "size_group", group, "icon", icon, "status", flag,
+ NULL );
+
+ return widget;
+}
+
+/**
+ * hildon_caption_is_mandatory:
+ * @caption : a #HildonCaption
+ *
+ * Query #HildonCaption whether this captioned control is a mandatory one.
+ *
+ * @Returns : is this captioned control a mandatory one?
+ */
+
+gboolean hildon_caption_is_mandatory( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return priv->status == HILDON_CAPTION_MANDATORY;
+}
+
+/**
+ * hildon_caption_set_icon_position:
+ * @caption : a #HildonCaption
+ * @pos : one of the values from #HildonCaptionIconPosition
+ *
+ * Sets #HildonCaption icon position.
+ *
+ * Since: 0.14.5
+ */
+
+void hildon_caption_set_icon_position( HildonCaption *caption,
+ HildonCaptionIconPosition pos )
+{
+ g_return_if_fail (HILDON_IS_CAPTION (caption));
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ g_return_if_fail (priv->caption_area != NULL);
+ int order = (pos == HILDON_CAPTION_POSITION_LEFT) ? -1 : 0;
+ gtk_box_reorder_child (GTK_BOX (priv->caption_area), priv->icon_align, order);
+
+ priv->icon_position = pos;
+}
+
+/**
+ * hildon_caption_get_icon_position:
+ * @caption : a #HildonCaption
+ *
+ * Gets #HildonCaption icon position.
+ *
+ * @Returns : one of the values from #HildonCaptionIconPosition.
+ *
+ * Since: 0.14.5
+ */
+
+HildonCaptionIconPosition hildon_caption_get_icon_position( const HildonCaption *caption )
+{
+ g_return_if_fail (HILDON_IS_CAPTION (caption));
+ HildonCaptionPrivate *priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return priv->icon_position;
+}
+
+/**
+ * hildon_caption_set_status:
+ * @caption : a #HildonCaption
+ * @flag : one of the values from #HildonCaptionStatus
+ *
+ * Sets #HildonCaption status.
+ */
+
+void hildon_caption_set_status( HildonCaption *caption,
+ HildonCaptionStatus flag )
+{
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+
+ g_object_set( G_OBJECT(caption), "status", flag, NULL );
+}
+
+/**
+ * hildon_caption_get_status:
+ * @caption : a #HildonCaption
+ *
+ * Gets #HildonCaption status.
+ *
+ * @Returns : one of the values from #HildonCaptionStatus
+ */
+
+HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), HILDON_CAPTION_OPTIONAL );
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return priv->status;
+}
+
+/**
+ * hildon_caption_set_icon_image:
+ * @caption : a #HildonCaption
+ * @icon : the #GtkImage to use as the icon.
+ * calls gtk_widget_show on the icon if !GTK_WIDGET_VISIBLE(icon)
+ *
+ * Sets the icon to be used by this hildon_caption widget.
+ */
+
+void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon )
+{
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+
+ g_object_set( G_OBJECT(caption), "icon", icon, NULL );
+}
+
+/**
+ * hildon_caption_get_icon_image:
+ * @caption : a #HildonCaption
+ *
+ * Gets icon of #HildonCaption
+ *
+ * @Returns : the #GtkImage that is being used as the icon by the
+ * hildon_caption, or NULL if no icon is in use
+ */
+
+GtkWidget *hildon_caption_get_icon_image( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return priv->icon;
+}
+
+/**
+ * hildon_caption_set_label:
+ * @caption : a #HildonCaption
+ * @label : the text to use
+ *
+ * Sets the label text that appears before the control.
+ * Separator character is added to the end of the label string. By default
+ * the separator is ":".
+ */
+
+void hildon_caption_set_label( HildonCaption *caption, const gchar *label )
+{
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+
+ g_object_set( G_OBJECT(caption), "label", label, NULL );
+}
+
+/**
+ * hildon_caption_get_label:
+ * @caption : a #HildonCaption
+ *
+ * Gets label of #HildonCaption
+ *
+ * @Returns : the text currently being used as the label of the caption
+ * control. The string is owned by the label and the caller should never
+ * free or modify this value.
+ */
+
+gchar *hildon_caption_get_label( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return (gchar*)gtk_label_get_text(GTK_LABEL(GTK_LABEL(priv->label)));
+}
+
+/**
+ * hildon_caption_set_separator:
+ * @caption : a #HildonCaption
+ * @separator : the separator to use
+ *
+ * Sets the separator character that appears after the label.
+ * The default seaparator character is ":"
+ * separately.
+ */
+
+void hildon_caption_set_separator( HildonCaption *caption,
+ const gchar *separator )
+{
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+
+ g_object_set( G_OBJECT(caption), "separator", separator, NULL );
+}
+
+/**
+ * hildon_caption_get_separator:
+ * @caption : a #HildonCaption
+ *
+ * Gets separator string of #HildonCaption
+ *
+ * @Returns : the text currently being used as the separator of the caption
+ * control. The string is owned by the caption control and the caller should
+ * never free or modify this value.
+ */
+
+gchar *hildon_caption_get_separator( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv;
+ g_return_val_if_fail(HILDON_IS_CAPTION(caption), "");
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ return priv->separator;
+}
+
+
+/**
+ * hildon_caption_get_control:
+ * @caption : a #HildonCaption
+ *
+ * Gets caption's control.
+ *
+ * @Returns : a #GtkWidget
+ *
+ * Deprecated: use gtk_bin_get_child instead
+ */
+GtkWidget *hildon_caption_get_control( const HildonCaption *caption )
+{
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), NULL );
+ return GTK_BIN(caption)->child;
+}
+
+/*activates the child control
+ *We have this signal so that if needed an application can
+ *know when we've been activated (useful for captions with
+ *multiple children
+ */
+/* FIXME: There never are multiple children. Possibly activate
+ signal could be removed entirely? (does anyone use it?) */
+static void hildon_caption_activate( GtkWidget *widget )
+{
+ HildonCaptionPrivate *priv;
+ GtkWidget *child = GTK_BIN(widget)->child;
+ priv = HILDON_CAPTION_GET_PRIVATE(widget);
+
+ gtk_widget_grab_focus( child );
+}
+
+/**
+ * hildon_caption_set_child_expand:
+ * @caption : a #HildonCaption
+ * @expand : gboolean to determine is the child expandable
+ *
+ * Sets child expandability.
+ */
+void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand )
+{
+ HildonCaptionPrivate *priv = NULL;
+ GtkWidget *child = NULL;
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+
+ /* Did the setting really change? */
+ if( priv->expand == expand )
+ return;
+
+ priv->expand = expand;
+ child = GTK_BIN(caption)->child;
+
+ /* We do not have a child, nothing to do */
+ if( !GTK_IS_WIDGET(child) )
+ return;
+
+ if( GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (caption) )
+ gtk_widget_queue_resize( child );
+
+ gtk_widget_child_notify( child, "expand" );
+}
+
+/**
+ * hildon_caption_get_child_expand:
+ * @caption : a #HildonCaption
+ *
+ * Gets childs expandability.
+ *
+ * @Returns : wheter the child is expandable or not.
+ */
+gboolean hildon_caption_get_child_expand( const HildonCaption *caption )
+{
+ HildonCaptionPrivate *priv = NULL;
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), FALSE );
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+ return priv->expand;
+}
+
+/**
+ * hildon_caption_set_control:
+ * @caption : a #HildonCaption
+ * @control : the control to use. Control should not be NULL.
+ *
+ * Sets the control of the caption.
+ * The old control will be destroyed, unless the caller has added a
+ * reference to it.
+ * Function unparents the old control (if there is one) and adds the new
+ * control.
+ *
+ * Deprecated: use gtk_container_add
+ */
+void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control )
+{
+ GtkWidget *child = NULL;
+ g_return_if_fail( HILDON_IS_CAPTION(caption) );
+ child = GTK_BIN(caption)->child;
+
+ if( child )
+ gtk_container_remove( GTK_CONTAINER(caption), child );
+
+ if( control )
+ {
+ gtk_container_add( GTK_CONTAINER(caption), control );
+ child = control;
+ }
+ else
+ child = NULL;
+}
+
+static void
+hildon_caption_set_label_text( HildonCaptionPrivate *priv )
+{
+ gchar *tmp = NULL;
+ g_assert ( priv != NULL );
+
+ if ( priv->text )
+ {
+ if( priv->separator )
+ {
+ /* Don't duplicate the separator, if the string already contains one */
+ if (g_str_has_suffix(priv->text, priv->separator))
+ {
+ gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
+ }
+ else
+ {
+ /* Append separator and set text */
+ tmp = g_strconcat( priv->text, priv->separator, NULL );
+ gtk_label_set_text( GTK_LABEL( priv->label ), tmp );
+ g_free( tmp );
+ }
+ }
+ else
+ {
+ gtk_label_set_text( GTK_LABEL( priv->label ), priv->text );
+ }
+ }
+ else
+ {
+ /* Clear the label */
+ gtk_label_set_text( GTK_LABEL( priv->label ), "" );
+ }
+
+}
+
+/**
+ * hildon_caption_set_label_alignment:
+ * @caption: a #HildonCaption widget
+ * @alignment: new vertical alignment
+ *
+ * Sets the vertical alignment to be used for the
+ * text part of the caption. Applications need to
+ * align the child control themselves.
+ *
+ * Since: 0.12.0
+ */
+void hildon_caption_set_label_alignment(HildonCaption *caption,
+ gfloat alignment)
+{
+ HildonCaptionPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_CAPTION(caption));
+
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+ g_object_set(priv->label, "yalign", alignment, NULL);
+ g_object_set(priv->icon_align, "yalign", alignment, NULL);
+
+}
+
+/**
+ * hildon_caption_get_label_alignment:
+ * @caption: a #HildonCaption widget
+ *
+ * Gets current vertical alignment for the text part.
+ *
+ * Returns: vertical alignment
+ *
+ * Since: 0.12.0
+ */
+gfloat hildon_caption_get_label_alignment(HildonCaption *caption)
+{
+ HildonCaptionPrivate *priv;
+ gfloat result;
+
+ g_return_val_if_fail( HILDON_IS_CAPTION(caption), 0);
+ priv = HILDON_CAPTION_GET_PRIVATE(caption);
+ g_object_get(priv->label, "yalign", &result, NULL);
+
+ return result;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_CAPTION_H__
+#define __HILDON_CAPTION_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtksizegroup.h>
+
+G_BEGIN_DECLS
+
+
+#define HILDON_TYPE_CAPTION ( hildon_caption_get_type() )
+#define HILDON_CAPTION(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_CAPTION, HildonCaption))
+#define HILDON_CAPTION_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_CAPTION, HildonCaptionClass))
+#define HILDON_IS_CAPTION(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_CAPTION))
+#define HILDON_IS_CAPTION_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CAPTION))
+
+
+/**
+ * HildonCaptionStatus:
+ * @HILDON_CAPTION_OPTIONAL: Optional.
+ * @HILDON_CAPTION_MANDATORY: Mandatory.
+ *
+ * Keys to set the #HildonCaption to be optional or mandatory.
+ */
+typedef enum /*< skip >*/
+{
+ HILDON_CAPTION_OPTIONAL = 0,
+ HILDON_CAPTION_MANDATORY
+} HildonCaptionStatus;
+
+/**
+ * HildonCaptionIconPosition:
+ * @HILDON_CAPTION_POSITION_LEFT: Show the icon on the left side.
+ * @HILDON_CAPTION_POSITION_RIGHT: Show the icon on the right side.
+ *
+ * Keys to set the icon placement in #HildonCaption.
+ *
+ * Since: 0.14.5
+ */
+typedef enum /*< skip >*/
+{
+ HILDON_CAPTION_POSITION_LEFT = 0,
+ HILDON_CAPTION_POSITION_RIGHT
+} HildonCaptionIconPosition;
+
+#define HILDON_TYPE_CAPTION_STATUS (hildon_caption_status_get_type ())
+
+#define HILDON_TYPE_CAPTION_ICON_POSITION (hildon_caption_icon_position_get_type ())
+
+GType hildon_caption_status_get_type (void) G_GNUC_CONST;
+
+GType hildon_caption_icon_position_get_type (void) G_GNUC_CONST;
+
+/**
+ * HildonCaption:
+ *
+ * Contains only private data.
+ */
+typedef struct _HildonCaption HildonCaption;
+typedef struct _HildonCaptionClass HildonCaptionClass;
+
+
+struct _HildonCaption
+{
+ GtkEventBox event_box;
+};
+
+
+struct _HildonCaptionClass
+{
+ GtkEventBoxClass parent_class;
+ void (*activate) (HildonCaption *widget);
+};
+
+
+GType hildon_caption_get_type (void) G_GNUC_CONST;
+
+GtkWidget *hildon_caption_new( GtkSizeGroup *group, const gchar *value,
+ GtkWidget *control, GtkWidget *icon,
+ HildonCaptionStatus flag );
+#ifndef HILDON_DISABLE_DEPRECATED
+GtkSizeGroup *hildon_caption_get_sizegroup( const HildonCaption *caption );
+
+void hildon_caption_set_sizegroup( const HildonCaption *caption,
+ GtkSizeGroup *new_group );
+#endif
+
+gboolean hildon_caption_is_mandatory( const HildonCaption *caption );
+
+void hildon_caption_set_status( HildonCaption *caption,
+ HildonCaptionStatus flag );
+
+HildonCaptionStatus hildon_caption_get_status( const HildonCaption *caption );
+
+void hildon_caption_set_icon_position( HildonCaption *caption,
+ HildonCaptionIconPosition pos );
+
+HildonCaptionIconPosition hildon_caption_get_icon_position( const HildonCaption *caption );
+
+void hildon_caption_set_icon_image( HildonCaption *caption, GtkWidget *icon );
+
+GtkWidget *hildon_caption_get_icon_image(const HildonCaption *caption);
+
+void hildon_caption_set_label( HildonCaption *caption, const gchar *label );
+
+gchar *hildon_caption_get_label( const HildonCaption *caption );
+
+void hildon_caption_set_separator( HildonCaption *caption,
+ const gchar *separator );
+
+gchar *hildon_caption_get_separator( const HildonCaption *caption );
+
+void hildon_caption_set_label_alignment(HildonCaption *caption,
+ gfloat alignment);
+gfloat hildon_caption_get_label_alignment(HildonCaption *caption);
+
+#ifndef HILDON_DISABLE_DEPRECATED
+GtkWidget *hildon_caption_get_control( const HildonCaption *caption );
+
+void hildon_caption_set_control( HildonCaption *caption, GtkWidget *control );
+#endif
+
+void hildon_caption_set_child_expand( HildonCaption *caption, gboolean expand );
+gboolean hildon_caption_get_child_expand( const HildonCaption *caption );
+
+G_END_DECLS
+#endif /* __HILDON_CAPTION_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#include "hildon-code-dialog.h"
+#include "hildon-defines.h"
+#include "hildon-banner.h"
+
+#include <gdk/gdkkeysyms.h>
+
+#include<gtk/gtkbutton.h>
+#include<gtk/gtkentry.h>
+#include<gtk/gtkicontheme.h>
+#include<gtk/gtktable.h>
+#include<gtk/gtkvbox.h>
+#include<gtk/gtkbbox.h>
+#include<gtk/gtklabel.h>
+#include<gtk/gtkalignment.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+
+#define HEIGHT (38-HILDON_MARGIN_DEFAULT)
+#define WIDTH (60-HILDON_MARGIN_DEFAULT)
+#define BACKSPACE_ICON "qgn_calculator_backspace"
+
+#define _(String) dgettext(PACKAGE, String)
+#define c_(String) dgettext("hildon-common-strings", String)
+#define DEVICELOCK_OK _("secu_enter_lock_code_dialog_ok")
+#define DEVICELOCK_CANCEL _("secu_enter_lock_code_dialog_cancel")
+#define DEVICELOCK_TITLE _("secu_application_title")
+#define DEVICELOCK_MAX_CHAR_REACHED c_("ckdg_ib_maximum_characters_reached")
+
+
+
+#define MAX_PINCODE_LEN (10)
+
+
+
+static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class);
+static void hildon_code_dialog_init (HildonCodeDialog *self);
+static void hildon_code_dialog_finalize (GObject *self);
+static void hildon_code_dialog_button_clicked (GtkButton *buttonm,
+ gpointer user_data);
+static void hildon_code_dialog_insert_text (GtkEditable *editable,
+ gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data);
+
+static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data);
+
+
+GtkDialogClass *parent_class;
+
+struct _HildonCodeDialogPrivate
+{
+ GtkWidget *entry;
+ GtkWidget *buttons[5][3];
+ GtkWidget *help_text;
+};
+
+GType hildon_code_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo info =
+ {
+ sizeof(HildonCodeDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_code_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonCodeDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_code_dialog_init
+ };
+ type = g_type_register_static (GTK_TYPE_DIALOG,
+ "HildonCodeDialog", &info, 0);
+ }
+ return type;
+}
+
+static void hildon_code_dialog_class_init (HildonCodeDialogClass *cd_class)
+{
+ /* Get convenience variables */
+ GObjectClass *object_class = G_OBJECT_CLASS (cd_class);
+
+ parent_class = GTK_DIALOG_CLASS (g_type_class_peek_parent (cd_class));
+
+ object_class->finalize = hildon_code_dialog_finalize;
+
+}
+
+static void hildon_code_dialog_init (HildonCodeDialog *dialog)
+{
+ HildonCodeDialogPrivate *priv;
+ gint i, x, y;
+ GtkWidget *dialog_vbox1 = NULL;
+ GtkWidget *table = NULL;
+ GtkWidget *alignment = NULL;
+ GtkWidget *vbox1 = NULL;
+ GtkWidget *image1 = NULL;
+ GtkWidget *dialog_action_area1 = NULL;
+ GdkGeometry hints;
+ GtkWidget *okButton;
+ GtkWidget *cancelButton;
+
+ priv = dialog->priv = (HildonCodeDialogPrivate*) g_malloc0
+ (sizeof (HildonCodeDialogPrivate));
+
+ const gchar* numstrs[10] = {
+ "0","1","2","3","4","5","6","7","8","9"
+ };
+
+ GdkPixbuf* pixbuf = NULL;
+ GtkIconTheme* icon_theme = NULL;
+ GtkIconInfo *icon_info = NULL;
+ gint base_size=0;
+
+ /* Set default title */
+ gtk_window_set_title (GTK_WINDOW (dialog), DEVICELOCK_TITLE);
+
+ gtk_window_set_type_hint(GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+ hints.min_width = -1;
+ hints.min_height = -1;
+ hints.max_width = -1;
+ hints.max_height = -1;
+
+ gtk_window_set_geometry_hints(GTK_WINDOW(dialog), GTK_WIDGET(dialog),
+ &hints,
+ GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
+
+ table = gtk_table_new (4, 3, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
+ gtk_table_set_col_spacings (GTK_TABLE (table), HILDON_MARGIN_DEFAULT );
+
+ dialog_vbox1 = GTK_DIALOG (dialog)->vbox;
+ vbox1 = gtk_vbox_new (FALSE, 0);
+ gtk_box_set_spacing (GTK_BOX(vbox1),HILDON_MARGIN_DOUBLE);
+
+ priv->help_text= gtk_label_new ("");
+ alignment=gtk_alignment_new(0.5,0,1,1);
+ gtk_container_add(GTK_CONTAINER(alignment),priv->help_text);
+
+ priv->entry = gtk_entry_new ();
+
+ GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(priv->entry),GTK_CAN_FOCUS);
+ gtk_entry_set_invisible_char (GTK_ENTRY(priv->entry), g_utf8_get_char ("*"));
+ gtk_entry_set_alignment (GTK_ENTRY(priv->entry),1.0);
+
+ gtk_editable_set_editable (GTK_EDITABLE(priv->entry),FALSE);
+ gtk_entry_set_visibility (GTK_ENTRY(priv->entry), FALSE);
+
+ gtk_box_pack_start (GTK_BOX (vbox1),alignment,TRUE,FALSE,0);
+ gtk_box_pack_start (GTK_BOX (vbox1),priv->entry,TRUE,FALSE,0);
+ gtk_box_pack_start (GTK_BOX (vbox1),table,FALSE,TRUE,0);
+
+ gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1,FALSE,TRUE,0);
+
+
+ for(i=1;i<=3;i++) {
+ priv->buttons[0][i-1] = gtk_button_new_with_mnemonic(numstrs[i]);
+ gtk_widget_set_size_request(priv->buttons[0][i-1],WIDTH,HEIGHT);
+ gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[0][i-1],
+ i-1,i,0,1);
+ }
+
+ for(i=4;i<=6;i++) {
+ priv->buttons[1][i-4] = gtk_button_new_with_mnemonic (numstrs[i]);
+ gtk_widget_set_size_request(priv->buttons[1][i-4],WIDTH,HEIGHT);
+ gtk_table_attach_defaults(GTK_TABLE(table),priv->buttons[1][i-4],
+ i-4,i-3,1,2);
+ }
+
+ for(i=7;i<=9;i++) {
+ priv->buttons[2][i-7] = gtk_button_new_with_mnemonic (numstrs[i]);
+ gtk_widget_set_size_request(priv->buttons[2][i-7], WIDTH,HEIGHT);
+ gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[2][i-7],
+ i-7,i-6,2,3);
+ }
+
+ priv->buttons[3][0] = priv->buttons[3][1] =
+ gtk_button_new_with_mnemonic (numstrs[0]);
+ gtk_widget_set_size_request (priv->buttons[3][0], WIDTH,HEIGHT);
+ gtk_table_attach (GTK_TABLE(table), priv->buttons[3][0],
+ 0,2,3,4, (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+
+ priv->buttons[3][2] = gtk_button_new ();
+ gtk_widget_set_size_request(priv->buttons[3][2], WIDTH,HEIGHT);
+ gtk_table_attach_defaults(GTK_TABLE(table), priv->buttons[3][2],
+ 2,3,3,4);
+
+ icon_theme = gtk_icon_theme_get_default ();
+
+ icon_info = gtk_icon_theme_lookup_icon(icon_theme, BACKSPACE_ICON, 1,
+ GTK_ICON_LOOKUP_NO_SVG);
+ base_size = gtk_icon_info_get_base_size(icon_info);
+ gtk_icon_info_free(icon_info);
+ icon_info = NULL;
+ pixbuf = gtk_icon_theme_load_icon (icon_theme,
+ BACKSPACE_ICON, base_size,
+ GTK_ICON_LOOKUP_NO_SVG,
+ NULL);
+ image1 = gtk_image_new_from_pixbuf (pixbuf);
+ g_object_unref (G_OBJECT(pixbuf));
+ gtk_container_add (GTK_CONTAINER (priv->buttons[3][2]), image1);
+ dialog_action_area1 = GTK_DIALOG (dialog)->action_area;
+ gtk_button_box_set_layout (GTK_BUTTON_BOX(dialog_action_area1),
+ GTK_BUTTONBOX_END);
+
+ okButton = gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_OK,
+ GTK_RESPONSE_OK);
+ cancelButton =
+ gtk_dialog_add_button (GTK_DIALOG(dialog),DEVICELOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+
+ gtk_widget_set_sensitive (okButton, FALSE);
+
+ priv->buttons[4][0] = priv->buttons[4][1] = okButton;
+ priv->buttons[4][2] = cancelButton;
+
+ /*
+ Connect signals.
+ */
+ g_signal_connect (G_OBJECT(priv->entry), "insert_text",
+ G_CALLBACK (hildon_code_dialog_insert_text), dialog);
+
+ gtk_entry_set_max_length(GTK_ENTRY(priv->entry),MAX_PINCODE_LEN);
+
+ for (x=0; x<3; x++)
+ {
+ for (y=0; y<3 ;y++)
+ {
+ g_signal_connect (G_OBJECT (priv->buttons[x][y]), "clicked",
+ G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
+ g_signal_connect (G_OBJECT (priv->buttons[x][y]), "key-press-event",
+ G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
+ }
+ }
+
+ g_signal_connect (G_OBJECT (priv->buttons[3][0]), "clicked",
+ G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
+ g_signal_connect (G_OBJECT (priv->buttons[3][0]), "key-press-event",
+ G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
+
+ g_signal_connect (G_OBJECT (priv->buttons[3][2]), "clicked",
+ G_CALLBACK (hildon_code_dialog_button_clicked), dialog);
+ g_signal_connect (G_OBJECT (priv->buttons[3][2]), "key-press-event",
+ G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
+
+ g_signal_connect (G_OBJECT (okButton), "key-press-event",
+ G_CALLBACK(hildon_code_dialog_key_press_event), dialog);
+
+ g_signal_connect (G_OBJECT (cancelButton), "key-press-event",
+ G_CALLBACK (hildon_code_dialog_key_press_event), dialog);
+
+}
+
+static void hildon_code_dialog_finalize (GObject *self)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (self);
+
+ fprintf( stderr, "called destroy\n" );
+
+ g_free (dialog->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (self);
+}
+
+/* Signal handlers */
+void hildon_code_dialog_button_clicked (GtkButton *button, gpointer user_data)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
+ HildonCodeDialogPrivate *priv = dialog->priv;
+ const char *number = gtk_button_get_label (button);
+
+ if (number && *number )
+ {
+ gtk_entry_append_text (GTK_ENTRY (priv->entry), number);
+ }
+ else
+ {
+ /* Backspace */
+ gchar *text = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->entry)));
+ gchar *pos;
+
+ pos = text;
+
+ while (*pos != '\0')
+ {
+ pos ++;
+ }
+
+ pos = g_utf8_find_prev_char (text, pos);
+
+ if (pos)
+ {
+ *pos=0;
+ }
+
+ gtk_entry_set_text (GTK_ENTRY (priv->entry), text);
+
+ if (*text == 0)
+ {
+ gtk_widget_set_sensitive (priv->buttons[4][0], FALSE);
+ }
+
+ g_free (text);
+ }
+
+}
+
+static void hildon_code_dialog_insert_text (GtkEditable *editable,
+ gchar *new_text,
+ gint new_text_length,
+ gint *position,
+ gpointer user_data)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
+ HildonCodeDialogPrivate *priv = dialog->priv;
+ gchar * text = g_strdup(gtk_entry_get_text (GTK_ENTRY (priv->entry)));
+ glong length = g_utf8_strlen (text, -1);
+ g_free (text);
+
+ if (length == MAX_PINCODE_LEN)
+ {
+ hildon_banner_show_information (dialog,
+ NULL,
+ DEVICELOCK_MAX_CHAR_REACHED);
+ }
+
+ else if (!length)
+ {
+ /* make the Ok button sensitive */
+ gtk_widget_set_sensitive(priv->buttons[4][0], TRUE);
+ }
+}
+
+static gboolean hildon_code_dialog_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ HildonCodeDialog *dialog = HILDON_CODE_DIALOG (user_data);
+ HildonCodeDialogPrivate *priv = dialog->priv;
+ GtkWidget *new_widget = widget;
+ gint x, y;
+
+ for (x = 0; x < 5; x++)
+ {
+ for (y = 0; y < 3; y++)
+ {
+ if (priv->buttons[x][y] == widget)
+ goto found;
+ }
+ }
+ return FALSE;
+
+found:
+
+ while (new_widget == widget)
+ {
+ switch (event->keyval)
+ {
+ case GDK_Up:
+ x = (x+4)%5;
+ break;
+
+ case GDK_Down:
+ x = (x+1)%5;
+ break;
+
+ case GDK_Left:
+ y = (y+2)%3;
+ break;
+
+ case GDK_Right:
+ y = (y+1)%3;
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ new_widget = priv->buttons[x][y];
+ }
+
+ gtk_widget_grab_focus (new_widget);
+
+ return TRUE;
+}
+
+/* Public methods */
+
+/**
+ * hildon_code_dialog_new:
+ *
+ * Use this function to create a new HildonCodeDialog.
+ *
+ * Return value: A @HildonCodeDialog.
+ **/
+GtkWidget *hildon_code_dialog_new()
+{
+ HildonCodeDialog *dialog = g_object_new (HILDON_TYPE_CODE_DIALOG, NULL);
+
+ return GTK_WIDGET (dialog);
+}
+
+/**
+ * hildon_code_dialog_get_code:
+ * @dialog: The #HildonCodeDialog from which to get the entered code
+ *
+ * Use this function to access the code entered by the user.
+ *
+ * Return value: The entered code.
+ **/
+const gchar *hildon_code_dialog_get_code (HildonCodeDialog *dialog)
+{
+ g_return_val_if_fail (HILDON_IS_CODE_DIALOG (dialog), NULL);
+ return gtk_entry_get_text (GTK_ENTRY (dialog->priv->entry));
+}
+
+/**
+ * hildon_code_dialog_clear_clode:
+ * @dialog: The #HildonCodeDialog whose entry should be cleared:
+ *
+ * Use this function to clear the user entered code.
+ **/
+void hildon_code_dialog_clear_code (HildonCodeDialog *dialog)
+{
+ g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
+ gtk_entry_set_text (GTK_ENTRY (dialog->priv->entry), "");
+ gtk_widget_set_sensitive (dialog->priv->buttons[4][0], FALSE);
+}
+
+/**
+ * hildon_code_dialog_set_help_text:
+ * @dialog: The #HildonCodeDialog whose entry should be cleared:
+ * @text: The text to use in the help label.
+ *
+ * Use this function to set the text that will be displayd in the
+ * help label
+ **/
+void hildon_code_dialog_set_help_text (HildonCodeDialog *dialog,
+ const gchar *text)
+{
+ g_return_if_fail (HILDON_IS_CODE_DIALOG (dialog));
+ gtk_label_set_text (GTK_LABEL (dialog->priv->help_text), text);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_CODE_DIALOG_H__
+#define __HILDON_CODE_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+
+#define HILDON_TYPE_CODE_DIALOG ( hildon_code_dialog_get_type() )
+#define HILDON_CODE_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_CODE_DIALOG, HildonCodeDialog))
+#define HILDON_CODE_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_CODE_DIALOG, HildonCodeDialogClass))
+#define HILDON_IS_CODE_DIALOG(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_CODE_DIALOG))
+#define HILDON_IS_CODE_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_CODE_DIALOG))
+
+
+typedef struct _HildonCodeDialogPrivate HildonCodeDialogPrivate;
+typedef struct _HildonCodeDialog HildonCodeDialog;
+typedef struct _HildonCodeDialogClass HildonCodeDialogClass;
+
+
+struct _HildonCodeDialog
+{
+ GtkDialog parent;
+
+ HildonCodeDialogPrivate *priv;
+};
+
+struct _HildonCodeDialogClass
+{
+ GtkDialogClass parent_class;
+};
+
+
+GType hildon_code_dialog_get_type (void);
+GtkWidget *hildon_code_dialog_new(void);
+const gchar *hildon_code_dialog_get_code (HildonCodeDialog *dialog);
+void hildon_code_dialog_clear_code (HildonCodeDialog *dialog);
+void hildon_code_dialog_set_help_text (HildonCodeDialog *dialog,
+ const gchar *text);
+
+
+G_END_DECLS
+#endif /* __HILDON_CODE_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-color-button
+ * @short_description: A widget to open HildonColorChooserDialog
+ * @see_also: #HildonColorChooserDialog, #HildonColorPopup
+ *
+ * HildonColorButton is a widget to open a HildonColorChooserDialog.
+ * The selected color is shown in the button.
+ * The selected color is a property of the button.
+ * The property name is "color" and its type is GtkColor.
+ */
+#include <config.h>
+
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <hildon-widgets/hildon-defines.h>
+
+#include "hildon-color-button.h"
+#include "hildon-color-chooser-dialog.h"
+
+#define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
+ ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
+
+#define COLOR_FILLED_HEIGHT 22
+#define COLOR_FILLED_WIDTH 22
+
+#define COLOR_BUTTON_WIDTH 52
+#define COLOR_BUTTON_HEIGHT 48
+
+/* the outer border color */
+#define OUTER_BORDER_RED 0
+#define OUTER_BORDER_BLUE 0
+#define OUTER_BORDER_GREEN 0
+#define OUTER_BORDER_THICKNESS 1
+
+/* the inner border color */
+#define INNER_BORDER_RED 65535
+#define INNER_BORDER_BLUE 65535
+#define INNER_BORDER_GREEN 65535
+#define INNER_BORDER_THICKNESS 2
+
+struct _HildonColorButtonPrivate
+{
+ GtkWidget *dialog;
+
+ GdkColor color;
+ GdkGC *gc;
+};
+
+enum
+{
+ PROP_NONE,
+ PROP_COLOR
+};
+
+static void
+hildon_color_button_class_init(HildonColorButtonClass *klass);
+static void
+hildon_color_button_init(HildonColorButton *color_button);
+
+static void
+hildon_color_button_finalize(GObject *object);
+static void
+hildon_color_button_set_property(GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec);
+static void
+hildon_color_button_get_property(GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec);
+static void
+hildon_color_button_realize(GtkWidget *widget);
+static void
+hildon_color_button_unrealize(GtkWidget *widget);
+static void
+hildon_color_button_clicked(GtkButton *button);
+static gboolean
+hildon_color_button_key_pressed(GtkWidget * button,
+ GdkEventKey * event,
+ gpointer data);
+static gint
+hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
+ HildonColorButton *cb);
+
+static gboolean
+hildon_color_button_mnemonic_activate( GtkWidget *widget,
+ gboolean group_cycling );
+
+static void
+draw_grid (GdkDrawable *drawable, GdkGC *gc,
+ int x, int y,
+ gint w, gint h);
+
+static gpointer parent_class = NULL;
+
+GType
+hildon_color_button_get_type(void)
+{
+ static GType color_button_type = 0;
+
+ if (!color_button_type)
+ {
+ static const GTypeInfo color_button_info =
+ {
+ sizeof (HildonColorButtonClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_color_button_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (HildonColorButton),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_color_button_init,
+ };
+
+ color_button_type =
+ g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
+ &color_button_info, 0);
+ }
+
+ return color_button_type;
+}
+
+static void
+hildon_color_button_class_init(HildonColorButtonClass *klass)
+{
+ GObjectClass *gobject_class;
+ GtkButtonClass *button_class;
+ GtkWidgetClass *widget_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ button_class = GTK_BUTTON_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->get_property = hildon_color_button_get_property;
+ gobject_class->set_property = hildon_color_button_set_property;
+ gobject_class->finalize = hildon_color_button_finalize;
+ widget_class->realize = hildon_color_button_realize;
+ widget_class->unrealize = hildon_color_button_unrealize;
+ button_class->clicked = hildon_color_button_clicked;
+ widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
+
+ /**
+ * HildonColorButton:color:
+ *
+ * The selected color.
+ */
+ g_object_class_install_property (gobject_class, PROP_COLOR,
+ g_param_spec_boxed ("color",
+ "Current Color",
+ "The selected color",
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
+}
+
+/* Draw a dotted grid over the specified area to make it look
+ * insensitive. Actually, we should generate that pixbuf once and
+ * just render it over later... */
+static void
+draw_grid (GdkDrawable *drawable, GdkGC *gc,
+ int x, int y,
+ gint w, gint h)
+{
+ int currentx;
+ int currenty;
+ for (currenty = y; currenty <= h; currenty++)
+ for (currentx = ((currenty % 2 == 0) ? x : x + 1); currentx <= w; currentx += 2)
+ gdk_draw_point (drawable, gc, currentx, currenty);
+}
+
+/* Handle exposure events for the color picker's drawing area */
+static gint
+hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
+ HildonColorButton *cb)
+{
+ GdkColor outer_border, inner_border;
+
+ /* Create the outer border color */
+ outer_border.pixel = 0;
+ outer_border.red = OUTER_BORDER_RED;
+ outer_border.blue = OUTER_BORDER_BLUE;
+ outer_border.green = OUTER_BORDER_GREEN;
+
+ /* Create the inner border color */
+ inner_border.pixel = 0;
+ inner_border.red = INNER_BORDER_RED;
+ inner_border.blue = INNER_BORDER_BLUE;
+ inner_border.green = INNER_BORDER_GREEN;
+
+ /* serve the outer border color to the Graphic Context */
+ gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
+ /* draw the outer border as a filled rectangle */
+ gdk_draw_rectangle(widget->window,
+ (GTK_WIDGET_IS_SENSITIVE (widget)) ? cb->priv->gc : widget->style->bg_gc [GTK_STATE_INSENSITIVE],
+ TRUE,
+ 0,
+ 0,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ /* serve the inner border color to the Graphic Context */
+ gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
+ /* draw the inner border as a filled rectangle */
+ gdk_draw_rectangle(widget->window,
+ cb->priv->gc,
+ TRUE,
+ OUTER_BORDER_THICKNESS,
+ OUTER_BORDER_THICKNESS,
+ widget->allocation.width - (OUTER_BORDER_THICKNESS * 2),
+ widget->allocation.height - (OUTER_BORDER_THICKNESS * 2));
+
+ /* serve the actual color to the Graphic Context */
+ gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
+ /* draw the actual rectangle */
+ gdk_draw_rectangle(widget->window,
+ cb->priv->gc,
+ TRUE,
+ INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+ INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+ widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
+ widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
+
+ if (! GTK_WIDGET_IS_SENSITIVE (widget)) {
+ draw_grid (GDK_DRAWABLE (widget->window), widget->style->bg_gc [GTK_STATE_INSENSITIVE],
+ INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+ INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS,
+ widget->allocation.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2,
+ widget->allocation.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2) + 2);
+ }
+
+ return FALSE;
+}
+
+static void
+hildon_color_button_init(HildonColorButton *cb)
+{
+ GtkWidget *align;
+ GtkWidget *drawing_area;
+
+ cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
+
+ cb->priv->dialog = NULL;
+ cb->priv->gc = NULL;
+
+ gtk_widget_push_composite_child();
+
+ /* create widgets and pixbuf */
+ align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
+
+ drawing_area = gtk_drawing_area_new(); /*composite widget*/
+
+ /* setting minimum sizes */
+ gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
+ COLOR_BUTTON_HEIGHT);
+ gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
+ COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
+
+ /* Connect the callback function for exposure event */
+ g_signal_connect(drawing_area, "expose-event",
+ G_CALLBACK(hildon_color_field_expose_event), cb);
+
+ /* Connect to callback function for key press event */
+ g_signal_connect(G_OBJECT(cb), "key-press-event",
+ G_CALLBACK(hildon_color_button_key_pressed), cb);
+
+ /* packing */
+ gtk_container_add(GTK_CONTAINER(align), drawing_area);
+ gtk_container_add(GTK_CONTAINER(cb), align);
+
+ gtk_widget_show_all(align);
+
+ gtk_widget_pop_composite_child();
+}
+
+/* Free memory used by HildonColorButton */
+static void
+hildon_color_button_finalize(GObject *object)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+
+ if (cb->priv->dialog)
+ {
+ gtk_widget_destroy(cb->priv->dialog);
+ cb->priv->dialog = NULL;
+ }
+
+ if( G_OBJECT_CLASS(parent_class)->finalize )
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+hildon_color_button_realize(GtkWidget *widget)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
+
+ GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+ cb->priv->gc = gdk_gc_new(widget->window);
+}
+
+static void
+hildon_color_button_unrealize(GtkWidget *widget)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
+
+ g_object_unref(cb->priv->gc);
+ cb->priv->gc = NULL;
+
+ GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+/* Make the widget sensitive with the keyboard event */
+static gboolean
+hildon_color_button_mnemonic_activate( GtkWidget *widget,
+ gboolean group_cycling )
+{
+ gtk_widget_grab_focus( widget );
+ return TRUE;
+}
+
+/* Popup a color selector dialog on button click */
+static void
+hildon_color_button_clicked(GtkButton *button)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
+ HildonColorChooserDialog *cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
+
+ /* Popup the color selector dialog */
+ if (!cs_dialog)
+ {
+ /* The dialog hasn't been created yet, do it. */
+ GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
+ cb->priv->dialog = hildon_color_chooser_dialog_new(GTK_WINDOW(parent));
+ cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
+ }
+
+ /* Set the initial color for the color selector dialog */
+ hildon_color_chooser_dialog_set_color(cs_dialog, &cb->priv->color);
+
+ /* Update the color for color button if selection was made */
+ if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
+ {
+ hildon_color_chooser_dialog_get_color(cs_dialog, &cb->priv->color);
+ hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
+ &(cb->priv->color) );
+ }
+
+ gtk_widget_hide(GTK_WIDGET(cs_dialog));
+}
+
+/* Popup a color selector dialog on hardkey Select press */
+static gboolean
+hildon_color_button_key_pressed(GtkWidget * button,
+ GdkEventKey * event,
+ gpointer data)
+{
+ g_return_val_if_fail (HILDON_IS_COLOR_BUTTON(button), FALSE);
+
+ if (event->keyval == HILDON_HARDKEY_SELECT)
+ {
+ hildon_color_button_clicked(GTK_BUTTON(button));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Set_property function for HildonColorButtonClass initialization */
+static void
+hildon_color_button_set_property(GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+
+ switch (param_id)
+ {
+ case PROP_COLOR:
+ cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
+ gtk_widget_queue_draw(GTK_WIDGET(cb));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+/* Get_property function for HildonColorButtonClass initialization */
+static void
+hildon_color_button_get_property(GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
+
+ switch (param_id)
+ {
+ case PROP_COLOR:
+ g_value_set_boxed(value, &cb->priv->color);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+/**
+ * hildon_color_button_new:
+ *
+ * Creates a new color button. This returns a widget in the form of a
+ * small button containing a swatch representing the selected color.
+ * When the button is clicked, a color-selection dialog will open,
+ * allowing the user to select a color. The swatch will be updated to
+ * reflect the new color when the user finishes.
+ *
+ * Returns: a new color button
+ */
+GtkWidget *
+hildon_color_button_new(void)
+{
+ return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
+}
+
+/**
+ * hildon_color_button_new_with_color:
+ * @color: a #GdkColor for the initial color
+ *
+ * Creates a new color button with @color as the initial color.
+ *
+ * Returns: a new color button
+ */
+GtkWidget *
+hildon_color_button_new_with_color(const GdkColor *color)
+{
+ return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
+}
+
+/**
+ * hildon_color_button_set_color:
+ * @button: a #HildonColorButton
+ * @color: a color to be set
+ *
+ * Sets the color selected by the button.
+ */
+void
+hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
+{
+ g_object_set( G_OBJECT(button), "color", color, NULL );
+}
+
+/**
+ * hildon_color_button_get_color:
+ * @button: a #HildonColorButton
+ *
+ * Returns: the color selected by the button
+ */
+GdkColor *
+hildon_color_button_get_color( HildonColorButton *button )
+{
+ GdkColor *color = NULL;
+ g_object_get( G_OBJECT(button), "color", &color, NULL );
+ return color;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_COLOR_BUTTON_H__
+#define __HILDON_COLOR_BUTTON_H__
+
+#include <gtk/gtkbutton.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_COLOR_BUTTON (hildon_color_button_get_type ())
+#define HILDON_COLOR_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButton))
+#define HILDON_COLOR_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_BUTTON, HildonColorButtonClass))
+#define HILDON_IS_COLOR_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_BUTTON))
+#define HILDON_IS_COLOR_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_COLOR_BUTTON))
+#define HILDON_COLOR_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonClass))
+
+typedef struct _HildonColorButton HildonColorButton;
+typedef struct _HildonColorButtonClass HildonColorButtonClass;
+typedef struct _HildonColorButtonPrivate HildonColorButtonPrivate;
+
+struct _HildonColorButton
+{
+ GtkButton button;
+ HildonColorButtonPrivate *priv;
+};
+
+struct _HildonColorButtonClass
+{
+ GtkButtonClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+
+GType
+hildon_color_button_get_type( void ) G_GNUC_CONST;
+
+GtkWidget *
+hildon_color_button_new( void );
+
+GtkWidget *
+hildon_color_button_new_with_color( const GdkColor *color );
+
+GdkColor *
+hildon_color_button_get_color( HildonColorButton *button );
+
+void
+hildon_color_button_set_color( HildonColorButton *button, GdkColor *color );
+
+G_END_DECLS
+
+#endif /* __HILDON_COLOR_BUTTON_H__ */
+
+
+
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#include <gtk/gtk.h>
+
+
+#include "hildon-color-chooser-button.h"
+
+#include "hildon-color-chooser-dialog.h"
+
+
+enum {
+ COLOR_CHANGED,
+ LAST_SIGNAL
+};
+
+
+static guint color_chooser_button_signals[LAST_SIGNAL] = { 0 };
+
+
+static GtkButtonClass *parent_klass = NULL;
+
+
+static void hildon_color_chooser_button_init(HildonColorChooserButton *object);
+static void hildon_color_chooser_button_class_init(HildonColorChooserButtonClass *klass);
+
+
+static void hildon_color_chooser_button_size_request(GtkWidget *widget, GtkRequisition *req);
+static void hildon_color_chooser_button_size_allocate(GtkWidget *widget, GtkAllocation *alloc);
+
+static void hildon_color_chooser_button_realize(GtkWidget *widget);
+static void hildon_color_chooser_button_unrealize(GtkWidget *widget);
+
+static void hildon_color_chooser_button_style_set(GtkWidget *widget, GtkStyle *previous_style);
+
+static void hildon_color_chooser_button_show(GtkWidget *widget);
+static void hildon_color_chooser_button_show_all(GtkWidget *widget);
+
+static void hildon_color_chooser_button_virtual_set_color(HildonColorChooserButton *button, GdkColor *color);
+static void hildon_color_chooser_button_virtual_color_changed(HildonColorChooserButton *button, GdkColor *color);
+
+static void hildon_color_chooser_button_clicked(GtkButton *button);
+
+
+static gboolean hildon_color_chooser_button_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data);
+
+
+static void hildon_color_chooser_button_helper_get_style_info(HildonColorChooserButton *button);
+
+
+GtkType hildon_color_chooser_button_get_type ()
+{
+ static GtkType button_type = 0;
+
+ if (!button_type)
+ {
+ static const GtkTypeInfo button_info =
+ {
+ "HildonColorChooserButton",
+ sizeof (HildonColorChooserButton),
+ sizeof (HildonColorChooserButtonClass),
+ (GtkClassInitFunc) hildon_color_chooser_button_class_init,
+ (GtkObjectInitFunc) hildon_color_chooser_button_init,
+ /* reserved_1 */ NULL,
+ /* reserved_1 */ NULL,
+ (GtkClassInitFunc) NULL
+ };
+
+ button_type = gtk_type_unique (GTK_TYPE_BUTTON, &button_info);
+ }
+
+ return button_type;
+}
+
+
+ /* initializer functions */
+static void hildon_color_chooser_button_init(HildonColorChooserButton *object)
+{
+ object->color.red = 0x0000;
+ object->color.green = 0x0000;
+ object->color.blue = 0x0000;
+ object->color.pixel = 0x00000000;
+
+
+ object->area = gtk_drawing_area_new();
+
+ gtk_container_add(GTK_CONTAINER(object), object->area);
+
+
+ g_signal_connect(G_OBJECT(object->area), "expose-event",
+ G_CALLBACK(hildon_color_chooser_button_area_expose), object);
+}
+
+static void hildon_color_chooser_button_class_init(HildonColorChooserButtonClass *klass)
+{
+ GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS(klass);
+ GtkButtonClass *button_klass = GTK_BUTTON_CLASS(klass);
+ GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
+
+
+ parent_klass = g_type_class_peek_parent(klass);
+
+
+ klass->set_color = hildon_color_chooser_button_virtual_set_color;
+ klass->color_changed = hildon_color_chooser_button_virtual_color_changed;
+
+
+ button_klass->clicked = hildon_color_chooser_button_clicked;
+
+
+ widget_klass->size_request = hildon_color_chooser_button_size_request;
+ widget_klass->size_allocate = hildon_color_chooser_button_size_allocate;
+
+ widget_klass->realize = hildon_color_chooser_button_realize;
+ widget_klass->unrealize = hildon_color_chooser_button_unrealize;
+
+ widget_klass->style_set = hildon_color_chooser_button_style_set;
+
+ widget_klass->show = hildon_color_chooser_button_show;
+ widget_klass->show_all = hildon_color_chooser_button_show_all;
+
+
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("outer_border",
+ "Outer border",
+ "Size of the outer border",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("inner_border",
+ "Inner border",
+ "Size of the inner border",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property(widget_klass,
+ g_param_spec_boxed("minimum_size",
+ "minimum_size",
+ "Minimum size of the color area",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+
+ color_chooser_button_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_klass),
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserButtonClass, color_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
+}
+
+
+ /* virtual widget functions */
+static void hildon_color_chooser_button_size_request(GtkWidget *widget, GtkRequisition *req)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+
+
+ req->width = button->style_info.outer.left + button->style_info.min.left + button->style_info.outer.right;
+ req->height = button->style_info.outer.top + button->style_info.min.right + button->style_info.outer.bottom;
+}
+
+static void hildon_color_chooser_button_size_allocate(GtkWidget *widget, GtkAllocation *alloc)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+ GtkAllocation child_alloc;
+ GdkRectangle clip_rect;
+
+
+ GTK_WIDGET_CLASS(parent_klass)->size_allocate(widget, alloc);
+ child_alloc = *alloc;
+
+
+ child_alloc.x += button->style_info.outer.left;
+ child_alloc.y += button->style_info.outer.top;
+
+ child_alloc.width -= (button->style_info.outer.left + button->style_info.outer.right);
+ child_alloc.height -= (button->style_info.outer.top + button->style_info.outer.bottom);
+
+
+ gtk_widget_size_allocate(button->area, &child_alloc);
+
+
+ if(GTK_WIDGET_REALIZED(widget)) {
+ clip_rect.x = button->style_info.inner.left;
+ clip_rect.y = button->style_info.inner.top;
+ clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
+ clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
+
+ gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
+ }
+}
+
+
+static void hildon_color_chooser_button_realize(GtkWidget *widget)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+ GdkRectangle clip_rect;
+
+
+ GTK_WIDGET_CLASS(parent_klass)->realize(widget);
+
+
+ button->color_gc = gdk_gc_new(widget->window);
+ gdk_gc_set_rgb_fg_color(button->color_gc, &button->color);
+
+
+ clip_rect.x = button->style_info.inner.left;
+ clip_rect.y = button->style_info.inner.top;
+ clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
+ clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
+
+ gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
+}
+
+static void hildon_color_chooser_button_unrealize(GtkWidget *widget)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+
+
+ g_object_unref(button->color_gc);
+ button->color_gc = NULL;
+
+
+ GTK_WIDGET_CLASS(parent_klass)->unrealize(widget);
+}
+
+
+static void hildon_color_chooser_button_style_set(GtkWidget *widget, GtkStyle *previous_style)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+ GdkRectangle clip_rect;
+
+
+ hildon_color_chooser_button_helper_get_style_info(button);
+
+
+ if(GTK_WIDGET_REALIZED(widget)) {
+ clip_rect.x = button->style_info.inner.left;
+ clip_rect.y = button->style_info.inner.top;
+ clip_rect.width = button->area->allocation.width - button->style_info.inner.left - button->style_info.inner.right;
+ clip_rect.height = button->area->allocation.height - button->style_info.inner.top - button->style_info.inner.bottom;
+
+ gdk_gc_set_clip_rectangle(button->color_gc, &clip_rect);
+ }
+}
+
+
+static void hildon_color_chooser_button_show(GtkWidget *widget)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(widget);
+
+
+ gtk_widget_show(button->area);
+
+ GTK_WIDGET_CLASS(parent_klass)->show(widget);
+}
+
+static void hildon_color_chooser_button_show_all(GtkWidget *widget)
+{
+ hildon_color_chooser_button_show(widget);
+}
+
+
+static void hildon_color_chooser_button_virtual_set_color(HildonColorChooserButton *button, GdkColor *color)
+{
+ button->color = *color;
+
+ if(GTK_WIDGET_REALIZED(button)) {
+ gdk_gc_set_rgb_fg_color(button->color_gc, &button->color);
+
+ gtk_widget_queue_draw(button->area);
+ }
+
+
+ g_signal_emit(button, color_chooser_button_signals[COLOR_CHANGED], 0, &button->color);
+}
+
+static void hildon_color_chooser_button_virtual_color_changed(HildonColorChooserButton *button, GdkColor *color)
+{
+}
+
+
+static void hildon_color_chooser_button_clicked(GtkButton *button)
+{
+ HildonColorChooserButton *color_button = HILDON_COLOR_CHOOSER_BUTTON(button);
+ GtkWidget *dialog;
+ GdkColor color;
+ gint result = 0;
+
+
+ dialog = hildon_color_chooser_dialog_new();
+ gtk_widget_realize(dialog);
+ hildon_color_chooser_dialog_set_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &color_button->color);
+ gtk_widget_show(dialog);
+
+
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+
+
+ if(result == GTK_RESPONSE_OK) {
+ hildon_color_chooser_dialog_get_color(HILDON_COLOR_CHOOSER_DIALOG(dialog), &color);
+ hildon_color_chooser_button_virtual_set_color(color_button, &color);
+ }
+
+
+/*g_object_unref(G_OBJECT(dialog));*/
+ gtk_widget_destroy(dialog);
+}
+
+
+ /* signal handlers */
+static gboolean hildon_color_chooser_button_area_expose(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+ HildonColorChooserButton *button = HILDON_COLOR_CHOOSER_BUTTON(data);
+ GtkWidget *button_widget = GTK_WIDGET(data);
+
+
+ if(button->style_info.inner.left > 0 || button->style_info.inner.right > 0 ||
+ button->style_info.inner.top > 0 || button->style_info.inner.bottom > 0) {
+ gtk_paint_box(gtk_widget_get_style(button_widget), widget->window, GTK_WIDGET_STATE(button_widget), GTK_SHADOW_NONE,
+ &event->area, button_widget, "color-button", 0, 0, widget->allocation.width, widget->allocation.height);
+ }
+
+
+ gdk_draw_rectangle(widget->window, button->color_gc, TRUE, event->area.x, event->area.y, event->area.width, event->area.height);
+
+
+ return FALSE;
+}
+
+
+ /* additional use-only-here functions */
+static void hildon_color_chooser_button_helper_get_style_info(HildonColorChooserButton *button)
+{
+ GtkBorder *in, *out, *min;
+
+ gtk_widget_style_get(GTK_WIDGET(button), "inner_border", &in,
+ "outer_border", &out,
+ "minimum_size", &min, NULL);
+
+
+ if(in) {
+ button->style_info.inner = *in;
+ g_free(in);
+ } else {
+ button->style_info.inner.left = 0;
+ button->style_info.inner.right = 0;
+ button->style_info.inner.top = 0;
+ button->style_info.inner.bottom = 0;
+ }
+
+ if(out) {
+ button->style_info.outer = *out;
+ g_free(out);
+ } else {
+ button->style_info.outer.left = 4;
+ button->style_info.outer.right = 4;
+ button->style_info.outer.top = 4;
+ button->style_info.outer.bottom = 4;
+ }
+
+ if(min) {
+ button->style_info.min = *min;
+ g_free(min);
+ } else {
+ button->style_info.min.left = 8;
+ button->style_info.min.right = 8;
+ button->style_info.min.top = 0;
+ button->style_info.min.bottom = 0;
+ }
+}
+
+
+ /* public API */
+GtkWidget *hildon_color_chooser_button_new()
+{
+ return gtk_type_new(HILDON_TYPE_COLOR_CHOOSER_BUTTON);
+}
+
+
+void hildon_color_chooser_button_set_color(HildonColorChooserButton *button, GdkColor *color)
+{
+ HILDON_COLOR_CHOOSER_BUTTON_CLASS(G_OBJECT_GET_CLASS(button))->set_color(button, color);
+}
+
+void hildon_color_chooser_button_get_color(HildonColorChooserButton *button, GdkColor *color)
+{
+ *color = button->color;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_COLOR_CHOOSER_BUTTON_H__
+#define __HILDON_COLOR_CHOOSER_BUTTON_H__
+
+
+#include <gdk/gdkcolor.h>
+
+#include <gtk/gtkwidget.h>
+
+
+#define HILDON_TYPE_COLOR_CHOOSER_BUTTON (hildon_color_chooser_button_get_type())
+
+#define HILDON_COLOR_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER_BUTTON, HildonColorChooserButton))
+#define HILDON_COLOR_CHOOSER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER_BUTTON, HildonColorChooserButtonClass))
+#define HILDON_IS_COLOR_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER_BUTTON))
+
+
+typedef struct HildonColorChooserButton_ HildonColorChooserButton;
+typedef struct HildonColorChooserButtonClass_ HildonColorChooserButtonClass;
+
+
+struct HildonColorChooserButton_
+{
+ GtkButton parent;
+
+ GdkColor color;
+
+ GtkWidget *area;
+
+ GdkGC *color_gc;
+
+
+ struct {
+ GtkBorder outer;
+ GtkBorder inner;
+ GtkBorder min;
+ } style_info;
+};
+
+struct HildonColorChooserButtonClass_
+{
+ GtkButtonClass parent;
+
+ void (*color_changed) (HildonColorChooserButton *button, GdkColor *color);
+
+ void (*set_color) (HildonColorChooserButton *, GdkColor *);
+};
+
+
+GtkType hildon_color_chooser_button_get_type();
+GtkWidget *hildon_color_chooser_button_new();
+
+void hildon_color_chooser_button_set_color(HildonColorChooserButton *button, GdkColor *color);
+void hildon_color_chooser_button_get_color(HildonColorChooserButton *button, GdkColor *color);
+
+
+#endif /* __HILDON_COLOR_CHOOSER_BUTTON_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+/**
+ * SECTION:hildon-color-chooser-dialog
+ * @short_description: A dialog to choose a color.
+ * @see_also: #HildonColorButton, #HildonColorChooser
+ *
+ * HildonColorChooserDialog is a widget widget to choose a color.
+ */
+#include <gtk/gtk.h>
+
+
+#include "hildon-color-chooser-dialog.h"
+
+#include "hildon-plugin-widget.h"
+
+
+enum {
+ COLOR_CHANGED,
+ LAST_SIGNAL
+};
+
+
+static HildonPluginWidgetInfo *global_plugin = NULL;
+
+
+static guint color_chooser_dialog_signals[LAST_SIGNAL] = { 0 };
+
+
+static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object);
+static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass);
+
+
+GtkType hildon_color_chooser_dialog_get_type ()
+{
+ static GtkType chooser_type = 0;
+
+ if (!chooser_type)
+ {
+ static const GtkTypeInfo chooser_info =
+ {
+ "HildonColorChooserDialog",
+ sizeof (HildonColorChooserDialog),
+ sizeof (HildonColorChooserDialogClass),
+ (GtkClassInitFunc) hildon_color_chooser_dialog_class_init,
+ (GtkObjectInitFunc) hildon_color_chooser_dialog_init,
+ /* reserved_1 */ NULL,
+ /* reserved_1 */ NULL,
+ (GtkClassInitFunc) NULL
+ };
+
+ chooser_type = gtk_type_unique (GTK_TYPE_DIALOG, &chooser_info);
+ }
+
+ return chooser_type;
+}
+
+
+static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object)
+{
+ int i;
+
+
+ object->color.red = 0x0000;
+ object->color.green = 0x0000;
+ object->color.blue = 0x0000;
+ object->color.pixel = 0x00000000;
+
+
+ for(i = 0; i < 32; i++) {
+ object->reserved[i] = 0;
+ }
+}
+
+static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass)
+{
+ GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
+ int i;
+
+
+ for(i = 0; i < 32; i++) {
+ klass->reserved[i] = 0;
+ }
+
+ klass->set_color = 0;
+
+
+ color_chooser_dialog_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_klass),
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserDialogClass, color_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
+}
+
+/**
+ * hildon_color_chooser_dialog_new:
+ *
+ * Creates a new color chooser dialog. The dialog is created through
+ * HildonPluginWidget API and is loaded from plugin. The initially selected
+ * color can be anything, so it's recommended to call
+ * hildon_color_chooser_dialog_set_color () after creating the widget.
+ *
+ * Returns: a new color chooser dialog
+ */
+GtkWidget *hildon_color_chooser_dialog_new()
+{
+ if(!global_plugin) {
+ global_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER_DIALOG, NULL);
+ g_return_val_if_fail (global_plugin != NULL, NULL);
+ }
+
+ return hildon_plugin_info_construct_widget(global_plugin);
+}
+
+/**
+ * hildon_color_chooser_dialog_set_color:
+ * @chooser: a #HildonColorChooserDialog
+ * @color: a color to be set
+ *
+ * Sets the color selected in the dialog.
+ */
+void hildon_color_chooser_dialog_set_color(HildonColorChooserDialog *chooser, GdkColor *color)
+{
+ HildonColorChooserDialogClass *klass = HILDON_COLOR_CHOOSER_DIALOG_CLASS(G_OBJECT_GET_CLASS(chooser));
+
+
+ chooser->color = *color;
+
+ if(klass->set_color) {
+ klass->set_color(chooser, color);
+ }
+}
+
+/**
+ * hildon_color_chooser_dialog_get_color:
+ * @chooser: a #HildonColorChooserDialog
+ * @color: a pointer to #GdkColor to be filled by the function
+ *
+ * Gets the color selected in the dialog.
+ */
+void hildon_color_chooser_dialog_get_color(HildonColorChooserDialog *chooser, GdkColor *color)
+{
+ *color = chooser->color;
+}
+
+
+void hildon_color_chooser_dialog_emit_color_changed(HildonColorChooserDialog *chooser)
+{
+ g_signal_emit(chooser, color_chooser_dialog_signals[COLOR_CHANGED], 0, &chooser->color);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_COLOR_CHOOSER_DIALOG_H__
+#define __HILDON_COLOR_CHOOSER_DIALOG_H__
+
+
+#include <gdk/gdkcolor.h>
+
+#include <gtk/gtkdialog.h>
+
+
+#define HILDON_TYPE_COLOR_CHOOSER_DIALOG (hildon_color_chooser_dialog_get_type())
+
+#define HILDON_COLOR_CHOOSER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER_DIALOG, HildonColorChooserDialog))
+#define HILDON_COLOR_CHOOSER_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER_DIALOG, HildonColorChooserDialogClass))
+#define HILDON_IS_COLOR_CHOOSER_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER_DIALOG))
+
+
+typedef struct HildonColorChooserDialog_ HildonColorChooserDialog;
+typedef struct HildonColorChooserDialogClass_ HildonColorChooserDialogClass;
+
+
+struct HildonColorChooserDialog_ {
+ GtkDialog parent;
+
+ GdkColor color;
+
+ guint32 reserved[32];
+};
+
+struct HildonColorChooserDialogClass_ {
+ GtkDialogClass parent_class;
+
+ gboolean (*color_changed) (HildonColorChooserDialog *chooser, GdkColor *color);
+
+ void (*set_color) (HildonColorChooserDialog *, GdkColor *);
+
+ void (*reserved[32]) (void *);
+};
+
+
+GtkType hildon_color_chooser_dialog_get_type();
+
+GtkWidget *hildon_color_chooser_dialog_new();
+
+void hildon_color_chooser_dialog_set_color(HildonColorChooserDialog *chooser, GdkColor *color);
+void hildon_color_chooser_dialog_get_color(HildonColorChooserDialog *chooser, GdkColor *color);
+
+void hildon_color_chooser_dialog_emit_color_changed(HildonColorChooserDialog *chooser);
+
+
+#endif /* __HILDON_COLOR_CHOOSER_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+/**
+ * SECTION:hildon-color-chooser
+ * @short_description: A widget to choose a color.
+ * @see_also: #HildonColorChooserDialog, #HildonColorButton
+ *
+ * HildonColorChooser is a widget to choose a color.
+ */
+#include <gtk/gtk.h>
+
+
+#include "hildon-color-chooser.h"
+
+#include "hildon-plugin-widget.h"
+
+
+enum {
+ COLOR_CHANGED,
+ LAST_SIGNAL
+};
+
+
+static HildonPluginWidgetInfo *global_plugin = NULL;
+
+
+static guint color_chooser_signals[LAST_SIGNAL] = { 0 };
+
+
+static void hildon_color_chooser_init(HildonColorChooser *sel);
+static void hildon_color_chooser_class_init(HildonColorChooserClass *klass);
+
+
+GtkType hildon_color_chooser_get_type ()
+{
+ static GtkType chooser_type = 0;
+
+ if (!chooser_type)
+ {
+ static const GtkTypeInfo chooser_info =
+ {
+ "HildonColorChooser",
+ sizeof (HildonColorChooser),
+ sizeof (HildonColorChooserClass),
+ (GtkClassInitFunc) hildon_color_chooser_class_init,
+ (GtkObjectInitFunc) hildon_color_chooser_init,
+ /* reserved_1 */ NULL,
+ /* reserved_1 */ NULL,
+ (GtkClassInitFunc) NULL
+ };
+
+ chooser_type = gtk_type_unique (GTK_TYPE_WIDGET, &chooser_info);
+ }
+
+ return chooser_type;
+}
+
+
+static void hildon_color_chooser_init(HildonColorChooser *sel)
+{
+ sel->color.red = 0x0000;
+ sel->color.green = 0x0000;
+ sel->color.blue = 0x0000;
+ sel->color.pixel = 0x00000000;
+}
+
+static void hildon_color_chooser_class_init(HildonColorChooserClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS(klass);
+
+ klass->set_color = NULL;
+
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_boxed("outer_border",
+ "Outer border",
+ "Size of outer border",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ color_chooser_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserClass, color_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
+}
+
+/**
+ * hildon_color_chooser_new:
+ *
+ * Creates a new color chooser widget. The dialog is created through
+ * HildonPluginWidget API and is loaded from plugin. The initially selected
+ * color can be anything, so it's recommended to call
+ * hildon_color_chooser_dialog_set_color () after creating the widget.
+ *
+ * Returns: a new color chooser widget
+ */
+GtkWidget *hildon_color_chooser_new()
+{
+ if(!global_plugin) {
+ global_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER, NULL);
+ }
+
+
+ return hildon_plugin_info_construct_widget(global_plugin);
+}
+
+/**
+ * hildon_color_chooser_set_color:
+ * @chooser: a #HildonColorChooser
+ * @color: a color to be set
+ *
+ * Sets the color selected in the widget.
+ */
+void hildon_color_chooser_set_color(HildonColorChooser *chooser, GdkColor *color)
+{
+ HildonColorChooserClass *klass = HILDON_COLOR_CHOOSER_CLASS(G_OBJECT_GET_CLASS(chooser));
+
+
+ chooser->color = *color;
+
+ if(klass->set_color) {
+ klass->set_color(chooser, color);
+ }
+}
+
+/**
+ * hildon_color_chooser_get_color:
+ * @chooser: a #HildonColorChooser
+ * @color: a pointer to #GdkColor to be filled by the function
+ *
+ * Gets the color selected in the widget.
+ */
+void hildon_color_chooser_get_color(HildonColorChooser *chooser, GdkColor *color)
+{
+ *color = chooser->color;
+}
+
+
+void hildon_color_chooser_emit_color_changed(HildonColorChooser *chooser)
+{
+ g_signal_emit(chooser, color_chooser_signals[COLOR_CHANGED], 0, &chooser->color);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_COLOR_CHOOSER_H__
+#define __HILDON_COLOR_CHOOSER_H__
+
+
+#include <gdk/gdkcolor.h>
+
+#include <gtk/gtkwidget.h>
+
+
+#define HILDON_TYPE_COLOR_CHOOSER (hildon_color_chooser_get_type())
+
+#define HILDON_COLOR_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HILDON_TYPE_COLOR_CHOOSER, HildonColorChooser))
+#define HILDON_COLOR_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_CHOOSER, HildonColorChooserClass))
+#define HILDON_IS_COLOR_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HILDON_TYPE_COLOR_CHOOSER))
+
+
+typedef struct HildonColorChooser_ HildonColorChooser;
+typedef struct HildonColorChooserClass_ HildonColorChooserClass;
+
+
+struct HildonColorChooser_
+{
+ GtkWidget parent;
+
+ GdkColor color;
+};
+
+struct HildonColorChooserClass_
+{
+ GtkWidgetClass parent;
+
+ void (*color_changed) (HildonColorChooser *selection, GdkColor *color);
+
+ void (*set_color) (HildonColorChooser *, GdkColor *);
+};
+
+
+GtkType hildon_color_chooser_get_type(void);
+GtkWidget *hildon_color_chooser_new(void);
+
+void hildon_color_chooser_set_color(HildonColorChooser *chooser, GdkColor *color);
+void hildon_color_chooser_get_color(HildonColorChooser *chooser, GdkColor *color);
+
+void hildon_color_chooser_emit_color_changed(HildonColorChooser *chooser);
+
+
+#endif /* __HILDON_COLOR_CHOOSER_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-color-popup
+ * @short_description: A popup dialog for editing a color and showing the
+ * edited result
+ * @see_also: #HildonColorButton, #HildonColorSelector
+ *
+ * #HildonColorPopup is only used inside #HildonColorButton. It is a
+ * popup dialog for editing a color. The color can be changed using
+ * three control bars that are used to adjust the red, green and blue
+ * color channels. The display is updated in real time when the bars are
+ * moved.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtkbox.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkdrawingarea.h>
+
+#include "hildon-color-selector.h"
+#include "hildon-color-popup.h"
+#include "hildon-controlbar.h"
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+/* Pixel sizes */
+#define HILDON_COLOR_PALETTE_SIZE 120
+#define HILDON_COLOR_CONTROLBAR_MAX 31
+#define HILDON_COLOR_CONTROLBAR_MIN 0
+#define HILDON_COLOR_LABELS_LEFT_PAD 35
+#define HILDON_COLOR_PALETTE_POS_PAD 45
+#define HILDON_COLOR_BAR_WIDTH 449
+#define HILDON_COLOR_COL_SPACING 18
+
+/*
+ * Private function prototype definitions
+ */
+
+static gboolean
+hildon_popup_palette_expose (GtkWidget * widget,
+ GdkEventExpose * event,
+ gpointer data);
+/**
+ * hildon_color_popup_new:
+ * @parent: the parent window of the dialog
+ * @initial_color: a #GdkColor with the initial values to be used
+ * @popup_data: a #HildonColorPopup
+ *
+ * This function creates a new popup dialog with three controlbars
+ * (red, green, blue) and a drawing area with the current color.
+ *
+ * Used as normal GtkDialog (run with gtk_dialog_run() and read
+ * stardard responses (GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL).
+ *
+ * Returns: the newly created popup dialog
+ */
+
+GtkWidget *
+hildon_color_popup_new(GtkWindow *parent, const GdkColor *initial_color,
+ HildonColorPopup *popup_data)
+{
+ GtkWidget *popup;
+ GtkTable *layout;
+ GtkWidget *area;
+ GtkWidget *l_red, *l_green, *l_blue;
+
+ /* Create control bars for HildonColorPopup */
+ popup_data->ctrlbar_red = hildon_controlbar_new ();
+ popup_data->ctrlbar_green = hildon_controlbar_new ();
+ popup_data->ctrlbar_blue = hildon_controlbar_new ();
+ area = gtk_drawing_area_new();
+ layout = GTK_TABLE(gtk_table_new(12, 2, FALSE));
+
+ /* Set widgets' size */
+ gtk_widget_set_size_request (area,
+ HILDON_COLOR_PALETTE_SIZE,
+ HILDON_COLOR_PALETTE_SIZE);
+ gtk_widget_set_size_request(popup_data->ctrlbar_red,
+ HILDON_COLOR_BAR_WIDTH, -1);
+ gtk_widget_set_size_request(popup_data->ctrlbar_green,
+ HILDON_COLOR_BAR_WIDTH, -1);
+ gtk_widget_set_size_request(popup_data->ctrlbar_blue,
+ HILDON_COLOR_BAR_WIDTH, -1);
+
+ /* Create labels for three kinds of color */
+ l_red = gtk_label_new(_("ecdg_fi_5bit_colour_selector_red"));
+ l_green = gtk_label_new(_("ecdg_fi_5bit_colour_selector_green"));
+ l_blue = gtk_label_new(_("ecdg_fi_5bit_colour_selector_blue"));
+
+ /* Position the labels to start about the same label as the controlbars */
+ gtk_misc_set_alignment(GTK_MISC(l_red), 0.08f, 0.5f);
+ gtk_misc_set_alignment(GTK_MISC(l_green), 0.08f, 0.5f);
+ gtk_misc_set_alignment(GTK_MISC(l_blue), 0.08f, 0.5f);
+
+ /* Add labels and control bars to the layout table */
+ gtk_table_set_col_spacing(layout, 0, HILDON_COLOR_COL_SPACING);
+ gtk_table_attach_defaults(layout, l_red, 0, 1, 0, 2);
+ gtk_table_attach_defaults(layout, popup_data->ctrlbar_red, 0, 1, 2, 4);
+ gtk_table_attach_defaults(layout, l_green, 0, 1, 4, 6);
+ gtk_table_attach_defaults(layout, popup_data->ctrlbar_green, 0, 1, 6, 8);
+ gtk_table_attach_defaults(layout, l_blue, 0, 1, 8, 10);
+ gtk_table_attach_defaults(layout, popup_data->ctrlbar_blue, 0, 1, 10, 12);
+ gtk_table_attach(layout, area, 1, 2, 3, 11, GTK_SHRINK, GTK_SHRINK, 0, 0);
+
+ /* Give the maximum and minimum limits for each control bar */
+ hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_red),
+ HILDON_COLOR_CONTROLBAR_MIN,
+ HILDON_COLOR_CONTROLBAR_MAX);
+ hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_green),
+ HILDON_COLOR_CONTROLBAR_MIN,
+ HILDON_COLOR_CONTROLBAR_MAX);
+ hildon_controlbar_set_range (HILDON_CONTROLBAR(popup_data->ctrlbar_blue),
+ HILDON_COLOR_CONTROLBAR_MIN,
+ HILDON_COLOR_CONTROLBAR_MAX);
+
+ /* Give the initial values for each control bar */
+ hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_red),
+ (initial_color->red >> 11)&0x1F);
+ hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_green),
+ (initial_color->green >> 11)&0x1F);
+ hildon_controlbar_set_value (HILDON_CONTROLBAR(popup_data->ctrlbar_blue),
+ (initial_color->blue >> 11)&0x1F);
+
+ /* Register controlbar callbacks */
+ g_signal_connect_swapped(popup_data->ctrlbar_red, "value-changed",
+ G_CALLBACK(gtk_widget_queue_draw), area);
+ g_signal_connect_swapped(popup_data->ctrlbar_green, "value-changed",
+ G_CALLBACK(gtk_widget_queue_draw), area);
+ g_signal_connect_swapped(popup_data->ctrlbar_blue, "value-changed",
+ G_CALLBACK(gtk_widget_queue_draw), area);
+
+ /* Attach expose_event callback function to drawing area */
+ g_signal_connect (area, "expose_event",
+ G_CALLBACK(hildon_popup_palette_expose),
+ popup_data);
+
+ /* Create popup dialog */
+ popup = gtk_dialog_new_with_buttons (_("ecdg_ti_5bit_colour_selector"),
+ GTK_WINDOW(parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT |
+ GTK_DIALOG_NO_SEPARATOR,
+ _("ecdg_bd_5bit_colour_selector_ok"), GTK_RESPONSE_OK,
+ _("ecdg_bd_5bit_colour_selector_cancel"),
+ GTK_RESPONSE_CANCEL,
+ NULL);
+
+ /* Select-key shouldn't do anything unless dialog's button is focused */
+ gtk_dialog_set_default_response(GTK_DIALOG(popup), GTK_RESPONSE_NONE);
+
+ /* Add layout table to the Vbox of the popup dialog */
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(popup)->vbox),
+ GTK_WIDGET(layout), TRUE, TRUE, 0);
+
+ /* Show thw Vbox of the popup dialog */
+ gtk_widget_show_all(GTK_DIALOG(popup)->vbox);
+
+ return popup;
+}
+
+/**
+ * hildon_color_popup_set_color_from_sliders:
+ * @color: a pointer to #GdkColor to which the new values will be put
+ * @popup_data: a #HildonColorPopup
+ *
+ * Sets the values in the given #GdkColor to the values of the
+ * controlbars.
+ */
+
+void
+hildon_color_popup_set_color_from_sliders(GdkColor *color,
+ HildonColorPopup *popup_data)
+{
+ color->pixel = 0;
+ color->red = hildon_controlbar_get_value (
+ HILDON_CONTROLBAR(popup_data->ctrlbar_red)) << 11;
+ color->green = hildon_controlbar_get_value (
+ HILDON_CONTROLBAR(popup_data->ctrlbar_green)) << 11;
+ color->blue = hildon_controlbar_get_value (
+ HILDON_CONTROLBAR(popup_data->ctrlbar_blue)) << 11;
+}
+
+/* expose_event callback function */
+static gboolean
+hildon_popup_palette_expose (GtkWidget * widget,
+ GdkEventExpose *event, gpointer data)
+{
+ if (GTK_WIDGET_DRAWABLE(widget))
+ {
+ GdkColor color;
+ GdkGC * gc = gdk_gc_new (widget->window);
+
+ /* Get the current color value */
+ hildon_color_popup_set_color_from_sliders(&color, data);
+ gdk_gc_set_rgb_fg_color(gc, &color);
+
+ /* draw the color area */
+ gdk_draw_rectangle( widget->window, gc, TRUE /* filled */,
+ 1, 1, widget->allocation.width - 2,
+ widget->allocation.height - 2);
+
+ color.pixel = color.red = color.green = color.blue = 0;
+ gdk_gc_set_rgb_fg_color(gc, &color);
+
+ /* Draw frames on color box */
+ gdk_draw_rectangle( widget->window, gc, FALSE,
+ 0, 0, widget->allocation.width - 1,
+ widget->allocation.height - 1);
+
+ /* Free memory used by the graphics contexts */
+ g_object_unref(gc);
+ }
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_COLOR_POPUP_H__
+#define __HILDON_COLOR_POPUP_H__
+
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ GtkWidget *ctrlbar_red;
+ GtkWidget *ctrlbar_green;
+ GtkWidget *ctrlbar_blue;
+
+} HildonColorPopup;
+
+GtkWidget *hildon_color_popup_new(GtkWindow *parent,
+ const GdkColor *initial_color,
+ HildonColorPopup *popupdata);
+
+void hildon_color_popup_set_color_from_sliders(GdkColor *color,
+ HildonColorPopup *popupdata);
+
+
+G_END_DECLS
+
+#endif /* __HILDON_COLOR_POPUP_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-color-selector
+ * @short_description: A widget for selecting a color
+ * @see_also: #HildonColorButton, #HildonColorPopup
+ *
+ * #HildonColorSelector allows selection of a color from a standard
+ * 16-color palette or a palette of 8 user-customizable colors.
+ * The user-customizable colors can be modified through HildonColorPopup.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtktable.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkdrawingarea.h>
+#include <gtk/gtkbutton.h>
+#include <gdk/gdkkeysyms.h>
+#include <gconf/gconf-client.h>
+
+#include "hildon-color-selector.h"
+#include "hildon-color-popup.h"
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+/* Color amounts */
+#define HILDON_BASE_COLOR_NUM 16
+#define HILDON_CUSTOM_COLOR_NUM 8
+#define HILDON_TOTAL_COLOR_NUM (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM)
+#define BLACKIND 0
+#define GREYIND 6
+#define WHITEIND 9
+
+#define SELECTION_BORDER_COLOR_NAME "ImageBorderColor"
+#define FOCUS_BORDER_COLOR "#8080FF"
+#define FOCUS_BORDER_WIDTH 2
+
+/* Pixel sizes */
+#define HILDON_COLOR_SELECTOR_BOX_W 26
+#define HILDON_COLOR_SELECTOR_BOX_H 26
+#define HILDON_COLOR_SELECTOR_BORDER_WIDTH 1
+#define HILDON_COLOR_SELECTOR_PADDING_WIDTH 1
+
+#define HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH \
+ ( HILDON_COLOR_SELECTOR_BOX_W \
+ + HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 \
+ + HILDON_COLOR_SELECTOR_PADDING_WIDTH * 2 )
+
+#define HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT \
+ ( HILDON_COLOR_SELECTOR_BOX_H \
+ + HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 \
+ + HILDON_COLOR_SELECTOR_PADDING_WIDTH * 2 )
+
+#define HILDON_COLOR_SELECTOR_COLS 8
+#define HILDON_COLOR_SELECTOR_ROWS 3
+
+/* gconf definitions */
+#define HILDON_COLOR_GCONF_PATH "/system/osso/af/color_selector"
+#define HILDON_COLOR_GCONF_KEYS "/system/osso/af/color_selector/custom_colors"
+
+/* Pointer parent class */
+static GtkDialogClass *parent_class;
+
+struct _HildonColorSelectorPriv
+{
+ GConfClient *client;
+ GtkWidget *drawing_area;
+ GtkWidget *modify_button;
+ gint selected_index;
+ gint focused_index;
+ guint notify_id;
+ /* one extra place for the modified base color */
+ GdkColor color[HILDON_TOTAL_COLOR_NUM + 1];
+};
+
+enum
+{
+ PROP_NONE,
+ PROP_COLOR
+};
+
+/*
+ * Private function prototype definitions
+ */
+static void
+hildon_color_selector_class_init (HildonColorSelectorClass * selector_class);
+
+static void
+hildon_color_selector_init (HildonColorSelector * selector);
+
+static gboolean
+hildon_color_selector_expose (GtkWidget * widget,
+ GdkEventExpose * event,
+ gpointer data);
+
+static gboolean key_pressed (GtkWidget * widget,
+ GdkEventKey * event);
+
+static gboolean color_pressed (GtkWidget * widget,
+ GdkEventButton * event,
+ gpointer user_data);
+
+static void select_color_index (HildonColorSelector *selector,
+ gint idx,
+ gboolean motion);
+
+static void select_color (HildonColorSelector * selector,
+ int event_x,
+ int event_y,
+ gboolean motion);
+
+static gboolean color_moved (GtkWidget * widget,
+ GdkEventMotion * event,
+ gpointer data);
+
+static void
+modify_button_clicked (GtkWidget * button,
+ HildonColorSelector * selector);
+
+static void modify_focused(HildonColorSelector * colselector);
+
+static void
+hildon_color_selector_set_property(GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void
+hildon_color_selector_get_property(GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+GType
+hildon_color_selector_get_type(void)
+{
+ static GType selector_type = 0;
+
+ if (!selector_type)
+ {
+ static const GTypeInfo selector_info =
+ {
+ sizeof(HildonColorSelectorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_color_selector_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonColorSelector),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_color_selector_init,
+ };
+
+ selector_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonColorSelector",
+ &selector_info, 0);
+ }
+ return selector_type;
+}
+
+static void
+hildon_color_selector_destroy(GtkObject *obj)
+{
+ HildonColorSelectorPriv *priv = HILDON_COLOR_SELECTOR(obj)->priv;
+
+ if (priv->client)
+ {
+ gconf_client_notify_remove(priv->client, priv->notify_id);
+ g_object_unref(priv->client);
+ priv->client = NULL;
+ }
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(obj);
+}
+
+static void
+hildon_color_selector_class_init(HildonColorSelectorClass * selector_class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(selector_class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (selector_class);
+
+ parent_class = g_type_class_peek_parent(selector_class);
+
+ widget_class->key_press_event = key_pressed;
+
+ g_type_class_add_private(selector_class,
+ sizeof(HildonColorSelectorPriv));
+
+ GTK_OBJECT_CLASS(selector_class)->destroy = hildon_color_selector_destroy;
+
+ gobject_class->get_property = hildon_color_selector_get_property;
+ gobject_class->set_property = hildon_color_selector_set_property;
+
+ /**
+ * HildonColorSelector:color:
+ *
+ * The selected color.
+ */
+ g_object_class_install_property (gobject_class, PROP_COLOR,
+ g_param_spec_boxed ("color",
+ "Current Color",
+ "The selected color",
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+}
+
+
+/**
+ * hildon_color_selector_new:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application
+ *
+ * Creates a new #HildonColorSelector dialog with 3x8 layout of
+ * base colors and 'OK', 'More..' and 'Cancel' buttons.
+ *
+ * Returns: new #HildonColorSelector
+ **/
+GtkWidget *hildon_color_selector_new(GtkWindow * parent)
+{
+ GtkWidget *dialog = g_object_new(HILDON_TYPE_COLOR_SELECTOR, NULL);
+
+ g_return_val_if_fail(dialog, NULL);
+
+ if (parent)
+ {
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+ }
+
+ return dialog;
+}
+
+static void
+hildon_color_selector_set_custom_colors(
+ HildonColorSelector *selector,
+ GConfValue *value)
+{
+ GSList *list;
+ gint i;
+
+ g_assert(HILDON_IS_COLOR_SELECTOR(selector));
+
+ /* We have to be really careful. At least gconftool's
+ stress test may generate unexpected value setups */
+ if (value == NULL
+ || value->type != GCONF_VALUE_LIST
+ || gconf_value_get_list_type(value) != GCONF_VALUE_STRING)
+ list = NULL;
+ else
+ list = gconf_value_get_list(value);
+
+ /* Use list to fill in the selector's color property */
+ for ( i = 0; i < HILDON_CUSTOM_COLOR_NUM; ++i)
+ {
+ const gchar *color_string = NULL;
+
+ if (list) {
+ color_string = gconf_value_get_string(list->data);
+ list = list->next;
+ } else {
+ color_string = "#FFFFFF";
+ }
+
+/* g_print("custom_color: %s\n", color_string); */
+
+ selector->priv->color[i].pixel = 0;
+ gdk_color_parse (color_string,
+ &(selector->priv->color[HILDON_BASE_COLOR_NUM+i]));
+ }
+}
+
+static void
+gconf_notify_func(GConfClient *client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer data)
+{
+ hildon_color_selector_set_custom_colors(HILDON_COLOR_SELECTOR(data),
+ gconf_entry_get_value(entry));
+ gtk_widget_queue_draw(GTK_WIDGET(data));
+}
+
+static void
+hildon_color_selector_init(HildonColorSelector * selector)
+{
+ guint i;
+ GtkWidget *hbox;
+ GConfValue *value;
+
+ /* 16 standard Windows colors */
+ const char base_colours[][HILDON_BASE_COLOR_NUM] = {
+ "#000000", "#FFFFFF", "#FF0000", "#660000", "#0000FF", "#000066",
+ "#FF33FF", "#660066", "#33CC33", "#006600", "#FFCC00", "#CC9900",
+ "#999999", "#666666", "#00CCCC", "#006666"
+ };
+
+ selector->priv =
+ G_TYPE_INSTANCE_GET_PRIVATE(selector,
+ HILDON_TYPE_COLOR_SELECTOR,
+ HildonColorSelectorPriv);
+
+ /* ***********test GConf*********** */
+ selector->priv->client = gconf_client_get_default ();
+ gconf_client_set_error_handling (selector->priv->client,
+ GCONF_CLIENT_HANDLE_UNRETURNED);
+
+ /* Add our directory to the list of directories the GConfClient will
+ watch. */
+ gconf_client_add_dir (selector->priv->client, HILDON_COLOR_GCONF_PATH,
+ GCONF_CLIENT_PRELOAD_NONE,
+ NULL);
+
+ /* Use the value directed by GConfValue to set the color */
+ value = gconf_client_get(selector->priv->client,
+ HILDON_COLOR_GCONF_KEYS, NULL);
+
+ hildon_color_selector_set_custom_colors(selector, value);
+
+ if (value) {
+ gconf_value_free(value);
+ }
+
+ /* Listen to changes to our key. */
+ selector->priv->notify_id = gconf_client_notify_add (selector->priv->client,
+ HILDON_COLOR_GCONF_KEYS, gconf_notify_func, selector, NULL, NULL);
+
+ /* ************************************ */
+
+ selector->priv->selected_index = GREYIND;
+ selector->priv->focused_index = GREYIND;
+
+ /* init base colors for color boxes */
+ for (i = 0; i < HILDON_BASE_COLOR_NUM; ++i)
+ {
+ selector->priv->color[i].pixel = 0;
+ gdk_color_parse (base_colours[i], &(selector->priv->color[i]));
+ }
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(selector), FALSE);
+
+ /* create drawing area */
+ hbox = gtk_hbox_new(TRUE, 0);
+ selector->priv->drawing_area = gtk_drawing_area_new();
+
+ /* receive focus from dialog buttons */
+ GTK_WIDGET_SET_FLAGS (selector->priv->drawing_area, GTK_CAN_FOCUS);
+
+ gtk_widget_add_events (selector->priv->drawing_area,
+ GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
+
+ /* Arrange size of the drawing area. */
+ gtk_widget_set_size_request (selector->priv->drawing_area,
+ (HILDON_COLOR_SELECTOR_COLS *
+ HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH),
+ (HILDON_COLOR_SELECTOR_ROWS *
+ HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT));
+
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(selector)->vbox),
+ hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), selector->priv->drawing_area,
+ FALSE, FALSE, 0);
+
+ /* Register callback functions for the drawing area */
+ g_signal_connect (selector->priv->drawing_area, "expose_event",
+ G_CALLBACK(hildon_color_selector_expose), selector);
+ g_signal_connect (selector->priv->drawing_area, "button_press_event",
+ G_CALLBACK(color_pressed), selector);
+ g_signal_connect (selector->priv->drawing_area, "motion-notify-event",
+ G_CALLBACK(color_moved), selector);
+
+ gtk_dialog_add_button (GTK_DIALOG(selector),
+ _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
+
+ selector->priv->modify_button =
+ gtk_button_new_with_label(_("ecdg_bd_colour_selector_modify"));
+ gtk_widget_set_sensitive(selector->priv->modify_button, FALSE);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(selector)->action_area),
+ selector->priv->modify_button, FALSE, TRUE, 0);
+
+ g_signal_connect(selector->priv->modify_button, "clicked",
+ G_CALLBACK(modify_button_clicked), selector);
+
+ gtk_dialog_add_button (GTK_DIALOG(selector),
+ _("ecdg_bd_colour_selector_cancel"),
+ GTK_RESPONSE_CANCEL);
+
+ gtk_dialog_set_default_response (GTK_DIALOG(selector), GTK_RESPONSE_OK);
+
+ gtk_window_set_title ( GTK_WINDOW(selector),
+ _("ecdg_ti_colour_selector") );
+ gtk_widget_show_all (GTK_DIALOG(selector)->vbox);
+}
+
+static gboolean
+hildon_color_selector_expose(GtkWidget * widget,
+ GdkEventExpose * event,
+ gpointer data)
+{
+ HildonColorSelector *selector;
+ GdkColor color;
+ GdkGC *gc, *gc_focus;
+ gint x, y, idx;
+
+ g_return_val_if_fail (GTK_IS_WIDGET(widget), FALSE);
+ g_return_val_if_fail (event, FALSE);
+ g_return_val_if_fail (HILDON_IS_COLOR_SELECTOR(data), FALSE);
+
+ if (!GTK_WIDGET_DRAWABLE(widget))
+ return FALSE;
+
+ selector = HILDON_COLOR_SELECTOR(data);
+ gc = gdk_gc_new (widget->window);
+
+ gc_focus = gdk_gc_new(widget->window);
+ gdk_gc_set_line_attributes(gc_focus, FOCUS_BORDER_WIDTH,
+ GDK_LINE_SOLID, GDK_CAP_BUTT,
+ GDK_JOIN_MITER);
+
+ /* draw the color boxes and a focus for one of them */
+ for (y = 0, idx = 0; y < HILDON_COLOR_SELECTOR_ROWS; ++y)
+ {
+ for (x = 0; x < HILDON_COLOR_SELECTOR_COLS; ++x, ++idx)
+ {
+ gint xpos = x * HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH;
+ gint ypos = y * HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT;
+
+ /* frames on color box */
+ gdk_draw_rectangle(widget->window, widget->style->black_gc, FALSE,
+ xpos + HILDON_COLOR_SELECTOR_PADDING_WIDTH,
+ ypos + HILDON_COLOR_SELECTOR_PADDING_WIDTH,
+ HILDON_COLOR_SELECTOR_BOX_W +
+ HILDON_COLOR_SELECTOR_PADDING_WIDTH,
+ HILDON_COLOR_SELECTOR_BOX_H +
+ HILDON_COLOR_SELECTOR_PADDING_WIDTH);
+
+ /* color box */
+ gdk_gc_set_rgb_fg_color(gc, &(selector->priv->color[idx]));
+ gdk_draw_rectangle(widget->window, gc,
+ TRUE, /* filled */
+ xpos + HILDON_COLOR_SELECTOR_PADDING_WIDTH +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH,
+ ypos + HILDON_COLOR_SELECTOR_PADDING_WIDTH +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH,
+ HILDON_COLOR_SELECTOR_BOX_W,
+ HILDON_COLOR_SELECTOR_BOX_H);
+
+ /* focus around the selected and focused color box */
+ if (idx == selector->priv->selected_index)
+ {
+ /* selected color box */
+ if (!gtk_style_lookup_logical_color(widget->style,
+ SELECTION_BORDER_COLOR_NAME, &color))
+ {
+ /* set default color if color looking up fails */
+ color.red = color.green = color.blue = 0;
+ }
+
+ gdk_gc_set_rgb_fg_color(gc_focus, &color);
+ gdk_draw_rectangle(widget->window, gc_focus, FALSE,
+ xpos + 1-(FOCUS_BORDER_WIDTH % 2),
+ ypos + 1-(FOCUS_BORDER_WIDTH % 2),
+ HILDON_COLOR_SELECTOR_BOX_W +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
+ (FOCUS_BORDER_WIDTH % 2),
+ HILDON_COLOR_SELECTOR_BOX_H +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
+ (FOCUS_BORDER_WIDTH % 2));
+ }
+ else if (idx == selector->priv->focused_index)
+ {
+ /* focused color box.
+ There's only zero or one so allocate GC in here. */
+ gdk_color_parse(FOCUS_BORDER_COLOR, &color);
+
+ gdk_gc_set_rgb_fg_color(gc_focus, &color);
+ gdk_draw_rectangle(widget->window, gc_focus, FALSE,
+ xpos + 1-(FOCUS_BORDER_WIDTH % 2),
+ ypos + 1-(FOCUS_BORDER_WIDTH % 2),
+ HILDON_COLOR_SELECTOR_BOX_W +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
+ (FOCUS_BORDER_WIDTH % 2),
+ HILDON_COLOR_SELECTOR_BOX_H +
+ HILDON_COLOR_SELECTOR_BORDER_WIDTH * 2 +
+ (FOCUS_BORDER_WIDTH % 2));
+ }
+ }
+ }
+
+ g_object_unref(gc);
+ g_object_unref(gc_focus);
+ return TRUE;
+}
+
+/**
+ * hildon_color_selector_get_color:
+ * @selector: a #HildonColorSelector
+ *
+ * Returns: the currently selected #GdkColor. The returned pointer must
+ * not be freed.
+ */
+G_CONST_RETURN GdkColor *hildon_color_selector_get_color(HildonColorSelector * selector)
+{
+ g_return_val_if_fail(HILDON_IS_COLOR_SELECTOR(selector), NULL);
+ return &(selector->priv->color[selector->priv->selected_index]);
+}
+
+/**
+ * hildon_color_selector_set_color:
+ * @selector: #HildonColorSelector
+ * @color: #Gdkcolor to set
+ *
+ * Selects the color specified. Does nothing if the color does not
+ * exist among the standard colors.
+ */
+void hildon_color_selector_set_color(HildonColorSelector * selector,
+ GdkColor * color)
+{
+ gint i;
+
+ g_return_if_fail(HILDON_IS_COLOR_SELECTOR(selector));
+ g_return_if_fail(color);
+
+ /* Select the specified color */
+ for (i = 0;
+ i < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM);
+ ++i)
+ {
+ if (selector->priv->color[i].red == color->red &&
+ selector->priv->color[i].green == color->green &&
+ selector->priv->color[i].blue == color->blue)
+ {
+ selector->priv->selected_index = i;
+ selector->priv->focused_index = i;
+
+ /* The modify button is active if the color index is bigger than
+ * the number of base colours.
+ */
+ gtk_widget_set_sensitive(selector->priv->modify_button,
+ selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
+ gtk_widget_queue_draw(selector->priv->drawing_area);
+ break;
+ }
+ }
+
+ /* Notify the color selector that the color has changed */
+ g_object_notify (G_OBJECT (selector), "color");
+}
+
+static gboolean
+color_pressed(GtkWidget * widget, GdkEventButton * event,
+ gpointer user_data)
+{
+ select_color(HILDON_COLOR_SELECTOR(user_data), event->x, event->y, FALSE);
+ return TRUE;
+}
+
+/* Handle key press of right, left, up, down and return */
+static gboolean key_pressed(GtkWidget * widget,
+ GdkEventKey * event)
+{
+ HildonColorSelector *selector;
+ gint index;
+
+ g_assert(widget);
+
+ selector = HILDON_COLOR_SELECTOR(widget);
+ index = selector->priv->focused_index;
+
+ /* if dialog buttons has the focus */
+ if (GTK_WIDGET_HAS_FOCUS(selector->priv->drawing_area) == FALSE)
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+
+ /* Since wrapping is not allowed,
+ * move only if the next index is a valid one.
+ */
+ switch (event->keyval) {
+ case GDK_KP_Right:
+ case GDK_Right:
+ if (index == (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1)
+ || index == (HILDON_CUSTOM_COLOR_NUM - 1)
+ || index == (2*HILDON_CUSTOM_COLOR_NUM - 1))
+ {
+ return TRUE;
+ }
+ index++;
+ break;
+ case GDK_KP_Left:
+ case GDK_Left:
+ if (index == 0
+ || index == (HILDON_CUSTOM_COLOR_NUM)
+ || index == (2*HILDON_CUSTOM_COLOR_NUM))
+ {
+ return TRUE;
+ }
+ index--;
+ break;
+ case GDK_KP_Up:
+ case GDK_Up:
+ if (index > (HILDON_COLOR_SELECTOR_COLS - 1))
+ {
+ index -= HILDON_COLOR_SELECTOR_COLS;
+ }
+ else
+ {
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+ }
+ break;
+ case GDK_KP_Down:
+ case GDK_Down:
+ if (index < (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM))
+ {
+ index += HILDON_COLOR_SELECTOR_COLS;
+ }
+ else
+ {
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+ }
+ break;
+ case GDK_KP_Enter:
+ case GDK_Return:
+ if (index < HILDON_BASE_COLOR_NUM)
+ select_color_index(selector, selector->priv->focused_index, FALSE);
+ else
+ modify_focused(selector);
+ default:
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+ }
+
+ if (index < (HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM))
+ {
+ selector->priv->focused_index = index;
+ }
+ else
+ {
+ selector->priv->focused_index =
+ HILDON_BASE_COLOR_NUM + HILDON_CUSTOM_COLOR_NUM - 1;
+ }
+ /* The modify button is active if the color index is bigger than
+ * the number of base colours.
+ */
+ gtk_widget_set_sensitive(selector->priv->modify_button,
+ selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
+
+ gtk_widget_queue_draw(selector->priv->drawing_area);
+
+ return TRUE;
+}
+
+static void
+select_color_index(HildonColorSelector * selector, gint idx, gboolean motion)
+{
+ /* If a custom colour is selected, open a popup to modify the colour */
+ if (!motion &&
+ selector->priv->focused_index >= HILDON_BASE_COLOR_NUM &&
+ selector->priv->focused_index == idx)
+ modify_focused(selector);
+
+ selector->priv->focused_index = selector->priv->selected_index = idx;
+ gtk_widget_set_sensitive(selector->priv->modify_button,
+ selector->priv->focused_index >= HILDON_BASE_COLOR_NUM);
+
+ gtk_widget_queue_draw(selector->priv->drawing_area);
+}
+
+static void
+select_color(HildonColorSelector * selector, gint event_x, gint event_y,
+ gboolean motion)
+{
+ gint x, y;
+
+ g_assert(HILDON_IS_COLOR_SELECTOR(selector));
+
+ /* Get the selection coordinates */
+ x = event_x / HILDON_COLOR_SELECTOR_BOX_FULL_WIDTH;
+ y = event_y / HILDON_COLOR_SELECTOR_BOX_FULL_HEIGHT;
+
+ /* Get the row and column numbers for the selected color */
+ if (x > (HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1))
+ {
+ x = HILDON_COLOR_SELECTOR_COLS + HILDON_CUSTOM_COLOR_NUM - 1;
+ }
+ else if (x < 0)
+ {
+ x = 0;
+ }
+ if (y > (HILDON_COLOR_SELECTOR_ROWS - 1))
+ {
+ y = HILDON_COLOR_SELECTOR_ROWS - 1;
+ }
+ else if (y < 0)
+ {
+ y = 0;
+ }
+
+ select_color_index(selector, (x + y * HILDON_COLOR_SELECTOR_COLS), motion);
+}
+
+static gboolean
+color_moved(GtkWidget * widget, GdkEventMotion * event, gpointer data)
+{
+ if ( event->state &
+ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK) )
+ {
+ select_color(HILDON_COLOR_SELECTOR(data), event->x, event->y, TRUE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+modify_button_clicked(GtkWidget * button, HildonColorSelector * selector)
+{
+ modify_focused (selector);
+}
+
+static void
+modify_focused(HildonColorSelector * colselector)
+{
+ HildonColorPopup popupdata;
+ GtkWidget *popup;
+
+ /* Create a HildonColorPopup dialog */
+ popup = hildon_color_popup_new(GTK_WINDOW(colselector),
+ hildon_color_selector_get_color(colselector), &popupdata);
+
+ if ( gtk_dialog_run(GTK_DIALOG(popup) ) == GTK_RESPONSE_OK)
+ {
+ GdkColor *color;
+
+ /* We cannot modify a base color */
+ if (colselector->priv->focused_index < HILDON_BASE_COLOR_NUM)
+ {
+ colselector->priv->color[HILDON_TOTAL_COLOR_NUM] =
+ colselector->priv->color[colselector->priv->focused_index];
+ colselector->priv->focused_index = HILDON_TOTAL_COLOR_NUM;
+ }
+
+ /* Update the focused color with the color selected in color popup */
+ color = &(colselector->priv->color[colselector->priv->focused_index]);
+ hildon_color_popup_set_color_from_sliders(color, &popupdata);
+
+ /* If we modified a base color we just accept the dialog */
+ if( colselector->priv->focused_index >= HILDON_TOTAL_COLOR_NUM)
+ {
+ gtk_dialog_response(GTK_DIALOG(colselector), GTK_RESPONSE_OK);
+ }
+ else /* If we mofied custom colors we have to save to gconf */
+ {
+ GConfValue *value;
+ GSList * list;
+ gint i;
+
+ value = gconf_value_new(GCONF_VALUE_LIST);
+ gconf_value_set_list_type(value, GCONF_VALUE_STRING);
+ list = NULL;
+
+ for ( i = HILDON_BASE_COLOR_NUM; i < HILDON_TOTAL_COLOR_NUM; i++)
+ {
+ GConfValue *item;
+ char buffer[32];
+
+ g_snprintf(buffer, sizeof(buffer), "#%.2X%.2X%.2X",
+ (colselector->priv->color[i].red>>8)&0xFF,
+ (colselector->priv->color[i].green>>8)&0xFF,
+ (colselector->priv->color[i].blue>>8)&0xFF );
+
+ item = gconf_value_new(GCONF_VALUE_STRING);
+ gconf_value_set_string(item, buffer);
+ list = g_slist_append (list, item);
+ }
+
+ gconf_value_set_list_nocopy(value, list);
+
+ /* gconf client handles the possible error */
+ gconf_client_set(colselector->priv->client,
+ HILDON_COLOR_GCONF_KEYS, value, NULL);
+
+ gconf_value_free(value);
+ }
+ }
+
+ gtk_widget_destroy (popup);
+ gtk_window_present (GTK_WINDOW(colselector));
+}
+
+static void
+hildon_color_selector_set_property(GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ HildonColorSelector *selector = HILDON_COLOR_SELECTOR(object);
+
+ switch (param_id)
+ {
+ case PROP_COLOR:
+ hildon_color_selector_set_color(selector, (GdkColor*)g_value_get_boxed(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_color_selector_get_property(GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ HildonColorSelector *selector = HILDON_COLOR_SELECTOR(object);
+
+ switch (param_id)
+ {
+ case PROP_COLOR:
+ g_value_set_boxed(value, (gconstpointer)hildon_color_selector_get_color(selector));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_COLOR_SELECTOR_H__
+#define __HILDON_COLOR_SELECTOR_H__
+
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_COLOR_SELECTOR \
+ ( hildon_color_selector_get_type() )
+#define HILDON_COLOR_SELECTOR(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_COLOR_SELECTOR, HildonColorSelector))
+#define HILDON_COLOR_SELECTOR_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_COLOR_SELECTOR,\
+ HildonColorSelectorClass))
+#define HILDON_IS_COLOR_SELECTOR(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_COLOR_SELECTOR))
+#define HILDON_IS_COLOR_SELECTOR_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_COLOR_SELECTOR_CLASS))
+ GType hildon_color_selector_get_type(void);
+
+typedef struct _HildonColorSelector HildonColorSelector;
+typedef struct _HildonColorSelectorClass HildonColorSelectorClass;
+
+/**
+ * HildonColorSelectorPriv:
+ *
+ * Internal struct for color selector.
+ */
+typedef struct _HildonColorSelectorPriv HildonColorSelectorPriv;
+
+struct _HildonColorSelector {
+ GtkDialog parent;
+ HildonColorSelectorPriv *priv;
+};
+
+struct _HildonColorSelectorClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_color_selector_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_color_selector_new(GtkWindow * parent);
+G_CONST_RETURN GdkColor *hildon_color_selector_get_color(HildonColorSelector * selector);
+void hildon_color_selector_set_color(HildonColorSelector * selector,
+ GdkColor * color);
+
+G_END_DECLS
+#endif /* __HILDON_COLOR_SELECTOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+#include "hildon-composite-widget.h"
+#include "hildon-date-editor.h"
+#include "hildon-time-editor.h"
+
+/* This function is a private function of hildon-libs. It hadles focus
+ * changing for composite hildon widgets: HildonDateEditor,
+ * HildonNumberEditor, HildonTimeEditor, HildonWeekdayPicker.
+ * Its purpose is to focus the first widget (from left) inside the container
+ * regardless of where the focus is coming from.
+ */
+gboolean
+hildon_composite_widget_focus (GtkWidget *widget, GtkDirectionType direction)
+{
+ GtkWidget *toplevel = NULL;
+ GtkWidget *focus_widget = NULL;
+
+ /* Get the topmost parent widget */
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (!GTK_IS_WINDOW(toplevel))
+ return GTK_WIDGET_CLASS (g_type_class_peek_parent (
+ GTK_WIDGET_GET_CLASS (widget)))->focus (widget, direction);
+ /* Get focus widget in the topmost parent widget */
+ focus_widget = GTK_WINDOW (toplevel)->focus_widget;
+
+ if (!GTK_IS_WIDGET (focus_widget))
+ return TRUE;
+
+ if (!gtk_widget_is_ancestor (focus_widget, widget))
+ {
+ gtk_widget_grab_focus (widget);
+ }
+ else
+ {
+ /* Containers grab_focus grabs the focus to the correct widget */
+ switch (direction) {
+ case GTK_DIR_UP:
+ case GTK_DIR_DOWN:
+ if (HILDON_IS_DATE_EDITOR(widget) || HILDON_IS_TIME_EDITOR(widget))
+ return FALSE;
+ else
+ return GTK_WIDGET_CLASS (g_type_class_peek_parent
+ (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
+ break;
+
+ default:
+ return GTK_WIDGET_CLASS (g_type_class_peek_parent
+ (GTK_WIDGET_GET_CLASS(widget)))->focus (widget, direction);
+ break;
+ }
+ }
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file
+ *
+ * Hildon composite widget includes all features which were not fitting into
+ * the any current class. A new, separate widget was not created because of the
+ * amount of current features is low. Need for this kind of class was not known
+ * when the building of the class hierarchy began. When a new feature is added,
+ * need for a new class should be re-considered. To make this decision one
+ * should really consider all the common features which are needed in the
+ * hildon composite widgets. Class position (for hildon-composite-widget)
+ * in the class hierarchy is between GtkContainer and any composite widget.
+ *
+ */
+
+#ifndef __HILDON_COMPOSITE_WIDGET__
+#define __HILDON_COMPOSITE_WIDGET__
+
+
+G_BEGIN_DECLS
+
+
+gboolean
+hildon_composite_widget_focus( GtkWidget *widget, GtkDirectionType direction );
+
+
+G_END_DECLS
+
+
+#endif /*__HILDON_COMPOSITE_WIDGET__*/
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-controlbar
+ * @short_description: A widget that allows increasing or decreasing
+ * a value within a pre-defined range
+ *
+ * #HildonControlbar is a horizontally positioned range widget that is
+ * visually divided into blocks and supports setting a minimum and
+ * maximum value for the range.
+ */
+
+
+#include <math.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include "hildon-controlbar.h"
+
+#include <libintl.h>
+#define _(string) dgettext(PACKAGE, string)
+
+#define HILDON_CONTROLBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+ HILDON_TYPE_CONTROLBAR, HildonControlbarPrivate));
+
+#define DEFAULT_WIDTH 234
+#define DEFAULT_HEIGHT 30
+#define DEFAULT_BORDER_WIDTH 2
+
+#define HILDON_CONTROLBAR_STEP_INCREMENT 1
+#define HILDON_CONTROLBAR_PAGE_INCREMENT 1
+#define HILDON_CONTROLBAR_PAGE_SIZE 0
+#define HILDON_CONTROLBAR_UPPER_VALUE 10
+#define HILDON_CONTROLBAR_LOWER_VALUE 0.0
+#define HILDON_CONTROLBAR_INITIAL_VALUE 0
+
+static GtkScaleClass *parent_class;
+
+typedef struct _HildonControlbarPrivate HildonControlbarPrivate;
+
+enum
+{
+ PROP_MIN = 1,
+ PROP_MAX,
+ PROP_VALUE
+};
+
+enum
+{
+ END_REACHED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+hildon_controlbar_class_init(HildonControlbarClass * controlbar_class);
+static void hildon_controlbar_init(HildonControlbar * controlbar);
+static GObject *
+hildon_controlbar_constructor(GType type, guint n_construct_properties,
+ GObjectConstructParam *construct_properties);
+
+static gint hildon_controlbar_button_press_event(GtkWidget * widget,
+ GdkEventButton * event);
+static gint hildon_controlbar_button_release_event(GtkWidget * widget,
+ GdkEventButton * event);
+static gint
+hildon_controlbar_expose_event(GtkWidget * widget, GdkEventExpose * event);
+static void
+hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req);
+static void
+hildon_controlbar_paint(HildonControlbar * self, GdkRectangle * area);
+static gboolean
+hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event);
+
+static void hildon_controlbar_set_property( GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec );
+static void hildon_controlbar_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec );
+
+static void
+hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range );
+
+/*
+ * Purpose of this function is to prevent Up and Down keys from
+ * changing the widget's value (like Left and Right). Instead they
+ * are used for changing focus to other widgtes.
+ */
+static gboolean
+hildon_controlbar_change_value( GtkRange *range, GtkScrollType scroll,
+ gdouble new_value, gpointer data );
+
+GType hildon_controlbar_get_type(void)
+{
+ static GType controlbar_type = 0;
+
+ if (!controlbar_type) {
+ static const GTypeInfo controlbar_info = {
+ sizeof(HildonControlbarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_controlbar_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonControlbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_controlbar_init,
+ };
+ controlbar_type = g_type_register_static(GTK_TYPE_SCALE,
+ "HildonControlbar",
+ &controlbar_info, 0);
+ }
+ return controlbar_type;
+}
+
+struct _HildonControlbarPrivate {
+ gboolean button_press;
+ gint old_value;
+};
+
+static void
+hildon_controlbar_class_init(HildonControlbarClass * controlbar_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(controlbar_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(controlbar_class);
+
+ parent_class = g_type_class_peek_parent(controlbar_class);
+
+ g_type_class_add_private(controlbar_class,
+ sizeof(HildonControlbarPrivate));
+
+ gobject_class->get_property = hildon_controlbar_get_property;
+ gobject_class->set_property = hildon_controlbar_set_property;
+ widget_class->size_request = hildon_controlbar_size_request;
+ widget_class->button_press_event = hildon_controlbar_button_press_event;
+ widget_class->button_release_event = hildon_controlbar_button_release_event;
+ widget_class->expose_event = hildon_controlbar_expose_event;
+ widget_class->key_press_event = hildon_controlbar_keypress;
+ G_OBJECT_CLASS(controlbar_class)->constructor = hildon_controlbar_constructor;
+ controlbar_class->end_reached = NULL;
+
+ /**
+ * HildonControlbar:min:
+ *
+ * Controlbar minimum value.
+ */
+ g_object_class_install_property( gobject_class, PROP_MIN,
+ g_param_spec_int("min",
+ "Minimum value",
+ "Smallest possible value",
+ G_MININT, G_MAXINT,
+ HILDON_CONTROLBAR_LOWER_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonControlbar:max:
+ *
+ * Controlbar maximum value.
+ */
+ g_object_class_install_property( gobject_class, PROP_MAX,
+ g_param_spec_int("max",
+ "Maximum value",
+ "Greatest possible value",
+ G_MININT, G_MAXINT,
+ HILDON_CONTROLBAR_UPPER_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonControlbar:value:
+ *
+ * Controlbar value.
+ */
+ g_object_class_install_property( gobject_class, PROP_VALUE,
+ g_param_spec_int("value",
+ "Current value",
+ "Current value",
+ G_MININT, G_MAXINT,
+ HILDON_CONTROLBAR_INITIAL_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("inner_border_width",
+ "Inner border width",
+ "The border spacing between the controlbar border and controlbar blocks.",
+ 0, G_MAXINT,
+ DEFAULT_BORDER_WIDTH,
+ G_PARAM_READABLE));
+
+ signals[END_REACHED] =
+ g_signal_new("end-reached",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET(HildonControlbarClass, end_reached),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+}
+
+static void hildon_controlbar_init(HildonControlbar * controlbar)
+{
+ GtkRange *range;
+ HildonControlbarPrivate *priv;
+
+ /* Initialize the private property */
+ priv = HILDON_CONTROLBAR_GET_PRIVATE(controlbar);
+ priv->button_press = FALSE;
+ priv->old_value = 0;
+ range = GTK_RANGE(controlbar);
+
+ range->has_stepper_a = TRUE;
+ range->has_stepper_d = TRUE;
+ range->round_digits = -1;
+
+ gtk_widget_set_size_request( GTK_WIDGET(controlbar), DEFAULT_WIDTH,
+ DEFAULT_HEIGHT );
+ g_signal_connect( range, "change-value",
+ G_CALLBACK(hildon_controlbar_change_value), NULL );
+}
+
+static GObject *hildon_controlbar_constructor(GType type,
+ guint n_construct_properties, GObjectConstructParam *construct_properties)
+{
+ GObject *obj;
+ GtkAdjustment *adj;
+
+ obj = G_OBJECT_CLASS(parent_class)->constructor(type,
+ n_construct_properties, construct_properties);
+
+ gtk_scale_set_draw_value (GTK_SCALE (obj), FALSE);
+
+ /* Initialize the GtkAdjustment of the controlbar*/
+ adj = GTK_RANGE(obj)->adjustment;
+ adj->step_increment = HILDON_CONTROLBAR_STEP_INCREMENT;
+ adj->page_increment = HILDON_CONTROLBAR_PAGE_INCREMENT;
+ adj->page_size = HILDON_CONTROLBAR_PAGE_SIZE;
+
+ g_signal_connect( adj, "value-changed",
+ G_CALLBACK(hildon_controlbar_value_changed), obj );
+ return obj;
+}
+
+static void hildon_controlbar_set_property (GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ HildonControlbar *controlbar = HILDON_CONTROLBAR(object);
+ switch (param_id)
+ {
+ case PROP_MIN:
+ hildon_controlbar_set_min (controlbar, g_value_get_int(value));
+ break;
+
+ case PROP_MAX:
+ hildon_controlbar_set_max (controlbar, g_value_get_int(value));
+ break;
+
+ case PROP_VALUE:
+ hildon_controlbar_set_value (controlbar, g_value_get_int(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_controlbar_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec )
+{
+ HildonControlbar *controlbar = HILDON_CONTROLBAR(object);
+ switch (param_id)
+ {
+ case PROP_MIN:
+ g_value_set_int (value, hildon_controlbar_get_min (controlbar));
+ break;
+
+ case PROP_MAX:
+ g_value_set_int (value, hildon_controlbar_get_max (controlbar));
+ break;
+
+ case PROP_VALUE:
+ g_value_set_int (value, hildon_controlbar_get_value (controlbar));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+
+static void
+hildon_controlbar_value_changed( GtkAdjustment *adj, GtkRange *range )
+{
+ HildonControlbarPrivate *priv = HILDON_CONTROLBAR_GET_PRIVATE(range);
+
+ /* Change the controlbar value if the adjusted value is large enough
+ * otherwise, keep the old value
+ */
+ if( ABS(ceil(adj->value) - priv->old_value) >= 1 )
+ {
+ priv->old_value = ceil(adj->value);
+ adj->value = priv->old_value;
+ }
+ else
+ g_signal_stop_emission_by_name( adj, "value-changed" );
+ gtk_adjustment_set_value( adj, priv->old_value );
+}
+
+/**
+ * hildon_controlbar_new:
+ *
+ * Creates a new #HildonControlbar widget.
+ *
+ * Returns: a #GtkWidget pointer of newly created control bar
+ * widget
+ */
+GtkWidget *hildon_controlbar_new(void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_CONTROLBAR, NULL));
+}
+
+/* This function prevents Up and Down keys from changing the
+ * widget's value (like Left and Right).
+ * Instead they are used for changing focus to other widgtes.
+ */
+static gboolean
+hildon_controlbar_keypress(GtkWidget * widget, GdkEventKey * event)
+{
+ if (event->keyval == GDK_Up || event->keyval == GDK_Down)
+ return FALSE;
+ return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget, event));
+}
+
+static void
+hildon_controlbar_size_request(GtkWidget * self, GtkRequisition * req)
+{
+ if (GTK_WIDGET_CLASS(parent_class)->size_request)
+ GTK_WIDGET_CLASS(parent_class)->size_request(self, req);
+
+ req->width = DEFAULT_WIDTH;
+ req->height = DEFAULT_HEIGHT;
+}
+
+/**
+ * hildon_controlbar_set_value:
+ * @self: pointer to #HildonControlbar
+ * @value: value in range of >= 0 && < G_MAX_INT
+ *
+ * Change the current value of the control bar to the specified value.
+ */
+void hildon_controlbar_set_value(HildonControlbar * self, gint value)
+{
+ GtkAdjustment *adj;
+ g_return_if_fail (HILDON_IS_CONTROLBAR (self));
+ adj = GTK_RANGE(self)->adjustment;
+
+ g_return_if_fail(value >= 0);
+
+ if (value >= adj->upper)
+ value = adj->upper;
+ else if (value <= adj->lower)
+ value = adj->lower;
+
+ adj->value = value;
+ gtk_adjustment_value_changed(adj);
+
+ g_object_notify (G_OBJECT(self), "value");
+}
+
+/**
+ * hildon_controlbar_get_value:
+ * @self: pointer to #HildonControlbar
+ *
+ * Returns: current value as gint
+ */
+gint hildon_controlbar_get_value(HildonControlbar * self)
+{
+ GtkAdjustment *adj;
+ g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0);
+ adj = GTK_RANGE(self)->adjustment;
+
+ return (gint) ceil(adj->value);
+}
+
+/**
+ * hildon_controlbar_set_max:
+ * @self: pointer to #HildonControlbar
+ * @max: maximum value to set. The value needs to be greater than 0.
+ *
+ * Set the control bar's maximum to the given value.
+ *
+ * If the new maximum is smaller than current value, the value will be
+ * adjusted so that it equals the new maximum.
+ */
+void hildon_controlbar_set_max(HildonControlbar * self, gint max)
+{
+ GtkAdjustment *adj;
+ g_return_if_fail (HILDON_IS_CONTROLBAR (self));
+ adj = GTK_RANGE(self)->adjustment;
+
+ if (max < adj->lower)
+ max = adj->lower;
+
+ if (adj->value > max)
+ hildon_controlbar_set_value (self, max);
+
+ adj->upper = max;
+ gtk_adjustment_changed(adj);
+
+ g_object_notify (G_OBJECT(self), "max");
+}
+
+/**
+ * hildon_controlbar_set_min:
+ * @self: pointer to #HildonControlbar
+ * @min: minimum value to set. The value needs to be greater than or
+ * equal to 0.
+ *
+ * Set the control bar's minimum to the given value.
+ *
+ * If the new minimum is smaller than current value, the value will be
+ * adjusted so that it equals the new minimum.
+ */
+void hildon_controlbar_set_min(HildonControlbar * self, gint min)
+{
+ GtkAdjustment *adj;
+ g_return_if_fail (HILDON_IS_CONTROLBAR (self));
+ adj = GTK_RANGE(self)->adjustment;
+
+ if (min > adj->upper)
+ min = adj->upper;
+
+ if (adj->value < min)
+ hildon_controlbar_set_value (self, min);
+
+ adj->lower = min;
+ gtk_adjustment_changed(adj);
+ g_object_notify (G_OBJECT(self), "min");
+}
+
+/**
+ * hildon_controlbar_set_range:
+ * @self: pointer to #HildonControlbar
+ * @max: maximum value to set. The value needs to be greater than 0.
+ * @min: Minimum value to set. The value needs to be greater than or
+ * equal to 0.
+ *
+ * Set the controlbars range to the given value
+ *
+ * If the new maximum is smaller than current value, the value will be
+ * adjusted so that it equals the new maximum.
+ *
+ * If the new minimum is smaller than current value, the value will be
+ * adjusted so that it equals the new minimum.
+ */
+void hildon_controlbar_set_range(HildonControlbar * self, gint min,
+ gint max)
+{
+ g_return_if_fail (HILDON_IS_CONTROLBAR (self));
+
+ if (min > max)
+ min = max;
+ /* We need to set max first here, because when min is set before
+ * max is set, it would end up 0, because max can't be bigger than 0.
+ */
+ hildon_controlbar_set_max (self, max);
+ hildon_controlbar_set_min (self, min);
+}
+
+/**
+ * hildon_controlbar_get_max:
+ * @self: a pointer to #HildonControlbar
+ *
+ * Returns: maximum value of control bar
+ */
+gint hildon_controlbar_get_max(HildonControlbar * self)
+{
+ GtkAdjustment *adj;
+ g_return_val_if_fail (HILDON_IS_CONTROLBAR (self), 0);
+ adj = GTK_RANGE(self)->adjustment;
+
+ return (gint) adj->upper;
+}
+
+/**
+ * hildon_controlbar_get_min:
+ * @self: a pointer to #HildonControlbar
+ *
+ * Returns: minimum value of controlbar
+ */
+gint hildon_controlbar_get_min(HildonControlbar * self)
+{
+ GtkAdjustment *adj = GTK_RANGE(self)->adjustment;
+ return (gint) adj->lower;
+}
+
+/*
+ * Event handler for button press
+ * Need to change button1 to button2 before passing this event to
+ * parent handler. (see specs)
+ * Also updates button_press variable so that we can draw hilites
+ * correctly
+ */
+static gint hildon_controlbar_button_press_event(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ HildonControlbar *self;
+ HildonControlbarPrivate *priv;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(event, FALSE);
+
+ self = HILDON_CONTROLBAR(widget);
+ priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
+
+ priv->button_press = TRUE;
+ event->button = event->button == 1 ? 2 : event->button;
+
+ /* Ugh dirty hack. We manipulate the mouse event location to
+ compensate for centering the widget in case it is taller than the
+ default height. */
+ if (widget->allocation.height > DEFAULT_HEIGHT) {
+ gint difference = widget->allocation.height - DEFAULT_HEIGHT;
+
+ if (difference & 1)
+ difference += 1;
+ difference = difference / 2;
+
+ event->y -= difference;
+ }
+
+
+ /* call the parent handler */
+ if (GTK_WIDGET_CLASS(parent_class)->button_press_event)
+ result =
+ GTK_WIDGET_CLASS(parent_class)->button_press_event(widget, event);
+
+ return result;
+}
+
+/*
+ * Purpose of this function is to prevent Up and Down keys from
+ * changing the widget's value (like Left and Right). Instead they
+ * are used for changing focus to other widgtes.
+ */
+static gboolean
+hildon_controlbar_change_value( GtkRange *range,
+ GtkScrollType scroll,
+ gdouble new_value,
+ gpointer data )
+{
+ HildonControlbarPrivate *priv;
+ GtkAdjustment *adj = range->adjustment;
+
+ priv = HILDON_CONTROLBAR_GET_PRIVATE(range);
+
+ /* Emit a signal when upper or lower limit is reached */
+ switch (scroll)
+ {
+ case GTK_SCROLL_STEP_FORWARD :
+ case GTK_SCROLL_PAGE_FORWARD :
+ if( adj->value == priv->old_value )
+ if( adj->value == adj->upper )
+ g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, TRUE );
+ break;
+
+ case GTK_SCROLL_STEP_BACKWARD :
+ case GTK_SCROLL_PAGE_BACKWARD :
+ if( adj->value == priv->old_value )
+ if( adj->value == adj->lower )
+ g_signal_emit( G_OBJECT(range), signals[END_REACHED], 0, FALSE );
+ break;
+
+ default:
+ break;
+ }
+return FALSE;
+}
+
+/*
+ * Event handler for button release
+ * Need to change button1 to button2 before passing this event to
+ * parent handler. (see specs)
+ * Also updates button_press variable so that we can draw hilites
+ * correctly
+ */
+static gint hildon_controlbar_button_release_event(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ HildonControlbar *self;
+ HildonControlbarPrivate *priv;
+ gboolean result = FALSE;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(event, FALSE);
+
+ self = HILDON_CONTROLBAR(widget);
+ priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
+
+ priv->button_press = FALSE;
+ event->button = event->button == 1 ? 2 : event->button;
+
+ /* call the parent handler */
+ if (GTK_WIDGET_CLASS(parent_class)->button_release_event)
+ result =
+ GTK_WIDGET_CLASS(parent_class)->button_release_event(widget, event);
+ return result;
+}
+
+/*
+ * Event handler for expose event
+ */
+static gint hildon_controlbar_expose_event(GtkWidget * widget,
+ GdkEventExpose * event)
+{
+ HildonControlbar *self = NULL;
+
+ gboolean result = FALSE;
+ gint old_height = -1;
+ gint old_y = -1;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(event, FALSE);
+ g_return_val_if_fail(HILDON_IS_CONTROLBAR(widget), FALSE);
+
+ self = HILDON_CONTROLBAR(widget);
+
+ old_height = widget->allocation.height;
+ old_y = widget->allocation.y;
+
+ if (widget->allocation.height > DEFAULT_HEIGHT) {
+ int difference = widget->allocation.height - DEFAULT_HEIGHT;
+
+ if (difference & 1)
+ difference += 1;
+ difference = difference / 2;
+
+ widget->allocation.y += difference;
+ widget->allocation.height = DEFAULT_HEIGHT;
+ }
+
+ /* call the parent handler */
+ if (GTK_WIDGET_CLASS(parent_class)->expose_event)
+ result = GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
+ hildon_controlbar_paint(self, &event->area);
+
+ widget->allocation.height = old_height;
+ widget->allocation.y = old_y;
+
+ return TRUE;
+}
+
+/*
+ * Paint method.
+ * This is where all the work is actually done...
+ */
+static void hildon_controlbar_paint(HildonControlbar * self,
+ GdkRectangle * area)
+{
+ HildonControlbarPrivate *priv;
+ GtkWidget *widget = GTK_WIDGET(self);
+ GtkAdjustment *ctrlbar = GTK_RANGE(self)->adjustment;
+ gint x = widget->allocation.x;
+ gint y = widget->allocation.y;
+ gint h = widget->allocation.height;
+ gint w = widget->allocation.width;
+ gint max = 0;
+ gint stepper_size = 0;
+ gint stepper_spacing = 0;
+ gint inner_border_width = 0;
+ gint block_area = 0, block_width = 0, block_x = 0, block_max = 0, block_height,block_y;
+ /* Number of blocks on the controlbar */
+ guint block_count = 0;
+ /* Number of displayed active blocks */
+ guint block_act = 0;
+ /* Minimum no. of blocks visible */
+ guint block_min = 0;
+ gint separatingpixels = 2;
+ gint block_remains = 0;
+ gint i, start_x, end_x, current_width;
+ GtkStateType state = GTK_STATE_NORMAL;
+
+ g_return_if_fail(area);
+
+ priv = HILDON_CONTROLBAR_GET_PRIVATE(self);
+ if (GTK_WIDGET_SENSITIVE(self) == FALSE)
+ state = GTK_STATE_INSENSITIVE;
+
+ gtk_widget_style_get(GTK_WIDGET(self),
+ "stepper-size", &stepper_size,
+ "stepper-spacing", &stepper_spacing,
+ "inner_border_width", &inner_border_width, NULL);
+ g_object_get(G_OBJECT(self), "minimum_visible_bars", &block_min, NULL);
+
+ block_area = (w - 2 * stepper_size - 2 * stepper_spacing - 2 * inner_border_width);
+ if (block_area <= 0)
+ return;
+
+ block_max = ctrlbar->upper - ctrlbar->lower + block_min;
+ block_act = priv->old_value - GTK_RANGE(self)->adjustment->lower + block_min;
+
+ /* We check border width and maximum value and adjust
+ * separating pixels for block width here. If the block size would
+ * become too small, we make the separators smaller. Graceful fallback.
+ */
+ max = ctrlbar->upper;
+ if( ctrlbar->upper == 0 )
+ {
+ separatingpixels = 3;
+ }
+ else if ((block_area - ((max - 1) * 3)) / max >= 4) {
+ separatingpixels = 3;
+ } else if ((block_area - ((max - 1) * 2)) / max >= 4) {
+ separatingpixels = 2;
+ } else if ((block_area - ((max - 1) * 1)) / max >= 4) {
+ separatingpixels = 1;
+ } else
+ separatingpixels = 0;
+
+ if( block_max == 0 )
+ {
+ /* If block max is 0 then we dim the whole control. */
+ state = GTK_STATE_INSENSITIVE;
+ block_width = block_area;
+ block_remains = 0;
+ block_max = 1;
+ }
+ else
+ {
+ block_width =
+ (block_area - (separatingpixels * (block_max - 1))) / block_max;
+ block_remains =
+ (block_area - (separatingpixels * (block_max - 1))) % block_max;
+ }
+
+ block_x = x + stepper_size + stepper_spacing + inner_border_width;
+ block_y = y + inner_border_width;
+ block_height = h - 2 * inner_border_width;
+
+ block_count = ctrlbar->value - ctrlbar->lower + block_min;
+
+ /* Without this there is vertical block corruption when block_height =
+ 1. This should work from 0 up to whatever */
+
+ if (block_height < 2)
+ block_height = 2;
+
+ /*
+ * Changed the drawing of the blocks completely,
+ * because of "do-not-resize-when-changing-max"-specs.
+ * Now the code calculates from the block_remains when
+ * it should add one pixel to the block and when not.
+ */
+
+ for (i = 1; i <= block_max; i++) {
+
+ /* Here we calculate whether we add one pixel to current_width or
+ not. */
+ start_x = block_width * (i - 1) + ((i - 1) * block_remains) / block_max;
+ end_x = block_width * i + (i * block_remains) / block_max;
+ current_width = end_x - start_x;
+
+ gtk_paint_box(widget->style, widget->window, state,
+ (i <= block_count) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
+ NULL, widget, "hildon_block",
+ block_x, block_y, current_width,
+ block_height);
+
+ /* We keep the block_x separate because of the
+ 'separatingpixels' */
+ block_x += current_width + separatingpixels;
+ }
+
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_CONTROLBAR_H__
+#define __HILDON_CONTROLBAR_H__
+
+#include <gtk/gtkscale.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_CONTROLBAR ( hildon_controlbar_get_type() )
+#define HILDON_CONTROLBAR(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_CONTROLBAR, HildonControlbar))
+#define HILDON_CONTROLBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_CONTROLBAR, HildonControlbarClass))
+#define HILDON_IS_CONTROLBAR(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_CONTROLBAR))
+#define HILDON_IS_CONTROLBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_CONTROLBAR))
+
+/**
+ * HildonControlbar:
+ *
+ * Contains gboolean variable named 'button_press' whether a button
+ * has been pressed.
+ */
+typedef struct _HildonControlbar HildonControlbar;
+typedef struct _HildonControlbarClass HildonControlbarClass;
+
+struct _HildonControlbar {
+ GtkScale scale;
+};
+
+struct _HildonControlbarClass {
+ GtkScaleClass parent_class;
+ void (*end_reached) (HildonControlbar *controlbar, gboolean end);
+};
+
+GType hildon_controlbar_get_type(void);
+GtkWidget *hildon_controlbar_new(void);
+void hildon_controlbar_set_value(HildonControlbar * self, gint value);
+gint hildon_controlbar_get_value(HildonControlbar * self);
+gint hildon_controlbar_get_max(HildonControlbar * self);
+gint hildon_controlbar_get_min(HildonControlbar * self);
+void hildon_controlbar_set_max(HildonControlbar * self, gint max);
+void hildon_controlbar_set_min(HildonControlbar * self, gint min);
+void hildon_controlbar_set_range(HildonControlbar * self, gint min,
+ gint max);
+
+G_END_DECLS
+#endif /* __HILDON_CONTROLBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-date-editor
+ * @short_description: A widget which queries a date from user or opens
+ * a HildonCalendarPopup
+ * @see_also: #HildonCalendarPopup, #HildonTimeEditor
+ *
+ * HildonDateEditor is a widget with three entry fields (day, month,
+ * year) and an icon (button): clicking on the icon opens up a
+ * HildonCalendarPopup.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <hildon-widgets/hildon-date-editor.h>
+#include <hildon-widgets/hildon-calendar-popup.h>
+#include <hildon-widgets/gtk-infoprint.h>
+#include <hildon-widgets/hildon-defines.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+#include "hildon-composite-widget.h"
+#include "hildon-marshalers.h"
+#include "hildon-libs-enum-types.h"
+
+#ifdef HAVE_CONFIG_H
+#include<config.h>
+#endif
+
+#include<libintl.h>
+#define _(string) dgettext(PACKAGE, string)
+
+#define ENTRY_BORDERS 11
+#define DATE_EDITOR_HEIGHT 30
+
+#define DAY_ENTRY_WIDTH 2
+#define MONTH_ENTRY_WIDTH 2
+#define YEAR_ENTRY_WIDTH 4
+
+#define DEFAULT_MIN_YEAR 1970
+#define DEFAULT_MAX_YEAR 2037
+
+#define HILDON_DATE_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj),\
+ HILDON_TYPE_DATE_EDITOR, HildonDateEditorPrivate));
+
+static GtkContainerClass *parent_class;
+
+typedef struct _HildonDateEditorPrivate HildonDateEditorPrivate;
+
+static void
+hildon_date_editor_class_init(HildonDateEditorClass * editor_class);
+
+static void hildon_date_editor_init(HildonDateEditor * editor);
+
+static gboolean
+hildon_date_editor_icon_press(GtkWidget * widget,
+ gpointer data);
+
+static gboolean
+hildon_date_editor_released(GtkWidget * widget,
+ gpointer data);
+
+static gboolean
+hildon_date_editor_keypress(GtkWidget * widget, GdkEventKey * event,
+ gpointer data);
+
+static gboolean
+hildon_date_editor_keyrelease(GtkWidget * widget, GdkEventKey * event,
+ gpointer data);
+static gboolean
+hildon_date_editor_clicked(GtkWidget * widget, gpointer data);
+static gint
+hildon_date_editor_entry_validate(GtkWidget *widget, gpointer data);
+
+static void
+hildon_date_editor_entry_changed(GtkEditable *widget, gpointer data);
+
+static gboolean
+hildon_date_editor_entry_focus_out(GtkWidget * widget, GdkEventFocus * event,
+ gpointer data);
+
+static gboolean hildon_date_editor_date_error(HildonDateEditor *editor,
+ HildonDateEditorErrorType type);
+
+static gboolean hildon_date_editor_entry_focusin(GtkWidget * widget,
+ GdkEventFocus * event,
+ gpointer data);
+static void hildon_date_editor_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec );
+static void hildon_date_editor_set_property (GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec);
+static void
+hildon_child_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer callback_data);
+
+static void hildon_date_editor_destroy(GtkObject * self);
+
+static void
+hildon_date_editor_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+
+static void
+hildon_date_editor_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+
+static gboolean
+_hildon_date_editor_entry_select_all(GtkWidget *widget);
+
+/* Property indices */
+enum
+{
+ PROP_DAY = 1,
+ PROP_MONTH,
+ PROP_YEAR,
+ PROP_MIN_YEAR,
+ PROP_MAX_YEAR
+};
+
+struct _HildonDateEditorPrivate {
+ /* Cache of values in the entries, used in setting only parts of the date */
+ guint year; /* current year in the entry */
+ guint month; /* current month in the entry */
+ guint day; /* current day in the entry */
+
+ gboolean calendar_icon_pressed;
+
+ GtkWidget *frame; /* borders around the date */
+ GtkWidget *d_button_image; /* icon */
+ GtkWidget *d_box_date; /* hbox for date */
+
+ GtkWidget *d_entry; /* GtkEntry for day */
+ GtkWidget *m_entry; /* GtkEntry for month */
+ GtkWidget *y_entry; /* GtkEntry for year */
+
+ GList *delims; /* List of delimeters between the fields (and possible at the ends) */
+ GtkWidget *calendar_icon;
+
+ gboolean skip_validation; /* don't validate date at all */
+
+ gint min_year; /* minimum year allowed */
+ gint max_year; /* maximum year allowed */
+};
+
+enum {
+ DATE_ERROR,
+ LAST_SIGNAL
+};
+
+static guint date_editor_signals[LAST_SIGNAL] = { 0 };
+
+GType hildon_date_editor_get_type(void)
+{
+ static GType editor_type = 0;
+
+ if (!editor_type) {
+ static const GTypeInfo editor_info = {
+ sizeof(HildonDateEditorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_date_editor_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonDateEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_date_editor_init,
+ };
+ editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonDateEditor",
+ &editor_info, 0);
+ }
+ return editor_type;
+}
+
+static void
+hildon_date_editor_class_init(HildonDateEditorClass * editor_class)
+{
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (editor_class);
+
+ parent_class = g_type_class_peek_parent(editor_class);
+
+ g_type_class_add_private(editor_class,
+ sizeof(HildonDateEditorPrivate));
+
+ gobject_class->set_property = hildon_date_editor_set_property;
+ gobject_class->get_property = hildon_date_editor_get_property;
+ widget_class->size_request = hildon_date_editor_size_request;
+ widget_class->size_allocate = hildon_date_editor_size_allocate;
+ widget_class->focus = hildon_composite_widget_focus;
+
+ container_class->forall = hildon_child_forall;
+ GTK_OBJECT_CLASS(editor_class)->destroy = hildon_date_editor_destroy;
+
+ editor_class->date_error = hildon_date_editor_date_error;
+
+ date_editor_signals[DATE_ERROR] =
+ g_signal_new("date-error",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(HildonDateEditorClass, date_error),
+ g_signal_accumulator_true_handled, NULL,
+ _hildon_marshal_BOOLEAN__ENUM,
+ G_TYPE_BOOLEAN, 1, HILDON_TYPE_DATE_EDITOR_ERROR_TYPE);
+
+ /**
+ * HildonDateEditor:year:
+ *
+ * Current year.
+ */
+ g_object_class_install_property( gobject_class, PROP_YEAR,
+ g_param_spec_uint("year",
+ "Current year",
+ "Current year",
+ 1, 2100,
+ 2005,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonDateEditor:month:
+ *
+ * Current month.
+ */
+ g_object_class_install_property( gobject_class, PROP_MONTH,
+ g_param_spec_uint("month",
+ "Current month",
+ "Current month",
+ 1, 12,
+ 1,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonDateEditor:day:
+ *
+ * Current day.
+ */
+ g_object_class_install_property( gobject_class, PROP_DAY,
+ g_param_spec_uint("day",
+ "Current day",
+ "Current day",
+ 1, 31,
+ 1,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonDateEditor:min-year:
+ *
+ * Minimum valid year.
+ */
+ g_object_class_install_property( gobject_class, PROP_MIN_YEAR,
+ g_param_spec_uint("min-year",
+ "Minimum valid year",
+ "Minimum valid year",
+ 1, 2100,
+ DEFAULT_MIN_YEAR,
+ G_PARAM_READWRITE) );
+
+ /**
+ * HildonDateEditor:max-year:
+ *
+ * Maximum valid year.
+ */
+ g_object_class_install_property( gobject_class, PROP_MAX_YEAR,
+ g_param_spec_uint("max-year",
+ "Maximum valid year",
+ "Maximum valid year",
+ 1, 2100,
+ DEFAULT_MAX_YEAR,
+ G_PARAM_READWRITE) );
+}
+
+/* Forces setting of the icon to certain state. Used initially
+ and from the actual setter function */
+static void
+real_set_calendar_icon_state(HildonDateEditorPrivate *priv,
+ gboolean pressed)
+{
+ gtk_image_set_from_icon_name(GTK_IMAGE(priv->calendar_icon),
+ pressed ? "qgn_widg_datedit_pr" : "qgn_widg_datedit",
+ HILDON_ICON_SIZE_WIDG);
+
+ priv->calendar_icon_pressed = pressed;
+}
+
+/* Sets the icon to given state (normal/pressed). Returns
+ info if the state actually changed. */
+static gboolean
+hildon_date_editor_set_calendar_icon_state(HildonDateEditor *editor,
+ gboolean pressed)
+{
+ HildonDateEditorPrivate *priv;
+
+ g_assert(HILDON_IS_DATE_EDITOR(editor));
+
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+ if (pressed != priv->calendar_icon_pressed) {
+ real_set_calendar_icon_state(priv, pressed);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Packing day, month and year entries depend on locale settings
+ We find out the order and all separators by converting a known
+ date to default format and inspecting the result string */
+static void apply_locale_field_order(HildonDateEditorPrivate *priv)
+{
+ GDate locale_test_date;
+ GtkWidget *delim;
+ gchar buffer[256];
+ gchar *iter, *delim_text;
+
+ g_date_set_dmy(&locale_test_date, 1, 2, 1970);
+ (void) g_date_strftime(buffer, sizeof(buffer), "%x", &locale_test_date);
+ iter = buffer;
+
+ while (*iter)
+ {
+ gchar *endp;
+ unsigned long value;
+
+ /* Try to convert the current location into number. */
+ value = strtoul(iter, &endp, 10);
+
+ /* If the conversion didn't progress or the detected value was
+ unknown (we used a fixed date, you remember), we treat
+ current position as a literal */
+ switch (value)
+ {
+ case 1:
+ gtk_box_pack_start(GTK_BOX(priv->d_box_date),
+ priv->d_entry, FALSE, FALSE, 0);
+ break;
+ case 2:
+ gtk_box_pack_start(GTK_BOX(priv->d_box_date),
+ priv->m_entry, FALSE, FALSE, 0);
+ break;
+ case 70: /* %x format uses only 2 numbers for some locales */
+ case 1970:
+ gtk_box_pack_start(GTK_BOX(priv->d_box_date),
+ priv->y_entry, FALSE, FALSE, 0);
+ break;
+ default:
+ /* All non-number characters starting from current position
+ form the delimeter */
+ for (endp = iter; *endp; endp++)
+ if (g_ascii_isdigit(*endp))
+ break;
+
+ /* Now endp points one place past the delimeter text */
+ delim_text = g_strndup(iter, endp - iter);
+ delim = gtk_label_new(delim_text);
+ gtk_box_pack_start(GTK_BOX(priv->d_box_date),
+ delim, FALSE, FALSE, 0);
+ priv->delims = g_list_append(priv->delims, delim);
+ g_free(delim_text);
+
+ break;
+ };
+
+ iter = endp;
+ }
+}
+
+static void hildon_date_editor_init(HildonDateEditor * editor)
+{
+ HildonDateEditorPrivate *priv;
+ GDate cur_date;
+
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ GTK_WIDGET_SET_FLAGS(GTK_WIDGET(editor), GTK_NO_WINDOW);
+
+ gtk_widget_push_composite_child();
+
+ /* initialize values */
+ g_date_clear(&cur_date, 1);
+ g_date_set_time(&cur_date, time(NULL));
+
+ priv->day = g_date_get_day(&cur_date);
+ priv->month = g_date_get_month(&cur_date);
+ priv->year = g_date_get_year(&cur_date);
+ priv->min_year = DEFAULT_MIN_YEAR;
+ priv->max_year = DEFAULT_MAX_YEAR;
+
+ /* make widgets */
+ priv->frame = gtk_frame_new(NULL);
+ gtk_container_set_border_width(GTK_CONTAINER(priv->frame), 0);
+
+ priv->d_entry = gtk_entry_new();
+ priv->m_entry = gtk_entry_new();
+ priv->y_entry = gtk_entry_new();
+
+ g_object_set (G_OBJECT(priv->d_entry), "input-mode",
+ HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
+ g_object_set (G_OBJECT(priv->m_entry), "input-mode",
+ HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
+ g_object_set (G_OBJECT(priv->y_entry), "input-mode",
+ HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
+
+ /* set entry look */
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->d_entry), DAY_ENTRY_WIDTH);
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->m_entry), MONTH_ENTRY_WIDTH);
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->y_entry), YEAR_ENTRY_WIDTH);
+
+ gtk_entry_set_max_length(GTK_ENTRY(priv->d_entry), DAY_ENTRY_WIDTH);
+ gtk_entry_set_max_length(GTK_ENTRY(priv->m_entry), MONTH_ENTRY_WIDTH);
+ gtk_entry_set_max_length(GTK_ENTRY(priv->y_entry), YEAR_ENTRY_WIDTH);
+
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->d_entry), FALSE);
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->m_entry), FALSE);
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->y_entry), FALSE);
+
+ gtk_widget_set_composite_name(priv->d_entry, "day_entry");
+ gtk_widget_set_composite_name(priv->m_entry, "month_entry");
+ gtk_widget_set_composite_name(priv->y_entry, "year_entry");
+
+ priv->d_box_date = gtk_hbox_new(FALSE, 0);
+
+ priv->d_button_image = gtk_button_new();
+ priv->calendar_icon = gtk_image_new();
+ real_set_calendar_icon_state(priv, FALSE);
+ GTK_WIDGET_UNSET_FLAGS(priv->d_button_image, GTK_CAN_FOCUS | GTK_CAN_DEFAULT);
+
+ apply_locale_field_order(priv);
+
+ gtk_container_add(GTK_CONTAINER(priv->frame), priv->d_box_date);
+ gtk_container_add(GTK_CONTAINER(priv->d_button_image), priv->calendar_icon);
+ gtk_button_set_relief(GTK_BUTTON(priv->d_button_image), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click(GTK_BUTTON(priv->d_button_image), FALSE);
+
+ gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->d_button_image, GTK_WIDGET(editor));
+ gtk_widget_show_all(priv->frame);
+ gtk_widget_show_all(priv->d_button_image);
+
+ /* image button signal connects */
+ g_signal_connect(GTK_OBJECT(priv->d_button_image), "pressed",
+ G_CALLBACK(hildon_date_editor_icon_press), editor);
+ g_signal_connect(GTK_OBJECT(priv->d_button_image), "released",
+ G_CALLBACK(hildon_date_editor_released), editor);
+ g_signal_connect(GTK_OBJECT(priv->d_button_image), "clicked",
+ G_CALLBACK(hildon_date_editor_clicked), editor);
+ g_signal_connect(GTK_OBJECT(priv->d_button_image), "key_press_event",
+ G_CALLBACK(hildon_date_editor_keypress), editor);
+
+ /* entry signal connects */
+ g_signal_connect(GTK_OBJECT(priv->d_entry), "focus-in-event",
+ G_CALLBACK(hildon_date_editor_entry_focusin), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->m_entry), "focus-in-event",
+ G_CALLBACK(hildon_date_editor_entry_focusin), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->y_entry), "focus-in-event",
+ G_CALLBACK(hildon_date_editor_entry_focusin), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->d_entry), "focus-out-event",
+ G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->m_entry), "focus-out-event",
+ G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->y_entry), "focus-out-event",
+ G_CALLBACK(hildon_date_editor_entry_focus_out), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->d_entry), "key-press-event",
+ G_CALLBACK(hildon_date_editor_keypress), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->m_entry), "key-press-event",
+ G_CALLBACK(hildon_date_editor_keypress), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->y_entry), "key-press-event",
+ G_CALLBACK(hildon_date_editor_keypress), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->d_entry), "key-release-event",
+ G_CALLBACK(hildon_date_editor_keyrelease), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->m_entry), "key-release-event",
+ G_CALLBACK(hildon_date_editor_keyrelease), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->y_entry), "key-release-event",
+ G_CALLBACK(hildon_date_editor_keyrelease), editor);
+
+ hildon_date_editor_set_date(editor, priv->year, priv->month, priv->day);
+
+ g_signal_connect(GTK_OBJECT(priv->d_entry), "changed",
+ G_CALLBACK(hildon_date_editor_entry_changed), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->m_entry), "changed",
+ G_CALLBACK(hildon_date_editor_entry_changed), editor);
+
+ g_signal_connect(GTK_OBJECT(priv->y_entry), "changed",
+ G_CALLBACK(hildon_date_editor_entry_changed), editor);
+
+ gtk_widget_pop_composite_child();
+}
+
+static void hildon_date_editor_set_property (GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ HildonDateEditor *editor = HILDON_DATE_EDITOR(object);
+ HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+ gint val;
+
+ switch (param_id)
+ {
+ case PROP_YEAR:
+ hildon_date_editor_set_year (editor, g_value_get_uint(value));
+ break;
+
+ case PROP_MONTH:
+ hildon_date_editor_set_month (editor, g_value_get_uint(value));
+ break;
+
+ case PROP_DAY:
+ hildon_date_editor_set_day (editor, g_value_get_uint(value));
+ break;
+
+ case PROP_MIN_YEAR:
+ val = g_value_get_uint(value);
+ if (val <= priv->max_year)
+ {
+ priv->min_year = val;
+ /* Clamp current year */
+ if (hildon_date_editor_get_year (editor) < priv->min_year)
+ hildon_date_editor_set_year (editor, priv->min_year);
+ }
+ else
+ g_warning("min-year cannot be greater than max-year");
+ break;
+
+ case PROP_MAX_YEAR:
+ val = g_value_get_uint(value);
+ if (val >= priv->min_year)
+ {
+ priv->max_year = val;
+ /* Clamp current year */
+ if (hildon_date_editor_get_year (editor) > priv->max_year)
+ hildon_date_editor_set_year (editor, priv->max_year);
+ }
+ else
+ g_warning("max-year cannot be less than min-year");
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_date_editor_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec )
+{
+ HildonDateEditor *editor = HILDON_DATE_EDITOR(object);
+ HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ switch (param_id)
+ {
+ case PROP_YEAR:
+ g_value_set_uint (value, hildon_date_editor_get_year (editor));
+ break;
+
+ case PROP_MONTH:
+ g_value_set_uint (value, hildon_date_editor_get_month (editor));
+ break;
+
+ case PROP_DAY:
+ g_value_set_uint (value, hildon_date_editor_get_day (editor));
+ break;
+
+ case PROP_MIN_YEAR:
+ g_value_set_uint (value, priv->min_year);
+ break;
+
+ case PROP_MAX_YEAR:
+ g_value_set_uint (value, priv->max_year);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_child_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonDateEditor *editor;
+ HildonDateEditorPrivate *priv;
+
+ g_assert(HILDON_IS_DATE_EDITOR(container));
+ g_assert(callback);
+
+ editor = HILDON_DATE_EDITOR(container);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ if (include_internals) {
+ (*callback) (priv->frame, callback_data);
+ (*callback) (priv->d_button_image, callback_data);
+ }
+}
+
+static void hildon_date_editor_destroy(GtkObject * self)
+{
+ HildonDateEditorPrivate *priv;
+
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(self);
+
+ if (priv->frame) {
+ gtk_widget_unparent(priv->frame);
+ priv->frame = NULL;
+ }
+ if (priv->d_button_image) {
+ gtk_widget_unparent(priv->d_button_image);
+ priv->d_button_image = NULL;
+ }
+ if (priv->delims) {
+ g_list_free(priv->delims);
+ priv->delims = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+/**
+ * hildon_date_editor_new:
+ *
+ * Creates a new date editor. The current system date
+ * is shown in the editor.
+ *
+ * Returns: pointer to a new @HildonDateEditor widget.
+ */
+GtkWidget *hildon_date_editor_new(void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_DATE_EDITOR, NULL));
+}
+
+/**
+ * hildon_date_editor_set_date:
+ * @date: the @HildonDateEditor widget
+ * @year: year
+ * @month: month
+ * @day: day
+ *
+ * Sets the date shown in the editor.
+ */
+void hildon_date_editor_set_date(HildonDateEditor * editor,
+ guint year, guint month, guint day)
+{
+ HildonDateEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_DATE_EDITOR(editor));
+
+ /* This function cannot be implemented by calling
+ component setters, since applying the individual
+ values one by one can make the date temporarily
+ invalid (depending on what the previous values were),
+ which in turn causes that the desired date
+ is not set (even though it's valid). We must set all the
+ components at one go and not try to do any validation etc
+ there in between. */
+
+ g_return_if_fail(HILDON_IS_DATE_EDITOR(editor));
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ if (g_date_valid_dmy(day, month, year))
+ {
+ GDate date;
+ gchar buffer[256];
+
+ priv->year = year;
+ priv->month = month;
+ priv->day = day;
+
+ g_date_set_dmy(&date, day, month, year);
+
+ /* We apply the new values, but do not want automatic focus move
+ etc to take place */
+ g_snprintf(buffer, sizeof(buffer), "%04d", year);
+ g_signal_handlers_block_by_func(priv->y_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->y_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->y_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_date_strftime(buffer, sizeof(buffer), "%m", &date);
+ g_signal_handlers_block_by_func(priv->m_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->m_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->m_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_date_strftime(buffer, sizeof(buffer), "%d", &date);
+ g_signal_handlers_block_by_func(priv->d_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->d_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->d_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_object_notify(G_OBJECT(editor), "year");
+ g_object_notify(G_OBJECT(editor), "month");
+ g_object_notify(G_OBJECT(editor), "day");
+ }
+}
+
+/**
+ * hildon_date_editor_get_date:
+ * @date: the @HildonDateEditor widget
+ * @year: year
+ * @month: month
+ * @day: day
+ *
+ * Returns: the year, month, and day currently on the
+ * date editor.
+ */
+void hildon_date_editor_get_date(HildonDateEditor * date,
+ guint * year, guint * month, guint * day)
+{
+ HildonDateEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_DATE_EDITOR(date));
+ g_return_if_fail(year);
+ g_return_if_fail(month);
+ g_return_if_fail(day);
+
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(date);
+
+ /* FIXME: The role of priv->{day,month,year} members vs. entry contents
+ is unclear. They do not neccesarily match and still the texts are
+ used as return values and members for some internal validation!!
+ At least a partly reason is to allow empty text to become
+ 0 return value, while members are restricted to valid ranges?!
+ However, if we change the current way, we are likely to break
+ some applications if they rely on some specific way how this
+ widget currently handles empty values and temporarily invalid values.
+
+ The key issue is this: What should the _get methods return while
+ user is editing a field and the result is incomplete. The
+ partial result? The last good result? If we return partial result
+ we also need a way to inform if the date is not valid. Current
+ implementation is some kind of hybrid of these two...
+
+ for example:
+ hildon_date_editor_set_day(editor, hildon_date_editor_get_day(editor));
+
+ easily fails, since set_day tries to force validity while get_day
+ doesn't do that.
+
+ Proposal: Always return the same values that are shown in the
+ fields. We add a separate flag (Or use GDate) to
+ indicate if the current date is valid. This would allow
+ setters to make the date invalid as well.
+ */
+ *year = /*priv->year;*/
+ (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->y_entry)));
+ *month = /*priv->month;*/
+ (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->m_entry)));
+ *day = /*priv->day;*/
+ (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->d_entry)));
+}
+
+/* icon button press event */
+static gboolean hildon_date_editor_icon_press(GtkWidget * widget,
+ gpointer data)
+{
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+
+ hildon_date_editor_set_calendar_icon_state(HILDON_DATE_EDITOR(data), TRUE);
+
+ return FALSE;
+}
+
+static gboolean hildon_date_editor_entry_focusin(GtkWidget * widget,
+ GdkEventFocus * event,
+ gpointer data)
+{
+ g_idle_add((GSourceFunc)
+ _hildon_date_editor_entry_select_all, GTK_ENTRY(widget));
+
+ return FALSE;
+}
+
+
+static void popup_calendar_dialog(HildonDateEditor *ed)
+{
+ guint y = 0, m = 0, d = 0;
+ GtkWidget *popup;
+ GtkWidget *parent;
+ guint result;
+ GValue val = {0, };
+
+ hildon_date_editor_get_date(ed, &y, &m, &d);
+
+ parent = gtk_widget_get_ancestor(GTK_WIDGET(ed), GTK_TYPE_WINDOW);
+ popup = hildon_calendar_popup_new(GTK_WINDOW(parent), y, m, d);
+
+ g_value_init(&val, G_TYPE_INT);
+ /* Set max/min year in calendar popup to date editor values */
+ g_object_get_property(G_OBJECT(ed), "min-year", &val);
+ g_object_set_property(G_OBJECT(popup), "min-year", &val);
+ g_object_get_property(G_OBJECT(ed), "max-year", &val);
+ g_object_set_property(G_OBJECT(popup), "max-year", &val);
+
+ /* Pop up calendar */
+ result = gtk_dialog_run(GTK_DIALOG(popup));
+ switch (result) {
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_ACCEPT:
+ hildon_calendar_popup_get_date(HILDON_CALENDAR_POPUP(popup), &y,
+ &m, &d);
+ hildon_date_editor_set_date(ed, y, m, d);
+ }
+
+ gtk_widget_destroy(popup);
+}
+
+/* button released */
+static gboolean hildon_date_editor_released(GtkWidget * widget,
+ gpointer data)
+{
+ HildonDateEditor *ed;
+
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+
+ ed = HILDON_DATE_EDITOR(data);
+
+ /* restores the icon state. The clicked cycle raises the dialog */
+ hildon_date_editor_set_calendar_icon_state(ed, FALSE);
+
+ return FALSE;
+}
+
+/* button released */
+static gboolean hildon_date_editor_clicked(GtkWidget * widget,
+ gpointer data)
+{
+ HildonDateEditor *ed;
+
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+
+ ed = HILDON_DATE_EDITOR(data);
+
+ /* restores the non-clicked button state and raises the dialog */
+ hildon_date_editor_set_calendar_icon_state(ed, FALSE);
+ popup_calendar_dialog(ed);
+
+ return FALSE;
+}
+
+/* This is called whenever some editor filed loses the focus and
+ when the all of the fields are filled.
+ Earlier this was called whenever an entry changed */
+/* FIXME: Validation on focus_out is broken by concept */
+static gint
+hildon_date_editor_entry_validate(GtkWidget *widget, gpointer data)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+ gint d, m, y, max_days;
+ gboolean r; /* temp return values for signals */
+ const gchar *text;
+ gint error_code = NO_ERROR;
+
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+ g_assert(GTK_IS_ENTRY(widget));
+
+ ed = HILDON_DATE_EDITOR(data);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+
+ if (priv->skip_validation)
+ return error_code;
+
+ /*check if the calling entry is empty*/
+ text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if(text == NULL || text[0] == 0)
+ {
+ if (widget == priv->d_entry)
+ g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_DAY, &r);
+ else if(widget == priv->m_entry)
+ g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_MONTH, &r);
+ else
+ g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, EMPTY_YEAR, &r);
+
+ /* restore empty entry to safe value */
+ hildon_date_editor_set_date (ed, priv->year, priv->month, priv->day);
+ return error_code;
+ }
+
+ /* Ok, we now check validity. Some fields can be empty */
+ text = gtk_entry_get_text(GTK_ENTRY(priv->d_entry));
+ if (text == NULL || text[0] == 0) return error_code;
+ d = atoi(text);
+ text = gtk_entry_get_text(GTK_ENTRY(priv->m_entry));
+ if (text == NULL || text[0] == 0) return error_code;
+ m = atoi(text);
+ text = gtk_entry_get_text(GTK_ENTRY(priv->y_entry));
+ if (text == NULL || text[0] == 0) return error_code;
+ y = atoi(text);
+
+ /* Did it actually change? */
+ if (d != priv->day || m != priv->month || y != priv->year)
+ {
+ /* We could/should use hildon_date_editor_set_year and such functions
+ * to set the date, instead of use gtk_entry_set_text, and then change
+ * the priv member but hildon_date_editor_set_year and such functions
+ * check if the date is valid, we do want to do date validation check
+ * here according to spec */
+
+ /* Validate month */
+ if(widget == priv->m_entry) {
+ if(m < 1) {
+ error_code = MIN_MONTH;
+ m = 1;
+ }
+ else if (m > 12) {
+ error_code = MAX_MONTH;
+ m = 12;
+ }
+ }
+
+ /* Validate year */
+ if(widget == priv->y_entry) {
+ if (y < priv->min_year) {
+ error_code = MIN_YEAR;
+ y = priv->min_year;
+ }
+ else if (y > priv->max_year) {
+ error_code = MAX_YEAR;
+ y = priv->max_year;
+ }
+ }
+
+ /* Validate day. We have to do this in every case, since
+ changing month or year can make the day number to be invalid */
+ max_days = g_date_get_days_in_month(m,y);
+ if(d < 1) {
+ error_code = MIN_DAY;
+ d = 1;
+ }
+ else if (d > max_days) {
+ if (d > 31) {
+ error_code = MAX_DAY;
+ d = max_days;
+ }
+ else { /* the date does not exist (is invalid) */
+ error_code = INVALID_DATE;
+ /* check what was changed and restore previous value */
+ if ( widget == priv->y_entry )
+ y = priv->year;
+ else if ( widget == priv->m_entry )
+ m = priv->month;
+ else
+ d = priv->day;
+ }
+ }
+
+ if (error_code != NO_ERROR)
+ {
+ g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, error_code, &r);
+
+ g_idle_add ((GSourceFunc)
+ _hildon_date_editor_entry_select_all,
+ widget);
+ }
+ }
+
+ /* Fix and reformat the date after error signal is processed.
+ reformatting can be needed even in a such case that numerical
+ values of the date components are the same as earlier. */
+ hildon_date_editor_set_date(ed, y, m, d);
+ return error_code;
+}
+
+/* When entry becomes full, we move the focus to the next field.
+ If we are on the last field, the whole contents are validated. */
+static void
+hildon_date_editor_entry_changed(GtkEditable *ed, gpointer data)
+{
+ GtkEntry *entry;
+ gint error_code;
+ HildonDateEditorPrivate *priv;
+
+ g_assert(GTK_IS_ENTRY(ed));
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+
+ entry = GTK_ENTRY(ed);
+
+ /* If day entry is full, move to next entry or validate */
+ if (g_utf8_strlen(gtk_entry_get_text(entry), -1) == gtk_entry_get_max_length(entry))
+ {
+ error_code = hildon_date_editor_entry_validate(GTK_WIDGET(entry), data);
+ if (error_code == NO_ERROR)
+ {
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(HILDON_DATE_EDITOR(data));
+ priv->skip_validation = TRUE;
+ gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_RIGHT);
+ }
+ }
+}
+
+static gboolean hildon_date_editor_keyrelease(GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+
+ g_return_val_if_fail(data, FALSE);
+ g_return_val_if_fail(widget, FALSE);
+
+ ed = HILDON_DATE_EDITOR(data);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+
+ if (event->keyval == GDK_KP_Enter || event->keyval == GDK_Return ||
+ event->keyval == GDK_ISO_Enter) {
+ if (hildon_date_editor_set_calendar_icon_state(ed, FALSE))
+ {
+ popup_calendar_dialog(ed);
+ return TRUE;
+ }
+ } else if (event->keyval == GDK_Escape)
+ priv->skip_validation = FALSE;
+
+ return FALSE;
+}
+
+/* keyboard handling */
+static gboolean hildon_date_editor_keypress(GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+ gint pos;
+ gboolean r;
+
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+ g_assert(GTK_IS_ENTRY(widget));
+
+ ed = HILDON_DATE_EDITOR(data);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+ pos = gtk_editable_get_position(GTK_EDITABLE(widget));
+
+ /* Show error message in case the key pressed is not allowed
+ (only digits and control characters are allowed )*/
+ if (!g_unichar_isdigit(event->keyval) && !(event->keyval & 0xF000)) {
+ g_signal_emit(ed, date_editor_signals[DATE_ERROR], 0, INVALID_CHAR, &r);
+ return TRUE;
+ }
+
+ switch (event->keyval) {
+ case GDK_Left:
+ if (pos == 0) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_LEFT);
+ return TRUE;
+ }
+ break;
+ case GDK_Right:
+ if (pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1)) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(data), GTK_DIR_RIGHT);
+ return TRUE;
+ }
+ break;
+ case GDK_Return:
+ case GDK_ISO_Enter:
+ /* Ignore return value, since we want to handle event at all times.
+ otherwise vkb would popup when the keyrepeat starts. */
+ (void) hildon_date_editor_set_calendar_icon_state(ed, TRUE);
+ return TRUE;
+
+ case GDK_Escape:
+ priv->skip_validation = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean hildon_date_editor_entry_focus_out(GtkWidget * widget,
+ GdkEventFocus * event,
+ gpointer data)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+
+ g_assert(HILDON_IS_DATE_EDITOR(data));
+
+ ed = HILDON_DATE_EDITOR(data);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+
+ hildon_date_editor_entry_validate(widget, data);
+ priv->skip_validation = FALSE;
+
+ return FALSE;
+}
+
+static gboolean
+hildon_date_editor_date_error(HildonDateEditor *editor,
+ HildonDateEditorErrorType type)
+{
+ HildonDateEditorPrivate *priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ switch(type)
+ {
+ case MAX_DAY:
+ gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), 31);
+ break;
+ case MAX_MONTH:
+ gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), 12);
+ break;
+ case MAX_YEAR:
+ gtk_infoprintf(NULL, _("ckct_ib_maximum_value"), priv->max_year);
+ break;
+ case MIN_DAY:
+ case MIN_MONTH:
+ gtk_infoprintf(NULL, _("ckct_ib_minimum_value"), 1);
+ break;
+ case MIN_YEAR:
+ gtk_infoprintf(NULL, _("ckct_ib_minimum_value"), priv->min_year);
+ break;
+ case EMPTY_DAY:
+ gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"), 1, 31);
+ break;
+ case EMPTY_MONTH:
+ gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"), 1, 12);
+ break;
+ case EMPTY_YEAR:
+ gtk_infoprintf(NULL, _("ckct_ib_set_a_value_within_range"),
+ priv->min_year, priv->max_year);
+ break;
+ case INVALID_CHAR:
+ gtk_infoprint(NULL, _("ckct_ib_illegal_character"));
+ break;
+ case INVALID_DATE:
+ gtk_infoprint(NULL, _("ckct_ib_date_does_not_exist"));
+ break;
+ default:
+ /*default error message ?*/
+ break;
+ }
+ return TRUE;
+}
+
+static void hildon_date_editor_size_request(GtkWidget * widget,
+ GtkRequisition * requisition)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+ GtkRequisition f_req, img_req;
+
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(requisition != NULL);
+
+ ed = HILDON_DATE_EDITOR(widget);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+
+ /* Our own children affect our size */
+ gtk_widget_size_request(priv->frame, &f_req);
+ gtk_widget_size_request(priv->d_button_image, &img_req);
+
+ /* calculate our size */
+ requisition->width = f_req.width + img_req.width + HILDON_MARGIN_DEFAULT;
+
+ /* FIXME: Fixed size is bad! We should use the maximum of our children, but
+ doing so would break current pixel specifications, since
+ the text entry by itself is already 30px tall + then frame takes
+ something */
+ requisition->height = DATE_EDITOR_HEIGHT;
+}
+
+static void hildon_date_editor_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonDateEditor *ed;
+ HildonDateEditorPrivate *priv;
+ GtkAllocation f_alloc, img_alloc;
+ GtkRequisition req;
+ GtkRequisition max_req;
+ GList *iter;
+
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(allocation != NULL);
+
+ ed = HILDON_DATE_EDITOR(widget);
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(ed);
+
+ widget->allocation = *allocation;
+
+ gtk_widget_get_child_requisition(widget, &max_req);
+
+ /* Center vertically */
+ f_alloc.y = img_alloc.y = allocation->y +
+ MAX(allocation->height - max_req.height, 0) / 2;
+
+ /* Center horizontally */
+ f_alloc.x = img_alloc.x = allocation->x +
+ MAX(allocation->width - max_req.width, 0) / 2;
+
+ /* allocate frame */
+ if (GTK_WIDGET_VISIBLE(priv->frame)) {
+ gtk_widget_get_child_requisition(priv->frame, &req);
+
+ f_alloc.width = req.width;
+ f_alloc.height = max_req.height;
+ gtk_widget_size_allocate(priv->frame, &f_alloc);
+ }
+
+ /* allocate icon */
+ if (GTK_WIDGET_VISIBLE(priv->d_button_image)) {
+ gtk_widget_get_child_requisition(priv->d_button_image,
+ &req);
+
+ img_alloc.x += f_alloc.width + HILDON_MARGIN_DEFAULT;
+ img_alloc.width = req.width;
+ img_alloc.height = max_req.height;
+ gtk_widget_size_allocate(priv->d_button_image, &img_alloc);
+ }
+
+ /* FIXME: We really should not alloc delimeters by hand (since they
+ are not our own children, but we need to force to appear
+ higher. This ugly hack is needed to compensate the forced
+ height in size_request. */
+ for (iter = priv->delims; iter; iter = iter->next)
+ {
+ GtkWidget *delim;
+ GtkAllocation alloc;
+
+ delim = GTK_WIDGET(iter->data);
+ alloc = delim->allocation;
+ alloc.height = max_req.height;
+ alloc.y = priv->d_entry->allocation.y - 2;
+
+ gtk_widget_size_allocate(delim, &alloc);
+ }
+}
+
+/**
+ * hildon_date_editor_set_year:
+ * @editor: the @HildonDateEditor widget
+ * @year: year
+ *
+ * Sets the year shown in the editor.
+ *
+ * Returns: TRUE if the year is valid
+ */
+gboolean hildon_date_editor_set_year(HildonDateEditor *editor, guint year)
+{
+ HildonDateEditorPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ if (g_date_valid_dmy(priv->day, priv->month, year))
+ {
+ gchar buffer[256];
+ priv->year = year;
+
+ g_snprintf(buffer, sizeof(buffer), "%04d", year);
+
+ /* We apply the new day, but do not want automatic focus move
+ etc to take place */
+ g_signal_handlers_block_by_func(priv->y_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->y_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->y_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_object_notify(G_OBJECT(editor), "year");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * hildon_date_editor_set_month:
+ * @editor: the @HildonDateEditor widget
+ * @month: month
+ *
+ * Sets the month shown in the editor.
+ *
+ * Returns: TRUE if the month is valid
+ */
+gboolean hildon_date_editor_set_month(HildonDateEditor *editor, guint month)
+{
+ HildonDateEditorPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ if (g_date_valid_dmy(priv->day, month, priv->year))
+ {
+ GDate date;
+ gchar buffer[256];
+
+ priv->month = month;
+ g_date_set_dmy(&date, priv->day, month, priv->year);
+ g_date_strftime(buffer, sizeof(buffer), "%m", &date);
+
+ /* We apply the new day, but do not want automatic focus move
+ etc to take place */
+ g_signal_handlers_block_by_func(priv->m_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->m_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->m_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_object_notify(G_OBJECT(editor), "month");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * hildon_date_editor_set_day:
+ * @editor: the @HildonDateEditor widget
+ * @day: day
+ *
+ * Sets the day shown in the editor.
+ *
+ * Returns: TRUE if the day is valid
+ */
+gboolean hildon_date_editor_set_day(HildonDateEditor *editor, guint day)
+{
+ HildonDateEditorPrivate *priv;
+
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), FALSE );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+
+ if (g_date_valid_dmy(day, priv->month, priv->year))
+ {
+ GDate date;
+ gchar buffer[256];
+
+ priv->day = day;
+ g_date_set_dmy(&date, day, priv->month, priv->year);
+ g_date_strftime(buffer, sizeof(buffer), "%d", &date);
+
+ /* We apply the new day, but do not want automatic focus move
+ etc to take place */
+ g_signal_handlers_block_by_func(priv->d_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+ gtk_entry_set_text(GTK_ENTRY(priv->d_entry), buffer);
+ g_signal_handlers_unblock_by_func(priv->d_entry,
+ (gpointer) hildon_date_editor_entry_changed, editor);
+
+ g_object_notify(G_OBJECT(editor), "day");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * hildon_date_editor_get_year:
+ * @editor: the @HildonDateEditor widget
+ *
+ * Returns: the current year shown in the editor.
+ */
+guint hildon_date_editor_get_year(HildonDateEditor *editor)
+{
+ HildonDateEditorPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+ return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->y_entry)));
+}
+
+/**
+ * hildon_date_editor_get_month:
+ * @editor: the @HildonDateEditor widget
+ *
+ * Gets the month shown in the editor.
+ *
+ * Returns: the current month shown in the editor.
+ */
+
+guint hildon_date_editor_get_month(HildonDateEditor *editor)
+{
+ HildonDateEditorPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+ return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->m_entry)));
+}
+
+/**
+ * hildon_date_editor_get_day:
+ * @editor: the @HildonDateEditor widget
+ *
+ * Gets the day shown in the editor.
+ *
+ * Returns: the current day shown in the editor
+ */
+
+guint hildon_date_editor_get_day(HildonDateEditor *editor)
+{
+ HildonDateEditorPrivate *priv;
+ g_return_val_if_fail( HILDON_IS_DATE_EDITOR(editor), 0 );
+ priv = HILDON_DATE_EDITOR_GET_PRIVATE(editor);
+ return (guint) atoi(gtk_entry_get_text(GTK_ENTRY(priv->d_entry)));
+}
+
+/* Idle callback */
+static gboolean
+_hildon_date_editor_entry_select_all (GtkWidget *widget)
+{
+ GDK_THREADS_ENTER ();
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_DATE_EDITOR_H__
+#define __HILDON_DATE_EDITOR_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+/**
+ * HILDON_TYPE_DATE_EDITOR:
+ *
+ * Macro for getting type of date editor.
+ * Since: 0.12.10
+ */
+#define HILDON_TYPE_DATE_EDITOR ( hildon_date_editor_get_type() )
+
+
+/**
+ * HILDON_DATE_EDITOR_TYPE:
+ *
+ * Deprecated: use #HILDON_TYPE_DATE_EDITOR instead
+ */
+#define HILDON_DATE_EDITOR_TYPE HILDON_TYPE_DATE_EDITOR
+
+#define HILDON_DATE_EDITOR(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_DATE_EDITOR, HildonDateEditor))
+#define HILDON_DATE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_DATE_EDITOR, HildonDateEditorClass))
+#define HILDON_IS_DATE_EDITOR(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_DATE_EDITOR))
+#define HILDON_IS_DATE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_DATE_EDITOR))
+
+/**
+ * HildonDateEditor:
+ *
+ * Internal struct for date editor.
+ */
+typedef struct _HildonDateEditor HildonDateEditor;
+typedef struct _HildonDateEditorClass HildonDateEditorClass;
+
+typedef enum
+{
+ NO_ERROR = -1,
+ MAX_DAY,
+ MAX_MONTH,
+ MAX_YEAR,
+ MIN_DAY,
+ MIN_MONTH,
+ MIN_YEAR,
+ EMPTY_DAY,
+ EMPTY_MONTH,
+ EMPTY_YEAR,
+ INVALID_DATE,
+ INVALID_CHAR
+
+}HildonDateEditorErrorType;
+
+struct _HildonDateEditor {
+ GtkContainer par;
+};
+
+struct _HildonDateEditorClass {
+ GtkContainerClass parent_class;
+
+ gboolean (*date_error) (HildonDateEditor *editor,
+ HildonDateEditorErrorType type);
+};
+
+GType hildon_date_editor_get_type(void) G_GNUC_CONST;
+
+GtkWidget *hildon_date_editor_new(void);
+
+void hildon_date_editor_set_date(HildonDateEditor * date,
+ guint year, guint month, guint day);
+
+void hildon_date_editor_get_date(HildonDateEditor * date,
+ guint * year, guint * month, guint * day);
+
+gboolean hildon_date_editor_set_year(HildonDateEditor *editor, guint year);
+gboolean hildon_date_editor_set_month(HildonDateEditor *editor, guint month);
+gboolean hildon_date_editor_set_day(HildonDateEditor *editor, guint day);
+
+guint hildon_date_editor_get_year(HildonDateEditor *editor);
+guint hildon_date_editor_get_month(HildonDateEditor *editor);
+guint hildon_date_editor_get_day(HildonDateEditor *editor);
+
+G_END_DECLS
+#endif /* __HILDON_DATE_EDITOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-defines
+ * @short_description: Not a widget, just a helper
+ *
+ */
+
+#include <gtk/gtk.h>
+#include "hildon-defines.h"
+
+const HildonIconSizes *hildoniconsizes = NULL;
+static HildonIconSizes iis; /* hildon internal icon sizes */
+
+/**
+ * hildon_icon_sizes_init:
+ *
+ * Initializes the icon sizes. This is automatically
+ * called when the icon sizes have not been initialized
+ * and one is requested.
+ **/
+void hildon_icon_sizes_init (void)
+{
+ if (hildoniconsizes != NULL)
+ return;
+
+ hildoniconsizes = &iis;
+
+ iis.icon_size_list = gtk_icon_size_register ("hildon_icon_size_list", 64, 64);
+ iis.icon_size_small = gtk_icon_size_register ("*icon_size_small", 26, 26);
+ iis.icon_size_toolbar = gtk_icon_size_register ("icon_size_toolbar", 26, 26);
+ iis.icon_size_widg = gtk_icon_size_register ("icon_size_widg", 26, 26);
+ iis.icon_size_widg_wizard = gtk_icon_size_register ("icon_size_widg_wizard", 50, 50);
+ iis.icon_size_grid = gtk_icon_size_register ("icon_size_grid", 64, 64);
+ iis.icon_size_big_note = gtk_icon_size_register ("icon_size_big_note", 50, 50);
+ iis.icon_size_note = gtk_icon_size_register ("icon_size_note", 26, 26);
+ iis.icon_size_statusbar = gtk_icon_size_register ("icon_size_statusbar", 40, 40);
+ iis.icon_size_indi_video_player_pre_roll = gtk_icon_size_register ("icon_size_indi_video_player_pre_roll", 64, 64);
+ iis.icon_size_indi_key_pad_lock = gtk_icon_size_register ("icon_size_indi_key_pad_lock", 50, 50);
+ iis.icon_size_indi_copy = gtk_icon_size_register ("icon_size_indi_copy", 64, 64);
+ iis.icon_size_indi_delete = gtk_icon_size_register ("icon_size_indi_delete", 64, 64);
+ iis.icon_size_indi_process = gtk_icon_size_register ("icon_size_indi_process", 64, 64);
+ iis.icon_size_indi_progressball = gtk_icon_size_register ("icon_size_indi_progressball", 64, 64);
+ iis.icon_size_indi_send = gtk_icon_size_register ("icon_size_indi_send", 64, 64);
+ iis.icon_size_indi_offmode_charging = gtk_icon_size_register ("icon_size_indi_offmode_charging", 50, 50);
+ iis.icon_size_indi_tap_and_hold = gtk_icon_size_register ("icon_size_indi_tap_and_hold", 34, 34);
+ iis.icon_size_indi_send_receive = gtk_icon_size_register ("icon_size_indi_send_receive", 64, 64);
+ iis.icon_size_indi_wlan_strength = gtk_icon_size_register ("icon_size_indi_wlan_strength", 64, 64);
+
+ iis.image_size_indi_nokia_logo = gtk_icon_size_register ("image_size_indi_nokia_logo", 64, 64);
+ iis.image_size_indi_startup_failed = gtk_icon_size_register ("image_size_indi_startup_failed", 64, 64);
+ iis.image_size_indi_startup_nokia_logo = gtk_icon_size_register ("image_size_indi_startup_nokia_logo", 64, 64);
+ iis.image_size_indi_nokia_hands = gtk_icon_size_register ("image_size_indi_nokia_hands", 64, 64);
+}
+
+typedef struct _HildonLogicalData HildonLogicalData;
+
+struct _HildonLogicalData
+{
+ GtkRcFlags rcflags;
+ GtkStateType state;
+ gchar *logicalcolorstring;
+ gchar *logicalfontstring;
+};
+
+
+static void hildon_change_style_recursive_from_ld (GtkWidget *widget, GtkStyle *prev_style, HildonLogicalData *ld)
+{
+ /* Change the style for child widgets */
+ if (GTK_IS_CONTAINER (widget)) {
+ GSList *iterator = gtk_container_get_children (GTK_CONTAINER (widget));
+ for (iterator; iterator; iterator = g_list_next (iterator))
+ hildon_change_style_recursive_from_ld (iterator->data, prev_style, ld);
+ }
+
+ /* gtk_widget_modify_*() emit "style_set" signals, so if we got here from
+ "style_set" signal, we need to block this function from being called
+ again or we get into inifinite loop.
+
+ FIXME: Compiling with gcc > 3.3 and -pedantic won't allow
+ conversion between function and object pointers. GLib API however
+ requires an object pointer for a function, so we have to work
+ around this.
+ See http://bugzilla.gnome.org/show_bug.cgi?id=310175
+ */
+ G_GNUC_EXTENSION
+ g_signal_handlers_block_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)),
+ 0, NULL,
+ (gpointer) hildon_change_style_recursive_from_ld,
+ NULL);
+
+ if (ld->logicalcolorstring != NULL)
+ {
+ /* Changing logical color */
+ GdkColor color;
+ gtk_widget_ensure_style (widget);
+ if (gtk_style_lookup_logical_color (widget->style, ld->logicalcolorstring, &color) == TRUE)
+ switch (ld->rcflags)
+ {
+ case GTK_RC_FG:
+ gtk_widget_modify_fg (widget, ld->state, &color);
+ break;
+ case GTK_RC_BG:
+ gtk_widget_modify_bg (widget, ld->state, &color);
+ break;
+ case GTK_RC_TEXT:
+ gtk_widget_modify_text (widget, ld->state, &color);
+ break;
+ case GTK_RC_BASE:
+ gtk_widget_modify_base (widget, ld->state, &color);
+ break;
+ } else
+ {
+ g_warning ("Failed to lookup '%s' color!", ld->logicalcolorstring);
+ }
+ }
+
+ if (ld->logicalfontstring != NULL)
+ {
+ /* Changing logical font */
+ GtkStyle *fontstyle = gtk_rc_get_style_by_paths (gtk_settings_get_default (), ld->logicalfontstring, NULL, G_TYPE_NONE);
+ if (fontstyle != NULL)
+ {
+ PangoFontDescription *fontdesc = fontstyle->font_desc;
+
+ if (fontdesc != NULL)
+ gtk_widget_modify_font (widget, fontdesc);
+ }
+ }
+
+
+ /* FIXME: Compilation workaround for gcc > 3.3 + -pedantic again */
+ G_GNUC_EXTENSION
+ g_signal_handlers_unblock_matched (G_OBJECT (widget), G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ g_signal_lookup ("style_set", G_TYPE_FROM_INSTANCE (widget)),
+ 0, NULL,
+ (gpointer) hildon_change_style_recursive_from_ld,
+ NULL);
+}
+
+static void hildon_logical_data_free (HildonLogicalData *ld)
+{
+ g_return_if_fail (ld != NULL);
+
+ if (ld->logicalcolorstring)
+ g_free(ld->logicalcolorstring);
+
+ if (ld->logicalfontstring)
+ g_free(ld->logicalfontstring);
+
+ g_free(ld);
+}
+
+/**
+ * hildon_gtk_widget_set_logical_font:
+ * @widget : A @GtkWidget to assign this logical font for.
+ * @logicalfontname : A gchar* with the logical font name to assign to the widget with an "osso-" -prefix.
+ *
+ * This function assigns a defined logical font to the @widget and all its child widgets.
+ * It also connects to the "style_set" signal which will retrieve & assign the new font for the given logical name each time the theme is changed.
+ * The returned signal id can be used to disconnect the signal.
+ * The previous signal (obtained by calling this function) is disconnected automatically and should not be used.
+ *
+ * Return value : The signal id that is triggered every time theme is changed. 0 if font set failed.
+ **/
+gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, const gchar *logicalfontname)
+{
+ HildonLogicalData *ld;
+ gulong signum = 0;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+ g_return_val_if_fail (logicalfontname != NULL, 0);
+
+ ld = g_malloc (sizeof (HildonLogicalData));
+
+ ld->rcflags = 0;
+ ld->state = 0;
+ ld->logicalcolorstring = NULL;
+ ld->logicalfontstring = g_strdup(logicalfontname);
+
+ /* Disconnects the previously connected signals. That calls the closure notify
+ * and effectively disposes the allocated data (hildon_logical_data_free) */
+ g_signal_handlers_disconnect_matched (G_OBJECT (widget), G_SIGNAL_MATCH_FUNC,
+ 0, NULL, NULL,
+ G_CALLBACK (hildon_change_style_recursive_from_ld), NULL);
+
+ /* Change the font now */
+ hildon_change_style_recursive_from_ld (widget, NULL, ld);
+
+ /* Connect to "style_set" so that the font gets changed whenever theme changes. */
+ signum = g_signal_connect_data (G_OBJECT (widget), "style_set",
+ G_CALLBACK (hildon_change_style_recursive_from_ld),
+ ld, (GClosureNotify) hildon_logical_data_free, 0);
+
+ return signum;
+}
+
+/**
+ * hildon_gtk_widget_set_logical_color:
+ * @widget : A @GtkWidget to assign this logical font for.
+ * @rcflags : @GtkRcFlags enumeration defining whether to assign to FG, BG, TEXT or BASE style.
+ * @state : @GtkStateType indicating to which state to assign the logical color
+ * @logicalcolorname : A gchar* with the logical font name to assign to the widget.
+ *
+ * This function assigns a defined logical color to the @widget and all it's child widgets.
+ * It also connects to the "style_set" signal which will retrieve & assign the new color for the given logical name each time the theme is changed.
+ * The returned signal id can be used to disconnect the signal.
+ * The previous signal (obtained by calling this function) is disconnected automatically and should not be used.
+ *
+ * Example : If the style you want to modify is bg[NORMAL] then set rcflags to GTK_RC_BG and state to GTK_STATE_NORMAL.
+ *
+ * Return value : The signal id that is triggered every time theme is changed. 0 if color set failed.
+ **/
+gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags,
+ GtkStateType state, const gchar *logicalcolorname)
+{
+ HildonLogicalData *ld;
+ gulong signum = 0;
+
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
+ g_return_val_if_fail (logicalcolorname != NULL, 0);
+
+ ld = g_malloc (sizeof (HildonLogicalData));
+
+ ld->rcflags = rcflags;
+ ld->state = state;
+ ld->logicalcolorstring = g_strdup(logicalcolorname);
+ ld->logicalfontstring = NULL;
+
+ /* Disconnects the previously connected signals. That calls the closure notify
+ * and effectively disposes the allocated data (hildon_logical_data_free) */
+ g_signal_handlers_disconnect_matched (G_OBJECT (widget), G_SIGNAL_MATCH_FUNC,
+ 0, NULL, NULL,
+ G_CALLBACK (hildon_change_style_recursive_from_ld), NULL);
+
+ /* Change the colors now */
+ hildon_change_style_recursive_from_ld (widget, NULL, ld);
+
+ /* Connect to "style_set" so that the colors gets changed whenever theme */
+ signum = g_signal_connect_data (G_OBJECT (widget), "style_set",
+ G_CALLBACK (hildon_change_style_recursive_from_ld),
+ ld, (GClosureNotify) hildon_logical_data_free, 0);
+
+ return signum;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_DEFINES_H__
+#define __HILDON_DEFINES_H__
+
+#include <gtk/gtkwindow.h>
+#include <gdk/gdkkeysyms.h>
+#include "hildon-appview.h"
+
+G_BEGIN_DECLS
+
+void hildon_icon_sizes_init (void);
+
+typedef struct _HildonIconSizes HildonIconSizes;
+
+struct _HildonIconSizes
+{
+ GtkIconSize icon_size_list;
+ GtkIconSize icon_size_small;
+ GtkIconSize icon_size_toolbar;
+ GtkIconSize icon_size_widg;
+ GtkIconSize icon_size_widg_wizard;
+ GtkIconSize icon_size_grid;
+ GtkIconSize icon_size_big_note;
+ GtkIconSize icon_size_note;
+ GtkIconSize icon_size_statusbar;
+ GtkIconSize icon_size_indi_video_player_pre_roll;
+ GtkIconSize icon_size_indi_key_pad_lock;
+ GtkIconSize icon_size_indi_copy;
+ GtkIconSize icon_size_indi_delete;
+ GtkIconSize icon_size_indi_process;
+ GtkIconSize icon_size_indi_progressball;
+ GtkIconSize icon_size_indi_send;
+ GtkIconSize icon_size_indi_offmode_charging;
+ GtkIconSize icon_size_indi_tap_and_hold;
+ GtkIconSize icon_size_indi_send_receive;
+ GtkIconSize icon_size_indi_wlan_strength;
+ GtkIconSize image_size_indi_nokia_logo;
+ GtkIconSize image_size_indi_startup_failed;
+ GtkIconSize image_size_indi_startup_nokia_logo;
+ GtkIconSize image_size_indi_nokia_hands;
+};
+
+extern const HildonIconSizes *hildoniconsizes;
+
+#define HILDON_ICON_SIZE_CHECK_AND_GET(iconvar) (!hildoniconsizes ? hildon_icon_sizes_init (), hildoniconsizes->iconvar : hildoniconsizes->iconvar)
+
+#define HILDON_ICON_SIZE_LIST HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_list)
+#define HILDON_ICON_SIZE_SMALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_small)
+#define HILDON_ICON_SIZE_TOOLBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_toolbar)
+#define HILDON_ICON_SIZE_WIDG HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg)
+#define HILDON_ICON_SIZE_WIDG_WIZARD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_widg_wizard)
+#define HILDON_ICON_SIZE_GRID HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_grid)
+#define HILDON_ICON_SIZE_BIG_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_big_note)
+#define HILDON_ICON_SIZE_NOTE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_note)
+#define HILDON_ICON_SIZE_STATUSBAR HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_statusbar)
+#define HILDON_ICON_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_video_player_pre_roll)
+#define HILDON_ICON_SIZE_INDI_COPY HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_copy)
+#define HILDON_ICON_SIZE_INDI_DELETE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_delete)
+#define HILDON_ICON_SIZE_INDI_PROCESS HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_process)
+#define HILDON_ICON_SIZE_INDI_PROGRESSBALL HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_progressball)
+#define HILDON_ICON_SIZE_INDI_SEND HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send)
+#define HILDON_ICON_SIZE_INDI_OFFMODE_CHARGING HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_offmode)
+#define HILDON_ICON_SIZE_INDI_TAP_AND_HOLD HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_tap_and_hold)
+#define HILDON_ICON_SIZE_INDI_SEND_RECEIVE HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_send_receive)
+#define HILDON_ICON_SIZE_INDI_WLAN_STRENGTH HILDON_ICON_SIZE_CHECK_AND_GET(icon_size_indi_wlan_strength)
+
+#define HILDON_IMAGE_SIZE_INDI_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_logo)
+#define HILDON_IMAGE_SIZE_INDI_STARTUP_FAILED HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_failed)
+#define HILDON_IMAGE_SIZE_INDI_STARTUP_NOKIA_LOGO HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_startup_nokia_logo)
+#define HILDON_IMAGE_SIZE_INDI_NOKIA_HAND HILDON_ICON_SIZE_CHECK_AND_GET(image_size_indi_nokia_hands)
+
+#define HILDON_ICON_PIXEL_SIZE_LIST 64
+#define HILDON_ICON_PIXEL_SIZE_SMALL 26
+#define HILDON_ICON_PIXEL_SIZE_TOOLBAR 26
+#define HILDON_ICON_PIXEL_SIZE_WIDG 26
+#define HILDON_ICON_PIXEL_SIZE_WIDG_WIZARD 50
+#define HILDON_ICON_PIXEL_SIZE_GRID 64
+#define HILDON_ICON_PIXEL_SIZE_BIG_NOTE 50
+#define HILDON_ICON_PIXEL_SIZE_NOTE 26
+#define HILDON_ICON_PIXEL_SIZE_STATUSBAR 40
+#define HILDON_ICON_PIXEL_SIZE_INDI_VIDEO_PLAYER_PRE_ROLL 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_KEY_PAD_LOCK 50
+#define HILDON_ICON_PIXEL_SIZE_INDI_COPY 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_DELETE 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_PROCESS 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_PROGRESSBALL 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_SEND 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_OFFMODE_CHARGING 50
+#define HILDON_ICON_PIXEL_SIZE_INDI_TAP_AND_HOLD 34
+#define HILDON_ICON_PIXEL_SIZE_INDI_SEND_RECEIVE 64
+#define HILDON_ICON_PIXEL_SIZE_INDI_WLAN_STRENGTH 64
+
+#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_LOGO 64
+#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_FAILED 64
+#define HILDON_IMAGE_PIXEL_SIZE_INDI_STARTUP_NOKIA_LOGO 64
+#define HILDON_IMAGE_PIXEL_SIZE_INDI_NOKIA_HANDS 64
+
+#define HILDON_MARGIN_HALF 3
+#define HILDON_MARGIN_DEFAULT 6
+#define HILDON_MARGIN_DOUBLE 12
+#define HILDON_MARGIN_TRIPLE 18
+
+#define HILDON_HARDKEY_UP GDK_Up
+#define HILDON_HARDKEY_LEFT GDK_Left
+#define HILDON_HARDKEY_RIGHT GDK_Right
+#define HILDON_HARDKEY_DOWN GDK_Down
+#define HILDON_HARDKEY_SELECT GDK_Return
+#define HILDON_HARDKEY_MENU GDK_F4
+#define HILDON_HARDKEY_HOME GDK_F5
+#define HILDON_HARDKEY_ESC GDK_Escape
+#define HILDON_HARDKEY_FULLSCREEN GDK_F6
+#define HILDON_HARDKEY_INCREASE GDK_F7
+#define HILDON_HARDKEY_DECREASE GDK_F8
+
+gulong hildon_gtk_widget_set_logical_font (GtkWidget *widget, const gchar *logicalfontname);
+gulong hildon_gtk_widget_set_logical_color (GtkWidget *widget, GtkRcFlags rcflags,
+ GtkStateType state, const gchar *logicalcolorname);
+
+G_END_DECLS
+#endif /* HILDON_DEFINES_H */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-dialoghelp
+ * @short_description: A helper which contains a button in a normal dialog to
+ * open a help if required
+ *
+ * #HildonDialoghelp is a helper that provides an API for enabling or
+ * disabling a help button in the titlebar area of normal dialogs that
+ * are derived from GtkDialog.
+ */
+
+#include <stdlib.h>
+#include <gdk/gdkx.h>
+#include "hildon-dialoghelp.h"
+
+static guint help_signal = 0;
+
+static GdkFilterReturn
+handle_xevent(GdkXEvent * xevent, GdkEvent * event, gpointer dialog)
+{
+ XAnyEvent *eventti = xevent;
+
+ if (eventti->type == ClientMessage) {
+ Atom help_atom, wm_atom;
+ Display *disp;
+ XClientMessageEvent *cm;
+
+ disp = GDK_DISPLAY();
+ cm = xevent;
+
+ help_atom = XInternAtom(disp, "_NET_WM_CONTEXT_HELP", True);
+ wm_atom = XInternAtom(disp, "WM_PROTOCOLS", True);
+
+ if (cm->message_type == wm_atom && cm->data.l[0] == help_atom) {
+ /* XClientMessageEvent *cm = xevent; */
+ g_signal_emit(G_OBJECT(dialog), help_signal, 0);
+ }
+
+ return GDK_FILTER_REMOVE; /* Event handled, don't process
+ further */
+ }
+
+ return GDK_FILTER_CONTINUE; /* Event not handled */
+}
+
+/**
+ * gtk_dialog_help_enable:
+ * @dialog: The dialog for which help is to be enabled.
+ *
+ * Enables context help button for a given dialog. The signal "help" can be
+ * connected to handler by normal GTK methods. Note that this function
+ * has to be called before the dialog is shown.
+ *
+ * The "help" signal itself has no other parameters than the dialog where
+ * it is connected to, ie.:
+ * void user_function(GtkDialog *dialog, gpointer user_data);
+ */
+void gtk_dialog_help_enable(GtkDialog * dialog)
+{
+ GdkWindow *window;
+ GdkDisplay *display;
+ Atom *protocols;
+ Atom *list;
+ Atom helpatom;
+ int amount = 0;
+ int n = 0;
+ int i = 0;
+ int help_enabled = 0;
+
+ /* Create help signal if it didn't exist */
+ if (help_signal == 0) {
+ help_signal = g_signal_new("help", GTK_TYPE_DIALOG,
+ G_SIGNAL_ACTION, (guint) - 1, NULL,
+ NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ }
+
+ g_return_if_fail(GTK_IS_DIALOG(dialog));
+
+ gtk_widget_realize(GTK_WIDGET(dialog));
+ window = GTK_WIDGET(dialog)->window;
+ display = gdk_drawable_get_display (window);
+
+ /* Create a list of atoms stored in GdkWindow */
+ XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ &list, &amount);
+
+ protocols = (Atom *) malloc ((amount+1) * sizeof (Atom));
+ helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
+
+ /* Enable the dialoghelp if help_atom is in the atoms' list */
+ for (i=0; i<amount; i++)
+ {
+ protocols[n++] = list[i];
+ if (list[i] == helpatom)
+ {
+ help_enabled = 1;
+ }
+ }
+ XFree (list);
+
+ /* Add the help_atom to the atoms' list if it was not in it */
+ if (!help_enabled)
+ {
+ protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
+ }
+
+ /* Replace the protocol property of the GdkWindow with the new atoms' list */
+ XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
+ free (protocols);
+
+ /* Add a callback function as event filter */
+ gdk_window_add_filter(window, handle_xevent, dialog);
+}
+
+
+/**
+ * gtk_dialog_help_disable:
+ * @dialog: The dialog for which help is to be disabled.
+ *
+ * Disables context help button for the given dialog.
+ **/
+void gtk_dialog_help_disable(GtkDialog * dialog)
+{
+ GdkWindow *window=NULL;
+ GdkDisplay *display;
+ Atom *protocols;
+ Atom *list;
+ Atom helpatom;
+ int amount = 0;
+ int n = 0;
+ int i = 0;
+
+ g_return_if_fail(GTK_IS_DIALOG(dialog));
+
+ gtk_widget_realize(GTK_WIDGET(dialog));
+ window = GTK_WIDGET(dialog)->window;
+ display = gdk_drawable_get_display (window);
+
+ /* Create a list of atoms stored in GdkWindow */
+ XGetWMProtocols(GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
+ &list, &amount);
+
+ helpatom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_CONTEXT_HELP");
+ protocols = (Atom *) malloc (amount * sizeof (Atom));
+
+ /* Remove the help_atom if it is in the atoms' list */
+ for (i=0; i<amount; i++)
+ {
+ if (list[i] != helpatom)
+ {
+ protocols[n++] = list[i];
+ }
+ }
+ XFree (list);
+
+ /* Replace the protocol property of the GdkWindow with the new atoms' list */
+ XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
+ free (protocols);
+
+ /* Remove the event filter */
+ gdk_window_remove_filter(window, handle_xevent, dialog);
+}
+
+
+
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_DIALOG_HELP_H__
+#define __HILDON_DIALOG_HELP_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+void gtk_dialog_help_enable (GtkDialog * dialog);
+void gtk_dialog_help_disable (GtkDialog * dialog);
+
+G_END_DECLS
+
+#endif /* __HILDON_DIALOG_HELP_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-file-handling-note
+ * @short_description: Displaying the notification when a move
+ * operation is in progress.
+ * @see_also: #HildonFileHandlingNote
+ *
+ * This is the notification displayed when a move operation is in
+ * progress. The notification uses a progress bar to indicate the
+ * progress of the operation. For operation containing multiple items, a
+ * separe progress bar is shown for each item. The notification has a
+ * single button, which allows users to stop the move operation.
+ */
+
+#include "hildon-note.h"
+#include "hildon-file-handling-note.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <libintl.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* Note types */
+#define MOVING_TYPE 0
+#define DELETING_TYPE 1
+#define OPENING_TYPE 2
+#define SAVING_TYPE 3
+
+/*#define _(String) dgettext(PACKAGE, String)*/
+#define _(String) dgettext("hildon-fm", String) /* FIXME: this file should be moved to hildon-fm */
+
+#define HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(obj)\
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_FILE_HANDLING_NOTE, HildonFileHandlingNotePrivate));
+
+typedef struct _HildonFileHandlingNotePrivate
+ HildonFileHandlingNotePrivate;
+
+struct _HildonFileHandlingNotePrivate {
+ guint note_type;
+};
+
+
+static HildonNote *parent_class;
+
+
+/* standard forbids empty source file, therefore the ifdef must be
+ placed here. */
+
+static void
+hildon_file_handling_note_class_init(HildonFileHandlingNoteClass * class);
+
+static void hildon_file_handling_note_init(HildonFileHandlingNote *
+ dialog);
+
+static void hildon_file_handling_note_finalize(GObject * obj_self);
+
+
+
+
+GType hildon_file_handling_note_get_type()
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonFileHandlingNoteClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_file_handling_note_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonFileHandlingNote),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_file_handling_note_init
+ };
+
+ dialog_type = g_type_register_static(HILDON_TYPE_NOTE,
+ "HildonFileHandlingNote",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+static void
+hildon_file_handling_note_class_init(HildonFileHandlingNoteClass * class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+
+ parent_class = g_type_class_peek_parent(class);
+ g_type_class_add_private(class, sizeof(HildonFileHandlingNotePrivate));
+ object_class->finalize = hildon_file_handling_note_finalize;
+}
+
+static void hildon_file_handling_note_init(HildonFileHandlingNote * dialog)
+{
+ HildonFileHandlingNotePrivate *priv;
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(dialog);
+ priv->note_type = OPENING_TYPE;
+}
+
+static void hildon_file_handling_note_finalize(GObject * obj_self)
+{
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(obj_self);
+}
+
+/**
+ * hildon_file_handling_note_set_counter_and_name:
+ * @note: the #HildonFileHandlingNote widget
+ * @current: progress, current item being processed
+ * @maximum: maximum value for counter (number of items)
+ * @name: filename
+ *
+ * This function sets current counter value, maximum
+ * counter value and filename for dialog
+ *
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+void hildon_file_handling_note_set_counter_and_name(HildonFileHandlingNote
+ * note, guint current,
+ guint maximum,
+ const gchar * name)
+{
+ gchar str[255];
+ HildonNote *p_note = HILDON_NOTE(note);
+ HildonFileHandlingNotePrivate *priv;
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(note);
+
+ if (priv->note_type == MOVING_TYPE) {
+ if (maximum == 1)
+ {
+ g_snprintf(str, 255, _("sfil_nw_moving_file"), name);
+ hildon_note_set_button_text(p_note, _("sfil_bd_moving_file"));
+ } else {
+ g_snprintf(str, 255, _("docm_nw_moving_files"),
+ current, maximum, name);
+ hildon_note_set_button_text(p_note, _("docm_bd_moving_files"));
+ }
+ } else if (priv->note_type == SAVING_TYPE) {
+ if (maximum == 1)
+ {
+ g_snprintf(str, 255, _("docm_nw_saving_file"), name);
+ hildon_note_set_button_text(p_note, _("docm_bd_saving_file"));
+ } else {
+ g_snprintf(str, 255, _("docm_nw_saving_files"),
+ current, maximum, name);
+ hildon_note_set_button_text(p_note, _("docm_bd_saving_files"));
+ }
+ } else if (priv->note_type == OPENING_TYPE) {
+ if (maximum == 1)
+ {
+ g_snprintf(str, 255, _("docm_nw_opening_file"), name);
+ hildon_note_set_button_text(p_note, _("docm_bd_opening_file"));
+ } else {
+ g_snprintf(str, 255, _("docm_nw_opening_files"),
+ current, maximum, name);
+ hildon_note_set_button_text(p_note, _("docm_bd_opening_files"));
+ }
+ } else if (priv->note_type == DELETING_TYPE) {
+ if (maximum == 1)
+ {
+ g_snprintf(str, 255, _("docm_nw_deleting_file"), name);
+ hildon_note_set_button_text(p_note, _("docm_bd_deleting_file"));
+ } else {
+ g_snprintf(str, 255, _("docm_nw_deleting_files"),
+ current, maximum, name);
+ hildon_note_set_button_text(p_note, _("docm_bd_deleting_files"));
+ }
+ }
+
+ g_object_set(p_note, "description", str, NULL);
+}
+
+/**
+ * hildon_file_handling_note_set_name:
+ * @note: the @HildonFileHandlingNote widget
+ * @name: filename
+ *
+ * This function sets the filename for dialog
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+void hildon_file_handling_note_set_name(HildonFileHandlingNote * note,
+ const gchar * name)
+{
+ gchar str[255];
+ HildonNote *p_note = HILDON_NOTE(note);
+ HildonFileHandlingNotePrivate *priv =
+ HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(note);
+
+ if (priv->note_type == MOVING_TYPE) {
+ g_snprintf(str, 255, _("sfil_nw_moving_file"), name);
+ } else if (priv->note_type == SAVING_TYPE) {
+ g_snprintf(str, 255, _("docm_nw_saving_file"), name);
+ } else if (priv->note_type == OPENING_TYPE) {
+ g_snprintf(str, 255, _("docm_nw_opening_file"), name);
+ } else if (priv->note_type == DELETING_TYPE) {
+ g_snprintf(str, 255, _("docm_nw_deleting_file"), name);
+ }
+
+ g_object_set(p_note, "description", str, NULL);
+}
+
+/**
+ * hildon_file_handling_note_set_fraction:
+ * @note: the @HildonFileHandlingNote widget
+ * @frac: value for progress bar
+
+ * This function sets fraction value for
+ * progress bar.
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+void hildon_file_handling_note_set_fraction(HildonFileHandlingNote * note,
+ gfloat frac)
+{
+ GtkWidget *progbar;
+
+ g_object_get(note, "progressbar", &progbar, NULL);
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progbar), frac);
+}
+
+/**
+ * hildon_file_handling_note_new_moving:
+ * @parent: parent GtkWindow
+ *
+ * This function creates new dialog
+ * which is "moving" type.
+ *
+ * Returns: a new #HildonFileHandlingNote
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+GtkWidget *hildon_file_handling_note_new_moving(GtkWindow * parent)
+{
+ GtkWidget *progbar;
+ HildonFileHandlingNote *file_note;
+ HildonFileHandlingNotePrivate *priv;
+
+ progbar = gtk_progress_bar_new();
+
+ file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
+ "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
+ "description", _("sfil_nw_moving_file"),
+ "progressbar", progbar, NULL);
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
+ priv->note_type = MOVING_TYPE;
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
+
+ return GTK_WIDGET(file_note);
+}
+
+/**
+ * hildon_file_handling_note_new_deleting:
+ * @parent: parent GtkWindow
+ *
+ * This function creates new dialog
+ * which is "deleting" type.
+ *
+ * Returns: a new #HildonFileHandlingNote
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+GtkWidget *hildon_file_handling_note_new_deleting(GtkWindow * parent)
+{
+ GtkWidget *progbar;
+ HildonFileHandlingNote *file_note;
+ HildonFileHandlingNotePrivate *priv;
+
+ progbar = gtk_progress_bar_new();
+
+ file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
+ "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
+ "description", _("docm_nw_deleting_file"),
+ "progressbar", progbar, NULL);
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
+ priv->note_type = DELETING_TYPE;
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
+
+ return GTK_WIDGET(file_note);
+}
+
+/**
+ * hildon_file_handling_note_new_opening:
+ * @parent: parent GtkWindow
+ *
+ * This function creates new dialog
+ * which is "opening" type
+ *
+ * Returns: a new #HildonFileHandlingNote
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+GtkWidget *hildon_file_handling_note_new_opening(GtkWindow * parent)
+{
+ GtkWidget *progbar;
+ HildonFileHandlingNote *file_note;
+ HildonFileHandlingNotePrivate *priv;
+
+ progbar = gtk_progress_bar_new();
+
+ file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
+ "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
+ "description", _("docm_nw_opening_file"),
+ "progressbar", progbar, NULL);
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
+ priv->note_type = OPENING_TYPE;
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
+
+ return GTK_WIDGET(file_note);
+}
+
+/**
+ * hildon_file_handling_note_new_saving:
+ * @parent: parent GtkWindow
+ *
+ * This function creates new dialog
+ * which is "saving" type.
+ *
+ * Returns: a new #HildonFileHandlingNote
+ * DEPRECATED: use hildon-note instead of hildon-file-handling-note.
+ */
+GtkWidget *hildon_file_handling_note_new_saving(GtkWindow * parent)
+{
+ GtkWidget *progbar;
+ HildonFileHandlingNote *file_note;
+ HildonFileHandlingNotePrivate *priv;
+
+ progbar = gtk_progress_bar_new();
+
+ file_note = g_object_new(HILDON_TYPE_FILE_HANDLING_NOTE,
+ "note_type", HILDON_NOTE_PROGRESSBAR_TYPE,
+ "description", _("docm_nw_saving_file"),
+ "progressbar", progbar, NULL);
+
+ priv = HILDON_FILE_HANDLING_NOTE_GET_PRIVATE(file_note);
+ priv->note_type = SAVING_TYPE;
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(file_note), parent);
+
+ return GTK_WIDGET(file_note);
+}
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_FILE_HANDLING_NOTE_H__
+#define __HILDON_FILE_HANDLING_NOTE_H__
+
+
+#ifndef HILDON_DISABLE_DEPRECATED
+
+#include "hildon-note.h"
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_FILE_HANDLING_NOTE \
+ ( hildon_file_handling_note_get_type() )
+#define HILDON_FILE_HANDLING_NOTE(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_FILE_HANDLING_NOTE,\
+ HildonFileHandlingNote))
+#define HILDON_FILE_HANDLING_NOTE_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_FILE_HANDLING_NOTE,\
+ HildonFileHandlingNoteClass))
+#define HILDON_IS_FILE_HANDLING_NOTE(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_FILE_HANDLING_NOTE))
+#define HILDON_IS_FILE_HANDLING_NOTE_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_FILE_HANDLING_NOTE))
+typedef struct _HildonFileHandlingNote HildonFileHandlingNote;
+typedef struct _HildonFileHandlingNoteClass HildonFileHandlingNoteClass;
+
+struct _HildonFileHandlingNote {
+ HildonNote parent;
+};
+
+struct _HildonFileHandlingNoteClass {
+ HildonNoteClass parent_class;
+};
+
+/* Note creation functions */
+GtkWidget *hildon_file_handling_note_new_moving(GtkWindow * parent);
+GtkWidget *hildon_file_handling_note_new_deleting(GtkWindow * parent);
+GtkWidget *hildon_file_handling_note_new_opening(GtkWindow * parent);
+GtkWidget *hildon_file_handling_note_new_saving(GtkWindow * parent);
+
+/* Function for progressbar status setting */
+void hildon_file_handling_note_set_fraction(HildonFileHandlingNote * note,
+ gfloat frac);
+void hildon_file_handling_note_set_counter_and_name(HildonFileHandlingNote
+ * note, guint current,
+ guint maximum,
+ const gchar * name);
+void hildon_file_handling_note_set_name(HildonFileHandlingNote * note,
+ const gchar * name);
+
+GType hildon_file_handling_note_get_type(void);
+
+G_END_DECLS
+#endif /* HILDON_DISABLE_DEPRECATED */
+
+#endif /* __HILDON_FILE_HANDLING_NOTE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-find-toolbar
+ * @short_description: A special toolbar to be used with HildonAppView
+ * @see_also: #HildonAppView
+ *
+ * HildonFindToolbar is a predefined toolbar for text searching purpose.
+ * It contains a GtkListStore which has the text items that the user has
+ * searched. But once the application is terminated, or HildonFindToolbar
+ * is trashed. Programmer is responsible for getting the GtkListStore through
+ * property "list", if he/she wants to use the information in the future.
+ * And through the same property, programmer is able to set the GtkListStore.
+ * Note, once the search button is pressed, string in the GtkComboxEntry is
+ * automatically added to the existing model, unless it is empty.
+ */
+
+#include "hildon-find-toolbar.h"
+#include "hildon-defines.h"
+#include <gdk/gdkkeysyms.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtktoolbutton.h>
+#include <gtk/gtktoolitem.h>
+#include <gtk/gtkcomboboxentry.h>
+#include <gtk/gtkseparatortoolitem.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+/*same define as gtkentry.c as entry will further handle this*/
+#define MAX_SIZE G_MAXUSHORT
+#define FIND_LABEL_XPADDING 6
+#define FIND_LABEL_YPADDING 0
+
+enum
+{
+ SEARCH = 0,
+ CLOSE,
+ INVALID_INPUT,
+ HISTORY_APPEND,
+
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_LABEL = 1,
+ PROP_PREFIX,
+ PROP_LIST,
+ PROP_COLUMN,
+ PROP_MAX,
+ PROP_HISTORY_LIMIT
+};
+
+struct _HildonFindToolbarPrivate
+{
+ GtkWidget* label;
+ GtkComboBoxEntry* entry_combo_box;
+ GtkToolItem* find_button;
+ GtkToolItem* separator;
+ GtkToolItem* close_button;
+
+ gint history_limit;
+};
+static guint HildonFindToolbar_signal[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE(HildonFindToolbar, hildon_find_toolbar, GTK_TYPE_TOOLBAR)
+
+static GtkTreeModel *
+hildon_find_toolbar_get_list_model(HildonFindToolbarPrivate *priv)
+{
+ GtkTreeModel *filter_model =
+ gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box));
+
+ return filter_model == NULL ? NULL :
+ gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(filter_model));
+}
+
+static GtkEntry *
+hildon_find_toolbar_get_entry(HildonFindToolbarPrivate *priv)
+{
+ return GTK_ENTRY(gtk_bin_get_child(GTK_BIN(priv->entry_combo_box)));
+}
+
+static gboolean
+hildon_find_toolbar_filter(GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer self)
+{
+ GtkTreePath *path;
+ const gint *indices;
+ gint n;
+ gint limit;
+ gint total;
+
+ total = gtk_tree_model_iter_n_children(model, NULL);
+ g_object_get(self, "history_limit", &limit, NULL);
+ path = gtk_tree_model_get_path(model, iter);
+ indices = gtk_tree_path_get_indices (path);
+
+ /* set the row's index, list store has only one level */
+ n = indices[0];
+ gtk_tree_path_free(path);
+
+ /*if the row is among the latest "history_limit" additions of the
+ * model, then we show it */
+ if( (total - limit <= n) && (n < total) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void
+hildon_find_toolbar_apply_filter(HildonFindToolbar *self, GtkTreeModel *model)
+{
+ GtkTreeModel *filter;
+ HildonFindToolbarPrivate *priv = self->priv;
+
+ /* Create a filter for the given model. Its only purpose is to hide
+ the oldest entries so only "history_limit" entries are visible. */
+ filter = gtk_tree_model_filter_new(model, NULL);
+
+ gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter),
+ hildon_find_toolbar_filter,
+ self, NULL);
+ gtk_combo_box_set_model(GTK_COMBO_BOX(priv->entry_combo_box), filter);
+
+ /* ComboBox keeps the only needed reference to the filter */
+ g_object_unref(filter);
+}
+
+static void
+hildon_find_toolbar_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(object)->priv;
+ const gchar *string;
+ gint c_n, max_len;
+
+ switch (prop_id)
+ {
+ case PROP_LABEL:
+ string = gtk_label_get_text(GTK_LABEL(priv->label));
+ g_value_set_string(value, string);
+ break;
+ case PROP_PREFIX:
+ string = gtk_entry_get_text(hildon_find_toolbar_get_entry(priv));
+ g_value_set_string(value, string);
+ break;
+ case PROP_LIST:
+ g_value_set_object(value, hildon_find_toolbar_get_list_model(priv));
+ break;
+ case PROP_COLUMN:
+ c_n = gtk_combo_box_entry_get_text_column(priv->entry_combo_box);
+ g_value_set_int(value, c_n);
+ break;
+ case PROP_MAX:
+ max_len = gtk_entry_get_max_length(hildon_find_toolbar_get_entry(priv));
+ g_value_set_int(value, max_len);
+ break;
+ case PROP_HISTORY_LIMIT:
+ g_value_set_int(value, priv->history_limit);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_find_toolbar_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HildonFindToolbar *self = HILDON_FIND_TOOLBAR(object);
+ HildonFindToolbarPrivate *priv = self->priv;
+ GtkTreeModel *model;
+ const gchar *string;
+
+ switch (prop_id)
+ {
+ case PROP_LABEL:
+ string = g_value_get_string(value);
+ gtk_label_set_text(GTK_LABEL(priv->label), string);
+ break;
+ case PROP_PREFIX:
+ string = g_value_get_string(value);
+ gtk_entry_set_text(hildon_find_toolbar_get_entry(priv), string);
+ break;
+ case PROP_LIST:
+ model = GTK_TREE_MODEL(g_value_get_object(value));
+ hildon_find_toolbar_apply_filter(self, model);
+ break;
+ case PROP_COLUMN:
+ gtk_combo_box_entry_set_text_column(priv->entry_combo_box,
+ g_value_get_int(value));
+ break;
+ case PROP_MAX:
+ gtk_entry_set_max_length(hildon_find_toolbar_get_entry(priv),
+ g_value_get_int(value));
+ break;
+ case PROP_HISTORY_LIMIT:
+ priv->history_limit = g_value_get_int(value);
+
+ /* Re-apply the history limit to the model. */
+ model = hildon_find_toolbar_get_list_model(priv);
+ if (model != NULL)
+ {
+ /* Note that refilter function doesn't update the status of the
+ combobox popup arrow, so we'll just recreate the filter. */
+ hildon_find_toolbar_apply_filter(self, model);
+
+ if (gtk_combo_box_entry_get_text_column(priv->entry_combo_box) == -1)
+ {
+ /* FIXME: This is only for backwards compatibility, although
+ probably nothing actually relies on it. The behavior was only
+ an accidental side effect of original code */
+ gtk_combo_box_entry_set_text_column(priv->entry_combo_box, 0);
+ }
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+hildon_find_toolbar_find_string(HildonFindToolbar *self,
+ GtkTreeIter *iter,
+ gint column,
+ const gchar *string)
+{
+ GtkTreeModel *model = NULL;
+ gchar *old_string;
+
+ model = hildon_find_toolbar_get_list_model(self->priv);
+
+ if (gtk_tree_model_get_iter_first(model, iter))
+ {
+ do {
+ gtk_tree_model_get(model, iter, column, &old_string, -1);
+ if (old_string != NULL && strcmp(string, old_string) == 0)
+ {
+ /* Found it */
+ return TRUE;
+ }
+ } while (gtk_tree_model_iter_next(model, iter));
+ }
+
+ return FALSE;
+}
+
+static gboolean
+hildon_find_toolbar_history_append(HildonFindToolbar *self,
+ gpointer data)
+{
+ HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(self)->priv;
+ gchar *string;
+ gint column = 0;
+ GtkTreeModel *model = NULL;
+ GtkListStore *list = NULL;
+ GtkTreeIter iter;
+ gboolean self_create = FALSE;
+
+ g_object_get(self, "prefix", &string, NULL);
+
+ if (*string == '\0')
+ {
+ /* empty prefix, ignore */
+ g_free(string);
+ return TRUE;
+ }
+
+
+ /* If list store is set, get it */
+ model = hildon_find_toolbar_get_list_model(priv);
+ if(model != NULL)
+ {
+ list = GTK_LIST_STORE(model);
+ g_object_get(self, "column", &column, NULL);
+
+ if (column < 0)
+ {
+ /* Column number is -1 if "column" property hasn't been set but
+ "list" property is. */
+ g_free(string);
+ return TRUE;
+ }
+
+ /* Latest string is always the first one in list. If the string
+ already exists, remove it so there are no duplicates in list. */
+ if (hildon_find_toolbar_find_string(self, &iter, column, string))
+ gtk_list_store_remove(list, &iter);
+ }
+ else
+ {
+ /* No list store set. Create our own. */
+ list = gtk_list_store_new(1, G_TYPE_STRING);
+ model = GTK_TREE_MODEL(list);
+ self_create = TRUE;
+ }
+
+ /* Add the string to first in list */
+ gtk_list_store_append(list, &iter);
+ gtk_list_store_set(list, &iter, column, string, -1);
+
+ if(self_create)
+ {
+ /* Add the created list to ComboBoxEntry */
+ hildon_find_toolbar_apply_filter(self, model);
+ /* ComboBoxEntry keeps the only needed reference to this list */
+ g_object_unref(list);
+
+ /* Set the column only after ComboBoxEntry's model is set
+ in hildon_find_toolbar_apply_filter() */
+ g_object_set(self, "column", 0, NULL);
+ }
+ else
+ {
+ /* Refilter to get the oldest entry hidden from history */
+ gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(
+ gtk_combo_box_get_model(GTK_COMBO_BOX(priv->entry_combo_box))));
+ }
+
+ g_free(string);
+
+ return TRUE;
+}
+
+static void
+hildon_find_toolbar_emit_search(GtkButton *button, gpointer self)
+{
+ gboolean rb;
+
+ /* Clicked search button. Perform search and add search prefix to history */
+ g_signal_emit_by_name(self, "search", NULL);
+ g_signal_emit_by_name(self, "history_append", &rb, NULL);
+}
+
+static void
+hildon_find_toolbar_emit_close(GtkButton *button, gpointer self)
+{
+ HildonFindToolbarPrivate *priv = HILDON_FIND_TOOLBAR(self)->priv;
+ GtkWidget *entry = gtk_bin_get_child(GTK_BIN(priv->entry_combo_box));
+ if (GTK_WIDGET_HAS_FOCUS(entry))
+ {
+ hildon_gtk_im_context_hide(GTK_ENTRY(entry)->im_context);
+ }
+ /* Clicked close button */
+ g_signal_emit_by_name(self, "close", NULL);
+}
+
+static void
+hildon_find_toolbar_emit_invalid_input(GtkEntry *entry,
+ GtkInvalidInputType type,
+ gpointer self)
+{
+ if(type == GTK_INVALID_INPUT_MAX_CHARS_REACHED)
+ g_signal_emit_by_name(self, "invalid_input", NULL);
+}
+
+static void
+hildon_find_toolbar_entry_activate (GtkWidget *widget,
+ gpointer user_data)
+{
+ GtkWidget *find_toolbar = GTK_WIDGET(user_data);
+ gboolean rb;
+
+ /* NB#40936 stop focus from moving to next widget */
+ g_signal_stop_emission_by_name (widget, "activate");
+
+ g_signal_emit_by_name(find_toolbar, "search", NULL);
+ g_signal_emit_by_name(find_toolbar, "history_append", &rb, NULL);
+}
+
+static void
+hildon_find_toolbar_class_init(HildonFindToolbarClass *klass)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private(klass, sizeof(HildonFindToolbarPrivate));
+
+ object_class = G_OBJECT_CLASS(klass);
+
+ object_class->get_property = hildon_find_toolbar_get_property;
+ object_class->set_property = hildon_find_toolbar_set_property;
+
+ klass->history_append = hildon_find_toolbar_history_append;
+
+ g_object_class_install_property(object_class, PROP_LABEL,
+ g_param_spec_string("label",
+ "Label", "Displayed name for"
+ " find-toolbar",
+ _("ecdg_ti_find_toolbar_label"),
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(object_class, PROP_PREFIX,
+ g_param_spec_string("prefix",
+ "Prefix", "Search string", NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_LIST,
+ g_param_spec_object("list",
+ "List"," GtkListStore model where "
+ "history list is kept",
+ GTK_TYPE_LIST_STORE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_COLUMN,
+ g_param_spec_int("column",
+ "Column", "Column number in GtkListStore "
+ "where history list strings are kept",
+ 0, G_MAXINT,
+ 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_MAX,
+ g_param_spec_int("max_characters",
+ "Maximum number of characters",
+ "Maximum number of characters "
+ "in search string",
+ 0, MAX_SIZE,
+ 0, G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(object_class, PROP_HISTORY_LIMIT,
+ g_param_spec_int("history_limit",
+ "Maximum number of history items",
+ "Maximum number of history items "
+ "in search combobox",
+ 0, G_MAXINT,
+ 5, G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /**
+ * HildonFindToolbar::search:
+ * @toolbar: the toolbar which received the signal
+ *
+ * Gets emitted when the find button is pressed.
+ */
+ HildonFindToolbar_signal[SEARCH] =
+ g_signal_new(
+ "search", HILDON_TYPE_FIND_TOOLBAR,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
+ (HildonFindToolbarClass, search),
+ NULL, NULL, gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * HildonFindToolbar::close:
+ * @toolbar: the toolbar which received the signal
+ *
+ * Gets emitted when the close button is pressed.
+ */
+ HildonFindToolbar_signal[CLOSE] =
+ g_signal_new(
+ "close", HILDON_TYPE_FIND_TOOLBAR,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
+ (HildonFindToolbarClass, close),
+ NULL, NULL, gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * HildonFindToolbar::invalid-input:
+ * @toolbar: the toolbar which received the signal
+ *
+ * Gets emitted when the maximum search prefix length is reached and
+ * user tries to type more.
+ */
+ HildonFindToolbar_signal[INVALID_INPUT] =
+ g_signal_new(
+ "invalid_input", HILDON_TYPE_FIND_TOOLBAR,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
+ (HildonFindToolbarClass, invalid_input),
+ NULL, NULL, gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * HildonFindToolbar::history-append:
+ * @toolbar: the toolbar which received the signal
+ *
+ * Gets emitted when the current search prefix should be added to history.
+ */
+ HildonFindToolbar_signal[HISTORY_APPEND] =
+ g_signal_new(
+ "history_append", HILDON_TYPE_FIND_TOOLBAR,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
+ (HildonFindToolbarClass, history_append),
+ g_signal_accumulator_true_handled, NULL,
+ gtk_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+}
+
+static void
+hildon_find_toolbar_init(HildonFindToolbar *self)
+{
+ GtkToolItem *label_container;
+ GtkToolItem *entry_combo_box_container;
+
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE(self,
+ HILDON_TYPE_FIND_TOOLBAR,
+ HildonFindToolbarPrivate);
+
+ /* Create the label */
+ self->priv->label = gtk_label_new(_("ecdg_ti_find_toolbar_label"));
+
+ gtk_misc_set_padding (GTK_MISC(self->priv->label), FIND_LABEL_XPADDING,
+ FIND_LABEL_YPADDING);
+
+ label_container = gtk_tool_item_new();
+ gtk_container_add(GTK_CONTAINER(label_container),
+ self->priv->label);
+ gtk_widget_show_all(GTK_WIDGET(label_container));
+ gtk_toolbar_insert (GTK_TOOLBAR(self), label_container, -1);
+
+ /* ComboBoxEntry for search prefix string / history list */
+ self->priv->entry_combo_box = GTK_COMBO_BOX_ENTRY(gtk_combo_box_entry_new());
+ g_signal_connect(hildon_find_toolbar_get_entry(self->priv),
+ "invalid_input",
+ G_CALLBACK(hildon_find_toolbar_emit_invalid_input), self);
+ entry_combo_box_container = gtk_tool_item_new();
+ gtk_tool_item_set_expand(entry_combo_box_container, TRUE);
+ gtk_container_add(GTK_CONTAINER(entry_combo_box_container),
+ GTK_WIDGET(self->priv->entry_combo_box));
+ gtk_widget_show_all(GTK_WIDGET(entry_combo_box_container));
+ gtk_toolbar_insert (GTK_TOOLBAR(self), entry_combo_box_container, -1);
+ g_signal_connect(hildon_find_toolbar_get_entry(self->priv),
+ "activate",
+ G_CALLBACK(hildon_find_toolbar_entry_activate), self);
+
+ /* Find button */
+ self->priv->find_button = gtk_tool_button_new (
+ gtk_image_new_from_icon_name ("qgn_toolb_browser_gobutton",
+ HILDON_ICON_SIZE_TOOLBAR),
+ "Find");
+ g_signal_connect(self->priv->find_button, "clicked",
+ G_CALLBACK(hildon_find_toolbar_emit_search), self);
+ gtk_widget_show_all(GTK_WIDGET(self->priv->find_button));
+ gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->find_button, -1);
+ if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->find_button)->child) )
+ GTK_WIDGET_UNSET_FLAGS(
+ GTK_BIN(self->priv->find_button)->child, GTK_CAN_FOCUS);
+
+ /* Separator */
+ self->priv->separator = gtk_separator_tool_item_new();
+ gtk_widget_show(GTK_WIDGET(self->priv->separator));
+ gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->separator, -1);
+
+ /* Close button */
+ self->priv->close_button = gtk_tool_button_new (
+ gtk_image_new_from_icon_name ("qgn_toolb_gene_close",
+ HILDON_ICON_SIZE_TOOLBAR),
+ "Close");
+ g_signal_connect(self->priv->close_button, "clicked",
+ G_CALLBACK(hildon_find_toolbar_emit_close), self);
+ gtk_widget_show_all(GTK_WIDGET(self->priv->close_button));
+ gtk_toolbar_insert (GTK_TOOLBAR(self), self->priv->close_button, -1);
+ if ( GTK_WIDGET_CAN_FOCUS( GTK_BIN(self->priv->close_button)->child) )
+ GTK_WIDGET_UNSET_FLAGS(
+ GTK_BIN(self->priv->close_button)->child, GTK_CAN_FOCUS);
+}
+
+/*Public functions*/
+
+/**
+ * hildon_find_toolbar_new:
+ * @label: label for the find_toolbar, NULL to set the label to
+ * default "Find"
+ *
+ * Returns a new HildonFindToolbar.
+ *
+ * Returns: a new HildonFindToolbar
+ */
+
+GtkWidget *
+hildon_find_toolbar_new(const gchar *label)
+{
+ GtkWidget *findtoolbar;
+
+ findtoolbar = GTK_WIDGET(g_object_new(HILDON_TYPE_FIND_TOOLBAR, NULL));
+ if(label != NULL)
+ g_object_set(findtoolbar, "label", label, NULL);
+
+ return findtoolbar;
+}
+
+/**
+ * hildon_find_toolbar_new_with_model
+ * @label: label for the find_toolbar, NULL to set the label to
+ * default "Find"
+ * @model: a @GtkListStore
+ * @column: indicating which column the search histry list will
+ * retreive string from
+ *
+ * Returns a new HildonFindToolbar, with a model.
+ *
+ * Returns: a new #HildonFindToolbar
+ */
+GtkWidget *
+hildon_find_toolbar_new_with_model(const gchar *label,
+ GtkListStore *model,
+ gint column)
+{
+ GtkWidget *findtoolbar;
+
+ findtoolbar = hildon_find_toolbar_new(label);
+ g_object_set(findtoolbar, "list", model,
+ "column", column, NULL);
+
+ return findtoolbar;
+}
+
+/**
+ * hildon_find_toolbar_highlight_entry
+ * @ftb: find Toolbar whose entry is to be highlighted
+ * @get_focus: if user passes TRUE to this value, then the text in
+ * the entry will not only get highlighted, but also get focused.
+ *
+ */
+void
+hildon_find_toolbar_highlight_entry(HildonFindToolbar *ftb,
+ gboolean get_focus)
+{
+ GtkEntry *entry = NULL;
+
+ g_return_if_fail(HILDON_IS_FIND_TOOLBAR(ftb));
+
+ entry = hildon_find_toolbar_get_entry(ftb->priv);
+
+ gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
+
+ if(get_focus)
+ gtk_widget_grab_focus(GTK_WIDGET(entry));
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_FIND_TOOLBAR_H__
+#define __HILDON_FIND_TOOLBAR_H__
+
+#include <gtk/gtktoolbar.h>
+#include <gtk/gtkliststore.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_FIND_TOOLBAR (hildon_find_toolbar_get_type())
+#define HILDON_FIND_TOOLBAR(object) \
+ (G_TYPE_CHECK_INSTANCE_CAST((object), HILDON_TYPE_FIND_TOOLBAR, \
+ HildonFindToolbar))
+#define HILDON_FIND_TOOLBARClass(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR, \
+ HildonFindToolbarClass))
+#define HILDON_IS_FIND_TOOLBAR(object) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((object), HILDON_TYPE_FIND_TOOLBAR))
+#define HILDON_IS_FIND_TOOLBAR_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), HILDON_TYPE_FIND_TOOLBAR))
+#define HILDON_FIND_TOOLBAR_GET_CLASS(object) \
+ (G_TYPE_INSTANCE_GET_CLASS((object), HILDON_TYPE_FIND_TOOLBAR, \
+ HildonFindToolbarClass))
+
+typedef struct _HildonFindToolbar HildonFindToolbar;
+typedef struct _HildonFindToolbarClass HildonFindToolbarClass;
+typedef struct _HildonFindToolbarPrivate HildonFindToolbarPrivate;
+
+struct _HildonFindToolbar
+{
+ GtkToolbar parent;
+
+ HildonFindToolbarPrivate *priv;
+};
+
+struct _HildonFindToolbarClass
+{
+ GtkToolbarClass parent_class;
+
+ void (*search) (HildonFindToolbar *toolbar);
+ void (*close) (HildonFindToolbar *toolbar);
+ void (*invalid_input) (HildonFindToolbar *toolbar);
+ gboolean (*history_append) (HildonFindToolbar *tooblar);
+};
+
+GType hildon_find_toolbar_get_type (void) G_GNUC_CONST;
+GtkWidget* hildon_find_toolbar_new (const gchar *label);
+GtkWidget* hildon_find_toolbar_new_with_model (const gchar *label,
+ GtkListStore*
+ model,
+ gint column);
+void hildon_find_toolbar_highlight_entry (HildonFindToolbar *ftb,
+ gboolean get_focus);
+
+G_END_DECLS
+
+#endif /* __HILDON_FIND_TOOLBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-font-selection-dialog
+ * @short_description: A widget used to allow users to select a font
+ * with certain properties
+ *
+ * Font selection can be made using this widget. Users can select font name,
+ * size, style, etc. Users can also preview text in the selected font.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtkstock.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkliststore.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "hildon-font-selection-dialog.h"
+#include <hildon-widgets/hildon-caption.h>
+#include <hildon-widgets/hildon-color-selector.h>
+#include <hildon-widgets/hildon-color-button.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+#define SUPERSCRIPT_RISE 3333
+#define SUBSCRIPT_LOW -3333
+#define ON_BIT 0x01
+#define OFF_BIT 0x02
+
+/*
+ * These are what we use as the standard font sizes, for the size list.
+ */
+static const guint16 font_sizes[] =
+{
+ 6, 8, 10, 12, 16, 24, 32
+};
+
+#define HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_FONT_SELECTION_DIALOG, \
+ HildonFontSelectionDialogPrivate))
+
+/*None of designed api function works, so now it all comes down to
+ *use properties to achieve what we are supposed to achieve*/
+enum
+{
+ PROP_FAMILY = 1,
+ PROP_FAMILY_SET,
+ PROP_SIZE,
+ PROP_SIZE_SET,
+ PROP_COLOR,
+ PROP_COLOR_SET,
+ PROP_BOLD,
+ PROP_BOLD_SET,
+ PROP_ITALIC,
+ PROP_ITALIC_SET,
+ PROP_UNDERLINE,
+ PROP_UNDERLINE_SET,
+ PROP_STRIKETHROUGH,
+ PROP_STRIKETHROUGH_SET,
+ PROP_POSITION,
+ PROP_POSITION_SET,
+ PROP_PREVIEW_TEXT,
+ PROP_FONT_SCALING
+};
+
+typedef struct
+_HildonFontSelectionDialogPrivate HildonFontSelectionDialogPrivate;
+
+struct _HildonFontSelectionDialogPrivate
+{
+ GtkNotebook *notebook;
+
+ gchar *preview_text;
+
+ /*Tab one*/
+ GtkWidget *cbx_font_type;
+ GtkWidget *cbx_font_size;
+ GtkWidget *font_color_button;
+
+ /*Tab two*/
+ GtkWidget *chk_bold;
+ GtkWidget *chk_italic;
+ GtkWidget *chk_underline;
+
+ /*Tab three*/
+ GtkWidget *chk_strikethrough;
+ GtkWidget *cbx_positioning;
+
+ /*Every family*/
+ PangoFontFamily **families;
+ gint n_families;
+
+ /*color_set is used to show whether the color is inconsistent
+ * The handler id is used to block the signal emission
+ * when we change the color setting*/
+
+ gboolean color_set;
+
+ /* font_scaling is the scaling factor applied to font
+ * scale in the preview dialog */
+
+ gdouble font_scaling;
+ gulong color_modified_signal_handler;
+};
+
+/*combo box active row indicator -2--inconsistent, -1--undefined
+ * please make sure that you use settings_init settings_apply
+ * and settings_destroy, dont even try to touch this structure
+ * without using the three above interface functions, of course
+ * if you know what you are doing, do as you please ;-)*/
+typedef struct
+{
+ HildonFontSelectionDialog
+ *fsd; /*pointer to our font selection dialog*/
+
+ gint family; /*combo box indicator*/
+ gint size; /*combo box indicator*/
+ GdkColor *color; /*free after read the setting*/
+ gboolean color_inconsist;
+ gint weight; /*bit mask*/
+ gint style; /*bit mask*/
+ gint underline; /*bit mask*/
+ gint strikethrough; /*bit mask*/
+ gint position; /*combo box indicator*/
+
+}HildonFontSelectionDialogSettings;
+
+static gboolean
+ hildon_font_selection_dialog_preview_key_press
+ (GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer unused);
+
+/*Some tools from gtk_font_selection*/
+static int cmp_families (const void *a, const void *b);
+
+static void hildon_font_selection_dialog_show_preview
+ (HildonFontSelectionDialog
+ *fontsel);
+
+static PangoAttrList*
+ hildon_font_selection_dialog_create_attrlist
+ (HildonFontSelectionDialog
+ *fontsel, guint start_index,
+ guint len);
+
+static void hildon_font_selection_dialog_show_available_positionings
+ (HildonFontSelectionDialogPrivate
+ *priv);
+
+static void hildon_font_selection_dialog_show_available_fonts
+ (HildonFontSelectionDialog
+ *fontsel);
+
+static void hildon_font_selection_dialog_show_available_sizes
+ (HildonFontSelectionDialogPrivate
+ *priv);
+
+static void hildon_font_selection_dialog_class_init
+ (HildonFontSelectionDialogClass
+ *klass);
+
+static void hildon_font_selection_dialog_init
+ (HildonFontSelectionDialog
+ *fontseldiag);
+
+static void hildon_font_selection_dialog_finalize
+ (GObject * object);
+
+static void hildon_font_selection_dialog_construct_notebook
+ (HildonFontSelectionDialog
+ *fontsel);
+
+static void color_modified_cb (HildonColorButton *button,
+ GParamSpec *pspec,
+ gpointer fsd_priv);
+
+static void check_tags (gpointer data,
+ gpointer user_data);
+
+static void settings_init (HildonFontSelectionDialogSettings
+ *setttings,
+ HildonFontSelectionDialog
+ *fsd);
+
+static void settings_apply (HildonFontSelectionDialogSettings
+ *setttings);
+
+static void settings_destroy (HildonFontSelectionDialogSettings
+ *setttings);
+
+static void bit_mask_toggle (gint mask, GtkToggleButton*
+ button, GObject *object,
+ const gchar *prop,
+ const gchar *prop_set);
+
+static void combo_active (gint active, GtkComboBox *box,
+ GObject *object,
+ const gchar *prop,
+ const gchar *prop_set);
+
+static void add_preview_text_attr (PangoAttrList *list,
+ PangoAttribute *attr,
+ guint start,
+ guint len);
+
+static void toggle_clicked (GtkButton *button,
+ gpointer unused);
+
+
+
+static GtkDialogClass *font_selection_dialog_parent_class = NULL;
+
+GType hildon_font_selection_dialog_get_type(void)
+{
+ static GType font_selection_dialog_type = 0;
+
+ if (!font_selection_dialog_type) {
+ static const GTypeInfo fontsel_diag_info = {
+ sizeof(HildonFontSelectionDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_font_selection_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonFontSelectionDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_font_selection_dialog_init,
+ };
+
+ font_selection_dialog_type =
+ g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonFontSelectionDialog",
+ &fontsel_diag_info, 0);
+ }
+
+ return font_selection_dialog_type;
+}
+
+static void
+hildon_font_selection_dialog_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ gint i;
+ GdkColor *color = NULL;
+
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
+ HILDON_FONT_SELECTION_DIALOG(object));
+
+
+ switch (prop_id)
+ {
+ case PROP_FAMILY:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
+ if(i >= 0 && i < priv->n_families)
+ g_value_set_string(value,
+ pango_font_family_get_name(priv->families[i]));
+ else
+ g_value_set_string(value, "Sans");
+ break;
+
+ case PROP_FAMILY_SET:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_type));
+ if(i >= 0 && i < priv->n_families)
+ g_value_set_boolean(value, TRUE);
+ else
+ g_value_set_boolean(value, FALSE);
+ break;
+
+ case PROP_SIZE:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
+ if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
+ g_value_set_int(value, font_sizes[i]);
+ else
+ g_value_set_int(value, 16);
+ break;
+
+ case PROP_SIZE_SET:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_font_size));
+ if(i >= 0 && i < G_N_ELEMENTS(font_sizes))
+ g_value_set_boolean(value, TRUE);
+ else
+ g_value_set_boolean(value, FALSE);
+ break;
+
+ case PROP_COLOR:
+ color = hildon_color_button_get_color
+ (HILDON_COLOR_BUTTON(priv->font_color_button));
+ g_value_set_boxed(value, (gconstpointer) color);
+ if(color != NULL)
+ gdk_color_free(color);
+ break;
+
+ case PROP_COLOR_SET:
+ g_value_set_boolean(value, priv->color_set);
+ break;
+
+ case PROP_BOLD:
+ g_value_set_boolean(value,
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->chk_bold)));
+ break;
+
+ case PROP_BOLD_SET:
+ g_value_set_boolean(value,
+ !gtk_toggle_button_get_inconsistent
+ (GTK_TOGGLE_BUTTON(priv->chk_bold)));
+ break;
+
+ case PROP_ITALIC:
+ g_value_set_boolean(value,
+ gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(priv->chk_italic)));
+ break;
+
+ case PROP_ITALIC_SET:
+ g_value_set_boolean(value,
+ !gtk_toggle_button_get_inconsistent
+ (GTK_TOGGLE_BUTTON(priv->chk_italic)));
+ break;
+
+ case PROP_UNDERLINE:
+ g_value_set_boolean(value,
+ gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(priv->chk_underline)));
+ break;
+
+ case PROP_UNDERLINE_SET:
+ g_value_set_boolean(value,
+ !gtk_toggle_button_get_inconsistent
+ (GTK_TOGGLE_BUTTON(priv->chk_underline)));
+ break;
+
+ case PROP_STRIKETHROUGH:
+ g_value_set_boolean(value,
+ gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
+ break;
+
+ case PROP_STRIKETHROUGH_SET:
+ g_value_set_boolean(value,
+ !gtk_toggle_button_get_inconsistent
+ (GTK_TOGGLE_BUTTON(priv->chk_strikethrough)));
+ break;
+
+ case PROP_POSITION:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
+ if(i == 1)/*super*/
+ g_value_set_int(value, 1);
+ else if(i == 2)/*sub*/
+ g_value_set_int(value, -1);
+ else
+ g_value_set_int(value, 0);
+ break;
+
+ case PROP_FONT_SCALING:
+ g_value_set_double(value, priv->font_scaling);
+ break;
+
+ case PROP_POSITION_SET:
+ i = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->cbx_positioning));
+ if(i >= 0 && i < 3)
+ g_value_set_boolean(value, TRUE);
+ else
+ g_value_set_boolean(value, FALSE);
+ break;
+
+ case PROP_PREVIEW_TEXT:
+ g_value_set_string(value,
+ hildon_font_selection_dialog_get_preview_text(
+ HILDON_FONT_SELECTION_DIALOG(object)));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_font_selection_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ gint i, size;
+ const gchar *str;
+ gboolean b;
+ GdkColor *color = NULL;
+ GdkColor black;
+
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(
+ HILDON_FONT_SELECTION_DIALOG(object));
+ black.red = black.green = black.blue = 0;
+
+ switch (prop_id)
+ {
+ case PROP_FAMILY:
+ str = g_value_get_string(value);
+ for(i = 0; i < priv->n_families; i++)
+ {
+ if(strcmp(str, pango_font_family_get_name(priv->families[i]))
+ == 0)
+ {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), i);
+ break;
+ }
+ }
+ break;
+
+ case PROP_FAMILY_SET:
+ b = g_value_get_boolean(value);
+ if(!b)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_type), -1);
+ break;
+
+ case PROP_SIZE:
+ size = g_value_get_int(value);
+ for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
+ {
+ if(size == font_sizes[i])
+ {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), i);
+ break;
+ }
+ }
+ break;
+
+ case PROP_SIZE_SET:
+ b = g_value_get_boolean(value);
+ if(!b)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_font_size), -1);
+ break;
+
+ case PROP_COLOR:
+ color = (GdkColor *) g_value_get_boxed(value);
+ if(color != NULL)
+ hildon_color_button_set_color(HILDON_COLOR_BUTTON
+ (priv->font_color_button),
+ color);
+ else
+ hildon_color_button_set_color(HILDON_COLOR_BUTTON
+ (priv->font_color_button),
+ &black);
+ break;
+
+ case PROP_COLOR_SET:
+ priv->color_set = g_value_get_boolean(value);
+ if(!priv->color_set)
+ {
+ /*set color to black, but block our signal handler*/
+ g_signal_handler_block((gpointer) priv->font_color_button,
+ priv->color_modified_signal_handler);
+
+ hildon_color_button_set_color(HILDON_COLOR_BUTTON
+ (priv->font_color_button),
+ &black);
+
+ g_signal_handler_unblock((gpointer) priv->font_color_button,
+ priv->color_modified_signal_handler);
+ }
+ break;
+
+ case PROP_BOLD:
+ /*this call will make sure that we dont get extra clicked signal*/
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
+ FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_bold),
+ g_value_get_boolean(value));
+ break;
+
+ case PROP_BOLD_SET:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_bold),
+ !g_value_get_boolean(value));
+ break;
+
+ case PROP_ITALIC:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
+ FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_italic),
+ g_value_get_boolean(value));
+ break;
+
+ case PROP_ITALIC_SET:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_italic),
+ !g_value_get_boolean(value));
+ break;
+
+ case PROP_UNDERLINE:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
+ (priv->chk_underline),
+ FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_underline),
+ g_value_get_boolean(value));
+ break;
+
+ case PROP_UNDERLINE_SET:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(priv->chk_underline),
+ !g_value_get_boolean(value));
+ break;
+
+ case PROP_STRIKETHROUGH:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
+ (priv->chk_strikethrough),
+ FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
+ g_value_get_boolean(value));
+ break;
+
+ case PROP_STRIKETHROUGH_SET:
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
+ (priv->chk_strikethrough),
+ !g_value_get_boolean(value));
+ break;
+
+ case PROP_POSITION:
+ i = g_value_get_int(value);
+ if( i == 1 )
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 1);
+ else if(i == -1)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 2);
+ else
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), 0);
+ break;
+
+ case PROP_FONT_SCALING:
+ priv->font_scaling = g_value_get_double(value);
+ break;
+
+ case PROP_POSITION_SET:
+ b = g_value_get_boolean(value);
+ if(!b)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->cbx_positioning), -1);
+ break;
+
+ case PROP_PREVIEW_TEXT:
+ hildon_font_selection_dialog_set_preview_text(
+ HILDON_FONT_SELECTION_DIALOG(object),
+ g_value_get_string(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_font_selection_dialog_class_init(HildonFontSelectionDialogClass *
+ klass)
+{
+ GObjectClass *gobject_class;
+
+ font_selection_dialog_parent_class = g_type_class_peek_parent(klass);
+ gobject_class = G_OBJECT_CLASS(klass);
+ gobject_class->finalize = hildon_font_selection_dialog_finalize;
+ gobject_class->get_property = hildon_font_selection_dialog_get_property;
+ gobject_class->set_property = hildon_font_selection_dialog_set_property;
+
+ /* Install property to the class */
+ g_object_class_install_property(gobject_class, PROP_FAMILY,
+ g_param_spec_string("family",
+ "Font family", "String defines"
+ " the font family", "Sans",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_FAMILY_SET,
+ g_param_spec_boolean ("family-set",
+ "family inconsistent state",
+ "Whether the family property"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_SIZE,
+ g_param_spec_int ("size",
+ "Font size",
+ "Font size in Pt",
+ 6, 32, 16,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_SIZE_SET,
+ g_param_spec_boolean ("size-set",
+ "size inconsistent state",
+ "Whether the size property"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_COLOR,
+ g_param_spec_boxed ("color",
+ "text color",
+ "gdk color for the text",
+ GDK_TYPE_COLOR,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_COLOR_SET,
+ g_param_spec_boolean ("color-set",
+ "color inconsistent state",
+ "Whether the color property"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_BOLD,
+ g_param_spec_boolean ("bold",
+ "text weight",
+ "Whether the text is bold",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_BOLD_SET,
+ g_param_spec_boolean ("bold-set",
+ "bold inconsistent state",
+ "Whether the bold"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_ITALIC,
+ g_param_spec_boolean ("italic",
+ "text style",
+ "Whether the text is italic",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_ITALIC_SET,
+ g_param_spec_boolean ("italic-set",
+ "italic inconsistent state",
+ "Whether the italic"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_UNDERLINE,
+ g_param_spec_boolean ("underline",
+ "text underline",
+ "Whether the text is underlined",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_UNDERLINE_SET,
+ g_param_spec_boolean ("underline-set",
+ "underline inconsistent state",
+ "Whether the underline"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH,
+ g_param_spec_boolean ("strikethrough",
+ "strikethroughed text",
+ "Whether the text is strikethroughed",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_STRIKETHROUGH_SET,
+ g_param_spec_boolean ("strikethrough-set",
+ "strikethrough inconsistent state",
+ "Whether the strikethrough"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_POSITION,
+ g_param_spec_int ("position",
+ "Font position",
+ "Font position super or subscript",
+ -1, 1, 0,
+ G_PARAM_READWRITE));
+
+ /* FIXME This was introduced in 0.14.1. We don't have documentation for
+ * properties anyways, but once it's there it needs to be marked as
+ * Since: 0.14.1 */
+ g_object_class_install_property(gobject_class, PROP_FONT_SCALING,
+ g_param_spec_double ("font-scaling",
+ "Font scaling",
+ "Font scaling for the preview dialog",
+ 0, 10, 1,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_POSITION_SET,
+ g_param_spec_boolean ("position-set",
+ "position inconsistent state",
+ "Whether the position"
+ " is inconsistent", FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property(gobject_class, PROP_PREVIEW_TEXT,
+ g_param_spec_string("preview-text",
+ "Preview Text",
+ "the text in preview dialog, which does"
+ "not include the reference text",
+ "",
+ G_PARAM_READWRITE));
+
+
+ g_type_class_add_private(klass,
+ sizeof(struct _HildonFontSelectionDialogPrivate));
+}
+
+
+static void
+hildon_font_selection_dialog_init(HildonFontSelectionDialog *fontseldiag)
+{
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontseldiag);
+ GtkWidget *preview_button;
+
+ priv->notebook = GTK_NOTEBOOK(gtk_notebook_new());
+
+ hildon_font_selection_dialog_construct_notebook(fontseldiag);
+
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->vbox),
+ GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
+
+ /* Add dialog buttons */
+ gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
+ _("ecdg_bd_font_dialog_ok"),
+ GTK_RESPONSE_OK);
+
+ preview_button = gtk_button_new_with_label(_("ecdg_bd_font_dialog_preview"));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fontseldiag)->action_area),
+ preview_button, FALSE, TRUE, 0);
+ g_signal_connect_swapped(preview_button, "clicked",
+ G_CALLBACK
+ (hildon_font_selection_dialog_show_preview),
+ fontseldiag);
+ gtk_widget_show(preview_button);
+
+ gtk_dialog_add_button(GTK_DIALOG(fontseldiag),
+ _("ecdg_bd_font_dialog_cancel"),
+ GTK_RESPONSE_CANCEL);
+
+ /*Set default preview text*/
+ priv->preview_text = g_strdup(_("ecdg_fi_preview_font_preview_text"));
+
+ gtk_window_set_title(GTK_WINDOW(fontseldiag), _("ecdg_ti_font"));
+ /*here is the line to make sure that notebook has the default focus*/
+ gtk_container_set_focus_child(GTK_CONTAINER(GTK_DIALOG(fontseldiag)->vbox),
+ GTK_WIDGET(priv->notebook));
+}
+
+static void
+hildon_font_selection_dialog_construct_notebook (HildonFontSelectionDialog
+ *fontsel)
+{
+ gint i;
+ GtkWidget *vbox_tab[3];
+ GtkWidget *font_color_box;
+ GtkWidget *caption_control;
+ GtkSizeGroup *group;
+
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
+
+ for (i = 0; i < 3; i++)
+ vbox_tab[i] = gtk_vbox_new(TRUE, 0);
+
+ group =
+ GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
+
+ /* Build the first page of the GtkNotebook: font style */
+ priv->cbx_font_type = gtk_combo_box_new_text();
+ hildon_font_selection_dialog_show_available_fonts(fontsel);
+ caption_control = hildon_caption_new(group,
+ _("ecdg_fi_font_font"),
+ priv->cbx_font_type,
+ NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
+ FALSE, FALSE, 0);
+
+ priv->cbx_font_size = gtk_combo_box_new_text();
+ hildon_font_selection_dialog_show_available_sizes(priv);
+ caption_control = hildon_caption_new(group,
+ _("ecdg_fi_font_size"),
+ priv->cbx_font_size,
+ NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
+ FALSE, FALSE, 0);
+
+ font_color_box = gtk_hbox_new(FALSE, 0);
+ priv->font_color_button = hildon_color_button_new();
+ priv->color_set = FALSE;
+ priv->font_scaling = 1.0;
+ priv->color_modified_signal_handler =
+ g_signal_connect(G_OBJECT(priv->font_color_button), "notify::color",
+ G_CALLBACK(color_modified_cb), (gpointer) priv);
+ gtk_box_pack_start(GTK_BOX(font_color_box),
+ priv->font_color_button, FALSE, FALSE, 0);
+
+ caption_control =
+ hildon_caption_new(group, _("ecdg_fi_font_colour_selector"),
+ font_color_box,
+ NULL, HILDON_CAPTION_OPTIONAL);
+
+ gtk_box_pack_start(GTK_BOX(vbox_tab[0]), caption_control,
+ FALSE, FALSE, 0);
+
+ /* Build the second page of the GtkNotebook: font formatting */
+ priv->chk_bold = gtk_check_button_new();
+ caption_control = hildon_caption_new(group,
+ _("ecdg_fi_font_bold"),
+ priv->chk_bold,
+ NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(priv->chk_bold), "clicked",
+ G_CALLBACK(toggle_clicked), NULL);
+
+ priv->chk_italic = gtk_check_button_new();
+ caption_control =
+ hildon_caption_new(group, _("ecdg_fi_font_italic"),
+ priv->chk_italic,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(priv->chk_italic), "clicked",
+ G_CALLBACK(toggle_clicked), NULL);
+
+ priv->chk_underline = gtk_check_button_new();
+ caption_control =
+ hildon_caption_new(group, _("ecdg_fi_font_underline"),
+ priv->chk_underline, NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[1]), caption_control,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(priv->chk_underline), "clicked",
+ G_CALLBACK(toggle_clicked), NULL);
+
+ /* Build the third page of the GtkNotebook: other font properties */
+ priv->chk_strikethrough = gtk_check_button_new();
+ caption_control =
+ hildon_caption_new(group, _("ecdg_fi_font_strikethrough"),
+ priv->chk_strikethrough, NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(priv->chk_strikethrough), "clicked",
+ G_CALLBACK(toggle_clicked), NULL);
+
+ priv->cbx_positioning = gtk_combo_box_new_text();
+ hildon_font_selection_dialog_show_available_positionings(priv);
+ caption_control =
+ hildon_caption_new(group, _("ecdg_fi_font_special"),
+ priv->cbx_positioning, NULL,
+ HILDON_CAPTION_OPTIONAL);
+ gtk_box_pack_start(GTK_BOX(vbox_tab[2]), caption_control,
+ FALSE, FALSE, 0);
+
+ /* Populate notebook */
+ gtk_notebook_insert_page(priv->notebook, vbox_tab[0], NULL, 0);
+ gtk_notebook_insert_page(priv->notebook, vbox_tab[1], NULL, 1);
+ gtk_notebook_insert_page(priv->notebook, vbox_tab[2], NULL, 2);
+ gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[0],
+ _("ecdg_ti_font_dialog_style"));
+ gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[1],
+ _("ecdg_ti_font_dialog_format"));
+ gtk_notebook_set_tab_label_text(priv->notebook, vbox_tab[2],
+ _("ecdg_ti_font_dialog_other"));
+
+ gtk_widget_show_all(GTK_WIDGET(priv->notebook));
+}
+
+static void
+color_modified_cb(HildonColorButton *button,
+ GParamSpec *pspec,
+ gpointer fsd_priv)
+{
+ HildonFontSelectionDialogPrivate *priv =
+ (HildonFontSelectionDialogPrivate *) fsd_priv;
+
+ priv->color_set = TRUE;
+}
+
+static void
+hildon_font_selection_dialog_finalize(GObject * object)
+{
+ HildonFontSelectionDialogPrivate *priv;
+ HildonFontSelectionDialog *fontsel;
+
+ g_assert(HILDON_IS_FONT_SELECTION_DIALOG(object));
+ fontsel = HILDON_FONT_SELECTION_DIALOG(object);
+
+ priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
+
+ g_free(priv->preview_text);
+ g_free(priv->families);
+
+ if (G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize)
+ G_OBJECT_CLASS(font_selection_dialog_parent_class)->finalize(object);
+}
+
+static int
+cmp_families(const void *a, const void *b)
+{
+ const char *a_name =
+ pango_font_family_get_name(*(PangoFontFamily **) a);
+ const char *b_name =
+ pango_font_family_get_name(*(PangoFontFamily **) b);
+
+ return g_utf8_collate(a_name, b_name);
+}
+
+/* Exits the preview dialog with GTK_RESPONSE_CANCEL if Esc key
+ * was pressed */
+static gboolean
+hildon_font_selection_dialog_preview_key_press(GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer unused)
+{
+ g_assert(widget);
+ g_assert(event);
+
+ if (event->keyval == GDK_Escape)
+ {
+ gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_CANCEL);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+add_preview_text_attr(PangoAttrList *list, PangoAttribute *attr,
+ guint start, guint len)
+{
+ attr->start_index = start;
+ attr->end_index = start + len;
+ pango_attr_list_insert(list, attr);
+}
+
+static PangoAttrList*
+hildon_font_selection_dialog_create_attrlist(HildonFontSelectionDialog *
+ fontsel, guint start_index, guint len)
+{
+ PangoAttrList *list;
+ PangoAttribute *attr;
+ gint size, position;
+ gboolean family_set, size_set, color_set, bold, bold_set,
+ italic, italic_set, underline, underline_set,
+ strikethrough, strikethrough_set, position_set;
+ GdkColor *color = NULL;
+ gchar *family = NULL;
+ gdouble font_scaling = 1.0;
+
+ list = pango_attr_list_new();
+
+ g_object_get(G_OBJECT(fontsel),
+ "family", &family, "family-set", &family_set,
+ "size", &size, "size-set", &size_set,
+ "color", &color, "color-set", &color_set,
+ "bold", &bold, "bold-set", &bold_set,
+ "italic", &italic, "italic-set", &italic_set,
+ "underline", &underline, "underline-set", &underline_set,
+ "strikethrough", &strikethrough, "strikethrough-set",
+ &strikethrough_set, "position", &position,
+ "position-set", &position_set,
+ "font-scaling", &font_scaling,
+ NULL);
+
+ /*family*/
+ if(family_set)
+ {
+ attr = pango_attr_family_new(family);
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+ g_free(family);
+
+ /*size*/
+ if(size_set)
+ {
+ attr = pango_attr_size_new(size * PANGO_SCALE);
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*color*/
+ if(color_set)
+ {
+ attr = pango_attr_foreground_new(color->red, color->green, color->blue);
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ if(color != NULL)
+ gdk_color_free(color);
+
+ /*weight*/
+ if(bold_set)
+ {
+ if(bold)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
+ else
+ attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
+
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*style*/
+ if(italic_set)
+ {
+ if(italic)
+ attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
+ else
+ attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
+
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*underline*/
+ if(underline_set)
+ {
+ if(underline)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
+ else
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
+
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*strikethrough*/
+ if(strikethrough_set)
+ {
+ if(strikethrough)
+ attr = pango_attr_strikethrough_new(TRUE);
+ else
+ attr = pango_attr_strikethrough_new(FALSE);
+
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*position*/
+ if(position_set)
+ {
+ switch(position)
+ {
+ case 1: /*super*/
+ attr = pango_attr_rise_new(SUPERSCRIPT_RISE);
+ break;
+ case -1: /*sub*/
+ attr = pango_attr_rise_new(SUBSCRIPT_LOW);
+ break;
+ default: /*normal*/
+ attr = pango_attr_rise_new(0);
+ break;
+ }
+
+ add_preview_text_attr(list, attr, start_index, len);
+ }
+
+ /*font scaling for preview*/
+ if(font_scaling)
+ {
+ attr = pango_attr_scale_new(font_scaling);
+ add_preview_text_attr(list, attr, 0, len + start_index);
+ }
+
+ return list;
+}
+
+static void
+hildon_font_selection_dialog_show_preview(HildonFontSelectionDialog *
+ fontsel)
+{
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
+ gint size;
+ gboolean family_set, size_set;
+ PangoAttribute *attr;
+ PangoAttrList *list;
+ GtkWidget *preview_dialog;
+ GtkWidget *preview_label;
+ gchar *str = NULL;
+ gboolean position_set = FALSE;
+ gint position = 0;
+ gboolean show_ref = FALSE;
+
+ g_object_get(G_OBJECT(fontsel), "position-set", &position_set, NULL);
+ if (position_set) {
+ g_object_get(G_OBJECT(fontsel), "position", &position, NULL);
+ if (position == 1 || position == -1)
+ show_ref = TRUE;
+ }
+
+ /*Preview dialog init*/
+ preview_dialog=
+ gtk_dialog_new_with_buttons(_("ecdg_ti_preview_font"), NULL,
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT |
+ GTK_DIALOG_NO_SEPARATOR,
+ _("ecdg_bd_font_dialog_ok"),
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ str = (show_ref) ? g_strconcat(_("ecdg_fi_preview_font_preview_reference"), priv->preview_text, 0) :
+ g_strdup (priv->preview_text);
+
+ preview_label = gtk_label_new(str);
+ gtk_label_set_line_wrap(GTK_LABEL(preview_label), TRUE);
+
+ g_free(str);
+ str = NULL;
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(preview_dialog)->vbox),
+ preview_label);
+
+
+ /* set keypress handler (ESC hardkey) */
+ g_signal_connect(G_OBJECT(preview_dialog), "key-press-event",
+ G_CALLBACK(hildon_font_selection_dialog_preview_key_press),
+ NULL);
+
+
+ /*Set the font*/
+ list = (show_ref) ? hildon_font_selection_dialog_create_attrlist(fontsel,
+ strlen(_("ecdg_fi_preview_font_preview_reference")),
+ strlen(priv->preview_text)) :
+ hildon_font_selection_dialog_create_attrlist(fontsel,
+ 0,
+ strlen(priv->preview_text));
+
+ g_object_get(G_OBJECT(fontsel), "family", &str, "family-set",
+ &family_set, "size", &size, "size-set", &size_set,
+ NULL);
+
+ /* FIXME: This is a slightly ugly hack to force the width of the window so that
+ * the whole text fits with various font sizes. It's being done in such a way,
+ * because of some GtkLabel wrapping issues and other mysterious bugs related to
+ * truncating ellipsizing. Needs a rethink in future. (MDK) */
+
+ gint dialog_width = (size_set && size > 24) ? 600 : 500;
+ gtk_window_set_default_size (GTK_WINDOW(preview_dialog), dialog_width, -1);
+
+ /*make reference text to have the same fontface and size*/
+ if(family_set)
+ {
+ attr = pango_attr_family_new(str);
+ add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
+ }
+ g_free(str);
+
+ /*size*/
+ if(size_set)
+ {
+ attr = pango_attr_size_new(size * PANGO_SCALE);
+ add_preview_text_attr(list, attr, 0, strlen(_("ecdg_fi_preview_font_preview_reference")));
+ }
+
+ gtk_label_set_attributes(GTK_LABEL(preview_label), list);
+ pango_attr_list_unref(list);
+
+ /*And show the dialog*/
+ gtk_window_set_transient_for(GTK_WINDOW(preview_dialog),
+ GTK_WINDOW(fontsel));
+
+ gtk_widget_show_all(preview_dialog);
+ gtk_dialog_run(GTK_DIALOG(preview_dialog));
+ gtk_widget_destroy(preview_dialog);
+}
+
+
+static gboolean is_internal_font(const gchar * name){
+ return strcmp(name, "DeviceSymbols") == 0
+ || strcmp(name, "Nokia Smiley" ) == 0
+ || strcmp(name, "NewCourier" ) == 0
+ || strcmp(name, "NewTimes" ) == 0
+ || strcmp(name, "SwissA" ) == 0
+ || strcmp(name, "Nokia Sans" ) == 0
+ || strcmp(name, "Nokia Sans Cn") == 0;
+}
+
+static void filter_out_internal_fonts(PangoFontFamily **families, int *n_families){
+ int i;
+ int n; /* counts valid fonts */
+ const gchar * name = NULL;
+
+ for(i = 0, n = 0; i < *n_families; i++){
+
+ name = pango_font_family_get_name(families[i]);
+
+ if(!is_internal_font(name)){
+
+ if(i!=n){ /* there are filtered out families */
+ families[n] = families[i]; /* shift the current family */
+ }
+
+ n++; /* count one more valid */
+ }
+ }/* foreach font family */
+
+ *n_families = n;
+}
+
+
+static void
+hildon_font_selection_dialog_show_available_fonts(HildonFontSelectionDialog
+ *fontsel)
+
+{
+ gint i;
+
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fontsel);
+
+ pango_context_list_families(gtk_widget_get_pango_context
+ (GTK_WIDGET(fontsel)), &priv->families,
+ &priv->n_families);
+
+ filter_out_internal_fonts(priv->families, &priv->n_families);
+
+ qsort(priv->families, priv->n_families, sizeof(PangoFontFamily *),
+ cmp_families);
+
+
+ for (i = 0; i < priv->n_families; i++)
+ {
+ const gchar *name = pango_font_family_get_name(priv->families[i]);
+
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_type),
+ name);
+ }
+}
+
+
+static void
+hildon_font_selection_dialog_show_available_positionings
+ (HildonFontSelectionDialogPrivate
+ *priv)
+{
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
+ _("ecdg_va_font_printpos_1"));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
+ _("ecdg_va_font_printpos_2"));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_positioning),
+ _("ecdg_va_font_printpos_3"));
+}
+
+/*Loads the sizes from a pre-allocated table*/
+static void
+hildon_font_selection_dialog_show_available_sizes
+ (HildonFontSelectionDialogPrivate
+ *priv)
+{
+ gchar *size_str;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS(font_sizes); i++)
+ {
+ size_str = g_strdup_printf ("%i%s",
+ font_sizes[i],
+ _("ecdg_va_font_size_trailer"));
+
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->cbx_font_size),
+ size_str);
+ g_free (size_str);
+ }
+}
+
+/* WARNING: This function is called only from deprecated API */
+static
+void check_tags(gpointer data, gpointer user_data)
+{
+ gchar *font_family;
+ GdkColor *fore_color = NULL;
+ gint p_size, p_weight, p_style, p_underline, p_rise;
+ gboolean b_st, ff_s, size_s, fgc_s, w_s, ss_s, u_s, sth_s, r_s;
+
+ GtkTextTag *tag = (GtkTextTag*) data;
+ HildonFontSelectionDialogSettings *settings =
+ (HildonFontSelectionDialogSettings *) user_data;
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
+
+ /*get all the properties*/
+ g_object_get(G_OBJECT(tag),
+ "family", &font_family, "family-set", &ff_s,
+ "size", &p_size, "size-set", &size_s,
+ "foreground-gdk", &fore_color, "foreground-set", &fgc_s,
+ "weight", &p_weight, "weight-set", &w_s,
+ "style", &p_style, "style-set", &ss_s,
+ "underline", &p_underline, "underline-set", &u_s,
+ "strikethrough", &b_st, "strikethrough-set", &sth_s,
+ "rise", &p_rise, "rise-set", & r_s,
+ NULL);
+
+ /* Check that the given values are valid.
+ * If not, set the combobox row indicator to 'inconsistent' */
+ if(ff_s)
+ {
+ gint new_f = -1;
+ gint i;
+
+ for(i = 0; i < priv->n_families; i++)
+ {
+ if(strcmp(font_family,
+ pango_font_family_get_name(priv->families[i])) == 0)
+ {
+ new_f = i;
+ break;
+ }
+ }
+
+ if(settings->family == -1)
+ settings->family = new_f;
+ else if(settings->family != -2 &&
+ settings->family != new_f)
+ settings->family = -2;/*inconsist*/
+
+ g_free(font_family);
+ }
+
+ if(size_s)
+ {
+ gint new_size = -1;
+ gint i;
+
+ for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
+ {
+ if(p_size == font_sizes[i] * PANGO_SCALE)
+ {
+ new_size = i;
+ break;
+ }
+ }
+
+ if(settings->size == -1)
+ settings->size = new_size;
+ else if(settings->size != -2 &&
+ settings->size != new_size)
+ settings->size = -2;/*inconsist*/
+ }
+
+ if(fgc_s && settings->color == NULL
+ && !settings->color_inconsist)
+ settings->color = fore_color;
+ else if(fore_color != NULL)
+ {
+ if(!gdk_color_equal(fore_color, settings->color)
+ && fgc_s)
+ settings->color_inconsist = TRUE;
+
+ gdk_color_free(fore_color);
+ }
+
+ if(w_s)
+ settings->weight |= p_weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
+
+ if(ss_s)
+ settings->style |= p_style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT;
+
+ if(u_s)
+ settings->underline |=
+ p_underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
+
+ if(sth_s)
+ settings->strikethrough |= b_st ? ON_BIT : OFF_BIT;
+
+ if(r_s)
+ {
+ gint new_rs = -1;
+
+ if(p_rise == 0)
+ new_rs = 0;/*normal*/
+ else if (p_rise > 0)
+ new_rs = 1;/*super*/
+ else
+ new_rs = 2;/*sub*/
+
+ if(settings->position == -1)
+ settings->position = new_rs;
+ else if(settings->position != -2 &&
+ settings->position != new_rs)
+ settings->position = -2;/*inconsist*/
+ }
+}
+
+/* WARNING: This function is called only from deprecated API */
+static
+void check_attrs(gpointer data, gpointer user_data)
+{
+ PangoAttribute *attr = (PangoAttribute *) data;
+ HildonFontSelectionDialogSettings *settings =
+ (HildonFontSelectionDialogSettings *) user_data;
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
+
+ gchar *family;
+ GdkColor color;
+ gint i;
+ gint size, weight, style, underline, strikethrough, rise;
+ gint new_f = -1, new_size = -1, new_rise = -1;
+
+ /* Check that the given values are valid.
+ * If not, set the combobox row indicator to 'inconsistent' */
+ switch(attr->klass->type)
+ {
+ case PANGO_ATTR_FAMILY:
+ family = ((PangoAttrString *) attr)->value;
+
+ for(i = 0; i < priv->n_families; i++)
+ {
+ if(strcmp(family,
+ pango_font_family_get_name(priv->families[i])) == 0)
+ {
+ new_f = i;
+ break;
+ }
+ }
+
+ if(settings->family == -1)
+ settings->family = new_f;
+ else if(settings->family != -2 &&
+ settings->family != new_f)
+ settings->family = -2;/*inconsist*/
+
+ break;
+ case PANGO_ATTR_SIZE:
+ size = ((PangoAttrInt *) attr)->value;
+
+ for(i = 0; i < G_N_ELEMENTS(font_sizes); i++)
+ {
+ if(size == font_sizes[i] * PANGO_SCALE)
+ {
+ new_size = i;
+ break;
+ }
+ }
+
+ if(settings->size == -1)
+ settings->size = new_size;
+ else if(settings->size != -2 &&
+ settings->size != new_size)
+ settings->size = -2;/*inconsist*/
+
+ break;
+ case PANGO_ATTR_FOREGROUND:
+ color.red = ((PangoAttrColor *) attr)->color.red;
+ color.green = ((PangoAttrColor *) attr)->color.green;
+ color.blue = ((PangoAttrColor *) attr)->color.blue;
+
+ if(!settings->color_inconsist && settings->color == NULL)
+ settings->color = gdk_color_copy(&color);
+ else if(settings->color != NULL &&
+ !gdk_color_equal(&color, settings->color))
+ settings->color_inconsist = TRUE;
+
+ break;
+ case PANGO_ATTR_WEIGHT:
+ weight = ((PangoAttrInt *) attr)->value;
+
+ settings->weight |= weight == PANGO_WEIGHT_NORMAL ? OFF_BIT : ON_BIT;
+
+ break;
+ case PANGO_ATTR_STYLE:
+ style = ((PangoAttrInt *) attr)->value;
+
+ settings->style |= style == PANGO_STYLE_NORMAL ? OFF_BIT : ON_BIT;
+
+ break;
+ case PANGO_ATTR_UNDERLINE:
+ underline = ((PangoAttrInt *) attr)->value;
+
+ settings->underline |=
+ underline == PANGO_UNDERLINE_NONE ? OFF_BIT : ON_BIT;
+
+ break;
+ case PANGO_ATTR_STRIKETHROUGH:
+ strikethrough = ((PangoAttrInt *) attr)->value;
+
+ settings->strikethrough |= strikethrough ? ON_BIT : OFF_BIT;
+
+ break;
+ case PANGO_ATTR_RISE:
+ rise = ((PangoAttrInt *) attr)->value;
+
+ if(rise == 0)
+ new_rise = 0;/*normal*/
+ else if (rise > 0)
+ new_rise = 1;/*super*/
+ else
+ new_rise = 2;/*sub*/
+
+ if(settings->position == -1)
+ settings->position = new_rise;
+ else if(settings->position != -2 &&
+ settings->position != new_rise)
+ settings->position = -2;/*inconsist*/
+
+ break;
+ default:
+ break;
+ }
+
+ pango_attribute_destroy(attr);
+}
+
+/* WARNING: This function is called only from deprecated API */
+static void
+settings_init(HildonFontSelectionDialogSettings *settings,
+ HildonFontSelectionDialog *fsd)
+{
+ settings->fsd = fsd;
+ settings->family = -1;
+ settings->size = -1;
+ settings->color = NULL;
+ settings->color_inconsist = FALSE;
+ settings->weight = 0;
+ settings->style = 0;
+ settings->underline = 0;
+ settings->strikethrough = 0;
+ settings->position = -1;
+}
+
+/* WARNING: This function is called only from deprecated API */
+static void
+bit_mask_toggle(gint mask, GtkToggleButton *button,
+ GObject *object, const gchar *prop,
+ const gchar *prop_set)
+{
+
+ if(mask == 3)
+ gtk_toggle_button_set_inconsistent(button, TRUE);
+ else
+ {
+ gtk_toggle_button_set_inconsistent(button, FALSE);
+
+ if(mask == 1)
+ gtk_toggle_button_set_active(button, TRUE);
+ else
+ gtk_toggle_button_set_active(button, FALSE);
+
+ g_object_notify(object, prop);
+ }
+
+ g_object_notify(object, prop_set);
+}
+
+/* WARNING: This function is called only from deprecated API */
+static void
+combo_active(gint active, GtkComboBox *box,
+ GObject *object, const gchar *prop, const gchar *prop_set)
+{
+ /*probaly not the best function, but we need all these
+ * parameters to keep things together*/
+
+
+ if(active >= 0)
+ {
+ gtk_combo_box_set_active(box, active);
+ g_object_notify(object, prop);
+ }
+ else
+ gtk_combo_box_set_active(box, -1);
+
+ g_object_notify(object, prop_set);
+}
+
+/* WARNING: This function is called only from deprecated API */
+static void
+settings_apply(HildonFontSelectionDialogSettings *settings)
+{
+
+ HildonFontSelectionDialogPrivate *priv =
+ HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(settings->fsd);
+
+ /*family*/
+ combo_active(settings->family, GTK_COMBO_BOX(priv->cbx_font_type),
+ G_OBJECT(settings->fsd), "family", "family-set");
+
+ /*size*/
+ combo_active(settings->size, GTK_COMBO_BOX(priv->cbx_font_size),
+ G_OBJECT(settings->fsd), "size", "size-set");
+
+ /*block our signal handler indicating color has been changed by
+ * the user before set the color, and unblock it after setting
+ * is done*/
+
+ if(settings->color == NULL || settings->color_inconsist)
+ {
+ GdkColor black;
+
+ black.red = black.green = black.blue = 0;
+ g_signal_handler_block((gpointer) priv->font_color_button,
+ priv->color_modified_signal_handler);
+
+ g_object_set(G_OBJECT(settings->fsd), "color", &black, "color-set",
+ FALSE, NULL);
+
+ g_signal_handler_unblock((gpointer) priv->font_color_button,
+ priv->color_modified_signal_handler);
+ }
+ else
+ g_object_set(G_OBJECT(settings->fsd), "color", settings->color, NULL);
+
+ /*weight*/
+ bit_mask_toggle(settings->weight, GTK_TOGGLE_BUTTON(priv->chk_bold),
+ G_OBJECT(settings->fsd), "bold", "bold-set");
+
+ /*style*/
+ bit_mask_toggle(settings->style, GTK_TOGGLE_BUTTON(priv->chk_italic),
+ G_OBJECT(settings->fsd), "italic", "italic-set");
+
+ /*underline*/
+ bit_mask_toggle(settings->underline,
+ GTK_TOGGLE_BUTTON(priv->chk_underline),
+ G_OBJECT(settings->fsd), "underline", "underline-set");
+
+ /*strikethrough*/
+ bit_mask_toggle(settings->strikethrough,
+ GTK_TOGGLE_BUTTON(priv->chk_strikethrough),
+ G_OBJECT(settings->fsd), "strikethrough",
+ "strikethrough-set");
+
+ /*position*/
+ combo_active(settings->position, GTK_COMBO_BOX(priv->cbx_positioning),
+ G_OBJECT(settings->fsd), "position", "position-set");
+}
+
+static void
+settings_destroy(HildonFontSelectionDialogSettings *settings)
+{
+ if(settings->color != NULL)
+ gdk_color_free(settings->color);
+}
+
+static void
+toggle_clicked(GtkButton *button, gpointer unused)
+{
+ GtkToggleButton *t_b = GTK_TOGGLE_BUTTON(button);
+
+ /*we have to remove the inconsistent state ourselves*/
+ if(gtk_toggle_button_get_inconsistent(t_b))
+ {
+ gtk_toggle_button_set_inconsistent(t_b, FALSE);
+ gtk_toggle_button_set_active(t_b, FALSE);
+ }
+}
+
+/*******************/
+/*Public functions*/
+/*******************/
+
+/**
+ * hildon_font_selection_dialog_new:
+ * @parent: the parent window
+ * @title: the title of font selection dialog
+ *
+ * If NULL is passed for title, then default title
+ * "Font" will be used.
+ *
+ * Returns: a new #HildonFontSelectionDialog
+ */
+GtkWidget *
+hildon_font_selection_dialog_new(GtkWindow * parent,
+ const gchar * title)
+{
+ HildonFontSelectionDialog *fontseldiag;
+
+ fontseldiag = g_object_new(HILDON_TYPE_FONT_SELECTION_DIALOG,
+ "has-separator", FALSE, NULL);
+
+ if (title)
+ gtk_window_set_title(GTK_WINDOW(fontseldiag), title);
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(fontseldiag), parent);
+
+ return GTK_WIDGET(fontseldiag);
+}
+
+/**
+ * hildon_font_selection_dialog_get_preview_text:
+ * @fsd: the font selection dialog
+ *
+ * Gets the text in preview dialog, which does not include the
+ * reference text. The returned string must be freed by the user.
+ *
+ * Returns: a string pointer
+ */
+gchar *
+hildon_font_selection_dialog_get_preview_text(HildonFontSelectionDialog * fsd)
+{
+ HildonFontSelectionDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
+ priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
+ return g_strdup(priv->preview_text);
+}
+
+/**
+ * hildon_font_selection_dialog_set_preview_text:
+ * @fsd: the font selection dialog
+ * @text: the text to be displayed in the preview dialog
+ *
+ * The default preview text is
+ * "The quick brown fox jumped over the lazy dogs"
+ */
+void
+hildon_font_selection_dialog_set_preview_text(HildonFontSelectionDialog *
+ fsd, const gchar * text)
+{
+ HildonFontSelectionDialogPrivate *priv = NULL;
+
+ g_return_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd));
+ g_return_if_fail(text);
+
+ priv = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
+
+ g_free(priv->preview_text);
+ priv->preview_text = g_strdup(text);
+ g_object_notify (G_OBJECT (fsd), "preview-text");
+}
+
+/**
+ * hildon_font_selection_dialog_get_text_tag:
+ * @fsd: the font selection dialog
+ *
+ * Get the #GtkTextTag for selections. This function
+ * is deprecated. The best way to use
+ * the text tags is to reuse them as much as possible.
+ * The recommended way is to get the properties of the font
+ * selection dialog on GTK_RESPONSE_OK, and according to
+ * these properties use the tags that you have pre-created.
+ *
+ * Returns: a #GtkTextTag having corresponding properties
+ * set
+ */
+GtkTextTag *
+hildon_font_selection_dialog_get_text_tag (HildonFontSelectionDialog *fsd)
+{
+ GtkTextTag *tag;
+ gint size, position;
+ gboolean family_set, size_set, color_set, bold, bold_set,
+ italic, italic_set, underline, underline_set,
+ strikethrough, strikethrough_set, position_set;
+ GdkColor *color = NULL;
+ gchar *family = NULL;
+
+ tag = gtk_text_tag_new(NULL);
+
+ g_object_get(G_OBJECT(fsd),
+ "family", &family, "family-set", &family_set,
+ "size", &size, "size-set", &size_set,
+ "color", &color, "color-set", &color_set,
+ "bold", &bold, "bold-set", &bold_set,
+ "italic", &italic, "italic-set", &italic_set,
+ "underline", &underline, "underline-set", &underline_set,
+ "strikethrough", &strikethrough, "strikethrough-set",
+ &strikethrough_set, "position", &position,
+ "position-set", &position_set, NULL);
+ /*family*/
+ if(family_set)
+ g_object_set(G_OBJECT(tag), "family",
+ family, "family-set", TRUE, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "family-set", FALSE, NULL);
+
+ g_free(family);
+
+ /*size*/
+ if(size_set)
+ g_object_set(G_OBJECT(tag), "size", size * PANGO_SCALE,
+ "size-set", TRUE, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "size-set", FALSE, NULL);
+
+ /*color*/
+ if(color_set)
+ g_object_set(G_OBJECT(tag), "foreground-gdk", color,
+ "foreground-set", TRUE ,NULL);
+ else
+ g_object_set(G_OBJECT(tag), "foreground-set", FALSE, NULL);
+
+ if(color != NULL)
+ gdk_color_free(color);
+
+ /*weight*/
+ if(bold_set)
+ {
+ if(bold)
+ g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_NORMAL, NULL);
+
+ g_object_set(G_OBJECT(tag), "weight-set", TRUE, NULL);
+ }
+ else
+ g_object_set(G_OBJECT(tag), "weight-set", FALSE, NULL);
+
+ /*style*/
+ if(italic_set)
+ {
+ if(italic)
+ g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL);
+
+ g_object_set(G_OBJECT(tag), "style-set", TRUE, NULL);
+ }
+ else
+ g_object_set(G_OBJECT(tag), "style-set", FALSE, NULL);
+
+ /*underline*/
+ if(underline_set)
+ {
+ if(underline)
+ g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_SINGLE, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_NONE, NULL);
+
+ g_object_set(G_OBJECT(tag), "underline-set", TRUE, NULL);
+ }
+ else
+ g_object_set(G_OBJECT(tag), "underline-set", FALSE, NULL);
+
+ /*strikethrough*/
+ if(strikethrough_set)
+ {
+ if(strikethrough)
+ g_object_set(G_OBJECT(tag), "strikethrough", TRUE, NULL);
+ else
+ g_object_set(G_OBJECT(tag), "strikethrough", FALSE, NULL);
+
+ g_object_set(G_OBJECT(tag), "strikethrough-set", TRUE, NULL);
+ }
+ else
+ g_object_set(G_OBJECT(tag), "strikethrough-set", FALSE, NULL);
+
+ /*position*/
+ if(position_set)
+ {
+ switch(position)
+ {
+ case 1: /*super*/
+ g_object_set(G_OBJECT(tag), "rise", SUPERSCRIPT_RISE, NULL);
+ break;
+ case -1: /*sub*/
+ g_object_set(G_OBJECT(tag), "rise", SUBSCRIPT_LOW, NULL);
+ break;
+ case 0: /*normal*/
+ g_object_set(G_OBJECT(tag), "rise", 0, NULL);
+ break;
+ }
+ g_object_set(G_OBJECT(tag), "rise-set", TRUE, NULL);
+ }
+ else
+ g_object_set(G_OBJECT(tag), "rise-set", FALSE, NULL);
+
+ return tag;
+}
+
+/**
+ * hildon_font_selection_dialog_set_buffer:
+ * @fsd: the font selection dialog
+ * @buffer: a #GtkTextBuffer containing the text to which the selections will
+ * be applied. Applying is responsibility of application.
+ *
+ * This is deprecated. GtkTextBuffer is not enough
+ * to get the attributes of currently selected text. Please
+ * inspect the attributes yourself, and set the properties of
+ * font selection dialog to reflect your inspection.
+ */
+void
+hildon_font_selection_dialog_set_buffer (HildonFontSelectionDialog *fsd,
+ GtkTextBuffer *buffer)
+{
+ GtkTextIter begin, end, iter;
+ HildonFontSelectionDialogSettings settings;
+
+ gtk_text_buffer_get_selection_bounds(buffer, &begin, &end);
+
+ settings_init(&settings, fsd);
+
+ iter = begin;
+
+ /* Keep original settings if the selection includes nothing */
+ if(gtk_text_iter_compare(&iter, &end) == 0)
+ {
+ GSList *slist;
+
+ slist = gtk_text_iter_get_tags(&iter);
+ g_slist_foreach(slist, check_tags, (gpointer) &settings);
+ g_slist_free(slist);
+ }
+
+ /* Apply the user settings to the selected text */
+ while(gtk_text_iter_compare(&iter, &end) < 0)
+ {
+ GSList *slist;
+
+ slist = gtk_text_iter_get_tags(&iter);
+ g_slist_foreach(slist, check_tags, (gpointer) &settings);
+ g_slist_free(slist);
+
+ if(!gtk_text_iter_forward_cursor_position(&iter))
+ break;
+ }
+
+ settings_apply(&settings);
+ settings_destroy(&settings);
+}
+
+/**
+ * hildon_font_selection_dialog_get_font:
+ * @fsd: the font selection dialog
+ *
+ * This is deprecated. @PangoAttrList needs
+ * starting index, and end index on construction.
+ *
+ * Returns: pointer to @PangoAttrList
+ */
+PangoAttrList
+*hildon_font_selection_dialog_get_font(HildonFontSelectionDialog * fsd)
+{
+ HildonFontSelectionDialogPrivate *priv
+ = HILDON_FONT_SELECTION_DIALOG_GET_PRIVATE(fsd);
+
+ g_return_val_if_fail(HILDON_IS_FONT_SELECTION_DIALOG(fsd), FALSE);
+ /*an approve of none working api, should have ask for start_index,
+ * and length in bytes of the string, currently using preview_text
+ * length, KLUDGE!*/
+
+ return hildon_font_selection_dialog_create_attrlist(fsd,
+ 0, strlen(priv->preview_text));
+}
+
+/**
+ * hildon_font_selection_dialog_set_font:
+ * @fsd: the font selection dialog
+ * @list: the pango attribute list
+ *
+ * This is a deprecated.
+ *
+ * Sets the font to the dialog.
+ */
+void
+hildon_font_selection_dialog_set_font(HildonFontSelectionDialog * fsd,
+ PangoAttrList * list)
+{
+ PangoAttrIterator *iter;
+ HildonFontSelectionDialogSettings settings;
+
+ iter = pango_attr_list_get_iterator(list);
+
+ settings_init(&settings, fsd);
+
+ while(iter != NULL)
+ {
+ GSList *slist;
+
+ slist = pango_attr_iterator_get_attrs(iter);
+ g_slist_foreach(slist, check_attrs, (gpointer) &settings);
+ g_slist_free(slist);
+
+ if(!pango_attr_iterator_next(iter))
+ break;
+ }
+
+ pango_attr_iterator_destroy(iter);
+
+ settings_apply(&settings);
+ settings_destroy(&settings);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_FONT_SELECTION_DIALOG_H__
+#define __HILDON_FONT_SELECTION_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+#include <gtk/gtktextbuffer.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_FONT_SELECTION_DIALOG \
+ (hildon_font_selection_dialog_get_type ())
+#define HILDON_FONT_SELECTION_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
+ HILDON_TYPE_FONT_SELECTION_DIALOG, HildonFontSelectionDialog))
+#define HILDON_FONT_SELECTION_DIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_FONT_SELECTION_DIALOG,\
+ HildonFontSelectionDialogClass))
+#define HILDON_IS_FONT_SELECTION_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ HILDON_TYPE_FONT_SELECTION_DIALOG))
+#define HILDON_IS_FONT_SELECTION_DIALOG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_FONT_SELECTION_DIALOG))
+#define HILDON_FONT_SELECTION_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj),\
+ HILDON_TYPE_FONT_SELECTION_DIALOG,\
+ HildonFontSelectionDialogClass))
+
+typedef struct _HildonFontSelectionDialog HildonFontSelectionDialog;
+typedef struct _HildonFontSelectionDialogClass HildonFontSelectionDialogClass;
+
+struct _HildonFontSelectionDialog
+{
+ GtkDialog parent;
+};
+
+struct _HildonFontSelectionDialogClass
+{
+ GtkDialogClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+#ifndef HILDON_DISABLE_DEPRECATED
+PangoAttrList* hildon_font_selection_dialog_get_font(HildonFontSelectionDialog *fsd);
+
+void hildon_font_selection_dialog_set_font(HildonFontSelectionDialog *fsd,
+ PangoAttrList *list);
+#endif
+
+
+GType hildon_font_selection_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget* hildon_font_selection_dialog_new (GtkWindow *parent,
+ const gchar *title);
+
+
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_font_selection_dialog_set_buffer (HildonFontSelectionDialog *fsd,
+ GtkTextBuffer *buffer);
+
+GtkTextTag* hildon_font_selection_dialog_get_text_tag (HildonFontSelectionDialog *fsd);
+#endif
+
+
+gchar* hildon_font_selection_dialog_get_preview_text (HildonFontSelectionDialog *fsd);
+
+void hildon_font_selection_dialog_set_preview_text (HildonFontSelectionDialog *fsd,
+ const gchar * text);
+
+G_END_DECLS
+
+#endif /* __HILDON_FONT_SELECTION_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-get-password-dialog
+ * @short_description: A widget used to get a password
+ * @see_also: #HildonSetPasswordDialog
+ *
+ * HildonGetPasswordDialog prompts the user for a password. It allows
+ * inputting password, with an optional configurable label eg. for
+ * showing the domain. The maximum length of the password can be set.
+ */
+
+#include <glib.h>
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <gtk/gtk.h>
+
+#include "gtk-infoprint.h"
+#include "hildon-input-mode-hint.h"
+
+#include <hildon-widgets/hildon-caption.h>
+#include <hildon-widgets/hildon-get-password-dialog.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+static GtkDialogClass * parent_class;
+
+typedef struct _HildonGetPasswordDialogPrivate
+ HildonGetPasswordDialogPrivate;
+
+struct _HildonGetPasswordDialogPrivate {
+ GtkButton *okButton;
+ GtkButton *cancelButton;
+
+ GtkLabel *domainLabel;
+ HildonCaption *passwordEntry;
+ gboolean get_old;
+};
+
+
+#define HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_GET_PASSWORD_DIALOG, HildonGetPasswordDialogPrivate));
+
+static void
+hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass *
+ class);
+static void hildon_get_password_dialog_init(HildonGetPasswordDialog *
+ widget);
+static void hildon_get_password_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_get_password_get_property(GObject * object,
+ guint prop_id, GValue * value,
+ GParamSpec * pspec);
+static void create_contents(HildonGetPasswordDialog *dialog);
+static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason,
+ gpointer unused);
+
+enum{
+ PROP_NONE = 0,
+ PROP_DOMAIN,
+ PROP_PASSWORD,
+ PROP_NUMBERS_ONLY,
+ PROP_CAPTION_LABEL,
+ PROP_MAX_CHARS,
+ PROP_GET_OLD
+};
+
+/* Private functions */
+static void
+hildon_get_password_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
+ HildonGetPasswordDialogPrivate *priv;
+
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id) {
+ case PROP_DOMAIN:
+ /* Set label text representing password domain */
+ gtk_label_set_text(priv->domainLabel, g_value_get_string(value));
+ break;
+ case PROP_PASSWORD:
+ gtk_entry_set_text(GTK_ENTRY
+ (hildon_caption_get_control (priv->passwordEntry)),
+ g_value_get_string(value));
+ break;
+ case PROP_NUMBERS_ONLY:
+ /* Set input mode for the password entry */
+ g_object_set(G_OBJECT(hildon_caption_get_control(priv->passwordEntry)),
+ "input-mode",
+ (g_value_get_boolean(value)
+ ? HILDON_INPUT_MODE_HINT_NUMERIC
+ : HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL),
+ NULL);
+ break;
+ case PROP_CAPTION_LABEL:
+ hildon_get_password_dialog_set_caption(dialog, g_value_get_string(value));
+ break;
+ case PROP_MAX_CHARS:
+ hildon_get_password_dialog_set_max_characters(dialog,
+ g_value_get_int(value));
+ break;
+ case PROP_GET_OLD:
+ priv->get_old = g_value_get_boolean(value);
+ create_contents(dialog);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_get_password_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonGetPasswordDialog *dialog = HILDON_GET_PASSWORD_DIALOG(object);
+ HildonGetPasswordDialogPrivate *priv;
+ const gchar *string;
+ gint max_length;
+ gint input_mode;
+
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id) {
+ case PROP_DOMAIN:
+ string = gtk_label_get_text(priv->domainLabel);
+ g_value_set_string(value, string);
+ break;
+ case PROP_PASSWORD:
+ string = gtk_entry_get_text(GTK_ENTRY (hildon_caption_get_control(priv->passwordEntry)));
+ g_value_set_string(value, string);
+ break;
+ case PROP_NUMBERS_ONLY:
+ /* This property is set if and only if the input mode
+ of the password entry has been set to numeric only */
+ g_object_get(G_OBJECT(hildon_caption_get_control(priv->passwordEntry)),
+ "input-mode", &input_mode, NULL);
+ g_value_set_boolean(value,
+ (input_mode == HILDON_INPUT_MODE_HINT_NUMERIC));
+ break;
+ case PROP_CAPTION_LABEL:
+ string = hildon_caption_get_label(priv->passwordEntry);
+ g_value_set_string(value, string);
+ break;
+ case PROP_MAX_CHARS:
+ max_length = gtk_entry_get_max_length(
+ GTK_ENTRY (hildon_caption_get_control (priv->passwordEntry)));
+ g_value_set_int(value, max_length);
+ break;
+ case PROP_GET_OLD:
+ g_value_set_boolean(value, priv->get_old);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_get_password_dialog_class_init(HildonGetPasswordDialogClass * class)
+{
+
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+
+ parent_class = g_type_class_peek_parent(class);
+
+ /* Override virtual functions */
+ object_class->set_property = hildon_get_password_set_property;
+ object_class->get_property = hildon_get_password_get_property;
+
+ /* Install new properties */
+ g_object_class_install_property
+ (object_class,
+ PROP_DOMAIN,
+ g_param_spec_string ("domain",
+ "Domain",
+ "Set domain(content) for optional label.",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_PASSWORD,
+ g_param_spec_string ("password",
+ "Password",
+ "Set content for password entry",
+ "DEFAULT",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_NUMBERS_ONLY,
+ g_param_spec_boolean ("numbers_only",
+ "NumbersOnly",
+ "Set entry to accept only numeric values",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_CAPTION_LABEL,
+ g_param_spec_string ("caption-label",
+ "Caption Label",
+ "The text to be set as the caption label",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_MAX_CHARS,
+ g_param_spec_int ("max-characters",
+ "Maximum Characters",
+ "The maximum number of characters the password"
+ " dialog accepts",
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class,
+ PROP_GET_OLD,
+ g_param_spec_boolean ("get-old",
+ "Get Old Password",
+ "TRUE if dialog is a get old password dialog, "
+ "FALSE if dialog is a get password dialog",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* Install private structure */
+ g_type_class_add_private(class,
+ sizeof(HildonGetPasswordDialogPrivate));
+}
+
+static void
+hildon_get_password_dialog_init(HildonGetPasswordDialog * dialog)
+{
+ /* Set initial properties for the dialog; the actual contents are
+ created once the 'get-old' property is set with g_object_new */
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+}
+
+static void
+create_contents(HildonGetPasswordDialog *dialog)
+{
+ HildonGetPasswordDialogPrivate *priv;
+ GtkSizeGroup * group;
+ GtkWidget *control;
+
+ /* Cache private pointer for faster member access */
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Sizegroup for captions */
+ group = GTK_SIZE_GROUP(gtk_size_group_new
+ (GTK_SIZE_GROUP_HORIZONTAL));
+
+ /* Dialog title */
+ gtk_window_set_title(GTK_WINDOW(dialog),
+ priv->get_old
+ ? _(HILDON_GET_PASSWORD_DIALOG_TITLE)
+ : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_TITLE));
+
+ /* Optional password domain label */
+ priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
+
+ /* Create buttons */
+ priv->okButton =
+ GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
+ (priv->get_old
+ ? _(HILDON_GET_PASSWORD_DIALOG_OK)
+ : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_OK)),
+
+ GTK_RESPONSE_OK));
+ priv->cancelButton =
+ GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
+ (priv->get_old
+ ? _(HILDON_GET_PASSWORD_DIALOG_CANCEL)
+ : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_CANCEL)),
+ GTK_RESPONSE_CANCEL));
+
+ /* Create password text entry */
+ control = gtk_entry_new();
+ gtk_entry_set_width_chars (GTK_ENTRY (control), 20);
+
+ g_object_set (control, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
+ gtk_entry_set_visibility(GTK_ENTRY(control), FALSE);
+ priv->passwordEntry = HILDON_CAPTION
+ (hildon_caption_new(group,
+ (priv->get_old
+ ? _(HILDON_GET_PASSWORD_DIALOG_PASSWORD)
+ : _(HILDON_GET_PASSWORD_VERIFY_DIALOG_PASSWORD)),
+ control, NULL,
+ HILDON_CAPTION_OPTIONAL));
+ hildon_caption_set_separator(HILDON_CAPTION(priv->passwordEntry), "");
+
+ /* Do the basic layout */
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(priv->passwordEntry), FALSE, FALSE, 0);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+
+ /* Ensure group is freed when all its contents have been removed */
+ g_object_unref(group);
+}
+
+
+/* Public functions */
+
+/**
+ * hildon_get_password_dialog_get_type:
+ *
+ * Returns GType for HildonGetPasswordDialog as produced by
+ * g_type_register_static().
+ *
+ * Returns: HildonGetPasswordDialog type
+ */
+GType hildon_get_password_dialog_get_type(void)
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonGetPasswordDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_get_password_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonGetPasswordDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_get_password_dialog_init
+ };
+
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonGetPasswordDialog",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+/**
+ * hildon_get_password_dialog_new:
+ * @parent: parent window; can be NULL
+ * @get_old: FALSE creates a new get password dialog and
+ * TRUE creates a new get old password dialog. That is,
+ * if the password to be obtained is the old password,
+ * this parameter is specified TRUE.
+ *
+ * Construct a new HildonGetPasswordDialog.
+ *
+ * Returns: a new #GtkWidget of type HildonGetPasswordDialog
+ */
+GtkWidget *hildon_get_password_dialog_new(GtkWindow * parent,
+ gboolean get_old)
+{
+ HildonGetPasswordDialog *dialog = g_object_new
+ (HILDON_TYPE_GET_PASSWORD_DIALOG,
+ "get-old", get_old, NULL);
+
+ if (parent != NULL) {
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+ }
+
+ return GTK_WIDGET(dialog);
+}
+
+/**
+ * hildon_get_password_dialog_new_with_default:
+ * @parent: parent window; can be NULL
+ * @password: a default password to be shown in password field
+ * @get_old: FALSE creates a new get password dialog and
+ * TRUE creates a new get old password dialog.That is,
+ * if the password to be obtained is the old password,
+ * this parameter is specified TRUE.
+ *
+ *
+ * Same as #hildon_get_password_dialog_new but with a default password
+ * in password field.
+ *
+ * Returns: a new #GtkWidget of type HildonGetPasswordDialog
+ */
+GtkWidget *hildon_get_password_dialog_new_with_default (GtkWindow * parent,
+ const gchar *password,
+ gboolean get_old)
+{
+ GtkWidget *dialog;
+
+ dialog = hildon_get_password_dialog_new(parent, get_old);
+ if(password != NULL)
+ g_object_set(G_OBJECT(dialog), "password", password, NULL);
+
+ return GTK_WIDGET(dialog);
+}
+
+/**
+ * hildon_get_password_dialog_get_password:
+ * @dialog: pointer to HildonSetPasswordDialog
+ *
+ * Gets the currently inputted password.
+ *
+ * Returns: current password ( if the dialog is successfully
+ * accepted with 'OK' )
+ */
+const gchar
+ *hildon_get_password_dialog_get_password(HildonGetPasswordDialog *
+ dialog)
+{
+ GtkEntry *entry1;
+ gchar *text1;
+
+ HildonGetPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog), NULL);
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Retrieve the password entry widget */
+ entry1 = GTK_ENTRY (hildon_caption_get_control(priv->passwordEntry));
+ text1 = GTK_ENTRY(entry1)->text;
+
+ return text1;
+}
+
+/**
+ * hildon_get_password_dialog_set_domain(GtkWidget *dialog,
+ * @dialog: the dialog
+ * @domain: the domain or some other descriptive text to be set
+ *
+ * Sets the optional descriptive text.
+ */
+
+void hildon_get_password_dialog_set_domain(HildonGetPasswordDialog *dialog,
+ const gchar *domain)
+{
+ HildonGetPasswordDialogPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
+
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ gtk_label_set_text(priv->domainLabel, domain);
+
+}
+
+/**
+ * hildon_get_password_dialog_set_title:
+ * @dialog: the dialog
+ * @new_title: the text to be set as the dialog title
+ *
+ * Sets the dialog title.
+ *
+ * DEPRECATED! use gtk_window_set_title instead.
+ */
+void hildon_get_password_dialog_set_title(HildonGetPasswordDialog *dialog,
+ const gchar *new_title)
+
+{
+ /* FIXME: This method is completely useless, should be deprecated/removed */
+ g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
+ g_return_if_fail (new_title !=NULL);
+ gtk_window_set_title(GTK_WINDOW(dialog),
+ new_title);
+}
+
+/**
+ * hildon_get_password_dialog_set_caption:
+ * @dialog: the dialog
+ * @new_caption: the text to be set as the caption label
+ *
+ * Sets the password entry field's neigbouring label.
+ */
+
+void hildon_get_password_dialog_set_caption(HildonGetPasswordDialog *dialog,
+ const gchar *new_caption)
+{
+
+
+ HildonGetPasswordDialogPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
+ g_return_if_fail (new_caption != NULL);
+
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ hildon_caption_set_label(priv->passwordEntry, new_caption);
+
+}
+
+/**
+ * hildon_get_password_dialog_set_max_characters:
+ * @dialog: the dialog
+ * @max_characters: the maximum number of characters the password dialog
+ * accepts
+ * @new_caption: the text to be set as the caption label
+ *
+ * sets the maximum number of characters allowed as the password
+ */
+
+void hildon_get_password_dialog_set_max_characters (HildonGetPasswordDialog *dialog, gint max_characters )
+{
+ HildonGetPasswordDialogPrivate *priv;
+
+ g_return_if_fail (max_characters > 0);
+ g_return_if_fail (HILDON_IS_GET_PASSWORD_DIALOG(dialog));
+
+ priv = HILDON_GET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Apply the given length to password entry */
+ gtk_entry_set_max_length(GTK_ENTRY
+ (hildon_caption_get_control
+ (priv->passwordEntry)),
+ max_characters);
+
+ /* Connect callback to show error banner if the limit is exceeded */
+ g_signal_connect(GTK_ENTRY
+ (hildon_caption_get_control
+ (priv->passwordEntry)),
+ "invalid_input",
+ G_CALLBACK(_invalid_input),
+ NULL
+ );
+}
+
+static void _invalid_input(GtkWidget *widget, GtkInvalidInputType reason,
+ gpointer unused)
+{
+ if (reason==GTK_INVALID_INPUT_MAX_CHARS_REACHED) {
+ gtk_infoprint(GTK_WINDOW(widget), _(HILDON_GET_PASSWORD_DIALOG_MAX_CHARS));
+ }
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_GET_PASSWORD_DIALOG_H__
+#define __HILDON_GET_PASSWORD_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_GET_PASSWORD_DIALOG ( hildon_get_password_dialog_get_type() )
+
+#define HILDON_GET_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_GET_PASSWORD_DIALOG,\
+ HildonGetPasswordDialog))
+
+#define HILDON_GET_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_GET_PASSWORD_DIALOG, \
+ HildonGetPasswordDialogClass))
+
+#define HILDON_IS_GET_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_GET_PASSWORD_DIALOG))
+
+#define HILDON_IS_GET_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_GET_PASSWORD_DIALOG))
+
+
+#define HILDON_GET_PASSWORD_DIALOG_TITLE "ecdg_ti_get_old_password"
+#define HILDON_GET_PASSWORD_DIALOG_PASSWORD "ecdg_fi_get_old_pwd_enter_pwd"
+#define HILDON_GET_PASSWORD_DIALOG_OK "ecdg_bd_get_old_password_dialog_ok"
+#define HILDON_GET_PASSWORD_DIALOG_CANCEL "ecdg_bd_get_old_password_dialog_cancel"
+
+#define HILDON_GET_PASSWORD_VERIFY_DIALOG_TITLE "ecdg_ti_verify_password"
+#define HILDON_GET_PASSWORD_VERIFY_DIALOG_PASSWORD "ecdg_fi_verify_pwd_enter_pwd"
+#define HILDON_GET_PASSWORD_VERIFY_DIALOG_OK "ecdg_bd_verify_password_dialog_ok"
+#define HILDON_GET_PASSWORD_VERIFY_DIALOG_CANCEL "ecdg_bd_verify_password_dialog_cancel"
+
+#define HILDON_GET_PASSWORD_DIALOG_MAX_CHARS "ckdg_ib_maximum_characters_reached"
+
+typedef struct _HildonGetPasswordDialog HildonGetPasswordDialog;
+typedef struct _HildonGetPasswordDialogClass HildonGetPasswordDialogClass;
+
+struct _HildonGetPasswordDialog {
+ GtkDialog parent;
+};
+
+struct _HildonGetPasswordDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_get_password_dialog_get_type(void) G_GNUC_CONST;
+
+GtkWidget *hildon_get_password_dialog_new (GtkWindow *parent,
+ gboolean get_old);
+
+GtkWidget *hildon_get_password_dialog_new_with_default (GtkWindow *parent,
+ const gchar *password,
+ gboolean get_old);
+
+void hildon_get_password_dialog_set_domain (HildonGetPasswordDialog *dialog,
+ const gchar *domain);
+
+void hildon_get_password_dialog_set_caption (HildonGetPasswordDialog *dialog,
+ const gchar *new_caption);
+
+void hildon_get_password_dialog_set_max_characters(HildonGetPasswordDialog *dialog,
+ gint max_characters);
+
+const gchar * hildon_get_password_dialog_get_password(HildonGetPasswordDialog * dialog);
+
+
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_get_password_dialog_set_title (HildonGetPasswordDialog *dialog,
+ const gchar *new_title);
+#endif /* HILDON_DISABLE_DEPRECATED */
+
+G_END_DECLS
+#endif /* __HILDON_GET_PASSWORD_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file hildon-grid-item-private.h
+ *
+ * This file is a private header file for he implementation of
+ * HildonGridItem. HildonGridItem is an item mainly used in HildonGrid. It
+ * has an icon, emblem and a label. This private header file exists so that
+ * grid can call semi-public functions of an item.
+ */
+
+#ifndef __HILDON_GRID_ITEM_PRIVATE_H__
+#define __HILDON_GRID_ITEM_PRIVATE_H__
+
+#include <hildon-widgets/hildon-grid-item.h>
+
+G_BEGIN_DECLS
+
+
+void _hildon_grid_item_set_label(HildonGridItem *item,
+ const gchar *label);
+
+void _hildon_grid_item_set_emblem_size(HildonGridItem *item,
+ const gint emblem_size);
+void _hildon_grid_item_set_label_pos(HildonGridItem *item,
+ HildonGridPositionType label_pos);
+
+void _hildon_grid_item_set_icon_size(HildonGridItem *item,
+ HildonGridItemIconSizeType icon_size);
+
+void _hildon_grid_item_set_focus_margin(HildonGridItem *item,
+ const gint focus_margin);
+void _hildon_grid_item_set_label_height(HildonGridItem *item,
+ const gint label_height);
+void _hildon_grid_item_set_label_icon_margin(HildonGridItem *item,
+ const gint label_icon_margin);
+void _hildon_grid_item_set_icon_width(HildonGridItem *item,
+ const gint icon_width);
+void _hildon_grid_item_set_icon_height(HildonGridItem *item,
+ const gint icon_height);
+void _hildon_grid_item_set_label_height(HildonGridItem *item,
+ const gint label_height);
+
+void _hildon_grid_item_done_updating_settings(HildonGridItem *item);
+
+
+G_END_DECLS
+
+#endif /* __HILDON_GRID_ITEM_PRIVATE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-grid-item
+ * @short_description: Creating grid items used by #HildonGrid
+ * @see_also: #HildonGrid
+ *
+ * HildonGridItem is used to create grid items used by #HildonGrid. The
+ * grid item consists of an icon and a label. Based on the displaying
+ * mode employed by #HildonGrid, the label is justified to the right or
+ * the bottom.
+ */
+
+/*
+ * TODO:
+ * - play with libtool to get _-functions private but accesable from grid
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkicontheme.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkmisc.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkenums.h>
+#include <pango/pango.h>
+
+#include "hildon-grid-item-private.h"
+#include <hildon-widgets/hildon-grid-item.h>
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_GRID_ITEM_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_GRID_ITEM, \
+ HildonGridItemPrivate))
+
+typedef struct _HildonGridItemPrivate HildonGridItemPrivate;
+
+
+/* Default icon. */
+#define DEFAULT_ICON_BASENAME "qgn_list_gene_unknown_file"
+#define HILDON_GRID_ICON_SIZE 26
+#define HILDON_GRID_EMBLEM_SIZE 16
+
+/* Use some alpha-thing for emblems. */
+#define USE_DIRTY_ALPHA
+
+struct _HildonGridItemPrivate {
+ gchar *icon_basename;
+ gint icon_size;
+ GtkWidget *icon;
+
+ gchar *emblem_basename;
+ gint emblem_size;
+
+ GtkWidget *label; /* TODO use pango! */
+ HildonGridPositionType label_pos;
+
+ gint focus_margin;
+ gint label_height;
+ gint label_icon_margin;
+ gint column_margin;
+ gint icon_width;
+ gint icon_height;
+ gint row_height;
+
+ gint pending_icon_size;
+ gint pending_emblem_size;
+ HildonGridPositionType pending_label_pos;
+ gint pending_focus_margin;
+ gint pending_label_height;
+ gint pending_label_icon_margin;
+ gint pending_icon_width;
+ gint pending_icon_height;
+
+ gboolean selected;
+};
+
+enum{
+ PROP_NONE = 0,
+ PROP_EMBLEM_TYPE,
+ PROP_ICON_BASENAME
+};
+
+/* Prototypes. */
+static void hildon_grid_item_class_init(HildonGridItemClass * klass);
+static void hildon_grid_item_init(HildonGridItem * item);
+static gboolean hildon_grid_item_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static void hildon_grid_item_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void hildon_grid_item_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static void hildon_grid_item_forall(GtkContainer * container,
+ gboolean include_int,
+ GtkCallback callback,
+ gpointer callback_data);
+static void hildon_grid_item_remove(GtkContainer * container,
+ GtkWidget * child);
+
+static void hildon_grid_item_finalize(GObject * object);
+
+static void update_icon(HildonGridItem * item);
+static void set_label_justify(HildonGridItem * item);
+
+static void hildon_grid_item_set_icon_size(HildonGridItem *item,
+ HildonGridItemIconSizeType icon_size);
+
+static void hildon_grid_item_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+
+static void hildon_grid_item_get_property(GObject * object,
+ guint prop_id, GValue * value,
+ GParamSpec * pspec);
+
+
+static GtkContainerClass *parent_class = NULL;
+
+/* Private functions */
+static void
+hildon_grid_item_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonGridItem *item = HILDON_GRID_ITEM(object);
+ HildonGridItemPrivate *priv;
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ switch (prop_id) {
+ case PROP_EMBLEM_TYPE:
+ hildon_grid_item_set_emblem_type(item, g_value_get_string(value));
+ break;
+ case PROP_ICON_BASENAME:
+ if(priv->icon_basename)
+ g_free(priv->icon_basename);
+
+ priv->icon_basename = g_strdup(g_value_get_string(value));
+ update_icon(item);
+
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_grid_item_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonGridItem *item = HILDON_GRID_ITEM(object);
+ HildonGridItemPrivate *priv;
+ const gchar *string;
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ switch (prop_id) {
+ case PROP_EMBLEM_TYPE:
+ string = hildon_grid_item_get_emblem_type(item);
+ g_value_set_string(value, string);
+ break;
+ case PROP_ICON_BASENAME:
+ g_value_set_string(value, priv->icon_basename);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+
+GType
+hildon_grid_item_get_type(void)
+{
+ static GType grid_item_type = 0;
+
+ if (!grid_item_type) {
+ static const GTypeInfo grid_item_info = {
+ sizeof(HildonGridItemClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_grid_item_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonGridItem),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_grid_item_init,
+ };
+ grid_item_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonGridItem",
+ &grid_item_info, 0);
+ }
+
+ return grid_item_type;
+}
+
+static void
+hildon_grid_item_class_init(HildonGridItemClass *klass)
+{
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+ GObjectClass *gobject_class;
+
+ widget_class = GTK_WIDGET_CLASS(klass);
+ gobject_class = G_OBJECT_CLASS(klass);
+ container_class = GTK_CONTAINER_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(HildonGridItemPrivate));
+
+ gobject_class->finalize = hildon_grid_item_finalize;
+
+ widget_class->expose_event = hildon_grid_item_expose;
+ widget_class->size_request = hildon_grid_item_size_request;
+ widget_class->size_allocate = hildon_grid_item_size_allocate;
+
+ container_class->forall = hildon_grid_item_forall;
+ container_class->remove = hildon_grid_item_remove;
+
+ gobject_class->set_property = hildon_grid_item_set_property;
+ gobject_class->get_property = hildon_grid_item_get_property;
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_EMBLEM_TYPE,
+ g_param_spec_string ("emblem-type",
+ "Emblem Type",
+ "The emblem's basename",
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_ICON_BASENAME,
+ g_param_spec_string ("icon-basename",
+ "Icon Basename",
+ "The icon's basename",
+ NULL,
+ G_PARAM_WRITABLE));
+
+}
+
+static void
+hildon_grid_item_init(HildonGridItem *item)
+{
+ HildonGridItemPrivate *priv;
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ priv->icon_basename = NULL;
+ priv->pending_icon_size = priv->icon_size = HILDON_GRID_ICON_SIZE;
+ priv->icon = NULL;
+
+ priv->emblem_basename = NULL;
+ priv->pending_emblem_size = priv->emblem_size = HILDON_GRID_EMBLEM_SIZE;
+
+ priv->label = NULL;
+ priv->pending_label_pos = priv->label_pos =
+ HILDON_GRID_ITEM_LABEL_POS_BOTTOM;
+
+ priv->selected = FALSE;
+
+ priv->pending_focus_margin = priv->focus_margin = 6;
+ priv->pending_label_height = priv->label_height = 30;
+ priv->pending_label_icon_margin = priv->label_icon_margin = 6;
+ priv->pending_icon_width = priv->icon_width = 64;
+ priv->pending_icon_height = priv->icon_height = 54;
+ priv->pending_label_height = priv->label_height = 30;
+
+
+ GTK_WIDGET_SET_FLAGS(GTK_WIDGET(item), GTK_CAN_FOCUS);
+
+ priv->label = gtk_label_new(NULL);
+ gtk_widget_set_name(priv->label, "hildon-grid-item-label");
+ gtk_widget_set_parent(priv->label, GTK_WIDGET(item));
+
+ update_icon(item);
+ set_label_justify(item);
+
+ gtk_widget_show(priv->label);
+}
+
+/**
+ * hildon_grid_item_new:
+ * @icon_basename: icon base name
+ *
+ * Creates a new #HildonGridItem.
+ *
+ * Returns: a new #HildonGridItem
+ */
+GtkWidget *
+hildon_grid_item_new(const gchar *icon_basename)
+{
+ HildonGridItem *item;
+
+ item = g_object_new(HILDON_TYPE_GRID_ITEM, "icon-basename", icon_basename, NULL);
+
+ return GTK_WIDGET(item);
+}
+
+/**
+ * hildon_grid_item_new_with_label:
+ * @icon_basename: icon base name
+ * @label: text label for icon
+ *
+ * Creates a new #HildonGridItem with a specified label for the icon.
+ *
+ * Returns: a new #HildonGridItem
+ */
+GtkWidget *
+hildon_grid_item_new_with_label(const gchar *icon_basename,
+ const gchar *label)
+{
+ HildonGridItem *item;
+
+ item = g_object_new(HILDON_TYPE_GRID_ITEM, "icon-basename", icon_basename, NULL);
+
+ hildon_grid_item_set_label(item, label);
+
+ return GTK_WIDGET(item);
+}
+
+
+static void
+update_icon(HildonGridItem *item)
+{
+ GtkIconTheme *icon_theme;
+ GdkPixbuf *icon;
+ GdkPixbuf *emblem_icon;
+ HildonGridItemPrivate *priv;
+ GError *error;
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ if (priv->icon != NULL) {
+ if (GTK_WIDGET_VISIBLE(priv->icon))
+ gtk_widget_hide(priv->icon);
+ gtk_widget_unparent(priv->icon);
+ }
+
+ icon_theme = gtk_icon_theme_get_default();
+
+ /* Load icon. Fall to default if loading fails. */
+ icon = NULL;
+ if (priv->icon_basename)
+ {
+ error = NULL;
+ icon = gtk_icon_theme_load_icon(icon_theme,
+ priv->icon_basename,
+ priv->icon_size, 0, &error);
+ if (icon == NULL) {
+ g_warning("Couldn't load icon \"%s\": %s", priv->icon_basename,
+ error->message);
+ g_error_free(error);
+ }
+ }
+
+ if (icon == NULL) {
+ error = NULL;
+ icon = gtk_icon_theme_load_icon(icon_theme,
+ DEFAULT_ICON_BASENAME,
+ priv->icon_size, 0, &error);
+ if (icon == NULL) {
+ g_warning("Couldn't load default icon: %s!\n", error->message);
+ g_error_free(error);
+ }
+ }
+ priv->icon_width = gdk_pixbuf_get_width(icon);
+ priv->icon_height = gdk_pixbuf_get_height(icon);
+
+
+ /* Load and merge emblem if one is specified. */
+ if (priv->emblem_basename != NULL) {
+ error = NULL;
+ emblem_icon = gtk_icon_theme_load_icon(icon_theme,
+ priv->emblem_basename,
+ priv->emblem_size,
+ 0, &error);
+ if (emblem_icon == NULL) {
+ g_warning("Couldn't load emblem \"%s\": %s",
+ priv->emblem_basename, error->message);
+ g_error_free(error);
+ } else {
+ gint icon_height;
+ gint width, height, y;
+
+#ifdef USE_DIRTY_ALPHA
+ GdkPixbuf *tmp;
+#endif
+
+ icon_height = gdk_pixbuf_get_height(icon);
+ width = MIN(gdk_pixbuf_get_width(emblem_icon),
+ gdk_pixbuf_get_width(icon));
+ height = MIN(gdk_pixbuf_get_height(emblem_icon), icon_height);
+ y = icon_height - height;
+#ifndef USE_DIRTY_ALPHA
+ gdk_pixbuf_copy_area(emblem_icon, 0, 0, width, height,
+ icon, 0, y);
+#else
+ /*
+ * Using composite to copy emblem to lower left corner creates
+ * some garbage on top of emblem. This way it can be avoided.
+ */
+ tmp = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE,
+ 8, width, icon_height);
+ gdk_pixbuf_fill(tmp, 0x00000000);
+ gdk_pixbuf_copy_area(emblem_icon, 0, 0, width, height,
+ tmp, 0, y);
+ gdk_pixbuf_composite(tmp, icon,
+ 0, 0, width, icon_height,
+ 0.0, 0.0, 1.0, 1.0,
+ GDK_INTERP_NEAREST, 255);
+ g_object_unref(tmp);
+#endif /* ifndef else USE_DIRTY_ALPHA */
+ g_object_unref(emblem_icon);
+ }
+ }
+
+ priv->icon = gtk_image_new_from_pixbuf(icon);
+ g_object_unref(icon);
+
+ gtk_widget_set_parent(priv->icon, GTK_WIDGET(item));
+ gtk_widget_show(priv->icon);
+
+ gtk_widget_queue_draw(priv->icon);
+}
+
+void
+hildon_grid_item_set_label(HildonGridItem *item, const gchar *label)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ if (label == NULL)
+ label = "";
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (strcmp (gtk_label_get_label (GTK_LABEL (priv->label)), label) == 0)
+ return;
+ gtk_label_set_label(GTK_LABEL(priv->label), label);
+}
+
+static void
+hildon_grid_item_set_icon_size(HildonGridItem *item,
+ HildonGridItemIconSizeType icon_size)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_icon_size == icon_size) {
+ return;
+ }
+ priv->pending_icon_size = icon_size;
+}
+
+
+void
+_hildon_grid_item_set_label_pos(HildonGridItem *item,
+ HildonGridPositionType label_pos)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_label_pos == label_pos) {
+ return;
+ }
+ priv->pending_label_pos = label_pos;
+}
+
+
+void
+_hildon_grid_item_set_emblem_size(HildonGridItem *item, gint emblem_size)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_emblem_size == emblem_size) {
+ return;
+ }
+ priv->pending_emblem_size = emblem_size;
+}
+
+
+void
+_hildon_grid_item_set_focus_margin(HildonGridItem *item,
+ const gint focus_margin)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_focus_margin == focus_margin) {
+ return;
+ }
+ priv->pending_focus_margin = focus_margin;
+}
+
+
+void
+_hildon_grid_item_set_label_height(HildonGridItem *item,
+ const gint label_height)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_label_height == label_height) {
+ return;
+ }
+ priv->pending_label_height = label_height;
+}
+
+
+void
+_hildon_grid_item_set_label_icon_margin(HildonGridItem *item,
+ const gint label_icon_margin)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_label_icon_margin == label_icon_margin) {
+ return;
+ }
+ priv->pending_label_icon_margin = label_icon_margin;
+}
+
+
+void
+_hildon_grid_item_set_icon_height(HildonGridItem *item,
+ const gint icon_height)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_icon_height == icon_height) {
+ return;
+ }
+ priv->pending_icon_height = icon_height;
+}
+
+
+void
+_hildon_grid_item_set_icon_width(HildonGridItem *item,
+ const gint icon_width)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ hildon_grid_item_set_icon_size(item, icon_width);
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ if (priv->pending_icon_width == icon_width) {
+ return;
+ }
+ priv->pending_icon_width = icon_width;
+}
+
+
+static void
+set_label_justify(HildonGridItem *item)
+{
+ HildonGridItemPrivate *priv;
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ if (priv->label != NULL) {
+ switch (priv->label_pos) {
+ case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
+ gtk_misc_set_alignment(GTK_MISC(priv->label), 0.5, 0.5);
+ break;
+
+ case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
+ gtk_misc_set_alignment(GTK_MISC(priv->label), 0.0, 0.5);
+ break;
+
+ default:
+ g_warning("Invalid position!");
+ break;
+ }
+ }
+}
+
+static void
+hildon_grid_item_remove(GtkContainer *container, GtkWidget *child)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+
+ item = HILDON_GRID_ITEM(container);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ g_return_if_fail(GTK_IS_WIDGET(child));
+ g_return_if_fail(child == priv->label || child == priv->icon);
+
+ if (child == priv->label) {
+ gtk_widget_unparent(child);
+ priv->label = NULL;
+ } else if (child == priv->icon) {
+ gtk_widget_unparent(child);
+ priv->icon = NULL;
+ }
+}
+
+static gboolean
+hildon_grid_item_expose(GtkWidget *widget, GdkEventExpose *event)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(HILDON_IS_GRID_ITEM(widget), FALSE);
+ g_return_val_if_fail(event, FALSE);
+
+ item = HILDON_GRID_ITEM(widget);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ if (priv->label == NULL && priv->icon == NULL) {
+ return FALSE;
+ }
+ if (GTK_WIDGET_HAS_FOCUS(GTK_WIDGET(item))) {
+ GdkRectangle clip;
+ GtkWidget *focused;
+
+ if (priv->label != NULL) {
+ focused = priv->label;
+ } else {
+ focused = priv->icon;
+ }
+
+ /* Determine the coordinates and size of clip */
+ switch (priv->label_pos) {
+ case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
+ clip.x = focused->allocation.x - priv->focus_margin;
+ clip.y = focused->allocation.y;
+ clip.width = focused->allocation.width + priv->focus_margin * 2;
+ clip.height = focused->allocation.height;
+ if (clip.x < widget->allocation.x ||
+ clip.width > widget->allocation.width) {
+ clip.x = widget->allocation.x;
+ clip.width = widget->allocation.width;
+ }
+ if (clip.y + clip.height >
+ widget->allocation.y + widget->allocation.height) {
+ clip.height = widget->allocation.y +
+ widget->allocation.height - clip.y;
+ }
+ break;
+
+ case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
+ clip.x = widget->allocation.x;
+ clip.y = widget->allocation.y;
+ clip.width = widget->allocation.width;
+ clip.height = widget->allocation.height;
+ break;
+ }
+
+ /* Build painting box for the exposure event */
+ gtk_paint_box(focused->style,
+ gtk_widget_get_toplevel(focused)->window,
+ GTK_STATE_SELECTED,
+ GTK_SHADOW_NONE,
+ &clip, focused, "selected",
+ clip.x, clip.y, clip.width, clip.height);
+ }
+
+ /*
+ * Items are not exposed unless they are visible.
+ * -> No need to "optimize" by checking if they need exposing.
+ */
+ gtk_container_propagate_expose(GTK_CONTAINER(widget),
+ priv->icon, event);
+ gtk_container_propagate_expose(GTK_CONTAINER(widget),
+ priv->label, event);
+ return TRUE;
+}
+
+
+static void
+hildon_grid_item_size_request(GtkWidget *widget, GtkRequisition *requisition)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+ GtkRequisition label_req;
+ gint label_margin;
+
+ item = HILDON_GRID_ITEM(widget);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ label_margin = priv->focus_margin;
+
+ gtk_widget_size_request(priv->icon, requisition);
+ gtk_widget_size_request(priv->label, &label_req);
+
+ switch (priv->label_pos) {
+ case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
+ requisition->width = MAX(requisition->width, label_req.width);
+ requisition->height += label_req.height + label_margin;
+ break;
+
+ case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
+ requisition->width += label_req.width + label_margin;
+ requisition->height = MAX(requisition->height, label_req.height);
+ break;
+ default:
+ g_warning("bad position");
+ return;
+ break;
+ }
+}
+
+static void
+hildon_grid_item_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+ GtkRequisition l_req;
+ GtkAllocation i_alloc, l_alloc;
+
+ g_return_if_fail(widget);
+ g_return_if_fail(allocation);
+
+ item = HILDON_GRID_ITEM(widget);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+ widget->allocation = *allocation;
+
+ /* If creating label and icon failed, don't show a thing... */
+ if (priv->label == NULL && priv->icon == NULL) {
+ return;
+ }
+ if (priv->label != NULL) {
+ gtk_widget_get_child_requisition(priv->label, &l_req);
+ } else {
+ l_req.width = l_req.height = 0;
+ }
+
+ /* Determine icon and label allocation based on label position */
+ switch (priv->label_pos) {
+ case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
+ i_alloc.x = (allocation->width - priv->icon_width) / 2 +
+ allocation->x;
+ if (priv->label != NULL) {
+ i_alloc.y = allocation->y + (allocation->height -
+ priv->label_height -
+ priv->label_icon_margin -
+ priv->icon_height) / 2;
+ } else {
+ i_alloc.y = (allocation->height - priv->icon_height) / 2 +
+ allocation->y;
+ }
+
+ if (priv->label != NULL) {
+ l_alloc.x = allocation->x + priv->focus_margin;
+ l_alloc.y = i_alloc.y + priv->icon_height +
+ priv->label_icon_margin;
+ l_alloc.width = allocation->width - priv->focus_margin * 2;
+ l_alloc.height = priv->label_height;
+ }
+ break;
+
+ case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
+ i_alloc.x = allocation->x + priv->focus_margin;
+ i_alloc.y = allocation->y +
+ (priv->label_height - priv->icon_height) / 2;
+
+ if (priv->label != NULL) {
+ l_alloc.x = allocation->x + priv->focus_margin +
+ priv->icon_width + priv->label_icon_margin;
+ l_alloc.y = allocation->y;
+ l_alloc.width = allocation->width - priv->focus_margin * 2 -
+ priv->label_icon_margin - priv->icon_width;
+ l_alloc.height = priv->label_height;
+ }
+ break;
+ default:
+ g_warning("bad label position");
+ return;
+ break;
+ }
+
+ if (i_alloc.y < allocation->y) {
+ i_alloc.height -= i_alloc.height - allocation->height;
+ i_alloc.y = allocation->y;
+ }
+ if (i_alloc.y + i_alloc.height > allocation->y + allocation->height) {
+ i_alloc.height-= i_alloc.y + i_alloc.height -
+ allocation->y - allocation->height;
+ }
+
+
+ i_alloc.width = priv->icon_width;
+ i_alloc.height = priv->icon_height;
+
+ if (priv->label != NULL) {
+ gtk_widget_size_allocate(priv->label, &l_alloc);
+ }
+ if (priv->icon != NULL) {
+ gtk_widget_size_allocate(priv->icon, &i_alloc);
+ }
+}
+
+static void
+hildon_grid_item_forall(GtkContainer *container,
+ gboolean include_int,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(container);
+ g_return_if_fail(callback);
+
+ item = HILDON_GRID_ITEM(container);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ /* Connect callback functions to the item */
+ if (priv->icon != NULL) {
+ (*callback) (priv->icon, callback_data);
+ }
+ if (priv->label != NULL) {
+ (*callback) (priv->label, callback_data);
+ }
+}
+
+static void
+hildon_grid_item_finalize(GObject *object)
+{
+ HildonGridItem *item;
+ HildonGridItemPrivate *priv;
+
+ item = HILDON_GRID_ITEM(object);
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ g_free(priv->icon_basename);
+ if (priv->emblem_basename != NULL) {
+ g_free(priv->emblem_basename);
+ }
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+#if 0
+static int hildon_time_get_font_width(GtkWidget * widget)
+{
+ PangoContext *context;
+ PangoFontMetrics *metrics;
+ gint digit_width;
+
+ context = gtk_widget_get_pango_context(widget);
+ metrics = pango_context_get_metrics(context,
+ widget->style->font_desc,
+ pango_context_get_language
+ (context));
+
+ digit_width = pango_font_metrics_get_approximate_digit_width(metrics);
+ digit_width = PANGO_PIXELS(digit_width);
+
+ pango_font_metrics_unref(metrics);
+
+ return digit_width;
+}
+#endif
+
+
+/**
+ * hildon_grid_item_set_emblem_type:
+ * @item: #HildonGridItem
+ * @emblem_basename: emblem's basename
+ *
+ * Sets item emblem type.
+ */
+void
+hildon_grid_item_set_emblem_type(HildonGridItem *item,
+ const gchar *emblem_basename)
+{
+ HildonGridItemPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ if (priv->emblem_basename != NULL) {
+ g_free(priv->emblem_basename);
+ }
+
+ priv->emblem_basename = g_strdup(emblem_basename);
+
+ update_icon(item);
+
+ g_object_notify (G_OBJECT (item), "emblem-type");
+}
+
+/**
+ * hildon_grid_item_get_emblem_type:
+ * @item: #HildonGridItem
+ *
+ * Returns: emblem's basename. Must not be changed or freed.
+ */
+const gchar *
+hildon_grid_item_get_emblem_type(HildonGridItem *item)
+{
+ g_return_val_if_fail(HILDON_IS_GRID_ITEM(item), NULL);
+
+ return HILDON_GRID_ITEM_GET_PRIVATE(item)->emblem_basename;
+}
+
+
+
+void
+_hildon_grid_item_done_updating_settings(HildonGridItem *item)
+{
+ gboolean need_update_icon;
+ gboolean need_resize;
+
+ HildonGridItemPrivate *priv;
+ g_return_if_fail(HILDON_IS_GRID_ITEM(item));
+ priv = HILDON_GRID_ITEM_GET_PRIVATE(item);
+
+ need_update_icon = need_resize = FALSE;
+
+ if (priv->pending_icon_size != priv->icon_size) {
+ if (priv->pending_icon_size > 0) {
+ priv->icon_size = priv->pending_icon_size;
+ } else {
+ priv->icon_size = 1;
+ }
+ need_update_icon = TRUE;
+ }
+ if (priv->pending_emblem_size != priv->emblem_size) {
+ priv->emblem_size = priv->pending_emblem_size;
+ need_update_icon = TRUE;
+ }
+ if (priv->pending_label_pos != priv->label_pos) {
+ priv->label_pos = priv->pending_label_pos;
+ /* No refresh here, grid will do it. */
+ set_label_justify(item);
+ }
+ /*
+ * grid will take care of this
+ *
+ if (priv->pending_focus_margin != priv->focus_margin) {
+ priv->focus_margin = priv->pending_focus_margin;
+ need_resize = TRUE;
+ }
+ if (priv->pending_label_height != priv->label_height) {
+ priv->label_height = priv->pending_label_height;
+ need_resize = TRUE;
+ }
+ if (priv->pending_label_icon_margin != priv->label_icon_margin) {
+ priv->label_icon_margin = priv->pending_label_icon_margin;
+ need_resize = TRUE;
+ }
+ if (priv->pending_icon_height != priv->icon_height) {
+ priv->icon_height = priv->pending_icon_height;
+ need_resize = TRUE;
+ }
+ if (priv->pending_icon_width != priv->icon_width) {
+ priv->icon_width = priv->pending_icon_width;
+ need_resize = TRUE;
+ }
+ */
+
+ if (need_update_icon == TRUE) {
+ update_icon(HILDON_GRID_ITEM(item));
+ }
+ /*
+ if (need_resize == TRUE) {
+ gtk_widget_queue_resize(GTK_WIDGET(item));
+ }
+ */
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file hildon-grid-item.h
+ *
+ * This file is a header file for he implementation of HildonGridItem.
+ * HildonGridItem is an item mainly used in HildonGrid. It has an icon,
+ * emblem and a label.
+ */
+
+#ifndef __HILDON_GRID_ITEM_H__
+#define __HILDON_GRID_ITEM_H__
+
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkitem.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_GRID_ITEM (hildon_grid_item_get_type ())
+#define HILDON_GRID_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ HILDON_TYPE_GRID_ITEM, \
+ HildonGridItem))
+#define HILDON_GRID_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_GRID_ITEM, \
+ HildonGridItemClass))
+#define HILDON_IS_GRID_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ HILDON_TYPE_GRID_ITEM))
+#define HILDON_IS_GRID_ITEM_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_GRID_ITEM))
+#define HILDON_GRID_ITEM_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ HILDON_TYPE_GRID_ITEM, HildonGridItemClass))
+
+typedef enum {
+ HILDON_GRID_ITEM_LABEL_POS_BOTTOM = 1,
+ HILDON_GRID_ITEM_LABEL_POS_RIGHT
+} HildonGridPositionType;
+
+typedef enum {
+ HILDON_GRID_ITEM_ICON_27x27 = 1,
+ HILDON_GRID_ITEM_ICON_128x128
+} HildonGridItemIconSizeType;
+
+
+typedef struct _HildonGridItem HildonGridItem;
+typedef struct _HildonGridItemClass HildonGridItemClass;
+
+
+struct _HildonGridItem {
+ GtkContainer parent;
+};
+
+struct _HildonGridItemClass {
+ GtkContainerClass parent_class;
+};
+
+
+
+GType hildon_grid_item_get_type(void);
+GtkWidget *hildon_grid_item_new(const gchar * icon_basename);
+GtkWidget *hildon_grid_item_new_with_label(const gchar * icon_basename,
+ const gchar * label);
+
+void hildon_grid_item_set_emblem_type(HildonGridItem * item,
+ const gchar * emblem_basename);
+const gchar *hildon_grid_item_get_emblem_type(HildonGridItem * item);
+void hildon_grid_item_set_label(HildonGridItem *item, const gchar *label);
+
+
+G_END_DECLS
+#endif /* __HILDON_GRID_ITEM_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-grid
+ * @short_description: Being used where ever a number of single tap
+ * activatable items need to be presented (e.g. Control Panel applets)
+ * @see_also: #HildonGridItem
+ *
+ * HildonGrid is a set of application-defineable items that are presented in a
+ * table. There are two modes for the form of the table; large icon mode
+ * and small icon mode.
+ *
+ * In large icon mode, the Grid View items are presented with a large
+ * icon and a label under it. In small icon mode, the items are
+ * presented with a small icon and a label on the right side of the
+ * icon.
+ *
+ * The label has a solid background as wide as the maximum text width.
+ * This allows the text to have focus as well as be legible when
+ * displayed upon a black or dark background image. Long names are
+ * truncated with an ellipsis ("...") appended.
+ */
+
+/*
+ * TODO
+ * - there must be a predefined place for the "no items" -label...
+ * - performance :-)
+ * - dimmed items & scrolling by scrollbar
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkrange.h>
+#include <gtk/gtkvscrollbar.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkenums.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "hildon-grid-item-private.h"
+#include "hildon-marshalers.h"
+#include "hildon-app.h"
+#include <hildon-widgets/hildon-grid.h>
+#include <hildon-widgets/hildon-grid-item.h>
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_GRID_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_GRID, \
+ HildonGridPrivate))
+
+
+#define DEFAULT_STYLE "largeicons-home"
+
+#define DEFAULT_N_COLUMNS 3
+#define GRID_LABEL_POS_PAD 16
+
+#define DRAG_SENSITIVITY 6
+
+
+enum {
+ ACTIVATE_CHILD,
+ POPUP_CONTEXT,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_0,
+ PROP_EMPTY_LABEL,
+ PROP_STYLE,
+ PROP_SCROLLBAR_POS
+};
+
+
+typedef struct _HildonGridChild HildonGridChild;
+typedef struct _HildonGridPrivate HildonGridPrivate;
+
+
+struct _HildonGridChild {
+ GtkWidget *widget;
+};
+
+
+struct _HildonGridPrivate {
+ GList *children;
+ GtkWidget *scrollbar;
+ gint old_sb_pos;
+ GdkWindow *event_window;
+
+ gchar *style;
+ gint emblem_size;
+ GtkWidget *empty_label;
+
+ gint item_width;
+ gint item_height;
+ gint h_margin;
+ gint v_margin;
+ gint focus_margin;
+ gint icon_label_margin;
+ gint icon_width;
+ gint num_columns;
+ HildonGridPositionType label_pos;
+ gint label_height;
+
+ gint focus_index;
+ guint click_x;
+ guint click_y;
+
+ /* Handy variables outsize _allocate. */
+ gint area_height;
+ gint area_rows;
+ gint scrollbar_width;
+
+ gint first_index;
+ GdkEventType last_button_event;
+ gint old_item_height;
+};
+
+
+
+/* Prototypes. */
+static void hildon_grid_class_init(HildonGridClass * klass);
+static void hildon_grid_init(HildonGrid * grid);
+static void hildon_grid_realize(GtkWidget * widget);
+static void hildon_grid_unrealize(GtkWidget * widget);
+static void hildon_grid_map(GtkWidget * widget);
+static void hildon_grid_unmap(GtkWidget * widget);
+static gboolean hildon_grid_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static void hildon_grid_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void hildon_grid_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static void hildon_grid_add(GtkContainer * container, GtkWidget * widget);
+static void hildon_grid_remove(GtkContainer * container,
+ GtkWidget * widget);
+static void hildon_grid_set_focus_child(GtkContainer * container,
+ GtkWidget * widget);
+static void hildon_grid_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void hildon_grid_tap_and_hold_setup(GtkWidget * widget,
+ GtkWidget * menu,
+ GtkCallback func,
+ GtkWidgetTapAndHoldFlags flags);
+
+static GType hildon_grid_child_type(GtkContainer * container);
+
+
+static void hildon_grid_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_grid_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static void hildon_grid_set_empty_label(HildonGrid *grid,
+ const gchar *empty_label);
+static const gchar *hildon_grid_get_empty_label(HildonGrid * grid);
+static void hildon_grid_set_num_columns(HildonGrid *grid, gint num_cols);
+static void hildon_grid_set_label_pos(HildonGrid *grid,
+ HildonGridPositionType label_pos);
+static void hildon_grid_set_focus_margin(HildonGrid *grid,
+ gint focus_margin);
+static void hildon_grid_set_icon_label_margin(HildonGrid *grid,
+ gint icon_label_margin);
+static void hildon_grid_set_icon_width(HildonGrid *grid, gint icon_width);
+static void hildon_grid_set_emblem_size(HildonGrid *grid, gint emblem_size);
+static void hildon_grid_set_label_height(HildonGrid *grid,
+ gint label_height);
+static void hildon_grid_destroy(GtkObject * self);
+static void hildon_grid_finalize(GObject * object);
+
+/* Signal handlers. */
+static gboolean hildon_grid_button_pressed(GtkWidget * widget,
+ GdkEventButton * event);
+static gboolean hildon_grid_button_released(GtkWidget * widget,
+ GdkEventButton * event);
+static gboolean hildon_grid_key_pressed(GtkWidget * widget,
+ GdkEventKey * event);
+static gboolean hildon_grid_scrollbar_moved(GtkWidget * widget,
+ gpointer data);
+static gboolean hildon_grid_state_changed(GtkWidget * widget,
+ GtkStateType state,
+ gpointer data);
+
+/* Other internal functions. */
+static void get_style_properties(HildonGrid * grid);
+static gint get_child_index(HildonGridPrivate * priv, GtkWidget * child);
+static gint get_child_index_by_coord(HildonGridPrivate * priv,
+ gint x, gint y);
+static GtkWidget *get_child_by_index(HildonGridPrivate * priv, gint index);
+
+static gboolean jump_scrollbar_to_focused(HildonGrid * grid);
+static gboolean adjust_scrollbar_height(HildonGrid * grid);
+static gboolean update_contents(HildonGrid * grid);
+static void set_focus(HildonGrid * grid,
+ GtkWidget * widget, gboolean refresh_view);
+
+static GtkContainerClass *parent_class = NULL;
+static guint grid_signals[LAST_SIGNAL] = { 0 };
+
+
+GType hildon_grid_get_type(void)
+{
+ static GType grid_type = 0;
+
+ if (!grid_type) {
+ static const GTypeInfo grid_info = {
+ sizeof(HildonGridClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_grid_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonGrid),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_grid_init,
+ };
+ grid_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonGrid", &grid_info, 0);
+ }
+
+ return grid_type;
+}
+
+
+
+static void hildon_grid_class_init(HildonGridClass * klass)
+{
+ GObjectClass *gobject_class;
+ GtkWidgetClass *widget_class;
+ GtkContainerClass *container_class;
+
+ widget_class = GTK_WIDGET_CLASS(klass);
+ container_class = GTK_CONTAINER_CLASS(klass);
+ gobject_class = G_OBJECT_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ g_type_class_add_private(klass, sizeof(HildonGridPrivate));
+
+ GTK_OBJECT_CLASS(klass)->destroy = hildon_grid_destroy;
+ gobject_class->finalize = hildon_grid_finalize;
+ gobject_class->set_property = hildon_grid_set_property;
+ gobject_class->get_property = hildon_grid_get_property;
+
+ widget_class->realize = hildon_grid_realize;
+ widget_class->unrealize = hildon_grid_unrealize;
+ widget_class->map = hildon_grid_map;
+ widget_class->unmap = hildon_grid_unmap;
+ widget_class->expose_event = hildon_grid_expose;
+ widget_class->size_request = hildon_grid_size_request;
+ widget_class->size_allocate = hildon_grid_size_allocate;
+ widget_class->tap_and_hold_setup = hildon_grid_tap_and_hold_setup;
+ widget_class->key_press_event = hildon_grid_key_pressed;
+ widget_class->button_press_event = hildon_grid_button_pressed;
+ widget_class->button_release_event = hildon_grid_button_released;
+
+ container_class->add = hildon_grid_add;
+ container_class->remove = hildon_grid_remove;
+ container_class->forall = hildon_grid_forall;
+ container_class->child_type = hildon_grid_child_type;
+ container_class->set_focus_child = hildon_grid_set_focus_child;
+
+ /* Install properties to the class */
+ g_object_class_install_property(gobject_class, PROP_EMPTY_LABEL,
+ g_param_spec_string("empty_label",
+ "Empty label",
+ "Label to show when grid has no items",
+ _("ckct_wi_grid_no_items"), G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_STYLE,
+ g_param_spec_string("style",
+ "Style",
+ "Widget's Style. Setting style sets widget size, "
+ "spacing, label position, number of columns, "
+ "and icon sizeLabel to show when grid has no items",
+ DEFAULT_STYLE, G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_SCROLLBAR_POS,
+ g_param_spec_int("scrollbar-position",
+ "Scrollbar Position",
+ "View (scrollbar) position.",
+ G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("item_width",
+ "Item width",
+ "Total width of an item (obsolete)",
+ 1, G_MAXINT, 212, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("item_height",
+ "Item height",
+ "Total height of an item",
+ 1, G_MAXINT, 96, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("item_hspacing",
+ "Item horizontal spacing",
+ "Margin between two columns and labels",
+ 0, G_MAXINT, 12, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("item_vspacing",
+ "Item vertical spacing",
+ "Icon on right: Margin between rows / Icon at bottom: Vertical margin betweeb label and icon",
+ 0, G_MAXINT, 6, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("label_hspacing",
+ "Focus margin",
+ "Margin between focus edge and item edge",
+ 0, G_MAXINT, 6, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("label_vspacing",
+ "Vertical label spacing",
+ "Vertical margin between item and label",
+ 0, G_MAXINT, 6, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("label_height",
+ "Label height",
+ "Height of icon label",
+ 1, G_MAXINT, 30, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("n_columns",
+ "Columns",
+ "Number of columns",
+ 0, G_MAXINT, DEFAULT_N_COLUMNS, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("label_pos",
+ "Label position",
+ "Position of label related to the icon",
+ 1, 2, 1, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("icon_size",
+ "Icon size",
+ "Size of the icon in pixels (width)",
+ 1, G_MAXINT, 64, G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_uint("emblem_size",
+ "Emblem size",
+ "Size of the emblem in pixels",
+ 1, G_MAXINT, 25, G_PARAM_READABLE));
+
+ /**
+ * HildonGrid::activate-child:
+ *
+ * Emitted when a child (@HildonGridItem) is activated either by
+ * tapping on it or by pressing enter.
+ */
+ grid_signals[ACTIVATE_CHILD] =
+ g_signal_new("activate-child",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(HildonGridClass, activate_child),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, HILDON_TYPE_GRID_ITEM);
+
+ /**
+ * HildonGrid::popup-context-menu:
+ *
+ * Emitted when popup-menu is supposed to open. Used for tap-and-hold.
+ */
+ grid_signals[POPUP_CONTEXT] =
+ g_signal_new("popup-context-menu",
+ G_OBJECT_CLASS_TYPE(gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(HildonGridClass, popup_context_menu),
+ NULL, NULL,
+ _hildon_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, HILDON_TYPE_GRID_ITEM);
+}
+
+
+
+/*
+ * hildon_grid_set_empty_label:
+ * @grid: #HildonGrid
+ * @empty_label: New label
+ *
+ * Sets empty label.
+ */
+static void
+hildon_grid_set_empty_label(HildonGrid * grid, const gchar * empty_label)
+{
+ /* No need to worry about update -- label receives a signal for it. */
+ gtk_label_set_label(GTK_LABEL(HILDON_GRID_GET_PRIVATE
+ (grid)->empty_label),
+ empty_label == NULL ? "" : empty_label);
+}
+
+/*
+ * _hildon_grid_get_empty_label:
+ * @grid: #HildonGrid
+ *
+ * Returns: empty label. Label must not be modified nor freed.
+ */
+static const gchar *
+hildon_grid_get_empty_label(HildonGrid * grid)
+{
+ return gtk_label_get_label(GTK_LABEL(HILDON_GRID_GET_PRIVATE
+ (grid)->empty_label));
+}
+
+/*
+ * hildon_grid_set_num_columns:
+ * @grid: #HildonGrid
+ * @columns: Number of columns
+ *
+ * Sets number of columns.
+ */
+static void
+hildon_grid_set_num_columns(HildonGrid * grid, gint columns)
+{
+ HildonGridPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID(grid));
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (priv->num_columns == columns) {
+ return;
+ }
+
+ if (columns != 0)
+ priv->num_columns = columns;
+ else
+ priv->num_columns = DEFAULT_N_COLUMNS;
+
+ /* Update estimated row-count for jump_scrollbar... */
+ priv->area_rows = MAX(priv->area_height / priv->num_columns, 1);
+
+ /* Size could have changed. Scroll view so there's something to show. */
+ adjust_scrollbar_height(grid);
+ jump_scrollbar_to_focused(grid);
+ gtk_widget_queue_resize(GTK_WIDGET(grid));
+}
+
+/*
+ * hildon_grid_set_label_pos:
+ * @grid: #HildonGrid
+ * @label_pos: Label position
+ *
+ * Sets icon label position.
+ */
+static void
+hildon_grid_set_label_pos(HildonGrid * grid,
+ HildonGridPositionType label_pos)
+{
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (label_pos == priv->label_pos)
+ return;
+
+ /* gtknotebook doesn't check if we use valid values -- why should
+ we?-) */
+
+ priv->label_pos = label_pos;
+
+ /* Set label position to each HildonGridItem */
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ _hildon_grid_item_set_label_pos(HILDON_GRID_ITEM(child),
+ label_pos);
+ }
+}
+
+/*
+ * hildon_grid_set_focus_margin:
+ * @grid: #HildonGrid
+ * @focus_margin: Focus margin
+ *
+ * Sets margin between icon edge and label edge
+ */
+static void
+hildon_grid_set_focus_margin(HildonGrid *grid, gint focus_margin)
+{
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ if (focus_margin == priv->focus_margin)
+ return;
+
+ priv->focus_margin = focus_margin;
+
+ /* Update children. */
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ _hildon_grid_item_set_focus_margin(HILDON_GRID_ITEM(child),
+ priv->focus_margin);
+ }
+}
+
+
+/*
+ * hildon_grid_set_icon_label_margin:
+ * @grid: #HildonGrid
+ * @hspacing: Vertical spacing
+ *
+ * Sets vertical spacing for label.
+ * XXX
+ */
+static void
+hildon_grid_set_icon_label_margin(HildonGrid *grid, gint icon_label_margin)
+{
+ HildonGridPrivate *priv;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ if (icon_label_margin == priv->icon_label_margin)
+ return;
+
+ priv->icon_label_margin = icon_label_margin;
+}
+
+
+/*
+ * hildon_grid_set_icon_width:
+ * @grid: #HildonGrid
+ * @icon_size: Icon size (width)
+ *
+ * Sets icon size (in pixels).
+ */
+static void
+hildon_grid_set_icon_width(HildonGrid * grid, gint icon_width)
+{
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (icon_width == priv->icon_width)
+ return;
+
+ priv->icon_width = icon_width;
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ _hildon_grid_item_set_icon_width(HILDON_GRID_ITEM(child),
+ icon_width);
+ }
+}
+
+
+/*
+ * hildon_grid_set_emblem_size:
+ * @grid: #HildonGrid
+ * @emblem_size: Emblem size
+ *
+ * Sets emblem size (in pixels).
+ */
+static void
+hildon_grid_set_emblem_size(HildonGrid *grid, gint emblem_size)
+{
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (emblem_size == priv->emblem_size)
+ return;
+
+ priv->emblem_size = emblem_size;
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ _hildon_grid_item_set_emblem_size(HILDON_GRID_ITEM(child),
+ emblem_size);
+ }
+}
+
+
+static void
+hildon_grid_set_label_height(HildonGrid *grid,
+ gint label_height)
+{
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (label_height == priv->label_height)
+ return;
+
+ priv->label_height = label_height;
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ _hildon_grid_item_set_label_height(HILDON_GRID_ITEM(child),
+ label_height);
+ }
+}
+
+
+static GType hildon_grid_child_type(GtkContainer * container)
+{
+ return GTK_TYPE_WIDGET;
+}
+
+static void hildon_grid_init(HildonGrid * grid)
+{
+ HildonGridPrivate *priv;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ GTK_CONTAINER(grid)->focus_child = NULL;
+ priv->focus_index = -1;
+
+ priv->scrollbar = gtk_vscrollbar_new(NULL);
+ priv->empty_label = gtk_label_new(_("ckct_wi_grid_no_items"));
+ priv->style = NULL;
+
+ priv->area_height = 1;
+ priv->area_rows = 1;
+ priv->children = NULL;
+
+ priv->first_index = 0;
+ priv->click_x = 0;
+ priv->click_y = 0;
+
+ priv->item_height = 96;
+ priv->h_margin = 12;
+ priv->v_margin = 6;
+ priv->focus_margin = 6;
+ priv->icon_label_margin = 6;
+ priv->icon_width = 64;
+ priv->label_pos = HILDON_GRID_ITEM_LABEL_POS_BOTTOM;
+
+ priv->old_sb_pos = -1;
+ priv->old_item_height = -1;
+
+ gtk_widget_set_parent(priv->scrollbar, GTK_WIDGET(grid));
+ gtk_widget_set_parent(priv->empty_label, GTK_WIDGET(grid));
+
+ priv->last_button_event = GDK_NOTHING;
+
+ GTK_WIDGET_SET_FLAGS(grid, GTK_NO_WINDOW);
+
+ /* Signal for scrollbar. */
+ g_signal_connect(G_OBJECT(priv->scrollbar), "value-changed",
+ G_CALLBACK(hildon_grid_scrollbar_moved), grid);
+
+ /* Signal for key press. */
+ GTK_WIDGET_SET_FLAGS(GTK_WIDGET(grid), GTK_CAN_FOCUS);
+ gtk_widget_set_events(GTK_WIDGET(grid), GDK_KEY_PRESS_MASK);
+
+ GTK_WIDGET_UNSET_FLAGS(priv->scrollbar, GTK_CAN_FOCUS);
+ hildon_grid_set_style(grid, DEFAULT_STYLE);
+}
+
+/**
+ * hildon_grid_new:
+ *
+ * Creates a new #HildonGrid.
+ *
+ * Returns: a new #HildonGrid
+ */
+GtkWidget *hildon_grid_new(void)
+{
+
+ HildonGrid *grid;
+
+ grid = g_object_new(HILDON_TYPE_GRID, NULL);
+
+ return GTK_WIDGET(grid);
+}
+
+
+static void hildon_grid_realize(GtkWidget * widget)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GdkWindowAttr attr;
+ gint attr_mask;
+
+
+ GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ /* Create GdkWindow for catching events. */
+ attr.x = widget->allocation.x;
+ attr.y = widget->allocation.y;
+ attr.width = widget->allocation.width - priv->scrollbar_width;
+ attr.height = widget->allocation.height;
+ attr.window_type = GDK_WINDOW_CHILD;
+ attr.event_mask = gtk_widget_get_events(widget)
+ | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
+
+ widget->window = gtk_widget_get_parent_window(widget);
+ g_object_ref(widget->window);
+
+ attr.wclass = GDK_INPUT_ONLY;
+ attr_mask = GDK_WA_X | GDK_WA_Y;
+
+ priv->event_window = gdk_window_new(widget->window, &attr, attr_mask);
+ gdk_window_set_user_data(priv->event_window, widget);
+
+ widget->style = gtk_style_attach(widget->style, widget->window);
+
+ gtk_style_set_background(widget->style,
+ widget->window, GTK_STATE_NORMAL);
+}
+
+
+static void hildon_grid_unrealize(GtkWidget * widget)
+{
+ HildonGridPrivate *priv;
+
+ priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(widget));
+
+ if (priv->event_window != NULL) {
+ gdk_window_set_user_data(priv->event_window, NULL);
+ gdk_window_destroy(priv->event_window);
+ priv->event_window = NULL;
+ }
+
+ if (GTK_WIDGET_CLASS(parent_class)->unrealize) {
+ (*GTK_WIDGET_CLASS(parent_class)->unrealize) (widget);
+ }
+}
+
+
+
+static void hildon_grid_map(GtkWidget * widget)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+
+ g_return_if_fail(HILDON_IS_GRID(widget));
+
+ if (!GTK_WIDGET_VISIBLE(widget))
+ return;
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ (*GTK_WIDGET_CLASS(parent_class)->map) (widget);
+
+ /* We shouldn't really need the following...*/
+ if (priv->scrollbar != NULL && GTK_WIDGET_VISIBLE(priv->scrollbar)) {
+ if (!GTK_WIDGET_MAPPED(priv->scrollbar)) {
+ gtk_widget_map(priv->scrollbar);
+ }
+ }
+
+ if (priv->empty_label != NULL &&
+ GTK_WIDGET_VISIBLE(priv->empty_label)) {
+ if (!GTK_WIDGET_MAPPED(priv->empty_label)) {
+ gtk_widget_map(priv->empty_label);
+ }
+ }
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ if (GTK_WIDGET_VISIBLE(child)) {
+ if (!GTK_WIDGET_MAPPED(child)) {
+ gtk_widget_map(child);
+ }
+ }
+ }
+ /* END OF don't really need */
+
+ /* Also make event window visible. */
+ gdk_window_show(priv->event_window);
+}
+
+
+
+static void hildon_grid_unmap(GtkWidget * widget)
+{
+ HildonGridPrivate *priv;
+
+ priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(widget));
+
+ if (priv->event_window != NULL) {
+ gdk_window_hide(priv->event_window);
+ }
+
+ (*GTK_WIDGET_CLASS(parent_class)->unmap) (widget);
+}
+
+
+
+static gboolean
+hildon_grid_expose(GtkWidget * widget, GdkEventExpose * event)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GtkContainer *container;
+ GList *list;
+ gint child_no;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(HILDON_IS_GRID(widget), FALSE);
+ g_return_val_if_fail(event, FALSE);
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ container = GTK_CONTAINER(grid);
+
+ /* If grid has no children,
+ * propagate the expose event to the label is one exists */
+ if (priv->children == NULL || g_list_length(priv->children) == 0) {
+ if (priv->empty_label != NULL) {
+ gtk_container_propagate_expose(container,
+ priv->empty_label, event);
+ }
+ return FALSE;
+ }
+
+ /* Only expose visible children. */
+
+ /* Jump over invisible. */
+ for (list = priv->children, child_no = 0;
+ list != NULL && child_no < priv->first_index;
+ list = list->next, child_no++) {
+ ; /* Nothing here. */
+ }
+
+ for (; list != NULL && child_no < priv->first_index +
+ priv->num_columns * priv->area_rows; list = list->next) {
+ gtk_container_propagate_expose(container,
+ ((HildonGridChild *) list->data)
+ ->widget, event);
+ }
+
+ /* Keep focused item focused. */
+ if (container->focus_child != NULL
+ && !GTK_WIDGET_HAS_FOCUS(container->focus_child)) {
+ set_focus(grid, container->focus_child, FALSE);
+ }
+ if (priv->scrollbar_width > 0 && priv->scrollbar != NULL) {
+ gtk_container_propagate_expose(container, priv->scrollbar, event);
+ }
+
+ return FALSE;
+}
+
+
+static void
+hildon_grid_size_request(GtkWidget * widget, GtkRequisition * requisition)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+ GtkRequisition req;
+
+ g_return_if_fail(widget);
+ g_return_if_fail(requisition);
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ /* Want as big as possible. */
+ requisition->width = 0x7fff; /* Largest possible gint16 */
+ requisition->height = 0x7fff; /* Largest possible gint16 */
+
+ if (priv->children == NULL) {
+ if (priv->empty_label != NULL &&
+ GTK_WIDGET_VISIBLE(priv->empty_label)) {
+ gtk_widget_size_request(priv->empty_label, &req);
+ }
+ }
+
+ if (priv->scrollbar != NULL && GTK_WIDGET_VISIBLE(priv->scrollbar)) {
+ gtk_widget_size_request(priv->scrollbar, &req);
+ }
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ gtk_widget_size_request(child, &req);
+ }
+}
+
+/*
+ * hildon_grid_size_allocate:
+ *
+ * Supposingly called when size of grid changes and after view have moved so
+ * that items need to be relocated.
+ */
+static void
+hildon_grid_size_allocate(GtkWidget * widget, GtkAllocation * allocation)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *child;
+ gint child_no;
+ gint y_offset;
+ gint row_margin;
+
+ GtkAllocation alloc;
+ GtkRequisition req;
+
+ g_return_if_fail(widget);
+ g_return_if_fail(allocation);
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ widget->allocation = *allocation;
+
+ get_style_properties(grid);
+
+ /* First of all, make sure GdkWindow is over our widget. */
+ if (priv->event_window != NULL) {
+ gdk_window_move_resize(priv->event_window,
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width -
+ priv->scrollbar_width,
+ widget->allocation.height);
+ }
+ /* Show the label if there are no items. */
+ if (priv->children == NULL) {
+ /*
+ * We probably don't need this as scrollbar should be hidden when
+ * removing items, but one can never be too sure...
+ */
+ if (priv->scrollbar != NULL &&
+ GTK_WIDGET_VISIBLE(priv->scrollbar)) {
+ priv->scrollbar_width = 0;
+ gtk_widget_hide(priv->scrollbar);
+ }
+
+ /* Show label if creating one actually worked. */
+ if (priv->empty_label != NULL) {
+ gtk_widget_get_child_requisition(priv->empty_label, &req);
+
+ /* ...for sure we must have a position for the label here... */
+ alloc.x = allocation->x + GRID_LABEL_POS_PAD;
+ alloc.y = allocation->y + GRID_LABEL_POS_PAD;
+ alloc.width = MIN(req.width, allocation->width -
+ GRID_LABEL_POS_PAD);
+ alloc.height = MIN(req.height, allocation->height -
+ GRID_LABEL_POS_PAD);
+
+ /* Make sure we don't use negative values. */
+ if (alloc.width < 0) {
+ alloc.width = 0;
+ }
+ if (alloc.height < 0) {
+ alloc.height = 0;
+ }
+
+ gtk_widget_size_allocate(priv->empty_label, &alloc);
+
+ if (!GTK_WIDGET_VISIBLE(priv->empty_label)) {
+ gtk_widget_show(priv->empty_label);
+ }
+ }
+
+ return;
+ }
+
+ /* As we have some items, hide label if it was visible. */
+ if (priv->empty_label != NULL &&
+ GTK_WIDGET_VISIBLE(priv->empty_label)) {
+ gtk_widget_hide(priv->empty_label);
+ }
+
+ priv->area_height = allocation->height;
+ priv->area_rows = allocation->height / priv->item_height;
+
+ /* Adjust/show/hide scrollbar. */
+ adjust_scrollbar_height(grid);
+ if (priv->old_item_height != priv->item_height) {
+ priv->old_item_height = priv->item_height;
+ jump_scrollbar_to_focused(grid);
+ }
+
+ /* Update item width. */
+ if (priv->num_columns == 1) {
+ priv->item_width = allocation->width - priv->scrollbar_width -
+ priv->h_margin - priv->scrollbar_width;
+ } else {
+ priv->item_width = (allocation->width - priv->scrollbar_width) /
+ priv->num_columns;
+ }
+
+ priv->first_index =
+ (int) gtk_range_get_value(GTK_RANGE(priv->scrollbar)) /
+ priv->item_height * priv->num_columns;
+
+ /* Hide items before visible ones. */
+ for (list = priv->children, child_no = 0;
+ list != NULL && child_no < priv->first_index;
+ list = list->next, child_no++) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ if (GTK_WIDGET_VISIBLE(child)) {
+ gtk_widget_hide(child);
+ }
+ }
+
+ /* Allocate visible items. */
+ alloc.width = priv->item_width - priv->h_margin;
+ switch (priv->label_pos) {
+ case HILDON_GRID_ITEM_LABEL_POS_BOTTOM:
+ row_margin = priv->icon_label_margin;
+ break;
+ case HILDON_GRID_ITEM_LABEL_POS_RIGHT:
+ row_margin = priv->v_margin;
+ break;
+ default:
+ row_margin = 0;
+ break;
+ }
+ alloc.height = priv->item_height - row_margin;
+
+ for (y_offset = priv->first_index / priv->num_columns * priv->item_height;
+ list != NULL && child_no < priv->first_index +
+ priv->area_rows * priv->num_columns;
+ list = list->next, child_no++) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ if (!GTK_WIDGET_VISIBLE(child)) {
+ gtk_widget_show(child);
+ }
+
+ /* Don't update icons which are not visible... */
+ alloc.y = (child_no / priv->num_columns) * priv->item_height +
+ allocation->y - y_offset + row_margin;
+ alloc.x = (child_no % priv->num_columns) * priv->item_width +
+ allocation->x;
+
+ _hildon_grid_item_done_updating_settings(HILDON_GRID_ITEM(child));
+ gtk_widget_size_allocate(child, &alloc);
+ }
+
+ /* Hide items after visible items. */
+ for (; list != NULL; list = list->next) {
+ child = ((HildonGridChild *) list->data)->widget;
+
+ if (GTK_WIDGET_VISIBLE(child)) {
+ gtk_widget_hide(child);
+ }
+ }
+}
+
+
+
+/**
+ * hildon_grid_add:
+ * @container: container (#HildonGrid) to add HildonGridItem into
+ * @widget: #GtkWidget (#HildonGridItem) to add
+ *
+ * Adds a new HildonGridItem into HildonGrid.
+ */
+static void hildon_grid_add(GtkContainer * container, GtkWidget * widget)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ HildonGridChild *child;
+
+
+ g_return_if_fail(HILDON_IS_GRID(container));
+ g_return_if_fail(HILDON_IS_GRID_ITEM(widget));
+
+ grid = HILDON_GRID(container);
+ priv = HILDON_GRID_GET_PRIVATE(HILDON_GRID(grid));
+ GTK_WIDGET_SET_FLAGS(widget, GTK_NO_WINDOW);
+
+ child = g_new(HildonGridChild, 1);
+ if (child == NULL) {
+ g_critical("no memory for child - not adding");
+ return;
+ }
+ child->widget = widget;
+
+ _hildon_grid_item_set_label_pos (HILDON_GRID_ITEM(widget), priv->label_pos);
+ _hildon_grid_item_set_focus_margin(HILDON_GRID_ITEM(widget), priv->focus_margin);
+ _hildon_grid_item_set_icon_width (HILDON_GRID_ITEM(widget), priv->icon_width);
+ _hildon_grid_item_set_emblem_size (HILDON_GRID_ITEM(widget), priv->emblem_size);
+
+ /* Add the new item to the grid */
+ priv->children = g_list_append(priv->children, child);
+ gtk_widget_set_parent(widget, GTK_WIDGET(grid));
+
+ /* Property changes (child's set_sensitive) */
+ g_signal_connect_after(G_OBJECT(widget), "state-changed",
+ G_CALLBACK(hildon_grid_state_changed), grid);
+
+ /* Matches both empty grid and all-dimmed grid. */
+ if (GTK_CONTAINER(grid)->focus_child == NULL)
+ set_focus(grid, widget, TRUE);
+
+ /*
+ * If item was added in visible area, relocate items. Otherwise update
+ * scrollbar and see if items need relocating.
+ */
+ if (g_list_length(priv->children) < priv->first_index +
+ priv->area_rows * priv->num_columns) {
+ gtk_widget_queue_resize(GTK_WIDGET(grid));
+ } else {
+ gboolean updated;
+
+ updated = adjust_scrollbar_height(grid);
+ /* Basically this other test is useless -- shouldn't need to jump.
+ */
+ updated |= jump_scrollbar_to_focused(grid);
+
+ if (updated) {
+ gtk_widget_queue_resize(GTK_WIDGET(grid));
+ }
+ }
+}
+
+/**
+ * hildon_grid_remove:
+ * @container: container (#HildonGrid) to remove #HildonGridItem from
+ * @widget: widget (#HildonGridItem) to be removed
+ *
+ * Removes HildonGridItem from HildonGrid.
+ */
+static void
+hildon_grid_remove(GtkContainer * container, GtkWidget * widget)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ HildonGridChild *child;
+ GtkWidget *child_widget;
+ GList *list;
+ gint index, old_index;
+ gboolean deleted;
+ gboolean updated;
+
+ g_return_if_fail(HILDON_IS_GRID(container));
+ g_return_if_fail(HILDON_IS_GRID_ITEM(widget));
+
+ grid = HILDON_GRID(container);
+ priv = HILDON_GRID_GET_PRIVATE(container);
+
+ old_index = priv->focus_index;
+ updated = GTK_WIDGET_VISIBLE(widget);
+
+ for (list = priv->children, index = 0, deleted = FALSE;
+ list != NULL; list = list->next, index++) {
+ child = (HildonGridChild *) list->data;
+ child_widget = child->widget;
+
+ /* Remove the Item if it is found in the grid */
+ if (child_widget == widget) {
+ gtk_widget_unparent(child_widget);
+ priv->children = g_list_remove_link(priv->children, list);
+ g_list_free(list);
+ g_free(child);
+
+ deleted = TRUE;
+
+ break;
+ }
+ }
+
+ /* Emit warning if the item is not found */
+ if (!deleted) {
+ g_warning("tried to remove unexisting item");
+ return;
+ }
+
+ /* Move focus somewhere. */
+ if (old_index == index) {
+ if (old_index == g_list_length(priv->children)) {
+ if (index == 0) {
+ set_focus(grid, NULL, TRUE);
+ } else {
+ set_focus(grid,
+ get_child_by_index(priv, old_index - 1), TRUE);
+ }
+ } else {
+ set_focus(grid, get_child_by_index(priv, old_index), TRUE);
+ }
+ } else {
+ set_focus(grid, GTK_CONTAINER(grid)->focus_child, TRUE);
+ }
+
+ updated |= adjust_scrollbar_height(grid);
+ updated |= jump_scrollbar_to_focused(grid);
+
+ if (updated) {
+ gtk_widget_queue_resize(GTK_WIDGET(grid));
+ }
+}
+
+/**
+ * hildon_grid_set_focus_child:
+ * @container: HildonGrid
+ * @widget: HildonGridItem
+ *
+ * Sets focus.
+ */
+static void
+hildon_grid_set_focus_child(GtkContainer * container, GtkWidget * widget)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID(container));
+ g_return_if_fail(HILDON_IS_GRID_ITEM(widget) || widget == NULL);
+
+ grid = HILDON_GRID(container);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ if (GTK_CONTAINER(grid)->focus_child == widget || widget == NULL)
+ return;
+
+ set_focus(grid, widget, TRUE);
+}
+
+
+
+static void
+set_focus(HildonGrid * grid, GtkWidget * widget, gboolean refresh_view)
+{
+ HildonGridPrivate *priv;
+ GtkContainer *container;
+ gboolean view_updated;
+
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ container = GTK_CONTAINER(grid);
+
+ /* If widget is NULL -> unfocus */
+ if (widget == NULL && container->focus_child != NULL)
+ GTK_WIDGET_UNSET_FLAGS(container->focus_child, GTK_HAS_FOCUS);
+
+ GTK_CONTAINER(grid)->focus_child = widget;
+ if (widget == NULL) {
+ priv->focus_index = -1;
+ return;
+ }
+
+ /* Get the child index which the user wanted to focus */
+ priv->focus_index = get_child_index(priv, widget);
+
+ gtk_widget_grab_focus(widget);
+
+ if (refresh_view) {
+ view_updated = jump_scrollbar_to_focused(grid);
+ } else {
+ view_updated = FALSE;
+ }
+
+ if (view_updated) {
+ hildon_grid_size_allocate(GTK_WIDGET(grid),
+ >K_WIDGET(grid)->allocation);
+ }
+}
+
+static void
+hildon_grid_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GList *list;
+
+ g_return_if_fail(container);
+ g_return_if_fail(callback);
+
+ grid = HILDON_GRID(container);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ /* Connect callback functions */
+ if (include_internals) {
+ if (priv->scrollbar != NULL) {
+ (*callback) (priv->scrollbar, callback_data);
+ }
+ if (priv->empty_label != NULL) {
+ (*callback) (priv->empty_label, callback_data);
+ }
+ }
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ (*callback) (((HildonGridChild *) list->data)->widget,
+ callback_data);
+ }
+}
+
+static void hildon_grid_destroy(GtkObject * self)
+{
+ HildonGridPrivate *priv;
+
+ g_return_if_fail(self != NULL);
+ g_return_if_fail(HILDON_IS_GRID(self));
+
+ priv = HILDON_GRID_GET_PRIVATE(self);
+
+ if (GTK_WIDGET(self)->window != NULL) {
+ g_object_unref(G_OBJECT(GTK_WIDGET(self)->window));
+ }
+
+ gtk_container_forall(GTK_CONTAINER(self),
+ (GtkCallback) gtk_object_ref, NULL);
+ gtk_container_forall(GTK_CONTAINER(self),
+ (GtkCallback) gtk_widget_unparent, NULL);
+
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+static void hildon_grid_finalize(GObject * object)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+
+ grid = HILDON_GRID(object);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ gtk_container_forall(GTK_CONTAINER(object),
+ (GtkCallback) gtk_object_unref, NULL);
+
+ if (priv->style != NULL) {
+ g_free(priv->style);
+ }
+ if (G_OBJECT_CLASS(parent_class)->finalize) {
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+ }
+}
+
+/*
+ * hildon_grid_key_pressed:
+ * @widget: Widget where we get the signal from
+ * @event: EventKey
+ * @data: #HildonGrid
+ *
+ * Handle user key press (keyboard navigation).
+ *
+ * And here's how it works if some items are dimmed (moving to right):
+ * . . . . . . # . . 2 # . . # . .
+ * . 1 # 2 . 1 # # 1 # # # 1 # # #
+ * . . . . . 2 . . . . 2 .
+ *
+ * '.' = item,
+ * '#' = dimmed item,
+ * '1' = starting position,
+ * '2' = final position
+ *
+ * ...although only the first example is implemented right now.
+ *
+ * Return value: Signal handled
+ */
+static gboolean
+hildon_grid_key_pressed(GtkWidget * widget,
+ GdkEventKey * event)
+{
+ GtkAdjustment *adjustment;
+ GtkContainer *container;
+ GtkWidget *new_focus;
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ gboolean shift;
+ gint keyval;
+ gint x, y;
+ gint focus_index;
+ gint child_count, child_rows;
+ gint t;
+ gint addition, max_add;
+
+ g_return_val_if_fail(widget, FALSE);
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ /*
+ * If focus was never lost, we could just see if an item is focused -
+ * if not, there's nothing else to focus...
+ */
+
+ /* No items? */
+ if (priv->children == NULL || g_list_length(priv->children) == 0)
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+
+ /* Focused item is dimmed? */
+ /* If we have no focus, allow non-existing focus to move... */
+ container = GTK_CONTAINER(grid);
+ if (container->focus_child != NULL
+ && !GTK_WIDGET_IS_SENSITIVE(container->focus_child)) {
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ }
+ /* At the moment we don't want to do anything here if alt or control
+ or MODX is pressed, so return now. Shift + TAB are accepted (from
+ hildon-table-grid) And right now modifiers do not make any
+ difference... */
+
+ /* Said somewhere that "foo = a == b" is not desirable. */
+ if (event->state & GDK_SHIFT_MASK) {
+ shift = TRUE;
+ } else {
+ shift = FALSE;
+ }
+
+ keyval = event->keyval;
+ if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL) {
+ switch (event->keyval) {
+ case GDK_Left:
+ keyval = GDK_Right;
+ break;
+ case GDK_KP_Left:
+ keyval = GDK_KP_Right;
+ break;
+ case GDK_Right:
+ keyval = GDK_Left;
+ break;
+ case GDK_KP_Right:
+ keyval = GDK_KP_Left;
+ break;
+ }
+ }
+
+ child_count = g_list_length(priv->children);
+ child_rows = (child_count - 1) / priv->num_columns + 1;
+
+ if (priv->focus_index != -1) {
+ x = priv->focus_index % priv->num_columns;
+ y = priv->focus_index / priv->num_columns;
+ } else {
+ x = y = 0;
+ }
+
+ switch (keyval) {
+ case GDK_KP_Page_Up:
+ case GDK_Page_Up:
+ if (priv->first_index == 0) {
+ if (priv->focus_index == 0) {
+ return TRUE;
+ }
+ set_focus(grid, get_child_by_index(priv, 0), TRUE);
+ return TRUE;
+ }
+
+ t = MAX(priv->first_index / priv->num_columns - priv->area_rows, 0);
+ adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
+ adjustment->value = (gdouble) (t * priv->item_height);
+ gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
+ gtk_widget_queue_draw(priv->scrollbar);
+ update_contents(grid);
+
+ /* Want to update now. */
+ hildon_grid_size_allocate(GTK_WIDGET(grid),
+ >K_WIDGET(grid)->allocation);
+
+ return TRUE;
+ break;
+
+ case GDK_KP_Page_Down:
+ case GDK_Page_Down:
+ if (priv->first_index / priv->num_columns ==
+ child_rows - priv->area_rows) {
+ if (priv->focus_index == child_count - 1) {
+ return TRUE;
+ }
+ set_focus(grid, get_child_by_index(priv, child_count - 1),
+ TRUE);
+ return TRUE;
+ }
+
+ t = MIN(priv->first_index / priv->num_columns +
+ priv->area_rows, child_rows - priv->area_rows);
+ adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
+ adjustment->value = (gdouble) (t * priv->item_height);
+ gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
+ gtk_widget_queue_draw(priv->scrollbar);
+ update_contents(grid);
+
+ /* Want to update now. */
+ hildon_grid_size_allocate(GTK_WIDGET(grid),
+ >K_WIDGET(grid)->allocation);
+
+ return TRUE;
+ break;
+
+ case GDK_KP_Up:
+ case GDK_Up:
+ if (y <= 0) {
+ return TRUE;
+ }
+ addition = -priv->num_columns;
+ max_add = y;
+ y--;
+ break;
+
+ case GDK_KP_Down:
+ case GDK_Down:
+ if (y >= (child_count - 1) / priv->num_columns) {
+ return TRUE;
+ }
+ t = child_count % priv->num_columns;
+ if (t == 0) {
+ t = priv->num_columns;
+ }
+ if (y == (child_count - 1) / priv->num_columns - 1 && x >= t) {
+ x = t - 1;
+ }
+ y++;
+ addition = priv->num_columns;
+ max_add = child_rows - y;
+ break;
+
+ case GDK_KP_Left:
+ case GDK_Left:
+ if (x <= 0) {
+ return TRUE;
+ }
+ addition = -1;
+ max_add = x;
+ x--;
+ break;
+
+ case GDK_KP_Right:
+ case GDK_Right:
+ if (x >= priv->num_columns - 1) {
+ return TRUE;
+ }
+ if (y == 0 && x >= child_count - 1) {
+ return TRUE;
+ }
+ x++;
+ addition = 1;
+ max_add = priv->num_columns - x;
+ if (y * priv->num_columns + x == child_count) {
+ y--;
+ }
+ break;
+ case GDK_KP_Enter:
+ case GDK_Return:
+ hildon_grid_activate_child(grid,
+ HILDON_GRID_ITEM
+ (GTK_CONTAINER(grid)->focus_child));
+ return TRUE;
+ break;
+ default:
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+ break;
+ }
+
+ focus_index = y * priv->num_columns + x;
+ new_focus = get_child_by_index(priv, focus_index);
+
+ while (new_focus != NULL &&
+ focus_index < child_count && !GTK_WIDGET_SENSITIVE(new_focus)) {
+ max_add--;
+
+ if (max_add == 0) {
+ return TRUE;
+ }
+ focus_index += addition;
+ new_focus = get_child_by_index(priv, focus_index);
+ }
+
+ if (new_focus != NULL) {
+ set_focus(grid, new_focus, TRUE);
+ }
+ return TRUE;
+}
+
+
+/*
+ * hildon_grid_button_pressed:
+ * @widget: Widget where signal is coming from
+ * @event: #EventButton
+ * @data: #HildonGrid
+ *
+ * Handle mouse button press.
+ *
+ * Return value: Signal handled
+ */
+static gboolean
+hildon_grid_button_pressed(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GtkWidget *child;
+ int child_no;
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+/* Watch out for double/triple click press events */
+
+ if (event->type == GDK_2BUTTON_PRESS ||
+ event->type == GDK_3BUTTON_PRESS) {
+ priv->last_button_event = event->type;
+ return FALSE;
+ }
+
+ priv->last_button_event = event->type;
+
+ if (event->type != GDK_BUTTON_PRESS)
+ return FALSE;
+
+
+ child_no = get_child_index_by_coord(priv, event->x, event->y);
+
+ if (child_no == -1 || child_no >= g_list_length(priv->children))
+ return FALSE;
+
+ child = get_child_by_index(priv, child_no);
+ if (!GTK_WIDGET_IS_SENSITIVE(child))
+ return FALSE;
+
+ priv->click_x = event->x;
+ priv->click_y = event->y;
+
+ return FALSE;
+}
+
+/*
+ * hildon_grid_button_released:
+ * @widget: Widget the signal is coming from
+ * @event: #EventButton
+ * @data: #HildonGrid
+ *
+ * Handle mouse button release.
+ *
+ * Return value: Signal handled
+ */
+static gboolean
+hildon_grid_button_released(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GtkWidget *child;
+ int child_no;
+ gboolean already_selected;
+
+ grid = HILDON_GRID(widget);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ /* In case of double/triple click, silently ignore the release event */
+
+ if (priv->last_button_event == GDK_2BUTTON_PRESS ||
+ priv->last_button_event == GDK_3BUTTON_PRESS) {
+ priv->last_button_event = event->type;
+ return FALSE;
+ }
+
+ child_no = get_child_index_by_coord(priv, event->x, event->y);
+
+ if (child_no == -1 || child_no >= g_list_length(priv->children)) {
+ return FALSE;
+ }
+ child = get_child_by_index(priv, child_no);
+ if (!GTK_WIDGET_IS_SENSITIVE(child)) {
+ return FALSE;
+ }
+ if (abs(priv->click_x - event->x) >= DRAG_SENSITIVITY
+ && abs(priv->click_y - event->y) >= DRAG_SENSITIVITY) {
+ return FALSE;
+ }
+
+ /* Check if this element was already selected */
+ already_selected = (priv->focus_index == child_no);
+
+ set_focus(grid, child, TRUE);
+ priv->last_button_event = event->type;
+
+ /* If this is not the first click in this element, activate it */
+ if (already_selected)
+ hildon_grid_activate_child(grid, HILDON_GRID_ITEM(child));
+
+ return FALSE;
+}
+
+/*
+ * hildon_grid_scrollbar_moved:
+ * @widget: Widget which sent the signal
+ * @data: #HildonGrid
+ *
+ * Update HildonGrid contents when scrollbar is moved.
+ *
+ * Return value: Signal handeld
+ */
+static gboolean
+hildon_grid_scrollbar_moved(GtkWidget * widget, gpointer data)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ gboolean updated = FALSE;
+
+ grid = HILDON_GRID(data);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ updated = update_contents(grid);
+
+ /*
+ * If grid changes focus while dragging scrollbar and pointer leaves
+ * scrollbar, focus is moved to prev_focus... This prevents that.
+ */
+ gtk_window_set_prev_focus_widget(GTK_WINDOW
+ (gtk_widget_get_toplevel(widget)),
+ GTK_CONTAINER(grid)->focus_child);
+
+ if (updated)
+ /* Don't just queue it, let's do it now! */
+ hildon_grid_size_allocate(GTK_WIDGET(grid),
+ >K_WIDGET(grid)->allocation);
+
+ return TRUE;
+}
+
+
+/*
+ * update_contents:
+ * @grid: #HildonGrid
+ *
+ * Update the view if scrollbar has moved so that first visible row
+ * should've changed. Returns true if location actually changed.
+ *
+ * Return value: Content changed
+ */
+static gboolean update_contents(HildonGrid * grid)
+{
+ HildonGridPrivate *priv;
+ gint new_row;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ new_row = (int) gtk_range_get_value(GTK_RANGE(priv->scrollbar))
+ / priv->item_height;
+
+ if (new_row != priv->old_sb_pos) {
+ priv->old_sb_pos = new_row;
+ priv->first_index = new_row * priv->num_columns;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+ * jump_scrollbar_to_focused:
+ * @grid: #HildonGrid
+ *
+ * Moves scrollbar position so that focused item will be shown
+ * in visible area.
+ * Returns TRUE if visible position of widgets have changed.
+ *
+ * Return value: Content changed
+ */
+static gboolean jump_scrollbar_to_focused(HildonGrid * grid)
+{
+ HildonGridPrivate *priv;
+ GtkAdjustment *adjustment;
+ gint child_count;
+ gint empty_grids;
+ gint new_row;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ /* If we don't have scrollbar, let the focus be broken, too. */
+ g_return_val_if_fail(priv->scrollbar != NULL, FALSE);
+
+ /* Make sure "first widget" is something sensible. */
+ priv->first_index = priv->first_index -
+ priv->first_index % priv->num_columns;
+
+ child_count = g_list_length(priv->children);
+ empty_grids = priv->num_columns * priv->area_rows - child_count +
+ priv->first_index;
+
+ /* Determine the position of the new row */
+ if (priv->focus_index < priv->first_index) {
+ new_row = priv->focus_index / priv->num_columns;
+ } else if (priv->focus_index >= priv->first_index +
+ priv->area_rows * priv->num_columns) {
+ gint last_top_row;
+ new_row = priv->focus_index / priv->num_columns -
+ priv->area_rows + 1;
+ last_top_row = child_count / priv->num_columns - priv->area_rows + 1;
+ if (child_count % priv->num_columns != 0) {
+ last_top_row++;
+ }
+ if (new_row > last_top_row) {
+ new_row = last_top_row;
+ }
+ } else if (empty_grids >= priv->num_columns) {
+ new_row = ((child_count - 1) / priv->num_columns + 1)
+ - priv->area_rows;
+ if (new_row < 0) {
+ new_row = 0;
+ }
+ } else {
+ return FALSE;
+ }
+
+ /* Move scrollbar accordingly. */
+ adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
+ adjustment->value = (gdouble) (new_row * priv->item_height);
+ gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
+ priv->first_index = new_row * priv->num_columns;
+ priv->old_sb_pos = new_row;
+
+ gtk_widget_queue_draw(priv->scrollbar);
+
+ return TRUE;
+}
+
+
+/*
+ * adjust_scrollbar_height:
+ * @grid: HildonGridPrivate
+ *
+ * Return value: View should change
+ *
+ * Adjust scrollbar according the #HildonGrid contents.
+ * Show/hide scrollbar if
+ * appropriate. Also sets priv->first_index.
+ */
+static gboolean adjust_scrollbar_height(HildonGrid * grid)
+{
+ HildonGridPrivate *priv;
+ GtkRequisition req;
+ GtkAdjustment *adj;
+ GtkAllocation alloc;
+ GtkAllocation *gridalloc;
+ gint old_upper;
+ gint need_rows;
+ gint need_pixels;
+ gboolean updated;
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ g_return_val_if_fail(priv->scrollbar != NULL, FALSE);
+
+ updated = FALSE;
+ gridalloc = >K_WIDGET(grid)->allocation;
+
+ /* See if we need scrollbar at all. */
+ if (priv->num_columns == 0) {
+ priv->num_columns = DEFAULT_N_COLUMNS;
+ } else {
+ priv->num_columns = MAX(1, priv->num_columns);
+ }
+
+ if (g_list_length(priv->children) != 0) {
+ need_rows = (g_list_length(priv->children) - 1) /
+ priv->num_columns + 1;
+ } else {
+ need_rows = 0;
+ }
+
+ if (need_rows <= priv->area_rows) {
+ updated = priv->first_index != 0;
+ priv->scrollbar_width = 0;
+
+ priv->first_index = 0;
+ if (GTK_WIDGET_VISIBLE(priv->scrollbar)) {
+ GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET (grid));
+ if (HILDON_IS_APP (parent))
+ g_object_set (parent, "scroll-control", FALSE, NULL);
+ gtk_widget_hide(priv->scrollbar);
+ updated = TRUE;
+ }
+
+ return updated;
+ }
+
+ /* All right then, we need scrollbar. Place scrollbar on the screen. */
+ gtk_widget_get_child_requisition(priv->scrollbar, &req);
+ priv->scrollbar_width = req.width;
+
+ alloc.width = req.width;
+ alloc.height = gridalloc->height;
+ alloc.x = gridalloc->width - req.width + gridalloc->x;
+ alloc.y = gridalloc->y;
+ gtk_widget_size_allocate(priv->scrollbar, &alloc);
+
+ if (!GTK_WIDGET_VISIBLE(priv->scrollbar)) {
+ GtkWidget *parent = gtk_widget_get_toplevel (GTK_WIDGET (grid));
+ if (HILDON_IS_APP (parent))
+ g_object_set (parent, "scroll-control", TRUE, NULL);
+ gtk_widget_show(priv->scrollbar);
+ updated = TRUE;
+ }
+
+
+ need_pixels = need_rows * priv->item_height;
+
+ /* Once we know how much space we need, update the scrollbar. */
+ adj = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
+ old_upper = (int) adj->upper;
+ adj->lower = 0.0;
+ adj->upper = (gdouble) need_pixels;
+ adj->step_increment = (gdouble) priv->item_height;
+ adj->page_increment = (gdouble) (priv->area_rows * priv->item_height);
+ adj->page_size =
+ (gdouble) (priv->area_height - priv->area_height % priv->item_height);
+
+ /* Also update position if needed to show focused item. */
+
+ gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adj);
+
+ /* Then set first_index. */
+ priv->first_index = (int) adj->value / priv->item_height *
+ priv->num_columns;
+
+ /* Finally, ask Gtk to redraw the scrollbar. */
+ if (old_upper != (int) adj->upper) {
+ gtk_widget_queue_draw(priv->scrollbar);
+ }
+ return updated;
+}
+
+/*
+ * get_child_index_by_coord:
+ * @priv: HildonGridPrivate
+ * @x: X-coordinate
+ * @y: Y-coordinate
+ *
+ * Returns index of child at given coordinates, -1 if no child.
+ *
+ * Return value: Index
+ */
+static gint
+get_child_index_by_coord(HildonGridPrivate * priv, gint x, gint y)
+{
+ int xgap, ygap;
+ int t;
+
+ if (priv->item_width==0 || priv->item_height==0) {
+ return -1;
+ }
+
+ xgap = x % priv->item_width;
+ ygap = y % priv->item_height;
+
+ if (xgap > priv->item_width - priv->h_margin) { /*FIXME*/
+ return -1;
+ }
+
+ /* Event may come from outside of the grid. Skipping those events */
+ if (x >= priv->item_width * priv->num_columns)
+ return -1;
+
+ t = y / priv->item_height * priv->num_columns +
+ x / priv->item_width + priv->first_index;
+
+ if (t >= priv->first_index + priv->area_rows * priv->num_columns ||
+ t >= g_list_length(priv->children) || t < 0) {
+ return -1;
+ }
+ return t;
+}
+
+/*
+ * get_child_by_index:
+ * @priv: HildonGridPrivate
+ * @index: Index of child
+ *
+ * Returns child that is #th in HildonGrid or NULL if child was not found
+ * among the children.
+ *
+ * Return value: GtkWidget
+ */
+static GtkWidget *get_child_by_index(HildonGridPrivate * priv, gint index)
+{
+ GList *list;
+ int i = 0;
+
+ if (index >= g_list_length(priv->children) || index < 0) {
+ return NULL;
+ }
+ for (list = priv->children, i = 0; list != NULL;
+ list = list->next, i++) {
+ if (index == i) {
+ return ((HildonGridChild *) list->data)->widget;
+ }
+ }
+
+ g_warning("no such child");
+ return NULL;
+}
+
+/*
+ * get_child_index:
+ * @priv: HildonGridPrivate
+ * @child: #GtkWidget to look for
+ *
+ * Returns index of a child or -1 if child was not found among the
+ * children.
+ *
+ * Return value: Index
+ */
+static gint get_child_index(HildonGridPrivate * priv, GtkWidget * child)
+{
+ GList *list;
+ gint index;
+
+ if (child == NULL)
+ return -1;
+
+ for (list = priv->children, index = 0;
+ list != NULL; list = list->next, index++) {
+ if (((HildonGridChild *) list->data)->widget == child) {
+ return index;
+ }
+ }
+
+ g_warning("no such child");
+ return -1;
+}
+
+
+/**
+ * hildon_grid_activate_child:
+ * @grid: #HildonGrid
+ * @item: #HildonGridItem
+ *
+ * Sends a signal to indicate that this HildonGridItem is activated.
+ */
+void hildon_grid_activate_child(HildonGrid * grid, HildonGridItem * item)
+{
+ g_return_if_fail(HILDON_IS_GRID(grid));
+
+ g_signal_emit(grid, grid_signals[ACTIVATE_CHILD], 0, item);
+}
+
+
+
+/**
+ * hildon_grid_set_style:
+ * @grid: #HildonGrid
+ * @style_name: style name
+ *
+ * Sets style. Setting style sets widget size, spacing, label position,
+ * number of columns, and icon size.
+ */
+void hildon_grid_set_style(HildonGrid * grid, const gchar * style_name)
+{
+ HildonGridPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_GRID(grid));
+
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ if (priv->style != NULL) {
+ g_free((gpointer) priv->style);
+ }
+ if (style_name != NULL) {
+ priv->style = g_strdup(style_name);
+ } else {
+ priv->style = NULL;
+ }
+
+ gtk_widget_set_name(GTK_WIDGET(grid), style_name);
+ get_style_properties(grid);
+
+ gtk_widget_queue_resize(GTK_WIDGET(grid));
+}
+
+/**
+ * hildon_grid_get_style:
+ * @grid: #HildonGrid
+ *
+ * Returns the name of style currently used in HildonGrid.
+ *
+ * Returns: style name
+ */
+const gchar *hildon_grid_get_style(HildonGrid * grid)
+{
+ g_return_val_if_fail(HILDON_IS_GRID(grid), NULL);
+
+ return gtk_widget_get_name(GTK_WIDGET(grid));
+}
+
+/*
+ * get_style_properties:
+ * @grid: #HildonGrid
+ *
+ * Gets widget size and other properties from gtkrc. If some properties
+ * have changed, notify children of this, too.
+ */
+static void get_style_properties(HildonGrid * grid)
+{
+ GList *iter;
+ gint num_columns;
+ HildonGridPositionType label_pos;
+ gint emblem_size;
+
+ gint h_margin, v_margin;
+ gint item_height;
+ gint icon_width;
+ gint focus_margin, icon_label_margin;
+ gint label_height;
+
+ HildonGridPrivate *priv;
+ g_return_if_fail(HILDON_IS_GRID(grid));
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+ gtk_widget_style_get(GTK_WIDGET(grid),
+ "item_hspacing", &h_margin,
+ "item_vspacing", &v_margin,
+ "item_height", &item_height,
+ "icon_size", &icon_width,
+ "n_columns", &num_columns,
+ "label_pos", &label_pos,
+ "label_hspacing", &focus_margin,
+ "label_vspacing", &icon_label_margin,
+ "emblem_size", &emblem_size,
+ "label_height", &label_height,
+ NULL);
+
+ hildon_grid_set_icon_width(grid, icon_width);
+ hildon_grid_set_num_columns(grid, num_columns);
+ hildon_grid_set_label_pos(grid, label_pos);
+ hildon_grid_set_focus_margin(grid, focus_margin);
+ hildon_grid_set_icon_label_margin(grid, icon_label_margin);
+ hildon_grid_set_emblem_size(grid, emblem_size);
+ hildon_grid_set_label_height(grid, label_height);
+
+ priv->h_margin = h_margin;
+ priv->v_margin = v_margin;
+ priv->item_height = item_height;
+
+ iter = NULL;
+ /*
+ for (iter = priv->children; iter != NULL; iter = iter->next) {
+ HildonGridItem *child;
+ child = HILDON_GRID_ITEM(((HildonGridChild *) iter->data)->widget);
+ _hildon_grid_item_done_updating_settings(child);
+ }
+ */
+}
+
+
+
+/**
+ * hildon_grid_set_scrollbar_pos:
+ * @grid: #HildonGrid
+ * @scrollbar_pos: new position (in pixels)
+ *
+ * Sets view (scrollbar) to specified position.
+ */
+void hildon_grid_set_scrollbar_pos(HildonGrid * grid, gint scrollbar_pos)
+{
+ HildonGridPrivate *priv;
+ GtkAdjustment *adjustment;
+
+ g_return_if_fail(HILDON_IS_GRID(grid));
+
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+ adjustment = gtk_range_get_adjustment(GTK_RANGE(priv->scrollbar));
+ adjustment->value = (gdouble) scrollbar_pos;
+
+ gtk_range_set_adjustment(GTK_RANGE(priv->scrollbar), adjustment);
+
+ g_object_notify (G_OBJECT (grid), "scrollbar-position");
+
+ /* If grid isn't drawable, updating anything could mess up focus. */
+ if (!GTK_WIDGET_DRAWABLE(GTK_WIDGET(grid)))
+ return;
+
+ update_contents(grid);
+}
+
+/**
+ * hildon_grid_get_scrollbar_pos:
+ * @grid: #HildonGrid
+ *
+ * Returns: position of scrollbar (in pixels).
+ */
+gint hildon_grid_get_scrollbar_pos(HildonGrid * grid)
+{
+ GtkAdjustment *adjustment;
+
+ g_return_val_if_fail(HILDON_IS_GRID(grid), -1);
+
+ adjustment = gtk_range_get_adjustment(GTK_RANGE
+ (HILDON_GRID_GET_PRIVATE
+ (grid)->scrollbar));
+ return (int) adjustment->value;
+}
+
+static void
+hildon_grid_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonGrid *grid;
+
+ grid = HILDON_GRID(object);
+
+ switch (prop_id) {
+ case PROP_EMPTY_LABEL:
+ hildon_grid_set_empty_label(grid, g_value_get_string(value));
+ break;
+
+ case PROP_STYLE:
+ hildon_grid_set_style(grid, g_value_get_string(value));
+ break;
+
+ case PROP_SCROLLBAR_POS:
+ hildon_grid_set_scrollbar_pos(grid, g_value_get_int(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_grid_get_property(GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ HildonGrid *grid;
+
+ grid = HILDON_GRID(object);
+
+ switch (prop_id) {
+ case PROP_EMPTY_LABEL:
+ g_value_set_string(value, hildon_grid_get_empty_label(grid));
+ break;
+
+ case PROP_STYLE:
+ g_value_set_string(value, hildon_grid_get_style(grid));
+ break;
+
+ case PROP_SCROLLBAR_POS:
+ g_value_set_int(value, hildon_grid_get_scrollbar_pos(grid));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+hildon_grid_state_changed(GtkWidget * widget,
+ GtkStateType state, gpointer data)
+{
+ HildonGrid *grid;
+ HildonGridPrivate *priv;
+ GList *list;
+ GtkWidget *current;
+ GtkWidget *prev_focusable, *next_focusable;
+ gboolean found_old;
+
+ g_return_val_if_fail(HILDON_IS_GRID(data), FALSE);
+ g_return_val_if_fail(HILDON_IS_GRID_ITEM(widget), FALSE);
+
+ grid = HILDON_GRID(data);
+ priv = HILDON_GRID_GET_PRIVATE(grid);
+
+
+ if (GTK_WIDGET_IS_SENSITIVE(widget))
+ return FALSE;
+
+ prev_focusable = next_focusable = NULL;
+ found_old = FALSE;
+
+ for (list = priv->children; list != NULL; list = list->next) {
+ current = ((HildonGridChild *) list->data)->widget;
+
+ if (GTK_WIDGET_IS_SENSITIVE(current)) {
+ if (found_old) {
+ next_focusable = current;
+ break;
+ } else {
+ prev_focusable = current;
+ }
+ } else if (current == widget) {
+ found_old = TRUE;
+ }
+ }
+
+ if (next_focusable == NULL) {
+ next_focusable = prev_focusable;
+ }
+
+ gtk_container_set_focus_child(GTK_CONTAINER(grid), next_focusable);
+
+ return FALSE;
+}
+
+
+
+static void
+hildon_grid_tap_and_hold_setup(GtkWidget * widget,
+ GtkWidget * menu,
+ GtkCallback func,
+ GtkWidgetTapAndHoldFlags flags)
+{
+ g_return_if_fail(HILDON_IS_GRID(widget) && GTK_IS_MENU(menu));
+
+ parent_class->parent_class.tap_and_hold_setup
+ (widget, menu, func, flags | GTK_TAP_AND_HOLD_NO_INTERNALS);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file hildon-grid.h
+ *
+ * This file is a header file for hildon-grid.c, the implementation of
+ * #HildonGrid. #HildonGrid is used in views like Home and Control Panel
+ * which have single-tap activated items.
+ */
+
+#ifndef __HILDON_GRID_H__
+#define __HILDON_GRID_H__
+
+#include <gtk/gtkcontainer.h>
+#include <hildon-widgets/hildon-grid-item.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_GRID (hildon_grid_get_type ())
+#define HILDON_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ HILDON_TYPE_GRID, \
+ HildonGrid))
+#define HILDON_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ HILDON_TYPE_GRID, \
+ HildonGridClass))
+#define HILDON_IS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ HILDON_TYPE_GRID))
+#define HILDON_IS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ HILDON_TYPE_GRID))
+#define HILDON_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ HILDON_TYPE_GRID, \
+ HildonGridClass))
+typedef struct _HildonGrid HildonGrid;
+typedef struct _HildonGridClass HildonGridClass;
+
+
+
+struct _HildonGrid {
+ GtkContainer parent;
+};
+
+struct _HildonGridClass {
+ GtkContainerClass parent_class;
+
+ void (*activate_child) (HildonGrid * grid, HildonGridItem * item);
+ void (*popup_context_menu) (HildonGrid * grid, HildonGridItem * item);
+};
+
+GType hildon_grid_get_type(void);
+GtkWidget *hildon_grid_new(void);
+
+/*
+ * Use GtkContainer API:
+ *
+ * void gtk_container_set_focus_child (GtkContainer *container,
+ * GtkWidget *child);
+ *
+ * GTK_CONTAINER (grid)->focus_child can be used to get focused child.
+ */
+
+void hildon_grid_set_style(HildonGrid * grid, const gchar * style_name);
+const gchar *hildon_grid_get_style(HildonGrid * grid);
+
+void hildon_grid_set_scrollbar_pos(HildonGrid * grid, gint scrollbar_pos);
+gint hildon_grid_get_scrollbar_pos(HildonGrid * grid);
+
+
+/*
+ * We are going to use gtk_container_add/remove, so these are internal.
+ * If GridView is not visible, it won't update the view, so it should be
+ * hidden when doing massive modifications.
+ *
+ *
+ * Use GtkContainer API:
+ *
+ * void gtk_container_add (GtkContainer *container,
+ * GtkWidget *widget);
+ *
+ * void gtk_container_remove (GtkContainer *container,
+ * GtkWidget *widget);
+ */
+
+void hildon_grid_activate_child(HildonGrid * grid, HildonGridItem * item);
+
+G_END_DECLS
+#endif /* __HILDON_GRID_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-hvolumebar
+ * @short_description: A widget that displays a horizontal volume bar
+ * @see_also: #HildonVVolumebar, #HildonVolumebar
+ *
+ * The #HildonHVolumebar widget displays a horizontal volume bar that allows
+ * increasing or decreasing volume within a pre-defined range, and includes
+ * a mute icon which users can click to mute the sound.
+ */
+
+
+/* Horizontal volumebar subclass */
+
+#include <gtk/gtktoolbar.h>
+#include "hildon-hvolumebar.h"
+#include "hildon-volumebar.h"
+#include "hildon-volumebar-range.h"
+#include "hildon-volumebar-private.h"
+
+/* Defines for normal version of HVolumebar */
+/* Toggle button */
+#define DEFAULT_TBUTTON_WIDTH 26
+#define DEFAULT_TBUTTON_HEIGHT 26
+/* Volume bar */
+#define MINIMUM_BAR_WIDTH 147
+#define DEFAULT_BAR_HEIGHT 58
+#define DEFAULT_ENDING_SIZE 20
+
+/* Gap to leave for mute button */
+#define VERTICAL_MUTE_GAP 16
+#define HORIZONTAL_MUTE_GAP 6
+
+/* Sizes inside a toolbar */
+/* Toggle button */
+#define TOOL_DEFAULT_TBUTTON_WIDTH 26
+#define TOOL_DEFAULT_TBUTTON_HEIGHT 26
+/* Volumebar */
+#define TOOL_MINIMUM_BAR_WIDTH 121
+#define TOOL_DEFAULT_BAR_HEIGHT 40
+#define TOOL_DEFAULT_ENDING_SIZE 0
+#define TOOL_VERTICAL_MUTE_GAP ((TOOL_DEFAULT_BAR_HEIGHT - TOOL_DEFAULT_TBUTTON_HEIGHT) / 2)
+
+static HildonVolumebarClass *parent_class;
+static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass);
+static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar);
+
+static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static void hildon_hvolumebar_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void hildon_hvolumebar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static void hildon_hvolumebar_map(GtkWidget * widget);
+
+
+GType hildon_hvolumebar_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof(HildonHVolumebarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_hvolumebar_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonHVolumebar),
+ 0,
+ (GInstanceInitFunc) hildon_hvolumebar_init,
+ };
+ type = g_type_register_static(HILDON_TYPE_VOLUMEBAR,
+ "HildonHVolumebar", &info, 0);
+ }
+ return type;
+}
+
+
+static void hildon_hvolumebar_class_init(HildonHVolumebarClass * klass)
+{
+ GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ volumebar_class->size_request = hildon_hvolumebar_size_request;
+ volumebar_class->size_allocate = hildon_hvolumebar_size_allocate;
+ volumebar_class->map = hildon_hvolumebar_map;
+ volumebar_class->expose_event = hildon_hvolumebar_expose;
+}
+
+
+static void hildon_hvolumebar_init(HildonHVolumebar * hvolumebar)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(hvolumebar);
+
+ priv->volumebar =
+ HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
+ (GTK_ORIENTATION_HORIZONTAL));
+
+ GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(hvolumebar), GTK_CAN_FOCUS);
+
+ gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(hvolumebar));
+ gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(hvolumebar));
+
+ gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
+
+ /* Signals */
+ g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
+ G_CALLBACK(hildon_volumebar_level_change),
+ hvolumebar);
+ g_signal_connect_swapped(priv->tbutton, "toggled",
+ G_CALLBACK(_hildon_volumebar_mute_toggled), hvolumebar);
+
+ gtk_widget_show(GTK_WIDGET(priv->volumebar));
+}
+
+/**
+ * hildon_hvolumebar_new:
+ *
+ * Creates a new #HildonHVolumebar widget.
+ *
+ * Returns: a new #HildonHVolumebar
+ */
+GtkWidget *hildon_hvolumebar_new(void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_HVOLUMEBAR, NULL));
+}
+
+static void hildon_hvolumebar_map(GtkWidget * widget)
+{
+ HildonVolumebarPrivate *priv;
+ GtkWidget *parent;
+
+ g_assert(HILDON_IS_HVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+ parent = gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_TOOLBAR);
+
+ /* Check if the volumebar is in a toolbar */
+ if (parent)
+ priv->is_toolbar = TRUE;
+
+ GTK_WIDGET_CLASS(parent_class)->map(widget);
+}
+
+static gboolean hildon_hvolumebar_expose(GtkWidget * widget,
+ GdkEventExpose * event)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_assert(HILDON_IS_HVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
+
+ if (GTK_WIDGET_DRAWABLE(widget)) {
+ /* Paint background */
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(priv->volumebar), GTK_SHADOW_OUT,
+ NULL, widget, "background",
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ /* The contents of the widget can paint themselves */
+ (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
+ }
+
+ return FALSE;
+}
+
+static void
+hildon_hvolumebar_size_request(GtkWidget * widget,
+ GtkRequisition * requisition)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_assert(HILDON_IS_HVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
+
+ /* Volumebar has different dimensions in toolbar */
+ requisition->width = (priv->is_toolbar
+ ? TOOL_MINIMUM_BAR_WIDTH
+ : MINIMUM_BAR_WIDTH);
+ requisition->height = (priv->is_toolbar
+ ? TOOL_DEFAULT_BAR_HEIGHT
+ : DEFAULT_BAR_HEIGHT);
+}
+
+static void
+hildon_hvolumebar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonVolumebarPrivate *priv;
+ GtkAllocation button_allocation, range_allocation;
+
+ g_assert(HILDON_IS_HVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ button_allocation.x = 0;
+ button_allocation.width = 0;
+
+ /* Center the widget vertically */
+ if (priv->is_toolbar && allocation->height > TOOL_DEFAULT_BAR_HEIGHT) {
+ allocation->y += (allocation->height - TOOL_DEFAULT_BAR_HEIGHT) / 2;
+ allocation->height = TOOL_DEFAULT_BAR_HEIGHT;
+ }
+ if (!priv->is_toolbar && allocation->height > DEFAULT_BAR_HEIGHT) {
+ allocation->y += (allocation->height - DEFAULT_BAR_HEIGHT) / 2;
+ allocation->height = DEFAULT_BAR_HEIGHT;
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
+
+ if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
+
+ /* Allocate space for the mute button */
+ if (priv->is_toolbar) {
+ button_allocation.x = allocation->x;
+ button_allocation.y = allocation->y + TOOL_VERTICAL_MUTE_GAP;
+ button_allocation.width = TOOL_DEFAULT_TBUTTON_WIDTH;
+ button_allocation.height = TOOL_DEFAULT_TBUTTON_HEIGHT;
+ } else {
+ button_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
+ button_allocation.y = allocation->y + VERTICAL_MUTE_GAP;
+ button_allocation.width = DEFAULT_TBUTTON_WIDTH;
+ button_allocation.height = DEFAULT_TBUTTON_HEIGHT;
+ }
+ gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
+ &button_allocation);
+ }
+ if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
+
+ /* Allocate space for the slider */
+ range_allocation.y = allocation->y;
+
+ if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
+ {
+ /* Leave room for the mute button */
+ range_allocation.x = button_allocation.x
+ + button_allocation.width
+ + HORIZONTAL_MUTE_GAP;
+
+ if (priv->is_toolbar)
+ {
+ /* In toolbar with mute button */
+ range_allocation.width = MAX(0,
+ allocation->width
+ - 2 * TOOL_DEFAULT_ENDING_SIZE
+ - TOOL_DEFAULT_TBUTTON_WIDTH
+ - HORIZONTAL_MUTE_GAP);
+
+ range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
+
+ }
+
+ else
+ {
+ /* Standalone with mute button */
+ range_allocation.width = MAX(0,
+ allocation->width
+ - 2 * DEFAULT_ENDING_SIZE
+ - DEFAULT_TBUTTON_WIDTH
+ - HORIZONTAL_MUTE_GAP);
+
+ range_allocation.height = DEFAULT_BAR_HEIGHT;
+ }
+
+ }
+
+ else
+ {
+ if (priv->is_toolbar)
+ {
+ /* In toolbar without mute button */
+ range_allocation.x = allocation->x;
+
+ range_allocation.width = MAX(0,
+ allocation->width
+ - 2 * TOOL_DEFAULT_ENDING_SIZE );
+
+ range_allocation.height = TOOL_DEFAULT_BAR_HEIGHT;
+
+ }
+
+ else
+ {
+ /* Standalone without mute button */
+ range_allocation.x = allocation->x + DEFAULT_ENDING_SIZE;
+
+ range_allocation.width = MAX(0,
+ allocation->width
+ - 2 * DEFAULT_ENDING_SIZE );
+
+ range_allocation.height = DEFAULT_BAR_HEIGHT;
+ }
+ }
+
+ gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),
+ &range_allocation);
+ }
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_HVOLUMEBAR_H__
+#define __HILDON_HVOLUMEBAR_H__
+
+#include <hildon-widgets/hildon-volumebar.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_HVOLUMEBAR ( hildon_hvolumebar_get_type() )
+#define HILDON_HVOLUMEBAR(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_HVOLUMEBAR, HildonHVolumebar))
+#define HILDON_HVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_HVOLUMEBAR, HildonHVolumebarClass))
+#define HILDON_IS_HVOLUMEBAR(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_HVOLUMEBAR))
+#define HILDON_IS_HVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_HVOLUMEBAR))
+
+typedef struct _HildonHVolumebar HildonHVolumebar;
+typedef struct _HildonHVolumebarClass HildonHVolumebarClass;
+
+struct _HildonHVolumebar {
+ /* This is our parent class */
+ HildonVolumebar volumebar;
+};
+
+struct _HildonHVolumebarClass {
+ HildonVolumebarClass parent_class;
+};
+
+GType hildon_hvolumebar_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_hvolumebar_new(void);
+
+G_END_DECLS
+#endif /* __HILDON_HVOLUMEBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_INPUT_MODE_HINT_H__
+#define __HILDON_INPUT_MODE_HINT_H__
+
+G_BEGIN_DECLS
+
+/* Hildon wrapper for setting the input mode in a GtkEntry
+ * Usage: g_object_set(G_OBJECT(entry), HILDON_INPUT_MODE_HINT, HILDON_INPUT_MODE_HINT_HEXA, NULL);
+ */
+#define HILDON_INPUT_MODE_HINT "input-mode"
+
+/* Hildon wrapper for setting the autocapitalization in text widgets.
+ * Usage: g_object_set(G_OBJECT(entry), HILDON_AUTOCAP, FALSE, NULL);
+ */
+#define HILDON_AUTOCAP "autocap"
+
+/**
+ * HildonInputModeHint:
+ * @HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL: accept all characters.
+ * @HILDON_INPUT_MODE_HINT_NUMERIC: accept only NUMERIC characters.
+ * @HILDON_INPUT_MODE_HINT_ALPHA: accept only ALPHA characters
+ * @HILDON_INPUT_MODE_HINT_NUMERICSPECIAL: accept only NUMERIC and SPECIAL
+ * @HILDON_INPUT_MODE_HINT_ALPHASPECIAL: accept only ALPHA and SPECIAL
+ * @HILDON_INPUT_MODE_HINT_ALPHANUMERIC: accept only ALPHA and NUMERIC
+ * @HILDON_INPUT_MODE_HINT_HEXA: accept only HEXA
+ * @HILDON_INPUT_MODE_HINT_HEXASPECIAL: accept only HEXA and SPECIAL
+ * @HILDON_INPUT_MODE_HINT_TELE: accept only TELEPHONE
+ * @HILDON_INPUT_MODE_HINT_TELESPECIAL: accept only TELEPHONE and SPECIAL
+ *
+ * Keys to set the mode in a GtkEntry widget into ALPHANUMERIC or NUMERIC mode. Note that this is only a hint; it only shows VKB with specified layout. Use it by calling 'g_object_set(G_OBJECT(entry), "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL);'.
+ */
+typedef enum {
+ HILDON_INPUT_MODE_HINT_ALPHANUMERICSPECIAL = 0,
+ HILDON_INPUT_MODE_HINT_NUMERIC,
+ HILDON_INPUT_MODE_HINT_ALPHA,
+ HILDON_INPUT_MODE_HINT_NUMERICSPECIAL,
+ HILDON_INPUT_MODE_HINT_ALPHASPECIAL,
+ HILDON_INPUT_MODE_HINT_ALPHANUMERIC,
+ HILDON_INPUT_MODE_HINT_HEXA,
+ HILDON_INPUT_MODE_HINT_HEXASPECIAL,
+ HILDON_INPUT_MODE_HINT_TELE,
+ HILDON_INPUT_MODE_HINT_TELESPECIAL
+
+} HildonInputModeHint;
+
+G_END_DECLS
+#endif /* __HILDON_INPUT_MODE_HINT_H__ */
--- /dev/null
+#include <hildon-widgets/hildon-marshalers.h>
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* BOOLEAN:ENUM (hildon-marshalers.list:26) */
+void
+_hildon_marshal_BOOLEAN__ENUM (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__ENUM) (gpointer data1,
+ gint arg_1,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__ENUM callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__ENUM) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_enum (param_values + 1),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* BOOLEAN:INT,INT,INT (hildon-marshalers.list:27) */
+void
+_hildon_marshal_BOOLEAN__INT_INT_INT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gboolean (*GMarshalFunc_BOOLEAN__INT_INT_INT) (gpointer data1,
+ gint arg_1,
+ gint arg_2,
+ gint arg_3,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__INT_INT_INT callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__INT_INT_INT) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_int (param_values + 1),
+ g_marshal_value_peek_int (param_values + 2),
+ g_marshal_value_peek_int (param_values + 3),
+ data2);
+
+ g_value_set_boolean (return_value, v_return);
+}
+
+/* VOID:OBJECT (hildon-marshalers.list:28) */
+
--- /dev/null
+
+#ifndef ___HILDON_MARSHALERS_H__
+#define ___HILDON_MARSHALERS_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* BOOLEAN:ENUM (hildon-marshalers.list:26) */
+extern void _hildon_marshal_BOOLEAN__ENUM (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* BOOLEAN:INT,INT,INT (hildon-marshalers.list:27) */
+extern void _hildon_marshal_BOOLEAN__INT_INT_INT (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:OBJECT (hildon-marshalers.list:28) */
+#define _hildon_marshal_VOID__OBJECT g_cclosure_marshal_VOID__OBJECT
+
+G_END_DECLS
+
+#endif /* __HILDON_MARSHALERS_H__ */
+
--- /dev/null
+# A copy of gtkmarshalers.list header for convenience
+#
+# see glib-genmarshal(1) for a detailed description of the file format,
+# possible parameter types are:
+# VOID indicates no return type, or no extra
+# parameters. if VOID is used as the parameter
+# list, no additional parameters may be present.
+# BOOLEAN for boolean types (gboolean)
+# CHAR for signed char types (gchar)
+# UCHAR for unsigned char types (guchar)
+# INT for signed integer types (gint)
+# UINT for unsigned integer types (guint)
+# LONG for signed long integer types (glong)
+# ULONG for unsigned long integer types (gulong)
+# ENUM for enumeration types (gint)
+# FLAGS for flag enumeration types (guint)
+# FLOAT for single-precision float types (gfloat)
+# DOUBLE for double-precision float types (gdouble)
+# STRING for string types (gchar*)
+# BOXED for boxed (anonymous but reference counted) types (GBoxed*)
+# POINTER for anonymous pointer types (gpointer)
+# OBJECT for GObject or derived types (GObject*)
+# NONE deprecated alias for VOID
+# BOOL deprecated alias for BOOLEAN
+
+BOOLEAN:ENUM
+BOOLEAN:INT,INT,INT
+VOID:OBJECT
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-name-password-dialog
+ * @short_description: A widget which allows a user to enter an username
+ * and a password
+ * @see_also: #HildonGetPasswordDialog, #HildonSetPasswordDialog
+ *
+ * #HildonNamePasswordDialog is used to enter a username and password
+ * when accessing a password protected function. The widget performs no
+ * input checking and is used only for retrieving a user name and a
+ * password.
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <hildon-name-password-dialog.h>
+#include <hildon-widgets/hildon-caption.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+static GtkDialogClass *parent_class;
+
+typedef struct _HildonNamePasswordDialogPrivate
+ HildonNamePasswordDialogPrivate;
+
+struct _HildonNamePasswordDialogPrivate {
+ GtkButton *okButton;
+ GtkButton *closeButton;
+
+ GtkLabel *domainLabel;
+ GtkEntry *nameEntry;
+ GtkEntry *passwordEntry;
+};
+
+/* Macro to access the private data of the object instance */
+#define HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), HILDON_TYPE_NAME_PASSWORD_DIALOG,\
+ HildonNamePasswordDialogPrivate))
+
+enum{
+ PROP_NONE = 0,
+ PROP_CONTENT,
+ PROP_USERNAME,
+ PROP_PASSWORD
+};
+
+static void
+hildon_name_password_dialog_class_init(HildonNamePasswordDialogClass *class);
+static void hildon_name_password_dialog_init(HildonNamePasswordDialog *widget);
+static void hildon_name_password_dialog_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_name_password_dialog_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+
+static void
+hildon_name_password_dialog_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonNamePasswordDialog *dialog = NULL;
+ HildonNamePasswordDialogPrivate *priv = NULL;
+
+ dialog = HILDON_NAME_PASSWORD_DIALOG(object);
+ priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id) {
+ case PROP_CONTENT:
+ /* Set the password domain text */
+ hildon_name_password_dialog_set_domain(dialog, g_value_get_string(value));
+ break;
+ case PROP_USERNAME:
+ /* Set the current username displayed in the dialog */
+ gtk_entry_set_text(priv->nameEntry, g_value_get_string(value));
+ break;
+ case PROP_PASSWORD:
+ /* Set the currently entered password */
+ gtk_entry_set_text(priv->passwordEntry, g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_name_password_dialog_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonNamePasswordDialog *dialog = NULL;
+ HildonNamePasswordDialogPrivate *priv = NULL;
+
+ dialog = HILDON_NAME_PASSWORD_DIALOG(object);
+ priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id) {
+ case PROP_CONTENT:
+ g_value_set_string(value, gtk_label_get_text(priv->domainLabel));
+ break;
+ case PROP_USERNAME:
+ g_value_set_string(value, hildon_name_password_dialog_get_name(dialog));
+ break;
+ case PROP_PASSWORD:
+ g_value_set_string(value, hildon_name_password_dialog_get_password(dialog));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_name_password_dialog_class_init(HildonNamePasswordDialogClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+
+ parent_class = g_type_class_peek_parent(class);
+
+ /* Override virtual functions */
+ object_class->set_property = hildon_name_password_dialog_set_property;
+ object_class->get_property = hildon_name_password_dialog_get_property;
+
+ /* Install new properties */
+ g_object_class_install_property(object_class,
+ PROP_CONTENT,
+ g_param_spec_string ("content",
+ "Content",
+ "Set content for content label.",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class,
+ PROP_USERNAME,
+ g_param_spec_string ("username",
+ "Username",
+ "Set content for name entry.",
+ "DEFAULT",
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class,
+ PROP_PASSWORD,
+ g_param_spec_string ("password",
+ "Password",
+ "Set content for password entry",
+ "DEFAULT",
+ G_PARAM_READWRITE));
+
+ /* Install private data structure */
+ g_type_class_add_private(class,
+ sizeof(HildonNamePasswordDialogPrivate));
+}
+
+static void
+hildon_name_password_dialog_init(HildonNamePasswordDialog * dialog)
+{
+ /* Access private structure */
+ HildonNamePasswordDialogPrivate *priv =
+ HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Size group for captions */
+ GtkSizeGroup *group =
+ GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
+ HildonCaption *caption;
+
+ /* Initialize dialog */
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+ gtk_window_set_title(GTK_WINDOW(dialog), _(HILDON_NAME_PASSWORD_DIALOG_TITLE));
+
+ /* Optional domain name label */
+ priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
+
+ /* Create buttons */
+ priv->okButton =
+ GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
+ _(HILDON_NAME_PASSWORD_DIALOG_OK),
+ GTK_RESPONSE_OK));
+ priv->closeButton =
+ GTK_BUTTON(gtk_dialog_add_button(GTK_DIALOG(dialog),
+ _(HILDON_NAME_PASSWORD_DIALOG_CANCEL),
+ GTK_RESPONSE_CANCEL));
+
+ /* Setup user name entry */
+ priv->nameEntry = GTK_ENTRY(gtk_entry_new());
+ g_object_set (priv->nameEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
+ gtk_entry_set_visibility(GTK_ENTRY(priv->nameEntry), FALSE);
+ caption = HILDON_CAPTION(hildon_caption_new
+ (group,
+ _(HILDON_NAME_PASSWORD_DIALOG_NAME ),
+ GTK_WIDGET(priv->nameEntry), NULL,
+ HILDON_CAPTION_OPTIONAL));
+ hildon_caption_set_separator(caption, "");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(caption), FALSE, FALSE, 0);
+
+ /* Setup password entry */
+ priv->passwordEntry = GTK_ENTRY(gtk_entry_new());
+ g_object_set (priv->passwordEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
+ gtk_entry_set_visibility(GTK_ENTRY(priv->passwordEntry), FALSE);
+ caption =
+ HILDON_CAPTION(hildon_caption_new(group,
+ _(HILDON_NAME_PASSWORD_DIALOG_PASSWORD),
+ GTK_WIDGET(priv->passwordEntry),
+ NULL,
+ HILDON_CAPTION_OPTIONAL));
+ hildon_caption_set_separator(caption, "");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(caption), FALSE, FALSE, 0);
+
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ /* Ensure group is freed when all its contents have been removed */
+ g_object_unref(group);
+}
+
+GType hildon_name_password_dialog_get_type(void)
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonNamePasswordDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_name_password_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonNamePasswordDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_name_password_dialog_init
+ };
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonNamePasswordDialog",
+ &dialog_info, 0);
+ }
+
+ return dialog_type;
+}
+
+/**
+ * hildon_name_password_dialog_new:
+ * @parent: the parent window of the dialog
+ *
+ * Creates a new #HildonNamePasswordDialog widget with Ok and Close
+ * buttons.
+ *
+ * Returns: the newly created #HildonNamePasswordDialog
+ */
+GtkWidget *hildon_name_password_dialog_new(GtkWindow * parent)
+{
+ GtkWidget *self = g_object_new(HILDON_TYPE_NAME_PASSWORD_DIALOG,NULL);
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(self), parent);
+
+ return self;
+}
+
+/**
+ * hildon_name_password_dialog_new_with_default:
+ * @parent: the parent window of the dialog
+ * @name: default username, NULL if unset
+ * @password: default password, NULL if unset
+ *
+ * Same as #hildon_name_password_dialog_new, but with a
+ * default name and password.
+ *
+ * Returns: the newly created #HildonNamePasswordDialog
+ */
+GtkWidget *hildon_name_password_dialog_new_with_default(GtkWindow *parent,
+ const gchar *name,
+ const gchar *password)
+{
+ GtkWidget *self = hildon_name_password_dialog_new(parent);
+
+ if(name != NULL)
+ g_object_set(G_OBJECT(self), "username", name, NULL);
+ if(password != NULL)
+ g_object_set(G_OBJECT(self), "password", password, NULL);
+
+ return self;
+}
+
+/**
+ * hildon_name_password_dialog_get_name:
+ * @dialog: the dialog
+ *
+ * Gets the text that's in the name entry.
+ *
+ * Returns: a pointer to the name string.
+ */
+const gchar *hildon_name_password_dialog_get_name(HildonNamePasswordDialog
+ * dialog)
+{
+ HildonNamePasswordDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog), NULL);
+
+ priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ return gtk_entry_get_text(priv->nameEntry);
+}
+
+/**
+ * hildon_name_password_dialog_get_password:
+ * @dialog: the dialog
+ *
+ * Gets the text that's in the password entry.
+ *
+ * Returns: a pointer to the password string
+ */
+const gchar *hildon_name_password_dialog_get_password(HildonNamePasswordDialog
+ * dialog)
+{
+ HildonNamePasswordDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog), NULL);
+
+ priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ return gtk_entry_get_text(priv->passwordEntry);
+}
+
+/**
+ * hildon_name_password_dialog_set_domain(GtkWidget *dialog,
+ * @dialog: the dialog
+ * @domain: the domain or some other descriptive text to be set
+ *
+ * sets the optional descriptive text
+ */
+
+void hildon_name_password_dialog_set_domain(HildonNamePasswordDialog *dialog,
+ const gchar *domain)
+{
+ HildonNamePasswordDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_NAME_PASSWORD_DIALOG(dialog));
+
+ priv = HILDON_NAME_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ gtk_label_set_text(priv->domainLabel, domain);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_NAME_PASSWORD_DIALOG_H__
+#define __HILDON_NAME_PASSWORD_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_NAME_PASSWORD_DIALOG \
+ ( hildon_name_password_dialog_get_type() )
+#define HILDON_NAME_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_NAME_PASSWORD_DIALOG,\
+ HildonNamePasswordDialog))
+#define HILDON_NAME_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NAME_PASSWORD_DIALOG, \
+ HildonNamePasswordDialogClass))
+#define HILDON_IS_NAME_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_NAME_PASSWORD_DIALOG))
+#define HILDON_IS_NAME_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NAME_PASSWORD_DIALOG))
+
+#define HILDON_NAME_PASSWORD_DIALOG_TITLE "frw_ti_get_user_name_and_pwd"
+#define HILDON_NAME_PASSWORD_DIALOG_NAME \
+ "frw_ti_get_user_name_and_pwd_enter_user_name"
+#define HILDON_NAME_PASSWORD_DIALOG_PASSWORD \
+ "frw_ti_get_user_name_and_pwd_enter_pwd"
+#define HILDON_NAME_PASSWORD_DIALOG_OK "frw_bd_get_user_name_and_pwd_ok"
+#define HILDON_NAME_PASSWORD_DIALOG_CANCEL \
+ "frw_bd_get_user_name_and_pwd_cancel"
+
+
+typedef struct _HildonNamePasswordDialog HildonNamePasswordDialog;
+typedef struct _HildonNamePasswordDialogClass
+ HildonNamePasswordDialogClass;
+
+struct _HildonNamePasswordDialog {
+ GtkDialog parent;
+};
+
+struct _HildonNamePasswordDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_name_password_dialog_get_type(void) G_GNUC_CONST;
+
+GtkWidget *hildon_name_password_dialog_new(GtkWindow * parent);
+
+GtkWidget *hildon_name_password_dialog_new_with_default(GtkWindow *parent,
+ const gchar *name,
+ const gchar *pass);
+
+
+const gchar *hildon_name_password_dialog_get_name(HildonNamePasswordDialog
+ * dialog);
+
+const gchar *hildon_name_password_dialog_get_password(HildonNamePasswordDialog
+ * dialog);
+
+void hildon_name_password_dialog_set_domain(HildonNamePasswordDialog *dialog,
+ const gchar *domain);
+
+G_END_DECLS
+#endif /* __HILDON_NAME_PASSWORD_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-note
+ * @short_description: A widget to ask confirmation from the user
+ *
+ * Notes are used to for confirmation (OK/Cancel/etc.) from the user.
+ * A simple note contains an information text and an OK button to be
+ * pressed. Additional features such as progress bars or animation can
+ * also be included.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "hildon-note.h"
+#include <gtk/gtklabel.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
+#include <libintl.h>
+#include <hildon-widgets/hildon-defines.h>
+#include <hildon-widgets/hildon-system-sound.h>
+#include <hildon-widgets/hildon-banner.h> /* for _hildon_gtk_label_set_text_n_lines */
+
+#include <stdio.h>
+#include <string.h>
+
+/* FIXME: Can these be included from somewhere? */
+#define CONFIRMATION_SOUND_PATH "/usr/share/sounds/ui-confirmation_note.wav"
+#define INFORMATION_SOUND_PATH "/usr/share/sounds/ui-information_note.wav"
+#define HILDON_NOTE_CONFIRMATION_ICON "qgn_note_confirm"
+#define HILDON_NOTE_INFORMATION_ICON "qgn_note_info"
+
+#define _(String) dgettext(PACKAGE, String)
+
+static GtkDialogClass *parent_class;
+
+#define HILDON_NOTE_GET_PRIVATE(obj)\
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_NOTE, HildonNotePrivate));
+
+typedef struct _HildonNotePrivate HildonNotePrivate;
+
+static void hildon_note_class_init(HildonNoteClass * class);
+static void hildon_note_init(HildonNote * dialog);
+
+static void hildon_note_rebuild(HildonNote *note);
+static void hildon_note_finalize(GObject * obj_self);
+static void hildon_note_realize (GtkWidget *widget);
+
+static void hildon_note_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_note_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static gboolean
+sound_handling(GtkWidget * widget, GdkEventExpose *event, gpointer data);
+
+struct _HildonNotePrivate {
+ GtkWidget *okButton;
+ GtkWidget *cancelButton;
+ GtkWidget *label;
+ GtkWidget *box;
+ GtkWidget *icon;
+
+ HildonNoteType note_n;
+ GtkWidget *progressbar;
+ gulong sound_signal_handler;
+
+ gchar *original_description;
+};
+
+enum {
+ PROP_NONE = 0,
+ PROP_HILDON_NOTE_TYPE,
+ PROP_HILDON_NOTE_DESCRIPTION,
+ PROP_HILDON_NOTE_ICON,
+ PROP_HILDON_NOTE_PROGRESSBAR,
+ PROP_HILDON_NOTE_STOCK_ICON
+};
+
+static void
+hildon_note_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonNote *note = HILDON_NOTE(object);
+ HildonNotePrivate *priv;
+ GtkWidget *widget;
+
+ priv = HILDON_NOTE_GET_PRIVATE(note);
+
+ switch (prop_id) {
+ case PROP_HILDON_NOTE_TYPE:
+ priv->note_n = g_value_get_enum(value);
+ hildon_note_rebuild(note);
+ break;
+ case PROP_HILDON_NOTE_DESCRIPTION:
+ g_free(priv->original_description);
+ priv->original_description = g_value_dup_string(value);
+
+ _hildon_gtk_label_set_text_n_lines(GTK_LABEL(priv->label),
+ priv->original_description,
+ priv->note_n == HILDON_NOTE_PROGRESSBAR_TYPE ? 1 : 5);
+
+ break;
+ case PROP_HILDON_NOTE_ICON:
+ gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
+ g_value_get_string(value), HILDON_ICON_SIZE_BIG_NOTE);
+ break;
+ case PROP_HILDON_NOTE_STOCK_ICON:
+ gtk_image_set_from_stock(GTK_IMAGE(priv->icon),
+ g_value_get_string(value), HILDON_ICON_SIZE_BIG_NOTE);
+ break;
+ case PROP_HILDON_NOTE_PROGRESSBAR:
+ widget = g_value_get_object(value);
+ if (widget != priv->progressbar)
+ {
+ if (priv->progressbar)
+ g_object_unref(priv->progressbar);
+
+ priv->progressbar = widget;
+
+ if (widget)
+ {
+ g_object_ref(widget);
+ gtk_object_sink(GTK_OBJECT(widget));
+ }
+
+ hildon_note_rebuild(note);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_note_get_property(GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ HildonNote *note = HILDON_NOTE(object);
+ HildonNotePrivate *priv;
+
+ priv = HILDON_NOTE_GET_PRIVATE(note);
+
+ switch (prop_id) {
+ case PROP_HILDON_NOTE_TYPE:
+ g_value_set_enum(value, priv->note_n);
+ break;
+ case PROP_HILDON_NOTE_DESCRIPTION:
+ g_value_set_string(value, priv->original_description);
+ break;
+ case PROP_HILDON_NOTE_ICON:
+ g_object_get_property(G_OBJECT(priv->icon), "icon-name", value);
+ break;
+ case PROP_HILDON_NOTE_STOCK_ICON:
+ g_object_get_property(G_OBJECT(priv->icon), "stock", value);
+ break;
+ case PROP_HILDON_NOTE_PROGRESSBAR:
+ g_value_set_object(value, priv->progressbar);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+GType hildon_note_type_get_type (void)
+{
+ static GType notetype = 0;
+ if (notetype == 0) {
+ static const GEnumValue values[] = {
+ { HILDON_NOTE_CONFIRMATION_TYPE, "HILDON_NOTE_CONFIRMATION_TYPE", "confirmation" },
+ { HILDON_NOTE_CONFIRMATION_BUTTON_TYPE, "HILDON_NOTE_CONFIRMATION_BUTTON_TYPE", "confirmation-button" },
+ { HILDON_NOTE_INFORMATION_TYPE, "HILDON_NOTE_INFORMATION_TYPE", "note-information" },
+ { HILDON_NOTE_INFORMATION_THEME_TYPE, "HILDON_NOTE_INFORMATION_THEME_TYPE", "note-information-theme" },
+ { HILDON_NOTE_PROGRESSBAR_TYPE, "HILDON_NOTE_PROGRESSBAR_TYPE", "note-progressbar" },
+ { 0, NULL, NULL }
+ };
+ notetype = g_enum_register_static ("HildonNoteType", values);
+ }
+ return notetype;
+}
+
+
+GType hildon_note_get_type()
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonNoteClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_note_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonNote),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_note_init
+ };
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonNote",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+static void hildon_note_class_init(HildonNoteClass * class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class);
+
+ /* set the global parent_class */
+ parent_class = g_type_class_peek_parent(class);
+
+ g_type_class_add_private(class, sizeof(HildonNotePrivate));
+
+ object_class->finalize = hildon_note_finalize;
+ object_class->set_property = hildon_note_set_property;
+ object_class->get_property = hildon_note_get_property;
+ widget_class->realize = hildon_note_realize;
+
+ g_object_class_install_property(object_class,
+ PROP_HILDON_NOTE_TYPE,
+ g_param_spec_enum("note_type",
+ "note type",
+ "The type of the note dialog",
+ hildon_note_type_get_type(),
+ HILDON_NOTE_CONFIRMATION_TYPE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+ /**
+ * HildonNote:description:
+ *
+ * Description for note.
+ */
+ g_object_class_install_property(object_class,
+ PROP_HILDON_NOTE_DESCRIPTION,
+ g_param_spec_string("description",
+ "note description",
+ "The text that appears in the note dialog",
+ "",
+ G_PARAM_READWRITE));
+
+ /**
+ * HildonNote:icon:
+ *
+ * Icon for note.
+ */
+ g_object_class_install_property(object_class,
+ PROP_HILDON_NOTE_ICON,
+ g_param_spec_string("icon",
+ "note icon",
+ "The name of the icon that appears in the note dialog",
+ "",
+ G_PARAM_READWRITE));
+
+ /**
+ * HildonNote:stock-icon:
+ *
+ * Stock icon for note.
+ */
+ g_object_class_install_property(object_class,
+ PROP_HILDON_NOTE_STOCK_ICON,
+ g_param_spec_string("stock-icon",
+ "Stock note icon",
+ "The stock name of the icon that appears in the note dialog",
+ "",
+ G_PARAM_READWRITE));
+
+ /**
+ * HildonNote:progressbar:
+ *
+ * Progressbar for note.
+ */
+ g_object_class_install_property(object_class,
+ PROP_HILDON_NOTE_PROGRESSBAR,
+ g_param_spec_object("progressbar",
+ "Progressbar widget",
+ "The progressbar that appears in the note dialog",
+ GTK_TYPE_PROGRESS_BAR,
+ G_PARAM_READWRITE));
+}
+
+static void hildon_note_init(HildonNote * dialog)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(dialog);
+
+ priv->label = gtk_label_new(NULL);
+ priv->icon = gtk_image_new();
+
+ /* Acquire real references to our internal children, since
+ they are not nessecarily packed into container in each
+ layout */
+ g_object_ref(priv->label);
+ g_object_ref(priv->icon);
+ gtk_object_sink(GTK_OBJECT(priv->label));
+ gtk_object_sink(GTK_OBJECT(priv->icon));
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+}
+
+
+static void hildon_note_finalize(GObject * obj_self)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(obj_self);
+
+ /* Free internal data */
+ g_object_unref(priv->label);
+ g_object_unref(priv->icon);
+ if (priv->progressbar)
+ g_object_unref(priv->progressbar);
+
+ g_free(priv->original_description);
+
+ G_OBJECT_CLASS(parent_class)->finalize(obj_self);
+}
+
+static void
+hildon_note_realize (GtkWidget *widget)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(widget);
+
+ /* Make widget->window accessible */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ /* Border only, no titlebar */
+ gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER);
+
+ /* Because ESD is synchronous, we wish to play sound after the
+ note is already on screen to avoid blocking its appearance */
+ if (priv->sound_signal_handler == 0)
+ priv->sound_signal_handler = g_signal_connect_after(widget,
+ "expose-event", G_CALLBACK(sound_handling), NULL);
+}
+
+/* Helper function for removing a widget from it's container.
+ we own a separate reference to each object we try to unpack,
+ so extra referencing is not needed. */
+static void unpack_widget(GtkWidget *widget)
+{
+ g_assert(widget == NULL || GTK_IS_WIDGET(widget));
+
+ if (widget && widget->parent)
+ gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
+}
+
+static void
+hildon_note_rebuild(HildonNote *note)
+{
+ GtkDialog *dialog;
+ HildonNotePrivate *priv;
+ gboolean IsHorizontal = TRUE;
+
+ g_assert(HILDON_IS_NOTE(note));
+
+ priv = HILDON_NOTE_GET_PRIVATE (note);
+ dialog = GTK_DIALOG(note);
+
+ /* Reuse exiting content widgets for new layout */
+ unpack_widget(priv->label);
+ unpack_widget(priv->icon);
+ unpack_widget(priv->progressbar);
+
+ /* Destroy old layout and buttons */
+ if (priv->box) {
+ gtk_widget_destroy(priv->box);
+ priv->box = NULL;
+ }
+ if (priv->okButton) {
+ gtk_widget_destroy(priv->okButton);
+ priv->okButton = NULL;
+ }
+ if (priv->cancelButton) {
+ gtk_widget_destroy(priv->cancelButton);
+ priv->cancelButton = NULL;
+ }
+
+ /* Add needed buttons and images for each note type */
+ switch (priv->note_n)
+ {
+ case HILDON_NOTE_CONFIRMATION_TYPE:
+ priv->okButton = gtk_dialog_add_button(dialog,
+ _("ecdg_bd_confirmation_note_ok"), GTK_RESPONSE_OK);
+ priv->cancelButton = gtk_dialog_add_button(dialog,
+ _("ecdg_bd_confirmation_note_cancel"), GTK_RESPONSE_CANCEL);
+
+ /* Fall through */
+ case HILDON_NOTE_CONFIRMATION_BUTTON_TYPE:
+ gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
+ HILDON_NOTE_CONFIRMATION_ICON,
+ HILDON_ICON_SIZE_BIG_NOTE);
+ break;
+
+ case HILDON_NOTE_INFORMATION_THEME_TYPE:
+ case HILDON_NOTE_INFORMATION_TYPE:
+ /* Add clickable OK button (cancel really,
+ but doesn't matter since this is info) */
+ priv->cancelButton = gtk_dialog_add_button(dialog,
+ _("ecdg_bd_information_note_ok"), GTK_RESPONSE_CANCEL);
+ gtk_image_set_from_icon_name(GTK_IMAGE(priv->icon),
+ HILDON_NOTE_INFORMATION_ICON,
+ HILDON_ICON_SIZE_BIG_NOTE);
+ break;
+
+ case HILDON_NOTE_PROGRESSBAR_TYPE:
+ priv->cancelButton = gtk_dialog_add_button(dialog,
+ _("ecdg_bd_cancel_note_cancel"), GTK_RESPONSE_CANCEL);
+ IsHorizontal = FALSE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (IsHorizontal) {
+ /* Pack item with label horizontally */
+ priv->box = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
+ gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
+
+ if (priv->icon) {
+ GtkWidget *alignment = gtk_alignment_new(0, 0, 0, 0);
+
+ gtk_box_pack_start(GTK_BOX(priv->box), alignment, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(alignment), priv->icon);
+ }
+ gtk_box_pack_start(GTK_BOX(priv->box), priv->label, TRUE, TRUE, 0);
+
+ } else {
+ /* Pack item with label vertically */
+ priv->box = gtk_vbox_new(FALSE, HILDON_MARGIN_DOUBLE);
+ gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
+ gtk_box_pack_start(GTK_BOX(priv->box), priv->label, TRUE, TRUE, 0);
+
+ if (priv->progressbar)
+ gtk_box_pack_start(GTK_BOX(priv->box), priv->progressbar, FALSE, FALSE, 0);
+ }
+
+ gtk_widget_show_all(priv->box);
+}
+
+/**
+ * hildon_note_new_confirmation_add_buttons:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly.
+ * In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @Varargs: arguments pairs for new buttons(label and return value).
+ * Terminate the list with %NULL value.
+ *
+ * Create a new confirmation note with custom buttons. Confirmation
+ * note has a text and any number of buttons. It's important to note
+ * that even though the name of the function might suggest, the
+ * default ok/cancel buttons are not appended but you have to provide
+ * all of the buttons.
+ *
+ * FIXME: This doc seems to be wrong, the two buttons aren't added so
+ * it would only contain the "additional" buttons? However, changing
+ * this would break those applications that rely on current behaviour.
+ *
+ * Returns: A #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_confirmation_add_buttons(GtkWindow *parent,
+ const gchar *description,
+ ...)
+{
+ va_list args;
+ char *message;
+ int value;
+
+ g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
+
+ GtkWidget *conf_note =
+ g_object_new(HILDON_TYPE_NOTE,
+ "note_type", HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
+ "description", description,
+ "icon", HILDON_NOTE_CONFIRMATION_ICON,
+ NULL);
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(conf_note), parent);
+
+ /* Add the buttons from varargs */
+ va_start(args, description);
+
+ while (TRUE) {
+ message = va_arg(args, char *);
+
+ if (!message) {
+ break;
+ }
+ value = va_arg(args, int);
+
+ gtk_dialog_add_button(GTK_DIALOG(conf_note), message, value);
+ }
+
+ va_end(args);
+
+ return conf_note;
+}
+
+
+/**
+ * hildon_note_new_confirmation:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ *
+ * Create a new confirmation note. Confirmation note has text (description)
+ * that you specify, two buttons and a default confirmation stock icon.
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_confirmation(GtkWindow * parent,
+ const gchar * description)
+{
+ return hildon_note_new_confirmation_with_icon_name
+ (parent, description, HILDON_NOTE_CONFIRMATION_ICON);
+}
+
+
+/**
+ * hildon_note_new_confirmation_with_icon_stock:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @stock_id: icon to be displayed. If NULL, default icon is used.
+ *
+ * Create a new confirmation note. Confirmation note has text (description)
+ * that you specify, two buttons and an icon.
+ *
+ * Deprecated: this function is broken, and really should not be used by anyone!
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_confirmation_with_icon_stock(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ stock_id)
+{
+ GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
+ "note_type",
+ HILDON_NOTE_CONFIRMATION_TYPE,
+ "description", description, "stock-icon",
+ stock_id, NULL);
+
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return dialog;
+}
+
+/**
+ * hildon_note_new_confirmation_with_icon_name:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @icon_name: icon to be displayed. If NULL, default icon is used.
+ *
+ * Create a new confirmation note. Confirmation note has text(description)
+ * that you specify, two buttons and an icon.
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_confirmation_with_icon_name(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ icon_name)
+{
+ GtkWidget *dialog = NULL;
+
+ g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
+
+ dialog = g_object_new(HILDON_TYPE_NOTE,
+ "note_type",
+ HILDON_NOTE_CONFIRMATION_TYPE,
+ "description", description, "icon",
+ icon_name, NULL);
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return dialog;
+}
+
+/**
+ * hildon_note_new_information:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ *
+ * Create a new information note. Information note has a text(description)
+ * that you specify, an OK button and an icon.
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_information(GtkWindow * parent,
+ const gchar * description)
+{
+ return hildon_note_new_information_with_icon_name
+ (parent, description, HILDON_NOTE_INFORMATION_ICON);
+}
+
+/**
+ * hildon_note_new_information_with_icon_stock:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @stock_id: icon to be displayed. If NULL, default icon is used.
+ *
+ * Create a new information note. Information note has text(description)
+ * that you specify, an OK button and a default stock note icon.
+ *
+ * Note! This function is broken and deprecated and should not be
+ * used by anybody. Since the platform doesn't use stock icons,
+ * use #hildon_note_new_information_with_icon_name instead.
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_information_with_icon_stock(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ stock_id)
+{
+ GtkWidget *dialog = NULL;
+
+ g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
+
+ dialog = g_object_new(HILDON_TYPE_NOTE,
+ "note_type",
+ HILDON_NOTE_INFORMATION_TYPE,
+ "description", description,
+ "icon", stock_id, NULL);
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return dialog;
+}
+
+/**
+ * hildon_note_new_information_with_icon_name:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @icon_name: icon to be displayed. If NULL, default icon is used.
+ *
+ * Create a new information note. Information note has text(description)
+ * that you specify, an OK button and an icon.
+ *
+ * Returns: a #GtkWidget pointer of the note
+ */
+GtkWidget *hildon_note_new_information_with_icon_name(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ icon_name)
+{
+ GtkWidget *dialog = NULL;
+
+ g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
+
+ dialog = g_object_new(HILDON_TYPE_NOTE,
+ "note_type",
+ HILDON_NOTE_INFORMATION_THEME_TYPE,
+ "description", description,
+ "icon", icon_name, NULL);
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return dialog;
+}
+
+/**
+ * hildon_note_new_information_with_icon_theme:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the message to confirm
+ * @icon: #GtkIconTheme icon to be displayed
+ *
+ * This function is deprecated. Use
+ * #hildon_note_new_information_with_icon_name instead.
+ *
+ * Create a new information note. Information note has text(description)
+ * that you specify, an OK button and an icon.
+ *
+ * Returns: a #GtkWidget pointer of the note.
+ */
+GtkWidget *hildon_note_new_information_with_icon_theme(GtkWindow *parent,
+ const gchar *description,
+ const gchar *icon)
+{
+ return hildon_note_new_information_with_icon_name(parent, description, icon);
+}
+
+/**
+ * hildon_note_new_cancel_with_progress_bar:
+ * @parent: the parent window. The X window ID of the parent window
+ * has to be the same as the X window ID of the application. This is
+ * important so that the window manager could handle the windows
+ * correctly. In GTK the X window ID can be checked using
+ * GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
+ * @description: the action to cancel
+ * @progressbar: a pointer to #GtkProgressBar to be filled with the
+ * progressbar assigned to this note. Use this to set the fraction of
+ * progressbar done. This parameter can be %NULL as well, in which
+ * case plain text cancel note appears.
+ *
+ * Create a new cancel note with a progress bar. Cancel note has
+ * text(description) that you specify, a Cancel button and a progress bar.
+ *
+ * Returns: a #GtkDialog. Use this to get rid of this note when you
+ * no longer need it.
+ */
+GtkWidget *hildon_note_new_cancel_with_progress_bar(GtkWindow * parent,
+ const gchar *
+ description,
+ GtkProgressBar *
+ progressbar)
+{
+ GtkWidget *dialog = NULL;
+
+ g_return_val_if_fail(parent == NULL || GTK_IS_WINDOW(parent), NULL);
+
+ dialog = g_object_new(HILDON_TYPE_NOTE,
+ "note_type",
+ HILDON_NOTE_PROGRESSBAR_TYPE,
+ "description", description,
+ "progressbar",
+ progressbar, NULL);
+ if (parent != NULL)
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+
+ return dialog;
+}
+
+
+/**
+ * hildon_note_set_button_text:
+ * @note: a #HildonNote
+ * @text: sets the button text and if there is two buttons in dialog,
+ * the button texts will be <text>, "Cancel".
+ *
+ * Sets the button text to be used by the hildon_note widget.
+ */
+void hildon_note_set_button_text(HildonNote * note, const gchar * text)
+{
+ HildonNotePrivate *priv;
+
+ g_return_if_fail(HILDON_IS_NOTE(note));
+
+ priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
+ if (priv->okButton) {
+ gtk_button_set_label(GTK_BUTTON(priv->okButton), text);
+ gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
+ _("ecdg_bd_confirmation_note_cancel"));
+ } else {
+ gtk_button_set_label(GTK_BUTTON(priv->cancelButton), text);
+ }
+}
+
+/**
+ * hildon_note_set_button_texts:
+ * @note: a #HildonNote
+ * @textOk: the new text of the default OK button
+ * @textCancel: the new text of the default cancel button
+ *
+ * Sets the button texts to be used by this hildon_note widget.
+ */
+void hildon_note_set_button_texts(HildonNote * note,
+ const gchar * textOk,
+ const gchar * textCancel)
+{
+ HildonNotePrivate *priv;
+
+ g_return_if_fail(HILDON_IS_NOTE(note));
+
+ priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
+ if (priv->okButton) {
+ gtk_button_set_label(GTK_BUTTON(priv->okButton), textOk);
+ gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
+ textCancel);
+ } else {
+ gtk_button_set_label(GTK_BUTTON(priv->cancelButton), textCancel);
+ }
+}
+
+/* We play a system sound when the note comes visible */
+static gboolean
+sound_handling(GtkWidget * widget, GdkEventExpose *event, gpointer data)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(widget);
+ g_signal_handler_disconnect(widget, priv->sound_signal_handler);
+ priv->sound_signal_handler = 0;
+
+ switch (priv->note_n)
+ {
+ case HILDON_NOTE_INFORMATION_TYPE:
+ case HILDON_NOTE_INFORMATION_THEME_TYPE:
+ hildon_play_system_sound(INFORMATION_SOUND_PATH);
+ break;
+ case HILDON_NOTE_CONFIRMATION_TYPE:
+ case HILDON_NOTE_CONFIRMATION_BUTTON_TYPE:
+ hildon_play_system_sound(CONFIRMATION_SOUND_PATH);
+ break;
+ default:
+ break;
+ };
+
+ return FALSE;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_NOTE_H__
+#define __HILDON_NOTE_H__
+
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkprogressbar.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_NOTE ( hildon_note_get_type() )
+#define HILDON_NOTE(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_NOTE, HildonNote))
+#define HILDON_NOTE_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NOTE, HildonNoteClass))
+#define HILDON_IS_NOTE(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_NOTE))
+#define HILDON_IS_NOTE_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NOTE))
+
+typedef struct _HildonNote HildonNote;
+typedef struct _HildonNoteClass HildonNoteClass;
+
+typedef enum /*< skip >*/
+{
+ HILDON_NOTE_CONFIRMATION_TYPE = 0,
+ HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
+ HILDON_NOTE_INFORMATION_TYPE,
+ HILDON_NOTE_INFORMATION_THEME_TYPE,
+ HILDON_NOTE_PROGRESSBAR_TYPE
+} HildonNoteType;
+
+struct _HildonNote {
+ GtkDialog parent;
+};
+
+struct _HildonNoteClass {
+ GtkDialogClass parent_class;
+};
+
+GtkWidget *hildon_note_new_confirmation(GtkWindow * parent,
+ const gchar * description);
+
+GtkWidget *hildon_note_new_confirmation_add_buttons(GtkWindow * parent,
+ const gchar *
+ description, ...);
+#ifndef HILDON_DISABLE_DEPRECATED
+GtkWidget *hildon_note_new_confirmation_with_icon_stock(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ stock_id);
+#endif /* HILDON_DISABLE_DEPRECATED */
+
+GtkWidget *hildon_note_new_confirmation_with_icon_name(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ icon_name);
+
+
+GtkWidget *hildon_note_new_cancel_with_progress_bar(GtkWindow * parent,
+ const gchar *
+ description,
+ GtkProgressBar *
+ progressbar);
+
+GtkWidget *hildon_note_new_information(GtkWindow * parent,
+ const gchar * description);
+
+GtkWidget *hildon_note_new_information_with_icon_name(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ icon_name);
+#ifndef HILDON_DISABLE_DEPRECATED
+GtkWidget *hildon_note_new_information_with_icon_stock(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ stock_id);
+
+GtkWidget *hildon_note_new_information_with_icon_theme(GtkWindow * parent,
+ const gchar *
+ description,
+ const gchar *
+ icon);
+#endif /* HILDON_DISABLE_DEPRECATED */
+
+void hildon_note_set_button_text(HildonNote * note, const gchar * text);
+
+void hildon_note_set_button_texts(HildonNote * note, const gchar * textOk,
+ const gchar * textCancel);
+
+GType hildon_note_get_type(void) G_GNUC_CONST;
+GType hildon_note_type_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+#endif /* __HILDON_NOTE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-number-editor
+ * @short_description: A widget used to enter a number within a pre-defined range
+ *
+ * HildonNumberEditor is used to enter a number from a specific range.
+ * There are two buttons to scroll the value in number field.
+ * Manual input is also possible.
+ */
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "hildon-number-editor.h"
+#include "hildon-marshalers.h"
+#include <hildon-widgets/gtk-infoprint.h>
+#include "hildon-composite-widget.h"
+#include <hildon-widgets/hildon-input-mode-hint.h>
+#include <hildon-widgets/hildon-defines.h>
+#include "hildon-libs-enum-types.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+
+/*Pixel spec defines*/
+#define NUMBER_EDITOR_HEIGHT 30
+
+/* Size of plus and minus buttons */
+#define BUTTON_HEIGHT 30
+#define BUTTON_WIDTH 30
+
+#define HILDON_NUMBER_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_NUMBER_EDITOR, \
+ HildonNumberEditorPrivate));
+
+typedef struct _HildonNumberEditorPrivate HildonNumberEditorPrivate;
+
+static void
+hildon_number_editor_class_init (HildonNumberEditorClass *editor_class);
+
+static void
+hildon_number_editor_init (HildonNumberEditor *editor);
+
+static gboolean
+hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
+ gpointer data);
+
+static void
+hildon_number_editor_entry_changed (GtkWidget *widget, gpointer data);
+
+static void
+hildon_number_editor_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+
+static void
+set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
+ const GtkAllocation *allocation);
+
+static void
+hildon_number_editor_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+static gboolean
+hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
+ gpointer data);
+
+static gboolean
+hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
+ gpointer data);
+
+static gboolean
+hildon_number_editor_entry_button_released (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+static gboolean
+hildon_number_editor_button_released (GtkWidget *widget,
+ GdkEvent *event,
+ HildonNumberEditor *editor);
+static gboolean
+do_mouse_timeout (HildonNumberEditor *editor);
+
+static void
+change_numbers (HildonNumberEditor *editor, gint update);
+
+static void
+hildon_number_editor_forall (GtkContainer *container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data);
+
+static void
+hildon_number_editor_destroy (GtkObject *self);
+
+static gboolean
+hildon_number_editor_start_timer (HildonNumberEditor *editor);
+
+static void
+hildon_number_editor_finalize (GObject *self);
+
+static gboolean
+hildon_number_editor_range_error(HildonNumberEditor *editor,
+ HildonNumberEditorErrorType type);
+
+static gboolean
+hildon_number_editor_select_all (HildonNumberEditorPrivate *priv);
+
+static void
+hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate);
+
+static void hildon_number_editor_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+
+static void hildon_number_editor_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+/* Signal indices */
+enum
+{
+ RANGE_ERROR,
+ LAST_SIGNAL
+};
+
+/* Property indices */
+enum {
+ PROP_0,
+ PROP_VALUE
+};
+
+static GtkContainerClass *parent_class;
+
+static guint HildonNumberEditor_signal[LAST_SIGNAL] = {0};
+
+struct _HildonNumberEditorPrivate
+{
+ /* Child widgets */
+ GtkWidget *num_entry;
+ GtkWidget *plus;
+ GtkWidget *minus;
+
+ gint start; /* Minimum */
+ gint end; /* Maximum */
+ gint default_val;
+ gint button_type; /* Type of button pressed: 1 = plus, -1 = minus */
+
+ /* Timer IDs */
+ guint button_event_id; /* Repeat change when button is held */
+ guint select_all_idle_id; /* Selection repaint hack
+ see hildon_number_editor_select_all */
+};
+
+
+GType hildon_number_editor_get_type(void)
+{
+ static GType editor_type = 0;
+
+ if (!editor_type)
+ {
+ static const GTypeInfo editor_info =
+ {
+ sizeof(HildonNumberEditorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_number_editor_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonNumberEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_number_editor_init,
+ };
+ editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonNumberEditor",
+ &editor_info, 0);
+ }
+ return editor_type;
+}
+
+static void
+hildon_number_editor_class_init(HildonNumberEditorClass * editor_class)
+{
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
+
+ g_type_class_add_private(editor_class,
+ sizeof(HildonNumberEditorPrivate));
+
+ parent_class = g_type_class_peek_parent(editor_class);
+
+ widget_class->size_request = hildon_number_editor_size_request;
+ widget_class->size_allocate = hildon_number_editor_size_allocate;
+ widget_class->focus = hildon_composite_widget_focus;
+
+ editor_class->range_error = hildon_number_editor_range_error;
+
+ /* Because we derived our widget from GtkContainer, we should override
+ forall method */
+ container_class->forall = hildon_number_editor_forall;
+ GTK_OBJECT_CLASS(editor_class)->destroy = hildon_number_editor_destroy;
+ gobject_class->finalize = hildon_number_editor_finalize;
+ gobject_class->set_property = hildon_number_editor_set_property;
+ gobject_class->get_property = hildon_number_editor_get_property;
+
+ g_object_class_install_property(gobject_class, PROP_VALUE,
+ g_param_spec_int("value",
+ "Value",
+ "The current value of number editor",
+ G_MININT,
+ G_MAXINT,
+ 0, G_PARAM_READWRITE));
+
+ HildonNumberEditor_signal[RANGE_ERROR] =
+ g_signal_new("range_error", HILDON_TYPE_NUMBER_EDITOR,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET
+ (HildonNumberEditorClass, range_error),
+ g_signal_accumulator_true_handled, NULL,
+ _hildon_marshal_BOOLEAN__ENUM,
+ G_TYPE_BOOLEAN, 1, HILDON_TYPE_NUMBER_EDITOR_ERROR_TYPE);
+}
+
+static void
+hildon_number_editor_forall(GtkContainer *container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonNumberEditorPrivate *priv =
+ HILDON_NUMBER_EDITOR_GET_PRIVATE(container);
+
+ g_assert(callback != NULL);
+
+ if (!include_internals)
+ return;
+
+ /* Enumerate child widgets */
+ (*callback) (priv->minus, callback_data);
+ (*callback) (priv->num_entry, callback_data);
+ (*callback) (priv->plus, callback_data);
+}
+
+static void
+hildon_number_editor_destroy(GtkObject *self)
+{
+ HildonNumberEditorPrivate *priv;
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
+
+ /* Free child widgets */
+ if (priv->minus)
+ {
+ gtk_widget_unparent(priv->minus);
+ priv->minus = NULL;
+ }
+ if (priv->num_entry)
+ {
+ gtk_widget_unparent(priv->num_entry);
+ priv->num_entry = NULL;
+ }
+ if (priv->plus)
+ {
+ gtk_widget_unparent(priv->plus);
+ priv->plus = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+static void
+hildon_number_editor_stop_repeat_timer(HildonNumberEditorPrivate *priv)
+{
+ if (priv->button_event_id)
+ {
+ g_source_remove(priv->button_event_id);
+ priv->button_event_id = 0;
+ }
+}
+
+static void
+hildon_number_editor_finalize (GObject *self)
+{
+ HildonNumberEditorPrivate *priv;
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(self);
+
+ /* Free timers */
+ hildon_number_editor_stop_repeat_timer(priv);
+
+ if (priv->select_all_idle_id)
+ g_source_remove (priv->select_all_idle_id);
+
+ /* Call parent class finalize, if have one */
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize(self);
+}
+
+static void
+hildon_number_editor_init (HildonNumberEditor *editor)
+{
+ HildonNumberEditorPrivate *priv;
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ GTK_WIDGET_SET_FLAGS(GTK_WIDGET(editor), GTK_NO_WINDOW);
+
+ /* Create child widgets */
+ priv->num_entry = gtk_entry_new();
+ priv->minus = gtk_button_new();
+ priv->plus = gtk_button_new();
+
+ gtk_widget_set_name( priv->minus, "ne-minus-button" );
+ gtk_widget_set_name( priv->plus, "ne-plus-button" );
+ gtk_widget_set_size_request( priv->minus, BUTTON_WIDTH, BUTTON_HEIGHT );
+ gtk_widget_set_size_request( priv->plus, BUTTON_WIDTH, BUTTON_HEIGHT );
+ gtk_entry_set_alignment (GTK_ENTRY(priv->num_entry), 1);
+
+ GTK_WIDGET_UNSET_FLAGS( priv->minus, GTK_CAN_FOCUS );
+ GTK_WIDGET_UNSET_FLAGS( priv->plus, GTK_CAN_FOCUS );
+
+ priv->button_event_id = 0;
+ priv->select_all_idle_id = 0;
+
+ gtk_widget_set_parent(priv->minus, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->num_entry, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->plus, GTK_WIDGET(editor));
+
+ /* Connect child widget signals */
+ g_signal_connect(GTK_OBJECT(priv->num_entry), "changed",
+ G_CALLBACK(hildon_number_editor_entry_changed),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->num_entry), "focus-out-event",
+ G_CALLBACK(hildon_number_editor_entry_focusout),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->num_entry), "key-press-event",
+ G_CALLBACK(hildon_number_editor_entry_keypress),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->num_entry), "button-release-event",
+ G_CALLBACK(hildon_number_editor_entry_button_released),
+ NULL);
+
+ g_signal_connect(GTK_OBJECT(priv->minus), "button-press-event",
+ G_CALLBACK(hildon_number_editor_button_pressed),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->plus), "button-press-event",
+ G_CALLBACK(hildon_number_editor_button_pressed),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->minus), "button-release-event",
+ G_CALLBACK(hildon_number_editor_button_released),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->plus), "button-release-event",
+ G_CALLBACK(hildon_number_editor_button_released),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->minus), "leave-notify-event",
+ G_CALLBACK(hildon_number_editor_button_released),
+ editor);
+
+ g_signal_connect(GTK_OBJECT(priv->plus), "leave-notify-event",
+ G_CALLBACK(hildon_number_editor_button_released),
+ editor);
+
+ g_object_set( G_OBJECT(priv->num_entry),
+ "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
+
+ gtk_widget_show(priv->num_entry);
+ gtk_widget_show(priv->minus);
+ gtk_widget_show(priv->plus);
+
+ hildon_number_editor_set_range(editor, G_MININT, G_MAXINT);
+}
+
+static gboolean
+hildon_number_editor_entry_button_released (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+ return FALSE;
+}
+
+static gboolean
+hildon_number_editor_button_released (GtkWidget *widget, GdkEvent *event,
+ HildonNumberEditor *editor)
+{
+ HildonNumberEditorPrivate *priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ hildon_number_editor_stop_repeat_timer(priv);
+ return FALSE;
+}
+
+/* Format given number to editor field, no checks performed, all signals
+ are sent normally. */
+static void
+hildon_number_editor_real_set_value (HildonNumberEditorPrivate *priv, gint value)
+{
+ gchar buffer[32];
+
+ /* Update text in entry to new value */
+ g_snprintf(buffer, sizeof(buffer), "%d", value);
+ gtk_entry_set_text(GTK_ENTRY(priv->num_entry), buffer);
+}
+
+static gboolean
+hildon_number_editor_button_pressed (GtkWidget *widget, GdkEventButton *event,
+ gpointer data)
+{
+ /* FIXME: XXX Why aren't we using hildon_number_editor_start_timer here? XXX */
+ /* Need to fetch current value from entry and increment or decrement
+ it */
+ HildonNumberEditor *editor;
+ HildonNumberEditorPrivate *priv;
+ GtkSettings *settings;
+ guint timeout;
+
+ g_assert(HILDON_IS_NUMBER_EDITOR(data));
+
+ editor = HILDON_NUMBER_EDITOR(data);
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ settings = gtk_settings_get_default();
+ g_object_get(settings, "gtk-initial-timeout", &timeout, NULL);
+
+ /* Save type of button pressed */
+ if (GTK_BUTTON(widget) == GTK_BUTTON(priv->plus))
+ priv->button_type = 1;
+ else
+ priv->button_type = -1;
+
+ /* Start repetition timer */
+ if (!priv->button_event_id)
+ {
+ do_mouse_timeout(editor);
+ priv->button_event_id = g_timeout_add (timeout,
+ (GSourceFunc) hildon_number_editor_start_timer,
+ editor);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+hildon_number_editor_start_timer (HildonNumberEditor *editor)
+{
+ HildonNumberEditorPrivate *priv;
+ GtkSettings *settings;
+ guint timeout;
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ settings = gtk_settings_get_default();
+ g_object_get(settings, "gtk-update-timeout", &timeout, NULL);
+
+ priv->button_event_id = g_timeout_add(timeout,
+ (GSourceFunc) do_mouse_timeout,
+ editor);
+ return FALSE;
+}
+
+static gboolean
+do_mouse_timeout (HildonNumberEditor *editor)
+{
+ HildonNumberEditorPrivate *priv;
+
+ GDK_THREADS_ENTER ();
+
+ g_assert(HILDON_IS_NUMBER_EDITOR(editor));
+
+ /* Update value based on button held */
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ change_numbers(editor, priv->button_type);
+
+ GDK_THREADS_LEAVE ();
+
+ return TRUE;
+}
+
+/* Changes the current number value by the amount of update
+ and verifies the result. */
+static void
+change_numbers (HildonNumberEditor *editor, gint update)
+{
+ HildonNumberEditorPrivate *priv;
+ gint current_value;
+
+ g_assert(HILDON_IS_NUMBER_EDITOR(editor));
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ current_value = hildon_number_editor_get_value(editor);
+
+ /* We need to rerun validation by hand, since validation
+ done in "changed" callback allows intermediate values */
+ hildon_number_editor_real_set_value(priv, current_value + update);
+ hildon_number_editor_validate_value(editor, FALSE);
+ g_object_notify (G_OBJECT(editor), "value");
+}
+
+static void
+add_select_all_idle (HildonNumberEditorPrivate *priv)
+{
+ if (!priv->select_all_idle_id)
+ {
+ priv->select_all_idle_id =
+ g_idle_add((GSourceFunc) hildon_number_editor_select_all, priv);
+ }
+}
+
+static void
+hildon_number_editor_validate_value(HildonNumberEditor *editor, gboolean allow_intermediate)
+{
+ HildonNumberEditorPrivate *priv;
+ gint error_code, fixup_value;
+ const gchar *text;
+ long value;
+ gchar *tail;
+ gboolean r;
+
+ g_assert(HILDON_IS_NUMBER_EDITOR(editor));
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ text = gtk_entry_get_text(GTK_ENTRY(priv->num_entry));
+ error_code = -1;
+ fixup_value = priv->default_val;
+
+ if (text && text[0])
+ {
+ /* Try to convert entry text to number */
+ value = strtol(text, &tail, 10);
+
+ /* Check if conversion succeeded */
+ if (tail[0] == 0)
+ {
+ /* Check if value is in allowed range. This is tricky in those
+ cases when user is editing a value.
+ For example: Range = [100, 500] and user have just inputted "4".
+ This should not lead into error message. Otherwise value is
+ resetted back to "100" and next "4" press will reset it back
+ and so on. */
+ if (allow_intermediate)
+ {
+ /* We now have the following error cases:
+ * If inputted value as above maximum and
+ maximum is either positive or then maximum
+ negative and value is positive.
+ * If inputted value is below minimum and minimum
+ is negative or minumum positive and value
+ negative or zero.
+ In all other cases situation can be fixed just by
+ adding new numbers to the string.
+ */
+ if (value > priv->end && (priv->end >= 0 || (priv->end < 0 && value >= 0)))
+ {
+ error_code = MAXIMUM_VALUE_EXCEED;
+ fixup_value = priv->end;
+ }
+ else if (value < priv->start && (priv->start < 0 || (priv->start >= 0 && value <= 0)))
+ {
+ error_code = MINIMUM_VALUE_EXCEED;
+ fixup_value = priv->start;
+ }
+ }
+ else
+ {
+ if (value > priv->end) {
+ error_code = MAXIMUM_VALUE_EXCEED;
+ fixup_value = priv->end;
+ }
+ else if (value < priv->start) {
+ error_code = MINIMUM_VALUE_EXCEED;
+ fixup_value = priv->start;
+ }
+ }
+ }
+ /* The only valid case when conversion can fail is when we
+ have plain '-', intermediate forms are allowed AND
+ minimum bound is negative */
+ else if (!allow_intermediate || strcmp(text, "-") != 0 || priv->start >= 0)
+ error_code = ERRONEOUS_VALUE;
+ }
+ else if (!allow_intermediate)
+ error_code = ERRONEOUS_VALUE;
+
+ if (error_code != -1)
+ {
+ /* If entry is empty and intermediate forms are nor allowed,
+ emit error signal */
+ /* Change to default value */
+ hildon_number_editor_set_value(editor, fixup_value);
+ g_signal_emit(editor, HildonNumberEditor_signal[RANGE_ERROR],
+ 0, error_code, &r);
+ add_select_all_idle(priv);
+ }
+}
+
+static void
+hildon_number_editor_entry_changed(GtkWidget *widget, gpointer data)
+{
+ g_assert(HILDON_IS_NUMBER_EDITOR(data));
+ hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), TRUE);
+ g_object_notify (G_OBJECT(data), "value");
+}
+
+static void
+hildon_number_editor_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ HildonNumberEditor *editor;
+ HildonNumberEditorPrivate *priv;
+ GtkRequisition req;
+
+ editor = HILDON_NUMBER_EDITOR(widget);
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+
+ /* Requested size is size of all child widgets plus border space */
+ gtk_widget_size_request(priv->minus, &req);
+ requisition->width = req.width;
+
+ gtk_widget_size_request(priv->num_entry, &req);
+ requisition->width += req.width;
+
+ gtk_widget_size_request(priv->plus, &req);
+ requisition->width += req.width;
+
+ requisition->width += HILDON_MARGIN_DEFAULT * 2;
+
+ /* FIXME: XXX Height is fixed */
+ requisition->height = NUMBER_EDITOR_HEIGHT;
+}
+
+/* Update @alloc->width so widget fits, update @alloc->x to point to free space */
+static void
+set_widget_allocation (GtkWidget *widget, GtkAllocation *alloc,
+ const GtkAllocation *allocation)
+{
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_child_requisition(widget, &child_requisition);
+
+ /* Fit to widget width */
+ if (allocation->width + allocation->x >
+ alloc->x + child_requisition.width)
+ alloc->width = child_requisition.width;
+ else
+ {
+ alloc->width = allocation->width - (alloc->x - allocation->x);
+ if (alloc->width < 0)
+ alloc->width = 0;
+ }
+
+ gtk_widget_size_allocate(widget, alloc);
+ /* Update x position */
+ alloc->x += alloc->width;
+}
+
+static void
+hildon_number_editor_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ HildonNumberEditor *editor;
+ HildonNumberEditorPrivate *priv;
+ GtkAllocation alloc;
+
+ editor = HILDON_NUMBER_EDITOR(widget);
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+
+ widget->allocation = *allocation;
+
+ /* Add upper border */
+ alloc.y = widget->allocation.y + widget->style->ythickness;
+
+ /* Fix height */
+ if (widget->allocation.height > NUMBER_EDITOR_HEIGHT)
+ {
+ alloc.height = NUMBER_EDITOR_HEIGHT - widget->style->ythickness * 2;
+ alloc.y += (widget->allocation.height - NUMBER_EDITOR_HEIGHT) / 2;
+ }
+ else
+ alloc.height = widget->allocation.height - widget->style->ythickness * 2;
+
+ if (alloc.height < 0)
+ alloc.height = 0;
+
+ /* Add left border */
+ alloc.x = allocation->x + widget->style->xthickness;
+
+ /* Allocate positions for widgets (left-to-right) */
+ set_widget_allocation(priv->minus, &alloc, &widget->allocation);
+ alloc.x += HILDON_MARGIN_DEFAULT;
+
+ set_widget_allocation(priv->num_entry, &alloc, &widget->allocation);
+ alloc.x += HILDON_MARGIN_DEFAULT;
+
+ set_widget_allocation(priv->plus, &alloc, &widget->allocation);
+}
+
+static gboolean
+hildon_number_editor_entry_focusout (GtkWidget *widget, GdkEventFocus *event,
+ gpointer data)
+{
+ g_assert(HILDON_IS_NUMBER_EDITOR(data));
+ hildon_number_editor_validate_value(HILDON_NUMBER_EDITOR(data), FALSE);
+ return FALSE;
+}
+
+static gboolean
+hildon_number_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
+ gpointer data)
+{
+ GtkEditable *editable;
+ gint cursor_pos;
+
+ g_assert(HILDON_IS_NUMBER_EDITOR(data));
+
+ editable = GTK_EDITABLE(widget);
+ cursor_pos = gtk_editable_get_position(editable);
+
+ switch (event->keyval)
+ {
+ case GDK_Left:
+ /* If the cursor is on the left, try to decrement */
+ if (cursor_pos == 0) {
+ change_numbers(HILDON_NUMBER_EDITOR(data), -1);
+ return TRUE;
+ }
+ break;
+
+ case GDK_Right:
+ /* If the cursor is on the right, try to increment */
+ if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1))
+ {
+ change_numbers(HILDON_NUMBER_EDITOR(data), 1);
+ gtk_editable_set_position(editable, cursor_pos);
+ return TRUE;
+ }
+ break;
+
+ default:
+ break;
+ };
+
+ return FALSE;
+}
+
+static gboolean
+hildon_number_editor_range_error(HildonNumberEditor *editor,
+ HildonNumberEditorErrorType type)
+{
+
+ gint min, max;
+ gchar *err_msg = NULL;
+ HildonNumberEditorPrivate *priv;
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ min = priv->start;
+ max = priv->end;
+
+ /* Construct error message */
+ switch (type)
+ {
+ case MAXIMUM_VALUE_EXCEED:
+ err_msg = g_strdup_printf(_("ckct_ib_maximum_value"), max, max);
+ break;
+ case MINIMUM_VALUE_EXCEED:
+ err_msg = g_strdup_printf(_("ckct_ib_minimum_value"), min, min);
+ break;
+ case ERRONEOUS_VALUE:
+ err_msg =
+ g_strdup_printf(_("ckct_ib_set_a_value_within_range"), min, max);
+ break;
+ }
+
+ /* Infoprint error */
+ if (err_msg)
+ {
+ gtk_infoprint(GTK_WINDOW(gtk_widget_get_ancestor(GTK_WIDGET(editor),
+ GTK_TYPE_WINDOW)), err_msg);
+ g_free(err_msg);
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * hildon_number_editor_new:
+ * @min: minimum accepted value
+ * @max: maximum accepted value
+ *
+ * Creates new number editor
+ *
+ * Returns: a new #HildonNumberEditor widget
+ */
+GtkWidget *
+hildon_number_editor_new (gint min, gint max)
+{
+ HildonNumberEditor *editor =
+ g_object_new(HILDON_TYPE_NUMBER_EDITOR, NULL);
+
+ /* Set user inputted range to editor */
+ hildon_number_editor_set_range(editor, min, max);
+
+ return GTK_WIDGET(editor);
+}
+
+/**
+ * hildon_number_editor_set_range:
+ * @editor: a #HildonNumberEditor widget
+ * @min: minimum accepted value
+ * @max: maximum accepted value
+ *
+ * Sets accepted number range for editor
+ */
+void
+hildon_number_editor_set_range (HildonNumberEditor *editor, gint min, gint max)
+{
+ HildonNumberEditorPrivate *priv;
+ gchar buffer_min[32], buffer_max[32];
+ gint a, b;
+
+ g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+
+ /* Set preferences */
+ priv->start = MIN(min, max);
+ priv->end = MAX(min, max);
+
+ /* Find maximum allowed length of value */
+ g_snprintf(buffer_min, sizeof(buffer_min), "%d", min);
+ g_snprintf(buffer_max, sizeof(buffer_max), "%d", max);
+ a = strlen(buffer_min);
+ b = strlen(buffer_max);
+
+ /* Set maximum size of entry */
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->num_entry), MAX(a, b));
+ hildon_number_editor_set_value(editor, priv->start);
+}
+
+/**
+ * hildon_number_editor_get_value:
+ * @editor: pointer to #HildonNumberEditor
+ *
+ * Returns: current NumberEditor value
+ */
+gint
+hildon_number_editor_get_value (HildonNumberEditor *editor)
+{
+ HildonNumberEditorPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_NUMBER_EDITOR(editor), 0);
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+ return atoi(gtk_entry_get_text(GTK_ENTRY(priv->num_entry)));
+}
+
+/**
+ * hildon_number_editor_set_value:
+ * @editor: pointer to #HildonNumberEditor
+ * @value: numeric value for number editor
+ *
+ * Sets numeric value for number editor
+ */
+void
+hildon_number_editor_set_value (HildonNumberEditor *editor, gint value)
+{
+ HildonNumberEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_NUMBER_EDITOR(editor));
+
+ priv = HILDON_NUMBER_EDITOR_GET_PRIVATE(editor);
+
+ g_return_if_fail(value <= priv->end);
+ g_return_if_fail(value >= priv->start);
+
+ priv->default_val = value;
+ hildon_number_editor_real_set_value(priv, value);
+ g_object_notify (G_OBJECT(editor), "value");
+}
+
+/* When calling gtk_entry_set_text, the entry widget does things that can
+ * cause the whole widget to redraw. This redrawing is delayed and if any
+ * selections are made right after calling the gtk_entry_set_text the
+ * setting of the selection might seem to have no effect.
+ *
+ * If the selection is delayed with a lower priority than the redrawing,
+ * the selection should stick. Calling this function with g_idle_add should
+ * do it.
+ */
+static gboolean
+hildon_number_editor_select_all (HildonNumberEditorPrivate *priv)
+{
+ GDK_THREADS_ENTER ();
+ gtk_editable_select_region(GTK_EDITABLE(priv->num_entry), 0, -1);
+ priv->select_all_idle_id = 0;
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
+
+static void
+hildon_number_editor_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonNumberEditor *editor;
+
+ editor = HILDON_NUMBER_EDITOR(object);
+
+ switch (prop_id) {
+ case PROP_VALUE:
+ hildon_number_editor_set_value(editor, g_value_get_int(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_number_editor_get_property(GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ HildonNumberEditor *editor;
+
+ editor = HILDON_NUMBER_EDITOR(object);
+
+ switch (prop_id) {
+ case PROP_VALUE:
+ g_value_set_int(value, hildon_number_editor_get_value(editor));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_NUMBER_EDITOR_H__
+#define __HILDON_NUMBER_EDITOR_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+
+
+
+#define HILDON_TYPE_NUMBER_EDITOR ( hildon_number_editor_get_type() )
+
+#define HILDON_NUMBER_EDITOR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_NUMBER_EDITOR, HildonNumberEditor))
+#define HILDON_NUMBER_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_NUMBER_EDITOR, HildonNumberEditorClass))
+#define HILDON_IS_NUMBER_EDITOR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_NUMBER_EDITOR))
+#define HILDON_IS_NUMBER_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_NUMBER_EDITOR))
+
+typedef struct _HildonNumberEditor HildonNumberEditor;
+typedef struct _HildonNumberEditorClass HildonNumberEditorClass;
+
+
+struct _HildonNumberEditor
+{
+ GtkContainer parent;
+};
+
+
+typedef enum
+{
+ MAXIMUM_VALUE_EXCEED,
+ MINIMUM_VALUE_EXCEED,
+ ERRONEOUS_VALUE
+
+} HildonNumberEditorErrorType;
+
+
+struct _HildonNumberEditorClass
+{
+ GtkContainerClass parent_class;
+
+ gboolean (*range_error) (HildonNumberEditor *editor, HildonNumberEditorErrorType type);
+};
+
+
+GType hildon_number_editor_get_type (void) G_GNUC_CONST;
+
+GtkWidget* hildon_number_editor_new (gint min, gint max);
+
+void hildon_number_editor_set_range (HildonNumberEditor *editor,
+ gint min,
+ gint max);
+
+gint hildon_number_editor_get_value (HildonNumberEditor *editor);
+void hildon_number_editor_set_value (HildonNumberEditor *editor, gint value);
+
+
+G_END_DECLS
+#endif /* __HILDON_NUMBER_EDITOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-plugin-widget
+ * @short_description: A simple interface to load plugin based widgets. Not
+ * compatible with GObject.
+ *
+ * #HildonPluginWidgetInfo is a struct containing information about loaded
+ * module which contains code for a widget.
+ */
+
+
+#include <stdio.h>
+#include <memory.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+
+#include "hildon-plugin-widget.h"
+
+
+#ifndef PLUGIN_DIR
+#define PLUGIN_DIR "/usr/lib/hildon-widgets"
+#endif
+
+
+struct HildonPluginWidgetInfo_ {
+ GType base_type;
+
+ gchar *filename;
+
+ GModule *module;
+ int refcount;
+
+ GType (*get_type) ();
+};
+
+
+static gchar *hildon_plugin_filename(GType base_type, const gchar *name);
+
+ /* WARNING: works properly only with ASCII */
+static gchar *ascii_decapitalize_without_dashes(gchar *source);
+
+static gchar *hildon_plugin_default_name(gchar *typename);
+
+/**
+ * hildon_plugin_info_initialize:
+ * @base_type: a #GType representing parent type of object that will be
+ * loaded.
+ * @name: Name of child. To load default (or #GtkSettings defined), NULL
+ * should be passed as name. To load specific child type, decapitalized name
+ * should be passed here.
+ *
+ * Creates a new #HildonPluginWidgetInfo structure and opens a module.
+ *
+ * The naming of child widgets (or objects) doesn't matter, but for plugins
+ * the file names should be type
+ * <decapitalized-parent-type-name-with-dashes>-<pluginname>.so where the
+ * decapitalized type name would be for example for #GtkWidget gtk-widget.
+ *
+ * The name comes from name argument or from #GtkSettings where the variable
+ * storing it is with name <ParentTypeName>-plugin, for #GtkWidget this would
+ * be "GtkWidget-plugin". If nothing is defined in #GtkSettings, name
+ * "default" is assumed. For this case there should be symlink to some child
+ * type plugin named <parent-type-name>-default.so
+ *
+ * Returns: a #HildonPluginWidgetInfo struct pointer upon success, NULL if
+ * failed.
+ */
+HildonPluginWidgetInfo *hildon_plugin_info_initialize(GType base_type, const gchar *name)
+{
+ HildonPluginWidgetInfo *ret;
+ GModule *module;
+ gchar *filename;
+
+
+ if(!base_type) {
+ return NULL;
+ }
+
+
+ filename = hildon_plugin_filename(base_type, name);
+ g_return_val_if_fail (filename != NULL, NULL);
+
+
+ module = g_module_open(filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+ if(!module) {
+ g_warning ("Failed to load plugin for '%s' (filename: '%s')", name, filename);
+ g_free(filename);
+ return NULL;
+ }
+
+
+ ret = (HildonPluginWidgetInfo *)g_malloc0(sizeof(HildonPluginWidgetInfo) + strlen(filename) + 1);
+ ret->filename = (gchar *)ret + sizeof(HildonPluginWidgetInfo);
+
+ ret->base_type = base_type;
+
+ ret->module = module;
+
+ g_module_symbol(module, "export_type", (void **)&ret->get_type);
+
+ memcpy(ret->filename, filename, strlen(filename));
+
+
+ g_free(filename);
+
+
+ return ret;
+}
+
+/**
+ * hildon_plugin_info_construct_widget:
+ * @info: pointer to a #HildonPluginWidgetInfo struct.
+ *
+ * Creates instance of loaded type from module stored in
+ * #HildonPluginWidgetInfo struct. Designed for loading types inherited from
+ * GtkWidget, but could be basically any GTK+ type.
+ *
+ * Returns: a GtkWidget pointer to instance of loaded type.
+ */
+GtkWidget *hildon_plugin_info_construct_widget(HildonPluginWidgetInfo *info)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+ info->refcount++;
+
+
+ return GTK_WIDGET(g_type_create_instance(info->get_type()));
+}
+
+/**
+ * hildon_plugin_info_kill:
+ * @info: a pointer to a #HildonPluginWidgetInfo struct that should be
+ * destroyed.
+ *
+ * Frees the plugin information structure and unloads the module.
+ */
+void hildon_plugin_info_kill(HildonPluginWidgetInfo *info)
+{
+ if(!info) {
+ return;
+ }
+
+
+ g_module_close(info->module);
+
+
+ g_free(info);
+}
+
+
+static gchar *hildon_plugin_filename(GType base_type, const gchar *name)
+{
+ gchar *ret, *name2, *plgbuf;
+ gchar *typename = (gchar *)g_type_name(base_type);
+ int retsize;
+
+
+ plgbuf = ascii_decapitalize_without_dashes(typename);
+
+
+ if(name) {
+ name2 = g_strdup(name);
+ } else {
+ name2 = hildon_plugin_default_name(typename);
+ }
+
+
+ retsize = strlen(PLUGIN_DIR) + strlen(plgbuf) + strlen(name2) + 6;
+ ret = (gchar *)g_malloc0(retsize);
+ g_snprintf(ret, retsize, "%s/%s_%s.so", PLUGIN_DIR, plgbuf, name2);
+
+
+ g_free(name2);
+ g_free(plgbuf);
+
+
+ return ret;
+}
+
+ /* possible speedup: pre-allocate more memory and ditch the first loop */
+static gchar *ascii_decapitalize_without_dashes(gchar *source)
+{
+ gchar *ptr, *ret = g_strdup (source);
+
+
+ for(ptr = ret; *ptr; ptr++) {
+ if(*ptr >= 'A' && *ptr <= 'Z') {
+ *ptr += 0x20;
+ }
+ }
+
+
+ return ret;
+}
+
+
+static gchar *hildon_plugin_default_name(gchar *typename)
+{
+ GtkSettings *settings;
+ gchar *ret, *val, *tmp;
+ int tmplen;
+
+
+ tmplen = strlen(typename) + strlen("-plugin") + 1;
+ tmp = (gchar *)g_malloc0(tmplen);
+ g_snprintf(tmp, tmplen, "%s-plugin", typename);
+
+
+ gtk_settings_install_property(g_param_spec_string(tmp,
+ tmp,
+ "Plugin for this pecific widget",
+ NULL,
+ G_PARAM_READWRITE));
+
+ settings = gtk_settings_get_default();
+
+ g_object_get(G_OBJECT(settings), tmp, &val, NULL);
+
+ g_free(tmp);
+
+
+ if(val) {
+ ret = (gchar *)g_malloc0(strlen(val)+1);
+ memcpy(ret, val, strlen(val));
+ g_free(val);
+ } else {
+ ret = (gchar *)g_malloc0(strlen("default")+1);
+
+
+ g_snprintf(ret, strlen("default")+1, "default");
+ }
+
+
+ return ret;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Author: Kuisma Salonen <kuisma.salonen@nokia.com>
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_PLUGIN_WIDGET_H__
+#define __HILDON_PLUGIN_WIDGET_H__
+
+
+#include <glib-object.h>
+
+#include <gtk/gtkwidget.h>
+
+
+/**
+ * HildonPluginWidgetInfo:
+ *
+ * Contains information about the loaded module which has some widget
+ * inherited from some non-plugin widget. The struct should be considered
+ * private and should not be used directly.
+ */
+typedef struct HildonPluginWidgetInfo_ HildonPluginWidgetInfo;
+
+
+HildonPluginWidgetInfo *hildon_plugin_info_initialize(GType base_type, const gchar *name);
+
+
+GtkWidget *hildon_plugin_info_construct_widget(HildonPluginWidgetInfo *info);
+
+
+void hildon_plugin_info_kill(HildonPluginWidgetInfo *info);
+
+
+
+#endif /* __HILDON_PLUGIN_WIDGET_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_PRIVATE_H__
+#define __HILDON_PRIVATE_H__
+
+#include <gtk/gtklabel.h>
+
+G_BEGIN_DECLS
+
+void
+_hildon_time_editor_get_time_separators(GtkLabel *hm_sep_label,
+ GtkLabel *ms_sep_label);
+
+G_END_DECLS
+#endif /* __HILDON_PRIVATE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file hildon-program.c
+ *
+ * This file implements the HildonProgram object
+ *
+ */
+
+#include "hildon-program.h"
+#include "hildon-window-private.h"
+
+/*FIXME*/
+#include <X11/Xatom.h>
+
+
+#define HILDON_PROGRAM_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_TYPE_PROGRAM, HildonProgramPriv));
+
+
+typedef struct _HildonProgramPriv HildonProgramPriv;
+
+struct _HildonProgramPriv
+{
+ gboolean killable;
+ gboolean is_topmost;
+ GdkWindow *group_leader;
+ guint window_count;
+ GtkWidget *common_menu;
+ GtkWidget *common_toolbar;
+ GSList *windows;
+ Window window_group;
+ gchar *name;
+};
+
+static void
+hildon_program_init (HildonProgram *self);
+
+static void
+hildon_program_finalize (GObject *self);
+
+static void
+hildon_program_class_init (HildonProgramClass *self);
+
+static void
+hildon_program_get_property(GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+static void
+hildon_program_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+
+enum
+{
+ PROP_0,
+ PROP_IS_TOPMOST,
+ PROP_KILLABLE
+};
+
+
+GType
+hildon_program_get_type (void)
+{
+ static GType program_type = 0;
+
+ if (!program_type)
+ {
+ static const GTypeInfo program_info =
+ {
+ sizeof(HildonProgramClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_program_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonProgram),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_program_init,
+ };
+ program_type = g_type_register_static(G_TYPE_OBJECT,
+ "HildonProgram", &program_info, 0);
+ }
+ return program_type;
+}
+
+static void
+hildon_program_init (HildonProgram *self)
+{
+ HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ priv->killable = FALSE;
+ priv->window_count = 0;
+ priv->is_topmost = FALSE;
+ priv->window_group = GDK_WINDOW_XID (gdk_display_get_default_group
+ (gdk_display_get_default()));
+ priv->common_toolbar = NULL;
+ priv->name = NULL;
+}
+
+static void
+hildon_program_finalize (GObject *self)
+{
+ HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (HILDON_PROGRAM (self));
+
+ if (priv->common_toolbar)
+ {
+ g_object_unref (priv->common_toolbar);
+ priv->common_toolbar = NULL;
+ }
+
+ if (priv->common_menu)
+ {
+ g_object_unref (priv->common_menu);
+ priv->common_menu = NULL;
+ }
+
+ g_free (priv->name);
+
+}
+
+static void
+hildon_program_class_init (HildonProgramClass *self)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(self);
+
+ g_type_class_add_private (self, sizeof(HildonProgramPriv));
+
+ /* Set up object virtual functions */
+ object_class->finalize = hildon_program_finalize;
+ object_class->set_property = hildon_program_set_property;
+ object_class->get_property = hildon_program_get_property;
+
+ /* Install properties */
+ g_object_class_install_property (object_class, PROP_IS_TOPMOST,
+ g_param_spec_boolean ("is-topmost",
+ "Is top-most",
+ "Whether one of the program's window or dialog currently "
+ "is activated by window manager",
+ FALSE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class, PROP_KILLABLE,
+ g_param_spec_boolean ("can-hibernate",
+ "Can hibernate",
+ "Whether the program should be set to hibernate by the Task "
+ "Navigator in low memory situation",
+ FALSE,
+ G_PARAM_READWRITE));
+ return;
+}
+
+
+static void
+hildon_program_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ switch (property_id){
+ case PROP_KILLABLE:
+ hildon_program_set_can_hibernate (HILDON_PROGRAM (object),
+ g_value_get_boolean (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+
+}
+
+static void
+hildon_program_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonProgramPriv *priv = HILDON_PROGRAM_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case PROP_KILLABLE:
+ g_value_set_boolean (value, priv->killable);
+ break;
+ case PROP_IS_TOPMOST:
+ g_value_set_boolean (value, priv->is_topmost);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+
+}
+
+/* Utilities */
+static gint
+hildon_program_window_list_compare (gconstpointer window_a,
+ gconstpointer window_b)
+{
+ g_return_val_if_fail (1, HILDON_IS_WINDOW(window_a) &&
+ HILDON_IS_WINDOW(window_b));
+
+ return window_a != window_b;
+}
+
+/*
+ * foreach function, checks if a window is topmost and acts consequently
+ */
+static void
+hildon_program_window_list_is_is_topmost (gpointer data, gpointer window_id_)
+{
+ if (data && HILDON_IS_WINDOW (data))
+ {
+ HildonWindow *window = HILDON_WINDOW (data);
+ Window window_id = * (Window*)window_id_;
+
+ hildon_window_update_topmost (window, window_id);
+ }
+}
+
+/*
+ * Check the _MB_CURRENT_APP_WINDOW on the root window, and update
+ * the top_most status accordingly
+ */
+static void
+hildon_program_update_top_most (HildonProgram *program)
+{
+ XWMHints *wm_hints;
+ Window active_window;
+ HildonProgramPriv *priv;
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (program);
+
+ active_window = hildon_window_get_active_window();
+
+ if (active_window)
+ {
+ wm_hints = XGetWMHints (GDK_DISPLAY (), active_window);
+
+ if (wm_hints)
+ {
+
+ if (wm_hints->window_group == priv->window_group)
+ {
+ if (!priv->is_topmost)
+ {
+ priv->is_topmost = TRUE;
+ g_object_notify (G_OBJECT (program), "is-topmost");
+ }
+ }
+ else if (priv->is_topmost)
+ {
+ priv->is_topmost = FALSE;
+ g_object_notify (G_OBJECT (program), "is-topmost");
+ }
+ }
+ XFree (wm_hints);
+ }
+
+ /* Check each window if it was is_topmost */
+ g_slist_foreach (priv->windows,
+ (GFunc)hildon_program_window_list_is_is_topmost, &active_window);
+}
+
+
+/* Event filter */
+
+/*
+ * We keep track of the _MB_CURRENT_APP_WINDOW property on the root window,
+ * to detect when a window belonging to this program was is_topmost. This
+ * is based on the window group WM hint.
+ */
+static GdkFilterReturn
+hildon_program_root_window_event_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XAnyEvent *eventti = xevent;
+ HildonProgram *program = HILDON_PROGRAM (data);
+ Atom active_app_atom =
+ XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
+
+ if (eventti->type == PropertyNotify)
+ {
+ XPropertyEvent *pevent = xevent;
+
+ if (pevent->atom == active_app_atom)
+ {
+ hildon_program_update_top_most (program);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+
+/**
+ * hildon_program_common_toolbar_topmost_window:
+ * @window: A @HildonWindow to be informed about its new common toolbar
+ * @data: Not used, it is here just to respect the API
+ *
+ * Checks if the window is the topmost window of the program and in
+ * that case forces the window to take the common toolbar.
+ **/
+static void
+hildon_program_common_toolbar_topmost_window (gpointer window, gpointer data)
+{
+ if (HILDON_IS_WINDOW (window) &&
+ hildon_window_get_is_topmost (HILDON_WINDOW (window)))
+ {
+ hildon_window_take_common_toolbar (HILDON_WINDOW (window));
+ }
+}
+
+/* Public methods */
+
+/**
+ * hildon_program_get_instance:
+ *
+ * Return value: Returns the #HildonProgram for the current process.
+ * The object is created on the first call.
+ **/
+HildonProgram *
+hildon_program_get_instance ()
+{
+ static HildonProgram *program = NULL;
+
+ if (!program)
+ {
+ program = g_object_new (HILDON_TYPE_PROGRAM, NULL);
+ }
+
+ return program;
+}
+
+/**
+ * hildon_program_add_window:
+ * @program: The @HildonProgram to which the window should be registered
+ * @window: A @HildonWindow to be added
+ *
+ * Registers a @HildonWindow as belonging to a given @HildonProgram. This
+ * allows to apply program-wide settings as all the registered windows,
+ * such as hildon_program_set_common_menu() and
+ * hildon_pogram_set_common_toolbar()
+ **/
+void
+hildon_program_add_window (HildonProgram *self, HildonWindow *window)
+{
+ HildonProgramPriv *priv;
+
+ g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ if (g_slist_find_custom (priv->windows, window,
+ hildon_program_window_list_compare) )
+ {
+ /* We already have that window */
+ return;
+ }
+
+ if (!priv->window_count)
+ {
+ hildon_program_update_top_most (self);
+
+ /* Now that we have a window we should start keeping track of
+ * the root window */
+ gdk_window_set_events (gdk_get_default_root_window (),
+ gdk_window_get_events (gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK);
+ gdk_window_add_filter (gdk_get_default_root_window (),
+ hildon_program_root_window_event_filter, self );
+ }
+
+ hildon_window_set_can_hibernate_property (window, &priv->killable);
+
+ hildon_window_set_program (window, G_OBJECT (self));
+
+ priv->windows = g_slist_append (priv->windows, window);
+ priv->window_count ++;
+}
+
+/**
+ * hildon_program_remove_window:
+ * @self: The #HildonProgram to which the window should be unregistered
+ * @window: The @HildonWindow to unregister
+ *
+ * Used to unregister a window from the program. Subsequent calls to
+ * hildon_program_set_common_menu() and hildon_pogram_set_common_toolbar()
+ * will not affect the window
+ **/
+void
+hildon_program_remove_window (HildonProgram *self, HildonWindow *window)
+{
+ HildonProgramPriv *priv;
+
+ g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ hildon_window_unset_program (window);
+
+ priv->windows = g_slist_remove (priv->windows, window);
+
+ priv->window_count --;
+
+ if (!priv->window_count)
+ {
+ gdk_window_remove_filter (gdk_get_default_root_window(),
+ hildon_program_root_window_event_filter,
+ self);
+ }
+}
+
+/**
+ * hildon_program_set_can_hibernate:
+ * @self: The #HildonProgram which can hibernate or not
+ * @can_hibernate: whether or not the #HildonProgram can hibernate
+ *
+ * Used to set whether or not the Hildon task navigator should
+ * be able to set the program to hibernation in case of low memory
+ **/
+void
+hildon_program_set_can_hibernate (HildonProgram *self, gboolean killable)
+{
+ HildonProgramPriv *priv;
+
+ g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ if (priv->killable != killable)
+ {
+ g_slist_foreach (priv->windows,
+ (GFunc)hildon_window_set_can_hibernate_property, &killable);
+ }
+
+ priv->killable = killable;
+
+}
+
+/**
+ * hildon_program_get_can_hibernate:
+ * @self: The #HildonProgram which can hibernate or not
+ *
+ * Return value: Whether or not this #HildonProgram is set to be
+ * support hibernation from the Hildon task navigator
+ **/
+gboolean
+hildon_program_get_can_hibernate (HildonProgram *self)
+{
+ HildonProgramPriv *priv;
+
+ g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ return priv->killable;
+
+}
+
+/**
+ * hildon_program_set_common_menu:
+ * @self: The #HildonProgram in which the common menu should be used
+ * @menu: A GtkMenu to use as common menu for the program
+ *
+ * Sets a GtkMenu that will appear in all the @HildonWindow registered
+ * to the #HildonProgram. Only one common GtkMenu can be set, further
+ * call will detach the previous common GtkMenu. A @HildonWindow
+ * can use it's own GtkMenu with @hildon_window_set_menu
+ **/
+void
+hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu)
+{
+ HildonProgramPriv *priv;
+
+ g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ if (priv->common_menu)
+ {
+ if (GTK_WIDGET_VISIBLE (priv->common_menu))
+ {
+ gtk_menu_popdown (GTK_MENU(priv->common_menu));
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->common_menu));
+ }
+
+ if (gtk_menu_get_attach_widget (GTK_MENU (priv->common_menu)))
+ {
+ gtk_menu_detach (GTK_MENU (priv->common_menu));
+ }
+ else
+ {
+ g_object_unref (priv->common_menu);
+ }
+ }
+
+ priv->common_menu = GTK_WIDGET (menu);
+
+ if (priv->common_menu)
+ {
+ g_object_ref (menu);
+ gtk_object_sink (GTK_OBJECT (menu));
+ gtk_widget_show_all (GTK_WIDGET (menu));
+ }
+}
+
+/**
+ * hildon_program_get_common_menu:
+ * @self: The #HildonProgram from which to retrieve the common menu
+ *
+ * Return value: the GtkMenu that was set as common menu for this
+ * #HildonProgram, or NULL of no common menu was set.
+ **/
+GtkMenu *
+hildon_program_get_common_menu (HildonProgram *self)
+{
+ HildonProgramPriv *priv;
+
+ g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ return GTK_MENU (priv->common_menu);
+}
+
+/**
+ * hildon_program_set_common_toolbar:
+ * @self: The #HildonProgram in which the common toolbar should be used
+ * @toolbar: A GtkToolbar to use as common toolbar for the program
+ *
+ * Sets a GtkToolbar that will appear in all the @HildonWindow registered
+ * to the #HildonProgram. Only one common GtkToolbar can be set, further
+ * call will detach the previous common GtkToolbar. A @HildonWindow
+ * can use its own GtkToolbar with @hildon_window_set_toolbar. Both
+ * #HildonProgram and @HildonWindow specific toolbars will be shown
+ **/
+void
+hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar)
+{
+ HildonProgramPriv *priv;
+
+ g_return_if_fail (self && HILDON_IS_PROGRAM (self));
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ if (priv->common_toolbar)
+ {
+ if (priv->common_toolbar->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (priv->common_toolbar->parent),
+ priv->common_toolbar);
+ }
+
+ g_object_unref (priv->common_toolbar);
+ }
+
+ priv->common_toolbar = GTK_WIDGET (toolbar);
+
+ if (priv->common_toolbar)
+ {
+ g_object_ref (priv->common_toolbar);
+ gtk_object_sink (GTK_OBJECT (priv->common_toolbar) );
+ }
+
+ /* if the program is the topmost we have to update the common
+ toolbar right now for the topmost window */
+ if (priv->is_topmost)
+ {
+ g_slist_foreach (priv->windows,
+ (GFunc) hildon_program_common_toolbar_topmost_window, NULL);
+ }
+}
+
+/**
+ * hildon_program_get_common_toolbar:
+ * @self: The #HildonProgram from which to retrieve the common toolbar
+ *
+ * Return value: the GtkToolbar that was set as common toolbar for this
+ * #HildonProgram, or NULL of no common menu was set.
+ **/
+GtkToolbar *
+hildon_program_get_common_toolbar (HildonProgram *self)
+{
+ HildonProgramPriv *priv;
+
+ g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), NULL);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ return priv->common_toolbar ? GTK_TOOLBAR (priv->common_toolbar) : NULL;
+}
+
+/**
+ * hildon_program_get_is_topmost:
+ * @self: A #HildonWindow
+ *
+ * Return value: Whether or not one of the program's window or dialog is
+ * currenltly activated by the window manager.
+ **/
+gboolean
+hildon_program_get_is_topmost (HildonProgram *self)
+{
+ HildonProgramPriv *priv;
+
+ g_return_val_if_fail (self && HILDON_IS_PROGRAM (self), FALSE);
+
+ priv = HILDON_PROGRAM_GET_PRIVATE (self);
+
+ return priv->is_topmost;
+}
+
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_PROGRAM_H__
+#define __HILDON_PROGRAM_H__
+
+#include<glib-object.h>
+#include"hildon-window.h"
+
+G_BEGIN_DECLS
+typedef struct _HildonProgram HildonProgram;
+typedef struct _HildonProgramClass HildonProgramClass;
+
+#define HILDON_TYPE_PROGRAM (hildon_program_get_type())
+#define HILDON_PROGRAM(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, \
+ HILDON_TYPE_PROGRAM, \
+ HildonProgram))
+#define HILDON_IS_PROGRAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, \
+ HILDON_TYPE_PROGRAM))
+
+/* deprecated */
+#define hildon_program_new hildon_program_get_instance
+
+
+
+struct _HildonProgram
+{
+ GObject parent;
+};
+
+struct _HildonProgramClass
+{
+ GObjectClass parent;
+
+ /* Padding for future extension */
+ void (*_hildon_reserved1)(void);
+ void (*_hildon_reserved2)(void);
+ void (*_hildon_reserved3)(void);
+ void (*_hildon_reserved4)(void);
+
+};
+
+GType
+hildon_program_get_type (void);
+
+/* Public methods */
+
+HildonProgram *
+hildon_program_get_instance (void);
+
+void
+hildon_program_add_window (HildonProgram *self, HildonWindow *window);
+
+void
+hildon_program_remove_window (HildonProgram *self, HildonWindow *window);
+
+void
+hildon_program_set_can_hibernate (HildonProgram *self, gboolean killable);
+
+gboolean
+hildon_program_get_can_hibernate (HildonProgram *self);
+
+void
+hildon_program_set_common_menu (HildonProgram *self, GtkMenu *menu);
+
+GtkMenu *
+hildon_program_get_common_menu (HildonProgram *self);
+
+void
+hildon_program_set_common_toolbar (HildonProgram *self, GtkToolbar *toolbar);
+
+GtkToolbar *
+hildon_program_get_common_toolbar (HildonProgram *self);
+
+gboolean
+hildon_program_get_is_topmost (HildonProgram *self);
+
+G_END_DECLS
+#endif /* __HILDON_PROGRAM_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-range-editor
+ * @short_description: A widget is used to ask bounds of a range
+ *
+ * HidlonRangeEditor allows entering a pair of integers, e.g. the lower
+ * and higher bounds of a range. A minimum and maximum can also be set
+ * for the bounds.
+ */
+
+#include <gtk/gtkbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkentry.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gprintf.h>
+#include <string.h>
+#include <stdlib.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+
+#include "hildon-range-editor.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#define _(string) dgettext(PACKAGE, string)
+
+/* Alignment in entry box ( 0 = left, 1 = right ) */
+#define DEFAULT_ALIGNMENT 1
+/* Amount of padding to add to each side of the separator */
+#define DEFAULT_PADDING 3
+
+#define DEFAULT_START -999
+#define DEFAULT_END 999
+#define DEFAULT_LENGTH 4
+
+#define HILDON_RANGE_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_RANGE_EDITOR, HildonRangeEditorPrivate));
+
+typedef struct _HildonRangeEditorPrivate HildonRangeEditorPrivate;
+
+/* Property indices */
+enum
+{
+ PROP_LOWER = 1,
+ PROP_HIGHER,
+ PROP_MIN,
+ PROP_MAX,
+ PROP_SEPARATOR
+};
+
+static GtkContainerClass *parent_class = NULL;
+
+/*Init functions*/
+static void
+hildon_range_editor_class_init (HildonRangeEditorClass *editor_class);
+static void
+hildon_range_editor_init (HildonRangeEditor *editor);
+static void
+hildon_range_editor_forall (GtkContainer *container,
+ gboolean include_internals, GtkCallback callback,
+ gpointer callback_data);
+static void
+hildon_range_editor_destroy (GtkObject *self);
+
+/*size and font functions */
+static void
+hildon_range_editor_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void
+hildon_range_editor_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean
+hildon_range_editor_entry_focus_in (GtkEditable *editable,
+ GdkEventFocus *event,
+ HildonRangeEditor *editor);
+static gboolean
+hildon_range_editor_entry_focus_out (GtkEditable *editable,
+ GdkEventFocus *event,
+ HildonRangeEditor *editor);
+static gboolean
+hildon_range_editor_entry_keypress (GtkWidget *widget, GdkEventKey *event,
+ HildonRangeEditor *editor);
+static gboolean
+hildon_range_editor_released (GtkEditable *editable, GdkEventButton *event,
+ HildonRangeEditor *editor);
+static gboolean
+hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
+ HildonRangeEditor *editor);
+
+static void hildon_range_editor_set_property( GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec );
+static void hildon_range_editor_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec );
+static void hildon_range_editor_entry_changed(GtkWidget *widget,
+ HildonRangeEditor *editor);
+
+/* Private struct */
+struct _HildonRangeEditorPrivate
+{
+ GtkWidget *start_entry; /* Entry for lower value */
+ GtkWidget *end_entry; /* Entry for higher value */
+
+ GtkWidget *label;
+
+ gint range_limits_start; /* Minimum value allowed for range start/end */
+ gint range_limits_end; /* Maximum value allowed for range start/end */
+
+ gboolean bp; /* Button pressed, don't overwrite selection */
+};
+
+/* Private functions */
+static void
+hildon_range_editor_class_init (HildonRangeEditorClass *editor_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(editor_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
+
+ parent_class = g_type_class_peek_parent(editor_class);
+
+ g_type_class_add_private(editor_class,
+ sizeof(HildonRangeEditorPrivate));
+
+ gobject_class->set_property = hildon_range_editor_set_property;
+ gobject_class->get_property = hildon_range_editor_get_property;
+ widget_class->size_request = hildon_range_editor_size_request;
+ widget_class->size_allocate = hildon_range_editor_size_allocate;
+
+ container_class->forall = hildon_range_editor_forall;
+ GTK_OBJECT_CLASS(editor_class)->destroy = hildon_range_editor_destroy;
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_int("hildon_range_editor_entry_alignment",
+ "Hildon RangeEditor entry alignment",
+ "Hildon RangeEditor entry alignment", 0, 1,
+ DEFAULT_ALIGNMENT,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property(widget_class,
+ g_param_spec_int("hildon_range_editor_separator_padding",
+ "Hildon RangeEditor separator padding",
+ "Hildon RangeEditor separaror padding",
+ G_MININT, G_MAXINT,
+ DEFAULT_PADDING,
+ G_PARAM_READABLE));
+
+ /**
+ * HildonRangeEditor:min:
+ *
+ * Minimum value in a range.
+ * Default: -999
+ */
+ g_object_class_install_property( gobject_class, PROP_MIN,
+ g_param_spec_int("min",
+ "Minimum value",
+ "Minimum value in a range",
+ G_MININT, G_MAXINT,
+ DEFAULT_START, G_PARAM_CONSTRUCT |
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonRangeEditor:max:
+ *
+ * Maximum value in a range.
+ * Default: 999
+ */
+ g_object_class_install_property( gobject_class, PROP_MAX,
+ g_param_spec_int("max",
+ "Maximum value",
+ "Maximum value in a range",
+ G_MININT, G_MAXINT,
+ DEFAULT_END, G_PARAM_CONSTRUCT |
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonRangeEditor:lower:
+ *
+ * Current value in the entry presenting lower end of selected range.
+ * Default: -999
+ */
+ g_object_class_install_property( gobject_class, PROP_LOWER,
+ g_param_spec_int("lower",
+ "Current lower value",
+ "Current value in the entry presenting lower end of selected range",
+ G_MININT, G_MAXINT,
+ DEFAULT_START, G_PARAM_CONSTRUCT |
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonRangeEditor:higher:
+ *
+ * Current value in the entry presenting higher end of selected range.
+ * Default: 999
+ */
+ g_object_class_install_property( gobject_class, PROP_HIGHER,
+ g_param_spec_int("higher",
+ "Current higher value",
+ "Current value in the entry presenting higher end of selected range",
+ G_MININT, G_MAXINT,
+ DEFAULT_END, G_PARAM_CONSTRUCT |
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonRangeEditor:separator:
+ *
+ * Separator string to separate range editor entries.
+ * Default: "-"
+ */
+ g_object_class_install_property( gobject_class, PROP_SEPARATOR,
+ g_param_spec_string("separator",
+ "Separator",
+ "Separator string to separate entries",
+ _("ckct_wi_range_separator"),
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+}
+
+static void
+hildon_range_editor_init (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+
+ gint range_editor_entry_alignment;
+ gint range_editor_separator_padding;
+
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
+
+ GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
+
+ gtk_widget_push_composite_child();
+
+ priv->start_entry = gtk_entry_new();
+ priv->end_entry = gtk_entry_new();
+ priv->label = gtk_label_new(_("ckct_wi_range_separator"));
+ priv->bp = FALSE;
+
+ /* Get values from gtkrc (or use defaults) */
+ /* FIXME: This is broken, styles are not yet attached */
+ gtk_widget_style_get(GTK_WIDGET(editor),
+ "hildon_range_editor_entry_alignment",
+ &range_editor_entry_alignment,
+ "hildon_range_editor_separator_padding",
+ &range_editor_separator_padding, NULL);
+
+ /* Add padding to separator */
+ gtk_misc_set_padding (GTK_MISC(priv->label),
+ range_editor_separator_padding, 0);
+
+ /* Align the text to right in entry box */
+ gtk_entry_set_alignment(GTK_ENTRY(priv->start_entry),
+ range_editor_entry_alignment);
+ gtk_entry_set_alignment(GTK_ENTRY(priv->end_entry),
+ range_editor_entry_alignment);
+
+ gtk_widget_set_composite_name(priv->start_entry, "start_entry");
+ gtk_widget_set_composite_name(priv->end_entry, "end_entry");
+ gtk_widget_set_composite_name(priv->label, "separator_label");
+ gtk_widget_set_parent(priv->start_entry, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->end_entry, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->label, GTK_WIDGET(editor));
+
+ g_signal_connect(G_OBJECT(priv->start_entry), "button-release-event",
+ G_CALLBACK(hildon_range_editor_released), editor);
+ g_signal_connect(G_OBJECT(priv->end_entry), "button-release-event",
+ G_CALLBACK(hildon_range_editor_released), editor);
+
+ g_signal_connect(G_OBJECT(priv->start_entry), "button-press-event",
+ G_CALLBACK(hildon_range_editor_press), editor);
+ g_signal_connect(G_OBJECT(priv->end_entry), "button-press-event",
+ G_CALLBACK(hildon_range_editor_press), editor);
+
+ g_signal_connect(G_OBJECT(priv->start_entry), "key-press-event",
+ G_CALLBACK(hildon_range_editor_entry_keypress), editor);
+ g_signal_connect(G_OBJECT(priv->end_entry), "key-press-event",
+ G_CALLBACK(hildon_range_editor_entry_keypress), editor);
+
+ g_signal_connect(G_OBJECT(priv->start_entry), "focus-in-event",
+ G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
+ g_signal_connect(G_OBJECT(priv->end_entry), "focus-in-event",
+ G_CALLBACK(hildon_range_editor_entry_focus_in), editor);
+
+ g_signal_connect(G_OBJECT(priv->start_entry), "focus-out-event",
+ G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
+ g_signal_connect(G_OBJECT(priv->end_entry), "focus-out-event",
+ G_CALLBACK(hildon_range_editor_entry_focus_out), editor);
+ g_signal_connect(priv->start_entry, "changed",
+ G_CALLBACK(hildon_range_editor_entry_changed), editor);
+ g_signal_connect(priv->end_entry, "changed",
+ G_CALLBACK(hildon_range_editor_entry_changed), editor);
+
+ g_object_set( G_OBJECT(priv->start_entry),
+ "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
+ g_object_set( G_OBJECT(priv->end_entry),
+ "input-mode", HILDON_INPUT_MODE_HINT_NUMERIC, NULL );
+
+ gtk_widget_show(priv->start_entry);
+ gtk_widget_show(priv->end_entry);
+ gtk_widget_show(priv->label);
+
+ gtk_widget_pop_composite_child();
+}
+
+static void hildon_range_editor_set_property (GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
+ switch (param_id)
+ {
+ case PROP_LOWER:
+ hildon_range_editor_set_lower (editor, g_value_get_int (value));
+ break;
+
+ case PROP_HIGHER:
+ hildon_range_editor_set_higher (editor, g_value_get_int (value));
+ break;
+
+ case PROP_MIN:
+ hildon_range_editor_set_min (editor, g_value_get_int (value));
+ break;
+
+ case PROP_MAX:
+ hildon_range_editor_set_max (editor, g_value_get_int (value));
+ break;
+
+ case PROP_SEPARATOR:
+ hildon_range_editor_set_separator (editor,
+ g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_range_editor_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec )
+{
+ HildonRangeEditor *editor = HILDON_RANGE_EDITOR(object);
+ switch (param_id)
+ {
+ case PROP_LOWER:
+ g_value_set_int (value, hildon_range_editor_get_lower (editor));
+ break;
+
+ case PROP_HIGHER:
+ g_value_set_int (value, hildon_range_editor_get_higher (editor));
+ break;
+
+ case PROP_MIN:
+ g_value_set_int (value, hildon_range_editor_get_min (editor));
+ break;
+
+ case PROP_MAX:
+ g_value_set_int (value, hildon_range_editor_get_max (editor));
+ break;
+
+ case PROP_SEPARATOR:
+ g_value_set_string (value, hildon_range_editor_get_separator (editor));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_range_editor_entry_validate(HildonRangeEditor *editor,
+ GtkWidget *edited_entry, gboolean allow_intermediate)
+{
+ HildonRangeEditorPrivate *priv;
+ const gchar *text;
+ long value;
+ gint min, max, fixup;
+ gchar *tail;
+ gchar buffer[256];
+ gboolean error = FALSE;
+
+ g_assert(HILDON_IS_RANGE_EDITOR(editor));
+ g_assert(GTK_IS_ENTRY(edited_entry));
+
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
+
+ /* Find the valid range for the modified component */
+ if (edited_entry == priv->start_entry) {
+ min = hildon_range_editor_get_min(editor);
+ max = hildon_range_editor_get_higher(editor);
+ } else {
+ min = hildon_range_editor_get_lower(editor);
+ max = hildon_range_editor_get_max(editor);
+ }
+
+ text = gtk_entry_get_text(edited_entry);
+
+ if (text && text[0])
+ {
+ /* Try to convert entry text to number */
+ value = strtol(text, &tail, 10);
+
+ /* Check if conversion succeeded */
+ if (tail[0] == 0)
+ {
+ /* Check if value is in allowed range. This is tricky in those
+ cases when user is editing a value.
+ For example: Range = [100, 500] and user have just inputted "4".
+ This should not lead into error message. Otherwise value is
+ resetted back to "100" and next "4" press will reset it back
+ and so on. */
+ if (allow_intermediate)
+ {
+ /* We now have the following error cases:
+ * If inputted value as above maximum and
+ maximum is either positive or then maximum
+ negative and value is positive.
+ * If inputted value is below minimum and minimum
+ is negative or minumum positive and value
+ negative.
+ In all other cases situation can be fixed just by
+ adding new numbers to the string.
+ */
+ if (value > max && (max >= 0 || (max < 0 && value >= 0)))
+ {
+ error = TRUE;
+ fixup = max;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
+ }
+ else if (value < min && (min < 0 || (min >= 0 && value < 0)))
+ {
+ error = TRUE;
+ fixup = min;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
+ }
+ }
+ else
+ {
+ if (value > max) {
+ error = TRUE;
+ fixup = max;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_maximum_value"), max);
+ }
+ else if (value < min) {
+ error = TRUE;
+ fixup = min;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_minimum_value"), min);
+ }
+ }
+
+ if (error) {
+ if (edited_entry == priv->start_entry)
+ hildon_range_editor_set_lower(editor, fixup);
+ else
+ hildon_range_editor_set_higher(editor, fixup);
+ }
+ }
+ /* The only valid case when conversion can fail is when we
+ have plain '-', intermediate forms are allowed AND
+ minimum bound is negative */
+ else if (!allow_intermediate || strcmp(text, "-") != 0 || min >= 0) {
+ error = TRUE;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
+ }
+ }
+ else if (!allow_intermediate) {
+ error = TRUE;
+ g_snprintf(buffer, sizeof(buffer), _("ckct_ib_set_a_value_within_range"), min, max);
+ }
+
+ if (error)
+ {
+ hildon_banner_show_information(edited_entry, NULL, buffer);
+ gtk_widget_grab_focus(edited_entry);
+ }
+}
+
+static gboolean
+hildon_range_editor_entry_focus_in (GtkEditable *editable,
+ GdkEventFocus *event,
+ HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
+ if(priv->bp)
+ {
+ priv->bp = FALSE;
+ return FALSE;
+ }
+ if (GTK_WIDGET(editable) == priv->start_entry)
+ gtk_editable_select_region(editable, -1, 0);
+ else
+ gtk_editable_select_region(editable, 0, -1);
+ return FALSE;
+}
+
+/* Gets and sets the current range. This has two usefull side effects:
+ * Values are now sorted to the correct order
+ * Out of range values are clamped to range */
+static void hildon_range_editor_apply_current_range(HildonRangeEditor *editor)
+{
+ g_assert(HILDON_IS_RANGE_EDITOR(editor));
+
+ hildon_range_editor_set_range(editor,
+ hildon_range_editor_get_lower(editor),
+ hildon_range_editor_get_higher(editor));
+}
+
+static void hildon_range_editor_entry_changed(GtkWidget *widget, HildonRangeEditor *editor)
+{
+ g_assert(HILDON_IS_RANGE_EDITOR(editor));
+ hildon_range_editor_entry_validate(editor, widget, TRUE);
+}
+
+static gboolean
+hildon_range_editor_entry_focus_out (GtkEditable *editable,
+ GdkEventFocus *event,
+ HildonRangeEditor *editor)
+{
+ g_assert(HILDON_IS_RANGE_EDITOR(editor));
+ hildon_range_editor_entry_validate(editor, GTK_WIDGET(editable), FALSE);
+ return FALSE;
+}
+
+static gboolean
+hildon_range_editor_press (GtkEditable *editable, GdkEventButton *event,
+ HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
+ priv->bp = TRUE;
+ return FALSE;
+}
+
+static void
+hildon_range_editor_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonRangeEditorPrivate *priv;
+
+ g_assert(HILDON_IS_RANGE_EDITOR(container));
+ g_assert(callback != NULL);
+
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE(container);
+
+ if (!include_internals)
+ return;
+
+ (*callback) (priv->start_entry, callback_data);
+ (*callback) (priv->end_entry, callback_data);
+ (*callback) (priv->label, callback_data);
+}
+
+static void
+hildon_range_editor_destroy(GtkObject *self)
+{
+ HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(self);
+
+ if (priv->start_entry)
+ {
+ gtk_widget_unparent(priv->start_entry);
+ priv->start_entry = NULL;
+ }
+ if (priv->end_entry)
+ {
+ gtk_widget_unparent(priv->end_entry);
+ priv->end_entry = NULL;
+ }
+ if (priv->label)
+ {
+ gtk_widget_unparent(priv->label);
+ priv->label = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+
+static void
+hildon_range_editor_size_request(GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ HildonRangeEditorPrivate *priv = NULL;
+ GtkRequisition lab_req, mreq;
+
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
+
+ gtk_entry_get_width_chars(GTK_ENTRY(priv->end_entry));
+
+ gtk_widget_size_request(priv->start_entry, &mreq);
+ gtk_widget_size_request(priv->end_entry, &mreq);
+ gtk_widget_size_request(priv->label, &lab_req);
+
+ /* Width for entries and separator label and border */
+ requisition->width = mreq.width * 2 + lab_req.width +
+ widget->style->xthickness * 2;
+ /* Add vertical border */
+ requisition->height = mreq.height + widget->style->ythickness * 2;
+ /* Fit label height */
+ requisition->height = MAX (requisition->height, lab_req.height);
+}
+
+static void
+hildon_range_editor_size_allocate(GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ HildonRangeEditorPrivate *priv;
+ GtkAllocation child1_allocation, child2_allocation, child3_allocation;
+
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE(widget);
+
+ widget->allocation = *allocation;
+
+ /* Allocate entries, left-to-right */
+ if (priv->start_entry && GTK_WIDGET_VISIBLE(priv->start_entry))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_child_requisition(priv->start_entry,
+ &child_requisition);
+
+ child1_allocation.x = allocation->x;
+ child1_allocation.y = allocation->y;
+
+ child1_allocation.width = child_requisition.width;
+ child1_allocation.height = allocation->height;
+
+ gtk_widget_size_allocate(priv->start_entry, &child1_allocation);
+ }
+
+ if (priv->label && GTK_WIDGET_VISIBLE(priv->label))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_child_requisition(priv->label, &child_requisition);
+
+ child2_allocation.x = child1_allocation.x + child1_allocation.width;
+ child2_allocation.y = allocation->y;
+ /* Add spacing */
+ child2_allocation.width = child_requisition.width + 4;
+ child2_allocation.height = allocation->height;
+
+ gtk_widget_size_allocate (priv->label, &child2_allocation);
+ }
+
+ if (priv->end_entry && GTK_WIDGET_VISIBLE(priv->end_entry))
+ {
+ GtkRequisition child_requisition;
+
+ gtk_widget_get_child_requisition (priv->end_entry, &child_requisition);
+
+ child3_allocation.x = child2_allocation.x + child2_allocation.width;
+ child3_allocation.y = allocation->y;
+
+ child3_allocation.width = child_requisition.width;
+ child3_allocation.height = allocation->height;
+
+ gtk_widget_size_allocate(priv->end_entry, &child3_allocation);
+ }
+}
+
+/* Button released inside entries */
+static gboolean
+hildon_range_editor_released(GtkEditable *editable, GdkEventButton *event,
+ HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv = HILDON_RANGE_EDITOR_GET_PRIVATE(editor);
+ if (GTK_WIDGET(editable) == priv->start_entry)
+ gtk_editable_select_region(editable, -1, 0);
+ else
+ gtk_editable_select_region(editable, 0, -1);
+ return FALSE;
+}
+
+static gboolean
+hildon_range_editor_entry_keypress(GtkWidget *widget, GdkEventKey *event,
+ HildonRangeEditor *editor)
+{
+ const gchar *text;
+ gint cursor_pos;
+
+ g_assert(HILDON_IS_RANGE_EDITOR(editor));
+
+ text = gtk_entry_get_text(GTK_ENTRY(widget));
+ cursor_pos = gtk_editable_get_position(GTK_EDITABLE(widget));
+
+ switch (event->keyval)
+ {
+ case GDK_Left:
+ /* If we are on the first character and press left,
+ try to move to previous field */
+ if (cursor_pos == 0) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_LEFT);
+ return TRUE;
+ }
+ break;
+
+ case GDK_Right:
+ /* If the cursor is on the right, try to move to the next field */
+ if (cursor_pos >= g_utf8_strlen(text, -1)) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_RIGHT);
+ return TRUE;
+ }
+ break;
+
+ default:
+ break;
+ };
+
+ return FALSE;
+}
+
+static void hildon_range_editor_refresh_widths(HildonRangeEditorPrivate *priv)
+{
+ gchar start_range[32], end_range[32];
+ gint length;
+
+ /* Calculate length of entry so extremes would fit */
+ g_snprintf(start_range, sizeof(start_range), "%d", priv->range_limits_start);
+ g_snprintf(end_range, sizeof(end_range), "%d", priv->range_limits_end);
+ length = MAX(g_utf8_strlen(start_range, -1), g_utf8_strlen(end_range, -1));
+
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->start_entry), length);
+ gtk_entry_set_max_length(GTK_ENTRY(priv->start_entry), length);
+ gtk_entry_set_width_chars(GTK_ENTRY (priv->end_entry), length);
+ gtk_entry_set_max_length(GTK_ENTRY (priv->end_entry), length);
+}
+
+/* Public functions */
+
+/**
+ * hildon_range_editor_get_type:
+ *
+ * Initializes, and returns the type of a hildon range editor.
+ *
+ * @Returns : GType of #HildonRangeEditor
+ *
+ */
+GType
+hildon_range_editor_get_type (void)
+{
+ static GType editor_type = 0;
+
+ if (!editor_type)
+ {
+ static const GTypeInfo editor_info =
+ {
+ sizeof(HildonRangeEditorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_range_editor_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonRangeEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_range_editor_init,
+ };
+ editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonRangeEditor",
+ &editor_info, 0);
+ }
+ return editor_type;
+}
+
+/**
+ * hildon_range_editor_new:
+ *
+ * HildonRangeEditor contains two GtkEntrys that accept numbers and minus.
+ *
+ * Returns: pointer to a new @HildonRangeEditor widget
+ */
+GtkWidget *
+hildon_range_editor_new (void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_RANGE_EDITOR, NULL));
+}
+
+
+/**
+ * hildon_range_editor_new_with_separator:
+ * @separator: a string that is shown between the numbers
+ *
+ * HildonRangeEditor contains two Gtk entries that accept numbers.
+ * A separator is displayed between two entries.
+ * CHECKME: Use '-' as a separator in the case of null separator?
+ *
+ * Returns: pointer to a new @HildonRangeEditor widget
+ */
+GtkWidget *
+hildon_range_editor_new_with_separator (const gchar *separator)
+{
+ return GTK_WIDGET (g_object_new (HILDON_TYPE_RANGE_EDITOR,
+ "separator", separator, NULL));
+}
+
+
+/**
+ * hildon_range_editor_set_range:
+ * @editor: the #HildonRangeEditor widget
+ * @start: range's start value
+ * @end: range's end value
+ *
+ * Sets a range to the editor. (The current value)
+ *
+ * Sets the range of the @HildonRangeEditor widget.
+ */
+void
+hildon_range_editor_set_range (HildonRangeEditor *editor, gint start, gint end)
+{
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+
+ /* Make sure that the start/end appear in the correct order */
+ hildon_range_editor_set_lower (editor, MIN(start, end));
+ hildon_range_editor_set_higher (editor, MAX(start, end));
+}
+
+
+/**
+ * hildon_range_editor_get_range:
+ * @editor: the #HildonRangeEditor widget
+ * @start: ranges start value
+ * @end: ranges end value
+ *
+ * Gets the range of the @HildonRangeEditor widget.
+ */
+void
+hildon_range_editor_get_range (HildonRangeEditor *editor, gint *start,
+ gint *end)
+{
+ HildonRangeEditorPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor) && start && end);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ *start = hildon_range_editor_get_lower (editor);
+ *end = hildon_range_editor_get_higher (editor);
+}
+
+
+/**
+ * hildon_range_editor_set_limits:
+ * @editor: the #HildonRangeEditor widget
+ * @start: minimum acceptable value (default: no limit)
+ * @end: maximum acceptable value (default: no limit)
+ *
+ * Sets the range of the @HildonRangeEditor widget.
+ */
+void
+hildon_range_editor_set_limits (HildonRangeEditor *editor, gint start,
+ gint end)
+{
+ /* FIXME: Setting start/end as separate steps can modify
+ the inputted range unneedlesly */
+ hildon_range_editor_set_min (editor, start);
+ hildon_range_editor_set_max (editor, end);
+}
+
+void
+hildon_range_editor_set_lower (HildonRangeEditor *editor, gint value)
+{
+ HildonRangeEditorPrivate *priv;
+ gchar buffer[32];
+
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
+ priv->range_limits_start, priv->range_limits_end));
+
+ /* Update entry text with new value */
+ gtk_entry_set_text (GTK_ENTRY (priv->start_entry), buffer);
+ g_object_notify (G_OBJECT (editor), "lower");
+}
+
+void
+hildon_range_editor_set_higher (HildonRangeEditor *editor, gint value)
+{
+ HildonRangeEditorPrivate *priv;
+ gchar buffer[32];
+
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ g_snprintf(buffer, sizeof(buffer), "%d", CLAMP(value,
+ priv->range_limits_start, priv->range_limits_end));
+
+ /* Update entry text with new value */
+ gtk_entry_set_text (GTK_ENTRY (priv->end_entry), buffer);
+ g_object_notify (G_OBJECT (editor), "higher");
+}
+
+gint
+hildon_range_editor_get_lower (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+ return atoi(gtk_entry_get_text(GTK_ENTRY(priv->start_entry)));
+}
+
+gint
+hildon_range_editor_get_higher (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+ return atoi(gtk_entry_get_text(GTK_ENTRY (priv->end_entry)));
+}
+
+void
+hildon_range_editor_set_min (HildonRangeEditor *editor, gint value)
+{
+ HildonRangeEditorPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+
+ /* We can cause many properties to change */
+ g_object_freeze_notify(G_OBJECT(editor));
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+ priv->range_limits_start = value;
+
+ if (priv->range_limits_end < value)
+ hildon_range_editor_set_max (editor, value);
+ /* Setting maximum applies widths and range in this case */
+ else {
+ hildon_range_editor_refresh_widths(priv);
+ hildon_range_editor_apply_current_range(editor);
+ }
+
+ g_object_notify (G_OBJECT (editor), "min");
+ g_object_thaw_notify(G_OBJECT(editor));
+}
+
+void
+hildon_range_editor_set_max (HildonRangeEditor *editor, gint value)
+{
+ HildonRangeEditorPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+
+ /* We can cause many properties to change */
+ g_object_freeze_notify(G_OBJECT(editor));
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+ priv->range_limits_end = value;
+
+ if (priv->range_limits_start > value)
+ hildon_range_editor_set_min (editor, value);
+ /* Setting minimum applies widths and range in this case */
+ else {
+ hildon_range_editor_refresh_widths(priv);
+ hildon_range_editor_apply_current_range(editor);
+ }
+
+ g_object_notify (G_OBJECT (editor), "max");
+ g_object_thaw_notify(G_OBJECT(editor));
+}
+
+gint
+hildon_range_editor_get_min (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ return priv->range_limits_start;
+}
+
+gint
+hildon_range_editor_get_max (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), 0);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ return priv->range_limits_end;
+}
+
+void
+hildon_range_editor_set_separator (HildonRangeEditor *editor,
+ const gchar *separator)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_if_fail (HILDON_IS_RANGE_EDITOR (editor));
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ gtk_label_set_text (GTK_LABEL (priv->label), separator);
+ g_object_notify (G_OBJECT(editor), "separator");
+}
+
+const gchar *
+hildon_range_editor_get_separator (HildonRangeEditor *editor)
+{
+ HildonRangeEditorPrivate *priv;
+ g_return_val_if_fail (HILDON_IS_RANGE_EDITOR (editor), NULL);
+ priv = HILDON_RANGE_EDITOR_GET_PRIVATE (editor);
+
+ return gtk_label_get_text (GTK_LABEL (priv->label));
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_RANGE_EDITOR_H__
+#define __HILDON_RANGE_EDITOR_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+/**
+ * HILDON_TYPE_RANGE_EDITOR
+ *
+ * Macro for getting type of range editor.
+ * Since: 0.12.10
+ */
+#define HILDON_TYPE_RANGE_EDITOR (hildon_range_editor_get_type())
+
+/**
+ * HILDON_RANGE_EDITOR_TYPE
+ *
+ * Deprecated: use #HILDON_TYPE_RANGE_EDITOR instead
+ */
+#define HILDON_RANGE_EDITOR_TYPE HILDON_TYPE_RANGE_EDITOR
+
+#define HILDON_RANGE_EDITOR(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_RANGE_EDITOR, HildonRangeEditor))
+#define HILDON_RANGE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_RANGE_EDITOR, HildonRangeEditorClass))
+#define HILDON_IS_RANGE_EDITOR(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_RANGE_EDITOR))
+#define HILDON_IS_RANGE_EDITOR_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_RANGE_EDITOR))
+/**
+ * HildonRangeEditor:
+ *
+ * Internal struct for range editor.
+ */
+typedef struct _HildonRangeEditor HildonRangeEditor;
+typedef struct _HildonRangeEditorClass HildonRangeEditorClass;
+
+
+struct _HildonRangeEditor {
+ GtkContainer parent;
+};
+
+struct _HildonRangeEditorClass {
+ GtkContainerClass parent_class;
+};
+
+GType hildon_range_editor_get_type(void) G_GNUC_CONST;
+
+GtkWidget *hildon_range_editor_new_with_separator(const gchar * separator);
+GtkWidget *hildon_range_editor_new(void);
+
+void hildon_range_editor_set_range(HildonRangeEditor * editor,
+ gint start, gint end);
+void hildon_range_editor_get_range(HildonRangeEditor * editor,
+ gint * start, gint * end);
+void hildon_range_editor_set_limits(HildonRangeEditor * editor,
+ gint start, gint end);
+
+void hildon_range_editor_set_lower (HildonRangeEditor *editor, gint value);
+void hildon_range_editor_set_higher (HildonRangeEditor *editor, gint value);
+gint hildon_range_editor_get_lower (HildonRangeEditor *editor);
+gint hildon_range_editor_get_higher (HildonRangeEditor *editor);
+void hildon_range_editor_set_min (HildonRangeEditor *editor, gint value);
+void hildon_range_editor_set_max (HildonRangeEditor *editor, gint value);
+gint hildon_range_editor_get_min (HildonRangeEditor *editor);
+gint hildon_range_editor_get_max (HildonRangeEditor *editor);
+void hildon_range_editor_set_separator (HildonRangeEditor *editor,
+ const gchar *separator);
+const gchar *hildon_range_editor_get_separator (HildonRangeEditor *editor);
+
+G_END_DECLS
+#endif /* __HILDON_RANGE_EDITOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-scroll-area
+ * @short_description: A helper to create Maemo specific views,
+ * which are using scrollable area
+ *
+ * #GtkScrollArea combines a large widget that needs scrolling (like a
+ * text editor or a tree view) and other widgets that wouldn't fit one
+ * the screen normally without scrolling (like entries, toolbars etc.)
+ * into one scrollable area.
+ */
+
+#include "hildon-scroll-area.h"
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkfixed.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
+#include <string.h>
+
+typedef struct
+ {
+ GtkWidget *fixed;
+
+ /* Scrolled windows */
+ GtkWidget *swouter;
+ GtkWidget *swinner;
+
+ /* Widget that's being contained */
+ GtkWidget *child;
+
+ /* Vertical adjustment for scrolled windows */
+ GtkAdjustment *outadj;
+ GtkAdjustment *inadj;
+
+ } HildonScrollArea;
+
+
+static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
+ HildonScrollArea *sc);
+static void hildon_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
+ HildonScrollArea *sc);
+static void hildon_scroll_area_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ HildonScrollArea *sc);
+static void hildon_scroll_area_child_requisition (GtkWidget *widget,
+ GtkRequisition *req,
+ HildonScrollArea *sc);
+static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ HildonScrollArea *sc);
+
+static int calculate_size (GtkWidget *widget);
+
+/**
+ * hildon_scroll_area_new:
+ * @sw: #GtkWidget - #GtkScrolledWindow
+ * @child: #GtkWidget - child to be place inside the sw
+ *
+ * This is not a widget. It's a helper function to create
+ * hildon-specific scrolling methods.
+ * A common situation where the scroll area should be used
+ * might be following. A view containing @GtkTreeView based widget,
+ * (or any similar widget which has built-in @GtkScrolledWindow support)
+ * and eg. couple buttons. Normaly @GtkScrolledWindow can not handle
+ * the situation so that the @GtkTreeView built-in support
+ * would work. The scroll area is connecting this built-in system to
+ * the scrolled window and also noticing the buttons. To use, one should
+ * create a box to which pack the buttons and the scroll area.
+ * The scroll area then contains the problematic widget eg. the @GtkTreeView.
+ * Then the box should be placed in the @GtkScrolledWindow.
+ * The function is currently assuming that the newly created scroll area
+ * hierarchy is not modified in anyway. Or if it is, it may lead to
+ * unwanted problems. Also assumed, that the @child will be packed
+ * to the @sw.
+ *
+ * Returns: a @GtkFixed
+ */
+GtkWidget *hildon_scroll_area_new (GtkWidget *sw, GtkWidget *child)
+{
+ GtkWidget *swi;
+ GtkWidget *fixed;
+ HildonScrollArea *sc;
+
+ g_return_val_if_fail (GTK_IS_SCROLLED_WINDOW (sw)
+ && GTK_IS_WIDGET (child), NULL);
+
+ swi = gtk_scrolled_window_new (NULL, NULL);
+ fixed = gtk_fixed_new ();
+ sc = g_malloc (sizeof (HildonScrollArea));
+ memset (sc, 0, sizeof (HildonScrollArea));
+
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swi),
+ GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+
+ gtk_container_add (GTK_CONTAINER (swi), child);
+ gtk_fixed_put (GTK_FIXED (fixed), swi, 0, 0);
+
+ sc->fixed = fixed;
+ sc->swouter = sw;
+ sc->swinner = swi;
+ sc->child = child;
+ sc->outadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw));
+ sc->inadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (swi));
+
+ g_signal_connect_after (G_OBJECT (child), "size-request",
+ G_CALLBACK (hildon_scroll_area_child_requisition), sc);
+
+ g_signal_connect_after (G_OBJECT (sc->outadj), "value_changed",
+ G_CALLBACK (hildon_scroll_area_outer_value_changed), sc);
+ g_signal_connect_after (G_OBJECT (sc->inadj), "value_changed",
+ G_CALLBACK (hildon_scroll_area_inner_value_changed), sc);
+
+ g_signal_connect_after (G_OBJECT (sw), "size-allocate",
+ G_CALLBACK (hildon_scroll_area_size_allocate), sc);
+ g_signal_connect (G_OBJECT (sc->fixed), "size-allocate",
+ G_CALLBACK (hildon_scroll_area_fixed_allocate), sc);
+ g_signal_connect_swapped (G_OBJECT (sw), "destroy",
+ G_CALLBACK (g_free), sc);
+
+ gtk_widget_show_all (sw);
+ return fixed;
+}
+
+static void hildon_scroll_area_fixed_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ HildonScrollArea *sc)
+{
+ gtk_widget_set_size_request (sc->swinner, -1,
+ MIN (sc->outadj->page_size, allocation->height));
+}
+
+
+static int calculate_size (GtkWidget *widget)
+{
+ int size = 0;
+
+ if (GTK_IS_TEXT_VIEW (widget))
+ return 0;
+
+ if (GTK_IS_CONTAINER (widget)) {
+ GList *children = gtk_container_get_children (GTK_CONTAINER (widget));
+ while (children != NULL) {
+ GtkWidget *wid = GTK_WIDGET (children->data);
+ gint sz = calculate_size (wid);
+ if ((GTK_WIDGET_VISIBLE (wid))) {
+ size += sz;
+ }
+
+ children = g_list_next (children);
+ }
+ } else {
+ size = widget->allocation.height;
+ }
+
+ return size;
+}
+
+static void hildon_scroll_area_child_requisition (GtkWidget *widget,
+ GtkRequisition *req,
+ HildonScrollArea *sc)
+{
+ /* Limit height to fixed height */
+ gint new_req = MAX (req->height, sc->fixed->allocation.height);
+ gint adjust_factor = calculate_size (sc->swouter) * 0.7;
+
+ adjust_factor = MAX (0, adjust_factor - sc->outadj->value);
+ new_req = MIN (sc->outadj->page_size - adjust_factor, new_req);
+
+ gtk_widget_set_size_request (sc->fixed, -1, req->height);
+ /* Request inner scrolled window at most page size */
+ gtk_widget_set_size_request (sc->swinner, -1, new_req);
+}
+
+static void hildon_scroll_area_outer_value_changed (GtkAdjustment *adjustment,
+ HildonScrollArea *sc)
+{
+ GtkRequisition req;
+ gtk_widget_size_request (sc->child, &req);
+
+ /* Update inner adjustment position based on outer one, update fixed position */
+ if ((sc->outadj->value + sc->outadj->page_size) > sc->fixed->allocation.y
+ && sc->outadj->value < (sc->fixed->allocation.y + req.height))
+ {
+ gdouble new_pos = 0;
+
+ new_pos = MAX (sc->outadj->value - sc->fixed->allocation.y, 0);
+ new_pos = MIN (new_pos, req.height - sc->inadj->page_size);
+ new_pos = MAX (new_pos, 0);
+
+ gtk_fixed_move (GTK_FIXED (sc->fixed), sc->swinner, 0, new_pos);
+ gtk_adjustment_set_value (sc->inadj, new_pos);
+ }
+}
+
+static void hildon_scroll_area_inner_value_changed (GtkAdjustment *adjustment,
+ HildonScrollArea *sc)
+{
+ /* Update outer adjustment based on inner adjustment position */
+ if (sc->outadj->value != sc->fixed->allocation.y + adjustment->value)
+ gtk_adjustment_set_value (sc->outadj,
+ sc->fixed->allocation.y + adjustment->value);
+}
+
+__inline__ static gint calculate_width (HildonScrollArea *sc)
+{
+ GtkScrolledWindow *scwin = GTK_SCROLLED_WINDOW (sc->swouter);
+ return (scwin->hscrollbar_visible * scwin->hscrollbar->allocation.width);
+}
+
+static void hildon_scroll_area_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation,
+ HildonScrollArea *sc)
+{
+ gtk_widget_set_size_request (sc->fixed, calculate_width (sc), sc->fixed->allocation.height);
+ gtk_widget_set_size_request (sc->child, sc->fixed->allocation.width, -1);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * The reason why this is not made as a widget:
+ * We can not create a widget which could return the correct child.
+ * (ie. by gtk_bin_get_child)
+ */
+
+#ifndef __HILDON_SCROLL_AREA_H__
+#define __HILDON_SCROLL_AREA_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+ GtkWidget * hildon_scroll_area_new(GtkWidget * sw, GtkWidget * child);
+
+G_END_DECLS
+#endif /* __HILDON_SCROLL_AREA_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-seekbar
+ * @short_description: A widget used to identify a place from a content
+ *
+ * HildonSeekbar allows seeking in media with a range widget. It
+ * supports for setting or getting the length (total time) of the media,
+ * the position within it and the fraction (maximum position in a
+ * stream/the amount currently downloaded). The position is clamped
+ * between zero and the total time, or zero and the fraction in case of
+ * a stream.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libintl.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <gtk/gtklabel.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtkalignment.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtktoolbar.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "hildon-seekbar.h"
+
+#define HILDON_SEEKBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_SEEKBAR, HildonSeekbarPrivate));
+
+typedef struct _HildonSeekbarPrivate HildonSeekbarPrivate;
+
+/* our parent class */
+static GtkScaleClass *parent_class = NULL;
+
+/* Init functions */
+static void hildon_seekbar_class_init(HildonSeekbarClass * seekbar_class);
+static void hildon_seekbar_init(HildonSeekbar * seekbar);
+
+/* property functions */
+static void hildon_seekbar_set_property(GObject * object, guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+
+static void hildon_seekbar_get_property(GObject * object, guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+
+/* virtual functions */
+static void hildon_seekbar_size_request(GtkWidget * widget,
+ GtkRequisition * event);
+static void hildon_seekbar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static gboolean hildon_seekbar_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static gboolean hildon_seekbar_button_press_event(GtkWidget * widget,
+ GdkEventButton * event);
+static gboolean hildon_seekbar_button_release_event(GtkWidget * widget,
+ GdkEventButton * event);
+static gboolean hildon_seekbar_keypress(GtkWidget * widget,
+ GdkEventKey * event);
+
+
+#define MINIMUM_WIDTH 115
+#define DEFAULT_HEIGHT 58
+
+/* Toolbar width and height defines */
+#define TOOL_MINIMUM_WIDTH 75
+#define TOOL_DEFAULT_HEIGHT 40
+
+#define DEFAULT_DISPLAYC_BORDER 10
+#define BUFFER_SIZE 32
+#define EXTRA_SIDE_BORDER 20
+#define TOOL_EXTRA_SIDE_BORDER 0
+
+/* the number of steps it takes to move from left to right */
+#define NUM_STEPS 20
+
+#define SECONDS_PER_MINUTE 60
+
+/* the number of digits precision for the internal range.
+ * note, this needs to be enough so that the step size for
+ * small total_times doesn't get rounded off. Currently set to 3
+ * this is because for the smallest total time ( i.e 1 ) and the current
+ * num steps ( 20 ) is: 1/20 = 0.05. 0.05 is 2 digits, and we
+ * add one for safety */
+#define MAX_ROUND_DIGITS 3
+
+/*
+ * FIXME HildonSeekbar introduced major changes in GtkRange mostly related
+ * to stream_indicator. These changes should be minimized.
+ */
+
+/* Property indices */
+enum {
+ PROP_TOTAL_TIME = 1,
+ PROP_POSITION,
+ PROP_FRACTION
+};
+
+/* private variables */
+struct _HildonSeekbarPrivate {
+ gboolean is_toolbar; /* TRUE if this widget is inside a toolbar */
+ guint fraction; /* This is the amount of time that has progressed from
+ the beginning. It should be an integer between the
+ minimum and maximum values of the corresponding
+ adjustment, ie. adjument->lower and ->upper.. */
+};
+
+/**
+ * Initialises, and returns the type of a hildon seekbar.
+ */
+GType hildon_seekbar_get_type(void)
+{
+ static GType seekbar_type = 0;
+
+ if (!seekbar_type) {
+ static const GTypeInfo seekbar_info = {
+ sizeof(HildonSeekbarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_seekbar_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonSeekbar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_seekbar_init,
+ };
+ seekbar_type = g_type_register_static(GTK_TYPE_SCALE,
+ "HildonSeekbar",
+ &seekbar_info, 0);
+ }
+ return seekbar_type;
+}
+
+/**
+ * Initialises the seekbar class.
+ */
+static void hildon_seekbar_class_init(HildonSeekbarClass * seekbar_class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(seekbar_class);
+ GObjectClass *object_class = G_OBJECT_CLASS(seekbar_class);
+
+ parent_class = g_type_class_peek_parent(seekbar_class);
+
+ g_type_class_add_private(seekbar_class, sizeof(HildonSeekbarPrivate));
+
+ widget_class->size_request = hildon_seekbar_size_request;
+ widget_class->size_allocate = hildon_seekbar_size_allocate;
+ widget_class->expose_event = hildon_seekbar_expose;
+ widget_class->button_press_event = hildon_seekbar_button_press_event;
+ widget_class->button_release_event =
+ hildon_seekbar_button_release_event;
+ widget_class->key_press_event = hildon_seekbar_keypress;
+
+ object_class->set_property = hildon_seekbar_set_property;
+ object_class->get_property = hildon_seekbar_get_property;
+
+ g_object_class_install_property(object_class, PROP_TOTAL_TIME,
+ g_param_spec_double("total_time",
+ "total time",
+ "Total playing time of this media file",
+ 0, /* min value */
+ G_MAXDOUBLE, /* max value */
+ 0, /* default */
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_POSITION,
+ g_param_spec_double("position",
+ "position",
+ "Current position in this media file",
+ 0, /* min value */
+ G_MAXDOUBLE, /* max value */
+ 0, /* default */
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_FRACTION,
+ g_param_spec_double("fraction",
+ "Fraction",
+ "current fraction related to the"
+ "progress indicator",
+ 0, /* min value */
+ G_MAXDOUBLE, /* max value */
+ 0, /* default */
+ G_PARAM_READWRITE));
+}
+
+
+static void hildon_seekbar_init(HildonSeekbar * seekbar)
+{
+ HildonSeekbarPrivate *priv;
+ GtkRange *range = GTK_RANGE(seekbar);
+
+ priv = HILDON_SEEKBAR_GET_PRIVATE(seekbar);
+
+ /* Initialize range widget */
+ range->orientation = GTK_ORIENTATION_HORIZONTAL;
+ range->flippable = TRUE;
+ range->has_stepper_a = TRUE;
+ range->has_stepper_d = TRUE;
+ range->round_digits = MAX_ROUND_DIGITS;
+
+ gtk_scale_set_draw_value (GTK_SCALE (seekbar), FALSE);
+}
+
+/*
+ * Purpose of this function is to prevent Up and Down keys from
+ * changing the widget's value (like Left and Right). Instead they
+ * are used for changing focus to other widgtes.
+ */
+static gboolean hildon_seekbar_keypress(GtkWidget * widget,
+ GdkEventKey * event)
+{
+ if (event->keyval == GDK_Up || event->keyval == GDK_Down)
+ return FALSE;
+ return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget,
+ event));
+}
+
+static void
+hildon_seekbar_set_property(GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonSeekbar *seekbar = HILDON_SEEKBAR(object);
+
+ switch (prop_id) {
+ case PROP_TOTAL_TIME:
+ hildon_seekbar_set_total_time(seekbar, g_value_get_double(value));
+ break;
+ case PROP_POSITION:
+ hildon_seekbar_set_position(seekbar, g_value_get_double(value));
+ break;
+ case PROP_FRACTION:
+ hildon_seekbar_set_fraction(seekbar, g_value_get_double(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/* handle getting of seekbar properties */
+static void
+hildon_seekbar_get_property(GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GtkRange *range = GTK_RANGE(object);
+
+ switch (prop_id) {
+ case PROP_TOTAL_TIME:
+ g_value_set_double(value, range->adjustment->upper);
+ break;
+ case PROP_POSITION:
+ g_value_set_double(value, range->adjustment->value);
+ break;
+ case PROP_FRACTION:
+ g_value_set_double(value,
+ hildon_seekbar_get_fraction(HILDON_SEEKBAR(object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * hildon_seekbar_new:
+ *
+ * Create a new #HildonSeekbar widget.
+ *
+ * Returns: a #GtkWidget pointer of #HildonSeekbar widget
+ */
+GtkWidget *hildon_seekbar_new(void)
+{
+ return g_object_new(HILDON_TYPE_SEEKBAR, NULL);
+}
+
+/**
+ * hildon_seekbar_get_total_time:
+ * @seekbar: pointer to #HildonSeekbar widget
+ *
+ * Returns: total playing time of media in seconds.
+ */
+gint hildon_seekbar_get_total_time(HildonSeekbar *seekbar)
+{
+ GtkWidget *widget;
+ widget = GTK_WIDGET (seekbar);
+ g_return_val_if_fail(HILDON_IS_SEEKBAR(seekbar), 0);
+ g_return_val_if_fail(GTK_RANGE(widget)->adjustment, 0);
+ return GTK_RANGE(widget)->adjustment->upper;
+}
+
+/**
+ * hildon_seekbar_set_total_time:
+ * @seekbar: pointer to #HildonSeekbar widget
+ * @time: integer greater than zero
+ *
+ * Set total playing time of media in seconds.
+ */
+void hildon_seekbar_set_total_time(HildonSeekbar *seekbar, gint time)
+{
+ GtkAdjustment *adj;
+ GtkWidget *widget;
+ gboolean value_changed = FALSE;
+
+ g_return_if_fail(HILDON_IS_SEEKBAR(seekbar));
+ widget = GTK_WIDGET (seekbar);
+
+ if (time <= 0) {
+ return;
+ }
+
+ g_return_if_fail(GTK_RANGE(widget)->adjustment);
+
+ adj = GTK_RANGE(widget)->adjustment;
+ adj->upper = time;
+
+ /* Clamp position to total time */
+ if (adj->value > time) {
+ adj->value = time;
+ value_changed = TRUE;
+ }
+
+ /* Calculate new step value */
+ adj->step_increment = adj->upper / NUM_STEPS;
+ adj->page_increment = adj->step_increment;
+
+ gtk_adjustment_changed(adj);
+
+ /* Update range widget position/fraction */
+ if (value_changed) {
+ gtk_adjustment_value_changed(adj);
+ hildon_seekbar_set_fraction(seekbar,
+ MIN(hildon_seekbar_get_fraction(seekbar),
+ time));
+
+ g_object_freeze_notify (G_OBJECT(seekbar));
+
+ hildon_seekbar_set_position(seekbar,
+ MIN(hildon_seekbar_get_position(seekbar),
+ time));
+
+ g_object_notify(G_OBJECT (seekbar), "total-time");
+
+ g_object_thaw_notify (G_OBJECT(seekbar));
+ }
+}
+
+/**
+ * hildon_seekbar_get_fraction:
+ * @seekbar: pointer to #HildonSeekbar widget
+ *
+ * Get current fraction value of the rage.
+ *
+ * Returns: current fraction
+ */
+guint hildon_seekbar_get_fraction( HildonSeekbar *seekbar )
+{
+ g_return_val_if_fail( HILDON_IS_SEEKBAR( seekbar ), 0 );
+
+ return osso_gtk_range_get_stream_position (GTK_RANGE(seekbar));
+}
+
+/**
+ * hildon_seekbar_set_fraction:
+ * @seekbar: pointer to #HildonSeekbar widget
+ * @fraction: the new position of the progress indicator
+ *
+ * Set current fraction value of the range.
+ * It should be between the minimal and maximal values of the range in seekbar.
+ */
+void hildon_seekbar_set_fraction( HildonSeekbar *seekbar, guint fraction )
+{
+ GtkRange *range = NULL;
+ g_return_if_fail( HILDON_IS_SEEKBAR( seekbar ) );
+
+ range = GTK_RANGE(GTK_WIDGET(seekbar));
+
+ g_return_if_fail(fraction <= range->adjustment->upper &&
+ fraction >= range->adjustment->lower);
+
+ /* Set to show stream indicator. */
+ g_object_set (G_OBJECT (seekbar), "stream_indicator", TRUE, NULL);
+
+ fraction = CLAMP(fraction, range->adjustment->lower,
+ range->adjustment->upper);
+
+ /* Update stream position of range widget */
+ osso_gtk_range_set_stream_position( range, fraction );
+
+ if (fraction < hildon_seekbar_get_position(seekbar))
+ hildon_seekbar_set_position(seekbar, fraction);
+
+ g_object_notify (G_OBJECT (seekbar), "fraction");
+}
+
+/**
+ * hildon_seekbar_get_position:
+ * @seekbar: pointer to #HildonSeekbar widget
+ *
+ * Get current position in stream in seconds.
+ *
+ * Returns: current position in stream in seconds
+ */
+gint hildon_seekbar_get_position(HildonSeekbar *seekbar)
+{
+ g_return_val_if_fail(HILDON_IS_SEEKBAR(seekbar), 0);
+ g_return_val_if_fail(GTK_RANGE(seekbar)->adjustment, 0);
+
+ return GTK_RANGE(seekbar)->adjustment->value;
+}
+
+/**
+ * hildon_seekbar_set_position:
+ * @seekbar: pointer to #HildonSeekbar widget
+ * @time: time within range of >= 0 && < G_MAXINT
+ *
+ * Set current position in stream in seconds.
+ */
+void hildon_seekbar_set_position(HildonSeekbar *seekbar, gint time)
+{
+ GtkRange *range;
+ GtkAdjustment *adj;
+ gint value;
+
+ g_return_if_fail(time >= 0);
+ g_return_if_fail(HILDON_IS_SEEKBAR(seekbar));
+ range = GTK_RANGE(seekbar);
+ adj = range->adjustment;
+ g_return_if_fail(adj);
+
+ /* only change value if it is a different int. this allows us to have
+ smooth scrolls for small total_times */
+ value = floor(adj->value);
+ if (time != value) {
+ value = (time < adj->upper) ? time : adj->upper;
+ if (value <= osso_gtk_range_get_stream_position (range)) {
+ adj->value = value;
+ gtk_adjustment_value_changed(adj);
+
+ g_object_notify(G_OBJECT(seekbar), "position");
+ }
+ }
+}
+
+static void hildon_seekbar_size_request(GtkWidget * widget,
+ GtkRequisition * req)
+{
+ HildonSeekbar *self = NULL;
+ HildonSeekbarPrivate *priv = NULL;
+ GtkWidget *parent = NULL;
+
+ self = HILDON_SEEKBAR(widget);
+ priv = HILDON_SEEKBAR_GET_PRIVATE(self);
+
+ parent = gtk_widget_get_ancestor(GTK_WIDGET(self), GTK_TYPE_TOOLBAR);
+
+ priv->is_toolbar = parent ? TRUE : FALSE;
+
+ if (GTK_WIDGET_CLASS(parent_class)->size_request)
+ GTK_WIDGET_CLASS(parent_class)->size_request(widget, req);
+
+ /* Request minimum size, depending on whether the widget is in a
+ * toolbar or not */
+ req->width = priv->is_toolbar ? TOOL_MINIMUM_WIDTH : MINIMUM_WIDTH;
+ req->height = priv->is_toolbar ? TOOL_DEFAULT_HEIGHT : DEFAULT_HEIGHT;
+}
+
+static void hildon_seekbar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonSeekbarPrivate *priv;
+
+ priv = HILDON_SEEKBAR_GET_PRIVATE(HILDON_SEEKBAR(widget));
+
+ if (priv->is_toolbar == TRUE)
+ {
+ /* Center vertically */
+ if (allocation->height > TOOL_DEFAULT_HEIGHT)
+ {
+ allocation->y +=
+ (allocation->height - TOOL_DEFAULT_HEIGHT) / 2;
+ allocation->height = TOOL_DEFAULT_HEIGHT;
+ }
+ /* Add space for border */
+ allocation->x += TOOL_EXTRA_SIDE_BORDER;
+ allocation->width -= 2 * TOOL_EXTRA_SIDE_BORDER;
+ }
+ else
+ {
+ /* Center vertically */
+ if (allocation->height > DEFAULT_HEIGHT)
+ {
+ allocation->y += (allocation->height - DEFAULT_HEIGHT) / 2;
+ allocation->height = DEFAULT_HEIGHT;
+ }
+
+ /* Add space for border */
+ allocation->x += EXTRA_SIDE_BORDER;
+ allocation->width -= 2 * EXTRA_SIDE_BORDER;
+ }
+
+ if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
+ GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
+}
+
+static gboolean hildon_seekbar_expose(GtkWidget * widget,
+ GdkEventExpose * event)
+{
+ HildonSeekbarPrivate *priv;
+ gint extra_side_borders = 0;
+
+ priv = HILDON_SEEKBAR_GET_PRIVATE(HILDON_SEEKBAR(widget));
+
+ extra_side_borders = priv->is_toolbar ? TOOL_EXTRA_SIDE_BORDER :
+ EXTRA_SIDE_BORDER;
+
+ if (GTK_WIDGET_DRAWABLE(widget)) {
+ /* Paint border */
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ NULL, widget, "seekbar",
+ widget->allocation.x - extra_side_borders,
+ widget->allocation.y,
+ widget->allocation.width + 2 * extra_side_borders,
+ widget->allocation.height);
+
+ (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
+ }
+
+ return FALSE;
+}
+
+/*
+ * Event handler for button press. Changes button1 to button2.
+ */
+static gboolean
+hildon_seekbar_button_press_event(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ gint result = FALSE;
+
+ /* We change here the button id because we want to use button2
+ * functionality for button1: jump to mouse position
+ * instead of slowly incrementing to it */
+ if (event->button == 1) event->button = 2;
+
+ /* call the parent handler */
+ if (GTK_WIDGET_CLASS(parent_class)->button_press_event)
+ result = GTK_WIDGET_CLASS(parent_class)->button_press_event(widget,
+ event);
+
+ return result;
+}
+/*
+ * Event handler for button release. Changes button1 to button2.
+ */
+static gboolean
+hildon_seekbar_button_release_event(GtkWidget * widget,
+ GdkEventButton * event)
+{
+ gboolean result = FALSE;
+
+ /* We change here the button id because we want to use button2
+ * functionality for button1: jump to mouse position
+ * instead of slowly incrementing to it */
+ event->button = event->button == 1 ? 2 : event->button;
+
+ /* call the parent handler */
+ if (GTK_WIDGET_CLASS(parent_class)->button_release_event)
+ result = GTK_WIDGET_CLASS(parent_class)->button_release_event(widget,
+ event);
+ return result;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_SEEKBAR_H__
+#define __HILDON_SEEKBAR_H__
+
+#include <gtk/gtkscale.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_SEEKBAR ( hildon_seekbar_get_type() )
+#define HILDON_SEEKBAR(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_SEEKBAR, HildonSeekbar))
+#define HILDON_SEEKBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_SEEKBAR, HildonSeekbarClass))
+#define HILDON_IS_SEEKBAR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_SEEKBAR))
+#define HILDON_IS_SEEKBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_SEEKBAR))
+/**
+ * HildonSeekbar:
+ *
+ * Contains only private data.
+ */
+typedef struct _HildonSeekbar HildonSeekbar;
+typedef struct _HildonSeekbarClass HildonSeekbarClass;
+
+struct _HildonSeekbar {
+ GtkScale scale;
+};
+
+struct _HildonSeekbarClass {
+ GtkScaleClass parent_class;
+};
+
+GType hildon_seekbar_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_seekbar_new(void);
+gint hildon_seekbar_get_total_time(HildonSeekbar *seekbar);
+void hildon_seekbar_set_total_time(HildonSeekbar *seekbar, gint time);
+gint hildon_seekbar_get_position(HildonSeekbar *seekbar);
+void hildon_seekbar_set_position(HildonSeekbar *seekbar, gint time);
+void hildon_seekbar_set_fraction(HildonSeekbar *seekbar, guint fraction);
+guint hildon_seekbar_get_fraction(HildonSeekbar *seekbar);
+
+G_END_DECLS
+#endif /* __HILDON_SEEKBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-set-password-dialog
+ * @short_description: A dialog used to set, change or remove a password
+ * @see_also: #HildonGetPasswordDialog
+ *
+ * HildonSetPasswordDialog allows setting and changing a password.
+ *
+ * In Change mode: Dialog is used to change or remove an existing
+ * password. Unselecting the check box dims the password fields below
+ * it. If the dialog is accepted with 'OK' while the check box is
+ * unselected, a Confirmation Note is shown. If the Confirmation Note
+ * Dialog is accepted with 'Remove', the password protection is removed.
+ *
+ * In Set mode: Set Password Dialog is used to define a password, or
+ * change a password that cannot be removed.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <hildon-widgets/hildon-caption.h>
+#include <hildon-widgets/gtk-infoprint.h>
+#include <hildon-widgets/hildon-set-password-dialog.h>
+#include <hildon-widgets/hildon-note.h>
+#include <hildon-widgets/hildon-defines.h>
+
+#include <libintl.h>
+#define _(String) dgettext(PACKAGE, String)
+#define c_(String) dgettext("hildon-common-strings", String)
+
+static GtkDialogClass *parent_class;
+
+#define HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(obj)\
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_SET_PASSWORD_DIALOG, HildonSetPasswordDialogPrivate));
+
+typedef struct
+_HildonSetPasswordDialogPrivate HildonSetPasswordDialogPrivate;
+
+static void
+hildon_set_password_dialog_class_init(HildonSetPasswordDialogClass *
+ class);
+static void hildon_set_password_dialog_init(HildonSetPasswordDialog *
+ dialog);
+static void hildon_checkbox_toggled(GtkWidget * widget, gpointer dialog);
+
+static void
+hildon_set_password_response_change(GtkDialog * d, gint arg1, gpointer unused);
+static void
+hildon_set_password_response_set(GtkDialog * d, gint arg1, gpointer unused);
+
+static void create_contents(HildonSetPasswordDialog *dialog);
+static void hildon_set_password_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_set_password_get_property(GObject * object,
+ guint prop_id, GValue * value,
+ GParamSpec * pspec);
+
+/* Private struct */
+struct _HildonSetPasswordDialogPrivate {
+ GtkWidget *checkboxCaption;
+ GtkWidget *checkbox;
+
+ GtkLabel *domainLabel;
+
+ GtkWidget *pwd1stEntry;
+ GtkWidget *pwd1stCaption;
+ gchar *pwd1stCaption_string;
+
+ GtkWidget *pwd2ndEntry;
+ GtkWidget *pwd2ndCaption;
+ gchar *pwd2ndCaption_string;
+
+ GtkWidget *okButton;
+ GtkWidget *cancelButton;
+
+ gboolean protection;
+};
+
+enum {
+ PROP_NONE = 0,
+ PROP_DOMAIN,
+ PROP_PASSWORD,
+ PROP_HILDON_PASSWORD_DIALOG
+};
+
+/* Private functions */
+static void
+hildon_set_password_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonSetPasswordDialog *dialog = HILDON_SET_PASSWORD_DIALOG(object);
+ HildonSetPasswordDialogPrivate *priv;
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ switch (prop_id) {
+ case PROP_DOMAIN:
+ /* Update domain label to display new value */
+ gtk_label_set_text(priv->domainLabel, g_value_get_string(value));
+ break;
+ case PROP_PASSWORD:
+ /* Update password entry to display new value */
+ gtk_entry_set_text(GTK_ENTRY(priv->pwd1stEntry), g_value_get_string(value));
+ break;
+ case PROP_HILDON_PASSWORD_DIALOG:
+ /* Note this is a G_PARAM_CONSTRUCT_ONLY type property */
+ priv->protection = g_value_get_boolean(value);
+
+ /* We now have the necessary information to populate the dialog */
+ create_contents(dialog);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_set_password_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ HildonSetPasswordDialogPrivate *priv = NULL;
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_DOMAIN:
+ g_value_set_string(value, gtk_label_get_text(priv->domainLabel));
+ break;
+ case PROP_PASSWORD:
+ g_value_set_string(value,
+ gtk_entry_get_text(GTK_ENTRY(priv->pwd1stEntry)));
+ break;
+ case PROP_HILDON_PASSWORD_DIALOG:
+ g_value_set_boolean(value, priv->protection);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+create_contents(HildonSetPasswordDialog *dialog)
+{
+ HildonSetPasswordDialogPrivate *priv = NULL;
+
+ GtkSizeGroup *group;
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ priv->checkbox = NULL;
+
+ /* Size group for labels */
+ group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+
+ /* Setup and pack domain label */
+ priv->domainLabel = GTK_LABEL(gtk_label_new(NULL));
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ GTK_WIDGET(priv->domainLabel), FALSE, FALSE, 0);
+ gtk_widget_show(GTK_WIDGET(priv->domainLabel));
+
+ if (priv->protection == TRUE) {
+ /* Use Change Password Dialog strings */
+ priv->pwd1stCaption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD);
+ priv->pwd2ndCaption_string = _(HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD);
+
+ /* Setup checkbox to enable/disable password protection */
+ priv->checkbox = gtk_check_button_new();
+ gtk_widget_show(priv->checkbox);
+ priv->checkboxCaption = hildon_caption_new
+ (group,
+ _(HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL),
+ priv->checkbox,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ hildon_caption_set_separator(HILDON_CAPTION(priv->checkboxCaption), "");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->checkboxCaption, TRUE, TRUE, 0);
+ gtk_widget_show(priv->checkboxCaption);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->checkbox),
+ TRUE);
+ gtk_signal_connect(GTK_OBJECT(priv->checkbox), "toggled",
+ G_CALLBACK(hildon_checkbox_toggled), dialog);
+
+ /* Setup appropriate response handler */
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(hildon_set_password_response_change),
+ NULL);
+ } else {
+ /* Use Set Password Dialog strings */
+ priv->pwd1stCaption_string = _(HILDON_SET_PASSWORD_DIALOG_PASSWORD);
+ priv->pwd2ndCaption_string = _(HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD);
+
+ /* Setup appropriate response handler */
+ g_signal_connect(G_OBJECT(dialog), "response",
+ G_CALLBACK(hildon_set_password_response_set),
+ NULL);
+ }
+
+ /* Create the password field */
+ priv->pwd1stEntry = gtk_entry_new();
+ g_object_set (priv->pwd1stEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
+ gtk_entry_set_visibility(GTK_ENTRY(priv->pwd1stEntry), FALSE);
+ gtk_widget_show(priv->pwd1stEntry);
+ priv->pwd1stCaption = hildon_caption_new(group,
+ priv->pwd1stCaption_string,
+ priv->pwd1stEntry,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ hildon_caption_set_separator(HILDON_CAPTION(priv->pwd1stCaption), "");
+ gtk_entry_set_visibility(GTK_ENTRY(priv->pwd1stEntry), FALSE);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->pwd1stCaption, TRUE, TRUE, 0);
+ gtk_widget_show(priv->pwd1stCaption);
+
+ /* Create the password verify field */
+ priv->pwd2ndEntry = gtk_entry_new();
+ g_object_set (priv->pwd2ndEntry, "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
+ gtk_widget_show(priv->pwd2ndEntry);
+ priv->pwd2ndCaption = hildon_caption_new(group,
+ priv->pwd2ndCaption_string,
+ priv->pwd2ndEntry,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ hildon_caption_set_separator(HILDON_CAPTION(priv->pwd2ndCaption), "");
+ gtk_entry_set_visibility(GTK_ENTRY(priv->pwd2ndEntry), FALSE);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->pwd2ndCaption, TRUE, TRUE, 0);
+ gtk_widget_show(priv->pwd2ndCaption);
+
+ /* Set dialog title */
+ gtk_window_set_title(GTK_WINDOW(dialog),
+ _(priv->protection
+ ? HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE
+ : HILDON_SET_PASSWORD_DIALOG_TITLE));
+
+ /* Create the OK/CANCEL buttons */
+ priv->okButton = gtk_dialog_add_button
+ (GTK_DIALOG(dialog), _(priv->protection
+ ? HILDON_SET_MODIFY_PASSWORD_DIALOG_OK
+ : HILDON_SET_PASSWORD_DIALOG_OK),
+ GTK_RESPONSE_OK);
+ priv->cancelButton = gtk_dialog_add_button
+ (GTK_DIALOG(dialog), _(priv->protection
+ ? HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL
+ : HILDON_SET_PASSWORD_DIALOG_CANCEL),
+ GTK_RESPONSE_CANCEL);
+
+ gtk_widget_show(priv->okButton);
+ gtk_widget_show(priv->cancelButton);
+
+ /* Ensure group is freed when all its contents have been removed */
+ g_object_unref(group);
+}
+
+static void
+hildon_set_password_dialog_class_init(HildonSetPasswordDialogClass * class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(class);
+
+ parent_class = g_type_class_peek_parent(class);
+
+ /* Override virtual methods */
+ object_class->set_property = hildon_set_password_set_property;
+ object_class->get_property = hildon_set_password_get_property;
+
+ /* Install new properties */
+ g_object_class_install_property(object_class,
+ PROP_DOMAIN,
+ g_param_spec_string ("domain",
+ "Domain",
+ "Set Domain (content) for domain label.",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class,
+ PROP_HILDON_PASSWORD_DIALOG,
+ g_param_spec_boolean ("modify_protection",
+ "Password type",
+ "Set type to dialog",
+ TRUE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class,
+ PROP_PASSWORD,
+ g_param_spec_string ("password",
+ "Password content",
+ "Set content to dialog",
+ "DEFAULT",
+ G_PARAM_READWRITE));
+
+ /* Install private structure */
+ g_type_class_add_private(class,
+ sizeof(HildonSetPasswordDialogPrivate));
+}
+
+static void
+hildon_set_password_dialog_init(HildonSetPasswordDialog * dialog)
+{
+ /* Most of the initializations are done in create_contents()
+ after the 'modify_protection' property has been set */
+
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+}
+
+
+/* We come here when response button is clicked and dialog
+ is used to change existing password. */
+static void
+hildon_set_password_response_change(GtkDialog * dialog, gint arg1,
+ gpointer unused)
+{
+ GtkEntry *pwd1stEntry;
+ GtkEntry *pwd2ndEntry;
+ gchar *text1;
+ gchar *text2;
+ HildonNote *note;
+ gint i;
+ HildonSetPasswordDialogPrivate *priv;
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Password and verification */
+ pwd1stEntry = GTK_ENTRY(gtk_bin_get_child
+ (GTK_BIN(priv->pwd1stCaption)));
+ pwd2ndEntry = GTK_ENTRY(gtk_bin_get_child
+ (GTK_BIN(priv->pwd2ndCaption)));
+ text1 = GTK_ENTRY(pwd1stEntry)->text;
+ text2 = GTK_ENTRY(pwd2ndEntry)->text;
+
+ /* User accepted the dialog */
+ if (arg1 == GTK_RESPONSE_OK){
+ /* Is the checkbox marked, so password protection is still in use? */
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbox))){
+ /* Yes, Something is given as password as well? */
+ if (text1[0] != '\0') {
+ if (strcmp (text1, text2) == 0) {
+ /* Passwords match, so accept change password */
+ priv->protection = TRUE;
+ } else if (text2[0] == '\0') {
+ /* Second field is empty, so show error, but don't clear fields */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog),
+ "response");
+ gtk_infoprint (NULL,
+ c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_widget_grab_focus(GTK_WIDGET(pwd2ndEntry));
+ } else {
+ /* Error: Passwords don't match, so start over */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog),
+ "response");
+ gtk_entry_set_text(pwd1stEntry, "");
+ gtk_entry_set_text(pwd2ndEntry, "");
+ gtk_infoprint (NULL,
+ c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
+ }
+ } else {
+ /* No, the password is empty */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
+ if (text2[0] == '\0') {
+ /* Error: Both fields are empty */
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
+ } else {
+ /* Error: Second field doesn't match
+ the empty first field, so start over */
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_entry_set_text(pwd2ndEntry, "");
+ }
+ gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
+ }
+ } else {
+ /* No, user wants to remove password protection.
+ Confirm remove password protection */
+ note = HILDON_NOTE(hildon_note_new_confirmation
+ (GTK_WINDOW(dialog),
+ c_(HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION
+ )));
+
+ hildon_note_set_button_texts
+ (HILDON_NOTE(note),
+ c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE),
+ c_(HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL));
+
+ /* Display confirmation note */
+ i = gtk_dialog_run(GTK_DIALOG(note));
+
+ gtk_widget_destroy(GTK_WIDGET(note));
+
+ if (i == GTK_RESPONSE_OK)
+ /* Remove password protection */
+ priv->protection = FALSE;
+ else {
+ /* Remove password protection cancelled */
+ priv->protection = TRUE;
+ g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
+ }
+ }
+
+ } else {
+ /* Watch out for fading boolean values */
+ priv->protection = TRUE;
+ }
+}
+
+/* We come here when response button is clicked and dialog
+ is used to set new password. */
+static void
+hildon_set_password_response_set(GtkDialog * dialog, gint arg1,
+ gpointer unused)
+{
+ GtkEntry *pwd1stEntry;
+ GtkEntry *pwd2ndEntry;
+ gchar *text1;
+ gchar *text2;
+
+ HildonSetPasswordDialogPrivate *priv;
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ /* Password and confirmation */
+ pwd1stEntry = GTK_ENTRY(gtk_bin_get_child
+ (GTK_BIN(priv->pwd1stCaption)));
+ pwd2ndEntry = GTK_ENTRY(gtk_bin_get_child
+ (GTK_BIN(priv->pwd2ndCaption)));
+ text1 = GTK_ENTRY(pwd1stEntry)->text;
+ text2 = GTK_ENTRY(pwd2ndEntry)->text;
+
+ if (arg1 == GTK_RESPONSE_OK) {
+ /* User provided something for password? */
+ if (text1[0] != '\0') {
+ if (strcmp (text1, text2) == 0) {
+ /* Passwords match, so accept set password */
+ priv->protection = TRUE;
+ } else if (text2[0] == '\0') {
+ /* Second field is empty, so show error,
+ but don't clear the fields */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_widget_grab_focus (GTK_WIDGET (priv->pwd2ndEntry));
+ } else {
+ /* Error: Passwords don't match, so start over */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
+ gtk_entry_set_text(pwd1stEntry, "");
+ gtk_entry_set_text(pwd2ndEntry, "");
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_widget_grab_focus(GTK_WIDGET(priv->pwd1stEntry));
+ }
+ } else {
+ /* First field is empty */
+ g_signal_stop_emission_by_name(G_OBJECT(dialog), "response");
+ if (text2[0] == '\0') {
+ /* Error: Both fields are empty */
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_EMPTY));
+ } else {
+ /* Error: Second field doesn't match
+ the empty first field, so start over */
+ gtk_infoprint (NULL, c_(HILDON_SET_PASSWORD_DIALOG_MISMATCH));
+ gtk_entry_set_text(pwd2ndEntry, "");
+ }
+ gtk_widget_grab_focus(GTK_WIDGET(pwd1stEntry));
+ }
+ } else {
+ /* Watch out for fading boolean values */
+ priv->protection = FALSE;
+ }
+}
+
+static void hildon_checkbox_toggled(GtkWidget * widget, gpointer dialog)
+{
+ HildonSetPasswordDialogPrivate *priv =
+ HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ gboolean active;
+
+ /* If the user enabled/disabled the password protection feature
+ we enable/disable password entries accordingly */
+ active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ gtk_widget_set_sensitive(GTK_WIDGET(priv->pwd1stEntry), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(priv->pwd2ndEntry), active);
+}
+
+/* Public functions */
+
+/**
+ * hildon_set_password_dialog_get_type:
+ *
+ * Returns GType for HildonPasswordDialog as produced by
+ * g_type_register_static().
+ *
+ * Returns: HildonSetPasswordDialog type
+ */
+GType hildon_set_password_dialog_get_type(void)
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonSetPasswordDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_set_password_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonSetPasswordDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_set_password_dialog_init
+ };
+
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonSetPasswordDialog",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+/**
+ * hildon_set_password_dialog_new:
+ * @parent: parent window; can be NULL
+ * @modify_protection: TRUE creates a new change password dialog and FALSE
+ * creates a new set password dialog
+ *
+ * Constructs a new HildonSetPasswordDialog.
+ *
+ * Returns: a new #GtkWidget of type HildonSetPasswordDialog
+ */
+
+GtkWidget *hildon_set_password_dialog_new(GtkWindow * parent,
+ gboolean modify_protection)
+{
+ return hildon_set_password_dialog_new_with_default(parent, "",
+ modify_protection);
+}
+
+/**
+ * hildon_set_password_dialog_new_with_default:
+ * @parent: parent window; can be NULL
+ * @password: a default password to be shown in password field
+ * @modify_protection: TRUE creates a new change password dialog and FALSE
+ * creates a new set password dialog
+ *
+ * Same as #hildon_set_password_dialog_new, but with a default password
+ * in password field.
+ *
+ * Returns: a new #GtkWidget of type HildonSetPasswordDialog
+ */
+
+GtkWidget *hildon_set_password_dialog_new_with_default
+ (GtkWindow *parent,
+ const gchar *password,
+ gboolean modify_protection)
+{
+ GtkWidget *dialog = g_object_new(HILDON_TYPE_SET_PASSWORD_DIALOG,
+ "modify_protection", modify_protection,
+ "password", password, NULL);
+
+ if (parent != NULL) {
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+ }
+
+ return dialog;
+}
+
+/**
+ * hildon_set_password_dialog_get_password:
+ * @dialog: pointer to HildonSetPasswordDialog
+ *
+ * Returns current password.
+ *
+ * Returns: changed password ( if the dialog is successfully
+ * accepted with 'OK' ( and when the check box is 'ON' ( in Change Password
+ * Dialog ))
+ */
+const gchar
+ *hildon_set_password_dialog_get_password(HildonSetPasswordDialog *
+ dialog)
+{
+ HildonSetPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog), NULL);
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ return GTK_ENTRY(priv->pwd1stEntry)->text;
+}
+
+/**
+ * hildon_set_password_dialog_get_protected:
+ * @dialog: pointer to HildonSetPasswordDialog
+ *
+ * Returns the protection mode.
+ *
+ * Returns: password protection mode ( TRUE when the protection is
+ * 'ON' and FALSE when the protection is 'OFF' )
+ */
+gboolean
+hildon_set_password_dialog_get_protected(HildonSetPasswordDialog * dialog)
+{
+ HildonSetPasswordDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog), FALSE);
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+
+ return priv->protection;
+}
+
+/**
+ * hildon_set_password_dialog_set_domain(GtkWidget *dialog,
+ * @dialog: the dialog
+ * @domain: the domain or some other descriptive text to be set
+ *
+ * Sets the optional descriptive text.
+ */
+
+void hildon_set_password_dialog_set_domain(HildonSetPasswordDialog *dialog,
+ const gchar *domain)
+{
+ HildonSetPasswordDialogPrivate *priv = NULL;
+
+ g_return_if_fail(HILDON_IS_SET_PASSWORD_DIALOG(dialog));
+
+ priv = HILDON_SET_PASSWORD_DIALOG_GET_PRIVATE(dialog);
+ gtk_label_set_text(priv->domainLabel, domain);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_SET_PASSWORD_DIALOG_H__
+#define __HILDON_SET_PASSWORD_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+
+#define HILDON_TYPE_SET_PASSWORD_DIALOG \
+ ( hildon_set_password_dialog_get_type() )
+#define HILDON_SET_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_SET_PASSWORD_DIALOG,\
+ HildonSetPasswordDialog))
+#define HILDON_SET_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_SET_PASSWORD_DIALOG, \
+ HildonSetPasswordDialogClass))
+#define HILDON_IS_SET_PASSWORD_DIALOG(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_SET_PASSWORD_DIALOG))
+#define HILDON_IS_SET_PASSWORD_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_SET_PASSWORD_DIALOG))
+
+
+
+#define HILDON_SET_PASSWORD_DIALOG_TITLE "ecdg_ti_set_password"
+#define HILDON_SET_PASSWORD_DIALOG_PASSWORD "ecdg_fi_set_passwd_enter_pwd"
+#define HILDON_SET_PASSWORD_DIALOG_VERIFY_PASSWORD "ecdg_fi_set_passwd_confirm"
+#define HILDON_SET_PASSWORD_DIALOG_OK "ecdg_bd_set_password_dialog_ok"
+#define HILDON_SET_PASSWORD_DIALOG_CANCEL "ecdg_bd_set_password_dialog_cancel"
+
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_TITLE "ckdg_ti_dialog_c_passwd_change_password"
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_LABEL "ckdg_fi_dialog_c_passwd_pwd_protect"
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_PASSWORD "ckdg_fi_dialog_c_passwd_new_pwd"
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_VERIFY_PASSWORD "ckdg_fi_dialog_c_passwd_ver_pwd"
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_OK "ckdg_bd_change_password_dialog_ok"
+#define HILDON_SET_MODIFY_PASSWORD_DIALOG_CANCEL "ckdg_bd_change_password_dialog_cancel"
+
+#define HILDON_SET_PASSWORD_DIALOG_MISMATCH "ecdg_ib_passwords_do_not_match"
+#define HILDON_SET_PASSWORD_DIALOG_EMPTY "ecdg_ib_password_is_empty"
+#define HILDON_SET_PASSWORD_DIALOG_REMOVE_PROTECTION "ckdg_nc_dialog_c_passwd_remove_pwd"
+
+#define HILDON_REMOVE_PROTECTION_CONFIRMATION_REMOVE "ckdg_bd_dialog_c_passwd_remove_button"
+#define HILDON_REMOVE_PROTECTION_CONFIRMATION_CANCEL "ckdg_bd_dialog_c_passwd_cancel_button"
+
+
+
+typedef struct _HildonSetPasswordDialog HildonSetPasswordDialog;
+typedef struct _HildonSetPasswordDialogClass HildonSetPasswordDialogClass;
+
+struct _HildonSetPasswordDialog {
+ GtkDialog parent;
+};
+
+struct _HildonSetPasswordDialogClass {
+ GtkDialogClass parent_class;
+};
+
+
+
+GtkWidget * hildon_set_password_dialog_new (GtkWindow *parent,
+ gboolean modify_protection);
+
+GtkWidget * hildon_set_password_dialog_new_with_default (GtkWindow *parent,
+ const gchar *password,
+ gboolean modify_protection);
+
+GType hildon_set_password_dialog_get_type (void) G_GNUC_CONST;
+
+const gchar *hildon_set_password_dialog_get_password (HildonSetPasswordDialog *dialog);
+
+gboolean hildon_set_password_dialog_get_protected (HildonSetPasswordDialog *dialog);
+
+void hildon_set_password_dialog_set_domain (HildonSetPasswordDialog *dialog,
+ const gchar *domain);
+
+
+G_END_DECLS
+
+#endif /* __HILDON_SET_PASSWORD_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-sort-dialog
+ * @short_description: A widget for defining the sorting order of items
+ *
+ * HildonSortDialog is used to define an order (ascending/descending)
+ * and a field by which items are sorted in a list. The combo boxes
+ * display the current value when the dialog is opened.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libintl.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkbox.h>
+#include <hildon-widgets/hildon-caption.h>
+#include "hildon-sort-dialog.h"
+
+
+#define _(String) dgettext(PACKAGE, String)
+
+static GtkDialogClass *parent_class;
+
+#define HILDON_SORT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), HILDON_TYPE_SORT_DIALOG, HildonSortDialogPrivate));
+
+typedef struct _HildonSortDialogPrivate HildonSortDialogPrivate;
+
+static void hildon_sort_dialog_class_init(HildonSortDialogClass * class);
+static void hildon_sort_dialog_init(HildonSortDialog * widget);
+static void hildon_sort_dialog_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_sort_dialog_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec);
+static void reconstruct_combo (HildonSortDialog * dialog,
+ gboolean remove,
+ gboolean reversed);
+static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog,
+ const gchar * sort_key,
+ gboolean sorting);
+static void sort_key_changed(GtkWidget * widget,
+ HildonSortDialog * dialog);
+static void hildon_sort_dialog_finalize(GObject * object);
+
+enum {
+ PROP_0,
+ PROP_SORT_KEY,
+ PROP_SORT_ORDER
+};
+
+/* private data */
+struct _HildonSortDialogPrivate {
+ /* Sort category widgets */
+ GtkWidget *combo_key;
+ GtkWidget *caption_key;
+
+ /* Sort order widgets */
+ GtkWidget *combo_order;
+ GtkWidget *caption_order;
+
+ /* Index value counter */
+ gint index_counter;
+
+ /* If the current order displayed is reversed */
+ gboolean reversed;
+
+ /* An array for each key representing if a key should be reverse-sorted */
+ gboolean *key_reversed;
+};
+
+/* Private functions */
+
+static void sort_key_changed(GtkWidget * widget, HildonSortDialog * dialog)
+{
+ g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
+
+ HildonSortDialogPrivate *priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+
+ gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+
+ if (priv->key_reversed [index] != priv->reversed) {
+ reconstruct_combo (dialog, TRUE, priv->key_reversed [index]);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
+ }
+
+ priv->reversed = priv->key_reversed [index];
+}
+
+/*
+ * Initialises the sort dialog class.
+ */
+static void hildon_sort_dialog_class_init(HildonSortDialogClass * class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+ parent_class = g_type_class_peek_parent(class);
+ g_type_class_add_private(class, sizeof(HildonSortDialogPrivate));
+
+ gobject_class->set_property = hildon_sort_dialog_set_property;
+ gobject_class->get_property = hildon_sort_dialog_get_property;
+ gobject_class->finalize = (gpointer) hildon_sort_dialog_finalize;
+
+ g_object_class_install_property(gobject_class, PROP_SORT_KEY,
+ g_param_spec_int("sort-key",
+ "Sort Key",
+ "The currently active sort key",
+ G_MININT,
+ G_MAXINT,
+ 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class, PROP_SORT_ORDER,
+ g_param_spec_enum("sort-order",
+ "Sort Order",
+ "The current sorting order",
+ GTK_TYPE_SORT_TYPE,
+ GTK_SORT_ASCENDING,
+ G_PARAM_READWRITE));
+}
+
+static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog, const gchar * sort_key, gboolean sorting)
+{
+ HildonSortDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+ gboolean *new_array = g_malloc (sizeof (gboolean) * (priv->index_counter + 1));
+
+ /* Rewrite the old values */
+ int i = 0;
+ for (i = 0; i < priv->index_counter; i++)
+ new_array [i] = priv->key_reversed [i];
+
+ new_array [priv->index_counter] = sorting;
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_key), sort_key);
+
+ /* Free the old one and reassign */
+ if (priv->key_reversed != NULL)
+ g_free (priv->key_reversed);
+ priv->key_reversed = new_array;
+
+ return priv->index_counter++;
+}
+
+static void reconstruct_combo (HildonSortDialog * dialog, gboolean remove, gboolean reversed)
+{
+ HildonSortDialogPrivate *priv;
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+
+ if (remove) {
+ gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 1);
+ gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 0);
+ }
+
+ if (reversed) {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
+ } else {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
+ gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
+ }
+}
+
+static void hildon_sort_dialog_init(HildonSortDialog * dialog)
+{
+ HildonSortDialogPrivate *priv;
+ GtkSizeGroup *group;
+
+ g_assert(HILDON_IS_SORT_DIALOG(dialog));
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+
+ priv->index_counter = 0;
+ priv->reversed = FALSE;
+ priv->key_reversed = NULL;
+
+ group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
+
+ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
+ gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+ gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_sort"));
+
+ /* Tab one */
+ priv->combo_key = gtk_combo_box_new_text();
+ priv->caption_key = hildon_caption_new(group, _("ckdg_fi_sort_field"), priv->combo_key,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ hildon_caption_set_separator(HILDON_CAPTION(priv->caption_key), "");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->caption_key, FALSE, FALSE, 0);
+
+ /* Tab two */
+ priv->combo_order = gtk_combo_box_new_text();
+ reconstruct_combo (dialog, FALSE, FALSE);
+
+ priv->caption_order = hildon_caption_new(group, _("ckdg_fi_sort_order"),
+ priv->combo_order,
+ NULL, HILDON_CAPTION_OPTIONAL);
+ hildon_caption_set_separator(HILDON_CAPTION(priv->caption_order), "");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ priv->caption_order, FALSE, FALSE, 0);
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_key), 0);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
+ g_signal_connect (G_OBJECT (priv->combo_key), "changed", (gpointer) sort_key_changed, dialog);
+
+ /* Create the OK/CANCEL buttons */
+ (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
+ _("ckdg_bd_sort_dialog_ok"),
+ GTK_RESPONSE_OK);
+ (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
+ _("ckdg_bd_sort_dialog_cancel"),
+ GTK_RESPONSE_CANCEL);
+ /* FIXME: Hardcoded sizes are bad */
+ gtk_window_resize(GTK_WINDOW(dialog), 370, 100);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+
+ g_object_unref(group); /* Captions now own their references to sizegroup */
+}
+
+/* Public functions */
+
+/**
+ * hildon_sort_dialog_get_type:
+ *
+ * Returns GType for HildonSortDialog as produced by
+ * g_type_register_static().
+ *
+ * Returns: HildonSortDialog type
+ */
+GType hildon_sort_dialog_get_type()
+{
+ static GType dialog_type = 0;
+
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info = {
+ sizeof(HildonSortDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_sort_dialog_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonSortDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_sort_dialog_init
+ };
+
+ dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
+ "HildonSortDialog",
+ &dialog_info, 0);
+ }
+ return dialog_type;
+}
+
+/**
+ * hildon_sort_dialog_new:
+ * @parent: widget to be transient for, or NULL if none
+ *
+ * HildonSortDialog contains two HildonCaptions with combo boxes.
+ *
+ * Returns: pointer to a new @HildonSortDialog widget
+ */
+GtkWidget *hildon_sort_dialog_new(GtkWindow * parent)
+{
+ GtkWidget *sort_dialog = g_object_new(HILDON_TYPE_SORT_DIALOG, NULL);
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(sort_dialog), parent);
+
+ return sort_dialog;
+}
+
+/**
+ * hildon_sort_dialog_get_sort_key:
+ * @dialog: the #HildonSortDialog widget
+ *
+ * Gets index to currently active sort key.
+ *
+ * Returns: an integer which is the index value of the "Sort by"
+ * field
+ */
+gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog)
+{
+ GtkWidget *combo_key;
+ HildonSortDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+
+ combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
+
+ return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_key));
+}
+
+/**
+ * hildon_sort_dialog_get_sort_order:
+ * @dialog: the #HildonSortDialog widget
+ *
+ * Gets current sorting order from "Sort order" field.
+ *
+ * Returns: current sorting order as #GtkSortType
+ */
+GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog)
+{
+ GtkWidget *combo_order;
+ HildonSortDialogPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), 0);
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+ combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
+
+ gint sort_order = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_order));
+
+ if (priv->reversed)
+ return (sort_order == 0) ? 1 : 0;
+ else
+ return sort_order;
+}
+
+/**
+ * hildon_sort_dialog_set_sort_key:
+ * @dialog: the #HildonSortDialog widget
+ * @key: combo box's index value
+ *
+ * Sets the index value of the #HildonSortDialog widget.
+ */
+void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key)
+{
+ GtkWidget *combo_key;
+ HildonSortDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+ combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_key), key);
+
+ g_object_notify (G_OBJECT (dialog), "sort-key");
+}
+
+/**
+ * hildon_sort_dialog_set_sort_order:
+ * @dialog: the #HildonSortDialog widget
+ * @order: combo box's index value
+ *
+ * Sets the index value of the #HildonSortDialog widget.
+ */
+void
+hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
+ GtkSortType order)
+{
+ GtkWidget *combo_order;
+ HildonSortDialogPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+ combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
+
+ if (priv->reversed)
+ order = (order == 0) ? 1 : 0;
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo_order), order);
+
+ g_object_notify (G_OBJECT (dialog), "sort-order");
+}
+
+/**
+ * hildon_sort_dialog_add_sort_key:
+ * @dialog: the #HildonSortDialog widget
+ * @sort_key: combo box's index value
+ *
+ * Adds a new sort key and returns the respective index in
+ * sort key combobox.
+ *
+ * Returns: an integer which is the index of the added combo box's
+ * item
+ */
+gint
+hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
+ const gchar * sort_key)
+{
+ return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, FALSE);
+}
+
+/**
+ * hildon_sort_dialog_add_sort_key_reversed:
+ * @dialog: the #HildonSortDialog widget
+ * @sort_key: combo box's index value
+ *
+ * Adds a new sort key and returns the respective index in
+ * sort key combobox. The default sort order for this key is reversed (Descending first).
+ *
+ * Returns: an integer which is the index of the added combo box's
+ * item
+ *
+ * Since: 0.14.1
+ */
+gint
+hildon_sort_dialog_add_sort_key_reversed(HildonSortDialog * dialog,
+ const gchar * sort_key)
+{
+ return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, TRUE);
+}
+
+static void
+hildon_sort_dialog_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ HildonSortDialog *dialog;
+
+ dialog = HILDON_SORT_DIALOG(object);
+
+ switch (prop_id) {
+ case PROP_SORT_KEY:
+ hildon_sort_dialog_set_sort_key(dialog, g_value_get_int(value));
+ break;
+ case PROP_SORT_ORDER:
+ hildon_sort_dialog_set_sort_order(dialog, g_value_get_enum(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_sort_dialog_get_property(GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ HildonSortDialog *dialog;
+
+ dialog = HILDON_SORT_DIALOG(object);
+
+ switch (prop_id) {
+ case PROP_SORT_KEY:
+ g_value_set_int(value, hildon_sort_dialog_get_sort_key(dialog));
+ break;
+ case PROP_SORT_ORDER:
+ g_value_set_enum(value, hildon_sort_dialog_get_sort_order(dialog));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_sort_dialog_finalize(GObject * object)
+{
+ HildonSortDialogPrivate *priv;
+ HildonSortDialog *dialog;
+
+ g_return_if_fail (HILDON_IS_SORT_DIALOG (object));
+ dialog = HILDON_SORT_DIALOG(object);
+
+ priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
+ if (priv != NULL && priv->key_reversed != NULL)
+ g_free(priv->key_reversed);
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_SORT_DIALOG_H__
+#define __HILDON_SORT_DIALOG_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+#define HILDON_TYPE_SORT_DIALOG \
+ ( hildon_sort_dialog_get_type() )
+#define HILDON_SORT_DIALOG(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_SORT_DIALOG, HildonSortDialog))
+#define HILDON_SORT_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_SORT_DIALOG, \
+ HildonSortDialogClass))
+#define HILDON_IS_SORT_DIALOG(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_SORT_DIALOG))
+#define HILDON_IS_SORT_DIALOG_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_SORT_DIALOG))
+typedef struct _HildonSortDialog HildonSortDialog;
+typedef struct _HildonSortDialogClass HildonSortDialogClass;
+
+
+
+struct _HildonSortDialog {
+ GtkDialog parent;
+};
+
+struct _HildonSortDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType hildon_sort_dialog_get_type(void) G_GNUC_CONST;
+
+
+GtkWidget *hildon_sort_dialog_new(GtkWindow * parent);
+gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog);
+GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog);
+void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key);
+void hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
+ GtkSortType order);
+gint hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
+ const gchar * sort_key);
+
+G_END_DECLS
+#endif /* __HILDON_SORT_DIALOG_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-system-sound
+ * @short_description: An esd-based utility function for playing a sound
+ *
+ * HildonSystemSound is an esd-based utility function for playing a sound
+ * from the system sounds directory with volume taken from GConf.
+ */
+
+#include <gconf/gconf-client.h>
+#include <esd.h>
+#include "hildon-system-sound.h"
+
+#define ALARM_GCONF_PATH "/apps/osso/sound/system_alert_volume"
+
+/**
+ * hildon_play_system_sound:
+ * @sample: sound file to play
+ *
+ * Plays the given sample using esd sound daemon.
+ * Volume level is received from gconf.
+ */
+void hildon_play_system_sound(const gchar *sample)
+{
+ GConfClient *client;
+ GConfValue *value;
+ gint volume, scale, sock, sample_id;
+
+ client = gconf_client_get_default();
+ value = gconf_client_get(client, ALARM_GCONF_PATH, NULL);
+
+ /* We want error cases to match full volume, not silence, so
+ we do not want to use gconf_client_get_int */
+ if (!value || value->type != GCONF_VALUE_INT)
+ volume = 2;
+ else
+ volume = gconf_value_get_int(value);
+
+ if (value)
+ gconf_value_free(value);
+ g_object_unref(client);
+
+ switch (volume)
+ {
+ case 0:
+ return;
+ case 1:
+ scale = 0x80;
+ break;
+ case 2:
+ default:
+ scale = 0xff;
+ break;
+ };
+
+ sock = esd_open_sound(NULL);
+ if (sock <= 0)
+ return;
+
+ sample_id = esd_file_cache(sock, g_get_prgname(), sample);
+ if (sample_id < 0) {
+ close(sock);
+ return;
+ }
+
+ esd_set_default_sample_pan(sock, sample_id, scale, scale);
+ esd_sample_play(sock, sample_id);
+ esd_sample_free(sock, sample_id);
+ close(sock);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_SYSTEM_SOUND_H__
+#define __HILDON_SYSTEM_SOUND_H__
+
+G_BEGIN_DECLS
+
+void hildon_play_system_sound(const gchar *sample);
+
+G_END_DECLS
+#endif /* __HILDON_SYSTEM_SOUND_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-telephone-editor.c
+ * @short_description: A widget which allows users to enter telephone numbers
+ *
+ * A single-line editor which allows user to enter a telephone number.
+ * There are two modes to choose from (coerce/free format).
+ * Coerce format has three fields which are placed horizontally.
+ * The fields are: country code, area code and number. When nothing is
+ * entered in the fields, assisting text is displayed. Tapping on the
+ * field highlights the field and allows users to input numbers.
+ *
+ * The widget is used where a user should enter a phone number. Free format
+ * should be used wherever possible as it enables the user to enter the
+ * phone number in the format she likes. Free format also supports DTMF
+ * strings as a part of the phone number. The format can not be changed
+ * at runtime.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <libintl.h>
+#include <string.h>
+#include "hildon-telephone-editor.h"
+#include "hildon-composite-widget.h"
+
+#define _(String) gettext (String)
+#define HILDON_TELEPHONE_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TELEPHONE_EDITOR_TYPE, HildonTelephoneEditorPriv));
+
+#define AREA_LEN 4
+#define COUNTRY_LEN 7
+#define NUMBER_LEN 10
+
+#define AREA_STR "Area"
+#define COUNTRY_STR "Country"
+#define NUMBER_STR "Number"
+
+typedef struct _HildonTelephoneEditorPriv HildonTelephoneEditorPriv;
+
+enum {
+ PROP_0,
+ PROP_COUNTRY_STR,
+ PROP_AREA_STR,
+ PROP_NUMBER_STR,
+ PROP_SHOW_BORDER,
+ PROP_SHOW_PLUS,
+ PROP_FORMAT
+};
+
+/*< private >*/
+struct _HildonTelephoneEditorPriv {
+ HildonTelephoneEditorFormat format; /* format of the editor */
+
+ gboolean edited_country; /* is the country edited */
+ gboolean edited_area; /* is the area edited */
+ gboolean edited_number; /* is the number edited */
+
+ gboolean editable_country; /* is the country editable */
+ gboolean editable_area; /* is the area editable */
+ gboolean editable_number; /* is the number editable */
+
+ gboolean show_plus; /* show '+' sign in country */
+ gboolean show_border; /* show border around the widget */
+
+ GtkWidget *frame; /* frame for border lines */
+ GtkWidget *plus; /* + in front of country code */
+ GtkWidget *plus_event; /* event box for the + -label */
+ GtkWidget *country; /* country code */
+ GtkWidget *area; /* area code */
+ GtkWidget *number; /* telephone number */
+
+ gint j;
+};
+
+
+static GtkContainerClass *parent_class;
+
+static void
+hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
+ editor_class);
+
+static void
+hildon_telephone_editor_init(HildonTelephoneEditor * editor);
+
+static void
+hildon_telephone_editor_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void
+hildon_telephone_editor_destroy(GtkObject * self);
+
+static void
+hildon_telephone_editor_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+
+static void
+hildon_telephone_editor_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+
+static gboolean
+hildon_telephone_editor_button_release(GtkWidget * widget,
+ GdkEventButton * event,
+ gpointer data);
+static void
+hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
+ gboolean edited,
+ gboolean move_left);
+static gboolean
+hildon_telephone_editor_entry_keypress(GtkWidget * widget,
+ GdkEventKey * event, gpointer data);
+
+static gboolean
+hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
+ gboolean group_cycling);
+
+static void
+hildon_telephone_editor_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void
+hildon_telephone_editor_get_property(GObject * object,
+ guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+GType hildon_telephone_editor_get_type(void)
+{
+ static GType editor_type = 0;
+
+ if (!editor_type) {
+ static const GTypeInfo editor_info = {
+ sizeof(HildonTelephoneEditorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_telephone_editor_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonTelephoneEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_telephone_editor_init,
+ };
+ editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonTelephoneEditor",
+ &editor_info, 0);
+ }
+ return editor_type;
+}
+
+static void
+hildon_telephone_editor_class_init(HildonTelephoneEditorClass *
+ editor_class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
+ GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
+
+ parent_class = g_type_class_peek_parent(editor_class);
+
+ g_type_class_add_private(editor_class, sizeof(HildonTelephoneEditorPriv));
+
+ widget_class->size_request = hildon_telephone_editor_size_request;
+ widget_class->size_allocate = hildon_telephone_editor_size_allocate;
+ container_class->forall = hildon_telephone_editor_forall;
+ widget_class->mnemonic_activate = hildon_telephone_editor_mnemonic_activate;
+ widget_class->focus = hildon_composite_widget_focus;
+ object_class->set_property = hildon_telephone_editor_set_property;
+ object_class->get_property = hildon_telephone_editor_get_property;
+
+ GTK_OBJECT_CLASS(editor_class)->destroy = hildon_telephone_editor_destroy;
+
+ /* Install properties */
+ g_object_class_install_property(object_class, PROP_COUNTRY_STR,
+ g_param_spec_string("country",
+ ("Country string"),
+ ("Country string"),
+ COUNTRY_STR, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_AREA_STR,
+ g_param_spec_string("area",
+ ("Area string"),
+ ("Area string"),
+ AREA_STR, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_NUMBER_STR,
+ g_param_spec_string("number",
+ ("Number string"),
+ ("Number string"),
+ NUMBER_STR, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_SHOW_BORDER,
+ g_param_spec_boolean ("show-border",
+ "Show Border",
+ "Wether to show the border around the widget",
+ TRUE, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_SHOW_PLUS,
+ g_param_spec_boolean ("show-plus",
+ "Show Plus",
+ "Wether to show the plus sign in front of"
+ " coerce format's country field",
+ TRUE, G_PARAM_READWRITE));
+
+ g_object_class_install_property(object_class, PROP_FORMAT,
+ g_param_spec_int("set-format",
+ ("Format"),
+ ("Sets telephoneditor format"),
+ HILDON_TELEPHONE_EDITOR_FORMAT_FREE,
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA,
+ 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
+}
+
+static void
+hildon_telephone_editor_init(HildonTelephoneEditor * editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ gboolean use_frames = FALSE; /* in entries, for debug purposes */
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ priv->frame = gtk_frame_new(NULL);
+ priv->plus = gtk_label_new("+");
+ priv->plus_event = gtk_event_box_new();
+ priv->country = gtk_entry_new();
+ priv->area = gtk_entry_new();
+ priv->number = gtk_entry_new();
+ priv->edited_country = FALSE;
+ priv->edited_area = FALSE;
+ priv->edited_number = FALSE;
+ priv->show_plus = TRUE;
+ priv->show_border = TRUE;
+ priv->editable_country = TRUE;
+ priv->editable_area = TRUE;
+ priv->editable_number = TRUE;
+
+ gtk_container_add(GTK_CONTAINER(priv->plus_event), priv->plus);
+
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->country), use_frames);
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->area), use_frames);
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->number), use_frames);
+
+ gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
+ gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
+
+ hildon_telephone_editor_set_widths(editor, COUNTRY_LEN, AREA_LEN,
+ NUMBER_LEN);
+
+ /* set signals for country entry */
+ gtk_signal_connect(GTK_OBJECT(priv->country), "button_release_event",
+ G_CALLBACK(hildon_telephone_editor_button_release),
+ editor);
+
+ gtk_signal_connect(GTK_OBJECT(priv->country), "key-press-event",
+ G_CALLBACK(hildon_telephone_editor_entry_keypress),
+ editor);
+
+ /* set signals for plus label */
+ gtk_signal_connect(GTK_OBJECT(priv->plus_event), "button_press_event",
+ G_CALLBACK(hildon_telephone_editor_button_release),
+ editor);
+
+ /* set signals for area entry */
+ gtk_signal_connect(GTK_OBJECT(priv->area), "button_release_event",
+ G_CALLBACK(hildon_telephone_editor_button_release),
+ editor);
+
+ gtk_signal_connect(GTK_OBJECT(priv->area), "key-press-event",
+ G_CALLBACK(hildon_telephone_editor_entry_keypress),
+ editor);
+
+ /* set signals for number entry */
+ gtk_signal_connect(GTK_OBJECT(priv->number), "button_release_event",
+ G_CALLBACK(hildon_telephone_editor_button_release),
+ editor);
+
+ gtk_signal_connect(GTK_OBJECT(priv->number), "key-press-event",
+ G_CALLBACK(hildon_telephone_editor_entry_keypress),
+ editor);
+
+ GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
+
+ gtk_widget_show(priv->number);
+ gtk_widget_show(priv->area);
+ gtk_widget_show(priv->country);
+ gtk_widget_show_all(priv->frame);
+ gtk_widget_show_all(priv->plus_event);
+}
+
+/**
+ * hildon_telephone_editor_new:
+ * @format: format of the editor
+ *
+ * Creates a new #HildonTelephoneEditor. The editor can be in a free
+ * format where the user can type in country code, area code and the
+ * phone number and can type in other characters than just digits. In
+ * coerse format the editor has fields where the user can input only
+ * digits. See #HildonTelephoneEditorFormat for the different coerse
+ * formats.
+ *
+ * Returns: new #HildonTelephoneEditor
+ */
+GtkWidget *
+hildon_telephone_editor_new(HildonTelephoneEditorFormat format)
+{
+
+ HildonTelephoneEditor *editor;
+
+ editor =
+ g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
+ "set-country", _(COUNTRY_STR), "set-area",
+ _(AREA_STR), "set-number", _(NUMBER_STR), NULL);
+
+ return GTK_WIDGET(editor);
+}
+
+/**
+ * hildon_telephone_editor_new_with_strings:
+ * @format: format of the editor
+ * @country: default text for the country field
+ * @area: default text for the area field
+ * @number: default text for the number field
+ *
+ * Creates a new #HildonTelephoneEditor. See hildon_telephone_editor_new
+ * for details.
+ *
+ * Returns: new #HildonTelephoneEditor
+ */
+GtkWidget *
+hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
+ format,
+ const gchar * country,
+ const gchar * area,
+ const gchar * number)
+{
+ HildonTelephoneEditor *editor;
+
+ editor =
+ g_object_new(HILDON_TELEPHONE_EDITOR_TYPE, "set-format", format,
+ "set-country", country, "set-area", area,
+ "set-number", number, NULL);
+
+ return GTK_WIDGET(editor);
+}
+
+static void
+hildon_telephone_editor_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+
+ editor = HILDON_TELEPHONE_EDITOR (object);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_COUNTRY_STR:
+ g_value_set_string(value,
+ hildon_telephone_editor_get_country(editor));
+ break;
+ case PROP_AREA_STR:
+ g_value_set_string(value,
+ hildon_telephone_editor_get_area(editor));
+ break;
+ case PROP_NUMBER_STR:
+ g_value_set_string(value,
+ hildon_telephone_editor_get_number(editor));
+ break;
+ case PROP_SHOW_BORDER:
+ g_value_set_boolean(value,
+ hildon_telephone_editor_get_show_border(editor));
+ break;
+ case PROP_SHOW_PLUS:
+ g_value_set_boolean(value,
+ hildon_telephone_editor_get_show_plus(editor));
+ break;
+ case PROP_FORMAT:
+ g_value_set_int(value, priv->format);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_telephone_editor_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+
+ editor = HILDON_TELEPHONE_EDITOR (object);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_COUNTRY_STR:
+ hildon_telephone_editor_set_country(editor,
+ _(g_value_get_string(value)));
+ break;
+ case PROP_AREA_STR:
+ hildon_telephone_editor_set_area(editor,
+ _(g_value_get_string(value)));
+ break;
+ case PROP_NUMBER_STR:
+ hildon_telephone_editor_set_number(editor,
+ _(g_value_get_string(value)));
+ break;
+ case PROP_SHOW_BORDER:
+ hildon_telephone_editor_set_show_border(
+ editor, g_value_get_boolean(value));
+ break;
+ case PROP_SHOW_PLUS:
+ hildon_telephone_editor_set_show_plus(
+ editor, g_value_get_boolean(value));
+ break;
+ case PROP_FORMAT:
+ priv->format = g_value_get_int(value);
+ if (priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ gtk_entry_set_text(GTK_ENTRY(priv->number), _(NUMBER_STR));
+
+ /* set proper fields according to selected format */
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ gtk_widget_set_parent(priv->area, GTK_WIDGET(object));
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ gtk_widget_set_parent(priv->country, GTK_WIDGET(object));
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ gtk_widget_set_parent(priv->number, GTK_WIDGET(object));
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+hildon_telephone_editor_mnemonic_activate( GtkWidget *widget,
+ gboolean group_cycling)
+{
+ HildonTelephoneEditorPriv *priv;
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(widget);
+
+ if (!GTK_CONTAINER(widget)->focus_child)
+ {
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ {
+ gtk_widget_grab_focus(priv->number);
+
+ if (priv->editable_number && !priv->edited_number)
+ gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
+ }
+ else
+ {
+ if (priv->editable_country)
+ {
+ gtk_widget_grab_focus(priv->country);
+ if (!priv->edited_country)
+ gtk_editable_select_region(GTK_EDITABLE(priv->country), 0, -1);
+ }
+ else if ((priv->editable_area) && (priv->format !=
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY))
+ {
+ gtk_widget_grab_focus(priv->area);
+ if (!priv->edited_area)
+ gtk_editable_select_region(GTK_EDITABLE(priv->area), 0, -1);
+ }
+ else if ((priv->editable_number) && (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE))
+ {
+ gtk_widget_grab_focus(priv->number);
+ if (!priv->edited_number)
+ gtk_editable_select_region(GTK_EDITABLE(priv->number), 0, -1);
+ }
+ else
+ gtk_widget_grab_focus(priv->country);
+ }
+ }
+ return TRUE;
+}
+
+static void
+hildon_telephone_editor_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+
+ editor = HILDON_TELEPHONE_EDITOR(container);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ g_return_if_fail(container);
+ g_return_if_fail(callback);
+
+ if (!include_internals)
+ return;
+
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ (*callback) (priv->number, callback_data);
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ (*callback) (priv->area, callback_data);
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ (*callback) (priv->country, callback_data);
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ (*callback) (priv->number, callback_data);
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ if (priv->show_plus)
+ (*callback) (priv->plus_event, callback_data);
+
+ if (priv->show_border)
+ (*callback) (priv->frame, callback_data);
+
+}
+
+static void
+hildon_telephone_editor_destroy(GtkObject * self)
+{
+ HildonTelephoneEditorPriv *priv;
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(self);
+
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ if (priv->number) {
+ gtk_widget_unparent(priv->number);
+ priv->number = NULL;
+ }
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ if (priv->area) {
+ gtk_widget_unparent(priv->area);
+ priv->area = NULL;
+ }
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ if (priv->country) {
+ gtk_widget_unparent(priv->country);
+ priv->country = NULL;
+ }
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ if (priv->number) {
+ gtk_widget_unparent(priv->number);
+ priv->number = NULL;
+ }
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ if (priv->plus_event) {
+ gtk_widget_unparent(priv->plus_event);
+ priv->plus_event = NULL;
+ }
+ if (priv->frame) {
+ gtk_widget_unparent(priv->frame);
+ priv->frame = NULL;
+ }
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+static void
+hildon_telephone_editor_size_request(GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+ GtkRequisition req;
+
+ g_return_if_fail(requisition);
+
+ editor = HILDON_TELEPHONE_EDITOR(widget);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ if (priv->show_border)
+ gtk_widget_size_request(priv->frame, requisition);
+
+ requisition->width = 0;
+ requisition->height = 0;
+
+ switch (priv->format)
+ {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ gtk_widget_size_request(priv->number, &req);
+ requisition->width += req.width;
+ if (requisition->height < req.height)
+ requisition->height = req.height;
+
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ gtk_widget_size_request(priv->area, &req);
+ requisition->width += req.width;
+ if (requisition->height < req.height)
+ requisition->height = req.height;
+
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ gtk_widget_size_request(priv->country, &req);
+ requisition->width += req.width;
+ if (requisition->height < req.height)
+ requisition->height = req.height;
+
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ gtk_widget_size_request(priv->number, &req);
+ requisition->width += req.width;
+ if (requisition->height < req.height)
+ requisition->height = req.height;
+
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ if (priv->show_plus)
+ {
+ gtk_widget_size_request(priv->plus_event, &req);
+ requisition->width += req.width;
+ if (requisition->height < req.height)
+ requisition->height = req.height;
+ }
+
+ requisition->width += GTK_CONTAINER(priv->frame)->border_width * 2;
+ requisition->height += GTK_CONTAINER(priv->frame)->border_width * 2;
+}
+
+static void
+hildon_telephone_editor_size_allocate(GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+ gint header_x = 6, frame_w = 12;
+ GtkAllocation alloc, country_alloc, area_alloc, number_alloc;
+ GtkRequisition requisition, country_requisition, area_requisition,
+ number_requisition;
+
+ g_return_if_fail(widget);
+ g_return_if_fail(allocation);
+
+ if (allocation->height < 0 )
+ allocation->height = 0;
+
+ widget->allocation = *allocation;
+
+ header_x += allocation->x;
+ editor = HILDON_TELEPHONE_EDITOR(widget);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+
+ if (priv->show_plus &&
+ priv->format != HILDON_TELEPHONE_EDITOR_FORMAT_FREE) {
+ gtk_widget_get_child_requisition(priv->plus_event, &requisition);
+
+ alloc.x = header_x;
+ alloc.y = allocation->y + 1;
+ alloc.width = requisition.width;
+ alloc.height = requisition.height;
+
+ header_x += alloc.width;
+ gtk_widget_size_allocate(priv->plus_event, &alloc);
+ frame_w += alloc.width;
+ }
+
+ gtk_widget_get_child_requisition(priv->number, &number_requisition);
+
+ number_alloc.width = number_requisition.width;
+
+ number_alloc.height = allocation->height - 4 -
+ GTK_CONTAINER(priv->frame)->border_width * 2;
+
+ /* get sizes */
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ gtk_widget_get_child_requisition(priv->area, &area_requisition);
+
+ area_alloc.width = area_requisition.width;
+ area_alloc.height = number_alloc.height;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ gtk_widget_get_child_requisition(priv->country, &country_requisition);
+
+ country_alloc.width = country_requisition.width;
+ country_alloc.height = number_alloc.height;
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+
+ /* allocate in coerce formats */
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ number_alloc.x = header_x + country_alloc.width + area_alloc.width;
+ number_alloc.y = allocation->y + 1;
+
+ gtk_widget_size_allocate(priv->number, &number_alloc);
+ frame_w += number_alloc.width;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ area_alloc.x = header_x + country_alloc.width;
+ area_alloc.y = allocation->y + 1;
+
+ gtk_widget_size_allocate(priv->area, &area_alloc);
+ frame_w += area_alloc.width;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ country_alloc.x = header_x;
+ country_alloc.y = allocation->y + 1;
+
+ gtk_widget_size_allocate(priv->country, &country_alloc);
+ frame_w += country_alloc.width;
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ number_alloc.x = header_x;
+ number_alloc.y = allocation->y + 1;
+
+ gtk_widget_size_allocate(priv->number, &number_alloc);
+ frame_w += number_alloc.width;
+ break;
+ default:
+ g_return_if_reached();
+ }
+
+ if (priv->show_border)
+ {
+ alloc.x = allocation->x;
+ alloc.y = allocation->y;
+
+ alloc.width = frame_w - 4;
+
+ alloc.height = allocation->height;
+ gtk_widget_size_allocate( GTK_WIDGET(priv->frame), &alloc );
+ }
+}
+
+static gboolean
+hildon_telephone_editor_button_release(GtkWidget * widget,
+ GdkEventButton * event, gpointer data)
+{
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+ return FALSE;
+}
+
+static void
+hildon_telephone_editor_focus_dest_entry(GtkWidget * widget,
+ gboolean edited,
+ gboolean move_left)
+{
+ /* full coerse mode, wrap to field */
+ gtk_widget_grab_focus(widget);
+
+ if (move_left)
+ gtk_editable_set_position(GTK_EDITABLE(widget), -1);
+ else
+ gtk_editable_set_position(GTK_EDITABLE(widget), 0);
+ /* new field not yet edited, select all */
+ if (!edited)
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+}
+
+static gboolean
+hildon_telephone_editor_entry_keypress(GtkWidget * widget,
+ GdkEventKey * event, gpointer data)
+{
+ HildonTelephoneEditor *editor;
+ HildonTelephoneEditorPriv *priv;
+ gint pos, width;
+ gint cpos, start, end;
+
+ g_return_val_if_fail(widget, FALSE);
+ g_return_val_if_fail(event, FALSE);
+ g_return_val_if_fail(data, FALSE);
+
+ editor = HILDON_TELEPHONE_EDITOR(data);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+ cpos = gtk_editable_get_position(GTK_EDITABLE(widget));
+ gtk_editable_get_selection_bounds(GTK_EDITABLE(widget), &start, &end);
+
+ if( event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||
+ event->keyval == GDK_Down || event->keyval == GDK_KP_Down )
+ return FALSE;
+
+ /* Wrap around should not happen; that's why following code */
+ switch (priv->format) {
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE:
+ if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
+ (widget == priv->country) && ((cpos == 0) ||
+ ((start == 0 && end == strlen(GTK_ENTRY(priv->country)->text)))))
+ ||
+ ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
+ && (widget == priv->number)
+ && (cpos >= strlen(GTK_ENTRY(priv->number)->text))))
+ return TRUE;
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA:
+ if (((event->keyval == GDK_Left || event->keyval == GDK_KP_Left) &&
+ (widget == priv->country) && ((cpos == 0) ||
+ ((start == 0
+ && end ==
+ strlen(GTK_ENTRY
+ (priv->country)->
+ text)))))
+ ||
+ ((event->keyval == GDK_Right || event->keyval == GDK_KP_Right)
+ && (widget == priv->area)
+ && (cpos >= strlen(GTK_ENTRY(priv->area)->text))))
+ return TRUE;
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY:
+ break;
+ case HILDON_TELEPHONE_EDITOR_FORMAT_FREE:
+ break;
+ }
+
+ /* valid key pressed */
+ if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left ||
+ event->keyval == GDK_Right || event->keyval == GDK_KP_Right ||
+ event->keyval == GDK_BackSpace || event->keyval == GDK_Delete ||
+ event->keyval == GDK_KP_Delete ||
+ (event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
+ (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
+ (event->keyval == GDK_slash || event->keyval == GDK_space ||
+ event->keyval == GDK_parenleft || event->keyval == GDK_parenright
+ || event->keyval == GDK_period || event->keyval == GDK_hyphen
+ || event->keyval == GDK_plus || event->keyval == GDK_asterisk
+ || event->keyval == GDK_KP_Multiply
+ || event->keyval == GDK_KP_Add || event->keyval == GDK_numbersign
+ || event->keyval == GDK_question || event->keyval == GDK_KP_Subtract
+ || event->keyval == GDK_minus)))
+ {
+ if ((event->keyval >= GDK_0 && event->keyval <= GDK_9) ||
+ (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
+ (event->keyval == GDK_slash || event->keyval == GDK_space ||
+ event->keyval == GDK_parenleft ||
+ event->keyval == GDK_parenright ||
+ event->keyval == GDK_period || event->keyval == GDK_hyphen ||
+ event->keyval == GDK_plus || event->keyval == GDK_asterisk ||
+ event->keyval == GDK_KP_Add ||
+ event->keyval == GDK_KP_Multiply ||
+ event->keyval == GDK_numbersign ||
+ event->keyval == GDK_question ||
+ event->keyval == GDK_KP_Subtract ||
+ event->keyval == GDK_minus)))
+ {
+ if (widget == priv->country)
+ priv->edited_country = TRUE;
+ if (widget == priv->area)
+ priv->edited_area = TRUE;
+ if (widget == priv->number)
+ priv->edited_number = TRUE;
+ }
+
+ pos = gtk_editable_get_position(GTK_EDITABLE(widget));
+
+ /* going left */
+ if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) {
+ /* not yet on the left edge and the widget is edited */
+ if (pos != 0 &&
+ ((widget == priv->country && priv->edited_country == TRUE)
+ || (widget == priv->area && priv->edited_area == TRUE)
+ || (widget == priv->number
+ && priv->edited_number == TRUE)))
+ return FALSE;
+
+ /* left edge of number field */
+ if (widget == priv->number) {
+ /* Stop signal handler, if only number field exists */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return TRUE;
+ else {
+ /* Grab the focus to the area field, if it is editable
+ */
+ if (priv->editable_area) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->area, priv->edited_area, TRUE);
+ }
+ /* Grab the focus to the country field, if it is
+ editable */
+ else if (priv->editable_country) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->country, priv->edited_country, TRUE);
+ } else
+ return TRUE;
+ }
+ }
+
+ /* left edge of area field */
+ if (widget == priv->area) { /* grab the focus to the country
+ field, if it is editable */
+ if (priv->editable_country) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->country, priv->edited_country, TRUE);
+ } else
+ return TRUE;
+ }
+
+ /* left edge of country field, let's wrap */
+ if (widget == priv->country) {
+ /* Stop the signal handler, if only country field exists */
+ if (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
+ return TRUE;
+ /* wrap to area, if in AREA mode */
+ else if (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->area, priv->edited_area, TRUE);
+ }
+
+ else {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->number, priv->edited_number, TRUE);
+ }
+ }
+ }
+ /* going right */
+ else if (event->keyval == GDK_Right || event->keyval == GDK_KP_Right) {
+ width = g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1);
+
+ /* not yet on the rigth edge and the widget is edited */
+ if (pos != width &&
+ ((widget == priv->country && priv->edited_country == TRUE)
+ || (widget == priv->area && priv->edited_area == TRUE)
+ || (widget == priv->number
+ && priv->edited_number == TRUE)))
+ return FALSE;
+
+ /* rigth edge of number field */
+ if (widget == priv->number) {
+ /* Stop signal handler, if only number field exists */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return TRUE;
+ else {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->country, priv->edited_country, FALSE);
+ }
+ }
+
+ /* rigth edge of area field */
+ if (widget == priv->area) {
+ /* area mode, wrap to country field */
+ if (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->country, priv->edited_country, FALSE);
+ }
+ /* grab the focus to the number field, if it is editable */
+ else if (priv->editable_number) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->number, priv->edited_number, FALSE);
+ } else
+ return TRUE;
+ }
+
+ /* rigth edge of country field */
+ if (widget == priv->country) {
+ /* wrap around, if only country field exists */
+ if (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
+ return TRUE;
+
+ /* area mode, move to area field */
+ else if (priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA ||
+ priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) {
+ /* grab the focus to the area field, if it is editable
+ */
+ if (priv->editable_area) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->area, priv->edited_area, FALSE);
+ }
+ /* grab the focus to the area field, if it is editable
+ */
+ else if ((priv->format ==
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE) &&
+ priv->editable_number) {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->number, priv->edited_number, FALSE);
+ } else
+ return TRUE;
+ }
+
+ else {
+ hildon_telephone_editor_focus_dest_entry
+ (priv->number, priv->edited_number, FALSE);
+ }
+ }
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * hildon_telephone_editor_set_editable:
+ * @hte: #HildonTelephoneEditor
+ * @country: set the editable status of the country field in coarce format
+ * @area: set the editable status of the area field in coarce format
+ * @number: set the editable status of the number field in coarce format
+ *
+ * Specify wheter the fields in coerse format are editable or
+ * not. This function is ignored if the editor is in free mode. The
+ * number or area and number parameters are ignored if the editor is
+ * in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY formats,
+ * respectively.
+ */
+void
+hildon_telephone_editor_set_editable(HildonTelephoneEditor * editor,
+ gboolean country,
+ gboolean area, gboolean number)
+{
+ HildonTelephoneEditorPriv *priv;
+
+ g_return_if_fail(editor);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ priv->editable_country = country;
+ priv->editable_area = area;
+ priv->editable_number = number;
+
+ if (priv->country)
+ {
+ gtk_editable_set_editable(GTK_EDITABLE(priv->country), country);
+ gtk_widget_set_sensitive(GTK_WIDGET(priv->plus), country);
+ }
+
+ if (priv->area)
+ gtk_editable_set_editable(GTK_EDITABLE(priv->area), area);
+
+ if (priv->number)
+ gtk_editable_set_editable(GTK_EDITABLE(priv->number), number);
+}
+
+/**
+ * hildon_telephone_editor_set_widths:
+ * @hte: #HildonTelephoneEditor
+ * @country: width (characters) of the country field in coarce mode
+ * @area: width (characters) of the area field in coarce mode
+ * @number: width (characters) of the number field in coarce mode
+ *
+ * Set widths of the fields in coecse format. Country and area parameters
+ * are ignored, if the editor is in free mode. The number or area and number
+ * parameters are ignored if the editor is in
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode, respectively.
+ */
+void
+hildon_telephone_editor_set_widths(HildonTelephoneEditor * editor,
+ guint country,
+ guint area, guint number)
+{
+ HildonTelephoneEditorPriv *priv;
+
+ g_return_if_fail(editor);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ if (priv->country) {
+ /*gtk_entry_set_max_length(GTK_ENTRY(priv->country), country);*/
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->country), country);
+ }
+
+ if (priv->area) {
+ /*gtk_entry_set_max_length(GTK_ENTRY(priv->area), area);*/
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->area), area);
+ }
+
+ if (priv->number) {
+ /*gtk_entry_set_max_length(GTK_ENTRY(priv->number), number);*/
+ gtk_entry_set_width_chars(GTK_ENTRY(priv->number), number);
+ }
+
+}
+
+/**
+ * hildon_telephone_editor_set_show_plus:
+ * @hte: #HildonTelephoneEditor
+ * @show: show the plus sign
+ *
+ * Show or hide the plus sign in front of coerce format's country field.
+ */
+void
+hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * editor,
+ gboolean show)
+{
+ HildonTelephoneEditorPriv *priv;
+
+ g_return_if_fail(editor);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* do nothing in FREE format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return;
+
+ if (show && !priv->show_plus) {
+ priv->show_plus = TRUE;
+ gtk_widget_set_parent(priv->plus_event, GTK_WIDGET(editor));
+ gtk_widget_show(priv->plus_event);
+ } else if (!show && priv->show_plus) {
+ gtk_widget_hide(priv->plus_event);
+ gtk_widget_unparent(priv->plus_event);
+ priv->show_plus = FALSE;
+ }
+}
+
+/**
+ * hildon_telephone_editor_get_show_plus:
+ * @hte: #HildonTelephoneEditor
+ *
+ * Get the visibility status of the plus sign in
+ * front of coerce format's country field.
+ *
+ * Returns: gboolean
+ */
+gboolean
+hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
+ editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_val_if_fail(editor, FALSE);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* no plus in FREE format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return FALSE;
+ return priv->show_plus;
+}
+
+/**
+ * hildon_telephone_editor_set_show_border:
+ * @hte: #HildonTelephoneEditor
+ * @show: show the border
+ *
+ * Show or hide the border around the widget
+ */
+void
+hildon_telephone_editor_set_show_border(HildonTelephoneEditor *
+ editor, gboolean show)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_if_fail(editor);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ if (show && !priv->show_border) {
+ priv->show_border = TRUE;
+ gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
+ gtk_widget_show(priv->frame);
+ } else if (!show && priv->show_border) {
+ gtk_widget_hide(priv->frame);
+ gtk_widget_unparent(priv->frame);
+ priv->show_border = FALSE;
+ }
+}
+
+/**
+ * hildon_telephone_editor_get_show_border:
+ * @hte: #HildonTelephoneEditor
+ *
+ * Get the visibility status of the border around the widget.
+ *
+ * Returns: gboolean
+ */
+gboolean
+hildon_telephone_editor_get_show_border(HildonTelephoneEditor * editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_val_if_fail(editor, FALSE);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ return priv->show_border;
+}
+
+/**
+ * hildon_telephone_editor_get_country:
+ * @hte: #HildonTelephoneEditor
+ *
+ * Get text in the country field in coarse format. This function must
+ * not be called if in free mode.
+ *
+ * Returns: pointer to the text in the country field. It must not
+ * be changed or freed.
+ */
+const gchar *
+hildon_telephone_editor_get_country(HildonTelephoneEditor *
+ editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_val_if_fail(editor, NULL);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* return NULL if in FREE format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return NULL;
+
+ return gtk_entry_get_text(GTK_ENTRY(priv->country));
+}
+
+/**
+ * hildon_telephone_editor_set_country:
+ * @hte: #HildonTelephoneEditor
+ * @country: text to be set in country field
+ *
+ * Set text in the country field in coarse format. This function must
+ * not be called if in free mode.
+ */
+void
+hildon_telephone_editor_set_country(HildonTelephoneEditor * editor,
+ const gchar * country)
+{
+ HildonTelephoneEditorPriv *priv;
+ const gchar *p;
+ gunichar u;
+
+ g_return_if_fail(editor);
+ g_return_if_fail(country);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* do nothing in FREE format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return;
+
+ if (!priv->country)
+ return;
+
+ p = country;
+ g_return_if_fail(g_utf8_validate(p, -1, NULL));
+
+ /* allow only digits */
+ do {
+ u = g_utf8_get_char(p);
+ if (!g_unichar_isdigit(*p))
+ return;
+
+ p = g_utf8_next_char(p);
+ } while (*p);
+
+ gtk_entry_set_text(GTK_ENTRY(priv->country), country);
+}
+
+/**
+ * hildon_telephone_editor_get_area:
+ * @hte: #HildonTelephoneEditor
+ *
+ * Get text in the area field in coarse format. This function must not
+ * be called if in free mode or in
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
+ *
+ * Returns: pointer to the text in the area field. It must not be
+ * changed or freed.
+ */
+const gchar *
+hildon_telephone_editor_get_area(HildonTelephoneEditor *
+ editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_val_if_fail(editor, NULL);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* return NULL if in FREE format or if in COERCE_COUNTRY format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return NULL;
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY)
+ return NULL;
+
+ return gtk_entry_get_text(GTK_ENTRY(priv->area));
+}
+
+/**
+ * hildon_telephone_editor_set_area:
+ * @hte: #HildonTelephoneEditor
+ * @area: text to be set in area field
+ *
+ * Set text in the area field in coarse format. This function must not
+ * be called if in free mode or in
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY mode.
+ */
+void
+hildon_telephone_editor_set_area(HildonTelephoneEditor * editor,
+ const gchar * area)
+{
+ HildonTelephoneEditorPriv *priv;
+ const gchar *p;
+ gunichar u;
+
+ g_return_if_fail(editor);
+ g_return_if_fail(area);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ /* do nothing in FREE format */
+ if (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE)
+ return;
+
+ if (!priv->area)
+ return;
+
+ p = area;
+ g_return_if_fail(g_utf8_validate(p, -1, NULL));
+
+ /* allow only digits */
+ do {
+ u = g_utf8_get_char(p);
+ if (!g_unichar_isdigit(u))
+ return;
+
+ p = g_utf8_next_char(p);
+ } while (*p);
+
+ gtk_entry_set_text(GTK_ENTRY(priv->area), area);
+}
+
+/**
+ * hildon_telephone_editor_get_number:
+ * @hte: #HildonTelephoneEditor
+ *
+ * Get text in the number field in all formats. In free mode, this
+ * functions returns the whole phone number. In coarce mode, it returns
+ * only the number field. This function must not be called if
+ * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA or
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
+ *
+ * Returns: pointer to text in the number field. It must not be
+ * changed or freed.
+ */
+const gchar *
+hildon_telephone_editor_get_number(HildonTelephoneEditor *
+ editor)
+{
+ HildonTelephoneEditorPriv *priv;
+ g_return_val_if_fail(editor, NULL);
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ return gtk_entry_get_text(GTK_ENTRY(priv->number));
+}
+
+/**
+ * hildon_telephone_editor_set_number:
+ * @hte: #HildonTelephoneEditor
+ * @number: text to be set to number field
+ *
+ * Set text in the number field in all formats. In free mode this
+ * functions sets the whole phone number. In coerce mode, it sets
+ * only the number field. This function must not be called if
+ * the editor is in HILDON_TELEPHONE_EDITOR_FORMAT_COERSE_AREA or
+ * HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY modes.
+ */
+void
+hildon_telephone_editor_set_number(HildonTelephoneEditor * editor,
+ const gchar * number)
+{
+ HildonTelephoneEditorPriv *priv;
+ const gchar *p;
+ gunichar u;
+
+ g_return_if_fail(editor);
+ g_return_if_fail(number);
+
+ priv = HILDON_TELEPHONE_EDITOR_GET_PRIVATE(editor);
+
+ if (!priv->number)
+ return;
+
+ p = number;
+ g_return_if_fail(g_utf8_validate(p, -1, NULL));
+
+ /* allow only digits in coerce format or some other in free format */
+ do {
+ u = g_utf8_get_char(p);
+ if (g_unichar_isdigit(u) ||
+ (priv->format == HILDON_TELEPHONE_EDITOR_FORMAT_FREE &&
+ (u == '+' ||
+ u == 'p' ||
+ u == 'w' ||
+ u == '(' ||
+ u == ')' ||
+ u == '/' ||
+ u == ' ' ||
+ u == '.' || u == '-' || u == '*' || u == '#' || u == '?')))
+ p = g_utf8_next_char(p);
+ else
+ return;
+
+ } while (*p);
+
+ gtk_entry_set_text(GTK_ENTRY(priv->number), number);
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_TELEPHONE_EDITOR_H__
+#define __HILDON_TELEPHONE_EDITOR_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+/**
+ * HILDON_TELEPHONE_EDITOR_TYPE:
+ *
+ * Macro for getting type of telephone editor.
+ */
+#define HILDON_TELEPHONE_EDITOR_TYPE \
+ ( hildon_telephone_editor_get_type() )
+#define HILDON_TELEPHONE_EDITOR(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TELEPHONE_EDITOR_TYPE, \
+ HildonTelephoneEditor))
+#define HILDON_TELEPHONE_EDITOR_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), HILDON_TELEPHONE_EDITOR_TYPE, \
+ HildonTelephoneEditorClass))
+#define HILDON_IS_TELEPHONE_EDITOR(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TELEPHONE_EDITOR_TYPE))
+#define HILDON_IS_TELEPHONE_EDITOR_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TELEPHONE_EDITOR_TYPE))
+/**
+ * HildonTelephoneEditorFormat:
+ * @HILDON_TELEPHONE_EDITOR_FORMAT_FREE: Free format.
+ * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE: Coerce format, three fields.
+ * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY: Coerce format, only
+ * country field.
+ * @HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA: Coerce format, country
+ * and area fields.
+ *
+ * Define all possible format modes for the HildonTelephoneEditor.
+ *
+ */
+ typedef enum {
+ HILDON_TELEPHONE_EDITOR_FORMAT_FREE = 0,
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE,
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_COUNTRY,
+ HILDON_TELEPHONE_EDITOR_FORMAT_COERCE_AREA
+} HildonTelephoneEditorFormat;
+
+
+/**
+ * HildonTelephoneEditor:
+ *
+ * Internal struct for telephone editor.
+ */
+typedef struct _HildonTelephoneEditor HildonTelephoneEditor;
+typedef struct _HildonTelephoneEditorClass HildonTelephoneEditorClass;
+
+/*< private >*/
+struct _HildonTelephoneEditor {
+ GtkContainer parent;
+};
+
+struct _HildonTelephoneEditorClass {
+ GtkContainerClass parent_class;
+};
+
+GType hildon_telephone_editor_get_type(void);
+
+GtkWidget *hildon_telephone_editor_new(HildonTelephoneEditorFormat format);
+GtkWidget
+ *hildon_telephone_editor_new_with_strings(HildonTelephoneEditorFormat
+ format,
+ const gchar * country,
+ const gchar * area,
+ const gchar * number);
+void hildon_telephone_editor_set_editable(HildonTelephoneEditor * hte,
+ gboolean country, gboolean area,
+ gboolean number);
+
+void hildon_telephone_editor_set_show_plus(HildonTelephoneEditor * hte,
+ gboolean show);
+
+gboolean hildon_telephone_editor_get_show_plus(HildonTelephoneEditor *
+ hte);
+
+void hildon_telephone_editor_set_show_border(HildonTelephoneEditor * hte,
+ gboolean show);
+
+gboolean hildon_telephone_editor_get_show_border(HildonTelephoneEditor *
+ hte);
+
+
+void hildon_telephone_editor_set_widths(HildonTelephoneEditor * hte,
+ guint country,
+ guint area, guint number);
+
+const gchar *hildon_telephone_editor_get_country(HildonTelephoneEditor *
+ hte);
+
+void hildon_telephone_editor_set_country(HildonTelephoneEditor * hte,
+ const gchar * country);
+
+const gchar *hildon_telephone_editor_get_area(HildonTelephoneEditor * hte);
+
+void hildon_telephone_editor_set_area(HildonTelephoneEditor * hte,
+ const gchar * area);
+
+const gchar *hildon_telephone_editor_get_number(HildonTelephoneEditor *
+ hte);
+
+void hildon_telephone_editor_set_number(HildonTelephoneEditor * hte,
+ const gchar * number);
+
+G_END_DECLS
+#endif /* __HILDON_TELEPHONE_EDITOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-time-editor
+ * @short_description: A widget used to enter time or duration in hours, minutes,
+ * and optional seconds
+ * @see_also: #HildonTimePicker
+ *
+ * HildonTimeEditor is used to edit time or duration. Time mode is
+ * restricted to normal 24 hour cycle, but Duration mode can select any
+ * amount of time up to 99 hours. It consists of entries for hours,
+ * minutes and seconds, and pm/am indicator as well as a button which
+ * popups a #HildonTimePicker dialog.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkframe.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <langinfo.h>
+#include <libintl.h>
+
+#include <hildon-widgets/hildon-defines.h>
+#include <hildon-widgets/hildon-time-editor.h>
+#include <hildon-widgets/hildon-time-picker.h>
+#include <hildon-widgets/hildon-banner.h>
+#include <hildon-widgets/hildon-input-mode-hint.h>
+#include <hildon-widgets/hildon-private.h>
+#include "hildon-composite-widget.h"
+#include "hildon-marshalers.h"
+#include "hildon-libs-enum-types.h"
+
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_TIME_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_TIME_EDITOR, HildonTimeEditorPrivate));
+
+#define TICKS(h,m,s) ((h) * 3600 + (m) * 60 + (s))
+
+#define TIME_EDITOR_HEIGHT 30
+#define ICON_PRESSED 4
+#define ICON_NAME "qgn_widg_timedit"
+#define ICON_SIZE "timepicker-size"
+#define MIN_DURATION 0
+#define MAX_DURATION TICKS(99, 59, 59)
+
+/* Default values for properties */
+#define HILDON_TIME_EDITOR_TICKS_VALUE 0
+#define HILDON_TIME_EDITOR_DURATION_MODE FALSE
+#define HILDON_TIME_EDITOR_DURATION_LOWER_VALUE 0
+#define HILDON_TIME_EDITOR_DURATION_UPPER_VALUE TICKS(99, 59, 59)
+
+#define HOURS_MAX_24 23
+#define HOURS_MAX_12 12
+#define HOURS_MIN_24 0
+#define HOURS_MIN_12 1
+#define MINUTES_MAX 59
+#define SECONDS_MAX 59
+#define MINUTES_MIN 0
+#define SECONDS_MIN 0
+
+static GtkContainerClass *parent_class;
+
+typedef struct _HildonTimeEditorPrivate HildonTimeEditorPrivate;
+
+enum
+{
+ PROP_TICKS = 1,
+ PROP_DURATION_MODE,
+ PROP_DURATION_MIN,
+ PROP_DURATION_MAX,
+ PROP_SHOW_SECONDS,
+ PROP_SHOW_HOURS
+};
+
+/* Indices for h/m/s entries in priv->entries */
+enum {
+ ENTRY_HOURS,
+ ENTRY_MINS,
+ ENTRY_SECS,
+
+ ENTRY_COUNT
+};
+
+/* Signals */
+enum {
+ TIME_ERROR,
+ LAST_SIGNAL
+};
+
+/* Error codes categories */
+enum {
+ MAX_VALUE,
+ MIN_VALUE,
+ WITHIN_RANGE,
+ NUM_ERROR_CODES
+};
+
+static guint time_editor_signals[LAST_SIGNAL] = { 0 };
+static guint hour_errors[NUM_ERROR_CODES] = { MAX_HOURS, MIN_HOURS, EMPTY_HOURS };
+static guint min_errors[NUM_ERROR_CODES] = { MAX_MINS, MIN_MINS, EMPTY_MINS };
+static guint sec_errors[NUM_ERROR_CODES] = { MAX_SECS, MIN_SECS, EMPTY_SECS };
+
+struct _HildonTimeEditorPrivate {
+ guint ticks; /* Current duration in seconds */
+
+ gchar *am_symbol;
+ gchar *pm_symbol;
+
+ GtkWidget *iconbutton; /* button for icon */
+
+ GtkWidget *frame; /* frame around the entries */
+ GtkWidget *entries[ENTRY_COUNT]; /* h, m, s entries */
+ GtkWidget *hm_label; /* between hour and minute */
+ GtkWidget *sec_label; /* between minute and second */
+ GtkWidget *ampm_label; /* label for showing am or pm */
+
+ GtkWidget *error_widget; /* field to highlight in idle */
+ GtkWidget *ampm_button; /* am/pm change button */
+
+
+ gboolean duration_mode; /* In HildonDurationEditor mode */
+ gboolean show_seconds; /* show seconds */
+ gboolean show_hours; /* show hours */
+
+ gboolean ampm_pos_after; /* is am/pm shown after others */
+ gboolean clock_24h; /* whether to show a 24h clock */
+ gboolean am; /* TRUE == am, FALSE == pm */
+
+ guint duration_min; /* duration editor ranges */
+ guint duration_max; /* duration editor ranges */
+
+ guint highlight_idle;
+ gboolean skipper; /* FIXME (MDK): To prevent us from looping inside the validation events.
+ When set to TRUE further validations (that can happen from-inside other validations)
+ are being skipped. Nasty hack to cope with a bad design. */
+};
+
+/***
+ * Widget functions
+ */
+
+static void hildon_time_editor_class_init (HildonTimeEditorClass *editor_class);
+static void hildon_time_editor_init (HildonTimeEditor *editor);
+
+static void hildon_time_editor_finalize (GObject *obj_self);
+
+static void hildon_time_editor_set_property(GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void hildon_time_editor_get_property(GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void hildon_time_editor_forall(GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+
+static void hildon_time_editor_destroy(GtkObject * self);
+
+/***
+ * Signal handlers
+ */
+
+static gboolean hildon_time_editor_entry_focusout(GtkWidget *widget,
+ GdkEventFocus *event,
+ gpointer data);
+
+static gboolean hildon_time_editor_entry_focusin(GtkWidget *widget,
+ GdkEventFocus *event,
+ gpointer data);
+
+static gboolean hildon_time_editor_time_error(HildonTimeEditor *editor,
+ HildonTimeEditorErrorType type);
+
+static gboolean hildon_time_editor_ampm_clicked(GtkWidget *widget,
+ gpointer data);
+
+static gboolean hildon_time_editor_icon_clicked(GtkWidget *widget,
+ gpointer data);
+
+static void hildon_time_editor_size_request(GtkWidget *widget,
+ GtkRequisition *requisition);
+
+static void hildon_time_editor_size_allocate(GtkWidget *widget,
+ GtkAllocation *allocation);
+
+static gboolean hildon_time_editor_entry_keypress(GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data);
+
+/***
+ * Internal functions
+ */
+
+static gboolean hildon_time_editor_check_locale(HildonTimeEditor * editor);
+
+static
+void hildon_time_editor_tap_and_hold_setup(GtkWidget * widget,
+ GtkWidget * menu,
+ GtkCallback func,
+ GtkWidgetTapAndHoldFlags flags);
+static void
+hildon_time_editor_validate (HildonTimeEditor *editor, gboolean allow_intermediate);
+
+static void hildon_time_editor_set_to_current_time (HildonTimeEditor * editor);
+
+static gboolean
+_hildon_time_editor_entry_select_all(GtkWidget *widget);
+
+
+/***
+ * Utility functions
+ */
+
+static void convert_to_12h (guint *h, gboolean *am);
+static void convert_to_24h (guint *h, gboolean am);
+
+static void ticks_to_time (guint ticks,
+ guint *hours,
+ guint *minutes,
+ guint *seconds);
+
+static void
+hildon_time_editor_inserted_text (GtkEditable * editable,
+ gchar * new_text,
+ gint new_text_length,
+ gint * position,
+ gpointer user_data);
+
+GType hildon_time_editor_get_type(void)
+{
+ static GType editor_type = 0;
+
+ if (!editor_type) {
+ static const GTypeInfo editor_info = {
+ sizeof(HildonTimeEditorClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_time_editor_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonTimeEditor),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_time_editor_init,
+ };
+ editor_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonTimeEditor",
+ &editor_info, 0);
+ }
+ return editor_type;
+}
+
+static void hildon_time_editor_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonTimeEditor *editor;
+ HildonTimeEditorPrivate *priv;
+
+ g_assert(HILDON_IS_TIME_EDITOR(container));
+ g_assert(callback != NULL);
+
+ editor = HILDON_TIME_EDITOR(container);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if (!include_internals)
+ return;
+
+ /* widget that are always shown */
+ (*callback) (priv->iconbutton, callback_data);
+ (*callback) (priv->frame, callback_data);
+}
+
+static void hildon_time_editor_destroy(GtkObject * self)
+{
+ HildonTimeEditorPrivate *priv;
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(self);
+
+ if (priv->iconbutton) {
+ gtk_widget_unparent(priv->iconbutton);
+ priv->iconbutton = NULL;
+ }
+ if (priv->frame) {
+ gtk_widget_unparent(priv->frame);
+ priv->frame = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+
+}
+
+static void
+hildon_time_editor_class_init(HildonTimeEditorClass * editor_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(editor_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(editor_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(editor_class);
+
+ parent_class = g_type_class_peek_parent(editor_class);
+
+ g_type_class_add_private(editor_class,
+ sizeof(HildonTimeEditorPrivate));
+
+ object_class->get_property = hildon_time_editor_get_property;
+ object_class->set_property = hildon_time_editor_set_property;
+ widget_class->size_request = hildon_time_editor_size_request;
+ widget_class->size_allocate = hildon_time_editor_size_allocate;
+ widget_class->tap_and_hold_setup =
+ hildon_time_editor_tap_and_hold_setup;
+ widget_class->focus = hildon_composite_widget_focus;
+
+ container_class->forall = hildon_time_editor_forall;
+ GTK_OBJECT_CLASS(editor_class)->destroy = hildon_time_editor_destroy;
+
+ object_class->finalize = hildon_time_editor_finalize;
+
+ editor_class->time_error = hildon_time_editor_time_error;
+
+ time_editor_signals[TIME_ERROR] =
+ g_signal_new("time-error",
+ G_OBJECT_CLASS_TYPE(object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(HildonTimeEditorClass, time_error),
+ g_signal_accumulator_true_handled, NULL,
+ _hildon_marshal_BOOLEAN__ENUM,
+ G_TYPE_BOOLEAN, 1, HILDON_TYPE_TIME_EDITOR_ERROR_TYPE);
+
+ /**
+ * HildonTimeEditor:ticks:
+ *
+ * If editor is in duration mode, contains the duration seconds.
+ * If not, contains seconds since midnight.
+ */
+ g_object_class_install_property( object_class, PROP_TICKS,
+ g_param_spec_uint("ticks",
+ "Duration value",
+ "Current value of duration",
+ 0, G_MAXUINT,
+ HILDON_TIME_EDITOR_TICKS_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonTimeEditor:show_seconds:
+ *
+ * Controls whether seconds are shown in the editor
+ */
+ g_object_class_install_property( object_class, PROP_SHOW_SECONDS,
+ g_param_spec_boolean("show_seconds",
+ "Show seconds property",
+ "Controls whether the seconds are shown in the editor",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonTimeEditor:show_hours:
+ *
+ * Controls whether hours are shown in the editor
+ */
+ g_object_class_install_property( object_class, PROP_SHOW_HOURS,
+ g_param_spec_boolean("show_hours",
+ "Show hours field",
+ "Controls whether the hours field is shown in the editor",
+ TRUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonTimeEditor:duration_mode:
+ *
+ * Controls whether the TimeEditor is in duration mode
+ */
+ g_object_class_install_property( object_class, PROP_DURATION_MODE,
+ g_param_spec_boolean("duration_mode",
+ "Duration mode",
+ "Controls whether the TimeEditor is in duration mode",
+ HILDON_TIME_EDITOR_DURATION_MODE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonTimeEditor:duration_min:
+ *
+ * Minimum allowed duration value.
+ */
+ g_object_class_install_property( object_class, PROP_DURATION_MIN,
+ g_param_spec_uint("duration_min",
+ "Minumum duration value",
+ "Smallest possible duration value",
+ MIN_DURATION, MAX_DURATION,
+ HILDON_TIME_EDITOR_DURATION_LOWER_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ /**
+ * HildonTimeEditor:duration_max:
+ *
+ * Maximum allowed duration value.
+ */
+ g_object_class_install_property( object_class, PROP_DURATION_MAX,
+ g_param_spec_uint("duration_max",
+ "Maximum duration value",
+ "Largest possible duration value",
+ 0, G_MAXUINT,
+ HILDON_TIME_EDITOR_DURATION_UPPER_VALUE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+}
+
+static
+void hildon_time_editor_tap_and_hold_setup(GtkWidget * widget,
+ GtkWidget * menu,
+ GtkCallback func,
+ GtkWidgetTapAndHoldFlags flags)
+{
+ HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(widget);
+ gint i;
+
+ /* Forward this tap_and_hold_setup signal to all our child widgets */
+ for (i = 0; i < ENTRY_COUNT; i++)
+ {
+ gtk_widget_tap_and_hold_setup(priv->entries[i], menu, func,
+ GTK_TAP_AND_HOLD_NO_SIGNALS);
+ }
+ gtk_widget_tap_and_hold_setup(priv->ampm_button, menu, func,
+ GTK_TAP_AND_HOLD_NO_SIGNALS);
+ gtk_widget_tap_and_hold_setup(priv->iconbutton, menu, func,
+ GTK_TAP_AND_HOLD_NONE);
+}
+
+static void hildon_time_editor_entry_changed(GtkWidget *widget, gpointer data)
+{
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+ hildon_time_editor_validate(HILDON_TIME_EDITOR(data), TRUE);
+}
+
+static void hildon_time_editor_init(HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+ GtkWidget *hbox, *icon;
+ gint i;
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ gtk_widget_push_composite_child();
+
+ /* Setup defaults and create widgets */
+ priv->ticks = 0;
+ priv->show_seconds = FALSE;
+ priv->show_hours = TRUE;
+ priv->ampm_pos_after = TRUE;
+ priv->clock_24h = TRUE;
+ priv->duration_mode = FALSE;
+ priv->iconbutton = gtk_button_new();
+ priv->ampm_label = gtk_label_new(NULL);
+ priv->hm_label = gtk_label_new(NULL);
+ priv->sec_label = gtk_label_new(NULL);
+ priv->frame = gtk_frame_new(NULL);
+ priv->ampm_button = gtk_button_new();
+ priv->skipper = FALSE;
+
+ icon = gtk_image_new_from_icon_name(ICON_NAME, HILDON_ICON_SIZE_WIDG);
+ hbox = gtk_hbox_new(FALSE, 0);
+
+ GTK_WIDGET_SET_FLAGS(editor, GTK_NO_WINDOW);
+ GTK_WIDGET_UNSET_FLAGS(priv->iconbutton, GTK_CAN_FOCUS | GTK_CAN_DEFAULT);
+
+ gtk_container_set_border_width(GTK_CONTAINER(priv->frame), 0);
+
+ gtk_container_add(GTK_CONTAINER(priv->iconbutton), icon);
+ gtk_container_add(GTK_CONTAINER(priv->ampm_button), priv->ampm_label);
+ gtk_button_set_relief(GTK_BUTTON(priv->ampm_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click(GTK_BUTTON(priv->ampm_button), FALSE);
+
+ /* Create hour, minute and second entries */
+ for (i = 0; i < ENTRY_COUNT; i++)
+ {
+ priv->entries[i] = gtk_entry_new();
+
+ /* No frames for entries, so that they all appear to be inside one long entry */
+ gtk_entry_set_has_frame(GTK_ENTRY(priv->entries[i]), FALSE);
+
+ /* Set the entries to accept only numeric characters */
+ g_object_set (priv->entries[i], "input-mode",
+ HILDON_INPUT_MODE_HINT_NUMERIC, NULL);
+
+ /* The entry fields all take exactly two characters */
+ gtk_entry_set_max_length (GTK_ENTRY(priv->entries[i]), 2);
+ gtk_entry_set_width_chars (GTK_ENTRY(priv->entries[i]), 2);
+
+ g_signal_connect(priv->entries[i], "focus-in-event",
+ G_CALLBACK(hildon_time_editor_entry_focusin), editor);
+ g_signal_connect(priv->entries[i], "focus-out-event",
+ G_CALLBACK(hildon_time_editor_entry_focusout), editor);
+ g_signal_connect(priv->entries[i], "key-press-event",
+ G_CALLBACK(hildon_time_editor_entry_keypress), editor);
+ g_signal_connect(priv->entries[i], "changed",
+ G_CALLBACK(hildon_time_editor_entry_changed), editor);
+
+ /* inserted signal sets time */
+ g_signal_connect_after (G_OBJECT(priv->entries[i]), "insert_text",
+ G_CALLBACK (hildon_time_editor_inserted_text),
+ editor);
+ }
+
+ /* clicked signal for am/pm label */
+ g_signal_connect(G_OBJECT(priv->ampm_button), "clicked",
+ G_CALLBACK(hildon_time_editor_ampm_clicked), editor);
+
+ /* clicked signal for icon */
+ g_signal_connect(G_OBJECT(priv->iconbutton), "clicked",
+ G_CALLBACK(hildon_time_editor_icon_clicked), editor);
+
+ /* Set ourself as the parent of all the widgets we created */
+ gtk_widget_set_parent(priv->iconbutton, GTK_WIDGET(editor));
+ gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_HOURS], FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->hm_label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_MINS], FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->sec_label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->entries[ENTRY_SECS], FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), priv->ampm_button, FALSE, FALSE, 0);
+ gtk_misc_set_padding(GTK_MISC(priv->ampm_label), 0, 0);
+
+ gtk_container_add(GTK_CONTAINER(priv->frame), hbox);
+
+ /* Show created widgets */
+ gtk_widget_set_parent(priv->frame, GTK_WIDGET(editor));
+ gtk_widget_show_all(priv->frame);
+ gtk_widget_show_all(priv->iconbutton);
+
+ /* Update AM/PM and time separators settings from locale */
+ if (!hildon_time_editor_check_locale(editor)) {
+ /* Using 12h clock */
+ priv->clock_24h = FALSE;
+ } else {
+ gtk_widget_hide(priv->ampm_button);
+ }
+
+ if (!priv->show_seconds) {
+ gtk_widget_hide(priv->sec_label);
+ gtk_widget_hide(priv->entries[ENTRY_SECS]);
+ }
+
+ /* set the default time to current time. */
+ hildon_time_editor_set_to_current_time (editor);
+
+ gtk_widget_pop_composite_child();
+}
+
+static void hildon_time_editor_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HildonTimeEditor *time_editor = HILDON_TIME_EDITOR(object);
+ switch (param_id)
+ {
+ case PROP_TICKS:
+ hildon_time_editor_set_ticks (time_editor, g_value_get_uint(value));
+ break;
+
+ case PROP_SHOW_SECONDS:
+ hildon_time_editor_set_show_seconds (time_editor, g_value_get_boolean(value));
+ break;
+
+ case PROP_SHOW_HOURS:
+ hildon_time_editor_set_show_hours (time_editor, g_value_get_boolean(value));
+ break;
+
+ case PROP_DURATION_MODE:
+ hildon_time_editor_set_duration_mode (time_editor, g_value_get_boolean(value));
+ break;
+
+ case PROP_DURATION_MIN:
+ hildon_time_editor_set_duration_min (time_editor, g_value_get_uint(value));
+ break;
+
+ case PROP_DURATION_MAX:
+ hildon_time_editor_set_duration_max (time_editor, g_value_get_uint(value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void hildon_time_editor_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonTimeEditor *time_editor = HILDON_TIME_EDITOR(object);
+ switch (param_id)
+ {
+
+ case PROP_TICKS:
+ g_value_set_uint (value, hildon_time_editor_get_ticks (time_editor));
+ break;
+
+ case PROP_SHOW_SECONDS:
+ g_value_set_boolean (value, hildon_time_editor_get_show_seconds (time_editor));
+ break;
+
+ case PROP_SHOW_HOURS:
+ g_value_set_boolean (value, hildon_time_editor_get_show_hours (time_editor));
+ break;
+
+ case PROP_DURATION_MODE:
+ g_value_set_boolean (value, hildon_time_editor_get_duration_mode (time_editor));
+ break;
+
+ case PROP_DURATION_MIN:
+ g_value_set_uint (value, hildon_time_editor_get_duration_min (time_editor));
+ break;
+
+ case PROP_DURATION_MAX:
+ g_value_set_uint (value, hildon_time_editor_get_duration_max (time_editor));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+/**
+ * hildon_time_editor_new:
+ *
+ * This function creates a new time editor.
+ *
+ * Returns: pointer to a new #HildonTimeEditor widget
+ */
+
+GtkWidget *hildon_time_editor_new(void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_TIME_EDITOR, NULL));
+}
+
+static void hildon_time_editor_finalize(GObject * obj_self)
+{
+ HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(obj_self);
+
+ g_free(priv->am_symbol);
+ g_free(priv->pm_symbol);
+
+ if (priv->highlight_idle)
+ g_source_remove(priv->highlight_idle);
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(obj_self);
+}
+
+/**
+ * _hildon_time_editor_get_time_separators:
+ * @editor: the #HildonTimeEditor
+ * @hm_sep_label: the label that will show the hour:minutes separator
+ * @ms_sep_label: the label that will show the minutes:seconds separator
+ *
+ * Gets hour-minute separator and minute-second separator from current
+ * locale and sets then to the labels we set as parameters. Both
+ * parameters can be NULL if you just want to assing one separator.
+ *
+ */
+void
+_hildon_time_editor_get_time_separators(GtkLabel *hm_sep_label,
+ GtkLabel *ms_sep_label)
+{
+ gchar buffer[256];
+ gchar *separator;
+ GDate locale_test_date;
+ gchar *iter, *endp = NULL;
+
+ /* Get localized time string */
+ g_date_set_dmy(&locale_test_date, 1, 2, 1970);
+ (void) g_date_strftime(buffer, sizeof(buffer), "%X", &locale_test_date);
+
+ if (hm_sep_label != NULL)
+ {
+ /* Find h-m separator */
+ iter = buffer;
+ while (*iter && g_ascii_isdigit(*iter)) iter++;
+
+ /* Extract h-m separator*/
+ endp = iter;
+ while (*endp && !g_ascii_isdigit(*endp)) endp++;
+ separator = g_strndup(iter, endp - iter);
+ gtk_label_set_label(hm_sep_label, separator);
+ g_free(separator);
+ }
+
+ if (ms_sep_label != NULL)
+ {
+ /* Find m-s separator */
+ iter = endp;
+ while (*iter && g_ascii_isdigit(*iter)) iter++;
+
+ /* Extract m-s separator*/
+ endp = iter;
+ while (*endp && !g_ascii_isdigit(*endp)) endp++;
+ separator = g_strndup(iter, endp - iter);
+ gtk_label_set_label(ms_sep_label, separator);
+ g_free(separator);
+ }
+
+}
+
+/* Convert ticks to H:M:S. Ticks = seconds since 00:00:00. */
+static void ticks_to_time (guint ticks,
+ guint *hours,
+ guint *minutes,
+ guint *seconds)
+{
+ guint left;
+
+ *hours = ticks / 3600;
+ left = ticks % 3600;
+ *minutes = left / 60;
+ *seconds = left % 60;
+}
+
+/**
+ * hildon_time_editor_set_ticks:
+ * @editor: the #HildonTimeEditor widget
+ * @ticks: the duration to set, in seconds
+ *
+ * Sets the current duration in seconds. This means seconds from
+ * midnight, if not in duration mode. In case of any errors, it tries
+ * to fix it.
+ */
+
+void hildon_time_editor_set_ticks (HildonTimeEditor * editor,
+ guint ticks)
+{
+ HildonTimeEditorPrivate *priv;
+ guint i, h, m, s;
+ gchar str[3];
+
+ g_assert(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* Validate ticks. If it's too low or too high, set it to
+ min/max value for the current mode. */
+ if (priv->duration_mode)
+ priv->ticks = CLAMP(ticks, priv->duration_min, priv->duration_max);
+ else {
+ /* Check that ticks value is valid. We only need to check that hours
+ don't exceed 23. */
+ ticks_to_time (ticks, &h, &m, &s);
+ if (h > HOURS_MAX_24)
+ ticks = TICKS(HOURS_MAX_24, m, s);
+
+ priv->ticks = ticks;
+ }
+
+ /* Get the time in H:M:S. */
+ ticks_to_time (priv->ticks, &h, &m, &s);
+
+ if (!priv->clock_24h && !priv->duration_mode)
+ {
+ /* Convert 24h H:M:S values to 12h mode, and update AM/PM state */
+ convert_to_12h (&h, &priv->am);
+ }
+
+ /* Set H:M:S values to entries. We do not want to invoke validation
+ callbacks (since they can cause new call to this function), so we
+ block signals while setting values. */
+ for (i = 0; i < ENTRY_COUNT; i++)
+ {
+ g_signal_handlers_block_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_changed, editor);
+
+ g_signal_handlers_block_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_inserted_text, editor);
+
+ g_signal_handlers_block_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_focusout, editor);
+
+ }
+
+ g_snprintf(str, sizeof(str), "%02u", h);
+ gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_HOURS]), str);
+
+ g_snprintf(str, sizeof(str), "%02u", m);
+ gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_MINS]), str);
+
+ g_snprintf(str, sizeof(str), "%02u", s);
+ gtk_entry_set_text(GTK_ENTRY(priv->entries[ENTRY_SECS]), str);
+
+ for (i = 0; i < ENTRY_COUNT; i++)
+ {
+ g_signal_handlers_unblock_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_changed, editor);
+
+ g_signal_handlers_unblock_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_inserted_text, editor);
+
+ g_signal_handlers_unblock_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_focusout, editor);
+
+ }
+
+ /* Update AM/PM label in case we're in 12h mode */
+ gtk_label_set_label(GTK_LABEL(priv->ampm_label),
+ priv->am ? priv->am_symbol : priv->pm_symbol);
+
+ g_object_notify (G_OBJECT (editor), "ticks");
+}
+
+static void
+hildon_time_editor_set_to_current_time (HildonTimeEditor * editor)
+{
+ time_t now;
+ const struct tm *tm;
+
+ now = time(NULL);
+ tm = localtime(&now);
+
+ if (tm != NULL)
+ hildon_time_editor_set_time(editor, tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+/**
+ * hildon_time_editor_get_ticks:
+ * @editor: the #HildonTimeEditor widget
+ *
+ * This function returns the current duration, in seconds.
+ * This means seconds from midnight, if not in duration mode.
+ *
+ * Returns: current duration in seconds
+ */
+
+guint hildon_time_editor_get_ticks (HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail(editor, 0);
+ g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ return (priv->ticks);
+}
+
+/**
+ * hildon_time_editor_set_show_seconds:
+ * @editor: the #HildonTimeEditor
+ * @show_seconds: enable or disable showing of seconds
+ *
+ * This function shows or hides the seconds field.
+ */
+
+void hildon_time_editor_set_show_seconds (HildonTimeEditor * editor,
+ gboolean show_seconds)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if (show_seconds != priv->show_seconds) {
+ priv->show_seconds = show_seconds;
+
+ /* show/hide seconds field and its ':' label if the value changed. */
+ if (show_seconds) {
+ gtk_widget_show(priv->entries[ENTRY_SECS]);
+ gtk_widget_show(priv->sec_label);
+ } else {
+ gtk_widget_hide(priv->entries[ENTRY_SECS]);
+ gtk_widget_hide(priv->sec_label);
+ }
+
+ g_object_notify (G_OBJECT (editor), "show_seconds");
+ }
+}
+
+/**
+ * hildon_time_editor_get_show_seconds:
+ * @editor: the #HildonTimeEditor widget
+ *
+ * This function returns a boolean indicating the visibility of
+ * seconds in the #HildonTimeEditor
+ *
+ * Returns: TRUE if the seconds are visible
+ */
+
+gboolean hildon_time_editor_get_show_seconds (HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ return (priv->show_seconds);
+}
+
+/**
+ * hildon_time_editor_set_duration_mode:
+ * @editor: the #HildonTimeEditor
+ * @duration_mode: enable or disable duration editor mode
+ *
+ * This function sets the duration editor mode in which the maximum hours
+ * is 99.
+ */
+
+void hildon_time_editor_set_duration_mode (HildonTimeEditor * editor,
+ gboolean duration_mode)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if (duration_mode != priv->duration_mode) {
+ priv->duration_mode = duration_mode;
+
+ if (duration_mode) {
+ /* FIXME: Why do we reset the duration range here?
+ Would change API, so won't touch this for now. */
+ hildon_time_editor_set_duration_range(editor, MIN_DURATION,
+ MAX_DURATION);
+ /* There's no AM/PM label or time picker icon in duration mode.
+ Make sure they're hidden. */
+ gtk_widget_hide(GTK_WIDGET(priv->ampm_label));
+ gtk_widget_hide(GTK_WIDGET(priv->ampm_button));
+ gtk_widget_hide(GTK_WIDGET(priv->iconbutton));
+ /* Duration mode has seconds by default. */
+ hildon_time_editor_set_show_seconds(editor, TRUE);
+ } else {
+ /* Make sure AM/PM label and time picker icons are visible if needed */
+ if (!priv->clock_24h)
+ gtk_widget_show(GTK_WIDGET(priv->ampm_label));
+
+ gtk_widget_show(GTK_WIDGET(priv->ampm_button));
+ gtk_widget_show(GTK_WIDGET(priv->iconbutton));
+
+ /* Reset the ticks to current time. Anything set in duration mode
+ * is bound to be invalid or useless in time mode.
+ */
+ hildon_time_editor_set_to_current_time (editor);
+ }
+
+ g_object_notify (G_OBJECT (editor), "duration_mode");
+ }
+}
+
+/**
+ * hildon_time_editor_get_duration_mode:
+ * @editor: the #HildonTimeEditor widget
+ *
+ * This function returns a boolean indicating whether the #HildonTimeEditor
+ * is in the duration mode.
+ *
+ * Returns: TRUE if the #HildonTimeEditor is in duration mode
+ */
+
+gboolean hildon_time_editor_get_duration_mode (HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ return (priv->duration_mode);
+}
+
+/**
+ * hildon_time_editor_set_duration_min:
+ * @editor: the #HildonTimeEditor widget
+ * @duration_min: mimimum allowed duration
+ *
+ * Sets the minimum allowed duration for the duration mode.
+ * Note: Has no effect in time mode
+ */
+
+void hildon_time_editor_set_duration_min (HildonTimeEditor * editor,
+ guint duration_min)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+ g_return_if_fail(duration_min >= MIN_DURATION);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if( !priv->duration_mode )
+ return;
+
+ priv->duration_min = duration_min;
+
+ /* Clamp the current value to the minimum if necessary */
+ if (priv->ticks < duration_min)
+ {
+ hildon_time_editor_set_ticks (editor, duration_min);
+ }
+
+ g_object_notify (G_OBJECT (editor), "duration_min");
+}
+
+/**
+ * hildon_time_editor_get_duration_min:
+ * @editor: the #HildonTimeEditor widget
+ *
+ * This function returns the smallest duration the #HildonTimeEditor
+ * allows in the duration mode.
+ *
+ * Returns: minimum allowed duration in seconds
+ */
+
+guint hildon_time_editor_get_duration_min (HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if( !priv->duration_mode )
+ return (0);
+
+ return (priv->duration_min);
+}
+
+/**
+ * hildon_time_editor_set_duration_max:
+ * @editor: the #HildonTimeEditor widget
+ * @duration_max: maximum allowed duration in seconds
+ *
+ * Sets the maximum allowed duration in seconds for the duration mode.
+ * Note: Has no effect in time mode
+ */
+
+void hildon_time_editor_set_duration_max (HildonTimeEditor * editor,
+ guint duration_max)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+ g_return_if_fail(duration_max <= MAX_DURATION);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if( !priv->duration_mode )
+ return;
+
+ priv->duration_max = duration_max;
+
+ /* Clamp the current value to the maximum if necessary */
+ if (priv->ticks > duration_max)
+ {
+ hildon_time_editor_set_ticks (editor, duration_max);
+ }
+
+ g_object_notify (G_OBJECT (editor), "duration_max");
+}
+
+/**
+ * hildon_time_editor_get_duration_max:
+ * @editor: the #HildonTimeEditor widget
+ *
+ * This function returns the longest duration the #HildonTimeEditor
+ * allows in the duration mode.
+ *
+ * Returns: maximum allowed duration in seconds
+ */
+
+guint hildon_time_editor_get_duration_max (HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_TIME_EDITOR(editor), 0);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if( !priv->duration_mode )
+ return (0);
+
+ return (priv->duration_max);
+}
+
+
+/**
+ * hildon_time_editor_set_time:
+ * @editor: the #HildonTimeEditor widget
+ * @hours: hours
+ * @minutes: minutes
+ * @seconds: seconds
+ *
+ * This function sets the time on an existing time editor. If the
+ * time specified by the arguments is invalid, it's fixed.
+ * The time is assumed to be in 24h format.
+ */
+
+void hildon_time_editor_set_time(HildonTimeEditor * editor, guint hours,
+ guint minutes, guint seconds)
+{
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ hildon_time_editor_set_ticks (editor, TICKS(hours, minutes, seconds));
+}
+
+/**
+ * hildon_time_editor_get_time:
+ * @editor: the #HildonTimeEditor widget
+ * @hours: hours
+ * @minutes: minutes
+ * @seconds: seconds
+ *
+ * Gets the time of the #HildonTimeEditor widget. The time returned is
+ * always in 24h format.
+ */
+
+void hildon_time_editor_get_time(HildonTimeEditor * editor,
+ guint * hours,
+ guint * minutes, guint * seconds)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ ticks_to_time (hildon_time_editor_get_ticks (editor),
+ hours, minutes, seconds);
+}
+
+/**
+ * hildon_time_editor_set_duration_range:
+ * @editor: the #HildonTimeEditor widget
+ * @min_seconds: minimum allowed time in seconds
+ * @max_seconds: maximum allowed time in seconds
+ *
+ * Sets the duration editor time range of the #HildonTimeEditor widget.
+ */
+
+void hildon_time_editor_set_duration_range(HildonTimeEditor * editor,
+ guint min_seconds,
+ guint max_seconds)
+{
+ HildonTimeEditorPrivate *priv;
+ guint tmp;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+ /* Swap values if reversed */
+ if (min_seconds > max_seconds)
+ {
+ tmp = max_seconds;
+ max_seconds = min_seconds;
+ min_seconds = tmp;
+ }
+
+ hildon_time_editor_set_duration_max (editor, max_seconds);
+ hildon_time_editor_set_duration_min (editor, min_seconds);
+
+ if (priv->duration_mode) {
+ /* Set minimum allowed value for duration editor.
+ FIXME: Shouldn't it be changed only if it's not in range?
+ Would change API, so won't touch this for now. */
+ hildon_time_editor_set_ticks(editor, min_seconds);
+ }
+}
+
+/**
+ * hildon_time_editor_get_duration_range:
+ * @editor: the #HildonTimeEditor widget
+ * @min_seconds: pointer to guint
+ * @max_seconds: pointer to guint
+ *
+ * Gets the duration editor time range of the #HildonTimeEditor widget.
+ */
+
+void hildon_time_editor_get_duration_range(HildonTimeEditor * editor,
+ guint * min_seconds,
+ guint * max_seconds)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ *min_seconds = priv->duration_min;
+ *max_seconds = priv->duration_max;
+}
+
+static gboolean hildon_time_editor_check_locale(HildonTimeEditor * editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* Update time separator symbols */
+ _hildon_time_editor_get_time_separators(GTK_LABEL(priv->hm_label), GTK_LABEL(priv->sec_label));
+
+ /* Get AM/PM symbols. */
+ priv->am_symbol = g_strdup(nl_langinfo(AM_STR));
+ priv->pm_symbol = g_strdup(nl_langinfo(PM_STR));
+
+ if (priv->am_symbol[0] == '\0')
+ return TRUE;
+ else {
+ /* 12h clock mode. Check if AM/PM should be before or after time.
+ %p is the AM/PM string, so we assume that if the format string
+ begins with %p it's in the beginning, and in any other case it's
+ in the end (although that's not necessarily the case). */
+ if (strncmp(nl_langinfo(T_FMT_AMPM), "%p", 2) == 0)
+ priv->ampm_pos_after = FALSE;
+ return FALSE;
+ }
+}
+
+static gboolean hildon_time_editor_entry_focusin(GtkWidget * widget,
+ GdkEventFocus * event,
+ gpointer data)
+{
+ g_idle_add((GSourceFunc) _hildon_time_editor_entry_select_all,
+ GTK_ENTRY(widget));
+
+ return FALSE;
+}
+
+static gboolean
+hildon_time_editor_time_error(HildonTimeEditor *editor,
+ HildonTimeEditorErrorType type)
+{
+ return TRUE;
+}
+
+/* Returns negative if we didn't get value,
+ * and should stop further validation
+ */
+static gint validated_conversion(HildonTimeEditorPrivate *priv,
+ GtkWidget *field,
+ gint min,
+ gint max,
+ gint def_value,
+ gboolean allow_intermediate,
+ guint *error_code,
+ GString *error_string)
+{
+ const gchar *text;
+ gchar *tail;
+ long value;
+
+ text = gtk_entry_get_text(GTK_ENTRY(field));
+
+ if (text && text[0])
+ {
+ /* Try to convert entry text to number */
+ value = strtol(text, &tail, 10);
+
+ /* Check if conversion succeeded */
+ if ((tail[0] == 0) && !(text[0] == '-'))
+ {
+ if (value > max) {
+ g_string_printf(error_string, _("ckct_ib_maximum_value"), max);
+ priv->error_widget = field;
+ *error_code = MAX_VALUE;
+ return max;
+ }
+ if (value < min && !allow_intermediate) {
+ g_string_printf(error_string, _("ckct_ib_minimum_value"), min);
+ priv->error_widget = field;
+ *error_code = MIN_VALUE;
+ return min;
+ }
+
+ return value;
+ }
+ /* We'll handle failed conversions soon */
+ else
+ {
+ if ((tail[0] == '-') || (text[0] == '-'))
+ {
+ g_string_printf(error_string, _("ckct_ib_minimum_value"), min);
+ priv->error_widget = field;
+ *error_code = MIN_VALUE;
+ return min;
+ }
+ }
+ }
+ else if (allow_intermediate)
+ return -1; /* Empty field while user is still editing. No error, but
+ cannot validate either... */
+ else /* Empty field: show error and set value to minimum allowed */
+ {
+ g_string_printf(error_string, _("ckct_ib_set_a_value_within_range"), min, max);
+ priv->error_widget = field;
+ *error_code = WITHIN_RANGE;
+ return def_value;
+ }
+
+ /* Empty field and not allowed intermediated OR failed conversion */
+ g_string_printf(error_string, _("ckct_ib_set_a_value_within_range"), min, max);
+ priv->error_widget = field;
+ *error_code = WITHIN_RANGE;
+ return -1;
+}
+
+static void
+hildon_time_editor_real_validate(HildonTimeEditor *editor,
+ gboolean allow_intermediate, GString *error_string)
+{
+ HildonTimeEditorPrivate *priv;
+ guint h, m, s, ticks;
+ guint error_code;
+ guint max_hours, min_hours, def_hours;
+ guint max_minutes, min_minutes, def_minutes;
+ guint max_seconds, min_seconds, def_seconds;
+ gboolean r;
+
+ g_assert(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* Find limits for field based validation. */
+ if (priv->duration_mode)
+ {
+ ticks_to_time(priv->duration_min, &min_hours, &min_minutes, &min_seconds);
+ ticks_to_time(priv->duration_max, &max_hours, &max_minutes, &max_seconds);
+ } else {
+ if (priv->clock_24h) {
+ max_hours = HOURS_MAX_24;
+ min_hours = HOURS_MIN_24;
+ } else {
+ max_hours = HOURS_MAX_12;
+ min_hours = HOURS_MIN_12;
+ }
+ }
+
+ hildon_time_editor_get_time(editor, &def_hours, &def_minutes, &def_seconds);
+
+ /* Get time components from fields and validate them... */
+ if (priv->show_hours) {
+ h = validated_conversion(priv, priv->entries[ENTRY_HOURS], min_hours, max_hours, def_hours,
+ allow_intermediate, &error_code, error_string);
+ if (priv->error_widget == priv->entries[ENTRY_HOURS])
+ g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, hour_errors[error_code], &r);
+ if ((gint) h < 0) return;
+ }
+ else h = 0;
+ m = validated_conversion(priv, priv->entries[ENTRY_MINS], MINUTES_MIN, MINUTES_MAX, def_minutes,
+ allow_intermediate, &error_code, error_string);
+ if (priv->error_widget == priv->entries[ENTRY_MINS])
+ g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, min_errors[error_code], &r);
+ if ((gint) m < 0) return;
+ if (priv->show_seconds) {
+ s = validated_conversion(priv, priv->entries[ENTRY_SECS], SECONDS_MIN, SECONDS_MAX, def_seconds,
+ allow_intermediate, &error_code, error_string);
+ if (priv->error_widget == priv->entries[ENTRY_SECS])
+ g_signal_emit (editor, time_editor_signals [TIME_ERROR], 0, sec_errors[error_code], &r);
+ if ((gint) s < 0) return;
+ }
+ else s = 0;
+
+ /* Ok, we now do separate check that tick count is valid for duration mode */
+ if (priv->duration_mode)
+ {
+ ticks = TICKS(h, m, s);
+
+ if (ticks < priv->duration_min && !allow_intermediate)
+ {
+ g_string_printf(error_string,
+ _("ckct_ib_min_allowed_duration_hts"),
+ min_hours, min_minutes, min_seconds);
+ hildon_time_editor_set_ticks (editor, priv->duration_min);
+ priv->error_widget = priv->show_hours ? priv->entries[ENTRY_HOURS] : priv->entries[ENTRY_MINS];
+ g_signal_emit (editor, time_editor_signals[TIME_ERROR], 0, MIN_DUR, &r);
+ return;
+ }
+ else if (ticks > priv->duration_max)
+ {
+ g_string_printf(error_string,
+ _("ckct_ib_max_allowed_duration_hts"),
+ max_hours, max_minutes, max_seconds);
+ hildon_time_editor_set_ticks (editor, priv->duration_max);
+ priv->error_widget = priv->show_hours ? priv->entries[ENTRY_HOURS] : priv->entries[ENTRY_MINS];
+ g_signal_emit (editor, time_editor_signals[TIME_ERROR], 0, MAX_DUR, &r);
+ return;
+ }
+ }
+ else if (!priv->clock_24h)
+ convert_to_24h (&h, priv->am);
+
+ /* The only case when we do not want to refresh the
+ time display, is when the user is editing a value
+ (unless the value was out of bounds and we have to fix it) */
+ if (!allow_intermediate || priv->error_widget)
+ hildon_time_editor_set_time (editor, h, m, s);
+}
+
+/* Setting text to entries causes entry to recompute itself
+ in idle callback, which remove selection. Because of this
+ we need to do selection in idle as well. */
+static gboolean highlight_callback(gpointer data)
+{
+ HildonTimeEditorPrivate *priv;
+ GtkWidget *widget;
+ gint i;
+
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(data);
+
+ GDK_THREADS_ENTER ();
+
+ widget = priv->error_widget;
+ priv->error_widget = NULL;
+
+ if (GTK_IS_WIDGET(widget) == FALSE)
+ goto Done;
+
+ /* Avoid revalidation because it will issue the date_error signal
+ twice when there is an empty field. We must block the signal
+ for all the entries because we do not know where the focus
+ comes from */
+ for (i = 0; i < ENTRY_COUNT; i++)
+ g_signal_handlers_block_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_focusout, data);
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+ gtk_widget_grab_focus(widget);
+ for (i = 0; i < ENTRY_COUNT; i++)
+ g_signal_handlers_unblock_by_func(priv->entries[i],
+ (gpointer) hildon_time_editor_entry_focusout, data);
+
+Done:
+ priv->highlight_idle = 0;
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+/* Update ticks from current H:M:S entries. If they're invalid, show an
+ infoprint and update the fields unless they're empty. */
+static void
+hildon_time_editor_validate (HildonTimeEditor *editor, gboolean allow_intermediate)
+{
+ HildonTimeEditorPrivate *priv;
+ GString *error_message;
+
+ g_assert(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* if there is already an error we do nothing until it will be managed by the idle */
+ if (priv->highlight_idle == 0 && priv->skipper == FALSE)
+ {
+ priv->skipper = TRUE;
+ error_message = g_string_new(NULL);
+ hildon_time_editor_real_validate(editor,
+ allow_intermediate, error_message);
+
+ if (priv->error_widget)
+ {
+ hildon_banner_show_information(priv->error_widget, NULL,
+ error_message->str);
+
+ priv->highlight_idle = g_idle_add(highlight_callback, editor);
+ }
+
+ priv->skipper = FALSE;
+ g_string_free(error_message, TRUE);
+ }
+}
+
+/* on inserted text, if entry has two digits, jumps to the next field. */
+static void
+hildon_time_editor_inserted_text (GtkEditable * editable,
+ gchar * new_text,
+ gint new_text_length,
+ gint * position,
+ gpointer user_data)
+{
+ HildonTimeEditor *editor;
+ GtkEntry *entry;
+ gchar *value;
+ HildonTimeEditorPrivate *priv;
+
+ entry = GTK_ENTRY(editable);
+ editor = HILDON_TIME_EDITOR(user_data);
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* if there is already an error we don't have to do anything */
+ if (!priv->error_widget)
+ {
+
+ value = (gchar *) gtk_entry_get_text(entry);
+
+ if (strlen(value) == 2)
+ {
+ if (GTK_WIDGET(editable) == priv->entries[ENTRY_HOURS])
+ {
+ /* We already checked the input in changed signal, but
+ * now we will re-check it again in focus-out we
+ * intermediate flag set to FALSE */
+ gtk_widget_grab_focus(priv->entries[ENTRY_MINS]);
+ *position = -1;
+ }
+ else if (GTK_WIDGET(editable) == priv->entries[ENTRY_MINS] &&
+ GTK_WIDGET_VISIBLE (priv->entries[ENTRY_SECS]))
+ {
+ /* See above */
+ gtk_widget_grab_focus(priv->entries[ENTRY_SECS]);
+ *position = -1;
+ }
+ }
+ }
+}
+
+static gboolean hildon_time_editor_entry_focusout(GtkWidget * widget,
+ GdkEventFocus * event,
+ gpointer data)
+{
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+
+ /* Validate the given time and update ticks. */
+ hildon_time_editor_validate(HILDON_TIME_EDITOR(data), FALSE);
+
+ return FALSE;
+}
+
+static gboolean
+hildon_time_editor_ampm_clicked(GtkWidget * widget,
+ gpointer data)
+{
+ HildonTimeEditor *editor;
+ HildonTimeEditorPrivate *priv;
+
+ g_assert(GTK_IS_WIDGET(widget));
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+
+ editor = HILDON_TIME_EDITOR(data);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* First validate the given time and update ticks. */
+ hildon_time_editor_validate (editor, FALSE);
+
+ /* Apply the AM/PM change by moving the current time by 12 hours */
+ if (priv->am) {
+ /* 00:00 .. 11:59 -> 12:00 .. 23:59 */
+ hildon_time_editor_set_ticks (editor, priv->ticks + 12*3600);
+ } else {
+ /* 12:00 .. 23:59 -> 00:00 .. 11:59 */
+ hildon_time_editor_set_ticks (editor, priv->ticks - 12*3600);
+ }
+ return FALSE;
+}
+
+static gboolean
+hildon_time_editor_icon_clicked(GtkWidget * widget, gpointer data)
+{
+ HildonTimeEditor *editor;
+ GtkWidget *picker;
+ GtkWidget *parent;
+ guint h, m, s, result;
+ HildonTimeEditorPrivate *priv;
+
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+
+ editor = HILDON_TIME_EDITOR(data);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* icon is passive in duration editor mode */
+ if (hildon_time_editor_get_duration_mode(editor))
+ return FALSE;
+
+ /* Validate and do not launch if broken */
+ hildon_time_editor_validate(HILDON_TIME_EDITOR(data), FALSE);
+ if (priv->error_widget != NULL)
+ return FALSE;
+
+ /* Launch HildonTimePicker dialog */
+ parent = gtk_widget_get_ancestor(GTK_WIDGET(editor), GTK_TYPE_WINDOW);
+ picker = hildon_time_picker_new(GTK_WINDOW(parent));
+
+ hildon_time_editor_get_time(editor, &h, &m, &s);
+ hildon_time_picker_set_time(HILDON_TIME_PICKER(picker), h, m);
+
+ result = gtk_dialog_run(GTK_DIALOG(picker));
+ switch (result) {
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_ACCEPT:
+ /* Use the selected time */
+ hildon_time_picker_get_time(HILDON_TIME_PICKER(picker), &h, &m);
+ hildon_time_editor_set_time(editor, h, m, 0);
+ break;
+ default:
+ break;
+ }
+
+ gtk_widget_destroy(picker);
+ return FALSE;
+}
+
+static void hildon_time_editor_size_request(GtkWidget * widget,
+ GtkRequisition * requisition)
+{
+ HildonTimeEditor *editor;
+ HildonTimeEditorPrivate *priv;
+ GtkRequisition req;
+
+ editor = HILDON_TIME_EDITOR(widget);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ /* Get frame's size */
+ gtk_widget_size_request(priv->frame, requisition);
+
+ if (GTK_WIDGET_VISIBLE(priv->iconbutton))
+ {
+ gtk_widget_size_request(priv->iconbutton, &req);
+ /* Reserve space for icon */
+ requisition->width += req.width + ICON_PRESSED +
+ HILDON_MARGIN_DEFAULT;
+ }
+
+ /* FIXME: It's evil to use hardcoded TIME_EDITOR_HEIGHT. For now we'll
+ want to force this since themes might have varying thickness values
+ which cause the height to change. */
+ requisition->height = TIME_EDITOR_HEIGHT;
+}
+
+static void hildon_time_editor_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonTimeEditorPrivate *priv = HILDON_TIME_EDITOR_GET_PRIVATE(widget);
+ GtkAllocation alloc;
+ GtkRequisition req, max_req;
+
+ widget->allocation = *allocation;
+ gtk_widget_get_child_requisition(widget, &max_req);
+
+ /* Center horizontally */
+ alloc.x = allocation->x + MAX(allocation->width - max_req.width, 0) / 2;
+ /* Center vertically */
+ alloc.y = allocation->y + MAX(allocation->height - max_req.height, 0) / 2;
+
+ /* allocate frame */
+ gtk_widget_get_child_requisition(priv->frame, &req);
+
+ alloc.width = req.width;
+ alloc.height = max_req.height;
+ gtk_widget_size_allocate(priv->frame, &alloc);
+
+ /* allocate icon */
+ if (GTK_WIDGET_VISIBLE(priv->iconbutton)) {
+ gtk_widget_get_child_requisition(priv->iconbutton, &req);
+
+ alloc.x += alloc.width + HILDON_MARGIN_DEFAULT;
+ alloc.width = req.width;
+ gtk_widget_size_allocate(priv->iconbutton, &alloc);
+ }
+
+ /* FIXME: ugly way to move labels up. They just don't seem move up
+ otherwise. This is likely because we force the editor to be
+ smaller than it otherwise would be. */
+ alloc = priv->ampm_label->allocation;
+ alloc.y = allocation->y - 2;
+ alloc.height = max_req.height + 2;
+ gtk_widget_size_allocate(priv->ampm_label, &alloc);
+
+ alloc = priv->hm_label->allocation;
+ alloc.y = allocation->y - 2;
+ alloc.height = max_req.height + 2;
+ gtk_widget_size_allocate(priv->hm_label, &alloc);
+
+ alloc = priv->sec_label->allocation;
+ alloc.y = allocation->y - 2;
+ alloc.height = max_req.height + 2;
+ gtk_widget_size_allocate(priv->sec_label, &alloc);
+}
+
+static gboolean hildon_time_editor_entry_keypress(GtkWidget * widget,
+ GdkEventKey * event,
+ gpointer data)
+{
+ HildonTimeEditor *editor;
+ HildonTimeEditorPrivate *priv;
+ gint cursor_pos;
+ gboolean r;
+
+ g_assert(GTK_IS_ENTRY(widget));
+ g_assert(event != NULL);
+ g_assert(HILDON_IS_TIME_EDITOR(data));
+
+ editor = HILDON_TIME_EDITOR(data);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+ cursor_pos = gtk_editable_get_position(GTK_EDITABLE(widget));
+
+ /* Show error message in case the key pressed is not allowed
+ (only digits and control characters are allowed )*/
+ if (!g_unichar_isdigit(event->keyval) && !(event->keyval & 0xF000)) {
+ g_signal_emit(editor, time_editor_signals[TIME_ERROR], 0, INVALID_CHAR, &r);
+ hildon_banner_show_information(widget, NULL, _("ckct_ib_illegal_character"));
+ return TRUE;
+ }
+
+ switch (event->keyval)
+ {
+ case GDK_Return:
+ /* Return key popups up time picker dialog. Visually it looks as if
+ the time picker icon was clicked. Before opening the time picker
+ the fields are first validated and fixed. */
+ hildon_time_editor_validate (editor, FALSE);
+ hildon_gtk_button_set_depressed(GTK_BUTTON(priv->iconbutton), TRUE);
+ hildon_time_editor_icon_clicked(widget, data);
+ hildon_gtk_button_set_depressed(GTK_BUTTON(priv->iconbutton), FALSE);
+ return TRUE;
+
+ case GDK_Left:
+ /* left arrow pressed in the entry. If we are on first position, try to
+ move to the previous field. */
+ if (cursor_pos == 0) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_LEFT);
+ return TRUE;
+ }
+ break;
+
+ case GDK_Right:
+ /* right arrow pressed in the entry. If we are on last position, try to
+ move to the next field. */
+ if (cursor_pos >= g_utf8_strlen(gtk_entry_get_text(GTK_ENTRY(widget)), -1)) {
+ (void) gtk_widget_child_focus(GTK_WIDGET(editor), GTK_DIR_RIGHT);
+ return TRUE;
+ }
+ break;
+
+ default:
+ break;
+ };
+
+ return FALSE;
+}
+
+/***
+ * Utility functions
+ */
+
+static void
+convert_to_12h (guint *h, gboolean *am)
+{
+ g_assert(0 <= *h && *h < 24);
+
+ /* 00:00 to 00:59 add 12 hours */
+ /* 01:00 to 11:59 straight to am */
+ /* 12:00 to 12:59 straight to pm */
+ /* 13:00 to 23:59 subtract 12 hours */
+
+ if ( *h == 0 ) { *am = TRUE; *h += 12;}
+ else if ( 1 <= *h && *h < 12 ) { *am = TRUE; }
+ else if ( 12 <= *h && *h < 13 ) { *am = FALSE; }
+ else { *am = FALSE; *h -= 12;}
+}
+
+static void
+convert_to_24h (guint *h, gboolean am)
+{
+ if (*h == 12 && am) /* 12 midnight - 12:59 AM subtract 12 hours */
+ {
+ *h -= 12;
+ }
+ else if (!am && 1 <= *h && *h < 12) /* 1:00 PM - 11:59 AM add 12 hours */
+ {
+ *h += 12;
+ }
+}
+
+/**
+ * hildon_time_editor_set_show_hours:
+ * @editor: The #HildonTimeEditor.
+ * @enable: Enable or disable showing of hours.
+ *
+ * This function shows or hides the hours field.
+ *
+ * Since: 0.12.4
+ **/
+void hildon_time_editor_set_show_hours(HildonTimeEditor * editor,
+ gboolean show_hours)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_TIME_EDITOR(editor));
+
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ if (show_hours != priv->show_hours) {
+ priv->show_hours = show_hours;
+
+ /* show/hide hours field and its ':' label if the value changed. */
+ if (show_hours) {
+ gtk_widget_show(priv->entries[ENTRY_HOURS]);
+ gtk_widget_show(priv->hm_label);
+ } else {
+ gtk_widget_hide(priv->entries[ENTRY_HOURS]);
+ gtk_widget_hide(priv->hm_label);
+ }
+
+ g_object_notify (G_OBJECT (editor), "show_hours");
+ }
+}
+
+/**
+ * hildon_time_editor_get_show_hours:
+ * @self: the @HildonTimeEditor widget.
+ *
+ * This function returns a boolean indicating the visibility of
+ * hours in the @HildonTimeEditor
+ *
+ * Return value: TRUE if hours are visible.
+ *
+ * Since: 0.12.4-1
+ **/
+gboolean hildon_time_editor_get_show_hours(HildonTimeEditor *editor)
+{
+ HildonTimeEditorPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_TIME_EDITOR (editor), FALSE);
+ priv = HILDON_TIME_EDITOR_GET_PRIVATE(editor);
+
+ return priv->show_hours;
+}
+
+/***
+ * Deprecated functions
+ */
+
+/**
+ * hildon_time_editor_show_seconds:
+ * @editor: the #HildonTimeEditor
+ * @enable: enable or disable showing of seconds
+ *
+ * This function is deprecated,
+ * use #hildon_time_editor_set_show_seconds instead.
+ */
+void hildon_time_editor_show_seconds(HildonTimeEditor * editor,
+ gboolean enable)
+{
+ hildon_time_editor_set_show_seconds (editor, enable);
+}
+/**
+ * hildon_time_editor_enable_duration_mode:
+ * @editor: the #HildonTimeEditor
+ * @enable: enable or disable duration editor mode
+ *
+ * This function is deprecated,
+ * use #hildon_time_editor_set_duration_mode instead.
+ */
+void hildon_time_editor_enable_duration_mode(HildonTimeEditor * editor,
+ gboolean enable)
+{
+ hildon_time_editor_set_duration_mode (editor, enable);
+}
+
+/* Idle callback */
+static gboolean
+_hildon_time_editor_entry_select_all (GtkWidget *widget)
+{
+ GDK_THREADS_ENTER ();
+ gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_TIME_EDITOR_H__
+#define __HILDON_TIME_EDITOR_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_TIME_EDITOR (hildon_time_editor_get_type())
+
+#define HILDON_TIME_EDITOR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_TIME_EDITOR, HildonTimeEditor))
+#define HILDON_TIME_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), HILDON_TYPE_TIME_EDITOR, HildonTimeEditorClass))
+
+#define HILDON_IS_TIME_EDITOR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_TIME_EDITOR))
+#define HILDON_IS_TIME_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_TIME_EDITOR))
+
+
+typedef enum
+{
+ NO_TIME_ERROR = -1,
+ MAX_HOURS,
+ MAX_MINS,
+ MAX_SECS,
+ MIN_HOURS,
+ MIN_MINS,
+ MIN_SECS,
+ EMPTY_HOURS,
+ EMPTY_MINS,
+ EMPTY_SECS,
+ MIN_DUR,
+ MAX_DUR,
+ INVALID_TIME,
+ INVALID_CHAR
+} HildonTimeEditorErrorType;
+
+typedef struct _HildonTimeEditor HildonTimeEditor;
+typedef struct _HildonTimeEditorClass HildonTimeEditorClass;
+
+struct _HildonTimeEditor {
+ GtkContainer parent;
+};
+
+struct _HildonTimeEditorClass {
+ GtkContainerClass parent_class;
+
+ gboolean (*time_error) (HildonTimeEditor *editor,
+ HildonTimeEditorErrorType type);
+};
+
+GType hildon_time_editor_get_type(void) G_GNUC_CONST;
+GtkWidget *hildon_time_editor_new(void);
+
+
+void hildon_time_editor_set_time (HildonTimeEditor * editor,
+ guint hours,
+ guint minutes,
+ guint seconds);
+
+void hildon_time_editor_get_time (HildonTimeEditor * editor,
+ guint * hours,
+ guint * minutes,
+ guint * seconds);
+
+#ifndef HILDON_DISABLE_DEPRECATED
+void hildon_time_editor_show_seconds (HildonTimeEditor * editor, gboolean enable);
+void hildon_time_editor_enable_duration_mode (HildonTimeEditor * editor, gboolean enable);
+#endif /* HILDON_DISABLE_DEPRECATED */
+
+
+void hildon_time_editor_set_duration_range (HildonTimeEditor * editor,
+ guint min_seconds,
+ guint max_seconds);
+
+void hildon_time_editor_get_duration_range (HildonTimeEditor * editor,
+ guint * min_seconds,
+ guint * max_seconds);
+
+void hildon_time_editor_set_ticks (HildonTimeEditor * editor, guint ticks);
+guint hildon_time_editor_get_ticks (HildonTimeEditor * editor);
+
+void hildon_time_editor_set_show_seconds (HildonTimeEditor * editor, gboolean show_seconds);
+gboolean hildon_time_editor_get_show_seconds (HildonTimeEditor * editor);
+
+void hildon_time_editor_set_show_hours (HildonTimeEditor * editor, gboolean show_hours);
+gboolean hildon_time_editor_get_show_hours (HildonTimeEditor * editor);
+
+void hildon_time_editor_set_duration_mode (HildonTimeEditor * editor, gboolean duration_mode);
+gboolean hildon_time_editor_get_duration_mode (HildonTimeEditor * editor);
+
+void hildon_time_editor_set_duration_min (HildonTimeEditor * editor, guint duration_min);
+guint hildon_time_editor_get_duration_min (HildonTimeEditor * editor);
+
+void hildon_time_editor_set_duration_max (HildonTimeEditor * editor, guint duration_max);
+guint hildon_time_editor_get_duration_max (HildonTimeEditor * editor);
+
+
+G_END_DECLS
+#endif /* __HILDON_TIME_EDITOR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-time-picker
+ * @short_description: A dialog popup widget which lets the user set the time
+ * @see_also: #HildonTimeEditor
+ *
+ * #HildonTimePicker is a dialog popup widget which lets the user set the time,
+ * using up/down arrows on hours and minutes. There are two arrows for minutes,
+ * so that minutes can be added also in 10 min increments.This widget is mainly
+ * used as a part of #HildonTimeEditor implementation.
+ */
+
+#include "hildon-time-picker.h"
+#include <hildon-widgets/hildon-defines.h>
+#include <hildon-widgets/hildon-private.h>
+#include <hildon-widgets/gtk-infoprint.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdk.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <langinfo.h>
+#include <libintl.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _(String) dgettext(PACKAGE, String)
+
+#define HILDON_TIME_PICKER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_TIME_PICKER, HildonTimePickerPrivate))
+
+#define DEFAULT_HOURS 1
+#define DEFAULT_MINUTES 1
+#define DEFAULT_ARROW_WIDTH 26
+#define DEFAULT_ARROW_HEIGHT 26
+
+#define MINS_IN_1H (60)
+#define MINS_IN_24H (MINS_IN_1H * 24)
+#define MINS_IN_12H (MINS_IN_1H * 12)
+
+#define HILDON_TIME_PICKER_LABEL_X_PADDING 0
+#define HILDON_TIME_PICKER_LABEL_Y_PADDING 1
+
+
+/* Indices for grouped labels in priv->widgets */
+enum
+{
+ WIDGET_GROUP_HOURS,
+ WIDGET_GROUP_10_MINUTES,
+ WIDGET_GROUP_1_MINUTES,
+ WIDGET_GROUP_AMPM,
+
+ WIDGET_GROUP_COUNT
+};
+
+/* Indices for up/down buttons in group->buttons */
+enum
+{
+ BUTTON_UP,
+ BUTTON_DOWN,
+
+ BUTTON_COUNT
+};
+
+typedef struct
+{
+ GtkWidget *frame;
+ GtkWidget *eventbox;
+ GtkLabel *label;
+
+ /* buttons are used for hours and minutes, but not for am/pm */
+ GtkWidget *buttons[BUTTON_COUNT];
+
+} HildonTimePickerWidgetGroup;
+
+static GtkDialogClass *parent_class;
+
+struct _HildonTimePickerPrivate
+{
+ HildonTimePickerWidgetGroup widgets[WIDGET_GROUP_COUNT];
+
+ gchar *am_symbol;
+ gchar *pm_symbol;
+
+ guint key_repeat;
+ guint minutes; /* time in minutes since midnight */
+ gint mul; /* for key repeat handling */
+ guint timer_id;
+
+ guint show_ampm : 1; /* 12 hour clock, show AM/PM */
+ guint ampm_left : 1;
+ guint button_press : 1;
+ guint start_key_repeat : 1;
+};
+
+enum
+{
+ PROP_MINUTES = 1
+};
+
+
+static const gint button_multipliers[WIDGET_GROUP_COUNT][2] =
+{
+ { MINS_IN_1H, -MINS_IN_1H },
+ { 10, -10 },
+ { 1, -1 },
+ { 0, 0 }
+};
+
+static void
+hildon_time_picker_class_init( HildonTimePickerClass *klass );
+
+static void
+hildon_time_picker_init( HildonTimePicker *picker );
+
+static gboolean
+hildon_time_picker_key_repeat_timeout( gpointer tpicker );
+
+static void
+hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes );
+
+static gboolean
+hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker );
+
+static gboolean
+hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker );
+static gboolean
+hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker );
+
+static void
+hildon_time_picker_finalize( GObject *object );
+
+static void
+hildon_time_picker_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec );
+
+static void
+hildon_time_picker_set_property( GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec );
+
+static gboolean
+hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
+ gpointer unused );
+
+static gboolean
+hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
+ gpointer unused );
+
+static gboolean
+hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
+ HildonTimePicker *picker );
+
+static gboolean
+hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
+ HildonTimePicker *picker );
+
+static gboolean
+hildon_time_picker_event_box_button_press( GtkWidget *widget, GdkEventKey *event,
+ gpointer unused );
+
+static void
+hildon_time_picker_map( GtkWidget *widget );
+
+static void
+frame_size_request (GtkWidget *widget, GtkRequisition *requistion);
+
+GType hildon_time_picker_get_type( void )
+{
+ static GType picker_type = 0;
+
+ if( !picker_type )
+ {
+ static const GTypeInfo picker_info =
+ {
+ sizeof(HildonTimePickerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)hildon_time_picker_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonTimePicker),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc)hildon_time_picker_init,
+ };
+ picker_type = g_type_register_static( GTK_TYPE_DIALOG, "HildonTimePicker",
+ &picker_info, 0 );
+ }
+ return picker_type;
+}
+
+
+static void
+hildon_time_picker_class_init( HildonTimePickerClass *klass )
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ parent_class = g_type_class_peek_parent( klass );
+
+ gobject_class->finalize = hildon_time_picker_finalize;
+ gobject_class->get_property = hildon_time_picker_get_property;
+ gobject_class->set_property = hildon_time_picker_set_property;
+ widget_class->map = hildon_time_picker_map;
+
+ /**
+ * HildonTimePicker:minutes:
+ *
+ * Currently selected time in minutes since midnight.
+ */
+ g_object_class_install_property( gobject_class, PROP_MINUTES,
+ g_param_spec_uint("minutes",
+ "Current minutes",
+ "The selected time in minutes "
+ "since midnight",
+ 0, MINS_IN_24H, 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE) );
+
+ gtk_widget_class_install_style_property( widget_class,
+ g_param_spec_uint("arrow-width",
+ "Arrow width",
+ "Increase/decrease arrows width.",
+ 0, G_MAXUINT,
+ DEFAULT_ARROW_WIDTH,
+ G_PARAM_READABLE) );
+
+ gtk_widget_class_install_style_property( widget_class,
+ g_param_spec_uint("arrow-height",
+ "Arrow height",
+ "Increase/decrease arrows height.",
+ 0, G_MAXUINT,
+ DEFAULT_ARROW_HEIGHT,
+ G_PARAM_READABLE) );
+
+ g_type_class_add_private( klass, sizeof(HildonTimePickerPrivate) );
+}
+
+/* Okay, this is really bad. We make the requisition of the frames a bit larger
+ * so that it doesn't "change" when digits are changed (see #37489). It's a
+ * really bad solution to a problem, but the whole layout of the time picker is
+ * on crack anyways */
+static void frame_size_request (GtkWidget *widget, GtkRequisition *requistion)
+{
+ int framed = requistion->width / 10;
+ requistion->width = (framed + 1) * 10;
+}
+
+static void hildon_time_picker_init( HildonTimePicker *picker )
+{
+ HildonTimePickerPrivate *priv = HILDON_TIME_PICKER_GET_PRIVATE(picker);
+ gint widget_group_table_column_pos[WIDGET_GROUP_COUNT];
+ GtkSettings *settings = NULL;
+ GtkDialog *dialog = GTK_DIALOG(picker);
+ GtkTable *table = NULL;
+ GtkWidget *maintocenter, *colon_label;
+ const struct tm *local = NULL;
+ time_t stamp;
+ gint i = 0;
+ GtkSizeGroup *size_group;
+
+ picker->priv = priv;
+
+ widget_group_table_column_pos[WIDGET_GROUP_HOURS] = 1;
+ widget_group_table_column_pos[WIDGET_GROUP_10_MINUTES] = 3;
+ widget_group_table_column_pos[WIDGET_GROUP_1_MINUTES] = 4;
+ widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 5;
+
+ /* Get AM/PM strings from locale. If they're set, the time is wanted
+ in 12 hour mode. */
+ priv->am_symbol = g_strdup(nl_langinfo(AM_STR));
+ priv->pm_symbol = g_strdup(nl_langinfo(PM_STR));
+
+ priv->show_ampm = priv->am_symbol[0] != '\0';
+ if (priv->show_ampm)
+ {
+ /* Check if AM/PM should be before or after time.
+ %p is the AM/PM string, so we assume that if the format string
+ begins with %p it's in the beginning, and in any other case it's
+ in the end (although that's not necessarily the case). */
+ if (strncmp(nl_langinfo(T_FMT_AMPM), "%p", 2) == 0)
+ {
+ /* Before time. Update column position. */
+ priv->ampm_left = TRUE;
+ widget_group_table_column_pos[WIDGET_GROUP_AMPM] = 0;
+ }
+ }
+
+ gtk_widget_push_composite_child();
+
+ /* Pack all our internal widgets into a table */
+ table = GTK_TABLE(gtk_table_new(3, 6, FALSE));
+
+ /* Put everything centered into window */
+ maintocenter = gtk_alignment_new( 0.5, 0, 0, 0 );
+
+ /* Create our internal widgets */
+ for (i = 0; i < WIDGET_GROUP_COUNT; i++)
+ {
+ HildonTimePickerWidgetGroup *group = &priv->widgets[i];
+ gint table_column = widget_group_table_column_pos[i];
+
+ /* Create frame and attach to table. With AM/PM label we're attaching
+ it later. */
+ group->frame = gtk_frame_new(NULL);
+ if (i != WIDGET_GROUP_AMPM)
+ {
+ gtk_table_attach(table, group->frame, table_column, table_column + 1,
+ 1, 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
+
+
+ }
+ /* FIXME: is it needed to force it to 0 here? */
+ gtk_container_set_border_width(GTK_CONTAINER(group->frame), 0);
+
+ /* Create eventbox inside frame */
+ group->eventbox = gtk_event_box_new();
+ gtk_container_add(GTK_CONTAINER(group->frame), group->eventbox);
+
+ g_object_set(group->eventbox, "can-focus", TRUE, NULL);
+ gtk_widget_set_events(group->eventbox,
+ GDK_FOCUS_CHANGE_MASK | GDK_BUTTON_PRESS_MASK );
+
+ /* Connect signals to eventbox */
+ g_signal_connect(group->eventbox, "key-release-event",
+ G_CALLBACK(hildon_time_picker_event_box_key_release),
+ picker);
+ g_signal_connect(group->eventbox, "key-press-event",
+ G_CALLBACK(hildon_time_picker_event_box_key_press),
+ picker);
+ g_signal_connect(group->eventbox, "focus-in-event",
+ G_CALLBACK(hildon_time_picker_event_box_focus_in),
+ picker);
+ g_signal_connect(group->eventbox, "focus-out-event",
+ G_CALLBACK(hildon_time_picker_event_box_focus_out),
+ picker);
+ g_signal_connect(group->eventbox, "button-press-event",
+ G_CALLBACK(hildon_time_picker_event_box_button_press),
+ picker);
+
+ /* Create label inside eventbox */
+ group->label = GTK_LABEL(gtk_label_new(NULL));
+ g_signal_connect(group->frame, "size-request",
+ G_CALLBACK(frame_size_request),
+ NULL);
+ gtk_misc_set_alignment (GTK_MISC (group->label), 0.5, 0.5);
+ gtk_container_add(GTK_CONTAINER(group->eventbox), GTK_WIDGET(group->label));
+
+ if (i != WIDGET_GROUP_AMPM)
+ {
+ gint button;
+
+ /* Add some padding to hour and minute labels, and make them bigger */
+ gtk_misc_set_padding(GTK_MISC(group->label),
+ HILDON_TIME_PICKER_LABEL_X_PADDING,
+ HILDON_TIME_PICKER_LABEL_Y_PADDING);
+ gtk_widget_set_name(GTK_WIDGET(group->label), "osso-LargeFont");
+
+ /* Create up and down buttons for hours and mins */
+ for (button = 0; button < BUTTON_COUNT; button++)
+ {
+ gint table_row = button == BUTTON_UP ? 0 : 2;
+
+ group->buttons[button] = gtk_button_new();
+ gtk_table_attach(table, group->buttons[button],
+ table_column, table_column + 1,
+ table_row, table_row + 1,
+ GTK_SHRINK, GTK_SHRINK, 0, 0);
+ g_object_set(group->buttons[button], "can-focus", FALSE, NULL);
+
+ /* Connect signals */
+ g_signal_connect(group->buttons[button], "button-press-event",
+ G_CALLBACK(hildon_time_picker_arrow_press), picker);
+ g_signal_connect(group->buttons[button], "button-release-event",
+ G_CALLBACK(hildon_time_picker_arrow_release), picker);
+ }
+
+ gtk_widget_set_name(group->buttons[BUTTON_UP],
+ "hildon-time-picker-up");
+ gtk_widget_set_name(group->buttons[BUTTON_DOWN],
+ "hildon-time-picker-down");
+ }
+ }
+
+ /* Label between hour and minutes */
+ colon_label = gtk_label_new(NULL);
+ _hildon_time_editor_get_time_separators(GTK_LABEL(colon_label), NULL);
+
+ gtk_table_attach(table, colon_label, 2, 3, 1, 2,
+ GTK_SHRINK, GTK_SHRINK, 6, 0); /* FIXME: magic */
+ gtk_widget_set_name(colon_label, "osso-LargeFont" );
+
+ priv->minutes = 0;
+ priv->mul = 0;
+ priv->key_repeat = 0;
+ priv->start_key_repeat = FALSE;
+ priv->timer_id = 0;
+ priv->button_press = FALSE;
+
+ gtk_table_set_row_spacing( table, 0, 6 );
+ gtk_table_set_row_spacing( table, 1, 6 );
+
+ if (priv->show_ampm)
+ {
+ gint table_column = widget_group_table_column_pos[WIDGET_GROUP_AMPM];
+ GtkWidget *ampmtotop = NULL;
+
+ /* Show the AM/PM label centered vertically */
+ ampmtotop = gtk_alignment_new( 0, 0.5, 0, 0 );
+ gtk_table_attach(table, ampmtotop, table_column, table_column + 1,
+ 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
+ gtk_container_add(GTK_CONTAINER(ampmtotop),
+ priv->widgets[WIDGET_GROUP_AMPM].frame);
+
+ if (table_column != 0)
+ gtk_table_set_col_spacing(table, table_column - 1, 9);
+
+ /* Connect AM/PM signal handlers */
+ g_signal_connect(priv->widgets[WIDGET_GROUP_AMPM].eventbox,
+ "button-release-event",
+ G_CALLBACK(hildon_time_picker_ampm_release), picker);
+ }
+
+ gtk_widget_pop_composite_child();
+
+ /* Get button press repeater timeout from settings (in milliseconds) */
+ settings = gtk_settings_get_default();
+ g_object_get( settings, "gtk-update-timeout", &priv->key_repeat, NULL );
+
+ /* This dialog isn't modal */
+ gtk_window_set_modal( GTK_WINDOW(dialog), FALSE );
+ /* And final dialog packing */
+ gtk_dialog_set_has_separator( dialog, FALSE );
+ gtk_dialog_add_button( dialog, _("ecdg_bd_time_picker_close"),
+ GTK_RESPONSE_OK );
+
+ gtk_container_add( GTK_CONTAINER(maintocenter), GTK_WIDGET(table) );
+ gtk_box_pack_start( GTK_BOX(dialog->vbox), maintocenter, TRUE, FALSE, 0 );
+
+ /* Set default time to current time */
+ stamp = time( NULL );
+ local = localtime( &stamp );
+ hildon_time_picker_set_time( picker, local->tm_hour, local->tm_min );
+
+ gtk_widget_show_all( maintocenter );
+}
+
+static void
+hildon_time_picker_set_property( GObject *object, guint param_id,
+ const GValue *value, GParamSpec *pspec )
+{
+ HildonTimePicker *picker = HILDON_TIME_PICKER(object);
+
+ switch( param_id )
+ {
+ case PROP_MINUTES:
+ hildon_time_picker_change_time( picker, g_value_get_uint(value) );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_time_picker_finalize( GObject *object )
+{
+ HildonTimePicker *picker = HILDON_TIME_PICKER(object);
+
+ /* Make sure the timer is stopped */
+ if (picker->priv->timer_id)
+ g_source_remove(picker->priv->timer_id);
+
+ g_free(picker->priv->am_symbol);
+ g_free(picker->priv->pm_symbol);
+
+ if (G_OBJECT_CLASS(parent_class)->finalize)
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+hildon_time_picker_get_property( GObject *object, guint param_id,
+ GValue *value, GParamSpec *pspec )
+{
+ HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(object)->priv;
+
+ switch( param_id )
+ {
+ case PROP_MINUTES:
+ g_value_set_uint( value, priv->minutes );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_time_picker_map( GtkWidget *widget )
+{
+ guint width, height;
+ gint i, button;
+ HildonTimePickerPrivate *priv = HILDON_TIME_PICKER(widget)->priv;
+
+ /* Widget is now mapped. Set border for the dialog. */
+ gdk_window_set_decorations( widget->window, GDK_DECOR_BORDER );
+
+ /* Update hour/minute up/down buttons sizes from style properties */
+ gtk_widget_style_get( widget,
+ "arrow-width", &width,
+ "arrow-height", &height, NULL );
+ for (i = 0; i < WIDGET_GROUP_COUNT; i++)
+ {
+ if (priv->widgets[i].buttons[0] != NULL)
+ {
+ for (button = 0; button < BUTTON_COUNT; button++)
+ {
+ gtk_widget_set_size_request(priv->widgets[i].buttons[button],
+ width, height);
+ }
+ }
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->map( widget );
+}
+
+
+static gboolean
+hildon_time_picker_event_box_button_press( GtkWidget *widget,
+ GdkEventKey *event, gpointer unused )
+{
+ /* Clicked hour/minute field. Move focus to it. */
+ gtk_widget_grab_focus( widget );
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_ampm_release( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker )
+{
+ /* Clicked AM/PM label. Move focus to it and move the time by 12 hours. */
+ gtk_widget_grab_focus( widget );
+ hildon_time_picker_change_time( picker, picker->priv->minutes > MINS_IN_12H ?
+ picker->priv->minutes - MINS_IN_12H :
+ picker->priv->minutes + MINS_IN_12H );
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_arrow_press( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker )
+{
+ HildonTimePickerPrivate *priv = picker->priv;
+ gint i, button;
+ gint newval = 0;
+
+ /* Make sure we don't add repeat timer twice. Normally it shouldn't
+ happen but WM can cause button release to be lost. */
+ if( priv->button_press )
+ return FALSE;
+
+ priv->start_key_repeat = priv->button_press = TRUE;
+
+ /* Find the widget which was clicked */
+ priv->mul = 0;
+ for (i = 0; i < WIDGET_GROUP_COUNT; i++)
+ {
+ for (button = 0; button < BUTTON_COUNT; button++)
+ {
+ if (priv->widgets[i].buttons[button] == widget)
+ {
+ /* Update multiplier and move the focus to the clicked field */
+ priv->mul = button_multipliers[i][button];
+ gtk_widget_grab_focus(priv->widgets[i].eventbox);
+ break;
+ }
+ }
+ }
+ g_assert(priv->mul != 0);
+
+ /* Change the time now, wrapping if needed. */
+ newval = priv->minutes + priv->mul;
+ if( newval < 0 )
+ newval += MINS_IN_24H;
+
+ hildon_time_picker_change_time( picker, newval );
+
+ /* Keep changing the time as long as button is being pressed.
+ The first repeat takes 3 times longer to start than the rest. */
+ priv->timer_id = g_timeout_add(priv->key_repeat * 3,
+ hildon_time_picker_key_repeat_timeout,
+ picker);
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_arrow_release( GtkWidget *widget, GdkEvent *event,
+ HildonTimePicker *picker )
+{
+ HildonTimePickerPrivate *priv = picker->priv;
+ if( priv->timer_id )
+ {
+ /* Stop repeat timer */
+ g_source_remove( priv->timer_id );
+ priv->timer_id = 0;
+ }
+ priv->button_press = FALSE;
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_event_box_focus_in( GtkWidget *widget, GdkEvent *event,
+ gpointer unused )
+{
+ /* Draw the widget in selected state so focus shows clearly. */
+ gtk_widget_set_state( widget, GTK_STATE_SELECTED );
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_event_box_focus_out( GtkWidget *widget, GdkEvent *event,
+ gpointer unused )
+{
+ /* Draw the widget in normal state */
+ gtk_widget_set_state( widget, GTK_STATE_NORMAL );
+ return FALSE;
+}
+
+static gint
+hildon_time_picker_lookup_eventbox_group(HildonTimePicker *picker,
+ GtkWidget *widget)
+{
+ gint i;
+
+ for (i = 0; i < WIDGET_GROUP_COUNT; i++)
+ {
+ if (picker->priv->widgets[i].eventbox == widget)
+ return i;
+ }
+ return -1;
+}
+
+static gboolean
+hildon_time_picker_event_box_key_press( GtkWidget *widget, GdkEventKey *event,
+ HildonTimePicker *picker )
+{
+ HildonTimePickerPrivate *priv = picker->priv;
+ HildonTimePickerWidgetGroup *group;
+ gint group_idx;
+
+ /* If mouse button is already being pressed, ignore this keypress */
+ if( priv->timer_id )
+ return TRUE;
+
+ group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
+ group = group_idx < 0 ? NULL : &picker->priv->widgets[group_idx];
+
+ /* Handle keypresses in hour/minute/AMPM fields */
+ switch( event->keyval )
+ {
+ case GDK_Up:
+ case GDK_Down:
+ if (group != NULL)
+ {
+ gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
+
+ if (group->buttons[button] != NULL)
+ {
+ /* Fake a button up/down press */
+ hildon_time_picker_arrow_press(group->buttons[button], NULL, picker);
+ gtk_widget_set_state(group->buttons[button], GTK_STATE_SELECTED);
+ }
+ else
+ {
+ /* Fake a AM/PM button release */
+ g_assert(group_idx == WIDGET_GROUP_AMPM);
+ hildon_time_picker_ampm_release(group->eventbox, NULL, picker);
+ }
+ }
+ return TRUE;
+
+ case GDK_Left:
+ /* If we're in leftmost field, stop this keypress signal.
+ Otherwise let the default key handler move focus to field in left. */
+ if (priv->show_ampm && priv->ampm_left)
+ {
+ /* AM/PM is the leftmost field */
+ if (group_idx == WIDGET_GROUP_AMPM)
+ return TRUE;
+ }
+ else
+ {
+ /* Hours is the leftmost field */
+ if (group_idx == WIDGET_GROUP_HOURS)
+ return TRUE;
+ }
+ break;
+
+ case GDK_Right:
+ /* If we're in rightmost field, stop this keypress signal.
+ Otherwise let the default key handler move focus to field in right. */
+ if (priv->show_ampm && !priv->ampm_left)
+ {
+ /* AM/PM is the rightmost field */
+ if (group_idx == WIDGET_GROUP_AMPM)
+ return TRUE;
+ }
+ else
+ {
+ /* 1-minutes is the leftmost field */
+ if (group_idx == WIDGET_GROUP_1_MINUTES)
+ return TRUE;
+ }
+ break;
+
+ case GDK_Escape:
+ gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_CANCEL);
+ return TRUE;
+
+ case GDK_Return:
+ gtk_dialog_response (GTK_DIALOG (picker), GTK_RESPONSE_OK);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+hildon_time_picker_event_box_key_release( GtkWidget *widget, GdkEventKey *event,
+ HildonTimePicker *picker )
+{
+ HildonTimePickerWidgetGroup *group;
+ gint group_idx;
+
+ /* Fake a button release if in key-press handler we faked a button press. */
+ switch( event->keyval )
+ {
+ case GDK_Up:
+ case GDK_Down:
+ group_idx = hildon_time_picker_lookup_eventbox_group(picker, widget);
+ if (group_idx >= 0)
+ {
+ gint button = event->keyval == GDK_Up ? BUTTON_UP : BUTTON_DOWN;
+
+ group = &picker->priv->widgets[group_idx];
+ if (group->buttons[button] != NULL)
+ {
+ /* Fake a button up/down press */
+ gtk_widget_set_state(group->buttons[button], GTK_STATE_NORMAL);
+ hildon_time_picker_arrow_release(group->buttons[button],
+ NULL, picker);
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/* Button up/down is being pressed. Update the time. */
+static gboolean
+hildon_time_picker_key_repeat_timeout( gpointer tpicker )
+{
+ HildonTimePicker *picker;
+ HildonTimePickerPrivate *priv = NULL;
+ gint newval = 0;
+
+ GDK_THREADS_ENTER ();
+
+ picker = HILDON_TIME_PICKER(tpicker);
+ g_assert(picker != NULL);
+
+ priv = picker->priv;
+
+ /* Change the time, wrapping if needed */
+ newval = priv->minutes + priv->mul;
+ if( newval < 0 )
+ newval += MINS_IN_24H;
+
+ hildon_time_picker_change_time( picker, newval );
+
+ if( priv->start_key_repeat )
+ {
+ /* This is the first repeat. Shorten the timeout to key_repeat
+ (instead of the first time's 3*key_repeat) */
+ priv->timer_id = g_timeout_add(priv->key_repeat,
+ hildon_time_picker_key_repeat_timeout,
+ picker);
+ priv->start_key_repeat = FALSE;
+
+ GDK_THREADS_LEAVE ();
+ return FALSE;
+ }
+
+ GDK_THREADS_LEAVE ();
+ return TRUE;
+}
+
+
+
+static void
+hildon_time_picker_change_time( HildonTimePicker *picker, guint minutes )
+{
+ HildonTimePickerPrivate *priv = picker->priv;
+ gchar str[3] = "00";
+ guint hours = 0;
+ gboolean ampm = TRUE;
+
+ /* If the minutes isn't in valid range, wrap them. */
+ minutes %= MINS_IN_24H;
+
+ if( priv->minutes == minutes )
+ return;
+
+ /* Minutes changed. Update widgets to show the new time. */
+ priv->minutes = minutes;
+
+ if (priv->show_ampm)
+ {
+ /* am < 12:00 <= pm */
+ ampm = !((guint)(minutes / MINS_IN_12H));
+ /* 12:00 - 23:59 -> 00:00 - 11:59 */
+ minutes %= MINS_IN_12H;
+ if( minutes < MINS_IN_1H )
+ /* 00:mm is always shown as 12:mm */
+ minutes += MINS_IN_12H;
+
+ /* Update the AM/PM label */
+ gtk_label_set_text(priv->widgets[WIDGET_GROUP_AMPM].label,
+ ampm ? priv->am_symbol : priv->pm_symbol);
+ }
+
+ /* Update hour and minute fields */
+ hours = minutes / MINS_IN_1H;
+ minutes %= MINS_IN_1H;
+
+ snprintf(str, sizeof(str), "%02d", hours);
+ gtk_label_set_text(priv->widgets[WIDGET_GROUP_HOURS].label, str);
+
+ snprintf(str, sizeof(str), "%d", minutes / 10);
+ gtk_label_set_text(priv->widgets[WIDGET_GROUP_10_MINUTES].label, str);
+
+ snprintf(str, sizeof(str), "%d", minutes % 10);
+ gtk_label_set_text(priv->widgets[WIDGET_GROUP_1_MINUTES].label, str);
+
+ g_object_notify( G_OBJECT(picker), "minutes" );
+}
+
+/**
+ * hildon_time_picker_new:
+ * @parent: parent window
+ *
+ * #HildonTimePicker shows time picker dialog. The close button is placed
+ * in the dialog's action area and time picker is placed in dialogs vbox.
+ * The actual time picker consists of two #GtkLabel fields - one for hours
+ * and one for minutes - and an AM/PM button. A colon (:) is placed
+ * between hour and minute fields.
+ *
+ * Returns: pointer to a new #HildonTimePicker widget.
+ */
+GtkWidget *hildon_time_picker_new( GtkWindow *parent )
+{
+ GtkWidget *widget = g_object_new( HILDON_TYPE_TIME_PICKER,
+ "minutes", 360, NULL );
+
+ if( parent )
+ gtk_window_set_transient_for( GTK_WINDOW(widget), parent );
+
+ return GTK_WIDGET(widget);
+}
+
+/**
+ * hildon_time_picker_set_time:
+ * @picker: the #HildonTimePicker widget
+ * @hours: hours
+ * @minutes: minutes
+ *
+ * Sets the time of the #HildonTimePicker widget.
+ */
+void hildon_time_picker_set_time( HildonTimePicker *picker,
+ guint hours, guint minutes )
+{
+ g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
+ hildon_time_picker_change_time( picker, hours * MINS_IN_1H + minutes );
+}
+
+/**
+ * hildon_time_picker_get_time:
+ * @picker: the #HildonTimePicker widget
+ * @hours: hours
+ * @minutes: minutes
+ *
+ * Gets the time of the #HildonTimePicker widget.
+ */
+void hildon_time_picker_get_time( HildonTimePicker *picker,
+ guint *hours, guint *minutes )
+{
+ guint current;
+ g_return_if_fail( HILDON_IS_TIME_PICKER(picker) );
+
+ current = picker->priv->minutes;
+ *hours = current / MINS_IN_1H;
+ *minutes = current % MINS_IN_1H;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_TIME_PICKER_H__
+#define __HILDON_TIME_PICKER_H__
+
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+
+#define HILDON_TYPE_TIME_PICKER (hildon_time_picker_get_type())
+#define HILDON_TIME_PICKER(obj) (GTK_CHECK_CAST (obj, \
+ HILDON_TYPE_TIME_PICKER, \
+ HildonTimePicker))
+#define HILDON_TIME_PICKER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
+ HILDON_TYPE_TIME_PICKER,\
+ HildonTimePickerClass))
+#define HILDON_IS_TIME_PICKER(obj) (GTK_CHECK_TYPE (obj, \
+ HILDON_TYPE_TIME_PICKER))
+#define HILDON_IS_TIME_PICKER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass),\
+ HILDON_TYPE_TIME_PICKER))
+
+
+typedef struct _HildonTimePicker HildonTimePicker;
+typedef struct _HildonTimePickerClass HildonTimePickerClass;
+typedef struct _HildonTimePickerPrivate HildonTimePickerPrivate;
+
+
+struct _HildonTimePicker
+{
+ GtkDialog parent;
+ HildonTimePickerPrivate *priv;
+};
+
+struct _HildonTimePickerClass
+{
+ GtkDialogClass parent_class;
+};
+
+
+GType hildon_time_picker_get_type( void ) G_GNUC_CONST;
+
+GtkWidget *hildon_time_picker_new( GtkWindow *parent );
+
+void hildon_time_picker_set_time( HildonTimePicker *picker,
+ guint hours, guint minutes );
+
+void hildon_time_picker_get_time( HildonTimePicker *picker,
+ guint *hours, guint *minutes );
+
+
+G_END_DECLS
+#endif /* __HILDON_TIME_PICKER_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_VOLUMEBAR_PRIVATE__
+#define __HILDON_VOLUMEBAR_PRIVATE__
+
+#include <gtk/gtktogglebutton.h>
+#include <hildon-widgets/hildon-volumebar-range.h>
+
+G_BEGIN_DECLS
+#define HILDON_VOLUMEBAR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_VOLUMEBAR, HildonVolumebarPrivate));
+
+typedef struct _HildonVolumebarPrivate HildonVolumebarPrivate;
+
+struct _HildonVolumebarPrivate {
+ HildonVolumebarRange *volumebar;
+ GtkToggleButton *tbutton;
+ gboolean is_toolbar; /* is inside toolbar (for horizontal volumebar) */
+ GdkWindow *event_window; /* input-only window to catch insensitive presses */
+};
+
+void _hildon_volumebar_mute_toggled(HildonVolumebar * self);
+
+G_END_DECLS
+#endif /* __HILDON_VOLUMEBAR_PRIVATE__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * @file hildon-volumebar-range.c
+ *
+ * This file contains the implementation of the HildonVolumebarRange.
+ * This widget is an "workhorse" for #HildonVolumebar widget.
+ * It is not designed to be used as a standalone widget.
+ *
+ * Purpose of this widget is to act as an "container" for GtkScale
+ * widget. #HildonVolumebarRange changes some event parameters so
+ * that #HildonVolumebar can meet its specifications.
+ *
+ * Currently #HildonVolumebarRange models range of [0..100].
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtkrange.h>
+#include <gdk/gdkkeysyms.h>
+#include "hildon-volumebar-range.h"
+
+#define VOLUMEBAR_RANGE_INITIAL_VALUE 50.0
+#define VOLUMEBAR_RANGE_MINIMUM_VALUE 0.0
+#define VOLUMEBAR_RANGE_MAXIMUM_VALUE 100.0
+#define VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE 5.0
+#define VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE 5.0
+#define VOLUMEBAR_RANGE_PAGE_SIZE_VALUE 0.0
+
+#define CHANGE_THRESHOLD 0.001
+
+static GtkScaleClass *parent_class;
+
+static void hildon_volumebar_range_class_init(HildonVolumebarRangeClass *
+ volumerange_class);
+static void hildon_volumebar_range_init(HildonVolumebarRange *
+ volumerange);
+static void hildon_volumebar_range_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_volumebar_range_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+static gint hildon_volumebar_range_button_press_event(GtkWidget * widget,
+ GdkEventButton *
+ event);
+static gint hildon_volumebar_range_button_release_event(GtkWidget * widget,
+ GdkEventButton *
+ event);
+static gboolean hildon_volumebar_range_keypress(GtkWidget * widget,
+ GdkEventKey * event);
+
+enum {
+ PROP_NONE = 0,
+ PROP_LEVEL
+};
+
+GType
+hildon_volumebar_range_get_type(void)
+{
+ static GType volumerange_type = 0;
+
+ if (!volumerange_type) {
+ static const GTypeInfo volumerange_info = {
+ sizeof(HildonVolumebarRangeClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_volumebar_range_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonVolumebarRange),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_volumebar_range_init,
+ };
+ volumerange_type = g_type_register_static(GTK_TYPE_SCALE,
+ "HildonVolumebarRange",
+ &volumerange_info, 0);
+ }
+ return volumerange_type;
+}
+
+static void
+hildon_volumebar_range_class_init(HildonVolumebarRangeClass *
+ volumerange_class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(volumerange_class);
+ GObjectClass *object_class = G_OBJECT_CLASS(volumerange_class);
+
+ parent_class = g_type_class_peek_parent(volumerange_class);
+
+ widget_class->button_press_event =
+ hildon_volumebar_range_button_press_event;
+ widget_class->button_release_event =
+ hildon_volumebar_range_button_release_event;
+ widget_class->key_press_event = hildon_volumebar_range_keypress;
+
+ object_class->set_property = hildon_volumebar_range_set_property;
+ object_class->get_property = hildon_volumebar_range_get_property;
+
+ g_object_class_install_property(object_class,
+ PROP_LEVEL,
+ g_param_spec_double("level",
+ "Level",
+ "Current volume level",
+ VOLUMEBAR_RANGE_MINIMUM_VALUE,
+ VOLUMEBAR_RANGE_MAXIMUM_VALUE,
+ VOLUMEBAR_RANGE_INITIAL_VALUE,
+ G_PARAM_READWRITE));
+ return;
+}
+
+static void
+hildon_volumebar_range_init(HildonVolumebarRange * volumerange)
+{
+ /* stepper_a = "less", stepper_d = "more" */
+ GTK_RANGE(volumerange)->has_stepper_a = TRUE;
+ GTK_RANGE(volumerange)->has_stepper_d = TRUE;
+}
+
+static void
+hildon_volumebar_range_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec)
+{
+ HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE(object);
+
+ switch (prop_id) {
+ case PROP_LEVEL:
+ hildon_volumebar_range_set_level(range, g_value_get_double(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_volumebar_range_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec)
+{
+ HildonVolumebarRange *range = HILDON_VOLUMEBAR_RANGE(object);
+
+ switch (prop_id) {
+ case PROP_LEVEL:
+ g_value_set_double(value, hildon_volumebar_range_get_level(range));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static
+gboolean hildon_volumebar_range_keypress(GtkWidget * widget,
+ GdkEventKey * event)
+{
+ /* Accept arrow keys only if they match the orientation of the widget */
+ if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (event->keyval == GDK_Up || event->keyval == GDK_Down) {
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (event->keyval == GDK_Left || event->keyval == GDK_Right) {
+ return FALSE;
+ }
+ }
+
+ return ((GTK_WIDGET_CLASS(parent_class)->key_press_event) (widget,
+ event));
+}
+
+GtkWidget *
+hildon_volumebar_range_new(GtkOrientation orientation)
+{
+ GtkAdjustment * adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (VOLUMEBAR_RANGE_INITIAL_VALUE,
+ VOLUMEBAR_RANGE_MINIMUM_VALUE,
+ VOLUMEBAR_RANGE_MAXIMUM_VALUE,
+ VOLUMEBAR_RANGE_STEP_INCREMENT_VALUE,
+ VOLUMEBAR_RANGE_PAGE_INCREMENT_VALUE,
+ VOLUMEBAR_RANGE_PAGE_SIZE_VALUE));
+ HildonVolumebarRange *self =
+ g_object_new(HILDON_TYPE_VOLUMEBAR_RANGE,
+ "adjustment", adjustment,
+ NULL);
+
+ GTK_RANGE(self)->orientation = orientation;
+
+ /* Default vertical range is upside down for purposes of this widget */
+ gtk_range_set_inverted(GTK_RANGE(self),
+ (orientation == GTK_ORIENTATION_VERTICAL));
+
+ return GTK_WIDGET(self);
+}
+
+gdouble
+hildon_volumebar_range_get_level(HildonVolumebarRange * self)
+{
+ g_return_val_if_fail(HILDON_IS_VOLUMEBAR_RANGE(self), -1.0);
+
+ return gtk_adjustment_get_value(gtk_range_get_adjustment(GTK_RANGE(self)));
+}
+
+void
+hildon_volumebar_range_set_level(HildonVolumebarRange * self,
+ gdouble level)
+{
+ GtkAdjustment *adjustment;
+
+ g_return_if_fail(HILDON_IS_VOLUMEBAR_RANGE(self));
+
+ adjustment = gtk_range_get_adjustment(GTK_RANGE(self));
+
+ /* Check that value has actually changed. Note that it's not safe to
+ * just compare if floats are equivalent or not */
+ if (ABS(gtk_adjustment_get_value(adjustment) - level) > CHANGE_THRESHOLD) {
+ gtk_adjustment_set_value(adjustment, level);
+ }
+}
+
+static gint
+hildon_volumebar_range_button_press_event(GtkWidget * widget,
+ GdkEventButton *
+ event)
+{
+ gboolean result = FALSE;
+
+ /* FIXME: By default, clicking left mouse button on GtkRange moves the
+ slider by one step towards the click location. However, we want stylus
+ taps to move the slider to the position of the tap, which by default
+ is the middle button behaviour. To avoid breaking default GtkRange
+ behaviour, this has been implemented by faking a middle button press. */
+ event->button = (event->button == 1) ? 2 : event->button;
+ if (GTK_WIDGET_CLASS(parent_class)->button_press_event) {
+ result =
+ GTK_WIDGET_CLASS(parent_class)->button_press_event(widget,
+ event);
+ }
+ return result;
+}
+
+static gint
+hildon_volumebar_range_button_release_event(GtkWidget * widget,
+ GdkEventButton *
+ event)
+{
+ gboolean result = FALSE;
+
+ /* FIXME: By default, clicking left mouse button on GtkRange moves the
+ slider by one step towards the click location. However, we want stylus
+ taps to move the slider to the position of the tap, which by default
+ is the middle button behaviour. To avoid breaking default GtkRange
+ behaviour, this has been implemented by faking a middle button press. */
+ event->button = event->button == 1 ? 2 : event->button;
+ if (GTK_WIDGET_CLASS(parent_class)->button_release_event) {
+ result =
+ GTK_WIDGET_CLASS(parent_class)->button_release_event(widget,
+ event);
+ }
+ return result;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_VOLUMEBAR_RANGE_H__
+#define __HILDON_VOLUMEBAR_RANGE_H__
+
+#include <gtk/gtkscale.h>
+
+G_BEGIN_DECLS
+
+/**
+ * HILDON_VOLUMEBAR_RANGE_TYPE
+ *
+ * Macro for getting type of volumebar range.
+ * Since: 0.12.10
+ */
+#define HILDON_TYPE_VOLUMEBAR_RANGE ( hildon_volumebar_range_get_type() )
+
+/**
+ * HILDON_VOLUMEBAR_RANGE_TYPE
+ *
+ * Deprecated: use #HILDON_VOLUMEBAR_RANGE_TYPE instead
+ */
+#define HILDON_VOLUMEBAR_RANGE_TYPE HILDON_TYPE_VOLUMEBAR_RANGE
+
+
+#define HILDON_VOLUMEBAR_RANGE(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_VOLUMEBAR_RANGE, HildonVolumebarRange))
+#define HILDON_VOLUMEBAR_RANGE_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_VOLUMEBAR_RANGE, HildonVolumebarRangeClass))
+#define HILDON_IS_VOLUMEBAR_RANGE(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_VOLUMEBAR_RANGE))
+#define HILDON_IS_VOLUMEBAR_RANGE_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VOLUMEBAR_RANGE))
+
+typedef struct _HildonVolumebarRange HildonVolumebarRange;
+typedef struct _HildonVolumebarRangeClass HildonVolumebarRangeClass;
+
+struct _HildonVolumebarRange {
+ GtkScale scale;
+};
+
+struct _HildonVolumebarRangeClass {
+ GtkScaleClass parent_class;
+};
+
+GType hildon_volumebar_range_get_type (void) G_GNUC_CONST;
+GtkWidget * hildon_volumebar_range_new (GtkOrientation orientation);
+gdouble hildon_volumebar_range_get_level (HildonVolumebarRange *self);
+void hildon_volumebar_range_set_level (HildonVolumebarRange *self,
+ gdouble level);
+
+
+G_END_DECLS
+
+#endif /* __HILDON_VOLUMEBAR_RANGE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-volumebar
+ * @short_description: Base class for widgets that display a volume bar
+ * @see_also: #HildonHVolumebar, #HildonVVolumebar
+ *
+ * #HildonVolumebar is a base class for widgets that display a volume bar that
+ * allows increasing or decreasing volume within a predefined range, and muting
+ * the volume when users click the mute icon.
+ */
+
+#include <gtk/gtkwindow.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "hildon-volumebar.h"
+#include "hildon-volumebar-range.h"
+#include "hildon-volumebar-private.h"
+
+static GtkContainerClass *parent_class;
+
+static void
+hildon_volumebar_class_init(HildonVolumebarClass * volumebar_class);
+static void
+hildon_volumebar_init(HildonVolumebar * volumebar);
+
+static void
+hildon_child_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void
+hildon_volumebar_destroy(GtkObject * self);
+
+static void hildon_volumebar_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec);
+static void hildon_volumebar_get_property(GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec);
+
+static void mute_toggled (HildonVolumebar *self);
+
+static gboolean
+hildon_volumebar_key_press(GtkWidget * widget,
+ GdkEventKey * event);
+
+static void hildon_volumebar_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void hildon_volumebar_realize (GtkWidget *widget);
+static void hildon_volumebar_unrealize (GtkWidget *widget);
+static void hildon_volumebar_map (GtkWidget *widget);
+static void hildon_volumebar_unmap (GtkWidget *widget);
+static void hildon_volumebar_notify (GObject *self, GParamSpec *param);
+
+
+enum
+{
+ MUTE_TOGGLED_SIGNAL,
+ LEVEL_CHANGED_SIGNAL,
+ LAST_SIGNAL
+};
+
+enum {
+ PROP_NONE = 0,
+ PROP_HILDON_HAS_MUTE,
+ PROP_HILDON_FOCUSABLE,
+ PROP_HILDON_LEVEL,
+ PROP_HILDON_MUTE
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType
+hildon_volumebar_get_type(void)
+{
+ static GType volumebar_type = 0;
+
+ if (!volumebar_type) {
+ static const GTypeInfo volumebar_info = {
+ sizeof(HildonVolumebarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_volumebar_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonVolumebar),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_volumebar_init,
+ };
+ volumebar_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonVolumebar",
+ &volumebar_info, 0);
+ }
+ return volumebar_type;
+}
+
+static void
+hildon_volumebar_class_init(HildonVolumebarClass *volumebar_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (volumebar_class);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS(volumebar_class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(volumebar_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(volumebar_class);
+
+ parent_class = g_type_class_peek_parent(volumebar_class);
+
+ g_type_class_add_private(volumebar_class,
+ sizeof(HildonVolumebarPrivate));
+
+ /* Because we derived our widget from GtkContainer, we should also
+ override forall method */
+ volumebar_class->mute_toggled = mute_toggled;
+ container_class->forall = hildon_child_forall;
+ widget_class->size_allocate = hildon_volumebar_size_allocate;
+ widget_class->realize = hildon_volumebar_realize;
+ widget_class->unrealize = hildon_volumebar_unrealize;
+ widget_class->map = hildon_volumebar_map;
+ widget_class->unmap = hildon_volumebar_unmap;
+ widget_class->key_press_event = hildon_volumebar_key_press;
+ object_class->destroy = hildon_volumebar_destroy;
+
+ signals[MUTE_TOGGLED_SIGNAL] = g_signal_new("mute_toggled",
+ G_OBJECT_CLASS_TYPE
+ (object_class),
+ G_SIGNAL_RUN_LAST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (HildonVolumebarClass,
+ mute_toggled), NULL, NULL,
+ gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[LEVEL_CHANGED_SIGNAL] = g_signal_new("level_changed",
+ G_OBJECT_CLASS_TYPE
+ (object_class),
+ G_SIGNAL_RUN_LAST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (HildonVolumebarClass,
+ level_changed), NULL,
+ NULL,
+ gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ gobject_class->notify = hildon_volumebar_notify;
+ gobject_class->set_property = hildon_volumebar_set_property;
+ gobject_class->get_property = hildon_volumebar_get_property;
+
+ /*This kind of property could be usefull in the gtkcontainer*/
+ g_object_class_install_property(gobject_class,
+ PROP_HILDON_FOCUSABLE,
+ g_param_spec_boolean("can-focus",
+ "The widget focusablility",
+ "The widget focusablility. TRUE is focusable",
+ TRUE,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class,
+ PROP_HILDON_HAS_MUTE,
+ g_param_spec_boolean("has_mute",
+ "Show/Hide the mute button",
+ "Whether the mute button is visible. Default value: TRUE",
+ TRUE,
+ G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class,
+ PROP_HILDON_LEVEL,
+ g_param_spec_double("level",
+ "Level",
+ "Current volume level",
+ 0.0,
+ 100.0,
+ 50.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(gobject_class,
+ PROP_HILDON_MUTE,
+ g_param_spec_boolean("mute",
+ "Mute",
+ "Whether volume is muted",
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+hildon_volumebar_init(HildonVolumebar * volumebar)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(volumebar);
+
+ /* Should set GTK_NO_WINDOW flag, because widget is derived from
+ GtkContainer */
+ GTK_WIDGET_SET_FLAGS(GTK_WIDGET(volumebar), GTK_NO_WINDOW);
+ GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(volumebar), GTK_CAN_FOCUS);
+
+ /* Initialize mute button */
+ priv->tbutton = GTK_TOGGLE_BUTTON(gtk_toggle_button_new());
+ g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
+}
+
+static void
+hildon_volumebar_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ gdk_window_move_resize (priv->event_window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+}
+
+static void
+hildon_volumebar_realize (GtkWidget *widget)
+{
+ HildonVolumebarPrivate *priv;
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.event_mask = GDK_BUTTON_PRESS_MASK;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ priv->event_window = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (priv->event_window, widget);
+}
+
+static void
+hildon_volumebar_unrealize (GtkWidget *widget)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ if (priv->event_window) {
+ gdk_window_set_user_data (priv->event_window, NULL);
+ gdk_window_destroy (priv->event_window);
+ priv->event_window = NULL;
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+static void
+hildon_volumebar_map (GtkWidget *widget)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ GTK_WIDGET_CLASS(parent_class)->map(widget);
+
+ /* the event window must be on top of all other widget windows, so show it
+ * last */
+ if (!GTK_WIDGET_SENSITIVE (widget))
+ gdk_window_show (priv->event_window);
+}
+
+static void hildon_volumebar_unmap (GtkWidget *widget)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ gdk_window_hide (priv->event_window);
+
+ GTK_WIDGET_CLASS(parent_class)->unmap(widget);
+}
+
+static void
+hildon_child_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_assert(HILDON_IS_VOLUMEBAR(container));
+ g_assert(callback != NULL);
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(container);
+
+ /* No external children */
+ if (!include_internals)
+ return;
+
+ /* Execute callback for both internals */
+ (*callback) (GTK_WIDGET(priv->tbutton), callback_data);
+ (*callback) (GTK_WIDGET(priv->volumebar), callback_data);
+}
+
+static void
+hildon_volumebar_notify (GObject *self, GParamSpec *param)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ if (GTK_WIDGET_MAPPED (self)) {
+ /* show/hide the event window on sensitivity change */
+ if (g_str_equal (param->name, "sensitive")) {
+ if (GTK_WIDGET_SENSITIVE (self))
+ gdk_window_hide (priv->event_window);
+ else
+ gdk_window_show (priv->event_window);
+ }
+ }
+
+ if (G_OBJECT_CLASS(parent_class)->notify)
+ G_OBJECT_CLASS(parent_class)->notify (self, param);
+}
+
+static void
+hildon_volumebar_destroy(GtkObject * self)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ if (priv->tbutton) {
+ gtk_widget_unparent(GTK_WIDGET(priv->tbutton));
+ priv->tbutton = NULL;
+ }
+ if (priv->volumebar) {
+ gtk_widget_unparent(GTK_WIDGET(priv->volumebar));
+ priv->volumebar = NULL;
+ }
+
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+}
+
+static void
+hildon_volumebar_set_property(GObject * object,
+ guint prop_id,
+ const GValue * value,
+ GParamSpec * pspec)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_HILDON_HAS_MUTE:
+ /* Mute button always exists, but might be hidden */
+ if (g_value_get_boolean(value))
+ gtk_widget_show(GTK_WIDGET(priv->tbutton));
+ else
+ gtk_widget_hide(GTK_WIDGET(priv->tbutton));
+ break;
+ case PROP_HILDON_FOCUSABLE:
+ g_object_set( G_OBJECT(priv->volumebar), "can-focus",
+ g_value_get_boolean(value), NULL );
+ break;
+ case PROP_HILDON_LEVEL:
+ hildon_volumebar_set_level(HILDON_VOLUMEBAR(priv->volumebar),
+ g_value_get_double(value));
+ break;
+ case PROP_HILDON_MUTE:
+ hildon_volumebar_set_mute(HILDON_VOLUMEBAR(priv->volumebar),
+ g_value_get_boolean(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+
+ break;
+ }
+}
+
+static void
+hildon_volumebar_get_property(GObject * object,
+ guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ HildonVolumebar *vb = HILDON_VOLUMEBAR(object);
+ HildonVolumebarPrivate *priv = HILDON_VOLUMEBAR_GET_PRIVATE(vb);
+
+ switch (prop_id) {
+ case PROP_HILDON_HAS_MUTE:
+ g_value_set_boolean(value, GTK_WIDGET_VISIBLE(priv->tbutton));
+ break;
+ case PROP_HILDON_FOCUSABLE:
+ g_value_set_boolean(value, GTK_WIDGET_CAN_FOCUS(priv->volumebar));
+ break;
+ case PROP_HILDON_LEVEL:
+ g_value_set_double(value, hildon_volumebar_get_level(vb));
+ break;
+ case PROP_HILDON_MUTE:
+ g_value_set_boolean(value, hildon_volumebar_get_mute(vb));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * hildon_volumebar_level_change:
+ * @self: a #HildonVolumebar widget
+ *
+ * Emits "level_changed" signal to the given volume bar. This function
+ * is mainly used by derived classes.
+ */
+void
+hildon_volumebar_level_change(HildonVolumebar * self)
+{
+ g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
+ g_signal_emit_by_name(GTK_WIDGET(self), "level_changed");
+}
+
+/**
+ * hildon_volumebar_set_level:
+ * @self: volume bar to change level on
+ * @level: new level
+ *
+ * Sets new volume level for this #HildonVolumebar.
+ */
+void
+hildon_volumebar_set_level(HildonVolumebar * self, gdouble level)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ hildon_volumebar_range_set_level(priv->volumebar, level);
+}
+
+/**
+ * hildon_volumebar_get_level:
+ * @self: volume bar to query level on
+ *
+ * Gets the volume level of this #HildonVolumebar.
+ *
+ * Returns: volume level or -1 on error
+ */
+gdouble
+hildon_volumebar_get_level(HildonVolumebar * self)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), -1);
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ return hildon_volumebar_range_get_level(priv->volumebar);
+}
+
+/**
+ * hildon_volumebar_set_mute:
+ * @self: volume bar to work on
+ * @mute: mute ON/OFF
+ *
+ * Sets mute status for this #HildonVolumebar.
+ */
+void
+hildon_volumebar_set_mute(HildonVolumebar * self, gboolean mute)
+{
+ HildonVolumebarPrivate *priv;
+ gboolean focusable = TRUE;
+
+ g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ /* Slider should be insensitive when mute is on */
+ gtk_widget_set_sensitive(GTK_WIDGET(priv->volumebar), !mute);
+
+ focusable = GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (priv->volumebar));
+
+ if (mute){
+ if (focusable){
+ /* Make mute button focusable since the slider isn't anymore */
+ g_object_set (G_OBJECT (priv->tbutton), "can-focus", TRUE, NULL);
+ gtk_widget_grab_focus (GTK_WIDGET(priv->tbutton));
+ }
+ }
+ else
+ {
+ g_object_set (G_OBJECT (priv->tbutton), "can-focus", FALSE, NULL);
+
+ /* Mute off grabs focus */
+ if (focusable){
+ gtk_widget_grab_focus (GTK_WIDGET (self));
+ }
+ else{
+ /* If volumebar is not focusable, focus the parent window instead */
+ GtkWidget *win = gtk_widget_get_ancestor (GTK_WIDGET (self),
+ GTK_TYPE_WINDOW);
+ gtk_window_set_focus (GTK_WINDOW (win), NULL);
+ }
+ }
+
+ /* Update mute button state and redraw */
+ gtk_toggle_button_set_active(priv->tbutton, mute);
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+/**
+ * hildon_volumebar_get_mute:
+ * @self: volume bar to query mute status
+ *
+ * Gets mute status of this #HildonVolumebar (ON/OFF).
+ *
+ * Returns: Mute status as #gboolean value.
+ */
+gboolean
+hildon_volumebar_get_mute(HildonVolumebar * self)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), TRUE);
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ return gtk_toggle_button_get_active(priv->tbutton);
+}
+
+/**
+ * hildon_volumebar_get_adjustment
+ * @self : a #HildonVolumebar
+ *
+ * Gets the GtkAdjustment used in volume bar. This can be handy
+ * to give to hildon_appview_set_connected_adjustment which
+ * will allow changing the volume with increase / decrease
+ * hardware buttons.
+ *
+ * This is a temporary solution until volume bar is restructured to
+ * be a child class of GtkRange.
+ *
+ * Returns: a #GtkAdjustment used by volume bar.
+ */
+GtkAdjustment *
+hildon_volumebar_get_adjustment (HildonVolumebar * self)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_return_val_if_fail(HILDON_IS_VOLUMEBAR(self), NULL);
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+ return gtk_range_get_adjustment (GTK_RANGE (priv->volumebar));
+}
+
+static void
+mute_toggled (HildonVolumebar *self)
+{
+ /* This looks like no-op, but it still does something meaningfull!
+ set_mute also updates the ui to match new state that
+ is already reported by get_mute */
+ hildon_volumebar_set_mute (self, hildon_volumebar_get_mute(self));
+}
+
+static gboolean
+hildon_volumebar_key_press (GtkWidget * widget,
+ GdkEventKey * event)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ /* Enter key toggles mute button (unless it is hidden) */
+ if (event->keyval == GDK_Return && GTK_WIDGET_VISIBLE(priv->tbutton)) {
+ gtk_toggle_button_set_active(priv->tbutton,
+ !hildon_volumebar_get_mute(HILDON_VOLUMEBAR(widget)));
+ return TRUE;
+ }
+
+ return GTK_WIDGET_CLASS(parent_class)->key_press_event(widget, event);
+}
+
+/* Sends mute-toggled signal to widget, used as a callback in derived classes
+ Just keep this "protected" in order to avoid introducing new API. */
+void
+_hildon_volumebar_mute_toggled(HildonVolumebar * self)
+{
+ g_return_if_fail(HILDON_IS_VOLUMEBAR(self));
+ g_signal_emit_by_name(self, "mute_toggled");
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+#ifndef __HILDON_VOLUMEBAR_H__
+#define __HILDON_VOLUMEBAR_H__
+
+#include <gtk/gtkcontainer.h>
+#include <gtk/gtkadjustment.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_VOLUMEBAR ( hildon_volumebar_get_type() )
+#define HILDON_VOLUMEBAR(obj) (GTK_CHECK_CAST (obj,\
+ HILDON_TYPE_VOLUMEBAR, HildonVolumebar))
+#define HILDON_VOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_VOLUMEBAR, HildonVolumebarClass))
+#define HILDON_IS_VOLUMEBAR(obj) (GTK_CHECK_TYPE (obj,\
+ HILDON_TYPE_VOLUMEBAR))
+#define HILDON_IS_VOLUMEBAR_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VOLUMEBAR))
+
+typedef struct _HildonVolumebar HildonVolumebar;
+typedef struct _HildonVolumebarClass HildonVolumebarClass;
+
+struct _HildonVolumebar {
+ GtkContainer par;
+};
+
+struct _HildonVolumebarClass {
+ GtkContainerClass parent_class;
+
+ /* signals */
+ void (*mute_toggled) (HildonVolumebar * self);
+ void (*level_changed) (HildonVolumebar * self);
+};
+
+
+GType hildon_volumebar_get_type (void) G_GNUC_CONST;
+
+double hildon_volumebar_get_level (HildonVolumebar *self);
+void hildon_volumebar_set_level (HildonVolumebar *self,
+ gdouble level);
+
+gboolean hildon_volumebar_get_mute (HildonVolumebar *self);
+void hildon_volumebar_set_mute (HildonVolumebar *self,
+ gboolean mute);
+
+void hildon_volumebar_level_change (HildonVolumebar *self);
+
+GtkAdjustment * hildon_volumebar_get_adjustment (HildonVolumebar *self);
+
+
+G_END_DECLS
+#endif /* __HILDON_VOLUMEBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/*
+ * SECTION:hildon-vvolumebar
+ * @short_description: A widget that displays a vertical volume bar
+ * @see_also: #HildonVolumebar, #HildonHVolumebar
+ *
+ * #HildonVVolumebar is a subclass of #HildonVolumebar. It displays a
+ * vertical volume bar that allows increasing or decreasing volume
+ * within a predefined range, and muting when users click the mute icon.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include "hildon-vvolumebar.h"
+#include "hildon-volumebar-range.h"
+#include "hildon-volumebar-private.h"
+
+/* Volume bar */
+#define DEFAULT_BAR_WIDTH 58
+#define MINIMUM_BAR_HEIGHT 165
+/* Toggle button */
+#define DEFAULT_VERTICAL_TBUTTON_WIDTH 26
+#define DEFAULT_VERTICAL_TBUTTON_HEIGHT 26
+#define DEFAULT_ENDING_SIZE 20
+/* Gap to leave for mute button */
+#define HORIZONTAL_MUTE_GAP 16
+#define VERTICAL_MUTE_GAP 6
+
+static HildonVolumebarClass *parent_class;
+static void hildon_vvolumebar_class_init(HildonVVolumebarClass * klass);
+static void hildon_vvolumebar_init(HildonVVolumebar * vvolumebar);
+static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
+ GdkEventExpose * event);
+static void hildon_vvolumebar_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void hildon_vvolumebar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+
+GType hildon_vvolumebar_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof(HildonVVolumebarClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_vvolumebar_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonVVolumebar),
+ 0,
+ (GInstanceInitFunc) hildon_vvolumebar_init,
+ };
+ type =
+ g_type_register_static(HILDON_TYPE_VOLUMEBAR,
+ "HildonVVolumebar", &info, 0);
+ }
+ return type;
+}
+
+static void hildon_vvolumebar_class_init(HildonVVolumebarClass * klass)
+{
+ GtkWidgetClass *volumebar_class = GTK_WIDGET_CLASS(klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ volumebar_class->size_request = hildon_vvolumebar_size_request;
+ volumebar_class->size_allocate = hildon_vvolumebar_size_allocate;
+ volumebar_class->expose_event = hildon_vvolumebar_expose;
+}
+
+static void hildon_vvolumebar_init(HildonVVolumebar * vvolumebar)
+{
+ HildonVolumebarPrivate *priv;
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(vvolumebar);
+
+ priv->volumebar =
+ HILDON_VOLUMEBAR_RANGE(hildon_volumebar_range_new
+ (GTK_ORIENTATION_VERTICAL));
+
+ GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(vvolumebar), GTK_CAN_FOCUS);
+
+ gtk_widget_set_parent(GTK_WIDGET(priv->tbutton), GTK_WIDGET(vvolumebar));
+ gtk_widget_set_parent(GTK_WIDGET(priv->volumebar), GTK_WIDGET(vvolumebar));
+
+ gtk_scale_set_draw_value(GTK_SCALE(priv->volumebar), FALSE);
+
+ /* Signals */
+ g_signal_connect_swapped(G_OBJECT(priv->volumebar), "value-changed",
+ G_CALLBACK(hildon_volumebar_level_change),
+ vvolumebar);
+ g_signal_connect_swapped(priv->tbutton, "toggled",
+ G_CALLBACK(_hildon_volumebar_mute_toggled), vvolumebar);
+
+ gtk_widget_show(GTK_WIDGET(priv->volumebar));
+}
+
+/**
+ * hildon_vvolumebar_new:
+ *
+ * Creates a new #HildonVVolumebar widget.
+ *
+ * Returns: a new #HildonVVolumebar
+ */
+GtkWidget *hildon_vvolumebar_new(void)
+{
+ return GTK_WIDGET(g_object_new(HILDON_TYPE_VVOLUMEBAR, NULL));
+}
+
+static gboolean hildon_vvolumebar_expose(GtkWidget * widget,
+ GdkEventExpose * event)
+{
+ HildonVolumebarPrivate *priv;
+
+ g_assert(HILDON_IS_VVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(HILDON_VOLUMEBAR(widget));
+
+ if (GTK_WIDGET_DRAWABLE(widget)) {
+ /* Paint background */
+ gtk_paint_box(widget->style, widget->window,
+ GTK_WIDGET_STATE(priv->volumebar), GTK_SHADOW_OUT,
+ NULL, widget, "background",
+ widget->allocation.x,
+ widget->allocation.y,
+ widget->allocation.width,
+ widget->allocation.height);
+
+ /* The contents of the widget can paint themselves */
+ (*GTK_WIDGET_CLASS(parent_class)->expose_event) (widget, event);
+ }
+
+ return FALSE;
+}
+
+static void
+hildon_vvolumebar_size_request(GtkWidget * widget,
+ GtkRequisition * requisition)
+{
+ g_assert(HILDON_IS_VVOLUMEBAR(widget));
+
+ requisition->height = MINIMUM_BAR_HEIGHT;
+ requisition->width = DEFAULT_BAR_WIDTH;
+}
+
+static void
+hildon_vvolumebar_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonVolumebarPrivate *priv;
+
+ GtkAllocation range_allocation, button_allocation;
+
+ g_assert(HILDON_IS_VVOLUMEBAR(widget));
+
+ priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+ /* Center the widget horizontally */
+ if (allocation->width > DEFAULT_BAR_WIDTH) {
+ allocation->x +=
+ (allocation->width - DEFAULT_BAR_WIDTH) / 2;
+ allocation->width = DEFAULT_BAR_WIDTH;
+ }
+
+ GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
+
+ if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
+ /* Allocate space for the slider */
+ range_allocation.x = allocation->x;
+ range_allocation.y = allocation->y + DEFAULT_ENDING_SIZE;
+
+ range_allocation.width = DEFAULT_BAR_WIDTH;
+
+ if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton))
+ {
+ /* Leave room for the mute button */
+ range_allocation.height = MAX(0,
+ allocation->height
+ - 2 * DEFAULT_ENDING_SIZE
+ - DEFAULT_VERTICAL_TBUTTON_HEIGHT
+ - VERTICAL_MUTE_GAP);
+ }
+
+ else
+ {
+ range_allocation.height = MAX(0,
+ allocation->height
+ - 2 * DEFAULT_ENDING_SIZE);
+ }
+
+ gtk_widget_size_allocate(GTK_WIDGET(priv->volumebar),
+ &range_allocation);
+ }
+
+ if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
+ /* Allocate space for the mute button */
+ button_allocation.x = allocation->x + HORIZONTAL_MUTE_GAP;
+ button_allocation.y = allocation->y + allocation->height -
+ VERTICAL_MUTE_GAP - 2 * DEFAULT_ENDING_SIZE;
+ button_allocation.width = DEFAULT_VERTICAL_TBUTTON_WIDTH;
+ button_allocation.height = DEFAULT_VERTICAL_TBUTTON_HEIGHT;
+ gtk_widget_size_allocate(GTK_WIDGET(priv->tbutton),
+ &button_allocation);
+ }
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_VVOLUMEBAR_H__
+#define __HILDON_VVOLUMEBAR_H__
+
+#include <hildon-widgets/hildon-volumebar.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_VVOLUMEBAR ( hildon_vvolumebar_get_type() )
+
+#define HILDON_VVOLUMEBAR(obj) (GTK_CHECK_CAST (obj, HILDON_TYPE_VVOLUMEBAR, HildonVVolumebar))
+
+#define HILDON_VVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_VVOLUMEBAR, HildonVVolumebarClass))
+
+#define HILDON_IS_VVOLUMEBAR(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_VVOLUMEBAR))
+
+#define HILDON_IS_VVOLUMEBAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_VVOLUMEBAR))
+
+
+typedef struct _HildonVVolumebar HildonVVolumebar;
+typedef struct _HildonVVolumebarClass HildonVVolumebarClass;
+
+struct _HildonVVolumebar {
+ HildonVolumebar volumebar; /* this is our parent class */
+};
+
+struct _HildonVVolumebarClass {
+ HildonVolumebarClass parent_class;
+};
+
+GType hildon_vvolumebar_get_type (void) G_GNUC_CONST;
+GtkWidget * hildon_vvolumebar_new (void);
+
+
+G_END_DECLS
+#endif /* __HILDON_VVOLUMEBAR_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-weekday-picker
+ * @short_description: A widget for picking days on which a certain event
+ * should take place
+ * @see_also: #HildonWeekdayPicker
+ *
+ * #HildonWeekdayPicker supports non-mutually exclusive selection of days of
+ * the week. Selected days of the week are shown with a pushed-in effect.
+ *
+ * #HildonWeekdayPicker is used where users are required to pick days on which
+ * a certain event should take place, for example, which days a Calendar event
+ * should be repeated on. It is used in Calendar in the Repeat dialog, in Tasks
+ * in the Repeat dialog and in the Email set-up wizard.
+ */
+
+ /* GDate numbers days from 1 to 7 and G_DATE_MONDAY is 1st day. However
+ according to locale settings first day is sunday. To get around this
+ problem, we addjust GDate days numbering to be same as locale
+ numbering */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <langinfo.h>
+#include <time.h>
+#include <gtk/gtksignal.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtksizegroup.h>
+#include <gtk/gtkwindow.h>
+#include "hildon-weekday-picker.h"
+#include "hildon-composite-widget.h"
+
+#define HILDON_WEEKDAY_PICKER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ HILDON_TYPE_WEEKDAY_PICKER, HildonWeekdayPickerPrivate));
+
+static GtkContainerClass *parent_class;
+
+typedef struct _HildonWeekdayPickerPrivate HildonWeekdayPickerPrivate;
+
+static void
+hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class);
+static void
+hildon_weekday_picker_init(HildonWeekdayPicker * picker);
+static void
+hildon_weekday_picker_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation);
+static void
+hildon_weekday_picker_size_request(GtkWidget * widget,
+ GtkRequisition * requisition);
+static void
+hildon_weekday_picker_forall(GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback, gpointer callback_data);
+static void
+hildon_weekday_picker_destroy(GtkObject * self);
+
+static void
+button_toggle(GtkToggleButton * togglebutton, gpointer wpicker);
+
+struct _HildonWeekdayPickerPrivate {
+ GtkWidget *buttons[8]; /* weekday buttons in show order */
+ GtkWidget *day_order_buttons[8]; /* weekday buttons in glib day order */
+};
+
+enum {
+ SELECTION_CHANGED_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GType hildon_weekday_picker_get_type(void)
+{
+ static GType picker_type = 0;
+
+ if (!picker_type) {
+ static const GTypeInfo picker_info = {
+ sizeof(HildonWeekdayPickerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_weekday_picker_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonWeekdayPicker),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_weekday_picker_init,
+ };
+ picker_type = g_type_register_static(GTK_TYPE_CONTAINER,
+ "HildonWeekdayPicker",
+ &picker_info, 0);
+ }
+ return picker_type;
+}
+
+static void
+hildon_weekday_picker_class_init(HildonWeekdayPickerClass * picker_class)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(picker_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS(picker_class);
+ GObjectClass *object_class = G_OBJECT_CLASS(picker_class);
+
+ parent_class = g_type_class_peek_parent(picker_class);
+
+ g_type_class_add_private(picker_class,
+ sizeof(HildonWeekdayPickerPrivate));
+
+ /* Override virtual methods */
+ widget_class->size_request = hildon_weekday_picker_size_request;
+ widget_class->size_allocate = hildon_weekday_picker_size_allocate;
+ widget_class->focus = hildon_composite_widget_focus;
+ container_class->forall = hildon_weekday_picker_forall;
+ GTK_OBJECT_CLASS(picker_class)->destroy =
+ hildon_weekday_picker_destroy;
+
+ /* Create a signal for reporting user actions */
+ signals[SELECTION_CHANGED_SIGNAL] = g_signal_new("selection_changed",
+ G_OBJECT_CLASS_TYPE
+ (object_class),
+ G_SIGNAL_RUN_LAST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (HildonWeekdayPickerClass,
+ selection_changed), NULL, NULL,
+ gtk_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+static void
+hildon_weekday_picker_init(HildonWeekdayPicker * picker)
+{
+ HildonWeekdayPickerPrivate *priv;
+ gint i, day;
+ /* weekday indexes to be used with nl_langinfo. These are shifted
+ * by one for glib compability */
+ int wdays[] = {
+ -1, /* 0 = invalid date */
+ ABDAY_2, /* 1 = monday in glib */
+ ABDAY_3, /* 2 = tuesday in glib */
+ ABDAY_4, /* 3 = wednesday in glib */
+ ABDAY_5, /* 4 = thursday in glib */
+ ABDAY_6, /* 5 = friday in glib */
+ ABDAY_7, /* 6 = saturday in glib */
+ ABDAY_1 }; /* 7 = sunday in glib */
+ GtkSizeGroup *sgroup;
+
+ sgroup = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
+
+ /* Check our first weekday */
+ day = *nl_langinfo(_NL_TIME_FIRST_WEEKDAY);
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ /* Shift the days by one. This is done because GDateWeekday
+ * starts with Monday(1) and langinfo's first day is Sunday */
+ day--;
+ if (day < 1)
+ day = 7;
+
+ /* Initialize and pack day buttons */
+ for (i = 1; i <= 7; i++) {
+ priv->buttons[i] =
+ gtk_toggle_button_new_with_label(nl_langinfo(wdays[day]));
+ priv->day_order_buttons[day] = priv->buttons[i];
+ day++;
+
+ if (day > 7)
+ day = 1;
+
+ g_signal_connect(GTK_WIDGET(priv->buttons[i]),
+ "toggled", G_CALLBACK(button_toggle), picker);
+
+ gtk_size_group_add_widget(sgroup, priv->buttons[i]);
+
+ gtk_widget_set_parent(priv->buttons[i], GTK_WIDGET(picker));
+ gtk_widget_show(priv->buttons[i]);
+ }
+
+ GTK_WIDGET_SET_FLAGS(picker, GTK_NO_WINDOW);
+
+ g_object_unref( sgroup );
+}
+
+/**
+ * hildon_weekday_picker_new:
+ *
+ * Creates a new #HildonWeekdayPicker.
+ *
+ * Returns: pointer to a new #HildonWeekdayPicker widget.
+ */
+GtkWidget *hildon_weekday_picker_new(void)
+{
+ return g_object_new(HILDON_TYPE_WEEKDAY_PICKER, NULL);
+}
+
+static void
+hildon_weekday_picker_forall(GtkContainer * container,
+ gboolean include_internals, GtkCallback callback,
+ gpointer callback_data)
+{
+ HildonWeekdayPicker *picker;
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+
+ g_assert(container);
+ g_assert(callback);
+
+ picker = HILDON_WEEKDAY_PICKER(container);
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ /* We only have internal children */
+ if (!include_internals)
+ return;
+
+ /* Activate callback for each day button */
+ for (i = 1; i <= 7; ++i) {
+ (*callback) (priv->buttons[i], callback_data);
+ }
+
+}
+
+static void
+hildon_weekday_picker_destroy(GtkObject * self)
+{
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(self);
+
+ /* Destroy internal children... */
+ for (i = 1; i <= 7; ++i) {
+ if (priv->buttons[i])
+ {
+ gtk_widget_unparent(priv->buttons[i]);
+ priv->buttons[i] = NULL;
+ }
+ }
+
+ /* ... and chain to parent. */
+ if (GTK_OBJECT_CLASS(parent_class)->destroy)
+ GTK_OBJECT_CLASS(parent_class)->destroy(self);
+
+}
+
+static void
+hildon_weekday_picker_size_request(GtkWidget * widget,
+ GtkRequisition *requisition)
+{
+ HildonWeekdayPicker *picker;
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+ GtkRequisition req;
+
+ picker = HILDON_WEEKDAY_PICKER(widget);
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+ requisition->width = 0;
+ requisition->height = 0;
+
+ /* Request an area that is as wide as all of the buttons
+ together and tall enough to hold heightest button */
+ for (i = 1; i <= 7; ++i) {
+ gtk_widget_size_request(priv->buttons[i], &req);
+ requisition->width += req.width;
+ if (req.height > requisition->height)
+ requisition->height = req.height;
+
+ }
+}
+
+static void
+hildon_weekday_picker_size_allocate(GtkWidget * widget,
+ GtkAllocation * allocation)
+{
+ HildonWeekdayPicker *picker;
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+ GtkAllocation alloc;
+ GtkRequisition child_requisition;
+ gint header_x;
+ guint sval;
+ GtkTextDirection direction;
+
+ g_assert(widget);
+ g_assert(allocation);
+
+ /* Check orientation */
+ direction = gtk_widget_get_direction(widget);
+
+ picker = HILDON_WEEKDAY_PICKER(widget);
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+ header_x = allocation->x;
+ widget->allocation = *allocation;
+
+ if (direction == GTK_TEXT_DIR_LTR || direction == GTK_TEXT_DIR_NONE)
+ sval = 1;
+ else
+ sval = 7;
+
+ /* Allocate day buttons side by side honouring the text direction */
+ for (i = 1; i <= 7; ++i) {
+ gtk_widget_get_child_requisition(priv->buttons[sval],
+ &child_requisition);
+
+ alloc.x = header_x;
+ alloc.y = allocation->y;
+ alloc.width = child_requisition.width;
+ alloc.height = child_requisition.height;
+ header_x += alloc.width;
+ gtk_widget_size_allocate(priv->buttons[sval], &alloc);
+ if (direction == GTK_TEXT_DIR_RTL)
+ sval--;
+ else
+ sval++;
+ }
+}
+
+static void
+button_toggle(GtkToggleButton * button, gpointer wpicker)
+{
+ HildonWeekdayPicker *picker;
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+
+ g_assert(button);
+ g_assert(wpicker);
+
+ picker = HILDON_WEEKDAY_PICKER(wpicker);
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ for (i = 1; i <= 7; ++i) {
+ if (GTK_WIDGET(button) == priv->day_order_buttons[i]) {
+ g_signal_emit (GTK_WIDGET(picker),
+ signals[SELECTION_CHANGED_SIGNAL], 0, i);
+ break;
+ }
+ }
+}
+
+/**
+ * hildon_weekday_picker_set_day:
+ * @picker: the #HildonWeekdayPicker widget
+ * @day: day to be set active
+ *
+ * Sets specified weekday active.
+ */
+void
+hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
+ GDateWeekday day)
+{
+ HildonWeekdayPickerPrivate *priv;
+
+ g_return_if_fail(picker);
+ g_return_if_fail(g_date_valid_weekday(day));
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (priv->day_order_buttons[day]), TRUE);
+}
+
+/**
+ * hildon_weekday_picker_unset_day:
+ * @picker: the #HildonWeekdayPicker widget
+ * @day: day to be set inactive
+ *
+ * Sets specified weekday inactive.
+ */
+void
+hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
+ GDateWeekday day)
+{
+ HildonWeekdayPickerPrivate *priv;
+
+ g_return_if_fail(picker);
+ g_return_if_fail(g_date_valid_weekday(day));
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (priv->day_order_buttons[day]), FALSE);
+}
+
+/**
+ * hildon_weekday_picker_toggle_day:
+ * @picker: the #HildonWeekdayPicker widget
+ * @day: day to be toggled
+ *
+ * Toggles current status of the specified weekday.
+ */
+void
+hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
+ GDateWeekday day)
+{
+ HildonWeekdayPickerPrivate *priv;
+
+ g_return_if_fail(picker);
+ g_return_if_fail(g_date_valid_weekday(day));
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(priv->day_order_buttons[day]),
+ !gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(priv->day_order_buttons[day])));
+}
+
+/**
+ * hildon_weekday_picker_set_all:
+ * @picker: the #HildonWeekdayPicker widget
+ *
+ * Sets all weekdays active.
+ */
+void
+hildon_weekday_picker_set_all(HildonWeekdayPicker * picker)
+{
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+
+ g_return_if_fail(picker);
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ for (i = 1; i <= 7; i++)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
+ TRUE);
+}
+
+/**
+ * hildon_weekday_picker_unset_all:
+ * @picker: the #HildonWeekdayPicker widget
+ *
+ * Sets all weekdays inactive.
+ */
+void
+hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker)
+{
+ HildonWeekdayPickerPrivate *priv;
+ gint i;
+
+ g_return_if_fail(picker);
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ for (i = 1; i <= 7; i++)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->buttons[i]),
+ FALSE);
+}
+
+/**
+ * hildon_weekday_picker_isset_day:
+ * @picker: the #HildonWeekdayPicker widget
+ * @day: day to be checked.
+ *
+ * Checks if the specified weekday is set active.
+ *
+ * Returns: TRUE if the day is set, FALSE if the day is not set
+ */
+gboolean
+hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
+ GDateWeekday day)
+{
+ HildonWeekdayPickerPrivate *priv;
+
+ g_return_val_if_fail(picker, FALSE);
+ g_return_val_if_fail(g_date_valid_weekday(day), FALSE);
+
+ priv = HILDON_WEEKDAY_PICKER_GET_PRIVATE(picker);
+
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
+ priv->day_order_buttons[day]));
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_WEEKDAY_PICKER_H__
+#define __HILDON_WEEKDAY_PICKER_H__
+
+#include <gtk/gtkcontainer.h>
+
+G_BEGIN_DECLS
+/**
+ * HILDON_TYPE_WEEKDAY_PICKER:
+ *
+ * Macro for getting type of weekday picker.
+ * Since: 0.12.10
+ */
+#define HILDON_TYPE_WEEKDAY_PICKER ( hildon_weekday_picker_get_type() )
+
+/**
+ * HILDON_WEEKDAY_PICKER_TYPE:
+ *
+ * Deprecated: use #HILDON_TYPE_WEEKDAY_PICKER instead.
+ */
+#define HILDON_WEEKDAY_PICKER_TYPE HILDON_TYPE_WEEKDAY_PICKER
+
+#define HILDON_WEEKDAY_PICKER(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_WEEKDAY_PICKER, \
+ HildonWeekdayPicker))
+#define HILDON_WEEKDAY_PICKER_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass), \
+ HILDON_TYPE_WEEKDAY_PICKER, HildonWeekdayPickerClass))
+#define HILDON_IS_WEEKDAY_PICKER(obj) \
+ (GTK_CHECK_TYPE (obj, HILDON_TYPE_WEEKDAY_PICKER))
+#define HILDON_IS_WEEKDAY_PICKER_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_WEEKDAY_PICKER))
+/**
+ * HildonWeekdayPicker:
+ *
+ * Internal struct for weekday picker.
+ */
+typedef struct _HildonWeekdayPicker HildonWeekdayPicker;
+typedef struct _HildonWeekdayPickerClass HildonWeekdayPickerClass;
+
+struct _HildonWeekdayPicker {
+ GtkContainer parent;
+};
+
+struct _HildonWeekdayPickerClass {
+ GtkContainerClass parent_class;
+
+ void (*selection_changed) (HildonWeekdayPicker * self);
+};
+
+GType hildon_weekday_picker_get_type(void) G_GNUC_CONST;
+
+/**
+ * hildon_weekday_picker_new:
+ *
+ * Creates a new #HildonWeekdayPicker.
+ *
+ * Return value: New #HildonWeekdayPicker.
+ **/
+GtkWidget *hildon_weekday_picker_new(void);
+
+/**
+ * hildon_weekday_picker_set_day:
+ * @picker: #HildonWeekdayPicker.
+ * @day: #GDateWeekday.
+ *
+ * Select specified weekday.
+ *
+ **/
+void hildon_weekday_picker_set_day(HildonWeekdayPicker * picker,
+ GDateWeekday day);
+
+/**
+ * hildon_weekday_picker_unset_day:
+ * @picker: #HildonWeekdayPicker.
+ * @day: #GDateWeekday.
+ *
+ * Unselect specified weekday.
+ *
+ **/
+void hildon_weekday_picker_unset_day(HildonWeekdayPicker * picker,
+ GDateWeekday day);
+
+/**
+ * hildon_weekday_picker_toggle_day:
+ * @picker: #HildonWeekdayPicker.
+ * @day: #GDateWeekday.
+ *
+ * Toggle current status of the specified weekday.
+ *
+ **/
+void hildon_weekday_picker_toggle_day(HildonWeekdayPicker * picker,
+ GDateWeekday day);
+
+/**
+ * hildon_weekday_picker_set_all:
+ * @picker: #HildonWeekdayPicker.
+ *
+ * Select all weekdays.
+ *
+ **/
+void hildon_weekday_picker_set_all(HildonWeekdayPicker * picker);
+
+/**
+ * hildon_weekday_picker_unset_all:
+ * @picker: #HildonWeekdayPicker.
+ *
+ * Unselect all weekdays.
+ *
+ **/
+void hildon_weekday_picker_unset_all(HildonWeekdayPicker * picker);
+
+/**
+ * hildon_weekday_picker_isset_day:
+ * @picker: #HildonWeekdayPicker.
+ * @day: #GDateWeekday.
+ *
+ * Check if the specified weekday is set.
+ *
+ * Return value: Set/not set.
+ **/
+gboolean hildon_weekday_picker_isset_day(HildonWeekdayPicker * picker,
+ GDateWeekday day);
+
+G_END_DECLS
+#endif /* __HILDON_WEEKDAY_PICKER_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_WINDOW_PRIVATE_H__
+#define __HILDON_WINDOW_PRIVATE_H__
+
+G_BEGIN_DECLS
+
+void
+hildon_window_set_program (HildonWindow *self, GObject *program);
+
+void
+hildon_window_unset_program (HildonWindow *self);
+
+void
+hildon_window_set_can_hibernate_property (HildonWindow *self,
+ gpointer can_hibernate);
+
+void
+hildon_window_take_common_toolbar (HildonWindow *self);
+
+void
+hildon_window_update_topmost (HildonWindow *self, Window window_id);
+
+Window
+hildon_window_get_active_window (void);
+
+void
+hildon_window_update_title (HildonWindow *window);
+
+G_END_DECLS
+#endif /* __HILDON_WINDOW_PRIVATE_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#include <memory.h>
+#include <string.h>
+#include <strings.h>
+#include <stdio.h>
+#include "hildon-app.h"
+#include <hildon-window.h>
+#include "hildon-program.h"
+#include "hildon-window-private.h"
+#include <hildon-find-toolbar.h>
+
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkimcontext.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkcheckmenuitem.h>
+#include <gtk/gtkmenushell.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtktextview.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkmain.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdk.h>
+
+#include<gtk/gtkprivate.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+
+#include <libintl.h>
+#define _(String) gettext(String)
+
+/*The size of screen*/
+#define WINDOW_HEIGHT 480
+#define WINDOW_WIDTH 800
+
+#define NAVIGATOR_HEIGHT WINDOW_HEIGHT
+
+#define APPVIEW_HEIGHT 396
+#define APPVIEW_WIDTH 672
+
+#define TOOLBAR_HEIGHT 40
+#define TOOLBAR_MIDDLE 10
+#define TOOLBAR_WIDTH APPVIEW_WIDTH
+
+/*FIXME*/
+#define CAN_HIBERNATE "CANKILL"
+#define CAN_HIBERNATE_LENGTH 7
+
+#define CAN_HIBERNATE_PROPERTY "_HILDON_ABLE_TO_HIBERNATE"
+
+#define TITLE_SEPARATOR " - "
+
+
+#define HILDON_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
+ HILDON_TYPE_WINDOW, HildonWindowPrivate))
+
+static GtkWindowClass *parent_class;
+
+static void
+hildon_window_init (HildonWindow * self);
+
+static void
+hildon_window_class_init (HildonWindowClass * window_class);
+
+static void
+hildon_window_menupopupfunc (GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget);
+static void
+hildon_window_menupopupfuncfull (GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget);
+static gboolean
+hildon_window_expose (GtkWidget * widget, GdkEventExpose * event);
+static void
+hildon_window_forall (GtkContainer * container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static void
+hildon_window_show_all (GtkWidget *widget);
+
+static void
+hildon_window_size_allocate (GtkWidget * widget,
+ GtkAllocation * allocation);
+static void
+hildon_window_size_request (GtkWidget * widget,
+ GtkRequisition * requisition);
+static void
+hildon_window_finalize (GObject * obj_self);
+static void
+hildon_window_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec);
+static void
+hildon_window_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec);
+static void
+hildon_window_destroy (GtkObject *obj);
+static void
+hildon_window_realize (GtkWidget *widget);
+static void
+hildon_window_unrealize (GtkWidget *widget);
+static gboolean
+hildon_window_key_press_event (GtkWidget *widget,
+ GdkEventKey *event);
+static gboolean
+hildon_window_key_release_event (GtkWidget *widget,
+ GdkEventKey *event);
+static gboolean
+hildon_window_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event);
+
+
+static void
+hildon_window_notify (GObject *gobject, GParamSpec *param);
+
+static void
+hildon_window_is_topmost_notify (HildonWindow *window);
+
+static gboolean
+hildon_window_toggle_menu (HildonWindow * self);
+
+static gboolean
+hildon_window_escape_timeout (gpointer data);
+
+static GdkFilterReturn
+hildon_window_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data );
+
+static GdkFilterReturn
+hildon_window_root_window_event_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data );
+
+static void
+hildon_window_get_borders (HildonWindow *window);
+
+static void
+visible_toolbar (gpointer data, gpointer user_data);
+static void
+paint_toolbar (GtkWidget *widget, GtkBox *box,
+ GdkEventExpose * event,
+ gboolean fullscreen);
+
+typedef void (*HildonWindowSignal) (HildonWindow *, gint, gpointer);
+
+
+
+enum
+{
+ PROP_0,
+ PROP_IS_TOPMOST
+};
+
+enum
+{
+ WIN_TYPE = 0,
+ WIN_TYPE_MESSAGE,
+ MAX_WIN_MESSAGES
+};
+
+struct _HildonWindowPrivate
+{
+ GtkWidget *menu;
+ GtkWidget *vbox;
+
+ GtkBorder *borders;
+ GtkBorder *toolbar_borders;
+
+ GtkAllocation allocation;
+
+ guint fullscreen;
+ guint is_topmost;
+ guint escape_timeout;
+ gint visible_toolbars;
+ gint previous_vbox_y;
+
+ HildonProgram *program;
+};
+
+GType
+hildon_window_get_type (void)
+{
+ static GType window_type = 0;
+
+ if (!window_type) {
+ static const GTypeInfo window_info = {
+ sizeof(HildonWindowClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) hildon_window_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(HildonWindow),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) hildon_window_init,
+ };
+ window_type = g_type_register_static(GTK_TYPE_WINDOW,
+ "HildonWindow",
+ &window_info, 0);
+ }
+ return window_type;
+}
+
+/* Virtual methods */
+
+static void
+hildon_window_class_init (HildonWindowClass * window_class)
+{
+ /* Get convenience variables */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (window_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (window_class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (window_class);
+
+ /* Set the global parent_class here */
+ parent_class = g_type_class_peek_parent (window_class);
+
+ object_class->set_property = hildon_window_set_property;
+ object_class->get_property = hildon_window_get_property;
+ object_class->notify = hildon_window_notify;
+
+ /* Set the widgets virtual functions */
+ widget_class->size_allocate = hildon_window_size_allocate;
+ widget_class->size_request = hildon_window_size_request;
+ widget_class->expose_event = hildon_window_expose;
+ widget_class->show_all = hildon_window_show_all;
+ widget_class->realize = hildon_window_realize;
+ widget_class->unrealize = hildon_window_unrealize;
+ widget_class->key_press_event = hildon_window_key_press_event;
+ widget_class->key_release_event = hildon_window_key_release_event;
+ widget_class->window_state_event = hildon_window_window_state_event;
+
+ /* now the object stuff */
+ object_class->finalize = hildon_window_finalize;
+
+ /* To the container */
+ container_class->forall = hildon_window_forall;
+
+ /* gtkobject stuff*/
+ GTK_OBJECT_CLASS (window_class)->destroy = hildon_window_destroy;
+
+ g_type_class_add_private (window_class,
+ sizeof (struct _HildonWindowPrivate));
+
+ /* Install properties */
+ g_object_class_install_property (object_class, PROP_IS_TOPMOST,
+ g_param_spec_boolean ("is-topmost",
+ "Is top-most",
+ "Whether the window is currently activated by the window "
+ "manager",
+ FALSE,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_boxed ("borders",
+ "Graphical borders",
+ "Size of graphical window borders",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_boxed ("toolbar-borders",
+ "Graphical toolbar borders",
+ "Size of graphical toolbar borders",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ /* opera hack, install clip operation signal */
+ g_signal_new ("clipboard_operation",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (HildonWindowClass, clipboard_operation),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+}
+
+static void
+hildon_window_init (HildonWindow * self)
+{
+ HildonWindowPrivate *priv = self->priv = HILDON_WINDOW_GET_PRIVATE(self);
+
+ self->priv->vbox = gtk_vbox_new (TRUE, TOOLBAR_MIDDLE);
+ gtk_widget_set_parent (self->priv->vbox, GTK_WIDGET(self));
+ priv->menu = NULL;
+ priv->visible_toolbars = 0;
+ priv->is_topmost = FALSE;
+ priv->borders = NULL;
+ priv->toolbar_borders = NULL;
+ priv->escape_timeout = 0;
+
+ priv->fullscreen = FALSE;
+
+ priv->program = NULL;
+
+ /* We need to track the root window _MB_CURRENT_APP_WINDOW property */
+ gdk_window_set_events (gdk_get_default_root_window (),
+ gdk_window_get_events (gdk_get_default_root_window ()) | GDK_PROPERTY_CHANGE_MASK);
+
+ gdk_window_add_filter (gdk_get_default_root_window (),
+ hildon_window_root_window_event_filter, self);
+}
+
+static void
+hildon_window_finalize (GObject * obj_self)
+{
+ HildonWindow *self;
+ g_return_if_fail (HILDON_WINDOW (obj_self));
+ self = HILDON_WINDOW (obj_self);
+
+ g_free (self->priv->borders);
+ g_free (self->priv->toolbar_borders);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize (obj_self);
+
+}
+
+static void
+hildon_window_realize (GtkWidget *widget)
+{
+ Atom *old_atoms, *new_atoms;
+ Display *disp;
+ Window window;
+ gint atom_count;
+ Window active_window;
+
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ gtk_widget_realize (GTK_WIDGET (HILDON_WINDOW (widget)->priv->vbox));
+
+
+ /* catch the custom button signal from mb to display the menu */
+ gdk_window_add_filter (widget->window, hildon_window_event_filter, widget );
+
+ window = GDK_WINDOW_XID ( widget->window );
+ disp = GDK_WINDOW_XDISPLAY ( widget->window );
+
+ /* Enable custom button that is used for menu */
+ XGetWMProtocols (disp, window, &old_atoms, &atom_count);
+ new_atoms = g_new (Atom, atom_count + 1);
+
+ memcpy (new_atoms, old_atoms, sizeof(Atom) * atom_count);
+
+ new_atoms[atom_count++] =
+ XInternAtom (disp, "_NET_WM_CONTEXT_CUSTOM", False);
+
+ XSetWMProtocols (disp, window, new_atoms, atom_count);
+
+ XFree(old_atoms);
+ g_free(new_atoms);
+
+ /* rely on GDK to set the window group to its default */
+ gdk_window_set_group (widget->window, NULL);
+
+ if (HILDON_WINDOW (widget)->priv->program)
+ {
+ gboolean can_hibernate = hildon_program_get_can_hibernate (
+ HILDON_WINDOW (widget)->priv->program);
+
+ hildon_window_set_can_hibernate_property (HILDON_WINDOW (widget),
+ &can_hibernate);
+ }
+
+ /* Update the topmost status */
+ active_window = hildon_window_get_active_window();
+ hildon_window_update_topmost (HILDON_WINDOW (widget), active_window);
+
+ /* Update the window title */
+ hildon_window_update_title(HILDON_WINDOW (widget));
+
+}
+
+static void
+hildon_window_unrealize (GtkWidget *widget)
+{
+
+ gdk_window_remove_filter (widget->window, hildon_window_event_filter,
+ widget);
+
+ gtk_widget_unrealize (GTK_WIDGET (HILDON_WINDOW (widget)->priv->vbox));
+ GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+static void
+hildon_window_set_property (GObject * object, guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ /*HildonWindow *window = HILDON_WINDOW (object);*/
+
+ switch (property_id) {
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+hildon_window_get_property (GObject * object, guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW_GET_PRIVATE (object);
+
+ switch (property_id) {
+
+ case PROP_IS_TOPMOST:
+ g_value_set_boolean (value, priv->is_topmost);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * Retrieve the graphical borders size used by the themes
+ */
+static void
+hildon_window_get_borders (HildonWindow *window)
+{
+
+ g_free (window->priv->borders);
+ g_free (window->priv->toolbar_borders);
+
+ gtk_widget_style_get (GTK_WIDGET (window), "borders",&window->priv->borders,
+ "toolbar-borders", &window->priv->toolbar_borders,
+ NULL);
+
+ if (!window->priv->borders)
+ {
+ window->priv->borders = (GtkBorder *)g_malloc0 (sizeof (GtkBorder));
+ }
+
+ if (!window->priv->toolbar_borders)
+ {
+ window->priv->toolbar_borders =
+ (GtkBorder *)g_malloc0 (sizeof (GtkBorder));
+ }
+}
+
+static void
+visible_toolbars (gpointer data, gpointer user_data)
+{
+ if (GTK_WIDGET_VISIBLE (GTK_WIDGET (((GtkBoxChild *)data)->widget)))
+ (*((gint *)user_data)) ++;
+}
+
+static gboolean
+hildon_window_expose (GtkWidget * widget, GdkEventExpose * event)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
+ GtkWidget *bx = HILDON_WINDOW(widget)->priv->vbox;
+ GtkBox *box = GTK_BOX(bx);
+ GtkBorder *b = HILDON_WINDOW(widget)->priv->borders;
+ GtkBorder *tb = HILDON_WINDOW(widget)->priv->toolbar_borders;
+ gint tb_height = 0;
+ gint currently_visible_toolbars = 0;
+
+ if (!priv->borders)
+ {
+ hildon_window_get_borders (HILDON_WINDOW (widget));
+ b = HILDON_WINDOW(widget)->priv->borders;
+ tb = HILDON_WINDOW(widget)->priv->toolbar_borders;
+ }
+
+ tb_height = bx->allocation.height + tb->top + tb->bottom;
+
+ g_list_foreach (box->children, visible_toolbars,
+ ¤tly_visible_toolbars);
+
+ paint_toolbar (widget, box,
+ event, priv->fullscreen);
+
+ if (!HILDON_WINDOW (widget)->priv->fullscreen)
+ {
+
+ /* Draw the left and right window border */
+ gint side_borders_height = widget->allocation.height - b->top;
+
+ if (currently_visible_toolbars)
+ side_borders_height -= tb_height;
+ else
+ side_borders_height -= b->bottom;
+
+ if (b->left > 0)
+ {
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, "left-border",
+ widget->allocation.x, widget->allocation.y +
+ b->top, b->left, side_borders_height);
+ }
+
+ if (b->right > 0)
+ {
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, "right-border",
+ widget->allocation.x + widget->allocation.width -
+ b->right, widget->allocation.y + b->top,
+ b->right, side_borders_height);
+ }
+
+ /* If no toolbar, draw the bottom window border */
+ if (!currently_visible_toolbars && b->bottom > 0)
+ {
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, "bottom-border",
+ widget->allocation.x, widget->allocation.y +
+ (widget->allocation.height - b->bottom),
+ widget->allocation.width, b->bottom);
+ }
+
+ /* Draw the top border */
+ if (b->top > 0)
+ {
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, "top-border",
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, b->top);
+ }
+
+
+ }
+
+ /* don't draw the window stuff as it overwrites our borders with a blank
+ * rectangle. Instead start with the drawing of the GtkBin */
+ GTK_WIDGET_CLASS (g_type_class_peek_parent (parent_class))->
+ expose_event (widget, event);
+ /*GTK_WIDGET_CLASS (parent_class))->
+ expose_event (widget, event);*/
+
+ return FALSE;
+
+}
+
+static void
+hildon_window_size_request (GtkWidget * widget, GtkRequisition * requisition)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
+ GtkWidget *child = GTK_BIN (widget)->child;
+ GtkRequisition req2;
+ gint border_width = GTK_CONTAINER(widget)->border_width;
+
+ if (!priv->borders)
+ {
+ hildon_window_get_borders (HILDON_WINDOW (widget));
+ }
+
+ if (child)
+ gtk_widget_size_request (child, requisition);
+
+ if (HILDON_WINDOW (widget)->priv->vbox != NULL)
+ gtk_widget_size_request (HILDON_WINDOW (widget)->priv->vbox,
+ &req2);
+
+ requisition->height += req2.height;
+ requisition->width = (requisition->width < req2.width) ?
+ req2.width : requisition->width;
+
+
+ requisition->width += 2 * border_width;
+ requisition->height += 2 * border_width;
+
+ if (!priv->fullscreen)
+ {
+ requisition->height += priv->borders->top;
+ if (req2.height == 0)
+ requisition->height += priv->borders->bottom;
+ requisition->width += priv->borders->left + priv->borders->right;
+ }
+}
+
+static void
+hildon_window_size_allocate (GtkWidget * widget, GtkAllocation * allocation)
+{
+ HildonWindowPrivate *priv = HILDON_WINDOW (widget)->priv;
+ GtkAllocation box_alloc;
+ GtkAllocation alloc = *allocation;
+ GtkRequisition req;
+ gint border_width = GTK_CONTAINER(widget)->border_width;
+
+ GtkWidget *box = HILDON_WINDOW(widget)->priv->vbox;
+ GtkBin *bin = GTK_BIN(widget);
+ GtkBorder *b = HILDON_WINDOW (widget)->priv->borders;
+ GtkBorder *tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
+
+ if (!priv->borders)
+ {
+ hildon_window_get_borders (HILDON_WINDOW (widget));
+ b = HILDON_WINDOW (widget)->priv->borders;
+ tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
+ }
+
+ widget->allocation = *allocation;
+
+ gtk_widget_get_child_requisition (box, &req);
+
+ box_alloc.width = allocation->width - tb->left - tb->right;
+ box_alloc.height = ( (req.height < allocation->height) ?
+ req.height : allocation->height );
+ box_alloc.x = allocation->x + tb->left;
+ box_alloc.y = allocation->y + allocation->height - box_alloc.height - tb->bottom;
+
+ if (bin->child != NULL && GTK_IS_WIDGET (bin->child)
+ && GTK_WIDGET_VISIBLE (bin->child))
+ {
+ alloc.x += border_width;
+ alloc.y += border_width;
+ alloc.width -= (border_width * 2);
+ alloc.height -= (border_width * 2) + box_alloc.height;
+
+ if (!(HILDON_WINDOW (widget)->priv->fullscreen))
+ {
+ alloc.x += b->left;
+ alloc.width -= (b->left + b->right);
+ alloc.y += b->top;
+
+ alloc.height -= b->top;
+
+ if (box_alloc.height <= 0)
+ alloc.height -= b->bottom;
+ else
+ alloc.height -= (tb->top + tb->bottom);
+ }
+ else
+ {
+ if (!(box_alloc.height <= 0))
+ alloc.height -= (tb->top + tb->bottom);
+ }
+
+ gtk_widget_size_allocate (bin->child, &alloc);
+ }
+
+
+ gtk_widget_size_allocate (box, &box_alloc);
+
+ if (priv->previous_vbox_y != box_alloc.y)
+ {
+ /* The size of the VBox has changed, we need to redraw part
+ * of the window borders */
+ gint draw_from_y = priv->previous_vbox_y < box_alloc.y?
+ priv->previous_vbox_y - tb->top:
+ box_alloc.y - tb->top;
+
+ gtk_widget_queue_draw_area (widget, 0, draw_from_y,
+ widget->allocation.width,
+ widget->allocation.height - draw_from_y);
+
+ priv->previous_vbox_y = box_alloc.y;
+ }
+
+}
+
+static void
+hildon_window_forall (GtkContainer * container, gboolean include_internals,
+ GtkCallback callback, gpointer callback_data)
+{
+ HildonWindow *self = HILDON_WINDOW (container);
+
+ g_return_if_fail (callback != NULL);
+
+ GTK_CONTAINER_CLASS (parent_class)->forall (container, include_internals,
+ callback, callback_data);
+ if (include_internals && self->priv->vbox != NULL)
+ (* callback)(GTK_WIDGET (self->priv->vbox), callback_data);
+}
+
+static void
+hildon_window_show_all (GtkWidget *widget)
+{
+ HildonWindow *self = HILDON_WINDOW (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->show_all (widget);
+ gtk_widget_show_all (self->priv->vbox);
+
+}
+
+static void
+hildon_window_destroy (GtkObject *obj)
+{
+ HildonWindow *self = HILDON_WINDOW (obj);
+ GList *menu_list;
+
+ if (self->priv->vbox != NULL)
+ {
+ if (self->priv->program)
+ {
+ GtkWidget * common_toolbar = GTK_WIDGET (
+ hildon_program_get_common_toolbar (self->priv->program));
+ if (common_toolbar && common_toolbar->parent == self->priv->vbox)
+ {
+ gtk_container_remove (GTK_CONTAINER (self->priv->vbox),
+ common_toolbar);
+ }
+ }
+
+ gtk_widget_unparent (self->priv->vbox);
+ self->priv->vbox = NULL;
+
+ }
+
+ menu_list = g_list_copy (gtk_menu_get_for_attach_widget (GTK_WIDGET (obj)));
+
+ while (menu_list)
+ {
+ if (GTK_IS_MENU(menu_list->data))
+ {
+ if (GTK_WIDGET_VISIBLE (GTK_WIDGET (menu_list->data)))
+ {
+ gtk_menu_popdown (GTK_MENU (menu_list->data));
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_list->data));
+ }
+ gtk_menu_detach (GTK_MENU (menu_list->data));
+ }
+ menu_list = menu_list->next;
+ }
+
+ g_list_free (menu_list);
+
+ if (self->priv->program)
+ {
+ hildon_program_remove_window (self->priv->program, self);
+ }
+
+ gdk_window_remove_filter (gdk_get_default_root_window(),
+ hildon_window_root_window_event_filter,
+ obj);
+
+ gtk_widget_set_events (GTK_WIDGET(obj), 0);
+
+ GTK_OBJECT_CLASS (parent_class)->destroy (obj);
+}
+
+
+static void
+hildon_window_notify (GObject *gobject, GParamSpec *param)
+{
+ HildonWindow *window = HILDON_WINDOW (gobject);
+
+ if (strcmp (param->name, "title") == 0)
+ {
+
+ hildon_window_update_title (window);
+ }
+ else if (strcmp (param->name, "is-topmost"))
+ {
+ hildon_window_is_topmost_notify (window);
+ }
+
+ if (G_OBJECT_CLASS(parent_class)->notify)
+ G_OBJECT_CLASS(parent_class)->notify (gobject, param);
+}
+
+/* Utilities */
+
+static void
+visible_toolbar (gpointer data, gpointer user_data)
+{
+ if (GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
+ (*((gint *)user_data))++;
+}
+
+static void
+find_findtoolbar_index (gpointer data, gpointer user_data)
+{
+ gint *pass_bundle = (gint *)user_data;
+
+ if(((GtkBoxChild *)data)->widget->allocation.y < pass_bundle[0]
+ && GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
+ pass_bundle[1]++;
+}
+
+static void
+find_findtoolbar (gpointer data, gpointer user_data)
+{
+ if(HILDON_IS_FIND_TOOLBAR (((GtkBoxChild *)data)->widget)
+ && GTK_WIDGET_VISIBLE (((GtkBoxChild *)data)->widget))
+ (*((GtkWidget **)user_data)) = ((GtkBoxChild *)data)->widget;
+}
+
+static void
+paint_toolbar (GtkWidget *widget, GtkBox *box,
+ GdkEventExpose * event,
+ gboolean fullscreen)
+{
+ gint toolbar_num = 0;
+ gint ftb_index = 0;
+ gint count;
+ GtkWidget *findtoolbar = NULL;
+ gchar toolbar_mode[40];
+ GtkBorder *tb = HILDON_WINDOW (widget)->priv->toolbar_borders;
+
+ /* collect info to help on painting the boxes */
+ g_list_foreach (box->children, visible_toolbar,
+ (gpointer) &toolbar_num);
+
+ if(toolbar_num <= 0)
+ return;
+
+ g_list_foreach (box->children, find_findtoolbar, (gpointer) &findtoolbar);
+
+ if (findtoolbar != NULL)
+ {
+ gint pass_bundle[2];/* an array for convient data passing
+ the first member contains the y allocation
+ of the find toolbar, and the second allocation
+ contains the index(how many toolbars are above
+ find toolbar) */
+ pass_bundle[0] = findtoolbar->allocation.y;
+ pass_bundle[1] = ftb_index;
+ g_list_foreach(box->children, find_findtoolbar_index,
+ (gpointer) pass_bundle);
+ ftb_index = pass_bundle[1];
+ }
+
+ /*upper border*/
+ sprintf (toolbar_mode, "toolbar%sframe-top",
+ fullscreen ? "-fullscreen-" : "-");
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE (widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET (box)->allocation.y - tb->top,
+ widget->allocation.width, tb->top);
+
+ /*top most toolbar painting*/
+ if (findtoolbar != NULL && ftb_index == 0 )
+ {
+ sprintf (toolbar_mode, "findtoolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y,
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ else
+ {
+ sprintf (toolbar_mode, "toolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y,
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ /*multi toolbar painting*/
+ for (count = 0; count < toolbar_num - 1; count++)
+ {
+ sprintf (toolbar_mode, "toolbar%sframe-middle",
+ fullscreen ? "-fullscreen-" : "-");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * TOOLBAR_HEIGHT +
+ count * TOOLBAR_MIDDLE,
+ widget->allocation.width,
+ TOOLBAR_MIDDLE);
+
+ if (findtoolbar != NULL && count + 1 == ftb_index)
+ {
+
+ sprintf (toolbar_mode, "findtoolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ else
+ {
+ sprintf (toolbar_mode, "toolbar%s",
+ fullscreen ? "-fullscreen" : "");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ (1 + count) * (TOOLBAR_HEIGHT + TOOLBAR_MIDDLE),
+ widget->allocation.width,
+ TOOLBAR_HEIGHT);
+ }
+ }
+ sprintf (toolbar_mode, "toolbar%sframe-bottom",
+ fullscreen ? "-fullscreen-" : "-");
+
+ gtk_paint_box (widget->style, widget->window,
+ GTK_WIDGET_STATE(widget), GTK_SHADOW_OUT,
+ &event->area, widget, toolbar_mode,
+ widget->allocation.x,
+ GTK_WIDGET(box)->allocation.y +
+ GTK_WIDGET(box)->allocation.height,
+ widget->allocation.width, tb->bottom);
+
+}
+
+/*
+ * Checks the root window to know which is the topped window
+ */
+Window
+hildon_window_get_active_window (void)
+{
+ Atom realtype;
+ int format;
+ int status;
+ Window ret;
+ unsigned long n;
+ unsigned long extra;
+ union
+ {
+ Window *win;
+ unsigned char *char_pointer;
+ } win;
+ Atom active_app_atom =
+ XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
+
+ win.win = NULL;
+
+ status = XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ active_app_atom, 0L, 16L,
+ 0, XA_WINDOW, &realtype, &format,
+ &n, &extra, &win.char_pointer);
+ if (!(status == Success && realtype == XA_WINDOW && format == 32
+ && n == 1 && win.win != NULL))
+ {
+ if (win.win != NULL)
+ XFree (win.char_pointer);
+ return None;
+ }
+
+ ret = win.win[0];
+
+ if (win.win != NULL)
+ XFree(win.char_pointer);
+
+ return ret;
+}
+
+static int
+xclient_message_type_check (XClientMessageEvent *cm, const gchar *name)
+{
+ return cm->message_type == XInternAtom(GDK_DISPLAY(), name, FALSE);
+}
+
+/*****************/
+/* Event filters */
+/*****************/
+
+/*
+ * Handle the window border custom button, which toggles the menu,
+ * and the Hildon input method copy paste messages
+ */
+static GdkFilterReturn
+hildon_window_event_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
+{
+ XAnyEvent *eventti = xevent;
+
+ if (eventti->type == ClientMessage)
+ {
+ XClientMessageEvent *cm = xevent;
+
+ if (xclient_message_type_check (cm, "_MB_GRAB_TRANSFER"))
+ {
+ hildon_window_toggle_menu (HILDON_WINDOW ( data ));
+ return GDK_FILTER_REMOVE;
+ }
+ /* opera hack clipboard client message */
+ else if (xclient_message_type_check (cm, "_HILDON_IM_CLIPBOARD_COPY"))
+ {
+ g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
+ HILDON_WINDOW_CO_COPY);
+ return GDK_FILTER_REMOVE;
+ }
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_CUT"))
+ {
+ g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
+ HILDON_WINDOW_CO_CUT);
+ return GDK_FILTER_REMOVE;
+ }
+ else if (xclient_message_type_check(cm, "_HILDON_IM_CLIPBOARD_PASTE"))
+ {
+ g_signal_emit_by_name(G_OBJECT(data), "clipboard_operation",
+ HILDON_WINDOW_CO_PASTE);
+ return GDK_FILTER_REMOVE;
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+/*
+ * Here we keep track of changes in the _MB_CURRENT_APP_WINDOW,
+ * to know when we acquire/lose topmost status
+ */
+static GdkFilterReturn
+hildon_window_root_window_event_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XAnyEvent *eventti = xevent;
+ HildonWindow *hwindow = HILDON_WINDOW (data);
+
+
+ if (eventti->type == PropertyNotify)
+ {
+ XPropertyEvent *pevent = xevent;
+ Atom active_app_atom =
+ XInternAtom (GDK_DISPLAY (), "_MB_CURRENT_APP_WINDOW", False);
+
+ if (pevent->atom == active_app_atom)
+ {
+ Window active_window = hildon_window_get_active_window();
+
+ hildon_window_update_topmost (hwindow, active_window);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+/***************************/
+/* Signal handlers */
+/***************************/
+
+/*
+ * Handle the menu hardware key here
+ */
+static gboolean
+hildon_window_key_press_event (GtkWidget *widget, GdkEventKey *event)
+{
+ HildonWindowPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_WINDOW (widget),FALSE);
+
+ priv = HILDON_WINDOW (widget)->priv;
+
+ switch (event->keyval)
+ {
+ case HILDON_HARDKEY_MENU:
+ if (hildon_window_toggle_menu (HILDON_WINDOW (widget)))
+ return TRUE;
+ break;
+ case HILDON_HARDKEY_ESC:
+ if (!priv->escape_timeout)
+ {
+ priv->escape_timeout = g_timeout_add
+ (HILDON_WINDOW_LONG_PRESS_TIME,
+ hildon_window_escape_timeout, widget);
+ }
+ break;
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+
+}
+
+static gboolean
+hildon_window_key_release_event (GtkWidget *widget, GdkEventKey *event)
+{
+ HildonWindowPrivate *priv;
+
+ g_return_val_if_fail (HILDON_IS_WINDOW (widget),FALSE);
+
+ priv = HILDON_WINDOW (widget)->priv;
+
+ switch (event->keyval)
+ {
+ case HILDON_HARDKEY_ESC:
+ if (priv->escape_timeout)
+ {
+ g_source_remove (priv->escape_timeout);
+ priv->escape_timeout = 0;
+ }
+ break;
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
+
+}
+
+/*
+ * We keep track of the window state changes, because the drawing
+ * (borders) differs whether we are in fullscreen mode or not
+ */
+static gboolean
+hildon_window_window_state_event (GtkWidget *widget,
+ GdkEventWindowState *event)
+{
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ HILDON_WINDOW (widget)->priv->fullscreen =
+ event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
+ }
+
+ if (GTK_WIDGET_CLASS (parent_class)->window_state_event)
+ {
+ return GTK_WIDGET_CLASS (parent_class)->window_state_event (
+ widget,
+ event);
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static void
+hildon_window_title_notify (GObject *gobject,
+ GParamSpec *arg1,
+ gpointer user_data)
+{
+ HildonWindow *window = HILDON_WINDOW (gobject);
+
+ hildon_window_update_title (window);
+
+}
+
+/*******************/
+/* General */
+/*******************/
+
+/*The menu popuping needs a menu popup-function*/
+static void
+hildon_window_menupopupfunc (GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in, GtkWidget *widget)
+{
+ gint window_x = 0;
+ gint window_y = 0;
+ GdkWindow *window = GTK_WIDGET(widget)->window;
+
+ if (window)
+ {
+ gdk_window_get_origin (window, &window_x, &window_y);
+ }
+
+ gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
+ "vertical-offset", y, NULL);
+
+ *x += window_x;
+ *y += window_y;
+
+}
+
+static void
+hildon_window_menupopupfuncfull ( GtkMenu *menu, gint *x, gint *y,
+ gboolean *push_in,
+ GtkWidget *widget )
+{
+ gtk_widget_style_get (GTK_WIDGET (menu), "horizontal-offset", x,
+ "vertical-offset", y, NULL);
+
+ *x = MAX (0, *x);
+ *y = MAX (0, *y);
+}
+
+
+/********************/
+/* Private methods */
+/********************/
+
+
+/*
+ * Takes the common toolbar when we acquire the top-most status
+ */
+static void
+hildon_window_is_topmost_notify (HildonWindow *window)
+{
+ if (window->priv->is_topmost)
+ {
+ hildon_window_take_common_toolbar (window);
+ }
+
+ else
+ {
+ /* If the window lost focus while the user started to press
+ * the ESC key, we won't get the release event. We need to
+ * stop the timeout*/
+ if (window->priv->escape_timeout)
+ {
+ g_source_remove (window->priv->escape_timeout);
+ window->priv->escape_timeout = 0;
+ }
+ }
+}
+
+/*
+ * Sets the program to which the window belongs. This should only be called
+ * by hildon_program_add_window
+ */
+void
+hildon_window_set_program (HildonWindow *self, GObject *program)
+{
+ if (self->priv->program)
+ {
+ g_object_unref (self->priv->program);
+ }
+
+ /* Now that we are bound to a program, we can rely on it to track the
+ * root window */
+ gdk_window_remove_filter (gdk_get_default_root_window(),
+ hildon_window_root_window_event_filter,
+ self);
+
+ self->priv->program = HILDON_PROGRAM (program);
+ g_object_ref (program);
+}
+
+/*
+ * Unsets the program to which the window belongs. This should only be called
+ * by hildon_program_add_window
+ */
+void
+hildon_window_unset_program (HildonWindow *self)
+{
+ g_return_if_fail(self && HILDON_IS_WINDOW (self));
+
+ if (self->priv->program)
+ {
+ g_object_unref (self->priv->program);
+ self->priv->program = NULL;
+
+ /* We need to start tacking the root window again */
+ gdk_window_set_events (gdk_get_default_root_window (),
+ gdk_window_get_events (gdk_get_default_root_window ())
+ | GDK_PROPERTY_CHANGE_MASK);
+
+ gdk_window_add_filter (gdk_get_default_root_window (),
+ hildon_window_root_window_event_filter, self );
+ }
+
+ self->priv->program = NULL;
+}
+
+/*
+ * Sets whether or not the program to which this window belongs is
+ * killable. This is used by the HildonProgram to signify to the
+ * Task Navigator whether or not it can hibernate in memory-low situations
+ **/
+void
+hildon_window_set_can_hibernate_property (HildonWindow *self,
+ gpointer _can_hibernate)
+{
+ GdkAtom killable_atom;
+ gboolean can_hibernate;
+
+ g_return_if_fail(self && HILDON_IS_WINDOW (self));
+
+ if (!GTK_WIDGET_REALIZED ((GTK_WIDGET (self))))
+ {
+ return;
+ }
+
+ can_hibernate = * ((gboolean *)_can_hibernate);
+
+ killable_atom = gdk_atom_intern (CAN_HIBERNATE_PROPERTY, FALSE);
+
+ if (can_hibernate)
+ {
+ gdk_property_change (GTK_WIDGET (self)->window, killable_atom,
+ (GdkAtom)31/* XA_STRING */, 8,
+ GDK_PROP_MODE_REPLACE, (const guchar *)CAN_HIBERNATE,
+ CAN_HIBERNATE_LENGTH);
+ }
+ else
+ {
+ gdk_property_delete (GTK_WIDGET (self)->window, killable_atom);
+ }
+
+}
+
+/*
+ * If a common toolbar was set to the program, reparent it to
+ * us
+ */
+void
+hildon_window_take_common_toolbar (HildonWindow *self)
+{
+ g_return_if_fail(self && HILDON_IS_WINDOW (self));
+
+ if (self->priv->program)
+ {
+ GtkWidget *common_toolbar =
+ GTK_WIDGET (hildon_program_get_common_toolbar (self->priv->program));
+
+ if (common_toolbar && common_toolbar->parent != self->priv->vbox)
+ {
+ g_object_ref (common_toolbar);
+ if (common_toolbar->parent)
+ {
+ gtk_container_remove (GTK_CONTAINER (common_toolbar->parent),
+ common_toolbar);
+ }
+
+ gtk_box_pack_end (GTK_BOX(self->priv->vbox), common_toolbar,
+ TRUE, TRUE, 0);
+ g_object_unref (common_toolbar);
+
+ gtk_widget_set_size_request (common_toolbar, -1, TOOLBAR_HEIGHT);
+
+ gtk_widget_show (self->priv->vbox);
+
+ }
+ }
+}
+
+/*
+ * Compare the window that was last topped, and act consequently
+ */
+void
+hildon_window_update_topmost (HildonWindow *self, Window window_id)
+{
+ Window my_window;
+
+ my_window = GDK_WINDOW_XID (GTK_WIDGET (self)->window);
+
+ if (window_id == my_window)
+ {
+ if (!self->priv->is_topmost)
+ {
+ self->priv->is_topmost = TRUE;
+ hildon_window_is_topmost_notify (self);
+ g_object_notify (G_OBJECT (self), "is-topmost");
+ }
+ }
+ else if (self->priv->is_topmost)
+ {
+ /* Should this go in the signal handler? */
+ GtkWidget *focus = gtk_window_get_focus (GTK_WINDOW (self));
+
+ if (GTK_IS_ENTRY (focus))
+ gtk_im_context_focus_out (GTK_ENTRY (focus)->im_context);
+ if (GTK_IS_TEXT_VIEW (focus))
+ gtk_im_context_focus_out (GTK_TEXT_VIEW (focus)->im_context);
+
+ self->priv->is_topmost = FALSE;
+ hildon_window_is_topmost_notify (self);
+ g_object_notify (G_OBJECT (self), "is-topmost");
+
+ }
+}
+
+/*
+ * If the application
+ * was given a name (with g_set_application_name(), set
+ * "ProgramName - WindowTitle" as the displayed
+ * title
+ */
+void
+hildon_window_update_title (HildonWindow *window)
+{
+ const gchar * application_name;
+ g_return_if_fail (window && HILDON_IS_WINDOW (window));
+
+ if (!GTK_WIDGET_REALIZED (window))
+ {
+ return;
+ }
+
+ application_name = g_get_application_name ();
+
+ if (application_name && application_name[0])
+ {
+ const gchar *old_title = gtk_window_get_title (GTK_WINDOW (window));
+
+ if (old_title && old_title[0])
+ {
+ gchar *title = NULL;
+
+ title = g_strjoin (TITLE_SEPARATOR, application_name,
+ old_title, NULL);
+
+ gdk_window_set_title (GTK_WIDGET (window)->window, title);
+
+ g_free (title);
+ }
+
+ }
+}
+
+static void
+detach_menu_func (GtkWidget *attach_widget, GtkMenu *menu)
+{
+}
+/*
+ * Toggles the display of the HildonWindow menu.
+ * Returns whether or not something was done (whether or not we had a menu
+ * to toggle)
+ */
+static gboolean
+hildon_window_toggle_menu (HildonWindow * self)
+{
+ GtkMenu *menu_to_use = NULL;
+ GList *menu_children = NULL;
+
+ g_return_val_if_fail (self && HILDON_IS_WINDOW (self), FALSE);
+
+ /* Select which menu to use, Window specific has highest priority,
+ * then program specific */
+ if (self->priv->menu)
+ {
+ menu_to_use = GTK_MENU (self->priv->menu);
+ }
+ else if (self->priv->program)
+ {
+ menu_to_use = hildon_program_get_common_menu (self->priv->program);
+ if (menu_to_use && gtk_menu_get_attach_widget (menu_to_use) !=
+ GTK_WIDGET (self))
+ {
+ g_object_ref (menu_to_use);
+ if (gtk_menu_get_attach_widget (menu_to_use))
+ {
+ gtk_menu_detach (menu_to_use);
+ }
+
+ gtk_menu_attach_to_widget (menu_to_use, GTK_WIDGET (self),
+ &detach_menu_func);
+ g_object_unref (menu_to_use);
+ }
+ }
+
+ if (!menu_to_use)
+ {
+ return FALSE;
+ }
+
+
+ if (GTK_WIDGET_MAPPED (GTK_WIDGET (menu_to_use)))
+ {
+ gtk_menu_popdown (menu_to_use);
+ gtk_menu_shell_deactivate (GTK_MENU_SHELL (menu_to_use));
+ return TRUE;
+ }
+
+ /* Check if the menu has items */
+ menu_children = gtk_container_get_children (GTK_CONTAINER (menu_to_use));
+
+ if (menu_children)
+ {
+ g_list_free (menu_children);
+
+ /* Apply right theming */
+ gtk_widget_set_name (GTK_WIDGET (menu_to_use),
+ "menu_force_with_corners");
+
+ if (self->priv->fullscreen)
+ {
+ gtk_menu_popup (menu_to_use, NULL, NULL,
+ (GtkMenuPositionFunc)
+ hildon_window_menupopupfuncfull,
+ self, 0,
+ gtk_get_current_event_time ());
+ }
+ else
+ {
+ gtk_menu_popup (menu_to_use, NULL, NULL,
+ (GtkMenuPositionFunc)
+ hildon_window_menupopupfunc,
+ self, 0,
+ gtk_get_current_event_time ());
+ }
+ gtk_menu_shell_select_first (GTK_MENU_SHELL (menu_to_use), TRUE);
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+/*
+ * If the ESC key was not released when the timeout expires,
+ * close the window
+ */
+static gboolean
+hildon_window_escape_timeout (gpointer data)
+{
+ HildonWindowPrivate *priv;
+ GdkEvent *event;
+
+ GDK_THREADS_ENTER ();
+
+ priv = HILDON_WINDOW(data)->priv;
+
+ /* Send fake event, simulation a situation that user
+ pressed 'x' from the corner */
+ event = gdk_event_new(GDK_DELETE);
+ ((GdkEventAny *)event)->window = GDK_WINDOW (g_object_ref (GTK_WIDGET(data)->window));
+ gtk_main_do_event(event);
+
+ /* That unrefs the window, so we're reffing it above */
+ gdk_event_free(event);
+
+ priv->escape_timeout = 0;
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
+
+/******************/
+/* public methods */
+/******************/
+
+
+/**
+ * hildon_window_new:
+ *
+ * Use this function to create a new HildonWindow.
+ *
+ * Return value: A @HildonWindow.
+ **/
+GtkWidget *
+hildon_window_new (void)
+{
+ HildonWindow *newwindow = g_object_new (HILDON_TYPE_WINDOW, NULL);
+
+ return GTK_WIDGET (newwindow);
+}
+
+/**
+ * hildon_window_add_with_scrollbar
+ * @self : A @HildonWindow
+ * @child : A @GtkWidget
+ *
+ * Adds the @child to the HildonWindow and creates a scrollbar
+ * to it. Similar as adding first a @GtkScrolledWindow and then the
+ * @child to it.
+ */
+void
+hildon_window_add_with_scrollbar (HildonWindow * self,
+ GtkWidget * child)
+{
+ GtkScrolledWindow *scrolledw;
+
+ g_return_if_fail (HILDON_IS_WINDOW (self));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (child->parent == NULL);
+
+ scrolledw = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL));
+ gtk_scrolled_window_set_policy (scrolledw, GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (scrolledw, GTK_SHADOW_NONE);
+
+ if (GTK_IS_VIEWPORT (child))
+ gtk_container_add (GTK_CONTAINER (scrolledw), child);
+ else
+ {
+ if (GTK_IS_CONTAINER (child) )
+ gtk_container_set_focus_vadjustment (GTK_CONTAINER(child),
+ gtk_scrolled_window_get_vadjustment (scrolledw) );
+ gtk_scrolled_window_add_with_viewport (scrolledw, child);
+ }
+
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (scrolledw));
+}
+
+/**
+ * hildon_window_add_toolbar:
+ * @self: A @HildonWindow
+ * @toolbar: A #GtkToolbar to add to the HildonWindow
+ *
+ * Adds a toolbar to the window.
+ **/
+void
+hildon_window_add_toolbar (HildonWindow *self, GtkToolbar *toolbar)
+{
+ GtkBox *vbox;
+
+ g_return_if_fail (self && HILDON_IS_WINDOW (self));
+ g_return_if_fail (toolbar && GTK_IS_TOOLBAR (toolbar));
+
+ vbox = GTK_BOX (self->priv->vbox);
+
+ gtk_box_pack_start (vbox, GTK_WIDGET(toolbar), TRUE, TRUE, 0);
+ gtk_box_reorder_child (vbox, GTK_WIDGET(toolbar), 0);
+ gtk_widget_set_size_request (GTK_WIDGET (toolbar), -1, TOOLBAR_HEIGHT);
+
+ gtk_widget_queue_resize (GTK_WIDGET(self));
+}
+
+/**
+ * hildon_window_remove_toolbar:
+ * @self: A @HildonWindow
+ * @toolbar: A #GtkToolbar to remove from the HildonWindow
+ *
+ * Removes a toolbar from the window.
+ **/
+void
+hildon_window_remove_toolbar (HildonWindow *self, GtkToolbar *toolbar)
+{
+ GtkContainer *vbox = GTK_CONTAINER (self->priv->vbox);
+
+ g_return_if_fail (self && HILDON_IS_WINDOW (self));
+
+ gtk_container_remove (vbox, GTK_WIDGET(toolbar));
+}
+
+/**
+ * hildon_window_get_menu:
+ * @self : #HildonWindow
+ *
+ * Gets the #GtMenu assigned to the #HildonAppview.
+ *
+ * Return value: The #GtkMenu assigned to this application view.
+ **/
+GtkMenu *
+hildon_window_get_menu (HildonWindow * self)
+{
+ g_return_val_if_fail (self && HILDON_IS_WINDOW (self), NULL);
+
+ return GTK_MENU (self->priv->menu);
+}
+
+
+/**
+ * hildon_window_set_menu:
+ * @self: A #HildonWindow
+ * @menu: The #GtkMenu to be used for this #HildonWindow
+ *
+ * Sets the menu to be used for this window. This menu overrides
+ * a program-wide menu that may have been set with
+ * hildon_program_set_common_menu. Pass NULL to remove the current
+ * menu.
+ **/
+void
+hildon_window_set_menu (HildonWindow *self, GtkMenu *menu)
+{
+ g_return_if_fail (HILDON_IS_WINDOW (self));
+
+ if (self->priv->menu != NULL) {
+ gtk_menu_detach (GTK_MENU (self->priv->menu));
+ g_object_unref (self->priv->menu);
+ }
+
+ self->priv->menu = (menu != NULL) ? GTK_WIDGET (menu) : NULL;
+ if (self->priv->menu != NULL) {
+ gtk_widget_set_name (self->priv->menu, "menu_force_with_corners");
+ gtk_menu_attach_to_widget (GTK_MENU (self->priv->menu), GTK_WIDGET (self), &detach_menu_func);
+ g_object_ref (GTK_MENU (self->priv->menu));
+ gtk_widget_show_all (GTK_WIDGET (self->priv->menu));
+ }
+}
+
+/**
+ * hildon_window_get_is_topmost:
+ * @self: A #HildonWindow
+ *
+ * Return value: Whether or not the #HildonWindow is currenltly activated
+ * by the window manager.
+ **/
+gboolean
+hildon_window_get_is_topmost(HildonWindow *self){
+ g_return_val_if_fail (HILDON_IS_WINDOW (self), FALSE);
+
+ return self->priv->is_topmost;
+}
+
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+
+#ifndef __HILDON_WINDOW_H__
+#define __HILDON_WINDOW_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtktoolbar.h>
+#include <gdk/gdkx.h>
+
+#include "hildon-defines.h"
+
+G_BEGIN_DECLS
+
+#define HILDON_WINDOW_LONG_PRESS_TIME 1500 /* in ms */
+
+#define HILDON_TYPE_WINDOW ( hildon_window_get_type() )
+#define HILDON_WINDOW(obj) \
+ (GTK_CHECK_CAST (obj, HILDON_TYPE_WINDOW, HildonWindow))
+#define HILDON_WINDOW_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST ((klass),\
+ HILDON_TYPE_WINDOW, HildonWindowClass))
+#define HILDON_IS_WINDOW(obj) (GTK_CHECK_TYPE (obj, HILDON_TYPE_WINDOW))
+#define HILDON_IS_WINDOW_CLASS(klass) \
+ (GTK_CHECK_CLASS_TYPE ((klass), HILDON_TYPE_WINDOW))
+
+typedef struct _HildonWindow HildonWindow;
+typedef struct _HildonWindowClass HildonWindowClass;
+
+/**
+ * HildonWindowPrivate:
+ *
+ * This structure contains just internal data.
+ * It should not be accessed directly.
+ */
+typedef struct _HildonWindowPrivate HildonWindowPrivate;
+
+struct _HildonWindow
+{
+ GtkWindow parent;
+
+ /*private*/
+ HildonWindowPrivate *priv;
+};
+
+enum
+{
+ HILDON_WINDOW_CO_COPY,
+ HILDON_WINDOW_CO_CUT,
+ HILDON_WINDOW_CO_PASTE
+};
+
+struct _HildonWindowClass
+{
+ GtkWindowClass parent_class;
+
+ /* opera hacks for clip board operation */
+ void (*clipboard_operation)(HildonWindow *hwindow, int operation);
+ /* Padding for future extension */
+ void (*_hildon_reserved1)(void);
+ void (*_hildon_reserved2)(void);
+ void (*_hildon_reserved3)(void);
+};
+
+
+GType hildon_window_get_type (void);
+
+GtkWidget * hildon_window_new (void);
+
+void hildon_window_add_with_scrollbar(HildonWindow *self,
+ GtkWidget *child);
+
+GtkMenu * hildon_window_get_menu (HildonWindow *self);
+void hildon_window_set_menu (HildonWindow *self,
+ GtkMenu *menu);
+
+void hildon_window_add_toolbar (HildonWindow *self,
+ GtkToolbar *toolbar);
+
+void hildon_window_remove_toolbar (HildonWindow *self,
+ GtkToolbar *toolbar);
+
+gboolean hildon_window_get_is_topmost (HildonWindow *self);
+
+
+G_END_DECLS
+#endif /* __HILDON_WINDOW_H__ */
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Fixes: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:hildon-wizard-dialog
+ * @short_description: A widget to create a guided installation
+ * process wizard
+ *
+ * #HildonWizardDialog is a widget to create a guided installation
+ * process. The dialog has four standard buttons, previous, next,
+ * finish, cancel, and contains several pages with optional icons.
+ * Response buttons are dimmed/undimmed automatically and the standard
+ * icon is shown/hidden in response to page navigation. The notebook
+ * widget provided by users contains the actual wizard pages.
+ */
+
+#include <gtk/gtkdialog.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
+#include <hildon-widgets/hildon-defines.h>
+
+#include "hildon-wizard-dialog.h"
+
+#include <libintl.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _(String) dgettext(PACKAGE, String)
+
+static GtkDialogClass *parent_class;
+
+static void class_init (HildonWizardDialogClass *wizard_dialog_class);
+
+static void init (HildonWizardDialog *wizard_dialog);
+
+static void create_title (HildonWizardDialog *wizard_dialog);
+
+static void set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void finalize (GObject *object);
+
+static void response (HildonWizardDialog *wizard,
+ gint response_id,
+ gpointer unused);
+
+static void make_buttons_sensitive (HildonWizardDialog *wizard_dialog,
+ gboolean previous,
+ gboolean finish,
+ gboolean next);
+
+enum {
+ PROP_ZERO,
+ PROP_WIZARD_NAME,
+ PROP_WIZARD_NOTEBOOK,
+ PROP_WIZARD_AUTOTITLE
+};
+
+struct _HildonWizardDialogPrivate {
+ gchar *wizard_name;
+ GtkNotebook *notebook;
+ GtkBox *box;
+ GtkWidget *image;
+ gboolean autotitle;
+};
+
+
+GType
+hildon_wizard_dialog_get_type (void)
+{
+ static GType wizard_dialog_type = 0;
+
+ if (!wizard_dialog_type) {
+
+ static const GTypeInfo wizard_dialog_info = {
+ sizeof (HildonWizardDialogClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (HildonWizardDialog),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) init,
+ };
+
+ wizard_dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
+ "HildonWizardDialog",
+ &wizard_dialog_info,
+ 0);
+ }
+
+ return wizard_dialog_type;
+}
+
+static void
+class_init (HildonWizardDialogClass *wizard_dialog_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (wizard_dialog_class);
+
+ parent_class = g_type_class_peek_parent (wizard_dialog_class);
+
+ g_type_class_add_private (wizard_dialog_class,
+ sizeof(HildonWizardDialogPrivate));
+
+ /* Override virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ /**
+ * HildonWizardDialog:wizard-name:
+ *
+ * The name of the wizard.
+ */
+ g_object_class_install_property (object_class, PROP_WIZARD_NAME,
+ g_param_spec_string
+ ("wizard-name",
+ "Wizard Name",
+ "The name of the HildonWizardDialog",
+ NULL,
+ G_PARAM_READWRITE));
+
+ /**
+ * HildonWizardDialog:wizard-notebook:
+ *
+ * The notebook object, which is used by the HildonWizardDialog.
+ */
+ g_object_class_install_property(object_class, PROP_WIZARD_NOTEBOOK,
+ g_param_spec_object
+ ("wizard-notebook",
+ "Wizard Notebook",
+ "GtkNotebook object to be used in the "
+ "HildonWizardDialog",
+ GTK_TYPE_NOTEBOOK, G_PARAM_READWRITE));
+
+ /**
+ * HildonWizardDialog:autotitle
+ *
+ * If the wizard should automatically try to change the window title when changing steps.
+ * Set to FALSE if you'd like to override the default behaviour.
+ *
+ * Since: 0.14.5
+ */
+ g_object_class_install_property(object_class, PROP_WIZARD_AUTOTITLE,
+ g_param_spec_boolean
+ ("autotitle",
+ "AutoTitle",
+ "If the wizard should autotitle itself",
+ TRUE,
+ G_PARAM_READWRITE));
+}
+
+static void
+finalize (GObject *object)
+{
+ HildonWizardDialog *dialog = HILDON_WIZARD_DIALOG (object);
+ g_return_if_fail (dialog != NULL);
+
+ if (dialog->priv->wizard_name != NULL)
+ g_free (HILDON_WIZARD_DIALOG (object)->priv->wizard_name);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize(object);
+}
+
+/* Disable or enable the Previous, Next and Finish buttons */
+static void
+make_buttons_sensitive (HildonWizardDialog *wizard_dialog,
+ gboolean previous,
+ gboolean finish,
+ gboolean next)
+{
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
+ HILDON_WIZARD_DIALOG_PREVIOUS,
+ previous);
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
+ HILDON_WIZARD_DIALOG_FINISH,
+ finish);
+
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (wizard_dialog),
+ HILDON_WIZARD_DIALOG_NEXT,
+ next);
+}
+
+static void
+init (HildonWizardDialog *wizard_dialog)
+{
+ /* Initialize private structure for faster member access */
+ HildonWizardDialogPrivate *priv =
+ G_TYPE_INSTANCE_GET_PRIVATE (wizard_dialog,
+ HILDON_TYPE_WIZARD_DIALOG,
+ HildonWizardDialogPrivate);
+
+ GtkDialog *dialog = GTK_DIALOG (wizard_dialog);
+
+ /* Init internal widgets */
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 0);
+ gtk_dialog_set_has_separator (dialog, FALSE);
+ wizard_dialog->priv = priv;
+ priv->box = GTK_BOX (gtk_hbox_new (FALSE, 0));
+ priv->image = gtk_image_new_from_icon_name ("qgn_widg_wizard",
+ HILDON_ICON_SIZE_WIDG_WIZARD);
+
+ /* Default values for user provided properties */
+ priv->notebook = NULL;
+ priv->wizard_name = NULL;
+ priv->autotitle = TRUE;
+
+ /* Build wizard layout */
+ gtk_box_pack_start_defaults (GTK_BOX (dialog->vbox), GTK_WIDGET (priv->box));
+ gtk_box_pack_start_defaults (GTK_BOX (priv->box), GTK_WIDGET (vbox));
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->image), FALSE, FALSE, 0);
+
+ /* Add response buttons: finish, previous, next, cancel */
+ gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_finish"), HILDON_WIZARD_DIALOG_FINISH);
+ gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_previous"), HILDON_WIZARD_DIALOG_PREVIOUS);
+ gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_next"), HILDON_WIZARD_DIALOG_NEXT);
+ gtk_dialog_add_button (dialog, _("ecdg_bd_wizard_cancel"), HILDON_WIZARD_DIALOG_CANCEL);
+
+ /* Set initial button states: previous and finish buttons are disabled */
+ make_buttons_sensitive (wizard_dialog, FALSE, FALSE, TRUE);
+
+ /* Show all the internal widgets */
+ gtk_widget_show_all (GTK_WIDGET (dialog->vbox));
+
+ /* connect to dialog's response signal */
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (response), NULL);
+}
+
+static void
+set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HildonWizardDialogPrivate *priv = HILDON_WIZARD_DIALOG(object)->priv;
+
+ switch (property_id) {
+
+ case PROP_WIZARD_AUTOTITLE:
+
+ priv->autotitle = g_value_get_boolean (value);
+
+ if (priv->autotitle &&
+ priv->wizard_name &&
+ priv->notebook)
+ create_title (HILDON_WIZARD_DIALOG (object));
+ else if (priv->wizard_name)
+ gtk_window_set_title (GTK_WINDOW (object), priv->wizard_name);
+
+ break;
+
+ case PROP_WIZARD_NAME:
+
+ /* Set new wizard name. This name will appear in titlebar */
+ if (priv->wizard_name)
+ g_free (priv->wizard_name);
+
+ gchar *str = (gchar *) g_value_get_string (value);
+ g_return_if_fail (str != NULL);
+
+ priv->wizard_name = g_strdup (str);
+
+ /* We need notebook in order to create title, since page information
+ is used in title generation */
+
+ if (priv->notebook && priv->autotitle)
+ create_title (HILDON_WIZARD_DIALOG (object));
+
+ break;
+
+ case PROP_WIZARD_NOTEBOOK: {
+
+ GtkNotebook *book = GTK_NOTEBOOK (g_value_get_object (value));
+ g_return_if_fail (book != NULL);
+
+ priv->notebook = book;
+
+ /* Set the default properties for the notebook (disable tabs,
+ * and remove borders) to make it look like a nice wizard widget */
+ gtk_notebook_set_show_tabs (priv->notebook, FALSE);
+ gtk_notebook_set_show_border (priv->notebook, FALSE);
+ gtk_box_pack_start_defaults (GTK_BOX( priv->box), GTK_WIDGET (priv->notebook));
+
+ /* Show the notebook so that a gtk_widget_show on the dialog is
+ * all that is required to display the dialog correctly */
+ gtk_widget_show (priv->notebook);
+
+ /* Update dialog title to reflect current page stats etc */
+ if (priv->wizard_name && priv->autotitle)
+ create_title (HILDON_WIZARD_DIALOG (object));
+
+ } break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HildonWizardDialogPrivate *priv = HILDON_WIZARD_DIALOG (object)->priv;
+
+ switch (property_id) {
+
+ case PROP_WIZARD_NAME:
+ g_value_set_string (value, priv->wizard_name);
+ break;
+
+ case PROP_WIZARD_NOTEBOOK:
+ g_value_set_object (value, priv->notebook);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+/*
+ * Creates the title of the dialog taking into account the current
+ * page of the notebook.
+ */
+static void
+create_title (HildonWizardDialog *wizard_dialog)
+{
+ gint pages, current;
+ gchar *str = NULL;
+ HildonWizardDialogPrivate *priv = wizard_dialog->priv;
+ GtkNotebook *notebook = priv->notebook;
+
+ if (!notebook)
+ return;
+
+ /* Get page information, we'll need that when creating title */
+ pages = gtk_notebook_get_n_pages (notebook);
+ current = gtk_notebook_get_current_page (priv->notebook);
+ if (current < 0)
+ current = 0;
+
+ /* the welcome title on the initial page */
+ if (current == 0) {
+ str = g_strdup_printf (_("ecdg_ti_wizard_welcome"),
+ priv->wizard_name, pages);
+ } else {
+ const gchar *steps = gtk_notebook_get_tab_label_text (notebook,
+ gtk_notebook_get_nth_page (notebook, current));
+
+ str = g_strdup_printf (_("ecdg_ti_wizard_step"),
+ priv->wizard_name, current + 1, pages, steps);
+ }
+
+ /* Update the dialog to display the generated title */
+ gtk_window_set_title (GTK_WINDOW (wizard_dialog), str);
+ g_free (str);
+}
+
+/*
+ * Response signal handler. This function is needed because GtkDialog's
+ * handler for this signal closes the dialog and we don't want that, we
+ * want to change pages and, dimm certain response buttons. Overriding the
+ * virtual function would not work because that would be called after the
+ * signal handler implemented by GtkDialog.
+ * FIXME: There is a much saner way to do that [MDK]
+ */
+static void
+response (HildonWizardDialog *wizard_dialog,
+ gint response_id,
+ gpointer unused)
+{
+ HildonWizardDialogPrivate *priv = wizard_dialog->priv;
+ GtkNotebook *notebook = priv->notebook;
+ gint current = 0;
+ gint last = gtk_notebook_get_n_pages (notebook) - 1;
+ gboolean is_first, is_last;
+
+ switch (response_id) {
+
+ case HILDON_WIZARD_DIALOG_PREVIOUS:
+ gtk_notebook_prev_page (notebook); /* go to previous page */
+ break;
+
+ case HILDON_WIZARD_DIALOG_NEXT:
+ gtk_notebook_next_page (notebook); /* go to next page */
+ break;
+
+ case HILDON_WIZARD_DIALOG_CANCEL:
+ case HILDON_WIZARD_DIALOG_FINISH:
+ return;
+
+ }
+
+ current = gtk_notebook_get_current_page (notebook);
+ is_last = current == last;
+ is_first = current == 0;
+
+ /* If first page, previous and finish are disabled,
+ if last page, next is disabled */
+ make_buttons_sensitive (wizard_dialog,
+ !is_first, !is_first, !is_last);
+
+ /* Don't let the dialog close */
+ g_signal_stop_emission_by_name (wizard_dialog, "response");
+
+ /* We show the default image on first and last pages */
+ if (current == last || current == 0)
+ gtk_widget_show (GTK_WIDGET(priv->image));
+ else
+ gtk_widget_hide (GTK_WIDGET(priv->image));
+
+ /* New page number may appear in the title, update it */
+ if (priv->autotitle)
+ create_title (wizard_dialog);
+}
+
+/**
+ * hildon_wizard_dialog_new:
+ * @parent: a #GtkWindow
+ * @wizard_name: the name of dialog
+ * @notebook: the notebook to be shown on the dialog
+ *
+ * Creates a new #HildonWizardDialog.
+ *
+ * Returns: a new #HildonWizardDialog
+ */
+GtkWidget*
+hildon_wizard_dialog_new (GtkWindow *parent,
+ const char *wizard_name,
+ GtkNotebook *notebook)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), NULL);
+
+ widget = GTK_WIDGET (g_object_new
+ (HILDON_TYPE_WIZARD_DIALOG,
+ "wizard-name", wizard_name,
+ "wizard-notebook", notebook, NULL));
+
+ if (parent)
+ gtk_window_set_transient_for (GTK_WINDOW (widget), parent);
+
+ return widget;
+}
--- /dev/null
+/*
+ * This file is part of hildon-libs
+ *
+ * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
+ *
+ * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Fixes: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __HILDON_WIZARD_DIALOG_H__
+#define __HILDON_WIZARD_DIALOG_H__
+
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define HILDON_TYPE_WIZARD_DIALOG (hildon_wizard_dialog_get_type())
+
+#define HILDON_WIZARD_DIALOG(obj) (GTK_CHECK_CAST ((obj), \
+ HILDON_TYPE_WIZARD_DIALOG, HildonWizardDialog))
+
+#define HILDON_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
+ HILDON_TYPE_WIZARD_DIALOG, HildonWizardDialogClass))
+
+#define HILDON_IS_WIZARD_DIALOG(obj) (GTK_CHECK_TYPE ((obj), \
+ HILDON_TYPE_WIZARD_DIALOG))
+
+#define HILDON_IS_WIZARD_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
+ HILDON_TYPE_WIZARD_DIALOG))
+
+typedef struct _HildonWizardDialog HildonWizardDialog;
+
+typedef struct _HildonWizardDialogClass HildonWizardDialogClass;
+
+typedef struct _HildonWizardDialogPrivate HildonWizardDialogPrivate;
+
+/* button response IDs */
+enum {
+ HILDON_WIZARD_DIALOG_CANCEL = GTK_RESPONSE_CANCEL,
+ HILDON_WIZARD_DIALOG_PREVIOUS = 0,
+ HILDON_WIZARD_DIALOG_NEXT,
+ HILDON_WIZARD_DIALOG_FINISH
+};
+
+struct _HildonWizardDialog {
+ GtkDialog parent;
+ HildonWizardDialogPrivate *priv;
+};
+
+struct _HildonWizardDialogClass {
+ GtkDialogClass parent_class;
+ void (*_gtk_reserved1) (void);
+ void (*_gtk_reserved2) (void);
+ void (*_gtk_reserved3) (void);
+ void (*_gtk_reserved4) (void);
+};
+
+
+GType hildon_wizard_dialog_get_type (void) G_GNUC_CONST;
+
+GtkWidget* hildon_wizard_dialog_new (GtkWindow *parent,
+ const char *wizard_name,
+ GtkNotebook *notebook);
+
+G_END_DECLS
+
+#endif /* __HILDON_WIZARD_DIALOG_H__ */