From c02783a86786224e81a534aad0a78e4df2f9b37e Mon Sep 17 00:00:00 2001 From: Thomas Wolff Date: Sun, 22 Sep 2024 00:00:00 +0200 Subject: [PATCH] visual feedback for drag-and-drop tab reordering (#1283) --- src/wintab.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/src/wintab.c b/src/wintab.c index 47379227a..6d6057e6a 100644 --- a/src/wintab.c +++ b/src/wintab.c @@ -84,6 +84,7 @@ tabbar_update() #endif wchar_t title_fit[256]; HDC tabdc = GetDC(tab_wnd); + //printf("tab DC %p\n", tabdc); SelectObject(tabdc, tabbar_font); tie.pszText = title_fit; SendMessage(tab_wnd, TCM_DELETEALLITEMS, 0, 0); @@ -164,6 +165,7 @@ container_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) static WORD dragmsg = 0; static int dragidx = -1; static int targidx = -1; +static int targpro = -1; if (msg == WM_MOUSEACTIVATE) { //printf("WM_MOUSEACTIVATE lo %02X hi %02X\n", LOWORD(lp), HIWORD(lp)); @@ -211,16 +213,42 @@ static int targidx = -1; int x = p.x - xoff; int dropidx = x / curr_tab_width; //printf("%d:%d (pw %d) x %d drop %d\n", (int)p.y, (int)p.x, curr_tab_width, x, dropidx); + bool redraw_tab = false; if (dropidx != targidx && targidx >= 0) { // clear hover highlighting of previous drop target - + + // clear visual indication via RedrawWindow/WM_DRAWITEM targidx = -1; + redraw_tab = true; } if (dropidx != dragidx) { // visual indication of tab dragging: hover highlighting - + // enquire tab rect to calculate relative cursor position + RECT tr; + SendMessage(tab_wnd, TCM_GETITEMRECT, dropidx, (LPARAM)&tr); + //printf("drop RECT %d %d %d %d\n", tr.left, tr.right, tr.top, tr.bottom); + int w = tr.right - tr.left; + int c = (tr.left + tr.right) / 2; + targpro = 100 - abs(x - c) * 100 / (w / 2); + //printf("drop %d [%d] %d: %d\n", tr.left, x, tr.right, targpro); +#ifdef hover_tab_within_wm_setcursor +#warning the RECT does not properly match what we have at WM_DRAWITEM ... + tr.right += xoff; // tune tab position + tr.bottom += xoff; // assuming yoff would be == xoff + HDC tabdc = GetDC(tab_wnd); + HBRUSH tabbr = CreateSolidBrush(RGB(50, 90, 200)); + FillRect(tabdc, &tr, tabbr); + DeleteObject(tabbr); + ReleaseDC(tab_wnd, tabdc); +#endif + // enquire tab rect to calculate relative cursor position + + // render visual indication via RedrawWindow/WM_DRAWITEM targidx = dropidx; + redraw_tab = true; } + if (redraw_tab) + RedrawWindow(tab_wnd, 0, 0, RDW_INVALIDATE | RDW_UPDATENOW); } } else if (HIWORD(lp) == WM_LBUTTONUP) { @@ -312,8 +340,10 @@ static int targidx = -1; else if (msg == WM_DRAWITEM) { //printf("tabbar con_proc WM_DRAWITEM\n"); LPDRAWITEMSTRUCT dis = (LPDRAWITEMSTRUCT)lp; + int itemID = dis->itemID; + HDC hdc = dis->hDC; - //printf("container received drawitem %llx %p\n", wp, dis); + //printf("WM_DRAWITEM %d DC %p RECT %d %d %d %d\n", itemID, hdc, dis->rcItem.left, dis->rcItem.right, dis->rcItem.top, dis->rcItem.bottom); int hcenter = (dis->rcItem.left + dis->rcItem.right) / 2; int vcenter = (dis->rcItem.top + dis->rcItem.bottom) / 2; @@ -323,11 +353,11 @@ static int targidx = -1; tie.mask = TCIF_TEXT; tie.pszText = buf; tie.cchTextMax = 256; - SendMessage(tab_wnd, TCM_GETITEMW, dis->itemID, (LPARAM)&tie); + SendMessage(tab_wnd, TCM_GETITEMW, itemID, (LPARAM)&tie); HBRUSH tabbr; colour tabbg = (colour)-1; - if (tabinfo[dis->itemID].wnd == wnd) { + if (tabinfo[itemID].wnd == wnd) { //tabbr = GetSysColorBrush(COLOR_ACTIVECAPTION); //SetTextColor(hdc, GetSysColor(COLOR_CAPTIONTEXT)); tabbr = GetSysColorBrush(COLOR_HIGHLIGHT); @@ -353,6 +383,23 @@ static int targidx = -1; //tabbr = GetSysColorBrush(COLOR_INACTIVECAPTION); SetTextColor(hdc, GetSysColor(COLOR_CAPTIONTEXT)); //printf("tab fg %06X\n", GetSysColor(COLOR_CAPTIONTEXT)); + + // drag-and-drop hover highlighting + if (itemID == targidx) { + colour bg1 = cfg.tab_bg_colour; + if (bg1 == (colour)-1) + bg1 = GetSysColor(COLOR_HIGHLIGHT); + colour bg0 = GetSysColor(COLOR_3DFACE); + + //int p = targpro * 80 / 100 + 10; + int p = (100 - sqr(100 - targpro) / 100) * 80 / 100 + 10; + int r = red(bg0) + p * (red(bg1) - red(bg0)) / 100; + int g = green(bg0) + p * (green(bg1) - green(bg0)) / 100; + int b = blue(bg0) + p * (blue(bg1) - blue(bg0)) / 100; + + tabbg = RGB(r, g, b); + tabbr = CreateSolidBrush(tabbg); + } } FillRect(hdc, &dis->rcItem, tabbr); if (tabbg != (colour)-1)