]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/splitter.cpp
Fixed bug with disappearing menus. They were
[wxWidgets.git] / src / generic / splitter.cpp
index 68a393a4a868504a7bbb451c86ac1eca742e965e..3b9a91b5185b5a038356174d313e6da3828d1a64 100644 (file)
 #include "wx/dcscreen.h"
 #include "wx/settings.h"
 #include "wx/log.h"
+#include "wx/utils.h"
+
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPLITTER_DOUBLECLICKED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPLITTER_UNSPLIT)
 
 IMPLEMENT_DYNAMIC_CLASS(wxSplitterWindow, wxWindow)
 IMPLEMENT_DYNAMIC_CLASS(wxSplitterEvent, wxCommandEvent)
@@ -51,14 +57,21 @@ BEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow)
     EVT_SPLITTER_SASH_POS_CHANGING(-1, wxSplitterWindow::OnSashPosChanged)
     EVT_SPLITTER_DCLICK(-1,           wxSplitterWindow::OnDoubleClick)
     EVT_SPLITTER_UNSPLIT(-1,          wxSplitterWindow::OnUnsplitEvent)
+
+    WX_EVENT_TABLE_CONTROL_CONTAINER(wxSplitterWindow)
 END_EVENT_TABLE()
 
+WX_DELEGATE_TO_CONTROL_CONTAINER(wxSplitterWindow);
+
 bool wxSplitterWindow::Create(wxWindow *parent, wxWindowID id,
                                    const wxPoint& pos,
                                    const wxSize& size,
                                    long style,
                                    const wxString& name)
 {
+    // allow TABbing from one window to the other
+    style |= wxTAB_TRAVERSAL;
+
     if (!wxWindow::Create(parent, id, pos, size, style, name))
         return FALSE;
 
@@ -75,12 +88,21 @@ bool wxSplitterWindow::Create(wxWindow *parent, wxWindowID id,
         m_borderSize = 1;
     else
         m_borderSize = 0;
+        
+#ifdef __WXMAC__
+    int major,minor;
+    wxGetOsVersion( &major, &minor );
+    if (major >= 10)
+        m_windowStyle |= wxSP_SASH_AQUA;
+#endif
 
     return TRUE;
 }
 
 void wxSplitterWindow::Init()
 {
+    m_container.SetContainerWindow(this);
+
     m_splitMode = wxSPLIT_VERTICAL;
     m_permitUnsplitAlways = TRUE;
     m_windowOne = (wxWindow *) NULL;
@@ -134,10 +156,12 @@ void wxSplitterWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
     DrawSash(dc);
 }
 
-void wxSplitterWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
+void wxSplitterWindow::OnIdle(wxIdleEvent& event)
 {
     if (m_needUpdating)
         SizeWindows();
+
+    event.Skip();
 }
 
 void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
@@ -307,7 +331,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
                 return;
             }
         }
-        
+
         if (new_sash_position == m_sashPosition)
             return;
 
@@ -492,7 +516,11 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
         if ( m_splitMode == wxSPLIT_VERTICAL )
         {
             dc.SetPen(*m_facePen);
-            dc.SetBrush(*m_faceBrush);
+
+            if (HasFlag( wxSP_SASH_AQUA ))
+                dc.SetBrush(*wxWHITE_BRUSH);
+            else
+                dc.SetBrush(*m_faceBrush);
             dc.DrawRectangle(m_sashPosition + 2, 0 , m_sashSize - 4, h );
 
             dc.SetBrush(*wxTRANSPARENT_BRUSH);
@@ -504,13 +532,18 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
             dc.SetPen(*m_hilightPen);
             dc.DrawLine(m_sashPosition+1, m_borderSize - 2, m_sashPosition+1, h - m_borderSize+2);
 
-            dc.SetPen(*m_mediumShadowPen);
-                        int yMedium = m_borderSize ? h-m_borderSize+1 : h ;
+            if (!HasFlag( wxSP_SASH_AQUA ))
+                dc.SetPen(*m_mediumShadowPen);
+
+            int yMedium = m_borderSize ? h-m_borderSize+1 : h ;
             dc.DrawLine(m_sashPosition+m_sashSize-2, xShadow, m_sashPosition+m_sashSize-2, yMedium);
 
-            dc.SetPen(*m_darkShadowPen);
+            if (HasFlag( wxSP_SASH_AQUA ))
+                dc.SetPen(*m_lightShadowPen);
+            else
+                dc.SetPen(*m_darkShadowPen);
             dc.DrawLine(m_sashPosition+m_sashSize-1, m_borderSize, m_sashPosition+m_sashSize-1, h-m_borderSize );
-
+            
             // Draw the top and bottom edges of the sash, if requested
             if (GetWindowStyle() & wxSP_FULLSASH)
             {
@@ -526,7 +559,10 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
         else
         {
             dc.SetPen(*m_facePen);
-            dc.SetBrush(*m_faceBrush);
+            if (HasFlag( wxSP_SASH_AQUA ))
+                dc.SetBrush(*wxWHITE_BRUSH);
+            else
+                dc.SetBrush(*m_faceBrush);
             dc.DrawRectangle( m_borderSize-2, m_sashPosition + 2, w-m_borderSize+2, m_sashSize - 4);
 
             dc.SetBrush(*wxTRANSPARENT_BRUSH);
@@ -537,10 +573,14 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
             dc.SetPen(*m_hilightPen);
             dc.DrawLine(m_borderSize-2, m_sashPosition+1, w-m_borderSize+1, m_sashPosition+1);
 
-            dc.SetPen(*m_mediumShadowPen);
+            if (!HasFlag( wxSP_SASH_AQUA ))
+                dc.SetPen(*m_mediumShadowPen);
             dc.DrawLine(m_borderSize-1, m_sashPosition+m_sashSize-2, w-m_borderSize+1, m_sashPosition+m_sashSize-2);
 
-            dc.SetPen(*m_darkShadowPen);
+            if (HasFlag( wxSP_SASH_AQUA ))
+                dc.SetPen(*m_lightShadowPen);
+            else
+                dc.SetPen(*m_darkShadowPen);
             dc.DrawLine(m_borderSize, m_sashPosition+m_sashSize-1, w-m_borderSize, m_sashPosition+m_sashSize-1);
 
             // Draw the left and right edges of the sash, if requested
@@ -649,6 +689,37 @@ void wxSplitterWindow::DrawSashTracker(int x, int y)
     screenDC.SetBrush(wxNullBrush);
 }
 
+void wxSplitterWindow::AdjustSashPosition(int &sashPos)
+{
+    int w, h;
+    GetClientSize(&w, &h);
+    int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h;
+    wxWindow *win;
+
+    if ( sashPos < m_minimumPaneSize )
+        sashPos = m_minimumPaneSize;
+    else if ( sashPos > window_size - m_minimumPaneSize )
+        sashPos = window_size - m_minimumPaneSize;
+    
+    win = GetWindow1();
+    if ( win )
+    {
+        int minSize = (m_splitMode == wxSPLIT_VERTICAL) ? 
+                       win->GetMinWidth() : win->GetMinHeight();
+        if ( minSize != -1 && sashPos < minSize + GetBorderSize() )
+            sashPos = minSize + GetBorderSize();
+    }
+
+    win = GetWindow2();
+    if ( win )
+    {
+        int minSize = (m_splitMode == wxSPLIT_VERTICAL) ? 
+                       win->GetMinWidth() : win->GetMinHeight();
+        if ( minSize != -1 && sashPos > window_size - minSize - GetBorderSize() )
+            sashPos = window_size - minSize - GetBorderSize();
+    }
+}
+
 // Position and size subwindows.
 // Note that the border size applies to each subwindow, not
 // including the edges next to the sash.
@@ -691,7 +762,7 @@ void wxSplitterWindow::SizeWindows()
     if ( GetBorderSize() > 0 )
         DrawBorders(dc);
     DrawSash(dc);
-    
+
     SetNeedUpdating(FALSE);
 }
 
@@ -720,9 +791,11 @@ bool wxSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, int
     if ( sashPosition > 0 )
         m_sashPosition = sashPosition;
     else if ( sashPosition < 0 )
-        m_sashPosition = w - sashPosition;
+        m_sashPosition = w + sashPosition;   // It's negative so adding is subtracting
     else    // default
         m_sashPosition = w/2;
+        
+    AdjustSashPosition(m_sashPosition);
 
     SizeWindows();
 
@@ -743,10 +816,12 @@ bool wxSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, i
     if ( sashPosition > 0 )
         m_sashPosition = sashPosition;
     else if ( sashPosition < 0 )
-        m_sashPosition = h - sashPosition;
+        m_sashPosition = h + sashPosition; // It's negative so adding is subtracting
     else    // default
         m_sashPosition = h/2;
 
+    AdjustSashPosition(m_sashPosition);
+
     SizeWindows();
 
     return TRUE;
@@ -815,6 +890,7 @@ bool wxSplitterWindow::ReplaceWindow(wxWindow *winOld, wxWindow *winNew)
 void wxSplitterWindow::SetSashPosition(int position, bool redraw)
 {
     m_sashPosition = position;
+    AdjustSashPosition(m_sashPosition);
 
     if ( redraw )
     {
@@ -833,30 +909,30 @@ void wxSplitterWindow::InitColours()
     wxDELETE( m_hilightPen );
 
     // Shadow colours
-#if defined(__WIN95__)
-    wxColour faceColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+#ifndef __WIN16__
+    wxColour faceColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
     m_facePen = new wxPen(faceColour, 1, wxSOLID);
     m_faceBrush = new wxBrush(faceColour, wxSOLID);
 
-    wxColour mediumShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW));
+    wxColour mediumShadowColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW));
     m_mediumShadowPen = new wxPen(mediumShadowColour, 1, wxSOLID);
 
-    wxColour darkShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DDKSHADOW));
+    wxColour darkShadowColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW));
     m_darkShadowPen = new wxPen(darkShadowColour, 1, wxSOLID);
 
-    wxColour lightShadowColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT));
+    wxColour lightShadowColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
     m_lightShadowPen = new wxPen(lightShadowColour, 1, wxSOLID);
 
-    wxColour hilightColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT));
+    wxColour hilightColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHILIGHT));
     m_hilightPen = new wxPen(hilightColour, 1, wxSOLID);
-#else // !Win32
+#else
     m_facePen = new wxPen("LIGHT GREY", 1, wxSOLID);
     m_faceBrush = new wxBrush("LIGHT GREY", wxSOLID);
     m_mediumShadowPen = new wxPen("GREY", 1, wxSOLID);
     m_darkShadowPen = new wxPen("BLACK", 1, wxSOLID);
     m_lightShadowPen = new wxPen("LIGHT GREY", 1, wxSOLID);
     m_hilightPen = new wxPen("WHITE", 1, wxSOLID);
-#endif // Win32/!Win32
+#endif // __WIN16__
 }
 
 void wxSplitterWindow::SendUnsplitEvent(wxWindow *winRemoved)
@@ -905,10 +981,7 @@ void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
     if ( !unsplit_scenario )
     {
         // If resultant pane would be too small, enlarge it
-        if ( newSashPosition < m_minimumPaneSize )
-            newSashPosition = m_minimumPaneSize;
-        if ( newSashPosition > window_size - m_minimumPaneSize )
-            newSashPosition = window_size - m_minimumPaneSize;
+        AdjustSashPosition(newSashPosition);
     }
 
     // If the result is out of bounds it means minimum size is too big,