aseprite/src/ui/slider.cpp

241 lines
4.9 KiB
C++
Raw Normal View History

// Aseprite UI Library
2013-01-27 12:13:13 -03:00
// Copyright (C) 2001-2013 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
2007-09-18 23:57:02 +00:00
#ifdef HAVE_CONFIG_H
2009-07-12 20:29:16 +00:00
#include "config.h"
#endif
2009-07-12 20:29:16 +00:00
#include "ui/slider.h"
#include "she/font.h"
2012-06-17 22:49:58 -03:00
#include "ui/manager.h"
#include "ui/message.h"
#include "ui/preferred_size_event.h"
#include "ui/system.h"
#include "ui/theme.h"
#include "ui/widget.h"
2007-09-18 23:57:02 +00:00
#include <cstdio>
namespace ui {
static int slider_press_x;
static int slider_press_value;
static bool slider_press_left;
Slider::Slider(int min, int max, int value)
: Widget(kSliderWidget)
2007-09-18 23:57:02 +00:00
{
m_min = min;
m_max = max;
m_value = MID(min, value, max);
2007-09-18 23:57:02 +00:00
this->setFocusStop(true);
initTheme();
2007-09-18 23:57:02 +00:00
}
void Slider::setRange(int min, int max)
2007-09-18 23:57:02 +00:00
{
m_min = min;
m_max = max;
m_value = MID(min, m_value, max);
2007-09-18 23:57:02 +00:00
invalidate();
2007-09-18 23:57:02 +00:00
}
void Slider::setValue(int value)
2007-09-18 23:57:02 +00:00
{
int old_value = m_value;
2007-09-18 23:57:02 +00:00
m_value = MID(m_min, value, m_max);
2007-09-18 23:57:02 +00:00
if (m_value != old_value)
invalidate();
2007-09-18 23:57:02 +00:00
// It DOES NOT emit CHANGE signal! to avoid recursive calls.
2007-09-18 23:57:02 +00:00
}
void Slider::getSliderThemeInfo(int* min, int* max, int* value)
2007-09-18 23:57:02 +00:00
{
if (min) *min = m_min;
if (max) *max = m_max;
if (value) *value = m_value;
2007-09-18 23:57:02 +00:00
}
bool Slider::onProcessMessage(Message* msg)
2007-09-18 23:57:02 +00:00
{
switch (msg->type()) {
2007-09-18 23:57:02 +00:00
case kFocusEnterMessage:
case kFocusLeaveMessage:
if (isEnabled())
invalidate();
2007-09-18 23:57:02 +00:00
break;
case kMouseDownMessage:
if (!isEnabled())
return true;
setSelected(true);
captureMouse();
2007-09-18 23:57:02 +00: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();
}
setupSliderCursor();
2007-09-18 23:57:02 +00:00
2014-02-08 19:26:13 -03:00
// Fall through
case kMouseMoveMessage:
if (hasCapture()) {
int value, accuracy, range;
gfx::Rect rc = getChildrenBounds();
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
range = m_max - m_min + 1;
// With left click
if (slider_press_left) {
value = m_min + range * (mousePos.x - rc.x) / rc.w;
}
// With right click
else {
accuracy = MID(1, rc.w / range, rc.w);
value = slider_press_value +
(mousePos.x - slider_press_x) / accuracy;
}
value = MID(m_min, value, m_max);
if (m_value != value) {
setValue(value);
onChange();
}
return true;
2007-09-18 23:57:02 +00:00
}
break;
case kMouseUpMessage:
if (hasCapture()) {
setSelected(false);
releaseMouse();
setupSliderCursor();
onSliderReleased();
2007-09-18 23:57:02 +00:00
}
break;
case kMouseEnterMessage:
case kMouseLeaveMessage:
// TODO theme stuff
if (isEnabled())
invalidate();
2007-09-18 23:57:02 +00:00
break;
case kKeyDownMessage:
if (hasFocus()) {
int min = m_min;
int max = m_max;
int value = m_value;
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;
default:
goto not_used;
}
if (m_value != value) {
setValue(value);
onChange();
}
return true;
2007-09-18 23:57:02 +00:00
}
break;
case kMouseWheelMessage:
if (isEnabled()) {
int value = m_value
+ static_cast<MouseMessage*>(msg)->wheelDelta().x
- static_cast<MouseMessage*>(msg)->wheelDelta().y;
2007-09-18 23:57:02 +00:00
value = MID(m_min, value, m_max);
2007-09-18 23:57:02 +00:00
if (m_value != value) {
this->setValue(value);
onChange();
}
return true;
2007-09-18 23:57:02 +00:00
}
break;
case kSetCursorMessage:
setupSliderCursor();
return true;
2007-09-18 23:57:02 +00:00
}
not_used:;
return Widget::onProcessMessage(msg);
2007-09-18 23:57:02 +00:00
}
void Slider::onPreferredSize(PreferredSizeEvent& ev)
2007-09-18 23:57:02 +00:00
{
char buf[256];
std::sprintf(buf, "%d", m_min);
int min_w = getFont()->textLength(buf);
std::sprintf(buf, "%d", m_max);
int max_w = getFont()->textLength(buf);
int w = MAX(min_w, max_w);
int h = getTextHeight();
2007-09-18 23:57:02 +00: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
ev.setPreferredSize(w, h);
}
2007-09-18 23:57:02 +00:00
void Slider::onPaint(PaintEvent& ev)
{
getTheme()->paintSlider(ev);
}
void Slider::onChange()
{
Change(); // Emit Change signal
}
void Slider::onSliderReleased()
{
SliderReleased();
2007-09-18 23:57:02 +00:00
}
void Slider::setupSliderCursor()
{
if (hasCapture()) {
if (slider_press_left)
jmouse_set_cursor(kArrowCursor);
else
jmouse_set_cursor(kSizeWECursor);
}
else
jmouse_set_cursor(kArrowCursor);
}
} // namespace ui