2012-01-06 01:12:57 -03:00
|
|
|
// ASEPRITE gui library
|
2012-01-06 00:52:11 -03:00
|
|
|
// Copyright (C) 2001-2012 David Capello
|
2010-09-27 19:18:17 -03:00
|
|
|
//
|
|
|
|
// 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>
|
|
|
|
|
2011-01-30 19:12:10 -03:00
|
|
|
#include "gui/font.h"
|
|
|
|
#include "gui/manager.h"
|
|
|
|
#include "gui/message.h"
|
|
|
|
#include "gui/rect.h"
|
|
|
|
#include "gui/system.h"
|
2010-12-04 16:13:21 -03:00
|
|
|
#include "gui/preferred_size_event.h"
|
|
|
|
#include "gui/slider.h"
|
2011-01-21 17:50:04 -03:00
|
|
|
#include "gui/theme.h"
|
2010-10-02 11:19:09 -03:00
|
|
|
#include "gui/widget.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
static int slider_press_x;
|
|
|
|
static int slider_press_value;
|
|
|
|
static int slider_press_left;
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
Slider::Slider(int min, int max, int value)
|
|
|
|
: Widget(JI_SLIDER)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
m_min = min;
|
|
|
|
m_max = max;
|
|
|
|
m_value = MID(min, value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
jwidget_focusrest(this, true);
|
2011-02-15 09:00:29 -03:00
|
|
|
initTheme();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
void Slider::setRange(int min, int max)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
m_min = min;
|
|
|
|
m_max = max;
|
|
|
|
m_value = MID(min, m_value, max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-01-21 19:45:04 -03:00
|
|
|
invalidate();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
void Slider::setValue(int value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
int old_value = m_value;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
m_value = MID(m_min, value, m_max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
if (m_value != old_value)
|
2011-01-21 19:45:04 -03:00
|
|
|
invalidate();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
// It DOES NOT emit CHANGE signal! to avoid recursive calls.
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
void Slider::getSliderThemeInfo(int* min, int* max, int* value)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
if (min) *min = m_min;
|
|
|
|
if (max) *max = m_max;
|
|
|
|
if (value) *value = m_value;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2011-04-02 13:14:07 -03:00
|
|
|
bool Slider::onProcessMessage(Message* msg)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
|
|
|
switch (msg->type) {
|
|
|
|
|
|
|
|
case JM_FOCUSENTER:
|
|
|
|
case JM_FOCUSLEAVE:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (isEnabled())
|
2012-01-05 19:45:03 -03:00
|
|
|
invalidate();
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONPRESSED:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (!isEnabled())
|
2012-01-05 19:45:03 -03:00
|
|
|
return true;
|
2007-11-28 14:19:36 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
setSelected(true);
|
|
|
|
captureMouse();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
|
|
|
slider_press_x = msg->mouse.x;
|
2010-12-04 16:13:21 -03:00
|
|
|
slider_press_value = m_value;
|
2007-09-18 23:57:02 +00:00
|
|
|
slider_press_left = msg->mouse.left;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2010-12-08 13:24:35 -03:00
|
|
|
setupSliderCursor();
|
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-12-04 16:13:21 -03:00
|
|
|
if (hasCapture()) {
|
2012-01-05 19:45:03 -03:00
|
|
|
int value, accuracy, range;
|
|
|
|
JRect rc = jwidget_get_child_rect(this);
|
|
|
|
|
|
|
|
range = m_max - m_min + 1;
|
|
|
|
|
|
|
|
/* with left click */
|
|
|
|
if (slider_press_left) {
|
|
|
|
value = m_min + range * (msg->mouse.x - rc->x1) / jrect_w(rc);
|
|
|
|
}
|
|
|
|
/* with right click */
|
|
|
|
else {
|
|
|
|
accuracy = MID(1, jrect_w(rc) / range, jrect_w(rc));
|
|
|
|
|
|
|
|
value = slider_press_value +
|
|
|
|
(msg->mouse.x - slider_press_x) / accuracy;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = MID(m_min, value, m_max);
|
|
|
|
|
|
|
|
if (m_value != value) {
|
|
|
|
this->setValue(value);
|
|
|
|
onChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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));
|
|
|
|
}
|
|
|
|
/* for right click */
|
|
|
|
else if (jmouse_control_infinite_scroll(getBounds() - getBorder())) {
|
|
|
|
slider_press_x = jmouse_x(0);
|
|
|
|
slider_press_value = m_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
jrect_free(rc);
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_BUTTONRELEASED:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (hasCapture()) {
|
2012-01-05 19:45:03 -03:00
|
|
|
setSelected(false);
|
|
|
|
releaseMouse();
|
|
|
|
setupSliderCursor();
|
2010-12-08 13:26:19 -03:00
|
|
|
|
2012-01-05 19:45:03 -03:00
|
|
|
onSliderReleased();
|
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) && */
|
2012-01-05 19:45:03 -03:00
|
|
|
/* jwidget_has_capture(widget)) { */
|
|
|
|
/* /\* swap the select status *\/ */
|
|
|
|
/* if (jwidget_is_selected(widget)) */
|
|
|
|
/* jwidget_deselect(widget); */
|
|
|
|
/* else */
|
|
|
|
/* jwidget_select(widget); */
|
|
|
|
|
|
|
|
/* /\* TODO switch slider signal *\/ */
|
2007-09-18 23:57:02 +00:00
|
|
|
/* } */
|
|
|
|
|
2007-11-28 14:19:36 +00:00
|
|
|
/* TODO theme stuff */
|
2010-12-04 16:13:21 -03:00
|
|
|
if (isEnabled())
|
2012-01-05 19:45:03 -03:00
|
|
|
invalidate();
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
case JM_KEYPRESSED:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (hasFocus()) {
|
2012-01-05 19:45:03 -03:00
|
|
|
int min = m_min;
|
|
|
|
int max = m_max;
|
|
|
|
int value = m_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;
|
|
|
|
case KEY_HOME: value = min; break;
|
|
|
|
case KEY_END: value = max; break;
|
|
|
|
default:
|
|
|
|
goto not_used;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_value != value) {
|
|
|
|
this->setValue(value);
|
|
|
|
onChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case JM_WHEEL:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (isEnabled()) {
|
2012-01-05 19:45:03 -03:00
|
|
|
int value = m_value + jmouse_z(0) - jmouse_z(1);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2012-01-05 19:45:03 -03:00
|
|
|
value = MID(m_min, value, m_max);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2012-01-05 19:45:03 -03:00
|
|
|
if (m_value != value) {
|
|
|
|
this->setValue(value);
|
|
|
|
onChange();
|
|
|
|
}
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
|
|
|
case JM_SETCURSOR:
|
2010-12-08 13:24:35 -03:00
|
|
|
setupSliderCursor();
|
2009-08-17 18:00:38 +00:00
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
not_used:;
|
|
|
|
return Widget::onProcessMessage(msg);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
void Slider::onPreferredSize(PreferredSizeEvent& ev)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
int w, h, min_w, max_w;
|
2007-09-18 23:57:02 +00:00
|
|
|
char buf[256];
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
usprintf(buf, "%d", m_min);
|
|
|
|
min_w = ji_font_text_len(this->getFont(), buf);
|
|
|
|
|
|
|
|
usprintf(buf, "%d", m_max);
|
|
|
|
max_w = ji_font_text_len(this->getFont(), buf);
|
|
|
|
|
|
|
|
w = MAX(min_w, max_w);
|
|
|
|
h = text_height(this->getFont());
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
w += this->border_width.l + this->border_width.r;
|
|
|
|
h += this->border_width.t + this->border_width.b;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
ev.setPreferredSize(w, h);
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-02-05 12:03:22 -03:00
|
|
|
void Slider::onPaint(PaintEvent& ev)
|
|
|
|
{
|
|
|
|
getTheme()->paintSlider(ev);
|
|
|
|
}
|
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
void Slider::onChange()
|
|
|
|
{
|
|
|
|
Change(); // Emit Change signal
|
|
|
|
}
|
|
|
|
|
2010-12-08 13:26:19 -03:00
|
|
|
void Slider::onSliderReleased()
|
2010-12-04 16:13:21 -03:00
|
|
|
{
|
2010-12-08 13:26:19 -03:00
|
|
|
SliderReleased();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2010-12-08 13:24:35 -03:00
|
|
|
void Slider::setupSliderCursor()
|
2008-02-29 19:29:49 +00:00
|
|
|
{
|
2010-12-04 16:13:21 -03:00
|
|
|
if (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);
|
|
|
|
}
|