fixes to sash adjusting code to avoid setting it to 0 initially

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14215 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-02-14 21:00:41 +00:00
parent 58b434187d
commit 2e8cc3e834
2 changed files with 130 additions and 106 deletions

View File

@@ -25,7 +25,7 @@ class WXDLLEXPORT wxSplitterEvent;
// splitter constants // splitter constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
enum enum wxSplitMode
{ {
wxSPLIT_HORIZONTAL = 1, wxSPLIT_HORIZONTAL = 1,
wxSPLIT_VERTICAL wxSPLIT_VERTICAL
@@ -92,10 +92,16 @@ public:
wxWindow *GetWindow2() const { return m_windowTwo; } wxWindow *GetWindow2() const { return m_windowTwo; }
// Sets the split mode // Sets the split mode
void SetSplitMode(int mode) { m_splitMode = mode; } void SetSplitMode(int mode)
{
wxASSERT_MSG( mode == wxSPLIT_VERTICAL || mode == wxSPLIT_HORIZONTAL,
_T("invalid split mode") );
m_splitMode = (wxSplitMode)mode;
}
// Gets the split mode // Gets the split mode
int GetSplitMode() const { return m_splitMode; }; wxSplitMode GetSplitMode() const { return m_splitMode; };
// Initialize with one window // Initialize with one window
void Initialize(wxWindow *window); void Initialize(wxWindow *window);
@@ -108,10 +114,12 @@ public:
// absolute value rather than the size of left/upper pane. // absolute value rather than the size of left/upper pane.
virtual bool SplitVertically(wxWindow *window1, virtual bool SplitVertically(wxWindow *window1,
wxWindow *window2, wxWindow *window2,
int sashPosition = 0); int sashPosition = 0)
{ return DoSplit(wxSPLIT_VERTICAL, window1, window2, sashPosition); }
virtual bool SplitHorizontally(wxWindow *window1, virtual bool SplitHorizontally(wxWindow *window1,
wxWindow *window2, wxWindow *window2,
int sashPosition = 0); int sashPosition = 0)
{ return DoSplit(wxSPLIT_HORIZONTAL, window1, window2, sashPosition); }
// Removes the specified (or second) window from the view // Removes the specified (or second) window from the view
// Doesn't actually delete the window. // Doesn't actually delete the window.
@@ -212,11 +220,19 @@ protected:
protected: protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
// adjusts sash position with respect to min. pane and window sizes
void AdjustSashPosition(int &sashPos);
int m_splitMode; // common part of SplitVertically() and SplitHorizontally()
bool DoSplit(wxSplitMode mode,
wxWindow *window1, wxWindow *window2,
int sashPosition);
// adjusts sash position with respect to min. pane and window sizes
int AdjustSashPosition(int sashPos) const;
// get either width or height depending on the split mode
int GetWindowSize() const;
wxSplitMode m_splitMode;
bool m_permitUnsplitAlways; bool m_permitUnsplitAlways;
bool m_needUpdating; // when in live mode, set this to TRUE to resize children in idle bool m_needUpdating; // when in live mode, set this to TRUE to resize children in idle
wxWindow* m_windowOne; wxWindow* m_windowOne;

View File

@@ -88,7 +88,7 @@ bool wxSplitterWindow::Create(wxWindow *parent, wxWindowID id,
m_borderSize = 1; m_borderSize = 1;
else else
m_borderSize = 0; m_borderSize = 0;
#ifdef __WXMAC__ #ifdef __WXMAC__
int major,minor; int major,minor;
wxGetOsVersion( &major, &minor ); wxGetOsVersion( &major, &minor );
@@ -166,8 +166,8 @@ void wxSplitterWindow::OnIdle(wxIdleEvent& event)
void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event) void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
{ {
wxCoord x = (wxCoord)event.GetX(), int x = (int)event.GetX(),
y = (wxCoord)event.GetY(); y = (int)event.GetY();
// reset the cursor // reset the cursor
#ifdef __WXMOTIF__ #ifdef __WXMOTIF__
@@ -221,11 +221,8 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
// Obtain window size. We are only interested in the dimension the sash // Obtain window size. We are only interested in the dimension the sash
// splits up // splits up
int w, h; int window_size = GetWindowSize();
GetClientSize(&w, &h); int new_sash_position = m_splitMode == wxSPLIT_VERTICAL ? x : y;
int window_size = (m_splitMode == wxSPLIT_VERTICAL ? w : h );
int new_sash_position =
(int) ( m_splitMode == wxSPLIT_VERTICAL ? x : y );
wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED, wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGED,
this); this);
@@ -316,8 +313,7 @@ void wxSplitterWindow::OnMouseEvent(wxMouseEvent& event)
// Obtain window size. We are only interested in the dimension the sash // Obtain window size. We are only interested in the dimension the sash
// splits up // splits up
int new_sash_position = int new_sash_position = m_splitMode == wxSPLIT_VERTICAL ? x : y;
(int) ( m_splitMode == wxSPLIT_VERTICAL ? x : y );
wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING, wxSplitterEvent eventSplitter(wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING,
this); this);
@@ -396,43 +392,44 @@ void wxSplitterWindow::OnSize(wxSizeEvent& event)
parent = parent->GetParent(); parent = parent->GetParent();
} }
bool iconized = FALSE; bool iconized;
wxFrame *frame = wxDynamicCast(parent, wxFrame);
if ( frame ) wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
iconized = frame->IsIconized(); if ( winTop )
{
iconized = winTop->IsIconized();
}
else else
{ {
wxDialog *dialog = wxDynamicCast(parent, wxDialog); wxFAIL_MSG(wxT("should have a top level parent!"));
if ( dialog )
iconized = dialog->IsIconized(); iconized = FALSE;
else
wxFAIL_MSG(wxT("should have a top level frame or dialog parent!"));
} }
if ( iconized ) if ( iconized )
{ {
event.Skip(); event.Skip();
}
else
{
int cw, ch;
GetClientSize( &cw, &ch );
if ( m_windowTwo )
{
if ( m_splitMode == wxSPLIT_VERTICAL )
{
if ( m_sashPosition >= (cw - 5) )
m_sashPosition = wxMax(10, cw - 40);
}
if ( m_splitMode == wxSPLIT_HORIZONTAL )
{
if ( m_sashPosition >= (ch - 5) )
m_sashPosition = wxMax(10, ch - 40);
}
}
SizeWindows(); return;
} }
int cw, ch;
GetClientSize( &cw, &ch );
if ( m_windowTwo )
{
if ( m_splitMode == wxSPLIT_VERTICAL )
{
if ( m_sashPosition >= (cw - 5) )
m_sashPosition = wxMax(10, cw - 40);
}
else // m_splitMode == wxSPLIT_HORIZONTAL
{
if ( m_sashPosition >= (ch - 5) )
m_sashPosition = wxMax(10, ch - 40);
}
}
SizeWindows();
} }
bool wxSplitterWindow::SashHitTest(int x, int y, int tolerance) bool wxSplitterWindow::SashHitTest(int x, int y, int tolerance)
@@ -543,7 +540,7 @@ void wxSplitterWindow::DrawSash(wxDC& dc)
else else
dc.SetPen(*m_darkShadowPen); dc.SetPen(*m_darkShadowPen);
dc.DrawLine(m_sashPosition+m_sashSize-1, m_borderSize, m_sashPosition+m_sashSize-1, h-m_borderSize ); 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 // Draw the top and bottom edges of the sash, if requested
if (GetWindowStyle() & wxSP_FULLSASH) if (GetWindowStyle() & wxSP_FULLSASH)
{ {
@@ -689,35 +686,59 @@ void wxSplitterWindow::DrawSashTracker(int x, int y)
screenDC.SetBrush(wxNullBrush); screenDC.SetBrush(wxNullBrush);
} }
void wxSplitterWindow::AdjustSashPosition(int &sashPos) int wxSplitterWindow::GetWindowSize() const
{ {
int w, h; wxSize size = GetClientSize();
GetClientSize(&w, &h);
int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h; return m_splitMode == wxSPLIT_VERTICAL ? size.x : size.y;
}
int wxSplitterWindow::AdjustSashPosition(int sashPos) const
{
int window_size = GetWindowSize();
if ( !window_size )
{
// don't do anything before the window has a valid size, otherwise we
// put the sash to 0 at the very beginning and it doesn't move from
// there any more
return sashPos;
}
wxWindow *win; wxWindow *win;
if ( sashPos < m_minimumPaneSize )
sashPos = m_minimumPaneSize;
else if ( sashPos > window_size - m_minimumPaneSize )
sashPos = window_size - m_minimumPaneSize;
win = GetWindow1(); win = GetWindow1();
if ( win ) if ( win )
{ {
int minSize = (m_splitMode == wxSPLIT_VERTICAL) ? // the window shouldn't be smaller than its own minimal size nor
win->GetMinWidth() : win->GetMinHeight(); // smaller than the minimual pane size specified for this splitter
if ( minSize != -1 && sashPos < minSize + GetBorderSize() ) int minSize = m_splitMode == wxSPLIT_VERTICAL ? win->GetMinWidth()
sashPos = minSize + GetBorderSize(); : win->GetMinHeight();
if ( minSize == -1 || m_minimumPaneSize > minSize )
minSize = m_minimumPaneSize;
minSize += GetBorderSize();
if ( sashPos < minSize )
sashPos = minSize;
} }
win = GetWindow2(); win = GetWindow2();
if ( win ) if ( win )
{ {
int minSize = (m_splitMode == wxSPLIT_VERTICAL) ? int minSize = m_splitMode == wxSPLIT_VERTICAL ? win->GetMinWidth()
win->GetMinWidth() : win->GetMinHeight(); : win->GetMinHeight();
if ( minSize != -1 && sashPos > window_size - minSize - GetBorderSize() )
sashPos = window_size - minSize - GetBorderSize(); if ( minSize == -1 || m_minimumPaneSize > minSize )
minSize = m_minimumPaneSize;
int maxSize = window_size - minSize - GetBorderSize();
if ( sashPos > maxSize )
sashPos = maxSize;
} }
return sashPos;
} }
// Position and size subwindows. // Position and size subwindows.
@@ -777,57 +798,47 @@ void wxSplitterWindow::Initialize(wxWindow *window)
// Associates the given window with window 2, drawing the appropriate sash // Associates the given window with window 2, drawing the appropriate sash
// and changing the split mode. // and changing the split mode.
// Does nothing and returns FALSE if the window is already split. // Does nothing and returns FALSE if the window is already split.
bool wxSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, int sashPosition) bool wxSplitterWindow::DoSplit(wxSplitMode mode,
wxWindow *window1, wxWindow *window2,
int sashPosition)
{ {
if ( IsSplit() ) if ( IsSplit() )
return FALSE; return FALSE;
int w, h; int window_size = GetWindowSize();
GetClientSize(&w, &h);
m_splitMode = wxSPLIT_VERTICAL; m_splitMode = mode;
m_windowOne = window1; m_windowOne = window1;
m_windowTwo = window2; m_windowTwo = window2;
if ( sashPosition > 0 ) if ( sashPosition > 0 )
{
m_sashPosition = sashPosition; m_sashPosition = sashPosition;
}
else if ( sashPosition < 0 ) else if ( sashPosition < 0 )
m_sashPosition = w + sashPosition; // It's negative so adding is subtracting {
else // default // It's negative so adding is subtracting
m_sashPosition = w/2; m_sashPosition = window_size + sashPosition;
}
AdjustSashPosition(m_sashPosition); else
{
// default
m_sashPosition = window_size/2;
}
// don't do it initially, i.e. when creating the window because it doesn't
// have a proper size yet and AdjustSashPosition() would happily set the
// sash position to 0!
if ( window_size > 0 )
{
m_sashPosition = AdjustSashPosition(m_sashPosition);
}
SizeWindows(); SizeWindows();
return TRUE; return TRUE;
} }
bool wxSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, int sashPosition)
{
if ( IsSplit() )
return FALSE;
int w, h;
GetClientSize(&w, &h);
m_splitMode = wxSPLIT_HORIZONTAL;
m_windowOne = window1;
m_windowTwo = window2;
if ( sashPosition > 0 )
m_sashPosition = sashPosition;
else if ( sashPosition < 0 )
m_sashPosition = h + sashPosition; // It's negative so adding is subtracting
else // default
m_sashPosition = h/2;
AdjustSashPosition(m_sashPosition);
SizeWindows();
return TRUE;
}
// Remove the specified (or second) window from the view // Remove the specified (or second) window from the view
// Doesn't actually delete the window. // Doesn't actually delete the window.
bool wxSplitterWindow::Unsplit(wxWindow *toRemove) bool wxSplitterWindow::Unsplit(wxWindow *toRemove)
@@ -889,8 +900,7 @@ bool wxSplitterWindow::ReplaceWindow(wxWindow *winOld, wxWindow *winNew)
void wxSplitterWindow::SetSashPosition(int position, bool redraw) void wxSplitterWindow::SetSashPosition(int position, bool redraw)
{ {
m_sashPosition = position; m_sashPosition = AdjustSashPosition(position);
AdjustSashPosition(m_sashPosition);
if ( redraw ) if ( redraw )
{ {
@@ -955,9 +965,7 @@ void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
int newSashPosition = event.GetSashPosition(); int newSashPosition = event.GetSashPosition();
// Obtain relevant window dimension for bottom / right threshold check // Obtain relevant window dimension for bottom / right threshold check
int w, h; int window_size = GetWindowSize();
GetClientSize(&w, &h);
int window_size = (m_splitMode == wxSPLIT_VERTICAL) ? w : h ;
bool unsplit_scenario = FALSE; bool unsplit_scenario = FALSE;
if ( m_permitUnsplitAlways if ( m_permitUnsplitAlways
@@ -981,7 +989,7 @@ void wxSplitterWindow::OnSashPosChanged(wxSplitterEvent& event)
if ( !unsplit_scenario ) if ( !unsplit_scenario )
{ {
// If resultant pane would be too small, enlarge it // If resultant pane would be too small, enlarge it
AdjustSashPosition(newSashPosition); newSashPosition = AdjustSashPosition(newSashPosition);
} }
// If the result is out of bounds it means minimum size is too big, // If the result is out of bounds it means minimum size is too big,