]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/combocmn.cpp
Simplify and correct bugs in wxMSW wxScrollBar message handling.
[wxWidgets.git] / src / common / combocmn.cpp
index 5df0a61af55efdc0200ad2e92a0edb0e9f1db3ad..898cbfd08c69dd1d986c3df25c96026af4766250 100644 (file)
@@ -32,7 +32,6 @@
     #include "wx/log.h"
     #include "wx/dcclient.h"
     #include "wx/settings.h"
-    #include "wx/dialog.h"
     #include "wx/timer.h"
     #include "wx/textctrl.h"
 #endif
 
 #if defined(__WXMSW__)
 
+// Let's use wxFrame as a fall-back solution until wxMSW gets wxNonOwnedWindow
+#include "wx/frame.h"
+#define wxCC_GENERIC_TLW_IS_FRAME
+#define wxComboCtrlGenericTLW   wxFrame
+
 #define USE_TRANSIENT_POPUP           1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
 #define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
                                         // native controls work on it like normal.
 
 #elif defined(__WXGTK__)
 
-#include "wx/gtk/private.h"
-
 // NB: It is not recommended to use wxDialog as popup on wxGTK, because of
 //     this bug: If wxDialog is hidden, its position becomes corrupt
 //     between hide and next show, but without internal coordinates being
 //     reflected (or something like that - atleast commenting out ->Hide()
 //     seemed to eliminate the position change).
 
+#include "wx/dialog.h"
+#define wxCC_GENERIC_TLW_IS_DIALOG
+#define wxComboCtrlGenericTLW   wxDialog
+
+#include "wx/gtk/private.h"
+
 // NB: Let's not be afraid to use wxGTK's wxPopupTransientWindow as a
 //     'perfect' popup, as it can succesfully host child controls even in
 //     popups that are shown in modal dialogs.
 
 #elif defined(__WXMAC__)
 
+#include "wx/nonownedwnd.h"
+#define wxCC_GENERIC_TLW_IS_NONOWNEDWINDOW
+#define wxComboCtrlGenericTLW   wxNonOwnedWindow
+
 #define USE_TRANSIENT_POPUP           1 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
 #define TRANSIENT_POPUPWIN_IS_PERFECT 1 // wxPopupTransientWindow works, its child can have focus, and common
                                         // native controls work on it like normal.
 
 #else
 
+#include "wx/dialog.h"
+#define wxCC_GENERIC_TLW_IS_DIALOG
+#define wxComboCtrlGenericTLW   wxDialog
+
 #define USE_TRANSIENT_POPUP           0 // Use wxPopupWindowTransient (preferred, if it works properly on platform)
 #define TRANSIENT_POPUPWIN_IS_PERFECT 0 // wxPopupTransientWindow works, its child can have focus, and common
                                         // native controls work on it like normal.
@@ -139,7 +155,7 @@ enum
     POPUPWIN_NONE                   = 0,
     POPUPWIN_WXPOPUPTRANSIENTWINDOW = 1,
     POPUPWIN_WXPOPUPWINDOW          = 2,
-    POPUPWIN_WXDIALOG               = 3
+    POPUPWIN_GENERICTLW             = 3
 };
 
 
@@ -157,9 +173,9 @@ enum
         #define SECONDARY_POPUP_TYPE        POPUPWIN_WXPOPUPWINDOW
         #define USES_WXPOPUPWINDOW          1
     #else
-        #define wxComboPopupWindowBase2     wxDialog
-        #define SECONDARY_POPUP_TYPE        POPUPWIN_WXDIALOG
-        #define USES_WXDIALOG               1
+        #define wxComboPopupWindowBase2     wxComboCtrlGenericTLW
+        #define SECONDARY_POPUP_TYPE        POPUPWIN_GENERICTLW
+        #define USES_GENERICTLW             1
     #endif
 
 #elif wxUSE_POPUPWIN
@@ -170,17 +186,17 @@ enum
     #define USES_WXPOPUPWINDOW          1
 
     #if !POPUPWIN_IS_PERFECT
-        #define wxComboPopupWindowBase2     wxDialog
-        #define SECONDARY_POPUP_TYPE        POPUPWIN_WXDIALOG
-        #define USES_WXDIALOG               1
+        #define wxComboPopupWindowBase2     wxComboCtrlGenericTLW
+        #define SECONDARY_POPUP_TYPE        POPUPWIN_GENERICTLW
+        #define USES_GENERICTLW             1
     #endif
 
 #else
     // wxPopupWindow is not implemented
 
-    #define wxComboPopupWindowBase      wxDialog
-    #define PRIMARY_POPUP_TYPE          POPUPWIN_WXDIALOG
-    #define USES_WXDIALOG               1
+    #define wxComboPopupWindowBase      wxComboCtrlGenericTLW
+    #define PRIMARY_POPUP_TYPE          POPUPWIN_GENERICTLW
+    #define USES_GENERICTLW             1
 
 #endif
 
@@ -193,8 +209,8 @@ enum
     #define USES_WXPOPUPWINDOW          0
 #endif
 
-#ifndef USES_WXDIALOG
-    #define USES_WXDIALOG               0
+#ifndef USES_GENERICTLW
+    #define USES_GENERICTLW             0
 #endif
 
 
@@ -435,7 +451,7 @@ public:
 
     void OnSizeEvent( wxSizeEvent& event );
     void OnKeyEvent(wxKeyEvent& event);
-#if USES_WXDIALOG
+#if USES_GENERICTLW
     void OnActivate( wxActivateEvent& event );
 #endif
 
@@ -449,7 +465,7 @@ private:
 BEGIN_EVENT_TABLE(wxComboPopupWindowEvtHandler, wxEvtHandler)
     EVT_KEY_DOWN(wxComboPopupWindowEvtHandler::OnKeyEvent)
     EVT_KEY_UP(wxComboPopupWindowEvtHandler::OnKeyEvent)
-#if USES_WXDIALOG
+#if USES_GENERICTLW
     EVT_ACTIVATE(wxComboPopupWindowEvtHandler::OnActivate)
 #endif
     EVT_SIZE(wxComboPopupWindowEvtHandler::OnSizeEvent)
@@ -470,7 +486,7 @@ void wxComboPopupWindowEvtHandler::OnKeyEvent( wxKeyEvent& event )
     child->GetEventHandler()->AddPendingEvent(event);
 }
 
-#if USES_WXDIALOG
+#if USES_GENERICTLW
 void wxComboPopupWindowEvtHandler::OnActivate( wxActivateEvent& event )
 {
     if ( !event.GetActive() )
@@ -888,6 +904,7 @@ wxComboCtrlBase::CreateTextCtrl(int style, const wxValidator& validator)
         m_text->Create(this, wxID_ANY, m_valueString,
                        wxDefaultPosition, wxSize(10,-1),
                        style, validator);
+        m_text->SetHint(m_hintText);
     }
 }
 
@@ -897,8 +914,27 @@ void wxComboCtrlBase::OnThemeChange()
     // be the correct colour and themed brush.  Instead we'll use
     // wxSYS_COLOUR_WINDOW in the EVT_PAINT handler as needed.
 #ifndef __WXMAC__
-    SetOwnBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
-#endif
+  #if defined(__WXMSW__) || defined(__WXGTK__)
+    wxVisualAttributes vattrs = wxComboBox::GetClassDefaultAttributes();
+  #else
+    wxVisualAttributes vattrs;
+    vattrs.colFg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+    vattrs.colBg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
+  #endif
+
+    // Only change the colours if application has not specified
+    // custom ones.
+    if ( !m_hasFgCol )
+    {
+        SetOwnForegroundColour(vattrs.colFg);
+        m_hasFgCol = false;
+    }
+    if ( !m_hasBgCol )
+    {
+        SetOwnBackgroundColour(vattrs.colBg);
+        m_hasBgCol = false;
+    }
+#endif // !__WXMAC__
 }
 
 wxComboCtrlBase::~wxComboCtrlBase()
@@ -1287,6 +1323,27 @@ wxValidator* wxComboCtrlBase::GetValidator()
 }
 #endif // wxUSE_VALIDATORS
 
+bool wxComboCtrlBase::SetForegroundColour(const wxColour& colour)
+{
+    if ( wxControl::SetForegroundColour(colour) )
+    {
+        if ( m_text )
+            m_text->SetForegroundColour(colour);
+        return true;
+    }
+    return false;
+}
+
+bool wxComboCtrlBase::SetBackgroundColour(const wxColour& colour)
+{
+    if ( wxControl::SetBackgroundColour(colour) )
+    {
+        if ( m_text )
+            m_text->SetBackgroundColour(colour);
+        return true;
+    }
+    return false;
+}
 // ----------------------------------------------------------------------------
 // painting
 // ----------------------------------------------------------------------------
@@ -1337,20 +1394,46 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
     selRect.width -= wcp + (focusSpacingX*2);
 
     wxColour bgCol;
+    wxColour fgCol;
+
     bool doDrawSelRect = true;
 
+    // Determine foreground colour
+    if ( isEnabled )
+    {
+        if ( doDrawFocusRect )
+        {
+            fgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
+        }
+        else if ( m_hasFgCol )
+        {
+            // Honour the custom foreground colour
+            fgCol = GetForegroundColour();
+        }
+        else
+        {
+            fgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
+        }
+    }
+    else
+    {
+        fgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT);
+    }
+
+    // Determine background colour
     if ( isEnabled )
     {
-        // If popup is hidden and this control is focused,
-        // then draw the focus-indicator (selbgcolor background etc.).
         if ( doDrawFocusRect )
         {
-            dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) );
             bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
         }
+        else if ( m_hasBgCol )
+        {
+            // Honour the custom background colour
+            bgCol = GetBackgroundColour();
+        }
         else
         {
-            dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) );
 #ifndef __WXMAC__  // see note in OnThemeChange
             doDrawSelRect = false;
             bgCol = GetBackgroundColour();
@@ -1361,7 +1444,6 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
     }
     else
     {
-        dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_GRAYTEXT) );
 #ifndef __WXMAC__  // see note in OnThemeChange
         bgCol = GetBackgroundColour();
 #else
@@ -1369,6 +1451,7 @@ void wxComboCtrlBase::PrepareBackground( wxDC& dc, const wxRect& rect, int flags
 #endif
     }
 
+    dc.SetTextForeground( fgCol );
     dc.SetBrush( bgCol );
     if ( doDrawSelRect )
     {
@@ -1618,7 +1701,7 @@ bool wxComboCtrlBase::PreprocessMouseEvent( wxMouseEvent& event,
     wxLongLong t = ::wxGetLocalTimeMillis();
     int evtType = event.GetEventType();
 
-#if USES_WXPOPUPWINDOW || USES_WXDIALOG
+#if USES_WXPOPUPWINDOW || USES_GENERICTLW
     if ( m_popupWinType != POPUPWIN_WXPOPUPTRANSIENTWINDOW )
     {
         if ( IsPopupWindowState(Visible) &&
@@ -1692,9 +1775,13 @@ void wxComboCtrlBase::OnKeyEvent(wxKeyEvent& event)
     }
     else // no popup
     {
-        if ( GetParent()->HasFlag(wxTAB_TRAVERSAL) &&
-             HandleAsNavigationKey(event) )
-            return;
+        wxWindow* mainCtrl = GetMainWindowOfCompositeControl();
+
+        if ( mainCtrl->GetParent()->HasFlag(wxTAB_TRAVERSAL) )
+        {
+            if ( mainCtrl->HandleAsNavigationKey(event) )
+                return;
+        }
 
         if ( IsKeyPopupToggle(event) )
         {
@@ -1772,12 +1859,23 @@ void wxComboCtrlBase::CreatePopup()
 #ifdef wxComboPopupWindowBase2
         if ( m_iFlags & wxCC_IFLAG_USE_ALT_POPUP )
         {
-        #if !USES_WXDIALOG
+        #if !USES_GENERICTLW
             m_winPopup = new wxComboPopupWindowBase2( this, wxNO_BORDER );
         #else
+            int tlwFlags = wxNO_BORDER;
+          #ifdef wxCC_GENERIC_TLW_IS_FRAME
+            tlwFlags |= wxFRAME_NO_TASKBAR;
+          #endif
+
+          #ifdef wxCC_GENERIC_TLW_IS_NONOWNEDWINDOW
+            m_winPopup = new wxComboPopupWindowBase2( this, wxID_ANY,
+                                                      wxPoint(-21,-21), wxSize(20, 20),
+                                                      tlwFlags );
+          #else
             m_winPopup = new wxComboPopupWindowBase2( this, wxID_ANY, wxEmptyString,
                                                       wxPoint(-21,-21), wxSize(20, 20),
-                                                      wxNO_BORDER );
+                                                      tlwFlags );
+          #endif
         #endif
             m_popupWinType = SECONDARY_POPUP_TYPE;
         }
@@ -1928,7 +2026,8 @@ void wxComboCtrlBase::ShowPopup()
     //     that if transient popup is open, then tab traversal is to be ignored.
     //     However, I think this code would still be needed for cases where
     //     transient popup doesn't work yet (wxWinCE?).
-    wxWindow* parent = GetParent();
+    wxWindow* mainCtrl = GetMainWindowOfCompositeControl();
+    wxWindow* parent = mainCtrl->GetParent();
     int parentFlags = parent->GetWindowStyle();
     if ( parentFlags & wxTAB_TRAVERSAL )
     {
@@ -2286,7 +2385,7 @@ wxPoint wxComboCtrlBase::DoGetMargins() const
     return wxPoint(m_marginLeft, -1);
 }
 
-#if WXWIN_COMPATIBILITY_2_6
+#if WXWIN_COMPATIBILITY_2_8
 void wxComboCtrlBase::SetTextIndent( int indent )
 {
     if ( indent < 0 )
@@ -2446,4 +2545,19 @@ void wxComboCtrlBase::Undo()
         m_text->Undo();
 }
 
+bool wxComboCtrlBase::SetHint(const wxString& hint)
+{
+    m_hintText = hint;
+    bool res = true;
+    if ( m_text )
+        res = m_text->SetHint(hint);
+    Refresh();
+    return res;
+}
+
+wxString wxComboCtrlBase::GetHint() const
+{
+    return m_hintText;
+}
+
 #endif // wxUSE_COMBOCTRL