]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
add wxGenericStaticText (#9656)
[wxWidgets.git] / src / common / wincmn.cpp
index 0c2f15dc96f56319a12de22eb4475865b2375ec6..03e49a2a0c49e9461eb0cd78e6abbc223b5110a8 100644 (file)
@@ -369,6 +369,20 @@ wxWindowBase::~wxWindowBase()
 #if wxUSE_ACCESSIBILITY
     delete m_accessible;
 #endif
 #if wxUSE_ACCESSIBILITY
     delete m_accessible;
 #endif
+
+#if wxUSE_HELP
+    // NB: this has to be called unconditionally, because we don't know
+    //     whether this window has associated help text or not
+    wxHelpProvider *helpProvider = wxHelpProvider::Get();
+    if ( helpProvider )
+        helpProvider->RemoveHelp(this);
+#endif
+}
+
+bool wxWindowBase::IsBeingDeleted() const
+{
+    return m_isBeingDeleted ||
+            (!IsTopLevel() && m_parent && m_parent->IsBeingDeleted());
 }
 
 void wxWindowBase::SendDestroyEvent()
 }
 
 void wxWindowBase::SendDestroyEvent()
@@ -394,7 +408,7 @@ bool wxWindowBase::Close(bool force)
 
     // return false if window wasn't closed because the application vetoed the
     // close event
 
     // return false if window wasn't closed because the application vetoed the
     // close event
-    return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
+    return HandleWindowEvent(event) && !event.GetVeto();
 }
 
 bool wxWindowBase::DestroyChildren()
 }
 
 bool wxWindowBase::DestroyChildren()
@@ -833,6 +847,23 @@ void wxWindowBase::DoGetScreenPosition(int *x, int *y) const
     ClientToScreen(x, y);
 }
 
     ClientToScreen(x, y);
 }
 
+void wxWindowBase::SendSizeEvent(int flags)
+{
+    wxSizeEvent event(GetSize(), GetId());
+    event.SetEventObject(this);
+    if ( flags & wxSEND_EVENT_POST )
+        wxPostEvent(this, event);
+    else
+        HandleWindowEvent(event);
+}
+
+void wxWindowBase::SendSizeEventToParent(int flags)
+{
+    wxWindow * const parent = GetParent();
+    if ( parent && !parent->IsBeingDeleted() )
+        parent->SendSizeEvent(flags);
+}
+
 // ----------------------------------------------------------------------------
 // show/hide/enable/disable the window
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // show/hide/enable/disable the window
 // ----------------------------------------------------------------------------
@@ -920,6 +951,52 @@ bool wxWindowBase::IsTopLevel() const
     return false;
 }
 
     return false;
 }
 
+// ----------------------------------------------------------------------------
+// Freeze/Thaw
+// ----------------------------------------------------------------------------
+
+void wxWindowBase::Freeze()
+{
+    if ( !m_freezeCount++ )
+    {
+        // physically freeze this window:
+        DoFreeze();
+
+        // and recursively freeze all children:
+        for ( wxWindowList::iterator i = GetChildren().begin();
+              i != GetChildren().end(); ++i )
+        {
+            wxWindow *child = *i;
+            if ( child->IsTopLevel() )
+                continue;
+
+            child->Freeze();
+        }
+    }
+}
+
+void wxWindowBase::Thaw()
+{
+    wxASSERT_MSG( m_freezeCount, "Thaw() without matching Freeze()" );
+
+    if ( !--m_freezeCount )
+    {
+        // recursively thaw all children:
+        for ( wxWindowList::iterator i = GetChildren().begin();
+              i != GetChildren().end(); ++i )
+        {
+            wxWindow *child = *i;
+            if ( child->IsTopLevel() )
+                continue;
+
+            child->Thaw();
+        }
+
+        // physically thaw this window:
+        DoThaw();
+    }
+}
+
 // ----------------------------------------------------------------------------
 // reparenting the window
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // reparenting the window
 // ----------------------------------------------------------------------------
@@ -935,12 +1012,25 @@ void wxWindowBase::AddChild(wxWindowBase *child)
 
     GetChildren().Append((wxWindow*)child);
     child->SetParent(this);
 
     GetChildren().Append((wxWindow*)child);
     child->SetParent(this);
+
+    // adding a child while frozen will assert when thawed, so freeze it as if
+    // it had been already present when we were frozen
+    if ( IsFrozen() && !child->IsTopLevel() )
+        child->Freeze();
 }
 
 void wxWindowBase::RemoveChild(wxWindowBase *child)
 {
     wxCHECK_RET( child, wxT("can't remove a NULL child") );
 
 }
 
 void wxWindowBase::RemoveChild(wxWindowBase *child)
 {
     wxCHECK_RET( child, wxT("can't remove a NULL child") );
 
+    // removing a child while frozen may result in permanently frozen window
+    // if used e.g. from Reparent(), so thaw it
+    //
+    // NB: IsTopLevel() doesn't return true any more when a TLW child is being
+    //     removed from its ~wxWindowBase, so check for IsBeingDeleted() too
+    if ( IsFrozen() && !child->IsBeingDeleted() && !child->IsTopLevel() )
+        child->Thaw();
+
     GetChildren().DeleteObject((wxWindow *)child);
     child->SetParent(NULL);
 }
     GetChildren().DeleteObject((wxWindow *)child);
     child->SetParent(NULL);
 }
@@ -1335,7 +1425,7 @@ void wxWindowBase::ClearBackground()
     // wxGTK uses its own version, no need to add never used code
 #ifndef __WXGTK__
     wxClientDC dc((wxWindow *)this);
     // wxGTK uses its own version, no need to add never used code
 #ifndef __WXGTK__
     wxClientDC dc((wxWindow *)this);
-    wxBrush brush(GetBackgroundColour(), wxSOLID);
+    wxBrush brush(GetBackgroundColour(), wxBRUSHSTYLE_SOLID);
     dc.SetBackground(brush);
     dc.Clear();
 #endif // __WXGTK__
     dc.SetBackground(brush);
     dc.Clear();
 #endif // __WXGTK__
@@ -1631,6 +1721,7 @@ void wxWindowBase::SetHelpText(const wxString& text)
     }
 }
 
     }
 }
 
+#if WXWIN_COMPATIBILITY_2_8
 // associate this help text with all windows with the same id as this
 // one
 void wxWindowBase::SetHelpTextForId(const wxString& text)
 // associate this help text with all windows with the same id as this
 // one
 void wxWindowBase::SetHelpTextForId(const wxString& text)
@@ -1641,6 +1732,7 @@ void wxWindowBase::SetHelpTextForId(const wxString& text)
         helpProvider->AddHelp(GetId(), text);
     }
 }
         helpProvider->AddHelp(GetId(), text);
     }
 }
+#endif // WXWIN_COMPATIBILITY_2_8
 
 // get the help string associated with this window (may be empty)
 // default implementation forwards calls to the help provider
 
 // get the help string associated with this window (may be empty)
 // default implementation forwards calls to the help provider
@@ -1664,7 +1756,29 @@ void wxWindowBase::OnHelp(wxHelpEvent& event)
     wxHelpProvider *helpProvider = wxHelpProvider::Get();
     if ( helpProvider )
     {
     wxHelpProvider *helpProvider = wxHelpProvider::Get();
     if ( helpProvider )
     {
-        if ( helpProvider->ShowHelpAtPoint(this, event.GetPosition(), event.GetOrigin()) )
+        wxPoint pos = event.GetPosition();
+        const wxHelpEvent::Origin origin = event.GetOrigin();
+        if ( origin == wxHelpEvent::Origin_Keyboard )
+        {
+            // if the help event was generated from keyboard it shouldn't
+            // appear at the mouse position (which is still the only position
+            // associated with help event) if the mouse is far away, although
+            // we still do use the mouse position if it's over the window
+            // because we suppose the user looks approximately at the mouse
+            // already and so it would be more convenient than showing tooltip
+            // at some arbitrary position which can be quite far from it
+            const wxRect rectClient = GetClientRect();
+            if ( !rectClient.Contains(ScreenToClient(pos)) )
+            {
+                // position help slightly under and to the right of this window
+                pos = ClientToScreen(wxPoint(
+                        2*GetCharWidth(),
+                        rectClient.height + GetCharHeight()
+                      ));
+            }
+        }
+
+        if ( helpProvider->ShowHelpAtPoint(this, pos, origin) )
         {
             // skip the event.Skip() below
             return;
         {
             // skip the event.Skip() below
             return;
@@ -2323,7 +2437,7 @@ static void DrawBorder(wxWindowBase *win, const wxRect& rect, bool fill = false)
 {
     wxClientDC dc((wxWindow *)win);
     dc.SetPen(*wxRED_PEN);
 {
     wxClientDC dc((wxWindow *)win);
     dc.SetPen(*wxRED_PEN);
-    dc.SetBrush(fill ? wxBrush(*wxRED, wxCROSSDIAG_HATCH): *wxTRANSPARENT_BRUSH);
+    dc.SetBrush(fill ? wxBrush(*wxRED, wxBRUSHSTYLE_CROSSDIAG_HATCH) : *wxTRANSPARENT_BRUSH);
     dc.DrawRectangle(rect.Deflate(1, 1));
 }
 
     dc.DrawRectangle(rect.Deflate(1, 1));
 }
 
@@ -2533,7 +2647,10 @@ void wxWindowBase::ReleaseMouse()
 
     wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
 
 
     wxASSERT_MSG( !ms_winCaptureChanging, _T("recursive ReleaseMouse call?") );
 
-    wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
+    wxASSERT_MSG( GetCapture() == this,
+                  "attempt to release mouse, but this window hasn't captured it" );
+    wxASSERT_MSG( ms_winCaptureCurrent == this,
+                  "attempt to release mouse, but this window hasn't captured it" );
 
     ms_winCaptureChanging = true;
 
 
     ms_winCaptureChanging = true;
 
@@ -2630,8 +2747,8 @@ bool wxWindowBase::TryValidator(wxEvent& wxVALIDATOR_PARAM(event))
     // is receiving the event
     if ( event.GetEventObject() == this )
     {
     // is receiving the event
     if ( event.GetEventObject() == this )
     {
-        wxValidator *validator = GetValidator();
-        if ( validator && validator->ProcessEvent(event) )
+        wxValidator * const validator = GetValidator();
+        if ( validator && validator->ProcessEventHere(event) )
         {
             return true;
         }
         {
             return true;
         }
@@ -2700,12 +2817,33 @@ bool wxWindowBase::DoNavigateIn(int flags)
     return false;
 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
     wxNavigationKeyEvent eventNav;
     return false;
 #else // !wxHAS_NATIVE_TAB_TRAVERSAL
     wxNavigationKeyEvent eventNav;
+    wxWindow *focused = FindFocus();
+    eventNav.SetCurrentFocus(focused);
+    eventNav.SetEventObject(focused);
     eventNav.SetFlags(flags);
     eventNav.SetFlags(flags);
-    eventNav.SetEventObject(FindFocus());
     return GetEventHandler()->ProcessEvent(eventNav);
 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
 }
 
     return GetEventHandler()->ProcessEvent(eventNav);
 #endif // wxHAS_NATIVE_TAB_TRAVERSAL/!wxHAS_NATIVE_TAB_TRAVERSAL
 }
 
+bool wxWindowBase::HandleAsNavigationKey(const wxKeyEvent& event)
+{
+    if ( event.GetKeyCode() != WXK_TAB )
+        return false;
+
+    int flags = wxNavigationKeyEvent::FromTab;
+
+    if ( event.ShiftDown() )
+        flags |= wxNavigationKeyEvent::IsBackward;
+    else
+        flags |= wxNavigationKeyEvent::IsForward;
+
+    if ( event.ControlDown() )
+        flags |= wxNavigationKeyEvent::WinChange;
+
+    Navigate(flags);
+    return true;
+}
+
 void wxWindowBase::DoMoveInTabOrder(wxWindow *win, WindowOrder move)
 {
     // check that we're not a top level window
 void wxWindowBase::DoMoveInTabOrder(wxWindow *win, WindowOrder move)
 {
     // check that we're not a top level window