#include "osgui_gtk.inl"
#include "oscontrol_gtk.inl"
#include "ospanel_gtk.inl"
#include "oswindow_gtk.inl"
#include "../osslider.h"
#include "../osslider.inl"
#include "../osgui.inl"
#include <core/event.h>
#include <core/heap.h>
#include <sewer/cassert.h>
#if !defined(__GTK3__)
#error This file is only for GTK Toolkit
#endif
struct _osslider_t
{
OSControl control;
gui_size_t size;
bool_t launch_event;
bool_t discrete;
uint32_t flags;
Listener *OnMoved;
};
static gboolean i_OnMoved(GtkRange *range, GtkScrollType step, double value, OSSlider *slider)
{
cassert_unref(slider->control.widget == GTK_WIDGET(range), range);
unref(step);
if (slider->launch_event == TRUE && slider->OnMoved != NULL)
{
EvSlider params;
params.pos = value;
params.incr = 0.f;
params.step = UINT32_MAX;
if (value < 0)
params.pos = 0;
else if (value > 1)
params.pos = 1;
listener_event(slider->OnMoved, ekGUI_EVENT_SLIDER, slider, ¶ms, NULL, OSSlider, EvSlider, void);
return slider->discrete;
}
return FALSE;
}
static gboolean i_OnPressed(GtkWidget *widget, GdkEvent *event, OSSlider *slider)
{
cassert_no_null(slider);
unref(widget);
unref(event);
if (_oswindow_mouse_down(cast(slider, OSControl)) == TRUE)
return FALSE;
return TRUE;
}
OSSlider *osslider_create(const uint32_t flags)
{
OSSlider *slider = heap_new0(OSSlider);
GtkOrientation o = slider_get_type(flags) == ekSLIDER_HORZ ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
GtkWidget *widget = gtk_scale_new_with_range(o, 0., 1., 0.1);
gtk_scale_set_draw_value(GTK_SCALE(widget), FALSE);
gtk_range_set_increments(GTK_RANGE(widget), .1, .1);
g_signal_connect(widget, "button-press-event", G_CALLBACK(i_OnPressed), (gpointer)slider);
g_signal_connect(widget, "change-value", G_CALLBACK(i_OnMoved), (gpointer)slider);
_oscontrol_init(&slider->control, ekGUI_TYPE_SLIDER, widget, widget, TRUE);
slider->size = ENUM_MAX(gui_size_t);
slider->flags = flags;
slider->launch_event = TRUE;
slider->discrete = FALSE;
return slider;
}
void osslider_destroy(OSSlider **slider)
{
cassert_no_null(slider);
cassert_no_null(*slider);
listener_destroy(&(*slider)->OnMoved);
_oscontrol_destroy(*dcast(slider, OSControl));
heap_delete(slider, OSSlider);
}
void osslider_OnMoved(OSSlider *slider, Listener *listener)
{
cassert_no_null(slider);
listener_update(&slider->OnMoved, listener);
}
void osslider_tooltip(OSSlider *slider, const char_t *text)
{
cassert_no_null(slider);
gtk_widget_set_tooltip_text(slider->control.widget, (const gchar *)text);
}
void osslider_tickmarks(OSSlider *slider, const uint32_t num_tickmarks, const bool_t tickmarks_at_left_top)
{
gdouble steps = 0.1;
cassert_no_null(slider);
cassert(num_tickmarks > 1);
if (num_tickmarks != UINT32_MAX)
{
steps = 1. / (num_tickmarks - 1.);
slider->discrete = TRUE;
}
else
{
slider->discrete = FALSE;
}
gtk_range_set_increments(GTK_RANGE(slider->control.widget), steps, steps);
unref(tickmarks_at_left_top);
}
void osslider_position(OSSlider *slider, const real32_t position)
{
cassert_no_null(slider);
slider->launch_event = FALSE;
gtk_range_set_value(GTK_RANGE(slider->control.widget), (gdouble)position);
slider->launch_event = TRUE;
}
real32_t osslider_get_position(const OSSlider *slider)
{
cassert_no_null(slider);
return (real32_t)gtk_range_get_value(GTK_RANGE(slider->control.widget));
}
void osslider_bounds(const OSSlider *slider, const real32_t length, const gui_size_t knob_size, real32_t *width, real32_t *height)
{
GtkRequisition s;
cassert_no_null(slider);
cassert_no_null(width);
cassert_no_null(height);
cassert_unref(knob_size == ekGUI_SIZE_REGULAR, knob_size);
gtk_widget_get_preferred_size(slider->control.widget, &s, NULL);
switch (slider_get_type(slider->flags))
{
case ekSLIDER_HORZ:
*width = length;
*height = (real32_t)s.height;
break;
case ekSLIDER_VERT:
*width = (real32_t)s.width;
*height = length;
break;
cassert_default();
}
}
void osslider_attach(OSSlider *slider, OSPanel *panel)
{
_ospanel_attach_control(panel, cast(slider, OSControl));
}
void osslider_detach(OSSlider *slider, OSPanel *panel)
{
_ospanel_detach_control(panel, cast(slider, OSControl));
}
void osslider_visible(OSSlider *slider, const bool_t visible)
{
_oscontrol_set_visible(cast(slider, OSControl), visible);
}
void osslider_enabled(OSSlider *slider, const bool_t enabled)
{
_oscontrol_set_enabled(cast(slider, OSControl), enabled);
}
void osslider_size(const OSSlider *slider, real32_t *width, real32_t *height)
{
_oscontrol_get_size(cast_const(slider, OSControl), width, height);
}
void osslider_origin(const OSSlider *slider, real32_t *x, real32_t *y)
{
_oscontrol_get_origin(cast_const(slider, OSControl), x, y);
}
void osslider_frame(OSSlider *slider, const real32_t x, const real32_t y, const real32_t width, const real32_t height)
{
_oscontrol_set_frame(cast(slider, OSControl), x, y, width, height);
}