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
51 static void gtk_progress_bar_set_property (GObject *object,
55 static void gtk_progress_bar_get_property (GObject *object,
59 static gboolean gtk_progress_bar_expose (GtkWidget *widget,
60 GdkEventExpose *event);
61 static void gtk_progress_bar_size_request (GtkWidget *widget,
62 GtkRequisition *requisition);
63 static void gtk_progress_bar_size_allocate (GtkWidget *widget,
64 GtkAllocation *allocation);
65 static void gtk_progress_bar_style_set (GtkWidget *widget,
67 static void gtk_progress_bar_real_update (GtkProgressBar *progress);
68 static void gtk_progress_bar_paint (GtkProgressBar *progress);
69 static void gtk_progress_bar_act_mode_enter (GtkProgressBar *progress);
70 static void gtk_progress_bar_realize (GtkWidget *widget);
71 static void gtk_progress_bar_finalize (GObject *object);
72 static void gtk_progress_bar_create_pixmap (GtkProgressBar *pbar);
79 } GtkProgressBarPrivate;
81 #define GTK_PROGRESS_BAR_GET_PRIVATE(o) \
82 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PROGRESS_BAR, GtkProgressBarPrivate))
84 G_DEFINE_TYPE (GtkProgressBar, gtk_progress_bar, GTK_TYPE_WIDGET)
87 gtk_progress_bar_class_init (GtkProgressBarClass *class)
89 GObjectClass *gobject_class;
90 GtkWidgetClass *widget_class;
92 gobject_class = G_OBJECT_CLASS (class);
93 widget_class = (GtkWidgetClass *) class;
95 gobject_class->set_property = gtk_progress_bar_set_property;
96 gobject_class->get_property = gtk_progress_bar_get_property;
97 gobject_class->finalize = gtk_progress_bar_finalize;
99 widget_class->realize = gtk_progress_bar_realize;
100 widget_class->expose_event = gtk_progress_bar_expose;
101 widget_class->size_request = gtk_progress_bar_size_request;
102 widget_class->size_allocate = gtk_progress_bar_size_allocate;
103 widget_class->style_set = gtk_progress_bar_style_set;
105 class->paint = gtk_progress_bar_paint;
106 class->update = gtk_progress_bar_real_update;
107 class->act_mode_enter = gtk_progress_bar_act_mode_enter;
109 g_object_class_install_property (gobject_class,
111 g_param_spec_enum ("orientation",
113 P_("Orientation and growth direction of the progress bar"),
114 GTK_TYPE_PROGRESS_BAR_ORIENTATION,
115 GTK_PROGRESS_LEFT_TO_RIGHT,
116 GTK_PARAM_READWRITE));
118 g_object_class_install_property (gobject_class,
120 g_param_spec_double ("fraction",
122 P_("The fraction of total work that has been completed"),
124 GTK_PARAM_READWRITE));
126 g_object_class_install_property (gobject_class,
128 g_param_spec_double ("pulse-step",
130 P_("The fraction of total progress to move the bouncing block when pulsed"),
132 GTK_PARAM_READWRITE));
134 g_object_class_install_property (gobject_class,
136 g_param_spec_string ("text",
138 P_("Text to be displayed in the progress bar"),
140 GTK_PARAM_READWRITE));
142 g_object_class_install_property (gobject_class,
144 g_param_spec_boolean ("show-text",
146 P_("Whether the progress is shown as text."),
148 GTK_PARAM_READWRITE));
151 * GtkProgressBar:ellipsize:
153 * The preferred place to ellipsize the string, if the progressbar does
154 * not have enough room to display the entire string, specified as a
155 * #PangoEllisizeMode.
157 * Note that setting this property to a value other than
158 * %PANGO_ELLIPSIZE_NONE has the side-effect that the progressbar requests
159 * only enough space to display the ellipsis "...". Another means to set a
160 * progressbar's width is gtk_widget_set_size_request().
164 g_object_class_install_property (gobject_class,
166 g_param_spec_enum ("ellipsize",
168 P_("The preferred place to ellipsize the string, if the progress bar "
169 "does not have enough room to display the entire string, if at all."),
170 PANGO_TYPE_ELLIPSIZE_MODE,
171 PANGO_ELLIPSIZE_NONE,
172 GTK_PARAM_READWRITE));
173 gtk_widget_class_install_style_property (widget_class,
174 g_param_spec_int ("xspacing",
176 P_("Extra spacing applied to the width of a progress bar."),
179 gtk_widget_class_install_style_property (widget_class,
180 g_param_spec_int ("yspacing",
182 P_("Extra spacing applied to the height of a progress bar."),
187 * GtkProgressBar:min-horizontal-bar-width:
189 * The minimum horizontal width of the progress bar.
193 gtk_widget_class_install_style_property (widget_class,
194 g_param_spec_int ("min-horizontal-bar-width",
195 P_("Min horizontal bar width"),
196 P_("The minimum horizontal width of the progress bar"),
197 1, G_MAXINT, MIN_HORIZONTAL_BAR_WIDTH,
200 * GtkProgressBar:min-horizontal-bar-height:
202 * Minimum horizontal height of the progress bar.
206 gtk_widget_class_install_style_property (widget_class,
207 g_param_spec_int ("min-horizontal-bar-height",
208 P_("Min horizontal bar height"),
209 P_("Minimum horizontal height of the progress bar"),
210 1, G_MAXINT, MIN_HORIZONTAL_BAR_HEIGHT,
213 * GtkProgressBar:min-vertical-bar-width:
215 * The minimum vertical width of the progress bar.
219 gtk_widget_class_install_style_property (widget_class,
220 g_param_spec_int ("min-vertical-bar-width",
221 P_("Min vertical bar width"),
222 P_("The minimum vertical width of the progress bar"),
223 1, G_MAXINT, MIN_VERTICAL_BAR_WIDTH,
226 * GtkProgressBar:min-vertical-bar-height:
228 * The minimum vertical height of the progress bar.
232 gtk_widget_class_install_style_property (widget_class,
233 g_param_spec_int ("min-vertical-bar-height",
234 P_("Min vertical bar height"),
235 P_("The minimum vertical height of the progress bar"),
236 1, G_MAXINT, MIN_VERTICAL_BAR_HEIGHT,
239 g_type_class_add_private (class, sizeof (GtkProgressBarPrivate));
243 gtk_progress_bar_init (GtkProgressBar *pbar)
245 GtkProgressBarPrivate* priv;
249 pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
250 pbar->pulse_fraction = 0.1;
251 pbar->activity_pos = 0;
252 pbar->activity_dir = 1;
253 pbar->activity_step = 3;
254 pbar->activity_blocks = 5;
255 pbar->ellipsize = PANGO_ELLIPSIZE_NONE;
256 pbar->show_text = FALSE;
258 /* FIXME: Put priv in the structure once we break ABI */
259 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
261 priv->fraction = 0.0;
265 gtk_progress_bar_realize (GtkWidget *widget)
267 GdkWindowAttr attributes;
268 gint attributes_mask;
270 gtk_widget_set_realized (widget, TRUE);
272 attributes.window_type = GDK_WINDOW_CHILD;
273 attributes.x = widget->allocation.x;
274 attributes.y = widget->allocation.y;
275 attributes.width = widget->allocation.width;
276 attributes.height = widget->allocation.height;
277 attributes.wclass = GDK_INPUT_OUTPUT;
278 attributes.visual = gtk_widget_get_visual (widget);
279 attributes.colormap = gtk_widget_get_colormap (widget);
280 attributes.event_mask = gtk_widget_get_events (widget);
281 attributes.event_mask |= GDK_EXPOSURE_MASK;
283 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
284 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
285 &attributes, attributes_mask);
286 gdk_window_set_user_data (widget->window, widget);
288 widget->style = gtk_style_attach (widget->style, widget->window);
289 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
291 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
295 gtk_progress_bar_set_property (GObject *object,
300 GtkProgressBar *pbar;
302 pbar = GTK_PROGRESS_BAR (object);
306 case PROP_ORIENTATION:
307 gtk_progress_bar_set_orientation (pbar, g_value_get_enum (value));
310 gtk_progress_bar_set_fraction (pbar, g_value_get_double (value));
312 case PROP_PULSE_STEP:
313 gtk_progress_bar_set_pulse_step (pbar, g_value_get_double (value));
316 gtk_progress_bar_set_text (pbar, g_value_get_string (value));
319 gtk_progress_bar_set_show_text (pbar, g_value_get_boolean (value));
322 gtk_progress_bar_set_ellipsize (pbar, g_value_get_enum (value));
325 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
331 gtk_progress_bar_get_property (GObject *object,
336 GtkProgressBar *pbar;
337 GtkProgressBarPrivate* priv;
339 pbar = GTK_PROGRESS_BAR (object);
340 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
344 case PROP_ORIENTATION:
345 g_value_set_enum (value, pbar->orientation);
348 g_value_set_double (value, priv->fraction);
350 case PROP_PULSE_STEP:
351 g_value_set_double (value, pbar->pulse_fraction);
354 g_value_set_string (value, priv->text);
357 g_value_set_boolean (value, pbar->show_text);
360 g_value_set_enum (value, pbar->ellipsize);
363 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
369 gtk_progress_bar_new (void)
373 pbar = g_object_new (GTK_TYPE_PROGRESS_BAR, NULL);
379 gtk_progress_bar_real_update (GtkProgressBar *pbar)
383 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
385 widget = GTK_WIDGET (pbar);
387 if (pbar->activity_mode)
391 /* advance the block */
392 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
393 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
395 /* Update our activity step. */
396 pbar->activity_step = widget->allocation.width * pbar->pulse_fraction;
398 size = MAX (2, widget->allocation.width / pbar->activity_blocks);
400 if (pbar->activity_dir == 0)
402 pbar->activity_pos += pbar->activity_step;
403 if (pbar->activity_pos + size >= widget->allocation.width - widget->style->xthickness)
405 pbar->activity_pos = widget->allocation.width -
406 widget->style->xthickness - size;
407 pbar->activity_dir = 1;
412 pbar->activity_pos -= pbar->activity_step;
413 if (pbar->activity_pos <= widget->style->xthickness)
415 pbar->activity_pos = widget->style->xthickness;
416 pbar->activity_dir = 0;
422 /* Update our activity step. */
423 pbar->activity_step = widget->allocation.height * pbar->pulse_fraction;
425 size = MAX (2, widget->allocation.height / pbar->activity_blocks);
427 if (pbar->activity_dir == 0)
429 pbar->activity_pos += pbar->activity_step;
430 if (pbar->activity_pos + size >= widget->allocation.height - widget->style->ythickness)
432 pbar->activity_pos = widget->allocation.height -
433 widget->style->ythickness - size;
434 pbar->activity_dir = 1;
439 pbar->activity_pos -= pbar->activity_step;
440 if (pbar->activity_pos <= widget->style->ythickness)
442 pbar->activity_pos = widget->style->ythickness;
443 pbar->activity_dir = 0;
449 gtk_widget_queue_draw (widget);
453 gtk_progress_bar_finalize (GObject *object)
455 GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
456 GtkProgressBarPrivate *priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
458 if (pbar->offscreen_pixmap)
459 g_object_unref (pbar->offscreen_pixmap);
463 G_OBJECT_CLASS (gtk_progress_bar_parent_class)->finalize (object);
467 gtk_progress_bar_expose (GtkWidget *widget,
468 GdkEventExpose *event)
470 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
472 if (gtk_widget_is_drawable (widget))
475 gtk_progress_bar_paint (pbar);
477 gdk_draw_drawable (widget->window,
478 widget->style->black_gc,
479 pbar->offscreen_pixmap,
480 event->area.x, event->area.y,
481 event->area.x, event->area.y,
490 get_current_text (GtkProgressBar *pbar)
492 GtkProgressBarPrivate *priv;
494 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
497 return g_strdup (priv->text);
499 return g_strdup_printf ("%.0f %%", priv->fraction * 100.0);
503 gtk_progress_bar_size_request (GtkWidget *widget,
504 GtkRequisition *requisition)
506 GtkProgressBar *pbar;
507 GtkProgressBarPrivate *priv;
509 PangoRectangle logical_rect;
512 gint xspacing, yspacing;
513 gint min_width, min_height;
515 g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
516 g_return_if_fail (requisition != NULL);
518 gtk_widget_style_get (widget,
519 "xspacing", &xspacing,
520 "yspacing", &yspacing,
523 pbar = GTK_PROGRESS_BAR (widget);
524 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
526 width = 2 * widget->style->xthickness + xspacing;
527 height = 2 * widget->style->ythickness + yspacing;
531 buf = get_current_text (pbar);
532 layout = gtk_widget_create_pango_layout (widget, buf);
534 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
538 PangoContext *context;
539 PangoFontMetrics *metrics;
542 /* The minimum size for ellipsized text is ~ 3 chars */
543 context = pango_layout_get_context (layout);
544 metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context));
546 char_width = pango_font_metrics_get_approximate_char_width (metrics);
547 pango_font_metrics_unref (metrics);
549 width += PANGO_PIXELS (char_width) * 3;
552 width += logical_rect.width;
554 height += logical_rect.height;
556 g_object_unref (layout);
560 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
561 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
562 gtk_widget_style_get (widget,
563 "min-horizontal-bar-width", &min_width,
564 "min-horizontal-bar-height", &min_height,
567 gtk_widget_style_get (widget,
568 "min-vertical-bar-width", &min_width,
569 "min-vertical-bar-height", &min_height,
572 requisition->width = MAX (min_width, width);
573 requisition->height = MAX (min_height, height);
577 gtk_progress_bar_size_allocate (GtkWidget *widget,
578 GtkAllocation *allocation)
580 widget->allocation = *allocation;
582 if (gtk_widget_get_realized (widget))
584 gdk_window_move_resize (widget->window,
585 allocation->x, allocation->y,
586 allocation->width, allocation->height);
588 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
593 gtk_progress_bar_create_pixmap (GtkProgressBar *pbar)
597 widget = GTK_WIDGET (pbar);
599 if (gtk_widget_get_realized (widget))
601 if (pbar->offscreen_pixmap)
602 g_object_unref (pbar->offscreen_pixmap);
604 pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
605 widget->allocation.width,
606 widget->allocation.height,
609 /* clear the pixmap for transparent themes */
610 gtk_paint_flat_box (widget->style,
611 pbar->offscreen_pixmap,
614 NULL, widget, "trough", 0, 0, -1, -1);
616 GTK_PROGRESS_BAR_GET_CLASS (pbar)->paint (pbar);
621 gtk_progress_bar_style_set (GtkWidget *widget,
624 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
628 GTK_WIDGET_CLASS (gtk_progress_bar_parent_class)->style_set (widget, previous);
632 gtk_progress_bar_act_mode_enter (GtkProgressBar *pbar)
635 GtkProgressBarOrientation orientation;
637 widget = GTK_WIDGET (pbar);
639 orientation = pbar->orientation;
640 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
642 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
643 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
644 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
645 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
648 /* calculate start pos */
650 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
651 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
653 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
655 pbar->activity_pos = widget->style->xthickness;
656 pbar->activity_dir = 0;
660 pbar->activity_pos = widget->allocation.width -
661 widget->style->xthickness - (widget->allocation.height -
662 widget->style->ythickness * 2);
663 pbar->activity_dir = 1;
668 if (orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
670 pbar->activity_pos = widget->style->ythickness;
671 pbar->activity_dir = 0;
675 pbar->activity_pos = widget->allocation.height -
676 widget->style->ythickness - (widget->allocation.width -
677 widget->style->xthickness * 2);
678 pbar->activity_dir = 1;
684 gtk_progress_bar_get_activity (GtkProgressBar *pbar,
685 GtkProgressBarOrientation orientation,
689 GtkWidget *widget = GTK_WIDGET (pbar);
691 *offset = pbar->activity_pos;
695 case GTK_PROGRESS_LEFT_TO_RIGHT:
696 case GTK_PROGRESS_RIGHT_TO_LEFT:
697 *amount = MAX (2, widget->allocation.width / pbar->activity_blocks);
700 case GTK_PROGRESS_TOP_TO_BOTTOM:
701 case GTK_PROGRESS_BOTTOM_TO_TOP:
702 *amount = MAX (2, widget->allocation.height / pbar->activity_blocks);
708 gtk_progress_bar_paint_activity (GtkProgressBar *pbar,
709 GtkProgressBarOrientation orientation)
711 GtkWidget *widget = GTK_WIDGET (pbar);
716 case GTK_PROGRESS_LEFT_TO_RIGHT:
717 case GTK_PROGRESS_RIGHT_TO_LEFT:
718 gtk_progress_bar_get_activity (pbar, orientation, &area.x, &area.width);
719 area.y = widget->style->ythickness;
720 area.height = widget->allocation.height - 2 * widget->style->ythickness;
723 case GTK_PROGRESS_TOP_TO_BOTTOM:
724 case GTK_PROGRESS_BOTTOM_TO_TOP:
725 gtk_progress_bar_get_activity (pbar, orientation, &area.y, &area.height);
726 area.x = widget->style->xthickness;
727 area.width = widget->allocation.width - 2 * widget->style->xthickness;
735 gtk_paint_box (widget->style,
736 pbar->offscreen_pixmap,
737 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
738 &area, widget, "bar",
739 area.x, area.y, area.width, area.height);
743 gtk_progress_bar_paint_continuous (GtkProgressBar *pbar,
745 GtkProgressBarOrientation orientation)
748 GtkWidget *widget = GTK_WIDGET (pbar);
755 case GTK_PROGRESS_LEFT_TO_RIGHT:
756 case GTK_PROGRESS_RIGHT_TO_LEFT:
758 area.height = widget->allocation.height - widget->style->ythickness * 2;
759 area.y = widget->style->ythickness;
761 area.x = widget->style->xthickness;
762 if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
763 area.x = widget->allocation.width - amount - area.x;
766 case GTK_PROGRESS_TOP_TO_BOTTOM:
767 case GTK_PROGRESS_BOTTOM_TO_TOP:
768 area.width = widget->allocation.width - widget->style->xthickness * 2;
769 area.height = amount;
770 area.x = widget->style->xthickness;
772 area.y = widget->style->ythickness;
773 if (orientation == GTK_PROGRESS_BOTTOM_TO_TOP)
774 area.y = widget->allocation.height - amount - area.y;
782 gtk_paint_box (widget->style,
783 pbar->offscreen_pixmap,
784 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
785 &area, widget, "bar",
786 area.x, area.y, area.width, area.height);
790 gtk_progress_bar_paint_text (GtkProgressBar *pbar,
793 GtkProgressBarOrientation orientation)
795 GtkWidget *widget = GTK_WIDGET (pbar);
801 PangoRectangle logical_rect;
802 GdkRectangle prelight_clip, start_clip, end_clip;
803 gfloat text_xalign = 0.5;
804 gfloat text_yalign = 0.5;
806 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
807 text_xalign = 1.0 - text_xalign;
809 buf = get_current_text (pbar);
811 layout = gtk_widget_create_pango_layout (widget, buf);
812 pango_layout_set_ellipsize (layout, pbar->ellipsize);
814 pango_layout_set_width (layout, widget->allocation.width * PANGO_SCALE);
816 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
818 x = widget->style->xthickness + 1 + text_xalign *
819 (widget->allocation.width - 2 * widget->style->xthickness -
820 2 - logical_rect.width);
822 y = widget->style->ythickness + 1 + text_yalign *
823 (widget->allocation.height - 2 * widget->style->ythickness -
824 2 - logical_rect.height);
826 rect.x = widget->style->xthickness;
827 rect.y = widget->style->ythickness;
828 rect.width = widget->allocation.width - 2 * widget->style->xthickness;
829 rect.height = widget->allocation.height - 2 * widget->style->ythickness;
831 prelight_clip = start_clip = end_clip = rect;
835 case GTK_PROGRESS_LEFT_TO_RIGHT:
837 prelight_clip.x = offset;
838 prelight_clip.width = amount;
839 start_clip.width = prelight_clip.x - start_clip.x;
840 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
841 end_clip.width -= prelight_clip.width + start_clip.width;
844 case GTK_PROGRESS_RIGHT_TO_LEFT:
846 prelight_clip.x = offset;
848 prelight_clip.x = rect.x + rect.width - amount;
849 prelight_clip.width = amount;
850 start_clip.width = prelight_clip.x - start_clip.x;
851 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
852 end_clip.width -= prelight_clip.width + start_clip.width;
855 case GTK_PROGRESS_TOP_TO_BOTTOM:
857 prelight_clip.y = offset;
858 prelight_clip.height = amount;
859 start_clip.height = prelight_clip.y - start_clip.y;
860 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
861 end_clip.height -= prelight_clip.height + start_clip.height;
864 case GTK_PROGRESS_BOTTOM_TO_TOP:
866 prelight_clip.y = offset;
868 prelight_clip.y = rect.y + rect.height - amount;
869 prelight_clip.height = amount;
870 start_clip.height = prelight_clip.y - start_clip.y;
871 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
872 end_clip.height -= prelight_clip.height + start_clip.height;
876 if (start_clip.width > 0 && start_clip.height > 0)
877 gtk_paint_layout (widget->style,
878 pbar->offscreen_pixmap,
887 if (end_clip.width > 0 && end_clip.height > 0)
888 gtk_paint_layout (widget->style,
889 pbar->offscreen_pixmap,
898 gtk_paint_layout (widget->style,
899 pbar->offscreen_pixmap,
908 g_object_unref (layout);
913 gtk_progress_bar_paint (GtkProgressBar *pbar)
915 GtkProgressBarPrivate *priv;
917 GtkProgressBarOrientation orientation;
919 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
920 widget = GTK_WIDGET (pbar);
922 orientation = pbar->orientation;
923 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
925 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
926 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
927 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
928 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
931 if (pbar->offscreen_pixmap)
933 gtk_paint_box (widget->style,
934 pbar->offscreen_pixmap,
935 GTK_STATE_NORMAL, GTK_SHADOW_IN,
936 NULL, widget, "trough",
938 widget->allocation.width,
939 widget->allocation.height);
941 if (pbar->activity_mode)
943 gtk_progress_bar_paint_activity (pbar, orientation);
950 gtk_progress_bar_get_activity (pbar, orientation, &offset, &amount);
951 gtk_progress_bar_paint_text (pbar, offset, amount, orientation);
959 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
960 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
961 space = widget->allocation.width - 2 * widget->style->xthickness;
963 space = widget->allocation.height - 2 * widget->style->ythickness;
965 amount = space * gtk_progress_bar_get_fraction (pbar);
967 gtk_progress_bar_paint_continuous (pbar, amount, orientation);
970 gtk_progress_bar_paint_text (pbar, -1, amount, orientation);
978 gtk_progress_bar_set_activity_mode (GtkProgressBar *pbar,
979 gboolean activity_mode)
981 activity_mode = !!activity_mode;
983 if (pbar->activity_mode != activity_mode)
985 pbar->activity_mode = activity_mode;
987 if (pbar->activity_mode)
988 GTK_PROGRESS_BAR_GET_CLASS (pbar)->act_mode_enter (pbar);
990 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
991 gtk_widget_queue_resize (GTK_WIDGET (pbar));
996 * gtk_progress_bar_set_fraction:
997 * @pbar: a #GtkProgressBar
998 * @fraction: fraction of the task that's been completed
1000 * Causes the progress bar to "fill in" the given fraction
1001 * of the bar. The fraction should be between 0.0 and 1.0,
1006 gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
1009 GtkProgressBarPrivate* priv;
1011 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1013 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1014 priv->fraction = fraction;
1015 gtk_progress_bar_set_activity_mode (pbar, FALSE);
1016 gtk_progress_bar_real_update (pbar);
1018 g_object_notify (G_OBJECT (pbar), "fraction");
1022 * gtk_progress_bar_pulse:
1023 * @pbar: a #GtkProgressBar
1025 * Indicates that some progress is made, but you don't know how much.
1026 * Causes the progress bar to enter "activity mode," where a block
1027 * bounces back and forth. Each call to gtk_progress_bar_pulse()
1028 * causes the block to move by a little bit (the amount of movement
1029 * per pulse is determined by gtk_progress_bar_set_pulse_step()).
1032 gtk_progress_bar_pulse (GtkProgressBar *pbar)
1034 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1036 gtk_progress_bar_set_activity_mode (pbar, TRUE);
1037 gtk_progress_bar_real_update (pbar);
1041 * gtk_progress_bar_set_text:
1042 * @pbar: a #GtkProgressBar
1043 * @text: (allow-none): a UTF-8 string, or %NULL
1045 * Causes the given @text to appear superimposed on the progress bar.
1048 gtk_progress_bar_set_text (GtkProgressBar *pbar,
1051 GtkProgressBarPrivate *priv;
1053 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1055 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1056 g_free (priv->text);
1057 priv->text = text && *text ? g_strdup (text) : NULL;
1059 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1060 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1062 g_object_notify (G_OBJECT (pbar), "text");
1066 * gtk_progress_bar_set_show_text:
1067 * @pbar: a #GtkProgressBar
1068 * @show_text: whether to show superimposed text
1070 * Sets whether the progressbar will show text superimposed
1071 * over the bar. The shown text is either the value of
1072 * the #GtkProgressBar::text property or, if that is %NULL,
1073 * the #GtkProgressBar::fraction value, as a percentage.
1078 gtk_progress_bar_set_show_text (GtkProgressBar *pbar,
1081 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1083 show_text = !!show_text;
1085 if (pbar->show_text != show_text)
1087 pbar->show_text = show_text;
1089 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1090 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1092 g_object_notify (G_OBJECT (pbar), "show-text");
1097 * gtk_progress_bar_get_show_text:
1098 * @pbar: a #GtkProgressBar
1100 * Gets the value of the #GtkProgressBar::show-text property.
1101 * See gtk_progress_bar_set_show_text().
1103 * Returns: %TRUE if text is shown in the progress bar
1108 gtk_progress_bar_get_show_text (GtkProgressBar *pbar)
1110 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), FALSE);
1112 return pbar->show_text;
1116 * gtk_progress_bar_set_pulse_step:
1117 * @pbar: a #GtkProgressBar
1118 * @fraction: fraction between 0.0 and 1.0
1120 * Sets the fraction of total progress bar length to move the
1121 * bouncing block for each call to gtk_progress_bar_pulse().
1124 gtk_progress_bar_set_pulse_step (GtkProgressBar *pbar,
1127 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1129 pbar->pulse_fraction = fraction;
1131 g_object_notify (G_OBJECT (pbar), "pulse-step");
1135 * gtk_progress_bar_set_orientation:
1136 * @pbar: a #GtkProgressBar
1137 * @orientation: orientation of the progress bar
1139 * Causes the progress bar to switch to a different orientation
1140 * (left-to-right, right-to-left, top-to-bottom, or bottom-to-top).
1143 gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
1144 GtkProgressBarOrientation orientation)
1146 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1148 if (pbar->orientation != orientation)
1150 pbar->orientation = orientation;
1152 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1153 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1155 g_object_notify (G_OBJECT (pbar), "orientation");
1160 * gtk_progress_bar_get_text:
1161 * @pbar: a #GtkProgressBar
1163 * Retrieves the text displayed superimposed on the progress bar,
1164 * if any, otherwise %NULL. The return value is a reference
1165 * to the text, not a copy of it, so will become invalid
1166 * if you change the text in the progress bar.
1168 * Return value: text, or %NULL; this string is owned by the widget
1169 * and should not be modified or freed.
1171 G_CONST_RETURN gchar*
1172 gtk_progress_bar_get_text (GtkProgressBar *pbar)
1174 GtkProgressBarPrivate* priv;
1176 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), NULL);
1178 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1183 * gtk_progress_bar_get_fraction:
1184 * @pbar: a #GtkProgressBar
1186 * Returns the current fraction of the task that's been completed.
1188 * Return value: a fraction from 0.0 to 1.0
1191 gtk_progress_bar_get_fraction (GtkProgressBar *pbar)
1193 GtkProgressBarPrivate* priv;
1195 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1197 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1198 return priv->fraction;
1202 * gtk_progress_bar_get_pulse_step:
1203 * @pbar: a #GtkProgressBar
1205 * Retrieves the pulse step set with gtk_progress_bar_set_pulse_step()
1207 * Return value: a fraction from 0.0 to 1.0
1210 gtk_progress_bar_get_pulse_step (GtkProgressBar *pbar)
1212 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1214 return pbar->pulse_fraction;
1218 * gtk_progress_bar_get_orientation:
1219 * @pbar: a #GtkProgressBar
1221 * Retrieves the current progress bar orientation.
1223 * Return value: orientation of the progress bar
1225 GtkProgressBarOrientation
1226 gtk_progress_bar_get_orientation (GtkProgressBar *pbar)
1228 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1230 return pbar->orientation;
1234 * gtk_progress_bar_set_ellipsize:
1235 * @pbar: a #GtkProgressBar
1236 * @mode: a #PangoEllipsizeMode
1238 * Sets the mode used to ellipsize (add an ellipsis: "...") the text
1239 * if there is not enough space to render the entire string.
1244 gtk_progress_bar_set_ellipsize (GtkProgressBar *pbar,
1245 PangoEllipsizeMode mode)
1247 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1248 g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE &&
1249 mode <= PANGO_ELLIPSIZE_END);
1251 if ((PangoEllipsizeMode)pbar->ellipsize != mode)
1253 pbar->ellipsize = mode;
1255 g_object_notify (G_OBJECT (pbar), "ellipsize");
1256 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1261 * gtk_progress_bar_get_ellipsize:
1262 * @pbar: a #GtkProgressBar
1264 * Returns the ellipsizing position of the progressbar.
1265 * See gtk_progress_bar_set_ellipsize().
1267 * Return value: #PangoEllipsizeMode
1272 gtk_progress_bar_get_ellipsize (GtkProgressBar *pbar)
1274 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), PANGO_ELLIPSIZE_NONE);
1276 return pbar->ellipsize;