gtk+ r21846 - in trunk: . gtk tests
- From: mitch svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk+ r21846 - in trunk: . gtk tests
- Date: Fri, 5 Dec 2008 11:31:30 +0000 (UTC)
Author: mitch
Date: Fri Dec 5 11:31:30 2008
New Revision: 21846
URL: http://svn.gnome.org/viewvc/gtk+?rev=21846&view=rev
Log:
2008-12-05 Michael Natterer <mitch imendio com>
Bug 546285 â Allow GtkEntry to draw progress
* gtk/gtkentry.[ch]: add new API similar to GtkProgressBar which
allows to set the entry's progress_fraction, its progress_pulse_step
and to let the entry's progress pulse.
* gtk/gtk.symbols: updated.
* tests/testgtk.c: add progress demo code to the "Entry" window.
Modified:
trunk/ChangeLog
trunk/gtk/gtk.symbols
trunk/gtk/gtkentry.c
trunk/gtk/gtkentry.h
trunk/tests/testgtk.c
Modified: trunk/gtk/gtk.symbols
==============================================================================
--- trunk/gtk/gtk.symbols (original)
+++ trunk/gtk/gtk.symbols Fri Dec 5 11:31:30 2008
@@ -1282,6 +1282,8 @@
gtk_entry_get_layout_offsets
gtk_entry_get_max_length
gtk_entry_get_overwrite_mode
+gtk_entry_get_progress_fraction
+gtk_entry_get_progress_pulse_step
gtk_entry_get_text
gtk_entry_get_text_length
gtk_entry_get_type G_GNUC_CONST
@@ -1293,6 +1295,7 @@
gtk_entry_new_with_max_length
gtk_entry_append_text
gtk_entry_prepend_text
+gtk_entry_progress_pulse
gtk_entry_select_region
gtk_entry_set_position
gtk_entry_set_editable
@@ -1305,6 +1308,8 @@
gtk_entry_set_invisible_char
gtk_entry_set_max_length
gtk_entry_set_overwrite_mode
+gtk_entry_set_progress_fraction
+gtk_entry_set_progress_pulse_step
gtk_entry_set_text
gtk_entry_set_visibility
gtk_entry_set_width_chars
Modified: trunk/gtk/gtkentry.c
==============================================================================
--- trunk/gtk/gtkentry.c (original)
+++ trunk/gtk/gtkentry.c Fri Dec 5 11:31:30 2008
@@ -26,6 +26,8 @@
*/
#include "config.h"
+
+#include <math.h>
#include <string.h>
#include "gdk/gdkkeysyms.h"
@@ -86,14 +88,20 @@
gfloat xalign;
gint insert_pos;
guint blink_time; /* time in msec the cursor has blinked since last user event */
- guint interior_focus : 1;
- guint real_changed : 1;
- guint invisible_char_set : 1;
- guint caps_lock_warning : 1;
- guint change_count : 8;
+ guint interior_focus : 1;
+ guint real_changed : 1;
+ guint invisible_char_set : 1;
+ guint caps_lock_warning : 1;
+ guint change_count : 8;
+ guint progress_pulse_mode : 1;
+ guint progress_pulse_way_back : 1;
gint focus_width;
GtkShadowType shadow_type;
+
+ gdouble progress_fraction;
+ gdouble progress_pulse_fraction;
+ gdouble progress_pulse_current;
};
typedef struct _GtkEntryPasswordHint GtkEntryPasswordHint;
@@ -149,7 +157,9 @@
PROP_OVERWRITE_MODE,
PROP_TEXT_LENGTH,
PROP_INVISIBLE_CHAR_SET,
- PROP_CAPS_LOCK_WARNING
+ PROP_CAPS_LOCK_WARNING,
+ PROP_PROGRESS_FRACTION,
+ PROP_PROGRESS_PULSE_STEP
};
static guint signals[LAST_SIGNAL] = { 0 };
@@ -184,6 +194,8 @@
GtkAllocation *allocation);
static void gtk_entry_draw_frame (GtkWidget *widget,
GdkRectangle *area);
+static void gtk_entry_draw_progress (GtkWidget *widget,
+ GdkEventExpose *event);
static gint gtk_entry_expose (GtkWidget *widget,
GdkEventExpose *event);
static gint gtk_entry_button_press (GtkWidget *widget,
@@ -668,6 +680,7 @@
P_("Whether new text overwrites existing text"),
FALSE,
GTK_PARAM_READWRITE));
+
/**
* GtkEntry:text-length:
*
@@ -699,8 +712,6 @@
FALSE,
GTK_PARAM_READWRITE));
-
-
/**
* GtkEntry:caps-lock-warning
*
@@ -717,7 +728,41 @@
TRUE,
GTK_PARAM_READWRITE));
-
+ /**
+ * GtkEntry:progress-fraction:
+ *
+ * The current fraction of the task that's been completed.
+ *
+ * Since: 2.16
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_PROGRESS_FRACTION,
+ g_param_spec_double ("progress-fraction",
+ P_("Progress Fraction"),
+ P_("The current fraction of the task that's been completed"),
+ 0.0,
+ 1.0,
+ 0.0,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkEntry:progress-pulse-step:
+ *
+ * The fraction of total entry width to move the progress
+ * bouncing block for each call to gtk_entry_progress_pulse().
+ *
+ * Since: 2.16
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_PROGRESS_PULSE_STEP,
+ g_param_spec_double ("progress-pulse-step",
+ P_("Progress Pulse Step"),
+ P_("The fraction of total entry width to move the progress bouncing block for each call to gtk_entry_progress_pulse()"),
+ 0.0,
+ 1.0,
+ 0.1,
+ GTK_PARAM_READWRITE));
+
signals[POPULATE_POPUP] =
g_signal_new (I_("populate-popup"),
G_OBJECT_CLASS_TYPE (gobject_class),
@@ -1142,6 +1187,14 @@
priv->caps_lock_warning = g_value_get_boolean (value);
break;
+ case PROP_PROGRESS_FRACTION:
+ gtk_entry_set_progress_fraction (entry, g_value_get_double (value));
+ break;
+
+ case PROP_PROGRESS_PULSE_STEP:
+ gtk_entry_set_progress_pulse_step (entry, g_value_get_double (value));
+ break;
+
case PROP_SCROLL_OFFSET:
case PROP_CURSOR_POSITION:
default:
@@ -1218,6 +1271,13 @@
case PROP_CAPS_LOCK_WARNING:
g_value_set_boolean (value, priv->caps_lock_warning);
break;
+ case PROP_PROGRESS_FRACTION:
+ g_value_set_double (value, priv->progress_fraction);
+ break;
+ case PROP_PROGRESS_PULSE_STEP:
+ g_value_set_double (value, priv->progress_pulse_fraction);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1289,6 +1349,8 @@
priv->shadow_type = GTK_SHADOW_IN;
priv->xalign = 0.0;
priv->caps_lock_warning = TRUE;
+ priv->progress_fraction = 0.0;
+ priv->progress_pulse_fraction = 0.1;
gtk_drag_dest_set (GTK_WIDGET (entry),
GTK_DEST_DEFAULT_HIGHLIGHT,
@@ -1784,6 +1846,52 @@
}
}
+static void
+gtk_entry_draw_progress (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ GtkEntryPrivate *private = GTK_ENTRY_GET_PRIVATE (widget);
+ GtkEntry *entry = GTK_ENTRY (widget);
+
+ if (private->progress_pulse_mode)
+ {
+ gdouble value = private->progress_pulse_current;
+ gint area_width, area_height;
+
+ gdk_drawable_get_size (entry->text_area, &area_width, &area_height);
+
+ gtk_paint_box (widget->style, entry->text_area,
+ GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+ &event->area, widget, "entry-progress",
+ value * area_width, 0,
+ private->progress_pulse_fraction * area_width, area_height);
+ }
+ else if (private->progress_fraction > 0)
+ {
+ gdouble value = private->progress_fraction;
+ gint area_width, area_height;
+
+ gdk_drawable_get_size (entry->text_area, &area_width, &area_height);
+
+ if (gtk_widget_get_direction (GTK_WIDGET (entry)) == GTK_TEXT_DIR_RTL)
+ {
+ gtk_paint_box (widget->style, entry->text_area,
+ GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+ &event->area, widget, "entry-progress",
+ area_width - value * area_width, 0,
+ value * area_width, area_height);
+ }
+ else
+ {
+ gtk_paint_box (widget->style, entry->text_area,
+ GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+ &event->area, widget, "entry-progress",
+ 0, 0,
+ value * area_width, area_height);
+ }
+ }
+}
+
static gint
gtk_entry_expose (GtkWidget *widget,
GdkEventExpose *event)
@@ -1811,6 +1919,8 @@
&event->area, widget, "entry_bg",
0, 0, area_width, area_height);
+ gtk_entry_draw_progress (widget, event);
+
if (entry->dnd_position != -1)
gtk_entry_draw_cursor (GTK_ENTRY (widget), CURSOR_DND);
@@ -6628,6 +6738,179 @@
return g_object_get_qdata (G_OBJECT (entry), quark_cursor_hadjustment);
}
+/**
+ * gtk_entry_set_progress_fraction:
+ * @entry: a #GtkEntry
+ * @fraction: fraction of the task that's been completed
+ *
+ * Causes the entry's progress indicator to "fill in" the given
+ * fraction of the bar. The fraction should be between 0.0 and 1.0,
+ * inclusive.
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_set_progress_fraction (GtkEntry *entry,
+ gdouble fraction)
+{
+ GtkEntryPrivate *private;
+ gdouble old_fraction;
+
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ private = GTK_ENTRY_GET_PRIVATE (entry);
+
+ if (private->progress_pulse_mode)
+ old_fraction = -1;
+ else
+ old_fraction = private->progress_fraction;
+
+ fraction = CLAMP (fraction, 0.0, 1.0);
+
+ private->progress_fraction = fraction;
+ private->progress_pulse_mode = FALSE;
+ private->progress_pulse_current = 0.0;
+
+ if (fabs (fraction - old_fraction) > 0.0001)
+ gtk_entry_queue_draw (entry);
+
+ if (fraction != old_fraction)
+ g_object_notify (G_OBJECT (entry), "progress-fraction");
+}
+
+/**
+ * gtk_entry_get_progress_fraction:
+ * @entry: a #GtkEntry
+ *
+ * Returns the current fraction of the task that's been completed.
+ * See gtk_entry_set_progress_fraction().
+ *
+ * Return value: a fraction from 0.0 to 1.0
+ *
+ * Since: 2.16
+ */
+gdouble
+gtk_entry_get_progress_fraction (GtkEntry *entry)
+{
+ GtkEntryPrivate *private;
+
+ g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0);
+
+ private = GTK_ENTRY_GET_PRIVATE (entry);
+
+ return private->progress_fraction;
+}
+
+/**
+ * gtk_entry_set_progress_pulse_step:
+ * @entry: a #GtkEntry
+ * @fraction: fraction between 0.0 and 1.0
+ *
+ * Sets the fraction of total entry width to move the progress
+ * bouncing block for each call to gtk_entry_progress_pulse().
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_set_progress_pulse_step (GtkEntry *entry,
+ gdouble fraction)
+{
+ GtkEntryPrivate *private;
+
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ private = GTK_ENTRY_GET_PRIVATE (entry);
+
+ fraction = CLAMP (fraction, 0.0, 1.0);
+
+ if (fraction != private->progress_pulse_fraction)
+ {
+ private->progress_pulse_fraction = fraction;
+
+ gtk_entry_queue_draw (entry);
+
+ g_object_notify (G_OBJECT (entry), "progress-pulse-step");
+ }
+}
+
+/**
+ * gtk_entry_get_progress_pulse_step:
+ * @entry: a #GtkEntry
+ *
+ * Retrieves the pulse step set with gtk_entry_set_progress_pulse_step().
+ *
+ * Return value: a fraction from 0.0 to 1.0
+ *
+ * Since: 2.16
+ */
+gdouble
+gtk_entry_get_progress_pulse_step (GtkEntry *entry)
+{
+ GtkEntryPrivate *private;
+
+ g_return_val_if_fail (GTK_IS_ENTRY (entry), 0.0);
+
+ private = GTK_ENTRY_GET_PRIVATE (entry);
+
+ return private->progress_pulse_fraction;
+}
+
+/**
+ * gtk_entry_progress_pulse:
+ * @entry: a #GtkEntry
+ *
+ * Indicates that some progress is made, but you don't know how much.
+ * Causes the entry's progress indicator to enter "activity mode,"
+ * where a block bounces back and forth. Each call to
+ * gtk_entry_progress_pulse() causes the block to move by a little bit
+ * (the amount of movement per pulse is determined by
+ * gtk_entry_set_progress_pulse_step()).
+ *
+ * Since: 2.16
+ */
+void
+gtk_entry_progress_pulse (GtkEntry *entry)
+{
+ GtkEntryPrivate *private;
+
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ private = GTK_ENTRY_GET_PRIVATE (entry);
+
+ if (private->progress_pulse_mode)
+ {
+ if (private->progress_pulse_way_back)
+ {
+ private->progress_pulse_current -= private->progress_pulse_fraction;
+
+ if (private->progress_pulse_current < 0.0)
+ {
+ private->progress_pulse_current = 0.0;
+ private->progress_pulse_way_back = FALSE;
+ }
+ }
+ else
+ {
+ private->progress_pulse_current += private->progress_pulse_fraction;
+
+ if (private->progress_pulse_current > 1.0 - private->progress_pulse_fraction)
+ {
+ private->progress_pulse_current = 1.0 - private->progress_pulse_fraction;
+ private->progress_pulse_way_back = TRUE;
+ }
+ }
+ }
+ else
+ {
+ private->progress_fraction = 0.0;
+ private->progress_pulse_mode = TRUE;
+ private->progress_pulse_way_back = FALSE;
+ private->progress_pulse_current = 0.0;
+ }
+
+ gtk_entry_queue_draw (entry);
+}
+
/* Caps Lock warning for password entries */
static void
@@ -6793,6 +7076,5 @@
remove_capslock_feedback (entry);
}
-
#define __GTK_ENTRY_C__
#include "gtkaliasdef.c"
Modified: trunk/gtk/gtkentry.h
==============================================================================
--- trunk/gtk/gtkentry.h (original)
+++ trunk/gtk/gtkentry.h Fri Dec 5 11:31:30 2008
@@ -212,6 +212,18 @@
GtkAdjustment *adjustment);
GtkAdjustment* gtk_entry_get_cursor_hadjustment (GtkEntry *entry);
+/* Progress API
+ */
+void gtk_entry_set_progress_fraction (GtkEntry *entry,
+ gdouble fraction);
+gdouble gtk_entry_get_progress_fraction (GtkEntry *entry);
+
+void gtk_entry_set_progress_pulse_step (GtkEntry *entry,
+ gdouble fraction);
+gdouble gtk_entry_get_progress_pulse_step (GtkEntry *entry);
+
+void gtk_entry_progress_pulse (GtkEntry *entry);
+
/* Deprecated compatibility functions
*/
Modified: trunk/tests/testgtk.c
==============================================================================
--- trunk/tests/testgtk.c (original)
+++ trunk/tests/testgtk.c Fri Dec 5 11:31:30 2008
@@ -5193,6 +5193,65 @@
gtk_widget_set_sensitive (entry, GTK_TOGGLE_BUTTON(checkbutton)->active);
}
+static gboolean
+entry_progress_timeout (gpointer data)
+{
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
+ {
+ gtk_entry_progress_pulse (GTK_ENTRY (data));
+ }
+ else
+ {
+ gdouble fraction;
+
+ fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
+
+ fraction += 0.05;
+ if (fraction > 1.0001)
+ fraction = 0.0;
+
+ gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
+ }
+
+ return TRUE;
+}
+
+static void
+entry_remove_timeout (gpointer data)
+{
+ g_source_remove (GPOINTER_TO_UINT (data));
+}
+
+static void
+entry_toggle_progress (GtkWidget *checkbutton,
+ GtkWidget *entry)
+{
+ if (GTK_TOGGLE_BUTTON (checkbutton)->active)
+ {
+ guint timeout = gdk_threads_add_timeout (100,
+ entry_progress_timeout,
+ entry);
+ g_object_set_data_full (G_OBJECT (entry), "timeout-id",
+ GUINT_TO_POINTER (timeout),
+ entry_remove_timeout);
+ }
+ else
+ {
+ g_object_set_data (G_OBJECT (entry), "timeout-id",
+ GUINT_TO_POINTER (0));
+
+ gtk_entry_set_progress_fraction (GTK_ENTRY (entry), 0.0);
+ }
+}
+
+static void
+entry_toggle_pulse (GtkWidget *checkbutton,
+ GtkWidget *entry)
+{
+ g_object_set_data (G_OBJECT (entry), "progress-pulse",
+ GINT_TO_POINTER (GTK_TOGGLE_BUTTON (checkbutton)->active));
+}
+
static void
entry_props_clicked (GtkWidget *button,
GObject *entry)
@@ -5211,6 +5270,7 @@
GtkWidget *hbox;
GtkWidget *has_frame_check;
GtkWidget *sensitive_check;
+ GtkWidget *progress_check;
GtkWidget *entry, *cb;
GtkWidget *button;
GtkWidget *separator;
@@ -5281,7 +5341,17 @@
g_signal_connect (has_frame_check, "toggled",
G_CALLBACK (entry_toggle_frame), entry);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
-
+
+ progress_check = gtk_check_button_new_with_label("Show Progress");
+ gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
+ g_signal_connect (progress_check, "toggled",
+ G_CALLBACK (entry_toggle_progress), entry);
+
+ progress_check = gtk_check_button_new_with_label("Pulse Progress");
+ gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
+ g_signal_connect (progress_check, "toggled",
+ G_CALLBACK (entry_toggle_pulse), entry);
+
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]