Initial commit
This commit is contained in:
245
engines/bagel/mfc/scrollbar.cpp
Normal file
245
engines/bagel/mfc/scrollbar.cpp
Normal file
@@ -0,0 +1,245 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/textconsole.h"
|
||||
#include "bagel/mfc/afxwin.h"
|
||||
|
||||
namespace Bagel {
|
||||
namespace MFC {
|
||||
|
||||
IMPLEMENT_DYNAMIC(CScrollBar, CWnd)
|
||||
BEGIN_MESSAGE_MAP(CScrollBar, CWnd)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_LBUTTONDOWN()
|
||||
ON_WM_LBUTTONUP()
|
||||
ON_WM_MOUSEMOVE()
|
||||
ON_WM_MOUSELEAVE()
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
bool CScrollBar::Create(uint32 dwStyle, const RECT &rect, CWnd *pParentWnd, unsigned int nID) {
|
||||
return CWnd::Create("SCROLLBAR", nullptr, dwStyle,
|
||||
rect, pParentWnd, nID);
|
||||
}
|
||||
|
||||
int CScrollBar::GetScrollPos() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
int CScrollBar::SetScrollPos(int nPos, bool bRedraw) {
|
||||
int oldPos = _value;
|
||||
_value = CLIP(nPos, _minValue, _maxValue);
|
||||
Invalidate();
|
||||
return oldPos;
|
||||
}
|
||||
|
||||
void CScrollBar::GetScrollRange(int *lpMinPos, int *lpMaxPos) const {
|
||||
if (lpMinPos)
|
||||
*lpMinPos = _minValue;
|
||||
if (lpMaxPos)
|
||||
*lpMaxPos = _maxValue;
|
||||
}
|
||||
|
||||
void CScrollBar::SetScrollRange(int nMinPos, int nMaxPos, bool bRedraw) {
|
||||
_minValue = nMinPos;
|
||||
_maxValue = nMaxPos;
|
||||
_pageSize = MAX<int>((_maxValue - _minValue + 1) / 10, 1);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
bool CScrollBar::SetScrollInfo(LPSCROLLINFO lpScrollInfo, bool bRedraw) {
|
||||
assert(lpScrollInfo->cbSize == sizeof(SCROLLINFO));
|
||||
_minValue = lpScrollInfo->nMin;
|
||||
_maxValue = lpScrollInfo->nMax;
|
||||
_pageSize = lpScrollInfo->nPage;
|
||||
_value = lpScrollInfo->nPos;
|
||||
|
||||
if (bRedraw)
|
||||
Invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CScrollBar::ShowScrollBar(bool bShow) {
|
||||
warning("TODO: CScrollBar::ShowScrollBar");
|
||||
}
|
||||
|
||||
void CScrollBar::OnPaint() {
|
||||
CPaintDC dc(this);
|
||||
CRect clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
const int thumbSize = clientRect.bottom;
|
||||
|
||||
// Clear background and draw border edge
|
||||
dc.FillSolidRect(&clientRect, RGB(211, 211, 211));
|
||||
CBrush borderBrush(RGB(0, 0, 0));
|
||||
dc.FrameRect(&clientRect, &borderBrush);
|
||||
|
||||
CRect left(0, 0, thumbSize, clientRect.bottom);
|
||||
drawSquare(dc, left);
|
||||
drawArrow(dc, left, true);
|
||||
CRect right(clientRect.right - thumbSize, 0,
|
||||
clientRect.right, clientRect.bottom);
|
||||
drawSquare(dc, right);
|
||||
drawArrow(dc, right, false);
|
||||
|
||||
drawSquare(dc, getThumbRect());
|
||||
}
|
||||
|
||||
void CScrollBar::drawSquare(CPaintDC &dc, const CRect &r) {
|
||||
CBrush black(RGB(0, 0, 0));
|
||||
dc.FrameRect(&r, &black);
|
||||
|
||||
CBrush darkGrey(RGB(169, 169, 169));
|
||||
CBrush white(RGB(255, 255, 255));
|
||||
CBrush *oldBrush = dc.SelectObject(&darkGrey);
|
||||
|
||||
dc.MoveTo(r.left + 2, r.bottom - 3);
|
||||
dc.LineTo(r.right - 2, r.bottom - 3);
|
||||
dc.MoveTo(r.left + 1, r.bottom - 2);
|
||||
dc.LineTo(r.right - 2, r.bottom - 2);
|
||||
dc.MoveTo(r.right - 3, r.top + 1);
|
||||
dc.LineTo(r.right - 3, r.bottom - 2);
|
||||
dc.MoveTo(r.right - 2, r.top + 1);
|
||||
dc.LineTo(r.right - 2, r.bottom - 2);
|
||||
|
||||
dc.MoveTo(r.left + 1, r.top + 1);
|
||||
dc.LineTo(r.right - 3, r.top + 1);
|
||||
dc.MoveTo(r.left + 1, r.top + 1);
|
||||
dc.MoveTo(r.left + 1, r.bottom - 3);
|
||||
|
||||
dc.SelectObject(oldBrush);
|
||||
}
|
||||
|
||||
void CScrollBar::drawArrow(CPaintDC &dc, const CRect &r, bool leftArrow) {
|
||||
int xCenter = (r.left + r.right) / 2;
|
||||
int yCenter = r.bottom / 2;
|
||||
int xDelta = leftArrow ? 1 : -1;
|
||||
int x = leftArrow ? xCenter - 3 : xCenter + 3;
|
||||
|
||||
CBrush black(RGB(0, 0, 0));
|
||||
CBrush *oldBrush = dc.SelectObject(&black);
|
||||
|
||||
for (int xCtr = 0; xCtr < 7; ++xCtr, x += xDelta) {
|
||||
int yDiff = (xCtr >= 4) ? 1 : xCtr;
|
||||
dc.MoveTo(x, yCenter - yDiff);
|
||||
dc.LineTo(x, yCenter + yDiff);
|
||||
}
|
||||
|
||||
dc.SelectObject(oldBrush);
|
||||
}
|
||||
|
||||
CRect CScrollBar::getThumbRect() const {
|
||||
CRect clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
|
||||
// The thumb will start after the left arrow button,
|
||||
// and at most, it will be drawn before the right arrow
|
||||
int slideArea = clientRect.right -
|
||||
(clientRect.bottom * 3) + 1;
|
||||
|
||||
int xStart = clientRect.bottom +
|
||||
slideArea * (_value - _minValue) /
|
||||
(_maxValue - _minValue);
|
||||
|
||||
return CRect(xStart, 0, xStart + clientRect.bottom,
|
||||
clientRect.bottom);
|
||||
}
|
||||
|
||||
int CScrollBar::getIndexFromX(int xp) const {
|
||||
CRect clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
|
||||
int slideStart = clientRect.bottom;
|
||||
int slideFinish = clientRect.right - (clientRect.bottom * 2) + 1;
|
||||
int slideArea = clientRect.right - (clientRect.bottom * 3) + 1;
|
||||
|
||||
if (xp < slideStart)
|
||||
return _minValue;
|
||||
if (xp >= slideFinish)
|
||||
return _maxValue;
|
||||
|
||||
return _minValue + (xp - slideStart)
|
||||
* (_maxValue - _minValue) / slideArea;
|
||||
}
|
||||
|
||||
void CScrollBar::OnLButtonDown(unsigned int nFlags, CPoint point) {
|
||||
CRect clientRect;
|
||||
GetClientRect(&clientRect);
|
||||
|
||||
if (point.x < clientRect.bottom) {
|
||||
// Left arrow button
|
||||
if (_value > _minValue) {
|
||||
SetScrollPos(_value - 1);
|
||||
scrollEvent(SB_LINELEFT);
|
||||
}
|
||||
|
||||
} else if (point.x >= (clientRect.right - clientRect.bottom)) {
|
||||
// Right arrow button
|
||||
if (_value < _maxValue) {
|
||||
SetScrollPos(_value + 1);
|
||||
scrollEvent(SB_LINERIGHT);
|
||||
}
|
||||
|
||||
} else {
|
||||
// We're in the slider area
|
||||
CRect thumbRect = getThumbRect();
|
||||
|
||||
if (point.x < thumbRect.left) {
|
||||
// Left of thumb, page left
|
||||
SetScrollPos(_value - _pageSize);
|
||||
scrollEvent(SB_PAGELEFT);
|
||||
} else if (point.x >= thumbRect.right) {
|
||||
// Right of thumb, page right
|
||||
SetScrollPos(_value + _pageSize);
|
||||
scrollEvent(SB_PAGERIGHT);
|
||||
} else {
|
||||
// Directly on thumb, so start dragging it
|
||||
SetScrollPos(getIndexFromX(point.x));
|
||||
SetCapture();
|
||||
scrollEvent(SB_THUMBTRACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CScrollBar::OnLButtonUp(unsigned int nFlags, CPoint point) {
|
||||
if (GetCapture() == m_hWnd) {
|
||||
ReleaseCapture();
|
||||
scrollEvent(SB_THUMBPOSITION);
|
||||
}
|
||||
|
||||
scrollEvent(SB_ENDSCROLL);
|
||||
}
|
||||
|
||||
void CScrollBar::OnMouseMove(unsigned int, CPoint point) {
|
||||
if (GetCapture() == m_hWnd) {
|
||||
SetScrollPos(getIndexFromX(point.x));
|
||||
scrollEvent(SB_THUMBTRACK);
|
||||
}
|
||||
}
|
||||
|
||||
void CScrollBar::scrollEvent(int action) {
|
||||
m_pParentWnd->SendMessage(WM_HSCROLL,
|
||||
MAKEWPARAM(action, _value),
|
||||
(LPARAM)m_hWnd);
|
||||
}
|
||||
|
||||
} // namespace MFC
|
||||
} // namespace Bagel
|
||||
Reference in New Issue
Block a user