*
* Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
*
- * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
+ * Contact: Rodrigo Novo <rodrigo.novo@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
* 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. Additional features
- * such as progress bars or animation can also be included.
- *
+ * #HildonNote is a convenient way to prompt users for a small amount of
+ * input. A simple note contains an information text and, in case of
+ * confirmation notes, it shows buttons to confirm or cancel. It also can
+ * include a progress bar.
+ *
+ * This widget provides convenient functions to create either
+ * information notes, confirmation notes or cancel notes, which are
+ * useful to show the progress of a requested task allowing the user
+ * to cancel it.
+ *
+ * To create information notes you can use
+ * hildon_note_new_information(). hildon_note_new_confirmation()
+ * creates a note with a text and two buttons to confirm or
+ * cancel. Note that it is possible to create a confirmation note with
+ * customized buttons by using
+ * hildon_note_new_confirmation_add_buttons().
+ *
+ * To create a note with a text, a progress bar and cancel button,
+ * hildon_note_new_cancel_with_progress_bar() can be used.
+ *
* <example>
* <title>HildonNote example</title>
* <programlisting>
#include "hildon-enum-types.h"
#include "hildon-note-private.h"
+#define HILDON_INFORMATION_NOTE_MIN_HEIGHT 140
+
+#define HILDON_INFORMATION_NOTE_MARGIN 100
#define CONFIRMATION_SOUND_PATH \
"/usr/share/sounds/ui-confirmation_note.wav"
hildon_note_rebuild (HildonNote *note);
static void
+hildon_note_rename (HildonNote *note);
+
+static void
hildon_note_finalize (GObject *obj_self);
static void
hildon_note_realize (GtkWidget *widget);
+static void
+hildon_note_unrealize (GtkWidget *widget);
+
+static void
+label_size_request (GtkWidget *label,
+ GtkRequisition *req,
+ GtkWidget *note);
+
static void
hildon_note_set_property (GObject *object,
guint prop_id,
static GtkDialogClass* parent_class;
+static gboolean
+event_box_press_event (GtkEventBox *event_box,
+ GdkEventButton *event,
+ GtkDialog *note)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (note);
+
+ if (priv->note_n == HILDON_NOTE_TYPE_INFORMATION ||
+ priv->note_n == HILDON_NOTE_TYPE_INFORMATION_THEME) {
+ gtk_dialog_response (note, GTK_RESPONSE_DELETE_EVENT);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
static void
hildon_note_set_property (GObject *object,
case PROP_HILDON_NOTE_TYPE:
priv->note_n = g_value_get_enum (value);
+ hildon_note_rename (note);
hildon_note_rebuild (note);
break;
object_class->set_property = hildon_note_set_property;
object_class->get_property = hildon_note_get_property;
widget_class->realize = hildon_note_realize;
+ widget_class->unrealize = hildon_note_unrealize;
g_object_class_install_property (object_class,
PROP_HILDON_NOTE_TYPE,
priv->label = gtk_label_new (NULL);
gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
+ priv->event_box = gtk_event_box_new ();
priv->icon = NULL;
priv->stock_icon = NULL;
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (priv->event_box), FALSE);
+ gtk_event_box_set_above_child (GTK_EVENT_BOX (priv->event_box), TRUE);
+ g_signal_connect (priv->event_box, "button-press-event",
+ G_CALLBACK (event_box_press_event), dialog);
+
/* Acquire real references to our internal children, since
they are not nessecarily packed into container in each
layout */
+ g_object_ref_sink (priv->event_box);
g_object_ref_sink (priv->label);
gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
/* FIXME Some of this stuff should be moved to dispose */
/* Free internal data */
+ if (priv->event_box)
+ g_object_unref (priv->event_box);
+
if (priv->label)
g_object_unref (priv->label);
G_OBJECT_CLASS (parent_class)->finalize (obj_self);
}
+static void
+label_size_request (GtkWidget *label,
+ GtkRequisition *req,
+ GtkWidget *note)
+{
+ gint note_height = MAX (HILDON_INFORMATION_NOTE_MIN_HEIGHT, req->height);
+ g_object_set (note, "height-request", note_height, NULL);
+}
+
+static void
+screen_size_changed (GdkScreen *screen,
+ GtkWidget *note)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (note);
+ gint screen_width = gdk_screen_get_width (screen);
+ gint text_width = screen_width - HILDON_INFORMATION_NOTE_MARGIN * 2;
+
+ g_object_set (note, "width-request", screen_width, NULL);
+ g_object_set (priv->label, "width-request", text_width, NULL);
+}
static void
hildon_note_realize (GtkWidget *widget)
{
GdkDisplay *display;
+ gboolean is_info_note = FALSE;
Atom atom;
const gchar *notification_type;
HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
if (priv->note_n == HILDON_NOTE_TYPE_INFORMATION ||
priv->note_n == HILDON_NOTE_TYPE_INFORMATION_THEME) {
notification_type = "_HILDON_NOTIFICATION_TYPE_INFO";
+ is_info_note = TRUE;
} else {
notification_type = "_HILDON_NOTIFICATION_TYPE_CONFIRMATION";
}
XChangeProperty (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XID (widget->window),
atom, XA_STRING, 8, PropModeReplace, (guchar *) notification_type,
strlen (notification_type));
+
+ if (is_info_note) {
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ g_signal_connect (priv->label, "size-request", G_CALLBACK (label_size_request), widget);
+ g_signal_connect (screen, "size-changed", G_CALLBACK (screen_size_changed), widget);
+ screen_size_changed (screen, widget);
+ }
+}
+
+static void
+hildon_note_unrealize (GtkWidget *widget)
+{
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+
+ g_signal_handlers_disconnect_by_func (screen, G_CALLBACK (screen_size_changed), widget);
+ g_signal_handlers_disconnect_by_func (priv->label, G_CALLBACK (label_size_request), widget);
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
}
+
/* 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. */
gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
}
+/*
+ Name the widget and text label based on the note type. This is used
+ by the theme to give proper backgrounds depending on the note type.
+*/
+static void
+hildon_note_rename (HildonNote *note)
+{
+ GEnumValue *value;
+ GEnumClass *enum_class;
+ gchar *name;
+
+ HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (note);
+
+ enum_class = g_type_class_ref (HILDON_TYPE_NOTE_TYPE);
+ value = g_enum_get_value (enum_class, priv->note_n);
+
+ name = g_strconcat ("HildonNote-", value->value_nick, NULL);
+ gtk_widget_set_name (GTK_WIDGET (note), name);
+ g_free (name);
+
+ name = g_strconcat ("HildonNoteLabel-", value->value_nick, NULL);
+ gtk_widget_set_name (priv->label, name);
+ g_free (name);
+
+ g_type_class_unref (enum_class);
+}
+
static void
hildon_note_rebuild (HildonNote *note)
{
/* Reuse exiting content widgets for new layout */
unpack_widget (priv->label);
unpack_widget (priv->progressbar);
+ unpack_widget (priv->event_box);
/* Destroy old layout and buttons */
if (priv->box) {
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);
+ gtk_container_add (GTK_CONTAINER (priv->event_box), priv->box);
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_container_add (GTK_CONTAINER (priv->event_box), 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);
+ gtk_container_add (GTK_CONTAINER (dialog->vbox), priv->event_box);
+
+ gtk_widget_show_all (priv->event_box);
}
/**