]> Pileus Git - ~andy/gtk/commitdiff
Introduced generic GtkProgress widget. Derived GtkProgressBar from
authorStefan Jeske <stefan@gtk.org>
Sun, 19 Jul 1998 10:35:39 +0000 (10:35 +0000)
committerStefan Jeske <stefan@src.gnome.org>
Sun, 19 Jul 1998 10:35:39 +0000 (10:35 +0000)
Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>

* gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
  gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
Introduced generic GtkProgress widget. Derived GtkProgressBar from
GtkProgress. Made GtkProgressBar much more flexible (see testgtk).

16 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/Makefile.am
gtk/gtk.h
gtk/gtkprogress.c [new file with mode: 0644]
gtk/gtkprogress.h [new file with mode: 0644]
gtk/gtkprogressbar.c
gtk/gtkprogressbar.h
gtk/gtkviewport.c
gtk/testgtk.c
tests/testgtk.c

index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index 93ef3ed9592a68c438e833fb4499a6339570b19a..5cdb41694e7c8acd51b2fe9e36ae676346382cb0 100644 (file)
@@ -1,3 +1,10 @@
+Sun Jul 19 12:19:16 1998  Stefan Jeske  <stefan@gtk.org>
+
+       * gtk/gtkprogress.c gtk/gtkprogress.h gtk/gtkprogressbar.c
+         gtk/gtkprogressbar.h gtk/Makefile.am gtk/gtk.h gtk/testgtk.c:
+       Introduced generic GtkProgress widget. Derived GtkProgressBar from
+       GtkProgress. Made GtkProgressBar much more flexible (see testgtk).
+
 Fri Jul 17 23:49:28 PDT 1998 Manish Singh <yosh@gimp.org>
 
        * gtk/gtktypeutils.h
index ce64ef32c0695b4489e59f13dc10d1914f517f88..0872ea1724a512f0de5f08f9aa54a4e12372d229 100644 (file)
@@ -67,6 +67,7 @@ libgtk_1_1_la_SOURCES = \
        gtkpaned.c              \
        gtkpixmap.c             \
        gtkpreview.c            \
+       gtkprogress.c           \
        gtkprogressbar.c        \
        gtkradiobutton.c        \
        gtkradiomenuitem.c      \
@@ -172,6 +173,7 @@ gtkinclude_HEADERS = \
        gtkpixmap.h             \
        gtkpreview.h            \
        gtkprivate.h            \
+       gtkprogress.h           \
        gtkprogressbar.h        \
        gtkradiobutton.h        \
        gtkradiomenuitem.h      \
index 9720591457abd14066110401691e638540772d92..7eb797f3f88275089c0e7db8054dde83feb5e385 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -84,6 +84,7 @@
 #include <gtk/gtkpaned.h>
 #include <gtk/gtkpixmap.h>
 #include <gtk/gtkpreview.h>
+#include <gtk/gtkprogress.h>
 #include <gtk/gtkprogressbar.h>
 #include <gtk/gtkradiobutton.h>
 #include <gtk/gtkradiomenuitem.h>
diff --git a/gtk/gtkprogress.c b/gtk/gtkprogress.c
new file mode 100644 (file)
index 0000000..7f5cde4
--- /dev/null
@@ -0,0 +1,540 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "gtkprogress.h" 
+#include "gtksignal.h"
+
+#define EPSILON  1e-5
+
+static void gtk_progress_class_init      (GtkProgressClass *klass);
+static void gtk_progress_init            (GtkProgress      *progress);
+static void gtk_progress_finalize        (GtkObject        *object);
+static void gtk_progress_realize         (GtkWidget        *widget);
+static gint gtk_progress_expose          (GtkWidget        *widget,
+                                         GdkEventExpose   *event);
+static void gtk_progress_size_allocate   (GtkWidget        *widget,
+                                         GtkAllocation    *allocation);
+static void gtk_progress_create_pixmap   (GtkProgress      *progress);
+
+
+static GtkWidgetClass *parent_class = NULL;
+
+
+guint
+gtk_progress_get_type (void)
+{
+  static guint progress_type = 0;
+
+  if (!progress_type)
+    {
+      GtkTypeInfo progress_info =
+      {
+       "GtkProgress",
+       sizeof (GtkProgress),
+       sizeof (GtkProgressClass),
+       (GtkClassInitFunc) gtk_progress_class_init,
+       (GtkObjectInitFunc) gtk_progress_init,
+        /* reserved_1 */ NULL,
+        /* reserved_2 */ NULL,
+        (GtkClassInitFunc) NULL
+      };
+
+      progress_type = gtk_type_unique (gtk_widget_get_type (), &progress_info);
+    }
+
+  return progress_type;
+}
+
+static void
+gtk_progress_class_init (GtkProgressClass *class)
+{
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass *) class;
+  widget_class = (GtkWidgetClass *) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  object_class->finalize = gtk_progress_finalize;
+
+  widget_class->realize = gtk_progress_realize;
+  widget_class->expose_event = gtk_progress_expose;
+  widget_class->size_allocate = gtk_progress_size_allocate;
+
+  /* to be overridden */
+  class->paint = NULL;
+  class->update = NULL;
+  class->act_mode_enter = NULL;
+}
+
+static void
+gtk_progress_init (GtkProgress *progress)
+{
+  GTK_WIDGET_SET_FLAGS (progress, GTK_BASIC);
+
+  progress->offscreen_pixmap = NULL;
+  progress->format = g_strdup ("%P %%");
+  progress->x_align = 0.5;
+  progress->y_align = 0.5;
+  progress->show_text = FALSE;
+  progress->activity_mode = FALSE;
+}
+
+static void
+gtk_progress_realize (GtkWidget *widget)
+{
+  GtkProgress *progress;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (widget));
+
+  progress = GTK_PROGRESS (widget);
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+  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_OUTPUT;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
+  attributes.event_mask = gtk_widget_get_events (widget);
+  attributes.event_mask |= GDK_EXPOSURE_MASK;
+
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+                                  &attributes, attributes_mask);
+  gdk_window_set_user_data (widget->window, progress);
+
+  widget->style = gtk_style_attach (widget->style, widget->window);
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+
+  gtk_progress_create_pixmap (progress);
+}
+
+static void
+gtk_progress_finalize (GtkObject *object)
+{
+  GtkProgress *progress;
+
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (object));
+
+  progress = GTK_PROGRESS (object);
+
+  if (progress->offscreen_pixmap)
+    gdk_pixmap_unref (progress->offscreen_pixmap);
+
+  if (progress->format)
+    g_free (progress->format);
+
+  GTK_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static gint
+gtk_progress_expose (GtkWidget      *widget,
+                    GdkEventExpose *event)
+{
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PROGRESS (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+
+  if (GTK_WIDGET_DRAWABLE (widget))
+    gdk_draw_pixmap (widget->window,
+                    widget->style->black_gc,
+                    GTK_PROGRESS (widget)->offscreen_pixmap,
+                    event->area.x, event->area.y,
+                    event->area.x, event->area.y,
+                    event->area.width,
+                    event->area.height);
+
+  return FALSE;
+}
+
+static void
+gtk_progress_size_allocate (GtkWidget     *widget,
+                           GtkAllocation *allocation)
+{
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (widget));
+  g_return_if_fail (allocation != NULL);
+
+  widget->allocation = *allocation;
+
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+      gtk_progress_create_pixmap (GTK_PROGRESS (widget));
+    }
+}
+
+static void
+gtk_progress_create_pixmap (GtkProgress *progress)
+{
+  GtkWidget *widget;
+
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (GTK_WIDGET_REALIZED (progress))
+    {
+      widget = GTK_WIDGET (progress);
+
+      if (progress->offscreen_pixmap)
+       gdk_pixmap_unref (progress->offscreen_pixmap);
+
+      progress->offscreen_pixmap = gdk_pixmap_new (widget->window,
+                                                  widget->allocation.width,
+                                                  widget->allocation.height,
+                                                  -1);
+      GTK_PROGRESS_CLASS (GTK_OBJECT (progress)->klass)->paint (progress);
+    }
+}
+
+static void
+gtk_progress_value_changed (GtkAdjustment *adjustment,
+                           GtkProgress   *progress)
+{
+  GTK_PROGRESS_CLASS (GTK_OBJECT (progress)->klass)->update (progress);
+}
+
+static gchar *
+gtk_progress_build_string (GtkProgress *progress,
+                          gfloat       value,
+                          gfloat       percentage)
+{
+  gchar buf[256] = { 0 };
+  gchar tmp[256] = { 0 };
+  gchar *src;
+  gchar *dest;
+  gchar fmt[10];
+
+  src = progress->format;
+  dest = buf;
+  while (src && *src)
+    {
+      if (*src != '%')
+       {
+         *dest = *src;
+         dest++;
+       }
+      else
+       {
+         gchar c;
+         gint digits;
+
+         c = *(src + sizeof(gchar));
+         digits = 0;
+
+         if (c >= '0' && c <= '2')
+           {
+             digits = (gint) (c - '0');
+             src++;
+             c = *(src + sizeof(gchar));
+           }
+
+         switch (c)
+           {
+           case '%':
+             *dest = '%';
+             src++;
+             dest++;
+             break;
+           case 'p':
+           case 'P':
+             if (digits)
+               {
+                 sprintf (fmt, "%%.%df", digits);
+                 sprintf (tmp, fmt, 100 * percentage);
+               }
+             else
+               sprintf (tmp, "%.0f", 100 * percentage);
+             strcat (buf, tmp);
+             dest = &(buf[strlen (buf)]);
+             src++;
+             break;
+           case 'v':
+           case 'V':
+             if (digits)
+               {
+                 sprintf (fmt, "%%.%df", digits);
+                 sprintf (tmp, fmt, value);
+               }
+             else
+               sprintf (tmp, "%.0f", value);
+             strcat (buf, tmp);
+             dest = &(buf[strlen (buf)]);
+             src++;
+             break;
+           case 'l':
+           case 'L':
+             if (digits)
+               {
+                 sprintf (fmt, "%%.%df", digits);
+                 sprintf (tmp, fmt, progress->adjustment->lower);
+               }
+             else
+               sprintf (tmp, "%.0f", progress->adjustment->lower);
+             strcat (buf, tmp);
+             dest = &(buf[strlen (buf)]);
+             src++;
+             break;
+           case 'u':
+           case 'U':
+             if (digits)
+               {
+                 sprintf (fmt, "%%.%df", digits);
+                 sprintf (tmp, fmt, progress->adjustment->upper);
+               }
+             else
+               sprintf (tmp, "%.0f", progress->adjustment->upper);
+             strcat (buf, tmp);
+             dest = &(buf[strlen (buf)]);
+             src++;
+             break;
+           default:
+             break;
+           }
+       }
+      src++;
+    }
+
+  return g_strdup (buf);
+}
+
+/***************************************************************/
+
+void
+gtk_progress_set_adjustment (GtkProgress   *progress,
+                            GtkAdjustment *adjustment)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (progress->adjustment != adjustment)
+    {
+      if (progress->adjustment)
+        {
+          gtk_signal_disconnect_by_data (GTK_OBJECT (progress->adjustment),
+                                         (gpointer) progress);
+          gtk_object_unref (GTK_OBJECT (progress->adjustment));
+        }
+      progress->adjustment = adjustment;
+      if (adjustment)
+        {
+          gtk_object_ref (GTK_OBJECT (adjustment));
+         gtk_object_sink (GTK_OBJECT (adjustment));
+          gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                             (GtkSignalFunc) gtk_progress_value_changed,
+                             (gpointer) progress);
+        }
+    }
+}
+
+void
+gtk_progress_reconfigure (GtkProgress *progress,
+                         gfloat value,
+                         gfloat min,
+                         gfloat max)
+{
+  GtkAdjustment *adj;
+  gboolean changed = FALSE;
+
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+  g_return_if_fail (min <= max);
+  g_return_if_fail (value >= min && value <= max);
+
+  adj = progress->adjustment;
+
+  if (fabs (adj->lower - min) > EPSILON || fabs (adj->upper - max) > EPSILON)
+    changed = TRUE;
+
+  adj->value = value;
+  adj->lower = min;
+  adj->upper = max;
+
+  gtk_signal_emit_by_name (GTK_OBJECT (adj), "value_changed");
+  if (changed)
+    gtk_signal_emit_by_name (GTK_OBJECT (progress->adjustment), "changed");
+}
+
+void
+gtk_progress_set_percentage (GtkProgress *progress,
+                            gfloat       percentage)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+  g_return_if_fail (percentage >= 0 && percentage <= 1.0);
+
+  gtk_progress_set_value (progress, progress->adjustment->lower + percentage * 
+                (progress->adjustment->upper - progress->adjustment->lower));
+}
+
+gfloat
+gtk_progress_get_current_percentage (GtkProgress *progress)
+{
+  g_return_val_if_fail (progress != NULL, 0);
+  g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
+
+  return (progress->adjustment->value - progress->adjustment->lower) /
+    (progress->adjustment->upper - progress->adjustment->lower);
+}
+
+gfloat
+gtk_progress_get_percentage_from_value (GtkProgress *progress,
+                                       gfloat       value)
+{
+  g_return_val_if_fail (progress != NULL, 0);
+  g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
+
+  if (value >= progress->adjustment->lower &&
+      value <= progress->adjustment->upper)
+    return (value - progress->adjustment->lower) /
+      (progress->adjustment->upper - progress->adjustment->lower);
+  else
+    return 0.0;
+}
+
+void
+gtk_progress_set_value (GtkProgress *progress,
+                       gfloat       value)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (fabs (progress->adjustment->value - value) > EPSILON)
+    gtk_adjustment_set_value (progress->adjustment, value);
+}
+
+gfloat
+gtk_progress_get_value (GtkProgress *progress)
+{
+  g_return_val_if_fail (progress != NULL, 0);
+  g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
+
+  return progress->adjustment->value;
+}
+
+void
+gtk_progress_set_show_text (GtkProgress *progress,
+                           gint        show_text)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (progress->show_text != show_text)
+    {
+      progress->show_text = show_text;
+
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
+       gtk_widget_queue_resize (GTK_WIDGET (progress));
+    }
+}
+
+void
+gtk_progress_set_text_alignment (GtkProgress *progress,
+                                gfloat       x_align,
+                                gfloat       y_align)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+  g_return_if_fail (x_align >= 0.0 && x_align <= 1.0);
+  g_return_if_fail (y_align >= 0.0 && y_align <= 1.0);
+
+  if (progress->x_align != x_align || progress->y_align != y_align)
+    {
+      progress->x_align = x_align;
+      progress->y_align = y_align;
+
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
+       gtk_widget_queue_resize (GTK_WIDGET (progress));
+    }
+}
+
+void
+gtk_progress_set_format_string (GtkProgress *progress,
+                               gchar       *format)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (format)
+    {
+      if (progress->format)
+       g_free (progress->format);
+      progress->format = g_strdup (format);
+
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
+       gtk_widget_queue_resize (GTK_WIDGET (progress));
+    }
+}
+
+gchar *
+gtk_progress_get_current_text (GtkProgress *progress)
+{
+  g_return_val_if_fail (progress != NULL, 0);
+  g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
+
+  return gtk_progress_build_string (progress, progress->adjustment->value,
+                   gtk_progress_get_current_percentage (progress));
+}
+
+gchar *
+gtk_progress_get_text_from_value (GtkProgress *progress,
+                                 gfloat       value)
+{
+  g_return_val_if_fail (progress != NULL, 0);
+  g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
+
+  return gtk_progress_build_string (progress, value,
+                   gtk_progress_get_percentage_from_value (progress, value));
+}
+
+void
+gtk_progress_set_activity_mode (GtkProgress *progress,
+                               guint        activity_mode)
+{
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  if (progress->activity_mode != (activity_mode != 0))
+    {
+      progress->activity_mode = (activity_mode != 0);
+
+      if (progress->activity_mode)
+       GTK_PROGRESS_CLASS 
+         (GTK_OBJECT (progress)->klass)->act_mode_enter (progress);
+
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
+       gtk_widget_queue_resize (GTK_WIDGET (progress));
+    }
+}
diff --git a/gtk/gtkprogress.h b/gtk/gtkprogress.h
new file mode 100644 (file)
index 0000000..7deaeea
--- /dev/null
@@ -0,0 +1,101 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_PROGRESS_H__
+#define __GTK_PROGRESS_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkadjustment.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_PROGRESS(obj)          GTK_CHECK_CAST (obj, gtk_progress_get_type (), GtkProgress)
+#define GTK_PROGRESS_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_progress_get_type (), GtkProgressClass)
+#define GTK_IS_PROGRESS(obj)       GTK_CHECK_TYPE (obj, gtk_progress_get_type ())
+
+
+typedef struct _GtkProgress       GtkProgress;
+typedef struct _GtkProgressClass  GtkProgressClass;
+
+
+struct _GtkProgress
+{
+  GtkWidget widget;
+
+  GtkAdjustment *adjustment;
+  GdkPixmap     *offscreen_pixmap;
+  gchar         *format;
+  gfloat         x_align;
+  gfloat         y_align;
+
+  guint          show_text : 1;
+  guint          activity_mode : 1;
+};
+
+struct _GtkProgressClass
+{
+  GtkWidgetClass parent_class;
+
+  void (* paint)            (GtkProgress *progress);
+  void (* update)           (GtkProgress *progress);
+  void (* act_mode_enter)   (GtkProgress *progress);
+};
+
+
+guint      gtk_progress_get_type            (void);
+void       gtk_progress_set_show_text       (GtkProgress   *progress,
+                                            gint           show_text);
+void       gtk_progress_set_text_alignment  (GtkProgress   *progress,
+                                            gfloat         x_align,
+                                            gfloat         y_align);
+void       gtk_progress_set_format_string   (GtkProgress   *progress,
+                                            gchar         *format);
+void       gtk_progress_set_adjustment      (GtkProgress   *progress,
+                                            GtkAdjustment *adjustment);
+void       gtk_progress_reconfigure         (GtkProgress   *progress,
+                                            gfloat         value,
+                                            gfloat         min,
+                                            gfloat         max);
+void       gtk_progress_set_percentage      (GtkProgress   *progress,
+                                            gfloat         percentage);
+void       gtk_progress_set_value           (GtkProgress   *progress,
+                                            gfloat         value);
+gfloat     gtk_progress_get_value           (GtkProgress   *progress);
+void       gtk_progress_set_activity_mode   (GtkProgress   *progress,
+                                            guint          activity_mode);
+gchar *    gtk_progress_get_current_text    (GtkProgress   *progress);
+gchar *    gtk_progress_get_text_from_value (GtkProgress   *progress,
+                                            gfloat         value);
+gfloat     gtk_progress_get_current_percentage (GtkProgress *progress);
+gfloat     gtk_progress_get_percentage_from_value (GtkProgress *progress,
+                                                  gfloat       value);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PROGRESS_H__ */
index c82ed8f0968b4e92fe37ad86b01d58b8030c80c9..f00e51e58cc042ec43e6fc08be203827090f4b41 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+#include <stdio.h>
 #include "gtkprogressbar.h"
+#include "gtksignal.h"
 
 
-#define MIN_WIDTH   200
-#define MIN_HEIGHT  20
+#define MIN_HORIZONTAL_BAR_WIDTH   150
+#define MIN_HORIZONTAL_BAR_HEIGHT  20
+#define MIN_VERTICAL_BAR_WIDTH     22
+#define MIN_VERTICAL_BAR_HEIGHT    80
+#define MAX_TEXT_LENGTH            80
+#define TEXT_SPACING               2
 
 
 static void gtk_progress_bar_class_init    (GtkProgressBarClass *klass);
 static void gtk_progress_bar_init          (GtkProgressBar      *pbar);
-static void gtk_progress_bar_realize       (GtkWidget           *widget);
-static void gtk_progress_bar_size_allocate (GtkWidget           *widget,
-                                           GtkAllocation       *allocation);
-static gint gtk_progress_bar_expose        (GtkWidget           *widget,
-                                           GdkEventExpose      *event);
-static void gtk_progress_bar_make_pixmap   (GtkProgressBar      *pbar);
-static void gtk_progress_bar_paint         (GtkProgressBar      *pbar);
+static void gtk_progress_bar_size_request  (GtkWidget           *widget,
+                                           GtkRequisition      *requisition);
+static void gtk_progress_bar_real_update   (GtkProgress         *progress);
+static void gtk_progress_bar_paint         (GtkProgress         *progress);
+static void gtk_progress_bar_act_mode_enter (GtkProgress        *progress);
 
 
 guint
@@ -48,12 +53,13 @@ gtk_progress_bar_get_type (void)
        sizeof (GtkProgressBarClass),
        (GtkClassInitFunc) gtk_progress_bar_class_init,
        (GtkObjectInitFunc) gtk_progress_bar_init,
-       /* reserved_1 */ NULL,
+        /* reserved_1 */ NULL,
         /* reserved_2 */ NULL,
-        (GtkClassInitFunc) NULL,
+        (GtkClassInitFunc) NULL
       };
 
-      progress_bar_type = gtk_type_unique (gtk_widget_get_type (), &progress_bar_info);
+      progress_bar_type = gtk_type_unique (gtk_progress_get_type (),
+                                          &progress_bar_info);
     }
 
   return progress_bar_type;
@@ -63,12 +69,16 @@ static void
 gtk_progress_bar_class_init (GtkProgressBarClass *class)
 {
   GtkWidgetClass *widget_class;
+  GtkProgressClass *progress_class;
+
+  widget_class = (GtkWidgetClass *) class;
+  progress_class = (GtkProgressClass *) class;
 
-  widget_class = (GtkWidgetClass*) class;
+  widget_class->size_request = gtk_progress_bar_size_request;
 
-  widget_class->realize = gtk_progress_bar_realize;
-  widget_class->size_allocate = gtk_progress_bar_size_allocate;
-  widget_class->expose_event = gtk_progress_bar_expose;
+  progress_class->paint = gtk_progress_bar_paint;
+  progress_class->update = gtk_progress_bar_real_update;
+  progress_class->act_mode_enter = gtk_progress_bar_act_mode_enter;
 }
 
 static void
@@ -76,187 +86,707 @@ gtk_progress_bar_init (GtkProgressBar *pbar)
 {
   GTK_WIDGET_SET_FLAGS (pbar, GTK_BASIC);
 
-  GTK_WIDGET (pbar)->requisition.width = MIN_WIDTH;
-  GTK_WIDGET (pbar)->requisition.height = MIN_HEIGHT;
-  pbar->offscreen_pixmap = NULL;
-  pbar->percentage = 0;
+  pbar->bar_style = GTK_PROGRESS_CONTINUOUS;
+  pbar->blocks = 10;
+  pbar->in_block = -1;
+  pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
+  pbar->activity_pos = 0;
+  pbar->activity_dir = 1;
+  pbar->activity_step = 3;
 }
 
 
-GtkWidget*
+GtkWidget *
 gtk_progress_bar_new (void)
 {
-  return GTK_WIDGET (gtk_type_new (gtk_progress_bar_get_type ()));
+  GtkProgressBar *pbar;
+
+  pbar = gtk_type_new (gtk_progress_bar_get_type ());
+
+  gtk_progress_bar_construct (pbar, NULL);
+
+  return GTK_WIDGET (pbar);
+}
+
+GtkWidget *
+gtk_progress_bar_new_with_adjustment (GtkAdjustment *adjustment)
+{
+  GtkProgressBar *pbar;
+
+  pbar = gtk_type_new (gtk_progress_bar_get_type ());
+
+  gtk_progress_bar_construct (pbar, adjustment);
+
+  return GTK_WIDGET (pbar);
 }
 
 void
-gtk_progress_bar_update (GtkProgressBar *pbar,
-                        gfloat          percentage)
+gtk_progress_bar_construct (GtkProgressBar *pbar,
+                           GtkAdjustment  *adjustment)
 {
   g_return_if_fail (pbar != NULL);
   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
 
-  if (percentage < 0.0)
-    percentage = 0.0;
-  else if (percentage > 1.0)
-    percentage = 1.0;
+  if (!adjustment)
+    adjustment = (GtkAdjustment *) gtk_adjustment_new (0, 0, 100, 0, 0, 0);
 
-  if (pbar->percentage != percentage)
+  gtk_progress_set_adjustment (GTK_PROGRESS (pbar), adjustment);
+}
+
+static void
+gtk_progress_bar_real_update (GtkProgress *progress)
+{
+  GtkProgressBar *pbar;
+  GtkWidget *widget;
+
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS (progress));
+
+  pbar = GTK_PROGRESS_BAR (progress);
+  widget = GTK_WIDGET (progress);
+  if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS ||
+      GTK_PROGRESS (pbar)->activity_mode)
     {
-      pbar->percentage = percentage;
-      gtk_progress_bar_paint (pbar);
-      gtk_widget_queue_draw (GTK_WIDGET (pbar));
+      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)
+           {
+             size = widget->allocation.height - 
+               widget->style->klass->ythickness * 2;
+
+             if (pbar->activity_dir == 0)
+               {
+                 pbar->activity_pos += pbar->activity_step;
+                 if (pbar->activity_pos + size >=
+                     widget->allocation.width -
+                     widget->style->klass->xthickness)
+                   {
+                     pbar->activity_pos = widget->allocation.width -
+                       widget->style->klass->xthickness - size;
+                     pbar->activity_dir = 1;
+                   }
+               }
+             else
+               {
+                 pbar->activity_pos -= pbar->activity_step;
+                 if (pbar->activity_pos <= widget->style->klass->xthickness)
+                   {
+                     pbar->activity_pos = widget->style->klass->xthickness;
+                     pbar->activity_dir = 0;
+                   }
+               }
+           }
+         else
+           {
+             size = widget->allocation.width - 
+               widget->style->klass->xthickness * 2;
+
+             if (pbar->activity_dir == 0)
+               {
+                 pbar->activity_pos += pbar->activity_step;
+                 if (pbar->activity_pos + size >=
+                     widget->allocation.height -
+                     widget->style->klass->ythickness)
+                   {
+                     pbar->activity_pos = widget->allocation.height -
+                       widget->style->klass->ythickness - size;
+                     pbar->activity_dir = 1;
+                   }
+               }
+             else
+               {
+                 pbar->activity_pos -= pbar->activity_step;
+                 if (pbar->activity_pos <= widget->style->klass->ythickness)
+                   {
+                     pbar->activity_pos = widget->style->klass->ythickness;
+                     pbar->activity_dir = 0;
+                   }
+               }
+           }
+       }
+      gtk_progress_bar_paint (progress);
+      gtk_widget_queue_draw (GTK_WIDGET (progress));
+    }
+  else
+    {
+      gint in_block;
+      
+      in_block = -1 + (gint)(gtk_progress_get_current_percentage (progress) *
+                            (gfloat)pbar->blocks);
+      
+      if (pbar->in_block != in_block)
+       {
+         pbar->in_block = in_block;
+         gtk_progress_bar_paint (progress);
+         gtk_widget_queue_draw (GTK_WIDGET (progress));
+       }
     }
 }
 
 static void
-gtk_progress_bar_realize (GtkWidget *widget)
+gtk_progress_bar_size_request (GtkWidget      *widget,
+                              GtkRequisition *requisition)
 {
+  GtkProgress *progress;
   GtkProgressBar *pbar;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
+  gchar *buf;
 
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
+  g_return_if_fail (requisition != NULL);
 
+  progress = GTK_PROGRESS (widget);
   pbar = GTK_PROGRESS_BAR (widget);
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
-  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_OUTPUT;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
-  attributes.event_mask = gtk_widget_get_events (widget);
-  attributes.event_mask |= GDK_EXPOSURE_MASK;
+  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
+      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+    {
+      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
+       {
+         buf = gtk_progress_get_text_from_value (progress,
+                                                 progress->adjustment->upper);
+
+         requisition->width = MAX (MIN_HORIZONTAL_BAR_WIDTH,
+                                   2 * widget->style->klass->xthickness + 3 +
+                                   gdk_text_width (widget->style->font, 
+                                                   buf, strlen (buf)) +
+                                   2 * TEXT_SPACING);
+
+         requisition->height = MAX (MIN_HORIZONTAL_BAR_HEIGHT,
+                                    2 * widget->style->klass->ythickness + 3 +
+                                    gdk_text_height (widget->style->font, 
+                                                     buf, strlen (buf)) +
+                                    2 * TEXT_SPACING);
+         g_free (buf);
+       }
+      else
+       {
+         requisition->width = MIN_HORIZONTAL_BAR_WIDTH;
+         requisition->height = MIN_HORIZONTAL_BAR_HEIGHT;
+       }
+    }
+  else
+    {
+      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
+       {         
+         buf = gtk_progress_get_text_from_value (progress,
+                                                 progress->adjustment->upper);
+
+         requisition->width = MAX (MIN_VERTICAL_BAR_WIDTH,
+                                   2 * widget->style->klass->xthickness + 3 +
+                                   gdk_text_width (widget->style->font, 
+                                                   buf, strlen (buf)) +
+                                   2 * TEXT_SPACING);
+
+         requisition->height = MAX (MIN_VERTICAL_BAR_HEIGHT,
+                                    2 * widget->style->klass->ythickness + 3 +
+                                    gdk_text_height (widget->style->font, 
+                                                     buf, strlen (buf)) +
+                                    2 * TEXT_SPACING);
+         g_free (buf);
+       }
+      else
+       {
+         requisition->width = MIN_VERTICAL_BAR_WIDTH;
+         requisition->height = MIN_VERTICAL_BAR_HEIGHT;
+       }
+    }
+}
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+static void
+gtk_progress_bar_act_mode_enter (GtkProgress *progress)
+{
+  GtkProgressBar *pbar;
+  GtkWidget *widget;
 
-  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
-  gdk_window_set_user_data (widget->window, pbar);
+  pbar = GTK_PROGRESS_BAR (progress);
+  widget = GTK_WIDGET (progress);
 
-  widget->style = gtk_style_attach (widget->style, widget->window);
-  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+  /* calculate start pos */
 
-  gtk_progress_bar_make_pixmap (pbar);
+  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
+      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+    {
+      if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
+       {
+         pbar->activity_pos = widget->style->klass->xthickness;
+         pbar->activity_dir = 0;
+       }
+      else
+       {
+         pbar->activity_pos = widget->allocation.width - 
+           widget->style->klass->xthickness - (widget->allocation.height - 
+               widget->style->klass->ythickness * 2);
+         pbar->activity_dir = 1;
+       }
+    }
+  else
+    {
+      if (pbar->orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
+       {
+         pbar->activity_pos = widget->style->klass->ythickness;
+         pbar->activity_dir = 0;
+       }
+      else
+       {
+         pbar->activity_pos = widget->allocation.height -
+           widget->style->klass->ythickness - (widget->allocation.width - 
+               widget->style->klass->xthickness * 2);
+         pbar->activity_dir = 1;
+       }
+    }
 }
 
 static void
-gtk_progress_bar_size_allocate (GtkWidget     *widget,
-                               GtkAllocation *allocation)
+gtk_progress_bar_paint (GtkProgress *progress)
 {
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
-  g_return_if_fail (allocation != NULL);
+  GtkProgressBar *pbar;
+  GtkWidget *widget;
+  gint amount;
+  gint block_delta = 0;
+  gint space = 0;
+  gint i;
+  gint x;
+  gint y;
+  gfloat percentage;
+
+  g_return_if_fail (progress != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (progress));
+
+  pbar = GTK_PROGRESS_BAR (progress);
+  widget = GTK_WIDGET (progress);
+
+  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
+      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+    space = widget->allocation.width -
+      2 * widget->style->klass->xthickness;
+  else
+    space = widget->allocation.height -
+      2 * widget->style->klass->ythickness;
+
+  percentage = gtk_progress_get_current_percentage (progress);
+
+  if (progress->offscreen_pixmap)
+    {
+      gtk_draw_shadow (widget->style,
+                      progress->offscreen_pixmap,
+                      GTK_STATE_NORMAL, GTK_SHADOW_IN, 0, 0,
+                      widget->allocation.width,
+                      widget->allocation.height);
+         
+      gdk_draw_rectangle (progress->offscreen_pixmap,
+                         widget->style->bg_gc[GTK_STATE_ACTIVE], TRUE,
+                         widget->style->klass->xthickness,
+                         widget->style->klass->ythickness,
+                         widget->allocation.width -
+                         widget->style->klass->xthickness * 2,
+                         widget->allocation.height -
+                         widget->style->klass->ythickness * 2);
 
-  widget->allocation = *allocation;
+      if (progress->activity_mode)
+       {
+         if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
+             pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
+           {
+             gdk_draw_rectangle (progress->offscreen_pixmap,
+                                 widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                 TRUE,
+                                 pbar->activity_pos,
+                                 widget->style->klass->ythickness,
+                                 widget->allocation.height - 
+                                 widget->style->klass->ythickness * 2,
+                                 widget->allocation.height - 
+                                 widget->style->klass->ythickness * 2);
+             
+             gtk_draw_shadow (widget->style,
+                              progress->offscreen_pixmap,
+                              GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                              pbar->activity_pos,
+                              widget->style->klass->ythickness,
+                              widget->allocation.height - 
+                              widget->style->klass->ythickness * 2,
+                              widget->allocation.height -
+                              widget->style->klass->ythickness * 2);
+             return;
+           }
+         else
+           {
+             gdk_draw_rectangle (progress->offscreen_pixmap,
+                                 widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                 TRUE,
+                                 widget->style->klass->xthickness,
+                                 pbar->activity_pos,
+                                 widget->allocation.width - 
+                                 widget->style->klass->xthickness * 2,
+                                 widget->allocation.width - 
+                                 widget->style->klass->xthickness * 2);
+             
+             gtk_draw_shadow (widget->style,
+                              progress->offscreen_pixmap,
+                              GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                              widget->style->klass->xthickness,
+                              pbar->activity_pos,
+                              widget->allocation.width -
+                              widget->style->klass->xthickness * 2,
+                              widget->allocation.width - 
+                              widget->style->klass->xthickness * 2);
+             return;
+           }
+       }
 
-  if (GTK_WIDGET_REALIZED (widget))
-    {
-      gdk_window_move_resize (widget->window,
-                             allocation->x, allocation->y,
-                             allocation->width, allocation->height);
+      amount = percentage * space;
+      
+      if (amount > 0)
+       {
+         switch (pbar->orientation)
+           {
+             
+           case GTK_PROGRESS_LEFT_TO_RIGHT:
+             
+             if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
+               {
+                 gdk_draw_rectangle (progress->offscreen_pixmap,
+                                     widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                     TRUE,
+                                     widget->style->klass->xthickness,
+                                     widget->style->klass->ythickness,
+                                     amount,
+                                     widget->allocation.height - 
+                                     widget->style->klass->ythickness * 2);
+                 gtk_draw_shadow (widget->style,
+                                  progress->offscreen_pixmap,
+                                  GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                  widget->style->klass->xthickness,
+                                  widget->style->klass->ythickness,
+                                  amount,
+                                  widget->allocation.height -
+                                  widget->style->klass->ythickness * 2);
+               }
+             else
+               {
+                 x = widget->style->klass->xthickness;
+                 
+                 for (i = 0; i <= pbar->in_block; i++)
+                   {
+                     block_delta = (((i + 1) * space) / pbar->blocks)
+                       - ((i * space) / pbar->blocks);
+                     
+                     gdk_draw_rectangle 
+                       (progress->offscreen_pixmap,
+                        widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                        TRUE,
+                        x,
+                        widget->style->klass->ythickness,
+                        block_delta,
+                        widget->allocation.height - 
+                        widget->style->klass->ythickness * 2);
+
+                     gtk_draw_shadow (widget->style,
+                                      progress->offscreen_pixmap,
+                                      GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                      x,
+                                      widget->style->klass->ythickness,
+                                      block_delta,
+                                      widget->allocation.height -
+                                      widget->style->klass->ythickness * 2);
+
+                     x +=  block_delta;
+                   }
+               }
+             break;
+
+           case GTK_PROGRESS_RIGHT_TO_LEFT:
+
+             if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
+               {
+                 gdk_draw_rectangle (progress->offscreen_pixmap,
+                                     widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                     TRUE,
+                                     widget->allocation.width - 
+                                     widget->style->klass->xthickness - amount,
+                                     widget->style->klass->ythickness,
+                                     amount,
+                                     widget->allocation.height - 
+                                     widget->style->klass->ythickness * 2);
+                 gtk_draw_shadow (widget->style,
+                                  progress->offscreen_pixmap,
+                                  GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                  widget->allocation.width - 
+                                  widget->style->klass->xthickness - amount,
+                                  widget->style->klass->ythickness,
+                                  amount,
+                                  widget->allocation.height -
+                                  widget->style->klass->ythickness * 2);
+               }
+             else
+               {
+                 x = widget->allocation.width - 
+                   widget->style->klass->xthickness;
+
+                 for (i = 0; i <= pbar->in_block; i++)
+                   {
+                     block_delta = (((i + 1) * space) / pbar->blocks) -
+                       ((i * space) / pbar->blocks);
+
+                     x -=  block_delta;
+
+                     gdk_draw_rectangle (progress->offscreen_pixmap,
+                                 widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                 TRUE,
+                                 x,
+                                 widget->style->klass->ythickness,
+                                 block_delta,
+                                 widget->allocation.height - 
+                                 widget->style->klass->ythickness * 2);
+
+                     gtk_draw_shadow (widget->style,
+                                      progress->offscreen_pixmap,
+                                      GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                      x,
+                                      widget->style->klass->ythickness,
+                                      block_delta,
+                                      widget->allocation.height -
+                                      widget->style->klass->ythickness * 2);
+                   }
+               }
+             break;
+
+           case GTK_PROGRESS_BOTTOM_TO_TOP:
+
+             if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
+               {
+                 gdk_draw_rectangle (progress->offscreen_pixmap,
+                                     widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                     TRUE,
+                                     widget->style->klass->xthickness,
+                                     widget->allocation.height - 
+                                     widget->style->klass->ythickness - amount,
+                                     widget->allocation.width - 
+                                     widget->style->klass->xthickness * 2,
+                                     amount);
+                 gtk_draw_shadow (widget->style,
+                                  progress->offscreen_pixmap,
+                                  GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                  widget->style->klass->xthickness,
+                                  widget->allocation.height - 
+                                  widget->style->klass->ythickness - amount,
+                                  widget->allocation.width -
+                                  widget->style->klass->xthickness * 2,
+                                  amount);
+               }
+             else
+               {
+                 y = widget->allocation.height - 
+                   widget->style->klass->ythickness;
+
+                 for (i = 0; i <= pbar->in_block; i++)
+                   {
+                     block_delta = (((i + 1) * space) / pbar->blocks) -
+                       ((i * space) / pbar->blocks);
+                     
+                     y -= block_delta;
+
+                     gdk_draw_rectangle 
+                       (progress->offscreen_pixmap,
+                        widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                        TRUE,
+                        widget->style->klass->xthickness,
+                        y,
+                        widget->allocation.width - 
+                        widget->style->klass->xthickness * 2,
+                        block_delta);
+
+                     gtk_draw_shadow (widget->style,
+                                      progress->offscreen_pixmap,
+                                      GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                      widget->style->klass->xthickness,
+                                      y,
+                                      widget->allocation.width - 
+                                      widget->style->klass->xthickness * 2,
+                                      block_delta);
+                   }
+               }
+             break;
+
+           case GTK_PROGRESS_TOP_TO_BOTTOM:
+
+             if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
+               {
+                 gdk_draw_rectangle (progress->offscreen_pixmap,
+                                     widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                                     TRUE,
+                                     widget->style->klass->xthickness,
+                                     widget->style->klass->ythickness,
+                                     widget->allocation.width -
+                                     widget->style->klass->xthickness * 2,
+                                     amount);
+                 gtk_draw_shadow (widget->style,
+                                  progress->offscreen_pixmap,
+                                  GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                  widget->style->klass->xthickness,
+                                  widget->style->klass->ythickness,
+                                  widget->allocation.width -
+                                  widget->style->klass->xthickness * 2,
+                                  amount);
+               }
+             else
+               {
+                 y = widget->style->klass->ythickness;
+
+                 for (i = 0; i <= pbar->in_block; i++)
+                   {
+
+                     block_delta = (((i + 1) * space) / pbar->blocks)
+                       - ((i * space) / pbar->blocks);
+
+                     gdk_draw_rectangle
+                       (progress->offscreen_pixmap,
+                        widget->style->bg_gc[GTK_STATE_PRELIGHT],
+                        TRUE,
+                        widget->style->klass->xthickness,
+                        y,
+                        widget->allocation.width -
+                        widget->style->klass->xthickness * 2,
+                        block_delta);
+
+                     gtk_draw_shadow (widget->style,
+                                      progress->offscreen_pixmap,
+                                      GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
+                                      widget->style->klass->xthickness,
+                                      y,
+                                      widget->allocation.width -
+                                      widget->style->klass->xthickness * 2,
+                                      block_delta);
+
+                     y += block_delta;
+                   }
+               }
+             break;
+
+           default:
+             break;
+           }
+       }
 
-      gtk_progress_bar_make_pixmap (GTK_PROGRESS_BAR (widget));
+      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
+       {
+         gint x;
+         gint y;
+         gchar *buf;
+         GdkRectangle rect;
+
+         buf = gtk_progress_get_current_text (progress);
+
+         x = widget->style->klass->xthickness + 1 + 
+           (widget->allocation.width - 2 * widget->style->klass->xthickness -
+            3 - gdk_text_width (widget->style->font, buf, strlen (buf)))
+           * progress->x_align; 
+
+         y = widget->style->font->ascent + 1 +
+           (widget->allocation.height - 2 * widget->style->klass->ythickness -
+            3 - gdk_text_height (widget->style->font, buf, strlen (buf)))
+           * progress->y_align;
+
+         rect.x = widget->style->klass->xthickness + 1;
+         rect.y = widget->style->klass->ythickness + 1;
+         rect.width = widget->allocation.width -
+           2 * widget->style->klass->xthickness - 3;
+         rect.height = widget->allocation.height -
+           2 * widget->style->klass->ythickness - 3;
+
+         gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state],
+                                    &rect);
+
+         gdk_draw_text (progress->offscreen_pixmap, widget->style->font,
+                        widget->style->fg_gc[widget->state],
+                        x, y, buf, strlen (buf));
+
+         gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state],
+                                    NULL);
+         g_free (buf);
+       }
     }
 }
 
-static gint
-gtk_progress_bar_expose (GtkWidget      *widget,
-                        GdkEventExpose *event)
+/*******************************************************************/
+
+void
+gtk_progress_bar_update (GtkProgressBar *pbar,
+                        gfloat          percentage)
 {
-  GtkProgressBar *pbar;
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_PROGRESS_BAR (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+  /***********************************************************************
+   *                 Use of this function is deprecated !               * 
+   * Use gtk_progress_set_value or gtk_progress_set_percentage instead.  *
+   ***********************************************************************/
 
-  if (GTK_WIDGET_DRAWABLE (widget))
+  gtk_progress_set_percentage (GTK_PROGRESS (pbar), percentage);
+}
+
+void
+gtk_progress_bar_set_orientation (GtkProgressBar           *pbar,
+                                 GtkProgressBarOrientation orientation)
+{
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+
+  if (pbar->orientation != orientation)
     {
-      pbar = GTK_PROGRESS_BAR (widget);
+      pbar->orientation = orientation;
 
-      gdk_draw_pixmap (widget->window,
-                      widget->style->black_gc,
-                      pbar->offscreen_pixmap,
-                      0, 0, 0, 0,
-                      widget->allocation.width,
-                      widget->allocation.height);
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
+       gtk_widget_queue_resize (GTK_WIDGET (pbar));
     }
-
-  return FALSE;
 }
 
-static void
-gtk_progress_bar_make_pixmap (GtkProgressBar *pbar)
+void
+gtk_progress_bar_set_bar_style (GtkProgressBar     *pbar,
+                               GtkProgressBarStyle bar_style)
 {
-  GtkWidget *widget;
-
   g_return_if_fail (pbar != NULL);
   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
 
-  if (GTK_WIDGET_REALIZED (pbar))
+  if (pbar->bar_style != bar_style)
     {
-      widget = GTK_WIDGET (pbar);
-
-      if (pbar->offscreen_pixmap)
-       gdk_pixmap_unref (pbar->offscreen_pixmap);
-
-      pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
-                                              widget->allocation.width,
-                                              widget->allocation.height,
-                                              -1);
+      pbar->bar_style = bar_style;
 
-      gtk_progress_bar_paint (pbar);
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
+       gtk_widget_queue_resize (GTK_WIDGET (pbar));
     }
 }
 
-static void
-gtk_progress_bar_paint (GtkProgressBar *pbar)
+void
+gtk_progress_bar_set_number_of_blocks (GtkProgressBar *pbar,
+                                      guint           blocks)
 {
-  GtkWidget *widget;
-  int amount;
-
   g_return_if_fail (pbar != NULL);
   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
+  g_return_if_fail (blocks > 1);
 
-  if (pbar->offscreen_pixmap)
+  if (pbar->blocks != blocks)
     {
-      widget = GTK_WIDGET (pbar);
-
-      gtk_draw_shadow (widget->style,
-                      pbar->offscreen_pixmap,
-                      GTK_STATE_NORMAL, GTK_SHADOW_IN, 0, 0,
-                      widget->allocation.width,
-                      widget->allocation.height);
+      pbar->blocks = blocks;
 
-      gdk_draw_rectangle (pbar->offscreen_pixmap,
-                         widget->style->bg_gc[GTK_STATE_ACTIVE], TRUE,
-                         widget->style->klass->xthickness,
-                         widget->style->klass->ythickness,
-                         widget->allocation.width - widget->style->klass->xthickness * 2,
-                         widget->allocation.height - widget->style->klass->ythickness * 2);
+      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
+       gtk_widget_queue_resize (GTK_WIDGET (pbar));
+    }
+}
 
+void
+gtk_progress_bar_set_activity_step (GtkProgressBar *pbar,
+                                    guint           step)
+{
+  g_return_if_fail (pbar != NULL);
+  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
 
-      amount = pbar->percentage * (widget->allocation.width - widget->style->klass->xthickness * 2);
-      if (amount > 0)
-       {
-         gdk_draw_rectangle (pbar->offscreen_pixmap,
-                             widget->style->bg_gc[GTK_STATE_PRELIGHT], TRUE,
-                             widget->style->klass->xthickness,
-                             widget->style->klass->ythickness,
-                             amount,
-                             widget->allocation.height - widget->style->klass->ythickness * 2);
-
-         gtk_draw_shadow (widget->style,
-                          pbar->offscreen_pixmap,
-                          GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
-                          widget->style->klass->xthickness,
-                          widget->style->klass->ythickness,
-                          amount,
-                          widget->allocation.height - widget->style->klass->ythickness * 2);
-       }
-    }
+  if (pbar->activity_step != step)
+    pbar->activity_step = step;
 }
index 8cb0c2336d091517afcb4056afc9f260b29d8dd9..6099ba36464b96fd22f7182ade92d4e0708b1153 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
 #ifndef __GTK_PROGRESS_BAR_H__
 #define __GTK_PROGRESS_BAR_H__
 
 
 #include <gdk/gdk.h>
-#include <gtk/gtkwidget.h>
+#include <gtk/gtkprogress.h>
 
 
 #ifdef __cplusplus
@@ -37,24 +38,56 @@ extern "C" {
 typedef struct _GtkProgressBar       GtkProgressBar;
 typedef struct _GtkProgressBarClass  GtkProgressBarClass;
 
+typedef enum
+{
+  GTK_PROGRESS_CONTINUOUS,
+  GTK_PROGRESS_DISCRETE
+} GtkProgressBarStyle;
+
+typedef enum
+{
+  GTK_PROGRESS_LEFT_TO_RIGHT,
+  GTK_PROGRESS_RIGHT_TO_LEFT,
+  GTK_PROGRESS_BOTTOM_TO_TOP,
+  GTK_PROGRESS_TOP_TO_BOTTOM
+} GtkProgressBarOrientation;
+
 struct _GtkProgressBar
 {
-  GtkWidget widget;
+  GtkProgress progress;
+
+  GtkProgressBarStyle bar_style;
+  GtkProgressBarOrientation orientation;
+
+  guint blocks;
+  gint  in_block;
 
-  GdkPixmap *offscreen_pixmap;
-  gfloat percentage;
+  gint  activity_pos;
+  guint activity_step;
+  guint activity_dir : 1;
 };
 
 struct _GtkProgressBarClass
 {
-  GtkWidgetClass parent_class;
+  GtkProgressClass parent_class;
 };
 
 
-guint      gtk_progress_bar_get_type (void);
-GtkWidget* gtk_progress_bar_new      (void);
-void       gtk_progress_bar_update   (GtkProgressBar *pbar,
-                                     gfloat          percentage);
+guint      gtk_progress_bar_get_type             (void);
+GtkWidget* gtk_progress_bar_new                  (void);
+GtkWidget* gtk_progress_bar_new_with_adjustment  (GtkAdjustment  *adjustment);
+void       gtk_progress_bar_construct            (GtkProgressBar *pbar,
+                                                 GtkAdjustment  *adjustment);
+void       gtk_progress_bar_set_bar_style        (GtkProgressBar *pbar,
+                                                 GtkProgressBarStyle style);
+void       gtk_progress_bar_set_number_of_blocks (GtkProgressBar *pbar,
+                                                 guint           blocks);
+void       gtk_progress_bar_set_activity_step    (GtkProgressBar *pbar,
+                                                  guint           step);
+void       gtk_progress_bar_set_orientation      (GtkProgressBar *pbar,
+                                                 GtkProgressBarOrientation orientation);
+void       gtk_progress_bar_update               (GtkProgressBar *pbar,
+                                                 gfloat          percentage);
 
 
 #ifdef __cplusplus
index ffc3088adf0ef418038c638ffb077f4d7de3366f..3fac8704ace1d4588102ea02f38f3b8cf2741778 100644 (file)
@@ -272,11 +272,11 @@ gtk_viewport_set_hadjustment (GtkViewport   *viewport,
       gtk_object_sink (GTK_OBJECT (viewport->hadjustment));
       
       gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                         gtk_viewport_adjustment_changed,
-                         viewport);
+                         (GtkSignalFunc) gtk_viewport_adjustment_changed,
+                         (gpointer) viewport);
       gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                         gtk_viewport_adjustment_value_changed,
-                         viewport);
+                         (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
+                         (gpointer) viewport);
 
       gtk_viewport_adjustment_changed (adjustment, viewport);
     }
@@ -304,11 +304,11 @@ gtk_viewport_set_vadjustment (GtkViewport   *viewport,
       gtk_object_sink (GTK_OBJECT (viewport->vadjustment));
       
       gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                         gtk_viewport_adjustment_changed,
-                         viewport);
+                         (GtkSignalFunc) gtk_viewport_adjustment_changed,
+                         (gpointer) viewport);
       gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                         gtk_viewport_adjustment_value_changed,
-                         viewport);
+                         (GtkSignalFunc) gtk_viewport_adjustment_value_changed,
+                         (gpointer) viewport);
 
       gtk_viewport_adjustment_changed (adjustment, viewport);
     }
index 5f99a8336fe09699ef9a7eef68a6d028e47d11d5..5bd02f3d2785eaae69733cb472169b31731c3a68 100644 (file)
@@ -5895,94 +5895,433 @@ create_wmhints (void)
 /*
  * Progress Bar
  */
-static int progress_timer = 0;
+
+typedef struct _ProgressData {
+  GtkWidget *window;
+  GtkWidget *pbar;
+  GtkWidget *block_spin;
+  GtkWidget *x_align_spin;
+  GtkWidget *y_align_spin;
+  GtkWidget *step_spin;
+  GtkWidget *label;
+  GtkWidget *omenu1;
+  GtkWidget *omenu3;
+  GtkWidget *entry;
+  int timer;
+} ProgressData;
+
 
 gint
 progress_timeout (gpointer data)
 {
   gfloat new_val;
+  GtkAdjustment *adj;
+
+  adj = GTK_PROGRESS (data)->adjustment;
 
-  new_val = GTK_PROGRESS_BAR (data)->percentage;
-  if (new_val >= 1.0)
-    new_val = 0.0;
-  new_val += 0.02;
+  new_val = adj->value + 1;
+  if (new_val > adj->upper)
+    new_val = adj->lower;
 
-  gtk_progress_bar_update (GTK_PROGRESS_BAR (data), new_val);
+  gtk_progress_set_value (GTK_PROGRESS (data), new_val);
 
   return TRUE;
 }
 
 static void
-destroy_progress (GtkWidget  *widget,
-                 GtkWidget **window)
+destroy_progress (GtkWidget     *widget,
+                 ProgressData **pdata)
 {
-  gtk_timeout_remove (progress_timer);
-  progress_timer = 0;
-  *window = NULL;
+  gtk_timeout_remove ((*pdata)->timer);
+  (*pdata)->timer = 0;
+  (*pdata)->window = NULL;
+  g_free (*pdata);
+  *pdata = NULL;
+}
+
+static void
+toggle_orientation (GtkWidget *widget, ProgressData *pdata)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)(pdata->omenu1))->menu_item), i);
+
+  gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
+                           (GtkProgressBarOrientation) (3-i));
+}
+
+static void
+toggle_show_text (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
+                             GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->x_align_spin,
+                           GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->y_align_spin,
+                           GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+static void
+toggle_bar_style (GtkWidget *widget, ProgressData *pdata)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)(pdata->omenu3))->menu_item), i);
+
+  i = 1 - i;
+
+  if (i == 1)
+    gtk_widget_set_sensitive (pdata->block_spin, TRUE);
+  else
+    gtk_widget_set_sensitive (pdata->block_spin, FALSE);
+
+  gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
+                                 (GtkProgressBarStyle) i);
+}
+
+static void
+progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
+{
+  char buf[20];
+
+  if (GTK_PROGRESS (pdata->pbar)->activity_mode)
+    sprintf (buf, "???");
+  else
+    sprintf (buf, "%.0f%%", 100 *
+            gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
+  gtk_label_set (GTK_LABEL (pdata->label), buf);
+}
+
+static void
+adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
+  gtk_progress_bar_set_number_of_blocks (GTK_PROGRESS_BAR (pdata->pbar),
+     gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
+}
+
+static void
+adjust_step (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
+     gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
+}
+
+static void
+adjust_align (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
+        gtk_spin_button_get_value_as_float 
+                                  (GTK_SPIN_BUTTON (pdata->x_align_spin)),
+        gtk_spin_button_get_value_as_float
+                                  (GTK_SPIN_BUTTON (pdata->y_align_spin)));
+}
+
+static void
+toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
+                                 GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->step_spin, 
+                           GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+static void
+entry_changed (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
+                         gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
 }
 
 void
 create_progress_bar (void)
 {
-  static GtkWidget *window = NULL;
   GtkWidget *button;
   GtkWidget *vbox;
-  GtkWidget *pbar;
+  GtkWidget *vbox2;
+  GtkWidget *hbox;
+  GtkWidget *check;
+  GtkWidget *frame;
+  GtkWidget *tab;
   GtkWidget *label;
-  GtkTooltips *tooltips;
-  
-  if (!window)
+  GtkWidget *align;
+  GtkAdjustment *adj;
+  GtkWidget *menu_item;
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GSList *group;
+  static ProgressData *pdata = NULL;
+
+  if (!pdata)
+    pdata = g_new0 (ProgressData, 1);
+
+  if (!pdata->window)
     {
-      window = gtk_dialog_new ();
+      pdata->window = gtk_dialog_new ();
 
-      gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                         GTK_SIGNAL_FUNC(destroy_progress),
-                         &window);
+      gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
 
-      gtk_window_set_title (GTK_WINDOW (window), "dialog");
-      gtk_container_border_width (GTK_CONTAINER (window), 0);
+      gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
+                         GTK_SIGNAL_FUNC (destroy_progress),
+                         &pdata);
 
-      tooltips = gtk_tooltips_new();
+      pdata->timer = 0;
+
+      gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
+      gtk_container_border_width (GTK_CONTAINER (pdata->window), 0);
 
       vbox = gtk_vbox_new (FALSE, 5);
       gtk_container_border_width (GTK_CONTAINER (vbox), 10);
-      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
-                         vbox, TRUE, TRUE, 0);
-      gtk_widget_show (vbox);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
+                         vbox, FALSE, TRUE, 0);
 
-      label = gtk_label_new ("progress...");
-      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
-      gtk_widget_show (label);
+      frame = gtk_frame_new ("Progress");
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+
+      vbox2 = gtk_vbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (frame), vbox2);
+
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
+
+      adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (progress_value_changed), pdata);
+
+      pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
+      gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
+                                     "%v from [%l,%u] (=%p%%)");
+      gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
+      pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
+
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (align), hbox);
+      label = gtk_label_new ("Label updated by user :"); 
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      pdata->label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
 
-      pbar = gtk_progress_bar_new ();
-      gtk_widget_set_events (pbar, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-      gtk_widget_set_usize (pbar, 200, 20);
-      gtk_box_pack_start (GTK_BOX (vbox), pbar, TRUE, TRUE, 0);
-      gtk_widget_show (pbar);
-      gtk_tooltips_set_tip (tooltips, pbar, "Countdown is progressing yet!", "Secret!");
-      gtk_tooltips_set_delay (tooltips, 0);
+      frame = gtk_frame_new ("Options");
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+
+      vbox2 = gtk_vbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (frame), vbox2);
+
+      tab = gtk_table_new (6, 2, FALSE);
+      gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
 
-      progress_timer = gtk_timeout_add (100, progress_timeout, pbar);
+      label = gtk_label_new ("Orientation :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      pdata->omenu1 = gtk_option_menu_new ();
+
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Left-Right");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation), 
+                         pdata);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Right-Left");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Bottom-Top");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Top-Bottom");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (pdata->omenu1), menu);
+      gtk_option_menu_set_history (GTK_OPTION_MENU (pdata->omenu1), 0);
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
+      
+      check = gtk_check_button_new_with_label ("Show text");
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_show_text),
+                         pdata);
+      gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      label = gtk_label_new ("Format : ");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      pdata->entry = gtk_entry_new ();
+      gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
+                         GTK_SIGNAL_FUNC (entry_changed),
+                         pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
+      gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
+      gtk_widget_set_usize (pdata->entry, 100, -1);
+      gtk_widget_set_sensitive (pdata->entry, FALSE);
+
+      label = gtk_label_new ("Text align :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      label = gtk_label_new ("x :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
+      pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_align), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
+
+      label = gtk_label_new ("y :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
+
+      adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
+      pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_align), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
+
+      label = gtk_label_new ("Bar Style :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      pdata->omenu3 = gtk_option_menu_new ();
+
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Continuous");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_bar_style),
+                         pdata);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Discrete");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_bar_style),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (pdata->omenu3), menu);
+      gtk_option_menu_set_history (GTK_OPTION_MENU (pdata->omenu3), 0);
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu3, TRUE, TRUE, 0);
+
+      label = gtk_label_new ("Block count :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
+      pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_blocks), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->block_spin, FALSE);
+
+      check = gtk_check_button_new_with_label ("Activity mode");
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_activity_mode),
+                         pdata);
+      gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      label = gtk_label_new ("Step size : ");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
+      pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_step), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->step_spin, FALSE);
 
       button = gtk_button_new_with_label ("close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                                GTK_SIGNAL_FUNC(gtk_widget_destroy),
-                                GTK_OBJECT (window));
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (pdata->window));
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
-      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
                          button, TRUE, TRUE, 0);
       gtk_widget_grab_default (button);
-      gtk_widget_show (button);
     }
 
-  if (!GTK_WIDGET_VISIBLE (window))
-    gtk_widget_show (window);
+  if (!GTK_WIDGET_VISIBLE (pdata->window))
+    gtk_widget_show_all (pdata->window);
   else
-    gtk_widget_destroy (window);
+    gtk_widget_destroy (pdata->window);
 }
 
-
 /*
  * Color Preview
  */
index 5f99a8336fe09699ef9a7eef68a6d028e47d11d5..5bd02f3d2785eaae69733cb472169b31731c3a68 100644 (file)
@@ -5895,94 +5895,433 @@ create_wmhints (void)
 /*
  * Progress Bar
  */
-static int progress_timer = 0;
+
+typedef struct _ProgressData {
+  GtkWidget *window;
+  GtkWidget *pbar;
+  GtkWidget *block_spin;
+  GtkWidget *x_align_spin;
+  GtkWidget *y_align_spin;
+  GtkWidget *step_spin;
+  GtkWidget *label;
+  GtkWidget *omenu1;
+  GtkWidget *omenu3;
+  GtkWidget *entry;
+  int timer;
+} ProgressData;
+
 
 gint
 progress_timeout (gpointer data)
 {
   gfloat new_val;
+  GtkAdjustment *adj;
+
+  adj = GTK_PROGRESS (data)->adjustment;
 
-  new_val = GTK_PROGRESS_BAR (data)->percentage;
-  if (new_val >= 1.0)
-    new_val = 0.0;
-  new_val += 0.02;
+  new_val = adj->value + 1;
+  if (new_val > adj->upper)
+    new_val = adj->lower;
 
-  gtk_progress_bar_update (GTK_PROGRESS_BAR (data), new_val);
+  gtk_progress_set_value (GTK_PROGRESS (data), new_val);
 
   return TRUE;
 }
 
 static void
-destroy_progress (GtkWidget  *widget,
-                 GtkWidget **window)
+destroy_progress (GtkWidget     *widget,
+                 ProgressData **pdata)
 {
-  gtk_timeout_remove (progress_timer);
-  progress_timer = 0;
-  *window = NULL;
+  gtk_timeout_remove ((*pdata)->timer);
+  (*pdata)->timer = 0;
+  (*pdata)->window = NULL;
+  g_free (*pdata);
+  *pdata = NULL;
+}
+
+static void
+toggle_orientation (GtkWidget *widget, ProgressData *pdata)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)(pdata->omenu1))->menu_item), i);
+
+  gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
+                           (GtkProgressBarOrientation) (3-i));
+}
+
+static void
+toggle_show_text (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_show_text (GTK_PROGRESS (pdata->pbar),
+                             GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->entry, GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->x_align_spin,
+                           GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->y_align_spin,
+                           GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+static void
+toggle_bar_style (GtkWidget *widget, ProgressData *pdata)
+{
+  gint i;
+
+  if (!GTK_WIDGET_MAPPED (widget))
+    return;
+
+  RADIOMENUTOGGLED ((GtkRadioMenuItem *)
+                   (((GtkOptionMenu *)(pdata->omenu3))->menu_item), i);
+
+  i = 1 - i;
+
+  if (i == 1)
+    gtk_widget_set_sensitive (pdata->block_spin, TRUE);
+  else
+    gtk_widget_set_sensitive (pdata->block_spin, FALSE);
+
+  gtk_progress_bar_set_bar_style (GTK_PROGRESS_BAR (pdata->pbar),
+                                 (GtkProgressBarStyle) i);
+}
+
+static void
+progress_value_changed (GtkAdjustment *adj, ProgressData *pdata)
+{
+  char buf[20];
+
+  if (GTK_PROGRESS (pdata->pbar)->activity_mode)
+    sprintf (buf, "???");
+  else
+    sprintf (buf, "%.0f%%", 100 *
+            gtk_progress_get_current_percentage (GTK_PROGRESS (pdata->pbar)));
+  gtk_label_set (GTK_LABEL (pdata->label), buf);
+}
+
+static void
+adjust_blocks (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_set_percentage (GTK_PROGRESS (pdata->pbar), 0);
+  gtk_progress_bar_set_number_of_blocks (GTK_PROGRESS_BAR (pdata->pbar),
+     gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->block_spin)));
+}
+
+static void
+adjust_step (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_bar_set_activity_step (GTK_PROGRESS_BAR (pdata->pbar),
+     gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (pdata->step_spin)));
+}
+
+static void
+adjust_align (GtkAdjustment *adj, ProgressData *pdata)
+{
+  gtk_progress_set_text_alignment (GTK_PROGRESS (pdata->pbar),
+        gtk_spin_button_get_value_as_float 
+                                  (GTK_SPIN_BUTTON (pdata->x_align_spin)),
+        gtk_spin_button_get_value_as_float
+                                  (GTK_SPIN_BUTTON (pdata->y_align_spin)));
+}
+
+static void
+toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_activity_mode (GTK_PROGRESS (pdata->pbar),
+                                 GTK_TOGGLE_BUTTON (widget)->active);
+  gtk_widget_set_sensitive (pdata->step_spin, 
+                           GTK_TOGGLE_BUTTON (widget)->active);
+}
+
+static void
+entry_changed (GtkWidget *widget, ProgressData *pdata)
+{
+  gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
+                         gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
 }
 
 void
 create_progress_bar (void)
 {
-  static GtkWidget *window = NULL;
   GtkWidget *button;
   GtkWidget *vbox;
-  GtkWidget *pbar;
+  GtkWidget *vbox2;
+  GtkWidget *hbox;
+  GtkWidget *check;
+  GtkWidget *frame;
+  GtkWidget *tab;
   GtkWidget *label;
-  GtkTooltips *tooltips;
-  
-  if (!window)
+  GtkWidget *align;
+  GtkAdjustment *adj;
+  GtkWidget *menu_item;
+  GtkWidget *menu;
+  GtkWidget *submenu;
+  GSList *group;
+  static ProgressData *pdata = NULL;
+
+  if (!pdata)
+    pdata = g_new0 (ProgressData, 1);
+
+  if (!pdata->window)
     {
-      window = gtk_dialog_new ();
+      pdata->window = gtk_dialog_new ();
 
-      gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                         GTK_SIGNAL_FUNC(destroy_progress),
-                         &window);
+      gtk_window_set_policy (GTK_WINDOW (pdata->window), FALSE, FALSE, TRUE);
 
-      gtk_window_set_title (GTK_WINDOW (window), "dialog");
-      gtk_container_border_width (GTK_CONTAINER (window), 0);
+      gtk_signal_connect (GTK_OBJECT (pdata->window), "destroy",
+                         GTK_SIGNAL_FUNC (destroy_progress),
+                         &pdata);
 
-      tooltips = gtk_tooltips_new();
+      pdata->timer = 0;
+
+      gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
+      gtk_container_border_width (GTK_CONTAINER (pdata->window), 0);
 
       vbox = gtk_vbox_new (FALSE, 5);
       gtk_container_border_width (GTK_CONTAINER (vbox), 10);
-      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), 
-                         vbox, TRUE, TRUE, 0);
-      gtk_widget_show (vbox);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->vbox), 
+                         vbox, FALSE, TRUE, 0);
 
-      label = gtk_label_new ("progress...");
-      gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
-      gtk_widget_show (label);
+      frame = gtk_frame_new ("Progress");
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+
+      vbox2 = gtk_vbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (frame), vbox2);
+
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
+
+      adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, 300, 0, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (progress_value_changed), pdata);
+
+      pdata->pbar = gtk_progress_bar_new_with_adjustment (adj);
+      gtk_progress_set_format_string (GTK_PROGRESS (pdata->pbar),
+                                     "%v from [%l,%u] (=%p%%)");
+      gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
+      pdata->timer = gtk_timeout_add (100, progress_timeout, pdata->pbar);
+
+      align = gtk_alignment_new (0.5, 0.5, 0, 0);
+      gtk_box_pack_start (GTK_BOX (vbox2), align, FALSE, FALSE, 5);
+
+      hbox = gtk_hbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (align), hbox);
+      label = gtk_label_new ("Label updated by user :"); 
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      pdata->label = gtk_label_new ("");
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
 
-      pbar = gtk_progress_bar_new ();
-      gtk_widget_set_events (pbar, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-      gtk_widget_set_usize (pbar, 200, 20);
-      gtk_box_pack_start (GTK_BOX (vbox), pbar, TRUE, TRUE, 0);
-      gtk_widget_show (pbar);
-      gtk_tooltips_set_tip (tooltips, pbar, "Countdown is progressing yet!", "Secret!");
-      gtk_tooltips_set_delay (tooltips, 0);
+      frame = gtk_frame_new ("Options");
+      gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
+
+      vbox2 = gtk_vbox_new (FALSE, 5);
+      gtk_container_add (GTK_CONTAINER (frame), vbox2);
+
+      tab = gtk_table_new (6, 2, FALSE);
+      gtk_box_pack_start (GTK_BOX (vbox2), tab, FALSE, TRUE, 0);
 
-      progress_timer = gtk_timeout_add (100, progress_timeout, pbar);
+      label = gtk_label_new ("Orientation :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      pdata->omenu1 = gtk_option_menu_new ();
+
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Left-Right");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation), 
+                         pdata);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Right-Left");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Bottom-Top");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Top-Bottom");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_orientation),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (pdata->omenu1), menu);
+      gtk_option_menu_set_history (GTK_OPTION_MENU (pdata->omenu1), 0);
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 0, 1,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu1, TRUE, TRUE, 0);
+      
+      check = gtk_check_button_new_with_label ("Show text");
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_show_text),
+                         pdata);
+      gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 1, 2,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      label = gtk_label_new ("Format : ");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+
+      pdata->entry = gtk_entry_new ();
+      gtk_signal_connect (GTK_OBJECT (pdata->entry), "changed",
+                         GTK_SIGNAL_FUNC (entry_changed),
+                         pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
+      gtk_entry_set_text (GTK_ENTRY (pdata->entry), "%v from [%l,%u] (=%p%%)");
+      gtk_widget_set_usize (pdata->entry, 100, -1);
+      gtk_widget_set_sensitive (pdata->entry, FALSE);
+
+      label = gtk_label_new ("Text align :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 2, 3,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      label = gtk_label_new ("x :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
+      
+      adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
+      pdata->x_align_spin = gtk_spin_button_new (adj, 0, 1);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_align), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->x_align_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->x_align_spin, FALSE);
+
+      label = gtk_label_new ("y :");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 5);
+
+      adj = (GtkAdjustment *) gtk_adjustment_new (0.5, 0, 1, 0.1, 0.1, 0);
+      pdata->y_align_spin = gtk_spin_button_new (adj, 0, 1);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_align), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->y_align_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->y_align_spin, FALSE);
+
+      label = gtk_label_new ("Bar Style :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 3, 4,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      pdata->omenu3 = gtk_option_menu_new ();
+
+      menu = gtk_menu_new ();
+      submenu = NULL;
+      group = NULL;
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Continuous");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_bar_style),
+                         pdata);
+      gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+      
+      menu_item = gtk_radio_menu_item_new_with_label (group, "Discrete");
+      gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+                         GTK_SIGNAL_FUNC (toggle_bar_style),
+                         pdata);
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menu_item));
+      gtk_menu_append (GTK_MENU (menu), menu_item);
+      gtk_widget_show (menu_item);
+
+      gtk_option_menu_set_menu (GTK_OPTION_MENU (pdata->omenu3), menu);
+      gtk_option_menu_set_history (GTK_OPTION_MENU (pdata->omenu3), 0);
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 3, 4,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->omenu3, TRUE, TRUE, 0);
+
+      label = gtk_label_new ("Block count :");
+      gtk_table_attach (GTK_TABLE (tab), label, 0, 1, 4, 5,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 4, 5,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      adj = (GtkAdjustment *) gtk_adjustment_new (10, 2, 20, 1, 5, 0);
+      pdata->block_spin = gtk_spin_button_new (adj, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_blocks), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->block_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->block_spin, FALSE);
+
+      check = gtk_check_button_new_with_label ("Activity mode");
+      gtk_signal_connect (GTK_OBJECT (check), "clicked",
+                         GTK_SIGNAL_FUNC (toggle_activity_mode),
+                         pdata);
+      gtk_table_attach (GTK_TABLE (tab), check, 0, 1, 5, 6,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_table_attach (GTK_TABLE (tab), hbox, 1, 2, 5, 6,
+                       GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
+                       5, 5);
+      label = gtk_label_new ("Step size : ");
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+      adj = (GtkAdjustment *) gtk_adjustment_new (3, 1, 20, 1, 5, 0);
+      pdata->step_spin = gtk_spin_button_new (adj, 0, 0);
+      gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
+                         GTK_SIGNAL_FUNC (adjust_step), pdata);
+      gtk_box_pack_start (GTK_BOX (hbox), pdata->step_spin, FALSE, TRUE, 0);
+      gtk_widget_set_sensitive (pdata->step_spin, FALSE);
 
       button = gtk_button_new_with_label ("close");
       gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                                GTK_SIGNAL_FUNC(gtk_widget_destroy),
-                                GTK_OBJECT (window));
+                                GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                                GTK_OBJECT (pdata->window));
       GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
-      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), 
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pdata->window)->action_area), 
                          button, TRUE, TRUE, 0);
       gtk_widget_grab_default (button);
-      gtk_widget_show (button);
     }
 
-  if (!GTK_WIDGET_VISIBLE (window))
-    gtk_widget_show (window);
+  if (!GTK_WIDGET_VISIBLE (pdata->window))
+    gtk_widget_show_all (pdata->window);
   else
-    gtk_widget_destroy (window);
+    gtk_widget_destroy (pdata->window);
 }
 
-
 /*
  * Color Preview
  */