progress API
- From: Havoc Pennington <hp redhat com>
- To: gtk-devel-list redhat com
- Subject: progress API
- Date: 29 Mar 2000 15:22:12 -0500
Hi,
GtkProgress/GtkProgressBar have serious problems.
- Only 3 or 4 functions are really needed for 95% of progress
interfaces; GtkProgress[Bar] has about 25 functions, and
doesn't even include these 3 or 4. This means a steep
learning curve.
- In activity mode, the API involves setting the adjustment
to any random value, just to have the side effect of
calling the progress bar update function - the adjustment
is totally ignored in activity mode
- You set the activity step as a pixel value, which means to
set the activity step you basically need to connect to
size_allocate
- There are ctree_set_expander_style() functions, to randomly
change look-and-feel for no good reason
- The split between GtkProgress and GtkProgressBar makes no sense
to me whatsoever.
This is a big wart on GTK and makes people waste lots of time, both
learning and using the interface.
So, I have added what I feel is the correct API, and marked all the
rest deprecated. However, the changes are 100% backward-compatible and
should break no existing code.
New API:
void gtk_progress_bar_pulse (GtkProgressBar *pbar);
void gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
gfloat fraction);
void gtk_progress_bar_set_text (GtkProgressBar *pbar,
const gchar *text);
void gtk_progress_bar_set_pulse_frequency (GtkProgressBar *pbar,
gfloat fraction);
void gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
GtkProgressBarOrientation orientation);
Rationale:
- pulse() means "I have made progress but don't know how much."
Activity mode is entered, and if we're already in activity mode
the little block moves.
- set_fraction() means "I have between 0.0 and 1.0 of the task
finished" and automatically leaves activity mode.
- set_pulse_frequency() controls the fraction of distance each
pulse() moves the activity block; useful to tune the speed of
your progress bar
- set_text() sets any text you want, NOT a format string.
If you want a format, just do g_strdup_printf () or something,
then set the text. This way people don't have to worry about
escaping strings, and they can do custom formatting easily.
- set_orientation() seems pretty questionable to me (since a vertical
bar is probably not a progress bar, it's probably a range indicator
of some kind), but is a "why not" sort of thing. I'm willing
to take this out.
To know why this patch should go in GTK, just look at the current
GtkProgress/GtkProgressBar docs, and then imagine the same docs
fitting on a single, easy-to-understand page with this new API. Then
try to think of a progress-indication case where this new API is
insufficient or even particularly inconvenient. Can we say "gratuitous
complexity"?
Patch appended.
Havoc
Index: gtkprogress.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprogress.c,v
retrieving revision 1.8
diff -u -u -r1.8 gtkprogress.c
--- gtkprogress.c 2000/03/14 19:57:24 1.8
+++ gtkprogress.c 2000/03/29 20:10:46
@@ -196,6 +196,7 @@
progress->y_align = 0.5;
progress->show_text = FALSE;
progress->activity_mode = FALSE;
+ progress->use_text_format = TRUE;
}
static void
@@ -355,6 +356,13 @@
gchar fmt[10];
src = progress->format;
+
+ /* This is the new supported version of this function */
+ if (!progress->use_text_format)
+ return g_strdup (src);
+
+ /* And here's all the deprecated goo. */
+
dest = buf;
while (src && *src)
@@ -609,6 +617,10 @@
g_return_if_fail (progress != NULL);
g_return_if_fail (GTK_IS_PROGRESS (progress));
+ /* Turn on format, in case someone called
+ gtk_progress_bar_set_text() and turned it off. */
+ progress->use_text_format = TRUE;
+
if (format)
{
if (progress->format)
Index: gtkprogress.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprogress.h,v
retrieving revision 1.6
diff -u -u -r1.6 gtkprogress.h
--- gtkprogress.h 2000/03/14 19:57:24 1.6
+++ gtkprogress.h 2000/03/29 20:10:46
@@ -62,6 +62,7 @@
guint show_text : 1;
guint activity_mode : 1;
+ guint use_text_format : 1;
};
struct _GtkProgressClass
@@ -73,6 +74,9 @@
void (* act_mode_enter) (GtkProgress *progress);
};
+
+/* This entire interface is deprecated. Use GtkProgressBar
+ directly. */
GtkType gtk_progress_get_type (void);
void gtk_progress_set_show_text (GtkProgress *progress,
Index: gtkprogressbar.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprogressbar.c,v
retrieving revision 1.16
diff -u -u -r1.16 gtkprogressbar.c
--- gtkprogressbar.c 1999/02/24 07:35:55 1.16
+++ gtkprogressbar.c 2000/03/29 20:10:46
@@ -52,7 +52,9 @@
ARG_BAR_STYLE,
ARG_ACTIVITY_STEP,
ARG_ACTIVITY_BLOCKS,
- ARG_DISCRETE_BLOCKS
+ ARG_DISCRETE_BLOCKS,
+ ARG_FRACTION,
+ ARG_PULSE_FREQUENCY
};
static void gtk_progress_bar_class_init (GtkProgressBarClass *klass);
@@ -130,7 +132,15 @@
GTK_TYPE_UINT,
GTK_ARG_READWRITE,
ARG_DISCRETE_BLOCKS);
-
+ gtk_object_add_arg_type ("GtkProgressBar::fraction",
+ GTK_TYPE_FLOAT,
+ GTK_ARG_READWRITE,
+ ARG_FRACTION);
+ gtk_object_add_arg_type ("GtkProgressBar::pulse_frequency",
+ GTK_TYPE_FLOAT,
+ GTK_ARG_READWRITE,
+ ARG_FRACTION);
+
object_class->set_arg = gtk_progress_bar_set_arg;
object_class->get_arg = gtk_progress_bar_get_arg;
@@ -148,6 +158,7 @@
pbar->blocks = 10;
pbar->in_block = -1;
pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
+ pbar->pulse_fraction = 0.1;
pbar->activity_pos = 0;
pbar->activity_dir = 1;
pbar->activity_step = 3;
@@ -183,6 +194,12 @@
case ARG_DISCRETE_BLOCKS:
gtk_progress_bar_set_discrete_blocks (pbar, GTK_VALUE_UINT (*arg));
break;
+ case ARG_FRACTION:
+ gtk_progress_bar_set_fraction (pbar, GTK_VALUE_FLOAT (*arg));
+ break;
+ case ARG_PULSE_FREQUENCY:
+ gtk_progress_bar_set_pulse_frequency (pbar, GTK_VALUE_FLOAT (*arg));
+ break;
default:
break;
}
@@ -217,6 +234,12 @@
case ARG_DISCRETE_BLOCKS:
GTK_VALUE_UINT (*arg) = pbar->blocks;
break;
+ case ARG_FRACTION:
+ GTK_VALUE_FLOAT (*arg) = gtk_progress_get_current_percentage (GTK_PROGRESS (pbar));
+ break;
+ case ARG_PULSE_FREQUENCY:
+ GTK_VALUE_FLOAT (*arg) = pbar->pulse_fraction;
+ break;
default:
arg->type = GTK_TYPE_INVALID;
break;
@@ -266,12 +289,16 @@
if (GTK_PROGRESS (pbar)->activity_mode)
{
guint size;
-
+
/* advance the block */
if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
{
+ /* Update our activity step. */
+
+ pbar->activity_step = widget->allocation.width * pbar->pulse_fraction;
+
size = MAX (2, widget->allocation.width / pbar->activity_blocks);
if (pbar->activity_dir == 0)
@@ -298,6 +325,10 @@
}
else
{
+ /* Update our activity step. */
+
+ pbar->activity_step = widget->allocation.height * pbar->pulse_fraction;
+
size = MAX (2, widget->allocation.height / pbar->activity_blocks);
if (pbar->activity_dir == 0)
@@ -744,6 +775,67 @@
/*******************************************************************/
void
+gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
+ gfloat fraction)
+{
+ g_return_if_fail (pbar != NULL);
+ g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+ /* If we know the percentage, we don't want activity mode. */
+ gtk_progress_set_activity_mode (GTK_PROGRESS (pbar), FALSE);
+
+ /* We use the deprecated GtkProgress interface internally.
+ Once everything's been deprecated for a good long time,
+ we can clean up all this code. */
+ gtk_progress_set_percentage (GTK_PROGRESS (pbar), fraction);
+}
+
+void
+gtk_progress_bar_pulse (GtkProgressBar *pbar)
+{
+ g_return_if_fail (pbar != NULL);
+ g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+ /* If we don't know the percentage, we must want activity mode. */
+ gtk_progress_set_activity_mode (GTK_PROGRESS (pbar), TRUE);
+
+ /* Sigh. */
+ gtk_progress_bar_real_update (GTK_PROGRESS (pbar));
+}
+
+void
+gtk_progress_bar_set_text (GtkProgressBar *pbar,
+ const gchar *text)
+{
+ g_return_if_fail (pbar != NULL);
+ g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+ /* We don't support formats in this interface */
+ GTK_PROGRESS (pbar)->use_text_format = FALSE;
+
+ if (text && *text)
+ {
+ gtk_progress_set_show_text (GTK_PROGRESS (pbar), TRUE);
+ gtk_progress_set_format_string (GTK_PROGRESS (pbar), text);
+ }
+ else
+ {
+ gtk_progress_set_show_text (GTK_PROGRESS (pbar), FALSE);
+ gtk_progress_set_format_string (GTK_PROGRESS (pbar), "");
+ }
+}
+
+void
+gtk_progress_bar_set_pulse_frequency (GtkProgressBar *pbar,
+ gfloat fraction)
+{
+ g_return_if_fail (pbar != NULL);
+ g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+ pbar->pulse_fraction = fraction;
+}
+
+void
gtk_progress_bar_update (GtkProgressBar *pbar,
gfloat percentage)
{
@@ -752,7 +844,7 @@
/***********************************************************************
* Use of gtk_progress_bar_update() is deprecated ! *
- * Use gtk_progress_set_value or gtk_progress_set_percentage instead. *
+ * Use gtk_progress_bar_set_percentage ()
***********************************************************************/
gtk_progress_set_percentage (GTK_PROGRESS (pbar), percentage);
Index: gtkprogressbar.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprogressbar.h,v
retrieving revision 1.8
diff -u -u -r1.8 gtkprogressbar.h
--- gtkprogressbar.h 2000/02/13 08:16:47 1.8
+++ gtkprogressbar.h 2000/03/29 20:10:46
@@ -75,6 +75,9 @@
gint activity_pos;
guint activity_step;
guint activity_blocks;
+
+ gfloat pulse_fraction;
+
guint activity_dir : 1;
};
@@ -86,20 +89,37 @@
GtkType gtk_progress_bar_get_type (void);
GtkWidget* gtk_progress_bar_new (void);
+
+/* The progress API now has only these five supported functions, all
+ the rest is confusing, near-useless cruft and should be removed
+ from the docs.
+*/
+void gtk_progress_bar_pulse (GtkProgressBar *pbar);
+void gtk_progress_bar_set_text (GtkProgressBar *pbar,
+ const gchar *text);
+void gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
+ gfloat fraction);
+
+void gtk_progress_bar_set_pulse_frequency (GtkProgressBar *pbar,
+ gfloat fraction);
+void gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
+ GtkProgressBarOrientation orientation);
+
+/* Everything below here is deprecated */
GtkWidget* gtk_progress_bar_new_with_adjustment (GtkAdjustment *adjustment);
void gtk_progress_bar_set_bar_style (GtkProgressBar *pbar,
GtkProgressBarStyle style);
void gtk_progress_bar_set_discrete_blocks (GtkProgressBar *pbar,
guint blocks);
+/* set_activity_step() is not only deprecated, it doesn't even work.
+ (Of course, it wasn't usable anyway, you had to set it from a size_allocate
+ handler or something) */
void gtk_progress_bar_set_activity_step (GtkProgressBar *pbar,
guint step);
void gtk_progress_bar_set_activity_blocks (GtkProgressBar *pbar,
guint blocks);
-void gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
- GtkProgressBarOrientation orientation);
void gtk_progress_bar_update (GtkProgressBar *pbar,
gfloat percentage);
-
#ifdef __cplusplus
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]