gtkprogressbar.c 21.8 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
15
16
17
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
18
 */
19

20
21
22
23
24
25
26
/*
 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

27
28
29
30
31
32
33
34
35
36
#if HAVE_CONFIG_H
#  include <config.h>
#  if STDC_HEADERS
#    include <string.h>
#    include <stdio.h>
#  endif
#else
#  include <stdio.h>
#endif

Elliot Lee's avatar
Elliot Lee committed
37
#include "gtkprogressbar.h"
38
#include "gtksignal.h"
Elliot Lee's avatar
Elliot Lee committed
39
40


41
42
43
44
45
46
#define MIN_HORIZONTAL_BAR_WIDTH   150
#define MIN_HORIZONTAL_BAR_HEIGHT  20
#define MIN_VERTICAL_BAR_WIDTH     22
#define MIN_VERTICAL_BAR_HEIGHT    80
#define MAX_TEXT_LENGTH            80
#define TEXT_SPACING               2
Elliot Lee's avatar
Elliot Lee committed
47

48
49
50
51
52
53
54
55
56
enum {
  ARG_0,
  ARG_ADJUSTMENT,
  ARG_ORIENTATION,
  ARG_BAR_STYLE,
  ARG_ACTIVITY_STEP,
  ARG_ACTIVITY_BLOCKS,
  ARG_DISCRETE_BLOCKS
};
Elliot Lee's avatar
Elliot Lee committed
57
58
59

static void gtk_progress_bar_class_init    (GtkProgressBarClass *klass);
static void gtk_progress_bar_init          (GtkProgressBar      *pbar);
60
61
62
63
64
65
static void gtk_progress_bar_set_arg       (GtkObject           *object,
					    GtkArg              *arg,
					    guint                arg_id);
static void gtk_progress_bar_get_arg       (GtkObject           *object,
					    GtkArg              *arg,
					    guint                arg_id);
66
67
68
69
70
static void gtk_progress_bar_size_request  (GtkWidget           *widget,
					    GtkRequisition      *requisition);
static void gtk_progress_bar_real_update   (GtkProgress         *progress);
static void gtk_progress_bar_paint         (GtkProgress         *progress);
static void gtk_progress_bar_act_mode_enter (GtkProgress        *progress);
Elliot Lee's avatar
Elliot Lee committed
71
72


73
GtkType
74
gtk_progress_bar_get_type (void)
Elliot Lee's avatar
Elliot Lee committed
75
{
76
  static GtkType progress_bar_type = 0;
Elliot Lee's avatar
Elliot Lee committed
77
78
79

  if (!progress_bar_type)
    {
80
      static const GtkTypeInfo progress_bar_info =
Elliot Lee's avatar
Elliot Lee committed
81
82
83
84
85
86
      {
	"GtkProgressBar",
	sizeof (GtkProgressBar),
	sizeof (GtkProgressBarClass),
	(GtkClassInitFunc) gtk_progress_bar_class_init,
	(GtkObjectInitFunc) gtk_progress_bar_init,
87
        /* reserved_1 */ NULL,
88
        /* reserved_2 */ NULL,
89
        (GtkClassInitFunc) NULL
Elliot Lee's avatar
Elliot Lee committed
90
91
      };

92
      progress_bar_type = gtk_type_unique (GTK_TYPE_PROGRESS, &progress_bar_info);
Elliot Lee's avatar
Elliot Lee committed
93
94
95
96
97
98
99
100
    }

  return progress_bar_type;
}

static void
gtk_progress_bar_class_init (GtkProgressBarClass *class)
{
101
  GtkObjectClass *object_class;
Elliot Lee's avatar
Elliot Lee committed
102
  GtkWidgetClass *widget_class;
103
  GtkProgressClass *progress_class;
104
105
  
  object_class = (GtkObjectClass *) class;
106
107
  widget_class = (GtkWidgetClass *) class;
  progress_class = (GtkProgressClass *) class;
108
109
110
  
  gtk_object_add_arg_type ("GtkProgressBar::adjustment",
			   GTK_TYPE_ADJUSTMENT,
111
			   GTK_ARG_READWRITE,
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
			   ARG_ADJUSTMENT);
  gtk_object_add_arg_type ("GtkProgressBar::orientation",
			   GTK_TYPE_PROGRESS_BAR_ORIENTATION,
			   GTK_ARG_READWRITE,
			   ARG_ORIENTATION);
  gtk_object_add_arg_type ("GtkProgressBar::bar_style",
			   GTK_TYPE_PROGRESS_BAR_STYLE,
			   GTK_ARG_READWRITE,
			   ARG_BAR_STYLE);
  gtk_object_add_arg_type ("GtkProgressBar::activity_step",
			   GTK_TYPE_UINT,
			   GTK_ARG_READWRITE,
			   ARG_ACTIVITY_STEP);
  gtk_object_add_arg_type ("GtkProgressBar::activity_blocks",
			   GTK_TYPE_UINT,
			   GTK_ARG_READWRITE,
			   ARG_ACTIVITY_BLOCKS);
  gtk_object_add_arg_type ("GtkProgressBar::discrete_blocks",
			   GTK_TYPE_UINT,
			   GTK_ARG_READWRITE,
			   ARG_DISCRETE_BLOCKS);

  object_class->set_arg = gtk_progress_bar_set_arg;
  object_class->get_arg = gtk_progress_bar_get_arg;
Elliot Lee's avatar
Elliot Lee committed
136

137
  widget_class->size_request = gtk_progress_bar_size_request;
Elliot Lee's avatar
Elliot Lee committed
138

139
140
141
  progress_class->paint = gtk_progress_bar_paint;
  progress_class->update = gtk_progress_bar_real_update;
  progress_class->act_mode_enter = gtk_progress_bar_act_mode_enter;
Elliot Lee's avatar
Elliot Lee committed
142
143
144
145
146
}

static void
gtk_progress_bar_init (GtkProgressBar *pbar)
{
147
148
149
150
151
152
153
  pbar->bar_style = GTK_PROGRESS_CONTINUOUS;
  pbar->blocks = 10;
  pbar->in_block = -1;
  pbar->orientation = GTK_PROGRESS_LEFT_TO_RIGHT;
  pbar->activity_pos = 0;
  pbar->activity_dir = 1;
  pbar->activity_step = 3;
154
  pbar->activity_blocks = 5;
Elliot Lee's avatar
Elliot Lee committed
155
156
}

157
158
159
160
161
162
163
164
static void
gtk_progress_bar_set_arg (GtkObject           *object,
			  GtkArg              *arg,
			  guint                arg_id)
{
  GtkProgressBar *pbar;

  pbar = GTK_PROGRESS_BAR (object);
Elliot Lee's avatar
Elliot Lee committed
165

166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  switch (arg_id)
    {
    case ARG_ADJUSTMENT:
      gtk_progress_set_adjustment (GTK_PROGRESS (pbar), GTK_VALUE_POINTER (*arg));
      break;
    case ARG_ORIENTATION:
      gtk_progress_bar_set_orientation (pbar, GTK_VALUE_ENUM (*arg));
      break;
    case ARG_BAR_STYLE:
      gtk_progress_bar_set_bar_style (pbar, GTK_VALUE_ENUM (*arg));
      break;
    case ARG_ACTIVITY_STEP:
      gtk_progress_bar_set_activity_step (pbar, GTK_VALUE_UINT (*arg));
      break;
    case ARG_ACTIVITY_BLOCKS:
      gtk_progress_bar_set_activity_blocks (pbar, GTK_VALUE_UINT (*arg));
      break;
    case ARG_DISCRETE_BLOCKS:
      gtk_progress_bar_set_discrete_blocks (pbar, GTK_VALUE_UINT (*arg));
      break;
    default:
      break;
    }
}

static void
gtk_progress_bar_get_arg (GtkObject           *object,
			  GtkArg              *arg,
			  guint                arg_id)
Elliot Lee's avatar
Elliot Lee committed
195
{
196
197
  GtkProgressBar *pbar;

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  pbar = GTK_PROGRESS_BAR (object);

  switch (arg_id)
    {
    case ARG_ADJUSTMENT:
      GTK_VALUE_POINTER (*arg) = GTK_PROGRESS (pbar)->adjustment;
      break;
    case ARG_ORIENTATION:
      GTK_VALUE_ENUM (*arg) = pbar->orientation;
      break;
    case ARG_BAR_STYLE:
      GTK_VALUE_ENUM (*arg) = pbar->bar_style;
      break;
    case ARG_ACTIVITY_STEP:
      GTK_VALUE_UINT (*arg) = pbar->activity_step;
      break;
    case ARG_ACTIVITY_BLOCKS:
      GTK_VALUE_UINT (*arg) = pbar->activity_blocks;
      break;
    case ARG_DISCRETE_BLOCKS:
      GTK_VALUE_UINT (*arg) = pbar->blocks;
      break;
    default:
      arg->type = GTK_TYPE_INVALID;
      break;
    }
}

GtkWidget*
gtk_progress_bar_new (void)
{
  GtkWidget *pbar;
230

231
  pbar = gtk_widget_new (GTK_TYPE_PROGRESS_BAR, NULL);
232

233
  return pbar;
234
235
}

236
GtkWidget*
237
238
gtk_progress_bar_new_with_adjustment (GtkAdjustment *adjustment)
{
239
  GtkWidget *pbar;
240

241
242
  g_return_val_if_fail (adjustment != NULL, NULL);
  g_return_val_if_fail (GTK_IS_ADJUSTMENT (adjustment), NULL);
243

244
245
246
  pbar = gtk_widget_new (GTK_TYPE_PROGRESS_BAR,
			 "adjustment", adjustment,
			 NULL);
247

248
  return pbar;
Elliot Lee's avatar
Elliot Lee committed
249
250
}

251
252
253
254
255
256
257
258
259
260
261
262
263
264
static void
gtk_progress_bar_real_update (GtkProgress *progress)
{
  GtkProgressBar *pbar;
  GtkWidget *widget;

  g_return_if_fail (progress != NULL);
  g_return_if_fail (GTK_IS_PROGRESS (progress));

  pbar = GTK_PROGRESS_BAR (progress);
  widget = GTK_WIDGET (progress);
 
  if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS ||
      GTK_PROGRESS (pbar)->activity_mode)
Elliot Lee's avatar
Elliot Lee committed
265
    {
266
267
268
269
270
271
272
273
274
      if (GTK_PROGRESS (pbar)->activity_mode)
	{
	  guint size;

	  /* advance the block */

	  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
	      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
	    {
275
	      size = MAX (2, widget->allocation.width / pbar->activity_blocks);
276
277
278
279
280
281

	      if (pbar->activity_dir == 0)
		{
		  pbar->activity_pos += pbar->activity_step;
		  if (pbar->activity_pos + size >=
		      widget->allocation.width -
282
		      widget->style->xthickness)
283
284
		    {
		      pbar->activity_pos = widget->allocation.width -
285
			widget->style->xthickness - size;
286
287
288
289
290
291
		      pbar->activity_dir = 1;
		    }
		}
	      else
		{
		  pbar->activity_pos -= pbar->activity_step;
292
		  if (pbar->activity_pos <= widget->style->xthickness)
293
		    {
294
		      pbar->activity_pos = widget->style->xthickness;
295
296
297
298
299
300
		      pbar->activity_dir = 0;
		    }
		}
	    }
	  else
	    {
301
	      size = MAX (2, widget->allocation.height / pbar->activity_blocks);
302
303
304
305
306
307

	      if (pbar->activity_dir == 0)
		{
		  pbar->activity_pos += pbar->activity_step;
		  if (pbar->activity_pos + size >=
		      widget->allocation.height -
308
		      widget->style->ythickness)
309
310
		    {
		      pbar->activity_pos = widget->allocation.height -
311
			widget->style->ythickness - size;
312
313
314
315
316
317
		      pbar->activity_dir = 1;
		    }
		}
	      else
		{
		  pbar->activity_pos -= pbar->activity_step;
318
		  if (pbar->activity_pos <= widget->style->ythickness)
319
		    {
320
		      pbar->activity_pos = widget->style->ythickness;
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
		      pbar->activity_dir = 0;
		    }
		}
	    }
	}
      gtk_progress_bar_paint (progress);
      gtk_widget_queue_draw (GTK_WIDGET (progress));
    }
  else
    {
      gint in_block;
      
      in_block = -1 + (gint)(gtk_progress_get_current_percentage (progress) *
			     (gfloat)pbar->blocks);
      
      if (pbar->in_block != in_block)
	{
	  pbar->in_block = in_block;
	  gtk_progress_bar_paint (progress);
	  gtk_widget_queue_draw (GTK_WIDGET (progress));
	}
Elliot Lee's avatar
Elliot Lee committed
342
343
344
345
    }
}

static void
346
347
gtk_progress_bar_size_request (GtkWidget      *widget,
			       GtkRequisition *requisition)
Elliot Lee's avatar
Elliot Lee committed
348
{
349
  GtkProgress *progress;
Elliot Lee's avatar
Elliot Lee committed
350
  GtkProgressBar *pbar;
351
  gchar *buf;
352
353
  PangoRectangle logical_rect;
  PangoLayout *layout;
Elliot Lee's avatar
Elliot Lee committed
354
355
356

  g_return_if_fail (widget != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
357
  g_return_if_fail (requisition != NULL);
Elliot Lee's avatar
Elliot Lee committed
358

359
  progress = GTK_PROGRESS (widget);
Elliot Lee's avatar
Elliot Lee committed
360
361
  pbar = GTK_PROGRESS_BAR (widget);

362
363
364
365
  if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
    {
      buf = gtk_progress_get_text_from_value (progress, progress->adjustment->upper);

366
      layout = gtk_widget_create_pango_layout (widget, buf);
367
      pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
368
	  
369
      g_object_unref (G_OBJECT (layout));
370
371
372
      g_free (buf);
    }
  
373
374
375
376
377
378
  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
    {
      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
	{
	  requisition->width = MAX (MIN_HORIZONTAL_BAR_WIDTH,
379
				    2 * widget->style->xthickness + 3 +
380
				    logical_rect.width + 2 * TEXT_SPACING);
381
382

	  requisition->height = MAX (MIN_HORIZONTAL_BAR_HEIGHT,
383
				     2 * widget->style->ythickness + 3 +
384
				     logical_rect.height + 2 * TEXT_SPACING);
385
386
387
388
389
390
391
392
393
394
395
396
	}
      else
	{
	  requisition->width = MIN_HORIZONTAL_BAR_WIDTH;
	  requisition->height = MIN_HORIZONTAL_BAR_HEIGHT;
	}
    }
  else
    {
      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
	{	  
	  requisition->width = MAX (MIN_VERTICAL_BAR_WIDTH,
397
				    2 * widget->style->xthickness + 3 +
398
				    logical_rect.width + 2 * TEXT_SPACING);
399
400

	  requisition->height = MAX (MIN_VERTICAL_BAR_HEIGHT,
401
				     2 * widget->style->ythickness + 3 +
402
				     logical_rect.height + 2 * TEXT_SPACING);
403
404
405
406
407
408
409
410
	}
      else
	{
	  requisition->width = MIN_VERTICAL_BAR_WIDTH;
	  requisition->height = MIN_VERTICAL_BAR_HEIGHT;
	}
    }
}
Elliot Lee's avatar
Elliot Lee committed
411

412
413
414
415
416
static void
gtk_progress_bar_act_mode_enter (GtkProgress *progress)
{
  GtkProgressBar *pbar;
  GtkWidget *widget;
417
  gint size;
Elliot Lee's avatar
Elliot Lee committed
418

419
420
  pbar = GTK_PROGRESS_BAR (progress);
  widget = GTK_WIDGET (progress);
Elliot Lee's avatar
Elliot Lee committed
421

422
  /* calculate start pos */
Elliot Lee's avatar
Elliot Lee committed
423

424
425
426
  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
    {
427
428
      size = MAX (2, widget->allocation.width / pbar->activity_blocks);

429
430
      if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT)
	{
431
	  pbar->activity_pos = widget->style->xthickness;
432
433
434
435
436
	  pbar->activity_dir = 0;
	}
      else
	{
	  pbar->activity_pos = widget->allocation.width - 
437
438
	    widget->style->xthickness - (widget->allocation.height - 
		widget->style->ythickness * 2);
439
440
441
442
443
	  pbar->activity_dir = 1;
	}
    }
  else
    {
444
445
      size = MAX (2, widget->allocation.height / pbar->activity_blocks);

446
447
      if (pbar->orientation == GTK_PROGRESS_TOP_TO_BOTTOM)
	{
448
	  pbar->activity_pos = widget->style->ythickness;
449
450
451
452
453
	  pbar->activity_dir = 0;
	}
      else
	{
	  pbar->activity_pos = widget->allocation.height -
454
455
	    widget->style->ythickness - (widget->allocation.width - 
		widget->style->xthickness * 2);
456
457
458
	  pbar->activity_dir = 1;
	}
    }
Elliot Lee's avatar
Elliot Lee committed
459
460
461
}

static void
462
gtk_progress_bar_paint (GtkProgress *progress)
Elliot Lee's avatar
Elliot Lee committed
463
{
464
465
466
467
468
469
470
471
472
  GtkProgressBar *pbar;
  GtkWidget *widget;
  gint amount;
  gint block_delta = 0;
  gint space = 0;
  gint i;
  gint x;
  gint y;
  gfloat percentage;
473
  gint size;
474
475
476
477
478
479
480
481
482
483

  g_return_if_fail (progress != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (progress));

  pbar = GTK_PROGRESS_BAR (progress);
  widget = GTK_WIDGET (progress);

  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
    space = widget->allocation.width -
484
      2 * widget->style->xthickness;
485
486
  else
    space = widget->allocation.height -
487
      2 * widget->style->ythickness;
488
489
490
491
492

  percentage = gtk_progress_get_current_percentage (progress);

  if (progress->offscreen_pixmap)
    {
493
494
495
496
497
498
499
500
      gtk_paint_box (widget->style,
		     progress->offscreen_pixmap,
		     GTK_STATE_NORMAL, GTK_SHADOW_IN, 
		     NULL, widget, "trough",
		     0, 0,
		     widget->allocation.width,
		     widget->allocation.height);
      
501
502
503
504
505
      if (progress->activity_mode)
	{
	  if (pbar->orientation == GTK_PROGRESS_LEFT_TO_RIGHT ||
	      pbar->orientation == GTK_PROGRESS_RIGHT_TO_LEFT)
	    {
506
	      size = MAX (2, widget->allocation.width / pbar->activity_blocks);
507
	      
508
509
510
511
512
	      gtk_paint_box (widget->style,
			     progress->offscreen_pixmap,
			     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
			     NULL, widget, "bar",
			     pbar->activity_pos,
513
			     widget->style->ythickness,
514
			     size,
515
			     widget->allocation.height - widget->style->ythickness * 2);
516
517
518
519
	      return;
	    }
	  else
	    {
520
	      size = MAX (2, widget->allocation.height / pbar->activity_blocks);
521
	      
522
523
524
525
	      gtk_paint_box (widget->style,
			     progress->offscreen_pixmap,
			     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
			     NULL, widget, "bar",
526
			     widget->style->xthickness,
527
			     pbar->activity_pos,
528
			     widget->allocation.width - widget->style->xthickness * 2,
529
			     size);
530
531
532
	      return;
	    }
	}
533
      
534
535
536
537
538
539
540
541
542
543
544
      amount = percentage * space;
      
      if (amount > 0)
	{
	  switch (pbar->orientation)
	    {
	      
	    case GTK_PROGRESS_LEFT_TO_RIGHT:
	      
	      if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
		{
545
546
547
548
		  gtk_paint_box (widget->style,
				 progress->offscreen_pixmap,
				 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				 NULL, widget, "bar",
549
550
				 widget->style->xthickness,
				 widget->style->ythickness,
551
				 amount,
552
				 widget->allocation.height - widget->style->ythickness * 2);
553
554
555
		}
	      else
		{
556
		  x = widget->style->xthickness;
557
558
559
560
561
562
		  
		  for (i = 0; i <= pbar->in_block; i++)
		    {
		      block_delta = (((i + 1) * space) / pbar->blocks)
			- ((i * space) / pbar->blocks);
		      
563
564
565
566
567
		      gtk_paint_box (widget->style,
				     progress->offscreen_pixmap,
				     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				     NULL, widget, "bar",
				     x,
568
				     widget->style->ythickness,
569
				     block_delta,
570
				     widget->allocation.height - widget->style->ythickness * 2);
571
		      
572
573
574
575
		      x +=  block_delta;
		    }
		}
	      break;
576
	      
577
	    case GTK_PROGRESS_RIGHT_TO_LEFT:
578
	      
579
580
	      if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
		{
581
582
583
584
585
		  gtk_paint_box (widget->style,
				 progress->offscreen_pixmap,
				 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				 NULL, widget, "bar",
				 widget->allocation.width - 
586
587
				 widget->style->xthickness - amount,
				 widget->style->ythickness,
588
589
				 amount,
				 widget->allocation.height -
590
				 widget->style->ythickness * 2);
591
592
593
594
		}
	      else
		{
		  x = widget->allocation.width - 
595
		    widget->style->xthickness;
596
		  
597
598
599
600
		  for (i = 0; i <= pbar->in_block; i++)
		    {
		      block_delta = (((i + 1) * space) / pbar->blocks) -
			((i * space) / pbar->blocks);
601
		      
602
		      x -=  block_delta;
603
604
605
606
607
608
		      
		      gtk_paint_box (widget->style,
				     progress->offscreen_pixmap,
				     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				     NULL, widget, "bar",
				     x,
609
				     widget->style->ythickness,
610
611
				     block_delta,
				     widget->allocation.height -
612
				     widget->style->ythickness * 2);
613
614
615
616
617
618
619
620
		    }
		}
	      break;

	    case GTK_PROGRESS_BOTTOM_TO_TOP:

	      if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
		{
621
622
623
624
		  gtk_paint_box (widget->style,
				 progress->offscreen_pixmap,
				 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				 NULL, widget, "bar",
625
				 widget->style->xthickness,
626
				 widget->allocation.height - 
627
				 widget->style->ythickness - amount,
628
				 widget->allocation.width -
629
				 widget->style->xthickness * 2,
630
				 amount);
631
632
633
634
		}
	      else
		{
		  y = widget->allocation.height - 
635
		    widget->style->ythickness;
636
		  
637
638
639
640
641
642
		  for (i = 0; i <= pbar->in_block; i++)
		    {
		      block_delta = (((i + 1) * space) / pbar->blocks) -
			((i * space) / pbar->blocks);
		      
		      y -= block_delta;
643
644
645
646
647
		      
		      gtk_paint_box (widget->style,
				     progress->offscreen_pixmap,
				     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				     NULL, widget, "bar",
648
				     widget->style->xthickness,
649
650
				     y,
				     widget->allocation.width - 
651
				     widget->style->xthickness * 2,
652
				     block_delta);
653
654
655
		    }
		}
	      break;
656
	      
657
	    case GTK_PROGRESS_TOP_TO_BOTTOM:
658
	      
659
660
	      if (pbar->bar_style == GTK_PROGRESS_CONTINUOUS)
		{
661
662
663
664
		  gtk_paint_box (widget->style,
				 progress->offscreen_pixmap,
				 GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				 NULL, widget, "bar",
665
666
				 widget->style->xthickness,
				 widget->style->ythickness,
667
				 widget->allocation.width -
668
				 widget->style->xthickness * 2,
669
				 amount);
670
671
672
		}
	      else
		{
673
		  y = widget->style->ythickness;
674
		  
675
676
		  for (i = 0; i <= pbar->in_block; i++)
		    {
677
		      
678
679
		      block_delta = (((i + 1) * space) / pbar->blocks)
			- ((i * space) / pbar->blocks);
680
681
682
683
684
		      
		      gtk_paint_box (widget->style,
				     progress->offscreen_pixmap,
				     GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
				     NULL, widget, "bar",
685
				     widget->style->xthickness,
686
687
				     y,
				     widget->allocation.width -
688
				     widget->style->xthickness * 2,
689
690
				     block_delta);
		      
691
692
693
694
		      y += block_delta;
		    }
		}
	      break;
695
	      
696
697
698
699
	    default:
	      break;
	    }
	}
700
      
701
702
703
704
705
706
      if (progress->show_text && pbar->bar_style != GTK_PROGRESS_DISCRETE)
	{
	  gint x;
	  gint y;
	  gchar *buf;
	  GdkRectangle rect;
707
708
	  PangoLayout *layout;
	  PangoRectangle logical_rect;
709
710
711

	  buf = gtk_progress_get_current_text (progress);

712
	  layout = gtk_widget_create_pango_layout (widget, buf);
713
	  pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
714
	  
715
716
	  x = widget->style->xthickness + 1 + 
	    (widget->allocation.width - 2 * widget->style->xthickness -
717
	     3 - logical_rect.width)
718
719
	    * progress->x_align; 

720
721
	  y = widget->style->ythickness + 1 +
	    (widget->allocation.height - 2 * widget->style->ythickness -
722
	     3 - logical_rect.height)
723
724
	    * progress->y_align;

725
726
	  rect.x = widget->style->xthickness + 1;
	  rect.y = widget->style->ythickness + 1;
727
	  rect.width = widget->allocation.width -
728
	    2 * widget->style->xthickness - 3;
729
	  rect.height = widget->allocation.height -
730
	    2 * widget->style->ythickness - 3;
731
732
733
734

	  gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state],
				     &rect);

735
736
737
	  gdk_draw_layout (progress->offscreen_pixmap, 
			   widget->style->fg_gc[widget->state],
			   x, y, layout);
738
739
740

	  gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state],
				     NULL);
741
          g_object_unref (G_OBJECT (layout));
742
743
	  g_free (buf);
 	}
Elliot Lee's avatar
Elliot Lee committed
744
745
746
    }
}

747
748
749
750
751
/*******************************************************************/

void
gtk_progress_bar_update (GtkProgressBar *pbar,
			 gfloat          percentage)
Elliot Lee's avatar
Elliot Lee committed
752
{
753
754
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
Elliot Lee's avatar
Elliot Lee committed
755

756
  /***********************************************************************
757
   *          Use of gtk_progress_bar_update() is deprecated !	         * 
758
759
   * Use gtk_progress_set_value or gtk_progress_set_percentage instead.  *
   ***********************************************************************/
Elliot Lee's avatar
Elliot Lee committed
760

761
762
763
764
765
766
767
768
769
770
771
  gtk_progress_set_percentage (GTK_PROGRESS (pbar), percentage);
}

void
gtk_progress_bar_set_orientation (GtkProgressBar           *pbar,
				  GtkProgressBarOrientation orientation)
{
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));

  if (pbar->orientation != orientation)
Elliot Lee's avatar
Elliot Lee committed
772
    {
773
      pbar->orientation = orientation;
Elliot Lee's avatar
Elliot Lee committed
774

775
776
      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
	gtk_widget_queue_resize (GTK_WIDGET (pbar));
Elliot Lee's avatar
Elliot Lee committed
777
778
779
    }
}

780
781
782
void
gtk_progress_bar_set_bar_style (GtkProgressBar     *pbar,
				GtkProgressBarStyle bar_style)
Elliot Lee's avatar
Elliot Lee committed
783
784
785
786
{
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));

787
  if (pbar->bar_style != bar_style)
Elliot Lee's avatar
Elliot Lee committed
788
    {
789
      pbar->bar_style = bar_style;
Elliot Lee's avatar
Elliot Lee committed
790

791
792
      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
	gtk_widget_queue_resize (GTK_WIDGET (pbar));
Elliot Lee's avatar
Elliot Lee committed
793
794
795
    }
}

796
void
797
798
gtk_progress_bar_set_discrete_blocks (GtkProgressBar *pbar,
				      guint           blocks)
Elliot Lee's avatar
Elliot Lee committed
799
800
801
{
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
802
  g_return_if_fail (blocks > 1);
Elliot Lee's avatar
Elliot Lee committed
803

804
  if (pbar->blocks != blocks)
Elliot Lee's avatar
Elliot Lee committed
805
    {
806
      pbar->blocks = blocks;
Elliot Lee's avatar
Elliot Lee committed
807

808
809
810
811
      if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (pbar)))
	gtk_widget_queue_resize (GTK_WIDGET (pbar));
    }
}
Elliot Lee's avatar
Elliot Lee committed
812

813
814
815
816
817
818
void
gtk_progress_bar_set_activity_step (GtkProgressBar *pbar,
                                    guint           step)
{
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
Elliot Lee's avatar
Elliot Lee committed
819

820
821
  if (pbar->activity_step != step)
    pbar->activity_step = step;
Elliot Lee's avatar
Elliot Lee committed
822
}
823
824
825
826
827
828
829
830
831
832
833
834

void
gtk_progress_bar_set_activity_blocks (GtkProgressBar *pbar,
				      guint           blocks)
{
  g_return_if_fail (pbar != NULL);
  g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
  g_return_if_fail (blocks > 1);

  if (pbar->activity_blocks != blocks)
    pbar->activity_blocks = blocks;
}