17 buf = g_malloc( strlen("Galaxy - ") + (( XGalaxy.filename ) ? strlen(XGalaxy.filename) : 0) + 1);
18 if ( XGalaxy.filename ) {
19 char *ptr = strrchr(XGalaxy.filename,'/');
20 if ( !ptr ) ptr = XGalaxy.filename; else ptr++;
21 sprintf(buf,"Galaxy - %s", ptr);
23 sprintf(buf,"Galaxy");
25 gtk_window_set_title (GTK_WINDOW(XGalaxy.window), buf);
30 clearData( GtkWidget *w, gpointer data ) {
31 if ( XGalaxy.runing ) return;
33 gtk_label_set_text( GTK_LABEL(XGalaxy.dataEnergyField), "0");
34 gtk_label_set_text( GTK_LABEL(XGalaxy.dataImpulseField), "0");
35 gtk_label_set_text( GTK_LABEL(XGalaxy.dataMomentField), "0");
37 gtk_entry_set_text(GTK_ENTRY(XGalaxy.deltaField), "3600");
38 gtk_entry_set_text(GTK_ENTRY(XGalaxy.errorField), "1e-8");
39 gtk_list_store_clear( GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(XGalaxy.dataField))) );
41 if ( XGalaxy.filename ) {
42 g_free(XGalaxy.filename);
43 XGalaxy.filename=NULL;
47 XGalaxy.Xangle = XGalaxy.Yangle = XGalaxy.Zangle = 0.0;
48 gtk_range_set_value(GTK_RANGE(XGalaxy.XSlider), 0);
49 gtk_range_set_value(GTK_RANGE(XGalaxy.YSlider), 0);
50 gtk_range_set_value(GTK_RANGE(XGalaxy.ZSlider), 0);
51 memset( &(XGalaxy.angle), 0, sizeof(XGalaxy.angle) );
54 gtk_clist_clear( GTK_CLIST(XGalaxy.resField) );
55 gtk_label_set_text( GTK_LABEL(XGalaxy.resEnergyField), "0");
56 gtk_label_set_text( GTK_LABEL(XGalaxy.resImpulseField), "0");
57 gtk_label_set_text( GTK_LABEL(XGalaxy.resMomentField), "0");
58 gtk_label_set_text( GTK_LABEL(XGalaxy.resDeltaField), "0");
59 gtk_label_set_text( GTK_LABEL(XGalaxy.resTimeField), "0");
67 FILE *out = fopen(XGalaxy.filename, "w");
71 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
72 GTK_DIALOG_DESTROY_WITH_PARENT,
75 "Error saving file '%s': %s",
76 XGalaxy.filename, g_strerror (errno));
77 gtk_dialog_run (GTK_DIALOG (dialog));
78 gtk_widget_destroy(dialog);
82 fprintf(out, "delta=%G\n", atof( gtk_entry_get_text( GTK_ENTRY(XGalaxy.deltaField) ) ) );
83 fprintf(out, "error=%G\n", atof( gtk_entry_get_text( GTK_ENTRY(XGalaxy.errorField) ) ) );
85 for(i=0;i<XGalaxy.nentry;i++)
86 fprintf(out,"%G\t%G\t%G\t%G\t%G\t%G\t%G\n",
87 XGalaxy.entry[i].mass,
101 saveAsFile( GtkWidget *w, gpointer data ) {
102 GtkWidget *dialog = gtk_file_chooser_dialog_new("Save as", GTK_WINDOW(XGalaxy.window), GTK_FILE_CHOOSER_ACTION_SAVE,
103 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
106 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
107 if ( XGalaxy.filename ) g_free(XGalaxy.filename);
108 XGalaxy.filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
114 gtk_widget_destroy (dialog);
118 saveFile( GtkWidget *w, gpointer data ) {
119 if ( !XGalaxy.filename ) {
133 GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(XGalaxy.dataField)));
135 if ( XGalaxy.runing )
138 in = fopen(XGalaxy.filename, "r");
140 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
141 GTK_DIALOG_DESTROY_WITH_PARENT,
144 "Error opening file '%s': %s",
145 XGalaxy.filename, g_strerror (errno));
146 gtk_dialog_run (GTK_DIALOG (dialog));
147 gtk_widget_destroy(dialog);
148 g_free(XGalaxy.filename);
149 XGalaxy.filename=NULL;
153 while(fgets(buf, 4096, in)) {
154 if ( strncmp("delta", buf, strlen("delta"))==0 ) {
155 sscanf(buf,"delta=%lG", &tmp);
156 sprintf(buf,"%G", tmp);
157 gtk_entry_set_text( GTK_ENTRY(XGalaxy.deltaField), buf );
158 } else if ( strncmp("error", buf, strlen("error"))==0 ) {
159 sscanf(buf,"error=%lG", &tmp);
160 sprintf(buf,"%G", tmp);
161 gtk_entry_set_text( GTK_ENTRY(XGalaxy.errorField), buf );
162 } else if ( strlen(buf)>6 ) {
163 sscanf(buf,"%lG\t%lG\t%lG\t%lG\t%lG\t%lG\t%lG",
172 gtk_list_store_append( store, &iter );
173 sprintf(buf, "%G", star.mass);
174 gtk_list_store_set( store, &iter, 1, buf, -1);
175 sprintf(buf, "%G", star.c.x);
176 gtk_list_store_set( store, &iter, 2, buf, -1);
177 sprintf(buf, "%G", star.c.y);
178 gtk_list_store_set( store, &iter, 3, buf, -1);
179 sprintf(buf, "%G", star.c.z);
180 gtk_list_store_set( store, &iter, 4, buf, -1);
181 sprintf(buf, "%G", star.v.x);
182 gtk_list_store_set( store, &iter, 5, buf, -1);
183 sprintf(buf, "%G", star.v.y);
184 gtk_list_store_set( store, &iter, 6, buf, -1);
185 sprintf(buf, "%G", star.v.z);
186 gtk_list_store_set( store, &iter, 7, buf, -1);
191 gtk_notebook_set_current_page(GTK_NOTEBOOK(XGalaxy.notebook), 0);
196 openFile( GtkWidget *w, gpointer data ) {
197 if ( !XGalaxy.runing ) {
198 GtkWidget *dialog = gtk_file_chooser_dialog_new("Open", GTK_WINDOW(XGalaxy.window), GTK_FILE_CHOOSER_ACTION_OPEN,
199 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
202 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
204 if ( XGalaxy.filename ) g_free(XGalaxy.filename);
205 XGalaxy.filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
210 gtk_widget_destroy (dialog);
215 showAbout( GtkWidget *w, gpointer data ) {
217 GtkWidget *dialog = gtk_about_dialog_new() ;
219 gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "XGalaxy");
220 gtk_about_dialog_get_comments(GTK_ABOUT_DIALOG(dialog), "Gravity modeling");
221 gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "1.0");
222 gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "COPYRIGHT");
223 gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(dialog),"(X)Galaxy is under BSD license");
224 gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog),"http://www.sigaev.ru");
225 gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog),"Teodor Sigaev");
227 gtk_show_about_dialog(GTK_WINDOW(XGalaxy.window),
229 "comments", "Gravity modeling",
231 "copyright", "COPYRIGHT",
232 "license", "XGalaxy is under BSD license",
233 "website", "http://www.sigaev.ru",
234 "authors", "Teodor Sigaev",
237 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
241 "XGalaxy - gravity modeling software.\nCopyright Teodor Sigaev <teodor@sigaev.ru>, 2004.\nPublished under BSD license"
243 gtk_dialog_run (GTK_DIALOG (dialog));
244 gtk_widget_destroy(dialog);
248 fillResult(int clearres) {
254 pthread_mutex_lock(&(XGalaxy.mutex));
255 sprintf(buf,"%G",XGalaxy.galaxy.kineticEnergy + XGalaxy.galaxy.potentialEnergy);
256 gtk_label_set_text( GTK_LABEL(XGalaxy.resEnergyField), buf);
258 sprintf(buf,"%G",XGalaxy.galaxy.Impulse);
259 gtk_label_set_text( GTK_LABEL(XGalaxy.resImpulseField), buf);
261 sprintf(buf,"%G",XGalaxy.galaxy.Moment);
262 gtk_label_set_text( GTK_LABEL(XGalaxy.resMomentField), buf);
264 sprintf(buf,"%G",XGalaxy.galaxy.delta);
265 gtk_label_set_text( GTK_LABEL(XGalaxy.resDeltaField), buf);
267 sprintf(buf,"%G",XGalaxy.galaxy.elapsedTime);
268 gtk_label_set_text( GTK_LABEL(XGalaxy.resTimeField), buf);
270 memcpy( XGalaxy.tmpentry, XGalaxy.galaxy.stars, sizeof(Star)*XGalaxy.galaxy.nstars );
271 pthread_mutex_unlock(&(XGalaxy.mutex));
273 gtk_clist_freeze( GTK_CLIST(XGalaxy.resField) );
275 gchar *data[7] = { "", "", "", "", "", "", "" };
276 gtk_clist_clear( GTK_CLIST(XGalaxy.resField) );
277 for(i=0;i<XGalaxy.nentry;i++)
278 gtk_clist_append(GTK_CLIST(XGalaxy.resField), data);
282 for(i=0;i<XGalaxy.nentry;i++) {
283 sprintf(buf,"%G", XGalaxy.tmpentry[i].mass);
284 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 0, buf);
285 sprintf(buf,"%G", XGalaxy.tmpentry[i].c.x);
286 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 1, buf);
287 sprintf(buf,"%G", XGalaxy.tmpentry[i].c.y);
288 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 2, buf);
289 sprintf(buf,"%G", XGalaxy.tmpentry[i].c.z);
290 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 3, buf);
291 sprintf(buf,"%G", XGalaxy.tmpentry[i].v.x);
292 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 4, buf);
293 sprintf(buf,"%G", XGalaxy.tmpentry[i].v.y);
294 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 5, buf);
295 sprintf(buf,"%G", XGalaxy.tmpentry[i].v.z);
296 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 6, buf);
297 sprintf(buf,"%G", sqrt( XGalaxy.tmpentry[i].v.z*XGalaxy.tmpentry[i].v.z + XGalaxy.tmpentry[i].v.y*XGalaxy.tmpentry[i].v.y + XGalaxy.tmpentry[i].v.x*XGalaxy.tmpentry[i].v.x ) );
298 gtk_clist_set_text(GTK_CLIST(XGalaxy.resField), i, 7, buf);
300 gtk_clist_thaw( GTK_CLIST(XGalaxy.resField) );
303 static u_int32_t cycles=0;
305 fillResultByTimeout(gpointer data) {
306 if ( XGalaxy.runing==0 )
310 if ( !XGalaxy.paused ) {
311 struct timeval begin;
312 XGalaxy.runTime -= ((double)XG_TIME_TICK)/1000.0;
314 if ( XGalaxy.runTime >= 0 )
317 gettimeofday( &begin, NULL );
318 switch( XGalaxy.page_active ) {
320 if ( cycles++ % (int)ceil(200/XG_TIME_TICK) == 0 )
334 XGalaxy.runTime = elapsedtime( &begin );
336 if ( cycles > 2000000000 )
344 show_resCList(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) {
350 runingGravity(void *notneed) {
351 while( XGalaxy.request_to_exit == 0 ) {
352 liveGalaxy( &(XGalaxy.galaxy), &(XGalaxy.mutex) );
355 XGalaxy.request_to_exit = 0;
364 if ( (rc=pthread_create(&(XGalaxy.thread), NULL, runingGravity, NULL))!=0 ) {
365 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
366 GTK_DIALOG_DESTROY_WITH_PARENT,
369 "Error starting thread': %s",
371 gtk_dialog_run (GTK_DIALOG (dialog));
372 gtk_widget_destroy(dialog);
378 actionStop( GtkWidget *w, gpointer data ) {
379 if ( !XGalaxy.runing )
382 if ( !XGalaxy.paused ) {
383 XGalaxy.request_to_exit = 1;
385 while(XGalaxy.request_to_exit);
389 freeGalaxy(&(XGalaxy.galaxy));
391 XGalaxy.locksignal=1;
392 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE);
393 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE);
394 g_object_set(G_OBJECT(XGalaxy.errorField), "editable", TRUE, NULL);
395 g_object_set(G_OBJECT(XGalaxy.deltaField), "editable", TRUE, NULL);
396 XGalaxy.locksignal=0;
398 XGalaxy.runing = XGalaxy.paused = XGalaxy.request_to_exit = 0;
400 if ( XGalaxy.drawaxis ) drawAxis();
405 actionPause( GtkWidget *w, gpointer data ) {
406 if (XGalaxy.locksignal)
408 XGalaxy.locksignal=1;
409 if ( !XGalaxy.runing ) {
410 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE);
411 XGalaxy.locksignal=0;
415 if ( XGalaxy.paused ) {
416 if ( startGravity() ) {
417 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), TRUE);
418 XGalaxy.locksignal=0;
421 XGalaxy.paused=XGalaxy.request_to_exit=0;
422 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE);
423 XGalaxy.locksignal=0;
427 XGalaxy.request_to_exit = 1;
429 while(XGalaxy.request_to_exit);
432 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), TRUE);
433 XGalaxy.locksignal=0;
439 actionRun( GtkWidget *w, gpointer data ) {
442 if (XGalaxy.locksignal)
445 XGalaxy.locksignal=1;
446 if ( XGalaxy.runing ) {
447 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), TRUE);
448 XGalaxy.locksignal=0;
452 if ( XGalaxy.nentry < 2 ) {
453 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
454 GTK_DIALOG_DESTROY_WITH_PARENT,
457 "Too small number of entries");
458 gtk_dialog_run (GTK_DIALOG (dialog));
459 gtk_widget_destroy(dialog);
461 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE);
462 XGalaxy.locksignal=0;
466 for(i=0;i<XGalaxy.nentry;i++)
467 if ( XGalaxy.entry[i].mass==0.0 || !finite(XGalaxy.entry[i].mass) ) {
468 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window),
469 GTK_DIALOG_DESTROY_WITH_PARENT,
473 gtk_dialog_run (GTK_DIALOG (dialog));
474 gtk_widget_destroy(dialog);
475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE);
476 XGalaxy.locksignal=0;
482 initGalaxy(&(XGalaxy.galaxy), XGalaxy.nentry);
483 memcpy(XGalaxy.galaxy.stars, XGalaxy.entry, XGalaxy.nentry*sizeof(Star));
485 g_object_set(G_OBJECT(XGalaxy.errorField), "editable", FALSE, NULL);
486 g_object_set(G_OBJECT(XGalaxy.deltaField), "editable", FALSE, NULL);
488 XGalaxy.galaxy.desiredDelta = atof(gtk_entry_get_text(GTK_ENTRY(XGalaxy.deltaField)));
489 XGalaxy.galaxy.errorLimit = atof(gtk_entry_get_text(GTK_ENTRY(XGalaxy.errorField)));
490 initLiveGalaxy( &(XGalaxy.galaxy) );
495 if ( startGravity() ) {
496 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE);
497 XGalaxy.locksignal=0;
498 freeGalaxy(&(XGalaxy.galaxy));
499 g_object_set(G_OBJECT(XGalaxy.errorField), "editable", TRUE, NULL);
500 g_object_set(G_OBJECT(XGalaxy.deltaField), "editable", TRUE, NULL);
505 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), TRUE);
506 XGalaxy.paused=XGalaxy.request_to_exit=0;
507 XGalaxy.locksignal=0;
508 g_timeout_add(XG_TIME_TICK, fillResultByTimeout, NULL);