#include #include "slider.h" #include #include #include #define DEFAULT_THUMBWIDTH 16 #define DEFAULT_THUMBHEIGHT 16 SliderWnd::SliderWnd() { seeking = 0; enabled = 1; hilite = 0; pos = 0; oldpos = -1; thumbwidth = DEFAULT_THUMBWIDTH; captured = 0; xShift = 0; yShift = 0; base_texture = NULL; use_base_texture = 0; no_default_background = 0; drawOnBorders = 0; hotPosition = -1; origPos = 0; vertical = 0; thumbCentered = 1; thumbOffset = 0; thumbStretched = 0; hotposrange = -1; setLimits(START, END); } SliderWnd::~SliderWnd() {} int SliderWnd::onPaint(Canvas *canvas) { if (canvas == NULL) { PaintBltCanvas paintcanvas; if (!paintcanvas.beginPaint(this)) return 0; SliderWnd::onPaint(&paintcanvas); } SLIDERWND_PARENT::onPaint(canvas); RECT r, origr; getClientRect(&r); origr = r; if (use_base_texture) { if (!base_texture) { renderBaseTexture(canvas, r); } else { RECT cr; cr.left = xShift; cr.top = yShift; cr.right = cr.left + (r.right - r.left); cr.bottom = cr.top + (r.bottom - r.top); base_texture->blitToRect(canvas, &cr, &r); } } if (vertical) { RECT br; br.left = r.left; br.right = r.right; if (left.getBitmap()) { br.top = r.top; br.bottom = left.getHeight(); left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } if (right.getBitmap()) { br.top = r.bottom - right.getHeight(); br.bottom = r.bottom; right.stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } if (middle.getBitmap()) { br.top = r.top + (left.getBitmap() ? left.getHeight() : 0); br.bottom = r.bottom - (right.getBitmap() ? right.getHeight() : 0); middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } } else { RECT br; br.top = r.top; br.bottom = r.bottom; if (left.getBitmap()) { br.left = r.left; br.right = br.left + left.getWidth(); left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } if (right.getBitmap()) { br.left = r.right - right.getWidth(); br.right = r.right; right.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } if (middle.getBitmap()) { br.left = r.left + (left.getBitmap() ? left.getWidth() : 0); br.right = r.right - (right.getBitmap() ? right.getWidth() : 0); middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha()); } } if (vertical) { int w = (r.bottom - r.top) - thumbHeight(); // ASSERT(w > 0); // if the control paints off the edge of the screen, this will needlessly assert. if (w < 0) w = 0; r.top += (pos * w) / length; r.bottom = r.top + thumbHeight(); if (!thumbStretched) { if (!thumbCentered) { r.left = origr.left + thumbOffset; r.right = origr.left + thumbWidth() + thumbOffset; } else { int w = ((r.right - r.left) - thumbWidth()) / 2; r.left = origr.left + w + thumbOffset; r.right = origr.right - w + thumbOffset; } } else { r.left = origr.left; r.right = origr.right; } } else { // offset for left bitmap if (!drawOnBorders) { if (left.getBitmap() != NULL) r.left += left.getWidth(); if (right.getBitmap() != NULL) r.right -= right.getWidth(); } int w = (r.right - r.left) - thumbWidth(); if (w < 0) w = 0; r.left += (pos * w) / length; r.right = r.left + thumbWidth(); if (r.right > origr.right) { r.left -= r.right - origr.right; r.right = origr.right; } if (!thumbStretched) { int thumbh = thumb.getBitmap() ? thumb.getHeight() : DEFAULT_THUMBWIDTH; if (thumbCentered) { int h = ((r.bottom - r.top) - thumbh) / 2; r.top = origr.top + h; r.bottom = origr.bottom - h; } else { r.top = origr.top + thumbOffset; r.bottom = origr.top + thumbh + thumbOffset; } } else { r.top = origr.top; r.bottom = origr.bottom; } } SkinBitmap *sb = getSeekStatus() ? (thumbdown.getBitmap() ? thumbdown.getBitmap() : thumb.getBitmap()) : ((hilite && thumbhilite.getBitmap()) ? thumbhilite.getBitmap() : thumb.getBitmap()); if (sb != NULL) sb->stretchToRectAlpha(canvas, &r, getPaintingAlpha()); else canvas->fillRect(&r, RGB(255, 0, 0)); return 1; } int SliderWnd::onInit() { SLIDERWND_PARENT::onInit(); if (!no_default_background) { if (vertical) { // Please note that these bitmaps here do not yet exist. if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.vertical.top"); if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.vertical.middle"); if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.vertical.bottom"); if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.vertical.button"); if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.vertical.button.pressed"); } else { if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.horizontal.left"); if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.horizontal.middle"); if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.horizontal.right"); if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.horizontal.button"); if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.horizontal.button.pressed"); } } return 1; } int SliderWnd::onLeftButtonDown(int x, int y) { SLIDERWND_PARENT::onLeftButtonDown(x, y); if (!enabled) return 0; seeking = 1; origPos = 0; RECT r; getClientRect(&r); if (vertical) { int w = (r.bottom - r.top) - thumbHeight(); if (w < 0) w = 0; r.top += (pos * w) / length; origPos = (y - r.top) - 1; /*if(origPos<0 || origPos>thumbHeight())*/ origPos = (thumbHeight() / 2) - 2; } else { if (!drawOnBorders) { if (left.getBitmap() != NULL) r.left += left.getWidth(); if (right.getBitmap() != NULL) r.right -= right.getWidth(); } int w = (r.right - r.left) - thumbWidth(); if (w < 0) w = 0; r.left += (pos * w) / length; origPos = (x - r.left) - 1; if (origPos < 0 || origPos > thumbWidth()) origPos = (thumbWidth() / 2) - 2; } if (!captured) { captured = 1; beginCapture(); } oldpos = pos; onMouseMove(x, y); return 1; } //FG> //removed cross-hierarchy deletion (crashs due to ancestor in common.dll trying to delete pointers in a different //heap scope than the one in which they were allocated) void SliderWnd::setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp) { setThumbBmp(thumbbmp); setThumbDownBmp(thumbdownbmp); setThumbHiliteBmp(thumbhighbmp); setLeftBmp(leftbmp); setRightBmp(rightbmp); setMiddleBmp(middlebmp); } void SliderWnd::setLeftBmp(const wchar_t *name) { left = name; invalidate(); } void SliderWnd::setMiddleBmp(const wchar_t *name) { middle = name; invalidate(); } void SliderWnd::setRightBmp(const wchar_t *name) { right = name; invalidate(); } void SliderWnd::setThumbBmp(const wchar_t *name) { thumb = name; invalidate(); } void SliderWnd::setThumbDownBmp(const wchar_t *name) { thumbdown = name; invalidate(); } void SliderWnd::setThumbHiliteBmp(const wchar_t *name) { thumbhilite = name; invalidate(); } SkinBitmap *SliderWnd::getLeftBitmap() { return left; } SkinBitmap *SliderWnd::getRightBitmap() { return right; } SkinBitmap *SliderWnd::getMiddleBitmap() { return middle; } SkinBitmap *SliderWnd::getThumbBitmap() { return thumb; } SkinBitmap *SliderWnd::getThumbDownBitmap() { return thumbdown; } SkinBitmap *SliderWnd::getThumbHiliteBitmap() { return thumbhilite; } int SliderWnd::getWidth() { if (vertical) return (getThumbBitmap() ? getThumbBitmap()->getWidth() : 0); else { return 64; } } int SliderWnd::getHeight() { if (!vertical) return (getThumbBitmap() ? getThumbBitmap()->getHeight() : 0); else { return 64; } } void SliderWnd::setEnable(int en) { if (enabled != en) invalidate(); enabled = en; } int SliderWnd::getEnable(void) { return enabled; } void SliderWnd::setPosition(int newpos, int wantcb) { if (newpos < minlimit) newpos = minlimit; else if (newpos > maxlimit) newpos = maxlimit; if (vertical) pos = maxlimit - newpos; else /* horizontal */ pos = newpos - minlimit; if (wantcb) onSetPosition(); invalidate(); } int SliderWnd::onMouseMove(int x, int y) { int p, w, mouseover; SLIDERWND_PARENT::onMouseMove(x, y); POINT po = {x, y}; clientToScreen(&po); mouseover = (WASABI_API_WND->rootWndFromPoint(&po) == this); if (mouseover && !seeking && !captured) { beginCapture(); captured = 1; onEnterArea(); } int lasthilite = hilite; hilite = enabled && mouseover; if (hilite != lasthilite) { if (!mouseover && !seeking && captured) { endCapture(); captured = 0; onLeaveArea(); invalidate(); return 0; } invalidate(); } if (!enabled) return 1; RECT r, origr; getClientRect(&r); x -= r.left; y -= r.top; origr = r; if (vertical) { w = (r.bottom - r.top) - thumbHeight(); // p = (y - (r.top-origr.top)) - (thumbHeight()/2-2); p = (y - (r.top - origr.top)) - origPos; } else { if (!drawOnBorders) { if (left != NULL) r.left += left.getWidth(); if (right != NULL) r.right -= right.getWidth(); } w = (r.right - r.left) - thumbWidth(); // p = (x - (r.left - origr.left)) - (thumbWidth()/2-2); p = (x - (r.left - origr.left)) - origPos; } if (seeking) { pos = (p * length) / w; if (pos < 0) pos = 0; else if (pos > length) pos = length; if (hotPosition != -1) { int a, c; if (vertical) a = r.bottom - r.top; else a = r.right - r.left; c = getHotPosRange(); if (c == -1) { int b = (int)(a * 0.075); c = (b * length) / a; } /** EQBand: minlimit -127, maxlimit 127, hotpos 0 PanBar: minlimit 0, maxlimit 225, hotpos 127 VSliders pos starts from top by 0 (winamp behaviour reversed!) */ if (vertical) { //if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition; if ((maxlimit - pos) > (hotPosition - c) && (maxlimit - pos) < (hotPosition + c)) pos = hotPosition - minlimit; // Hehe, now it works ;) } else { if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition; //if ((pos - maxlimit)> (hotPosition - c) && (pos - maxlimit) < (hotPosition + c)) pos = hotPosition - minlimit; } } onSetPosition(); invalidate(); } return 1; } void SliderWnd::onCancelCapture() { SLIDERWND_PARENT::onCancelCapture(); if (seeking && captured) abort(); } int SliderWnd::onLeftButtonUp(int x, int y) { SLIDERWND_PARENT::onLeftButtonUp(x, y); int wasseeking = seeking; seeking = 0; captured = 0; oldpos = -1; endCapture(); if (wasseeking) onSetFinalPosition(); invalidate(); return 1; } int SliderWnd::onRightButtonDown(int x, int y) { SLIDERWND_PARENT::onRightButtonDown(x, y); if (seeking && captured) { abort(); } return 1; } int SliderWnd::onChar(unsigned int c) { SLIDERWND_PARENT::onChar(c); if (seeking && captured && (c == 27)) { abort(); } return 1; } int SliderWnd::onSetPosition() { if (!isInited()) return 0; notifyParent(ChildNotify::SLIDER_INTERIM_POSITION, getSliderPosition()); return 0; } int SliderWnd::onSetFinalPosition() { if (!isInited()) return 0; notifyParent(ChildNotify::SLIDER_FINAL_POSITION, getSliderPosition()); return 0; } int SliderWnd::getSliderPosition() { if (vertical) return maxlimit -pos; else return pos + minlimit; } int SliderWnd::getSeekStatus() { return seeking; } int SliderWnd::thumbWidth() { if (thumb.getBitmap() == NULL) return DEFAULT_THUMBWIDTH; return thumb.getWidth(); } int SliderWnd::thumbHeight() { if (thumb.getBitmap() == NULL) return DEFAULT_THUMBHEIGHT; return thumb.getHeight(); } void SliderWnd::setUseBaseTexture(int useit) { use_base_texture = useit; invalidate(); } void SliderWnd::setBaseTexture(SkinBitmap *bmp, int x, int y) { base_texture = bmp; use_base_texture = TRUE; xShift = x; yShift = y; invalidate(); } void SliderWnd::setNoDefaultBackground(int no) { no_default_background = no; } void SliderWnd::setDrawOnBorders(int draw) { drawOnBorders = draw; } void SliderWnd::onEnterArea() { SLIDERWND_PARENT::onEnterArea(); } void SliderWnd::onLeaveArea() { SLIDERWND_PARENT::onLeaveArea(); } void SliderWnd::setOrientation(int o) { vertical = o; } void SliderWnd::setHotPosition(int h) { hotPosition = h; } void SliderWnd::setThumbCentered(int c) { thumbCentered = c; } void SliderWnd::setThumbStretched(int c) { thumbStretched = c; } void SliderWnd::setThumbOffset(int o) { thumbOffset = o; } void SliderWnd::abort() { if (oldpos != -1) { seeking = 0; captured = 0; endCapture(); pos = oldpos; onSetPosition(); invalidate(); oldpos = -1; } return ; } void SliderWnd::setLimits(int pminlimit, int pmaxlimit) { minlimit = pminlimit; maxlimit = pmaxlimit; length = maxlimit - minlimit; } int SliderWnd::onKeyDown(int vkcode) { switch (vkcode) { case VK_LEFT: move_left(Std::keyModifier(STDKEY_CONTROL)); return 1; case VK_RIGHT: move_right(Std::keyModifier(STDKEY_CONTROL)); return 1; case VK_HOME: move_start(); return 1; case VK_END: move_end(); return 1; default: return SLIDERWND_PARENT::onKeyDown(vkcode); } } void SliderWnd::move_left(int bigstep) { int pos = getSliderPosition(); if (!bigstep) pos--; else pos -= (ABS(maxlimit - minlimit) / 10); if (pos < minlimit) pos = minlimit; setPosition(pos); } void SliderWnd::move_right(int bigstep) { int pos = getSliderPosition(); if (!bigstep) pos++; else pos += (ABS(maxlimit - minlimit) / 10); if (pos > maxlimit) pos = maxlimit; setPosition(pos); } void SliderWnd::move_start() { setPosition(minlimit); } void SliderWnd::move_end() { setPosition(maxlimit); }