Added wxSashWindow, wxSashLayoutWindow, wxLayoutAlgorithm classes and sample

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@702 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
1998-09-07 09:27:34 +00:00
parent 97b3455a6d
commit a6d7030871
12 changed files with 1747 additions and 0 deletions

226
src/generic/laywin.cpp Normal file
View File

@@ -0,0 +1,226 @@
/////////////////////////////////////////////////////////////////////////////
// Name: laywin.cpp
// Purpose: Implements a simple layout algorithm, plus
// wxSashLayoutWindow which is an example of a window with
// layout-awareness (via event handlers). This is suited to
// IDE-style window layout.
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#include "wx/mdi.h"
#endif
#include "wx/laywin.h"
IMPLEMENT_DYNAMIC_CLASS(wxQueryLayoutInfoEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxCalculateLayoutEvent, wxEvent)
IMPLEMENT_CLASS(wxSashLayoutWindow, wxSashWindow)
BEGIN_EVENT_TABLE(wxSashLayoutWindow, wxSashWindow)
EVT_CALCULATE_LAYOUT(wxSashLayoutWindow::OnCalculateLayout)
EVT_QUERY_LAYOUT_INFO(wxSashLayoutWindow::OnQueryLayoutInfo)
END_EVENT_TABLE()
wxSashLayoutWindow::wxSashLayoutWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos,
const wxSize& size, long style, const wxString& name):
wxSashWindow(parent, id, pos, size, style, name)
{
m_orientation = wxLAYOUT_HORIZONTAL;
m_alignment = wxLAYOUT_TOP;
}
// These are the functions that wxWin will call to ascertain the window
// dimensions.
void wxSashLayoutWindow::OnQueryLayoutInfo(wxQueryLayoutInfoEvent& event)
{
int flags = event.GetFlags();
int requestedLength = event.GetRequestedLength();
// This code won't be in the final thing, it's just so we don't have to give it
// real windows: mock up some dimensions.
event.SetOrientation(m_orientation);
event.SetAlignment(m_alignment);
if (m_orientation == wxLAYOUT_HORIZONTAL)
event.SetSize(wxSize(requestedLength, m_defaultSize.y));
else
event.SetSize(wxSize(m_defaultSize.x, requestedLength));
}
// Called by parent to allow window to take a bit out of the
// client rectangle, and size itself if not in wxLAYOUT_QUERY mode.
// Will eventually be an event.
void wxSashLayoutWindow::OnCalculateLayout(wxCalculateLayoutEvent& event)
{
wxRect clientSize(event.GetRect());
int flags = event.GetFlags();
if (!IsShown())
return;
// Let's assume that all windows stretch the full extent of the window in
// the direction of that window orientation. This will work for non-docking toolbars,
// and the status bar. Note that the windows have to have been created in a certain
// order to work, else you might get a left-aligned window going to the bottom
// of the window, and the status bar appearing to the right of it. The
// status bar would have to be created after or before the toolbar(s).
wxRect thisRect;
// Try to stretch
int length = (GetOrientation() == wxLAYOUT_HORIZONTAL) ? clientSize.width : clientSize.height;
wxLayoutOrientation orient = GetOrientation();
// We assume that a window that says it's horizontal, wants to be stretched in that
// direction. Is this distinction too fine? Do we assume that any horizontal
// window needs to be stretched in that direction? Possibly.
int whichDimension = (GetOrientation() == wxLAYOUT_HORIZONTAL) ? wxLAYOUT_LENGTH_X : wxLAYOUT_LENGTH_Y;
wxQueryLayoutInfoEvent infoEvent(GetId());
infoEvent.SetEventObject(this);
infoEvent.SetRequestedLength(length);
infoEvent.SetFlags(orient | whichDimension);
if (!GetEventHandler()->ProcessEvent(infoEvent))
return;
wxSize sz = infoEvent.GetSize();
if (sz.x == 0 && sz.y == 0) // Assume it's invisible
return;
// Now we know the size it wants to be. We wish to decide where to place it, i.e.
// how it's aligned.
switch (GetAlignment())
{
case wxLAYOUT_TOP:
{
thisRect.x = clientSize.x; thisRect.y = clientSize.y;
thisRect.width = sz.x; thisRect.height = sz.y;
clientSize.y += thisRect.height;
clientSize.height -= thisRect.height;
break;
}
case wxLAYOUT_LEFT:
{
thisRect.x = clientSize.x; thisRect.y = clientSize.y;
thisRect.width = sz.x; thisRect.height = sz.y;
clientSize.x += thisRect.width;
clientSize.width -= thisRect.width;
break;
}
case wxLAYOUT_RIGHT:
{
thisRect.x = clientSize.x + (clientSize.width - sz.x); thisRect.y = clientSize.y;
thisRect.width = sz.x; thisRect.height = sz.y;
clientSize.width -= thisRect.width;
break;
}
case wxLAYOUT_BOTTOM:
{
thisRect.x = clientSize.x; thisRect.y = clientSize.y + (clientSize.height - sz.y);
thisRect.width = sz.x; thisRect.height = sz.y;
clientSize.height -= thisRect.height;
break;
}
}
if ((flags & wxLAYOUT_QUERY) == 0)
{
// If not in query mode, resize the window.
// TODO: add wxRect& form to wxWindow::SetSize
SetSize(thisRect.x, thisRect.y, thisRect.width, thisRect.height);
}
event.SetRect(clientSize);
}
/*
* wxLayoutAlgorithm
*/
// Lays out windows for an MDI frame. The MDI client area gets what's left
// over.
bool wxLayoutAlgorithm::LayoutMDIFrame(wxMDIParentFrame* frame)
{
int cw, ch;
frame->GetClientSize(& cw, & ch);
wxRect rect(0, 0, cw, ch);
wxCalculateLayoutEvent event;
event.SetRect(rect);
wxNode* node = frame->GetChildren()->First();
while (node)
{
wxWindow* win = (wxWindow*) node->Data();
event.SetId(win->GetId());
event.SetEventObject(win);
event.SetFlags(0); // ??
win->GetEventHandler()->ProcessEvent(event);
node = node->Next();
}
wxWindow* clientWindow = frame->GetClientWindow();
rect = event.GetRect();
clientWindow->SetSize(rect.x, rect.y, rect.width, rect.height);
return TRUE;
}
// Layout algorithm for normal frame. mainWindow gets what's left over.
bool wxLayoutAlgorithm::LayoutFrame(wxFrame* frame, wxWindow* mainWindow)
{
int cw, ch;
frame->GetClientSize(& cw, & ch);
wxRect rect(0, 0, cw, ch);
wxCalculateLayoutEvent event;
event.SetRect(rect);
wxNode* node = frame->GetChildren()->First();
while (node)
{
wxWindow* win = (wxWindow*) node->Data();
event.SetId(win->GetId());
event.SetEventObject(win);
event.SetFlags(0); // ??
win->GetEventHandler()->ProcessEvent(event);
node = node->Next();
}
rect = event.GetRect();
mainWindow->SetSize(rect.x, rect.y, rect.width, rect.height);
return TRUE;
}