]> git.saurik.com Git - wxWidgets.git/commitdiff
wxSizer patches by Alexander Smishlajev <als@turnhere.com>
authorRobin Dunn <robin@alldunn.com>
Tue, 9 Nov 1999 23:02:41 +0000 (23:02 +0000)
committerRobin Dunn <robin@alldunn.com>
Tue, 9 Nov 1999 23:02:41 +0000 (23:02 +0000)
    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

15 files changed:
docs/latex/wx/boxsizer.tex
docs/latex/wx/sizer.tex
include/wx/defs.h
include/wx/sizer.h
samples/propsize/Makefile.in [new file with mode: 0644]
samples/propsize/makefile.g95 [new file with mode: 0644]
samples/propsize/makefile.vc [new file with mode: 0644]
samples/propsize/mondrian.ico [new file with mode: 0644]
samples/propsize/mondrian.xpm [new file with mode: 0644]
samples/propsize/propsize.cpp [new file with mode: 0644]
samples/propsize/propsize.rc [new file with mode: 0644]
src/common/sizer.cpp
utils/wxPython/demo/Sizers.py
utils/wxPython/lib/grids.py
utils/wxPython/src/_defs.i

index f00db53148f286297d0cdd2f0c308b0bb4ece926..42a0cf11048389c5f767344f786138dcadd306b4 100644 (file)
@@ -1,6 +1,6 @@
 \section{\class{wxBoxSizer}}\label{wxboxsizer}
 
 \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
 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
 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
 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
 
 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 );
   wxDialog( parent, id, title, wxDefaultPosition, wxDefaultSize, wxDIALOG_STYLE | wxRESIZE_BORDER )
 {
   wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
-  
+
   // create text ctrl with minimal size 100x60
   // 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
     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(
 
   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(
      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
      0,           // make horizontally unstretchable
      wxALL,       // make border all around (implicit top alignment)
      10 );        // set border width to 10
-  
-  topsizer->Add( 
+
+  topsizer->Add(
      button_sizer,
      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
 
   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}
 
 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}
 by the users. Documented for information.
 
 \membersection{wxBoxSizer::CalcMin}\label{wxboxsizercalcmin}
index 47e9cf030234bdfcd9e2cb394a4ebc5c62cde318..802c70d17d755d34b3facf83eeb7714e1bb3cf49 100644 (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
 \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
 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
 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.}
 
 
 \docparam{border}{Determines the border width, if the {\it flag} parameter is set to any border.}
 
index 1cf504cb50d0b45fb734be86441b36b94db57054..8a546d325d97562053ffc98d2dc27180611bb709 100644 (file)
@@ -695,12 +695,17 @@ enum wxDirection
 enum wxAlignment
 {
     wxALIGN_NOT               = 0x0000,
 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_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
 };
 
 enum wxStretch
@@ -708,7 +713,8 @@ enum wxStretch
     wxSTRETCH_NOT             = 0x0000,
     wxSHRINK                  = 0x1000,
     wxGROW                    = 0x2000,
     wxSTRETCH_NOT             = 0x0000,
     wxSHRINK                  = 0x1000,
     wxGROW                    = 0x2000,
-    wxEXPAND                  = wxGROW
+    wxEXPAND                  = wxGROW,
+    wxSHAPED                  = 0x4000
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
index c94ebfee7187fa6e9e546391f7eb3a9be447ced5..c8e4503f515550508e8fe36174b4441d577b39a6 100644 (file)
@@ -56,6 +56,15 @@ public:
   virtual wxSize CalcMin();
   virtual void SetDimension( wxPoint pos, wxSize size );
 
   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();
   bool IsWindow();
   bool IsSizer();
   bool IsSpacer();
@@ -81,6 +90,10 @@ protected:
   int          m_option;
   int          m_border;
   int          m_flag;
   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;
 };
 
   wxObject    *m_userData;
 };
 
diff --git a/samples/propsize/Makefile.in b/samples/propsize/Makefile.in
new file mode 100644 (file)
index 0000000..f889d28
--- /dev/null
@@ -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
diff --git a/samples/propsize/makefile.g95 b/samples/propsize/makefile.g95
new file mode 100644 (file)
index 0000000..7a2bd64
--- /dev/null
@@ -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
+
diff --git a/samples/propsize/makefile.vc b/samples/propsize/makefile.vc
new file mode 100644 (file)
index 0000000..c356f69
--- /dev/null
@@ -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
diff --git a/samples/propsize/mondrian.ico b/samples/propsize/mondrian.ico
new file mode 100644 (file)
index 0000000..2310c5d
Binary files /dev/null and b/samples/propsize/mondrian.ico differ
diff --git a/samples/propsize/mondrian.xpm b/samples/propsize/mondrian.xpm
new file mode 100644 (file)
index 0000000..0d72d68
--- /dev/null
@@ -0,0 +1,44 @@
+/* XPM */\r
+static char *mondrian_xpm[] = {\r
+/* columns rows colors chars-per-pixel */\r
+"32 32 6 1",\r
+"  c Black",\r
+". c Blue",\r
+"X c #00bf00",\r
+"o c Red",\r
+"O c Yellow",\r
+"+ c Gray100",\r
+/* pixels */\r
+"                                ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+" oooooo +++++++++++++++++++++++ ",\r
+"                                ",\r
+" ++++++ ++++++++++++++++++ .... ",\r
+" ++++++ ++++++++++++++++++ .... ",\r
+" ++++++ ++++++++++++++++++ .... ",\r
+" ++++++ ++++++++++++++++++ .... ",\r
+" ++++++ ++++++++++++++++++ .... ",\r
+" ++++++ ++++++++++++++++++      ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++ ++++++++++++++++++ ++++ ",\r
+" ++++++                    ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",\r
+"                                "\r
+};
\ No newline at end of file
diff --git a/samples/propsize/propsize.cpp b/samples/propsize/propsize.cpp
new file mode 100644 (file)
index 0000000..2189f89
--- /dev/null
@@ -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);
+}
diff --git a/samples/propsize/propsize.rc b/samples/propsize/propsize.rc
new file mode 100644 (file)
index 0000000..4e06231
--- /dev/null
@@ -0,0 +1,5 @@
+mondrian ICON "mondrian.ico"
+#include "wx/msw/wx.rc"
+
+#define MINIMAL_QUIT   1
+#define MINIMAL_ABOUT  102
index e412f5a70ce3e3815a88c1c6ced66e7755563a99..ea20ee7168722f7dd98554227f19f448d4350fb2 100644 (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;
 
     m_minSize.x = width;
     m_minSize.y = height;
 
+    SetRatio(width, height);
+
     // size is set directly
     m_size = m_minSize;
 }
     // 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();
 
     // 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 = ...
 }
     // 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 = ...
 
     // minimal size is calculated later
     // m_minSize = ...
+    m_ratio = 0;
 
     // size is calculated later
     // m_size = ...
 
     // size is calculated later
     // m_size = ...
@@ -119,7 +125,13 @@ wxSize wxSizerItem::CalcMin()
 {
     wxSize ret;
     if (IsSizer())
 {
     wxSize ret;
     if (IsSizer())
+    {
         ret = m_sizer->CalcMin();
         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
 /*
     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;
     }
     {
         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 );
 
     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) );
 
            wxPoint child_pos( pt );
            wxSize  child_size( wxSize( size.x, height) );
 
-           if (item->GetFlag() & wxALIGN_RIGHT)
+           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;
              child_pos.x += m_size.x - size.x;
-           else if (item->GetFlag() & wxCENTER)
+           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;
              child_pos.x += (m_size.x - size.x) / 2;
-           else if (item->GetFlag() & wxEXPAND)
-             child_size.x = m_size.x;
 
            item->SetDimension( child_pos, child_size );
 
 
            item->SetDimension( child_pos, child_size );
 
@@ -393,12 +429,14 @@ void wxBoxSizer::RecalcSizes()
            wxPoint child_pos( pt );
            wxSize  child_size( wxSize(width, size.y) );
 
            wxPoint child_pos( pt );
            wxSize  child_size( wxSize(width, size.y) );
 
-           if (item->GetFlag() & wxALIGN_BOTTOM)
+           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;
              child_pos.y += m_size.y - size.y;
-           else if (item->GetFlag() & wxCENTER)
+           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;
              child_pos.y += (m_size.y - size.y) / 2;
-           else if (item->GetFlag() & wxEXPAND)
-             child_size.y = m_size.y;
 
            item->SetDimension( child_pos, child_size );
 
 
            item->SetDimension( child_pos, child_size );
 
index 0ea2df780718d9af0af7fa20654a7c4ec12b595f..24545c108d3ccaf0bff2494ee5e33a36f268bf33 100644 (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 = 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)
 
     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 = 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)
     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, '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),
                  (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 "
 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,
     ("", 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."
      ),
 
      "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."
      ),
 
      "\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."
+     ),
+
     ]
 #----------------------------------------------------------------------
 
     ]
 #----------------------------------------------------------------------
 
index d67443e07b38d83876115911b6ebd0aebad6c7fd..df4d7c9969f78b939adb968e47b1512ec76b2ae8 100644 (file)
@@ -132,22 +132,18 @@ class wxGridSizer(wxPySizer):
         isz = item.CalcMin()
         flag = item.GetFlag()
 
         isz = item.CalcMin()
         flag = item.GetFlag()
 
-        if flag & wxEXPAND:
+        if flag & wxEXPAND or flag & wxSHAPED:
             isz = wxSize(w, h)
             isz = wxSize(w, h)
-
-        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)
+        else:
+            if flag & wxALIGN_CENTER_HORIZONTAL:
+                ipt.x = x + (w - isz.width) / 2
+            elif flag & wxALIGN_RIGHT:
+                ipt.x = x + (w - isz.width)
+
+            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)
 
 
         item.SetDimension(ipt, isz)
 
index 98c6124f097f64cdb18b287f8e5dedd63ddf8e28..fbed419f639576dd9a6334356527e739dad25046 100644 (file)
@@ -232,11 +232,16 @@ enum {
     wxCOLOURED,
     wxFIXED_LENGTH,
     wxALIGN_LEFT,
     wxCOLOURED,
     wxFIXED_LENGTH,
     wxALIGN_LEFT,
-    wxALIGN_CENTER,
-    wxALIGN_CENTRE,
+    wxALIGN_CENTER_HORIZONTAL,
+    wxALIGN_CENTRE_HORIZONTAL,
     wxALIGN_RIGHT,
     wxALIGN_BOTTOM,
     wxALIGN_RIGHT,
     wxALIGN_BOTTOM,
+    wxALIGN_CENTER_VERTICAL,
+    wxALIGN_CENTRE_VERTICAL,
     wxALIGN_TOP,
     wxALIGN_TOP,
+    wxALIGN_CENTER,
+    wxALIGN_CENTRE,
+    wxSHAPED,
     wxLB_NEEDED_SB,
     wxLB_ALWAYS_SB,
     wxLB_SORT,
     wxLB_NEEDED_SB,
     wxLB_ALWAYS_SB,
     wxLB_SORT,