Reworked the thumb drawing code, thumb calculation code, channel
calculation code, and corrected some bugs in how tics are drawn and how clicks are handled.
This commit is contained in:
parent
c616625945
commit
f64a59f2fe
|
@ -7,7 +7,6 @@
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
* - Some messages.
|
* - Some messages.
|
||||||
* - more display code.
|
|
||||||
* - handle dragging slider better
|
* - handle dragging slider better
|
||||||
* - better tic handling.
|
* - better tic handling.
|
||||||
* - more notifications.
|
* - more notifications.
|
||||||
|
@ -19,7 +18,6 @@
|
||||||
-TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
|
-TBM_SETRANGEMAX & TBM_SETRANGEMIN should only change the view of the
|
||||||
trackbar, not the actual amount of tics in the list.
|
trackbar, not the actual amount of tics in the list.
|
||||||
-TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
|
-TBM_GETTIC & TBM_GETTICPOS shouldn't rely on infoPtr->tics being sorted.
|
||||||
- Make drawing code exact match of w95 drawing.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,47 +113,43 @@ static VOID
|
||||||
TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
|
TRACKBAR_CalcChannel (HWND hwnd, TRACKBAR_INFO *infoPtr)
|
||||||
{
|
{
|
||||||
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
|
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
|
||||||
INT cyChannel;
|
INT cyChannel,offsettop,offsetedge;
|
||||||
RECT lpRect,*channel = & infoPtr->rcChannel;
|
RECT lpRect,*channel = & infoPtr->rcChannel;
|
||||||
|
|
||||||
GetClientRect (hwnd, &lpRect);
|
GetClientRect (hwnd, &lpRect);
|
||||||
|
|
||||||
if (dwStyle & TBS_ENABLESELRANGE)
|
if (dwStyle & TBS_ENABLESELRANGE)
|
||||||
cyChannel = max(infoPtr->uThumbLen - 8, 4);
|
cyChannel = ((int)(infoPtr->uThumbLen/4.5)+1)*3;
|
||||||
else
|
else
|
||||||
cyChannel = 4;
|
cyChannel = 4;
|
||||||
|
|
||||||
if (dwStyle & TBS_VERT) {
|
offsettop = (int)(infoPtr->uThumbLen/4.5);
|
||||||
channel->top = lpRect.top + 8;
|
offsetedge = (int)(infoPtr->uThumbLen/4.5) + 3;
|
||||||
channel->bottom = lpRect.bottom - 8;
|
|
||||||
|
|
||||||
if (dwStyle & TBS_BOTH) {
|
if (dwStyle & TBS_VERT) {
|
||||||
channel->left = (lpRect.right - cyChannel) / 2;
|
channel->top = lpRect.top + offsetedge;
|
||||||
channel->right = (lpRect.right + cyChannel) / 2;
|
channel->bottom = lpRect.bottom - offsetedge;
|
||||||
}
|
|
||||||
else if (dwStyle & TBS_LEFT) {
|
if (dwStyle & (TBS_BOTH | TBS_LEFT)) {
|
||||||
channel->left = lpRect.left + 10;
|
channel->left = lpRect.left + offsettop + 8 ;
|
||||||
channel->right = channel->left + cyChannel;
|
channel->right = channel->left + cyChannel;
|
||||||
}
|
}
|
||||||
else { /* TBS_RIGHT */
|
else { /* TBS_RIGHT */
|
||||||
channel->right = lpRect.right - 10;
|
channel->left = lpRect.left + offsettop;
|
||||||
channel->left = channel->right - cyChannel;
|
channel->right = channel->left + cyChannel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
channel->left = lpRect.left + 8;
|
channel->left = lpRect.left + offsetedge;
|
||||||
channel->right = lpRect.right - 8;
|
channel->right = lpRect.right - offsetedge;
|
||||||
if (dwStyle & TBS_BOTH) {
|
|
||||||
channel->top = (lpRect.bottom - cyChannel) / 2;
|
if (dwStyle & (TBS_BOTH|TBS_TOP)) {
|
||||||
channel->bottom = (lpRect.bottom + cyChannel) / 2;
|
channel->top = lpRect.top + offsettop + 8 ;
|
||||||
}
|
channel->bottom = channel->top + cyChannel;
|
||||||
else if (dwStyle & TBS_TOP) {
|
|
||||||
channel->top = lpRect.top + 10;
|
|
||||||
channel->bottom = channel->top + cyChannel;
|
|
||||||
}
|
}
|
||||||
else { /* TBS_BOTTOM */
|
else { /* TBS_BOTTOM */
|
||||||
channel->bottom = lpRect.bottom - 10;
|
channel->top = lpRect.top + offsettop;
|
||||||
channel->top = channel->bottom - cyChannel;
|
channel->bottom = channel->top + cyChannel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,26 +158,40 @@ static VOID
|
||||||
TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
|
TRACKBAR_CalcThumb (HWND hwnd, TRACKBAR_INFO *infoPtr)
|
||||||
{
|
{
|
||||||
RECT *thumb;
|
RECT *thumb;
|
||||||
int range, width;
|
int range, width, thumbdepth;
|
||||||
|
DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
|
||||||
|
|
||||||
thumb=&infoPtr->rcThumb;
|
thumb=&infoPtr->rcThumb;
|
||||||
range=infoPtr->nRangeMax - infoPtr->nRangeMin;
|
range=infoPtr->nRangeMax - infoPtr->nRangeMin;
|
||||||
if (!range) return; /* FIXME: may this happen? */
|
thumbdepth = ((INT)((FLOAT)infoPtr->uThumbLen / 4.5) * 2) + 2;
|
||||||
if (GetWindowLongA (hwnd, GWL_STYLE) & TBS_VERT) {
|
|
||||||
width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
|
|
||||||
thumb->left = infoPtr->rcChannel.left - 1;
|
|
||||||
thumb->right = infoPtr->rcChannel.left + infoPtr->uThumbLen - 8;
|
|
||||||
thumb->top = infoPtr->rcChannel.top +
|
|
||||||
(width*infoPtr->nPos)/range - 5;
|
|
||||||
thumb->bottom = thumb->top + infoPtr->uThumbLen/3;
|
|
||||||
|
|
||||||
} else {
|
if (!range) return; /* FIXME: may this happen? */
|
||||||
|
|
||||||
|
if (dwStyle & TBS_VERT)
|
||||||
|
{
|
||||||
|
width=infoPtr->rcChannel.bottom - infoPtr->rcChannel.top;
|
||||||
|
|
||||||
|
if (dwStyle & (TBS_BOTH | TBS_LEFT))
|
||||||
|
thumb->left = 10;
|
||||||
|
else
|
||||||
|
thumb-> left =2;
|
||||||
|
thumb->right = thumb -> left + infoPtr->uThumbLen;
|
||||||
|
thumb->top = infoPtr->rcChannel.top +
|
||||||
|
(width*infoPtr->nPos)/range - thumbdepth/2;
|
||||||
|
thumb->bottom = thumb->top + thumbdepth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
|
width=infoPtr->rcChannel.right - infoPtr->rcChannel.left;
|
||||||
thumb->left = infoPtr->rcChannel.left +
|
|
||||||
(width*infoPtr->nPos)/range - 5;
|
thumb->left = infoPtr->rcChannel.left +
|
||||||
thumb->right = thumb->left + infoPtr->uThumbLen/3;
|
(width*infoPtr->nPos)/range - thumbdepth/2;
|
||||||
thumb->top = infoPtr->rcChannel.top - 1;
|
thumb->right = thumb->left + thumbdepth;
|
||||||
thumb->bottom = infoPtr->rcChannel.top + infoPtr->uThumbLen - 8;
|
if (dwStyle & (TBS_BOTH | TBS_TOP))
|
||||||
|
thumb->top = 10;
|
||||||
|
else
|
||||||
|
thumb->top = 2;
|
||||||
|
thumb->bottom = thumb -> top + infoPtr->uThumbLen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,10 +290,10 @@ TRACKBAR_DrawVertTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
|
||||||
width=rcChannel.bottom - rcChannel.top;
|
width=rcChannel.bottom - rcChannel.top;
|
||||||
|
|
||||||
if (flags & TBS_TOP) {
|
if (flags & TBS_TOP) {
|
||||||
x=rcChannel.right-2;
|
x=rcChannel.left-2;
|
||||||
side=-1;
|
side=-1;
|
||||||
} else {
|
} else {
|
||||||
x=rcChannel.left+2;
|
x=rcChannel.right+2;
|
||||||
side=1;
|
side=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +353,141 @@ TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
|
||||||
|
{
|
||||||
|
HBRUSH oldbr,hbr = GetSysColorBrush(COLOR_BTNFACE);
|
||||||
|
HPEN oldpen=(HPEN)NULL,hpn;
|
||||||
|
RECT thumb = infoPtr->rcThumb;
|
||||||
|
int BlackUntil=3;
|
||||||
|
int PointCount=6;
|
||||||
|
POINT points[6];
|
||||||
|
|
||||||
|
static INT PointDepth = 4;
|
||||||
|
|
||||||
|
oldbr = SelectObject (hdc, hbr);
|
||||||
|
SetPolyFillMode (hdc,WINDING);
|
||||||
|
|
||||||
|
if (dwStyle & TBS_BOTH)
|
||||||
|
{
|
||||||
|
points[0].x=thumb.right;
|
||||||
|
points[0].y=thumb.top;
|
||||||
|
points[1].x=thumb.right;
|
||||||
|
points[1].y=thumb.bottom;
|
||||||
|
points[2].x=thumb.left;
|
||||||
|
points[2].y=thumb.bottom;
|
||||||
|
points[3].x=thumb.left;
|
||||||
|
points[3].y=thumb.top;
|
||||||
|
points[4].x=points[0].x;
|
||||||
|
points[4].y=points[0].y;
|
||||||
|
PointCount = 5;
|
||||||
|
BlackUntil = 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dwStyle & TBS_VERT)
|
||||||
|
{
|
||||||
|
if (dwStyle & TBS_LEFT)
|
||||||
|
{
|
||||||
|
points[0].x=thumb.right;
|
||||||
|
points[0].y=thumb.top;
|
||||||
|
points[1].x=thumb.right;
|
||||||
|
points[1].y=thumb.bottom;
|
||||||
|
points[2].x=thumb.left + PointDepth;
|
||||||
|
points[2].y=thumb.bottom;
|
||||||
|
points[3].x=thumb.left;
|
||||||
|
points[3].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
|
||||||
|
points[4].x=thumb.left + PointDepth;
|
||||||
|
points[4].y=thumb.top;
|
||||||
|
points[5].x=points[0].x;
|
||||||
|
points[5].y=points[0].y;
|
||||||
|
BlackUntil = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
points[0].x=thumb.right;
|
||||||
|
points[0].y=(thumb.bottom - thumb.top) / 2 + thumb.top;
|
||||||
|
points[1].x=thumb.right - PointDepth;
|
||||||
|
points[1].y=thumb.bottom;
|
||||||
|
points[2].x=thumb.left;
|
||||||
|
points[2].y=thumb.bottom;
|
||||||
|
points[3].x=thumb.left;
|
||||||
|
points[3].y=thumb.top;
|
||||||
|
points[4].x=thumb.right - PointDepth;
|
||||||
|
points[4].y=thumb.top;
|
||||||
|
points[5].x=points[0].x;
|
||||||
|
points[5].y=points[0].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dwStyle & TBS_TOP)
|
||||||
|
{
|
||||||
|
points[0].x=(thumb.right - thumb.left) / 2 + thumb.left ;
|
||||||
|
points[0].y=thumb.top;
|
||||||
|
points[1].x=thumb.right;
|
||||||
|
points[1].y=thumb.top + PointDepth;
|
||||||
|
points[2].x=thumb.right;
|
||||||
|
points[2].y=thumb.bottom;
|
||||||
|
points[3].x=thumb.left;
|
||||||
|
points[3].y=thumb.bottom;
|
||||||
|
points[4].x=thumb.left;
|
||||||
|
points[4].y=thumb.top + PointDepth;
|
||||||
|
points[5].x=points[0].x;
|
||||||
|
points[5].y=points[0].y;
|
||||||
|
BlackUntil = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
points[0].x=thumb.right;
|
||||||
|
points[0].y=thumb.top;
|
||||||
|
points[1].x=thumb.right;
|
||||||
|
points[1].y=thumb.bottom - PointDepth;
|
||||||
|
points[2].x=(thumb.right - thumb.left) / 2 + thumb.left ;
|
||||||
|
points[2].y=thumb.bottom;
|
||||||
|
points[3].x=thumb.left;
|
||||||
|
points[3].y=thumb.bottom - PointDepth;
|
||||||
|
points[4].x=thumb.left;
|
||||||
|
points[4].y=thumb.top;
|
||||||
|
points[5].x=points[0].x;
|
||||||
|
points[5].y=points[0].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill the shape
|
||||||
|
*/
|
||||||
|
Polygon (hdc, points, PointCount);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw the edge
|
||||||
|
*/
|
||||||
|
hpn = GetStockObject(BLACK_PEN);
|
||||||
|
oldpen = SelectObject(hdc,hpn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Black part
|
||||||
|
*/
|
||||||
|
Polyline(hdc,points,BlackUntil);
|
||||||
|
|
||||||
|
SelectObject(hdc,oldpen);
|
||||||
|
hpn = GetStockObject(WHITE_PEN);
|
||||||
|
SelectObject(hdc,hpn);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* White Part
|
||||||
|
*/
|
||||||
|
Polyline(hdc,&points[BlackUntil-1],PointCount+1-BlackUntil);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* restore the brush and pen
|
||||||
|
*/
|
||||||
|
SelectObject(hdc,oldbr);
|
||||||
|
if (oldpen)
|
||||||
|
SelectObject(hdc,oldpen);
|
||||||
|
}
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
TRACKBAR_Refresh (HWND hwnd, HDC hdc)
|
TRACKBAR_Refresh (HWND hwnd, HDC hdc)
|
||||||
|
@ -419,42 +562,9 @@ TRACKBAR_Refresh (HWND hwnd, HDC hdc)
|
||||||
|
|
||||||
/* draw thumb */
|
/* draw thumb */
|
||||||
|
|
||||||
if (!(dwStyle & TBS_NOTHUMB)) {
|
if (!(dwStyle & TBS_NOTHUMB))
|
||||||
|
{
|
||||||
HBRUSH hbr = CreateSolidBrush (COLOR_BTNFACE);
|
TRACKBAR_DrawThumb(infoPtr,hdc,dwStyle);
|
||||||
RECT thumb = infoPtr->rcThumb;
|
|
||||||
|
|
||||||
SelectObject (hdc, hbr);
|
|
||||||
|
|
||||||
if (dwStyle & TBS_BOTH) {
|
|
||||||
FillRect (hdc, &thumb, hbr);
|
|
||||||
DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
|
|
||||||
} else {
|
|
||||||
POINT points[5];
|
|
||||||
|
|
||||||
/* first, fill the thumb */
|
|
||||||
/* FIXME: revamp. check for TBS_VERT */
|
|
||||||
|
|
||||||
SetPolyFillMode (hdc,WINDING);
|
|
||||||
points[0].x=thumb.left;
|
|
||||||
points[0].y=thumb.top;
|
|
||||||
points[1].x=thumb.right - 1;
|
|
||||||
points[1].y=thumb.top;
|
|
||||||
points[2].x=thumb.right - 1;
|
|
||||||
points[2].y=thumb.bottom -2;
|
|
||||||
points[3].x=thumb.left;
|
|
||||||
points[3].y=thumb.bottom -2;
|
|
||||||
points[4].x=points[0].x;
|
|
||||||
points[4].y=points[0].y;
|
|
||||||
Polygon (hdc, points, 5);
|
|
||||||
|
|
||||||
if (dwStyle & TBS_VERT) {
|
|
||||||
/* draw edge */
|
|
||||||
} else {
|
|
||||||
DrawEdge (hdc, &thumb, EDGE_RAISED, BF_TOPLEFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DeleteObject (hbr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoPtr->bFocus)
|
if (infoPtr->bFocus)
|
||||||
|
@ -1144,23 +1254,15 @@ TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
|
TRACKBAR_INFO *infoPtr = TRACKBAR_GetInfoPtr (hwnd);
|
||||||
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
|
DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
|
||||||
int clickPlace,prevPos,vertical;
|
POINT clickPoint;
|
||||||
DOUBLE clickPos;
|
|
||||||
|
|
||||||
SetFocus (hwnd);
|
SetFocus (hwnd);
|
||||||
|
|
||||||
vertical = (dwStyle & TBS_VERT) ? 1 : 0;
|
clickPoint.y = HIWORD(lParam);
|
||||||
if (vertical)
|
clickPoint.x = LOWORD(lParam);
|
||||||
clickPlace=(INT)HIWORD(lParam);
|
|
||||||
else
|
|
||||||
clickPlace=(INT)LOWORD(lParam);
|
|
||||||
|
|
||||||
if ((vertical &&
|
if (PtInRect(&(infoPtr->rcThumb),clickPoint))
|
||||||
(clickPlace>infoPtr->rcThumb.top) &&
|
{
|
||||||
(clickPlace<infoPtr->rcThumb.bottom)) ||
|
|
||||||
(!vertical &&
|
|
||||||
(clickPlace>infoPtr->rcThumb.left) &&
|
|
||||||
(clickPlace<infoPtr->rcThumb.right))) {
|
|
||||||
infoPtr->flags |= TB_DRAG_MODE;
|
infoPtr->flags |= TB_DRAG_MODE;
|
||||||
if (dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
|
if (dwStyle & TBS_TOOLTIPS) { /* enable tooltip */
|
||||||
TTTOOLINFOA ti;
|
TTTOOLINFOA ti;
|
||||||
|
@ -1181,25 +1283,39 @@ TRACKBAR_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (PtInRect(&(infoPtr->rcChannel),clickPoint))
|
||||||
|
{
|
||||||
|
int clickPlace,prevPos,vertical;
|
||||||
|
DOUBLE clickPos;
|
||||||
|
|
||||||
clickPos = TRACKBAR_ConvertPlaceToPosition (infoPtr, clickPlace, vertical);
|
vertical = (dwStyle & TBS_VERT) ? 1 : 0;
|
||||||
prevPos = infoPtr->nPos;
|
if (vertical)
|
||||||
|
clickPlace=(INT)HIWORD(lParam);
|
||||||
|
else
|
||||||
|
clickPlace=(INT)LOWORD(lParam);
|
||||||
|
|
||||||
if (vertical ^ (clickPos < (int)prevPos)) { /* similar to VK_NEXT */
|
clickPos = TRACKBAR_ConvertPlaceToPosition(infoPtr, clickPlace,
|
||||||
infoPtr->nPos += infoPtr->nPageSize;
|
vertical);
|
||||||
if (infoPtr->nPos > infoPtr->nRangeMax)
|
prevPos = infoPtr->nPos;
|
||||||
infoPtr->nPos = infoPtr->nRangeMax;
|
if (clickPos > (int)prevPos)
|
||||||
TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
|
{ /* similar to VK_NEXT */
|
||||||
} else {
|
infoPtr->nPos += infoPtr->nPageSize;
|
||||||
infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
|
if (infoPtr->nPos > infoPtr->nRangeMax)
|
||||||
if (infoPtr->nPos < infoPtr->nRangeMin)
|
infoPtr->nPos = infoPtr->nRangeMax;
|
||||||
infoPtr->nPos = infoPtr->nRangeMin;
|
TRACKBAR_SendNotify (hwnd, TB_PAGEUP);
|
||||||
TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
infoPtr->nPos -= infoPtr->nPageSize; /* similar to VK_PRIOR */
|
||||||
|
if (infoPtr->nPos < infoPtr->nRangeMin)
|
||||||
|
infoPtr->nPos = infoPtr->nRangeMin;
|
||||||
|
TRACKBAR_SendNotify (hwnd, TB_PAGEDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
if (prevPos!=infoPtr->nPos) {
|
if (prevPos!=infoPtr->nPos) {
|
||||||
infoPtr->flags |= TB_THUMBPOSCHANGED;
|
infoPtr->flags |= TB_THUMBPOSCHANGED;
|
||||||
InvalidateRect (hwnd, NULL, FALSE);
|
InvalidateRect (hwnd, NULL, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue