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"
37 #define MIN_HORIZONTAL_BAR_WIDTH 150
38 #define MIN_HORIZONTAL_BAR_HEIGHT 20
39 #define MIN_VERTICAL_BAR_WIDTH 22
40 #define MIN_VERTICAL_BAR_HEIGHT 80
52 static void gtk_progress_bar_set_property (GObject *object,
56 static void gtk_progress_bar_get_property (GObject *object,
60 static gboolean gtk_progress_bar_expose (GtkWidget *widget,
61 GdkEventExpose *event);
62 static void gtk_progress_bar_size_request (GtkWidget *widget,
63 GtkRequisition *requisition);
64 static void gtk_progress_bar_size_allocate (GtkWidget *widget,
65 GtkAllocation *allocation);
66 static void gtk_progress_bar_style_set (GtkWidget *widget,
68 static void gtk_progress_bar_real_update (GtkProgressBar *progress);
69 static void gtk_progress_bar_paint (GtkProgressBar *progress);
70 static void gtk_progress_bar_act_mode_enter (GtkProgressBar *progress);
71 static void gtk_progress_bar_realize (GtkWidget *widget);
72 static void gtk_progress_bar_finalize (GObject *object);
73 static void gtk_progress_bar_create_pixmap (GtkProgressBar *pbar);
80 } GtkProgressBarPrivate;
82 #define GTK_PROGRESS_BAR_GET_PRIVATE(o) \
83 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PROGRESS_BAR, GtkProgressBarPrivate))
85 G_DEFINE_TYPE (GtkProgressBar, gtk_progress_bar, GTK_TYPE_WIDGET)
88 gtk_progress_bar_class_init (GtkProgressBarClass *class)
90 GObjectClass *gobject_class;
91 GtkWidgetClass *widget_class;
93 gobject_class = G_OBJECT_CLASS (class);
94 widget_class = (GtkWidgetClass *) class;
96 gobject_class->set_property = gtk_progress_bar_set_property;
97 gobject_class->get_property = gtk_progress_bar_get_property;
98 gobject_class->finalize = gtk_progress_bar_finalize;
100 widget_class->realize = gtk_progress_bar_realize;
101 widget_class->expose_event = gtk_progress_bar_expose;
102 widget_class->size_request = gtk_progress_bar_size_request;
103 widget_class->size_allocate = gtk_progress_bar_size_allocate;
104 widget_class->style_set = gtk_progress_bar_style_set;
106 class->paint = gtk_progress_bar_paint;
107 class->update = gtk_progress_bar_real_update;
108 class->act_mode_enter = gtk_progress_bar_act_mode_enter;
110 g_object_class_install_property (gobject_class,
112 g_param_spec_enum ("orientation",
114 P_("Orientation and growth direction of the progress bar"),
115 GTK_TYPE_PROGRESS_BAR_ORIENTATION,
116 GTK_PROGRESS_LEFT_TO_RIGHT,
117 GTK_PARAM_READWRITE));
119 g_object_class_install_property (gobject_class,
121 g_param_spec_double ("fraction",
123 P_("The fraction of total work that has been completed"),
125 GTK_PARAM_READWRITE));
127 g_object_class_install_property (gobject_class,
129 g_param_spec_double ("pulse-step",
131 P_("The fraction of total progress to move the bouncing block when pulsed"),
133 GTK_PARAM_READWRITE));
135 g_object_class_install_property (gobject_class,
137 g_param_spec_string ("text",
139 P_("Text to be displayed in the progress bar"),
141 GTK_PARAM_READWRITE));
143 g_object_class_install_property (gobject_class,
145 g_param_spec_boolean ("show-text",
147 P_("Whether the progress is shown as text."),
149 GTK_PARAM_READWRITE));
152 * GtkProgressBar:ellipsize:
154 * The preferred place to ellipsize the string, if the progressbar does
155 * not have enough room to display the entire string, specified as a
156 * #PangoEllisizeMode.
158 * Note that setting this property to a value other than
159 * %PANGO_ELLIPSIZE_NONE has the side-effect that the progressbar requests
160 * only enough space to display the ellipsis "...". Another means to set a
161 * progressbar's width is gtk_widget_set_size_request().
165 g_object_class_install_property (gobject_class,
167 g_param_spec_enum ("ellipsize",
169 P_("The preferred place to ellipsize the string, if the progress bar "
170 "does not have enough room to display the entire string, if at all."),
171 PANGO_TYPE_ELLIPSIZE_MODE,
172 PANGO_ELLIPSIZE_NONE,
173 GTK_PARAM_READWRITE));
174 gtk_widget_class_install_style_property (widget_class,
175 g_param_spec_int ("xspacing",
177 P_("Extra spacing applied to the width of a progress bar."),
180 gtk_widget_class_install_style_property (widget_class,
181 g_param_spec_int ("yspacing",
183 P_("Extra spacing applied to the height of a progress bar."),
188 * GtkProgressBar:min-horizontal-bar-width:
190 * The minimum horizontal width of the progress bar.
194 gtk_widget_class_install_style_property (widget_class,
195 g_param_spec_int ("min-horizontal-bar-width",
196 P_("Min horizontal bar width"),
197 P_("The minimum horizontal width of the progress bar"),
198 1, G_MAXINT, MIN_HORIZONTAL_BAR_WIDTH,
201 * GtkProgressBar:min-horizontal-bar-height:
203 * Minimum horizontal height of the progress bar.
207 gtk_widget_class_install_style_property (widget_class,
208 g_param_spec_int ("min-horizontal-bar-height",
209 P_("Min horizontal bar height"),
210 P_("Minimum horizontal height of the progress bar"),
211 1, G_MAXINT, MIN_HORIZONTAL_BAR_HEIGHT,
214 * GtkProgressBar:min-vertical-bar-width:
216 * The minimum vertical width of the progress bar.
220 gtk_widget_class_install_style_property (widget_class,
221 g_param_spec_int ("min-vertical-bar-width",
222 P_("Min vertical bar width"),
223 P_("The minimum vertical width of the progress bar"),
224 1, G_MAXINT, MIN_VERTICAL_BAR_WIDTH,
227 * GtkProgressBar:min-vertical-bar-height:
229 * The minimum vertical height of the progress bar.
233 gtk_widget_class_install_style_property (widget_class,
234 g_param_spec_int ("min-vertical-bar-height",
235 P_("Min vertical bar height"),
236 P_("The minimum vertical height of the progress bar"),
237 1, G_MAXINT, MIN_VERTICAL_BAR_HEIGHT,
240 g_type_class_add_private (class, sizeof (GtkProgressBarPrivate));
244 gtk_progress_bar_init (GtkProgressBar *pbar)
246 GtkProgressBarPrivate* priv;
250 pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
251 pbar->pulse_fraction = 0.1;
252 pbar->activity_pos = 0;
253 pbar->activity_dir = 1;
254 pbar->activity_step = 3;
255 pbar->activity_blocks = 5;
256 pbar->ellipsize = PANGO_ELLIPSIZE_NONE;
257 pbar->show_text = FALSE;
259 /* FIXME: Put priv in the structure once we break ABI */
260 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
262 priv->fraction = 0.0;
266 gtk_progress_bar_realize (GtkWidget *widget)
268 GdkWindowAttr attributes;
269 gint attributes_mask;
271 gtk_widget_set_realized (widget, TRUE);
273 attributes.window_type = GDK_WINDOW_CHILD;
274 attributes.x = widget->allocation.x;
275 attributes.y = widget->allocation.y;
276 attributes.width = widget->allocation.width;
277 attributes.height = widget->allocation.height;
278 attributes.wclass = GDK_INPUT_OUTPUT;
279 attributes.visual = gtk_widget_get_visual (widget);
280 attributes.colormap = gtk_widget_get_colormap (widget);
281 attributes.event_mask = gtk_widget_get_events (widget);
282 attributes.event_mask |= GDK_EXPOSURE_MASK;
284 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
285 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
286 &attributes, attributes_mask);
287 gdk_window_set_user_data (widget->window, widget);
289 widget->style = gtk_style_attach (widget->style, widget->window);
290 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
292 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
296 gtk_progress_bar_set_property (GObject *object,
301 GtkProgressBar *pbar;
303 pbar = GTK_PROGRESS_BAR (object);
307 case PROP_ORIENTATION:
308 gtk_progress_bar_set_orientation (pbar, g_value_get_enum (value));
311 gtk_progress_bar_set_fraction (pbar, g_value_get_double (value));
313 case PROP_PULSE_STEP:
314 gtk_progress_bar_set_pulse_step (pbar, g_value_get_double (value));
317 gtk_progress_bar_set_text (pbar, g_value_get_string (value));
320 gtk_progress_bar_set_show_text (pbar, g_value_get_boolean (value));
323 gtk_progress_bar_set_ellipsize (pbar, g_value_get_enum (value));
326 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
332 gtk_progress_bar_get_property (GObject *object,
337 GtkProgressBar *pbar;
338 GtkProgressBarPrivate* priv;
340 pbar = GTK_PROGRESS_BAR (object);
341 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
345 case PROP_ORIENTATION:
346 g_value_set_enum (value, pbar->orientation);
349 g_value_set_double (value, priv->fraction);
351 case PROP_PULSE_STEP:
352 g_value_set_double (value, pbar->pulse_fraction);
355 g_value_set_string (value, priv->text);
358 g_value_set_boolean (value, pbar->show_text);
361 g_value_set_enum (value, pbar->ellipsize);
364 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
370 gtk_progress_bar_new (void)
374 pbar = g_object_new (GTK_TYPE_PROGRESS_BAR, NULL);
380 gtk_progress_bar_real_update (GtkProgressBar *pbar)
384 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
386 widget = GTK_WIDGET (pbar);
388 if (pbar->activity_mode)
392 /* advance the block */
393 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
394 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
396 /* Update our activity step. */
397 pbar->activity_step = widget->allocation.width * pbar->pulse_fraction;
399 size = MAX (2, widget->allocation.width / pbar->activity_blocks);
401 if (pbar->activity_dir == 0)
403 pbar->activity_pos += pbar->activity_step;
404 if (pbar->activity_pos + size >= widget->allocation.width - widget->style->xthickness)
406 pbar->activity_pos = widget->allocation.width -
407 widget->style->xthickness - size;
408 pbar->activity_dir = 1;
413 pbar->activity_pos -= pbar->activity_step;
414 if (pbar->activity_pos <= widget->style->xthickness)
416 pbar->activity_pos = widget->style->xthickness;
417 pbar->activity_dir = 0;
423 /* Update our activity step. */
424 pbar->activity_step = widget->allocation.height * pbar->pulse_fraction;
426 size = MAX (2, widget->allocation.height / pbar->activity_blocks);
428 if (pbar->activity_dir == 0)
430 pbar->activity_pos += pbar->activity_step;
431 if (pbar->activity_pos + size >= widget->allocation.height - widget->style->ythickness)
433 pbar->activity_pos = widget->allocation.height -
434 widget->style->ythickness - size;
435 pbar->activity_dir = 1;
440 pbar->activity_pos -= pbar->activity_step;
441 if (pbar->activity_pos <= widget->style->ythickness)
443 pbar->activity_pos = widget->style->ythickness;
444 pbar->activity_dir = 0;
450 gtk_widget_queue_draw (widget);
454 gtk_progress_bar_finalize (GObject *object)
456 GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
457 GtkProgressBarPrivate *priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
459 if (pbar->offscreen_pixmap)
460 g_object_unref (pbar->offscreen_pixmap);
464 G_OBJECT_CLASS (gtk_progress_bar_parent_class)->finalize (object);
468 gtk_progress_bar_expose (GtkWidget *widget,
469 GdkEventExpose *event)
471 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
473 if (gtk_widget_is_drawable (widget))
476 gtk_progress_bar_paint (pbar);
478 gdk_draw_drawable (widget->window,
479 widget->style->black_gc,
480 pbar->offscreen_pixmap,
481 event->area.x, event->area.y,
482 event->area.x, event->area.y,
491 get_current_text (GtkProgressBar *pbar)
493 GtkProgressBarPrivate *priv;
495 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
498 return g_strdup (priv->text);
500 return g_strdup_printf ("%.0f %%", priv->fraction * 100.0);
504 gtk_progress_bar_size_request (GtkWidget *widget,
505 GtkRequisition *requisition)
507 GtkProgressBar *pbar;
508 GtkProgressBarPrivate *priv;
510 PangoRectangle logical_rect;
513 gint xspacing, yspacing;
514 gint min_width, min_height;
516 g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
517 g_return_if_fail (requisition != NULL);
519 gtk_widget_style_get (widget,
520 "xspacing", &xspacing,
521 "yspacing", &yspacing,
524 pbar = GTK_PROGRESS_BAR (widget);
525 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
527 width = 2 * widget->style->xthickness + xspacing;
528 height = 2 * widget->style->ythickness + yspacing;
532 buf = get_current_text (pbar);
533 layout = gtk_widget_create_pango_layout (widget, buf);
535 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
539 PangoContext *context;
540 PangoFontMetrics *metrics;
543 /* The minimum size for ellipsized text is ~ 3 chars */
544 context = pango_layout_get_context (layout);
545 metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context));
547 char_width = pango_font_metrics_get_approximate_char_width (metrics);
548 pango_font_metrics_unref (metrics);
550 width += PANGO_PIXELS (char_width) * 3;
553 width += logical_rect.width;
555 height += logical_rect.height;
557 g_object_unref (layout);
561 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
562 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
563 gtk_widget_style_get (widget,
564 "min-horizontal-bar-width", &min_width,
565 "min-horizontal-bar-height", &min_height,
568 gtk_widget_style_get (widget,
569 "min-vertical-bar-width", &min_width,
570 "min-vertical-bar-height", &min_height,
573 requisition->width = MAX (min_width, width);
574 requisition->height = MAX (min_height, height);
578 gtk_progress_bar_size_allocate (GtkWidget *widget,
579 GtkAllocation *allocation)
581 widget->allocation = *allocation;
583 if (gtk_widget_get_realized (widget))
585 gdk_window_move_resize (widget->window,
586 allocation->x, allocation->y,
587 allocation->width, allocation->height);
589 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
594 gtk_progress_bar_create_pixmap (GtkProgressBar *pbar)
598 widget = GTK_WIDGET (pbar);
600 if (gtk_widget_get_realized (widget))
602 if (pbar->offscreen_pixmap)
603 g_object_unref (pbar->offscreen_pixmap);
605 pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
606 widget->allocation.width,
607 widget->allocation.height,
610 /* clear the pixmap for transparent themes */
611 gtk_paint_flat_box (widget->style,
612 pbar->offscreen_pixmap,
615 NULL, widget, "trough", 0, 0, -1, -1);
617 GTK_PROGRESS_BAR_GET_CLASS (pbar)->paint (pbar);
622 gtk_progress_bar_style_set (GtkWidget *widget,
625 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
629 GTK_WIDGET_CLASS (gtk_progress_bar_parent_class)->style_set (widget, previous);
633 gtk_progress_bar_act_mode_enter (GtkProgressBar *pbar)
636 GtkProgressBarOrientation orientation;
638 widget = GTK_WIDGET (pbar);
640 orientation = pbar->orientation;
641 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
643 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
644 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
645 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
646 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
649 /* calculate start pos */
651 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
652 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
654 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
656 pbar->activity_pos = widget->style->xthickness;
657 pbar->activity_dir = 0;
661 pbar->activity_pos = widget->allocation.width -
662 widget->style->xthickness - (widget->allocation.height -
663 widget->style->ythickness * 2);
664 pbar->activity_dir = 1;
669 if (orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
671 pbar->activity_pos = widget->style->ythickness;
672 pbar->activity_dir = 0;
676 pbar->activity_pos = widget->allocation.height -
677 widget->style->ythickness - (widget->allocation.width -
678 widget->style->xthickness * 2);
679 pbar->activity_dir = 1;
685 gtk_progress_bar_get_activity (GtkProgressBar *pbar,
686 GtkProgressBarOrientation orientation,
690 GtkWidget *widget = GTK_WIDGET (pbar);
692 *offset = pbar->activity_pos;
696 case GTK_PROGRESS_LEFT_TO_RIGHT:
697 case GTK_PROGRESS_RIGHT_TO_LEFT:
698 *amount = MAX (2, widget->allocation.width / pbar->activity_blocks);
701 case GTK_PROGRESS_TOP_TO_BOTTOM:
702 case GTK_PROGRESS_BOTTOM_TO_TOP:
703 *amount = MAX (2, widget->allocation.height / pbar->activity_blocks);
709 gtk_progress_bar_paint_activity (GtkProgressBar *pbar,
710 GtkProgressBarOrientation orientation)
712 GtkWidget *widget = GTK_WIDGET (pbar);
717 case GTK_PROGRESS_LEFT_TO_RIGHT:
718 case GTK_PROGRESS_RIGHT_TO_LEFT:
719 gtk_progress_bar_get_activity (pbar, orientation, &area.x, &area.width);
720 area.y = widget->style->ythickness;
721 area.height = widget->allocation.height - 2 * widget->style->ythickness;
724 case GTK_PROGRESS_TOP_TO_BOTTOM:
725 case GTK_PROGRESS_BOTTOM_TO_TOP:
726 gtk_progress_bar_get_activity (pbar, orientation, &area.y, &area.height);
727 area.x = widget->style->xthickness;
728 area.width = widget->allocation.width - 2 * widget->style->xthickness;
736 gtk_paint_box (widget->style,
737 pbar->offscreen_pixmap,
738 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
739 &area, widget, "bar",
740 area.x, area.y, area.width, area.height);
744 gtk_progress_bar_paint_continuous (GtkProgressBar *pbar,
746 GtkProgressBarOrientation orientation)
749 GtkWidget *widget = GTK_WIDGET (pbar);
756 case GTK_PROGRESS_LEFT_TO_RIGHT:
757 case GTK_PROGRESS_RIGHT_TO_LEFT:
759 area.height = widget->allocation.height - widget->style->ythickness * 2;
760 area.y = widget->style->ythickness;
762 area.x = widget->style->xthickness;
763 if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
764 area.x = widget->allocation.width - amount - area.x;
767 case GTK_PROGRESS_TOP_TO_BOTTOM:
768 case GTK_PROGRESS_BOTTOM_TO_TOP:
769 area.width = widget->allocation.width - widget->style->xthickness * 2;
770 area.height = amount;
771 area.x = widget->style->xthickness;
773 area.y = widget->style->ythickness;
774 if (orientation == GTK_PROGRESS_BOTTOM_TO_TOP)
775 area.y = widget->allocation.height - amount - area.y;
783 gtk_paint_box (widget->style,
784 pbar->offscreen_pixmap,
785 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
786 &area, widget, "bar",
787 area.x, area.y, area.width, area.height);
791 gtk_progress_bar_paint_text (GtkProgressBar *pbar,
794 GtkProgressBarOrientation orientation)
796 GtkWidget *widget = GTK_WIDGET (pbar);
802 PangoRectangle logical_rect;
803 GdkRectangle prelight_clip, start_clip, end_clip;
804 gfloat text_xalign = 0.5;
805 gfloat text_yalign = 0.5;
807 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
808 text_xalign = 1.0 - text_xalign;
810 buf = get_current_text (pbar);
812 layout = gtk_widget_create_pango_layout (widget, buf);
813 pango_layout_set_ellipsize (layout, pbar->ellipsize);
815 pango_layout_set_width (layout, widget->allocation.width * PANGO_SCALE);
817 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
819 x = widget->style->xthickness + 1 + text_xalign *
820 (widget->allocation.width - 2 * widget->style->xthickness -
821 2 - logical_rect.width);
823 y = widget->style->ythickness + 1 + text_yalign *
824 (widget->allocation.height - 2 * widget->style->ythickness -
825 2 - logical_rect.height);
827 rect.x = widget->style->xthickness;
828 rect.y = widget->style->ythickness;
829 rect.width = widget->allocation.width - 2 * widget->style->xthickness;
830 rect.height = widget->allocation.height - 2 * widget->style->ythickness;
832 prelight_clip = start_clip = end_clip = rect;
836 case GTK_PROGRESS_LEFT_TO_RIGHT:
838 prelight_clip.x = offset;
839 prelight_clip.width = amount;
840 start_clip.width = prelight_clip.x - start_clip.x;
841 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
842 end_clip.width -= prelight_clip.width + start_clip.width;
845 case GTK_PROGRESS_RIGHT_TO_LEFT:
847 prelight_clip.x = offset;
849 prelight_clip.x = rect.x + rect.width - amount;
850 prelight_clip.width = amount;
851 start_clip.width = prelight_clip.x - start_clip.x;
852 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
853 end_clip.width -= prelight_clip.width + start_clip.width;
856 case GTK_PROGRESS_TOP_TO_BOTTOM:
858 prelight_clip.y = offset;
859 prelight_clip.height = amount;
860 start_clip.height = prelight_clip.y - start_clip.y;
861 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
862 end_clip.height -= prelight_clip.height + start_clip.height;
865 case GTK_PROGRESS_BOTTOM_TO_TOP:
867 prelight_clip.y = offset;
869 prelight_clip.y = rect.y + rect.height - amount;
870 prelight_clip.height = amount;
871 start_clip.height = prelight_clip.y - start_clip.y;
872 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
873 end_clip.height -= prelight_clip.height + start_clip.height;
877 if (start_clip.width > 0 && start_clip.height > 0)
878 gtk_paint_layout (widget->style,
879 pbar->offscreen_pixmap,
888 if (end_clip.width > 0 && end_clip.height > 0)
889 gtk_paint_layout (widget->style,
890 pbar->offscreen_pixmap,
899 gtk_paint_layout (widget->style,
900 pbar->offscreen_pixmap,
909 g_object_unref (layout);
914 gtk_progress_bar_paint (GtkProgressBar *pbar)
916 GtkProgressBarPrivate *priv;
918 GtkProgressBarOrientation orientation;
920 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
921 widget = GTK_WIDGET (pbar);
923 orientation = pbar->orientation;
924 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
926 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
927 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
928 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
929 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
932 if (pbar->offscreen_pixmap)
934 gtk_paint_box (widget->style,
935 pbar->offscreen_pixmap,
936 GTK_STATE_NORMAL, GTK_SHADOW_IN,
937 NULL, widget, "trough",
939 widget->allocation.width,
940 widget->allocation.height);
942 if (pbar->activity_mode)
944 gtk_progress_bar_paint_activity (pbar, orientation);
951 gtk_progress_bar_get_activity (pbar, orientation, &offset, &amount);
952 gtk_progress_bar_paint_text (pbar, offset, amount, orientation);
960 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
961 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
962 space = widget->allocation.width - 2 * widget->style->xthickness;
964 space = widget->allocation.height - 2 * widget->style->ythickness;
966 amount = space * gtk_progress_bar_get_fraction (pbar);
968 gtk_progress_bar_paint_continuous (pbar, amount, orientation);
971 gtk_progress_bar_paint_text (pbar, -1, amount, orientation);
979 gtk_progress_bar_set_activity_mode (GtkProgressBar *pbar,
980 gboolean activity_mode)
982 activity_mode = !!activity_mode;
984 if (pbar->activity_mode != activity_mode)
986 pbar->activity_mode = activity_mode;
988 if (pbar->activity_mode)
989 GTK_PROGRESS_BAR_GET_CLASS (pbar)->act_mode_enter (pbar);
991 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
992 gtk_widget_queue_resize (GTK_WIDGET (pbar));
997 * gtk_progress_bar_set_fraction:
998 * @pbar: a #GtkProgressBar
999 * @fraction: fraction of the task that's been completed
1001 * Causes the progress bar to "fill in" the given fraction
1002 * of the bar. The fraction should be between 0.0 and 1.0,
1007 gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
1010 GtkProgressBarPrivate* priv;
1012 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1014 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1015 priv->fraction = fraction;
1016 gtk_progress_bar_set_activity_mode (pbar, FALSE);
1017 gtk_progress_bar_real_update (pbar);
1019 g_object_notify (G_OBJECT (pbar), "fraction");
1023 * gtk_progress_bar_pulse:
1024 * @pbar: a #GtkProgressBar
1026 * Indicates that some progress is made, but you don't know how much.
1027 * Causes the progress bar to enter "activity mode," where a block
1028 * bounces back and forth. Each call to gtk_progress_bar_pulse()
1029 * causes the block to move by a little bit (the amount of movement
1030 * per pulse is determined by gtk_progress_bar_set_pulse_step()).
1033 gtk_progress_bar_pulse (GtkProgressBar *pbar)
1035 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1037 gtk_progress_bar_set_activity_mode (pbar, TRUE);
1038 gtk_progress_bar_real_update (pbar);
1042 * gtk_progress_bar_set_text:
1043 * @pbar: a #GtkProgressBar
1044 * @text: (allow-none): a UTF-8 string, or %NULL
1046 * Causes the given @text to appear superimposed on the progress bar.
1049 gtk_progress_bar_set_text (GtkProgressBar *pbar,
1052 GtkProgressBarPrivate *priv;
1054 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1056 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1057 g_free (priv->text);
1058 priv->text = text && *text ? g_strdup (text) : NULL;
1060 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1061 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1063 g_object_notify (G_OBJECT (pbar), "text");
1067 * gtk_progress_bar_set_show_text:
1068 * @pbar: a #GtkProgressBar
1069 * @show_text: whether to show superimposed text
1071 * Sets whether the progressbar will show text superimposed
1072 * over the bar. The shown text is either the value of
1073 * the #GtkProgressBar::text property or, if that is %NULL,
1074 * the #GtkProgressBar::fraction value, as a percentage.
1079 gtk_progress_bar_set_show_text (GtkProgressBar *pbar,
1082 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1084 show_text = !!show_text;
1086 if (pbar->show_text != show_text)
1088 pbar->show_text = show_text;
1090 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1091 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1093 g_object_notify (G_OBJECT (pbar), "show-text");
1098 * gtk_progress_bar_get_show_text:
1099 * @pbar: a #GtkProgressBar
1101 * Gets the value of the #GtkProgressBar::show-text property.
1102 * See gtk_progress_bar_set_show_text().
1104 * Returns: %TRUE if text is shown in the progress bar
1109 gtk_progress_bar_get_show_text (GtkProgressBar *pbar)
1111 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), FALSE);
1113 return pbar->show_text;
1117 * gtk_progress_bar_set_pulse_step:
1118 * @pbar: a #GtkProgressBar
1119 * @fraction: fraction between 0.0 and 1.0
1121 * Sets the fraction of total progress bar length to move the
1122 * bouncing block for each call to gtk_progress_bar_pulse().
1125 gtk_progress_bar_set_pulse_step (GtkProgressBar *pbar,
1128 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1130 pbar->pulse_fraction = fraction;
1132 g_object_notify (G_OBJECT (pbar), "pulse-step");
1136 * gtk_progress_bar_set_orientation:
1137 * @pbar: a #GtkProgressBar
1138 * @orientation: orientation of the progress bar
1140 * Causes the progress bar to switch to a different orientation
1141 * (left-to-right, right-to-left, top-to-bottom, or bottom-to-top).
1144 gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
1145 GtkProgressBarOrientation orientation)
1147 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1149 if (pbar->orientation != orientation)
1151 pbar->orientation = orientation;
1153 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1154 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1156 g_object_notify (G_OBJECT (pbar), "orientation");
1161 * gtk_progress_bar_get_text:
1162 * @pbar: a #GtkProgressBar
1164 * Retrieves the text displayed superimposed on the progress bar,
1165 * if any, otherwise %NULL. The return value is a reference
1166 * to the text, not a copy of it, so will become invalid
1167 * if you change the text in the progress bar.
1169 * Return value: text, or %NULL; this string is owned by the widget
1170 * and should not be modified or freed.
1172 G_CONST_RETURN gchar*
1173 gtk_progress_bar_get_text (GtkProgressBar *pbar)
1175 GtkProgressBarPrivate* priv;
1177 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), NULL);
1179 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1184 * gtk_progress_bar_get_fraction:
1185 * @pbar: a #GtkProgressBar
1187 * Returns the current fraction of the task that's been completed.
1189 * Return value: a fraction from 0.0 to 1.0
1192 gtk_progress_bar_get_fraction (GtkProgressBar *pbar)
1194 GtkProgressBarPrivate* priv;
1196 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1198 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1199 return priv->fraction;
1203 * gtk_progress_bar_get_pulse_step:
1204 * @pbar: a #GtkProgressBar
1206 * Retrieves the pulse step set with gtk_progress_bar_set_pulse_step()
1208 * Return value: a fraction from 0.0 to 1.0
1211 gtk_progress_bar_get_pulse_step (GtkProgressBar *pbar)
1213 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1215 return pbar->pulse_fraction;
1219 * gtk_progress_bar_get_orientation:
1220 * @pbar: a #GtkProgressBar
1222 * Retrieves the current progress bar orientation.
1224 * Return value: orientation of the progress bar
1226 GtkProgressBarOrientation
1227 gtk_progress_bar_get_orientation (GtkProgressBar *pbar)
1229 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1231 return pbar->orientation;
1235 * gtk_progress_bar_set_ellipsize:
1236 * @pbar: a #GtkProgressBar
1237 * @mode: a #PangoEllipsizeMode
1239 * Sets the mode used to ellipsize (add an ellipsis: "...") the text
1240 * if there is not enough space to render the entire string.
1245 gtk_progress_bar_set_ellipsize (GtkProgressBar *pbar,
1246 PangoEllipsizeMode mode)
1248 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1249 g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE &&
1250 mode <= PANGO_ELLIPSIZE_END);
1252 if ((PangoEllipsizeMode)pbar->ellipsize != mode)
1254 pbar->ellipsize = mode;
1256 g_object_notify (G_OBJECT (pbar), "ellipsize");
1257 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1262 * gtk_progress_bar_get_ellipsize:
1263 * @pbar: a #GtkProgressBar
1265 * Returns the ellipsizing position of the progressbar.
1266 * See gtk_progress_bar_set_ellipsize().
1268 * Return value: #PangoEllipsizeMode
1273 gtk_progress_bar_get_ellipsize (GtkProgressBar *pbar)
1275 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), PANGO_ELLIPSIZE_NONE);
1277 return pbar->ellipsize;
1281 #define __GTK_PROGRESS_BAR_C__
1282 #include "gtkaliasdef.c"