1 /*
2 * Dr Geo an interactive geometry software
3 * (C) Copyright Hilaire Fernandes 2001
4 * hilaire@ofset.org
5 *
6 *
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public Licences as by published
11 * by the Free Software Foundation; either version 2; or (at your option)
12 * any later version
13 *
14 * This program is distributed in the hope that it will entertaining,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Publis License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.
21 * 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include <stdio.h>
25 #include <glade/glade.h>
26
27 #include "drgeo_gtkproperty.h"
28 #include "drgeo_gtkdrawable.h"
29 #include "drgeo_numeric.h"
30 #include "drgeo_command.h"
31 #include "drgeo_point.h"
32 #include "drgeo_script.h"
33 #include "drgeo_gtkhelpers.h"
34 #include "drgenius_mdi.h"
35
36 extern drgeniusMDI *mdi;
37 extern const char * drgeniusHelp[];
38
39 // Callback for the free point property dialog
40 static void
on_freePointAbscissaEntry_activate(GtkWidget * widget,gpointer data)41 on_freePointAbscissaEntry_activate (GtkWidget * widget, gpointer data)
42 {
43 drgeoVector v (0, 0);
44 drgeoGtkPropertyDialog *dialog;
45 point *item;
46 gdouble val;
47
48 val = strtod (gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
49
50 dialog = (drgeoGtkPropertyDialog *) data;
51 item = (point *) dialog->getItem ();
52 v.setX (val - item->getCoordinate ().getX ());
53 dialog->moveItem (v);
54 }
55
56 static void
on_freePointOrdinateEntry_activate(GtkWidget * widget,gpointer data)57 on_freePointOrdinateEntry_activate (GtkWidget * widget, gpointer data)
58 {
59 drgeoVector v (0, 0);
60 drgeoGtkPropertyDialog *dialog;
61 point *item;
62 gdouble val;
63
64 val = strtod (gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
65
66 dialog = (drgeoGtkPropertyDialog *) data;
67 item = (point *) dialog->getItem ();
68 v.setY (val - item->getCoordinate ().getY ());
69 dialog->moveItem (v);
70 }
71
72 static void
movePointWithEntriesValues(GtkWidget * widget,drgeoGtkPropertyDialog * dialog)73 movePointWithEntriesValues (GtkWidget * widget,
74 drgeoGtkPropertyDialog * dialog)
75 {
76
77 GtkEntry *abscissa, *ordinate;
78 drgeoVector v;
79 point *item;
80 gdouble val1, val2;
81
82 abscissa = (GtkEntry *) gtk_object_get_data (GTK_OBJECT (widget),
83 "abscissaEntry");
84 ordinate = (GtkEntry *) gtk_object_get_data (GTK_OBJECT (widget),
85 "ordinateEntry");
86 val1 = strtod (gtk_entry_get_text (abscissa), NULL);
87 val2 = strtod (gtk_entry_get_text (ordinate), NULL);
88
89 item = (point *) dialog->getItem ();
90 v.set (val1 - item->getCoordinate ().getX (),
91 val2 - item->getCoordinate ().getY ());
92 dialog->moveItem (v);
93 }
94
95 static void
on_freePointDialog_reponse(GtkDialog * d,gint r,gpointer data)96 on_freePointDialog_reponse (GtkDialog *d, gint r, gpointer data)
97 {
98 drgeoGtkPropertyDialog *dialog;
99
100 dialog = (drgeoGtkPropertyDialog *) data;
101
102 switch (r)
103 {
104 case GTK_RESPONSE_OK:
105 movePointWithEntriesValues (GTK_WIDGET (d), dialog);
106 dialog->hide ();
107 break;
108 case GTK_RESPONSE_APPLY:
109 movePointWithEntriesValues (GTK_WIDGET (d), dialog);
110 break;
111 case GTK_RESPONSE_CANCEL:
112 dialog->hide ();
113 break;
114 }
115 }
116
117 // Callback for the edit value property dialog
118 static void
on_editValueEntry_activate(GtkWidget * widget,gpointer data)119 on_editValueEntry_activate (GtkWidget * widget, gpointer data)
120 {
121 drgeoGtkPropertyDialog *dialog;
122 gdouble val;
123
124 val = g_ascii_strtod (gtk_entry_get_text (GTK_ENTRY (widget)), NULL);
125
126 dialog = (drgeoGtkPropertyDialog *) data;
127 dialog->setValue (val);
128 }
129
130 static void
on_editValueDialog_response(GtkWidget * widget,gint b,gpointer data)131 on_editValueDialog_response (GtkWidget * widget, gint b, gpointer data)
132 {
133 drgeoGtkPropertyDialog *drgeoDialog;
134 drgeoDialog = (drgeoGtkPropertyDialog *) data;
135 widget = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (widget),
136 "valueEntry"));
137 switch (b)
138 {
139 case GTK_RESPONSE_OK:
140 // Ok
141 on_editValueEntry_activate (widget, drgeoDialog);
142 drgeoDialog->hide ();
143 break;
144 case GTK_RESPONSE_APPLY:
145 // Apply
146 on_editValueEntry_activate (widget, drgeoDialog);
147 break;
148 case GTK_RESPONSE_CANCEL:
149 // Cancel
150 drgeoDialog->hide ();
151 break;
152 }
153 }
154
155 // When the user close the window containing the dialog
156 static gint
on_propertyDialog_delete(GtkWidget * widget,GdkEventAny * e,gpointer data)157 on_propertyDialog_delete (GtkWidget * widget, GdkEventAny * e, gpointer data)
158 {
159 drgeoGtkPropertyDialog *dialog;
160 dialog = (drgeoGtkPropertyDialog *) data;
161 dialog->hide ();
162 return TRUE;
163 }
164
165 // Callback for the script edit dialog
166 static void
on_scriptDialog_response(GtkWidget * widget,gint b,drgeoGtkPropertyDialog * drgeoDialog)167 on_scriptDialog_response (GtkWidget *widget, gint b,
168 drgeoGtkPropertyDialog *drgeoDialog)
169 {
170 GtkTextView *text;
171 gchar *code;
172
173 text = (GtkTextView *) gtk_object_get_data (GTK_OBJECT (widget),
174 "script");
175 code = gtk_text_view_get_text (text);
176
177 switch (b)
178 {
179 case GTK_RESPONSE_OK:
180 // Ok
181 drgeoDialog->setScript (code);
182 drgeoDialog->hide ();
183 break;
184 case GTK_RESPONSE_APPLY:
185 // Apply
186 drgeoDialog->setScript (code);
187 break;
188 case GTK_RESPONSE_CANCEL:
189 // Cancel
190 drgeoDialog->hide ();
191 break;
192 }
193 }
194
drgeoGtkPropertyDialog(drgeoGtkDrawable * aDrawable)195 drgeoGtkPropertyDialog::drgeoGtkPropertyDialog (drgeoGtkDrawable * aDrawable)
196 {
197 drawable = aDrawable;
198 dialog = NULL;
199 category = NO_OBJECT;
200 type = NO_TYPE;
201 }
202
~drgeoGtkPropertyDialog()203 drgeoGtkPropertyDialog::~drgeoGtkPropertyDialog ()
204 {
205 hide ();
206 if (dialog)
207 {
208 gtk_widget_destroy (dialog);
209 dialog = NULL;
210 }
211 }
212
213 void
show()214 drgeoGtkPropertyDialog::show ()
215 {
216 if (dialog)
217 gtk_widget_show_all (dialog);
218 }
219
220 void
hide()221 drgeoGtkPropertyDialog::hide ()
222 {
223 if (dialog)
224 {
225 gtk_widget_hide (dialog);
226 /* unselected the selected item so they do no blink
227 anymore */
228 drawable->figure->clearSelection ();
229 }
230 }
231
232 void
edit(class geometricObject * aItem)233 drgeoGtkPropertyDialog::edit (class geometricObject * aItem)
234 {
235 GladeXML *xml;
236 GtkWidget *widget, *widget2;
237 drgeoPoint p;
238 gchar out[256] = "";
239
240 if (dialog && (aItem->getCategory () != category)
241 && (aItem->getType () != type))
242 gtk_widget_destroy (dialog);
243
244 // Acording to the object category, we build the corresponding dialog.
245 switch (aItem->getCategory ())
246 {
247 case FREE_PT:
248
249 if (category != aItem->getCategory ())
250 {
251 xml = glade_xml_new (DRGEO_GLADEDIR "/drgeo2.glade",
252 "freePointPropertyDialog", NULL);
253
254 dialog = glade_xml_get_widget (xml, "freePointPropertyDialog");
255
256 //set transient
257 mdi->setTransientDialog (GTK_WINDOW (dialog));
258
259 widget = glade_xml_get_widget (xml, "abscissaEntry");
260 gtk_signal_connect (GTK_OBJECT (widget), "activate",
261 GTK_SIGNAL_FUNC
262 (on_freePointAbscissaEntry_activate),
263 (gpointer) this);
264 gtk_object_set_data (GTK_OBJECT (dialog), "abscissaEntry", widget);
265
266 widget = glade_xml_get_widget (xml, "ordinateEntry");
267 gtk_signal_connect (GTK_OBJECT (widget), "activate",
268 GTK_SIGNAL_FUNC
269 (on_freePointOrdinateEntry_activate),
270 (gpointer) this);
271 gtk_object_set_data (GTK_OBJECT (dialog), "ordinateEntry", widget);
272
273 gtk_signal_connect (GTK_OBJECT (dialog), "response",
274 GTK_SIGNAL_FUNC (on_freePointDialog_reponse),
275 (gpointer) this);
276
277 g_object_unref (G_OBJECT (xml));
278 }
279 p = ((point *) aItem)->getCoordinate ();
280 // Update the entries field
281 widget = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (dialog),
282 "abscissaEntry");
283 snprintf (out, 255, "%f", p.getX ());
284 gtk_entry_set_text (GTK_ENTRY (widget), out);
285
286 widget = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (dialog),
287 "ordinateEntry");
288 snprintf (out, 255, "%f", p.getY ());
289 gtk_entry_set_text (GTK_ENTRY (widget), out);
290 break;
291 case NUMERIC:
292 // Only free value can be edited
293 if (aItem->getType () == FREE_VALUE)
294 {
295 if (category != aItem->getCategory ())
296 {
297 xml = glade_xml_new (DRGEO_GLADEDIR "/drgeo2.glade",
298 "editValuePropertyDialog", NULL);
299 dialog = glade_xml_get_widget (xml, "editValuePropertyDialog");
300
301 //set transient
302 mdi->setTransientDialog (GTK_WINDOW (dialog));
303
304 widget = glade_xml_get_widget (xml, "valueEntry");
305 gtk_signal_connect (GTK_OBJECT (widget), "activate",
306 GTK_SIGNAL_FUNC
307 (on_editValueEntry_activate),
308 (gpointer) this);
309 gtk_object_set_data (GTK_OBJECT (dialog), "valueEntry", widget);
310
311 gtk_signal_connect (GTK_OBJECT (dialog), "response",
312 GTK_SIGNAL_FUNC (on_editValueDialog_response),
313 (gpointer) this);
314
315 g_object_unref (G_OBJECT (xml));
316 }
317 // Update the entries field
318 widget = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (dialog),
319 "valueEntry");
320 snprintf (out, 255, "%f", ((numeric *) aItem)->getValue ());
321 gtk_entry_set_text (GTK_ENTRY (widget), out);
322 break;
323 }
324 break;
325 case SCRIPT:
326 if (category != aItem->getCategory ())
327 {
328 // the corresponding dialog is not opened
329 xml = glade_xml_new (DRGEO_GLADEDIR "/drgeo2.glade",
330 "scriptDialog", NULL);
331 dialog = glade_xml_get_widget (xml, "scriptDialog");
332
333 //set transient
334 mdi->setTransientDialog (GTK_WINDOW (dialog));
335
336 widget2 = glade_xml_get_widget (xml, "scriptText");
337 gtk_object_set_data (GTK_OBJECT (dialog), "script", widget2);
338
339 gtk_signal_connect (GTK_OBJECT (dialog), "response",
340 GTK_SIGNAL_FUNC (on_scriptDialog_response),
341 (gpointer) this);
342
343 widget = glade_xml_get_widget (xml, "help");
344 gtk_signal_connect (GTK_OBJECT (widget), "clicked",
345 GTK_SIGNAL_FUNC (open_help_cb),
346 (gpointer) (drgeniusHelp[2]));
347
348 gtk_signal_connect (GTK_OBJECT (dialog), "delete_event",
349 GTK_SIGNAL_FUNC (on_propertyDialog_delete),
350 (gpointer) this);
351
352
353 g_object_unref (G_OBJECT (xml));
354 }
355 // Update the text field with the script
356 // First empty the scriptText dialog
357 widget = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (dialog),
358 "script");
359 gtk_text_view_set_text (GTK_TEXT_VIEW (widget),
360 ((script *) aItem)->getScript ());
361 break;
362 default:
363 dialog = NULL;
364 return;
365 }
366 // These are the characteristics of the item under edition:
367 item = aItem;
368 category = item->getCategory ();
369 type = item->getType ();
370
371 show ();
372 }
373
374 void
moveItem(drgeoVector & v)375 drgeoGtkPropertyDialog::moveItem (drgeoVector & v)
376 {
377 drgeoVector t (0, 0);
378
379 drawable->getFigure ()->moveItem (item, v);
380 drawable->getFigure ()->dragSelection (t, v);
381 drawable->refresh ();
382 }
383
384 void
setValue(gdouble value)385 drgeoGtkPropertyDialog::setValue (gdouble value)
386 {
387 gdouble *val;
388
389 val = (gdouble *) g_malloc (sizeof (gdouble));
390 *val = value;
391 drawable->getFigure ()->setItemAttribute (item, drgeoValue, (gpointer) val);
392 }
393
394 void
setScript(gchar * script)395 drgeoGtkPropertyDialog::setScript (gchar * script)
396 {
397 drawable->getFigure ()->setItemAttribute (item, drgeoScript,
398 (gpointer) script);
399 }
400
401 void
refresh()402 drgeoGtkPropertyDialog::refresh ()
403 {
404 drawable->refresh ();
405 }
406
407 geometricObject *
getItem()408 drgeoGtkPropertyDialog::getItem ()
409 {
410 return item;
411 }
412
413
getDrawable()414 drgeoDrawable & drgeoGtkPropertyDialog::getDrawable ()
415 {
416 return (*((drgeoDrawable *) drawable));
417 }
418