1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gtkprogressbar.h"
32 #include "gtkprivate.h"
36 #define MIN_HORIZONTAL_BAR_WIDTH 150
37 #define MIN_HORIZONTAL_BAR_HEIGHT 20
38 #define MIN_VERTICAL_BAR_WIDTH 22
39 #define MIN_VERTICAL_BAR_HEIGHT 80
42 struct _GtkProgressBarPriv
44 GtkProgressBarOrientation orientation;
46 GdkPixmap *offscreen_pixmap;
51 gdouble pulse_fraction;
57 guint activity_blocks;
60 guint activity_dir : 1;
61 guint activity_mode : 1;
77 static void gtk_progress_bar_set_property (GObject *object,
81 static void gtk_progress_bar_get_property (GObject *object,
85 static gboolean gtk_progress_bar_expose (GtkWidget *widget,
86 GdkEventExpose *event);
87 static void gtk_progress_bar_size_request (GtkWidget *widget,
88 GtkRequisition *requisition);
89 static void gtk_progress_bar_size_allocate (GtkWidget *widget,
90 GtkAllocation *allocation);
91 static void gtk_progress_bar_style_set (GtkWidget *widget,
93 static void gtk_progress_bar_real_update (GtkProgressBar *progress);
94 static void gtk_progress_bar_paint (GtkProgressBar *progress);
95 static void gtk_progress_bar_act_mode_enter (GtkProgressBar *progress);
96 static void gtk_progress_bar_realize (GtkWidget *widget);
97 static void gtk_progress_bar_finalize (GObject *object);
98 static void gtk_progress_bar_create_pixmap (GtkProgressBar *pbar);
101 G_DEFINE_TYPE (GtkProgressBar, gtk_progress_bar, GTK_TYPE_WIDGET)
104 gtk_progress_bar_class_init (GtkProgressBarClass *class)
106 GObjectClass *gobject_class;
107 GtkWidgetClass *widget_class;
109 gobject_class = G_OBJECT_CLASS (class);
110 widget_class = (GtkWidgetClass *) class;
112 gobject_class->set_property = gtk_progress_bar_set_property;
113 gobject_class->get_property = gtk_progress_bar_get_property;
114 gobject_class->finalize = gtk_progress_bar_finalize;
116 widget_class->realize = gtk_progress_bar_realize;
117 widget_class->expose_event = gtk_progress_bar_expose;
118 widget_class->size_request = gtk_progress_bar_size_request;
119 widget_class->size_allocate = gtk_progress_bar_size_allocate;
120 widget_class->style_set = gtk_progress_bar_style_set;
122 class->act_mode_enter = gtk_progress_bar_act_mode_enter;
124 g_object_class_install_property (gobject_class,
126 g_param_spec_enum ("orientation",
128 P_("Orientation and growth direction of the progress bar"),
129 GTK_TYPE_PROGRESS_BAR_ORIENTATION,
130 GTK_PROGRESS_LEFT_TO_RIGHT,
131 GTK_PARAM_READWRITE));
133 g_object_class_install_property (gobject_class,
135 g_param_spec_double ("fraction",
137 P_("The fraction of total work that has been completed"),
139 GTK_PARAM_READWRITE));
141 g_object_class_install_property (gobject_class,
143 g_param_spec_double ("pulse-step",
145 P_("The fraction of total progress to move the bouncing block when pulsed"),
147 GTK_PARAM_READWRITE));
149 g_object_class_install_property (gobject_class,
151 g_param_spec_string ("text",
153 P_("Text to be displayed in the progress bar"),
155 GTK_PARAM_READWRITE));
157 g_object_class_install_property (gobject_class,
159 g_param_spec_boolean ("show-text",
161 P_("Whether the progress is shown as text."),
163 GTK_PARAM_READWRITE));
166 * GtkProgressBar:ellipsize:
168 * The preferred place to ellipsize the string, if the progressbar does
169 * not have enough room to display the entire string, specified as a
170 * #PangoEllisizeMode.
172 * Note that setting this property to a value other than
173 * %PANGO_ELLIPSIZE_NONE has the side-effect that the progressbar requests
174 * only enough space to display the ellipsis "...". Another means to set a
175 * progressbar's width is gtk_widget_set_size_request().
179 g_object_class_install_property (gobject_class,
181 g_param_spec_enum ("ellipsize",
183 P_("The preferred place to ellipsize the string, if the progress bar "
184 "does not have enough room to display the entire string, if at all."),
185 PANGO_TYPE_ELLIPSIZE_MODE,
186 PANGO_ELLIPSIZE_NONE,
187 GTK_PARAM_READWRITE));
188 gtk_widget_class_install_style_property (widget_class,
189 g_param_spec_int ("xspacing",
191 P_("Extra spacing applied to the width of a progress bar."),
194 gtk_widget_class_install_style_property (widget_class,
195 g_param_spec_int ("yspacing",
197 P_("Extra spacing applied to the height of a progress bar."),
202 * GtkProgressBar:min-horizontal-bar-width:
204 * The minimum horizontal width of the progress bar.
208 gtk_widget_class_install_style_property (widget_class,
209 g_param_spec_int ("min-horizontal-bar-width",
210 P_("Min horizontal bar width"),
211 P_("The minimum horizontal width of the progress bar"),
212 1, G_MAXINT, MIN_HORIZONTAL_BAR_WIDTH,
215 * GtkProgressBar:min-horizontal-bar-height:
217 * Minimum horizontal height of the progress bar.
221 gtk_widget_class_install_style_property (widget_class,
222 g_param_spec_int ("min-horizontal-bar-height",
223 P_("Min horizontal bar height"),
224 P_("Minimum horizontal height of the progress bar"),
225 1, G_MAXINT, MIN_HORIZONTAL_BAR_HEIGHT,
228 * GtkProgressBar:min-vertical-bar-width:
230 * The minimum vertical width of the progress bar.
234 gtk_widget_class_install_style_property (widget_class,
235 g_param_spec_int ("min-vertical-bar-width",
236 P_("Min vertical bar width"),
237 P_("The minimum vertical width of the progress bar"),
238 1, G_MAXINT, MIN_VERTICAL_BAR_WIDTH,
241 * GtkProgressBar:min-vertical-bar-height:
243 * The minimum vertical height of the progress bar.
247 gtk_widget_class_install_style_property (widget_class,
248 g_param_spec_int ("min-vertical-bar-height",
249 P_("Min vertical bar height"),
250 P_("The minimum vertical height of the progress bar"),
251 1, G_MAXINT, MIN_VERTICAL_BAR_HEIGHT,
254 g_type_class_add_private (class, sizeof (GtkProgressBarPriv));
258 gtk_progress_bar_init (GtkProgressBar *pbar)
260 GtkProgressBarPriv *priv;
262 pbar->priv = G_TYPE_INSTANCE_GET_PRIVATE (pbar,
263 GTK_TYPE_PROGRESS_BAR,
269 priv->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
270 priv->pulse_fraction = 0.1;
271 priv->activity_pos = 0;
272 priv->activity_dir = 1;
273 priv->activity_step = 3;
274 priv->activity_blocks = 5;
275 priv->ellipsize = PANGO_ELLIPSIZE_NONE;
276 priv->show_text = FALSE;
279 priv->fraction = 0.0;
283 gtk_progress_bar_realize (GtkWidget *widget)
285 GdkWindowAttr attributes;
286 gint attributes_mask;
288 gtk_widget_set_realized (widget, TRUE);
290 attributes.window_type = GDK_WINDOW_CHILD;
291 attributes.x = widget->allocation.x;
292 attributes.y = widget->allocation.y;
293 attributes.width = widget->allocation.width;
294 attributes.height = widget->allocation.height;
295 attributes.wclass = GDK_INPUT_OUTPUT;
296 attributes.visual = gtk_widget_get_visual (widget);
297 attributes.colormap = gtk_widget_get_colormap (widget);
298 attributes.event_mask = gtk_widget_get_events (widget);
299 attributes.event_mask |= GDK_EXPOSURE_MASK;
301 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
302 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
303 &attributes, attributes_mask);
304 gdk_window_set_user_data (widget->window, widget);
306 widget->style = gtk_style_attach (widget->style, widget->window);
307 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
309 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
313 gtk_progress_bar_set_property (GObject *object,
318 GtkProgressBar *pbar;
320 pbar = GTK_PROGRESS_BAR (object);
324 case PROP_ORIENTATION:
325 gtk_progress_bar_set_orientation (pbar, g_value_get_enum (value));
328 gtk_progress_bar_set_fraction (pbar, g_value_get_double (value));
330 case PROP_PULSE_STEP:
331 gtk_progress_bar_set_pulse_step (pbar, g_value_get_double (value));
334 gtk_progress_bar_set_text (pbar, g_value_get_string (value));
337 gtk_progress_bar_set_show_text (pbar, g_value_get_boolean (value));
340 gtk_progress_bar_set_ellipsize (pbar, g_value_get_enum (value));
343 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
349 gtk_progress_bar_get_property (GObject *object,
354 GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
355 GtkProgressBarPriv* priv = pbar->priv;
359 case PROP_ORIENTATION:
360 g_value_set_enum (value, priv->orientation);
363 g_value_set_double (value, priv->fraction);
365 case PROP_PULSE_STEP:
366 g_value_set_double (value, priv->pulse_fraction);
369 g_value_set_string (value, priv->text);
372 g_value_set_boolean (value, priv->show_text);
375 g_value_set_enum (value, priv->ellipsize);
378 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
384 gtk_progress_bar_new (void)
388 pbar = g_object_new (GTK_TYPE_PROGRESS_BAR, NULL);
394 gtk_progress_bar_real_update (GtkProgressBar *pbar)
396 GtkProgressBarPriv *priv;
399 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
402 widget = GTK_WIDGET (pbar);
404 if (priv->activity_mode)
408 /* advance the block */
409 if (priv->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
410 priv->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
412 /* Update our activity step. */
413 priv->activity_step = widget->allocation.width * priv->pulse_fraction;
415 size = MAX (2, widget->allocation.width / priv->activity_blocks);
417 if (priv->activity_dir == 0)
419 priv->activity_pos += priv->activity_step;
420 if (priv->activity_pos + size >= widget->allocation.width - widget->style->xthickness)
422 priv->activity_pos = widget->allocation.width -
423 widget->style->xthickness - size;
424 priv->activity_dir = 1;
429 priv->activity_pos -= priv->activity_step;
430 if (priv->activity_pos <= widget->style->xthickness)
432 priv->activity_pos = widget->style->xthickness;
433 priv->activity_dir = 0;
439 /* Update our activity step. */
440 priv->activity_step = widget->allocation.height * priv->pulse_fraction;
442 size = MAX (2, widget->allocation.height / priv->activity_blocks);
444 if (priv->activity_dir == 0)
446 priv->activity_pos += priv->activity_step;
447 if (priv->activity_pos + size >= widget->allocation.height - widget->style->ythickness)
449 priv->activity_pos = widget->allocation.height -
450 widget->style->ythickness - size;
451 priv->activity_dir = 1;
456 priv->activity_pos -= priv->activity_step;
457 if (priv->activity_pos <= widget->style->ythickness)
459 priv->activity_pos = widget->style->ythickness;
460 priv->activity_dir = 0;
466 gtk_widget_queue_draw (widget);
470 gtk_progress_bar_finalize (GObject *object)
472 GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
473 GtkProgressBarPriv *priv = pbar->priv;
475 if (priv->offscreen_pixmap)
476 g_object_unref (priv->offscreen_pixmap);
480 G_OBJECT_CLASS (gtk_progress_bar_parent_class)->finalize (object);
484 gtk_progress_bar_expose (GtkWidget *widget,
485 GdkEventExpose *event)
487 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
488 GtkProgressBarPriv *priv = pbar->priv;
490 if (gtk_widget_is_drawable (widget))
495 gtk_progress_bar_paint (pbar);
497 cr = gdk_cairo_create (widget->window);
498 gdk_cairo_set_source_pixmap (cr, priv->offscreen_pixmap, 0, 0);
499 gdk_cairo_rectangle (cr, &event->area);
508 get_current_text (GtkProgressBar *pbar)
510 GtkProgressBarPriv *priv = pbar->priv;
513 return g_strdup (priv->text);
515 return g_strdup_printf ("%.0f %%", priv->fraction * 100.0);
519 gtk_progress_bar_size_request (GtkWidget *widget,
520 GtkRequisition *requisition)
522 GtkProgressBar *pbar;
523 GtkProgressBarPriv *priv;
525 PangoRectangle logical_rect;
528 gint xspacing, yspacing;
529 gint min_width, min_height;
531 g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
532 g_return_if_fail (requisition != NULL);
534 gtk_widget_style_get (widget,
535 "xspacing", &xspacing,
536 "yspacing", &yspacing,
539 pbar = GTK_PROGRESS_BAR (widget);
542 width = 2 * widget->style->xthickness + xspacing;
543 height = 2 * widget->style->ythickness + yspacing;
547 buf = get_current_text (pbar);
548 layout = gtk_widget_create_pango_layout (widget, buf);
550 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
554 PangoContext *context;
555 PangoFontMetrics *metrics;
558 /* The minimum size for ellipsized text is ~ 3 chars */
559 context = pango_layout_get_context (layout);
560 metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context));
562 char_width = pango_font_metrics_get_approximate_char_width (metrics);
563 pango_font_metrics_unref (metrics);
565 width += PANGO_PIXELS (char_width) * 3;
568 width += logical_rect.width;
570 height += logical_rect.height;
572 g_object_unref (layout);
576 if (priv->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
577 priv->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
578 gtk_widget_style_get (widget,
579 "min-horizontal-bar-width", &min_width,
580 "min-horizontal-bar-height", &min_height,
583 gtk_widget_style_get (widget,
584 "min-vertical-bar-width", &min_width,
585 "min-vertical-bar-height", &min_height,
588 requisition->width = MAX (min_width, width);
589 requisition->height = MAX (min_height, height);
593 gtk_progress_bar_size_allocate (GtkWidget *widget,
594 GtkAllocation *allocation)
596 widget->allocation = *allocation;
598 if (gtk_widget_get_realized (widget))
600 gdk_window_move_resize (widget->window,
601 allocation->x, allocation->y,
602 allocation->width, allocation->height);
604 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
609 gtk_progress_bar_create_pixmap (GtkProgressBar *pbar)
611 GtkProgressBarPriv *priv = pbar->priv;
612 GtkWidget *widget = GTK_WIDGET (pbar);
614 if (gtk_widget_get_realized (widget))
616 if (priv->offscreen_pixmap)
617 g_object_unref (priv->offscreen_pixmap);
619 priv->offscreen_pixmap = gdk_pixmap_new (widget->window,
620 widget->allocation.width,
621 widget->allocation.height,
624 /* clear the pixmap for transparent themes */
625 gtk_paint_flat_box (widget->style,
626 priv->offscreen_pixmap,
629 NULL, widget, "trough", 0, 0, -1, -1);
631 gtk_progress_bar_paint (pbar);
636 gtk_progress_bar_style_set (GtkWidget *widget,
639 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
640 GtkProgressBarPriv *priv = pbar->priv;
644 GTK_WIDGET_CLASS (gtk_progress_bar_parent_class)->style_set (widget, previous);
648 gtk_progress_bar_act_mode_enter (GtkProgressBar *pbar)
650 GtkProgressBarPriv *priv = pbar->priv;
651 GtkWidget *widget = GTK_WIDGET (pbar);
652 GtkProgressBarOrientation orientation;
654 orientation = priv->orientation;
655 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
657 if (priv->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
658 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
659 else if (priv->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
660 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
663 /* calculate start pos */
665 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
666 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
668 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
670 priv->activity_pos = widget->style->xthickness;
671 priv->activity_dir = 0;
675 priv->activity_pos = widget->allocation.width -
676 widget->style->xthickness - (widget->allocation.height -
677 widget->style->ythickness * 2);
678 priv->activity_dir = 1;
683 if (orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
685 priv->activity_pos = widget->style->ythickness;
686 priv->activity_dir = 0;
690 priv->activity_pos = widget->allocation.height -
691 widget->style->ythickness - (widget->allocation.width -
692 widget->style->xthickness * 2);
693 priv->activity_dir = 1;
699 gtk_progress_bar_get_activity (GtkProgressBar *pbar,
700 GtkProgressBarOrientation orientation,
704 GtkProgressBarPriv *priv = pbar->priv;
705 GtkWidget *widget = GTK_WIDGET (pbar);
707 *offset = priv->activity_pos;
711 case GTK_PROGRESS_LEFT_TO_RIGHT:
712 case GTK_PROGRESS_RIGHT_TO_LEFT:
713 *amount = MAX (2, widget->allocation.width / priv->activity_blocks);
716 case GTK_PROGRESS_TOP_TO_BOTTOM:
717 case GTK_PROGRESS_BOTTOM_TO_TOP:
718 *amount = MAX (2, widget->allocation.height / priv->activity_blocks);
724 gtk_progress_bar_paint_activity (GtkProgressBar *pbar,
725 GtkProgressBarOrientation orientation)
727 GtkProgressBarPriv *priv = pbar->priv;
728 GtkWidget *widget = GTK_WIDGET (pbar);
733 case GTK_PROGRESS_LEFT_TO_RIGHT:
734 case GTK_PROGRESS_RIGHT_TO_LEFT:
735 gtk_progress_bar_get_activity (pbar, orientation, &area.x, &area.width);
736 area.y = widget->style->ythickness;
737 area.height = widget->allocation.height - 2 * widget->style->ythickness;
740 case GTK_PROGRESS_TOP_TO_BOTTOM:
741 case GTK_PROGRESS_BOTTOM_TO_TOP:
742 gtk_progress_bar_get_activity (pbar, orientation, &area.y, &area.height);
743 area.x = widget->style->xthickness;
744 area.width = widget->allocation.width - 2 * widget->style->xthickness;
752 gtk_paint_box (widget->style,
753 priv->offscreen_pixmap,
754 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
755 &area, widget, "bar",
756 area.x, area.y, area.width, area.height);
760 gtk_progress_bar_paint_continuous (GtkProgressBar *pbar,
762 GtkProgressBarOrientation orientation)
764 GtkProgressBarPriv *priv = pbar->priv;
765 GtkWidget *widget = GTK_WIDGET (pbar);
773 case GTK_PROGRESS_LEFT_TO_RIGHT:
774 case GTK_PROGRESS_RIGHT_TO_LEFT:
776 area.height = widget->allocation.height - widget->style->ythickness * 2;
777 area.y = widget->style->ythickness;
779 area.x = widget->style->xthickness;
780 if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
781 area.x = widget->allocation.width - amount - area.x;
784 case GTK_PROGRESS_TOP_TO_BOTTOM:
785 case GTK_PROGRESS_BOTTOM_TO_TOP:
786 area.width = widget->allocation.width - widget->style->xthickness * 2;
787 area.height = amount;
788 area.x = widget->style->xthickness;
790 area.y = widget->style->ythickness;
791 if (orientation == GTK_PROGRESS_BOTTOM_TO_TOP)
792 area.y = widget->allocation.height - amount - area.y;
800 gtk_paint_box (widget->style,
801 priv->offscreen_pixmap,
802 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
803 &area, widget, "bar",
804 area.x, area.y, area.width, area.height);
808 gtk_progress_bar_paint_text (GtkProgressBar *pbar,
811 GtkProgressBarOrientation orientation)
813 GtkProgressBarPriv *priv = pbar->priv;
814 GtkWidget *widget = GTK_WIDGET (pbar);
820 PangoRectangle logical_rect;
821 GdkRectangle prelight_clip, start_clip, end_clip;
822 gfloat text_xalign = 0.5;
823 gfloat text_yalign = 0.5;
825 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
826 text_xalign = 1.0 - text_xalign;
828 buf = get_current_text (pbar);
830 layout = gtk_widget_create_pango_layout (widget, buf);
831 pango_layout_set_ellipsize (layout, priv->ellipsize);
833 pango_layout_set_width (layout, widget->allocation.width * PANGO_SCALE);
835 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
837 x = widget->style->xthickness + 1 + text_xalign *
838 (widget->allocation.width - 2 * widget->style->xthickness -
839 2 - logical_rect.width);
841 y = widget->style->ythickness + 1 + text_yalign *
842 (widget->allocation.height - 2 * widget->style->ythickness -
843 2 - logical_rect.height);
845 rect.x = widget->style->xthickness;
846 rect.y = widget->style->ythickness;
847 rect.width = widget->allocation.width - 2 * widget->style->xthickness;
848 rect.height = widget->allocation.height - 2 * widget->style->ythickness;
850 prelight_clip = start_clip = end_clip = rect;
854 case GTK_PROGRESS_LEFT_TO_RIGHT:
856 prelight_clip.x = offset;
857 prelight_clip.width = amount;
858 start_clip.width = prelight_clip.x - start_clip.x;
859 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
860 end_clip.width -= prelight_clip.width + start_clip.width;
863 case GTK_PROGRESS_RIGHT_TO_LEFT:
865 prelight_clip.x = offset;
867 prelight_clip.x = rect.x + rect.width - amount;
868 prelight_clip.width = amount;
869 start_clip.width = prelight_clip.x - start_clip.x;
870 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
871 end_clip.width -= prelight_clip.width + start_clip.width;
874 case GTK_PROGRESS_TOP_TO_BOTTOM:
876 prelight_clip.y = offset;
877 prelight_clip.height = amount;
878 start_clip.height = prelight_clip.y - start_clip.y;
879 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
880 end_clip.height -= prelight_clip.height + start_clip.height;
883 case GTK_PROGRESS_BOTTOM_TO_TOP:
885 prelight_clip.y = offset;
887 prelight_clip.y = rect.y + rect.height - amount;
888 prelight_clip.height = amount;
889 start_clip.height = prelight_clip.y - start_clip.y;
890 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
891 end_clip.height -= prelight_clip.height + start_clip.height;
895 if (start_clip.width > 0 && start_clip.height > 0)
896 gtk_paint_layout (widget->style,
897 priv->offscreen_pixmap,
906 if (end_clip.width > 0 && end_clip.height > 0)
907 gtk_paint_layout (widget->style,
908 priv->offscreen_pixmap,
917 gtk_paint_layout (widget->style,
918 priv->offscreen_pixmap,
927 g_object_unref (layout);
932 gtk_progress_bar_paint (GtkProgressBar *pbar)
934 GtkProgressBarPriv *priv = pbar->priv;
935 GtkWidget *widget = GTK_WIDGET (pbar);
936 GtkProgressBarOrientation orientation;
938 orientation = priv->orientation;
939 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
941 if (priv->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
942 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
943 else if (priv->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
944 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
947 if (priv->offscreen_pixmap)
949 gtk_paint_box (widget->style,
950 priv->offscreen_pixmap,
951 GTK_STATE_NORMAL, GTK_SHADOW_IN,
952 NULL, widget, "trough",
954 widget->allocation.width,
955 widget->allocation.height);
957 if (priv->activity_mode)
959 gtk_progress_bar_paint_activity (pbar, orientation);
966 gtk_progress_bar_get_activity (pbar, orientation, &offset, &amount);
967 gtk_progress_bar_paint_text (pbar, offset, amount, orientation);
975 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
976 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
977 space = widget->allocation.width - 2 * widget->style->xthickness;
979 space = widget->allocation.height - 2 * widget->style->ythickness;
981 amount = space * gtk_progress_bar_get_fraction (pbar);
983 gtk_progress_bar_paint_continuous (pbar, amount, orientation);
986 gtk_progress_bar_paint_text (pbar, -1, amount, orientation);
994 gtk_progress_bar_set_activity_mode (GtkProgressBar *pbar,
995 gboolean activity_mode)
997 GtkProgressBarPriv *priv = pbar->priv;
999 activity_mode = !!activity_mode;
1001 if (priv->activity_mode != activity_mode)
1003 priv->activity_mode = activity_mode;
1005 if (priv->activity_mode)
1006 GTK_PROGRESS_BAR_GET_CLASS (pbar)->act_mode_enter (pbar);
1008 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1009 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1014 * gtk_progress_bar_set_fraction:
1015 * @pbar: a #GtkProgressBar
1016 * @fraction: fraction of the task that's been completed
1018 * Causes the progress bar to "fill in" the given fraction
1019 * of the bar. The fraction should be between 0.0 and 1.0,
1024 gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
1027 GtkProgressBarPriv* priv;
1029 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1033 priv->fraction = fraction;
1034 gtk_progress_bar_set_activity_mode (pbar, FALSE);
1035 gtk_progress_bar_real_update (pbar);
1037 g_object_notify (G_OBJECT (pbar), "fraction");
1041 * gtk_progress_bar_pulse:
1042 * @pbar: a #GtkProgressBar
1044 * Indicates that some progress is made, but you don't know how much.
1045 * Causes the progress bar to enter "activity mode," where a block
1046 * bounces back and forth. Each call to gtk_progress_bar_pulse()
1047 * causes the block to move by a little bit (the amount of movement
1048 * per pulse is determined by gtk_progress_bar_set_pulse_step()).
1051 gtk_progress_bar_pulse (GtkProgressBar *pbar)
1053 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1055 gtk_progress_bar_set_activity_mode (pbar, TRUE);
1056 gtk_progress_bar_real_update (pbar);
1060 * gtk_progress_bar_set_text:
1061 * @pbar: a #GtkProgressBar
1062 * @text: (allow-none): a UTF-8 string, or %NULL
1064 * Causes the given @text to appear superimposed on the progress bar.
1067 gtk_progress_bar_set_text (GtkProgressBar *pbar,
1070 GtkProgressBarPriv *priv;
1072 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1076 g_free (priv->text);
1077 priv->text = text && *text ? g_strdup (text) : NULL;
1079 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1080 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1082 g_object_notify (G_OBJECT (pbar), "text");
1086 * gtk_progress_bar_set_show_text:
1087 * @pbar: a #GtkProgressBar
1088 * @show_text: whether to show superimposed text
1090 * Sets whether the progressbar will show text superimposed
1091 * over the bar. The shown text is either the value of
1092 * the #GtkProgressBar::text property or, if that is %NULL,
1093 * the #GtkProgressBar::fraction value, as a percentage.
1098 gtk_progress_bar_set_show_text (GtkProgressBar *pbar,
1101 GtkProgressBarPriv *priv;
1103 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1107 show_text = !!show_text;
1109 if (priv->show_text != show_text)
1111 priv->show_text = show_text;
1113 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1114 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1116 g_object_notify (G_OBJECT (pbar), "show-text");
1121 * gtk_progress_bar_get_show_text:
1122 * @pbar: a #GtkProgressBar
1124 * Gets the value of the #GtkProgressBar::show-text property.
1125 * See gtk_progress_bar_set_show_text().
1127 * Returns: %TRUE if text is shown in the progress bar
1132 gtk_progress_bar_get_show_text (GtkProgressBar *pbar)
1134 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), FALSE);
1136 return pbar->priv->show_text;
1140 * gtk_progress_bar_set_pulse_step:
1141 * @pbar: a #GtkProgressBar
1142 * @fraction: fraction between 0.0 and 1.0
1144 * Sets the fraction of total progress bar length to move the
1145 * bouncing block for each call to gtk_progress_bar_pulse().
1148 gtk_progress_bar_set_pulse_step (GtkProgressBar *pbar,
1151 GtkProgressBarPriv *priv;
1153 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1157 priv->pulse_fraction = fraction;
1159 g_object_notify (G_OBJECT (pbar), "pulse-step");
1163 * gtk_progress_bar_set_orientation:
1164 * @pbar: a #GtkProgressBar
1165 * @orientation: orientation of the progress bar
1167 * Causes the progress bar to switch to a different orientation
1168 * (left-to-right, right-to-left, top-to-bottom, or bottom-to-top).
1171 gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
1172 GtkProgressBarOrientation orientation)
1174 GtkProgressBarPriv *priv;
1176 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1180 if (priv->orientation != orientation)
1182 priv->orientation = orientation;
1184 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1185 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1187 g_object_notify (G_OBJECT (pbar), "orientation");
1192 * gtk_progress_bar_get_text:
1193 * @pbar: a #GtkProgressBar
1195 * Retrieves the text displayed superimposed on the progress bar,
1196 * if any, otherwise %NULL. The return value is a reference
1197 * to the text, not a copy of it, so will become invalid
1198 * if you change the text in the progress bar.
1200 * Return value: text, or %NULL; this string is owned by the widget
1201 * and should not be modified or freed.
1203 G_CONST_RETURN gchar*
1204 gtk_progress_bar_get_text (GtkProgressBar *pbar)
1206 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), NULL);
1208 return pbar->priv->text;
1212 * gtk_progress_bar_get_fraction:
1213 * @pbar: a #GtkProgressBar
1215 * Returns the current fraction of the task that's been completed.
1217 * Return value: a fraction from 0.0 to 1.0
1220 gtk_progress_bar_get_fraction (GtkProgressBar *pbar)
1222 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1224 return pbar->priv->fraction;
1228 * gtk_progress_bar_get_pulse_step:
1229 * @pbar: a #GtkProgressBar
1231 * Retrieves the pulse step set with gtk_progress_bar_set_pulse_step()
1233 * Return value: a fraction from 0.0 to 1.0
1236 gtk_progress_bar_get_pulse_step (GtkProgressBar *pbar)
1238 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1240 return pbar->priv->pulse_fraction;
1244 * gtk_progress_bar_get_orientation:
1245 * @pbar: a #GtkProgressBar
1247 * Retrieves the current progress bar orientation.
1249 * Return value: orientation of the progress bar
1251 GtkProgressBarOrientation
1252 gtk_progress_bar_get_orientation (GtkProgressBar *pbar)
1254 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1256 return pbar->priv->orientation;
1260 * gtk_progress_bar_set_ellipsize:
1261 * @pbar: a #GtkProgressBar
1262 * @mode: a #PangoEllipsizeMode
1264 * Sets the mode used to ellipsize (add an ellipsis: "...") the text
1265 * if there is not enough space to render the entire string.
1270 gtk_progress_bar_set_ellipsize (GtkProgressBar *pbar,
1271 PangoEllipsizeMode mode)
1273 GtkProgressBarPriv *priv;
1275 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1276 g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE &&
1277 mode <= PANGO_ELLIPSIZE_END);
1281 if ((PangoEllipsizeMode)priv->ellipsize != mode)
1283 priv->ellipsize = mode;
1285 g_object_notify (G_OBJECT (pbar), "ellipsize");
1286 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1291 * gtk_progress_bar_get_ellipsize:
1292 * @pbar: a #GtkProgressBar
1294 * Returns the ellipsizing position of the progressbar.
1295 * See gtk_progress_bar_set_ellipsize().
1297 * Return value: #PangoEllipsizeMode
1302 gtk_progress_bar_get_ellipsize (GtkProgressBar *pbar)
1304 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), PANGO_ELLIPSIZE_NONE);
1306 return pbar->priv->ellipsize;