mirror of
https://github.com/csete/gpredict
synced 2026-08-13 17:39:46 -04:00
git-svn-id: https://gpredict.svn.sourceforge.net/svnroot/gpredict/trunk@1 ab6734ba-2843-0410-b83b-99c217ef6c0f
797 lines
22 KiB
C
797 lines
22 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
|
/*
|
|
Gpredict: Real-time satellite tracking and orbit prediction program
|
|
|
|
Copyright (C) 2001-2007 Alexandru Csete, OZ9AEC.
|
|
|
|
Authors: Alexandru Csete <oz9aec@gmail.com>
|
|
|
|
Comments, questions and bugreports should be submitted via
|
|
http://sourceforge.net/projects/groundstation/
|
|
More details can be found at the project home page:
|
|
|
|
http://groundstation.sourceforge.net/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, visit http://www.fsf.org/
|
|
*/
|
|
/** \brief Azel Plot Widget.
|
|
*
|
|
* More info...
|
|
*/
|
|
#include <gtk/gtk.h>
|
|
#include <glib/gi18n.h>
|
|
#include "sgpsdp/sgp4sdp4.h"
|
|
#include "sat-log.h"
|
|
#include "config-keys.h"
|
|
#include "sat-cfg.h"
|
|
#include "time-tools.h"
|
|
#include "sat-popup-menu.h"
|
|
#include "gtk-sat-data.h"
|
|
#include "gpredict-utils.h"
|
|
#include "gtk-azel-plot.h"
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <build-config.h>
|
|
#endif
|
|
#include <goocanvas.h>
|
|
|
|
|
|
|
|
#define POLV_DEFAULT_SIZE 300
|
|
#define POLV_X_MARGIN 40
|
|
#define POLV_Y_MARGIN 40
|
|
|
|
|
|
/* extra size for line outside 0 deg circle (inside margin) */
|
|
#define POLV_LINE_EXTRA 5
|
|
|
|
#define MARKER_SIZE 5
|
|
|
|
|
|
static void gtk_azel_plot_class_init (GtkAzelPlotClass *class);
|
|
static void gtk_azel_plot_init (GtkAzelPlot *polview);
|
|
static void gtk_azel_plot_destroy (GtkObject *object);
|
|
static void size_allocate_cb (GtkWidget *widget,
|
|
GtkAllocation *allocation,
|
|
gpointer data);
|
|
static gboolean on_motion_notify (GooCanvasItem *item,
|
|
GooCanvasItem *target,
|
|
GdkEventMotion *event,
|
|
gpointer data);
|
|
static void on_item_created (GooCanvas *canvas,
|
|
GooCanvasItem *item,
|
|
GooCanvasItemModel *model,
|
|
gpointer data);
|
|
static void on_canvas_realized (GtkWidget *canvas, gpointer data);
|
|
static GooCanvasItemModel* create_canvas_model (GtkAzelPlot *polv);
|
|
static void get_canvas_bg_color (GtkAzelPlot *polv, GdkColor *color);
|
|
static void xy_to_graph (GtkAzelPlot *p, gfloat x, gfloat y, gdouble *t, gdouble *az, gdouble *el);
|
|
static void az_to_xy (GtkAzelPlot *p, gdouble t, gdouble az, gdouble *x, gdouble *y);
|
|
static void el_to_xy (GtkAzelPlot *p, gdouble t, gdouble el, gdouble *x, gdouble *y);
|
|
|
|
|
|
static GtkVBoxClass *parent_class = NULL;
|
|
|
|
|
|
GtkType
|
|
gtk_azel_plot_get_type ()
|
|
{
|
|
static GType gtk_azel_plot_type = 0;
|
|
|
|
if (!gtk_azel_plot_type) {
|
|
static const GTypeInfo gtk_azel_plot_info = {
|
|
sizeof (GtkAzelPlotClass),
|
|
NULL, /* base init */
|
|
NULL, /* base finalise */
|
|
(GClassInitFunc) gtk_azel_plot_class_init,
|
|
NULL, /* class finalise */
|
|
NULL, /* class data */
|
|
sizeof (GtkAzelPlot),
|
|
5, /* n_preallocs */
|
|
(GInstanceInitFunc) gtk_azel_plot_init,
|
|
};
|
|
|
|
gtk_azel_plot_type = g_type_register_static (GTK_TYPE_VBOX,
|
|
"GtkAzelPlot",
|
|
>k_azel_plot_info,
|
|
0);
|
|
}
|
|
|
|
return gtk_azel_plot_type;
|
|
}
|
|
|
|
|
|
static void
|
|
gtk_azel_plot_class_init (GtkAzelPlotClass *class)
|
|
{
|
|
GObjectClass *gobject_class;
|
|
GtkObjectClass *object_class;
|
|
GtkWidgetClass *widget_class;
|
|
GtkContainerClass *container_class;
|
|
|
|
gobject_class = G_OBJECT_CLASS (class);
|
|
object_class = (GtkObjectClass*) class;
|
|
widget_class = (GtkWidgetClass*) class;
|
|
container_class = (GtkContainerClass*) class;
|
|
|
|
parent_class = g_type_class_peek_parent (class);
|
|
|
|
object_class->destroy = gtk_azel_plot_destroy;
|
|
//widget_class->size_allocate = gtk_azel_plot_size_allocate;
|
|
}
|
|
|
|
|
|
static void
|
|
gtk_azel_plot_init (GtkAzelPlot *polview)
|
|
{
|
|
polview->qth = NULL;
|
|
polview->width = 0;
|
|
polview->height = 0;
|
|
polview->x0 = 0;
|
|
polview->y0 = 0;
|
|
polview->xmax = 0;
|
|
polview->ymax = 0;
|
|
polview->maxaz = 0.0;
|
|
polview->qthinfo = FALSE;
|
|
polview->cursinfo = FALSE;
|
|
polview->extratick = FALSE;
|
|
}
|
|
|
|
|
|
static void
|
|
gtk_azel_plot_destroy (GtkObject *object)
|
|
{
|
|
|
|
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
|
|
}
|
|
|
|
|
|
/** \brief Create a new GtkAzelPlot widget.
|
|
* \param cfgdata The configuration data of the parent module.
|
|
* \param sats Pointer to the hash table containing the asociated satellites.
|
|
* \param qth Pointer to the ground station data.
|
|
*/
|
|
GtkWidget*
|
|
gtk_azel_plot_new (qth_t *qth, pass_t *pass)
|
|
{
|
|
GtkWidget *polv;
|
|
GooCanvasItemModel *root;
|
|
GdkColor bg_color = {0, 0xFFFF, 0xFFFF, 0xFFFF};
|
|
guint i,n;
|
|
pass_detail_t *detail;
|
|
|
|
polv = g_object_new (GTK_TYPE_AZEL_PLOT, NULL);
|
|
|
|
GTK_AZEL_PLOT (polv)->qth = qth;
|
|
GTK_AZEL_PLOT (polv)->pass = pass;
|
|
|
|
/* get settings */
|
|
GTK_AZEL_PLOT (polv)->qthinfo = sat_cfg_get_bool (SAT_CFG_BOOL_POL_SHOW_QTH_INFO);
|
|
GTK_AZEL_PLOT (polv)->extratick = sat_cfg_get_bool (SAT_CFG_BOOL_POL_SHOW_EXTRA_AZ_TICKS);
|
|
GTK_AZEL_PLOT (polv)->cursinfo = TRUE;
|
|
|
|
/* check maximum Az */
|
|
n = g_slist_length (pass->details);
|
|
for (i = 0; i < n; i++) {
|
|
detail = PASS_DETAIL (g_slist_nth_data (pass->details, i));
|
|
|
|
if (detail->az > GTK_AZEL_PLOT (polv)->maxaz) {
|
|
GTK_AZEL_PLOT (polv)->maxaz = detail->az;
|
|
}
|
|
}
|
|
|
|
if (GTK_AZEL_PLOT (polv)->maxaz > 180.0)
|
|
GTK_AZEL_PLOT (polv)->maxaz = 360.0;
|
|
else
|
|
GTK_AZEL_PLOT (polv)->maxaz = 180.0;
|
|
|
|
/* create the canvas */
|
|
GTK_AZEL_PLOT (polv)->canvas = goo_canvas_new ();
|
|
get_canvas_bg_color (GTK_AZEL_PLOT (polv), &bg_color);
|
|
gtk_widget_modify_base (GTK_AZEL_PLOT (polv)->canvas, GTK_STATE_NORMAL, &bg_color);
|
|
gtk_widget_set_size_request (GTK_AZEL_PLOT (polv)->canvas,
|
|
POLV_DEFAULT_SIZE, POLV_DEFAULT_SIZE);
|
|
goo_canvas_set_bounds (GOO_CANVAS (GTK_AZEL_PLOT (polv)->canvas), 0, 0,
|
|
POLV_DEFAULT_SIZE, POLV_DEFAULT_SIZE);
|
|
|
|
/* connect size-request signal */
|
|
g_signal_connect (GTK_AZEL_PLOT (polv)->canvas, "size-allocate",
|
|
G_CALLBACK (size_allocate_cb), polv);
|
|
g_signal_connect (GTK_AZEL_PLOT (polv)->canvas, "item_created",
|
|
(GtkSignalFunc) on_item_created, polv);
|
|
g_signal_connect_after (GTK_AZEL_PLOT (polv)->canvas, "realize",
|
|
(GtkSignalFunc) on_canvas_realized, polv);
|
|
|
|
gtk_widget_show (GTK_AZEL_PLOT (polv)->canvas);
|
|
|
|
|
|
/* Create the canvas model */
|
|
root = create_canvas_model (GTK_AZEL_PLOT (polv));
|
|
goo_canvas_set_root_item_model (GOO_CANVAS (GTK_AZEL_PLOT (polv)->canvas), root);
|
|
|
|
g_object_unref (root);
|
|
|
|
gtk_container_add (GTK_CONTAINER (polv), GTK_AZEL_PLOT (polv)->canvas);
|
|
|
|
return polv;
|
|
}
|
|
|
|
|
|
static GooCanvasItemModel *
|
|
create_canvas_model (GtkAzelPlot *polv)
|
|
{
|
|
GooCanvasItemModel *root;
|
|
guint32 col;
|
|
guint i;
|
|
gdouble xstep,ystep;
|
|
gdouble t,az,el;
|
|
time_t tim;
|
|
gchar buff[7];
|
|
gchar *txt;
|
|
|
|
root = goo_canvas_group_model_new (NULL, NULL);
|
|
|
|
/* graph dimensions */
|
|
polv->width = POLV_DEFAULT_SIZE;
|
|
polv->height = POLV_DEFAULT_SIZE;
|
|
|
|
/* update coordinate system */
|
|
polv->x0 = POLV_X_MARGIN;
|
|
polv->xmax = polv->width - POLV_X_MARGIN;
|
|
polv->y0 = polv->height - POLV_Y_MARGIN;
|
|
polv->ymax = POLV_Y_MARGIN;
|
|
|
|
col = sat_cfg_get_int (SAT_CFG_INT_POLAR_AXIS_COL);
|
|
|
|
/* frame */
|
|
polv->frame = goo_canvas_rect_model_new (root,
|
|
(gdouble) polv->x0,
|
|
(gdouble) polv->ymax,
|
|
(gdouble) (polv->xmax - polv->x0),
|
|
(gdouble) (polv->y0 - POLV_Y_MARGIN),
|
|
"stroke-color-rgba", 0x000000FF,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
xstep = (polv->xmax - polv->x0) / (AZEL_PLOT_NUM_TICKS+1);
|
|
ystep = (polv->y0 - polv->ymax) / (AZEL_PLOT_NUM_TICKS+1);
|
|
|
|
/* tick marks */
|
|
for (i = 0; i < AZEL_PLOT_NUM_TICKS; i++) {
|
|
|
|
/* bottom x tick marks */
|
|
polv->xticksb[i] = goo_canvas_polyline_model_new_line (root,
|
|
(gdouble) (polv->x0 + (i+1) * xstep),
|
|
(gdouble) polv->y0,
|
|
(gdouble) (polv->x0 + (i+1) * xstep),
|
|
(gdouble) (polv->y0 - MARKER_SIZE),
|
|
"fill-color-rgba", col,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
/* top x tick marks */
|
|
polv->xtickst[i] = goo_canvas_polyline_model_new_line (root,
|
|
(gdouble) (polv->x0 + (i+1) * xstep),
|
|
(gdouble) polv->ymax,
|
|
(gdouble) (polv->x0 + (i+1) * xstep),
|
|
(gdouble) (polv->ymax + MARKER_SIZE),
|
|
"fill-color-rgba", col,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
/* x tick labels */
|
|
/* get time */
|
|
xy_to_graph (polv, polv->x0 + (i+1) * xstep, 0.0, &t, &az, &el);
|
|
|
|
/* convert julian date to struct tm */
|
|
tim = (t - 2440587.5)*86400.0;
|
|
|
|
/* format either local time or UTC depending on check box */
|
|
if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_LOCAL_TIME))
|
|
strftime (buff, 7, "%H:%M", localtime (&tim));
|
|
else
|
|
strftime (buff, 7, "%H:%M", gmtime (&tim));
|
|
|
|
buff[6]='\0';
|
|
|
|
polv->xlab[i] = goo_canvas_text_model_new (root, buff,
|
|
(gfloat) (polv->x0 + (i+1) * xstep),
|
|
(gfloat) (polv->y0 + 5),
|
|
-1,
|
|
GTK_ANCHOR_N,
|
|
"font", "Sans 8",
|
|
"fill-color-rgba", 0x000000FF,
|
|
NULL);
|
|
|
|
/* left y tick marks */
|
|
polv->yticksl[i] = goo_canvas_polyline_model_new_line (root,
|
|
(gdouble) polv->x0,
|
|
(gdouble) (polv->y0 - (i+1) * ystep),
|
|
(gdouble) (polv->x0 + MARKER_SIZE),
|
|
(gdouble) (polv->y0 - (i+1) * ystep),
|
|
"fill-color-rgba", col,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
/* right y tick marks */
|
|
polv->yticksr[i] = goo_canvas_polyline_model_new_line (root,
|
|
(gdouble) polv->xmax,
|
|
(gdouble) (polv->y0 - (i+1) * ystep),
|
|
(gdouble) (polv->xmax - MARKER_SIZE),
|
|
(gdouble) (polv->y0 - (i+1) * ystep),
|
|
"fill-color-rgba", col,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
/* Az tick labels */
|
|
txt = g_strdup_printf ("%.0f\302\260", polv->maxaz / (AZEL_PLOT_NUM_TICKS+1) * (i+1));
|
|
polv->azlab[i] = goo_canvas_text_model_new (root, txt,
|
|
(gfloat) (polv->x0 - 5),
|
|
(gfloat) (polv->y0 - (i+1) * ystep),
|
|
-1,
|
|
GTK_ANCHOR_E,
|
|
"font", "Sans 8",
|
|
"fill-color-rgba", 0x0000BFFF,
|
|
NULL);
|
|
g_free (txt);
|
|
|
|
/* El tick labels */
|
|
txt = g_strdup_printf ("%.0f\302\260", 90.0 / (AZEL_PLOT_NUM_TICKS+1) * (i+1));
|
|
polv->ellab[i] = goo_canvas_text_model_new (root, txt,
|
|
(gfloat) (polv->xmax + 5),
|
|
(gfloat) (polv->y0 - (i+1) * ystep),
|
|
-1,
|
|
GTK_ANCHOR_W,
|
|
"font", "Sans 8",
|
|
"fill-color-rgba", 0xBF0000FF,
|
|
NULL);
|
|
g_free (txt);
|
|
|
|
}
|
|
|
|
/* x legend */
|
|
if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_LOCAL_TIME)) {
|
|
polv->xleg = goo_canvas_text_model_new (root, _("Local Time"),
|
|
(gfloat) (polv->x0 + (polv->xmax - polv->x0) / 2),
|
|
(gfloat) (polv->height - 5),
|
|
-1,
|
|
GTK_ANCHOR_S,
|
|
"font", "Sans 9",
|
|
"fill-color-rgba", 0x000000FF,
|
|
NULL);
|
|
}
|
|
else {
|
|
polv->xleg = goo_canvas_text_model_new (root, _("UTC"),
|
|
(gfloat) (polv->x0 + (polv->xmax - polv->x0) / 2),
|
|
(gfloat) (polv->height - 5),
|
|
-1,
|
|
GTK_ANCHOR_S,
|
|
"font", "Sans 9",
|
|
"fill-color-rgba", 0x000000FF,
|
|
NULL);
|
|
}
|
|
|
|
/* cursor text in upper right corner */
|
|
polv->curs = goo_canvas_text_model_new (root, "",
|
|
(gfloat) (polv->x0 + (polv->xmax - polv->x0) / 2),
|
|
5.0,
|
|
-1,
|
|
GTK_ANCHOR_N,
|
|
"font", "Sans 8",
|
|
"fill-color-rgba", 0x000000FF,
|
|
NULL);
|
|
|
|
/* Az legend */
|
|
polv->azleg = goo_canvas_text_model_new (root, _("Az"),
|
|
(gfloat) (polv->x0 - 7),
|
|
(gfloat) polv->ymax,
|
|
-1,
|
|
GTK_ANCHOR_NE,
|
|
"font", "Sans 9",
|
|
"fill-color-rgba", 0x0000BFFF,
|
|
NULL);
|
|
|
|
/* El legend */
|
|
polv->elleg = goo_canvas_text_model_new (root, _("El"),
|
|
(gfloat) (polv->xmax + 7),
|
|
(gfloat) polv->ymax,
|
|
-1,
|
|
GTK_ANCHOR_NW,
|
|
"font", "Sans 9",
|
|
"fill-color-rgba", 0xBF0000FF,
|
|
NULL);
|
|
|
|
/* Az graph */
|
|
polv->azg = goo_canvas_polyline_model_new_line (root, 0, 0, 10, 10,
|
|
"stroke-color-rgba", 0x0000BFFF,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
/* El graph */
|
|
polv->elg = goo_canvas_polyline_model_new_line (root, 30, 30, 40, 40,
|
|
"stroke-color-rgba", 0xBF0000FF,
|
|
"fill-color-rgba", 0xBF00001A,
|
|
"line-cap", CAIRO_LINE_CAP_SQUARE,
|
|
"line-join", CAIRO_LINE_JOIN_MITER,
|
|
"line-width", 1.0,
|
|
NULL);
|
|
|
|
return root;
|
|
}
|
|
|
|
|
|
/** \brief Manage new size allocation.
|
|
*
|
|
* This function is called when the canvas receives a new size allocation,
|
|
* e.g. when the container is re-sized. The function re-calculates the graph
|
|
* dimensions based on the new canvas size.
|
|
*/
|
|
static void
|
|
size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, gpointer data)
|
|
{
|
|
GtkAzelPlot *polv;
|
|
GooCanvasPoints *pts;
|
|
gdouble dx,dy;
|
|
gdouble xstep,ystep;
|
|
guint i,n;
|
|
pass_detail_t *detail;
|
|
|
|
|
|
if (GTK_WIDGET_REALIZED (widget)) {
|
|
|
|
/* get graph dimensions */
|
|
polv = GTK_AZEL_PLOT (data);
|
|
|
|
polv->width = allocation->width;
|
|
polv->height = allocation->height;
|
|
|
|
/* update coordinate system */
|
|
polv->x0 = POLV_X_MARGIN;
|
|
polv->xmax = polv->width - POLV_X_MARGIN;
|
|
polv->y0 = polv->height - POLV_Y_MARGIN;
|
|
polv->ymax = POLV_Y_MARGIN;
|
|
|
|
/* frame */
|
|
g_object_set (polv->frame,
|
|
"x", (gdouble) polv->x0,
|
|
"y", (gdouble) polv->ymax,
|
|
"width", (gdouble) (polv->xmax - polv->x0),
|
|
"height", (gdouble) (polv->y0 - POLV_Y_MARGIN),
|
|
NULL);
|
|
|
|
|
|
xstep = (polv->xmax - polv->x0) / (AZEL_PLOT_NUM_TICKS+1);
|
|
ystep = (polv->y0 - polv->ymax) / (AZEL_PLOT_NUM_TICKS+1);
|
|
|
|
/* tick marks */
|
|
for (i = 0; i < AZEL_PLOT_NUM_TICKS; i++) {
|
|
|
|
pts = goo_canvas_points_new (2);
|
|
|
|
/* bottom x tick marks */
|
|
pts->coords[0] = (gdouble) (polv->x0 + (i+1) * xstep);
|
|
pts->coords[1] = (gdouble) polv->y0;
|
|
pts->coords[2] = (gdouble) (polv->x0 + (i+1) * xstep);
|
|
pts->coords[3] = (gdouble) (polv->y0 - MARKER_SIZE);
|
|
g_object_set (polv->xticksb[i], "points", pts, NULL);
|
|
|
|
/* top x tick marks */
|
|
pts->coords[0] = (gdouble) (polv->x0 + (i+1) * xstep);
|
|
pts->coords[1] = (gdouble) polv->ymax;
|
|
pts->coords[2] = (gdouble) (polv->x0 + (i+1) * xstep);
|
|
pts->coords[3] = (gdouble) (polv->ymax + MARKER_SIZE);
|
|
g_object_set (polv->xtickst[i], "points", pts, NULL);
|
|
|
|
/* x tick labels */
|
|
g_object_set (polv->xlab[i],
|
|
"x", (gfloat) (polv->x0 + (i+1) * xstep),
|
|
"y", (gfloat) (polv->y0 + 5.0),
|
|
NULL);
|
|
|
|
/* left y tick marks */
|
|
pts->coords[0] = (gdouble) (gdouble) polv->x0;
|
|
pts->coords[1] = (gdouble) (gdouble) (polv->y0 - (i+1) * ystep);
|
|
pts->coords[2] = (gdouble) (gdouble) (polv->x0 + MARKER_SIZE);
|
|
pts->coords[3] = (gdouble) (gdouble) (polv->y0 - (i+1) * ystep);
|
|
g_object_set (polv->yticksl[i], "points", pts, NULL);
|
|
|
|
/* right y tick marks */
|
|
pts->coords[0] = (gdouble) polv->xmax;
|
|
pts->coords[1] = (gdouble) (polv->y0 - (i+1) * ystep);
|
|
pts->coords[2] = (gdouble) (polv->xmax - MARKER_SIZE);
|
|
pts->coords[3] = (gdouble) (polv->y0 - (i+1) * ystep);
|
|
g_object_set (polv->yticksr[i], "points", pts, NULL);
|
|
|
|
goo_canvas_points_unref (pts);
|
|
|
|
/* Az tick labels */
|
|
g_object_set (polv->azlab[i],
|
|
"x", (gfloat) (polv->x0 - 5),
|
|
"y", (gfloat) (polv->y0 - (i+1) * ystep),
|
|
NULL);
|
|
|
|
/* El tick labels */
|
|
g_object_set (polv->ellab[i],
|
|
"x", (gfloat) (polv->xmax + 5),
|
|
"y", (gfloat) (polv->y0 - (i+1) * ystep),
|
|
NULL);
|
|
|
|
}
|
|
|
|
/* Az legend */
|
|
g_object_set (polv->azleg,
|
|
"x", (gfloat) (polv->x0 - 7),
|
|
"y", (gfloat) (polv->ymax),
|
|
NULL);
|
|
|
|
/* El legend */
|
|
g_object_set (polv->elleg,
|
|
"x", (gfloat) (polv->xmax + 7),
|
|
"y", (gfloat) (polv->ymax),
|
|
NULL);
|
|
|
|
/* x legend */
|
|
g_object_set (polv->xleg,
|
|
"x", (gfloat) (polv->x0 + (polv->xmax - polv->x0) / 2),
|
|
"y", (gfloat) (polv->height - 5),
|
|
NULL);
|
|
|
|
/* Az graph */
|
|
n = g_slist_length (polv->pass->details);
|
|
pts = goo_canvas_points_new (n);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
detail = PASS_DETAIL (g_slist_nth_data (polv->pass->details, i));
|
|
az_to_xy (polv, detail->time, detail->az, &dx, &dy);
|
|
pts->coords[2*i] = dx;
|
|
pts->coords[2*i+1] = dy;
|
|
}
|
|
pts->coords[0] = polv->x0;
|
|
pts->coords[2*n-2] = polv->xmax;
|
|
g_object_set (polv->azg, "points", pts, NULL);
|
|
goo_canvas_points_unref (pts);
|
|
|
|
/* El graph */
|
|
n = g_slist_length (polv->pass->details);
|
|
pts = goo_canvas_points_new (n);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
detail = PASS_DETAIL (g_slist_nth_data (polv->pass->details, i));
|
|
el_to_xy (polv, detail->time, detail->el, &dx, &dy);
|
|
pts->coords[2*i] = dx;
|
|
pts->coords[2*i+1] = dy;
|
|
}
|
|
pts->coords[1] = polv->y0;
|
|
pts->coords[2*n-1] = polv->y0;
|
|
g_object_set (polv->elg, "points", pts, NULL);
|
|
goo_canvas_points_unref (pts);
|
|
|
|
/* cursor track */
|
|
g_object_set (polv->curs,
|
|
"x", (gfloat) (polv->x0 + (polv->xmax - polv->x0) / 2),
|
|
"y", (gfloat) 5.0,
|
|
NULL);
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/** \brief Manage canvas realise signals.
|
|
*
|
|
* This function is used to re-initialise the graph dimensions when
|
|
* the graph is realized, i.e. displayed for the first time. This is
|
|
* necessary in order to compensate for missing "re-allocate" signals for
|
|
* graphs that have not yet been realised, e.g. when opening several module
|
|
*/
|
|
static void
|
|
on_canvas_realized (GtkWidget *canvas, gpointer data)
|
|
{
|
|
GtkAllocation aloc;
|
|
|
|
aloc.width = canvas->allocation.width;
|
|
aloc.height = canvas->allocation.height;
|
|
size_allocate_cb (canvas, &aloc, data);
|
|
|
|
}
|
|
|
|
|
|
/** \brief Convert Az/El to canvas based XY coordinates. */
|
|
/* static void */
|
|
/* graph_to_xy (GtkAzelPlot *p, gdouble t, gdouble az, gdouble el, gfloat *x, gfloat *y) */
|
|
/* { */
|
|
/* gdouble rel; */
|
|
|
|
|
|
/* } */
|
|
|
|
|
|
/** \brief Convert canvas based coordinates to Az/El. */
|
|
static void
|
|
xy_to_graph (GtkAzelPlot *p, gfloat x, gfloat y, gdouble *t, gdouble *az, gdouble *el)
|
|
{
|
|
gdouble tpp; /* time per pixel */
|
|
gdouble dpp; /* degrees per pixel */
|
|
|
|
/* time */
|
|
tpp = (p->pass->los - p->pass->aos) / (p->xmax - p->x0);
|
|
*t = p->pass->aos + tpp * (x - p->x0);
|
|
|
|
/* az */
|
|
dpp = p->maxaz / (p->y0 - p->ymax);
|
|
*az = dpp * (p->y0 - y);
|
|
|
|
/* el */
|
|
dpp = 90.0 / (p->y0 - p->ymax);
|
|
*el = dpp * (p->y0 - y);
|
|
|
|
}
|
|
|
|
|
|
static void
|
|
az_to_xy (GtkAzelPlot *p, gdouble t, gdouble az, gdouble *x, gdouble *y)
|
|
{
|
|
gdouble tpp; /* time per pixel */
|
|
gdouble dpp; /* degrees per pixel */
|
|
|
|
/* time */
|
|
tpp = (p->pass->los - p->pass->aos) / (p->xmax - p->x0);
|
|
*x = p->x0 + (t - p->pass->aos) / tpp;
|
|
|
|
/* Az */
|
|
dpp = (gdouble) (p->maxaz / (p->y0 - p->ymax));
|
|
*y = (gdouble) (p->y0 - az / dpp);
|
|
}
|
|
|
|
|
|
static void
|
|
el_to_xy (GtkAzelPlot *p, gdouble t, gdouble el, gdouble *x, gdouble *y)
|
|
{
|
|
gdouble tpp; /* time per pixel */
|
|
gdouble dpp; /* degrees per pixel */
|
|
|
|
/* time */
|
|
tpp = (p->pass->los - p->pass->aos) / (p->xmax - p->x0);
|
|
*x = p->x0 + (t - p->pass->aos) / tpp;
|
|
|
|
/* Az */
|
|
dpp = (gdouble) (90.0 / (p->y0 - p->ymax));
|
|
*y = (gdouble) (p->y0 - el / dpp);
|
|
}
|
|
|
|
|
|
/** \brief Manage mouse motion events. */
|
|
static gboolean
|
|
on_motion_notify (GooCanvasItem *item,
|
|
GooCanvasItem *target,
|
|
GdkEventMotion *event,
|
|
gpointer data)
|
|
{
|
|
GtkAzelPlot *polv = GTK_AZEL_PLOT (data);
|
|
gdouble t,az,el;
|
|
time_t tim;
|
|
gfloat x,y;
|
|
gchar *text;
|
|
gchar buff[10];
|
|
|
|
if (polv->cursinfo) {
|
|
|
|
/* get (x,y) */
|
|
x = event->x;
|
|
y = event->y;
|
|
|
|
/* get (t,az,el) */
|
|
|
|
/* show vertical line at that time */
|
|
|
|
/* print (t,az,el) */
|
|
if ((x > polv->x0) && (x < polv->xmax) &&
|
|
(y > polv->ymax) && (y < polv->y0)) {
|
|
|
|
xy_to_graph (polv, x, y, &t, &az, &el);
|
|
|
|
/* convert julian date to struct tm */
|
|
tim = (t - 2440587.5)*86400.0;
|
|
|
|
/* format either local time or UTC depending on check box */
|
|
if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_LOCAL_TIME))
|
|
strftime (buff, 10, "%H:%M:%S", localtime (&tim));
|
|
else
|
|
strftime (buff, 10, "%H:%M:%S", gmtime (&tim));
|
|
|
|
buff[8]='\0';
|
|
|
|
/* cursor track */
|
|
text = g_strdup_printf ("T: %s, AZ: %.0f\302\260, EL: %.0f\302\260", buff, az, el);
|
|
g_object_set (polv->curs, "text", text, NULL);
|
|
g_free (text);
|
|
}
|
|
else {
|
|
g_object_set (polv->curs, "text", "", NULL);
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/** \brief Finish canvas item setup.
|
|
* \param canvas
|
|
* \param item
|
|
* \param model
|
|
* \param data Pointer to the GtkAzelPlot object.
|
|
*
|
|
* This function is called when a canvas item is created. Its purpose is to connect
|
|
* the corresponding signals to the created items.
|
|
*/
|
|
static void
|
|
on_item_created (GooCanvas *canvas,
|
|
GooCanvasItem *item,
|
|
GooCanvasItemModel *model,
|
|
gpointer data)
|
|
{
|
|
if (!goo_canvas_item_model_get_parent (model)) {
|
|
/* root item / canvas */
|
|
g_signal_connect (item, "motion_notify_event",
|
|
(GtkSignalFunc) on_motion_notify, data);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/** \brief Retrieve background color.
|
|
*
|
|
* This function retrieves the canvas background color, which is in 0xRRGGBBAA
|
|
* format and converts it to GdkColor style. Besides extractibg the RGB components
|
|
* we also need to scale from [0;255] to [0;65535], i.e. multiply by 257.
|
|
*/
|
|
static void
|
|
get_canvas_bg_color (GtkAzelPlot *polv, GdkColor *color)
|
|
{
|
|
guint32 col,tmp;
|
|
guint16 r,g,b;
|
|
|
|
|
|
col = sat_cfg_get_int (SAT_CFG_INT_POLAR_BGD_COL);
|
|
|
|
/* red */
|
|
tmp = col & 0xFF000000;
|
|
r = (guint16) (tmp >> 24);
|
|
|
|
/* green */
|
|
tmp = col & 0x00FF0000;
|
|
g = (guint16) (tmp >> 16);
|
|
|
|
/* blue */
|
|
tmp = col & 0x0000FF00;
|
|
b = (guint16) (tmp >> 8);
|
|
|
|
/* store colours */
|
|
color->red = 257 * r;
|
|
color->green = 257 * g;
|
|
color->blue = 257 * b;
|
|
}
|