1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2  *
3  * Copyright (C) 2009-2012 Richard Hughes <richard@hughsie.com>
4  *
5  * Licensed under the GNU Lesser General Public License Version 2.1
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 2.1 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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
20  */
21 
22 #include "config.h"
23 
24 #include <glib-object.h>
25 
26 #include <colord.h>
27 
28 #include "cd-sample-widget.h"
29 #include "cd-sample-window.h"
30 
31 static void     cd_sample_window_finalize	(GObject     *object);
32 
33 #define CD_SAMPLE_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_SAMPLE_WINDOW, CdSampleWindowPrivate))
34 #define CD_SAMPLE_WINDOW_PULSE_DELAY		80	/* ms */
35 
36 /**
37  * CdSampleWindowPrivate:
38  *
39  * Private #CdSampleWindow data
40  **/
41 struct _CdSampleWindowPrivate
42 {
43 	GtkWidget			*sample_widget;
44 	GtkWidget			*progress_bar;
45 	guint				 pulse_id;
46 };
47 
G_DEFINE_TYPE(CdSampleWindow,cd_sample_window,GTK_TYPE_WINDOW)48 G_DEFINE_TYPE (CdSampleWindow, cd_sample_window, GTK_TYPE_WINDOW)
49 
50 /**
51  * cd_sample_window_pulse_cb:
52  **/
53 static gboolean
54 cd_sample_window_pulse_cb (CdSampleWindow *sample_window)
55 {
56 	gtk_progress_bar_pulse (GTK_PROGRESS_BAR (sample_window->priv->progress_bar));
57 	return TRUE;
58 }
59 
60 /**
61  * cd_sample_window_set_fraction:
62  * @sample_window: a valid #CdSampleWindow instance
63  * @fraction: the fraction value to show, or -1 for pulsing.
64  *
65  * Sets the percentage value on the window.
66  *
67  * Since: 0.1.22
68  **/
69 void
cd_sample_window_set_fraction(CdSampleWindow * sample_window,gdouble fraction)70 cd_sample_window_set_fraction (CdSampleWindow *sample_window,
71 			       gdouble fraction)
72 {
73 	CdSampleWindowPrivate *priv = sample_window->priv;
74 
75 	/* make pulse */
76 	if (fraction == -1) {
77 		if (priv->pulse_id == 0) {
78 			priv->pulse_id = g_timeout_add (CD_SAMPLE_WINDOW_PULSE_DELAY,
79 							(GSourceFunc) cd_sample_window_pulse_cb,
80 							sample_window);
81 		}
82 		return;
83 	}
84 
85 	/* no more pulsing */
86 	if (priv->pulse_id != 0) {
87 		g_source_remove (priv->pulse_id);
88 		priv->pulse_id = 0;
89 	}
90 
91 	/* set static value */
92 	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (sample_window->priv->progress_bar), fraction);
93 }
94 
95 /**
96  * cd_sample_window_set_color:
97  * @sample_window: a valid #CdSampleWindow instance
98  * @color: the color
99  *
100  * Sets the window to a specific color.
101  *
102  * Since: 0.1.22
103  **/
104 void
cd_sample_window_set_color(CdSampleWindow * sample_window,const CdColorRGB * color)105 cd_sample_window_set_color (CdSampleWindow *sample_window,
106 			    const CdColorRGB *color)
107 {
108 	g_debug ("setting RGB: %f, %f, %f", color->R, color->G, color->B);
109 	cd_sample_widget_set_color (CD_SAMPLE_WIDGET (sample_window->priv->sample_widget), color);
110 
111 	/* force redraw */
112 	gtk_widget_set_visible (sample_window->priv->sample_widget, FALSE);
113 	gtk_widget_set_visible (sample_window->priv->sample_widget, TRUE);
114 }
115 
116 /**
117  * cd_sample_window_class_init:
118  **/
119 static void
cd_sample_window_class_init(CdSampleWindowClass * klass)120 cd_sample_window_class_init (CdSampleWindowClass *klass)
121 {
122 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
123 	object_class->finalize = cd_sample_window_finalize;
124 	g_type_class_add_private (klass, sizeof (CdSampleWindowPrivate));
125 }
126 
127 /**
128  * cd_sample_window_enter_notify_cb:
129  **/
130 static gboolean
cd_sample_window_enter_notify_cb(GtkWidget * widget,GdkEventCrossing * event,CdSampleWindow * sample_window)131 cd_sample_window_enter_notify_cb (GtkWidget *widget, GdkEventCrossing *event, CdSampleWindow *sample_window)
132 {
133 	GdkCursor *cursor;
134 
135 	/* hide cursor */
136 	cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_BLANK_CURSOR);
137 	gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
138 	g_object_unref (cursor);
139 
140 	return FALSE;
141 }
142 
143 /**
144  * cd_sample_window_leave_notify_cb:
145  **/
146 static gboolean
cd_sample_window_leave_notify_cb(GtkWidget * widget,GdkEventCrossing * event,CdSampleWindow * sample_window)147 cd_sample_window_leave_notify_cb (GtkWidget *widget, GdkEventCrossing *event,
148 				   CdSampleWindow *sample_window)
149 {
150 	/* restore cursor */
151 	gdk_window_set_cursor (gtk_widget_get_window (widget), NULL);
152 	return FALSE;
153 }
154 
155 static gboolean
cd_sample_window_visibility_notify_cb(GtkWidget * widget,GdkEventVisibility * event,CdSampleWindow * sample_window)156 cd_sample_window_visibility_notify_cb (GtkWidget *widget, GdkEventVisibility *event,
157 					CdSampleWindow *sample_window)
158 {
159 	/* reshow it */
160 	gtk_window_present (GTK_WINDOW (widget));
161 	return TRUE;
162 }
163 
164 /**
165  * cd_sample_window_init:
166  **/
167 static void
cd_sample_window_init(CdSampleWindow * sample_window)168 cd_sample_window_init (CdSampleWindow *sample_window)
169 {
170 	GtkWindow *window = GTK_WINDOW (sample_window);
171 	GtkWidget *vbox;
172 	sample_window->priv = CD_SAMPLE_WINDOW_GET_PRIVATE (sample_window);
173 	sample_window->priv->sample_widget = cd_sample_widget_new ();
174 	sample_window->priv->progress_bar = gtk_progress_bar_new ();
175 
176 	/* pack in two widgets into the window */
177 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
178 	gtk_container_add (GTK_CONTAINER (sample_window), vbox);
179 	gtk_box_pack_start (GTK_BOX (vbox), sample_window->priv->sample_widget, TRUE, TRUE, 0);
180 	gtk_box_pack_start (GTK_BOX (vbox), sample_window->priv->progress_bar, FALSE, FALSE, 0);
181 	gtk_widget_set_size_request (sample_window->priv->sample_widget, 400, 400);
182 	gtk_widget_show_all (vbox);
183 
184 	/* be clever and allow the colorimeter to do it's job */
185 	g_signal_connect (window, "enter-notify-event",
186 			  G_CALLBACK(cd_sample_window_enter_notify_cb),
187 			  sample_window);
188 	g_signal_connect (window, "leave-notify-event",
189 			  G_CALLBACK(cd_sample_window_leave_notify_cb),
190 			  sample_window);
191 	g_signal_connect (window, "visibility-notify-event",
192 			  G_CALLBACK(cd_sample_window_visibility_notify_cb),
193 			  sample_window);
194 
195 	/* show on all virtual desktops */
196 	gtk_window_stick (window);
197 }
198 
199 /**
200  * cd_sample_window_finalize:
201  **/
202 static void
cd_sample_window_finalize(GObject * object)203 cd_sample_window_finalize (GObject *object)
204 {
205 	CdSampleWindow *sample_window = CD_SAMPLE_WINDOW (object);
206 	CdSampleWindowPrivate *priv = sample_window->priv;
207 
208 	if (priv->pulse_id != 0)
209 		g_source_remove (priv->pulse_id);
210 
211 	G_OBJECT_CLASS (cd_sample_window_parent_class)->finalize (object);
212 }
213 
214 /**
215  * cd_sample_window_new:
216  *
217  * Return value: a new #CdSampleWindow object.
218  *
219  * Since: 0.1.22
220  **/
221 GtkWindow *
cd_sample_window_new(void)222 cd_sample_window_new (void)
223 {
224 	CdSampleWindow *sample_window;
225 	sample_window = g_object_new (CD_TYPE_SAMPLE_WINDOW,
226 				      "accept-focus", FALSE,
227 				      "decorated", FALSE,
228 				      "default-height", 400,
229 				      "default-width", 400,
230 				      "deletable", FALSE,
231 				      "destroy-with-parent", TRUE,
232 				      "icon-name", "icc-profile",
233 				      "resizable", FALSE,
234 				      "skip-pager-hint", TRUE,
235 				      "skip-taskbar-hint", TRUE,
236 				      "title", "calibration square",
237 				      "type-hint", GDK_WINDOW_TYPE_HINT_SPLASHSCREEN,
238 				      "urgency-hint", TRUE,
239 				      NULL);
240 	return GTK_WINDOW (sample_window);
241 }
242