Commit e54fdf21 authored by Dimitrie O. Paun's avatar Dimitrie O. Paun Committed by Alexandre Julliard

- Implement custom draw support.

- Fix thumb drawing. - Some cleanups, reorganizations, etc.
parent 1da4ea28
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* TODO:
* - custom draw notifications
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -88,6 +86,14 @@ DEFINE_COMMON_NOTIFICATIONS(TRACKBAR_INFO, hwndSelf); ...@@ -88,6 +86,14 @@ DEFINE_COMMON_NOTIFICATIONS(TRACKBAR_INFO, hwndSelf);
static BOOL TRACKBAR_SendNotify (TRACKBAR_INFO *infoPtr, UINT code); static BOOL TRACKBAR_SendNotify (TRACKBAR_INFO *infoPtr, UINT code);
static inline int
notify_customdraw(NMCUSTOMDRAW *pnmcd, int stage)
{
pnmcd->dwDrawStage = stage;
return SendMessageW (GetParent(pnmcd->hdr.hwndFrom), WM_NOTIFY,
pnmcd->hdr.idFrom, (LPARAM)pnmcd);
}
static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr) static void TRACKBAR_RecalculateTics (TRACKBAR_INFO *infoPtr)
{ {
int i, tic, nrTics; int i, tic, nrTics;
...@@ -283,17 +289,21 @@ TRACKBAR_InvalidateAll(TRACKBAR_INFO * infoPtr) ...@@ -283,17 +289,21 @@ TRACKBAR_InvalidateAll(TRACKBAR_INFO * infoPtr)
} }
static void static void
TRACKBAR_InvalidateThumbMove (TRACKBAR_INFO *infoPtr, LONG oldPos, LONG newPos) TRACKBAR_InvalidateThumb (TRACKBAR_INFO *infoPtr, LONG thumbPos)
{ {
RECT oldThumb; RECT rcThumb;
RECT newThumb;
TRACKBAR_CalcThumb(infoPtr, oldPos, &oldThumb); TRACKBAR_CalcThumb(infoPtr, thumbPos, &rcThumb);
TRACKBAR_CalcThumb(infoPtr, newPos, &newThumb); InflateRect(&rcThumb, 1, 1);
InflateRect(&oldThumb, 1, 1); InvalidateRect(infoPtr->hwndSelf, &rcThumb, FALSE);
InflateRect(&newThumb, 1, 1); }
InvalidateRect(infoPtr->hwndSelf, &oldThumb, FALSE);
InvalidateRect(infoPtr->hwndSelf, &newThumb, FALSE); static inline void
TRACKBAR_InvalidateThumbMove (TRACKBAR_INFO *infoPtr, LONG oldPos, LONG newPos)
{
TRACKBAR_InvalidateThumb (infoPtr, oldPos);
if (newPos != oldPos)
TRACKBAR_InvalidateThumb (infoPtr, newPos);
} }
static BOOL inline static BOOL inline
...@@ -356,10 +366,21 @@ TRACKBAR_AutoPage (TRACKBAR_INFO *infoPtr, POINT clickPoint) ...@@ -356,10 +366,21 @@ TRACKBAR_AutoPage (TRACKBAR_INFO *infoPtr, POINT clickPoint)
/* Trackbar drawing code. I like my spaghetti done milanese. */ /* Trackbar drawing code. I like my spaghetti done milanese. */
/* ticPos is in tic-units, not in pixels */ static void
TRACKBAR_DrawChannel (TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
{
RECT rcChannel = infoPtr->rcChannel;
DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */
FillRect (hdc, &rcChannel, GetStockObject(WHITE_BRUSH));
if (TRACKBAR_HasSelection(infoPtr))
FillRect (hdc, &infoPtr->rcSelection, GetSysColorBrush(COLOR_HIGHLIGHT));
}
}
static void static void
TRACKBAR_DrawTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags) TRACKBAR_DrawOneTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags)
{ {
int x, y, ox, oy, range, side, offset = 5, indent = 0, len = 3; int x, y, ox, oy, range, side, offset = 5, indent = 0, len = 3;
RECT rcTics; RECT rcTics;
...@@ -431,16 +452,46 @@ TRACKBAR_DrawTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags) ...@@ -431,16 +452,46 @@ TRACKBAR_DrawTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags)
} }
static void static inline void
TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags) TRACKBAR_DrawTic (TRACKBAR_INFO *infoPtr, HDC hdc, LONG ticPos, int flags)
{ {
TRACE("\n");
if ((flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH)) if ((flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH))
TRACKBAR_DrawTic (infoPtr, hdc, ticPos, flags | TBS_LEFT); TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags | TBS_LEFT);
if (!(flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH)) if (!(flags & (TBS_LEFT | TBS_TOP)) || (flags & TBS_BOTH))
TRACKBAR_DrawTic (infoPtr, hdc, ticPos, flags); TRACKBAR_DrawOneTic (infoPtr, hdc, ticPos, flags);
}
static void
TRACKBAR_DrawTics (TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
{
int i, ticFlags = dwStyle & 0x0f;
LOGPEN ticPen = { PS_SOLID, {1, 0}, GetSysColor (COLOR_3DDKSHADOW) };
HPEN hOldPen, hTicPen;
/* create the pen to draw the tics with */
hTicPen = CreatePenIndirect(&ticPen);
hOldPen = hTicPen ? SelectObject(hdc, hTicPen) : 0;
/* actually draw the tics */
for (i=0; i<infoPtr->uNumTics; i++)
TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->tics[i], ticFlags);
TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lRangeMin, ticFlags | TIC_EDGE);
TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lRangeMax, ticFlags | TIC_EDGE);
if ((dwStyle & TBS_ENABLESELRANGE) && TRACKBAR_HasSelection(infoPtr)) {
TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lSelMin,
ticFlags | TIC_SELECTIONMARKMIN);
TRACKBAR_DrawTic (infoPtr, hdc, infoPtr->lSelMax,
ticFlags | TIC_SELECTIONMARKMAX);
}
/* clean up the pen, if we created one */
if (hTicPen) {
SelectObject(hdc, hOldPen);
DeleteObject(hTicPen);
}
} }
static void static void
...@@ -452,10 +503,12 @@ TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle) ...@@ -452,10 +503,12 @@ TRACKBAR_DrawThumb(TRACKBAR_INFO *infoPtr, HDC hdc, DWORD dwStyle)
int BlackUntil = 3; int BlackUntil = 3;
int PointCount = 6; int PointCount = 6;
POINT points[6]; POINT points[6];
int fillClr;
static INT PointDepth = 4; static INT PointDepth = 4;
oldbr = SelectObject (hdc, GetSysColorBrush(COLOR_BTNFACE)); fillClr = infoPtr->flags & TB_DRAG_MODE ? COLOR_BTNHILIGHT : COLOR_BTNFACE;
oldbr = SelectObject (hdc, GetSysColorBrush(fillClr));
SetPolyFillMode (hdc, WINDING); SetPolyFillMode (hdc, WINDING);
if (dwStyle & TBS_BOTH) if (dwStyle & TBS_BOTH)
...@@ -619,10 +672,11 @@ static void ...@@ -619,10 +672,11 @@ static void
TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst) TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst)
{ {
DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE); DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
RECT rcClient, rcChannel = infoPtr->rcChannel; RECT rcClient;
HDC hdc; HDC hdc;
HBITMAP hOldBmp = 0, hOffScreenBmp = 0; HBITMAP hOldBmp = 0, hOffScreenBmp = 0;
int i; NMCUSTOMDRAW nmcd;
int gcdrf, icdrf;
if (infoPtr->flags & TB_THUMBCHANGED) { if (infoPtr->flags & TB_THUMBCHANGED) {
TRACKBAR_UpdateThumb (infoPtr); TRACKBAR_UpdateThumb (infoPtr);
...@@ -635,6 +689,8 @@ TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst) ...@@ -635,6 +689,8 @@ TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst)
if (infoPtr->flags & TB_DRAG_MODE) if (infoPtr->flags & TB_DRAG_MODE)
TRACKBAR_UpdateToolTip (infoPtr); TRACKBAR_UpdateToolTip (infoPtr);
infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED);
GetClientRect (infoPtr->hwndSelf, &rcClient); GetClientRect (infoPtr->hwndSelf, &rcClient);
/* try to render offscreen, if we fail, carrry onscreen */ /* try to render offscreen, if we fail, carrry onscreen */
...@@ -651,48 +707,74 @@ TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst) ...@@ -651,48 +707,74 @@ TRACKBAR_Refresh (TRACKBAR_INFO *infoPtr, HDC hdcDst)
hdc = hdcDst; hdc = hdcDst;
} }
infoPtr->flags &= ~ (TB_THUMBCHANGED | TB_SELECTIONCHANGED); ZeroMemory(&nmcd, sizeof(nmcd));
nmcd.hdr.hwndFrom = infoPtr->hwndSelf;
nmcd.hdr.idFrom = GetWindowLongW (infoPtr->hwndSelf, GWL_ID);
nmcd.hdr.code = NM_CUSTOMDRAW;
nmcd.hdc = hdc;
/* start the paint cycle */
nmcd.rc = rcClient;
gcdrf = notify_customdraw(&nmcd, CDDS_PREPAINT);
if (gcdrf & CDRF_SKIPDEFAULT) goto cleanup;
/* Erase backbround */ /* Erase backbround */
if (gcdrf == CDRF_DODEFAULT ||
notify_customdraw(&nmcd, CDDS_PREERASE) != CDRF_SKIPDEFAULT) {
FillRect (hdc, &rcClient, GetSysColorBrush(COLOR_BTNFACE)); FillRect (hdc, &rcClient, GetSysColorBrush(COLOR_BTNFACE));
if (gcdrf != CDRF_DODEFAULT)
notify_customdraw(&nmcd, CDDS_POSTERASE);
}
/* draw channel */ /* draw channel */
DrawEdge (hdc, &rcChannel, EDGE_SUNKEN, BF_RECT | BF_ADJUST); if (gcdrf & CDRF_NOTIFYITEMDRAW) {
if (dwStyle & TBS_ENABLESELRANGE) { /* fill the channel */ nmcd.dwItemSpec = TBCD_CHANNEL;
FillRect (hdc, &rcChannel, GetStockObject(WHITE_BRUSH)); nmcd.uItemState = CDIS_DEFAULT;
if (TRACKBAR_HasSelection(infoPtr)) nmcd.rc = infoPtr->rcChannel;
FillRect (hdc, &infoPtr->rcSelection, GetSysColorBrush(COLOR_HIGHLIGHT)); icdrf = notify_customdraw(&nmcd, CDDS_ITEMPREPAINT);
} else icdrf = CDRF_DODEFAULT;
if ( !(icdrf & CDRF_SKIPDEFAULT) ) {
TRACKBAR_DrawChannel (infoPtr, hdc, dwStyle);
if (icdrf & CDRF_NOTIFYPOSTPAINT)
notify_customdraw(&nmcd, CDDS_ITEMPOSTPAINT);
} }
/* draw tics */ /* draw tics */
if (!(dwStyle & TBS_NOTICKS)) { if (!(dwStyle & TBS_NOTICKS)) {
int ticFlags = dwStyle & 0x0f; if (gcdrf & CDRF_NOTIFYITEMDRAW) {
LOGPEN ticPen = { PS_SOLID, {1, 0}, GetSysColor (COLOR_3DDKSHADOW) }; nmcd.dwItemSpec = TBCD_TICS;
HPEN hOldPen, hTicPen; nmcd.uItemState = CDIS_DEFAULT;
nmcd.rc = rcClient;
hTicPen = CreatePenIndirect(&ticPen); icdrf = notify_customdraw(&nmcd, CDDS_ITEMPREPAINT);
hOldPen = hTicPen ? SelectObject(hdc, hTicPen) : 0; } else icdrf = CDRF_DODEFAULT;
if ( !(icdrf & CDRF_SKIPDEFAULT) ) {
for (i=0; i<infoPtr->uNumTics; i++) TRACKBAR_DrawTics (infoPtr, hdc, dwStyle);
TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->tics[i], ticFlags); if (icdrf & CDRF_NOTIFYPOSTPAINT)
notify_customdraw(&nmcd, CDDS_ITEMPOSTPAINT);
TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->lRangeMin, ticFlags | TIC_EDGE);
TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->lRangeMax, ticFlags | TIC_EDGE);
if ((dwStyle & TBS_ENABLESELRANGE) && TRACKBAR_HasSelection(infoPtr)) {
TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->lSelMin,
ticFlags | TIC_SELECTIONMARKMIN);
TRACKBAR_DrawTics (infoPtr, hdc, infoPtr->lSelMax,
ticFlags | TIC_SELECTIONMARKMAX);
} }
if (hTicPen) SelectObject(hdc, hOldPen);
} }
/* draw thumb */ /* draw thumb */
if (!(dwStyle & TBS_NOTHUMB)) if (!(dwStyle & TBS_NOTHUMB)) {
if (gcdrf & CDRF_NOTIFYITEMDRAW) {
nmcd.dwItemSpec = TBCD_THUMB;
nmcd.uItemState = infoPtr->flags & TB_DRAG_MODE ? CDIS_HOT : CDIS_DEFAULT;
nmcd.rc = infoPtr->rcThumb;
icdrf = notify_customdraw(&nmcd, CDDS_ITEMPREPAINT);
} else icdrf = CDRF_DODEFAULT;
if ( !(icdrf & CDRF_SKIPDEFAULT) ) {
TRACKBAR_DrawThumb(infoPtr, hdc, dwStyle); TRACKBAR_DrawThumb(infoPtr, hdc, dwStyle);
if (icdrf & CDRF_NOTIFYPOSTPAINT)
notify_customdraw(&nmcd, CDDS_ITEMPOSTPAINT);
}
}
/* finish up the painting */
if (gcdrf & CDRF_NOTIFYPOSTPAINT)
notify_customdraw(&nmcd, CDDS_POSTPAINT);
cleanup:
/* cleanup, if we rendered offscreen */ /* cleanup, if we rendered offscreen */
if (hdc != hdcDst) { if (hdc != hdcDst) {
BitBlt(hdcDst, 0, 0, rcClient.right, rcClient.bottom, hdc, 0, 0, SRCCOPY); BitBlt(hdcDst, 0, 0, rcClient.right, rcClient.bottom, hdc, 0, 0, SRCCOPY);
...@@ -1226,6 +1308,7 @@ TRACKBAR_LButtonDown (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts) ...@@ -1226,6 +1308,7 @@ TRACKBAR_LButtonDown (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts)
SetCapture (infoPtr->hwndSelf); SetCapture (infoPtr->hwndSelf);
TRACKBAR_UpdateToolTip (infoPtr); TRACKBAR_UpdateToolTip (infoPtr);
TRACKBAR_ActivateToolTip (infoPtr, TRUE); TRACKBAR_ActivateToolTip (infoPtr, TRUE);
TRACKBAR_InvalidateThumb(infoPtr, infoPtr->lPos);
} else { } else {
LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint); LONG dir = TRACKBAR_GetAutoPageDirection(infoPtr, clickPoint);
if (dir == 0) return 0; if (dir == 0) return 0;
...@@ -1248,6 +1331,7 @@ TRACKBAR_LButtonUp (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts) ...@@ -1248,6 +1331,7 @@ TRACKBAR_LButtonUp (TRACKBAR_INFO *infoPtr, DWORD fwKeys, POINTS pts)
ReleaseCapture (); ReleaseCapture ();
notify_releasedcapture(infoPtr); notify_releasedcapture(infoPtr);
TRACKBAR_ActivateToolTip(infoPtr, FALSE); TRACKBAR_ActivateToolTip(infoPtr, FALSE);
TRACKBAR_InvalidateThumb(infoPtr, infoPtr->lPos);
} }
if (infoPtr->flags & TB_AUTO_PAGE) { if (infoPtr->flags & TB_AUTO_PAGE) {
KillTimer (infoPtr->hwndSelf, TB_REFRESH_TIMER); KillTimer (infoPtr->hwndSelf, TB_REFRESH_TIMER);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment