]> Pileus Git - ~andy/gtk/blob - gtk/gtkprogressbar.c
changed reversed_[12] to reserved_[12] in gtk_*_get_type functions.
[~andy/gtk] / gtk / gtkprogressbar.c
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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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 #include "gtkprogressbar.h"
20
21
22 #define MIN_WIDTH   200
23 #define MIN_HEIGHT  20
24
25
26 static void gtk_progress_bar_class_init    (GtkProgressBarClass *klass);
27 static void gtk_progress_bar_init          (GtkProgressBar      *pbar);
28 static void gtk_progress_bar_realize       (GtkWidget           *widget);
29 static void gtk_progress_bar_size_allocate (GtkWidget           *widget,
30                                             GtkAllocation       *allocation);
31 static gint gtk_progress_bar_expose        (GtkWidget           *widget,
32                                             GdkEventExpose      *event);
33 static void gtk_progress_bar_make_pixmap   (GtkProgressBar      *pbar);
34 static void gtk_progress_bar_paint         (GtkProgressBar      *pbar);
35
36
37 guint
38 gtk_progress_bar_get_type (void)
39 {
40   static guint progress_bar_type = 0;
41
42   if (!progress_bar_type)
43     {
44       GtkTypeInfo progress_bar_info =
45       {
46         "GtkProgressBar",
47         sizeof (GtkProgressBar),
48         sizeof (GtkProgressBarClass),
49         (GtkClassInitFunc) gtk_progress_bar_class_init,
50         (GtkObjectInitFunc) gtk_progress_bar_init,
51         /* reserved_1 */ NULL,
52         /* reserved_2 */ NULL,
53         (GtkClassInitFunc) NULL,
54       };
55
56       progress_bar_type = gtk_type_unique (gtk_widget_get_type (), &progress_bar_info);
57     }
58
59   return progress_bar_type;
60 }
61
62 static void
63 gtk_progress_bar_class_init (GtkProgressBarClass *class)
64 {
65   GtkWidgetClass *widget_class;
66
67   widget_class = (GtkWidgetClass*) class;
68
69   widget_class->realize = gtk_progress_bar_realize;
70   widget_class->size_allocate = gtk_progress_bar_size_allocate;
71   widget_class->expose_event = gtk_progress_bar_expose;
72 }
73
74 static void
75 gtk_progress_bar_init (GtkProgressBar *pbar)
76 {
77   GTK_WIDGET_SET_FLAGS (pbar, GTK_BASIC);
78
79   GTK_WIDGET (pbar)->requisition.width = MIN_WIDTH;
80   GTK_WIDGET (pbar)->requisition.height = MIN_HEIGHT;
81   pbar->offscreen_pixmap = NULL;
82   pbar->percentage = 0;
83 }
84
85
86 GtkWidget*
87 gtk_progress_bar_new (void)
88 {
89   return GTK_WIDGET (gtk_type_new (gtk_progress_bar_get_type ()));
90 }
91
92 void
93 gtk_progress_bar_update (GtkProgressBar *pbar,
94                          gfloat          percentage)
95 {
96   g_return_if_fail (pbar != NULL);
97   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
98
99   if (percentage < 0.0)
100     percentage = 0.0;
101   else if (percentage > 1.0)
102     percentage = 1.0;
103
104   if (pbar->percentage != percentage)
105     {
106       pbar->percentage = percentage;
107       gtk_progress_bar_paint (pbar);
108       gtk_widget_queue_draw (GTK_WIDGET (pbar));
109     }
110 }
111
112 static void
113 gtk_progress_bar_realize (GtkWidget *widget)
114 {
115   GtkProgressBar *pbar;
116   GdkWindowAttr attributes;
117   gint attributes_mask;
118
119   g_return_if_fail (widget != NULL);
120   g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
121
122   pbar = GTK_PROGRESS_BAR (widget);
123   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
124
125   attributes.window_type = GDK_WINDOW_CHILD;
126   attributes.x = widget->allocation.x;
127   attributes.y = widget->allocation.y;
128   attributes.width = widget->allocation.width;
129   attributes.height = widget->allocation.height;
130   attributes.wclass = GDK_INPUT_OUTPUT;
131   attributes.visual = gtk_widget_get_visual (widget);
132   attributes.colormap = gtk_widget_get_colormap (widget);
133   attributes.event_mask = gtk_widget_get_events (widget);
134   attributes.event_mask |= GDK_EXPOSURE_MASK;
135
136   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
137
138   widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
139   gdk_window_set_user_data (widget->window, pbar);
140
141   widget->style = gtk_style_attach (widget->style, widget->window);
142   gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
143
144   gtk_progress_bar_make_pixmap (pbar);
145 }
146
147 static void
148 gtk_progress_bar_size_allocate (GtkWidget     *widget,
149                                 GtkAllocation *allocation)
150 {
151   g_return_if_fail (widget != NULL);
152   g_return_if_fail (GTK_IS_PROGRESS_BAR (widget));
153   g_return_if_fail (allocation != NULL);
154
155   widget->allocation = *allocation;
156
157   if (GTK_WIDGET_REALIZED (widget))
158     {
159       gdk_window_move_resize (widget->window,
160                               allocation->x, allocation->y,
161                               allocation->width, allocation->height);
162
163       gtk_progress_bar_make_pixmap (GTK_PROGRESS_BAR (widget));
164     }
165 }
166
167 static gint
168 gtk_progress_bar_expose (GtkWidget      *widget,
169                          GdkEventExpose *event)
170 {
171   GtkProgressBar *pbar;
172
173   g_return_val_if_fail (widget != NULL, FALSE);
174   g_return_val_if_fail (GTK_IS_PROGRESS_BAR (widget), FALSE);
175   g_return_val_if_fail (event != NULL, FALSE);
176
177   if (GTK_WIDGET_DRAWABLE (widget))
178     {
179       pbar = GTK_PROGRESS_BAR (widget);
180
181       gdk_draw_pixmap (widget->window,
182                        widget->style->black_gc,
183                        pbar->offscreen_pixmap,
184                        0, 0, 0, 0,
185                        widget->allocation.width,
186                        widget->allocation.height);
187     }
188
189   return FALSE;
190 }
191
192 static void
193 gtk_progress_bar_make_pixmap (GtkProgressBar *pbar)
194 {
195   GtkWidget *widget;
196
197   g_return_if_fail (pbar != NULL);
198   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
199
200   if (GTK_WIDGET_REALIZED (pbar))
201     {
202       widget = GTK_WIDGET (pbar);
203
204       if (pbar->offscreen_pixmap)
205         gdk_pixmap_unref (pbar->offscreen_pixmap);
206
207       pbar->offscreen_pixmap = gdk_pixmap_new (widget->window,
208                                                widget->allocation.width,
209                                                widget->allocation.height,
210                                                -1);
211
212       gtk_progress_bar_paint (pbar);
213     }
214 }
215
216 static void
217 gtk_progress_bar_paint (GtkProgressBar *pbar)
218 {
219   GtkWidget *widget;
220   int amount;
221
222   g_return_if_fail (pbar != NULL);
223   g_return_if_fail (GTK_IS_PROGRESS_BAR (pbar));
224
225   if (pbar->offscreen_pixmap)
226     {
227       widget = GTK_WIDGET (pbar);
228
229       gtk_draw_shadow (widget->style,
230                        pbar->offscreen_pixmap,
231                        GTK_STATE_NORMAL, GTK_SHADOW_IN, 0, 0,
232                        widget->allocation.width,
233                        widget->allocation.height);
234
235       gdk_draw_rectangle (pbar->offscreen_pixmap,
236                           widget->style->bg_gc[GTK_STATE_ACTIVE], TRUE,
237                           widget->style->klass->xthickness,
238                           widget->style->klass->ythickness,
239                           widget->allocation.width - widget->style->klass->xthickness * 2,
240                           widget->allocation.height - widget->style->klass->ythickness * 2);
241
242
243       amount = pbar->percentage * (widget->allocation.width - widget->style->klass->xthickness * 2);
244       if (amount > 0)
245         {
246           gdk_draw_rectangle (pbar->offscreen_pixmap,
247                               widget->style->bg_gc[GTK_STATE_PRELIGHT], TRUE,
248                               widget->style->klass->xthickness,
249                               widget->style->klass->ythickness,
250                               amount,
251                               widget->allocation.height - widget->style->klass->ythickness * 2);
252
253           gtk_draw_shadow (widget->style,
254                            pbar->offscreen_pixmap,
255                            GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
256                            widget->style->klass->xthickness,
257                            widget->style->klass->ythickness,
258                            amount,
259                            widget->allocation.height - widget->style->klass->ythickness * 2);
260         }
261     }
262 }