diff options
author | csaba <csaba> | 2023-11-11 15:40:09 (GMT) |
---|---|---|
committer | csaba <csaba> | 2023-11-11 15:40:09 (GMT) |
commit | 159de930ebab887a76084df77fdeb7e5d6053bb2 (patch) | |
tree | 46b57cee6b3dc742a8105c00b248417505fe2362 /win | |
parent | 84f2fa8523fe199ffa607bba122c3e08fa11a750 (diff) | |
parent | 41f133078d560e8e8c4f60cea681c55232487aaa (diff) | |
download | tk-159de930ebab887a76084df77fdeb7e5d6053bb2.zip tk-159de930ebab887a76084df77fdeb7e5d6053bb2.tar.gz tk-159de930ebab887a76084df77fdeb7e5d6053bb2.tar.bz2 |
Merged the branch bug-eedd2e078d into trunk.
Diffstat (limited to 'win')
-rw-r--r-- | win/ttkWinTheme.c | 159 | ||||
-rw-r--r-- | win/ttkWinXPTheme.c | 111 |
2 files changed, 264 insertions, 6 deletions
diff --git a/win/ttkWinTheme.c b/win/ttkWinTheme.c index d526bfe..0c1c651 100644 --- a/win/ttkWinTheme.c +++ b/win/ttkWinTheme.c @@ -725,6 +725,164 @@ static const Ttk_ElementSpec SliderElementSpec = { * +++ Notebook elements. */ +typedef struct { + Tcl_Obj *borderWidthObj; + Tcl_Obj *backgroundObj; +} TabElement; + +static const Ttk_ElementOptionSpec TabElementOptions[] = { + { "-borderwidth", TK_OPTION_PIXELS, + offsetof(TabElement,borderWidthObj), "1" }, + { "-background", TK_OPTION_BORDER, + offsetof(TabElement,backgroundObj), DEFAULT_BACKGROUND }, + {0,TK_OPTION_BOOLEAN,0,0} +}; + +extern Ttk_PositionSpec nbTabsStickBit; /* see ttkNotebook.c */ + +static void TabElementSize( + TCL_UNUSED(void *), + void *elementRecord, + Tk_Window tkwin, + TCL_UNUSED(void *), + TCL_UNUSED(void *), + Ttk_Padding *paddingPtr) +{ + TabElement *tab = (TabElement *)elementRecord; + int borderWidth = 1; + + Tk_GetPixelsFromObj(0, tkwin, tab->borderWidthObj, &borderWidth); + *paddingPtr = Ttk_UniformPadding((short)borderWidth); + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + paddingPtr->bottom = 0; + break; + case TTK_STICK_N: + paddingPtr->top = 0; + break; + case TTK_STICK_E: + paddingPtr->right = 0; + break; + case TTK_STICK_W: + paddingPtr->left = 0; + break; + } +} + +static void TabElementDraw( + TCL_UNUSED(void *), + void *elementRecord, + Tk_Window tkwin, + Drawable d, + Ttk_Box b, + unsigned int state) +{ + TabElement *tab = (TabElement *)elementRecord; + Tk_3DBorder border = Tk_Get3DBorderFromObj(tkwin, tab->backgroundObj); + XPoint pts[6]; + double scalingLevel = TkScalingLevel(tkwin); + int cut = round(2 * scalingLevel); + Display *disp = Tk_Display(tkwin); + int borderWidth = 1; + + if (state & TTK_STATE_SELECTED) { + /* + * Draw slightly outside of the allocated parcel, + * to overwrite the client area border. + */ + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + b.height += 2; + break; + case TTK_STICK_N: + b.height += 2; b.y -= 2; + break; + case TTK_STICK_E: + b.width += 2; + break; + case TTK_STICK_W: + break; + } + } + + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + pts[0].x = b.x; pts[0].y = b.y + b.height-1; + pts[1].x = b.x; pts[1].y = b.y + cut; + pts[2].x = b.x + cut; pts[2].y = b.y; + pts[3].x = b.x + b.width-1 - cut; pts[3].y = b.y; + pts[4].x = b.x + b.width-1; pts[4].y = b.y + cut; + pts[5].x = b.x + b.width-1; pts[5].y = b.y + b.height; + break; + case TTK_STICK_N: + pts[0].x = b.x; pts[0].y = b.y; + pts[1].x = b.x; pts[1].y = b.y + b.height-1 - cut; + pts[2].x = b.x + cut; pts[2].y = b.y + b.height-1; + pts[3].x = b.x + b.width-1 - cut; pts[3].y = b.y + b.height-1; + pts[4].x = b.x + b.width-1; pts[4].y = b.y + b.height-1 - cut; + pts[5].x = b.x + b.width-1; pts[5].y = b.y-1; + break; + case TTK_STICK_E: + pts[0].x = b.x + b.width-1; pts[0].y = b.y; + pts[1].x = b.x + cut; pts[1].y = b.y; + pts[2].x = b.x; pts[2].y = b.y + cut; + pts[3].x = b.x; pts[3].y = b.y + b.height-1 - cut; + pts[4].x = b.x + cut; pts[4].y = b.y + b.height-1; + pts[5].x = b.x + b.width; pts[5].y = b.y + b.height-1; + break; + case TTK_STICK_W: + pts[0].x = b.x; pts[0].y = b.y; + pts[1].x = b.x + b.width-1 - cut; pts[1].y = b.y; + pts[2].x = b.x + b.width-1; pts[2].y = b.y + cut; + pts[3].x = b.x + b.width-1; pts[3].y = b.y + b.height-1 - cut; + pts[4].x = b.x + b.width-1 - cut; pts[4].y = b.y + b.height-1; + pts[5].x = b.x-1; pts[5].y = b.y + b.height-1; + break; + } + + XFillPolygon(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC), + pts, 6, Convex, CoordModeOrigin); + + Tcl_GetIntFromObj(NULL, tab->borderWidthObj, &borderWidth); + while (borderWidth--) { + XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC), + pts, 4, CoordModeOrigin); + XDrawLines(disp, d, Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC), + pts+3, 3, CoordModeOrigin); + + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + ++pts[0].x; ++pts[1].x; ++pts[2].y; + ++pts[3].y; --pts[4].x; --pts[5].x; + break; + case TTK_STICK_N: + ++pts[0].x; ++pts[1].x; --pts[2].y; + --pts[3].y; --pts[4].x; --pts[5].x; + break; + case TTK_STICK_E: + ++pts[0].y; ++pts[1].y; ++pts[2].x; + ++pts[3].x; --pts[4].y; --pts[5].y; + break; + case TTK_STICK_W: + ++pts[0].y; ++pts[1].y; --pts[2].x; + --pts[3].x; --pts[4].y; --pts[5].y; + break; + } + } +} + +static const Ttk_ElementSpec TabElementSpec = { + TK_STYLE_VERSION_2, + sizeof(TabElement), + TabElementOptions, + TabElementSize, + TabElementDraw +}; + static void ClientElementSize( TCL_UNUSED(void *), TCL_UNUSED(void *), @@ -814,6 +972,7 @@ int TtkWinTheme_Init( Ttk_RegisterElementSpec(themePtr, "Scrollbar.trough", &TroughElementSpec, TroughClientDataInit(interp)); + Ttk_RegisterElementSpec(themePtr, "tab", &TabElementSpec, NULL); Ttk_RegisterElementSpec(themePtr, "client", &ClientElementSpec, NULL); for (fce = FrameControlElements; fce->name != 0; ++fce) { diff --git a/win/ttkWinXPTheme.c b/win/ttkWinXPTheme.c index 1ad3bfc..03bbc48 100644 --- a/win/ttkWinXPTheme.c +++ b/win/ttkWinXPTheme.c @@ -27,6 +27,10 @@ typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme); typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, OPTIONAL const RECT *pClipRect); +typedef HRESULT (STDAPICALLTYPE DrawThemeEdgeProc)(HTHEME hTheme, + HDC hdc, int iPartId, int iStateId, const RECT *pDestRect, + unsigned int uEdge, unsigned int uFlags, + OPTIONAL RECT *pContentRect); typedef HRESULT (STDAPICALLTYPE GetThemePartSizeProc)(HTHEME,HDC, int iPartId, int iStateId, RECT *prc, enum THEMESIZE eSize, SIZE *psz); @@ -48,6 +52,7 @@ typedef struct GetThemePartSizeProc *GetThemePartSize; GetThemeSysSizeProc *GetThemeSysSize; DrawThemeBackgroundProc *DrawThemeBackground; + DrawThemeEdgeProc *DrawThemeEdge; DrawThemeTextProc *DrawThemeText; GetThemeTextExtentProc *GetThemeTextExtent; IsThemeActiveProc *IsThemeActive; @@ -101,6 +106,7 @@ LoadXPThemeProcs(HINSTANCE *phlib) && LOADPROC(GetThemePartSize) && LOADPROC(GetThemeSysSize) && LOADPROC(DrawThemeBackground) + && LOADPROC(DrawThemeEdge) && LOADPROC(GetThemeTextExtent) && LOADPROC(DrawThemeText) && LOADPROC(IsThemeActive) @@ -719,6 +725,38 @@ static const Ttk_ElementSpec PbarElementSpec = * The TIS_* and TILES_* definitions are identical, so * we can use the same statemap no matter what the partId. */ + +extern Ttk_PositionSpec nbTabsStickBit; /* see ttkNotebook.c */ + +static void TabElementSize( + void *clientData, + void *elementRecord, + Tk_Window tkwin, + int *widthPtr, + int *heightPtr, + Ttk_Padding *paddingPtr) +{ + GenericElementSize(clientData, elementRecord, tkwin, + widthPtr, heightPtr, paddingPtr); + + *paddingPtr = Ttk_UniformPadding(3); + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + paddingPtr->bottom = 0; + break; + case TTK_STICK_N: + paddingPtr->top = 0; + break; + case TTK_STICK_E: + paddingPtr->right = 0; + break; + case TTK_STICK_W: + paddingPtr->left = 0; + break; + } +} + static void TabElementDraw( void *clientData, TCL_UNUSED(void *), @@ -729,15 +767,76 @@ static void TabElementDraw( { ElementData *elementData = (ElementData *)clientData; int partId = elementData->info->partId; + int isSelected = (state & TTK_STATE_SELECTED); + int stateId = Ttk_StateTableLookup(elementData->info->statemap, state); + + /* + * Correct the members of b if needed + */ + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + break; + case TTK_STICK_N: + b.y -= isSelected ? 0 : 1; b.height -= isSelected ? 1 : 0; + break; + case TTK_STICK_E: + b.width -= isSelected ? 1 : 0; + break; + case TTK_STICK_W: + b.x -= isSelected ? 3 : 4; b.width += isSelected ? 1 : 2; + break; + } + RECT rc = BoxToRect(b); if (!InitElementData(elementData, tkwin, d)) return; - if (state & TTK_STATE_USER1) - partId = TABP_TABITEMLEFTEDGE; - elementData->procs->DrawThemeBackground( - elementData->hTheme, elementData->hDC, partId, - Ttk_StateTableLookup(elementData->info->statemap, state), &rc, NULL); + + if (nbTabsStickBit == TTK_STICK_S) { + if (state & TTK_STATE_USER1) { + partId = TABP_TABITEMLEFTEDGE; + } + + /* + * Draw the border and fill into rc + */ + elementData->procs->DrawThemeBackground( + elementData->hTheme, elementData->hDC, partId, stateId, &rc, NULL); + } else { + /* + * Draw the fill but no border into rc + */ + RECT rc2 = rc; + --rc2.top; --rc2.left; ++rc2.bottom; ++rc2.right; + elementData->procs->DrawThemeBackground( + elementData->hTheme, elementData->hDC, partId, stateId, &rc2, &rc); + } + + /* + * Draw a flat border at 3 edges + */ + switch (nbTabsStickBit) { + default: + case TTK_STICK_S: + break; + case TTK_STICK_N: + elementData->procs->DrawThemeEdge( + elementData->hTheme, elementData->hDC, partId, stateId, &rc, + BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_RIGHT|BF_BOTTOM, NULL); + break; + case TTK_STICK_E: + elementData->procs->DrawThemeEdge( + elementData->hTheme, elementData->hDC, partId, stateId, &rc, + BDR_RAISEDINNER, BF_FLAT|BF_LEFT|BF_TOP|BF_BOTTOM, NULL); + break; + case TTK_STICK_W: + elementData->procs->DrawThemeEdge( + elementData->hTheme, elementData->hDC, partId, stateId, &rc, + BDR_RAISEDINNER, BF_FLAT|BF_TOP|BF_RIGHT|BF_BOTTOM, NULL); + break; + } + FreeElementData(elementData); } @@ -746,7 +845,7 @@ static const Ttk_ElementSpec TabElementSpec = TK_STYLE_VERSION_2, sizeof(NullElement), TtkNullElementOptions, - GenericElementSize, + TabElementSize, TabElementDraw }; |