[Gpredict-svn] SF.net SVN: gpredict: [54] trunk/src
Real time satellite tracking and orbit prediction
Status: Beta
Brought to you by:
csete
From: <cs...@us...> - 2008-05-02 23:35:16
|
Revision: 54 http://gpredict.svn.sourceforge.net/gpredict/?rev=54&view=rev Author: csete Date: 2008-05-02 16:35:22 -0700 (Fri, 02 May 2008) Log Message: ----------- Done some work on the rotator control widget and its integration into GtkSatModule. Modified Paths: -------------- trunk/src/gtk-rot-ctrl.c trunk/src/gtk-rot-ctrl.h trunk/src/gtk-sat-module-popup.c trunk/src/gtk-sat-module.c trunk/src/gtk-sat-module.h Modified: trunk/src/gtk-rot-ctrl.c =================================================================== --- trunk/src/gtk-rot-ctrl.c 2008-05-02 07:09:58 UTC (rev 53) +++ trunk/src/gtk-rot-ctrl.c 2008-05-02 23:35:22 UTC (rev 54) @@ -37,26 +37,44 @@ #include <gtk/gtk.h> #include <glib/gi18n.h> #include <math.h> +#include "sat-log.h" #include "gtk-rot-ctrl.h" #ifdef HAVE_CONFIG_H # include <build-config.h> #endif +#define FMTSTR "%7.2f\302\260" + static void gtk_rot_ctrl_class_init (GtkRotCtrlClass *class); static void gtk_rot_ctrl_init (GtkRotCtrl *list); static void gtk_rot_ctrl_destroy (GtkObject *object); -static GtkWidget *create_status_widgets (void); -static GtkWidget *create_setup_widgets (void); -static GtkWidget *create_control_widgets (void); +static GtkWidget *create_az_widgets (GtkRotCtrl *ctrl); +static GtkWidget *create_el_widgets (GtkRotCtrl *ctrl); +static GtkWidget *create_target_widgets (GtkRotCtrl *ctrl); +static GtkWidget *create_conf_widgets (GtkRotCtrl *ctrl); +static GtkWidget *create_plot_widget (GtkRotCtrl *ctrl); +static void store_sats (gpointer key, gpointer value, gpointer user_data); +static void sat_selected_cb (GtkComboBox *satsel, gpointer data); +static void track_toggle_cb (GtkToggleButton *button, gpointer data); +static void delay_changed_cb (GtkSpinButton *spin, gpointer data); +static void toler_changed_cb (GtkSpinButton *spin, gpointer data); +static gboolean rot_ctrl_timeout_cb (gpointer data); + + static GtkVBoxClass *parent_class = NULL; +static GdkColor ColBlack = { 0, 0, 0, 0}; +static GdkColor ColWhite = { 0, 0xFFFF, 0xFFFF, 0xFFFF}; +static GdkColor ColRed = { 0, 0xFFFF, 0, 0}; +static GdkColor ColGreen = {0, 0, 0xFFFF, 0}; + GType gtk_rot_ctrl_get_type () { @@ -110,13 +128,27 @@ static void gtk_rot_ctrl_init (GtkRotCtrl *ctrl) { - + ctrl->sats = NULL; + ctrl->target = NULL; + ctrl->tracking = FALSE; + ctrl->busy = FALSE; + ctrl->delay = 1000; + ctrl->timerid = 0; + ctrl->tolerance = 1.0; } static void gtk_rot_ctrl_destroy (GtkObject *object) { + GtkRotCtrl *ctrl = GTK_ROT_CTRL (object); + + + /* stop timer */ + if (ctrl->timerid > 0) + g_source_remove (ctrl->timerid); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } @@ -127,89 +159,364 @@ * */ GtkWidget * -gtk_rot_ctrl_new () +gtk_rot_ctrl_new (GtkSatModule *module) { GtkWidget *widget; GtkWidget *table; - guint i; widget = g_object_new (GTK_TYPE_ROT_CTRL, NULL); + + /* store satellites */ + g_hash_table_foreach (module->satellites, store_sats, widget); + + GTK_ROT_CTRL (widget)->target = SAT (g_slist_nth_data (GTK_ROT_CTRL (widget)->sats, 0)); + + /* initialise custom colors */ + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &ColBlack); + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &ColWhite); + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &ColRed); + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &ColGreen); /* create contents */ - table = gtk_table_new (2, 2, FALSE); - gtk_table_attach (GTK_TABLE (table), create_status_widgets (), - 0, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); - gtk_table_attach (GTK_TABLE (table), create_setup_widgets (), - 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); - gtk_table_attach (GTK_TABLE (table), create_control_widgets (), - 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 5, 5); + table = gtk_table_new (3, 2, TRUE); + gtk_table_set_row_spacings (GTK_TABLE (table), 5); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + gtk_container_set_border_width (GTK_CONTAINER (table), 10); + gtk_table_attach (GTK_TABLE (table), create_az_widgets (GTK_ROT_CTRL (widget)), + 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), create_el_widgets (GTK_ROT_CTRL (widget)), + 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), create_target_widgets (GTK_ROT_CTRL (widget)), + 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), create_conf_widgets (GTK_ROT_CTRL (widget)), + 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), create_plot_widget (GTK_ROT_CTRL (widget)), + 1, 2, 1, 3, GTK_FILL, GTK_FILL, 0, 0); gtk_container_add (GTK_CONTAINER (widget), table); + GTK_ROT_CTRL (widget)->timerid = g_timeout_add (GTK_ROT_CTRL (widget)->delay, + rot_ctrl_timeout_cb, + GTK_ROT_CTRL (widget)); + return widget; } -/** \brief Create status widgets. */ -static GtkWidget *create_status_widgets () +/** \brief Update rotator control state. + * \param ctrl Pointer to the GtkRotCtrl. + * + * This function is called by the parent, i.e. GtkSatModule, indicating that + * the satellite data has been updated. The function updates the internal state + * of the controller and the rotator. + */ +void +gtk_rot_ctrl_update (GtkRotCtrl *ctrl, gdouble t) { - GtkWidget *frame,*table,*label,*ctrbut; + gchar *buff; - table = gtk_table_new (3,7, TRUE); + if (ctrl->target) { + /* update target displays */ + buff = g_strdup_printf (FMTSTR, ctrl->target->az); + gtk_label_set_text (GTK_LABEL (ctrl->AzSat), buff); + g_free (buff); + buff = g_strdup_printf (FMTSTR, ctrl->target->el); + gtk_label_set_text (GTK_LABEL (ctrl->ElSat), buff); + g_free (buff); + } +} + + +/** \brief Create azimuth control widgets. + * \param ctrl Pointer to the GtkRotCtrl widget. + * + * This function creates and initialises the widgets for controlling the + * azimuth of the the rotator. + */ +static +GtkWidget *create_az_widgets (GtkRotCtrl *ctrl) +{ + GtkWidget *frame; - /* table header */ - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>SAT</b>"); - gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1); + frame = gtk_frame_new (_("Azimuth")); - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>\316\224</b>"); - gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 0, 1); + return frame; +} + + +/** \brief Create elevation control widgets. + * \param ctrl Pointer to the GtkRotCtrl widget. + * + * This function creates and initialises the widgets for controlling the + * elevation of the the rotator. + */ +static +GtkWidget *create_el_widgets (GtkRotCtrl *ctrl) +{ + GtkWidget *frame; - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>SET</b>"); - gtk_table_attach_defaults (GTK_TABLE (table), label, 4, 5, 0, 1); + frame = gtk_frame_new (_("Elevation")); - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>READ</b>"); - gtk_table_attach_defaults (GTK_TABLE (table), label, 5, 6, 0, 1); + return frame; +} + +/** \brief Create target widgets. + * \param ctrl Pointer to the GtkRotCtrl widget. + */ +static +GtkWidget *create_target_widgets (GtkRotCtrl *ctrl) +{ + GtkWidget *frame,*table,*label,*satsel,*track; + gchar *buff; + guint i, n; + sat_t *sat = NULL; - /* Azimuth widgets */ - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>AZ:</b>"); + + buff = g_strdup_printf (FMTSTR, 0.0); + + table = gtk_table_new (4, 3, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + + /* sat selector */ + satsel = gtk_combo_box_new_text (); + n = g_slist_length (ctrl->sats); + for (i = 0; i < n; i++) { + sat = SAT (g_slist_nth_data (ctrl->sats, i)); + if (sat) { + gtk_combo_box_append_text (GTK_COMBO_BOX (satsel), sat->tle.sat_name); + } + } + gtk_combo_box_set_active (GTK_COMBO_BOX (satsel), 0); + gtk_widget_set_tooltip_text (satsel, _("Select target object")); + g_signal_connect (satsel, "changed", G_CALLBACK (sat_selected_cb), ctrl); + gtk_table_attach (GTK_TABLE (table), satsel, 0, 2, 0, 1, + GTK_FILL, GTK_FILL, 5, 5); + + /* tracking button */ + track = gtk_toggle_button_new_with_label (_("Track")); + gtk_widget_set_tooltip_text (track, _("Track the satellite when it is within range")); + gtk_table_attach (GTK_TABLE (table), track, 2, 3, 0, 1, + GTK_SHRINK, GTK_SHRINK, 5, 0); + g_signal_connect (track, "toggled", G_CALLBACK (track_toggle_cb), ctrl); + + /* Azimuth */ + label = gtk_label_new (_("Az:")); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2); - /* Eevation widgets */ - label = gtk_label_new (NULL); - gtk_label_set_markup (GTK_LABEL (label), "<b>EL:</b>"); + ctrl->AzSat = gtk_label_new (buff); + gtk_misc_set_alignment (GTK_MISC (ctrl->AzSat), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), ctrl->AzSat, 1, 2, 1, 2); + + + /* Elevation */ + label = gtk_label_new (_("El:")); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3); - frame = gtk_frame_new (_("STATUS")); + ctrl->ElSat = gtk_label_new (buff); + gtk_misc_set_alignment (GTK_MISC (ctrl->ElSat), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), ctrl->ElSat, 1, 2, 2, 3); + + /* count down */ + label = gtk_label_new (_("Time:")); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4); + + frame = gtk_frame_new (_("Target")); + //gtk_container_set_border_width (GTK_CONTAINER (frame), 5); gtk_container_add (GTK_CONTAINER (frame), table); - gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); + g_free (buff); + return frame; } -/** \brief Create setup widgets. */ -static GtkWidget *create_setup_widgets () +static GtkWidget * +create_conf_widgets (GtkRotCtrl *ctrl) { - GtkWidget *frame; + GtkWidget *frame,*table,*label,*timer,*toler; - frame = gtk_frame_new (_("SETUP")); - gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); + table = gtk_table_new (2, 3, TRUE); + gtk_table_set_col_spacings (GTK_TABLE (table), 5); + /* Timeout */ + label = gtk_label_new (_("Cycle:")); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1); + + timer = gtk_spin_button_new_with_range (100, 5000, 10); + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (timer), 0); + gtk_widget_set_tooltip_text (timer, + _("This parameter controls the delay between "\ + "commands sent to the rotator.")); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (timer), ctrl->delay); + g_signal_connect (timer, "value-changed", G_CALLBACK (delay_changed_cb), ctrl); + gtk_table_attach (GTK_TABLE (table), timer, 1, 2, 0, 1, + GTK_FILL, GTK_FILL, 0, 0); + + label = gtk_label_new (_("msec")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 0, 1); + + /* Tolerance */ + label = gtk_label_new (_("Tolerance:")); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2); + + toler = gtk_spin_button_new_with_range (0.0, 10.0, 0.1); + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (toler), 1); + gtk_widget_set_tooltip_text (toler, + _("This parameter controls the tolerance between "\ + "the target and rotator values for the rotator.\n"\ + "If the difference between the target and rotator values "\ + "is smaller than the tolerance, no new commands are sent")); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (toler), ctrl->tolerance); + g_signal_connect (toler, "value-changed", G_CALLBACK (toler_changed_cb), ctrl); + gtk_table_attach (GTK_TABLE (table), toler, 1, 2, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + + + label = gtk_label_new (_("deg")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 1, 2); + + + frame = gtk_frame_new (_("Settings")); + gtk_container_add (GTK_CONTAINER (frame), table); + return frame; } -/** \brief Create control buttons. */ -static GtkWidget *create_control_widgets () + +/** \brief Create target widgets. + * \param ctrl Pointer to the GtkRotCtrl widget. + */ +static +GtkWidget *create_plot_widget (GtkRotCtrl *ctrl) { GtkWidget *frame; - frame = gtk_frame_new (_("CONTROL")); - gtk_frame_set_label_align (GTK_FRAME (frame), 0.5, 0.5); + frame = gtk_frame_new (NULL); return frame; } + + +/** \brief Copy satellite from hash table to singly linked list. + */ +static void +store_sats (gpointer key, gpointer value, gpointer user_data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL( user_data); + sat_t *sat = SAT (value); + + ctrl->sats = g_slist_append (ctrl->sats, sat); +} + + +/** \brief Manage satellite selections + * \param satsel Pointer to the GtkComboBox. + * \param data Pointer to the GtkRotCtrl widget. + * + * This function is called when the user selects a new satellite. + */ +static void +sat_selected_cb (GtkComboBox *satsel, gpointer data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); + gint i; + + i = gtk_combo_box_get_active (satsel); + if (i >= 0) { + ctrl->target = SAT (g_slist_nth_data (ctrl->sats, i)); + } + else { + sat_log_log (SAT_LOG_LEVEL_ERROR, + _("%s:%s: Invalid satellite selection: %d"), + __FILE__, __FUNCTION__, i); + } +} + + +/** \brief Manage toggle signals (tracking) + * \param button Pointer to the GtkToggle button. + * \param data Pointer to the GtkRotCtrl widget. + */ +static void +track_toggle_cb (GtkToggleButton *button, gpointer data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); + + ctrl->tracking = gtk_toggle_button_get_active (button); +} + + +/** \brief Manage cycle delay changes. + * \param spin Pointer to the spin button. + * \param data Pointer to the GtkRotCtrl widget. + * + * This function is called when the user changes the value of the + * cycle delay. + */ +static void +delay_changed_cb (GtkSpinButton *spin, gpointer data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); + + + ctrl->delay = (guint) gtk_spin_button_get_value (spin); + + if (ctrl->timerid > 0) + g_source_remove (ctrl->timerid); + + ctrl->timerid = g_timeout_add (ctrl->delay, rot_ctrl_timeout_cb, ctrl); +} + + + +/** \brief Manage tolerance changes. + * \param spin Pointer to the spin button. + * \param data Pointer to the GtkRotCtrl widget. + * + * This function is called when the user changes the value of the + * tolerance. + */ +static void +toler_changed_cb (GtkSpinButton *spin, gpointer data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); + + ctrl->tolerance = gtk_spin_button_get_value (spin); +} + + + + +/** \brief Rotator controller timeout function + * \param data Pointer to the GtkRotCtrl widget. + * \return Always TRUE to let the timer continue. + */ +static gboolean +rot_ctrl_timeout_cb (gpointer data) +{ + GtkRotCtrl *ctrl = GTK_ROT_CTRL (data); + + if (ctrl->busy) { + sat_log_log (SAT_LOG_LEVEL_ERROR,_("%s missed the deadline"),__FUNCTION__); + return TRUE; + } + + ctrl->busy = TRUE; + + /* do something */ + + ctrl->busy = FALSE; + + return TRUE; +} + + + + Modified: trunk/src/gtk-rot-ctrl.h =================================================================== --- trunk/src/gtk-rot-ctrl.h 2008-05-02 07:09:58 UTC (rev 53) +++ trunk/src/gtk-rot-ctrl.h 2008-05-02 23:35:22 UTC (rev 54) @@ -31,8 +31,9 @@ #include <glib.h> #include <glib/gi18n.h> #include <gtk/gtk.h> +#include "sgpsdp/sgp4sdp4.h" +#include "gtk-sat-module.h" - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -66,7 +67,19 @@ /* Elevation labels */ GtkWidget *ElSat,*ElDelta,*ElLock,*ElSet,*ElRead; + + /* other widgets */ + + /* satellites */ + GSList *sats; + sat_t *target; + guint delay; /*!< Timeout delay. */ + guint timerid; /*!< Timer ID */ + gdouble tolerance; /*!< Error tolerance */ + + gboolean tracking; + gboolean busy; }; struct _GtkRotCtrlClass @@ -77,7 +90,8 @@ GtkType gtk_rot_ctrl_get_type (void); -GtkWidget* gtk_rot_ctrl_new (void); +GtkWidget* gtk_rot_ctrl_new (GtkSatModule *module); +void gtk_rot_ctrl_update (GtkRotCtrl *ctrl, gdouble t); #ifdef __cplusplus Modified: trunk/src/gtk-sat-module-popup.c =================================================================== --- trunk/src/gtk-sat-module-popup.c 2008-05-02 07:09:58 UTC (rev 53) +++ trunk/src/gtk-sat-module-popup.c 2008-05-02 23:35:22 UTC (rev 54) @@ -59,6 +59,8 @@ static void delete_cb (GtkWidget *menuitem, gpointer data); static void close_cb (GtkWidget *menuitem, gpointer data); static void name_changed (GtkWidget *widget, gpointer data); +static void destroy_rotctrl (GtkWidget *window, gpointer data); +static void destroy_rigctrl (GtkWidget *window, gpointer data); static gint window_delete (GtkWidget *widget, GdkEvent *event, gpointer data); @@ -243,7 +245,24 @@ static void config_cb (GtkWidget *menuitem, gpointer data) { - gtk_sat_module_config_cb (menuitem, data); + GtkSatModule *module = GTK_SAT_MODULE (data); + + if (module->rigctrlwin || module->rotctrlwin) { + GtkWidget *dialog; + /* FIXME: should offer option to close controllers */ + dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("A module can not be configured while the "\ + "radio or rotator controller is active.\n\n"\ + "Please close the radio and rotator controllers "\ + "and try again.")); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + } + else { + gtk_sat_module_config_cb (menuitem, data); + } } @@ -848,30 +867,54 @@ rigctrl_cb (GtkWidget *menuitem, gpointer data) { GtkSatModule *module = GTK_SAT_MODULE (data); - GtkWidget *window; GtkWidget *rigctrl; gchar *buff; + if (module->rigctrlwin != NULL) { + /* there is already a roto controller for this module */ + gtk_window_present (GTK_WINDOW (module->rigctrlwin)); + return; + } - //rigctrl = gtk_rig_ctrl_new (); + //rigctrl = gtk_rot_ctrl_new (); /* create a window */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - buff = g_strdup_printf (_("Gpredict Radio Control (%s)"), module->name); - gtk_window_set_title (GTK_WINDOW (window), buff); + module->rigctrlwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + buff = g_strdup_printf (_("Gpredict Radio Control: %s"), module->name); + gtk_window_set_title (GTK_WINDOW (module->rigctrlwin), buff); g_free (buff); - g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (window_delete), NULL); + g_signal_connect (G_OBJECT (module->rigctrlwin), "delete_event", + G_CALLBACK (window_delete), NULL); + g_signal_connect (G_OBJECT (module->rigctrlwin), "destroy", + G_CALLBACK (destroy_rigctrl), module); /* window icon */ buff = icon_file_name ("gpredict-oscilloscope.png"); - gtk_window_set_icon_from_file (GTK_WINDOW (window), buff, NULL); + gtk_window_set_icon_from_file (GTK_WINDOW (module->rigctrlwin), buff, NULL); g_free (buff); - //gtk_container_add (GTK_CONTAINER (window), rigctrl); + //gtk_container_add (GTK_CONTAINER (module->rigctrlwin), rigctrl); - gtk_widget_show_all (window); + gtk_widget_show_all (module->rigctrlwin); + } + +/** \brief Destroy radio control window. + * \param window Pointer to the radio control window. + * \param data Pointer to the GtkSatModule to which this controller is attached. + * + * This function is called automatically when the window is destroyed. + */ +static void +destroy_rigctrl (GtkWidget *window, gpointer data) +{ + GtkSatModule *module = GTK_SAT_MODULE (data); + + module->rigctrlwin = NULL; +} + + /** \brief Open antenna rotator control window. * \param menuitem The menuitem that was selected. * \param data Pointer the GtkSatModule. @@ -880,34 +923,65 @@ rotctrl_cb (GtkWidget *menuitem, gpointer data) { GtkSatModule *module = GTK_SAT_MODULE (data); - GtkWidget *window; GtkWidget *rotctrl; gchar *buff; + if (module->rotctrlwin != NULL) { + /* there is already a roto controller for this module */ + gtk_window_present (GTK_WINDOW (module->rotctrlwin)); + return; + } - rotctrl = gtk_rot_ctrl_new (); + rotctrl = gtk_rot_ctrl_new (module); + module->rotctrl = rotctrl; /* create a window */ - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - buff = g_strdup_printf (_("Gpredict Rotator Control (%s)"), module->name); - gtk_window_set_title (GTK_WINDOW (window), buff); + module->rotctrlwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + buff = g_strdup_printf (_("Gpredict Rotator Control: %s"), module->name); + gtk_window_set_title (GTK_WINDOW (module->rotctrlwin), buff); g_free (buff); - g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (window_delete), NULL); + g_signal_connect (G_OBJECT (module->rotctrlwin), "delete_event", + G_CALLBACK (window_delete), module); + g_signal_connect (G_OBJECT (module->rotctrlwin), "destroy", + G_CALLBACK (destroy_rotctrl), module); /* window icon */ buff = icon_file_name ("gpredict-antenna.png"); - gtk_window_set_icon_from_file (GTK_WINDOW (window), buff, NULL); + gtk_window_set_icon_from_file (GTK_WINDOW (module->rotctrlwin), buff, NULL); g_free (buff); - gtk_container_add (GTK_CONTAINER (window), rotctrl); + gtk_container_add (GTK_CONTAINER (module->rotctrlwin), rotctrl); - /* store pointer to window */ + gtk_widget_show_all (module->rotctrlwin); +} + + +/** \brief Destroy rotator control window. + * \param window Pointer to the rotator control window. + * \param data Pointer to the GtkSatModule to which this controller is attached. + * + * This function is called automatically when the window is destroyed. + */ +static void +destroy_rotctrl (GtkWidget *window, gpointer data) +{ + GtkSatModule *module = GTK_SAT_MODULE (data); - gtk_widget_show_all (window); + module->rotctrlwin = NULL; + module->rotctrl = NULL; } +/* ensure that deleted top-level windows are destroyed */ +static gint +window_delete (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + return FALSE; +} + /** \brief Close module. * * This function is called when the user selects the close menu @@ -1040,17 +1114,7 @@ -/* ensure that deleted top-level windows are destroyed */ -static gint -window_delete (GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - return FALSE; -} - - /** \brief Snoop window position and size when main window receives configure event. * \param widget Pointer to the module window. * \param event Pointer to the event structure. Modified: trunk/src/gtk-sat-module.c =================================================================== --- trunk/src/gtk-sat-module.c 2008-05-02 07:09:58 UTC (rev 53) +++ trunk/src/gtk-sat-module.c 2008-05-02 23:35:22 UTC (rev 54) @@ -64,6 +64,7 @@ #include "gtk-polar-view.h" #include "gtk-single-sat.h" #include "gtk-met.h" +#include "gtk-rot-ctrl.h" //#ifdef G_OS_WIN32 //# include "libc_internal.h" @@ -96,7 +97,6 @@ static void reload_sats_in_child (GtkWidget *widget, GtkSatModule *module); -static void destroy_gtk_widget (gpointer data); static GtkVBoxClass *parent_class = NULL; @@ -168,17 +168,10 @@ g_free, g_free); - module->rotctrl = g_hash_table_new_full (g_int_hash, - g_int_equal, - g_free, - destroy_gtk_widget); - - module->rigctrl = g_hash_table_new_full (g_int_hash, - g_int_equal, - g_free, - destroy_gtk_widget); + module->rotctrlwin = NULL; + module->rotctrl = NULL; + module->rigctrlwin = NULL; - module->state = GTK_SAT_MOD_STATE_DOCKED; module->busy = FALSE; @@ -190,6 +183,8 @@ module->vpanedpos = -1; module->hpanedpos = -1; + module->timerid = 0; + module->throttle = 1; module->rtNow = 0.0; module->rtPrev = 0.0; @@ -208,7 +203,7 @@ /* stop timeout */ - if (module->timerid != -1) + if (module->timerid > 0) g_source_remove (module->timerid); /* destroy time controller */ @@ -216,19 +211,15 @@ gtk_widget_destroy (module->tmgWin); module->tmgActive = FALSE; } - - /* destroy radio controllers */ - if (module->rigctrl) { - g_hash_table_destroy (module->rigctrl); - module->rigctrl = NULL; - } - /* destroy rotator controllers */ - if (module->rotctrl) { - g_hash_table_destroy (module->rotctrl); - module->rotctrl = NULL; + /* destroy radio and rotator controllers */ + if (module->rigctrlwin) { + gtk_widget_destroy (module->rigctrlwin); } - + if (module->rotctrlwin) { + gtk_widget_destroy (module->rotctrlwin); + } + /* clean up QTH */ if (module->qth) { gtk_sat_data_free_qth (module->qth); @@ -877,6 +868,10 @@ if (mod->child_3 != NULL) update_child (mod->child_3, mod->tmgCdnum); + /* send notice to radio and rotator controller */ + if (mod->rotctrl) + gtk_rot_ctrl_update (GTK_ROT_CTRL (mod->rotctrl), mod->tmgCdnum); + mod->event_count++; @@ -1545,7 +1540,8 @@ if (GTK_SAT_MODULE (module)->child_3 != NULL) reload_sats_in_child (GTK_SAT_MODULE (module)->child_3, GTK_SAT_MODULE (module)); - + /* FIXME: radio and rotator controller */ + /* unlock module */ module->busy = FALSE; @@ -1597,15 +1593,3 @@ { } - -/** \brief Destroy a Gtk+ widget. - * \param data Pointer to the widget to destroy. - * - * This function is a simple wrapper for gtk_widget_destroy. The difference is - * in the parameter types; this wrapper can be used as a GDestroyNotify callback. - */ -static void -destroy_gtk_widget (gpointer data) -{ - gtk_widget_destroy (GTK_WIDGET (data)); -} Modified: trunk/src/gtk-sat-module.h =================================================================== --- trunk/src/gtk-sat-module.h 2008-05-02 07:09:58 UTC (rev 53) +++ trunk/src/gtk-sat-module.h 2008-05-02 23:35:22 UTC (rev 54) @@ -93,6 +93,10 @@ GtkWidget *win; /*!< Window when module is not docked */ + GtkWidget *rotctrlwin; /*!< Rotator controller window */ + GtkWidget *rotctrl; + GtkWidget *rigctrlwin; /*!< Radio controller window */ + GtkWidget *header; guint head_count; guint head_timeout; @@ -116,8 +120,6 @@ qth_t *qth; /*!< QTH information. */ GHashTable *satellites; /*!< Satellites. */ - GHashTable *rotctrl; /*!< Rotator controllers. */ - GHashTable *rigctrl; /*!< Radio controllers. */ guint32 timeout; /*!< Timeout value [msec] */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |