1 
2 /*
3  *  Ump - Unnamed Math Program
4  *  Copyright (c) 2004-2006 by Mattias Hultgren <mattias_hultgren@tele2.se>
5  *
6  *  See main.cpp
7  */
8 
9 #include "gradient_editor.h"
10 #include "picture2gtk.h"
11 #include "math2.h"
12 
13 const int32 GRADIENT_PICTURE_WIDTH  = 100;
14 const int32 GRADIENT_PICTURE_HEIGHT = 200;
15 
16 int active_color;
17 picture2gtk gradient_picture;
18 Vector<picture_h::colorrgb> working_gradient;
19 GtkWidget *the_parent;
20 
21 void gradient_update_color(void);
22 
23 void gradient_select_color( const picture2gtk *src, int32 x, int32 y, int32 button);
24 
25 void gradient_change_color(GtkButton *button, gpointer user_data);
26 void gradient_add_color(GtkButton *button, gpointer user_data);
27 void gradient_remove_color(GtkButton *button, gpointer user_data);
28 void gradient_move_up(GtkButton *button, gpointer user_data);
29 void gradient_move_down(GtkButton *button, gpointer user_data);
30 
gradient_editor(GtkWidget * parent,Vector<picture_h::colorrgb> & gradient)31 void gradient_editor( GtkWidget *parent, Vector<picture_h::colorrgb> &gradient ) throw(error_obj)
32 {
33 	GtkWidget *dialog, *box, *box2, *button, *drawarea;
34 
35 	dialog = gtk_dialog_new_with_buttons( _("Gradient editor"), GTK_WINDOW(parent),
36 	                                      GtkDialogFlags(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL),
37 	                                      GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
38 	                                      NULL );
39 	the_parent = dialog;
40 
41 	working_gradient = gradient;
42 
43 	box = gtk_hbox_new( FALSE, 3 );
44 	gtk_container_set_border_width( GTK_CONTAINER(box), 3 );
45 	gtk_box_pack_start( GTK_BOX( GTK_DIALOG(dialog)->vbox), box, FALSE, FALSE, 3 );
46 
47 	active_color = gradient.get_size() -1;
48 
49 	gradient_picture.set_size( GRADIENT_PICTURE_WIDTH, GRADIENT_PICTURE_HEIGHT );
50 
51 	gradient_update_color();
52 	drawarea = gtk_drawing_area_new();
53 	gradient_picture.connect_to_drawing_area( drawarea );
54 
55 	gradient_picture.mousedown_func = gradient_select_color;
56 
57 	gtk_box_pack_start( GTK_BOX(box), drawarea, FALSE, FALSE, 0 );
58 
59 
60 	box2 = gtk_vbox_new( TRUE, 0 );
61 	gtk_box_pack_start( GTK_BOX(box), box2, FALSE, FALSE, 0 );
62 
63 
64 	{
65 		GtkWidget *tmp_hbox;
66 
67 		button = gtk_button_new();
68 		gtk_box_pack_start( GTK_BOX(box2), button, FALSE, FALSE, 0 );
69 		tmp_hbox = gtk_hbox_new( FALSE, 0 );
70 		gtk_container_add( GTK_CONTAINER(button), tmp_hbox );
71 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_image_new_from_stock( GTK_STOCK_SELECT_COLOR, GTK_ICON_SIZE_BUTTON ),
72 		                    FALSE, FALSE, 0 );
73 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_label_new( _("Change color") ), FALSE, FALSE, 0 );
74 		g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(gradient_change_color), NULL );
75 
76 
77 		button = gtk_button_new();
78 		gtk_box_pack_start( GTK_BOX(box2), button, FALSE, FALSE, 0 );
79 		tmp_hbox = gtk_hbox_new( FALSE, 0 );
80 		gtk_container_add( GTK_CONTAINER(button), tmp_hbox );
81 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_image_new_from_stock( GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON ),
82 		                    FALSE, FALSE, 0 );
83 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_label_new( _("Add color") ), FALSE, FALSE, 0 );
84 		g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(gradient_add_color), NULL );
85 
86 
87 		button = gtk_button_new();
88 		gtk_box_pack_start( GTK_BOX(box2), button, FALSE, FALSE, 0 );
89 		tmp_hbox = gtk_hbox_new( FALSE, 0 );
90 		gtk_container_add( GTK_CONTAINER(button), tmp_hbox );
91 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_image_new_from_stock( GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON ),
92 		                    FALSE, FALSE, 0 );
93 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_label_new( _("Remove color") ), FALSE, FALSE, 0 );
94 		g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(gradient_remove_color), NULL );
95 
96 
97 		button = gtk_button_new();
98 		gtk_box_pack_start( GTK_BOX(box2), button, FALSE, FALSE, 0 );
99 		tmp_hbox = gtk_hbox_new( FALSE, 0 );
100 		gtk_container_add( GTK_CONTAINER(button), tmp_hbox );
101 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_image_new_from_stock( GTK_STOCK_GO_UP, GTK_ICON_SIZE_BUTTON ),
102 		                    FALSE, FALSE, 0 );
103 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_label_new( _("Move up") ), FALSE, FALSE, 0 );
104 		g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(gradient_move_up), NULL );
105 
106 
107 		button = gtk_button_new();
108 		gtk_box_pack_start( GTK_BOX(box2), button, FALSE, FALSE, 0 );
109 		tmp_hbox = gtk_hbox_new( FALSE, 0 );
110 		gtk_container_add( GTK_CONTAINER(button), tmp_hbox );
111 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_image_new_from_stock( GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_BUTTON ),
112 		                    FALSE, FALSE, 0 );
113 		gtk_box_pack_start( GTK_BOX(tmp_hbox), gtk_label_new( _("Move down") ), FALSE, FALSE, 0 );
114 		g_signal_connect( GTK_OBJECT(button), "clicked", G_CALLBACK(gradient_move_down), NULL );
115 	}
116 
117 	gtk_widget_show_all(dialog);
118 	if( gtk_dialog_run( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
119 		gradient = working_gradient;
120 
121 	gtk_widget_destroy(dialog);
122 }
123 
gradient_update_color(void)124 void gradient_update_color(void)
125 {
126 	for( int32 i=0; i<gradient_picture.get_height(); i++ )
127 	{
128 		picture_h::colorrgb tmp_color;
129 		math::color_list_get_color( working_gradient, 0.0, floatx(gradient_picture.get_height()-1),
130 		                            floatx(gradient_picture.get_height()-1-i), &tmp_color );
131 		gradient_picture.line( 0, i, gradient_picture.get_width()-1, i, tmp_color );
132 	}
133 
134 	if( active_color >= working_gradient.get_size() )
135 		active_color = working_gradient.get_size() -1;
136 
137 	if( working_gradient.get_size() > 1 )
138 	{
139 		int32 middle = int32( (1.0- float(active_color) / float(working_gradient.get_size() -1) ) *
140 		                      float(gradient_picture.get_height()) );
141 
142 		if( active_color == 0 )
143 			middle -= 7;
144 		if( active_color == (working_gradient.get_size() -1) )
145 			middle += 6;
146 
147 		gradient_picture.box( 0, middle -6, gradient_picture.get_width(), 13, picture_h::color::WHITE );
148 		gradient_picture.box( 1, middle -5, gradient_picture.get_width() -2, 11, picture_h::color::BLACK );
149 		gradient_picture.box( 2, middle -4, gradient_picture.get_width() -4, 9, picture_h::color::WHITE );
150 	}
151 
152 	gradient_picture.update();
153 }
154 
gradient_select_color(const picture2gtk * src,int32 x,int32 y,int32 button)155 void gradient_select_color( const picture2gtk *src, int32 x, int32 y, int32 button)
156 {
157 	if( button == 1 ) // left button
158 	{
159 		if( y < 0 )
160 			y = 0;
161 		if( y >= gradient_picture.get_height() )
162 			y = gradient_picture.get_height() -1;
163 
164 		active_color = int32( (1.0 - float(y) / float(gradient_picture.get_height() -1) ) *
165 		                      float(working_gradient.get_size() -1) + 0.5f);
166 		gradient_update_color();
167 	}
168 }
169 
gradient_change_color(GtkButton * button,gpointer user_data)170 void gradient_change_color(GtkButton *button, gpointer user_data)
171 {
172 	GtkColorSelectionDialog *colordialog;
173 	GdkColor color;
174 
175 	colorrgb_to_gdkcolor( *working_gradient[active_color], color );
176 
177 	colordialog = (GtkColorSelectionDialog *) gtk_color_selection_dialog_new(NULL);
178 
179 	gtk_color_selection_set_current_color( GTK_COLOR_SELECTION(colordialog->colorsel), &color );
180 
181 	gtk_window_set_transient_for( GTK_WINDOW(colordialog), GTK_WINDOW(the_parent) );
182 	gtk_window_set_modal( GTK_WINDOW(colordialog), TRUE );
183 
184 	gtk_widget_show_all( GTK_WIDGET(colordialog) );
185 
186 	gtk_widget_hide(colordialog->help_button);
187 
188 	if( gtk_dialog_run( GTK_DIALOG(colordialog) ) == GTK_RESPONSE_OK )
189 	{
190 		picture_h::colorrgb colorr;
191 
192 		gtk_color_selection_get_current_color( GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colordialog)->colorsel), &color );
193 		gdkcolor_to_colorrgb( color, colorr );
194 		*working_gradient[active_color] = colorr;
195 		gradient_update_color();
196 	}
197 	gtk_widget_destroy( GTK_WIDGET(colordialog) );
198 }
199 
gradient_add_color(GtkButton * button,gpointer user_data)200 void gradient_add_color(GtkButton *button, gpointer user_data)
201 {
202 	GtkColorSelectionDialog *colordialog;
203 	GdkColor color;
204 
205 	colorrgb_to_gdkcolor( *working_gradient[active_color], color );
206 
207 	colordialog = (GtkColorSelectionDialog *) gtk_color_selection_dialog_new(NULL);
208 
209 	gtk_color_selection_set_current_color( GTK_COLOR_SELECTION(colordialog->colorsel), &color );
210 
211 	gtk_window_set_transient_for( GTK_WINDOW(colordialog), GTK_WINDOW(the_parent) );
212 	gtk_window_set_modal( GTK_WINDOW(colordialog), TRUE );
213 
214 	gtk_widget_show_all( GTK_WIDGET(colordialog) );
215 
216 	gtk_widget_hide(colordialog->help_button);
217 
218 	if( gtk_dialog_run( GTK_DIALOG(colordialog) ) == GTK_RESPONSE_OK )
219 	{
220 		picture_h::colorrgb colorr;
221 
222 		gtk_color_selection_get_current_color( GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colordialog)->colorsel), &color );
223 		gdkcolor_to_colorrgb( color, colorr );
224 		working_gradient.insert( colorr, active_color );
225 		gradient_update_color();
226 	}
227 	gtk_widget_destroy( GTK_WIDGET(colordialog) );
228 }
229 
gradient_remove_color(GtkButton * button,gpointer user_data)230 void gradient_remove_color(GtkButton *button, gpointer user_data)
231 {
232 	if( working_gradient.get_size() > 1 )
233 	{
234 		working_gradient.remove( active_color );
235 		gradient_update_color();
236 	}
237 }
238 
gradient_move_up(GtkButton * button,gpointer user_data)239 void gradient_move_up(GtkButton *button, gpointer user_data)
240 {
241 	if( active_color != (working_gradient.get_size() -1) )
242 	{
243 		picture_h::colorrgb color;
244 
245 		color = *working_gradient[active_color];
246 		*working_gradient[active_color] = *working_gradient[active_color +1];
247 		*working_gradient[active_color +1] = color;
248 		active_color++;
249 		gradient_update_color();
250 	}
251 }
252 
gradient_move_down(GtkButton * button,gpointer user_data)253 void gradient_move_down(GtkButton *button, gpointer user_data)
254 {
255 	if( active_color != 0 )
256 	{
257 		picture_h::colorrgb color;
258 
259 		color = *working_gradient[active_color];
260 		*working_gradient[active_color] = *working_gradient[active_color -1];
261 		*working_gradient[active_color -1] = color;
262 		active_color--;
263 		gradient_update_color();
264 	}
265 }
266