1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
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.
18  */
19 
20 /*
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/.
25  */
26 
27 #include "config.h"
28 #include <math.h>
29 #include <string.h>
30 
31 #undef GDK_DISABLE_DEPRECATED
32 #undef GTK_DISABLE_DEPRECATED
33 #define __GTK_PROGRESS_C__
34 
35 #include "gtkprogress.h"
36 #include "gtkprivate.h"
37 #include "gtkintl.h"
38 #include "gtkalias.h"
39 
40 #define EPSILON  1e-5
41 #define DEFAULT_FORMAT "%P %%"
42 
43 enum {
44   PROP_0,
45   PROP_ACTIVITY_MODE,
46   PROP_SHOW_TEXT,
47   PROP_TEXT_XALIGN,
48   PROP_TEXT_YALIGN
49 };
50 
51 
52 static void gtk_progress_set_property    (GObject          *object,
53 					  guint             prop_id,
54 					  const GValue     *value,
55 					  GParamSpec       *pspec);
56 static void gtk_progress_get_property    (GObject          *object,
57 					  guint             prop_id,
58 					  GValue           *value,
59 					  GParamSpec       *pspec);
60 static void gtk_progress_destroy         (GtkObject        *object);
61 static void gtk_progress_finalize        (GObject          *object);
62 static void gtk_progress_realize         (GtkWidget        *widget);
63 static gboolean gtk_progress_expose      (GtkWidget        *widget,
64 				 	  GdkEventExpose   *event);
65 static void gtk_progress_size_allocate   (GtkWidget        *widget,
66 				 	  GtkAllocation    *allocation);
67 static void gtk_progress_create_pixmap   (GtkProgress      *progress);
68 static void gtk_progress_value_changed   (GtkAdjustment    *adjustment,
69 					  GtkProgress      *progress);
70 static void gtk_progress_changed         (GtkAdjustment    *adjustment,
71 					  GtkProgress      *progress);
72 
G_DEFINE_ABSTRACT_TYPE(GtkProgress,gtk_progress,GTK_TYPE_WIDGET)73 G_DEFINE_ABSTRACT_TYPE (GtkProgress, gtk_progress, GTK_TYPE_WIDGET)
74 
75 static void
76 gtk_progress_class_init (GtkProgressClass *class)
77 {
78   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
79   GtkObjectClass *object_class;
80   GtkWidgetClass *widget_class;
81 
82   object_class = (GtkObjectClass *) class;
83   widget_class = (GtkWidgetClass *) class;
84 
85   gobject_class->finalize = gtk_progress_finalize;
86 
87   gobject_class->set_property = gtk_progress_set_property;
88   gobject_class->get_property = gtk_progress_get_property;
89   object_class->destroy = gtk_progress_destroy;
90 
91   widget_class->realize = gtk_progress_realize;
92   widget_class->expose_event = gtk_progress_expose;
93   widget_class->size_allocate = gtk_progress_size_allocate;
94 
95   /* to be overridden */
96   class->paint = NULL;
97   class->update = NULL;
98   class->act_mode_enter = NULL;
99 
100   g_object_class_install_property (gobject_class,
101                                    PROP_ACTIVITY_MODE,
102                                    g_param_spec_boolean ("activity-mode",
103 							 P_("Activity mode"),
104 							 P_("If TRUE, the GtkProgress is in activity mode, meaning that it signals "
105                                                             "something is happening, but not how much of the activity is finished. "
106                                                             "This is used when you're doing something but don't know how long it will take."),
107 							 FALSE,
108 							 GTK_PARAM_READWRITE));
109   g_object_class_install_property (gobject_class,
110                                    PROP_SHOW_TEXT,
111                                    g_param_spec_boolean ("show-text",
112 							 P_("Show text"),
113 							 P_("Whether the progress is shown as text."),
114 							 FALSE,
115 							 GTK_PARAM_READWRITE));
116   g_object_class_install_property (gobject_class,
117 				   PROP_TEXT_XALIGN,
118 				   g_param_spec_float ("text-xalign",
119 						       P_("Text x alignment"),
120                                                        P_("The horizontal text alignment, from 0 (left) to 1 (right). Reversed for RTL layouts."),
121 						       0.0, 1.0, 0.5,
122 						       GTK_PARAM_READWRITE));
123   g_object_class_install_property (gobject_class,
124 				   PROP_TEXT_YALIGN,
125 				   g_param_spec_float ("text-yalign",
126 						       P_("Text y alignment"),
127                                                        P_("The vertical text alignment, from 0 (top) to 1 (bottom)."),
128 						       0.0, 1.0, 0.5,
129 						       GTK_PARAM_READWRITE));
130 }
131 
132 static void
gtk_progress_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)133 gtk_progress_set_property (GObject      *object,
134 			   guint         prop_id,
135 			   const GValue *value,
136 			   GParamSpec   *pspec)
137 {
138   GtkProgress *progress;
139 
140   progress = GTK_PROGRESS (object);
141 
142   switch (prop_id)
143     {
144     case PROP_ACTIVITY_MODE:
145       gtk_progress_set_activity_mode (progress, g_value_get_boolean (value));
146       break;
147     case PROP_SHOW_TEXT:
148       gtk_progress_set_show_text (progress, g_value_get_boolean (value));
149       break;
150     case PROP_TEXT_XALIGN:
151       gtk_progress_set_text_alignment (progress,
152 				       g_value_get_float (value),
153 				       progress->y_align);
154       break;
155     case PROP_TEXT_YALIGN:
156       gtk_progress_set_text_alignment (progress,
157 				       progress->x_align,
158 				       g_value_get_float (value));
159       break;
160     default:
161       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
162       break;
163     }
164 }
165 
166 static void
gtk_progress_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)167 gtk_progress_get_property (GObject      *object,
168 			   guint         prop_id,
169 			   GValue       *value,
170 			   GParamSpec   *pspec)
171 {
172   GtkProgress *progress;
173 
174   progress = GTK_PROGRESS (object);
175 
176   switch (prop_id)
177     {
178     case PROP_ACTIVITY_MODE:
179       g_value_set_boolean (value, (progress->activity_mode != FALSE));
180       break;
181     case PROP_SHOW_TEXT:
182       g_value_set_boolean (value, (progress->show_text != FALSE));
183       break;
184     case PROP_TEXT_XALIGN:
185       g_value_set_float (value, progress->x_align);
186       break;
187     case PROP_TEXT_YALIGN:
188       g_value_set_float (value, progress->y_align);
189       break;
190     default:
191       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
192       break;
193     }
194 }
195 
196 static void
gtk_progress_init(GtkProgress * progress)197 gtk_progress_init (GtkProgress *progress)
198 {
199   progress->adjustment = NULL;
200   progress->offscreen_pixmap = NULL;
201   progress->format = g_strdup (DEFAULT_FORMAT);
202   progress->x_align = 0.5;
203   progress->y_align = 0.5;
204   progress->show_text = FALSE;
205   progress->activity_mode = FALSE;
206   progress->use_text_format = TRUE;
207 }
208 
209 static void
gtk_progress_realize(GtkWidget * widget)210 gtk_progress_realize (GtkWidget *widget)
211 {
212   GtkProgress *progress = GTK_PROGRESS (widget);
213   GdkWindowAttr attributes;
214   gint attributes_mask;
215 
216   gtk_widget_set_realized (widget, TRUE);
217 
218   attributes.window_type = GDK_WINDOW_CHILD;
219   attributes.x = widget->allocation.x;
220   attributes.y = widget->allocation.y;
221   attributes.width = widget->allocation.width;
222   attributes.height = widget->allocation.height;
223   attributes.wclass = GDK_INPUT_OUTPUT;
224   attributes.visual = gtk_widget_get_visual (widget);
225   attributes.colormap = gtk_widget_get_colormap (widget);
226   attributes.event_mask = gtk_widget_get_events (widget);
227   attributes.event_mask |= GDK_EXPOSURE_MASK;
228 
229   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
230 
231   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
232 				   &attributes, attributes_mask);
233   gdk_window_set_user_data (widget->window, progress);
234 
235   widget->style = gtk_style_attach (widget->style, widget->window);
236   gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
237 
238   gtk_progress_create_pixmap (progress);
239 }
240 
241 static void
gtk_progress_destroy(GtkObject * object)242 gtk_progress_destroy (GtkObject *object)
243 {
244   GtkProgress *progress = GTK_PROGRESS (object);
245 
246   if (progress->adjustment)
247     {
248       g_signal_handlers_disconnect_by_func (progress->adjustment,
249 					    gtk_progress_value_changed,
250 					    progress);
251       g_signal_handlers_disconnect_by_func (progress->adjustment,
252 					    gtk_progress_changed,
253 					    progress);
254       g_object_unref (progress->adjustment);
255       progress->adjustment = NULL;
256     }
257 
258   GTK_OBJECT_CLASS (gtk_progress_parent_class)->destroy (object);
259 }
260 
261 static void
gtk_progress_finalize(GObject * object)262 gtk_progress_finalize (GObject *object)
263 {
264   GtkProgress *progress = GTK_PROGRESS (object);
265 
266   if (progress->offscreen_pixmap)
267     g_object_unref (progress->offscreen_pixmap);
268 
269   g_free (progress->format);
270 
271   G_OBJECT_CLASS (gtk_progress_parent_class)->finalize (object);
272 }
273 
274 static gboolean
gtk_progress_expose(GtkWidget * widget,GdkEventExpose * event)275 gtk_progress_expose (GtkWidget      *widget,
276 		     GdkEventExpose *event)
277 {
278   if (GTK_WIDGET_DRAWABLE (widget))
279     gdk_draw_drawable (widget->window,
280 		       widget->style->black_gc,
281 		       GTK_PROGRESS (widget)->offscreen_pixmap,
282 		       event->area.x, event->area.y,
283 		       event->area.x, event->area.y,
284 		       event->area.width,
285 		       event->area.height);
286 
287   return FALSE;
288 }
289 
290 static void
gtk_progress_size_allocate(GtkWidget * widget,GtkAllocation * allocation)291 gtk_progress_size_allocate (GtkWidget     *widget,
292 			    GtkAllocation *allocation)
293 {
294   widget->allocation = *allocation;
295 
296   if (gtk_widget_get_realized (widget))
297     {
298       gdk_window_move_resize (widget->window,
299 			      allocation->x, allocation->y,
300 			      allocation->width, allocation->height);
301 
302       gtk_progress_create_pixmap (GTK_PROGRESS (widget));
303     }
304 }
305 
306 static void
gtk_progress_create_pixmap(GtkProgress * progress)307 gtk_progress_create_pixmap (GtkProgress *progress)
308 {
309   GtkWidget *widget;
310 
311   g_return_if_fail (GTK_IS_PROGRESS (progress));
312 
313   widget = GTK_WIDGET (progress);
314 
315   if (gtk_widget_get_realized (widget))
316     {
317       if (progress->offscreen_pixmap)
318 	g_object_unref (progress->offscreen_pixmap);
319 
320       progress->offscreen_pixmap = gdk_pixmap_new (widget->window,
321 						   widget->allocation.width,
322 						   widget->allocation.height,
323 						   -1);
324 
325       /* clear the pixmap for transparent themes */
326       gtk_paint_flat_box (widget->style,
327                           progress->offscreen_pixmap,
328                           GTK_STATE_NORMAL, GTK_SHADOW_NONE,
329                           NULL, widget, "trough", 0, 0, -1, -1);
330 
331       GTK_PROGRESS_GET_CLASS (progress)->paint (progress);
332     }
333 }
334 
335 static void
gtk_progress_changed(GtkAdjustment * adjustment,GtkProgress * progress)336 gtk_progress_changed (GtkAdjustment *adjustment,
337 		      GtkProgress   *progress)
338 {
339   /* A change in the value of adjustment->upper can change
340    * the size request
341    */
342   if (progress->use_text_format && progress->show_text)
343     gtk_widget_queue_resize (GTK_WIDGET (progress));
344   else
345     GTK_PROGRESS_GET_CLASS (progress)->update (progress);
346 }
347 
348 static void
gtk_progress_value_changed(GtkAdjustment * adjustment,GtkProgress * progress)349 gtk_progress_value_changed (GtkAdjustment *adjustment,
350 			    GtkProgress   *progress)
351 {
352   GTK_PROGRESS_GET_CLASS (progress)->update (progress);
353 }
354 
355 static gchar *
gtk_progress_build_string(GtkProgress * progress,gdouble value,gdouble percentage)356 gtk_progress_build_string (GtkProgress *progress,
357 			   gdouble      value,
358 			   gdouble      percentage)
359 {
360   gchar buf[256] = { 0 };
361   gchar tmp[256] = { 0 };
362   gchar *src;
363   gchar *dest;
364   gchar fmt[10];
365 
366   src = progress->format;
367 
368   /* This is the new supported version of this function */
369   if (!progress->use_text_format)
370     return g_strdup (src);
371 
372   /* And here's all the deprecated goo. */
373 
374   dest = buf;
375 
376   while (src && *src)
377     {
378       if (*src != '%')
379 	{
380 	  *dest = *src;
381 	  dest++;
382 	}
383       else
384 	{
385 	  gchar c;
386 	  gint digits;
387 
388 	  c = *(src + sizeof(gchar));
389 	  digits = 0;
390 
391 	  if (c >= '0' && c <= '2')
392 	    {
393 	      digits = (gint) (c - '0');
394 	      src++;
395 	      c = *(src + sizeof(gchar));
396 	    }
397 
398 	  switch (c)
399 	    {
400 	    case '%':
401 	      *dest = '%';
402 	      src++;
403 	      dest++;
404 	      break;
405 	    case 'p':
406 	    case 'P':
407 	      if (digits)
408 		{
409 		  g_snprintf (fmt, sizeof (fmt), "%%.%df", digits);
410 		  g_snprintf (tmp, sizeof (tmp), fmt, 100 * percentage);
411 		}
412 	      else
413 		g_snprintf (tmp, sizeof (tmp), "%.0f", 100 * percentage);
414 	      strcat (buf, tmp);
415 	      dest = &(buf[strlen (buf)]);
416 	      src++;
417 	      break;
418 	    case 'v':
419 	    case 'V':
420 	      if (digits)
421 		{
422 		  g_snprintf (fmt, sizeof (fmt), "%%.%df", digits);
423 		  g_snprintf (tmp, sizeof (tmp), fmt, value);
424 		}
425 	      else
426 		g_snprintf (tmp, sizeof (tmp), "%.0f", value);
427 	      strcat (buf, tmp);
428 	      dest = &(buf[strlen (buf)]);
429 	      src++;
430 	      break;
431 	    case 'l':
432 	    case 'L':
433 	      if (digits)
434 		{
435 		  g_snprintf (fmt, sizeof (fmt), "%%.%df", digits);
436 		  g_snprintf (tmp, sizeof (tmp), fmt, progress->adjustment->lower);
437 		}
438 	      else
439 		g_snprintf (tmp, sizeof (tmp), "%.0f", progress->adjustment->lower);
440 	      strcat (buf, tmp);
441 	      dest = &(buf[strlen (buf)]);
442 	      src++;
443 	      break;
444 	    case 'u':
445 	    case 'U':
446 	      if (digits)
447 		{
448 		  g_snprintf (fmt, sizeof (fmt), "%%.%df", digits);
449 		  g_snprintf (tmp, sizeof (tmp), fmt, progress->adjustment->upper);
450 		}
451 	      else
452 		g_snprintf (tmp, sizeof (tmp), "%.0f", progress->adjustment->upper);
453 	      strcat (buf, tmp);
454 	      dest = &(buf[strlen (buf)]);
455 	      src++;
456 	      break;
457 	    default:
458 	      break;
459 	    }
460 	}
461       src++;
462     }
463 
464   return g_strdup (buf);
465 }
466 
467 /***************************************************************/
468 
469 void
gtk_progress_set_adjustment(GtkProgress * progress,GtkAdjustment * adjustment)470 gtk_progress_set_adjustment (GtkProgress   *progress,
471 			     GtkAdjustment *adjustment)
472 {
473   g_return_if_fail (GTK_IS_PROGRESS (progress));
474   if (adjustment)
475     g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
476   else
477     adjustment = (GtkAdjustment*) gtk_adjustment_new (0, 0, 100, 0, 0, 0);
478 
479   if (progress->adjustment != adjustment)
480     {
481       if (progress->adjustment)
482         {
483 	  g_signal_handlers_disconnect_by_func (progress->adjustment,
484 						gtk_progress_changed,
485 						progress);
486 	  g_signal_handlers_disconnect_by_func (progress->adjustment,
487 						gtk_progress_value_changed,
488 						progress);
489           g_object_unref (progress->adjustment);
490         }
491       progress->adjustment = adjustment;
492       if (adjustment)
493         {
494           g_object_ref_sink (adjustment);
495           g_signal_connect (adjustment, "changed",
496 			    G_CALLBACK (gtk_progress_changed),
497 			    progress);
498           g_signal_connect (adjustment, "value-changed",
499 			    G_CALLBACK (gtk_progress_value_changed),
500 			    progress);
501         }
502 
503       gtk_progress_changed (adjustment, progress);
504     }
505 }
506 
507 void
gtk_progress_configure(GtkProgress * progress,gdouble value,gdouble min,gdouble max)508 gtk_progress_configure (GtkProgress *progress,
509 			gdouble      value,
510 			gdouble      min,
511 			gdouble      max)
512 {
513   GtkAdjustment *adj;
514   gboolean changed = FALSE;
515 
516   g_return_if_fail (GTK_IS_PROGRESS (progress));
517   g_return_if_fail (min <= max);
518   g_return_if_fail (value >= min && value <= max);
519 
520   if (!progress->adjustment)
521     gtk_progress_set_adjustment (progress, NULL);
522   adj = progress->adjustment;
523 
524   if (fabs (adj->lower - min) > EPSILON || fabs (adj->upper - max) > EPSILON)
525     changed = TRUE;
526 
527   adj->value = value;
528   adj->lower = min;
529   adj->upper = max;
530 
531   gtk_adjustment_value_changed (adj);
532   if (changed)
533     gtk_adjustment_changed (adj);
534 }
535 
536 void
gtk_progress_set_percentage(GtkProgress * progress,gdouble percentage)537 gtk_progress_set_percentage (GtkProgress *progress,
538 			     gdouble      percentage)
539 {
540   g_return_if_fail (GTK_IS_PROGRESS (progress));
541   g_return_if_fail (percentage >= 0 && percentage <= 1.0);
542 
543   if (!progress->adjustment)
544     gtk_progress_set_adjustment (progress, NULL);
545   gtk_progress_set_value (progress, progress->adjustment->lower + percentage *
546 		 (progress->adjustment->upper - progress->adjustment->lower));
547 }
548 
549 gdouble
gtk_progress_get_current_percentage(GtkProgress * progress)550 gtk_progress_get_current_percentage (GtkProgress *progress)
551 {
552   g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
553 
554   if (!progress->adjustment)
555     gtk_progress_set_adjustment (progress, NULL);
556 
557   return gtk_progress_get_percentage_from_value (progress, progress->adjustment->value);
558 }
559 
560 gdouble
gtk_progress_get_percentage_from_value(GtkProgress * progress,gdouble value)561 gtk_progress_get_percentage_from_value (GtkProgress *progress,
562 					gdouble      value)
563 {
564   g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
565 
566   if (!progress->adjustment)
567     gtk_progress_set_adjustment (progress, NULL);
568 
569   if (progress->adjustment->lower < progress->adjustment->upper &&
570       value >= progress->adjustment->lower &&
571       value <= progress->adjustment->upper)
572     return (value - progress->adjustment->lower) /
573       (progress->adjustment->upper - progress->adjustment->lower);
574   else
575     return 0.0;
576 }
577 
578 void
gtk_progress_set_value(GtkProgress * progress,gdouble value)579 gtk_progress_set_value (GtkProgress *progress,
580 			gdouble      value)
581 {
582   g_return_if_fail (GTK_IS_PROGRESS (progress));
583 
584   if (!progress->adjustment)
585     gtk_progress_set_adjustment (progress, NULL);
586 
587   if (fabs (progress->adjustment->value - value) > EPSILON)
588     gtk_adjustment_set_value (progress->adjustment, value);
589 }
590 
591 gdouble
gtk_progress_get_value(GtkProgress * progress)592 gtk_progress_get_value (GtkProgress *progress)
593 {
594   g_return_val_if_fail (GTK_IS_PROGRESS (progress), 0);
595 
596   return progress->adjustment ? progress->adjustment->value : 0;
597 }
598 
599 void
gtk_progress_set_show_text(GtkProgress * progress,gboolean show_text)600 gtk_progress_set_show_text (GtkProgress *progress,
601 			    gboolean     show_text)
602 {
603   g_return_if_fail (GTK_IS_PROGRESS (progress));
604 
605   if (progress->show_text != show_text)
606     {
607       progress->show_text = show_text;
608 
609       gtk_widget_queue_resize (GTK_WIDGET (progress));
610 
611       g_object_notify (G_OBJECT (progress), "show-text");
612     }
613 }
614 
615 void
gtk_progress_set_text_alignment(GtkProgress * progress,gfloat x_align,gfloat y_align)616 gtk_progress_set_text_alignment (GtkProgress *progress,
617 				 gfloat       x_align,
618 				 gfloat       y_align)
619 {
620   g_return_if_fail (GTK_IS_PROGRESS (progress));
621   g_return_if_fail (x_align >= 0.0 && x_align <= 1.0);
622   g_return_if_fail (y_align >= 0.0 && y_align <= 1.0);
623 
624   if (progress->x_align != x_align || progress->y_align != y_align)
625     {
626       g_object_freeze_notify (G_OBJECT (progress));
627       if (progress->x_align != x_align)
628 	{
629 	  progress->x_align = x_align;
630 	  g_object_notify (G_OBJECT (progress), "text-xalign");
631 	}
632 
633       if (progress->y_align != y_align)
634 	{
635 	  progress->y_align = y_align;
636 	  g_object_notify (G_OBJECT (progress), "text-yalign");
637 	}
638       g_object_thaw_notify (G_OBJECT (progress));
639 
640       if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
641 	gtk_widget_queue_resize (GTK_WIDGET (progress));
642     }
643 }
644 
645 void
gtk_progress_set_format_string(GtkProgress * progress,const gchar * format)646 gtk_progress_set_format_string (GtkProgress *progress,
647 				const gchar *format)
648 {
649   gchar *old_format;
650 
651   g_return_if_fail (GTK_IS_PROGRESS (progress));
652 
653   /* Turn on format, in case someone called
654    * gtk_progress_bar_set_text() and turned it off.
655    */
656   progress->use_text_format = TRUE;
657 
658   old_format = progress->format;
659 
660   if (!format)
661     format = DEFAULT_FORMAT;
662 
663   progress->format = g_strdup (format);
664   g_free (old_format);
665 
666   gtk_widget_queue_resize (GTK_WIDGET (progress));
667 }
668 
669 gchar *
gtk_progress_get_current_text(GtkProgress * progress)670 gtk_progress_get_current_text (GtkProgress *progress)
671 {
672   g_return_val_if_fail (GTK_IS_PROGRESS (progress), NULL);
673 
674   if (!progress->adjustment)
675     gtk_progress_set_adjustment (progress, NULL);
676 
677   return gtk_progress_build_string (progress, progress->adjustment->value,
678 				    gtk_progress_get_current_percentage (progress));
679 }
680 
681 gchar *
gtk_progress_get_text_from_value(GtkProgress * progress,gdouble value)682 gtk_progress_get_text_from_value (GtkProgress *progress,
683 				  gdouble      value)
684 {
685   g_return_val_if_fail (GTK_IS_PROGRESS (progress), NULL);
686 
687   if (!progress->adjustment)
688     gtk_progress_set_adjustment (progress, NULL);
689 
690   return gtk_progress_build_string (progress, value,
691 				    gtk_progress_get_percentage_from_value (progress, value));
692 }
693 
694 void
gtk_progress_set_activity_mode(GtkProgress * progress,gboolean activity_mode)695 gtk_progress_set_activity_mode (GtkProgress *progress,
696 				gboolean     activity_mode)
697 {
698   g_return_if_fail (GTK_IS_PROGRESS (progress));
699 
700   if (progress->activity_mode != (activity_mode != FALSE))
701     {
702       progress->activity_mode = (activity_mode != FALSE);
703 
704       if (progress->activity_mode)
705 	GTK_PROGRESS_GET_CLASS (progress)->act_mode_enter (progress);
706 
707       if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (progress)))
708 	gtk_widget_queue_resize (GTK_WIDGET (progress));
709 
710       g_object_notify (G_OBJECT (progress), "activity-mode");
711     }
712 }
713 
714 #include "gtkaliasdef.c"
715