miscellaneous LnF improvements, including support for Vista-style (patch 1588794)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44735 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-03-10 18:06:11 +00:00
parent 33e61c47c0
commit c905c0d60f
5 changed files with 392 additions and 168 deletions

View File

@@ -44,6 +44,7 @@
// parameters.
#if 0
#include <tmschema.h>
#include <VSStyle.h>
#else
//----------------------------------
#define EP_EDITTEXT 1
@@ -58,7 +59,55 @@
#define TMT_TEXTCOLOR 3803
#define TMT_BORDERCOLOR 3801
#define TMT_EDGEFILLCOLOR 3808
//----------------------------------
#define TMT_BGTYPE 4001
#define BT_IMAGEFILE 0
#define BT_BORDERFILL 1
#define CP_DROPDOWNBUTTON 1
#define CP_BACKGROUND 2 // This and above are Vista and later only
#define CP_TRANSPARENTBACKGROUND 3
#define CP_BORDER 4
#define CP_READONLY 5
#define CP_DROPDOWNBUTTONRIGHT 6
#define CP_DROPDOWNBUTTONLEFT 7
#define CP_CUEBANNER 8
#define CBXS_NORMAL 1
#define CBXS_HOT 2
#define CBXS_PRESSED 3
#define CBXS_DISABLED 4
#define CBXSR_NORMAL 1
#define CBXSR_HOT 2
#define CBXSR_PRESSED 3
#define CBXSR_DISABLED 4
#define CBXSL_NORMAL 1
#define CBXSL_HOT 2
#define CBXSL_PRESSED 3
#define CBXSL_DISABLED 4
#define CBTBS_NORMAL 1
#define CBTBS_HOT 2
#define CBTBS_DISABLED 3
#define CBTBS_FOCUSED 4
#define CBB_NORMAL 1
#define CBB_HOT 2
#define CBB_FOCUSED 3
#define CBB_DISABLED 4
#define CBRO_NORMAL 1
#define CBRO_HOT 2
#define CBRO_PRESSED 3
#define CBRO_DISABLED 4
#define CBCB_NORMAL 1
#define CBCB_HOT 2
#define CBCB_PRESSED 3
#define CBCB_DISABLED 4
#endif
@@ -68,7 +117,7 @@
#define TEXTCTRLXADJUST_XP 1
#define TEXTCTRLYADJUST_XP 3
#define TEXTCTRLXADJUST_CLASSIC 1
#define TEXTCTRLYADJUST_CLASSIC 2
#define TEXTCTRLYADJUST_CLASSIC 3
#define COMBOBOX_ANIMATION_RESOLUTION 10
@@ -114,9 +163,9 @@ bool wxComboCtrl::Create(wxWindow *parent,
if ( !border )
{
// For XP, have 1-width custom border, for older version use sunken
if ( theme )
{
// For XP, have 1-width custom border, for older version use sunken
border = wxBORDER_NONE;
m_widthCustomBorder = 1;
}
@@ -137,6 +186,12 @@ bool wxComboCtrl::Create(wxWindow *parent,
name) )
return false;
if ( theme )
{
if ( ::wxGetWinVersion() >= wxWinVersion_Vista )
m_iFlags |= wxCC_BUTTON_STAYS_DOWN |wxCC_BUTTON_COVERS_BORDER;
}
if ( style & wxCC_STD_BUTTON )
m_iFlags |= wxCC_POPUP_ON_MOUSE_UP;
@@ -252,11 +307,10 @@ void
wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
wxUxThemeHandle hTheme(this, L"COMBOBOX");
//COLORREF cref;
wxSize sz = GetClientSize();
bool isEnabled;
bool isFocused; // also selected
bool doDrawFocusRect; // also selected
// For smaller size control (and for disabled background) use less spacing
int focusSpacingX;
@@ -266,7 +320,7 @@ wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
// Drawing control
isEnabled = IsEnabled();
isFocused = ShouldDrawFocus();
doDrawFocusRect = ShouldDrawFocus();
// Windows-style: for smaller size control (and for disabled background) use less spacing
if ( hTheme )
@@ -294,7 +348,7 @@ wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const
{
// Drawing a list item
isEnabled = true; // they are never disabled
isFocused = flags & wxCONTROL_SELECTED ? true : false;
doDrawFocusRect = flags & wxCONTROL_SELECTED ? true : false;
focusSpacingX = 0;
focusSpacingY = 0;
@@ -318,70 +372,61 @@ wxComboCtrl::PrepareBackground( wxDC& dc, const wxRect& rect, int flags ) const
// theme = wxUxThemeEngine::GetIfActive();
wxColour bgCol;
bool drawDottedEdge = false;
bool doDrawDottedEdge = false;
bool doDrawSelRect = true;
// TODO: doDrawDottedEdge = true when focus has arrived to control via tab.
// (and other cases which are not that apparent).
if ( isEnabled )
{
// If popup is hidden and this control is focused,
// then draw the focus-indicator (selbgcolor background etc.).
if ( isFocused )
if ( doDrawFocusRect )
{
#if 0
// TODO: Proper theme color getting (JMS: I don't know which parts/colors to use,
// those below don't work)
if ( hTheme )
// NB: We can't really use XP visual styles to get TMT_TEXTCOLOR since
// it is not properly defined for combo boxes. Instead, they expect
// you to use DrawThemeText.
//
// Here is, however, sample code how to get theme colours:
//
// COLORREF cref;
// theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_NORMAL,TMT_TEXTCOLOR,&cref);
// dc.SetTextForeground( wxRGBToColour(cref) );
if ( (m_iFlags & wxCC_FULL_BUTTON) && !(flags & wxCONTROL_ISSUBMENU) )
{
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_SELECTED,TMT_TEXTCOLOR,&cref);
dc.SetTextForeground( wxRGBToColour(cref) );
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_SELECTED,TMT_FILLCOLOR,&cref);
bgCol = wxRGBToColour(cref);
// Vista style read-only combo
doDrawSelRect = false;
doDrawDottedEdge = true;
}
else
#endif
{
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
if ( m_windowStyle & wxCB_READONLY )
drawDottedEdge = true;
}
}
else
{
/*if ( hTheme )
{
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_NORMAL,TMT_TEXTCOLOR,&cref);
dc.SetTextForeground( wxRGBToColour(cref) );
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_NORMAL,TMT_FILLCOLOR,&cref);
bgCol = wxRGBToColour(cref);
}
else
{*/
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
bgCol = GetBackgroundColour();
//}
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
bgCol = GetBackgroundColour();
doDrawSelRect = false;
}
}
else
{
/*if ( hTheme )
{
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_DISABLED,TMT_TEXTCOLOR,&cref);
dc.SetTextForeground( wxRGBToColour(cref) );
theme->GetThemeColor(hTheme,EP_EDITTEXT,ETS_DISABLED,TMT_EDGEFILLCOLOR,&cref);
bgCol = wxRGBToColour(cref);
}
else
{*/
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT) );
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
//}
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT) );
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
}
dc.SetBrush(bgCol);
dc.SetPen(bgCol);
dc.DrawRectangle(selRect);
if ( drawDottedEdge )
wxMSWDrawFocusRect(dc,selRect);
if ( doDrawSelRect )
{
dc.SetPen(bgCol);
dc.DrawRectangle(selRect);
}
if ( doDrawDottedEdge )
wxMSWDrawFocusRect(dc, selRect);
// Don't clip exactly to the selection rectangle so we can draw
// to the non-selected area in front of it.
@@ -397,84 +442,187 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
wxSize sz = GetClientSize();
wxAutoBufferedPaintDC dc(this);
const wxRect& rectb = m_btnArea;
wxRect rect = m_tcArea;
bool isEnabled = IsEnabled();
const wxRect& rectButton = m_btnArea;
wxRect rectTextField = m_tcArea;
const bool isEnabled = IsEnabled();
wxColour bgCol = GetBackgroundColour();
wxColour fgCol;
HDC hDc = GetHdcOf(dc);
HWND hWnd = GetHwndOf(this);
wxUxThemeEngine* theme = NULL;
wxUxThemeHandle hTheme(this, L"COMBOBOX");
int etsState;
// area around both controls
wxRect rect2(0,0,sz.x,sz.y);
if ( hTheme )
theme = wxUxThemeEngine::GetIfActive();
wxRect borderRect(0,0,sz.x,sz.y);
if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
{
rect2 = m_tcArea;
rect2.Inflate(1);
borderRect = m_tcArea;
borderRect.Inflate(1);
}
// Use theme to draw border on XP
int drawButFlags = 0;
if ( hTheme )
{
theme = wxUxThemeEngine::GetIfActive();
COLORREF cref;
const bool useVistaComboBox = ::wxGetWinVersion() >= wxWinVersion_Vista;
RECT rFull;
wxCopyRectToRECT(borderRect, rFull);
RECT rButton;
wxCopyRectToRECT(rectButton, rButton);
RECT rBorder;
wxCopyRectToRECT(borderRect, rBorder);
bool isNonStdButton = (m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) ||
(m_iFlags & wxCC_IFLAG_HAS_NONSTANDARD_BUTTON);
//
// Get some states for themed drawing
int butState;
// Select correct border colour
if ( !isEnabled )
etsState = ETS_DISABLED;
else
etsState = ETS_NORMAL;
if ( m_widthCustomBorder )
{
theme->GetThemeColor(hTheme,EP_EDITTEXT,etsState,TMT_BORDERCOLOR,&cref);
// Set border colour
dc.SetPen( wxRGBToColour(cref) );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle(rect2);
butState = CBXS_DISABLED;
}
// Vista will display the drop-button as depressed always
// when the popup window is visilbe
else if ( (m_btnState & wxCONTROL_PRESSED) ||
(useVistaComboBox && !IsPopupWindowState(Hidden)) )
{
butState = CBXS_PRESSED;
}
else if ( m_btnState & wxCONTROL_CURRENT )
{
butState = CBXS_HOT;
}
else
{
butState = CBXS_NORMAL;
}
theme->GetThemeColor(hTheme,EP_EDITTEXT,etsState,TMT_TEXTCOLOR,&cref);
fgCol = wxRGBToColour(cref);
int comboBoxPart = 0; // For XP, use the 'default' part
RECT* rUseForBg = &rBorder;
bool drawFullButton = false;
int bgState = butState;
const bool isFocused = (FindFocus() == GetMainWindowOfCompositeControl()) ? true : false;
if ( useVistaComboBox )
{
// FIXME: Either SetBackgroundColour or GetBackgroundColour
// doesn't work under Vista, so here's a temporary
// workaround.
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
// Draw the entire control as a single button?
if ( !isNonStdButton )
{
if ( HasFlag(wxCB_READONLY) )
drawFullButton = true;
}
if ( drawFullButton )
{
comboBoxPart = CP_READONLY;
rUseForBg = &rFull;
// It should be safe enough to update this flag here.
m_iFlags |= wxCC_FULL_BUTTON;
}
else
{
comboBoxPart = CP_BORDER;
m_iFlags &= ~wxCC_FULL_BUTTON;
if ( isFocused )
bgState = CBB_FOCUSED;
else
bgState = CBB_NORMAL;
}
}
//
// Draw parent's background, if necessary
RECT* rUseForTb = NULL;
if ( theme->IsThemeBackgroundPartiallyTransparent( hTheme, comboBoxPart, bgState ) )
rUseForTb = &rFull;
else if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
rUseForTb = &rButton;
if ( rUseForTb )
theme->DrawThemeParentBackground( hWnd, hDc, rUseForTb );
//
// Draw the control background (including the border)
if ( m_widthCustomBorder > 0 )
{
theme->DrawThemeBackground( hTheme, hDc, comboBoxPart, bgState, rUseForBg, NULL );
}
else
{
// No border. We can't use theme, since it cannot be relied on
// to deliver borderless drawing, even with DrawThemeBackgroundEx.
dc.SetBrush(bgCol);
dc.SetPen(bgCol);
dc.DrawRectangle(borderRect);
}
//
// Draw the drop-button
if ( !isNonStdButton )
{
drawButFlags = Button_BitmapOnly;
int butPart = CP_DROPDOWNBUTTON;
if ( useVistaComboBox )
{
if ( drawFullButton )
{
// We need to alter the button style slightly before
// drawing the actual button (but it was good above
// when background etc was done).
if ( butState == CBXS_HOT || butState == CBXS_PRESSED )
butState = CBXS_NORMAL;
}
if ( m_btnSide == wxRIGHT )
butPart = CP_DROPDOWNBUTTONRIGHT;
else
butPart = CP_DROPDOWNBUTTONLEFT;
}
theme->DrawThemeBackground( hTheme, hDc, butPart, butState, &rButton, NULL );
}
else if ( useVistaComboBox &&
(m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) )
{
// We'll do this, because DrawThemeParentBackground
// doesn't seem to be reliable on Vista.
drawButFlags |= Button_PaintBackground;
}
}
else
{
// draw regular background
fgCol = GetForegroundColour();
// Windows 2000 and earlier
drawButFlags = Button_PaintBackground;
dc.SetBrush(bgCol);
dc.SetPen(bgCol);
dc.DrawRectangle(borderRect);
}
rect2.Deflate(m_widthCustomBorder);
// Button rendering (may only do the bitmap on button, depending on the flags)
DrawButton( dc, rectButton, drawButFlags );
dc.SetBrush(bgCol);
dc.SetPen(bgCol);
// clear main background
dc.DrawRectangle(rect);
// Button background with theme?
int drawButFlags = Draw_PaintBg;
if ( hTheme && m_blankButtonBg )
{
RECT r;
wxCopyRectToRECT(rectb, r);
// Draw parent background if needed (since button looks like its out of
// the combo, this is preferred).
theme->DrawThemeParentBackground(GetHwndOf(this),
GetHdcOf(dc),
&r);
drawButFlags = 0;
}
// Standard button rendering
DrawButton(dc,rectb,drawButFlags);
// paint required portion on the control
// Paint required portion of the custom image on the control
if ( (!m_text || m_widthCustomPaint) )
{
wxASSERT( m_widthCustomPaint >= 0 );
@@ -482,15 +630,15 @@ void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
// this is intentionally here to allow drawed rectangle's
// right edge to be hidden
if ( m_text )
rect.width = m_widthCustomPaint;
rectTextField.width = m_widthCustomPaint;
dc.SetFont( GetFont() );
dc.SetClippingRegion(rect);
dc.SetClippingRegion(rectTextField);
if ( m_popupInterface )
m_popupInterface->PaintComboControl(dc,rect);
m_popupInterface->PaintComboControl(dc,rectTextField);
else
wxComboPopup::DefaultPaintComboControl(this,dc,rect);
wxComboPopup::DefaultPaintComboControl(this,dc,rectTextField);
}
}