Compare commits
1 Commits
rounded-re
...
range-sele
Author | SHA1 | Date | |
---|---|---|---|
|
aa4af4c946 |
@@ -1,5 +1,6 @@
|
||||
gtk_tests = [
|
||||
# testname, optional extra sources
|
||||
['testrange'],
|
||||
['testdropdown'],
|
||||
['rendernode'],
|
||||
['rendernode-create-tests'],
|
||||
|
658
tests/testrange.c
Normal file
658
tests/testrange.c
Normal file
@@ -0,0 +1,658 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (DemoSlider, demo_slider, DEMO, SLIDER, GtkWidget)
|
||||
|
||||
struct _DemoSlider
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
};
|
||||
|
||||
struct _DemoSliderClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (DemoHighlight, demo_highlight, DEMO, HIGHLIGHT, GtkWidget)
|
||||
|
||||
struct _DemoHighlight
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
};
|
||||
|
||||
struct _DemoHighlightClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (DemoTrough, demo_trough, DEMO, TROUGH, GtkWidget)
|
||||
|
||||
struct _DemoTrough
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
};
|
||||
|
||||
struct _DemoTroughClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
|
||||
|
||||
struct _DemoWidget
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *trough;
|
||||
GtkWidget *highlight;
|
||||
GtkWidget *min_slider;
|
||||
GtkWidget *max_slider;
|
||||
|
||||
GtkWidget *grab_location;
|
||||
|
||||
double range_min;
|
||||
double range_max;
|
||||
double min_value;
|
||||
double max_value;
|
||||
|
||||
gboolean shift;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_RANGE_MIN = 1,
|
||||
PROP_RANGE_MAX,
|
||||
PROP_MIN_VALUE,
|
||||
PROP_MAX_VALUE,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
|
||||
|
||||
struct _DemoWidgetClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (DemoSlider, demo_slider, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
demo_slider_init (DemoSlider *slider)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
demo_slider_class_init (DemoSliderClass *class)
|
||||
{
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "slider");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
demo_slider_new (void)
|
||||
{
|
||||
return g_object_new (demo_slider_get_type (), NULL);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (DemoHighlight, demo_highlight, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
demo_highlight_init (DemoHighlight *highlight)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
demo_highlight_class_init (DemoHighlightClass *class)
|
||||
{
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "highlight");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
demo_highlight_new (void)
|
||||
{
|
||||
return g_object_new (demo_highlight_get_type (), NULL);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (DemoTrough, demo_trough, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
demo_trough_init (DemoTrough *trough)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
demo_trough_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (gtk_widget_get_parent (widget));
|
||||
int min1, nat1;
|
||||
int min2, nat2;
|
||||
int min3, nat3;
|
||||
|
||||
gtk_widget_measure (demo->min_slider,
|
||||
orientation, -1,
|
||||
&min1, &nat1,
|
||||
NULL, NULL);
|
||||
|
||||
gtk_widget_measure (demo->max_slider,
|
||||
orientation, -1,
|
||||
&min2, &nat2,
|
||||
NULL, NULL);
|
||||
|
||||
gtk_widget_measure (demo->highlight,
|
||||
orientation, for_size,
|
||||
&min3, &nat3,
|
||||
NULL, NULL);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
||||
{
|
||||
*minimum = MAX (min1 + min2, min3);
|
||||
*natural = MAX (nat1 + nat2, nat3);
|
||||
}
|
||||
else
|
||||
{
|
||||
*minimum = MAX (MAX (min1, min2), min3);
|
||||
*natural = MAX (MAX (nat1, nat2), min3);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
allocate_slider (DemoWidget *demo,
|
||||
GtkWidget *slider,
|
||||
int x)
|
||||
{
|
||||
int trough_height;
|
||||
int width, height;
|
||||
int y;
|
||||
|
||||
gtk_widget_measure (slider,
|
||||
GTK_ORIENTATION_HORIZONTAL, -1,
|
||||
&width, NULL,
|
||||
NULL, NULL);
|
||||
gtk_widget_measure (slider,
|
||||
GTK_ORIENTATION_VERTICAL, -1,
|
||||
&height, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
trough_height = gtk_widget_get_height (demo->trough);
|
||||
|
||||
y = floor ((trough_height - height) / 2);
|
||||
|
||||
gtk_widget_size_allocate (slider,
|
||||
&(GtkAllocation) { x, y, width, height},
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_trough_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (gtk_widget_get_parent (widget));
|
||||
int min, max;
|
||||
|
||||
min = floor (width * (demo->min_value - demo->range_min) / (demo->range_max - demo->range_min));
|
||||
max = floor (width * (demo->max_value - demo->range_min) / (demo->range_max - demo->range_min));
|
||||
|
||||
allocate_slider (demo, demo->min_slider, min);
|
||||
allocate_slider (demo, demo->max_slider, max);
|
||||
|
||||
gtk_widget_size_allocate (demo->highlight,
|
||||
&(GtkAllocation) { min, 0, max - min, height},
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_trough_class_init (DemoTroughClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
widget_class->measure = demo_trough_measure;
|
||||
widget_class->size_allocate = demo_trough_size_allocate;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "trough");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
demo_trough_new (void)
|
||||
{
|
||||
return g_object_new (demo_trough_get_type (), NULL);
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE (DemoWidget, demo_widget, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
click_gesture_pressed (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoWidget *demo)
|
||||
{
|
||||
guint button;
|
||||
GdkModifierType state;
|
||||
|
||||
demo->grab_location = gtk_widget_pick (GTK_WIDGET (demo), x, y, 0);
|
||||
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
demo->shift = (button == GDK_BUTTON_PRIMARY && ((state & GDK_SHIFT_MASK) != 0)) ||
|
||||
button == GDK_BUTTON_SECONDARY;
|
||||
}
|
||||
|
||||
static void
|
||||
click_gesture_released (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoWidget *demo)
|
||||
{
|
||||
demo->grab_location = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_gesture_begin (GtkGestureDrag *gesture,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
DemoWidget *demo)
|
||||
{
|
||||
if (demo->grab_location == demo->min_slider ||
|
||||
demo->grab_location == demo->max_slider)
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_gesture_update (GtkGestureDrag *gesture,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
DemoWidget *demo)
|
||||
{
|
||||
double start_x, start_y;
|
||||
int width;
|
||||
double value;
|
||||
double size;
|
||||
|
||||
gtk_gesture_drag_get_start_point (gesture, &start_x, &start_y);
|
||||
|
||||
width = gtk_widget_get_width (GTK_WIDGET (demo));
|
||||
|
||||
value = ((start_x + offset_x) / width) * (demo->range_max - demo->range_min) + demo->range_min;
|
||||
value = CLAMP (value, demo->range_min, demo->range_max);
|
||||
size = demo->max_value - demo->min_value;
|
||||
|
||||
if (demo->shift)
|
||||
{
|
||||
if (demo->grab_location == demo->min_slider)
|
||||
{
|
||||
demo->max_value = MIN (demo->range_max, value + size);
|
||||
demo->min_value = demo->max_value - size;
|
||||
}
|
||||
else if (demo->grab_location == demo->max_slider)
|
||||
{
|
||||
demo->min_value = MAX (demo->range_min, value - size);
|
||||
demo->max_value = demo->min_value + size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (demo->grab_location == demo->min_slider)
|
||||
{
|
||||
demo->min_value = value;
|
||||
demo->max_value = MAX (demo->max_value, value);
|
||||
}
|
||||
else if (demo->grab_location == demo->max_slider)
|
||||
{
|
||||
demo->min_value = MIN (demo->min_value, value);
|
||||
demo->max_value = value;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MIN_VALUE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MAX_VALUE]);
|
||||
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (demo));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_init (DemoWidget *demo)
|
||||
{
|
||||
GtkGesture *click_gesture, *drag_gesture;
|
||||
|
||||
demo->range_min = 0;
|
||||
demo->range_max = 0;
|
||||
demo->min_value = 0;
|
||||
demo->max_value = 0;
|
||||
|
||||
demo->trough = demo_trough_new ();
|
||||
gtk_widget_set_parent (demo->trough, GTK_WIDGET (demo));
|
||||
demo->highlight = demo_highlight_new ();
|
||||
gtk_widget_set_parent (demo->highlight, demo->trough);
|
||||
demo->min_slider = demo_slider_new ();
|
||||
gtk_widget_set_parent (demo->min_slider, demo->trough);
|
||||
demo->max_slider = demo_slider_new ();
|
||||
gtk_widget_set_parent (demo->max_slider, demo->trough);
|
||||
|
||||
drag_gesture = gtk_gesture_drag_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag_gesture), 0);
|
||||
g_signal_connect (drag_gesture, "drag-begin", G_CALLBACK (drag_gesture_begin), demo);
|
||||
g_signal_connect (drag_gesture, "drag-update", G_CALLBACK (drag_gesture_update), demo);
|
||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (drag_gesture));
|
||||
|
||||
click_gesture = gtk_gesture_click_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (click_gesture), 0);
|
||||
g_signal_connect (click_gesture, "pressed", G_CALLBACK (click_gesture_pressed), demo);
|
||||
g_signal_connect (click_gesture, "released", G_CALLBACK (click_gesture_released), demo);
|
||||
gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (click_gesture));
|
||||
|
||||
gtk_gesture_group (click_gesture, drag_gesture);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (widget);
|
||||
|
||||
gtk_widget_measure (demo->trough,
|
||||
orientation, -1,
|
||||
minimum, natural,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (widget);
|
||||
int min_height;
|
||||
|
||||
gtk_widget_measure (demo->trough,
|
||||
GTK_ORIENTATION_VERTICAL, -1,
|
||||
&min_height, NULL,
|
||||
NULL, NULL);
|
||||
|
||||
gtk_widget_size_allocate (demo->trough,
|
||||
&(GtkAllocation) { 0, 0, width, min_height},
|
||||
-1);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_dispose (GObject *object)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (object);
|
||||
|
||||
g_clear_pointer (&demo->trough, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (demo_widget_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_set_range (DemoWidget *demo,
|
||||
double range_min,
|
||||
double range_max)
|
||||
{
|
||||
double value;
|
||||
|
||||
g_return_if_fail (range_min <= range_max);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (demo));
|
||||
|
||||
if (demo->range_min != range_min)
|
||||
{
|
||||
demo->range_min = range_min;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_RANGE_MIN]);
|
||||
}
|
||||
|
||||
if (demo->range_max != range_max)
|
||||
{
|
||||
demo->range_max = range_max;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_RANGE_MAX]);
|
||||
}
|
||||
|
||||
value = CLAMP (demo->min_value, range_min, range_max);
|
||||
if (demo->min_value != value)
|
||||
{
|
||||
demo->min_value = value;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MIN_VALUE]);
|
||||
}
|
||||
|
||||
value = CLAMP (demo->max_value, range_min, range_max);
|
||||
if (demo->max_value != value)
|
||||
{
|
||||
demo->max_value = value;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MAX_VALUE]);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (demo));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_set_values (DemoWidget *demo,
|
||||
double min_value,
|
||||
double max_value)
|
||||
{
|
||||
double value;
|
||||
|
||||
g_return_if_fail (min_value <= max_value);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (demo));
|
||||
|
||||
value = CLAMP (min_value, demo->range_min, demo->range_max);
|
||||
if (demo->min_value != value)
|
||||
{
|
||||
demo->min_value = value;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MIN_VALUE]);
|
||||
}
|
||||
|
||||
value = CLAMP (max_value, demo->range_min, demo->range_max);
|
||||
if (demo->max_value != value)
|
||||
{
|
||||
demo->max_value = value;
|
||||
g_object_notify_by_pspec (G_OBJECT (demo), properties[PROP_MAX_VALUE]);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (demo));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (object);
|
||||
double v;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_RANGE_MIN:
|
||||
v = g_value_get_double (value);
|
||||
demo_widget_set_range (demo, v, MAX (v, demo->range_max));
|
||||
break;
|
||||
|
||||
case PROP_RANGE_MAX:
|
||||
v = g_value_get_double (value);
|
||||
demo_widget_set_range (demo, MIN (v, demo->range_min), v);
|
||||
break;
|
||||
|
||||
case PROP_MIN_VALUE:
|
||||
v = g_value_get_double (value);
|
||||
demo_widget_set_values (demo, v, MAX (v, demo->max_value));
|
||||
break;
|
||||
|
||||
case PROP_MAX_VALUE:
|
||||
v = g_value_get_double (value);
|
||||
demo_widget_set_values (demo, MIN (v, demo->min_value), v);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_RANGE_MIN:
|
||||
g_value_set_double (value, demo->range_min);
|
||||
break;
|
||||
|
||||
case PROP_RANGE_MAX:
|
||||
g_value_set_double (value, demo->range_max);
|
||||
break;
|
||||
|
||||
case PROP_MIN_VALUE:
|
||||
g_value_set_double (value, demo->min_value);
|
||||
break;
|
||||
|
||||
case PROP_MAX_VALUE:
|
||||
g_value_set_double (value, demo->max_value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_widget_class_init (DemoWidgetClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo_widget_dispose;
|
||||
object_class->set_property = demo_widget_set_property;
|
||||
object_class->get_property = demo_widget_get_property;
|
||||
|
||||
widget_class->measure = demo_widget_measure;
|
||||
widget_class->size_allocate = demo_widget_size_allocate;
|
||||
|
||||
properties[PROP_RANGE_MIN] = g_param_spec_double ("range-min",
|
||||
"Range Min",
|
||||
"Range Min",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_RANGE_MAX] = g_param_spec_double ("range-max",
|
||||
"Range Max",
|
||||
"Range Max",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_MIN_VALUE] = g_param_spec_double ("min-value",
|
||||
"Min Value",
|
||||
"Min Value",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0,
|
||||
G_PARAM_READWRITE);
|
||||
properties[PROP_MAX_VALUE] = g_param_spec_double ("max-value",
|
||||
"Max Value",
|
||||
"Max Value",
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "scale");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
demo_widget_new (void)
|
||||
{
|
||||
return g_object_new (demo_widget_get_type (), NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
update_range_label (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (object);
|
||||
|
||||
if (pspec->name == g_intern_static_string ("range-min") ||
|
||||
pspec->name == g_intern_static_string ("range-max"))
|
||||
{
|
||||
char *text;
|
||||
|
||||
text = g_strdup_printf ("Allowed values: [%.1f, %.1f]\n", demo->range_min, demo->range_max);
|
||||
gtk_label_set_label (GTK_LABEL (data), text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_values_label (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
DemoWidget *demo = DEMO_WIDGET (object);
|
||||
|
||||
if (pspec->name == g_intern_static_string ("min-value") ||
|
||||
pspec->name == g_intern_static_string ("max-value"))
|
||||
{
|
||||
char *text;
|
||||
|
||||
text = g_strdup_printf ("Selected range: [%.1f, %.1f]\n", demo->min_value, demo->max_value);
|
||||
gtk_label_set_label (GTK_LABEL (data), text);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWindow *window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *demo;
|
||||
GtkWidget *label;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
window = GTK_WINDOW (gtk_window_new ());
|
||||
gtk_window_set_title (window, "Pick a range");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_window_set_child (window, box);
|
||||
|
||||
demo = demo_widget_new ();
|
||||
gtk_widget_set_halign (demo, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (demo, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_hexpand (demo, TRUE);
|
||||
|
||||
gtk_box_append (GTK_BOX (box), demo);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
g_signal_connect (demo, "notify", G_CALLBACK (update_range_label), label);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
g_signal_connect (demo, "notify", G_CALLBACK (update_values_label), label);
|
||||
gtk_box_append (GTK_BOX (box), label);
|
||||
|
||||
demo_widget_set_range (DEMO_WIDGET (demo), 0, 1000);
|
||||
demo_widget_set_values (DEMO_WIDGET (demo), 100, 500);
|
||||
|
||||
gtk_window_present (window);
|
||||
|
||||
while (g_list_model_get_n_items (gtk_window_get_toplevels ()) > 0)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user