[PATCH 2/2] comctl32: Add support for the sort arrows.
Huw Davies
huw at codeweavers.com
Wed Oct 19 10:08:27 CDT 2016
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/comctl32/header.c | 98 ++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 79 insertions(+), 19 deletions(-)
diff --git a/dlls/comctl32/header.c b/dlls/comctl32/header.c
index 224ff9e..0206e3c 100644
--- a/dlls/comctl32/header.c
+++ b/dlls/comctl32/header.c
@@ -326,6 +326,48 @@ HEADER_DrawItemFrame(HEADER_INFO *infoPtr, HDC hdc, RECT *r, const HEADER_ITEM *
}
}
+/* Create a region for the sort arrow with its bounding rect's top-left
+ co-ord x,y and its height h. */
+static HRGN create_sort_arrow( INT x, INT y, INT h, BOOL is_up )
+{
+ char buffer[256];
+ RGNDATA *data = (RGNDATA *)buffer;
+ DWORD size = FIELD_OFFSET(RGNDATA, Buffer[h * sizeof(RECT)]);
+ INT i, yinc = 1;
+ HRGN rgn;
+
+ if (size > sizeof(buffer))
+ {
+ data = HeapAlloc( GetProcessHeap(), 0, size );
+ if (!data) return NULL;
+ }
+ data->rdh.dwSize = sizeof(data->rdh);
+ data->rdh.iType = RDH_RECTANGLES;
+ data->rdh.nCount = 0;
+ data->rdh.nRgnSize = h * sizeof(RECT);
+
+ if (!is_up)
+ {
+ y += h - 1;
+ yinc = -1;
+ }
+
+ x += h - 1; /* set x to the centre */
+
+ for (i = 0; i < h; i++, y += yinc)
+ {
+ RECT *rect = (RECT *)data->Buffer + data->rdh.nCount;
+ rect->left = x - i;
+ rect->top = y;
+ rect->right = x + i + 1;
+ rect->bottom = y + 1;
+ data->rdh.nCount++;
+ }
+ rgn = ExtCreateRegion( NULL, size, data );
+ if (data != (RGNDATA *)buffer) HeapFree( GetProcessHeap(), 0, data );
+ return rgn;
+}
+
static INT
HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESULT lCDFlags)
{
@@ -413,10 +455,11 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
INT cx, tx, ix, bx;
UINT cw, tw, iw, bw;
INT img_cx, img_cy;
+ INT sort_w, sort_x, sort_h;
BITMAP bmp;
HEADER_PrepareCallbackItems(infoPtr, iItem, HDI_TEXT|HDI_IMAGE);
- cw = iw = bw = 0;
+ cw = iw = bw = sort_w = 0;
rw = r.right - r.left;
rh = r.bottom - r.top;
@@ -435,23 +478,28 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
cw = textRect.right - textRect.left + 2 * infoPtr->iMargin;
}
- if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) {
- iw = img_cx + 2 * infoPtr->iMargin;
- x = &ix;
- w = &iw;
- }
-
- if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
- GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp);
- bw = bmp.bmWidth + 2 * infoPtr->iMargin;
- if (!iw) {
- x = &bx;
- w = &bw;
- }
- }
+ if (phdi->fmt & (HDF_SORTUP | HDF_SORTDOWN)) {
+ sort_h = MulDiv( infoPtr->nHeight - VERT_BORDER, 4, 13 );
+ sort_w = 2 * sort_h - 1 + infoPtr->iMargin * 2;
+ cw += sort_w;
+ } else { /* sort arrows take precedent over images/bitmaps */
+ if ((phdi->fmt & HDF_IMAGE) && ImageList_GetIconSize( infoPtr->himl, &img_cx, &img_cy )) {
+ iw = img_cx + 2 * infoPtr->iMargin;
+ x = &ix;
+ w = &iw;
+ }
- if (bw || iw)
- cw += *w;
+ if ((phdi->fmt & HDF_BITMAP) && (phdi->hbm)) {
+ GetObjectW (phdi->hbm, sizeof(BITMAP), &bmp);
+ bw = bmp.bmWidth + 2 * infoPtr->iMargin;
+ if (!iw) {
+ x = &bx;
+ w = &bw;
+ }
+ }
+ if (bw || iw)
+ cw += *w;
+ }
/* align cx using the unclipped cw */
if ((phdi->fmt & HDF_JUSTIFYMASK) == HDF_LEFT)
@@ -470,7 +518,10 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
tx = cx + infoPtr->iMargin;
/* since cw might have changed we have to recalculate tw */
tw = cw - infoPtr->iMargin * 2;
-
+
+ tw -= sort_w;
+ sort_x = cx + tw + infoPtr->iMargin * 3;
+
if (iw || bw) {
tw -= *w;
if (phdi->fmt & HDF_BITMAP_ON_RIGHT) {
@@ -494,11 +545,20 @@ HEADER_DrawItem (HEADER_INFO *infoPtr, HDC hdc, INT iItem, BOOL bHotTrack, LRESU
bx = cx + cw + infoPtr->iMargin;
}
- if (iw || bw) {
+ if (sort_w || iw || bw) {
HDC hClipDC = GetDC(infoPtr->hwndSelf);
HRGN hClipRgn = CreateRectRgn(r.left, r.top, r.right, r.bottom);
SelectClipRgn(hClipDC, hClipRgn);
+ if (sort_w) {
+ HRGN arrow = create_sort_arrow( sort_x, r.top + (rh - sort_h) / 2,
+ sort_h, phdi->fmt & HDF_SORTUP );
+ if (arrow) {
+ FillRgn( hClipDC, arrow, GetSysColorBrush( COLOR_GRAYTEXT ) );
+ DeleteObject( arrow );
+ }
+ }
+
if (bw) {
HDC hdcBitmap = CreateCompatibleDC (hClipDC);
SelectObject (hdcBitmap, phdi->hbm);
--
2.8.2
More information about the wine-patches
mailing list