00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <gtk/gtk.h>
00014
00015 #include <celengine/selection.h>
00016 #include <celengine/simulation.h>
00017 #include <celmath/vecmath.h>
00018
00019 #include "dialog-goto.h"
00020 #include "common.h"
00021
00022
00023
00024 static int changeGotoUnits(GtkButton* w, gpointer choice);
00025 static void responseGotoObject(GtkDialog* w, gint response, gotoObjectData* d);
00026
00027
00028 static gboolean GetEntryFloat(GtkWidget* w, float& f);
00029 static void GotoObject(gotoObjectData* gotoObjectDlg);
00030
00031
00032
00033 void dialogGotoObject(AppData* app)
00034 {
00035 gotoObjectData *data = g_new0(gotoObjectData, 1);
00036 data->app = app;
00037
00038 data->dialog = gtk_dialog_new_with_buttons("Goto Object",
00039 GTK_WINDOW(app->mainWindow),
00040 GTK_DIALOG_DESTROY_WITH_PARENT,
00041 "Go To",
00042 GTK_RESPONSE_OK,
00043 GTK_STOCK_CLOSE,
00044 GTK_RESPONSE_CLOSE,
00045 NULL);
00046 data->nameEntry = gtk_entry_new();
00047 data->latEntry = gtk_entry_new();
00048 data->longEntry = gtk_entry_new();
00049 data->distEntry = gtk_entry_new();
00050
00051 if (data->dialog == NULL ||
00052 data->nameEntry == NULL ||
00053 data->latEntry == NULL ||
00054 data->longEntry == NULL ||
00055 data->distEntry == NULL)
00056 {
00057
00058 return;
00059 }
00060
00061
00062 double distance, longitude, latitude;
00063 app->simulation->getSelectionLongLat(distance, longitude, latitude);
00064
00065
00066 if (app->simulation->getSelection().body() != NULL)
00067 {
00068 char temp[20];
00069 distance = distance - (double) app->simulation->getSelection().body()->getRadius();
00070 sprintf(temp, "%.1f", (float)distance);
00071 gtk_entry_set_text(GTK_ENTRY(data->distEntry), temp);
00072 sprintf(temp, "%.5f", (float)longitude);
00073 gtk_entry_set_text(GTK_ENTRY(data->longEntry), temp);
00074 sprintf(temp, "%.5f", (float)latitude);
00075 gtk_entry_set_text(GTK_ENTRY(data->latEntry), temp);
00076 gtk_entry_set_text(GTK_ENTRY(data->nameEntry), (char*) app->simulation->getSelection().body()->getName().c_str());
00077 }
00078
00079 GtkWidget* vbox = gtk_vbox_new(TRUE, CELSPACING);
00080 gtk_container_set_border_width(GTK_CONTAINER(vbox), CELSPACING);
00081 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(data->dialog)->vbox), vbox, TRUE, TRUE, 0);
00082
00083 GtkWidget* align = NULL;
00084 GtkWidget* hbox = NULL;
00085 GtkWidget* label = NULL;
00086
00087
00088 align = gtk_alignment_new(1, 0, 0, 0);
00089 hbox = gtk_hbox_new(FALSE, CELSPACING);
00090 label = gtk_label_new("Object name:");
00091 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
00092 gtk_box_pack_start(GTK_BOX(hbox), data->nameEntry, FALSE, TRUE, 0);
00093 gtk_container_add(GTK_CONTAINER(align), hbox);
00094 gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, TRUE, 0);
00095
00096
00097 align = gtk_alignment_new(1, 0, 0, 0);
00098 hbox = gtk_hbox_new(FALSE, CELSPACING);
00099 label = gtk_label_new("Latitude:");
00100 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
00101 gtk_box_pack_start(GTK_BOX(hbox), data->latEntry, FALSE, TRUE, 0);
00102 gtk_container_add(GTK_CONTAINER(align), hbox);
00103 gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, TRUE, 0);
00104
00105 align = gtk_alignment_new(1, 0, 0, 0);
00106 hbox = gtk_hbox_new(FALSE, CELSPACING);
00107 label = gtk_label_new("Longitude:");
00108 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
00109 gtk_box_pack_start(GTK_BOX(hbox), data->longEntry, FALSE, TRUE, 0);
00110 gtk_container_add(GTK_CONTAINER(align), hbox);
00111 gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, TRUE, 0);
00112
00113
00114 align = gtk_alignment_new(1, 0, 0, 0);
00115 hbox = gtk_hbox_new(FALSE, CELSPACING);
00116 label = gtk_label_new("Distance:");
00117 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
00118 gtk_box_pack_start(GTK_BOX(hbox), data->distEntry, FALSE, TRUE, 0);
00119 gtk_container_add(GTK_CONTAINER(align), hbox);
00120 gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, TRUE, 0);
00121
00122
00123 data->units = 0;
00124 hbox = gtk_hbox_new(FALSE, CELSPACING);
00125 makeRadioItems(unitLabels, hbox, GTK_SIGNAL_FUNC(changeGotoUnits), NULL, data);
00126 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
00127
00128 g_signal_connect(data->dialog, "response",
00129 G_CALLBACK(responseGotoObject), data);
00130
00131 gtk_widget_show_all(data->dialog);
00132 }
00133
00134
00135
00136 static int changeGotoUnits(GtkButton* w, gpointer choice)
00137 {
00138 gotoObjectData* data = (gotoObjectData *)g_object_get_data(G_OBJECT(w), "data");
00139 gint selection = GPOINTER_TO_INT(choice);
00140
00141 data->units = selection;
00142
00143 return TRUE;
00144 }
00145
00146
00147
00148
00149 static void responseGotoObject(GtkDialog* w, gint response, gotoObjectData* d)
00150 {
00151 switch (response) {
00152 case GTK_RESPONSE_OK:
00153 GotoObject(d);
00154 break;
00155 case GTK_RESPONSE_CLOSE:
00156 gtk_widget_destroy(GTK_WIDGET(w));
00157 g_free(d);
00158 }
00159 }
00160
00161
00162
00163 static gboolean GetEntryFloat(GtkWidget* w, float& f)
00164 {
00165 GtkEntry* entry = GTK_ENTRY(w);
00166 bool tmp;
00167 if (entry == NULL)
00168 return false;
00169
00170 gchar* text = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
00171 f = 0.0;
00172 if (text == NULL)
00173 return false;
00174
00175 tmp = sscanf(text, " %f", &f) == 1;
00176 g_free(text);
00177 return tmp;
00178 }
00179
00180
00181
00182 static void GotoObject(gotoObjectData* gotoObjectDlg)
00183 {
00184 const gchar* objectName = gtk_entry_get_text(GTK_ENTRY(gotoObjectDlg->nameEntry));
00185
00186 if (objectName != NULL)
00187 {
00188 Simulation* simulation = gotoObjectDlg->app->simulation;
00189 Selection sel = simulation->findObjectFromPath(objectName);
00190
00191 if (!sel.empty())
00192 {
00193 simulation->setSelection(sel);
00194 simulation->follow();
00195
00196 float distance = (float) (sel.radius() * 5.0f);
00197 if (GetEntryFloat(gotoObjectDlg->distEntry, distance))
00198 {
00199
00200 if (gotoObjectDlg->units == 2)
00201 distance = astro::AUtoKilometers(distance);
00202 else if (gotoObjectDlg->units == 1)
00203 distance = distance * (float) sel.radius();
00204
00205 distance += (float) sel.radius();
00206 }
00207 distance = astro::kilometersToLightYears(distance);
00208
00209 float longitude, latitude;
00210 if (GetEntryFloat(gotoObjectDlg->latEntry, latitude) &&
00211 GetEntryFloat(gotoObjectDlg->longEntry, longitude))
00212 {
00213 simulation->gotoSelectionLongLat(5.0,
00214 distance,
00215 degToRad(longitude),
00216 degToRad(latitude),
00217 Vec3f(0, 1, 0));
00218 }
00219 else
00220 {
00221 simulation->gotoSelection(5.0,
00222 distance,
00223 Vec3f(0, 1, 0),
00224 astro::ObserverLocal);
00225 }
00226 }
00227 }
00228 }