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

@@ -377,12 +377,14 @@ bool wxComboPopupWindow::Show( bool show )
wxASSERT( IsKindOf(CLASSINFO(wxPopupTransientWindow)) );
wxPopupTransientWindow* ptw = (wxPopupTransientWindow*) this;
wxComboCtrlBase* combo = (wxComboCtrlBase*) GetParent();
if ( show != ptw->IsShown() )
{
if ( show )
ptw->Popup(combo->GetPopupControl()->GetControl());
// We used to do wxPopupTransientWindow::Popup here,
// but this would hide normal Show, which we are
// also going to need.
ptw->Show();
else
ptw->Dismiss();
}
@@ -571,6 +573,7 @@ private:
BEGIN_EVENT_TABLE(wxComboBoxExtraInputHandler, wxEvtHandler)
EVT_KEY_DOWN(wxComboBoxExtraInputHandler::OnKey)
EVT_SET_FOCUS(wxComboBoxExtraInputHandler::OnFocus)
EVT_KILL_FOCUS(wxComboBoxExtraInputHandler::OnFocus)
END_EVENT_TABLE()
@@ -592,7 +595,8 @@ void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event)
{
// FIXME: This code does run when control is clicked,
// yet on Windows it doesn't select all the text.
if ( !(m_combo->GetInternalFlags() & wxCC_NO_TEXT_AUTO_SELECT) )
if ( event.GetEventType() == wxEVT_SET_FOCUS &&
!(m_combo->GetInternalFlags() & wxCC_NO_TEXT_AUTO_SELECT) )
{
if ( m_combo->GetTextCtrl() )
m_combo->GetTextCtrl()->SelectAll();
@@ -606,7 +610,7 @@ void wxComboBoxExtraInputHandler::OnFocus(wxFocusEvent& event)
// wxEVT_SET_FOCUSes (since m_text->SetFocus is called
// from combo's focus event handler), they should be quite
// harmless.
wxFocusEvent evt2(wxEVT_SET_FOCUS,m_combo->GetId());
wxFocusEvent evt2(event.GetEventType(),m_combo->GetId());
evt2.SetEventObject(m_combo);
m_combo->GetEventHandler()->ProcessEvent(evt2);
@@ -659,6 +663,9 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
wxSize sz = m_combo->GetPopupControl()->GetControl()->GetClientSize();
int evtType = event.GetEventType();
bool isInside = pt.x >= 0 && pt.y >= 0 && pt.x < sz.x && pt.y < sz.y;
bool relayToButton = false;
event.Skip();
if ( evtType == wxEVT_MOTION ||
evtType == wxEVT_LEFT_DOWN ||
@@ -668,7 +675,6 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
if ( !isInside || !m_combo->IsPopupShown() )
{
event.Skip(false);
return;
}
}
else if ( evtType == wxEVT_LEFT_UP )
@@ -676,10 +682,9 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
if ( !m_combo->IsPopupShown() )
{
event.Skip(false);
return;
relayToButton = true;
}
if ( !m_beenInside )
else if ( !m_beenInside )
{
if ( isInside )
{
@@ -687,27 +692,48 @@ void wxComboPopupExtraEventHandler::OnMouseEvent( wxMouseEvent& event )
}
else
{
//
// Some mouse events to popup that happen outside it, before cursor
// has been inside the popu, need to be ignored by it but relayed to
// the dropbutton.
//
wxWindow* btn = m_combo->GetButton();
if ( btn )
btn->GetEventHandler()->AddPendingEvent(event);
else
m_combo->GetEventHandler()->AddPendingEvent(event);
return;
relayToButton = true;
}
event.Skip();
}
}
event.Skip();
if ( relayToButton )
{
//
// Some mouse events to popup that happen outside it, before cursor
// has been inside the popup, need to be ignored by it but relayed to
// the dropbutton.
//
wxWindow* eventSink = m_combo;
wxWindow* btn = m_combo->GetButton();
if ( btn )
eventSink = btn;
eventSink->GetEventHandler()->ProcessEvent(event);
}
}
// ----------------------------------------------------------------------------
// wxComboCtrlTextCtrl
// ----------------------------------------------------------------------------
class wxComboCtrlTextCtrl : public wxTextCtrl
{
public:
wxComboCtrlTextCtrl() : wxTextCtrl() { }
virtual ~wxComboCtrlTextCtrl() { }
virtual wxWindow *GetMainWindowOfCompositeControl()
{
wxComboCtrl* combo = (wxComboCtrl*) GetParent();
// Returning this instead of just 'parent' lets FindFocus work
// correctly even when parent control is a child of a composite
// generic control (as is case with wxGenericDatePickerCtrl).
return combo->GetMainWindowOfCompositeControl();
}
};
// ----------------------------------------------------------------------------
// wxComboCtrlBase
// ----------------------------------------------------------------------------
@@ -841,9 +867,10 @@ wxComboCtrlBase::CreateTextCtrl(int style, const wxValidator& validator)
else
m_ignoreEvtText = 0;
m_text = new wxTextCtrl(this, wxID_ANY, m_valueString,
wxDefaultPosition, wxSize(10,-1),
style, validator);
m_text = new wxComboCtrlTextCtrl();
m_text->Create(this, wxID_ANY, m_valueString,
wxDefaultPosition, wxSize(10,-1),
style, validator);
}
}
@@ -898,6 +925,12 @@ void wxComboCtrlBase::CalculateAreas( int btnWidth )
m_iFlags |= wxCC_IFLAG_BUTTON_OUTSIDE;
btnBorder = 0;
}
else if ( (m_iFlags & wxCC_BUTTON_COVERS_BORDER) &&
m_btnSpacingX == 0 && !m_bmpNormal.Ok() )
{
m_iFlags &= ~(wxCC_IFLAG_BUTTON_OUTSIDE);
btnBorder = 0;
}
else
{
m_iFlags &= ~(wxCC_IFLAG_BUTTON_OUTSIDE);
@@ -972,6 +1005,11 @@ void wxComboCtrlBase::CalculateAreas( int btnWidth )
{
int newY = butHeight+(customBorder*2);
SetClientSize(wxDefaultCoord,newY);
if ( m_bmpNormal.Ok() || m_btnArea.width != butWidth || m_btnArea.height != butHeight )
m_iFlags |= wxCC_IFLAG_HAS_NONSTANDARD_BUTTON;
else
m_iFlags &= ~wxCC_IFLAG_HAS_NONSTANDARD_BUTTON;
sz.y = newY;
}
}
@@ -1217,7 +1255,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
{
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;
@@ -1227,7 +1265,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
{
// Drawing control
isEnabled = IsEnabled();
isFocused = ShouldDrawFocus();
doDrawFocusRect = ShouldDrawFocus() & !(m_iFlags & wxCC_FULL_BUTTON);
// Windows-style: for smaller size control (and for disabled background) use less spacing
focusSpacingX = isEnabled ? 2 : 1;
@@ -1237,7 +1275,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
{
// 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;
@@ -1257,12 +1295,13 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
selRect.width -= wcp + (focusSpacingX*2);
wxColour bgCol;
bool doDrawSelRect = true;
if ( isEnabled )
{
// If popup is hidden and this control is focused,
// then draw the focus-indicator (selbgcolor background etc.).
if ( isFocused )
if ( doDrawFocusRect )
{
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
@@ -1271,6 +1310,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
{
dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
#ifndef __WXMAC__ // see note in OnThemeChange
doDrawSelRect = false;
bgCol = GetBackgroundColour();
#else
bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
@@ -1288,8 +1328,11 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
}
dc.SetBrush( bgCol );
dc.SetPen( bgCol );
dc.DrawRectangle( selRect );
if ( doDrawSelRect )
{
dc.SetPen( bgCol );
dc.DrawRectangle( selRect );
}
// Don't clip exactly to the selection rectangle so we can draw
// to the non-selected area in front of it.
@@ -1304,14 +1347,13 @@ void wxComboCtrlBase::PrepareBackground( wxDC&, const wxRect&, int ) const
}
#endif
void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int paintBg )
void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int flags )
{
int drawState = m_btnState;
#ifdef __WXGTK__
if ( GetPopupWindowState() >= Animating )
if ( (m_iFlags & wxCC_BUTTON_STAYS_DOWN) &&
GetPopupWindowState() >= Animating )
drawState |= wxCONTROL_PRESSED;
#endif
wxRect drawRect(rect.x+m_btnSpacingX,
rect.y+((rect.height-m_btnSize.y)/2),
@@ -1331,8 +1373,11 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int paintBg )
if ( !m_bmpNormal.Ok() )
{
if ( flags & Button_BitmapOnly )
return;
// Need to clear button background even if m_btn is present
if ( paintBg )
if ( flags & Button_PaintBackground )
{
wxColour bgCol;
@@ -1371,7 +1416,7 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int paintBg )
{
// If using blank button background, we need to clear its background
// with button face colour instead of colour for rest of the control.
if ( paintBg )
if ( flags & Button_PaintBackground )
{
wxColour bgCol = GetParent()->GetBackgroundColour(); //wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
//wxColour bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
@@ -1380,18 +1425,20 @@ void wxComboCtrlBase::DrawButton( wxDC& dc, const wxRect& rect, int paintBg )
dc.DrawRectangle(rect);
}
wxRendererNative::Get().DrawPushButton(this,
dc,
drawRect,
drawState);
if ( !(flags & Button_BitmapOnly) )
{
wxRendererNative::Get().DrawPushButton(this,
dc,
drawRect,
drawState);
}
}
else
{
// Need to clear button background even if m_btn is present
// (assume non-button background was cleared just before this call so brushes are good)
if ( paintBg )
if ( flags & Button_PaintBackground )
dc.DrawRectangle(rect);
}
@@ -1438,13 +1485,14 @@ void wxComboCtrlBase::OnTextCtrlEvent(wxCommandEvent& event)
// call if cursor is on button area or mouse is captured for the button
bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
int flags )
int flags )
{
int type = event.GetEventType();
if ( type == wxEVT_MOTION )
{
if ( flags & wxCC_MF_ON_BUTTON )
if ( (flags & wxCC_MF_ON_BUTTON) &&
IsPopupWindowState(Hidden) )
{
if ( !(m_btnState & wxCONTROL_CURRENT) )
{
@@ -1513,6 +1561,11 @@ bool wxComboCtrlBase::HandleButtonMouseEvent( wxMouseEvent& event,
else
return false;
// Never have 'hot' state when popup is being shown
// (this is mostly needed because of the animation).
if ( !IsPopupWindowState(Hidden) )
m_btnState &= ~wxCONTROL_CURRENT;
return true;
}
@@ -1535,7 +1588,7 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event,
}
#endif
// Filter out clicks on button immediately after popup dismiss (Windows like behaviour)
// Filter out clicks on button immediately after popup dismiss
if ( evtType == wxEVT_LEFT_DOWN && t < m_timeCanAcceptClick )
{
event.SetEventType(0);
@@ -1648,7 +1701,9 @@ void wxComboCtrlBase::OnFocusEvent( wxFocusEvent& event )
#ifdef __WXMAC__
m_resetFocus = true;
#else
{
tc->SetFocus();
}
#endif
}
@@ -1700,7 +1755,7 @@ void wxComboCtrlBase::CreatePopup()
m_popupWinType = SECONDARY_POPUP_TYPE;
}
else
#endif
#endif // wxComboPopupWindowBase2
{
m_winPopup = new wxComboPopupWindow( this, wxNO_BORDER );
m_popupWinType = PRIMARY_POPUP_TYPE;
@@ -1986,7 +2041,12 @@ void wxComboCtrlBase::DoShowPopup( const wxRect& rect, int WXUNUSED(flags) )
// (though the bug was probably fixed).
winPopup->SetSize( rect );
winPopup->Show();
#if USES_WXPOPUPTRANSIENTWINDOW
if ( m_popupWinType == POPUPWIN_WXPOPUPTRANSIENTWINDOW )
((wxPopupTransientWindow*)winPopup)->Popup(m_popup);
else
#endif
winPopup->Show();
m_popupWinState = Visible;
}
@@ -1998,6 +2058,8 @@ void wxComboCtrlBase::DoShowPopup( const wxRect& rect, int WXUNUSED(flags) )
m_popupWinState = Hidden;
}
Refresh();
}
void wxComboCtrlBase::OnPopupDismiss()