#include "ScrollHV.h" ScrollHV::ScrollHV() : _valueV(0), _maxV(10), _rangeV(5), _mausDownTime(0.0f), _blockMausUp(false), _valueH(0), _maxH(10), _rangeH(5), _buttonHeight(16), _buttonWidth(16), _distFirstRow(3), _rowHeight(10), _selectedRow(0), _hoverRow(-1), _isRowSelection(false), _wheelIncr(2), _isKeyControl(true), _sizeV(10), _sizeH(10), _isButtonBorder(true), _lastAlpha(255.f), _isSelectableOnClick(true), _showHoverRow(false) { set_color(_selRowCol, 255,0,0); set_color(_backColor, 32,32,32); btnDown.setType(Button::Type::ArrowDown); btnUp.setType(Button::Type::ArrowUp); btnRight.setType(Button::Type::ArrowRight); btnLeft.setType(Button::Type::ArrowLeft); btnBarV.setBorder(false); btnBarV.setAlpha(0); btnBarH.setBorder(false); btnBarH.setAlpha(0); _state.set(ButtonsV, true); _state.set(SliderV, true); _state.set(ButtonsH, true); _state.set(SliderH, true); setBorder(true); } void ScrollHV::setRowSelection(bool isRowSelection) { _isRowSelection = isRowSelection; } void ScrollHV::setShowHoverRow(bool showHoverRow) { _showHoverRow = showHoverRow; } void ScrollHV::setSelRowColor(const Color& color) { _selRowCol = color; } void ScrollHV::setScrollBarV(bool isButtons, bool isSlider) { _state.set(ButtonsV, isButtons); _state.set(SliderV, isSlider); btnUp.setVisible(isButtons); btnDown.setVisible(isButtons); btnSliderV.setVisible(isSlider); } void ScrollHV::setScrollBarH(bool isButtons, bool isSlider) { _state.set(ButtonsH, isButtons); _state.set(SliderH, isSlider); btnLeft.setVisible(isButtons); btnRight.setVisible(isButtons); btnSliderH.setVisible(isSlider); } void ScrollHV::setButtonSize(int width, int height) { _buttonWidth = width; _buttonHeight = height; } void ScrollHV::setButtonForeColor(int r, int g, int b) { btnUp.setForeColor(r, g, b); btnDown.setForeColor(r, g, b); btnLeft.setForeColor(r, g, b); btnRight.setForeColor(r, g, b); } void ScrollHV::setBackColor(int r, int g, int b, int r2, int g2, int b2) { set_color(_backColor, r, g, b); if(r2 != -1) { btnDown.setBackColor(r2, g2, b2); btnUp.setBackColor(r2, g2, b2); btnRight.setBackColor(r2, g2, b2); btnLeft.setBackColor(r2, g2, b2); btnSliderV.setBackColor(r2, g2, b2); btnSliderH.setBackColor(r2, g2, b2); } } void ScrollHV::setButtonBackColor(int r, int g, int b, int r2, int g2, int b2) { btnDown.setBackColor(r, g, b); btnUp.setBackColor(r, g, b); btnRight.setBackColor(r, g, b); btnLeft.setBackColor(r, g, b); if(r2 != -1) r = r2, g = g2, b = b2; btnSliderV.setBackColor(r, g, b); btnSliderH.setBackColor(r, g, b); } void ScrollHV::setBorderColor(int r, int g, int b) { Ctl::setBorderColor(r, g, b); btnUp.setBorderColor(r, g, b); btnDown.setBorderColor(r, g, b); btnLeft.setBorderColor(r, g, b); btnRight.setBorderColor(r, g, b); btnSliderV.setBorderColor(r, g, b); btnSliderH.setBorderColor(r, g, b); } void ScrollHV::setBounds(int x, int y, int w, int h) { w = w == -1 ? _buttonWidth : w; h = h == -1 ? _buttonHeight : h; set_rect(_bounds,x,y,w,h); refresh(); } void ScrollHV::refresh() { int x = _bounds.x; int y = _bounds.y; int w = _bounds.w; int h = _bounds.h; int bh = _buttonHeight; int bw = _buttonWidth; bwv = btnUp.isVisible() ? bw : 0, bhv = btnUp.isVisible() ? bh : 0; bwh = btnLeft.isVisible() ? bw : 0, bhh = btnLeft.isVisible() ? bh : 0; btnUp.setBounds(x+w-bwv, y, bwv, bhv); btnDown.setBounds(x+w-bwv, y+h-bhh-bhv, bw, bh); btnLeft.setBounds(x, y+h-bhh, bw, bh); btnRight.setBounds(x+w-bwv-bwh, y+h-bhh, bw, bh); int vdr = isStripH() ? bh : 0; int hdr = isStripV() ? bh : 0; if(bhv == 0 && vdr != 0) _barLenV = h-vdr-bhh; else _barLenV = h-bhv-bhv-bhh; if(bwh == 0 && hdr != 0) _barLenH = w-hdr-bwv; else _barLenH = w-bwh-bwh-bwv; btnBarV.setBounds(x+w-bw, y+bhv, bw, _barLenV); btnBarH.setBounds(x+bwh, y+h-bh, _barLenH, bh); _rangeV -= _isvdr ? vdr : 0; _rangeH -= _ishdr ? hdr : 0; setSliderV(); setSliderH(); setValueV(_valueV); setValueH(_valueH); } void ScrollHV::setSizeV(int maxV, int rangeV) { _sizeV = maxV + 1; if(_isvdr = rangeV == -1) _rangeV = _bounds.h; else _rangeV = rangeV; _maxV = std::max(0, maxV - (rangeV-1)); btnUp.setVisible(_state.test(ButtonsV) ? (_maxV > 0) : false); btnDown.setVisible(_state.test(ButtonsV) ? (_maxV > 0) : false); btnSliderV.setVisible(_state.test(SliderV) ? (_maxV > 0) : false); refresh(); } void ScrollHV::setSizeH(int maxH, int rangeH) { _sizeH = maxH + 1; if(_ishdr = rangeH == -1) _rangeH = _bounds.w; else _rangeH = rangeH; _maxH = std::max(0, maxH - (_rangeH-1)); btnLeft.setVisible(_state.test(ButtonsH) ? (_maxH > 0) : false); btnRight.setVisible(_state.test(ButtonsH) ? (_maxH > 0) : false); btnSliderH.setVisible(_state.test(SliderH) ? (_maxH > 0) : false); _valueH = 0; refresh(); } void ScrollHV::setSliderV() { int bh = _buttonHeight; int bw = _buttonWidth; int x = _bounds.x, y = _bounds.y; int w = _bounds.w, h = _bounds.h; float sh = mp::ruleof3(_rangeV, _maxV, _barLenV);//Sliderhöhe (in Pixel) sh = num::fit(sh, _barLenV/3.f, _barLenV * 7.f/8.f);//Sliderhöhe min max: _barLenV/3.f <= sh <= _barLenV * 7.f/8.f _slRangeV = _barLenV - sh;//Verschiebbare Spanne des Sliders (in Pixel) int slPos = std::max((float)(y + bhv), y + bhv + (_slRangeV * _valueV / std::max(1.f, (float)_maxV))); btnSliderV.setBounds(x+w-bw, slPos, bw, (int)sh+1); } void ScrollHV::setSliderH() { int bh = _buttonHeight; int bw = _buttonWidth; int x = _bounds.x, y = _bounds.y; int w = _bounds.w, h = _bounds.h; float sw = mp::ruleof3(_rangeH, _maxH, _barLenH);//Sliderbreite (in Pixel) sw = num::fit(sw, _barLenH/3.f, _barLenH * 7.f/8.f);//Sliderbreite min max: _barLenH/3.f <= sh <= _barLenH * 7.f/8.f _slRangeH = _barLenH - sw;//Verschiebbare Spanne des Sliders (in Pixel) int slPos = std::max((float)(x + bwh), x + bwh + (_slRangeH * _valueH / std::max(1.f, (float)_maxH))); btnSliderH.setBounds(slPos, y+h-bh, (int)sw+1, bh); } void ScrollHV::setValueV(int valueV) { if(valueV < 0) _valueV = 0; else if(valueV > _maxV) _valueV = _maxV; else _valueV = valueV; setSliderV(); } void ScrollHV::setValueH(int valueH) { if(valueH < 0) _valueH = 0; else if(valueH > _maxH) _valueH = _maxH; else _valueH = valueH; setSliderH(); } void ScrollHV::changeValueV(int updown, int incr) { int newVal = _valueV; if(updown == PLUS) { setValueV(newVal + incr); } else//MINUS { setValueV(newVal - incr); } } void ScrollHV::changeValueH(int leftRight, int incr) { int newVal = _valueH; if(leftRight == PLUS) { setValueH(newVal + incr); } else//MINUS { setValueH(newVal - incr); } } int ScrollHV::processEvent() { if(!_isVisible) return 0; double valueV = _valueV; int result = 0; //SliderV... if(_state.test(SliderV)) { if(btnSliderV.processEvent() == 1)//MouseDown { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); _startY = tpos.y - btnSliderV.bounds().y; } if(btnSliderV.isMouseDown()) { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); tpos.y -= btnSliderV.bounds().y; int dy = (tpos.y - _startY); int dv = dy / (float)_slRangeV * _maxV; int val = _valueV; val += dv; setValueV(val); } //Zwischenraum (Vertikale Leiste).. if(btnBarV.processEvent() == 2)//MouseUp { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); if(tpos.y > btnSliderV.bounds().y + btnSliderV.bounds().h) { if(!_blockMausUp) changeValueV(PLUS, _rangeV-1); result = 2; } else if(tpos.y < btnSliderV.bounds().y) { if(!_blockMausUp) changeValueV(MINUS, _rangeV-1); result = 1; } else _blockMausUp = false; } } //SliderH... if(_state.test(SliderH)) { if(btnSliderH.processEvent() == 1)//MouseDown { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); _startX = tpos.x - btnSliderH.bounds().x; } if(btnSliderH.isMouseDown()) { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); tpos.x -= btnSliderH.bounds().x; int dx = (tpos.x - _startX); int dv = dx / (float)_slRangeH * _maxH; int val = _valueH; val += dv; setValueH(val); } //Zwischenraum (Horizonale Leiste).. if(btnBarH.processEvent() == 2)//MouseUp { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(mouse_x,mouse_y), &tpos); if(tpos.x > btnSliderH.bounds().x + btnSliderH.bounds().w) { if(!_blockMausUp) changeValueH(PLUS, _rangeH-1); result = 5; } else if(tpos.x < btnSliderH.bounds().x) { if(!_blockMausUp) changeValueH(MINUS, _rangeH-1); result = 4; } else _blockMausUp = false; } } //Up Down Buttons... if(_state.test(ButtonsV)) { if(btnDown.processEvent() == 2)//MouseUp { if(!_blockMausUp) changeValueV(PLUS); result = 2; } else _blockMausUp = false; if(btnUp.processEvent() == 2)//MouseUp { if(!_blockMausUp) changeValueV(MINUS); result = 1; } else _blockMausUp = false; } //Left Right Buttons... if(_state.test(ButtonsH)) { if(btnRight.processEvent() == 2)//MouseUp { if(!_blockMausUp) changeValueH(PLUS); result = 5; } else _blockMausUp = false; if(btnLeft.processEvent() == 2)//MouseUp { if(!_blockMausUp) changeValueH(MINUS); result = 4; } else _blockMausUp = false; } if(Input::mouse(fire_on::leftDown)) { _isActive = _isHover; } if(_isActive) { if(Input::keyboard() && _isKeyControl) { int key = Input::key(); switch(key) { case SDLK_DOWN: changeValueV(PLUS); result = 2; break; case SDLK_UP: changeValueV(MINUS); result = 1; break; case SDLK_RIGHT: changeValueH(PLUS); result = 5; break; case SDLK_LEFT: changeValueH(MINUS); result = 4; break; case 13://Return... _isActive = false; result = 3; break; } } else if(Input::mouse(fire_on::wheelUp)) { changeValueV(MINUS, _wheelIncr); result = 1; } else if(Input::mouse(fire_on::wheelDown)) { changeValueV(PLUS, _wheelIncr); result = 2; } else if(Input::mouse(fire_on::leftDown)) { if(isNotOverBar(Input::x, Input::y)) { if(_isSelectableOnClick) { mousePos2rowIdx(Input::y); result = 6; } } } } if(_isHover && isNotOverBar(Input::x, Input::y)) mousePos2hovRow(Input::y); else _hoverRow = -1; return result; } bool ScrollHV::isNotOverBar(int x, int y) { int x1 = _bounds.x; int x2 = x1 + _bounds.w - (isStripV() ? _buttonWidth : 0); int y1 = _bounds.y; int y2 = y1 + _bounds.h - (isStripH() ? _buttonHeight : 0); Vector2d tpos; gApp.guiPlane->reTransformPos(Point(x,y), &tpos); return tpos.x >= x1 && tpos.x <= x2 && tpos.y >= y1 && tpos.y <= y2; } void ScrollHV::mousePos2rowIdx(int ypos) { Vector2d tpos; gApp.guiPlane->reTransformPos(Point(0,ypos), &tpos); int y = std::max(0, tpos.y - _bounds.y - _distFirstRow); _selectedRow = y / _rowHeight + _valueV; _selectedRow = std::min(_sizeV-1, _selectedRow); } void ScrollHV::mousePos2hovRow(int ypos) { Vector2d tpos; gApp.guiPlane->reTransformPos(Point(0,ypos), &tpos); int y = std::max(0, tpos.y - _bounds.y - _distFirstRow); _hoverRow = y / _rowHeight + _valueV; _hoverRow = std::min(_sizeV-1, _hoverRow); } int ScrollHV::repeatEvent() { int result = 0; double valueV = _valueV; if(btnUp.isMouseDown()) { if(_mausDownTime > 0.3f) { changeValueV(MINUS); result = 1; _blockMausUp = true; set_sleep } _mausDownTime += frame_sec; } else if(btnDown.isMouseDown()) { if(_mausDownTime > 0.3f) { changeValueV(PLUS); result = 2; _blockMausUp = true; set_sleep } _mausDownTime += frame_sec; } else if(btnRight.isMouseDown()) { if(_mausDownTime > 0.3f) { changeValueH(PLUS); result = 5; _blockMausUp = true; set_sleep } _mausDownTime += frame_sec; } else if(btnLeft.isMouseDown()) { if(_mausDownTime > 0.3f) { changeValueH(MINUS); result = 4; _blockMausUp = true; set_sleep } _mausDownTime += frame_sec; } else if(btnBarV.isMouseDown()) { if(_mausDownTime > 0.3f) { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); if(mouse_y > btnSliderV.bounds().y + btnSliderV.bounds().h) { changeValueV(PLUS, _rangeV-1); _blockMausUp = true; result = 2; set_sleep } else if(mouse_y < btnSliderV.bounds().y) { changeValueV(MINUS, _rangeV-1); _blockMausUp = true; result = 1; set_sleep } } _mausDownTime += frame_sec; } else if(btnBarH.isMouseDown()) { if(_mausDownTime > 0.3f) { int mouse_x, mouse_y; SDL_GetMouseState(&mouse_x, &mouse_y); if(mouse_x > btnSliderH.bounds().x + btnSliderH.bounds().w) { changeValueH(PLUS, _rangeH-1); _blockMausUp = true; result = 5; set_sleep } else if(mouse_x < btnSliderH.bounds().x) { changeValueH(MINUS, _rangeH-1); _blockMausUp = true; result = 4; set_sleep } } _mausDownTime += frame_sec; } else { _blockMausUp = false; _mausDownTime = 0.0f; } return result; } bool ScrollHV::isStripH() { return _state.test(ButtonsH) || _state.test(SliderH); } bool ScrollHV::isStripV() { return _state.test(ButtonsV) || _state.test(SliderV); } void ScrollHV::drawSelRow() { if(_selectedRow >= _sizeV) return; int x = _bounds.x; int y = _bounds.y + (_selectedRow - _valueV) * _rowHeight + _distFirstRow; int w = _bounds.w - (isStripV() ? _buttonWidth : 0); int h = _rowHeight; if(y >= _bounds.y && (y + h) <= _bounds.y + _bounds.h - (isStripH() ? _buttonHeight : 0) + 1) gApp.guiPlane->drawFilledRect(Rect(x, y, w, h), _selRowCol, _alpha/2.5); } void ScrollHV::drawHovRow() { if(_hoverRow >= _sizeV) return; int x = _bounds.x; int y = _bounds.y + (_hoverRow - _valueV) * _rowHeight + _distFirstRow; int w = _bounds.w - (isStripV() ? _buttonWidth : 0); int h = _rowHeight; if(y >= _bounds.y && (y + h) <= _bounds.y + _bounds.h - (isStripH() ? _buttonHeight : 0) + 1) gApp.guiPlane->drawFilledRect(Rect(x, y, w, h), Color(255,255,255) , _alpha/6); } void ScrollHV::draw() { if(!_isVisible) return; checkLocalCursorPosition(); //BACKCOLOR.. if(_isFilled) { gApp.guiPlane->drawFilledRect(_bounds, _backColor, _alpha); } if(_isRowSelection) drawSelRow(); if(_showHoverRow) drawHovRow(); //SCROLLBAR HINTERGRUND.. if(isStripV()) { int x = _bounds.x + _bounds.w - _buttonWidth; gApp.guiPlane->drawFilledRect(Rect(x, _bounds.y, _buttonWidth, _bounds.h), Color(15,25,35), _alpha); btnBarV.draw(); } if(isStripH()) { int y = _bounds.y + _bounds.h - _buttonHeight; gApp.guiPlane->drawFilledRect(Rect(_bounds.x, y, _bounds.w, _buttonHeight), Color(15,25,35), _alpha); btnBarH.draw(); } //RAHMEN.. if(_isBorder) { gApp.guiPlane->drawRect(_bounds, _borderColor, 2, _alpha); } setButtonsAlpha(_alpha); if(_isButtonBorder)//?? { //BUTTONS (Draw-order in Abhängigkeit von Cursorposition).. if(btnUp.isHover()) { btnSliderH.draw(); btnSliderV.draw(); btnRight.draw(); btnLeft.draw(); btnDown.draw(); btnUp.draw(); } else if(btnDown.isHover()) { btnSliderH.draw(); btnSliderV.draw(); btnRight.draw(); btnLeft.draw(); btnUp.draw(); btnDown.draw(); } else if(btnLeft.isHover()) { btnRight.draw(); btnUp.draw(); btnDown.draw(); btnSliderH.draw(); btnSliderV.draw(); btnLeft.draw(); } else if(btnRight.isHover()) { btnLeft.draw(); btnUp.draw(); btnDown.draw(); btnSliderH.draw(); btnSliderV.draw(); btnRight.draw(); } else if(btnSliderV.isHover()) { btnRight.draw(); btnLeft.draw(); btnUp.draw(); btnDown.draw(); btnSliderH.draw(); btnSliderV.draw(); } else { btnRight.draw(); btnLeft.draw(); btnUp.draw(); btnDown.draw(); btnSliderV.draw(); btnSliderH.draw(); } } else//Wenn kein Rahmen, Draw-Order immer gleich.. { btnSliderH.draw(); btnSliderV.draw(); btnRight.draw(); btnLeft.draw(); btnUp.draw(); btnDown.draw(); } } void ScrollHV::setBorder(bool isBorder, bool isButtonBorder) { _isBorder = isBorder; _isButtonBorder = isButtonBorder; btnUp.setBorder(isButtonBorder); btnDown.setBorder(isButtonBorder); btnLeft.setBorder(isButtonBorder); btnRight.setBorder(isButtonBorder); btnSliderV.setBorder(isButtonBorder); btnSliderH.setBorder(isButtonBorder); } void ScrollHV::setFilled(bool isFilled, bool isButtonFilled) { _isFilled = isFilled; btnUp.setFilled(isButtonFilled); btnDown.setFilled(isButtonFilled); btnLeft.setFilled(isButtonFilled); btnRight.setFilled(isButtonFilled); btnSliderV.setFilled(isButtonFilled); btnSliderH.setFilled(isButtonFilled); } void ScrollHV::setButtonsAlpha(float a) { if(_lastAlpha != a) { _lastAlpha = a; btnRight.setAlpha(a); btnLeft.setAlpha(a); btnUp.setAlpha(a); btnDown.setAlpha(a); btnSliderH.setAlpha(a); btnSliderV.setAlpha(a); } }