gtk/demos/gtk-demo/spinbutton.c
Matthias Clasen d732c869c2 gtk-demo: Add keywords to demos
Add the names of the main widgets as keywords to
our demos, but also things like "game". This helps
finding relevant demos in our growing list. You
can now for example type "label", and find the
"error states" and "links" demos showing GtkLabel
features.
2020-09-13 15:00:14 -04:00

245 lines
6.5 KiB
C

/* Spin Buttons
* #Keywords: GtkEntry
*
* GtkSpinButton provides convenient ways to input data
* that can be seen as a value in a range. The examples
* here show that this does not necessarily mean numeric
* values, and it can include custom formatting.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <math.h>
#include <stdlib.h>
int
spinbutton_hex_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
const char *buf;
char *err;
double res;
buf = gtk_editable_get_text (GTK_EDITABLE (spin_button));
res = strtol (buf, &err, 16);
*new_val = res;
if (*err)
return GTK_INPUT_ERROR;
else
return TRUE;
}
int
spinbutton_hex_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
char *buf;
double val;
adjustment = gtk_spin_button_get_adjustment (spin_button);
val = gtk_adjustment_get_value (adjustment);
if (fabs (val) < 1e-5)
buf = g_strdup ("0x00");
else
buf = g_strdup_printf ("0x%.2X", (int) val);
if (strcmp (buf, gtk_editable_get_text (GTK_EDITABLE (spin_button))))
gtk_editable_set_text (GTK_EDITABLE (spin_button), buf);
g_free (buf);
return TRUE;
}
int
spinbutton_time_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
const char *text;
char **str;
gboolean found = FALSE;
int hours;
int minutes;
char *endh;
char *endm;
text = gtk_editable_get_text (GTK_EDITABLE (spin_button));
str = g_strsplit (text, ":", 2);
if (g_strv_length (str) == 2)
{
hours = strtol (str[0], &endh, 10);
minutes = strtol (str[1], &endm, 10);
if (!*endh && !*endm &&
0 <= hours && hours < 24 &&
0 <= minutes && minutes < 60)
{
*new_val = hours * 60 + minutes;
found = TRUE;
}
}
g_strfreev (str);
if (!found)
{
*new_val = 0.0;
return GTK_INPUT_ERROR;
}
return TRUE;
}
int
spinbutton_time_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
char *buf;
double hours;
double minutes;
adjustment = gtk_spin_button_get_adjustment (spin_button);
hours = gtk_adjustment_get_value (adjustment) / 60.0;
minutes = (hours - floor (hours)) * 60.0;
buf = g_strdup_printf ("%02.0f:%02.0f", floor (hours), floor (minutes + 0.5));
if (strcmp (buf, gtk_editable_get_text (GTK_EDITABLE (spin_button))))
gtk_editable_set_text (GTK_EDITABLE (spin_button), buf);
g_free (buf);
return TRUE;
}
static const char *month[12] = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};
int
spinbutton_month_spin_input (GtkSpinButton *spin_button,
double *new_val)
{
int i;
char *tmp1, *tmp2;
gboolean found = FALSE;
for (i = 1; i <= 12; i++)
{
tmp1 = g_ascii_strup (month[i - 1], -1);
tmp2 = g_ascii_strup (gtk_editable_get_text (GTK_EDITABLE (spin_button)), -1);
if (strstr (tmp1, tmp2) == tmp1)
found = TRUE;
g_free (tmp1);
g_free (tmp2);
if (found)
break;
}
if (!found)
{
*new_val = 0.0;
return GTK_INPUT_ERROR;
}
*new_val = (double) i;
return TRUE;
}
int
spinbutton_month_spin_output (GtkSpinButton *spin_button)
{
GtkAdjustment *adjustment;
double value;
int i;
adjustment = gtk_spin_button_get_adjustment (spin_button);
value = gtk_adjustment_get_value (adjustment);
for (i = 1; i <= 12; i++)
if (fabs (value - (double)i) < 1e-5)
{
if (strcmp (month[i-1], gtk_editable_get_text (GTK_EDITABLE (spin_button))))
gtk_editable_set_text (GTK_EDITABLE (spin_button), month[i-1]);
}
return TRUE;
}
static gboolean
value_to_label (GBinding *binding,
const GValue *from,
GValue *to,
gpointer user_data)
{
g_value_take_string (to, g_strdup_printf ("%g", g_value_get_double (from)));
return TRUE;
}
GtkWidget *
do_spinbutton (GtkWidget *do_widget)
{
static GtkWidget *window;
if (!window)
{
GtkBuilder *builder;
GtkAdjustment *adj;
GtkWidget *label;
builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Spin Buttons");
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "basic_adjustment"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "basic_label"));
g_object_bind_property_full (adj, "value",
label, "label",
G_BINDING_SYNC_CREATE,
value_to_label,
NULL,
NULL, NULL);
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hex_adjustment"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "hex_label"));
g_object_bind_property_full (adj, "value",
label, "label",
G_BINDING_SYNC_CREATE,
value_to_label,
NULL,
NULL, NULL);
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "time_adjustment"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "time_label"));
g_object_bind_property_full (adj, "value",
label, "label",
G_BINDING_SYNC_CREATE,
value_to_label,
NULL,
NULL, NULL);
adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "month_adjustment"));
label = GTK_WIDGET (gtk_builder_get_object (builder, "month_label"));
g_object_bind_property_full (adj, "value",
label, "label",
G_BINDING_SYNC_CREATE,
value_to_label,
NULL,
NULL, NULL);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}