#include #include #include #include #include #include #include #include "tools.h" #include "tmalloc.h" #include "xgalaxy.h" void galaxy_set_title() { char *buf; buf = g_malloc( strlen("Galaxy - ") + (( XGalaxy.filename ) ? strlen(XGalaxy.filename) : 0) + 1); if ( XGalaxy.filename ) { char *ptr = strrchr(XGalaxy.filename,'/'); if ( !ptr ) ptr = XGalaxy.filename; else ptr++; sprintf(buf,"Galaxy - %s", ptr); } else sprintf(buf,"Galaxy"); gtk_window_set_title (GTK_WINDOW(XGalaxy.window), buf); g_free(buf); } void clearData( GtkWidget *w, gpointer data ) { if ( XGalaxy.runing ) return; gtk_label_set_text( GTK_LABEL(XGalaxy.dataEnergyField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.dataImpulseField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.dataMomentField), "0"); gtk_entry_set_text(GTK_ENTRY(XGalaxy.deltaField), "3600"); gtk_entry_set_text(GTK_ENTRY(XGalaxy.errorField), "1e-8"); gtk_list_store_clear( GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(XGalaxy.dataField))) ); if ( XGalaxy.filename ) { g_free(XGalaxy.filename); XGalaxy.filename=NULL; galaxy_set_title(); } freeStarEntry(); XGalaxy.Xangle = XGalaxy.Yangle = XGalaxy.Zangle = 0.0; gtk_range_set_value(GTK_RANGE(XGalaxy.XSlider), 0); gtk_range_set_value(GTK_RANGE(XGalaxy.YSlider), 0); gtk_range_set_value(GTK_RANGE(XGalaxy.ZSlider), 0); memset( &(XGalaxy.angle), 0, sizeof(XGalaxy.angle) ); XGalaxy.angle.w=1; gtk_clist_clear( GTK_CLIST(XGalaxy.resField) ); gtk_label_set_text( GTK_LABEL(XGalaxy.resEnergyField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.resImpulseField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.resMomentField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.resDeltaField), "0"); gtk_label_set_text( GTK_LABEL(XGalaxy.resTimeField), "0"); clearDraw(); drawGalaxy(); } void saveData() { FILE *out = fopen(XGalaxy.filename, "w"); u_int32_t i; if ( !out ) { GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Error saving file '%s': %s", XGalaxy.filename, g_strerror (errno)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); return; } fprintf(out, "delta=%G\n", atof( gtk_entry_get_text( GTK_ENTRY(XGalaxy.deltaField) ) ) ); fprintf(out, "error=%G\n", atof( gtk_entry_get_text( GTK_ENTRY(XGalaxy.errorField) ) ) ); fprintf(out, "\n"); for(i=0;i6 ) { sscanf(buf,"%lG\t%lG\t%lG\t%lG\t%lG\t%lG\t%lG", &(star.mass), &(star.c.x), &(star.c.y), &(star.c.z), &(star.v.x), &(star.v.y), &(star.v.z) ); gtk_list_store_append( store, &iter ); sprintf(buf, "%G", star.mass); gtk_list_store_set( store, &iter, 1, buf, -1); sprintf(buf, "%G", star.c.x); gtk_list_store_set( store, &iter, 2, buf, -1); sprintf(buf, "%G", star.c.y); gtk_list_store_set( store, &iter, 3, buf, -1); sprintf(buf, "%G", star.c.z); gtk_list_store_set( store, &iter, 4, buf, -1); sprintf(buf, "%G", star.v.x); gtk_list_store_set( store, &iter, 5, buf, -1); sprintf(buf, "%G", star.v.y); gtk_list_store_set( store, &iter, 6, buf, -1); sprintf(buf, "%G", star.v.z); gtk_list_store_set( store, &iter, 7, buf, -1); addEntry(&star); } } fclose(in); gtk_notebook_set_current_page(GTK_NOTEBOOK(XGalaxy.notebook), 0); cntEntry(); } void openFile( GtkWidget *w, gpointer data ) { if ( !XGalaxy.runing ) { GtkWidget *dialog = gtk_file_chooser_dialog_new("Open", GTK_WINDOW(XGalaxy.window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { clearData(w,data); if ( XGalaxy.filename ) g_free(XGalaxy.filename); XGalaxy.filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); galaxy_set_title(); loadData(); } gtk_widget_destroy (dialog); } } void showAbout( GtkWidget *w, gpointer data ) { /* 2.6 only GtkWidget *dialog = gtk_about_dialog_new() ; gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), "XGalaxy"); gtk_about_dialog_get_comments(GTK_ABOUT_DIALOG(dialog), "Gravity modeling"); gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), "1.0"); gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(dialog), "COPYRIGHT"); gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(dialog),"(X)Galaxy is under BSD license"); gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(dialog),"http://www.sigaev.ru"); gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(dialog),"Teodor Sigaev"); gtk_show_about_dialog(GTK_WINDOW(XGalaxy.window), "name", "XGalaxy", "comments", "Gravity modeling", "version", "1.0", "copyright", "COPYRIGHT", "license", "XGalaxy is under BSD license", "website", "http://www.sigaev.ru", "authors", "Teodor Sigaev", NULL); */ GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "XGalaxy - gravity modeling software.\nCopyright Teodor Sigaev , 2004.\nPublished under BSD license" ); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); } void fillResult(int clearres) { char buf[128]; int i; pthread_mutex_lock(&(XGalaxy.mutex)); sprintf(buf,"%G",XGalaxy.galaxy.kineticEnergy + XGalaxy.galaxy.potentialEnergy); gtk_label_set_text( GTK_LABEL(XGalaxy.resEnergyField), buf); sprintf(buf,"%G",XGalaxy.galaxy.Impulse); gtk_label_set_text( GTK_LABEL(XGalaxy.resImpulseField), buf); sprintf(buf,"%G",XGalaxy.galaxy.Moment); gtk_label_set_text( GTK_LABEL(XGalaxy.resMomentField), buf); sprintf(buf,"%G",XGalaxy.galaxy.delta); gtk_label_set_text( GTK_LABEL(XGalaxy.resDeltaField), buf); sprintf(buf,"%G",XGalaxy.galaxy.elapsedTime); gtk_label_set_text( GTK_LABEL(XGalaxy.resTimeField), buf); memcpy( XGalaxy.tmpentry, XGalaxy.galaxy.stars, sizeof(Star)*XGalaxy.galaxy.nstars ); pthread_mutex_unlock(&(XGalaxy.mutex)); gtk_clist_freeze( GTK_CLIST(XGalaxy.resField) ); if ( clearres ) { gchar *data[7] = { "", "", "", "", "", "", "" }; gtk_clist_clear( GTK_CLIST(XGalaxy.resField) ); for(i=0;i= 0 ) return TRUE; gettimeofday( &begin, NULL ); switch( XGalaxy.page_active ) { case 2: if ( cycles++ % (int)ceil(200/XG_TIME_TICK) == 0 ) fillResult(FALSE); if (XGalaxy.trace) drawStars(); break; case 1: drawGalaxy(); break; default: if (XGalaxy.trace) drawStars(); break; } XGalaxy.runTime = elapsedtime( &begin ); if ( cycles > 2000000000 ) cycles=1; } return TRUE; } gboolean show_resCList(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { g_print("EVENT\n"); return FALSE; } void* runingGravity(void *notneed) { while( XGalaxy.request_to_exit == 0 ) { liveGalaxy( &(XGalaxy.galaxy), &(XGalaxy.mutex) ); pthread_yield(); } XGalaxy.request_to_exit = 0; return NULL; } int startGravity() { int rc; if ( (rc=pthread_create(&(XGalaxy.thread), NULL, runingGravity, NULL))!=0 ) { GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Error starting thread': %s", g_strerror (errno)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); } return rc; } void actionStop( GtkWidget *w, gpointer data ) { if ( !XGalaxy.runing ) return; if ( !XGalaxy.paused ) { XGalaxy.request_to_exit = 1; /* wait thread */ while(XGalaxy.request_to_exit); } fillResult(FALSE); freeGalaxy(&(XGalaxy.galaxy)); XGalaxy.locksignal=1; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE); g_object_set(G_OBJECT(XGalaxy.errorField), "editable", TRUE, NULL); g_object_set(G_OBJECT(XGalaxy.deltaField), "editable", TRUE, NULL); XGalaxy.locksignal=0; XGalaxy.runing = XGalaxy.paused = XGalaxy.request_to_exit = 0; clearDraw(); if ( XGalaxy.drawaxis ) drawAxis(); drawGalaxy(); } void actionPause( GtkWidget *w, gpointer data ) { if (XGalaxy.locksignal) return; XGalaxy.locksignal=1; if ( !XGalaxy.runing ) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE); XGalaxy.locksignal=0; return; } if ( XGalaxy.paused ) { if ( startGravity() ) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), TRUE); XGalaxy.locksignal=0; return; } XGalaxy.paused=XGalaxy.request_to_exit=0; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), FALSE); XGalaxy.locksignal=0; return; } XGalaxy.request_to_exit = 1; /* wait thread */ while(XGalaxy.request_to_exit); XGalaxy.paused = 1; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonPause), TRUE); XGalaxy.locksignal=0; fillResult(FALSE); drawGalaxy(); } void actionRun( GtkWidget *w, gpointer data ) { int i; if (XGalaxy.locksignal) return; XGalaxy.locksignal=1; if ( XGalaxy.runing ) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), TRUE); XGalaxy.locksignal=0; return; } if ( XGalaxy.nentry < 2 ) { GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW(XGalaxy.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "Too small number of entries"); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy(dialog); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(XGalaxy.buttonRun), FALSE); XGalaxy.locksignal=0; return; } for(i=0;i