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 #undef GTK_DISABLE_DEPRECATED
32 #define __GTK_PROGRESS_BAR_C__
34 #include "gtkprogressbar.h"
35 #include "gtkprivate.h"
40 #define MIN_HORIZONTAL_BAR_WIDTH 150
41 #define MIN_HORIZONTAL_BAR_HEIGHT 20
42 #define MIN_VERTICAL_BAR_WIDTH 22
43 #define MIN_VERTICAL_BAR_HEIGHT 80
55 static void gtk_progress_bar_set_property (GObject *object,
59 static void gtk_progress_bar_get_property (GObject *object,
63 static gboolean gtk_progress_bar_expose (GtkWidget *widget,
64 GdkEventExpose *event);
65 static void gtk_progress_bar_size_request (GtkWidget *widget,
66 GtkRequisition *requisition);
67 static void gtk_progress_bar_size_allocate (GtkWidget *widget,
68 GtkAllocation *allocation);
69 static void gtk_progress_bar_style_set (GtkWidget *widget,
71 static void gtk_progress_bar_real_update (GtkProgressBar *progress);
72 static void gtk_progress_bar_paint (GtkProgressBar *progress);
73 static void gtk_progress_bar_act_mode_enter (GtkProgressBar *progress);
74 static void gtk_progress_bar_realize (GtkWidget *widget);
75 static void gtk_progress_bar_finalize (GObject *object);
76 static void gtk_progress_bar_create_pixmap (GtkProgressBar *pbar);
83 } GtkProgressBarPrivate;
85 #define GTK_PROGRESS_BAR_GET_PRIVATE(o) \
86 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PROGRESS_BAR, GtkProgressBarPrivate))
88 G_DEFINE_TYPE (GtkProgressBar, gtk_progress_bar, GTK_TYPE_WIDGET)
91 gtk_progress_bar_class_init (GtkProgressBarClass *class)
93 GObjectClass *gobject_class;
94 GtkWidgetClass *widget_class;
96 gobject_class = G_OBJECT_CLASS (class);
97 widget_class = (GtkWidgetClass *) class;
99 gobject_class->set_property = gtk_progress_bar_set_property;
100 gobject_class->get_property = gtk_progress_bar_get_property;
101 gobject_class->finalize = gtk_progress_bar_finalize;
103 widget_class->realize = gtk_progress_bar_realize;
104 widget_class->expose_event = gtk_progress_bar_expose;
105 widget_class->size_request = gtk_progress_bar_size_request;
106 widget_class->size_allocate = gtk_progress_bar_size_allocate;
107 widget_class->style_set = gtk_progress_bar_style_set;
109 class->paint = gtk_progress_bar_paint;
110 class->update = gtk_progress_bar_real_update;
111 class->act_mode_enter = gtk_progress_bar_act_mode_enter;
113 g_object_class_install_property (gobject_class,
115 g_param_spec_enum ("orientation",
117 P_("Orientation and growth direction of the progress bar"),
118 GTK_TYPE_PROGRESS_BAR_ORIENTATION,
119 GTK_PROGRESS_LEFT_TO_RIGHT,
120 GTK_PARAM_READWRITE));
122 g_object_class_install_property (gobject_class,
124 g_param_spec_double ("fraction",
126 P_("The fraction of total work that has been completed"),
128 GTK_PARAM_READWRITE));
130 g_object_class_install_property (gobject_class,
132 g_param_spec_double ("pulse-step",
134 P_("The fraction of total progress to move the bouncing block when pulsed"),
136 GTK_PARAM_READWRITE));
138 g_object_class_install_property (gobject_class,
140 g_param_spec_string ("text",
142 P_("Text to be displayed in the progress bar"),
144 GTK_PARAM_READWRITE));
146 g_object_class_install_property (gobject_class,
148 g_param_spec_boolean ("show-text",
150 P_("Whether the progress is shown as text."),
152 GTK_PARAM_READWRITE));
155 * GtkProgressBar:ellipsize:
157 * The preferred place to ellipsize the string, if the progressbar does
158 * not have enough room to display the entire string, specified as a
159 * #PangoEllisizeMode.
161 * Note that setting this property to a value other than
162 * %PANGO_ELLIPSIZE_NONE has the side-effect that the progressbar requests
163 * only enough space to display the ellipsis "...". Another means to set a
164 * progressbar's width is gtk_widget_set_size_request().
168 g_object_class_install_property (gobject_class,
170 g_param_spec_enum ("ellipsize",
172 P_("The preferred place to ellipsize the string, if the progress bar "
173 "does not have enough room to display the entire string, if at all."),
174 PANGO_TYPE_ELLIPSIZE_MODE,
175 PANGO_ELLIPSIZE_NONE,
176 GTK_PARAM_READWRITE));
177 gtk_widget_class_install_style_property (widget_class,
178 g_param_spec_int ("xspacing",
180 P_("Extra spacing applied to the width of a progress bar."),
183 gtk_widget_class_install_style_property (widget_class,
184 g_param_spec_int ("yspacing",
186 P_("Extra spacing applied to the height of a progress bar."),
191 * GtkProgressBar:min-horizontal-bar-width:
193 * The minimum horizontal width of the progress bar.
197 gtk_widget_class_install_style_property (widget_class,
198 g_param_spec_int ("min-horizontal-bar-width",
199 P_("Min horizontal bar width"),
200 P_("The minimum horizontal width of the progress bar"),
201 1, G_MAXINT, MIN_HORIZONTAL_BAR_WIDTH,
204 * GtkProgressBar:min-horizontal-bar-height:
206 * Minimum horizontal height of the progress bar.
210 gtk_widget_class_install_style_property (widget_class,
211 g_param_spec_int ("min-horizontal-bar-height",
212 P_("Min horizontal bar height"),
213 P_("Minimum horizontal height of the progress bar"),
214 1, G_MAXINT, MIN_HORIZONTAL_BAR_HEIGHT,
217 * GtkProgressBar:min-vertical-bar-width:
219 * The minimum vertical width of the progress bar.
223 gtk_widget_class_install_style_property (widget_class,
224 g_param_spec_int ("min-vertical-bar-width",
225 P_("Min vertical bar width"),
226 P_("The minimum vertical width of the progress bar"),
227 1, G_MAXINT, MIN_VERTICAL_BAR_WIDTH,
230 * GtkProgressBar:min-vertical-bar-height:
232 * The minimum vertical height of the progress bar.
236 gtk_widget_class_install_style_property (widget_class,
237 g_param_spec_int ("min-vertical-bar-height",
238 P_("Min vertical bar height"),
239 P_("The minimum vertical height of the progress bar"),
240 1, G_MAXINT, MIN_VERTICAL_BAR_HEIGHT,
243 g_type_class_add_private (class, sizeof (GtkProgressBarPrivate));
247 gtk_progress_bar_init (GtkProgressBar *pbar)
249 GtkProgressBarPrivate* priv;
253 pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
254 pbar->pulse_fraction = 0.1;
255 pbar->activity_pos = 0;
256 pbar->activity_dir = 1;
257 pbar->activity_step = 3;
258 pbar->activity_blocks = 5;
259 pbar->ellipsize = PANGO_ELLIPSIZE_NONE;
260 pbar->show_text = FALSE;
262 /* FIXME: Put priv in the structure once we break ABI */
263 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
265 priv->fraction = 0.0;
269 gtk_progress_bar_realize (GtkWidget *widget)
271 GdkWindowAttr attributes;
272 gint attributes_mask;
274 gtk_widget_set_realized (widget, TRUE);
276 attributes.window_type = GDK_WINDOW_CHILD;
277 attributes.x = widget->allocation.x;
278 attributes.y = widget->allocation.y;
279 attributes.width = widget->allocation.width;
280 attributes.height = widget->allocation.height;
281 attributes.wclass = GDK_INPUT_OUTPUT;
282 attributes.visual = gtk_widget_get_visual (widget);
283 attributes.colormap = gtk_widget_get_colormap (widget);
284 attributes.event_mask = gtk_widget_get_events (widget);
285 attributes.event_mask |= GDK_EXPOSURE_MASK;
287 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
288 widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
289 &attributes, attributes_mask);
290 gdk_window_set_user_data (widget->window, widget);
292 widget->style = gtk_style_attach (widget->style, widget->window);
293 gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
295 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
299 gtk_progress_bar_set_property (GObject *object,
304 GtkProgressBar *pbar;
306 pbar = GTK_PROGRESS_BAR (object);
310 case PROP_ORIENTATION:
311 gtk_progress_bar_set_orientation (pbar, g_value_get_enum (value));
314 gtk_progress_bar_set_fraction (pbar, g_value_get_double (value));
316 case PROP_PULSE_STEP:
317 gtk_progress_bar_set_pulse_step (pbar, g_value_get_double (value));
320 gtk_progress_bar_set_text (pbar, g_value_get_string (value));
323 gtk_progress_bar_set_show_text (pbar, g_value_get_boolean (value));
326 gtk_progress_bar_set_ellipsize (pbar, g_value_get_enum (value));
329 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
335 gtk_progress_bar_get_property (GObject *object,
340 GtkProgressBar *pbar;
341 GtkProgressBarPrivate* priv;
343 pbar = GTK_PROGRESS_BAR (object);
344 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
348 case PROP_ORIENTATION:
349 g_value_set_enum (value, pbar->orientation);
352 g_value_set_double (value, priv->fraction);
354 case PROP_PULSE_STEP:
355 g_value_set_double (value, pbar->pulse_fraction);
358 g_value_set_string (value, priv->text);
361 g_value_set_boolean (value, pbar->show_text);
364 g_value_set_enum (value, pbar->ellipsize);
367 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
373 gtk_progress_bar_new (void)
377 pbar = g_object_new (GTK_TYPE_PROGRESS_BAR, NULL);
383 gtk_progress_bar_real_update (GtkProgressBar *pbar)
387 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
389 widget = GTK_WIDGET (pbar);
391 if (pbar->activity_mode)
395 /* advance the block */
396 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
397 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
399 /* Update our activity step. */
400 pbar->activity_step = widget->allocation.width * pbar->pulse_fraction;
402 size = MAX (2, widget->allocation.width / pbar->activity_blocks);
404 if (pbar->activity_dir == 0)
406 pbar->activity_pos += pbar->activity_step;
407 if (pbar->activity_pos + size >= widget->allocation.width - widget->style->xthickness)
409 pbar->activity_pos = widget->allocation.width -
410 widget->style->xthickness - size;
411 pbar->activity_dir = 1;
416 pbar->activity_pos -= pbar->activity_step;
417 if (pbar->activity_pos <= widget->style->xthickness)
419 pbar->activity_pos = widget->style->xthickness;
420 pbar->activity_dir = 0;
426 /* Update our activity step. */
427 pbar->activity_step = widget->allocation.height * pbar->pulse_fraction;
429 size = MAX (2, widget->allocation.height / pbar->activity_blocks);
431 if (pbar->activity_dir == 0)
433 pbar->activity_pos += pbar->activity_step;
434 if (pbar->activity_pos + size >= widget->allocation.height - widget->style->ythickness)
436 pbar->activity_pos = widget->allocation.height -
437 widget->style->ythickness - size;
438 pbar->activity_dir = 1;
443 pbar->activity_pos -= pbar->activity_step;
444 if (pbar->activity_pos <= widget->style->ythickness)
446 pbar->activity_pos = widget->style->ythickness;
447 pbar->activity_dir = 0;
453 gtk_widget_queue_draw (widget);
457 gtk_progress_bar_finalize (GObject *object)
459 GtkProgressBar *pbar = GTK_PROGRESS_BAR (object);
460 GtkProgressBarPrivate *priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
462 if (pbar->offscreen_pixmap)
463 g_object_unref (pbar->offscreen_pixmap);
467 G_OBJECT_CLASS (gtk_progress_bar_parent_class)->finalize (object);
471 gtk_progress_bar_expose (GtkWidget *widget,
472 GdkEventExpose *event)
474 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
476 if (gtk_widget_is_drawable (widget))
479 gtk_progress_bar_paint (pbar);
481 gdk_draw_drawable (widget->window,
482 widget->style->black_gc,
483 pbar->offscreen_pixmap,
484 event->area.x, event->area.y,
485 event->area.x, event->area.y,
494 get_current_text (GtkProgressBar *pbar)
496 GtkProgressBarPrivate *priv;
498 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
501 return g_strdup (priv->text);
503 return g_strdup_printf ("%.0f %%", priv->fraction * 100.0);
507 gtk_progress_bar_size_request (GtkWidget *widget,
508 GtkRequisition *requisition)
510 GtkProgressBar *pbar;
511 GtkProgressBarPrivate *priv;
513 PangoRectangle logical_rect;
516 gint xspacing, yspacing;
517 gint min_width, min_height;
519 g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
520 g_return_if_fail (requisition != NULL);
522 gtk_widget_style_get (widget,
523 "xspacing", &xspacing,
524 "yspacing", &yspacing,
527 pbar = GTK_PROGRESS_BAR (widget);
528 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
530 width = 2 * widget->style->xthickness + xspacing;
531 height = 2 * widget->style->ythickness + yspacing;
535 buf = get_current_text (pbar);
536 layout = gtk_widget_create_pango_layout (widget, buf);
538 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
542 PangoContext *context;
543 PangoFontMetrics *metrics;
546 /* The minimum size for ellipsized text is ~ 3 chars */
547 context = pango_layout_get_context (layout);
548 metrics = pango_context_get_metrics (context, widget->style->font_desc, pango_context_get_language (context));
550 char_width = pango_font_metrics_get_approximate_char_width (metrics);
551 pango_font_metrics_unref (metrics);
553 width += PANGO_PIXELS (char_width) * 3;
556 width += logical_rect.width;
558 height += logical_rect.height;
560 g_object_unref (layout);
564 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
565 pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
566 gtk_widget_style_get (widget,
567 "min-horizontal-bar-width", &min_width,
568 "min-horizontal-bar-height", &min_height,
571 gtk_widget_style_get (widget,
572 "min-vertical-bar-width", &min_width,
573 "min-vertical-bar-height", &min_height,
576 requisition->width = MAX (min_width, width);
577 requisition->height = MAX (min_height, height);
581 gtk_progress_bar_size_allocate (GtkWidget *widget,
582 GtkAllocation *allocation)
584 widget->allocation = *allocation;
586 if (gtk_widget_get_realized (widget))
588 gdk_window_move_resize (widget->window,
589 allocation->x, allocation->y,
590 allocation->width, allocation->height);
592 gtk_progress_bar_create_pixmap (GTK_PROGRESS_BAR (widget));
597 gtk_progress_bar_create_pixmap (GtkProgressBar *pbar)
601 widget = GTK_WIDGET (pbar);
603 if (gtk_widget_get_realized (widget))
605 if (pbar->offscreen_pixmap)
606 g_object_unref (pbar->offscreen_pixmap);
608 pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
609 widget->allocation.width,
610 widget->allocation.height,
613 /* clear the pixmap for transparent themes */
614 gtk_paint_flat_box (widget->style,
615 pbar->offscreen_pixmap,
618 NULL, widget, "trough", 0, 0, -1, -1);
620 GTK_PROGRESS_BAR_GET_CLASS (pbar)->paint (pbar);
625 gtk_progress_bar_style_set (GtkWidget *widget,
628 GtkProgressBar *pbar = GTK_PROGRESS_BAR (widget);
632 GTK_WIDGET_CLASS (gtk_progress_bar_parent_class)->style_set (widget, previous);
636 gtk_progress_bar_act_mode_enter (GtkProgressBar *pbar)
639 GtkProgressBarOrientation orientation;
641 widget = GTK_WIDGET (pbar);
643 orientation = pbar->orientation;
644 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
646 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
647 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
648 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
649 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
652 /* calculate start pos */
654 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
655 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
657 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
659 pbar->activity_pos = widget->style->xthickness;
660 pbar->activity_dir = 0;
664 pbar->activity_pos = widget->allocation.width -
665 widget->style->xthickness - (widget->allocation.height -
666 widget->style->ythickness * 2);
667 pbar->activity_dir = 1;
672 if (orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
674 pbar->activity_pos = widget->style->ythickness;
675 pbar->activity_dir = 0;
679 pbar->activity_pos = widget->allocation.height -
680 widget->style->ythickness - (widget->allocation.width -
681 widget->style->xthickness * 2);
682 pbar->activity_dir = 1;
688 gtk_progress_bar_get_activity (GtkProgressBar *pbar,
689 GtkProgressBarOrientation orientation,
693 GtkWidget *widget = GTK_WIDGET (pbar);
695 *offset = pbar->activity_pos;
699 case GTK_PROGRESS_LEFT_TO_RIGHT:
700 case GTK_PROGRESS_RIGHT_TO_LEFT:
701 *amount = MAX (2, widget->allocation.width / pbar->activity_blocks);
704 case GTK_PROGRESS_TOP_TO_BOTTOM:
705 case GTK_PROGRESS_BOTTOM_TO_TOP:
706 *amount = MAX (2, widget->allocation.height / pbar->activity_blocks);
712 gtk_progress_bar_paint_activity (GtkProgressBar *pbar,
713 GtkProgressBarOrientation orientation)
715 GtkWidget *widget = GTK_WIDGET (pbar);
720 case GTK_PROGRESS_LEFT_TO_RIGHT:
721 case GTK_PROGRESS_RIGHT_TO_LEFT:
722 gtk_progress_bar_get_activity (pbar, orientation, &area.x, &area.width);
723 area.y = widget->style->ythickness;
724 area.height = widget->allocation.height - 2 * widget->style->ythickness;
727 case GTK_PROGRESS_TOP_TO_BOTTOM:
728 case GTK_PROGRESS_BOTTOM_TO_TOP:
729 gtk_progress_bar_get_activity (pbar, orientation, &area.y, &area.height);
730 area.x = widget->style->xthickness;
731 area.width = widget->allocation.width - 2 * widget->style->xthickness;
739 gtk_paint_box (widget->style,
740 pbar->offscreen_pixmap,
741 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
742 &area, widget, "bar",
743 area.x, area.y, area.width, area.height);
747 gtk_progress_bar_paint_continuous (GtkProgressBar *pbar,
749 GtkProgressBarOrientation orientation)
752 GtkWidget *widget = GTK_WIDGET (pbar);
759 case GTK_PROGRESS_LEFT_TO_RIGHT:
760 case GTK_PROGRESS_RIGHT_TO_LEFT:
762 area.height = widget->allocation.height - widget->style->ythickness * 2;
763 area.y = widget->style->ythickness;
765 area.x = widget->style->xthickness;
766 if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
767 area.x = widget->allocation.width - amount - area.x;
770 case GTK_PROGRESS_TOP_TO_BOTTOM:
771 case GTK_PROGRESS_BOTTOM_TO_TOP:
772 area.width = widget->allocation.width - widget->style->xthickness * 2;
773 area.height = amount;
774 area.x = widget->style->xthickness;
776 area.y = widget->style->ythickness;
777 if (orientation == GTK_PROGRESS_BOTTOM_TO_TOP)
778 area.y = widget->allocation.height - amount - area.y;
786 gtk_paint_box (widget->style,
787 pbar->offscreen_pixmap,
788 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
789 &area, widget, "bar",
790 area.x, area.y, area.width, area.height);
794 gtk_progress_bar_paint_text (GtkProgressBar *pbar,
797 GtkProgressBarOrientation orientation)
799 GtkWidget *widget = GTK_WIDGET (pbar);
805 PangoRectangle logical_rect;
806 GdkRectangle prelight_clip, start_clip, end_clip;
807 gfloat text_xalign = 0.5;
808 gfloat text_yalign = 0.5;
810 if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
811 text_xalign = 1.0 - text_xalign;
813 buf = get_current_text (pbar);
815 layout = gtk_widget_create_pango_layout (widget, buf);
816 pango_layout_set_ellipsize (layout, pbar->ellipsize);
818 pango_layout_set_width (layout, widget->allocation.width * PANGO_SCALE);
820 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
822 x = widget->style->xthickness + 1 + text_xalign *
823 (widget->allocation.width - 2 * widget->style->xthickness -
824 2 - logical_rect.width);
826 y = widget->style->ythickness + 1 + text_yalign *
827 (widget->allocation.height - 2 * widget->style->ythickness -
828 2 - logical_rect.height);
830 rect.x = widget->style->xthickness;
831 rect.y = widget->style->ythickness;
832 rect.width = widget->allocation.width - 2 * widget->style->xthickness;
833 rect.height = widget->allocation.height - 2 * widget->style->ythickness;
835 prelight_clip = start_clip = end_clip = rect;
839 case GTK_PROGRESS_LEFT_TO_RIGHT:
841 prelight_clip.x = offset;
842 prelight_clip.width = amount;
843 start_clip.width = prelight_clip.x - start_clip.x;
844 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
845 end_clip.width -= prelight_clip.width + start_clip.width;
848 case GTK_PROGRESS_RIGHT_TO_LEFT:
850 prelight_clip.x = offset;
852 prelight_clip.x = rect.x + rect.width - amount;
853 prelight_clip.width = amount;
854 start_clip.width = prelight_clip.x - start_clip.x;
855 end_clip.x = start_clip.x + start_clip.width + prelight_clip.width;
856 end_clip.width -= prelight_clip.width + start_clip.width;
859 case GTK_PROGRESS_TOP_TO_BOTTOM:
861 prelight_clip.y = offset;
862 prelight_clip.height = amount;
863 start_clip.height = prelight_clip.y - start_clip.y;
864 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
865 end_clip.height -= prelight_clip.height + start_clip.height;
868 case GTK_PROGRESS_BOTTOM_TO_TOP:
870 prelight_clip.y = offset;
872 prelight_clip.y = rect.y + rect.height - amount;
873 prelight_clip.height = amount;
874 start_clip.height = prelight_clip.y - start_clip.y;
875 end_clip.y = start_clip.y + start_clip.height + prelight_clip.height;
876 end_clip.height -= prelight_clip.height + start_clip.height;
880 if (start_clip.width > 0 && start_clip.height > 0)
881 gtk_paint_layout (widget->style,
882 pbar->offscreen_pixmap,
891 if (end_clip.width > 0 && end_clip.height > 0)
892 gtk_paint_layout (widget->style,
893 pbar->offscreen_pixmap,
902 gtk_paint_layout (widget->style,
903 pbar->offscreen_pixmap,
912 g_object_unref (layout);
917 gtk_progress_bar_paint (GtkProgressBar *pbar)
919 GtkProgressBarPrivate *priv;
921 GtkProgressBarOrientation orientation;
923 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
924 widget = GTK_WIDGET (pbar);
926 orientation = pbar->orientation;
927 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
929 if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
930 orientation = GTK_PROGRESS_RIGHT_TO_LEFT;
931 else if (pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
932 orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
935 if (pbar->offscreen_pixmap)
937 gtk_paint_box (widget->style,
938 pbar->offscreen_pixmap,
939 GTK_STATE_NORMAL, GTK_SHADOW_IN,
940 NULL, widget, "trough",
942 widget->allocation.width,
943 widget->allocation.height);
945 if (pbar->activity_mode)
947 gtk_progress_bar_paint_activity (pbar, orientation);
954 gtk_progress_bar_get_activity (pbar, orientation, &offset, &amount);
955 gtk_progress_bar_paint_text (pbar, offset, amount, orientation);
963 if (orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
964 orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
965 space = widget->allocation.width - 2 * widget->style->xthickness;
967 space = widget->allocation.height - 2 * widget->style->ythickness;
969 amount = space * gtk_progress_bar_get_fraction (pbar);
971 gtk_progress_bar_paint_continuous (pbar, amount, orientation);
974 gtk_progress_bar_paint_text (pbar, -1, amount, orientation);
982 gtk_progress_bar_set_activity_mode (GtkProgressBar *pbar,
983 gboolean activity_mode)
985 activity_mode = !!activity_mode;
987 if (pbar->activity_mode != activity_mode)
989 pbar->activity_mode = activity_mode;
991 if (pbar->activity_mode)
992 GTK_PROGRESS_BAR_GET_CLASS (pbar)->act_mode_enter (pbar);
994 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
995 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1000 * gtk_progress_bar_set_fraction:
1001 * @pbar: a #GtkProgressBar
1002 * @fraction: fraction of the task that's been completed
1004 * Causes the progress bar to "fill in" the given fraction
1005 * of the bar. The fraction should be between 0.0 and 1.0,
1010 gtk_progress_bar_set_fraction (GtkProgressBar *pbar,
1013 GtkProgressBarPrivate* priv;
1015 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1017 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1018 priv->fraction = fraction;
1019 gtk_progress_bar_set_activity_mode (pbar, FALSE);
1020 gtk_progress_bar_real_update (pbar);
1022 g_object_notify (G_OBJECT (pbar), "fraction");
1026 * gtk_progress_bar_pulse:
1027 * @pbar: a #GtkProgressBar
1029 * Indicates that some progress is made, but you don't know how much.
1030 * Causes the progress bar to enter "activity mode," where a block
1031 * bounces back and forth. Each call to gtk_progress_bar_pulse()
1032 * causes the block to move by a little bit (the amount of movement
1033 * per pulse is determined by gtk_progress_bar_set_pulse_step()).
1036 gtk_progress_bar_pulse (GtkProgressBar *pbar)
1038 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1040 gtk_progress_bar_set_activity_mode (pbar, TRUE);
1041 gtk_progress_bar_real_update (pbar);
1045 * gtk_progress_bar_set_text:
1046 * @pbar: a #GtkProgressBar
1047 * @text: (allow-none): a UTF-8 string, or %NULL
1049 * Causes the given @text to appear superimposed on the progress bar.
1052 gtk_progress_bar_set_text (GtkProgressBar *pbar,
1055 GtkProgressBarPrivate *priv;
1057 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1059 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1060 g_free (priv->text);
1061 priv->text = text && *text ? g_strdup (text) : NULL;
1063 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1064 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1066 g_object_notify (G_OBJECT (pbar), "text");
1070 * gtk_progress_bar_set_show_text:
1071 * @pbar: a #GtkProgressBar
1072 * @show_text: whether to show superimposed text
1074 * Sets whether the progressbar will show text superimposed
1075 * over the bar. The shown text is either the value of
1076 * the #GtkProgressBar::text property or, if that is %NULL,
1077 * the #GtkProgressBar::fraction value, as a percentage.
1082 gtk_progress_bar_set_show_text (GtkProgressBar *pbar,
1085 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1087 show_text = !!show_text;
1089 if (pbar->show_text != show_text)
1091 pbar->show_text = show_text;
1093 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1094 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1096 g_object_notify (G_OBJECT (pbar), "show-text");
1101 * gtk_progress_bar_get_show_text:
1102 * @pbar: a #GtkProgressBar
1104 * Gets the value of the #GtkProgressBar::show-text property.
1105 * See gtk_progress_bar_set_show_text().
1107 * Returns: %TRUE if text is shown in the progress bar
1112 gtk_progress_bar_get_show_text (GtkProgressBar *pbar)
1114 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), FALSE);
1116 return pbar->show_text;
1120 * gtk_progress_bar_set_pulse_step:
1121 * @pbar: a #GtkProgressBar
1122 * @fraction: fraction between 0.0 and 1.0
1124 * Sets the fraction of total progress bar length to move the
1125 * bouncing block for each call to gtk_progress_bar_pulse().
1128 gtk_progress_bar_set_pulse_step (GtkProgressBar *pbar,
1131 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1133 pbar->pulse_fraction = fraction;
1135 g_object_notify (G_OBJECT (pbar), "pulse-step");
1139 * gtk_progress_bar_set_orientation:
1140 * @pbar: a #GtkProgressBar
1141 * @orientation: orientation of the progress bar
1143 * Causes the progress bar to switch to a different orientation
1144 * (left-to-right, right-to-left, top-to-bottom, or bottom-to-top).
1147 gtk_progress_bar_set_orientation (GtkProgressBar *pbar,
1148 GtkProgressBarOrientation orientation)
1150 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1152 if (pbar->orientation != orientation)
1154 pbar->orientation = orientation;
1156 if (gtk_widget_is_drawable (GTK_WIDGET (pbar)))
1157 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1159 g_object_notify (G_OBJECT (pbar), "orientation");
1164 * gtk_progress_bar_get_text:
1165 * @pbar: a #GtkProgressBar
1167 * Retrieves the text displayed superimposed on the progress bar,
1168 * if any, otherwise %NULL. The return value is a reference
1169 * to the text, not a copy of it, so will become invalid
1170 * if you change the text in the progress bar.
1172 * Return value: text, or %NULL; this string is owned by the widget
1173 * and should not be modified or freed.
1175 G_CONST_RETURN gchar*
1176 gtk_progress_bar_get_text (GtkProgressBar *pbar)
1178 GtkProgressBarPrivate* priv;
1180 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), NULL);
1182 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1187 * gtk_progress_bar_get_fraction:
1188 * @pbar: a #GtkProgressBar
1190 * Returns the current fraction of the task that's been completed.
1192 * Return value: a fraction from 0.0 to 1.0
1195 gtk_progress_bar_get_fraction (GtkProgressBar *pbar)
1197 GtkProgressBarPrivate* priv;
1199 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1201 priv = GTK_PROGRESS_BAR_GET_PRIVATE (pbar);
1202 return priv->fraction;
1206 * gtk_progress_bar_get_pulse_step:
1207 * @pbar: a #GtkProgressBar
1209 * Retrieves the pulse step set with gtk_progress_bar_set_pulse_step()
1211 * Return value: a fraction from 0.0 to 1.0
1214 gtk_progress_bar_get_pulse_step (GtkProgressBar *pbar)
1216 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1218 return pbar->pulse_fraction;
1222 * gtk_progress_bar_get_orientation:
1223 * @pbar: a #GtkProgressBar
1225 * Retrieves the current progress bar orientation.
1227 * Return value: orientation of the progress bar
1229 GtkProgressBarOrientation
1230 gtk_progress_bar_get_orientation (GtkProgressBar *pbar)
1232 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), 0);
1234 return pbar->orientation;
1238 * gtk_progress_bar_set_ellipsize:
1239 * @pbar: a #GtkProgressBar
1240 * @mode: a #PangoEllipsizeMode
1242 * Sets the mode used to ellipsize (add an ellipsis: "...") the text
1243 * if there is not enough space to render the entire string.
1248 gtk_progress_bar_set_ellipsize (GtkProgressBar *pbar,
1249 PangoEllipsizeMode mode)
1251 g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
1252 g_return_if_fail (mode >= PANGO_ELLIPSIZE_NONE &&
1253 mode <= PANGO_ELLIPSIZE_END);
1255 if ((PangoEllipsizeMode)pbar->ellipsize != mode)
1257 pbar->ellipsize = mode;
1259 g_object_notify (G_OBJECT (pbar), "ellipsize");
1260 gtk_widget_queue_resize (GTK_WIDGET (pbar));
1265 * gtk_progress_bar_get_ellipsize:
1266 * @pbar: a #GtkProgressBar
1268 * Returns the ellipsizing position of the progressbar.
1269 * See gtk_progress_bar_set_ellipsize().
1271 * Return value: #PangoEllipsizeMode
1276 gtk_progress_bar_get_ellipsize (GtkProgressBar *pbar)
1278 g_return_val_if_fail (GTK_IS_PROGRESS_BAR (pbar), PANGO_ELLIPSIZE_NONE);
1280 return pbar->ellipsize;
1284 #define __GTK_PROGRESS_BAR_C__
1285 #include "gtkaliasdef.c"