picplanner/src/time-picker/time-picker.c

240 wiersze
7.3 KiB
C

/*
* time-picker.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/>.
*/
#include "time-picker.h"
struct _TimePicker
{
GtkBox parent_instance;
/* Time and date selector */
GtkWidget *label_time_zone;
GtkWidget *calendar;
GtkWidget *calendar_popover;
GtkWidget *calendar_button;
GtkWidget *spin_button_hour;
GtkWidget *spin_button_minute;
GtkWidget *time_button;
};
G_DEFINE_TYPE (TimePicker, time_picker, GTK_TYPE_BOX)
static guint signal_change;
void
time_picker_set_date_time (TimePicker *time_picker,
GDateTime *date_time)
{
gtk_calendar_select_day (GTK_CALENDAR (time_picker->calendar),
date_time);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (time_picker->spin_button_hour),
g_date_time_get_hour (date_time));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (time_picker->spin_button_minute),
g_date_time_get_minute (date_time));
}
void
time_picker_set_time_zone (TimePicker *time_picker,
double time_zone)
{
g_autofree char *char_time_zone = NULL;
char_time_zone = g_strdup_printf ("UTC %s%.1f", time_zone>=0 ? "+" : "", time_zone);
gtk_label_set_text (GTK_LABEL (time_picker->label_time_zone), char_time_zone);
}
int
time_picker_get_year (TimePicker *time_picker)
{
int year;
GDateTime *date_selected;
date_selected = gtk_calendar_get_date (GTK_CALENDAR (time_picker->calendar));
year = g_date_time_get_year (date_selected);
g_date_time_unref (date_selected);
return year;
}
int
time_picker_get_month (TimePicker *time_picker)
{
int month;
GDateTime *date_selected;
date_selected = gtk_calendar_get_date (GTK_CALENDAR (time_picker->calendar));
month = g_date_time_get_month (date_selected);
g_date_time_unref (date_selected);
return month;
}
int
time_picker_get_day (TimePicker *time_picker)
{
int day;
GDateTime *date_selected;
date_selected = gtk_calendar_get_date (GTK_CALENDAR (time_picker->calendar));
day = g_date_time_get_day_of_month (date_selected);
g_date_time_unref (date_selected);
return day;
}
int
time_picker_get_hour (TimePicker *time_picker)
{
int hour;
hour = gtk_spin_button_get_value (GTK_SPIN_BUTTON (time_picker->spin_button_hour));
return hour;
}
int
time_picker_get_minute (TimePicker *time_picker)
{
int minute;
minute = gtk_spin_button_get_value (GTK_SPIN_BUTTON (time_picker->spin_button_minute));
return minute;
}
static void
input_changed (GtkWidget *self,
TimePicker *time_picker)
{
(void) self;
char *time_button_text;
time_button_text = g_strdup_printf ("%02.f:%02.f",
gtk_spin_button_get_value (GTK_SPIN_BUTTON (time_picker->spin_button_hour)),
gtk_spin_button_get_value (GTK_SPIN_BUTTON (time_picker->spin_button_minute)));
gtk_menu_button_set_label (GTK_MENU_BUTTON (time_picker->time_button), time_button_text);
g_free (time_button_text);
g_signal_emit (time_picker,
signal_change,
0, NULL);
}
/*
* 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;
g_autofree char *button_text = NULL;
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);
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.
* TODO: combine with input_changed function
*/
static void
day_selected (GtkCalendar *self,
TimePicker *time_picker)
{
g_autoptr (GDateTime) date_selected = NULL;
g_autofree char *button_text = NULL;
(void) self;
date_selected = gtk_calendar_get_date (GTK_CALENDAR (time_picker->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 (time_picker->calendar_button),
button_text);
input_changed (GTK_WIDGET (self), time_picker);
}
static void
time_picker_init (TimePicker *time_picker)
{
gtk_widget_init_template (GTK_WIDGET (time_picker));
g_signal_connect (G_OBJECT (time_picker->spin_button_hour),
"value-changed",
G_CALLBACK (input_changed),
time_picker);
g_signal_connect (G_OBJECT (time_picker->spin_button_minute),
"value-changed",
G_CALLBACK (input_changed),
time_picker);
g_signal_connect (G_OBJECT (time_picker->calendar),
"day-selected",
G_CALLBACK (day_selected),
time_picker);
}
static void
time_picker_class_init (TimePickerClass *class)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
gtk_widget_class_set_template_from_resource (widget_class,
"/de/zwarf/picplanner/time-picker/time-picker.ui");
gtk_widget_class_bind_template_child (widget_class, TimePicker, label_time_zone);
gtk_widget_class_bind_template_child (widget_class, TimePicker, calendar);
gtk_widget_class_bind_template_child (widget_class, TimePicker, calendar_popover);
gtk_widget_class_bind_template_child (widget_class, TimePicker, calendar_button);
gtk_widget_class_bind_template_child (widget_class, TimePicker, spin_button_hour);
gtk_widget_class_bind_template_child (widget_class, TimePicker, spin_button_minute);
gtk_widget_class_bind_template_child (widget_class, TimePicker, time_button);
gtk_widget_class_bind_template_callback (widget_class, day_selected);
gtk_widget_class_bind_template_callback (widget_class, time_spin_button_text);
signal_change = g_signal_new ("date_time_changed",
G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
G_TYPE_NONE,
0);
}
TimePicker *
time_picker_new (void)
{
return g_object_new (TIME_PICKER_TYPE, NULL);
}