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