1
/* This file is part of GQ
4
* Sven Herzberg <herzi@gnome-de.org>
6
* Copyright (C) 2006 Sven Herzberg
8
* This program is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public License as
10
* published by the Free Software Foundation; either version 2.1 of the
11
* License, or (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24
#include "gq-change-bar.h"
26
#include <glib/gi18n.h>
28
struct GqChangeBarPrivate {
29
GtkWidget * comparison;
30
GtkWidget * input_form;
31
GqDifference* difference;
33
#define P(i) (G_TYPE_INSTANCE_GET_PRIVATE((i), GQ_TYPE_CHANGE_BAR, struct GqChangeBarPrivate))
36
gq_change_bar_new(GqComparison* comparison,
39
return g_object_new(GQ_TYPE_CHANGE_BAR,
40
"comparison", comparison,
46
G_DEFINE_TYPE(GqChangeBar, gq_change_bar, GTK_TYPE_DRAWING_AREA);
55
gq_change_bar_init(GqChangeBar* self G_GNUC_UNUSED)
59
change_bar_dispose(GObject* object)
61
if(P(object)->difference) {
62
g_signal_handlers_disconnect_by_func(P(object)->difference, gtk_widget_queue_draw, object);
63
g_object_unref(P(object)->difference);
64
P(object)->difference = NULL;
67
if(P(object)->comparison) {
68
g_object_unref(P(object)->comparison);
69
P(object)->comparison = NULL;
72
if(P(object)->input_form) {
73
g_object_unref(P(object)->input_form);
74
P(object)->input_form = NULL;
77
G_OBJECT_CLASS(gq_change_bar_parent_class)->dispose(object);
81
change_bar_get_property(GObject * object,
88
g_value_set_object(value, P(object)->comparison);
91
g_value_set_object(value, P(object)->input_form);
94
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
100
change_bar_set_property(GObject * object,
106
case PROP_COMPARISON:
107
if(P(object)->comparison) {
108
g_signal_handlers_disconnect_by_func(P(object)->difference, gtk_widget_queue_draw, object);
109
g_object_unref(P(object)->difference);
110
P(object)->difference = NULL;
111
g_object_unref(P(object)->comparison);
113
P(object)->comparison = (GtkWidget*)g_value_dup_object(value);
114
if(P(object)->comparison) {
115
P(object)->difference = g_object_ref(gq_comparison_get_difference(GQ_COMPARISON(P(object)->comparison)));
116
g_signal_connect_swapped(P(object)->difference, "updated",
117
G_CALLBACK(gtk_widget_queue_draw), object);
119
g_object_notify(object, "comparison");
121
case PROP_INPUT_FORM:
122
if(P(object)->input_form) {
123
g_object_unref(P(object)->input_form);
125
P(object)->input_form = (GtkWidget*)g_value_dup_object(value);
126
g_object_notify(object, "input-form");
129
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
135
change_bar_display_change(GqFormfill* form1,
140
gpointer * self_and_cr = user_data;
141
GtkWidget* form = P(self_and_cr[0])->input_form;
142
GtkWidget* comp1 = !form1 ? NULL : gtk_widget_get_parent(
143
gtk_widget_get_parent(
144
gtk_widget_get_parent(
145
gtk_widget_get_parent(
146
gtk_widget_get_parent(
147
gq_formfill_get_event_box(form1) // GtkEventBox
148
) // should return GtkTable
150
) // should return GtkViewport
151
) // should return GtkScrolledWindow
152
); // should return GqInputForm
153
GtkWidget* comp2 = !form2 ? NULL : gtk_widget_get_parent(
154
gtk_widget_get_parent(
155
gtk_widget_get_parent(
156
gtk_widget_get_parent(
157
gtk_widget_get_parent(
158
gq_formfill_get_event_box(form2) // GtkEventBox
159
) // should return GtkTable
160
) // should return GtkVBox
161
) // should return GtkViewport
162
) // should return GtkScrolledWindow
163
); // should return GqInputForm
169
if(comp1 == form || comp2 == form) {
170
GtkWidget* reference = self_and_cr[1];
173
cairo_t* cr = self_and_cr[2];
174
cairo_set_line_width(cr, 1.0);
176
ebox = gq_formfill_get_event_box(form1);
179
ebox = gq_formfill_get_event_box(form2);
181
table = gtk_widget_get_parent(ebox);
182
cairo_rectangle(cr, 0.5, ((int)1.0*reference->allocation.height*(ebox->allocation.y+table->allocation.x)/(table->allocation.height+table->allocation.x))+0.5, 11.0, 3.0);
184
cairo_set_source_rgb(cr, 0.45, 0.62, 0.81);
187
cairo_set_source_rgb(cr, 0.54, 0.88, 0.2);
189
cairo_fill_preserve(cr);
191
cairo_set_source_rgb(cr, 0.13, 0.29, 0.53);
195
cairo_set_source_rgb(cr, 0.3, 0.6, 0.02);
202
change_bar_expose_event(GtkWidget * widget,
203
GdkEventExpose* event G_GNUC_UNUSED)
205
GtkWidget* reference = gtk_bin_get_child(GTK_BIN(gq_input_form_get_scrolled_window(GQ_INPUT_FORM(P(widget)->input_form))));
206
cairo_t* cr = gdk_cairo_create(widget->window);
207
gpointer self_ref_and_cr[3] = {widget, reference, cr};
208
cairo_translate(cr, 0.0, reference->allocation.y - widget->allocation.y);
209
gq_difference_foreach(P(widget)->difference, change_bar_display_change, self_ref_and_cr);
215
change_bar_size_request(GtkWidget * widget G_GNUC_UNUSED,
216
GtkRequisition* requisition)
218
requisition->width = 12;
222
gq_change_bar_class_init(GqChangeBarClass* self_class)
224
GObjectClass* object_class = G_OBJECT_CLASS(self_class);
225
GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(self_class);
228
object_class->dispose = change_bar_dispose;
229
object_class->get_property = change_bar_get_property;
230
object_class->set_property = change_bar_set_property;
232
g_object_class_install_property(object_class, PROP_COMPARISON,
233
g_param_spec_object("comparison",
235
_("The compare widget"),
238
g_object_class_install_property(object_class, PROP_INPUT_FORM,
239
g_param_spec_object("input-form",
241
_("The input form of this change bar"),
246
widget_class->expose_event = change_bar_expose_event;
247
widget_class->size_request = change_bar_size_request;
249
/* GqChangeBarClass */
250
g_type_class_add_private(self_class, sizeof(struct GqChangeBarPrivate));