Further GTK+ date/time picker refinement and bugfixes.
This commit is contained in:
parent
8b7d661405
commit
f0dc52d1dc
|
@ -8,3 +8,5 @@
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
|
|
||||||
extern GtkWidget *newDTP(void);
|
extern GtkWidget *newDTP(void);
|
||||||
|
extern GtkWidget *newDP(void);
|
||||||
|
extern GtkWidget *newTP(void);
|
||||||
|
|
|
@ -18,6 +18,9 @@ struct dateTimePickerWidget {
|
||||||
|
|
||||||
gulong toggledSignal;
|
gulong toggledSignal;
|
||||||
|
|
||||||
|
gboolean hasTime;
|
||||||
|
gboolean hasDate;
|
||||||
|
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GtkWidget *box;
|
GtkWidget *box;
|
||||||
GtkWidget *calendar;
|
GtkWidget *calendar;
|
||||||
|
@ -45,32 +48,42 @@ static int realSpinValue(GtkSpinButton *spinButton)
|
||||||
return (int) gtk_adjustment_get_value(adj);
|
return (int) gtk_adjustment_get_value(adj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO switch to GDateTime?
|
static GDateTime *selected(dateTimePickerWidget *d)
|
||||||
|
{
|
||||||
|
// choose a day for which all times are likely to be valid for the default date in case we're only dealing with time
|
||||||
|
guint year = 1970, month = 1, day = 1;
|
||||||
|
guint hour = 0, minute = 0, second = 0;
|
||||||
|
|
||||||
|
if (d->hasDate)
|
||||||
|
gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day);
|
||||||
|
if (d->hasTime) {
|
||||||
|
hour = realSpinValue(GTK_SPIN_BUTTON(d->hours));
|
||||||
|
if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0)
|
||||||
|
hour += 12;
|
||||||
|
minute = realSpinValue(GTK_SPIN_BUTTON(d->minutes));
|
||||||
|
second = realSpinValue(GTK_SPIN_BUTTON(d->seconds));
|
||||||
|
}
|
||||||
|
return g_date_time_new_local(year, month, day, hour, minute, second);
|
||||||
|
}
|
||||||
|
|
||||||
static void setLabel(dateTimePickerWidget *d)
|
static void setLabel(dateTimePickerWidget *d)
|
||||||
{
|
{
|
||||||
guint year, month, day;
|
GDateTime *dt;
|
||||||
struct tm tm;
|
const char *fmt;
|
||||||
time_t tt;
|
char *msg;
|
||||||
gchar *str;
|
|
||||||
|
|
||||||
gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day);
|
dt = selected(d);
|
||||||
tm.tm_hour = realSpinValue(GTK_SPIN_BUTTON(d->hours));
|
// TODO switch to D_FMT + " " + T_FMT?
|
||||||
if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0)
|
if (d->hasDate && d->hasTime)
|
||||||
tm.tm_hour += 12;
|
fmt = nl_langinfo(D_T_FMT);
|
||||||
tm.tm_min = realSpinValue(GTK_SPIN_BUTTON(d->minutes));
|
else if (d->hasDate)
|
||||||
tm.tm_sec = realSpinValue(GTK_SPIN_BUTTON(d->seconds));
|
fmt = nl_langinfo(D_FMT);
|
||||||
tm.tm_mon = month;
|
else
|
||||||
tm.tm_mday = day;
|
fmt = nl_langinfo(T_FMT);
|
||||||
tm.tm_year = year - 1900;
|
msg = g_date_time_format(dt, fmt);
|
||||||
tm.tm_isdst = -1; // not available
|
gtk_button_set_label(GTK_BUTTON(d), msg);
|
||||||
// fill in the missing fields
|
g_free(msg);
|
||||||
tt = mktime(&tm);
|
g_date_time_unref(dt);
|
||||||
tm = *localtime(&tt);
|
|
||||||
// and strip the newline
|
|
||||||
str = g_strdup(asctime(&tm));
|
|
||||||
str[strlen(str) - 1] = '\0';
|
|
||||||
gtk_button_set_label(GTK_BUTTON(d), str);
|
|
||||||
g_free(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dateTimeChanged(dateTimePickerWidget *d)
|
static void dateTimeChanged(dateTimePickerWidget *d)
|
||||||
|
@ -279,6 +292,7 @@ static gboolean zeroPadSpinbox(GtkSpinButton *sb, gpointer data)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this is really hacky but we can't use GtkCombobox here :(
|
||||||
static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data)
|
static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data)
|
||||||
{
|
{
|
||||||
double *out = (double *) ptr;
|
double *out = (double *) ptr;
|
||||||
|
@ -286,13 +300,14 @@ static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data)
|
||||||
char firstAM, firstPM;
|
char firstAM, firstPM;
|
||||||
|
|
||||||
text = gtk_entry_get_text(GTK_ENTRY(sb));
|
text = gtk_entry_get_text(GTK_ENTRY(sb));
|
||||||
firstAM = nl_langinfo(AM_STR)[0];
|
// TODO don't use ASCII here for case insensitivity
|
||||||
firstPM = nl_langinfo(PM_STR)[0];
|
firstAM = g_ascii_tolower(nl_langinfo(AM_STR)[0]);
|
||||||
|
firstPM = g_ascii_tolower(nl_langinfo(PM_STR)[0]);
|
||||||
for (; *text != '\0'; text++)
|
for (; *text != '\0'; text++)
|
||||||
if (*text == firstAM) {
|
if (g_ascii_tolower(*text) == firstAM) {
|
||||||
*out = 0;
|
*out = 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else if (*text == firstPM) {
|
} else if (g_ascii_tolower(*text) == firstPM) {
|
||||||
*out = 1;
|
*out = 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +356,21 @@ static void dateChanged(GtkCalendar *c, gpointer data)
|
||||||
dateTimeChanged(d);
|
dateTimeChanged(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setDateOnly(dateTimePickerWidget *d)
|
||||||
|
{
|
||||||
|
d->hasTime = FALSE;
|
||||||
|
gtk_container_remove(GTK_CONTAINER(d->box), d->timebox);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setTimeOnly(dateTimePickerWidget *d)
|
||||||
|
{
|
||||||
|
d->hasDate = FALSE;
|
||||||
|
gtk_container_remove(GTK_CONTAINER(d->box), d->calendar);
|
||||||
|
}
|
||||||
|
|
||||||
static void dateTimePickerWidget_init(dateTimePickerWidget *d)
|
static void dateTimePickerWidget_init(dateTimePickerWidget *d)
|
||||||
{
|
{
|
||||||
|
// TODO give a more pronounced shadow
|
||||||
d->window = gtk_window_new(GTK_WINDOW_POPUP);
|
d->window = gtk_window_new(GTK_WINDOW_POPUP);
|
||||||
gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE);
|
gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE);
|
||||||
gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d));
|
gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d));
|
||||||
|
@ -405,6 +433,9 @@ static void dateTimePickerWidget_init(dateTimePickerWidget *d)
|
||||||
d->keyboard = NULL;
|
d->keyboard = NULL;
|
||||||
d->mouse = NULL;
|
d->mouse = NULL;
|
||||||
|
|
||||||
|
d->hasTime = TRUE;
|
||||||
|
d->hasDate = TRUE;
|
||||||
|
|
||||||
// TODO set current time to now
|
// TODO set current time to now
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,3 +464,23 @@ GtkWidget *newDTP(void)
|
||||||
setLabel(dateTimePickerWidget(w));
|
setLabel(dateTimePickerWidget(w));
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GtkWidget *newDP(void)
|
||||||
|
{
|
||||||
|
GtkWidget *w;
|
||||||
|
|
||||||
|
w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL));
|
||||||
|
setDateOnly(dateTimePickerWidget(w));
|
||||||
|
setLabel(dateTimePickerWidget(w));
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *newTP(void)
|
||||||
|
{
|
||||||
|
GtkWidget *w;
|
||||||
|
|
||||||
|
w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL));
|
||||||
|
setTimeOnly(dateTimePickerWidget(w));
|
||||||
|
setLabel(dateTimePickerWidget(w));
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ int main(void)
|
||||||
gtk_container_add(GTK_CONTAINER(mainwin), box);
|
gtk_container_add(GTK_CONTAINER(mainwin), box);
|
||||||
button = newDTP();
|
button = newDTP();
|
||||||
gtk_container_add(GTK_CONTAINER(box), button);
|
gtk_container_add(GTK_CONTAINER(box), button);
|
||||||
|
button = newDP();
|
||||||
|
gtk_container_add(GTK_CONTAINER(box), button);
|
||||||
|
button = newTP();
|
||||||
|
gtk_container_add(GTK_CONTAINER(box), button);
|
||||||
gtk_container_add(GTK_CONTAINER(box), gtk_entry_new());
|
gtk_container_add(GTK_CONTAINER(box), gtk_entry_new());
|
||||||
|
|
||||||
gtk_widget_show_all(mainwin);
|
gtk_widget_show_all(mainwin);
|
||||||
|
|
Loading…
Reference in New Issue