wxSizer patches by Alexander Smishlajev <als@turnhere.com>

Adds some wxALIGN_* flags to increase ability to position item
    within its allotted space.

    Adds wxSHAPED flag that enforces proportional resizing on growable
    items.

    Adds a sample and updated documentation.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4461 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn 1999-11-09 23:02:41 +00:00
parent a7540f46f7
commit be2577e4e6
15 changed files with 555 additions and 54 deletions

View File

@ -1,6 +1,6 @@
\section{\class{wxBoxSizer}}\label{wxboxsizer}
The basic idea behind a box sizer is that windows will most often be laid out in rather
The basic idea behind a box sizer is that windows will most often be laid out in rather
simple basic geomerty, typically in a row or a column or several hierachies of either.
As an exmaple, we will construct a dialog that will contain a text field at the top and
@ -21,13 +21,16 @@ when adding a window (or another sizer) to a sizer. It is interpreted
as a weight factor, i.e. it can be zero, indicating that the window may not be resized
at all, or above zero. If several windows have a value above zero, the value is interpreted
relative to the sum of all weight factors of the sizer, so when adding two windows with
a value of 1, they will both get resized equally much and each half as much as the sizer
a value of 1, they will both get resized equally much and each half as much as the sizer
owning them. Then what do we do when a column sizer changes its width? This behaviour is
controlled by {\it flags} (the second parameter of the Add() function): Zero or no flag indicates that
the window will get aligned at the left (in a column sizer) and the top (row sizer), whereas
wxALIGN\_RIGHT and wxALIGN\_BOTTOM will do what they say. The item can also be centered
using the wxCENTRE flag (same as wxCENTER) or it can be forced to grow with the sizer (using
the wxGROW flag (same as wxEXPAND)).
controlled by {\it flags} (the second parameter of the Add() function): Zero or no flag
indicates that the window will preserve it's original size, wxGROW flag (same as wxEXPAND)
forces the window to grow with the sizer, and wxSHAPED flag tells the window to change it's
size proportionally, preserving original aspect ratio. When wxGROW flag is not used,
the item can be aligned within available space. wxALIGN\_LEFT, wxALIGN\_TOP, wxALIGN\_RIGHT,
wxALIGN\_BOTTOM, wxALIGN\_CENTER\_HORIZONTAL and wxALIGN\_CENTER\_VERTICAL do what they say.
wxALIGN\_CENTRE (same as wxALIGN\_CENTER) is defined as (wxALIGN\_CENTER\_HORIZONTAL |
wxALIGN\_CENTER\_VERTICAL). Default alignment is wxALIGN\_LEFT | wxALIGN\_TOP.
As mentioned above, any window belonging to a sizer may have border, and it can be specified
which of the four sides may have this border, using the wxTOP, wxLEFT, wxRIGHT and wxBOTTOM
@ -45,9 +48,9 @@ MyDialog::MyDialog(wxFrame *parent, wxWindowID id, const wxString &title ) :
wxDialog( parent, id, title, wxDefaultPosition, wxDefaultSize, wxDIALOG_STYLE | wxRESIZE_BORDER )
{
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// create text ctrl with minimal size 100x60
topsizer->Add(
topsizer->Add(
new wxTextCtrl( this, -1, "My text.", wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE),
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
@ -57,20 +60,20 @@ MyDialog::MyDialog(wxFrame *parent, wxWindowID id, const wxString &title ) :
wxBoxSizer *button_sizer = new wxBoxSizer( wxHORIZONTAL );
button_sizer->Add(
new wxButton( this, wxID_OK, "OK" ),
new wxButton( this, wxID_OK, "OK" ),
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
10 ); // set border width to 10
button_sizer->Add(
new wxButton( this, wxID_CANCEL, "Cancel" ),
new wxButton( this, wxID_CANCEL, "Cancel" ),
0, // make horizontally unstretchable
wxALL, // make border all around (implicit top alignment)
10 ); // set border width to 10
topsizer->Add(
topsizer->Add(
button_sizer,
0, // make vertically unstretchable
wxCENTER ); // no border and centre horizontally
0, // make vertically unstretchable
wxALIGN_CENTER ); // no border and centre horizontally
SetAutoLayout( TRUE ); // tell dialog to use sizer
SetSizer( topsizer ); // actually set the sizer
@ -98,7 +101,7 @@ or wxHORIZONTAL for creating either a column sizer or a row sizer.
Implements the calculation of a box sizer's dimensions and then sets
the size of its its children (calling \helpref{wxWindow::SetSize}{wxwindowsetsize}
if the child is a window). It is used internally only and must not be called
if the child is a window). It is used internally only and must not be called
by the users. Documented for information.
\membersection{wxBoxSizer::CalcMin}\label{wxboxsizercalcmin}

View File

@ -1,7 +1,7 @@
\section{\class{wxSizer}}\label{wxsizer}
wxSizer is the abstract base class used for laying out subwindows in a window. You
cannot use wxSizer directly; instead, you'll have to use \helpref{wxBoxSizer}{wxboxsizer}
cannot use wxSizer directly; instead, you'll have to use \helpref{wxBoxSizer}{wxboxsizer}
or \helpref{wxStaticBoxSizer}{wxstaticboxsizer}.
The layout algorithm used by sizers in wxWindows closely related to layout
@ -87,9 +87,12 @@ determine the child window's behaviour if the size of the sizer changes, but - i
the {\it option} flag - not in the main orientation, but the respectively other orientation. So
if you created a wxBoxSizer with the wxVERTICAL option, these flags will be relevant if the
sizer changes its horizontal size. A child may get resized to completely fill out the new size (using
either wxGROW or wxEXPAND), may get centered (wxCENTER or wxCENTRE) or may get aligned to either
side (wxALIGN\_LEFT and wxALIGN\_TOP are set to 0 and thus represent the default, wxALIGN\_RIGHT and
wxALIGN\_BOTTOM have their obvious meaning).}
either wxGROW or wxEXPAND), may get proportionally resized (wxSHAPED), may get centered (wxALIGN\_CENTER
or wxALIGN\_CENTRE) or may get aligned to either side (wxALIGN\_LEFT and wxALIGN\_TOP are set to 0
and thus represent the default, wxALIGN\_RIGHT and wxALIGN\_BOTTOM have their obvious meaning).
With proportional resize, a child may also be centered in the main orientation using
wxALIGN\_CENTER\_VERTICAL (same as wxALIGN\_CENTRE\_VERTICAL) and wxALIGN\_CENTER\_HORIZONTAL
(same as wxALIGN\_CENTRE\_HORIZONTAL) flags.}
\docparam{border}{Determines the border width, if the {\it flag} parameter is set to any border.}

View File

@ -695,12 +695,17 @@ enum wxDirection
enum wxAlignment
{
wxALIGN_NOT = 0x0000,
wxALIGN_CENTER = 0x0100,
wxALIGN_CENTRE = wxALIGN_CENTER,
wxALIGN_CENTER_HORIZONTAL = 0x0100,
wxALIGN_CENTRE_HORIZONTAL = wxALIGN_CENTER_HORIZONTAL,
wxALIGN_LEFT = wxALIGN_NOT,
wxALIGN_TOP = wxALIGN_NOT,
wxALIGN_RIGHT = 0x0200,
wxALIGN_BOTTOM = 0x0400
wxALIGN_BOTTOM = 0x0400,
wxALIGN_CENTER_VERTICAL = 0x0800,
wxALIGN_CENTRE_VERTICAL = wxALIGN_CENTER_VERTICAL,
wxALIGN_CENTER = (wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL),
wxALIGN_CENTRE = wxALIGN_CENTER
};
enum wxStretch
@ -708,7 +713,8 @@ enum wxStretch
wxSTRETCH_NOT = 0x0000,
wxSHRINK = 0x1000,
wxGROW = 0x2000,
wxEXPAND = wxGROW
wxEXPAND = wxGROW,
wxSHAPED = 0x4000
};
// ----------------------------------------------------------------------------

View File

@ -56,6 +56,15 @@ public:
virtual wxSize CalcMin();
virtual void SetDimension( wxPoint pos, wxSize size );
void SetRatio( int width, int height )
// if either of dimensions is zero, ratio is assumed to be 1
// to avoid "divide by zero" errors
{ m_ratio = (width && height) ? ((float) width / (float) height) : 1; }
void SetRatio( wxSize size )
{ m_ratio = (size.x && size.y) ? ((float) size.x / (float) size.y) : 1; }
void SetRatio( float ratio ) { m_ratio = ratio; }
float GetRatio() const { return m_ratio; }
bool IsWindow();
bool IsSizer();
bool IsSpacer();
@ -81,6 +90,10 @@ protected:
int m_option;
int m_border;
int m_flag;
// als: aspect ratio can always be calculated from m_size,
// but this would cause precision loss when the window
// is shrinked. it is safer to preserve initial value.
float m_ratio;
wxObject *m_userData;
};

View File

@ -0,0 +1,20 @@
#
# File: makefile.unx
# Author: Julian Smart
# Created: 1998
# Updated:
# Copyright: (c) 1998 Julian Smart
#
# "%W% %G%"
#
# Makefile for wxWindows sample (UNIX).
top_srcdir = @top_srcdir@
top_builddir = ../..
program_dir = samples/propsize
PROGRAM=propsize
OBJECTS=$(PROGRAM).o
include ../../src/makeprog.env

View File

@ -0,0 +1,16 @@
#
# File: makefile.g95
# Author: Julian Smart
# Created: 1999
# Updated:
# Copyright: (c) Julian Smart, 1999
#
# Makefile for wxWindows sample (Cygwin/Mingw32).
WXDIR = ../..
TARGET=propsize
OBJECTS = $(TARGET).o
include $(WXDIR)\src\makeprog.g95

View File

@ -0,0 +1,17 @@
#
# File: makefile.vc
# Author: Julian Smart
# Created: 1999
# Updated:
# Copyright: (c) Julian Smart
#
# Makefile : Builds sample (VC++, WIN32)
# Use FINAL=1 argument to nmake to build final version with no debug info.
# Set WXDIR for your system
WXDIR = $(WXWIN)
PROGRAM=propsize
OBJECTS = $(PROGRAM).obj
!include $(WXDIR)\src\makeprog.vc

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,44 @@
/* XPM */
static char *mondrian_xpm[] = {
/* columns rows colors chars-per-pixel */
"32 32 6 1",
" c Black",
". c Blue",
"X c #00bf00",
"o c Red",
"O c Yellow",
"+ c Gray100",
/* pixels */
" ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" oooooo +++++++++++++++++++++++ ",
" ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ .... ",
" ++++++ ++++++++++++++++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++++++++++++++++ ++++ ",
" ++++++ ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
" "
};

View File

@ -0,0 +1,249 @@
/////////////////////////////////////////////////////////////////////////////
// Name: propsize.cpp
// Purpose: Minimal wxWindows sample
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "propsize.cpp"
#pragma interface "propsize.cpp"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/statline.h"
// ----------------------------------------------------------------------------
// ressources
// ----------------------------------------------------------------------------
// the application icon
#if defined(__WXGTK__) || defined(__WXMOTIF__)
#include "mondrian.xpm"
#endif
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
// override base class virtuals
// ----------------------------
// this one is called on application startup and is a good place for the app
// initialization (doing it here and not in the ctor allows to have an error
// return: if OnInit() returns false, the application terminates)
virtual bool OnInit();
};
// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
// ctor(s)
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
private:
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// IDs for the controls and the menu commands
enum
{
// menu items
Minimal_Quit = 1,
Minimal_About
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWindows
// ----------------------------------------------------------------------------
// the event tables connect the wxWindows events with the functions (event
// handlers) which process them. It can be also done at run-time, but for the
// simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
EVT_MENU(Minimal_About, MyFrame::OnAbout)
END_EVENT_TABLE()
// Create a new application object: this macro will allow wxWindows to create
// the application object during program execution (it's better than using a
// static object for many reasons) and also declares the accessor function
// wxGetApp() which will return the reference of the right type (i.e. MyApp and
// not wxApp)
IMPLEMENT_APP(MyApp)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------
// `Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
// Create the main application window
MyFrame *frame = new MyFrame("Proportional resize",
wxPoint(50, 50), wxSize(450, 340));
// Show it and tell the application that it's our main window
// @@@ what does it do exactly, in fact? is it necessary here?
frame->Show(TRUE);
SetTopWindow(frame);
// success: wxApp::OnRun() will be called which will enter the main message
// loop and the application will run. If we returned FALSE here, the
// application would exit immediately.
return TRUE;
}
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
// frame constructor
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
// set the frame icon
SetIcon(wxICON(mondrian));
// create a menu bar
wxMenu *menuFile = new wxMenu("", wxMENU_TEAROFF);
menuFile->Append(Minimal_About, "&About...\tCtrl-A", "Show about dialog");
menuFile->AppendSeparator();
menuFile->Append(Minimal_Quit, "E&xit\tAlt-X", "Quit this program");
// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, "&File");
// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
#if wxUSE_STATUSBAR
// create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(1);
SetStatusText("Resize the frame to see how controls react");
#endif // wxUSE_STATUSBAR
#define AddLine(orient) \
Add( new wxStaticLine( this, -1, wxDefaultPosition, wxSize(2,2), orient), \
0, wxEXPAND)
#define AddButton(label,align) Add( \
new wxButton( this, -1, label, wxDefaultPosition, wxSize(100,50)), \
1, wxSHAPED | align)
wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
// top row -- top-aligned
wxBoxSizer *hsizer1 = new wxBoxSizer( wxHORIZONTAL );
hsizer1->AddButton( "one", wxALIGN_LEFT | wxALIGN_TOP);
hsizer1->AddLine(wxVERTICAL);
hsizer1->AddButton( "two", wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP);
hsizer1->AddLine(wxVERTICAL);
hsizer1->AddButton( "three", wxALIGN_RIGHT | wxALIGN_TOP);
topsizer->Add(hsizer1, 1, wxEXPAND);
topsizer->AddLine(wxHORIZONTAL);
wxBoxSizer *hsizer2 = new wxBoxSizer( wxHORIZONTAL );
hsizer2->AddButton( "four", wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
hsizer2->AddLine(wxVERTICAL);
// sizer that preserves it's shape
wxBoxSizer *vsizer = new wxBoxSizer( wxVERTICAL );
vsizer->Add(
new wxButton( this, -1, "up", wxDefaultPosition, wxSize(100,25)), \
1, wxEXPAND);
vsizer->Add(
new wxButton( this, -1, "down", wxDefaultPosition, wxSize(100,25)), \
1, wxEXPAND);
hsizer2->Add(vsizer, 1, wxSHAPED | wxALIGN_CENTER);
hsizer2->AddLine(wxVERTICAL);
hsizer2->AddButton( "six", wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
topsizer->Add(hsizer2, 1, wxEXPAND);
topsizer->AddLine(wxHORIZONTAL);
wxBoxSizer *hsizer3 = new wxBoxSizer( wxHORIZONTAL );
hsizer3->AddButton( "seven", wxALIGN_LEFT | wxALIGN_BOTTOM);
hsizer3->AddLine(wxVERTICAL);
hsizer3->AddButton( "eight", wxALIGN_CENTER_HORIZONTAL | wxALIGN_BOTTOM);
hsizer3->AddLine(wxVERTICAL);
// wxEXPAND should have no effect
hsizer3->AddButton( "nine", wxEXPAND | wxALIGN_RIGHT | wxALIGN_BOTTOM);
topsizer->Add(hsizer3, 1, wxEXPAND);
// set frame to minimum size
topsizer->Fit( this );
// don't allow frame to get smaller than what the sizers tell ye
// topsizer->SetSizeHints( this );
SetSizer( topsizer );
SetAutoLayout( TRUE );
}
// event handlers
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// TRUE is to force the frame to close
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxString msg;
msg.Printf( _T("This is the about dialog of proportional sizer test.\n")
_T("Welcome to %s")
#ifdef wxBETA_NUMBER
_T(" (beta %d)!")
#endif // wxBETA_NUMBER
, wxVERSION_STRING
#ifdef wxBETA_NUMBER
, wxBETA_NUMBER
#endif // wxBETA_NUMBER
);
wxMessageBox(msg, "About Shaped Sizer", wxOK | wxICON_INFORMATION, this);
}

View File

@ -0,0 +1,5 @@
mondrian ICON "mondrian.ico"
#include "wx/msw/wx.rc"
#define MINIMAL_QUIT 1
#define MINIMAL_ABOUT 102

View File

@ -48,6 +48,8 @@ wxSizerItem::wxSizerItem( int width, int height, int option, int flag, int borde
m_minSize.x = width;
m_minSize.y = height;
SetRatio(width, height);
// size is set directly
m_size = m_minSize;
}
@ -64,6 +66,9 @@ wxSizerItem::wxSizerItem( wxWindow *window, int option, int flag, int border, wx
// minimal size is the initial size
m_minSize = window->GetSize();
// aspect ratio calculated from initial size
SetRatio(m_minSize);
// size is calculated later
// m_size = ...
}
@ -79,6 +84,7 @@ wxSizerItem::wxSizerItem( wxSizer *sizer, int option, int flag, int border, wxOb
// minimal size is calculated later
// m_minSize = ...
m_ratio = 0;
// size is calculated later
// m_size = ...
@ -119,7 +125,13 @@ wxSize wxSizerItem::CalcMin()
{
wxSize ret;
if (IsSizer())
{
ret = m_sizer->CalcMin();
// if we have to preserve aspect ratio _AND_ this is
// the first-time calculation, consider ret to be initial size
if ((m_flag & wxSHAPED) && !m_ratio) SetRatio(ret);
}
/*
The minimum size of a window should be the
initial size, as saved in m_minSize, not the
@ -163,6 +175,28 @@ void wxSizerItem::SetDimension( wxPoint pos, wxSize size )
{
size.y -= m_border;
}
if (m_flag & wxSHAPED) {
// adjust aspect ratio
int rwidth = (int) (size.y * m_ratio);
if (rwidth > size.x) {
// fit horizontally
int rheight = (int) (size.x / m_ratio);
// add vertical space
if (m_flag & wxALIGN_CENTER_VERTICAL)
pos.y += (size.y - rheight) / 2;
else if (m_flag & wxALIGN_BOTTOM)
pos.y += (size.y - rheight);
// use reduced dimensions
size.y =rheight;
} else if (rwidth < size.x) {
// add horizontal space
if (m_flag & wxALIGN_CENTER_HORIZONTAL)
pos.x += (size.x - rwidth) / 2;
else if (m_flag & wxALIGN_RIGHT)
pos.x += (size.x - rwidth);
size.x = rwidth;
}
}
if (IsSizer())
m_sizer->SetDimension( pos.x, pos.y, size.x, size.y );
@ -370,12 +404,14 @@ void wxBoxSizer::RecalcSizes()
wxPoint child_pos( pt );
wxSize child_size( wxSize( size.x, height) );
if (item->GetFlag() & wxALIGN_RIGHT)
child_pos.x += m_size.x - size.x;
else if (item->GetFlag() & wxCENTER)
child_pos.x += (m_size.x - size.x) / 2;
else if (item->GetFlag() & wxEXPAND)
if (item->GetFlag() & (wxEXPAND | wxSHAPED))
child_size.x = m_size.x;
else if (item->GetFlag() & wxALIGN_RIGHT)
child_pos.x += m_size.x - size.x;
else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_HORIZONTAL))
// XXX wxCENTER is added for backward compatibility;
// wxALIGN_CENTER should be used in new code
child_pos.x += (m_size.x - size.x) / 2;
item->SetDimension( child_pos, child_size );
@ -393,12 +429,14 @@ void wxBoxSizer::RecalcSizes()
wxPoint child_pos( pt );
wxSize child_size( wxSize(width, size.y) );
if (item->GetFlag() & wxALIGN_BOTTOM)
child_pos.y += m_size.y - size.y;
else if (item->GetFlag() & wxCENTER)
child_pos.y += (m_size.y - size.y) / 2;
else if (item->GetFlag() & wxEXPAND)
if (item->GetFlag() & (wxEXPAND | wxSHAPED))
child_size.y = m_size.y;
else if (item->GetFlag() & wxALIGN_BOTTOM)
child_pos.y += m_size.y - size.y;
else if (item->GetFlag() & (wxCENTER | wxALIGN_CENTER_VERTICAL))
// XXX wxCENTER is added for backward compatibility;
// wxALIGN_CENTER should be used in new code
child_pos.y += (m_size.y - size.y) / 2;
item->SetDimension( child_pos, child_size );

View File

@ -69,7 +69,7 @@ def makeSimpleBox6(win):
box = wxBoxSizer(wxHORIZONTAL)
box.Add(wxButton(win, 1010, "one"), 1, wxALIGN_TOP)
box.Add(wxButton(win, 1010, "two"), 1, wxEXPAND)
box.Add(wxButton(win, 1010, "three"), 1, wxCENTER)
box.Add(wxButton(win, 1010, "three"), 1, wxALIGN_CENTER)
box.Add(wxButton(win, 1010, "four"), 1, wxEXPAND)
box.Add(wxButton(win, 1010, "five"), 1, wxALIGN_BOTTOM)
@ -93,7 +93,7 @@ def makeSimpleBox8(win):
box = wxBoxSizer(wxVERTICAL)
box.Add(wxButton(win, 1010, "one"), 0, wxEXPAND)
box.Add(0,0, 1)
box.Add(wxButton(win, 1010, "two"), 0, wxCENTER)
box.Add(wxButton(win, 1010, "two"), 0, wxALIGN_CENTER)
box.Add(0,0, 1)
box.Add(wxButton(win, 1010, "three"), 0, wxEXPAND)
box.Add(wxButton(win, 1010, "four"), 0, wxEXPAND)
@ -243,7 +243,7 @@ def makeGrid2(win):
(wxButton(win, 1010, 'two'), 0, wxEXPAND),
(wxButton(win, 1010, 'three'), 0, wxALIGN_LEFT | wxALIGN_BOTTOM),
(wxButton(win, 1010, 'four'), 0, wxEXPAND),
(wxButton(win, 1010, 'five'), 0, wxCENTER),
(wxButton(win, 1010, 'five'), 0, wxALIGN_CENTER),
(wxButton(win, 1010, 'six'), 0, wxEXPAND),
(box, 0, wxEXPAND | wxALL, 10),
(wxButton(win, 1010, 'eight'), 0, wxEXPAND),
@ -276,6 +276,76 @@ def makeGrid3(win):
#----------------------------------------------------------------------
def makeGrid4(win):
bpos = wxDefaultPosition
bsize = wxSize(100, 50)
gs = wxGridSizer(3, 3, 2, 2) # rows, cols, hgap, vgap
gs.AddMany([ (wxButton(win, 1010, 'one', bpos, bsize),
0, wxALIGN_TOP | wxALIGN_LEFT ),
(wxButton(win, 1010, 'two', bpos, bsize),
0, wxALIGN_TOP | wxALIGN_CENTER_HORIZONTAL ),
(wxButton(win, 1010, 'three', bpos, bsize),
0, wxALIGN_TOP | wxALIGN_RIGHT ),
(wxButton(win, 1010, 'four', bpos, bsize),
0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT ),
(wxButton(win, 1010, 'five', bpos, bsize),
0, wxALIGN_CENTER ),
(wxButton(win, 1010, 'six', bpos, bsize),
0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT ),
(wxButton(win, 1010, 'seven', bpos, bsize),
0, wxALIGN_BOTTOM | wxALIGN_LEFT ),
(wxButton(win, 1010, 'eight', bpos, bsize),
0, wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL ),
(wxButton(win, 1010, 'nine', bpos, bsize),
0, wxALIGN_BOTTOM | wxALIGN_RIGHT ),
])
return gs
#----------------------------------------------------------------------
def makeShapes(win):
bpos = wxDefaultPosition
bsize = wxSize(100, 50)
gs = wxGridSizer(3, 3, 2, 2) # rows, cols, hgap, vgap
gs.AddMany([ (wxButton(win, 1010, 'one', bpos, bsize),
0, wxSHAPED | wxALIGN_TOP | wxALIGN_LEFT ),
(wxButton(win, 1010, 'two', bpos, bsize),
0, wxSHAPED | wxALIGN_TOP | wxALIGN_CENTER_HORIZONTAL ),
(wxButton(win, 1010, 'three', bpos, bsize),
0, wxSHAPED | wxALIGN_TOP | wxALIGN_RIGHT ),
(wxButton(win, 1010, 'four', bpos, bsize),
0, wxSHAPED | wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT ),
(wxButton(win, 1010, 'five', bpos, bsize),
0, wxSHAPED | wxALIGN_CENTER ),
(wxButton(win, 1010, 'six', bpos, bsize),
0, wxSHAPED | wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT ),
(wxButton(win, 1010, 'seven', bpos, bsize),
0, wxSHAPED | wxALIGN_BOTTOM | wxALIGN_LEFT ),
(wxButton(win, 1010, 'eight', bpos, bsize),
0, wxSHAPED | wxALIGN_BOTTOM | wxALIGN_CENTER_HORIZONTAL ),
(wxButton(win, 1010, 'nine', bpos, bsize),
0, wxSHAPED | wxALIGN_BOTTOM | wxALIGN_RIGHT ),
])
return gs
#----------------------------------------------------------------------
def makeSimpleBoxShaped(win):
box = wxBoxSizer(wxHORIZONTAL)
box.Add(wxButton(win, 1010, "one"), 0, wxEXPAND)
box.Add(wxButton(win, 1010, "two"), 0, wxEXPAND)
box.Add(wxButton(win, 1010, "three"), 0, wxEXPAND)
box.Add(wxButton(win, 1010, "four"), 0, wxEXPAND)
box.Add(wxButton(win, 1010, "five"), 1, wxSHAPED)
return box
#----------------------------------------------------------------------
theTests = [
("Simple horizontal boxes", makeSimpleBox1,
"This is a HORIZONTAL box sizer with four non-stretchable buttons held "
@ -328,7 +398,7 @@ theTests = [
("", None, ""),
("Simple border sizer", makeSimpleBorder1,
"The wxBorderSizer leaves empty space around its contents. This one "
"The wxBoxSizer can leave empty space around its contents. This one "
"gives a border all the way around."
),
@ -380,6 +450,22 @@ theTests = [
"\nThere is also a spacer in the middle cell instead of an actual window."
),
("Grid with Alignment", makeGrid4,
"New alignment flags allow for the positioning of items in any corner or centered "
"position."
),
("", None, ""),
("Proportional resize", makeSimpleBoxShaped,
"Managed items can preserve their original aspect ratio. The last item has the "
"wxSHAPED flag set and will resize proportional to its origingal size."
),
("Proportional resize with Alignments", makeShapes,
"This one shows various alignments as well as proportional resizing for all items."
),
]
#----------------------------------------------------------------------

View File

@ -132,22 +132,18 @@ class wxGridSizer(wxPySizer):
isz = item.CalcMin()
flag = item.GetFlag()
if flag & wxEXPAND:
if flag & wxEXPAND or flag & wxSHAPED:
isz = wxSize(w, h)
else:
if flag & wxALIGN_CENTER_HORIZONTAL:
ipt.x = x + (w - isz.width) / 2
elif flag & wxALIGN_RIGHT:
ipt.x = x + (w - isz.width)
elif flag & wxCENTER:
ipt.x = x + (w - isz.width) / 2
ipt.y = y + (h - isz.height) / 2
if flag & wxALIGN_LEFT:
ipt.x = x
elif flag & wxALIGN_RIGHT:
ipt.x = x + (w - isz.width)
if flag & wxALIGN_TOP:
ipt.y = y
elif flag & wxALIGN_BOTTOM:
ipt.y = y + (h - isz.height)
if flag & wxALIGN_CENTER_VERTICAL:
ipt.y = y + (h - isz.height) / 2
elif flag & wxALIGN_BOTTOM:
ipt.y = y + (h - isz.height)
item.SetDimension(ipt, isz)

View File

@ -232,11 +232,16 @@ enum {
wxCOLOURED,
wxFIXED_LENGTH,
wxALIGN_LEFT,
wxALIGN_CENTER,
wxALIGN_CENTRE,
wxALIGN_CENTER_HORIZONTAL,
wxALIGN_CENTRE_HORIZONTAL,
wxALIGN_RIGHT,
wxALIGN_BOTTOM,
wxALIGN_CENTER_VERTICAL,
wxALIGN_CENTRE_VERTICAL,
wxALIGN_TOP,
wxALIGN_CENTER,
wxALIGN_CENTRE,
wxSHAPED,
wxLB_NEEDED_SB,
wxLB_ALWAYS_SB,
wxLB_SORT,