add .gitignore
[xgalaxy.git] / xgalaxy.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <locale.h>
6 #include <gtk/gtk.h>
7
8 #include "tmalloc.h"
9 #include "xgalaxy.h"
10 #include "gtkcellrendererbutton.h"
11
12 XGlalaxyStruct XGalaxy;
13
14 gint 
15 delete( GtkWidget *widget, GtkWidget *event, gpointer   data ) {
16         if ( XGalaxy.runing && !XGalaxy.paused ) {
17                 XGalaxy.request_to_exit = 1;
18                 /* wait thread */
19                 while(XGalaxy.request_to_exit);
20         }
21
22         gtk_main_quit();
23         return(FALSE);
24 }
25
26 gboolean    
27 check_number(GtkWidget *widget, GdkEventFocus *event, gpointer user_data) {
28         char buf[128];
29         if ( atof(gtk_entry_get_text(GTK_ENTRY(widget))) <= 0 ) 
30                 sprintf(buf, "%G", *(double*)user_data );
31         else  
32                 sprintf(buf, "%G", atof(gtk_entry_get_text(GTK_ENTRY(widget))) );
33         gtk_entry_set_text(GTK_ENTRY(widget), buf);     
34         return FALSE;
35 }
36
37 typedef struct {
38         GtkListStore    *store;
39         int             colnumber;
40 } ColInfo;
41
42 void 
43 set_edited_data(GtkCellRendererText *cellrenderertext, gchar *arg1, gchar *arg2, gpointer user_data) {
44         GtkTreeIter   iter;
45         GtkTreePath *path;
46         ColInfo     *info = (ColInfo*)user_data;
47         char buf[128];
48         double val = atof(arg2);
49
50         if ( XGalaxy.runing ) return;
51
52         path = gtk_tree_path_new_from_string (arg1);
53         gtk_tree_model_get_iter(GTK_TREE_MODEL (info->store), &iter, path);
54         gtk_tree_path_free (path);
55
56         if ( info->colnumber==1 && val < 0 )
57                 val=-val;
58         sprintf(buf,"%G", val);
59         gtk_list_store_set( info->store, &iter, info->colnumber, buf, -1);
60         editEntry(atoi(arg1), info->colnumber, val);
61         cntEntry();
62 }
63
64 static int row_to_delete=-1;
65
66 void
67 cell_toggled(GtkCellRendererButton *cell_renderer, gchar *path, gpointer user_data) {
68         GtkTreePath *treepath;
69         GtkTreeIter   iter;
70         GtkListStore *store = GTK_LIST_STORE(user_data);
71
72         if ( XGalaxy.runing || row_to_delete>=0 ) return;
73
74         row_to_delete = atoi(path);
75         treepath = gtk_tree_path_new_from_string (path);
76         gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &iter, treepath);
77         gtk_tree_path_free (treepath);
78
79         gtk_list_store_set (GTK_LIST_STORE (store), &iter, 0, TRUE, -1);
80 }
81
82 gboolean    
83 button_release(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
84         char path[16];
85         GtkTreePath *treepath;
86         GtkTreeIter   iter;
87         GtkListStore *store = GTK_LIST_STORE(user_data);
88
89         if (row_to_delete<0)
90                 return FALSE;
91
92         sprintf(path,"%d", row_to_delete);
93         treepath = gtk_tree_path_new_from_string (path);
94         gtk_tree_model_get_iter(GTK_TREE_MODEL (store), &iter, treepath);
95         gtk_tree_path_free (treepath);
96
97         gtk_list_store_remove(store, &iter);
98         deleteEntry(row_to_delete);
99         cntEntry();
100
101         row_to_delete=-1;
102         
103         return FALSE;
104 }
105
106 void
107 append_row(GtkTreeViewColumn *treeviewcolumn, gpointer user_data) {
108         GtkTreeIter   iter;
109         GtkListStore *store = GTK_LIST_STORE(user_data);
110         int i;
111
112         if ( XGalaxy.runing ) return;
113         gtk_list_store_append( store, &iter );
114         for(i=1;i<8;i++) 
115                 gtk_list_store_set( store, &iter, i, "0", -1);
116         addEntry(NULL);
117 }
118
119 static int size_allocation_treelist_oldwidth=0;
120
121 static gint 
122 size_allocation_treelist(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) {
123         /* workaround to prevent size-allocation storm */
124         if ( size_allocation_treelist_oldwidth != allocation->width ) {
125                 int i;
126                 int colwidth = (allocation->width-18)/7;
127
128                 for(i=1;i<8;i++)
129                         gtk_tree_view_column_set_fixed_width( 
130                                 gtk_tree_view_get_column(GTK_TREE_VIEW(widget), i),
131                                 colwidth
132                         );
133
134                 size_allocation_treelist_oldwidth=allocation->width;
135         }
136         return TRUE;
137 }
138
139
140 static double default_delta=3600;
141 static double default_error=1e-8;
142
143 GtkWidget*
144 inputPage() {
145         GtkWidget *table, *frame;
146         GtkWidget *scrolled;
147         GtkWidget *label, *subtable, *aligment;
148         gchar *titles[8] = { "+", "Mass", "X", "Y", "Z", "Vx", "Vy", "Vz" };
149
150         table = gtk_table_new(3,100,FALSE);
151
152         frame=gtk_frame_new("Options");
153         gtk_container_set_border_width(GTK_CONTAINER (frame), 5);
154         gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 0, 1);  
155         gtk_widget_show (frame);
156
157         subtable = gtk_table_new(3,3,FALSE);
158
159         label = gtk_label_new("Delta T (secs):");
160         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
161         gtk_widget_show(label);
162         aligment=gtk_alignment_new(1,1,0,0);
163         gtk_container_add(GTK_CONTAINER(aligment), label);
164         gtk_container_set_border_width(GTK_CONTAINER (aligment), 3);
165         gtk_widget_show(aligment);
166         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,0,1);
167
168         XGalaxy.deltaField = gtk_entry_new_with_max_length(15);
169         gtk_entry_set_text(GTK_ENTRY(XGalaxy.deltaField), "3600");
170         gtk_signal_connect (GTK_OBJECT(XGalaxy.deltaField),"focus-out-event", (GtkSignalFunc) check_number, (gpointer)&default_delta);
171         gtk_widget_show(XGalaxy.deltaField);
172         aligment=gtk_alignment_new(0,1,0,0);
173         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.deltaField);
174         gtk_widget_show(aligment);
175         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,0,1);
176         
177         label = gtk_label_new("Quality:");
178         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
179         gtk_widget_show(label);
180         aligment=gtk_alignment_new(1,0,0,0);
181         gtk_container_add(GTK_CONTAINER(aligment), label);
182         gtk_container_set_border_width(GTK_CONTAINER (aligment), 3);
183         gtk_widget_show(aligment);
184         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,1,2);
185
186         XGalaxy.errorField = gtk_entry_new_with_max_length(15);
187         gtk_entry_set_text(GTK_ENTRY(XGalaxy.errorField), "1e-8");
188         gtk_signal_connect (GTK_OBJECT(XGalaxy.errorField),"focus-out-event", (GtkSignalFunc) check_number, (gpointer)&default_error);
189         gtk_widget_show(XGalaxy.errorField);
190         aligment=gtk_alignment_new(0,0,0,0);
191         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.errorField);
192         gtk_widget_show(aligment);
193         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,1,2);
194
195         gtk_widget_show(subtable);
196         gtk_container_add(GTK_CONTAINER(frame), subtable);
197
198         frame=gtk_frame_new("Summary information");
199         gtk_container_set_border_width(GTK_CONTAINER (frame), 5);
200         gtk_table_attach_defaults(GTK_TABLE(table), frame, 1, 2, 0, 1);  
201         gtk_widget_show (frame);
202
203         subtable = gtk_table_new(4,2,FALSE);
204
205         label = gtk_label_new("Energy:");
206         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
207         gtk_widget_show(label);
208         aligment=gtk_alignment_new(1,0.5,0,0);
209         gtk_container_add(GTK_CONTAINER(aligment), label);
210         gtk_widget_show(aligment);
211         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,0,1);
212
213         XGalaxy.dataEnergyField = gtk_label_new("0");
214         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.dataEnergyField), FALSE);
215         gtk_widget_show(XGalaxy.dataEnergyField);
216         aligment=gtk_alignment_new(0,0.5,0,0);
217         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.dataEnergyField);
218         gtk_widget_show(aligment);
219         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,0,1);
220
221         label = gtk_label_new("Impulse:");
222         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
223         gtk_widget_show(label);
224         aligment=gtk_alignment_new(1,0.5,0,0);
225         gtk_container_add(GTK_CONTAINER(aligment), label);
226         gtk_widget_show(aligment);
227         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,1,2);
228
229         XGalaxy.dataImpulseField = gtk_label_new("0");
230         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.dataImpulseField), FALSE);
231         gtk_widget_show(XGalaxy.dataImpulseField);
232         aligment=gtk_alignment_new(0,0.5,0,0);
233         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.dataImpulseField);
234         gtk_widget_show(aligment);
235         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,1,2);
236
237         label = gtk_label_new("Moment:");
238         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
239         gtk_widget_show(label);
240         aligment=gtk_alignment_new(1,0.5,0,0);
241         gtk_container_add(GTK_CONTAINER(aligment), label);
242         gtk_widget_show(aligment);
243         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,2,3);
244
245         XGalaxy.dataMomentField = gtk_label_new("0");
246         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.dataMomentField), FALSE);
247         gtk_widget_show(XGalaxy.dataMomentField);
248         aligment=gtk_alignment_new(0,0.5,0,0);
249         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.dataMomentField);
250         gtk_widget_show(aligment);
251         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,2,3);
252
253         gtk_widget_show(subtable);
254         gtk_container_add(GTK_CONTAINER(frame), subtable);
255
256         scrolled = gtk_scrolled_window_new(NULL,NULL);
257         gtk_container_set_border_width(GTK_CONTAINER (scrolled), 5);
258         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
259         gtk_table_attach_defaults(GTK_TABLE(table), scrolled, 0, 2, 1, 99);  
260         gtk_widget_show (scrolled);
261
262         do {
263                 int i;
264                 GtkListStore *store = gtk_list_store_new (8, 
265                                 G_TYPE_BOOLEAN, /* + */
266                                 G_TYPE_STRING,  /* mass */
267                                 G_TYPE_STRING,  /* X */
268                                 G_TYPE_STRING,  /* Y */
269                                 G_TYPE_STRING,  /* Z */
270                                 G_TYPE_STRING,  /* Vx */
271                                 G_TYPE_STRING,  /* Vy */
272                                 G_TYPE_STRING  /* Vz */
273                 );
274                 XGalaxy.dataField = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
275
276                 for(i=0;i<8;i++) {
277                         GtkCellRenderer *renderer;
278                         GtkTreeViewColumn *column;
279
280                         if ( i>0 ) {
281                                 ColInfo   *info = tmalloc(sizeof(ColInfo));
282
283                                 info->store=store;
284                                 info->colnumber=i;
285                                 renderer = gtk_cell_renderer_text_new ();
286
287                                 g_object_set (G_OBJECT (renderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
288                                 g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
289                                 g_object_set (G_OBJECT (renderer), "editable-set", TRUE, NULL);
290                                 g_object_set (G_OBJECT (renderer), "single-paragraph-mode", TRUE, NULL);
291                                 gtk_signal_connect (GTK_OBJECT(renderer),"edited", (GtkSignalFunc) set_edited_data, info);
292                                 column = gtk_tree_view_column_new_with_attributes(
293                                         titles[i],
294                                         renderer,
295                                         "text",
296                                         i,
297                                         NULL
298                                 );
299                                 gtk_tree_view_column_set_clickable(column, FALSE);
300                                 gtk_tree_view_column_set_resizable(column, TRUE);
301                                 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
302                                 gtk_tree_view_column_set_fixed_width(column, (640-56)/7);
303                         } else {
304                                 renderer = gtk_cell_renderer_button_new();
305                                 g_object_set (G_OBJECT (renderer), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
306                                 g_object_set (G_OBJECT (renderer), "activatable", TRUE, NULL);
307                                 gtk_signal_connect (GTK_OBJECT(renderer), "toggled", (GtkSignalFunc) cell_toggled, store);
308                                 column = gtk_tree_view_column_new_with_attributes(
309                                         titles[i],
310                                         renderer, "active", 0,
311                                         NULL
312                                 );
313                                 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
314                                 gtk_tree_view_column_set_fixed_width(column, 20);
315                                 gtk_tree_view_column_set_clickable(column, TRUE);
316                                 gtk_tree_view_column_set_resizable(column, FALSE);
317                                 gtk_signal_connect (GTK_OBJECT(column), "clicked", (GtkSignalFunc) append_row, store);
318                         }
319                         gtk_tree_view_append_column (GTK_TREE_VIEW (XGalaxy.dataField), column);
320                 }
321                 gtk_signal_connect (GTK_OBJECT(XGalaxy.dataField),"button-release-event", (GtkSignalFunc) button_release, store);
322         } while(0);
323         gtk_signal_connect (GTK_OBJECT(XGalaxy.dataField),"size-allocate", (GtkSignalFunc) size_allocation_treelist, NULL);
324         gtk_widget_show(XGalaxy.dataField);
325         gtk_container_add(GTK_CONTAINER(scrolled), XGalaxy.dataField);
326
327         gtk_widget_show(table);
328
329         return table;
330 }
331
332 static gint 
333 size_allocation_clist(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) {
334         int i;
335         int colwidth = (allocation->width-52)/8;
336
337         for(i=0;i<8;i++) 
338                 gtk_clist_set_column_width (GTK_CLIST(widget), i, colwidth);
339
340         return FALSE;
341 }
342
343 GtkWidget*
344 resPage() {
345         GtkWidget *scrolled, *frame, *label, *aligment, *subtable, *vbox;
346         gchar *titles[11] = { "Mass", "X", "Y", "Z", "Vx", "Vy", "Vz", "|V|", "A", "E", "I" };
347
348         vbox = gtk_vbox_new (FALSE, 1);
349         gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
350         gtk_widget_show (vbox);
351
352         frame=gtk_frame_new("Summary information");
353         gtk_container_set_border_width(GTK_CONTAINER (frame), 5);
354         gtk_widget_show (frame);
355
356         subtable = gtk_table_new(1,10,FALSE);
357
358         label = gtk_label_new("Energy:");
359         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
360         gtk_widget_show(label);
361         aligment=gtk_alignment_new(1,0.5,0,0);
362         gtk_container_add(GTK_CONTAINER(aligment), label);
363         gtk_widget_show(aligment);
364         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 0,1,0,1);
365
366         XGalaxy.resEnergyField = gtk_label_new("0");
367         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.resEnergyField), FALSE);
368         gtk_widget_show(XGalaxy.resEnergyField);
369         aligment=gtk_alignment_new(0.05,0.5,0,0);
370         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.resEnergyField);
371         gtk_widget_show(aligment);
372         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 1,2,0,1);
373
374         label = gtk_label_new("Impulse:");
375         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
376         gtk_widget_show(label);
377         aligment=gtk_alignment_new(1,0.5,0,0);
378         gtk_container_add(GTK_CONTAINER(aligment), label);
379         gtk_widget_show(aligment);
380         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 2,3,0,1);
381
382         XGalaxy.resImpulseField = gtk_label_new("0");
383         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.resImpulseField), FALSE);
384         gtk_widget_show(XGalaxy.resImpulseField);
385         aligment=gtk_alignment_new(0.05,0.5,0,0);
386         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.resImpulseField);
387         gtk_widget_show(aligment);
388         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 3,4,0,1);
389
390         label = gtk_label_new("Moment:");
391         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
392         gtk_widget_show(label);
393         aligment=gtk_alignment_new(1,0.5,0,0);
394         gtk_container_add(GTK_CONTAINER(aligment), label);
395         gtk_widget_show(aligment);
396         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 4,5,0,1);
397
398         XGalaxy.resMomentField = gtk_label_new("0");
399         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.resMomentField), FALSE);
400         gtk_widget_show(XGalaxy.resMomentField);
401         aligment=gtk_alignment_new(0.05,0.5,0,0);
402         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.resMomentField);
403         gtk_widget_show(aligment);
404         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 5,6,0,1);
405
406         label = gtk_label_new("Delta:");
407         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
408         gtk_widget_show(label);
409         aligment=gtk_alignment_new(1,0.5,0,0);
410         gtk_container_add(GTK_CONTAINER(aligment), label);
411         gtk_widget_show(aligment);
412         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 6,7,0,1);
413
414         XGalaxy.resDeltaField = gtk_label_new("0");
415         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.resDeltaField), FALSE);
416         gtk_widget_show(XGalaxy.resDeltaField);
417         aligment=gtk_alignment_new(0.05,0.5,0,0);
418         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.resDeltaField);
419         gtk_widget_show(aligment);
420         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 7,8,0,1);
421
422         label = gtk_label_new("Elapsed:");
423         gtk_label_set_line_wrap(GTK_LABEL(label), FALSE);
424         gtk_widget_show(label);
425         aligment=gtk_alignment_new(1,0.5,0,0);
426         gtk_container_add(GTK_CONTAINER(aligment), label);
427         gtk_widget_show(aligment);
428         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 8,9,0,1);
429
430         XGalaxy.resTimeField = gtk_label_new("0");
431         gtk_label_set_line_wrap(GTK_LABEL(XGalaxy.resTimeField), FALSE);
432         gtk_widget_show(XGalaxy.resTimeField);
433         aligment=gtk_alignment_new(0.05,0.5,0,0);
434         gtk_container_add(GTK_CONTAINER(aligment), XGalaxy.resTimeField);
435         gtk_widget_show(aligment);
436         gtk_table_attach_defaults(GTK_TABLE(subtable), aligment, 9,10,0,1);
437
438         gtk_widget_show(subtable);
439
440         gtk_container_add(GTK_CONTAINER(frame), subtable);
441         gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
442
443         scrolled = gtk_scrolled_window_new(NULL,NULL);
444         gtk_container_set_border_width(GTK_CONTAINER (scrolled), 5);
445         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
446         gtk_widget_show (scrolled);
447
448         XGalaxy.resField = gtk_clist_new_with_titles( 8, titles);
449         gtk_signal_connect (GTK_OBJECT(XGalaxy.resField),"size-allocate", (GtkSignalFunc) size_allocation_clist, NULL);
450         gtk_signal_connect (GTK_OBJECT(XGalaxy.resField),"hide", (GtkSignalFunc) show_resCList, NULL);
451         gtk_clist_set_selection_mode(GTK_CLIST(XGalaxy.resField),GTK_SELECTION_SINGLE);
452         gtk_container_add(GTK_CONTAINER(scrolled), XGalaxy.resField);
453
454         gtk_widget_show(XGalaxy.resField);
455         
456         gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
457         
458         return vbox;
459 }
460
461 static void 
462 scale_clicked (GtkButton *button, gpointer user_data) {
463         if ( XGalaxy.trace )
464                 return;
465         if ( (int)user_data )
466                 XGalaxy.Scale *= 1.5;
467         else
468                 XGalaxy.Scale /= 1.5;
469
470         drawGalaxy();
471 }
472
473 static void 
474 trace_clicked (GtkToggleButton *button, gpointer user_data) {
475         XGalaxy.trace = gtk_toggle_button_get_active(button);
476         drawGalaxy();
477 }
478
479 static void 
480 axis_clicked (GtkToggleButton *button, gpointer user_data) {
481         if ( XGalaxy.locksignal )
482                 return;
483         if ( XGalaxy.trace ) {
484                 XGalaxy.locksignal=1;
485                 gtk_toggle_button_set_active( button, !gtk_toggle_button_get_active(button) );
486                 XGalaxy.locksignal=0;
487                 return;
488         }
489         XGalaxy.drawaxis = gtk_toggle_button_get_active(button); 
490         drawGalaxy();
491 }
492
493 static gboolean
494 mouse_button_press(GtkWidget      *widget, GdkEventButton *event) {
495         XGalaxy.beginx = event->x;
496         XGalaxy.beginy = event->y;
497
498         memset( &(XGalaxy.motion.d), 0, sizeof(Vector));
499         XGalaxy.motion.w=1.0;
500
501         return FALSE;
502 }
503
504 GtkWidget*
505 viewPage() {
506         GtkWidget *vbox, *hbox, *separator, *button, *table;
507         GtkTooltips *button_bar_tips;
508         button_bar_tips = gtk_tooltips_new ();
509         
510         vbox = gtk_vbox_new (FALSE, 1);
511         gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
512         gtk_widget_show (vbox);
513
514         hbox=gtk_hbutton_box_new();
515         gtk_widget_show (hbox);
516
517         XGalaxy.buttonRun = gtk_toggle_button_new_with_label("Go!");
518         gtk_signal_connect (GTK_OBJECT(XGalaxy.buttonRun),"toggled", (GtkSignalFunc) actionRun, NULL);
519         gtk_container_set_border_width(GTK_CONTAINER (XGalaxy.buttonRun), 5);
520         gtk_widget_show(XGalaxy.buttonRun);
521         gtk_box_pack_start (GTK_BOX (hbox), XGalaxy.buttonRun, FALSE, TRUE, 0);
522         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), XGalaxy.buttonRun, "Start modeling", "");
523
524         XGalaxy.buttonPause = gtk_toggle_button_new_with_label("Pause");
525         gtk_signal_connect (GTK_OBJECT(XGalaxy.buttonPause),"toggled", (GtkSignalFunc) actionPause, NULL);
526         gtk_container_set_border_width(GTK_CONTAINER (XGalaxy.buttonPause), 5);
527         gtk_widget_show(XGalaxy.buttonPause);
528         gtk_box_pack_start (GTK_BOX (hbox), XGalaxy.buttonPause, FALSE, TRUE, 0);
529         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), XGalaxy.buttonPause, "Pause modeling", "");
530
531         button = gtk_button_new_with_label("Stop");
532         gtk_signal_connect (GTK_OBJECT(button),"clicked", (GtkSignalFunc) actionStop, NULL);
533         gtk_container_set_border_width(GTK_CONTAINER (button), 5);
534         gtk_widget_show(button);
535         gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
536         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), button, "Stop modeling", "");
537
538         //button = gtk_button_new_from_stock(GTK_STOCK_ZOOM_IN);
539         button = gtk_button_new_with_label("Scale +");
540         gtk_container_set_border_width(GTK_CONTAINER (button), 5);
541         gtk_widget_show(button);
542         gtk_signal_connect (GTK_OBJECT(button),"clicked", (GtkSignalFunc) scale_clicked, (gpointer)1);
543         gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
544         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), button, "Increase scale", "");
545
546         //button = gtk_button_new_from_stock(GTK_STOCK_ZOOM_OUT);
547         button = gtk_button_new_with_label("Scale -");
548         gtk_container_set_border_width(GTK_CONTAINER (button), 5);
549         gtk_widget_show(button);
550         gtk_signal_connect (GTK_OBJECT(button),"clicked", (GtkSignalFunc) scale_clicked, (gpointer)0);
551         gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
552         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), button, "Decrease scale", "");
553
554         button = gtk_toggle_button_new_with_label("Trace");
555         gtk_container_set_border_width(GTK_CONTAINER (button), 5);
556         gtk_widget_show(button);
557         gtk_signal_connect (GTK_OBJECT(button),"toggled", (GtkSignalFunc) trace_clicked, (gpointer)0);
558         gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
559         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), button, "Turn on/off trace of stars", "");
560
561         button = gtk_toggle_button_new_with_label("Axis");
562         gtk_container_set_border_width(GTK_CONTAINER (button), 5);
563         gtk_widget_show(button);
564         gtk_signal_connect (GTK_OBJECT(button),"toggled", (GtkSignalFunc) axis_clicked, (gpointer)0);
565         gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
566         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), button, "Axis show on/off", "");
567
568         gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
569         
570         separator = gtk_hseparator_new();
571         gtk_widget_show(separator);
572         
573         gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
574
575
576         table = gtk_table_new(1000,1000,FALSE);
577
578         XGalaxy.YSlider = gtk_hscale_new_with_range(-180, 180, 1);
579         gtk_scale_set_draw_value(GTK_SCALE(XGalaxy.YSlider), FALSE);
580         gtk_range_set_value(GTK_RANGE(XGalaxy.YSlider), 0);
581         gtk_signal_connect (GTK_OBJECT(XGalaxy.YSlider),"value-changed", (GtkSignalFunc) angle_changed, (gpointer)'Y');
582         gtk_widget_show (XGalaxy.YSlider);
583         gtk_table_attach_defaults(GTK_TABLE(table), XGalaxy.YSlider, 1,999, 999,1000);
584         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), XGalaxy.YSlider, "Turn around Y-axis", "");
585
586         XGalaxy.XSlider = gtk_vscale_new_with_range(-180, 180, 1);
587         gtk_scale_set_draw_value(GTK_SCALE(XGalaxy.XSlider), FALSE);
588         gtk_range_set_value(GTK_RANGE(XGalaxy.XSlider), 0);
589         gtk_signal_connect (GTK_OBJECT(XGalaxy.XSlider),"value-changed", (GtkSignalFunc) angle_changed, (gpointer)'X');
590         gtk_widget_show (XGalaxy.XSlider);
591         gtk_table_attach_defaults(GTK_TABLE(table), XGalaxy.XSlider, 0,1, 0,999);
592         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), XGalaxy.XSlider, "Turn around X-axis", "");
593
594         XGalaxy.ZSlider = gtk_vscale_new_with_range(-180, 180, 1);
595         gtk_scale_set_draw_value(GTK_SCALE(XGalaxy.ZSlider), FALSE);
596         gtk_range_set_value(GTK_RANGE(XGalaxy.ZSlider), 0);
597         gtk_signal_connect (GTK_OBJECT(XGalaxy.ZSlider),"value-changed", (GtkSignalFunc) angle_changed, (gpointer)'Z');
598         gtk_widget_show (XGalaxy.ZSlider);
599         gtk_table_attach_defaults(GTK_TABLE(table), XGalaxy.ZSlider, 999, 1000, 0, 999 );
600         gtk_tooltips_set_tip (GTK_TOOLTIPS (button_bar_tips), XGalaxy.ZSlider, "Turn around Z-axis", "");
601
602         XGalaxy.drawing_area = gtk_drawing_area_new ();
603         gtk_widget_set_events(XGalaxy.drawing_area,
604                         GDK_EXPOSURE_MASK|
605                         GDK_BUTTON_PRESS_MASK|
606                         GDK_BUTTON_RELEASE_MASK|
607                         GDK_POINTER_MOTION_MASK|
608                         GDK_POINTER_MOTION_HINT_MASK);
609         gtk_drawing_area_size (GTK_DRAWING_AREA (XGalaxy.drawing_area), 100,100);
610         gtk_widget_show (XGalaxy.drawing_area);
611         gtk_signal_connect (GTK_OBJECT (XGalaxy.drawing_area), "expose_event", (GtkSignalFunc) expose_event, NULL);
612         gtk_signal_connect (GTK_OBJECT(XGalaxy.drawing_area),"configure_event", (GtkSignalFunc) configure_event, NULL);
613         gtk_signal_connect (GTK_OBJECT(XGalaxy.drawing_area),"button_press_event", (GtkSignalFunc) mouse_button_press, NULL);
614         gtk_signal_connect (GTK_OBJECT(XGalaxy.drawing_area),"motion_notify_event", (GtkSignalFunc) mouse_motion_notify, NULL);
615         gtk_table_attach_defaults(GTK_TABLE(table), XGalaxy.drawing_area, 1,999, 0,999);
616
617         gtk_widget_show(table); 
618
619         gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
620
621         return vbox;
622 }
623
624 static GtkItemFactoryEntry menu_items[] = {
625   { "/_File",         NULL,         NULL, 0, "<Branch>" },
626   { "/File/_Open",    "<control>O", openFile, 0, NULL },
627   { "/File/_Save",    "<control>S", saveFile, 0, NULL },
628   { "/File/Save _As", NULL,         saveAsFile, 0, NULL },
629   { "/File/sep1",     NULL,         NULL, 0, "<Separator>" },
630   { "/File/Quit",     "<control>Q", gtk_main_quit, 0, NULL },
631   { "/_Options",      NULL,         NULL, 0, "<Branch>" },
632   { "/Options/Clear", NULL,         clearData, 0, NULL },
633   { "/Options/Fill",  NULL,         NULL, 0, NULL },
634   { "/_Help",         NULL,         NULL, 0, "<LastBranch>" },
635   { "/_Help/About",   NULL,         showAbout, 0, NULL },
636 };
637
638 static  GtkWidget*
639 get_main_menu(GtkWidget *window) {
640         GtkItemFactory *item_factory;
641         GtkAccelGroup *accel_group;
642         GtkWidget *menubar;
643         gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
644         
645         accel_group = gtk_accel_group_new ();
646
647         item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
648
649         gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
650
651         gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
652         
653         menubar = gtk_item_factory_get_widget (item_factory, "<main>");
654
655         return menubar;
656 }
657
658 void
659 page_switched(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data) {
660         XGalaxy.page_active = page_num; 
661 }
662
663 int
664 main( int argc, char *argv[] ) {
665         GtkWidget *window, *notebook, *menubar, *main_vbox;
666         int rc;
667
668         memset(&XGalaxy, 0, sizeof(XGalaxy));
669         XGalaxy.angle.w=1;
670         XGalaxy.motion.w=1.0;
671         XGalaxy.Scale=1.0;
672
673         gtk_init (&argc, &argv);
674
675         if ( (rc=pthread_mutex_init(&(XGalaxy.mutex), NULL)) != 0 ) {
676                 g_print("pthread_mutex_init returns %d: %s\n", rc, g_strerror(errno));
677                 exit(1);
678         }
679
680         XGalaxy.window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
681         galaxy_set_title();
682         gtk_window_set_default_size (GTK_WINDOW(window), 640, 480);
683         gtk_signal_connect (GTK_OBJECT (window), "delete_event", GTK_SIGNAL_FUNC (delete), NULL);
684
685         main_vbox = gtk_vbox_new (FALSE, 1);
686         gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 2);
687         gtk_container_add(GTK_CONTAINER(window), main_vbox);
688         gtk_widget_show (main_vbox);
689
690         menubar = get_main_menu(window);
691         gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, TRUE, 0);
692         gtk_widget_show (menubar);
693
694         notebook = gtk_notebook_new ();
695         gtk_notebook_set_tab_pos(GTK_NOTEBOOK (notebook), GTK_POS_TOP);
696         gtk_widget_show(notebook);
697
698         gtk_notebook_append_page( GTK_NOTEBOOK (notebook), inputPage(), gtk_label_new("Input") );
699         gtk_notebook_append_page( GTK_NOTEBOOK (notebook), viewPage(), gtk_label_new("View") );
700         gtk_notebook_append_page( GTK_NOTEBOOK (notebook), resPage(), gtk_label_new("Data View") );
701         gtk_signal_connect (GTK_OBJECT(notebook),"switch-page", (GtkSignalFunc) page_switched, NULL);
702         XGalaxy.notebook = notebook;
703
704         gtk_box_pack_start (GTK_BOX (main_vbox), notebook, TRUE, TRUE, 0);      
705
706
707         setlocale(LC_NUMERIC, "C");
708         gtk_widget_show(window);
709
710         gtk_main ();
711
712         return 0;
713 }
714