#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::HoVeR(int& x, int& y) const { return IsVert() ? y : x; } void SliderCtrl::Paint(Draw& w) { Size size = GetSize(); int ii = IsEnabled() ? HasCapture() || HasFocus() ? CTRL_PRESSED : HasMouse() ? CTRL_HOT : CTRL_NORMAL : CTRL_DISABLED; int l = SliderToClient(min); int t = Nvl(SliderToClient(value)); int h = SliderToClient(max) - l; Color hl = SColorHighlight(); if(Difference(hl, Gray()) < 16) hl = SBlack(); if(IsVert()) { int half = size.cx >> 1; w.DrawRect(half - DPI(1), l, DPI(2), t - l, hl); w.DrawRect(half - DPI(1), t, DPI(2), h - t, Gray()); if(!IsNull(value)) w.DrawImage((size.cx - CtrlImg::vthumb().GetSize().cx) >> 1, t, CtrlImg::Get(CtrlImg::I_vthumb + ii)); } else { int half = size.cy >> 1; w.DrawRect(l, half - DPI(1), t - l, DPI(2), hl); w.DrawRect(t, half - DPI(1), h - t, DPI(2), Gray()); if(!IsNull(value)) w.DrawImage(t, (size.cy - CtrlImg::hthumb().GetSize().cy) >> 1, CtrlImg::Get(CtrlImg::I_hthumb + ii)); } if(HasFocus()) DrawFocus(w, size); } 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(p >= thumb && p < thumb + HoVe(CtrlImg::hthumb().GetSize().cx, CtrlImg::vthumb().GetSize().cy)) SetCapture(); else if(jump) { value = ClientToSlider(p); WhenSlideFinish(); UpdateActionRefresh(); } else { if( ( ( p < thumb) && (min == Min() ) ) || ( (p > thumb) && ( min == Max() ) ) ) 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(); Refresh(); ReleaseCapture(); } 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; } int SliderCtrl::SliderToClient(int v) const { if(IsNull(v)) return Null; v = minmax(v, Min(), Max()); v = iscale(v - min, HoVe(GetSize().cx - CtrlImg::hthumb().GetSize().cx, GetSize().cy - CtrlImg::vthumb().GetSize().cy), max - min); return v; } int SliderCtrl::ClientToSlider(int p) const { Size hsz = CtrlImg::hthumb().GetSize(); Size vsz = CtrlImg::vthumb().GetSize(); p -= HoVe(hsz.cx / 2, vsz.cy / 2); return minmax(min + iscale(p, max - min, HoVe(GetSize().cx - hsz.cx, GetSize().cy - vsz.cy)), Min(), Max()); } 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() {} }