1 /* tour1d_pp_ui.c */
2 /*
3 * ggobi
4 * Copyright (C) AT&T, Duncan Temple Lang, Dianne Cook 1999-2005
5 *
6 * ggobi is free software; you may use, redistribute, and/or modify it
7 * under the terms of the Eclipse Public License, which is distributed
8 * with the source code and displayed on the ggobi web site,
9 * www.ggobi.org. For more information, contact the authors:
10 *
11 * Deborah F. Swayne dfs@research.att.com
12 * Di Cook dicook@iastate.edu
13 * Duncan Temple Lang duncan@wald.ucdavis.edu
14 * Andreas Buja andreas.buja@wharton.upenn.edu
15 */
16
17 #include <gtk/gtk.h>
18 #include "vars.h"
19 #include "externs.h"
20
21 #define WIDTH 200
22 #define HEIGHT 100
23
24 /*-- projection pursuit indices --*/
25 #define PCA 0
26 #define LDA 1
27 #define CGINI 2
28 #define CENTROPY 3
29 #define CART_VAR 4
30 #define SUBD 5
31
32 /* terms in expansion, bandwidth */
33 /*
34 static GtkWidget *param_vb, *param_lbl, *param_scale;
35 static GtkAdjustment *param_adj;
36 */
37
38 /*-- called when closed from the close menu item --*/
action_close_cb(GtkAction * action,displayd * dsp)39 static void action_close_cb (GtkAction *action, displayd *dsp) {
40 gtk_widget_hide (dsp->t1d_window);
41 t1d_optimz(0, &dsp->t1d.get_new_target,
42 &dsp->t1d.target_selection_method, dsp);
43
44 /* free_optimize0_p(&dsp->t1d_pp_op); * should this go here? *
45 free_pp(&dsp->t1d_pp_param); seems not, causes a crash because window
46 just gets hidden, so shouldn't
47 free the arrays. */
48 }
49 /*-- called when destroyed from the window manager --*/
50 static void
close_wmgr_cb(GtkWidget * w,GdkEventButton * event,displayd * dsp)51 close_wmgr_cb (GtkWidget *w, GdkEventButton *event, displayd *dsp) {
52 gtk_widget_hide (dsp->t1d_window);
53 t1d_optimz(0, &dsp->t1d.get_new_target,
54 &dsp->t1d.target_selection_method, dsp);
55
56 free_optimize0_p(&dsp->t1d_pp_op);
57 free_pp(&dsp->t1d_pp_param);
58 gtk_widget_destroy (dsp->t1d_window);
59 dsp->t1d_window = NULL;
60 }
61
62 static void
action_show_controls_cb(GtkToggleAction * action,displayd * dsp)63 action_show_controls_cb(GtkToggleAction *action, displayd *dsp) {
64 if (gtk_toggle_action_get_active(action))
65 gtk_widget_show (dsp->t1d_control_frame);
66 else
67 gtk_widget_hide (dsp->t1d_control_frame);
68 }
69
70 /*static void
71 line_options_cb(gpointer data, guint action, GtkCheckMenuItem *w) {
72 g_printerr ("action = %d\n", action);
73
74 switch (action) {
75 case 0:
76 case 1:
77 case 2:
78 default:
79 fprintf(stderr, "Unhandled switch-case in line_options_cb\n");
80 }
81 }*/
82
83 /*static void
84 bitmap_size_cb(gpointer data, guint action, GtkCheckMenuItem *w) {
85 g_printerr ("action = %d\n", action);
86
87 switch (action) {
88 case 0:
89 case 1:
90 case 2:
91 default:
92 fprintf(stderr, "Unhandled switch-case in bitmap_size_cb\n");
93 }
94 }*/
95
96 /*static void
97 replot_freq_cb(gpointer data, guint action, GtkCheckMenuItem *w) {
98 g_printerr ("action = %d\n", action);
99
100 switch (action) {
101 case 1:
102 case 2:
103 case 4:
104 case 8:
105 case 16:
106 break;
107 default:
108 fprintf(stderr, "Unhandled switch-case in replot_freq_cb\n");
109 }
110 }*/
111
112 static void
t1d_optimz_cb(GtkToggleButton * w,displayd * dsp)113 t1d_optimz_cb (GtkToggleButton *w, displayd *dsp) {
114 if (dsp == NULL) {
115 g_printerr ("No display corresponds to these controls\n");
116 return;
117 }
118
119 t1d_optimz(w->active, &dsp->t1d.get_new_target,
120 &dsp->t1d.target_selection_method, dsp);
121 }
122
t1d_pptemp_set_cb(GtkAdjustment * adj,displayd * dsp)123 static void t1d_pptemp_set_cb (GtkAdjustment *adj, displayd *dsp) {
124
125 t1d_pptemp_set(adj->value, dsp, dsp->d->gg);
126 }
127
t1d_ppcool_set_cb(GtkAdjustment * adj,displayd * dsp)128 static void t1d_ppcool_set_cb (GtkAdjustment *adj, displayd *dsp) {
129
130 t1d_ppcool_set(adj->value, dsp, dsp->d->gg);
131 }
132
133 gchar *t1d_pp_func_lbl[] = {"Holes","Central Mass","PCA","LDA","Gini-C","Entropy-C"};
134 /*,"LDA","CART Gini","CART Entropy",
135 "CART Variance","SUB-D"
136 };*/
t1d_pp_func_cb(GtkWidget * w,displayd * dsp)137 void t1d_pp_func_cb (GtkWidget *w, displayd *dsp)
138 {
139 cpaneld *cpanel = NULL;
140 gint indx = gtk_combo_box_get_active(GTK_COMBO_BOX(w));
141 gchar *label = g_strdup("PP index: (0.000) 0.0000 (0.000)");
142 ggobid *gg;
143
144 if (dsp == NULL) {
145 g_printerr ("No display corresponds to these controls\n");
146 return;
147 }
148 gg = GGobiFromDisplay (dsp);
149
150 cpanel = &dsp->cpanel;
151 cpanel->t1d.pp_indx = indx;
152 dsp->t1d.get_new_target = true;
153
154 dsp->t1d.ppval = 0.0;
155 dsp->t1d.oppval = -1.0;
156 dsp->t1d_pp_op.index_best = 0.0;
157 sprintf(label, "PP index: (%3.1f) %5.3f (%3.1f) ",0.0,dsp->t1d.ppval,0.0);
158 gtk_label_set_text(GTK_LABEL(dsp->t1d_pplabel),label);
159
160 t1d_clear_ppda(dsp, gg);
161
162 /* if (indx == SUBD || LDA || CART_GINI || CART_ENTROPY || CART_VAR || PCA)
163 gtk_widget_hide (param_vb);
164 else {
165 gtk_widget_show (param_vb);
166 }*/
167 }
168
169 /*
170 static void bitmap_cb (GtkButton *button)
171 {
172 g_printerr ("drop a new bitmp\n");
173 }
174 static void
175 return_to_bitmap_cb (GtkToggleButton *w) {
176 g_printerr ("return to bitmap? %d\n", w->active);
177 }
178 static void
179 record_bitmap_cb (GtkToggleButton *w) {
180 g_printerr ("record bitmap? %d\n", w->active);
181 }
182 */
183
184 static gint
ppda_configure_cb(GtkWidget * w,GdkEventConfigure * event,displayd * dsp)185 ppda_configure_cb (GtkWidget *w, GdkEventConfigure *event, displayd *dsp)
186 {
187 gint wid = w->allocation.width, hgt = w->allocation.height;
188
189 if (dsp->t1d_pp_pixmap != NULL)
190 gdk_pixmap_unref (dsp->t1d_pp_pixmap);
191
192 dsp->t1d_pp_pixmap = gdk_pixmap_new (dsp->t1d_ppda->window,
193 wid, hgt, -1);
194
195 return false;
196 }
197
198 static gint
ppda_expose_cb(GtkWidget * w,GdkEventConfigure * event,displayd * dsp)199 ppda_expose_cb (GtkWidget *w, GdkEventConfigure *event, displayd *dsp)
200 {
201 ggobid *gg = dsp->d->gg;
202 /*
203 gint margin=10;
204 gint j;
205 gint xpos, ypos, xstrt, ystrt;
206 gchar *tickmk;
207 GtkStyle *style = gtk_widget_get_style (dsp->t1d_ppda);
208 GGobiData *d = dsp->d;
209 */
210 gint wid = w->allocation.width, hgt = w->allocation.height;
211 /* static gboolean init = true;*/
212
213 /* if (init) {
214 t1d_clear_ppda(dsp, gg);
215 init=false;
216 }*/
217
218 gdk_draw_pixmap (dsp->t1d_ppda->window, gg->plot_GC, dsp->t1d_pp_pixmap,
219 0, 0, 0, 0,
220 wid, hgt);
221
222 return false;
223 }
224
225 static const gchar* tour1dpp_ui =
226 "<ui>"
227 " <menubar>"
228 " <menu action='File'>"
229 " <menuitem action='Close'/>"
230 " </menu>"
231 " <menu action='Options'>"
232 " <menuitem action='ShowControls'/>"
233 " </menu>"
234 " </menubar>"
235 "</ui>";
236
237 static GtkActionEntry entries[] = {
238 { "File", NULL, "_File" },
239 { "Close", GTK_STOCK_CLOSE, "_Close", "<control>C",
240 "Hide the projection pursuit window", G_CALLBACK(action_close_cb)
241 },
242 { "Options", NULL, "_Options" }
243 };
244 static GtkToggleActionEntry t_entries[] = {
245 { "ShowControls", NULL, "_Show controls", "<control>S",
246 "Hide the controls on the left so that the graph consumes the entire window",
247 G_CALLBACK(action_show_controls_cb), true
248 }
249 };
250
251
252 void
tour1dpp_window_open(ggobid * gg)253 tour1dpp_window_open (ggobid *gg) {
254 GtkWidget *hbox, *vbox, *vbc, *vb, *frame, *tgl, *hb, *opt, *sbar, *lbl;
255 GtkObject *adj;
256 /*GtkWidget *da, *label, *entry;*/
257 displayd *dsp = gg->current_display; /* ok as long as we only use the gui */
258 GGobiData *d = dsp->d;
259 /*-- to initialize the checkboxes in the menu --*/
260
261 if (dsp->t1d_window == NULL) {
262 GtkUIManager *manager = gtk_ui_manager_new();
263 GtkActionGroup *actions = gtk_action_group_new("Tour1DPPActions");
264
265 dsp->t1d_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
266 gtk_window_set_title (GTK_WINDOW (dsp->t1d_window),
267 "Projection Pursuit - 1D");
268 g_signal_connect (G_OBJECT (dsp->t1d_window), "delete_event",
269 G_CALLBACK (close_wmgr_cb), (gpointer) dsp);
270 /*gtk_window_set_policy (GTK_WINDOW (dsp->t1d_window), true, true, false);*/
271 g_signal_connect (G_OBJECT(d), "rows_in_plot_changed",
272 G_CALLBACK(reset_pp), gg);
273
274 gtk_container_set_border_width (GTK_CONTAINER (dsp->t1d_window), 10);
275
276 /*
277 * Add the main menu bar
278 */
279 vbox = gtk_vbox_new (FALSE, 1);
280 gtk_container_set_border_width (GTK_CONTAINER (vbox), 1);
281 gtk_container_add (GTK_CONTAINER (dsp->t1d_window), vbox);
282
283 gtk_action_group_add_actions(actions, entries, G_N_ELEMENTS(entries), dsp);
284 gtk_action_group_add_toggle_actions(actions, t_entries, G_N_ELEMENTS(t_entries), dsp);
285 gtk_ui_manager_insert_action_group(manager, actions, 0);
286 g_object_unref(G_OBJECT(actions));
287 dsp->t1d_mbar = create_menu_bar(manager, tour1dpp_ui, dsp->t1d_window);
288 /*dsp->t1d_pp_accel_group = gtk_accel_group_new ();
289 factory = get_main_menu (menu_items,
290 sizeof (menu_items) / sizeof (menu_items[0]),
291 dsp->t1d_pp_accel_group, dsp->t1d_window, &dsp->t1d_mbar,
292 (gpointer) dsp);*/
293 gtk_box_pack_start (GTK_BOX (vbox), dsp->t1d_mbar, false, true, 0);
294
295 /*
296 * Divide the window: controls on the left, plot on the right
297 */
298 hbox = gtk_hbox_new (false, 1);
299 gtk_container_set_border_width (GTK_CONTAINER (hbox), 1);
300 gtk_box_pack_start (GTK_BOX (vbox),
301 hbox, true, true, 1);
302
303 /*
304 * Controls
305 */
306 dsp->t1d_control_frame = gtk_frame_new (NULL);
307 //gtk_frame_set_shadow_type (GTK_FRAME (dsp->t1d_control_frame), GTK_SHADOW_IN);
308 gtk_container_set_border_width (GTK_CONTAINER (dsp->t1d_control_frame), 5);
309 gtk_box_pack_start (GTK_BOX (hbox),
310 dsp->t1d_control_frame, false, false, 1);
311
312 vbc = gtk_vbox_new (false, 5);
313 gtk_container_set_border_width (GTK_CONTAINER (vbc), 5);
314 gtk_container_add (GTK_CONTAINER (dsp->t1d_control_frame), vbc);
315
316 /*
317 * Optimize toggle
318 */
319 tgl = gtk_check_button_new_with_mnemonic ("_Optimize");
320 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), tgl,
321 "Guide the tour using projection pursuit optimization or tour passively",
322 NULL);
323 g_signal_connect (G_OBJECT (tgl), "toggled",
324 G_CALLBACK (t1d_optimz_cb), (gpointer) dsp);
325 gtk_box_pack_start (GTK_BOX (vbc),
326 tgl, false, false, 1);
327
328 /*
329 * Box to hold temp start and cooling controls
330 */
331 hb = gtk_hbox_new (true, 2);
332
333 vb = gtk_vbox_new (false, 0);
334
335 lbl = gtk_label_new_with_mnemonic ("_Temp start:");
336 gtk_box_pack_start (GTK_BOX (vb), lbl, false, false, 0);
337
338 /*-- value, lower, upper, step --*/
339 adj = gtk_adjustment_new (1.0, 0.1, 3.0, 0.1, 0.1, 0.0);
340 g_signal_connect (G_OBJECT (adj), "value_changed",
341 G_CALLBACK (t1d_pptemp_set_cb), dsp);
342
343 sbar = gtk_hscale_new (GTK_ADJUSTMENT (adj));
344 gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), sbar);
345 gtk_widget_set_name (sbar, "TOUR1D:PP_TEMPST");
346 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), sbar,
347 "Adjust starting temp of pp", NULL);
348 gtk_range_set_update_policy (GTK_RANGE (sbar), GTK_UPDATE_CONTINUOUS);
349 gtk_scale_set_value_pos (GTK_SCALE (sbar), GTK_POS_BOTTOM);
350 gtk_scale_set_digits (GTK_SCALE (sbar), 2);
351
352 gtk_box_pack_start (GTK_BOX (vb), sbar,
353 false, false, 0);
354 gtk_box_pack_start (GTK_BOX (hb), vb,
355 false, false, 0);
356
357 /*-- value, lower, upper, step --*/
358 vb = gtk_vbox_new (false, 0);
359
360 lbl = gtk_label_new_with_mnemonic ("_Cooling:");
361 gtk_box_pack_start (GTK_BOX (vb), lbl,
362 false, false, 0);
363
364 adj = gtk_adjustment_new (0.99, 0.5, 1.0, 0.05, 0.05, 0.0);
365 g_signal_connect (G_OBJECT (adj), "value_changed",
366 G_CALLBACK (t1d_ppcool_set_cb), dsp);
367
368 sbar = gtk_hscale_new (GTK_ADJUSTMENT (adj));
369 gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), sbar);
370 gtk_widget_set_name (sbar, "TOUR1D:PP_COOLING");
371 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), sbar,
372 "Adjust cooling", NULL);
373 gtk_range_set_update_policy (GTK_RANGE (sbar), GTK_UPDATE_CONTINUOUS);
374 gtk_scale_set_value_pos (GTK_SCALE (sbar), GTK_POS_BOTTOM);
375 gtk_scale_set_digits (GTK_SCALE (sbar), 2);
376
377 gtk_box_pack_start (GTK_BOX (vb), sbar,
378 false, false, 0);
379 gtk_box_pack_start (GTK_BOX (hb), vb,
380 false, false, 0);
381
382 gtk_box_pack_start (GTK_BOX (vbc), hb, false, false, 0);
383
384 /*
385 * Index value with label
386 */
387 hb = gtk_hbox_new (false, 3);
388 gtk_box_pack_start (GTK_BOX (vbc), hb, false, false, 2);
389
390 dsp->t1d_pplabel = gtk_label_new ("PP index: (0.00) 0.0000 (0.00)");
391 gtk_misc_set_alignment (GTK_MISC (dsp->t1d_pplabel), 0, 0.5);
392 gtk_box_pack_start (GTK_BOX (hb), dsp->t1d_pplabel, false, false, 0);
393 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), dsp->t1d_pplabel,
394 "The value of the projection pursuit index for the current projection",
395 NULL);
396
397 /* entry = gtk_entry_new_with_max_length (32);
398 gtk_entry_set_editable (GTK_ENTRY (entry), false);
399 gtk_entry_set_text (GTK_ENTRY (entry), "0");
400 gtk_box_pack_start (GTK_BOX (hb), entry, false, false, 2);
401 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), entry,
402 "The value of the projection pursuit index for the current projection",
403 NULL);
404 g_signal_connect (G_OBJECT (entry), "value_changed",
405 G_CALLBACK (t1d_writeindx_cb), gg);*/
406 /* g_signal_connect (G_OBJECT (dsp->t1d.ppval), "value_changed",
407 G_CALLBACK (t1d_writeindx_cb), gg);*/
408
409 /*
410 * pp index menu and scale inside frame
411 */
412 /* frame = gtk_frame_new ("PP index function");
413 //gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT);
414 gtk_box_pack_start (GTK_BOX (vbc), frame, false, false, 0);
415 */
416
417 vb = gtk_vbox_new (false, 3);
418 gtk_box_pack_start (GTK_BOX (vbc), vb, false, false, 2);
419 /* gtk_container_add (GTK_CONTAINER (frame), vb);*/
420
421 opt = gtk_combo_box_new_text ();
422 //gtk_container_set_border_width (GTK_CONTAINER (opt), 4);
423 /*
424 gtk_misc_set_alignment (opt, 0, 0.5);
425 */
426 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), opt,
427 "Set the projection pursuit index", NULL);
428 gtk_box_pack_start (GTK_BOX (vb), opt, false, false, 0);
429 /* gtk_box_pack_start (GTK_BOX (hb), opt, false, false, 0);*/
430 populate_combo_box (opt, t1d_pp_func_lbl, G_N_ELEMENTS(t1d_pp_func_lbl),
431 G_CALLBACK(t1d_pp_func_cb), (gpointer) dsp);
432
433 /* param_vb = gtk_vbox_new (false, 3);
434 gtk_container_set_border_width (GTK_CONTAINER (param_vb), 4);
435 gtk_box_pack_start (GTK_BOX (vb), param_vb, false, false, 2);
436
437 param_lbl = gtk_label_new ("Terms in expansion:");
438 gtk_misc_set_alignment (GTK_MISC (param_lbl), 0, 0.5);
439 gtk_box_pack_start (GTK_BOX (param_vb), param_lbl, false, false, 0);
440
441 param_adj = (GtkAdjustment *) gtk_adjustment_new (1.0,
442 1.0, 30.0,
443 1.0, 1.0, 0.0);
444 param_scale = gtk_hscale_new (GTK_ADJUSTMENT (param_adj));
445 gtk_tooltips_set_tip (GTK_TOOLTIPS (gg->tips), param_scale,
446 "Set number of terms in the expansion for some indices; bandwidth for others", NULL);
447 gtk_range_set_update_policy (GTK_RANGE (param_scale),
448 GTK_UPDATE_CONTINUOUS);
449 gtk_scale_set_digits (GTK_SCALE (param_scale), 0);
450 gtk_scale_set_value_pos (GTK_SCALE (param_scale), GTK_POS_BOTTOM);
451
452 gtk_box_pack_start (GTK_BOX (param_vb), param_scale, true, true, 0);
453 */
454
455 /*
456 * Drawing area in a frame
457 */
458 frame = gtk_frame_new (NULL);
459 //gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
460 gtk_container_set_border_width (GTK_CONTAINER (frame), 5);
461 gtk_box_pack_start (GTK_BOX (hbox),
462 frame, true, true, 1);
463
464 dsp->t1d_ppda = gtk_drawing_area_new ();
465 gtk_widget_set_double_buffered(dsp->t1d_ppda, false);
466 gtk_widget_set_size_request (GTK_WIDGET (dsp->t1d_ppda), WIDTH, HEIGHT);
467 g_signal_connect (G_OBJECT (dsp->t1d_ppda),
468 "configure_event",
469 G_CALLBACK(ppda_configure_cb),
470 (gpointer) dsp);
471
472 g_signal_connect (G_OBJECT (dsp->t1d_ppda),
473 "expose_event",
474 G_CALLBACK(ppda_expose_cb),
475 (gpointer) dsp);
476
477 gtk_container_add (GTK_CONTAINER (frame), dsp->t1d_ppda);
478
479 gtk_widget_show_all (dsp->t1d_window);
480
481
482 }
483
484 alloc_optimize0_p(&dsp->t1d_pp_op, d->nrows_in_plot, dsp->t1d.nactive, 1);
485 alloc_pp(&dsp->t1d_pp_param, d->nrows_in_plot, dsp->t1d.nactive, 1);
486
487 gtk_widget_show_all (dsp->t1d_window);
488 }
489
490 #undef SUBD
491 #undef LDA
492 #undef CGINI
493 #undef CENTROPY
494 #undef CART_VAR
495 #undef PCA
496