#include "CtrlLib.h" namespace Upp { SliderCtrl::SliderCtrl() : value(Null) , min(0) , max(100) , step(1) , round_step(true) , jump(false) { Transparent(); NoWantFocus(); } bool SliderCtrl::IsVert() const { return GetSize().cx < GetSize().cy; } int SliderCtrl::HoVe(int x, int y) const { return IsVert() ? y : x; } int SliderCtrl::ThumbSz() const { return HoVe(CtrlImg::hthumb().GetSize().cx, CtrlImg::vthumb().GetSize().cy); } int SliderCtrl::SliderSz() const { Size sz = GetSize(); return HoVe(sz.cx, sz.cy) - ThumbSz(); } int SliderCtrl::SliderToClient(int v) const { if(IsNull(v)) return Null; int sz = SliderSz(); v = iscale(clamp(v, Min(), Max()) - min, sz, max - min); return HoVe(v, sz - v) + ThumbSz() / 2; } void SliderCtrl::Paint(Draw& w) { Size size = GetSize(); int ii = IsEnabled() ? HasCapture() || HasFocus() ? CTRL_PRESSED : HasMouseIn() ? CTRL_HOT : CTRL_NORMAL : CTRL_DISABLED; int l = SliderToClient(min); int t = Nvl(SliderToClient(value), l); int h = SliderToClient(max); Color c1 = SColorHighlight(); if(Difference(c1, Gray()) < 16) c1 = SBlack(); Color c2 = Gray(); if(max < min) Swap(c1, c2); if(IsVert()) { int half = size.cx >> 1; w.DrawRect(half - DPI(1), h, DPI(2), t - h, c2); w.DrawRect(half - DPI(1), t, DPI(2), l - t, c1); if(!IsNull(value)) w.DrawImage((size.cx - CtrlImg::vthumb().GetSize().cx) >> 1, t - ThumbSz() / 2, CtrlImg::Get(CtrlImg::I_vthumb + ii)); } else { int half = size.cy >> 1; w.DrawRect(l, half - DPI(1), t - l, DPI(2), c1); w.DrawRect(t, half - DPI(1), h - t, DPI(2), c2); if(!IsNull(value)) w.DrawImage(t - ThumbSz() / 2, (size.cy - CtrlImg::hthumb().GetSize().cy) >> 1, CtrlImg::Get(CtrlImg::I_hthumb + ii)); } if(HasFocus()) DrawFocus(w, size); } int SliderCtrl::ClientToSlider(int p) const { int sz = SliderSz(); p -= ThumbSz() / 2; if(IsVert()) p = sz - p; return clamp(min + iscale(p, max - min, sz), Min(), Max()); } bool SliderCtrl::Key(dword key, int repcnt) { if(IsEditable()) switch(key) { case K_LEFT: case K_UP: Dec(); return true; case K_RIGHT: case K_DOWN: Inc(); return true; } return Ctrl::Key(key, repcnt); } void SliderCtrl::LeftDown(Point pos, dword keyflags) { if(!IsEditable()) return; SetWantFocus(); int thumb = SliderToClient(value); int p = HoVe(pos.x, pos.y); if(IsNull(thumb)) { value = ClientToSlider(p); WhenSlideFinish(); UpdateActionRefresh(); } else if(abs(p - thumb) <= ThumbSz() / 2) SetCapture(); else if(jump) { value = ClientToSlider(p); WhenSlideFinish(); UpdateActionRefresh(); } else { if((min < max) != IsVert() ? p < thumb : p > thumb) Dec(); else Inc(); } Refresh(); } void SliderCtrl::LeftRepeat(Point p, dword f) { if(!HasCapture()) LeftDown(p, f); } void SliderCtrl::LeftUp(Point pos, dword keyflags) { if(HasCapture()) WhenSlideFinish(); ReleaseCapture(); Refresh(); } void SliderCtrl::MouseMove(Point pos, dword keyflags) { if(HasCapture()) { int n = ClientToSlider(HoVe(pos.x, pos.y)); if(n != value) { value = n; UpdateActionRefresh(); } } Refresh(); } void SliderCtrl::MouseEnter(Point p, dword keyflags) { Refresh(); } void SliderCtrl::MouseLeave() { Refresh(); } void SliderCtrl::SetData(const Value& v) { int i = v; if(!IsNull(i)) i = minmax(i, Min(), Max() ); if(i != value) { value = i; UpdateRefresh(); } } Value SliderCtrl::GetData() const { return value; } SliderCtrl& SliderCtrl::MinMax(int _min, int _max) { if(min != _min || max != _max) { min = _min; max = _max; if(!IsNull(value)) { int v = minmax(value, Min(), Max()); if(value != v) { value = v; Update(); } } Refresh(); } return *this; } void SliderCtrl::Dec() { int n = value; if(IsNull(value)) n = Max(); else if(n > Min()) { if(round_step && step > 1) n = idivfloor(n - 1, step) * step; else n -= step; if(n < Min()) n = Min(); } if(n != value) { value = n; WhenSlideFinish(); UpdateActionRefresh(); } } void SliderCtrl::Inc() { int n = value; if(IsNull(value)) n = Min(); else if(n < Max()) { if(round_step && step > 1) n = idivceil(n + 1, step) * step; else n += step; if(n > Max()) n = Max(); } if(n != value) { value = n; WhenSlideFinish(); UpdateActionRefresh(); } } void SliderCtrl::GotFocus() { Refresh(); } void SliderCtrl::LostFocus() { Refresh(); } SliderCtrl::~SliderCtrl() {} }