1 /* LIBGIMP - The GIMP Library
2 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
3 *
4 * gimpprogressbar.c
5 * Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
6 *
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 3 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include <gtk/gtk.h>
25
26 #ifdef GDK_WINDOWING_WIN32
27 #include <gdk/gdkwin32.h>
28 #endif
29
30 #ifdef GDK_WINDOWING_X11
31 #include <gdk/gdkx.h>
32 #endif
33
34 #include "gimpuitypes.h"
35
36 #include "gimp.h"
37
38 #include "gimpprogressbar.h"
39
40
41 /**
42 * SECTION: gimpprogressbar
43 * @title: GimpProgressBar
44 * @short_description: A widget providing a progress bar.
45 *
46 * A widget providing a progress bar that automatically redirects any
47 * progress calls to itself.
48 **/
49
50
51 static void gimp_progress_bar_dispose (GObject *object);
52
53 static void gimp_progress_bar_start (const gchar *message,
54 gboolean cancelable,
55 gpointer user_data);
56 static void gimp_progress_bar_end (gpointer user_data);
57 static void gimp_progress_bar_set_text (const gchar *message,
58 gpointer user_data);
59 static void gimp_progress_bar_set_value (gdouble percentage,
60 gpointer user_data);
61 static void gimp_progress_bar_pulse (gpointer user_data);
62 static guint32 gimp_progress_bar_get_window (gpointer user_data);
63
64
G_DEFINE_TYPE(GimpProgressBar,gimp_progress_bar,GTK_TYPE_PROGRESS_BAR)65 G_DEFINE_TYPE (GimpProgressBar, gimp_progress_bar, GTK_TYPE_PROGRESS_BAR)
66
67 #define parent_class gimp_progress_bar_parent_class
68
69
70 static void
71 gimp_progress_bar_class_init (GimpProgressBarClass *klass)
72 {
73 GObjectClass *object_class = G_OBJECT_CLASS (klass);
74
75 object_class->dispose = gimp_progress_bar_dispose;
76 }
77
78 static void
gimp_progress_bar_init(GimpProgressBar * bar)79 gimp_progress_bar_init (GimpProgressBar *bar)
80 {
81 GimpProgressVtable vtable = { 0, };
82
83 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (bar), " ");
84 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (bar), PANGO_ELLIPSIZE_END);
85
86 vtable.start = gimp_progress_bar_start;
87 vtable.end = gimp_progress_bar_end;
88 vtable.set_text = gimp_progress_bar_set_text;
89 vtable.set_value = gimp_progress_bar_set_value;
90 vtable.pulse = gimp_progress_bar_pulse;
91 vtable.get_window = gimp_progress_bar_get_window;
92
93 bar->progress_callback = gimp_progress_install_vtable (&vtable, bar);
94 }
95
96 static void
gimp_progress_bar_dispose(GObject * object)97 gimp_progress_bar_dispose (GObject *object)
98 {
99 GimpProgressBar *bar = GIMP_PROGRESS_BAR (object);
100
101 if (bar->progress_callback)
102 {
103 gimp_progress_uninstall (bar->progress_callback);
104 bar->progress_callback = NULL;
105 }
106
107 G_OBJECT_CLASS (parent_class)->dispose (object);
108 }
109
110 static void
gimp_progress_bar_start(const gchar * message,gboolean cancelable,gpointer user_data)111 gimp_progress_bar_start (const gchar *message,
112 gboolean cancelable,
113 gpointer user_data)
114 {
115 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
116
117 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (bar), message ? message : " ");
118 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
119
120 if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
121 while (gtk_events_pending ())
122 gtk_main_iteration ();
123 }
124
125 static void
gimp_progress_bar_end(gpointer user_data)126 gimp_progress_bar_end (gpointer user_data)
127 {
128 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
129
130 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (bar), " ");
131 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
132
133 if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
134 while (gtk_events_pending ())
135 gtk_main_iteration ();
136 }
137
138 static void
gimp_progress_bar_set_text(const gchar * message,gpointer user_data)139 gimp_progress_bar_set_text (const gchar *message,
140 gpointer user_data)
141 {
142 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
143
144 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (bar), message ? message : " ");
145
146 if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
147 while (gtk_events_pending ())
148 gtk_main_iteration ();
149 }
150
151 static void
gimp_progress_bar_set_value(gdouble percentage,gpointer user_data)152 gimp_progress_bar_set_value (gdouble percentage,
153 gpointer user_data)
154 {
155 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
156
157 if (percentage >= 0.0)
158 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), percentage);
159 else
160 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar));
161
162 if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
163 while (gtk_events_pending ())
164 gtk_main_iteration ();
165 }
166
167 static void
gimp_progress_bar_pulse(gpointer user_data)168 gimp_progress_bar_pulse (gpointer user_data)
169 {
170 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
171
172 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar));
173
174 if (gtk_widget_is_drawable (GTK_WIDGET (bar)))
175 while (gtk_events_pending ())
176 gtk_main_iteration ();
177 }
178
179 static guint32
gimp_window_get_native_id(GtkWindow * window)180 gimp_window_get_native_id (GtkWindow *window)
181 {
182 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
183
184 #ifdef GDK_NATIVE_WINDOW_POINTER
185 #ifdef __GNUC__
186 #warning gimp_window_get_native() unimplementable for the target windowing system
187 #endif
188 #endif
189
190 #ifdef GDK_WINDOWING_WIN32
191 if (window && gtk_widget_get_realized (GTK_WIDGET (window)))
192 return GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (window)));
193 #endif
194
195 #ifdef GDK_WINDOWING_X11
196 if (window && gtk_widget_get_realized (GTK_WIDGET (window)))
197 return GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (window)));
198 #endif
199
200 return 0;
201 }
202
203 static guint32
gimp_progress_bar_get_window(gpointer user_data)204 gimp_progress_bar_get_window (gpointer user_data)
205 {
206 GimpProgressBar *bar = GIMP_PROGRESS_BAR (user_data);
207 GtkWidget *toplevel;
208
209 toplevel = gtk_widget_get_toplevel (GTK_WIDGET (bar));
210
211 if (GTK_IS_WINDOW (toplevel))
212 return gimp_window_get_native_id (GTK_WINDOW (toplevel));
213
214 return 0;
215 }
216
217 /**
218 * gimp_progress_bar_new:
219 *
220 * Creates a new #GimpProgressBar widget.
221 *
222 * Return value: the new widget.
223 *
224 * Since: 2.2
225 **/
226 GtkWidget *
gimp_progress_bar_new(void)227 gimp_progress_bar_new (void)
228 {
229 return g_object_new (GIMP_TYPE_PROGRESS_BAR, NULL);
230 }
231