2013-08-08 21:01:20 -03:00
|
|
|
// Aseprite UI Library
|
2013-01-27 12:13:13 -03:00
|
|
|
// Copyright (C) 2001-2013 David Capello
|
2010-09-27 19:18:17 -03:00
|
|
|
//
|
2013-08-08 21:01:20 -03:00
|
|
|
// This source file is distributed under MIT license,
|
|
|
|
// please read LICENSE.txt for more information.
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-08-05 21:20:19 -03:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2009-07-12 20:29:16 +00:00
|
|
|
#include "config.h"
|
2013-08-05 21:20:19 -03:00
|
|
|
#endif
|
2009-07-12 20:29:16 +00:00
|
|
|
|
2012-06-17 22:49:58 -03:00
|
|
|
#include "ui/font.h"
|
|
|
|
#include "ui/manager.h"
|
|
|
|
#include "ui/message.h"
|
|
|
|
#include "ui/preferred_size_event.h"
|
|
|
|
#include "ui/slider.h"
|
|
|
|
#include "ui/system.h"
|
|
|
|
#include "ui/theme.h"
|
|
|
|
#include "ui/widget.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-07-28 21:17:07 -03:00
|
|
|
#include <cstdio>
|
|
|
|
|
2012-06-17 22:02:54 -03:00
|
|
|
namespace ui {
|
|
|
|
|
2008-02-29 19:29:49 +00:00
|
|
|
static int slider_press_x;
|
|
|
|
static int slider_press_value;
|
2013-07-28 21:17:07 -03:00
|
|
|
static bool slider_press_left;
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2010-12-04 16:13:21 -03:00
|
|
|
Slider::Slider(int min, int max, int value)
|
2013-04-03 22:07:24 -03:00
|
|
|
: Widget(kSliderWidget)
|
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
|
|
|
|
2012-04-05 19:00:19 -03:00
|
|
|
this->setFocusStop(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
|
|
|
{
|
2013-07-28 21:17:07 -03:00
|
|
|
switch (msg->type()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kFocusEnterMessage:
|
|
|
|
case kFocusLeaveMessage:
|
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;
|
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kMouseDownMessage:
|
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
|
|
|
|
2013-07-28 21:17:07 -03:00
|
|
|
{
|
|
|
|
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
|
|
|
slider_press_x = mousePos.x;
|
|
|
|
slider_press_value = m_value;
|
|
|
|
slider_press_left = static_cast<MouseMessage*>(msg)->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
|
|
|
|
2014-02-08 19:26:13 -03:00
|
|
|
// Fall through
|
2007-11-28 14:19:36 +00:00
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kMouseMoveMessage:
|
2010-12-04 16:13:21 -03:00
|
|
|
if (hasCapture()) {
|
2012-01-05 19:45:03 -03:00
|
|
|
int value, accuracy, range;
|
2013-05-20 20:40:18 -03:00
|
|
|
gfx::Rect rc = getChildrenBounds();
|
2013-07-28 21:17:07 -03:00
|
|
|
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
2012-01-05 19:45:03 -03:00
|
|
|
|
|
|
|
range = m_max - m_min + 1;
|
|
|
|
|
2013-05-20 20:40:18 -03:00
|
|
|
// With left click
|
2012-01-05 19:45:03 -03:00
|
|
|
if (slider_press_left) {
|
2013-07-28 21:17:07 -03:00
|
|
|
value = m_min + range * (mousePos.x - rc.x) / rc.w;
|
2012-01-05 19:45:03 -03:00
|
|
|
}
|
2013-05-20 20:40:18 -03:00
|
|
|
// With right click
|
2012-01-05 19:45:03 -03:00
|
|
|
else {
|
2013-05-20 20:40:18 -03:00
|
|
|
accuracy = MID(1, rc.w / range, rc.w);
|
2012-01-05 19:45:03 -03:00
|
|
|
|
|
|
|
value = slider_press_value +
|
2013-07-28 21:17:07 -03:00
|
|
|
(mousePos.x - slider_press_x) / accuracy;
|
2012-01-05 19:45:03 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
value = MID(m_min, value, m_max);
|
|
|
|
|
|
|
|
if (m_value != value) {
|
2013-05-20 20:40:18 -03:00
|
|
|
setValue(value);
|
2012-01-05 19:45:03 -03:00
|
|
|
onChange();
|
|
|
|
}
|
|
|
|
|
2013-05-20 20:40:18 -03:00
|
|
|
// For left click
|
2012-01-05 19:45:03 -03:00
|
|
|
if (slider_press_left) {
|
2014-02-02 18:46:19 -03:00
|
|
|
int x = mousePos.x;
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2013-05-20 20:40:18 -03:00
|
|
|
if (x < rc.x-1)
|
|
|
|
x = rc.x-1;
|
|
|
|
else if (x > rc.x2())
|
|
|
|
x = rc.x2();
|
2012-01-05 19:45:03 -03:00
|
|
|
|
2014-02-02 18:46:19 -03:00
|
|
|
if (x != mousePos.x)
|
|
|
|
ui::set_mouse_position(gfx::Point(x, mousePos.y));
|
2012-01-05 19:45:03 -03:00
|
|
|
}
|
2013-05-20 20:40:18 -03:00
|
|
|
// For right click
|
2014-02-02 18:46:19 -03:00
|
|
|
else {
|
|
|
|
gfx::Point newPoint =
|
|
|
|
ui::control_infinite_scroll(this, getBounds() - getBorder(), mousePos);
|
|
|
|
|
|
|
|
if (newPoint != mousePos) {
|
|
|
|
slider_press_x = newPoint.x;
|
|
|
|
slider_press_value = m_value;
|
|
|
|
}
|
2012-01-05 19:45:03 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kMouseUpMessage:
|
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;
|
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kMouseEnterMessage:
|
|
|
|
case kMouseLeaveMessage:
|
2013-07-28 21:17:07 -03: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;
|
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kKeyDownMessage:
|
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;
|
|
|
|
|
2013-07-28 21:17:07 -03:00
|
|
|
switch (static_cast<KeyMessage*>(msg)->scancode()) {
|
|
|
|
case kKeyLeft: value = MAX(value-1, min); break;
|
|
|
|
case kKeyRight: value = MIN(value+1, max); break;
|
|
|
|
case kKeyPageDown: value = MAX(value-(max-min+1)/4, min); break;
|
|
|
|
case kKeyPageUp: value = MIN(value+(max-min+1)/4, max); break;
|
|
|
|
case kKeyHome: value = min; break;
|
|
|
|
case kKeyEnd: value = max; break;
|
2012-01-05 19:45:03 -03:00
|
|
|
default:
|
|
|
|
goto not_used;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_value != value) {
|
2013-07-28 21:17:07 -03:00
|
|
|
setValue(value);
|
2012-01-05 19:45:03 -03:00
|
|
|
onChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kMouseWheelMessage:
|
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
|
|
|
|
2013-04-04 21:53:29 -03:00
|
|
|
case kSetCursorMessage:
|
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];
|
|
|
|
|
2013-07-28 21:17:07 -03:00
|
|
|
std::sprintf(buf, "%d", m_min);
|
2010-12-04 16:13:21 -03:00
|
|
|
min_w = ji_font_text_len(this->getFont(), buf);
|
|
|
|
|
2013-07-28 21:17:07 -03:00
|
|
|
std::sprintf(buf, "%d", m_max);
|
2010-12-04 16:13:21 -03:00
|
|
|
max_w = ji_font_text_len(this->getFont(), buf);
|
|
|
|
|
|
|
|
w = MAX(min_w, max_w);
|
2014-03-21 19:45:35 -03:00
|
|
|
h = getTextHeight();
|
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)
|
2012-08-10 23:14:54 -03:00
|
|
|
jmouse_set_cursor(kArrowCursor);
|
2008-02-29 19:29:49 +00:00
|
|
|
else
|
2012-08-10 23:14:54 -03:00
|
|
|
jmouse_set_cursor(kSizeLCursor);
|
2008-02-29 19:29:49 +00:00
|
|
|
}
|
|
|
|
else
|
2012-08-10 23:14:54 -03:00
|
|
|
jmouse_set_cursor(kArrowCursor);
|
2008-02-29 19:29:49 +00:00
|
|
|
}
|
2012-06-17 22:02:54 -03:00
|
|
|
|
|
|
|
} // namespace ui
|