diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2025-09-12 14:14:26 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2025-09-12 14:14:26 (GMT) |
| commit | 87a60afbc2b6575f5d95996436bdaca5d138fdaf (patch) | |
| tree | 7c260cd92b99ab7bf6d3265c42e9c2fdbec2bc3e | |
| parent | bc0bf14e28a221b797b6cae526d33efa8a3df9be (diff) | |
| parent | dd655f079219fe95caa1051af4c6ec6e0c9507ef (diff) | |
| download | tk-core-no-xp-theme.zip tk-core-no-xp-theme.tar.gz tk-core-no-xp-theme.tar.bz2 | |
Eliminate classic and XP theme on Windowscore-no-xp-theme
| -rw-r--r-- | generic/tkIntPlatDecls.h | 2 | ||||
| -rw-r--r-- | generic/tkStubInit.c | 6 | ||||
| -rw-r--r-- | win/Makefile.in | 1 | ||||
| -rw-r--r-- | win/makefile.vc | 1 | ||||
| -rw-r--r-- | win/tkWinInt.h | 8 | ||||
| -rw-r--r-- | win/tkWinMenu.c | 42 | ||||
| -rw-r--r-- | win/tkWinX.c | 54 | ||||
| -rw-r--r-- | win/ttkWinMonitor.c | 2 | ||||
| -rw-r--r-- | win/ttkWinXPTheme.c | 1473 |
9 files changed, 36 insertions, 1553 deletions
diff --git a/generic/tkIntPlatDecls.h b/generic/tkIntPlatDecls.h index 7d55a30..b613cfd 100644 --- a/generic/tkIntPlatDecls.h +++ b/generic/tkIntPlatDecls.h @@ -738,6 +738,8 @@ extern const TkIntPlatStubs *tkIntPlatStubsPtr; #ifndef TK_NO_DEPRECATED # define TkMacOSXDrawable Tk_MacOSXGetNSWindowForDrawable +# undef TkWinGetPlatformTheme +# define TkWinGetPlatformTheme() 3 #endif #undef TCL_STORAGE_CLASS diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index b3fe123..f5dfb5b 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -43,6 +43,11 @@ MODULE_SCOPE const TkStubs tkStubs; #undef XPutImage #define TkUnusedStubEntry 0 +#ifdef TK_NO_DEPRECATED +# undef TkWinGetPlatformTheme +# define TkWinGetPlatformTheme 0 +#endif /* TK_NO_DEPRECATED */ + #if !defined(MAC_OSX_TK) static int doNothing(void) @@ -188,6 +193,7 @@ TkPutImage( # define TkWinDialogDebug 0 # define TkWinGetMenuSystemDefault 0 # define TkWinSetHINSTANCE 0 +# undef TkWinGetPlatformTheme # define TkWinGetPlatformTheme 0 # define TkWinChildProc 0 diff --git a/win/Makefile.in b/win/Makefile.in index 476ad3e..8a44499 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -406,7 +406,6 @@ TK_OBJS = \ TTK_OBJS = \ ttkWinMonitor.$(OBJEXT) \ ttkWinTheme.$(OBJEXT) \ - ttkWinXPTheme.$(OBJEXT) \ ttkBlink.$(OBJEXT) \ ttkButton.$(OBJEXT) \ ttkCache.$(OBJEXT) \ diff --git a/win/makefile.vc b/win/makefile.vc index 67db96e..df3b5aa 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -272,7 +272,6 @@ TKOBJS = \ TTK_OBJS = \
$(TMP_DIR)\ttkWinMonitor.obj \
$(TMP_DIR)\ttkWinTheme.obj \
- $(TMP_DIR)\ttkWinXPTheme.obj \
$(TMP_DIR)\ttkBlink.obj \
$(TMP_DIR)\ttkButton.obj \
$(TMP_DIR)\ttkCache.obj \
diff --git a/win/tkWinInt.h b/win/tkWinInt.h index 36aa6a4..8345795 100644 --- a/win/tkWinInt.h +++ b/win/tkWinInt.h @@ -188,9 +188,11 @@ MODULE_SCOPE void TkWinSetupSystemFonts(TkMainInfo *mainPtr); * Values returned by TkWinGetPlatformTheme. */ -#define TK_THEME_WIN_CLASSIC 1 -#define TK_THEME_WIN_XP 2 -#define TK_THEME_WIN_VISTA 3 +#ifndef TK_NO_DEPRECATED +# define TK_THEME_WIN_CLASSIC 1 +# define TK_THEME_WIN_XP 2 +# define TK_THEME_WIN_VISTA 3 +#endif /* * The following is implemented in tkWinWm and used by tkWinEmbed.c diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index bf888c7..990137e 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -1925,18 +1925,16 @@ DrawMenuEntryAccelerator( * Draw disabled 3D text highlight only with the Win95/98 look. */ - if (TkWinGetPlatformTheme() != TK_THEME_WIN_XP) { - if ((mePtr->state == ENTRY_DISABLED) - && (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) { - COLORREF oldFgColor = gc->foreground; - - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - if (!(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge + 1, baseline + 1); - } - gc->foreground = oldFgColor; + if ((mePtr->state == ENTRY_DISABLED) + && (menuPtr->disabledFgPtr != NULL) && (accel != NULL)) { + COLORREF oldFgColor = gc->foreground; + + gc->foreground = GetSysColor(COLOR_3DHILIGHT); + if (!(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { + Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, + mePtr->accelLength, leftEdge + 1, baseline + 1); } + gc->foreground = oldFgColor; } if (accel != NULL) { @@ -2469,22 +2467,20 @@ DrawMenuEntryLabel( int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; const char *label = Tcl_GetString(mePtr->labelPtr); - if (TkWinGetPlatformTheme() != TK_THEME_WIN_XP) { /* * Win 95/98 systems draw disabled menu text with a 3D * highlight, unless the menu item is highlighted, */ - if ((mePtr->state == ENTRY_DISABLED) && - !(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { - COLORREF oldFgColor = gc->foreground; + if ((mePtr->state == ENTRY_DISABLED) && + !(mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)) { + COLORREF oldFgColor = gc->foreground; - gc->foreground = GetSysColor(COLOR_3DHILIGHT); - Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge + textXOffset + 1, - baseline + textYOffset + 1); - gc->foreground = oldFgColor; - } + gc->foreground = GetSysColor(COLOR_3DHILIGHT); + Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, + mePtr->labelLength, leftEdge + textXOffset + 1, + baseline + textYOffset + 1); + gc->foreground = oldFgColor; } Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, mePtr->labelLength, leftEdge + textXOffset, @@ -3383,10 +3379,6 @@ SetDefaults( metrics.cbSize = sizeof(metrics); - if (TkWinGetPlatformTheme() != TK_THEME_WIN_VISTA) { - metrics.cbSize -= sizeof(int); - } - SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0); menuFont = CreateFontIndirectW(&metrics.lfMenuFont); diff --git a/win/tkWinX.c b/win/tkWinX.c index aec0b14..5f661c0 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -87,7 +87,6 @@ static const char winScreenName[] = ":0"; /* Default name of windows display. */ static HINSTANCE tkInstance = NULL; /* Application instance handle. */ static int childClassInitialized; /* Registered child class? */ static WNDCLASSW childClass; /* Window class for child windows. */ -static int tkWinTheme = 0; /* See TkWinGetPlatformTheme */ static Tcl_Encoding keyInputEncoding = NULL; /* The current character encoding for * keyboard input */ @@ -339,60 +338,19 @@ TkWinXCleanup( * Return the Windows drawing style we should be using. * * Results: - * The return value is one of: - * TK_THEME_WIN_CLASSIC 95/98/NT or XP in classic mode - * TK_THEME_WIN_XP XP not in classic mode - * TK_THEME_WIN_VISTA Vista or higher + * The return value is: + * 3 Vista or higher * *---------------------------------------------------------------------- */ - +#ifndef TK_NO_DEPRECATED +#undef TkWinGetPlatformTheme int TkWinGetPlatformTheme(void) { - if (tkWinTheme == 0) { - OSVERSIONINFOW os; - - os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); - GetVersionExW(&os); - - if (os.dwPlatformId != VER_PLATFORM_WIN32_NT) { - Tcl_Panic("Windows NT is the only supported platform"); - } - - /* - * Set tkWinTheme to be TK_THEME_WIN_(CLASSIC|XP|VISTA). The - * TK_THEME_WIN_CLASSIC could be set even when running under XP if the - * windows classic theme was selected. - */ - if (os.dwMajorVersion == 5 && os.dwMinorVersion >= 1) { - HKEY hKey; - LPCWSTR szSubKey = L"Control Panel\\Appearance"; - LPCWSTR szCurrent = L"Current"; - DWORD dwSize = 200; - WCHAR pBuffer[200]; - - memset(pBuffer, 0, dwSize); - if (RegOpenKeyExW(HKEY_CURRENT_USER, szSubKey, 0L, - KEY_READ, &hKey) != ERROR_SUCCESS) { - tkWinTheme = TK_THEME_WIN_XP; - } else { - RegQueryValueExW(hKey, szCurrent, NULL, NULL, (LPBYTE) pBuffer, &dwSize); - RegCloseKey(hKey); - if (wcscmp(pBuffer, L"Windows Standard") == 0) { - tkWinTheme = TK_THEME_WIN_CLASSIC; - } else { - tkWinTheme = TK_THEME_WIN_XP; - } - } - } else if (os.dwMajorVersion > 5) { - tkWinTheme = TK_THEME_WIN_VISTA; - } else { - tkWinTheme = TK_THEME_WIN_CLASSIC; - } - } - return tkWinTheme; + return 3; /* TK_THEME_WIN_VISTA */ } +#endif /* TK_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/win/ttkWinMonitor.c b/win/ttkWinMonitor.c index 32d2a07..8f309cf 100644 --- a/win/ttkWinMonitor.c +++ b/win/ttkWinMonitor.c @@ -145,7 +145,6 @@ WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) */ MODULE_SCOPE int TtkWinTheme_Init(Tcl_Interp *, HWND hwnd); -MODULE_SCOPE int TtkXPTheme_Init(Tcl_Interp *, HWND hwnd); MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp); MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp) @@ -156,7 +155,6 @@ MODULE_SCOPE int Ttk_WinPlatformInit(Tcl_Interp *interp) Ttk_RegisterCleanup(interp, hwnd, DestroyThemeMonitorWindow); TtkWinTheme_Init(interp, hwnd); - TtkXPTheme_Init(interp, hwnd); return TCL_OK; } diff --git a/win/ttkWinXPTheme.c b/win/ttkWinXPTheme.c deleted file mode 100644 index d3d82f0..0000000 --- a/win/ttkWinXPTheme.c +++ /dev/null @@ -1,1473 +0,0 @@ -/* - * Tk theme engine which uses the Windows XP "Visual Styles" API - * Adapted from Georgios Petasis' XP theme patch. - * - * Copyright © 2003 Georgios Petasis, petasis@iit.demokritos.gr. - * Copyright © 2003 Joe English - * Copyright © 2003 Pat Thoyts - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * See also: - * - * <URL: http://msdn.microsoft.com/library/en-us/ - * shellcc/platform/commctls/userex/refentry.asp > - */ - -#include "tkWinInt.h" -#include <windows.h> -#include <uxtheme.h> -#include <vssym32.h> -#include "ttk/ttkThemeInt.h" - -typedef HTHEME (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd, - LPCWSTR pszClassList); -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); -typedef int (STDAPICALLTYPE GetThemeSysSizeProc)(HTHEME,int); -/* GetThemeTextExtent and DrawThemeText only used with BROKEN_TEXT_ELEMENT */ -typedef HRESULT (STDAPICALLTYPE GetThemeTextExtentProc)(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, const RECT *pBoundingRect, RECT *pExtent); -typedef HRESULT (STDAPICALLTYPE DrawThemeTextProc)(HTHEME hTheme, HDC hdc, - int iPartId, int iStateId, LPCWSTR pszText, int iCharCount, - DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect); -typedef BOOL (STDAPICALLTYPE IsThemeActiveProc)(void); -typedef BOOL (STDAPICALLTYPE IsAppThemedProc)(void); - -typedef struct -{ - OpenThemeDataProc *OpenThemeData; - CloseThemeDataProc *CloseThemeData; - GetThemePartSizeProc *GetThemePartSize; - GetThemeSysSizeProc *GetThemeSysSize; - DrawThemeBackgroundProc *DrawThemeBackground; - DrawThemeEdgeProc *DrawThemeEdge; - DrawThemeTextProc *DrawThemeText; - GetThemeTextExtentProc *GetThemeTextExtent; - IsThemeActiveProc *IsThemeActive; - IsAppThemedProc *IsAppThemed; - - HWND stubWindow; -} XPThemeProcs; - -typedef struct -{ - HINSTANCE hlibrary; - XPThemeProcs *procs; -} XPThemeData; - -/* - *---------------------------------------------------------------------- - * - * LoadXPThemeProcs -- - * Initialize XP theming support. - * - * XP theme support is included in UXTHEME.DLL - * We dynamically load this DLL at runtime instead of linking - * to it at build-time. - * - * Returns: - * A pointer to an XPThemeProcs table if successful, NULL otherwise. - */ - -static XPThemeProcs * -LoadXPThemeProcs(HINSTANCE *phlib) -{ - /* - * Load the library "uxtheme.dll", where the native widget - * drawing routines are implemented. This will only succeed - * if we are running at least on Windows XP. - */ - HINSTANCE handle; - *phlib = handle = LoadLibraryW(L"uxtheme.dll"); - if (handle != 0) { - /* - * We have successfully loaded the library. Proceed in storing the - * addresses of the functions we want to use. - */ - XPThemeProcs *procs = (XPThemeProcs *)ckalloc(sizeof(XPThemeProcs)); -#define LOADPROC(name) \ - (0 != (procs->name = (name ## Proc *)(void *)GetProcAddress(handle, #name) )) - - if (LOADPROC(OpenThemeData) - && LOADPROC(CloseThemeData) - && LOADPROC(GetThemePartSize) - && LOADPROC(GetThemeSysSize) - && LOADPROC(DrawThemeBackground) - && LOADPROC(DrawThemeEdge) - && LOADPROC(GetThemeTextExtent) - && LOADPROC(DrawThemeText) - && LOADPROC(IsThemeActive) - && LOADPROC(IsAppThemed)) { - return procs; - } -#undef LOADPROC - ckfree(procs); - } - return 0; -} - -/* - * XPThemeDeleteProc -- - * - * Release any theme allocated resources. - */ - -static void -XPThemeDeleteProc(void *clientData) -{ - XPThemeData *themeData = (XPThemeData *)clientData; - FreeLibrary(themeData->hlibrary); - ckfree(clientData); -} - -static int -XPThemeEnabled( - TCL_UNUSED(Ttk_Theme), - void *clientData) -{ - XPThemeData *themeData = (XPThemeData *)clientData; - int active = themeData->procs->IsThemeActive(); - int themed = themeData->procs->IsAppThemed(); - - return (active && themed); -} - -/* - * BoxToRect -- - * Helper routine. Returns a RECT data structure. - */ -static RECT -BoxToRect(Ttk_Box b) -{ - RECT rc; - rc.top = b.y; - rc.left = b.x; - rc.bottom = b.y + b.height; - rc.right = b.x + b.width; - return rc; -} - -/* - * Map Tk state bitmaps to XP style enumerated values. - */ -static const Ttk_StateTable null_statemap[] = { {0,0,0} }; - -/* - * Pushbuttons (Tk: "Button") - */ -static const Ttk_StateTable pushbutton_statemap[] = -{ - { PBS_DISABLED, TTK_STATE_DISABLED, 0 }, - { PBS_PRESSED, TTK_STATE_PRESSED, 0 }, - { PBS_HOT, TTK_STATE_ACTIVE, 0 }, - { PBS_DEFAULTED, TTK_STATE_ALTERNATE, 0 }, - { PBS_NORMAL, 0, 0 } -}; - -/* - * Checkboxes (Tk: "Checkbutton") - */ -static const Ttk_StateTable checkbox_statemap[] = -{ -{CBS_MIXEDDISABLED, TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0}, -{CBS_MIXEDPRESSED, TTK_STATE_ALTERNATE|TTK_STATE_PRESSED, 0}, -{CBS_MIXEDHOT, TTK_STATE_ALTERNATE|TTK_STATE_ACTIVE, 0}, -{CBS_MIXEDNORMAL, TTK_STATE_ALTERNATE, 0}, -{CBS_CHECKEDDISABLED, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0}, -{CBS_CHECKEDPRESSED, TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0}, -{CBS_CHECKEDHOT, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0}, -{CBS_CHECKEDNORMAL, TTK_STATE_SELECTED, 0}, -{CBS_UNCHECKEDDISABLED, TTK_STATE_DISABLED, 0}, -{CBS_UNCHECKEDPRESSED, TTK_STATE_PRESSED, 0}, -{CBS_UNCHECKEDHOT, TTK_STATE_ACTIVE, 0}, -{CBS_UNCHECKEDNORMAL, 0,0 } -}; - -/* - * Radiobuttons: - */ -static const Ttk_StateTable radiobutton_statemap[] = -{ -{RBS_UNCHECKEDDISABLED, TTK_STATE_ALTERNATE|TTK_STATE_DISABLED, 0}, -{RBS_UNCHECKEDNORMAL, TTK_STATE_ALTERNATE, 0}, -{RBS_CHECKEDDISABLED, TTK_STATE_SELECTED|TTK_STATE_DISABLED, 0}, -{RBS_CHECKEDPRESSED, TTK_STATE_SELECTED|TTK_STATE_PRESSED, 0}, -{RBS_CHECKEDHOT, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0}, -{RBS_CHECKEDNORMAL, TTK_STATE_SELECTED, 0}, -{RBS_UNCHECKEDDISABLED, TTK_STATE_DISABLED, 0}, -{RBS_UNCHECKEDPRESSED, TTK_STATE_PRESSED, 0}, -{RBS_UNCHECKEDHOT, TTK_STATE_ACTIVE, 0}, -{RBS_UNCHECKEDNORMAL, 0,0 } -}; - -/* - * Groupboxes (tk: "frame") - */ -static const Ttk_StateTable groupbox_statemap[] = -{ -{GBS_DISABLED, TTK_STATE_DISABLED, 0}, -{GBS_NORMAL, 0,0 } -}; - -/* - * Edit fields (tk: "entry") - */ -static const Ttk_StateTable edittext_statemap[] = -{ - { ETS_DISABLED, TTK_STATE_DISABLED, 0 }, - { ETS_READONLY, TTK_STATE_READONLY, 0 }, - { ETS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { ETS_HOT, TTK_STATE_ACTIVE, 0 }, - { ETS_NORMAL, 0, 0 } -/* NOT USED: ETS_ASSIST, ETS_SELECTED */ -}; - -/* - * Combobox text field statemap: - * Same as edittext_statemap, but doesn't use ETS_READONLY - * (fixes: #1032409) - */ -static const Ttk_StateTable combotext_statemap[] = -{ - { ETS_DISABLED, TTK_STATE_DISABLED, 0 }, - { ETS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { ETS_HOT, TTK_STATE_ACTIVE, 0 }, - { ETS_NORMAL, 0, 0 } -}; - -/* - * Combobox button: (CBP_DROPDOWNBUTTON) - */ -static const Ttk_StateTable combobox_statemap[] = { - { CBXS_DISABLED, TTK_STATE_DISABLED, 0 }, - { CBXS_PRESSED, TTK_STATE_PRESSED, 0 }, - { CBXS_HOT, TTK_STATE_ACTIVE, 0 }, - { CBXS_HOT, TTK_STATE_HOVER, 0 }, - { CBXS_NORMAL, 0, 0 } -}; - -/* - * Toolbar buttons (TP_BUTTON): - */ -static const Ttk_StateTable toolbutton_statemap[] = { - { TS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TS_PRESSED, TTK_STATE_PRESSED, 0 }, - { TS_HOTCHECKED, TTK_STATE_SELECTED|TTK_STATE_ACTIVE, 0 }, - { TS_CHECKED, TTK_STATE_SELECTED, 0 }, - { TS_HOT, TTK_STATE_ACTIVE, 0 }, - { TS_NORMAL, 0,0 } -}; - -/* - * Scrollbars (Tk: "Scrollbar.thumb") - */ -static const Ttk_StateTable scrollbar_statemap[] = -{ - { SCRBS_DISABLED, TTK_STATE_DISABLED, 0 }, - { SCRBS_PRESSED, TTK_STATE_PRESSED, 0 }, - { SCRBS_HOT, TTK_STATE_ACTIVE, 0 }, - { SCRBS_NORMAL, 0, 0 } -}; - -static const Ttk_StateTable uparrow_statemap[] = -{ - { ABS_UPDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_UPPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_UPHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_UPNORMAL, 0, 0 } -}; - -static const Ttk_StateTable downarrow_statemap[] = -{ - { ABS_DOWNDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_DOWNPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_DOWNHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_DOWNNORMAL, 0, 0 } -}; - -static const Ttk_StateTable leftarrow_statemap[] = -{ - { ABS_LEFTDISABLED, TTK_STATE_DISABLED, 0 }, - { ABS_LEFTPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_LEFTHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_LEFTNORMAL, 0, 0 } -}; - -static const Ttk_StateTable rightarrow_statemap[] = -{ - { ABS_RIGHTDISABLED,TTK_STATE_DISABLED, 0 }, - { ABS_RIGHTPRESSED, TTK_STATE_PRESSED, 0 }, - { ABS_RIGHTHOT, TTK_STATE_ACTIVE, 0 }, - { ABS_RIGHTNORMAL, 0, 0 } -}; - -static const Ttk_StateTable spinbutton_statemap[] = -{ - { DNS_DISABLED, TTK_STATE_DISABLED, 0 }, - { DNS_PRESSED, TTK_STATE_PRESSED, 0 }, - { DNS_HOT, TTK_STATE_ACTIVE, 0 }, - { DNS_NORMAL, 0, 0 }, -}; - -/* - * Trackbar thumb: (Tk: "scale slider") - */ -static const Ttk_StateTable scale_statemap[] = -{ - { TUS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TUS_PRESSED, TTK_STATE_PRESSED, 0 }, - { TUS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { TUS_HOT, TTK_STATE_ACTIVE, 0 }, - { TUS_NORMAL, 0, 0 } -}; - -static const Ttk_StateTable tabitem_statemap[] = -{ - { TIS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TIS_SELECTED, TTK_STATE_SELECTED, 0 }, - { TIS_HOT, TTK_STATE_ACTIVE, 0 }, - { TIS_FOCUSED, TTK_STATE_FOCUS, 0 }, - { TIS_NORMAL, 0, 0 }, -}; - - -/* - *---------------------------------------------------------------------- - * +++ Element data: - * - * The following structure is passed as the 'clientData' pointer - * to most elements in this theme. It contains data relevant - * to a single XP Theme "part". - * - * <<NOTE-GetThemeMargins>>: - * In theory, we should be call GetThemeMargins(...TMT_CONTENTRECT...) - * to calculate the internal padding. In practice, this routine - * only seems to work properly for BP_PUSHBUTTON. So we hardcode - * the required padding at element registration time instead. - * - * The PAD_MARGINS flag bit determines whether the padding - * should be added on the inside (0) or outside (1) of the element. - * - * <<NOTE-GetThemePartSize>>: - * This gives bogus metrics for some parts (in particular, - * BP_PUSHBUTTONS). Set the IGNORE_THEMESIZE flag to skip this call. - */ - -typedef struct /* XP element specifications */ -{ - const char *elementName; /* Tk theme engine element name */ - const Ttk_ElementSpec *elementSpec; - /* Element spec (usually GenericElementSpec) */ - LPCWSTR className; /* Windows window class name */ - int partId; /* BP_PUSHBUTTON, BP_CHECKBUTTON, etc. */ - const Ttk_StateTable *statemap; /* Map Tk states to XP states */ - Ttk_Padding padding; /* See NOTE-GetThemeMargins */ - unsigned flags; -# define IGNORE_THEMESIZE 0x80000000U /* See NOTE-GetThemePartSize */ -# define PAD_MARGINS 0x40000000U /* See NOTE-GetThemeMargins */ -# define HEAP_ELEMENT 0x20000000U /* ElementInfo is on heap */ -# define HALF_HEIGHT 0x10000000U /* Used by GenericSizedElements */ -# define HALF_WIDTH 0x08000000U /* Used by GenericSizedElements */ -} ElementInfo; - -typedef struct -{ - /* - * Static data, initialized when element is registered: - */ - const ElementInfo *info; - XPThemeProcs *procs; /* Pointer to theme procedure table */ - - /* - * Dynamic data, allocated by InitElementData: - */ - HTHEME hTheme; - HDC hDC; - HWND hwnd; - - /* For TkWinDrawableReleaseDC: */ - Drawable drawable; - TkWinDCState dcState; -} ElementData; - -static ElementData * -NewElementData(XPThemeProcs *procs, const ElementInfo *info) -{ - ElementData *elementData = (ElementData *)ckalloc(sizeof(ElementData)); - - elementData->procs = procs; - elementData->info = info; - elementData->hTheme = elementData->hDC = 0; - - return elementData; -} - -/* - * Destroy elements. If the element was created by the element factory - * then the info member is dynamically allocated. Otherwise it was - * static data from the C object and only the ElementData needs freeing. - */ -static void DestroyElementData(void *clientData) -{ - ElementData *elementData = (ElementData *)clientData; - if (elementData->info->flags & HEAP_ELEMENT) { - ckfree((void *)elementData->info->statemap); - ckfree((void *)elementData->info->className); - ckfree((void *)elementData->info->elementName); - ckfree((void *)elementData->info); - } - ckfree(clientData); -} - -/* - * InitElementData -- - * Looks up theme handle. If Drawable argument is non-NULL, - * also initializes DC. - * - * Returns: - * 1 on success, 0 on error. - * Caller must later call FreeElementData() so this element - * can be reused. - */ - -static int -InitElementData(ElementData *elementData, Tk_Window tkwin, Drawable d) -{ - Window win = Tk_WindowId(tkwin); - - if (win) { - elementData->hwnd = Tk_GetHWND(win); - } else { - elementData->hwnd = elementData->procs->stubWindow; - } - - elementData->hTheme = elementData->procs->OpenThemeData( - elementData->hwnd, elementData->info->className); - - if (!elementData->hTheme) { - return 0; - } - - elementData->drawable = d; - if (d != 0) { - elementData->hDC = TkWinGetDrawableDC(Tk_Display(tkwin), d, - &elementData->dcState); - } - - return 1; -} - -static void -FreeElementData(ElementData *elementData) -{ - elementData->procs->CloseThemeData(elementData->hTheme); - if (elementData->drawable != 0) { - TkWinReleaseDrawableDC( - elementData->drawable, elementData->hDC, &elementData->dcState); - } -} - -/*---------------------------------------------------------------------- - * +++ Generic element implementation. - * - * Used for elements which are handled entirely by the XP Theme API, - * such as radiobutton and checkbutton indicators, scrollbar arrows, etc. - */ - -static void GenericElementSize( - void *clientData, - TCL_UNUSED(void *), /* elementRecord */ - Tk_Window tkwin, - int *widthPtr, - int *heightPtr, - Ttk_Padding *paddingPtr) -{ - ElementData *elementData = (ElementData *)clientData; - HRESULT result; - SIZE size; - - if (!InitElementData(elementData, tkwin, 0)) { - return; - } - - if (!(elementData->info->flags & IGNORE_THEMESIZE)) { - result = elementData->procs->GetThemePartSize( - elementData->hTheme, - NULL, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, 0), - NULL /*RECT *prc*/, - TS_TRUE, - &size); - - if (SUCCEEDED(result)) { - *widthPtr = size.cx; - *heightPtr = size.cy; - } - } - - /* See NOTE-GetThemeMargins - */ - *paddingPtr = elementData->info->padding; - if (elementData->info->flags & PAD_MARGINS) { - *widthPtr += Ttk_PaddingWidth(elementData->info->padding); - *heightPtr += Ttk_PaddingHeight(elementData->info->padding); - } -} - -static void GenericElementDraw( - void *clientData, - TCL_UNUSED(void *), /* elementRecord */ - Tk_Window tkwin, - Drawable d, - Ttk_Box b, - Ttk_State state) -{ - ElementData *elementData = (ElementData *)clientData; - RECT rc; - - if (!InitElementData(elementData, tkwin, d)) { - return; - } - - if (elementData->info->flags & PAD_MARGINS) { - b = Ttk_PadBox(b, elementData->info->padding); - } - rc = BoxToRect(b); - - elementData->procs->DrawThemeBackground( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, state), - &rc, - NULL/*pContentRect*/); - - FreeElementData(elementData); -} - -static const Ttk_ElementSpec GenericElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Sized element implementation. - * - * Used for elements which are handled entirely by the XP Theme API, - * but that require a fixed size adjustment. - * Note that GetThemeSysSize calls through to GetSystemMetrics - */ - -static void -GenericSizedElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = (ElementData *)clientData; - - if (!InitElementData(elementData, tkwin, 0)) { - return; - } - - GenericElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - *widthPtr = elementData->procs->GetThemeSysSize(NULL, - (elementData->info->flags >> 8) & 0xff); - *heightPtr = elementData->procs->GetThemeSysSize(NULL, - elementData->info->flags & 0xff); - if (elementData->info->flags & HALF_HEIGHT) { - *heightPtr /= 2; - } - if (elementData->info->flags & HALF_WIDTH) { - *widthPtr /= 2; - } -} - -static const Ttk_ElementSpec GenericSizedElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericSizedElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Spinbox arrow element. - * These are half-height scrollbar buttons. - */ - -static void -SpinboxArrowElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = (ElementData *)clientData; - - if (!InitElementData(elementData, tkwin, 0)) { - return; - } - - GenericSizedElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - /* force the arrow button height to half size */ - *heightPtr /= 2; -} - -static const Ttk_ElementSpec SpinboxArrowElementSpec = { - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - SpinboxArrowElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Scrollbar thumb element. - * Same as a GenericElement, but don't draw in the disabled state. - */ - -static void ThumbElementDraw( - void *clientData, - TCL_UNUSED(void *), /* elementRecord */ - Tk_Window tkwin, - Drawable d, - Ttk_Box b, - Ttk_State state) -{ - ElementData *elementData = (ElementData *)clientData; - unsigned stateId = Ttk_StateTableLookup(elementData->info->statemap, state); - RECT rc = BoxToRect(b); - - /* - * Don't draw the thumb if we are disabled. - */ - if (state & TTK_STATE_DISABLED) { - return; - } - - if (!InitElementData(elementData, tkwin, d)) { - return; - } - - elementData->procs->DrawThemeBackground(elementData->hTheme, - elementData->hDC, elementData->info->partId, stateId, - &rc, NULL); - - FreeElementData(elementData); -} - -static const Ttk_ElementSpec ThumbElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - ThumbElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Progress bar element. - * Increases the requested length of PP_CHUNK and PP_CHUNKVERT parts - * so that indeterminate progress bars show 3 bars instead of 1. - */ - -static void PbarElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - ElementData *elementData = (ElementData *)clientData; - int nBars = 3; - - GenericElementSize(clientData, elementRecord, tkwin, - widthPtr, heightPtr, paddingPtr); - - if (elementData->info->partId == PP_CHUNK) { - *widthPtr *= nBars; - } else if (elementData->info->partId == PP_CHUNKVERT) { - *heightPtr *= nBars; - } -} - -static const Ttk_ElementSpec PbarElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - PbarElementSize, - GenericElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Notebook tab element. - * Same as generic element, with additional logic to select - * proper iPartID for the leftmost tab. - * - * Notes: TABP_TABITEMRIGHTEDGE (or TABP_TOPTABITEMRIGHTEDGE, - * which appears to be identical) should be used if the - * tab is exactly at the right edge of the notebook, but - * not if it's simply the rightmost tab. This information - * is not available. - * - * The TIS_* and TILES_* definitions are identical, so - * we can use the same statemap no matter what the partId. - */ - -static void TabElementSize( - void *clientData, - void *elementRecord, - Tk_Window tkwin, - int *widthPtr, - int *heightPtr, - Ttk_Padding *paddingPtr) -{ - Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S; - TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr; - - if (mainInfoPtr != NULL) { - nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit; - } - - 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 *), /* elementRecord */ - Tk_Window tkwin, - Drawable d, - Ttk_Box b, - Ttk_State state) -{ - Ttk_PositionSpec nbTabsStickBit = TTK_STICK_S; - TkMainInfo *mainInfoPtr = ((TkWindow *) tkwin)->mainPtr; - ElementData *elementData = (ElementData *)clientData; - int partId = elementData->info->partId; - int isSelected = (state & TTK_STATE_SELECTED); - int stateId = Ttk_StateTableLookup(elementData->info->statemap, state); - - if (mainInfoPtr != NULL) { - nbTabsStickBit = (Ttk_PositionSpec) mainInfoPtr->ttkNbTabsStickBit; - } - - /* - * 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 ? 1 : 2; b.width -= isSelected ? 1 : 0; - break; - } - - RECT rc = BoxToRect(b); - - if (!InitElementData(elementData, tkwin, d)) { - return; - } - - if (nbTabsStickBit == TTK_STICK_S) { - if (state & TTK_STATE_FIRST) { - 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); -} - -static const Ttk_ElementSpec TabElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - TabElementSize, - TabElementDraw -}; - -/*---------------------------------------------------------------------- - * +++ Tree indicator element. - * - * Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set - */ - -static const Ttk_StateTable header_statemap[] = -{ - { HIS_PRESSED, TTK_STATE_PRESSED, 0 }, - { HIS_HOT, TTK_STATE_ACTIVE, 0 }, - { HIS_NORMAL, 0,0 }, -}; - -static const Ttk_StateTable treeview_statemap[] = -{ - { TREIS_DISABLED, TTK_STATE_DISABLED, 0 }, - { TREIS_SELECTED, TTK_STATE_SELECTED, 0}, - { TREIS_HOT, TTK_STATE_ACTIVE, 0 }, - { TREIS_NORMAL, 0,0 }, -}; - -static const Ttk_StateTable tvpglyph_statemap[] = -{ - { GLPS_OPENED, TTK_STATE_OPEN, 0 }, - { GLPS_CLOSED, 0,0 }, -}; - -static void TreeIndicatorElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, Ttk_State state) -{ - if (!(state & TTK_STATE_LEAF)) { - GenericElementDraw(clientData,elementRecord,tkwin,d,b,state); - } -} - -static const Ttk_ElementSpec TreeIndicatorElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(NullElement), - TtkNullElementOptions, - GenericElementSize, - TreeIndicatorElementDraw -}; - -#ifdef BROKEN_TEXT_ELEMENT - -/* - *---------------------------------------------------------------------- - * Text element (does not work yet). - * - * According to "Using Windows XP Visual Styles", we need to select - * a font into the DC before calling DrawThemeText(). - * There's just no easy way to get an HFONT out of a Tk_Font. - * Maybe GetThemeFont() would work? - * - */ - -typedef struct -{ - Tcl_Obj *textObj; - Tcl_Obj *fontObj; -} TextElement; - -static const Ttk_ElementOptionSpec TextElementOptions[] = -{ - { "-text", TK_OPTION_STRING, - offsetof(TextElement,textObj), "" }, - { "-font", TK_OPTION_FONT, - offsetof(TextElement,fontObj), DEFAULT_FONT }, - { NULL } -}; - -static void TextElementSize( - void *clientData, void *elementRecord, Tk_Window tkwin, - int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) -{ - TextElement *element = elementRecord; - ElementData *elementData = clientData; - RECT rc = {0, 0}; - HRESULT hr = S_OK; - const char *src; - Tcl_Size len; - Tcl_DString ds; - - if (!InitElementData(elementData, tkwin, 0)) { - return; - } - - src = Tcl_GetStringFromObj(element->textObj, &len); - Tcl_DStringInit(&ds); - hr = elementData->procs->GetThemeTextExtent( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, 0), - Tcl_UtfToWCharDString(src, len, &ds), - -1, - DT_LEFT /* | DT_BOTTOM | DT_NOPREFIX */, - NULL, - &rc); - - if (SUCCEEDED(hr)) { - *widthPtr = rc.right - rc.left; - *heightPtr = rc.bottom - rc.top; - } - if (*widthPtr < 80) *widthPtr = 80; - if (*heightPtr < 20) *heightPtr = 20; - - Tcl_DStringFree(&ds); - FreeElementData(elementData); -} - -static void TextElementDraw( - void *clientData, void *elementRecord, Tk_Window tkwin, - Drawable d, Ttk_Box b, Ttk_State state) -{ - TextElement *element = elementRecord; - ElementData *elementData = clientData; - RECT rc = BoxToRect(b); - HRESULT hr = S_OK; - const char *src; - Tcl_Size len; - Tcl_DString ds; - - if (!InitElementData(elementData, tkwin, d)) { - return; - } - - src = Tcl_GetStringFromObj(element->textObj, &len); - Tcl_DStringInit(&ds); - hr = elementData->procs->DrawThemeText( - elementData->hTheme, - elementData->hDC, - elementData->info->partId, - Ttk_StateTableLookup(elementData->info->statemap, state), - Tcl_UtfToWCharDString(src, len, &ds), - -1, - DT_LEFT /* | DT_BOTTOM | DT_NOPREFIX */, - (state & TTK_STATE_DISABLED) ? DTT_GRAYED : 0, - &rc); - - Tcl_DStringFree(&ds); - FreeElementData(elementData); -} - -static const Ttk_ElementSpec TextElementSpec = -{ - TK_STYLE_VERSION_2, - sizeof(TextElement), - TextElementOptions, - TextElementSize, - TextElementDraw -}; - -#endif /* BROKEN_TEXT_ELEMENT */ - -/*---------------------------------------------------------------------- - * +++ Widget layouts: - */ - -TTK_BEGIN_LAYOUT_TABLE(LayoutTable) - -TTK_LAYOUT("TButton", - TTK_GROUP("Button.button", TTK_FILL_BOTH, - TTK_GROUP("Button.focus", TTK_FILL_BOTH, - TTK_GROUP("Button.padding", TTK_FILL_BOTH, - TTK_NODE("Button.label", TTK_FILL_BOTH))))) - -TTK_LAYOUT("TMenubutton", - TTK_NODE("Menubutton.dropdown", TTK_PACK_RIGHT|TTK_FILL_Y) - TTK_GROUP("Menubutton.button", TTK_FILL_BOTH, - TTK_GROUP("Menubutton.padding", TTK_FILL_X, - TTK_NODE("Menubutton.label", 0)))) - -TTK_LAYOUT("Horizontal.TScrollbar", - TTK_GROUP("Horizontal.Scrollbar.trough", TTK_FILL_X, - TTK_NODE("Horizontal.Scrollbar.leftarrow", TTK_PACK_LEFT) - TTK_NODE("Horizontal.Scrollbar.rightarrow", TTK_PACK_RIGHT) - TTK_GROUP("Horizontal.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT, - TTK_NODE("Horizontal.Scrollbar.grip", 0)))) - -TTK_LAYOUT("Vertical.TScrollbar", - TTK_GROUP("Vertical.Scrollbar.trough", TTK_FILL_Y, - TTK_NODE("Vertical.Scrollbar.uparrow", TTK_PACK_TOP) - TTK_NODE("Vertical.Scrollbar.downarrow", TTK_PACK_BOTTOM) - TTK_GROUP("Vertical.Scrollbar.thumb", TTK_FILL_BOTH|TTK_UNIT, - TTK_NODE("Vertical.Scrollbar.grip", 0)))) - -TTK_LAYOUT("Horizontal.TScale", - TTK_GROUP("Scale.focus", TTK_FILL_BOTH, - TTK_GROUP("Horizontal.Scale.trough", TTK_FILL_BOTH, - TTK_NODE("Horizontal.Scale.track", TTK_FILL_X) - TTK_NODE("Horizontal.Scale.slider", TTK_PACK_LEFT) ))) - -TTK_LAYOUT("Vertical.TScale", - TTK_GROUP("Scale.focus", TTK_FILL_BOTH, - TTK_GROUP("Vertical.Scale.trough", TTK_FILL_BOTH, - TTK_NODE("Vertical.Scale.track", TTK_FILL_Y) - TTK_NODE("Vertical.Scale.slider", TTK_PACK_TOP) ))) - -TTK_END_LAYOUT_TABLE - -/*---------------------------------------------------------------------- - * +++ XP element info table: - */ - -#define PAD(l,t,r,b) {l,t,r,b} -#define NOPAD {0,0,0,0} - -/* name spec className partId statemap padding flags */ - -static const ElementInfo ElementInfoTable[] = { - { "Checkbutton.indicator", &GenericElementSpec, L"BUTTON", - BP_CHECKBOX, checkbox_statemap, PAD(0, 0, 4, 0), PAD_MARGINS }, - { "Radiobutton.indicator", &GenericElementSpec, L"BUTTON", - BP_RADIOBUTTON, radiobutton_statemap, PAD(0, 0, 4, 0), PAD_MARGINS }, - { "Button.button", &GenericElementSpec, L"BUTTON", - BP_PUSHBUTTON, pushbutton_statemap, PAD(3, 3, 3, 3), IGNORE_THEMESIZE }, - { "Labelframe.border", &GenericElementSpec, L"BUTTON", - BP_GROUPBOX, groupbox_statemap, PAD(2, 2, 2, 2), 0 }, - { "Entry.field", &GenericElementSpec, L"EDIT", EP_EDITTEXT, - edittext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Combobox.field", &GenericElementSpec, L"EDIT", - EP_EDITTEXT, combotext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Combobox.downarrow", &GenericSizedElementSpec, L"COMBOBOX", - CP_DROPDOWNBUTTON, combobox_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Vertical.Scrollbar.trough", &GenericElementSpec, L"SCROLLBAR", - SBP_UPPERTRACKVERT, scrollbar_statemap, NOPAD, 0 }, - { "Vertical.Scrollbar.thumb", &ThumbElementSpec, L"SCROLLBAR", - SBP_THUMBBTNVERT, scrollbar_statemap, NOPAD, 0 }, - { "Vertical.Scrollbar.grip", &GenericElementSpec, L"SCROLLBAR", - SBP_GRIPPERVERT, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.trough", &GenericElementSpec, L"SCROLLBAR", - SBP_UPPERTRACKHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.thumb", &ThumbElementSpec, L"SCROLLBAR", - SBP_THUMBBTNHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Horizontal.Scrollbar.grip", &GenericElementSpec, L"SCROLLBAR", - SBP_GRIPPERHORZ, scrollbar_statemap, NOPAD, 0 }, - { "Scrollbar.uparrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, uparrow_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Scrollbar.downarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, downarrow_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Scrollbar.leftarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, leftarrow_statemap, NOPAD, - (SM_CXHSCROLL << 8) | SM_CYHSCROLL }, - { "Scrollbar.rightarrow", &GenericSizedElementSpec, L"SCROLLBAR", - SBP_ARROWBTN, rightarrow_statemap, NOPAD, - (SM_CXHSCROLL << 8) | SM_CYHSCROLL }, - { "Horizontal.Scale.slider", &GenericElementSpec, L"TRACKBAR", - TKP_THUMB, scale_statemap, NOPAD, 0 }, - { "Vertical.Scale.slider", &GenericElementSpec, L"TRACKBAR", - TKP_THUMBVERT, scale_statemap, NOPAD, 0 }, - { "Horizontal.Scale.track", &GenericElementSpec, L"TRACKBAR", - TKP_TRACK, scale_statemap, NOPAD, 0 }, - { "Vertical.Scale.track", &GenericElementSpec, L"TRACKBAR", - TKP_TRACKVERT, scale_statemap, NOPAD, 0 }, - /* ttk::progressbar elements */ - { "Horizontal.Progressbar.pbar", &PbarElementSpec, L"PROGRESS", - PP_CHUNK, null_statemap, NOPAD, 0 }, - { "Vertical.Progressbar.pbar", &PbarElementSpec, L"PROGRESS", - PP_CHUNKVERT, null_statemap, NOPAD, 0 }, - { "Horizontal.Progressbar.trough", &GenericElementSpec, L"PROGRESS", - PP_BAR, null_statemap, PAD(3,3,3,3), IGNORE_THEMESIZE }, - { "Vertical.Progressbar.trough", &GenericElementSpec, L"PROGRESS", - PP_BARVERT, null_statemap, PAD(3,3,3,3), IGNORE_THEMESIZE }, - /* ttk::notebook */ - { "tab", &TabElementSpec, L"TAB", - TABP_TABITEM, tabitem_statemap, PAD(3,3,3,0), 0 }, - { "client", &GenericElementSpec, L"TAB", - TABP_PANE, null_statemap, PAD(1,1,3,3), 0 }, - { "NotebookPane.background", &GenericElementSpec, L"TAB", - TABP_BODY, null_statemap, NOPAD, 0 }, - { "Toolbutton.border", &GenericElementSpec, L"TOOLBAR", - TP_BUTTON, toolbutton_statemap, NOPAD, 0 }, - { "Menubutton.button", &GenericElementSpec, L"TOOLBAR", - TP_SPLITBUTTON, toolbutton_statemap, NOPAD, 0 }, - { "Menubutton.dropdown", &GenericSizedElementSpec, L"TOOLBAR", - TP_SPLITBUTTONDROPDOWN, toolbutton_statemap, NOPAD, - (SM_CXVSCROLL << 8) | SM_CYVSCROLL }, - { "Treeview.field", &GenericElementSpec, L"TREEVIEW", - TVP_TREEITEM, treeview_statemap, PAD(1, 1, 1, 1), IGNORE_THEMESIZE }, - { "Treeitem.indicator", &TreeIndicatorElementSpec, L"TREEVIEW", - TVP_GLYPH, tvpglyph_statemap, PAD(1,1,6,0), PAD_MARGINS }, - { "Treeheading.border", &GenericElementSpec, L"HEADER", - HP_HEADERITEM, header_statemap, PAD(4,0,4,0), 0 }, - { "sizegrip", &GenericElementSpec, L"STATUS", - SP_GRIPPER, null_statemap, NOPAD, 0 }, - { "Spinbox.field", &GenericElementSpec, L"EDIT", - EP_EDITTEXT, edittext_statemap, PAD(1, 1, 1, 1), 0 }, - { "Spinbox.uparrow", &SpinboxArrowElementSpec, L"SPIN", - SPNP_UP, spinbutton_statemap, NOPAD, - PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, - { "Spinbox.downarrow", &SpinboxArrowElementSpec, L"SPIN", - SPNP_DOWN, spinbutton_statemap, NOPAD, - PAD_MARGINS | ((SM_CXVSCROLL << 8) | SM_CYVSCROLL) }, -#ifdef BROKEN_TEXT_ELEMENT - { "Labelframe.text", &TextElementSpec, L"BUTTON", - BP_GROUPBOX, groupbox_statemap, NOPAD, 0 }, -#endif - { 0, 0, 0, 0, 0, NOPAD, 0 } -}; -#undef PAD - - -static int -GetSysFlagFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr) -{ - static const char *const names[] = { - "SM_CXBORDER", "SM_CYBORDER", "SM_CXVSCROLL", "SM_CYVSCROLL", - "SM_CXHSCROLL", "SM_CYHSCROLL", "SM_CXMENUCHECK", "SM_CYMENUCHECK", - "SM_CXMENUSIZE", "SM_CYMENUSIZE", "SM_CXSIZE", "SM_CYSIZE", "SM_CXSMSIZE", - "SM_CYSMSIZE", NULL - }; - int flags[] = { - SM_CXBORDER, SM_CYBORDER, SM_CXVSCROLL, SM_CYVSCROLL, - SM_CXHSCROLL, SM_CYHSCROLL, SM_CXMENUCHECK, SM_CYMENUCHECK, - SM_CXMENUSIZE, SM_CYMENUSIZE, SM_CXSIZE, SM_CYSIZE, SM_CXSMSIZE, - SM_CYSMSIZE - }; - - Tcl_Obj **objv; - Tcl_Size i, objc; - - if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { - return TCL_ERROR; - } - if (objc != 2) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("wrong # args", TCL_INDEX_NONE)); - Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", (char *)NULL); - return TCL_ERROR; - } - for (i = 0; i < objc; ++i) { - int option; - if (Tcl_GetIndexFromObjStruct(interp, objv[i], names, - sizeof(char *), "system constant", 0, &option) != TCL_OK) - return TCL_ERROR; - *resultPtr |= (flags[option] << (8 * (1 - i))); - } - return TCL_OK; -} - -/*---------------------------------------------------------------------- - * Windows Visual Styles API Element Factory - * - * The Vista release has shown that the Windows Visual Styles can be - * extended with additional elements. This element factory can permit - * the programmer to create elements for use with script-defined layouts - * - * eg: to create the small close button: - * style element create smallclose vsapi \ - * WINDOW 19 {disabled 4 pressed 3 active 2 {} 1} - */ - -static int -Ttk_CreateVsapiElement( - Tcl_Interp *interp, - void *clientData, - Ttk_Theme theme, - const char *elementName, - Tcl_Size objc, - Tcl_Obj *const objv[]) -{ - XPThemeData *themeData = (XPThemeData *)clientData; - ElementInfo *elementPtr = NULL; - void *elementData; - LPCWSTR className; - int partId = 0; - Ttk_StateTable *stateTable; - Ttk_Padding pad = {0, 0, 0, 0}; - int flags = 0; - Tcl_Size length = 0; - char *name; - LPWSTR wname; - const Ttk_ElementSpec *elementSpec = &GenericElementSpec; - Tcl_DString classBuf; - - static const char *const optionStrings[] = - { "-halfheight", "-halfwidth", "-height", "-margins", "-padding", - "-syssize", "-width", NULL }; - enum { O_HALFHEIGHT, O_HALFWIDTH, O_HEIGHT, O_MARGINS, O_PADDING, - O_SYSSIZE, O_WIDTH }; - - if (objc < 2) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "missing required arguments 'class' and/or 'partId'", TCL_INDEX_NONE)); - Tcl_SetErrorCode(interp, "TTK", "VSAPI", "REQUIRED", (char *)NULL); - return TCL_ERROR; - } - - if (Tcl_GetIntFromObj(interp, objv[1], &partId) != TCL_OK) { - return TCL_ERROR; - } - name = Tcl_GetStringFromObj(objv[0], &length); - Tcl_DStringInit(&classBuf); - className = Tcl_UtfToWCharDString(name, length, &classBuf); - - /* flags or padding */ - if (objc > 3) { - Tcl_Size i = 3; - int option = 0; - for (i = 3; i < objc; i += 2) { - int tmp = 0; - if (i == objc -1) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "Missing value for \"%s\".", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TTK", "VSAPI", "MISSING", (char *)NULL); - goto retErr; - } - if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, - "option", 0, &option) != TCL_OK) - goto retErr; - switch (option) { - case O_PADDING: - if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) { - goto retErr; - } - break; - case O_MARGINS: - if (Ttk_GetBorderFromObj(interp, objv[i+1], &pad) != TCL_OK) { - goto retErr; - } - flags |= PAD_MARGINS; - break; - case O_WIDTH: - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - goto retErr; - } - pad.left = pad.right = tmp; - flags |= IGNORE_THEMESIZE; - break; - case O_HEIGHT: - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - goto retErr; - } - pad.top = pad.bottom = tmp; - flags |= IGNORE_THEMESIZE; - break; - case O_SYSSIZE: - if (GetSysFlagFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - goto retErr; - } - elementSpec = &GenericSizedElementSpec; - flags |= (tmp & 0xFFFF); - break; - case O_HALFHEIGHT: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - goto retErr; - } - if (tmp) { - flags |= HALF_HEIGHT; - } - break; - case O_HALFWIDTH: - if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { - goto retErr; - } - if (tmp) { - flags |= HALF_WIDTH; - } - break; - } - } - } - - /* convert a statemap into a state table */ - if (objc > 2) { - Tcl_Obj **specs; - Tcl_Size n, j, count; - int status = TCL_OK; - if (Tcl_ListObjGetElements(interp, objv[2], &count, &specs) != TCL_OK) { - goto retErr; - } - /* we over-allocate to ensure there is a terminating entry */ - stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable) * (count + 1)); - memset(stateTable, 0, sizeof(Ttk_StateTable) * (count + 1)); - for (n = 0, j = 0; status == TCL_OK && n < count; n += 2, ++j) { - Ttk_StateSpec spec = {0,0}; - status = Ttk_GetStateSpecFromObj(interp, specs[n], &spec); - if (status == TCL_OK) { - stateTable[j].onBits = spec.onbits; - stateTable[j].offBits = spec.offbits; - status = Tcl_GetIntFromObj(interp, specs[n+1], - &stateTable[j].index); - } - } - if (status != TCL_OK) { - ckfree(stateTable); - Tcl_DStringFree(&classBuf); - return status; - } - } else { - stateTable = (Ttk_StateTable *)ckalloc(sizeof(Ttk_StateTable)); - memset(stateTable, 0, sizeof(Ttk_StateTable)); - } - - elementPtr = (ElementInfo *)ckalloc(sizeof(ElementInfo)); - elementPtr->elementSpec = elementSpec; - elementPtr->partId = partId; - elementPtr->statemap = stateTable; - elementPtr->padding = pad; - elementPtr->flags = HEAP_ELEMENT | flags; - - /* set the element name to an allocated copy */ - name = (char *)ckalloc(strlen(elementName) + 1); - strcpy(name, elementName); - elementPtr->elementName = name; - - /* set the class name to an allocated copy */ - wname = (LPWSTR)ckalloc(Tcl_DStringLength(&classBuf) + sizeof(WCHAR)); - wcscpy(wname, className); - elementPtr->className = wname; - - elementData = NewElementData(themeData->procs, elementPtr); - Ttk_RegisterElement(NULL, - theme, elementName, elementPtr->elementSpec, elementData); - - Ttk_RegisterCleanup(interp, elementData, DestroyElementData); - Tcl_SetObjResult(interp, Tcl_NewStringObj(elementName, TCL_INDEX_NONE)); - Tcl_DStringFree(&classBuf); - return TCL_OK; - -retErr: - Tcl_DStringFree(&classBuf); - return TCL_ERROR; -} - -/*---------------------------------------------------------------------- - * +++ Initialization routine: - */ - -MODULE_SCOPE int -TtkXPTheme_Init(Tcl_Interp *interp, HWND hwnd) -{ - XPThemeData *themeData; - XPThemeProcs *procs; - HINSTANCE hlibrary; - Ttk_Theme themePtr, parentPtr, vistaPtr; - const ElementInfo *infoPtr; - - procs = LoadXPThemeProcs(&hlibrary); - if (!procs) { - return TCL_ERROR; - } - procs->stubWindow = hwnd; - - /* - * Create the new style engine. - */ - parentPtr = Ttk_GetTheme(interp, "winnative"); - themePtr = Ttk_CreateTheme(interp, "xpnative", parentPtr); - - if (!themePtr) { - return TCL_ERROR; - } - - /* - * Set theme data and cleanup proc - */ - - themeData = (XPThemeData *)ckalloc(sizeof(XPThemeData)); - themeData->procs = procs; - themeData->hlibrary = hlibrary; - - Ttk_SetThemeEnabledProc(themePtr, XPThemeEnabled, themeData); - Ttk_RegisterCleanup(interp, themeData, XPThemeDeleteProc); - Ttk_RegisterElementFactory(interp, "vsapi", Ttk_CreateVsapiElement, themeData); - - /* - * Create the vista theme on suitable platform versions and set the theme - * enable function. The theme itself is defined in script. - */ - - if (TkWinGetPlatformTheme() == TK_THEME_WIN_VISTA) { - vistaPtr = Ttk_CreateTheme(interp, "vista", themePtr); - if (vistaPtr) { - Ttk_SetThemeEnabledProc(vistaPtr, XPThemeEnabled, themeData); - } - } - - /* - * New elements: - */ - for (infoPtr = ElementInfoTable; infoPtr->elementName != 0; ++infoPtr) { - void *clientData = NewElementData(procs, infoPtr); - Ttk_RegisterElement(NULL, - themePtr, infoPtr->elementName, infoPtr->elementSpec, clientData); - Ttk_RegisterCleanup(interp, clientData, DestroyElementData); - } - - Ttk_RegisterElement(NULL, themePtr, "Scale.trough", &ttkNullElementSpec, 0); - - /* - * Layouts: - */ - Ttk_RegisterLayouts(themePtr, LayoutTable); - - Tcl_PkgProvide(interp, "ttk::theme::xpnative", TTK_VERSION); - - return TCL_OK; -} |
