2010-09-27 19:18:17 -03:00
|
|
|
// ASE gui library
|
|
|
|
// Copyright (C) 2001-2010 David Capello
|
|
|
|
//
|
|
|
|
// This source file is ditributed under a BSD-like license, please
|
|
|
|
// read LICENSE.txt for more information.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-07-12 20:29:16 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
#include <allegro.h>
|
|
|
|
|
2010-09-26 15:59:32 -03:00
|
|
|
#include "gui/jfont.h"
|
|
|
|
#include "gui/jmanager.h"
|
|
|
|
#include "gui/jmessage.h"
|
|
|
|
#include "gui/jrect.h"
|
|
|
|
#include "gui/jsystem.h"
|
|
|
|
#include "gui/jtheme.h"
|
2010-10-02 11:19:09 -03:00
|
|
|
#include "gui/widget.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
typedef struct Slider
|
|
|
|
{
|
|
|
|
int min;
|
|
|
|
int max;
|
|
|
|
int value;
|
|
|
|
} Slider;
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
static int slider_press_x;
|
|
|
|
static int slider_press_value;
|
|
|
|
static int slider_press_left;
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
static bool slider_msg_proc(JWidget widget, JMessage msg);
|
|
|
|
static void slider_request_size(JWidget widget, int *w, int *h);
|
2008-02-29 19:29:49 +00:00
|
|
|
static void slider_setcursor(JWidget widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
JWidget jslider_new(int min, int max, int value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-01-26 00:38:05 +00:00
|
|
|
Widget* widget = new Widget(JI_SLIDER);
|
|
|
|
Slider* slider = jnew(Slider, 1);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
slider->min = min;
|
|
|
|
slider->max = max;
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(min, value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_add_hook(widget, JI_SLIDER, slider_msg_proc, slider);
|
2009-08-17 18:00:38 +00:00
|
|
|
jwidget_focusrest(widget, true);
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_init_theme(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
return widget;
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jslider_set_range(JWidget widget, int min, int max)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
slider->min = min;
|
|
|
|
slider->max = max;
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(min, slider->value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jslider_set_value(JWidget widget, int value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
int old_value = slider->value;
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
slider->value = MID(slider->min, value, slider->max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (slider->value != old_value)
|
2008-01-07 15:10:17 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
/* it DOES NOT emit CHANGE signal! to avoid recursive calls */
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
int jslider_get_value(JWidget widget)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
return slider->value;
|
|
|
|
}
|
|
|
|
|
2008-01-07 15:10:17 +00:00
|
|
|
void jtheme_slider_info(JWidget widget, int *min, int *max, int *value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (min) *min = slider->min;
|
|
|
|
if (max) *max = slider->max;
|
|
|
|
if (value) *value = slider->value;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
static bool slider_msg_proc(JWidget widget, JMessage msg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_DESTROY:
|
2007-11-28 14:19:36 +00:00
|
|
|
jfree(slider);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_REQSIZE:
|
2007-11-28 14:19:36 +00:00
|
|
|
slider_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2009-11-19 02:59:20 +00:00
|
|
|
|
|
|
|
case JM_DRAW:
|
|
|
|
widget->theme->draw_slider(widget, &msg->draw.rect);
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
case JM_FOCUSENTER:
|
|
|
|
case JM_FOCUSLEAVE:
|
2010-07-03 15:26:27 -03:00
|
|
|
if (widget->isEnabled())
|
2007-11-28 14:19:36 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONPRESSED:
|
2010-07-03 15:26:27 -03:00
|
|
|
if (!widget->isEnabled())
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-11-28 14:19:36 +00:00
|
|
|
|
2010-07-03 15:03:26 -03:00
|
|
|
widget->setSelected(true);
|
2010-04-25 12:03:25 -03:00
|
|
|
widget->captureMouse();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
slider_press_x = msg->mouse.x;
|
|
|
|
slider_press_value = slider->value;
|
|
|
|
slider_press_left = msg->mouse.left;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
|
|
|
slider_setcursor(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
/* continue to JM_MOTION */
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
case JM_MOTION:
|
2010-04-25 12:03:25 -03:00
|
|
|
if (widget->hasCapture()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
int value, accuracy, range;
|
2008-03-22 18:43:56 +00:00
|
|
|
JRect rc = jwidget_get_child_rect(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
range = slider->max - slider->min + 1;
|
|
|
|
|
|
|
|
/* with left click */
|
|
|
|
if (slider_press_left) {
|
2008-03-22 18:43:56 +00:00
|
|
|
value = slider->min + range * (msg->mouse.x - rc->x1) / jrect_w(rc);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
/* with right click */
|
|
|
|
else {
|
2008-03-22 18:43:56 +00:00
|
|
|
accuracy = MID(1, jrect_w(rc) / range, jrect_w(rc));
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
value = slider_press_value +
|
|
|
|
(msg->mouse.x - slider_press_x) / accuracy;
|
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
value = MID(slider->min, value, slider->max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
if (slider->value != value) {
|
2007-11-28 14:19:36 +00:00
|
|
|
jslider_set_value(widget, value);
|
|
|
|
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
/* for left click */
|
|
|
|
if (slider_press_left) {
|
|
|
|
int x = jmouse_x(0);
|
|
|
|
|
2008-03-22 18:43:56 +00:00
|
|
|
if (x < rc->x1-1)
|
|
|
|
x = rc->x1-1;
|
|
|
|
else if (x > rc->x2)
|
|
|
|
x = rc->x2;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
|
|
|
if (x != jmouse_x(0))
|
|
|
|
jmouse_set_position(x, jmouse_y(0));
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
/* for right click */
|
2008-03-22 18:43:56 +00:00
|
|
|
else if (jmouse_control_infinite_scroll(rc)) {
|
2007-09-26 19:34:06 +00:00
|
|
|
slider_press_x = jmouse_x(0);
|
2007-09-18 23:57:02 +00:00
|
|
|
slider_press_value = slider->value;
|
|
|
|
}
|
|
|
|
|
2008-03-22 18:43:56 +00:00
|
|
|
jrect_free(rc);
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONRELEASED:
|
2010-04-25 12:03:25 -03:00
|
|
|
if (widget->hasCapture()) {
|
2010-07-03 15:03:26 -03:00
|
|
|
widget->setSelected(false);
|
2010-04-25 12:03:25 -03:00
|
|
|
widget->releaseMouse();
|
2008-02-29 19:29:49 +00:00
|
|
|
slider_setcursor(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_MOUSEENTER:
|
|
|
|
case JM_MOUSELEAVE:
|
2007-11-28 14:19:36 +00:00
|
|
|
/* if (jwidget_is_enabled(widget) && */
|
|
|
|
/* jwidget_has_capture(widget)) { */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* /\* swap the select status *\/ */
|
2007-11-28 14:19:36 +00:00
|
|
|
/* if (jwidget_is_selected(widget)) */
|
|
|
|
/* jwidget_deselect(widget); */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* else */
|
2007-11-28 14:19:36 +00:00
|
|
|
/* jwidget_select(widget); */
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-12-04 21:50:31 +00:00
|
|
|
/* /\* TODO switch slider signal *\/ */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* } */
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
/* TODO theme stuff */
|
2010-07-03 15:26:27 -03:00
|
|
|
if (widget->isEnabled())
|
2007-11-28 14:19:36 +00:00
|
|
|
jwidget_dirty(widget);
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
case JM_KEYPRESSED:
|
2010-04-25 12:03:25 -03:00
|
|
|
if (widget->hasFocus()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
int min = slider->min;
|
|
|
|
int max = slider->max;
|
|
|
|
int value = slider->value;
|
|
|
|
|
|
|
|
switch (msg->key.scancode) {
|
2007-11-28 14:19:36 +00:00
|
|
|
case KEY_LEFT: value = MAX(value-1, min); break;
|
|
|
|
case KEY_RIGHT: value = MIN(value+1, max); break;
|
|
|
|
case KEY_PGDN: value = MAX(value-(max-min+1)/4, min); break;
|
|
|
|
case KEY_PGUP: value = MIN(value+(max-min+1)/4, max); break;
|
2007-09-18 23:57:02 +00:00
|
|
|
case KEY_HOME: value = min; break;
|
|
|
|
case KEY_END: value = max; break;
|
|
|
|
default:
|
2009-08-17 18:00:38 +00:00
|
|
|
return false;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (slider->value != value) {
|
2007-11-28 14:19:36 +00:00
|
|
|
jslider_set_value(widget, value);
|
|
|
|
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_WHEEL:
|
2010-07-03 15:26:27 -03:00
|
|
|
if (widget->isEnabled()) {
|
2007-09-26 19:34:06 +00:00
|
|
|
int value = slider->value + jmouse_z(0) - jmouse_z(1);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
value = MID(slider->min, value, slider->max);
|
|
|
|
|
|
|
|
if (slider->value != value) {
|
|
|
|
jslider_set_value(widget, value);
|
|
|
|
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
|
|
|
|
}
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
|
|
|
case JM_SETCURSOR:
|
|
|
|
slider_setcursor(widget);
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-08-17 18:00:38 +00:00
|
|
|
return false;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
static void slider_request_size(JWidget widget, int *w, int *h)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2008-09-30 21:01:54 +00:00
|
|
|
Slider* slider = reinterpret_cast<Slider*>(jwidget_get_data(widget, JI_SLIDER));
|
2007-09-18 23:57:02 +00:00
|
|
|
int min_w, max_w;
|
|
|
|
char buf[256];
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
usprintf(buf, "%d", slider->min);
|
2010-01-26 00:38:05 +00:00
|
|
|
min_w = ji_font_text_len(widget->getFont(), buf);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
usprintf(buf, "%d", slider->max);
|
2010-01-26 00:38:05 +00:00
|
|
|
max_w = ji_font_text_len(widget->getFont(), buf);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
*w = MAX(min_w, max_w);
|
2010-01-26 00:38:05 +00:00
|
|
|
*h = text_height(widget->getFont());
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
*w += widget->border_width.l + widget->border_width.r;
|
|
|
|
*h += widget->border_width.t + widget->border_width.b;
|
|
|
|
}
|
2008-02-29 19:29:49 +00:00
|
|
|
|
|
|
|
static void slider_setcursor(JWidget widget)
|
|
|
|
{
|
2010-04-25 12:03:25 -03:00
|
|
|
if (widget->hasCapture()) {
|
2008-02-29 19:29:49 +00:00
|
|
|
if (slider_press_left)
|
|
|
|
jmouse_set_cursor(JI_CURSOR_NORMAL);
|
|
|
|
else
|
|
|
|
jmouse_set_cursor(JI_CURSOR_SIZE_L);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
jmouse_set_cursor(JI_CURSOR_NORMAL);
|
|
|
|
}
|