diff options
Diffstat (limited to 'Src/Wasabi/api/wnd/wndclass/slider.cpp')
-rw-r--r-- | Src/Wasabi/api/wnd/wndclass/slider.cpp | 705 |
1 files changed, 705 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/wndclass/slider.cpp b/Src/Wasabi/api/wnd/wndclass/slider.cpp new file mode 100644 index 00000000..51157d7f --- /dev/null +++ b/Src/Wasabi/api/wnd/wndclass/slider.cpp @@ -0,0 +1,705 @@ +#include <precomp.h> +#include "slider.h" + +#include <tataki/canvas/canvas.h> +#include <api/wnd/notifmsg.h> +#include <api/wnd/PaintCanvas.h> + +#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); +} |