Refactor docking panel tab bar to improve dpi compatibility
- reduce flickering when resizing panels Ref #14959 Close #15282pull/15285/head^2
parent
7a6768b029
commit
f2fbeadfea
|
@ -768,10 +768,8 @@ LRESULT DockingCont::runProcTab(HWND hwnd, UINT Message, WPARAM wParam, LPARAM l
|
||||||
RECT rcIntersect {};
|
RECT rcIntersect {};
|
||||||
if (IntersectRect(&rcIntersect, &ps.rcPaint, &dis.rcItem))
|
if (IntersectRect(&rcIntersect, &ps.rcPaint, &dis.rcItem))
|
||||||
{
|
{
|
||||||
dis.rcItem.top += NppParameters::getInstance()._dpiManager.scaleY(1);
|
|
||||||
dis.rcItem.right -= 1;
|
dis.rcItem.right -= 1;
|
||||||
dis.rcItem.bottom += 2;
|
::OffsetRect(&dis.rcItem, 0, _dpiManager.scale(CAPTION_GAP * 2));
|
||||||
|
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
POINT edges[] = {
|
POINT edges[] = {
|
||||||
|
@ -1012,9 +1010,9 @@ LRESULT DockingCont::runProcTab(HWND hwnd, UINT Message, WPARAM wParam, LPARAM l
|
||||||
return ::CallWindowProc(_hDefaultTabProc, hwnd, Message, wParam, lParam);
|
return ::CallWindowProc(_hDefaultTabProc, hwnd, Message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct)
|
void DockingCont::drawTabItem(DRAWITEMSTRUCT* pDrawItemStruct)
|
||||||
{
|
{
|
||||||
TCITEM tcItem {};
|
TCITEM tcItem{};
|
||||||
RECT rc = pDrawItemStruct->rcItem;
|
RECT rc = pDrawItemStruct->rcItem;
|
||||||
|
|
||||||
int nTab = pDrawItemStruct->itemID;
|
int nTab = pDrawItemStruct->itemID;
|
||||||
|
@ -1026,41 +1024,29 @@ void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct)
|
||||||
if (!tcItem.lParam)
|
if (!tcItem.lParam)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TCHAR *text = reinterpret_cast<tTbData*>(tcItem.lParam)->pszName;
|
auto tbData = reinterpret_cast<tTbData*>(tcItem.lParam);
|
||||||
int length = lstrlen(reinterpret_cast<tTbData*>(tcItem.lParam)->pszName);
|
|
||||||
|
|
||||||
|
const TCHAR* text = tbData->pszName;
|
||||||
|
int length = lstrlen(tbData->pszName);
|
||||||
|
|
||||||
// get drawing context
|
// get drawing context
|
||||||
HDC hDc = pDrawItemStruct->hDC;
|
HDC hDc = pDrawItemStruct->hDC;
|
||||||
|
|
||||||
int nSavedDC = ::SaveDC(hDc);
|
int nSavedDC = ::SaveDC(hDc);
|
||||||
|
|
||||||
// For some bizarre reason the rcItem you get extends above the actual
|
|
||||||
// drawing area. We have to workaround this "feature".
|
|
||||||
rc.top += ::GetSystemMetrics(SM_CYEDGE);
|
|
||||||
|
|
||||||
::SetBkMode(hDc, TRANSPARENT);
|
::SetBkMode(hDc, TRANSPARENT);
|
||||||
|
|
||||||
|
const int onePadding = _dpiManager.scale(1);
|
||||||
|
|
||||||
if (NppDarkMode::isEnabled())
|
if (NppDarkMode::isEnabled())
|
||||||
{
|
{
|
||||||
RECT selectedRect = rc;
|
::FillRect(hDc, &rc, isSelected ? NppDarkMode::getSofterBackgroundBrush() : NppDarkMode::getBackgroundBrush());
|
||||||
selectedRect.top -= 2;
|
::OffsetRect(&rc, 0, -onePadding);
|
||||||
selectedRect.bottom += 2;
|
|
||||||
if (isSelected)
|
|
||||||
{
|
|
||||||
::FillRect(hDc, &selectedRect, NppDarkMode::getSofterBackgroundBrush());
|
|
||||||
}
|
}
|
||||||
else
|
else if (isSelected) // draw orange bar
|
||||||
{
|
|
||||||
::FillRect(hDc, &selectedRect, NppDarkMode::getBackgroundBrush());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw orange bar
|
|
||||||
if (!NppDarkMode::isEnabled() && _bDrawOgLine && isSelected)
|
|
||||||
{
|
{
|
||||||
RECT barRect = rc;
|
RECT barRect = rc;
|
||||||
barRect.top += rc.bottom - 4;
|
barRect.top = rc.bottom - _dpiManager.scale(4);
|
||||||
|
|
||||||
HBRUSH hBrush = ::CreateSolidBrush(RGB(250, 170, 60));
|
HBRUSH hBrush = ::CreateSolidBrush(RGB(250, 170, 60));
|
||||||
::FillRect(hDc, &barRect, hBrush);
|
::FillRect(hDc, &barRect, hBrush);
|
||||||
|
@ -1068,42 +1054,34 @@ void DockingCont::drawTabItem(DRAWITEMSTRUCT *pDrawItemStruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw icon if enabled
|
// draw icon if enabled
|
||||||
if (((tTbData*)tcItem.lParam)->uMask & DWS_ICONTAB)
|
if ((tbData->uMask & DWS_ICONTAB) == DWS_ICONTAB)
|
||||||
{
|
{
|
||||||
HIMAGELIST hImageList = (HIMAGELIST)::SendMessage(_hParent, DMM_GETIMAGELIST, 0, 0);
|
const int wPadding = _dpiManager.scale(g_dockingContTabIconPadding);
|
||||||
int iPosImage = static_cast<int32_t>(::SendMessage(_hParent, DMM_GETICONPOS, 0, reinterpret_cast<LPARAM>(reinterpret_cast<tTbData*>(tcItem.lParam)->hClient)));
|
const int iconSize = _dpiManager.scale(g_dockingContTabIconSize);
|
||||||
|
|
||||||
if ((hImageList != NULL) && (iPosImage >= 0))
|
const int iconDpiDynamicalX = rc.left + (isSelected ? wPadding : (rc.right - rc.left - iconSize + 1) / 2);
|
||||||
{
|
const int iconDpiDynamicalY = rc.top + (rc.bottom - rc.top - iconSize - onePadding) / 2;
|
||||||
// Get height of image so we
|
|
||||||
IMAGEINFO info {};
|
|
||||||
const RECT& imageRect = info.rcImage;
|
|
||||||
|
|
||||||
ImageList_GetImageInfo(hImageList, iPosImage, &info);
|
::DrawIconEx(hDc, iconDpiDynamicalX, iconDpiDynamicalY, tbData->hIconTab, 0, 0, 0, nullptr, DI_NORMAL);
|
||||||
|
|
||||||
int darkPaddingX = NppDarkMode::isEnabled() ? 1 : 0;
|
|
||||||
int darkPaddingY = NppDarkMode::isEnabled() ? 2 : (isSelected ? 1 : 0);
|
|
||||||
|
|
||||||
int iconDpiDynamicalX = isSelected ? rc.left + 3
|
|
||||||
: rc.left + (rc.right - rc.left - imageRect.right + imageRect.left) / 2 + darkPaddingX;
|
|
||||||
int iconDpiDynamicalY = NppParameters::getInstance()._dpiManager.scaleY(5) + darkPaddingY;
|
|
||||||
|
|
||||||
ImageList_Draw(hImageList, iPosImage, hDc, iconDpiDynamicalX, iconDpiDynamicalY, ILD_NORMAL);
|
|
||||||
|
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
{
|
{
|
||||||
rc.left += imageRect.right - imageRect.left + 5;
|
rc.left += iconSize + wPadding * 2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSelected)
|
if (isSelected)
|
||||||
{
|
{
|
||||||
|
if (NppDarkMode::isEnabled())
|
||||||
|
{
|
||||||
|
const int textOffset = 3 * onePadding / 2 - 1;
|
||||||
|
::OffsetRect(&rc, 0, -textOffset);
|
||||||
|
}
|
||||||
|
|
||||||
COLORREF _unselectedColor = RGB(0, 0, 0);
|
COLORREF _unselectedColor = RGB(0, 0, 0);
|
||||||
::SetTextColor(hDc, NppDarkMode::isEnabled() ? NppDarkMode::getTextColor() : _unselectedColor);
|
::SetTextColor(hDc, NppDarkMode::isEnabled() ? NppDarkMode::getTextColor() : _unselectedColor);
|
||||||
|
|
||||||
// draw text
|
// draw text
|
||||||
rc.top -= ::GetSystemMetrics(SM_CYEDGE);
|
|
||||||
::SelectObject(hDc, _hFont);
|
::SelectObject(hDc, _hFont);
|
||||||
::DrawText(hDc, text, length, &rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
|
::DrawText(hDc, text, length, &rc, DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX);
|
||||||
}
|
}
|
||||||
|
@ -1142,8 +1120,10 @@ intptr_t CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l
|
||||||
_hDefaultTabProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hContTab, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wndTabProc)));
|
_hDefaultTabProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hContTab, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(wndTabProc)));
|
||||||
|
|
||||||
// set min tab width
|
// set min tab width
|
||||||
int tabDpiDynamicalMinWidth = NppParameters::getInstance()._dpiManager.scaleX(24);
|
const int tabDpiPadding = _dpiManager.scale(g_dockingContTabIconSize + g_dockingContTabIconPadding * 2);
|
||||||
::SendMessage(_hContTab, TCM_SETMINTABWIDTH, 0, tabDpiDynamicalMinWidth);
|
::SendMessage(_hContTab, TCM_SETMINTABWIDTH, 0, tabDpiPadding);
|
||||||
|
TabCtrl_SetPadding(_hContTab, tabDpiPadding / 2, 0);
|
||||||
|
TabCtrl_SetItemSize(_hContTab, 2 * tabDpiPadding, tabDpiPadding);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1165,15 +1145,28 @@ intptr_t CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_ERASEBKGND:
|
case WM_ERASEBKGND:
|
||||||
{
|
{
|
||||||
if (!NppDarkMode::isEnabled())
|
HDC hDC = reinterpret_cast<HDC>(wParam);
|
||||||
{
|
|
||||||
break;
|
RECT rc{};
|
||||||
}
|
|
||||||
RECT rc {};
|
|
||||||
getClientRect(rc);
|
getClientRect(rc);
|
||||||
::FillRect(reinterpret_cast<HDC>(wParam), &rc, NppDarkMode::getDarkerBackgroundBrush());
|
|
||||||
|
RECT rcTab{};
|
||||||
|
getMappedChildRect(_hContTab, rcTab);
|
||||||
|
|
||||||
|
RECT rcClientTab{};
|
||||||
|
getMappedChildRect(IDC_CLIENT_TAB, rcClientTab);
|
||||||
|
|
||||||
|
RECT rcCap{};
|
||||||
|
getMappedChildRect(_hCaption, rcCap);
|
||||||
|
|
||||||
|
::ExcludeClipRect(hDC, rcTab.left, rcTab.top, rcTab.right, rcTab.bottom);
|
||||||
|
::ExcludeClipRect(hDC, rcClientTab.left, rcClientTab.top, rcClientTab.right, rcClientTab.bottom);
|
||||||
|
::ExcludeClipRect(hDC, rcCap.left, rcCap.top, rcCap.right, rcCap.bottom);
|
||||||
|
|
||||||
|
::FillRect(hDC, &rc, NppDarkMode::isEnabled() ? NppDarkMode::getDarkerBackgroundBrush() : ::GetSysColorBrush(COLOR_3DFACE));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,7 +1259,7 @@ void DockingCont::onSize()
|
||||||
if (iItemCnt >= 1)
|
if (iItemCnt >= 1)
|
||||||
{
|
{
|
||||||
// resize to docked window
|
// resize to docked window
|
||||||
int tabDpiDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(16) + 8;
|
const int tabDpiDynamicalHeight = _dpiManager.scale(g_dockingContTabIconSize + (g_dockingContTabIconPadding) * 2 + CAPTION_GAP);
|
||||||
if (_isFloating == false)
|
if (_isFloating == false)
|
||||||
{
|
{
|
||||||
// draw caption
|
// draw caption
|
||||||
|
@ -1359,7 +1352,6 @@ void DockingCont::onSize()
|
||||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get active item data
|
// get active item data
|
||||||
size_t iItemCnt2 = static_cast<size_t>(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0));
|
size_t iItemCnt2 = static_cast<size_t>(::SendMessage(_hContTab, TCM_GETITEMCOUNT, 0, 0));
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ enum eMousePos {
|
||||||
#define CLOSEBTN_POS_TOP 3
|
#define CLOSEBTN_POS_TOP 3
|
||||||
|
|
||||||
constexpr int g_dockingContTabIconSize = 14;
|
constexpr int g_dockingContTabIconSize = 14;
|
||||||
|
constexpr int g_dockingContTabIconPadding = 3;
|
||||||
|
|
||||||
class DockingCont : public StaticDialog
|
class DockingCont : public StaticDialog
|
||||||
{
|
{
|
||||||
|
@ -118,15 +119,11 @@ public:
|
||||||
updateCaption();
|
updateCaption();
|
||||||
};
|
};
|
||||||
|
|
||||||
void setTabStyle(const BOOL & bDrawOgLine) {
|
|
||||||
_bDrawOgLine = bDrawOgLine;
|
|
||||||
::RedrawWindow(_hContTab, nullptr, nullptr, RDW_INVALIDATE);
|
|
||||||
};
|
|
||||||
|
|
||||||
void destroy() override{
|
void destroy() override{
|
||||||
for (int iTb = static_cast<int>(_vTbData.size()); iTb > 0; iTb--)
|
for (auto& tTbData : _vTbData)
|
||||||
{
|
{
|
||||||
delete _vTbData[iTb-1];
|
::DestroyIcon(tTbData->hIconTab);
|
||||||
|
delete tTbData;
|
||||||
}
|
}
|
||||||
::DestroyWindow(_hSelf);
|
::DestroyWindow(_hSelf);
|
||||||
};
|
};
|
||||||
|
@ -192,9 +189,6 @@ private:
|
||||||
BOOL _isMouseOver = FALSE;
|
BOOL _isMouseOver = FALSE;
|
||||||
RECT _rcCaption{};
|
RECT _rcCaption{};
|
||||||
|
|
||||||
// tab style
|
|
||||||
BOOL _bDrawOgLine = TRUE;
|
|
||||||
|
|
||||||
// Important value for DlgMoving class
|
// Important value for DlgMoving class
|
||||||
BOOL _dragFromTab = FALSE;
|
BOOL _dragFromTab = FALSE;
|
||||||
|
|
||||||
|
|
|
@ -260,12 +260,6 @@ LRESULT DockingManager::runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l
|
||||||
hWndServer = NULL;
|
hWndServer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy imagelist if it exists
|
|
||||||
if (_hImageList != NULL)
|
|
||||||
{
|
|
||||||
::ImageList_Destroy(_hImageList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// destroy containers
|
// destroy containers
|
||||||
for (int32_t i = static_cast<int32_t>(_vContainer.size()); i > 0; i--)
|
for (int32_t i = static_cast<int32_t>(_vContainer.size()); i > 0; i--)
|
||||||
{
|
{
|
||||||
|
@ -395,21 +389,7 @@ LRESULT DockingManager::runProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM l
|
||||||
toggleVisTb(reinterpret_cast<DockingCont*>(lParam), DMM_DOCK);
|
toggleVisTb(reinterpret_cast<DockingCont*>(lParam), DMM_DOCK);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
case DMM_GETIMAGELIST:
|
|
||||||
{
|
|
||||||
return reinterpret_cast<LPARAM>(_hImageList);
|
|
||||||
}
|
|
||||||
case DMM_GETICONPOS:
|
|
||||||
{
|
|
||||||
for (size_t uImageCnt = 0, len = _vImageList.size(); uImageCnt < len; ++uImageCnt)
|
|
||||||
{
|
|
||||||
if (reinterpret_cast<HWND>(lParam) == _vImageList[uImageCnt])
|
|
||||||
{
|
|
||||||
return uImageCnt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
default :
|
default :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -585,23 +565,6 @@ void DockingManager::reSizeTo(RECT & rc)
|
||||||
|
|
||||||
void DockingManager::createDockableDlg(tTbData data, int iCont, bool isVisible)
|
void DockingManager::createDockableDlg(tTbData data, int iCont, bool isVisible)
|
||||||
{
|
{
|
||||||
// add icons
|
|
||||||
if ((data.uMask & DWS_ICONTAB) && data.hIconTab != NULL)
|
|
||||||
{
|
|
||||||
// create image list if not exist
|
|
||||||
if (_hImageList == NULL)
|
|
||||||
{
|
|
||||||
const int iconDpiDynamicalSize = DPIManagerV2::scale(g_dockingContTabIconSize, data.hClient);
|
|
||||||
_hImageList = ::ImageList_Create(iconDpiDynamicalSize, iconDpiDynamicalSize, ILC_COLOR32 | ILC_MASK, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add icon
|
|
||||||
::ImageList_AddIcon(_hImageList, data.hIconTab);
|
|
||||||
|
|
||||||
// do the reference here to find later the correct position
|
|
||||||
_vImageList.push_back(data.hClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((data.uMask & DWS_USEOWNDARKMODE) != DWS_USEOWNDARKMODE && NppDarkMode::isEnabledForPlugins())
|
if ((data.uMask & DWS_USEOWNDARKMODE) != DWS_USEOWNDARKMODE && NppDarkMode::isEnabledForPlugins())
|
||||||
{
|
{
|
||||||
NppDarkMode::autoSubclassAndThemePluginDockWindow(data.hClient);
|
NppDarkMode::autoSubclassAndThemePluginDockWindow(data.hClient);
|
||||||
|
|
|
@ -35,7 +35,7 @@ public :
|
||||||
~DockingManager();
|
~DockingManager();
|
||||||
|
|
||||||
void init(HINSTANCE hInst, HWND hWnd, Window ** ppWin);
|
void init(HINSTANCE hInst, HWND hWnd, Window ** ppWin);
|
||||||
virtual void reSizeTo(RECT & rc);
|
void reSizeTo(RECT & rc) override;
|
||||||
|
|
||||||
void setClientWnd(Window ** ppWin) {
|
void setClientWnd(Window ** ppWin) {
|
||||||
_ppWindow = ppWin;
|
_ppWindow = ppWin;
|
||||||
|
@ -73,14 +73,9 @@ public :
|
||||||
_vContainer[CONT_BOTTOM]->setCaptionTop(captionOnTop);
|
_vContainer[CONT_BOTTOM]->setCaptionTop(captionOnTop);
|
||||||
};
|
};
|
||||||
|
|
||||||
void setTabStyle(BOOL orangeLine) {
|
|
||||||
for (size_t i = 0; i < _vContainer.size(); ++i)
|
|
||||||
_vContainer[i]->setTabStyle(orangeLine);
|
|
||||||
};
|
|
||||||
|
|
||||||
int getDockedContSize(int iCont);
|
int getDockedContSize(int iCont);
|
||||||
void setDockedContSize(int iCont, int iSize);
|
void setDockedContSize(int iCont, int iSize);
|
||||||
virtual void destroy();
|
void destroy() override;
|
||||||
void resize();
|
void resize();
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
@ -88,8 +83,6 @@ private :
|
||||||
RECT _rcWork = {};
|
RECT _rcWork = {};
|
||||||
RECT _rect = {};
|
RECT _rect = {};
|
||||||
Window **_ppMainWindow = nullptr;
|
Window **_ppMainWindow = nullptr;
|
||||||
std::vector<HWND> _vImageList;
|
|
||||||
HIMAGELIST _hImageList = nullptr;
|
|
||||||
std::vector<DockingCont*> _vContainer;
|
std::vector<DockingCont*> _vContainer;
|
||||||
tDockMgr _dockData;
|
tDockMgr _dockData;
|
||||||
static BOOL _isRegistered;
|
static BOOL _isRegistered;
|
||||||
|
@ -107,7 +100,4 @@ private :
|
||||||
BOOL ContExists(size_t iCont);
|
BOOL ContExists(size_t iCont);
|
||||||
int FindEmptyContainer();
|
int FindEmptyContainer();
|
||||||
LRESULT SendNotify(HWND hWnd, UINT message);
|
LRESULT SendNotify(HWND hWnd, UINT message);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
#define DMM_FLOATALL (DMM_MSG + 5)
|
#define DMM_FLOATALL (DMM_MSG + 5)
|
||||||
#define DMM_MOVE (DMM_MSG + 6)
|
#define DMM_MOVE (DMM_MSG + 6)
|
||||||
#define DMM_UPDATEDISPINFO (DMM_MSG + 7)
|
#define DMM_UPDATEDISPINFO (DMM_MSG + 7)
|
||||||
#define DMM_GETIMAGELIST (DMM_MSG + 8)
|
//#define DMM_GETIMAGELIST (DMM_MSG + 8)
|
||||||
#define DMM_GETICONPOS (DMM_MSG + 9)
|
//#define DMM_GETICONPOS (DMM_MSG + 9)
|
||||||
#define DMM_DROPDATA (DMM_MSG + 10)
|
#define DMM_DROPDATA (DMM_MSG + 10)
|
||||||
#define DMM_MOVE_SPLITTER (DMM_MSG + 11)
|
#define DMM_MOVE_SPLITTER (DMM_MSG + 11)
|
||||||
#define DMM_CANCEL_MOVE (DMM_MSG + 12)
|
#define DMM_CANCEL_MOVE (DMM_MSG + 12)
|
||||||
|
|
Loading…
Reference in New Issue