Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

dialog-star.cpp

Go to the documentation of this file.
00001 /*
00002  *  Celestia GTK+ Front-End
00003  *  Copyright (C) 2005 Pat Suwalski <pat@suwalski.net>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  $Id: dialog-star.cpp,v 1.2 2005/12/13 06:19:57 suwalski Exp $
00011  */
00012 
00013 #include <gtk/gtk.h>
00014 
00015 #include <celengine/body.h>
00016 #include <celengine/selection.h>
00017 #include <celengine/simulation.h>
00018 #include <celengine/star.h>
00019 #include <celengine/starbrowser.h>
00020 #include <celengine/stardb.h>
00021 #include <celengine/univcoord.h>
00022 #include <celmath/vecmath.h>
00023 #include <celutil/utf8.h>
00024 
00025 #include "dialog-star.h"
00026 #include "actions.h"
00027 #include "common.h"
00028 
00029 
00030 /* Declarations: Callbacks */
00031 static void listStarSelect(GtkTreeSelection* sel, AppData* app);
00032 static void radioClicked(GtkButton*, gpointer choice);
00033 static void refreshBrowser(GtkWidget*, sbData* sb);
00034 static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb);
00035 static void listStarSliderChange(GtkRange *range, sbData* sb);
00036 static void starDestroy(GtkWidget* w, gint, sbData* sb);
00037 
00038 /* Declarations: Helpers */
00039 static void addStars(sbData* sb);
00040 
00041 
00042 /* ENTRY: Navigation -> Star Browser... */
00043 void dialogStarBrowser(AppData* app)
00044 {
00045         sbData* sb = g_new0(sbData, 1);
00046         sb->app = app;
00047         sb->numListStars = 100;
00048         
00049         GtkWidget *browser = gtk_dialog_new_with_buttons("Star System Browser",
00050                                                          GTK_WINDOW(app->mainWindow),
00051                                                          GTK_DIALOG_DESTROY_WITH_PARENT,
00052                                                          GTK_STOCK_OK, GTK_RESPONSE_OK,
00053                                                          NULL);
00054         app->simulation->setSelection(Selection((Star *) NULL));
00055  
00056         /* Star System Browser */
00057         GtkWidget *mainbox = gtk_vbox_new(FALSE, CELSPACING);
00058         gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING);
00059         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(browser)->vbox), mainbox, TRUE, TRUE, 0);
00060 
00061         GtkWidget *scrolled_win = gtk_scrolled_window_new (NULL, NULL);
00062 
00063         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_win),
00064                                        GTK_POLICY_AUTOMATIC,
00065                                        GTK_POLICY_ALWAYS);
00066         gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0);
00067 
00068         /* Create listbox list */
00069         sb->starListStore = gtk_list_store_new(6,
00070                                                G_TYPE_STRING,
00071                                                G_TYPE_STRING,
00072                                                G_TYPE_STRING,
00073                                                G_TYPE_STRING,
00074                                                G_TYPE_STRING,
00075                                                G_TYPE_POINTER);
00076         GtkWidget *starList = gtk_tree_view_new_with_model(GTK_TREE_MODEL(sb->starListStore));
00077 
00078         gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(starList), TRUE);
00079         gtk_container_add(GTK_CONTAINER(scrolled_win), starList);
00080 
00081         GtkCellRenderer *renderer;
00082         GtkTreeViewColumn *column;
00083 
00084         /* Add the columns */
00085         for (int i=0; i<5; i++) {
00086                 renderer = gtk_cell_renderer_text_new();
00087                 column = gtk_tree_view_column_new_with_attributes (sbTitles[i], renderer, "text", i, NULL);
00088                 if (i > 0 && i < 4) {
00089                         /* Right align */
00090                         gtk_tree_view_column_set_alignment(column, 1.0);
00091                         g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
00092                 }
00093                 gtk_tree_view_append_column(GTK_TREE_VIEW(starList), column);
00094         }
00095 
00096         /* Initialize the star browser */
00097         sb->browser.setSimulation(sb->app->simulation);
00098 
00099         /* Set up callback for when a star is selected */
00100         GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(starList));
00101         g_signal_connect(selection, "changed", G_CALLBACK(listStarSelect), app);
00102 
00103         /* From now on, it's the bottom-of-the-window controls */
00104         GtkWidget *frame = gtk_frame_new("Star Search Criteria");
00105         gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0);
00106 
00107         GtkWidget *hbox = gtk_hbox_new(FALSE, CELSPACING);
00108         gtk_container_set_border_width(GTK_CONTAINER(hbox), CELSPACING);
00109         gtk_container_add(GTK_CONTAINER(frame), hbox);
00110 
00111         /* List viewing preference settings */
00112         GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
00113         GtkWidget *hbox2 = gtk_hbox_new(FALSE, CELSPACING);
00114         GtkWidget *label = gtk_label_new("Maximum Stars Displayed in List");
00115         gtk_box_pack_start(GTK_BOX(hbox2), label, TRUE, FALSE, 0);
00116         sb->entry = gtk_entry_new_with_max_length(3);
00117         gtk_entry_set_width_chars(GTK_ENTRY(sb->entry), 5);
00118         gtk_box_pack_start(GTK_BOX(hbox2), sb->entry, TRUE, FALSE, 0);
00119         gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, FALSE, 0);
00120         sb->scale = gtk_hscale_new_with_range(MINLISTSTARS, MAXLISTSTARS, 1);
00121         gtk_scale_set_draw_value(GTK_SCALE(sb->scale), FALSE);
00122         gtk_range_set_update_policy(GTK_RANGE(sb->scale), GTK_UPDATE_DISCONTINUOUS);
00123         g_signal_connect(sb->scale, "value-changed", G_CALLBACK(listStarSliderChange), sb);
00124         g_signal_connect(sb->entry, "focus-out-event", G_CALLBACK(listStarEntryChange), sb);
00125         gtk_box_pack_start(GTK_BOX(vbox), sb->scale, TRUE, FALSE, 0);
00126         gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, FALSE, 0);
00127 
00128         /* Set initial Star Value */
00129         gtk_range_set_value(GTK_RANGE(sb->scale), sb->numListStars);
00130         if (sb->numListStars == MINLISTSTARS)
00131         {
00132                 /* Force update manually (scale won't trigger event) */
00133                 listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb);
00134                 refreshBrowser(NULL, sb);
00135         }
00136 
00137         /* Radio Buttons */
00138         vbox = gtk_vbox_new(TRUE, 0);
00139         makeRadioItems(sbRadioLabels, vbox, GTK_SIGNAL_FUNC(radioClicked), NULL, sb);
00140         gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
00141 
00142         /* Common Buttons */
00143         hbox = gtk_hbox_new(TRUE, CELSPACING);
00144         if (buttonMake(hbox, "Center", (GtkSignalFunc)actionCenterSelection, app))
00145                 return;
00146         if (buttonMake(hbox, "Go To", (GtkSignalFunc)actionGotoSelection, app))
00147                 return;
00148         if (buttonMake(hbox, "Refresh", (GtkSignalFunc)refreshBrowser, sb))
00149                 return;
00150         gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0);
00151 
00152         g_signal_connect(browser, "response", G_CALLBACK(starDestroy), browser);
00153         
00154         gtk_widget_set_usize(browser, 500, 400); /* Absolute Size, urghhh */
00155         gtk_widget_show_all(browser);
00156 }
00157 
00158 
00159 /* CALLBACK: When Star is selected in Star Browser */
00160 static void listStarSelect(GtkTreeSelection* sel, AppData* app)
00161 {
00162         GValue value = { 0, 0 }; /* Initialize GValue to 0 */
00163         GtkTreeIter iter;
00164         GtkTreeModel* model;
00165 
00166         /* IF prevents selection while list is being updated */
00167         if (!gtk_tree_selection_get_selected(sel, &model, &iter))
00168                 return;
00169 
00170         gtk_tree_model_get_value(model, &iter, 5, &value);
00171         Star *selStar = (Star *)g_value_get_pointer(&value);
00172         g_value_unset(&value);
00173 
00174         if (selStar)
00175                 app->simulation->setSelection(Selection(selStar));
00176 }
00177 
00178 
00179 /* CALLBACK: Refresh button is pressed. */
00180 static void refreshBrowser(GtkWidget*, sbData* sb)
00181 {
00182         addStars(sb);
00183 }
00184 
00185 
00186 /* CALLBACK: One of the RadioButtons is pressed */
00187 static void radioClicked(GtkButton* r, gpointer choice)
00188 {
00189         sbData* sb = (sbData*)g_object_get_data(G_OBJECT(r), "data");
00190         gint selection = GPOINTER_TO_INT(choice);
00191         
00192         sb->browser.setPredicate(selection);
00193         refreshBrowser(NULL, sb);
00194 }
00195 
00196 
00197 /* CALLBACK: Maximum stars EntryBox changed. */
00198 static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb)
00199 {
00200         /* If not called by the slider, but rather by user.
00201            Prevents infinite recursion. */
00202         if (event != NULL)
00203         {
00204                 sb->numListStars = atoi(gtk_entry_get_text(entry));
00205                 
00206                 /* Sanity Check */
00207                 if (sb->numListStars < MINLISTSTARS)
00208                 {
00209                         sb->numListStars = MINLISTSTARS;
00210                         /* Call self to set text (NULL event = no recursion) */
00211                         listStarEntryChange(entry, NULL, sb);
00212                 }
00213                 if (sb->numListStars > MAXLISTSTARS)
00214                 {
00215                         sb->numListStars = MAXLISTSTARS;
00216                         /* Call self to set text */
00217                         listStarEntryChange(entry, NULL, sb);
00218                 }
00219 
00220                 gtk_range_set_value(GTK_RANGE(sb->scale), (gdouble)sb->numListStars);
00221         }
00222 
00223         /* Update value of this box */
00224         char stars[4];
00225         sprintf(stars, "%d", sb->numListStars);
00226         gtk_entry_set_text(entry, stars);
00227 }
00228 
00229 
00230 /* CALLBACK: Maximum stars RangeSlider changed. */
00231 static void listStarSliderChange(GtkRange *range, sbData* sb)
00232 {
00233         /* Update the value of the text entry box */
00234         sb->numListStars = (int)gtk_range_get_value(GTK_RANGE(range));
00235         listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb);
00236 
00237         /* Refresh the browser listbox */
00238         refreshBrowser(NULL, sb);
00239 }
00240 
00241 
00242 /* CALLBACK: Destroy Window */
00243 static void starDestroy(GtkWidget* w, gint, sbData*)
00244 {
00245         gtk_widget_destroy(GTK_WIDGET(w));
00246 
00247         /* Cannot do this, as the program crashes because of the StarBrowser:
00248          * g_free(sb); */
00249 }
00250 
00251 
00252 /* HELPER: Clear and Add stars to the starListStore */
00253 static void addStars(sbData* sb)
00254 {
00255         const char *values[5];
00256         GtkTreeIter iter;
00257         
00258         StarDatabase* stardb;
00259         vector<const Star*> *stars;
00260         unsigned int currentLength;
00261         UniversalCoord ucPos;
00262         
00263         /* Load the catalogs and set data */
00264         stardb = sb->app->simulation->getUniverse()->getStarCatalog();
00265         sb->browser.refresh();
00266         stars = sb->browser.listStars(sb->numListStars);
00267         currentLength = (*stars).size();
00268         sb->app->simulation->setSelection(Selection((Star *)(*stars)[0]));
00269         ucPos = sb->app->simulation->getObserver().getPosition();
00270 
00271         gtk_list_store_clear(sb->starListStore);
00272 
00273         for (unsigned int i = 0; i < currentLength; i++)
00274         {
00275                 char buf[20];
00276                 const Star *star=(*stars)[i];
00277                 values[0] = g_strdup(ReplaceGreekLetterAbbr((stardb->getStarName(*star))).c_str());
00278 
00279                 Point3f pStar = star->getPosition();
00280                 Vec3d v(pStar.x * 1e6 - (float)ucPos.x, 
00281                         pStar.y * 1e6 - (float)ucPos.y, 
00282                         pStar.z * 1e6 - (float)ucPos.z);
00283                 double d = v.length() * 1e-6;
00284 
00285                 sprintf(buf, " %.3f ", d);
00286                 values[1] = g_strdup(buf);
00287 
00288                 Vec3f r = star->getPosition() - ucPos;
00289                 sprintf(buf, " %.2f ", astro::absToAppMag(star->getAbsoluteMagnitude(), d));
00290                 values[2] = g_strdup(buf);
00291 
00292                 sprintf(buf, " %.2f ", star->getAbsoluteMagnitude());
00293                 values[3] = g_strdup(buf);
00294 
00295                 gtk_list_store_append(sb->starListStore, &iter);
00296                 gtk_list_store_set(sb->starListStore, &iter,
00297                                    0, values[0],
00298                                    1, values[1],
00299                                    2, values[2],
00300                                    3, values[3],
00301                                    4, star->getSpectralType(),
00302                                    5, (gpointer)star, -1);
00303         }
00304 
00305         delete stars;
00306 }

Generated on Sat Jan 14 22:30:30 2006 for Celestia by  doxygen 1.4.1