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