dialog-star.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:10k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /*
  2.  *  Celestia GTK+ Front-End
  3.  *  Copyright (C) 2005 Pat Suwalski <pat@suwalski.net>
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  $Id: dialog-star.cpp,v 1.3 2006-09-05 04:57:51 suwalski Exp $
  11.  */
  12. #include <gtk/gtk.h>
  13. #include <celengine/body.h>
  14. #include <celengine/selection.h>
  15. #include <celengine/simulation.h>
  16. #include <celengine/star.h>
  17. #include <celengine/starbrowser.h>
  18. #include <celengine/stardb.h>
  19. #include <celengine/univcoord.h>
  20. #include <celmath/vecmath.h>
  21. #include <celutil/utf8.h>
  22. #include "dialog-star.h"
  23. #include "actions.h"
  24. #include "common.h"
  25. /* Declarations: Callbacks */
  26. static void listStarSelect(GtkTreeSelection* sel, AppData* app);
  27. static void radioClicked(GtkButton*, gpointer choice);
  28. static void refreshBrowser(GtkWidget*, sbData* sb);
  29. static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb);
  30. static void listStarSliderChange(GtkRange *range, sbData* sb);
  31. static void starDestroy(GtkWidget* w, gint, sbData* sb);
  32. /* Declarations: Helpers */
  33. static void addStars(sbData* sb);
  34. /* ENTRY: Navigation -> Star Browser... */
  35. void dialogStarBrowser(AppData* app)
  36. {
  37. sbData* sb = g_new0(sbData, 1);
  38. sb->app = app;
  39. sb->numListStars = 100;
  40. GtkWidget *browser = gtk_dialog_new_with_buttons("Star System Browser",
  41.                                                  GTK_WINDOW(app->mainWindow),
  42.                                                  GTK_DIALOG_DESTROY_WITH_PARENT,
  43.                                                  GTK_STOCK_OK, GTK_RESPONSE_OK,
  44.                                                  NULL);
  45. app->simulation->setSelection(Selection((Star *) NULL));
  46.  
  47. /* Star System Browser */
  48. GtkWidget *mainbox = gtk_vbox_new(FALSE, CELSPACING);
  49. gtk_container_set_border_width(GTK_CONTAINER(mainbox), CELSPACING);
  50. gtk_box_pack_start(GTK_BOX(GTK_DIALOG(browser)->vbox), mainbox, TRUE, TRUE, 0);
  51. GtkWidget *scrolled_win = gtk_scrolled_window_new (NULL, NULL);
  52. gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (scrolled_win),
  53.                                GTK_POLICY_AUTOMATIC,
  54.                                GTK_POLICY_ALWAYS);
  55. gtk_box_pack_start(GTK_BOX(mainbox), scrolled_win, TRUE, TRUE, 0);
  56. /* Create listbox list */
  57. sb->starListStore = gtk_list_store_new(6,
  58.                                        G_TYPE_STRING,
  59.                                        G_TYPE_STRING,
  60.                                        G_TYPE_STRING,
  61.                                        G_TYPE_STRING,
  62.                                        G_TYPE_STRING,
  63.                                        G_TYPE_POINTER);
  64. GtkWidget *starList = gtk_tree_view_new_with_model(GTK_TREE_MODEL(sb->starListStore));
  65. gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(starList), TRUE);
  66. gtk_container_add(GTK_CONTAINER(scrolled_win), starList);
  67. GtkCellRenderer *renderer;
  68. GtkTreeViewColumn *column;
  69. /* Add the columns */
  70. for (int i=0; i<5; i++) {
  71. renderer = gtk_cell_renderer_text_new();
  72. column = gtk_tree_view_column_new_with_attributes (sbTitles[i], renderer, "text", i, NULL);
  73. if (i > 0 && i < 4) {
  74. /* Right align */
  75. gtk_tree_view_column_set_alignment(column, 1.0);
  76. g_object_set(G_OBJECT(renderer), "xalign", 1.0, NULL);
  77. }
  78. gtk_tree_view_append_column(GTK_TREE_VIEW(starList), column);
  79. }
  80. /* Initialize the star browser */
  81. sb->browser.setSimulation(sb->app->simulation);
  82. /* Set up callback for when a star is selected */
  83. GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(starList));
  84. g_signal_connect(selection, "changed", G_CALLBACK(listStarSelect), app);
  85. /* From now on, it's the bottom-of-the-window controls */
  86. GtkWidget *frame = gtk_frame_new("Star Search Criteria");
  87. gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0);
  88. GtkWidget *hbox = gtk_hbox_new(FALSE, CELSPACING);
  89. gtk_container_set_border_width(GTK_CONTAINER(hbox), CELSPACING);
  90. gtk_container_add(GTK_CONTAINER(frame), hbox);
  91. /* List viewing preference settings */
  92. GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
  93. GtkWidget *hbox2 = gtk_hbox_new(FALSE, CELSPACING);
  94. GtkWidget *label = gtk_label_new("Maximum Stars Displayed in List");
  95. gtk_box_pack_start(GTK_BOX(hbox2), label, TRUE, FALSE, 0);
  96. sb->entry = gtk_entry_new_with_max_length(3);
  97. gtk_entry_set_width_chars(GTK_ENTRY(sb->entry), 5);
  98. gtk_box_pack_start(GTK_BOX(hbox2), sb->entry, TRUE, FALSE, 0);
  99. gtk_box_pack_start(GTK_BOX(vbox), hbox2, TRUE, FALSE, 0);
  100. sb->scale = gtk_hscale_new_with_range(MINLISTSTARS, MAXLISTSTARS, 1);
  101. gtk_scale_set_draw_value(GTK_SCALE(sb->scale), FALSE);
  102. gtk_range_set_update_policy(GTK_RANGE(sb->scale), GTK_UPDATE_DISCONTINUOUS);
  103. g_signal_connect(sb->scale, "value-changed", G_CALLBACK(listStarSliderChange), sb);
  104. g_signal_connect(sb->entry, "focus-out-event", G_CALLBACK(listStarEntryChange), sb);
  105. gtk_box_pack_start(GTK_BOX(vbox), sb->scale, TRUE, FALSE, 0);
  106. gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, FALSE, 0);
  107. /* Set initial Star Value */
  108. gtk_range_set_value(GTK_RANGE(sb->scale), sb->numListStars);
  109. if (sb->numListStars == MINLISTSTARS)
  110. {
  111. /* Force update manually (scale won't trigger event) */
  112. listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb);
  113. refreshBrowser(NULL, sb);
  114. }
  115. /* Radio Buttons */
  116. vbox = gtk_vbox_new(TRUE, 0);
  117. makeRadioItems(sbRadioLabels, vbox, GTK_SIGNAL_FUNC(radioClicked), NULL, sb);
  118. gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
  119. /* Common Buttons */
  120. hbox = gtk_hbox_new(TRUE, CELSPACING);
  121. if (buttonMake(hbox, "Center", (GtkSignalFunc)actionCenterSelection, app))
  122. return;
  123. if (buttonMake(hbox, "Go To", (GtkSignalFunc)actionGotoSelection, app))
  124. return;
  125. if (buttonMake(hbox, "Refresh", (GtkSignalFunc)refreshBrowser, sb))
  126. return;
  127. gtk_box_pack_start(GTK_BOX(mainbox), hbox, FALSE, FALSE, 0);
  128. g_signal_connect(browser, "response", G_CALLBACK(starDestroy), browser);
  129. gtk_widget_set_usize(browser, 500, 400); /* Absolute Size, urghhh */
  130. gtk_widget_show_all(browser);
  131. }
  132. /* CALLBACK: When Star is selected in Star Browser */
  133. static void listStarSelect(GtkTreeSelection* sel, AppData* app)
  134. {
  135. GValue value = { 0, 0 }; /* Initialize GValue to 0 */
  136. GtkTreeIter iter;
  137. GtkTreeModel* model;
  138. /* IF prevents selection while list is being updated */
  139. if (!gtk_tree_selection_get_selected(sel, &model, &iter))
  140. return;
  141. gtk_tree_model_get_value(model, &iter, 5, &value);
  142. Star *selStar = (Star *)g_value_get_pointer(&value);
  143. g_value_unset(&value);
  144. if (selStar)
  145. app->simulation->setSelection(Selection(selStar));
  146. }
  147. /* CALLBACK: Refresh button is pressed. */
  148. static void refreshBrowser(GtkWidget*, sbData* sb)
  149. {
  150. addStars(sb);
  151. }
  152. /* CALLBACK: One of the RadioButtons is pressed */
  153. static void radioClicked(GtkButton* r, gpointer choice)
  154. {
  155. sbData* sb = (sbData*)g_object_get_data(G_OBJECT(r), "data");
  156. gint selection = GPOINTER_TO_INT(choice);
  157. sb->browser.setPredicate(selection);
  158. refreshBrowser(NULL, sb);
  159. }
  160. /* CALLBACK: Maximum stars EntryBox changed. */
  161. static void listStarEntryChange(GtkEntry *entry, GdkEventFocus *event, sbData* sb)
  162. {
  163. /* If not called by the slider, but rather by user.
  164.    Prevents infinite recursion. */
  165. if (event != NULL)
  166. {
  167. sb->numListStars = atoi(gtk_entry_get_text(entry));
  168. /* Sanity Check */
  169. if (sb->numListStars < MINLISTSTARS)
  170. {
  171. sb->numListStars = MINLISTSTARS;
  172. /* Call self to set text (NULL event = no recursion) */
  173. listStarEntryChange(entry, NULL, sb);
  174. }
  175. if (sb->numListStars > MAXLISTSTARS)
  176. {
  177. sb->numListStars = MAXLISTSTARS;
  178. /* Call self to set text */
  179. listStarEntryChange(entry, NULL, sb);
  180. }
  181. gtk_range_set_value(GTK_RANGE(sb->scale), (gdouble)sb->numListStars);
  182. }
  183. /* Update value of this box */
  184. char stars[4];
  185. sprintf(stars, "%d", sb->numListStars);
  186. gtk_entry_set_text(entry, stars);
  187. }
  188. /* CALLBACK: Maximum stars RangeSlider changed. */
  189. static void listStarSliderChange(GtkRange *range, sbData* sb)
  190. {
  191. /* Update the value of the text entry box */
  192. sb->numListStars = (int)gtk_range_get_value(GTK_RANGE(range));
  193. listStarEntryChange(GTK_ENTRY(sb->entry), NULL, sb);
  194. /* Refresh the browser listbox */
  195. refreshBrowser(NULL, sb);
  196. }
  197. /* CALLBACK: Destroy Window */
  198. static void starDestroy(GtkWidget* w, gint, sbData*)
  199. {
  200. gtk_widget_destroy(GTK_WIDGET(w));
  201. /* Cannot do this, as the program crashes because of the StarBrowser:
  202.  * g_free(sb); */
  203. }
  204. /* HELPER: Clear and Add stars to the starListStore */
  205. static void addStars(sbData* sb)
  206. {
  207. const char *values[5];
  208. GtkTreeIter iter;
  209. StarDatabase* stardb;
  210. vector<const Star*> *stars;
  211. unsigned int currentLength;
  212. UniversalCoord ucPos;
  213. /* Load the catalogs and set data */
  214. stardb = sb->app->simulation->getUniverse()->getStarCatalog();
  215. sb->browser.refresh();
  216. stars = sb->browser.listStars(sb->numListStars);
  217. currentLength = (*stars).size();
  218. sb->app->simulation->setSelection(Selection((Star *)(*stars)[0]));
  219. ucPos = sb->app->simulation->getObserver().getPosition();
  220. gtk_list_store_clear(sb->starListStore);
  221. for (unsigned int i = 0; i < currentLength; i++)
  222. {
  223. char buf[20];
  224. const Star *star=(*stars)[i];
  225. values[0] = g_strdup(ReplaceGreekLetterAbbr((stardb->getStarName(*star))).c_str());
  226. Point3f pStar = star->getPosition();
  227. Vec3d v(pStar.x * 1e6 - (float)ucPos.x, 
  228.         pStar.y * 1e6 - (float)ucPos.y, 
  229.         pStar.z * 1e6 - (float)ucPos.z);
  230. float d = v.length() * 1e-6;
  231. sprintf(buf, " %.3f ", d);
  232. values[1] = g_strdup(buf);
  233. Vec3f r = star->getPosition() - ucPos;
  234. sprintf(buf, " %.2f ", astro::absToAppMag(star->getAbsoluteMagnitude(), d));
  235. values[2] = g_strdup(buf);
  236. sprintf(buf, " %.2f ", star->getAbsoluteMagnitude());
  237. values[3] = g_strdup(buf);
  238. gtk_list_store_append(sb->starListStore, &iter);
  239. gtk_list_store_set(sb->starListStore, &iter,
  240.                    0, values[0],
  241.                    1, values[1],
  242.                    2, values[2],
  243.                    3, values[3],
  244.                    4, star->getSpectralType(),
  245.                    5, (gpointer)star, -1);
  246. }
  247. delete stars;
  248. }