picplanner/src/window/overview-page/overview-view.c

868 wiersze
35 KiB
C

/*
* overview-view.c
* Copyright (C) 2021 Zwarf <zwarf@mail.de>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
/*
* TODO:
* - Catching Azimuth 0 deg errors
*/
#include "overview-view.h"
#include "calculations/calculations_transformations.h"
#include "calculations/calculations_sun.h"
#include "calculations/calculations_moon.h"
#include "calculations/calculations_milky_way.h"
#include "map/draw-layer.h"
#include "map/marker.h"
#include <libgweather/gweather.h>
#define LENGTH_SCALE_FACTOR 0.38
#define ICON_SIZE_SMALL 32
#define ICON_SIZE_LARGE 48
static guint signal_input_changed;
static guint signal_ui_changed;
struct _PicplannerOverview
{
GtkBox parent_instance;
GtkWidget *calendar;
GtkWidget *calendar_popover;
GtkWidget *calendar_button;
GtkWidget *spin_button_hour;
GtkWidget *spin_button_minute;
GtkWidget *switch_sun;
GtkWidget *switch_moon;
GtkWidget *switch_milky_way;
GtkWidget *label_time_zone;
GtkWidget *label_sun_rise;
GtkWidget *label_sun_set;
GtkWidget *label_moon_rise;
GtkWidget *label_moon_set;
GtkWidget *label_milky_way_rise;
GtkWidget *label_milky_way_set;
GtkWidget *label_elevation_sun;
GtkWidget *label_elevation_moon;
GtkWidget *label_elevation_milky_way;
GtkWidget *label_azimuth_sun;
GtkWidget *label_azimuth_moon;
GtkWidget *label_azimuth_milky_way;
GtkWidget *expander_date_time;
GtkWidget *expander_basic_information;
ShumateSimpleMap *map;
ShumateViewport *viewport;
PicplannerMarker *pp_marker_center;
PicplannerDrawLayer *pp_layer_center;
PicplannerMarker *pp_marker_sun;
PicplannerDrawLayer *pp_layer_sun;
PicplannerDrawLayer *pp_layer_sun_rise_set;
PicplannerMarker *pp_marker_moon;
PicplannerDrawLayer *pp_layer_moon;
PicplannerDrawLayer *pp_layer_moon_rise_set;
PicplannerMarker *pp_marker_milky_way;
PicplannerDrawLayer *pp_layer_milky_way;
PicplannerDrawLayer *pp_layer_milky_way_rise_set;
GDateTime *date_time;
GSettings *settings;
};
G_DEFINE_TYPE (PicplannerOverview, picplanner_overview, GTK_TYPE_BOX)
/*
* Changing the date_time variable after a user input was recognized.
* Afterwards, emit a signal to start the calculations.
*/
void
picplanner_update_date_time (PicplannerOverview *overview)
{
int year, month, day, hour, minute;
double latitude, longitude;
char *char_time_zone;
GDateTime *date_selected;
GWeatherLocation *loc;
latitude = shumate_location_get_latitude (SHUMATE_LOCATION (overview->viewport));
longitude = shumate_location_get_longitude (SHUMATE_LOCATION (overview->viewport));
loc = gweather_location_new_detached ("Custom Location", NULL, latitude, longitude);
/*
* Get year, month and day information from the calendar widget.
*/
date_selected = gtk_calendar_get_date (GTK_CALENDAR (overview->calendar));
year = g_date_time_get_year (date_selected);
month = g_date_time_get_month (date_selected);
day = g_date_time_get_day_of_month (date_selected);
/*
* Get hour and minute from the spin buttons.
*/
hour = gtk_spin_button_get_value (GTK_SPIN_BUTTON (overview->spin_button_hour));
minute = gtk_spin_button_get_value (GTK_SPIN_BUTTON (overview->spin_button_minute));
/*
* Save the information into the date_time variable.
*/
overview->date_time = g_date_time_new (gweather_location_get_timezone (loc),
year, month, day,
hour, minute,
0);
g_settings_set_double (overview->settings,
"time-zone",
(double) g_date_time_get_utc_offset (overview->date_time)/3600/1000/1000);
char_time_zone = g_strdup_printf ("Timezone: %.1f", (double) g_date_time_get_utc_offset (overview->date_time)/3600/1000/1000);
gtk_label_set_text (GTK_LABEL (overview->label_time_zone), char_time_zone);
g_free (char_time_zone);
g_date_time_unref (date_selected);
}
static void
emit_signal_changed (GtkWidget *self,
gpointer overview_user_input,
gpointer overview_view_size_change)
{
(void) self;
PicplannerOverview *overview;
if (PICPLANNER_IS_OVERVIEW (overview_user_input))
{
overview = PICPLANNER_OVERVIEW (overview_user_input);
g_signal_emit (overview, signal_input_changed, 0, NULL);
}
else
{
overview = PICPLANNER_OVERVIEW (overview_view_size_change);
g_signal_emit (overview, signal_ui_changed, 0, NULL);
}
}
/*
* Create all the "get" functions.
* These are used so the main window function can collect all the information inputed
* by the user on the overview page after it received the input-changed signal.
*/
GDateTime
*picplanner_overview_get_date_time (PicplannerOverview *overview)
{
return overview->date_time;
}
void
picplanner_overview_set_current_coordinates_sun (PicplannerOverview *overview,
double *array_coordinates_sun,
int *rise_upper_set_index,
int current_index)
{
char *char_elevation_sun;
char *char_azimuth_sun;
char *char_sun_rise;
char *char_sun_set;
GDateTime *date_time_noon;
GDateTime *date_time_rise;
GDateTime *date_time_set;
date_time_noon = g_date_time_new (g_date_time_get_timezone (overview->date_time),
g_date_time_get_year (overview->date_time),
g_date_time_get_month (overview->date_time),
g_date_time_get_day_of_month (overview->date_time),
12, 0, 0);
date_time_rise = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[0]*24*60/NUM_DATA_POINTS-12*60);
date_time_set = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[2]*24*60/NUM_DATA_POINTS-12*60);
if (rise_upper_set_index[0]>0)
{
char_sun_rise = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_rise),
g_date_time_get_minute (date_time_rise));
}
else
{
char_sun_rise = g_strdup_printf ("--:--");
}
if (rise_upper_set_index[2]>0)
{
char_sun_set = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_set),
g_date_time_get_minute (date_time_set));
}
else
{
char_sun_set = g_strdup_printf ("--:--");
}
char_elevation_sun = g_strdup_printf ("%.0f\u00B0", array_coordinates_sun[current_index*2+1]);
char_azimuth_sun = g_strdup_printf ("%.0f\u00B0", array_coordinates_sun[current_index*2]);
gtk_label_set_text (GTK_LABEL (overview->label_sun_rise), char_sun_rise);
gtk_label_set_text (GTK_LABEL (overview->label_sun_set), char_sun_set);
gtk_label_set_text (GTK_LABEL (overview->label_elevation_sun), char_elevation_sun);
gtk_label_set_text (GTK_LABEL (overview->label_azimuth_sun), char_azimuth_sun);
g_date_time_unref (date_time_rise);
g_date_time_unref (date_time_set);
g_free (char_sun_rise);
g_free (char_sun_set);
g_free (char_elevation_sun);
g_free (char_azimuth_sun);
}
void
picplanner_overview_set_current_coordinates_moon (PicplannerOverview *overview,
double *array_coordinates_moon,
int *rise_upper_set_index,
int current_index)
{
char *char_elevation_moon;
char *char_azimuth_moon;
char *char_moon_rise;
char *char_moon_set;
GDateTime *date_time_noon;
GDateTime *date_time_rise;
GDateTime *date_time_set;
date_time_noon = g_date_time_new (g_date_time_get_timezone (overview->date_time),
g_date_time_get_year (overview->date_time),
g_date_time_get_month (overview->date_time),
g_date_time_get_day_of_month (overview->date_time),
12, 0, 0);
date_time_rise = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[0]*24*60/NUM_DATA_POINTS-12*60);
date_time_set = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[2]*24*60/NUM_DATA_POINTS-12*60);
if (rise_upper_set_index[0]>0)
{
char_moon_rise = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_rise),
g_date_time_get_minute (date_time_rise));
}
else
{
char_moon_rise = g_strdup_printf ("--:--");
}
if (rise_upper_set_index[2]>0)
{
char_moon_set = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_set),
g_date_time_get_minute (date_time_set));
}
else
{
char_moon_set = g_strdup_printf ("--:--");
}
char_elevation_moon = g_strdup_printf ("%.0f\u00B0", array_coordinates_moon[current_index*2+1]);
char_azimuth_moon = g_strdup_printf ("%.0f\u00B0", array_coordinates_moon[current_index*2]);
gtk_label_set_text (GTK_LABEL (overview->label_moon_rise), char_moon_rise);
gtk_label_set_text (GTK_LABEL (overview->label_moon_set), char_moon_set);
gtk_label_set_text (GTK_LABEL (overview->label_elevation_moon), char_elevation_moon);
gtk_label_set_text (GTK_LABEL (overview->label_azimuth_moon), char_azimuth_moon);
g_date_time_unref (date_time_rise);
g_date_time_unref (date_time_set);
g_free (char_moon_rise);
g_free (char_moon_set);
g_free (char_elevation_moon);
g_free (char_azimuth_moon);
}
void
picplanner_overview_set_current_coordinates_milky_way (PicplannerOverview *overview,
double *array_coordinates_milky_way,
int *rise_upper_set_index,
int current_index)
{
char *char_elevation_milky_way;
char *char_azimuth_milky_way;
char *char_milky_way_rise;
char *char_milky_way_set;
GDateTime *date_time_noon;
GDateTime *date_time_rise;
GDateTime *date_time_set;
date_time_noon = g_date_time_new (g_date_time_get_timezone (overview->date_time),
g_date_time_get_year (overview->date_time),
g_date_time_get_month (overview->date_time),
g_date_time_get_day_of_month (overview->date_time),
12, 0, 0);
date_time_rise = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[0]*24*60/NUM_DATA_POINTS-12*60);
date_time_set = g_date_time_add_minutes (date_time_noon, rise_upper_set_index[2]*24*60/NUM_DATA_POINTS-12*60);
if (rise_upper_set_index[0]>0)
{
char_milky_way_rise = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_rise),
g_date_time_get_minute (date_time_rise));
}
else
{
char_milky_way_rise = g_strdup_printf ("--:--");
}
if (rise_upper_set_index[2]>0)
{
char_milky_way_set = g_strdup_printf ("%02d:%02d",
g_date_time_get_hour (date_time_set),
g_date_time_get_minute (date_time_set));
}
else
{
char_milky_way_set = g_strdup_printf ("--:--");
}
char_elevation_milky_way = g_strdup_printf ("%.0f\u00B0", array_coordinates_milky_way[current_index*2+1]);
char_azimuth_milky_way = g_strdup_printf ("%.0f\u00B0", array_coordinates_milky_way[current_index*2]);
gtk_label_set_text (GTK_LABEL (overview->label_milky_way_rise), char_milky_way_rise);
gtk_label_set_text (GTK_LABEL (overview->label_milky_way_set), char_milky_way_set);
gtk_label_set_text (GTK_LABEL (overview->label_elevation_milky_way), char_elevation_milky_way);
gtk_label_set_text (GTK_LABEL (overview->label_azimuth_milky_way), char_azimuth_milky_way);
g_date_time_unref (date_time_rise);
g_date_time_unref (date_time_set);
g_free (char_milky_way_rise);
g_free (char_milky_way_set);
g_free (char_elevation_milky_way);
g_free (char_azimuth_milky_way);
}
void
picplanner_overview_remove_map_content (PicplannerOverview *overview)
{
picplanner_draw_layer_remove_all (overview->pp_layer_sun);
picplanner_draw_layer_remove_all (overview->pp_layer_sun_rise_set);
picplanner_draw_layer_remove_all (overview->pp_layer_moon);
picplanner_draw_layer_remove_all (overview->pp_layer_moon_rise_set);
picplanner_draw_layer_remove_all (overview->pp_layer_milky_way);
picplanner_draw_layer_remove_all (overview->pp_layer_milky_way_rise_set);
}
void
picplanner_overview_update_map_center (PicplannerOverview *overview)
{
GtkWidget *image_center;
picplanner_draw_layer_remove_all (overview->pp_layer_center);
image_center = gtk_image_new_from_icon_name ("location-icon-symbolic-red");
gtk_image_set_pixel_size (GTK_IMAGE (image_center), ICON_SIZE_SMALL);
picplanner_marker_set_location (overview->pp_marker_center, 1./2., 1./2., 0, -ICON_SIZE_SMALL/2);
picplanner_marker_set_child (overview->pp_marker_center, image_center);
picplanner_draw_layer_add_marker (overview->pp_layer_center, overview->pp_marker_center);
}
void
picplanner_overview_update_map_sun (PicplannerOverview *overview,
double *array_coordinates_sun,
int current_index,
int *rise_upper_set_sun)
{
int sun_stroke_width = 6;
static GdkRGBA sun_color = {1., 0.9, 0., 0.8};
static GdkRGBA sun_rise_set_color = {1., 0.8, 0., 0.5};
double x_sun, y_sun;
double x_sunrise, y_sunrise;
double x_sunset, y_sunset;
double azimuth_sun, azimuth_sunrise, azimuth_sunset;
gboolean visible_sun = TRUE;
GtkWidget *image_sun;
picplanner_draw_layer_remove_all (overview->pp_layer_sun);
picplanner_draw_layer_remove_all (overview->pp_layer_sun_rise_set);
if (array_coordinates_sun[current_index*2+1]<0)
visible_sun = FALSE;
image_sun = gtk_image_new_from_icon_name ("sun");
gtk_image_set_pixel_size (GTK_IMAGE (image_sun), ICON_SIZE_LARGE);
gtk_widget_set_visible (image_sun, visible_sun);
azimuth_sun = array_coordinates_sun[current_index*2];
x_sun = 1./2. + sin(calc_deg_to_rad (azimuth_sun)) * LENGTH_SCALE_FACTOR;
y_sun = 1./2. - cos(calc_deg_to_rad (azimuth_sun)) * LENGTH_SCALE_FACTOR;
azimuth_sunrise = array_coordinates_sun[rise_upper_set_sun[0]*2];
x_sunrise = 1./2. + sin(calc_deg_to_rad (azimuth_sunrise)) * LENGTH_SCALE_FACTOR;
y_sunrise = 1./2. - cos(calc_deg_to_rad (azimuth_sunrise)) * LENGTH_SCALE_FACTOR;
azimuth_sunset = array_coordinates_sun[rise_upper_set_sun[2]*2];
x_sunset = 1./2. + sin(calc_deg_to_rad (azimuth_sunset)) * LENGTH_SCALE_FACTOR;
y_sunset = 1./2. - cos(calc_deg_to_rad (azimuth_sunset)) * LENGTH_SCALE_FACTOR;
picplanner_marker_set_location (overview->pp_marker_sun, x_sun, y_sun, 0, 0);
picplanner_marker_set_child (overview->pp_marker_sun, image_sun);
picplanner_draw_layer_add_marker (overview->pp_layer_sun, overview->pp_marker_sun);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_sun, 1./2., 1./2.);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_sun, x_sun, y_sun);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_sun, &sun_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_sun, sun_stroke_width);
picplanner_draw_layer_set_stroke (overview->pp_layer_sun, visible_sun);
if (rise_upper_set_sun[0]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_sun_rise_set, x_sunrise, y_sunrise);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_sun_rise_set, 1./2., 1./2.);
if (rise_upper_set_sun[2]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_sun_rise_set, x_sunset, y_sunset);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_sun_rise_set, &sun_rise_set_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_sun_rise_set, sun_stroke_width);
}
void
picplanner_overview_update_map_moon (PicplannerOverview *overview,
double *array_coordinates_moon,
int current_index,
int *rise_upper_set_moon)
{
int moon_stroke_width = 6;
static GdkRGBA moon_color = {0.8, 0.8, 0.8, 0.8};
static GdkRGBA moon_rise_set_color = {0.5, 0.5, 0.5, 0.5};
double x_moon, y_moon;
double x_moonrise, y_moonrise;
double x_moonset, y_moonset;
double azimuth_moon, azimuth_moonrise, azimuth_moonset;
gboolean visible_moon = TRUE;
GtkWidget *image_moon;
picplanner_draw_layer_remove_all (overview->pp_layer_moon);
picplanner_draw_layer_remove_all (overview->pp_layer_moon_rise_set);
if (array_coordinates_moon[current_index*2+1]<0)
visible_moon = FALSE;
image_moon = gtk_image_new_from_icon_name ("weather-clear-night-symbolic");
gtk_image_set_pixel_size (GTK_IMAGE (image_moon), ICON_SIZE_LARGE);
gtk_widget_set_visible (image_moon, visible_moon);
azimuth_moon = array_coordinates_moon[current_index*2];
x_moon = 1./2. + sin(calc_deg_to_rad (azimuth_moon)) * LENGTH_SCALE_FACTOR;
y_moon = 1./2. - cos(calc_deg_to_rad (azimuth_moon)) * LENGTH_SCALE_FACTOR;
azimuth_moonrise = array_coordinates_moon[rise_upper_set_moon[0]*2];
x_moonrise = 1./2. + sin(calc_deg_to_rad (azimuth_moonrise)) * LENGTH_SCALE_FACTOR;
y_moonrise = 1./2. - cos(calc_deg_to_rad (azimuth_moonrise)) * LENGTH_SCALE_FACTOR;
azimuth_moonset = array_coordinates_moon[rise_upper_set_moon[2]*2];
x_moonset = 1./2. + sin(calc_deg_to_rad (azimuth_moonset)) * LENGTH_SCALE_FACTOR;
y_moonset = 1./2. - cos(calc_deg_to_rad (azimuth_moonset)) * LENGTH_SCALE_FACTOR;
picplanner_marker_set_location (overview->pp_marker_moon, x_moon, y_moon, 0 , 0);
picplanner_marker_set_child (overview->pp_marker_moon, image_moon);
picplanner_draw_layer_add_marker (overview->pp_layer_moon, overview->pp_marker_moon);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_moon, 1./2., 1./2.);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_moon, x_moon, y_moon);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_moon, &moon_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_moon, moon_stroke_width);
picplanner_draw_layer_set_stroke (overview->pp_layer_moon, visible_moon);
if (rise_upper_set_moon[0]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_moon_rise_set, x_moonrise, y_moonrise);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_moon_rise_set, 1./2., 1./2.);
if (rise_upper_set_moon[2]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_moon_rise_set, x_moonset, y_moonset);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_moon_rise_set, &moon_rise_set_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_moon_rise_set, moon_stroke_width);
}
void
picplanner_overview_update_map_milky_way (PicplannerOverview *overview,
double *array_coordinates_milky_way,
int current_index,
int *rise_upper_set_milky_way)
{
int milky_way_stroke_width = 6;
static GdkRGBA milky_way_color = {0.2, 0.2, 0.7, 0.8};
static GdkRGBA milky_way_rise_set_color = {0.0, 0.0, 0.4, 0.5};
double x_milky_way, y_milky_way;
double x_milky_way_rise, y_milky_way_rise;
double x_milky_way_set, y_milky_way_set;
double azimuth_milky_way, azimuth_milky_way_rise, azimuth_milky_way_set;
gboolean visible_milky_way = TRUE;
GtkWidget *image_milky_way;
picplanner_draw_layer_remove_all (overview->pp_layer_milky_way);
picplanner_draw_layer_remove_all (overview->pp_layer_milky_way_rise_set);
if (array_coordinates_milky_way[current_index*2+1]<0)
visible_milky_way = FALSE;
image_milky_way = gtk_image_new_from_icon_name ("milky-way-symbolic");
gtk_image_set_pixel_size (GTK_IMAGE (image_milky_way), ICON_SIZE_LARGE);
gtk_widget_set_visible (image_milky_way, visible_milky_way);
azimuth_milky_way = array_coordinates_milky_way[current_index*2];
x_milky_way = 1./2. + sin(calc_deg_to_rad (azimuth_milky_way)) * LENGTH_SCALE_FACTOR;
y_milky_way = 1./2. - cos(calc_deg_to_rad (azimuth_milky_way)) * LENGTH_SCALE_FACTOR;
azimuth_milky_way_rise = array_coordinates_milky_way[rise_upper_set_milky_way[0]*2];
x_milky_way_rise = 1./2. + sin(calc_deg_to_rad (azimuth_milky_way_rise)) * LENGTH_SCALE_FACTOR;
y_milky_way_rise = 1./2. - cos(calc_deg_to_rad (azimuth_milky_way_rise)) * LENGTH_SCALE_FACTOR;
azimuth_milky_way_set = array_coordinates_milky_way[rise_upper_set_milky_way[2]*2];
x_milky_way_set = 1./2. + sin(calc_deg_to_rad (azimuth_milky_way_set)) * LENGTH_SCALE_FACTOR;
y_milky_way_set = 1./2. - cos(calc_deg_to_rad (azimuth_milky_way_set)) * LENGTH_SCALE_FACTOR;
picplanner_marker_set_location (overview->pp_marker_milky_way, x_milky_way, y_milky_way, 0, 0);
picplanner_marker_set_child (overview->pp_marker_milky_way, image_milky_way);
picplanner_draw_layer_add_marker (overview->pp_layer_milky_way, overview->pp_marker_milky_way);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_milky_way, 1./2., 1./2.);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_milky_way, x_milky_way, y_milky_way);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_milky_way, &milky_way_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_milky_way, milky_way_stroke_width);
picplanner_draw_layer_set_stroke (overview->pp_layer_milky_way, visible_milky_way);
if (rise_upper_set_milky_way[0]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_milky_way_rise_set, x_milky_way_rise, y_milky_way_rise);
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_milky_way_rise_set, 1./2., 1./2.);
if (rise_upper_set_milky_way[2]!=-1)
picplanner_draw_layer_add_node_coordinates (overview->pp_layer_milky_way_rise_set, x_milky_way_set, y_milky_way_set);
picplanner_draw_layer_set_stroke_color (overview->pp_layer_milky_way_rise_set, &milky_way_rise_set_color);
picplanner_draw_layer_set_stroke_width (overview->pp_layer_milky_way_rise_set, milky_way_stroke_width);
}
/*
* Change the text of the GtkSpinButton to always be a two digit number.
* E.g. don't show one o'clock AM as 1:0 but show 01:00
*/
static gboolean
time_spin_button_text (GtkSpinButton *self)
{
int value;
char *button_text;
GtkAdjustment *adjustment;
adjustment = gtk_spin_button_get_adjustment (self);
value = (int) gtk_adjustment_get_value (adjustment);
button_text = g_strdup_printf ("%02d", value);
gtk_editable_set_text (GTK_EDITABLE (self),
button_text);
g_free (button_text);
return TRUE;
}
/*
* Change the text of the button which presents the calender after a date was selected.
* Furthermore the behavior of the popup is controlled.
*/
static void
day_selected (GtkCalendar *self, PicplannerOverview *overview)
{
(void) self;
GDateTime *date_selected;
GtkPopover *popover;
char *button_text;
date_selected = gtk_calendar_get_date (GTK_CALENDAR (overview->calendar));
/*
* Set text of the button to the selected date
*/
button_text = g_strdup_printf ("%d.%d.%d",
g_date_time_get_day_of_month (date_selected),
g_date_time_get_month (date_selected),
g_date_time_get_year (date_selected));
gtk_menu_button_set_label (GTK_MENU_BUTTON (overview->calendar_button),
button_text);
/*
* Close Popover after the day was selected
* TODO: Popdown happens automatically if a month is chosen which has less days then
* the day number previously selected.
*/
popover = GTK_POPOVER(overview->calendar_popover);
gtk_popover_popdown (popover);
g_free (button_text);
g_date_time_unref (date_selected);
}
static void
shumate_map_metric_imperial_scale (GSettings *settings,
gchar *key,
gpointer user_data)
{
(void) settings;
(void) key;
PicplannerOverview *overview = user_data;
ShumateScale *scale;
gboolean metric;
gboolean imperial;
scale = shumate_simple_map_get_scale (overview->map);
metric = g_settings_get_boolean (settings, "map-unit-metric");
imperial = g_settings_get_boolean (settings, "map-unit-imperial");
gtk_widget_set_visible (GTK_WIDGET (scale), TRUE);
if (metric && imperial)
shumate_scale_set_unit (scale, SHUMATE_UNIT_BOTH);
else if (metric)
shumate_scale_set_unit (scale, SHUMATE_UNIT_METRIC);
else if (imperial)
shumate_scale_set_unit (scale, SHUMATE_UNIT_IMPERIAL);
else
gtk_widget_set_visible (GTK_WIDGET (scale), FALSE);
}
static void
picplanner_overview_init (PicplannerOverview *overview)
{
GTimeZone *timezone;
ShumateMapSource *map_source;
ShumateMapSourceRegistry *registry;
gtk_widget_init_template (GTK_WIDGET (overview));
overview->settings = g_settings_new ("de.zwarf.picplanner");
/*
* Setting the date and time of the date and time selector to the current date and time
* with the timezone set in preferences
*/
timezone = g_time_zone_new_offset (g_settings_get_double (overview->settings, "time-zone") * 3600);
overview->date_time = g_date_time_new_now (timezone);
gtk_calendar_select_day (GTK_CALENDAR (overview->calendar), overview->date_time);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (overview->spin_button_hour),
g_date_time_get_hour (overview->date_time));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (overview->spin_button_minute),
g_date_time_get_minute (overview->date_time));
/*
* Initialise values necessary for displaying the map
*/
registry = shumate_map_source_registry_new_with_defaults ();
map_source = shumate_map_source_registry_get_by_id (registry, SHUMATE_MAP_SOURCE_OSM_MAPNIK);
overview->viewport = shumate_simple_map_get_viewport (overview->map);
shumate_map_metric_imperial_scale (overview->settings, NULL, overview);
shumate_map_source_set_license (map_source, "\xC2\xA9 OpenStreetMap Contributors");
shumate_simple_map_set_map_source (overview->map, map_source);
// Initialise drawing layers for the map
overview->pp_marker_center = picplanner_marker_new ();
g_object_ref (overview->pp_marker_center);
overview->pp_marker_milky_way = picplanner_marker_new ();
g_object_ref (overview->pp_marker_milky_way);
overview->pp_layer_milky_way = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_milky_way));
overview->pp_layer_milky_way_rise_set = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_milky_way_rise_set));
overview->pp_marker_moon = picplanner_marker_new ();
g_object_ref (overview->pp_marker_moon);
overview->pp_layer_moon = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_moon));
overview->pp_layer_moon_rise_set = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_moon_rise_set));
overview->pp_marker_sun = picplanner_marker_new ();
g_object_ref (overview->pp_marker_sun);
overview->pp_layer_sun_rise_set = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_sun_rise_set));
overview->pp_layer_sun = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_sun));
overview->pp_layer_center = picplanner_draw_layer_new (overview->viewport);
shumate_simple_map_add_overlay_layer (overview->map, SHUMATE_LAYER (overview->pp_layer_center));
/*
* Make all the bindings between widget properties and g_settings.
*/
g_settings_bind (overview->settings, "longitude",
overview->viewport, "longitude",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (overview->settings, "latitude",
overview->viewport, "latitude",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (overview->settings, "zoom-level",
overview->viewport, "zoom-level",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (overview->settings, "sun-visible",
overview->switch_sun, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (overview->settings, "moon-visible",
overview->switch_moon, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (overview->settings, "milky-way-visible",
overview->switch_milky_way, "active",
G_SETTINGS_BIND_DEFAULT);
/*
* Connect the signals which recognize user input.
* The user inputs are:
* Changes of: north coordinate, east coordinate, hour, minute and a date change in the calendar.
* The map is not treated seperately because the coordinates of the map are bound to the entry
* values above.
*/
g_signal_connect (G_OBJECT (overview->spin_button_hour),
"value-changed",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->spin_button_minute),
"value-changed",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->calendar),
"day-selected",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->viewport),
"notify::zoom-level",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->expander_date_time),
"notify::expanded",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->expander_basic_information),
"notify::expanded",
G_CALLBACK (emit_signal_changed),
overview);
g_signal_connect (G_OBJECT (overview->settings),
"changed::map-unit-metric",
G_CALLBACK (shumate_map_metric_imperial_scale),
overview);
g_signal_connect (G_OBJECT (overview->settings),
"changed::map-unit-imperial",
G_CALLBACK (shumate_map_metric_imperial_scale),
overview);
}
static void
picplanner_overview_class_init (PicplannerOverviewClass *class)
{
g_type_ensure (SHUMATE_TYPE_SIMPLE_MAP);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/de/zwarf/picplanner/window/overview-page/overview-view.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, calendar);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, calendar_popover);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, calendar_button);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, spin_button_hour);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, spin_button_minute);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, map);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, switch_sun);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, switch_moon);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, switch_milky_way);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_time_zone);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_sun_rise);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_sun_set);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_moon_rise);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_moon_set);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_milky_way_rise);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_milky_way_set);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_elevation_sun);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_elevation_moon);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_elevation_milky_way);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_azimuth_sun);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_azimuth_moon);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, label_azimuth_milky_way);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, expander_date_time);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PicplannerOverview, expander_basic_information);
gtk_widget_class_bind_template_callback (class, day_selected);
gtk_widget_class_bind_template_callback (class, time_spin_button_text);
/*
* Define the signal that is emitted if the user makes an input.
* The signal is emitted (in the change_date_time function) after a limiter
* that reduces the amount of signals that can be emitted in a specific time interval.
*/
signal_input_changed = g_signal_new ("input-changed",
G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE,
0);
signal_ui_changed = g_signal_new ("ui-changed",
G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE,
0);
}
PicplannerOverview *
picplanner_overview_new ()
{
return g_object_new (PICPLANNER_OVERVIEW_TYPE, NULL);
}