aseprite/src/gui/slider.cpp

282 lines
6.4 KiB
C++
Raw Normal View History

// 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>
#include "gui/jfont.h"
#include "gui/jmanager.h"
#include "gui/jmessage.h"
#include "gui/jrect.h"
#include "gui/jsystem.h"
#include "gui/jtheme.h"
#include "gui/widget.h"
2007-09-18 23:57:02 +00:00
typedef struct Slider
{
int min;
int max;
int value;
} Slider;
static int slider_press_x;
static int slider_press_value;
static int slider_press_left;
static bool slider_msg_proc(JWidget widget, JMessage msg);
static void slider_request_size(JWidget widget, int *w, int *h);
static void slider_setcursor(JWidget widget);
2007-09-18 23:57:02 +00:00
JWidget jslider_new(int min, int max, int value)
2007-09-18 23:57:02 +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;
slider->value = MID(min, value, max);
2007-09-18 23:57:02 +00:00
jwidget_add_hook(widget, JI_SLIDER, slider_msg_proc, slider);
jwidget_focusrest(widget, true);
jwidget_init_theme(widget);
2007-09-18 23:57:02 +00:00
return widget;
}
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;
slider->value = MID(min, slider->value, max);
2007-09-18 23:57:02 +00:00
jwidget_dirty(widget);
2007-09-18 23:57:02 +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;
slider->value = MID(slider->min, value, slider->max);
2007-09-18 23:57:02 +00:00
if (slider->value != old_value)
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
/* it DOES NOT emit CHANGE signal! to avoid recursive calls */
}
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;
}
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;
}
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:
jfree(slider);
2007-09-18 23:57:02 +00:00
break;
case JM_REQSIZE:
slider_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
return true;
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:
if (widget->isEnabled())
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
break;
case JM_BUTTONPRESSED:
if (!widget->isEnabled())
return true;
widget->setSelected(true);
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;
slider_setcursor(widget);
2007-09-18 23:57:02 +00:00
/* continue to JM_MOTION */
2007-09-18 23:57:02 +00:00
case JM_MOTION:
if (widget->hasCapture()) {
2007-09-18 23:57:02 +00:00
int value, accuracy, range;
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) {
value = slider->min + range * (msg->mouse.x - rc->x1) / jrect_w(rc);
2007-09-18 23:57:02 +00:00
}
/* with right click */
else {
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;
}
value = MID(slider->min, value, slider->max);
2007-09-18 23:57:02 +00:00
if (slider->value != value) {
jslider_set_value(widget, value);
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
2007-09-18 23:57:02 +00:00
}
/* for left click */
if (slider_press_left) {
int x = jmouse_x(0);
if (x < rc->x1-1)
x = rc->x1-1;
else if (x > rc->x2)
x = rc->x2;
if (x != jmouse_x(0))
jmouse_set_position(x, jmouse_y(0));
}
2007-09-18 23:57:02 +00:00
/* for right click */
else if (jmouse_control_infinite_scroll(rc)) {
slider_press_x = jmouse_x(0);
2007-09-18 23:57:02 +00:00
slider_press_value = slider->value;
}
jrect_free(rc);
return true;
2007-09-18 23:57:02 +00:00
}
break;
case JM_BUTTONRELEASED:
if (widget->hasCapture()) {
widget->setSelected(false);
widget->releaseMouse();
slider_setcursor(widget);
2007-09-18 23:57:02 +00:00
}
break;
case JM_MOUSEENTER:
case JM_MOUSELEAVE:
/* if (jwidget_is_enabled(widget) && */
/* jwidget_has_capture(widget)) { */
2007-09-18 23:57:02 +00:00
/* /\* swap the select status *\/ */
/* if (jwidget_is_selected(widget)) */
/* jwidget_deselect(widget); */
2007-09-18 23:57:02 +00:00
/* else */
/* 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
/* } */
/* TODO theme stuff */
if (widget->isEnabled())
jwidget_dirty(widget);
2007-09-18 23:57:02 +00:00
break;
case JM_KEYPRESSED:
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) {
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:
return false;
2007-09-18 23:57:02 +00:00
}
if (slider->value != value) {
jslider_set_value(widget, value);
jwidget_emit_signal(widget, JI_SIGNAL_SLIDER_CHANGE);
2007-09-18 23:57:02 +00:00
}
return true;
2007-09-18 23:57:02 +00:00
}
break;
case JM_WHEEL:
if (widget->isEnabled()) {
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);
}
return true;
2007-09-18 23:57:02 +00:00
}
break;
case JM_SETCURSOR:
slider_setcursor(widget);
return true;
2007-09-18 23:57:02 +00:00
}
return false;
2007-09-18 23:57:02 +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];
usprintf(buf, "%d", slider->min);
min_w = ji_font_text_len(widget->getFont(), buf);
2007-09-18 23:57:02 +00:00
usprintf(buf, "%d", slider->max);
max_w = ji_font_text_len(widget->getFont(), buf);
2007-09-18 23:57:02 +00:00
*w = MAX(min_w, max_w);
*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;
}
static void slider_setcursor(JWidget widget)
{
if (widget->hasCapture()) {
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);
}