]> git.saurik.com Git - wxWidgets.git/commitdiff
Added fl (frame layout) to wxWindows, from source tidied by Hans Van Leemputten ...
authorJulian Smart <julian@anthemion.co.uk>
Tue, 24 Jul 2001 15:27:12 +0000 (15:27 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Tue, 24 Jul 2001 15:27:12 +0000 (15:27 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11170 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

109 files changed:
contrib/configure
contrib/configure.in
contrib/include/wx/fl/antiflickpl.h [new file with mode: 0644]
contrib/include/wx/fl/bardragpl.h [new file with mode: 0644]
contrib/include/wx/fl/barhintspl.h [new file with mode: 0644]
contrib/include/wx/fl/cbcustom.h [new file with mode: 0644]
contrib/include/wx/fl/controlbar.h [new file with mode: 0644]
contrib/include/wx/fl/dynbarhnd.h [new file with mode: 0644]
contrib/include/wx/fl/dyntbar.h [new file with mode: 0644]
contrib/include/wx/fl/dyntbarhnd.h [new file with mode: 0644]
contrib/include/wx/fl/frmview.h [new file with mode: 0644]
contrib/include/wx/fl/garbagec.h [new file with mode: 0644]
contrib/include/wx/fl/gcupdatesmgr.h [new file with mode: 0644]
contrib/include/wx/fl/hintanimpl.h [new file with mode: 0644]
contrib/include/wx/fl/newbmpbtn.h [new file with mode: 0644]
contrib/include/wx/fl/panedrawpl.h [new file with mode: 0644]
contrib/include/wx/fl/rowdragpl.h [new file with mode: 0644]
contrib/include/wx/fl/rowlayoutpl.h [new file with mode: 0644]
contrib/include/wx/fl/toolwnd.h [new file with mode: 0644]
contrib/include/wx/fl/updatesmgr.h [new file with mode: 0644]
contrib/samples/Makefile.in
contrib/samples/fl/Makefile.in [new file with mode: 0644]
contrib/samples/fl/bitmaps/bookmarks.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/class_icon.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/class_icon1.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/copy.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/cut.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/file_icon.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/folder_icon.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/help_icon.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/new.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/nextmark.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/open.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/paste.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/prevmark.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/res_icon.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/save.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/saveall.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/search.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/start95_dp.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/start95_pr.bmp [new file with mode: 0644]
contrib/samples/fl/bitmaps/tile.bmp [new file with mode: 0644]
contrib/samples/fl/fl_demo1/Makefile.in [new file with mode: 0644]
contrib/samples/fl/fl_demo1/fl_demo.dsp [new file with mode: 0644]
contrib/samples/fl/fl_demo1/fl_demo.dsw [new file with mode: 0644]
contrib/samples/fl/fl_demo1/fl_demo1.cpp [new file with mode: 0644]
contrib/samples/fl/fl_demo1/fl_demo1.h [new file with mode: 0644]
contrib/samples/fl/fl_demo1/fl_demo1.rc [new file with mode: 0644]
contrib/samples/fl/fl_demo1/makefile.b32 [new file with mode: 0644]
contrib/samples/fl/fl_demo1/makefile.g95 [new file with mode: 0644]
contrib/samples/fl/fl_demo1/makefile.vc [new file with mode: 0644]
contrib/samples/fl/fl_demo2/Makefile.in [new file with mode: 0644]
contrib/samples/fl/fl_demo2/fl_demo.dsp [new file with mode: 0644]
contrib/samples/fl/fl_demo2/fl_demo.dsw [new file with mode: 0644]
contrib/samples/fl/fl_demo2/fl_demo2.cpp [new file with mode: 0644]
contrib/samples/fl/fl_demo2/fl_demo2.h [new file with mode: 0644]
contrib/samples/fl/fl_demo2/fl_demo2.rc [new file with mode: 0644]
contrib/samples/fl/fl_demo2/makefile.b32 [new file with mode: 0644]
contrib/samples/fl/fl_demo2/makefile.g95 [new file with mode: 0644]
contrib/samples/fl/fl_demo2/makefile.vc [new file with mode: 0644]
contrib/samples/fl/fl_sample1/Makefile.in [new file with mode: 0644]
contrib/samples/fl/fl_sample1/fl_demo.dsp [new file with mode: 0644]
contrib/samples/fl/fl_sample1/fl_demo.dsw [new file with mode: 0644]
contrib/samples/fl/fl_sample1/fl_sample1.cpp [new file with mode: 0644]
contrib/samples/fl/fl_sample1/fl_sample1.rc [new file with mode: 0644]
contrib/samples/fl/fl_sample1/makefile.b32 [new file with mode: 0644]
contrib/samples/fl/fl_sample1/makefile.g95 [new file with mode: 0644]
contrib/samples/fl/fl_sample1/makefile.vc [new file with mode: 0644]
contrib/samples/fl/fl_sample2/Makefile.in [new file with mode: 0644]
contrib/samples/fl/fl_sample2/fl_demo.dsp [new file with mode: 0644]
contrib/samples/fl/fl_sample2/fl_demo.dsw [new file with mode: 0644]
contrib/samples/fl/fl_sample2/fl_sample2.cpp [new file with mode: 0644]
contrib/samples/fl/fl_sample2/fl_sample2.rc [new file with mode: 0644]
contrib/samples/fl/fl_sample2/makefile.b32 [new file with mode: 0644]
contrib/samples/fl/fl_sample2/makefile.g95 [new file with mode: 0644]
contrib/samples/fl/fl_sample2/makefile.vc [new file with mode: 0644]
contrib/samples/fl/fl_sample3/Makefile.in [new file with mode: 0644]
contrib/samples/fl/fl_sample3/fl_demo.dsp [new file with mode: 0644]
contrib/samples/fl/fl_sample3/fl_demo.dsw [new file with mode: 0644]
contrib/samples/fl/fl_sample3/fl_sample3.cpp [new file with mode: 0644]
contrib/samples/fl/fl_sample3/fl_sample3.rc [new file with mode: 0644]
contrib/samples/fl/fl_sample3/makefile.b32 [new file with mode: 0644]
contrib/samples/fl/fl_sample3/makefile.g95 [new file with mode: 0644]
contrib/samples/fl/fl_sample3/makefile.vc [new file with mode: 0644]
contrib/src/Makefile.in
contrib/src/fl/Makefile.in [new file with mode: 0644]
contrib/src/fl/antiflickpl.cpp [new file with mode: 0644]
contrib/src/fl/bardragpl.cpp [new file with mode: 0644]
contrib/src/fl/barhintspl.cpp [new file with mode: 0644]
contrib/src/fl/cbcustom.cpp [new file with mode: 0644]
contrib/src/fl/controlbar.cpp [new file with mode: 0644]
contrib/src/fl/dyntbar.cpp [new file with mode: 0644]
contrib/src/fl/dyntbarhnd.cpp [new file with mode: 0644]
contrib/src/fl/files.lst [new file with mode: 0644]
contrib/src/fl/flVC.dsp [new file with mode: 0644]
contrib/src/fl/flVC.dsw [new file with mode: 0644]
contrib/src/fl/frmview.cpp [new file with mode: 0644]
contrib/src/fl/garbagec.cpp [new file with mode: 0644]
contrib/src/fl/gcupdatesmgr.cpp [new file with mode: 0644]
contrib/src/fl/hintanimpl.cpp [new file with mode: 0644]
contrib/src/fl/makefile.b32 [new file with mode: 0644]
contrib/src/fl/makefile.g95 [new file with mode: 0644]
contrib/src/fl/makefile.vc [new file with mode: 0644]
contrib/src/fl/newbmpbtn.cpp [new file with mode: 0644]
contrib/src/fl/panedrawpl.cpp [new file with mode: 0644]
contrib/src/fl/rowdragpl.cpp [new file with mode: 0644]
contrib/src/fl/rowlayoutpl.cpp [new file with mode: 0644]
contrib/src/fl/toolwnd.cpp [new file with mode: 0644]
contrib/src/fl/updatesmgr.cpp [new file with mode: 0644]

index 5f5ab2decda283d9fa57cda8bc21dbd6b164dcd4..9cb5da925ff351eedffd03d655726a20b7680887 100755 (executable)
@@ -812,7 +812,6 @@ done
 ac_given_srcdir=$srcdir
 
 trap 'rm -fr `echo "
 ac_given_srcdir=$srcdir
 
 trap 'rm -fr `echo "
-            Makefile
             src/Makefile
             src/ogl/Makefile
             src/mmedia/Makefile
             src/Makefile
             src/ogl/Makefile
             src/mmedia/Makefile
@@ -822,6 +821,7 @@ trap 'rm -fr `echo "
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
+            src/fl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -838,6 +838,11 @@ trap 'rm -fr `echo "
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
+            samples/fl/fl_demo1
+            samples/fl/fl_demo2
+            samples/fl/fl_sample1
+            samples/fl/fl_sample2
+            samples/fl/fl_sample3
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
@@ -930,6 +935,7 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
+            src/fl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -946,6 +952,11 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
+            samples/fl/fl_demo1
+            samples/fl/fl_demo2
+            samples/fl/fl_sample1
+            samples/fl/fl_sample2
+            samples/fl/fl_sample3
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
index bf39a34e41cb0944a25cde140ea3fbd0fe79484d..4f65ed0b03c162d38731e2081bf9f7345dc5cf92 100644 (file)
@@ -37,7 +37,6 @@ dnl File output
 
 
 AC_OUTPUT([
 
 
 AC_OUTPUT([
-            Makefile
             src/Makefile
             src/ogl/Makefile
             src/mmedia/Makefile
             src/Makefile
             src/ogl/Makefile
             src/mmedia/Makefile
@@ -47,6 +46,7 @@ AC_OUTPUT([
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
             src/gizmos/Makefile
             src/plot/Makefile
             src/applet/Makefile
+            src/fl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
             samples/Makefile
             samples/mmedia/Makefile
             samples/ogl/Makefile
@@ -63,6 +63,11 @@ AC_OUTPUT([
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
             samples/xrc/Makefile
             samples/plot/Makefile
             samples/applet/Makefile
+            samples/fl/fl_demo1
+            samples/fl/fl_demo2
+            samples/fl/fl_sample1
+            samples/fl/fl_sample2
+            samples/fl/fl_sample3
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
             utils/Makefile
             utils/wxrc/Makefile
             utils/wxrcedit/Makefile
diff --git a/contrib/include/wx/fl/antiflickpl.h b/contrib/include/wx/fl/antiflickpl.h
new file mode 100644 (file)
index 0000000..9b44d85
--- /dev/null
@@ -0,0 +1,64 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas (@Lithuania)
+// Modified by:
+// Created:     23/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ANTIFLICKPL_G__
+#define __ANTIFLICKPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "antiflickpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+class cbAntiflickerPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbAntiflickerPlugin )
+protected:
+       // double-buffers are shared "resource" among all instances of 
+       // antiflicker plugin within the application 
+       //
+       // TODO:: locking should be implemented, for multithreaded GUIs
+
+       static wxBitmap*   mpVertBuf;
+       static wxBitmap*   mpHorizBuf;
+       static wxMemoryDC* mpVertBufDc;
+       static wxMemoryDC* mpHorizBufDc;
+
+       static int mRefCount;
+
+       wxDC*  mpLRUBufDc; // last-reacently-used buffer
+       wxRect mLRUArea;   // last-reacently-used area
+
+protected:
+       // returns NULL, if sutable buffer is not present
+       wxDC* FindSuitableBuffer( const wxRect& forArea );
+       wxDC* AllocNewBuffer( const wxRect& forArea );
+       wxDC& GetWindowDC();
+
+       wxDC& GetClientDC();
+public:
+
+       cbAntiflickerPlugin(void);
+
+       cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       virtual ~cbAntiflickerPlugin();
+
+       // handlers for plugin events
+
+       void OnStartDrawInArea ( cbStartDrawInAreaEvent& event );
+       void OnFinishDrawInArea( cbFinishDrawInAreaEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __ANTIFLICKPL_G__ */
+
diff --git a/contrib/include/wx/fl/bardragpl.h b/contrib/include/wx/fl/bardragpl.h
new file mode 100644 (file)
index 0000000..a9df99a
--- /dev/null
@@ -0,0 +1,122 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     23/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __BARDRAGPL_G__
+#define __BARDRAGPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "bardragpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+#include "wx/fl/toolwnd.h"
+
+class cbBarDragPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbBarDragPlugin )
+protected:
+
+       // plugin is active only in bar-dragging state
+       bool           mBarDragStarted;
+       bool           mCanStick;          // flag used to prevent "bouncing" of hint-rectangle
+       wxScreenDC*    mpScrDc;            // created while tracking hint-rect
+       wxCursor*      mpCurCursor;
+
+       // rectnagle shows the position/dimensions of the bar, 
+       // if it would be docked now
+
+       wxRect         mPrevHintRect;
+       wxRect         mHintRect;
+
+
+       int            mMouseInRectX;
+       int            mMouseInRectY;
+
+       cbDockPane*    mpSrcPane;          // pane, from which the bar was originally taken
+       int            mBarWidthInSrcPane;
+
+       cbDockPane*    mpCurPane;
+
+       cbBarInfo*     mpDraggedBar;       // bar, which is being dragged
+       bool           mBarWasFloating;
+       wxRect         mFloatedBarBounds;
+
+public: /*** public properties ***/
+
+       int            mInClientHintBorder; // when hint-rect moves within client window area,
+                                        // the thicker rectangle is drawn using hatched brush,
+                                                                               // the default border width for this rectangle is 8 pix.
+
+protected:
+
+
+       void AdjustHintRect( wxPoint& mousePos );
+
+       void ClipRectInFrame( wxRect& rect );
+       void ClipPosInFrame( wxPoint& pos );
+
+       cbDockPane* HitTestPanes( wxRect& rect );
+       cbDockPane* HitTestPanes( wxPoint& pos );
+       bool HitsPane( cbDockPane* pPane, wxRect& rect );
+
+       void CalcOnScreenDims( wxRect& rect );
+
+       int  GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos );
+
+       bool IsInOtherPane ( wxPoint& mousePos );
+       bool IsInClientArea( wxPoint& mousePos );
+       bool IsInClientArea( wxRect& rect );
+
+       void StickToPane( cbDockPane* pPane, wxPoint& mousePos );
+       void UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos );
+
+       int GetBarWidthInPane( cbDockPane* pPane );
+       int GetBarHeightInPane( cbDockPane* pPane );
+
+       // on-screen hint-tracking related methods
+
+       void StartTracking();
+
+       void DrawHintRect ( wxRect& rect, bool isInClientRect);
+       void EraseHintRect( wxRect& rect, bool isInClientRect);
+
+       void FinishTracking();
+
+       void DoDrawHintRect( wxRect& rect, bool isInClientRect);
+
+       void RectToScr( wxRect& frameRect, wxRect& scrRect );
+
+       void ShowHint( bool prevWasInClient );
+
+public:
+       cbBarDragPlugin(void);
+
+       cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       virtual ~cbBarDragPlugin();
+
+       // handlers for plugin events
+
+       void OnMouseMove( cbMotionEvent& event );
+       void OnLButtonUp( cbLeftUpEvent& event );
+       void OnLButtonDown( cbLeftDownEvent& event );
+       void OnLDblClick( cbLeftDClickEvent& event );
+
+       // handles event, which oriniates from itself
+       void OnDrawHintRect( cbDrawHintRectEvent& event );        
+
+       void OnStartBarDragging( cbStartBarDraggingEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __BARDRAGPL_G__ */
+
diff --git a/contrib/include/wx/fl/barhintspl.h b/contrib/include/wx/fl/barhintspl.h
new file mode 100644 (file)
index 0000000..809b101
--- /dev/null
@@ -0,0 +1,96 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     30/11/98 (my 22th birthday :-)
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DRAGHINTSPL_G__
+#define __DRAGHINTSPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "barhintspl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+#include "wx/fl/toolwnd.h"
+
+/*
+ * Intercepts bar-decoration and sizing events, draws 3d-hints
+ * around fixed and flexible bars, similar to those in Microsoft DevStudio 6.x
+ */
+
+class cbBarHintsPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbBarHintsPlugin )
+
+protected:
+       cbDockPane* mpPane; // is set up temorarely, while handling event
+
+       cbMiniButton* mBoxes[2];
+
+       bool        mBtnPressed;
+       bool        mClosePressed;
+       cbBarInfo*  mpClickedBar;
+       bool        mDepressed;
+
+protected:
+       // drawing helpers
+
+       void Draw3DBox      ( wxDC& dc, const wxPoint& pos, bool pressed );
+       void DrawCloseBox   ( wxDC& dc, const wxPoint& pos, bool pressed );
+       void DrawCollapseBox( wxDC& dc, const wxPoint& pos, 
+                                                 bool atLeft, bool disabled, bool pressed );
+
+       void DrawGrooves    ( wxDC& dc, const wxPoint& pos, int length );
+
+       void DoDrawHint( wxDC& dc, wxRect& rect, int pos, int boxOfs, int grooveOfs, bool isFixed );
+       
+       void GetHintsLayout( wxRect& rect, cbBarInfo& info, 
+                                                int& boxOfs, int& grooveOfs, int& pos );
+
+       int HitTestHints( cbBarInfo& info, const wxPoint& pos );
+
+       void ExcludeHints( wxRect& rect, cbBarInfo& info );
+
+       void CreateBoxes();
+
+public:
+       /* public properties */
+
+       bool mCloseBoxOn;    // default: ON
+       bool mCollapseBoxOn; // default: ON
+       int  mGrooveCount;   // default: 2 (two shaded bars)
+       int  mHintGap;       // default: 5 (pixels from above, below, right and left)
+       int  mXWeight;       // default: 2 (width in pixels of lines which used for drawing cross)
+
+public:
+
+       cbBarHintsPlugin(void);
+
+       cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask = wxALL_PANES );
+
+    ~cbBarHintsPlugin();
+
+       void SetGrooveCount( int nGrooves );
+
+       void OnInitPlugin();
+
+       // handlers of plugin-events
+
+       void OnSizeBarWindow( cbSizeBarWndEvent& event );
+       void OnDrawBarDecorations( cbDrawBarDecorEvent& event );
+
+       void OnLeftDown( cbLeftDownEvent& event );
+       void OnLeftUp  ( cbLeftUpEvent&   event );
+       void OnMotion  ( cbMotionEvent&   event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __DRAGHINTSPL_G__ */
+
diff --git a/contrib/include/wx/fl/cbcustom.h b/contrib/include/wx/fl/cbcustom.h
new file mode 100644 (file)
index 0000000..ff0c344
--- /dev/null
@@ -0,0 +1,47 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     28/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __CBCUSTOM_G__
+#define __CBCUSTOM_G__
+
+#ifdef __GNUG__
+    #pragma interface "cbcustom.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+class cbSimpleCustomizationPlugin : public cbPluginBase
+{
+public:
+       DECLARE_DYNAMIC_CLASS( cbSimpleCustomizationPlugin )
+
+       int mCustMenuItemId;
+public:
+
+       cbSimpleCustomizationPlugin(void);
+
+       cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       // plugin-event handlers
+
+       void OnCustomizeBar( cbCustomizeBarEvent& event );
+
+       void OnCustomizeLayout( cbCustomizeLayoutEvent& event );
+
+       // menu-event handler
+
+       void OnMenuItemSelected( wxCommandEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __CBCUSTOM_G__ */
+
diff --git a/contrib/include/wx/fl/controlbar.h b/contrib/include/wx/fl/controlbar.h
new file mode 100644 (file)
index 0000000..d67be75
--- /dev/null
@@ -0,0 +1,1740 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Central header file for control-bar related classes
+//
+// Author:      Aleksandras Gluchovas <mailto:alex@soften.ktu.lt>
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __CONTROLBAR_G__
+#define __CONTROLBAR_G__
+
+#ifdef __GNUG__
+    #pragma interface "controlbar.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/window.h"
+#include "wx/dynarray.h"
+
+#define WXCONTROLBAR_VERSION      1.3
+
+// forward declarations
+
+class  wxFrameLayout;
+
+class  cbDockPane;
+class  cbUpdatesManagerBase;
+class  cbBarDimHandlerBase;
+class  cbPluginBase;
+class  cbPluginEvent;
+class  cbPaneDrawPlugin;
+
+class cbBarInfo;
+class cbRowInfo;
+class cbDimInfo;
+class cbCommonPaneProperties;
+
+typedef cbBarInfo* BarInfoPtrT;
+typedef cbRowInfo* RowInfoPtrT;
+
+WX_DEFINE_ARRAY( BarInfoPtrT, BarArrayT );
+WX_DEFINE_ARRAY( RowInfoPtrT, RowArrayT );
+
+// control bar states
+
+#define wxCBAR_DOCKED_HORIZONTALLY 0
+#define wxCBAR_DOCKED_VERTICALLY   1
+#define wxCBAR_FLOATING            2
+#define wxCBAR_HIDDEN              3
+
+// the states are enumerated above
+#define MAX_BAR_STATES             4
+
+// control bar alignments
+
+#if !defined(FL_ALIGN_TOP)
+
+#define FL_ALIGN_TOP        0
+#define FL_ALIGN_BOTTOM     1
+#define FL_ALIGN_LEFT       2
+#define FL_ALIGN_RIGHT      3
+
+#endif
+
+// one pane for each alignment
+#define MAX_PANES      4
+
+// masks for each pane
+
+#define FL_ALIGN_TOP_PANE         0x0001
+#define FL_ALIGN_BOTTOM_PANE   0x0002
+#define FL_ALIGN_LEFT_PANE        0x0004
+#define FL_ALIGN_RIGHT_PANE   0x0008
+
+#define wxALL_PANES    0x000F
+
+// enumeration of hittest results, see cbDockPane::HitTestPaneItems(..) 
+
+enum CB_HITTEST_RESULT
+{
+       CB_NO_ITEMS_HITTED,
+
+       CB_UPPER_ROW_HANDLE_HITTED,
+       CB_LOWER_ROW_HANDLE_HITTED,
+       CB_LEFT_BAR_HANDLE_HITTED,
+       CB_RIGHT_BAR_HANDLE_HITTED,
+       CB_BAR_CONTENT_HITTED
+};
+
+// FIXME:: somehow in debug v. originall wxASSERT's are not compiled in...
+
+//#undef  wxASSERT
+//#define wxASSERT(x) if ( !(x) ) throw;
+
+// helper class, used for spying for not-handled mouse events on control-bars
+// and forwarding them to the frame layout
+
+class cbBarSpy : public wxEvtHandler 
+{
+public:
+       DECLARE_DYNAMIC_CLASS( cbBarSpy )
+
+       wxFrameLayout* mpLayout;
+       wxWindow*      mpBarWnd;
+
+public:
+       cbBarSpy(void);
+
+       cbBarSpy( wxFrameLayout* pPanel );
+
+       void SetBarWindow( wxWindow* pWnd );
+
+       // overriden
+
+       virtual bool ProcessEvent(wxEvent& event);
+};
+
+/* wxFrameLayout manages containment and docking of control bars. 
+ * which can be docked along top, bottom, righ, or left side of the 
+ * parent frame
+ */
+
+class wxFrameLayout : public wxEvtHandler
+{
+public:
+       wxFrameLayout(void); // used only while serializing
+
+       wxFrameLayout( wxWindow* pParentFrame, 
+                                  wxWindow* pFrameClient = NULL, 
+                                  bool      activateNow  = TRUE );
+
+       // (doesn't destroy bar windows)
+       virtual ~wxFrameLayout();
+
+       // (by default floating of control-bars is ON)
+       virtual void EnableFloating( bool enable = TRUE );
+
+       // Can be called after some other layout has been deactivated,
+       // and this one must "take over" the current contents of frame window.
+       //
+       // Effectively hooks itself to the frame window, re-displays all not-hidden 
+       // bar-windows and repaints decorations
+
+       virtual void Activate();
+
+       // unhooks itself from frame window, and hides all not-hidden windows
+       //
+       // NOTE:: two frame-layouts should not be active at the same time in the
+       //        same frame window, it would cause messy overlapping of bar windows 
+       //        from both layouts
+
+       virtual void Deactivate();
+
+       // also hides the client window if presents
+
+       void HideBarWindows();
+
+       virtual void DestroyBarWindows();
+
+       // passes the client window (e.g. MDI-client frame) to be controled by
+       // frame layout, the size and position of which should be adjusted to be 
+       // surrounded by controlbar panes, whenever frame is resized, or dimensions 
+       // of control panes change
+
+       void SetFrameClient( wxWindow* pFrameClient );
+
+       wxWindow* GetFrameClient();
+
+       wxWindow& GetParentFrame() { return *mpFrame; }
+
+       // used by updates-managers
+       cbDockPane** GetPanesArray() { return mPanes; }
+
+       // see pane alignment types 
+       cbDockPane* GetPane( int alignment )
+
+               { return mPanes[alignment]; }
+
+       // Adds bar information to frame-layout, appearence of layout is not refreshed
+       // immediately, RefreshNow() can be called if necessary.
+       //
+       // NOTES:: argument pBarWnd can by NULL, resulting bar decorations to be drawn
+       //         around the empty rectangle (filled with default background colour).
+       //         Argument dimInfo, can be re-used for adding any number of bars, since
+       //         it is not used directly, instead it's members are copied. If dimensions- 
+       //         handler is present, it's instance shared (reference counted). Dimension 
+       //         handler should always be allocated on the heap!)
+
+       virtual void AddBar( wxWindow*        pBarWnd, 
+                         const cbDimInfo&       dimInfo,
+
+                                                // defaults:
+                                                int alignment    = FL_ALIGN_TOP,
+                                                int rowNo        = 0,      // vert. position - row in the pane (if docked state)
+                                                int columnPos    = 0,      // horiz. position in the row in pixels (if docked state)
+                                                const wxString& name="bar",// name, by which the bar could be referred
+                                                                           // in layout customization dialogs
+
+                                                bool spyEvents    = FALSE,     // if TRUE - input events for the bar should 
+                                                                                                       // be "spyed" in order to forward not-handled 
+                                                                                                       // mouse clicks to frame layout (e.g. to enable 
+                                                                                                       // easy-draggablity of toolbars just by clicking 
+                                                                                                       // on their interior regions). For widgets like 
+                                                                                                       // text/tree control this value should be FALSE 
+                                                                                                       // (since there's _no_ certain way to detect 
+                                                                                                       //  whether the event was actually handled...)
+
+                                                int state        = wxCBAR_DOCKED_HORIZONTALLY // e.g. wxCBAR_FLOATING
+                                                                                                                                          // or wxCBAR_HIDDEN
+                                          );
+
+       // can be used for repositioning already existing bars. The given bar is first removed
+       // from the pane it currently belongs to, and inserted into the pane, which "matches"
+       // the given recantular area. If pToPane is not NULL, bar is docked to this given pane
+       
+       // to dock the bar which is floated, use wxFrameLayout::DockBar(..) method
+
+       virtual bool RedockBar( cbBarInfo* pBar, const wxRect& shapeInParent, 
+                                                       cbDockPane* pToPane = NULL, bool updateNow = TRUE );
+
+       // methods for access and modification of bars in frame layout
+
+       cbBarInfo* FindBarByName( const wxString& name );
+
+       cbBarInfo* FindBarByWindow( const wxWindow* pWnd );
+
+       BarArrayT& GetBars();
+
+       // changes bar's docking state (see possible control bar states)
+
+       void SetBarState( cbBarInfo* pBar, int newStatem, bool updateNow );
+
+       void InverseVisibility( cbBarInfo* pBar );
+
+       // reflects changes in bar information structure visually
+       // (e.g. moves bar, changes it's dimension info, pane to which it is docked)
+
+       void ApplyBarProperties( cbBarInfo* pBar );
+
+       // removes bar from layout permanently, hides it's corresponding window if present
+
+       void RemoveBar( cbBarInfo* pBar );
+
+       // recalcualtes layout of panes, and all bars/rows in each pane
+
+       virtual void RecalcLayout( bool repositionBarsNow = FALSE );
+
+       int     GetClientHeight();
+       int     GetClientWidth();
+       wxRect& GetClientRect()         { return mClntWndBounds;     }
+
+       // NOTE:: in future ubdates-manager will become a normal plugin
+       
+       cbUpdatesManagerBase& GetUpdatesManager();
+       
+       // destroys the previous manager if any, set the new one
+
+       void SetUpdatesManager( cbUpdatesManagerBase* pUMgr );
+
+       // NOTE:: changing properties of panes, does not result immediate on-screen update
+
+       virtual void GetPaneProperties( cbCommonPaneProperties& props, int alignment = FL_ALIGN_TOP );
+
+       virtual void SetPaneProperties( const cbCommonPaneProperties& props, 
+                                           int paneMask = wxALL_PANES );
+
+       // TODO:: margins should go into cbCommonPaneProperties in the future
+       //
+       // NOTE:: this method should be called before any custom plugins are attached
+
+       virtual void SetMargins( int top, int bottom, int left, int right,
+                                    int paneMask = wxALL_PANES );
+
+       virtual void SetPaneBackground( const wxColour& colour );
+
+       // recalculates layoute and performs on-screen update of all panes
+
+       void RefreshNow( bool recalcLayout = TRUE );
+
+       // event handlers
+
+       void OnSize       ( wxSizeEvent&  event );
+       void OnLButtonDown( wxMouseEvent& event );
+       void OnLDblClick  ( wxMouseEvent& event );
+       void OnLButtonUp  ( wxMouseEvent& event );
+       void OnRButtonDown( wxMouseEvent& event );
+       void OnRButtonUp  ( wxMouseEvent& event );
+       void OnMouseMove  ( wxMouseEvent& event );
+
+       /*** plugin-related methods ***/
+
+       // should be used, instead of passing the event to ProcessEvent(..) method
+       // of the top-plugin directly. This method checks if events are currently 
+       // captured and ensures that plugin-event is routed correctly.
+
+       virtual void FirePluginEvent( cbPluginEvent& event );
+       
+       // captures/releases user-input event's for the given plugin
+       // Input events are: mouse movement, mouse clicks, keyboard input
+
+       virtual void CaptureEventsForPlugin ( cbPluginBase* pPlugin );
+       virtual void ReleaseEventsFromPlugin( cbPluginBase* pPlugin );
+
+       // called by plugins ( also captures/releases mouse in parent frame)
+       void CaptureEventsForPane( cbDockPane* toPane );
+       void ReleaseEventsFromPane( cbDockPane* fromPane );
+
+       // returns current top-level plugin (the one which receives events first,
+       // with an exception if input-events are currently captured by some other plugin)
+       
+       virtual cbPluginBase& GetTopPlugin();
+
+       // hooking custom plugins to frame layout
+       //
+       // NOTE:: when hooking one plugin on top of the other -
+       //        use SetNextHandler(..) or similar methods
+       //                of wxEvtHandler class to compose the chain of plugins,
+       //        than pass the left-most handler in this chain to
+       //        the above methods (assuming that events are delegated
+       //        from left-most towards right-most handler)
+       //
+       //        NOTE2:: this secenario is very inconvenient and "low-level",
+       //                use Add/Push/PopPlugin methods instead
+
+       virtual void SetTopPlugin( cbPluginBase* pPlugin );
+
+       // similar to wxWindow's "push/pop-event-handler" methods, execept
+       // that plugin is *deleted* upon "popping"
+
+       virtual void PushPlugin( cbPluginBase* pPugin );
+       virtual void PopPlugin();
+
+       virtual void PopAllPlugins();
+
+       // default plugins are : cbPaneDrawPlugin, cbRowLayoutPlugin, cbBarDragPlugin,
+       //                                               cbAntiflickerPlugin, cbSimpleCustomizePlugin
+       //
+       // this method is automatically invoked, if no plugins were found upon 
+       // fireing of the first plugin-event, i.e. wxFrameLayout *CONFIGURES* itself
+
+       virtual void PushDefaultPlugins();
+
+       /* "Advanced" methods for plugin-configuration  using their */
+       /* dynamic class information (e.g. CLASSINFO(pluginClass) ) */
+
+       // first checks if plugin of the given class is already "hooked up", 
+       // if not, adds it to the top of plugins chain
+
+       virtual void AddPlugin( wxClassInfo* pPlInfo, int paneMask = wxALL_PANES );
+
+       // first checks if plugin of the givne class already hooked,
+       // if so, removes it, and then inserts it to the chain
+       // before plugin of the class given by "pNextPlInfo"
+       //
+       // NOTE:: this method is "handy" in some cases, where the order
+       //        of plugin-chain could be important, e.g. one plugin overrides
+       //        some functionallity of the other already hooked plugin,
+       //        thefore the former should be hooked before the one
+       //        who's functionality is being overriden
+
+       virtual void AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, 
+                                                                 int paneMask = wxALL_PANES );
+
+       // checks if plugin of the given class is hooked, removes
+       // it if found
+       //
+       // @param pPlInfo class information structure for the plugin
+       // @note  
+       // @see wxFrameLayout::Method
+
+
+       virtual void RemovePlugin( wxClassInfo* pPlInfo );
+
+       // returns NULL, if plugin of the given class is not hooked
+
+       virtual cbPluginBase* FindPlugin( wxClassInfo* pPlInfo );
+
+       bool HasTopPlugin();
+
+       DECLARE_EVENT_TABLE()
+       DECLARE_DYNAMIC_CLASS( wxFrameLayout )
+
+public: /* protected really, acessed only by plugins and serializers */
+
+       friend class cbDockPane;
+       friend class wxBarHandler;
+
+       wxWindow*    mpFrame;           // parent frame
+       wxWindow*    mpFrameClient;         // client window
+       cbDockPane*  mPanes[MAX_PANES]; // panes in the panel
+
+       // misc. cursors
+       wxCursor*    mpHorizCursor;
+       wxCursor*    mpVertCursor;
+       wxCursor*    mpNormalCursor;
+       wxCursor*    mpDragCursor;
+       wxCursor*    mpNECursor; // no-entry cursor
+
+       // pens for decoration and shades
+
+       wxPen        mDarkPen;   // default wxSYS_COLOUR_3DSHADOW
+       wxPen        mLightPen;  // default wxSYS_COLOUR_3DHILIGHT
+       wxPen        mGrayPen;   // default wxSYS_COLOUR_3DFACE
+       wxPen        mBlackPen;  // default wxColour(  0,  0,  0)
+       wxPen        mBorderPen; // default wxSYS_COLOUR_3DFACE
+
+       wxPen        mNullPen;   // transparent pen
+
+       // pane to which the all mouse input is currently directed (caputred)
+
+       cbDockPane*  mpPaneInFocus;
+
+       // pane, from which mouse pointer had just left
+
+       cbDockPane*  mpLRUPane;    
+
+       // bounds of client window in parent frame's coordinates
+
+       wxRect       mClntWndBounds;
+       wxRect       mPrevClntWndBounds;
+
+       bool         mFloatingOn;
+       wxPoint      mNextFloatedWndPos;
+       wxSize       mFloatingPosStep;
+
+       // current plugin (right-most) plugin which receives events first
+
+       cbPluginBase* mpTopPlugin;
+
+       // plugin, which currently has captured all input events, otherwise NULL 
+
+       cbPluginBase* mpCaputesInput;
+
+       // list of event handlers which are "pushed" onto each bar, to catch 
+       // mouse events which are not handled by bars, and froward them to the ,
+       // frome-layout and further to plugins
+
+       wxList        mBarSpyList;
+
+       // list of top-most frames which contain floated bars
+
+       wxList        mFloatedFrames;
+
+       // linked list of references to all bars (docked/floated/hidden)
+
+       BarArrayT    mAllBars;
+
+       // FOR NOW:: dirty stuff...
+       bool         mClientWndRefreshPending;
+       bool         mRecalcPending;
+       bool         mCheckFocusWhenIdle;
+
+public: /* protected really (accessed only by plugins) */
+
+       // refrence to custom updates manager 
+       cbUpdatesManagerBase* mpUpdatesMgr;
+
+       // called to set calculated layout to window objects
+       void PositionClientWindow();
+       void PositionPanes();
+       void CreateCursors();
+
+       void RepositionFloatedBar( cbBarInfo* pBar );
+       void DoSetBarState( cbBarInfo* pBar );
+
+       bool LocateBar( cbBarInfo* pBarInfo, 
+                                       cbRowInfo**  ppRow,
+                                       cbDockPane** ppPane );
+
+
+       bool HitTestPane( cbDockPane* pPane, int x, int y );
+       cbDockPane* HitTestPanes( const wxRect& rect, cbDockPane* pCurPane );
+
+       // returns panes, to which the given bar belongs
+
+       cbDockPane* GetBarPane( cbBarInfo* pBar );
+
+       // delegated from "bar-spy"
+       void ForwardMouseEvent( wxMouseEvent& event, 
+                                                       cbDockPane*   pToPane,
+                                                       int           eventType );
+
+       void RouteMouseEvent( wxMouseEvent& event, int pluginEvtType );
+
+       void ShowFloatedWindows( bool show );
+
+       void UnhookFromFrame();
+       void HookUpToFrame();
+
+       // NOTE:: reparenting of windows may NOT work on all platforms
+       //        (reparenting allows control-bars to be floated)
+
+       bool CanReparent();
+       void ReparentWindow( wxWindow* pChild, wxWindow* pNewParent );
+
+       wxRect& GetPrevClientRect() { return mPrevClntWndBounds; }
+
+       void OnPaint( wxPaintEvent& event );
+       void OnEraseBackground( wxEraseEvent& event );
+       void OnKillFocus( wxFocusEvent& event );
+       void OnSetFocus( wxFocusEvent& event );
+       void OnActivate( wxActivateEvent& event );
+       void OnIdle( wxIdleEvent& event );
+
+       // factory method
+       virtual cbUpdatesManagerBase* CreateUpdatesManager();
+};
+
+/* structure, which is present in each item of layout,
+ * it used by any specific updates-manager to store
+ * auxilary information to be used by it's specific 
+ * updating algorithm 
+ */
+
+class cbUpdateMgrData : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbUpdateMgrData )
+public:
+       wxRect mPrevBounds;      // previous state of layout item (in parent frame's coordinates)
+
+       bool   mIsDirty;         // overrides result of current-against-previous bounds comparison,
+                                // i.e. requires item to be updated, regardless of it's current area
+       
+       wxObject*  mpCustomData; // any custom data stored by specific updates mgr.
+
+       cbUpdateMgrData();   // is-dirty flag is set TRUE initially
+
+       void StoreItemState( const wxRect& boundsInParent );
+
+       void SetDirty( bool isDirty = TRUE );
+
+       void SetCustomData( wxObject* pCustomData );
+
+       inline bool IsDirty() { return mIsDirty; }
+};
+
+/* Abstract interface for bar-size handler classes.
+ * These objects receive notifications, whenever the docking 
+ * state of the bar is changed, thus they have a possibility 
+ * to adjust the values in cbDimInfo::mSizes accordingly.
+ * Specific handlers can be hooked to specific types of bars.
+ */
+
+class cbBarDimHandlerBase : public wxObject
+{
+       DECLARE_ABSTRACT_CLASS( cbBarDimHandlerBase )
+
+public:
+       int mRefCount; // since one dim-handler can be assigned
+                      // to multiple bars, it's instance is
+                                  // reference-counted
+public:
+
+       // initial reference count is 0, since handler is not used, until the
+       // first invocation of AddRef()
+
+       cbBarDimHandlerBase();
+
+       void AddRef();
+       void RemoveRef();
+
+       // "bar-state-changes" notification
+       virtual void OnChangeBarState(cbBarInfo* pBar, int newState ) = 0;
+       virtual void OnResizeBar( cbBarInfo* pBar, const wxSize& given, wxSize& preferred ) = 0;
+};
+
+/* helper classes (used internally by wxFrameLayout class) */
+
+// holds and manages information about bar dimensions
+
+class cbDimInfo : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbDimInfo )
+public:
+       wxSize mSizes[MAX_BAR_STATES];  // preferred sizes for each possible bar state
+
+       wxRect mBounds[MAX_BAR_STATES]; // saved positions and sizes for each
+                                                                       // possible state, values contain (-1)s if
+                                                                   // not initialized yet
+
+       int    mLRUPane; // pane to which this bar was docked before it was floated
+                        // (FL_ALIGN_TOP,FL_ALIGN_BOTTOM,..)
+
+       // top/bottom gap, separates decorations
+       // from the bar's actual window, filled
+       // with frame's beckground color, default: 0
+
+       int    mVertGap;        
+
+       // left/right gap, separates decorations
+       // from the bar's actual window, filled
+       // with frame's beckground colour, default: 0
+
+       int    mHorizGap;       // NOTE:: gaps are given in frame's coord. orientation
+
+       // TRUE, if vertical/horizotal dimensions cannot be mannualy adjusted
+       //       by user using resizing handles. If FALSE, the frame-layout
+       //       *automatically* places resizing handles among not-fixed bars
+
+       bool   mIsFixed;
+
+       cbBarDimHandlerBase* mpHandler; // NULL, if no handler present 
+
+public:
+
+       cbDimInfo(void);
+
+       cbDimInfo( cbBarDimHandlerBase* pDimHandler,
+                          bool                 isFixed          // (see comments on mIsFixed member)
+                        );
+
+       cbDimInfo( int dh_x, int dh_y, // dims when docked horizontally
+                          int dv_x, int dv_y, // dims when docked vertically
+                          int f_x,  int f_y,  // dims when floating
+
+                          bool isFixed  = TRUE,// (see comments on mIsFixed member)
+                          int  horizGap = 6,   // (see comments on mHorizGap member)
+                          int  vertGap  = 6,   // -/-
+
+                          cbBarDimHandlerBase* pDimHandler = NULL
+                        );
+
+    cbDimInfo( int x, int y,  
+               bool isFixed  = TRUE, 
+               int  gap = 6, 
+               cbBarDimHandlerBase* pDimHandler = NULL
+             ); 
+
+       const cbDimInfo& operator=( const cbDimInfo& other );
+
+       // destroys handler automatically, if present
+       ~cbDimInfo();
+
+       inline cbBarDimHandlerBase* GetDimHandler() { return mpHandler; } 
+};
+
+WX_DEFINE_ARRAY(float, cbArrayFloat);
+
+class cbRowInfo : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbRowInfo )
+public:
+
+       BarArrayT  mBars;  // row content
+
+       // row flags (set up according to row-relations)
+
+       bool    mHasUpperHandle;
+       bool    mHasLowerHandle;
+       bool    mHasOnlyFixedBars;
+       int     mNotFixedBarsCnt;
+
+       int             mRowWidth;
+       int             mRowHeight;
+       int             mRowY;
+
+       // stores precalculated row's bounds in parent frame's coordinates
+       wxRect mBoundsInParent;
+
+       // info stored for updates-manager
+       cbUpdateMgrData mUMgrData;
+
+       cbRowInfo*    mpNext;
+       cbRowInfo*    mpPrev;
+
+       cbBarInfo*    mpExpandedBar; // NULL, if non of the bars is currently expanded
+
+       cbArrayFloat  mSavedRatios;  // length-ratios bofore some of the bars was expanded
+
+public:
+       cbRowInfo(void);
+
+       ~cbRowInfo();
+
+       // convenience method
+
+       inline cbBarInfo* GetFirstBar() 
+
+               { return mBars.GetCount() ? mBars[0] : NULL; }
+};
+
+class cbBarInfo : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbBarInfo )
+public:
+       // textual name, by which this bar is refered in layout-customization dialogs
+       wxString      mName;
+
+       // stores bar's bounds in pane's coordinates
+       wxRect        mBounds;             
+
+       // stores precalculated bar's bounds in parent frame's coordinates
+       wxRect        mBoundsInParent;     
+
+       // back-ref to the row, which contains this bar
+       cbRowInfo*    mpRow;               
+
+       // are set up according to the types of the surrounding bars in the row
+       bool          mHasLeftHandle;
+       bool          mHasRightHandle;
+
+       cbDimInfo     mDimInfo;       // preferred sizes for each, control bar state
+                                                                 
+       int           mState;         // (see definition of controlbar states)
+
+       int           mAlignment;     // alignment of the pane to which this
+                                     // bar is currently placed
+
+       int           mRowNo;         // row, into which this bar would be placed,
+                                     // when in the docking state
+
+       wxWindow*     mpBarWnd;           // the actual window object, NULL if no window
+                                     // is attached to the control bar (possible!)
+
+       double        mLenRatio;      // length ratio among not-fixed-size bars
+
+       wxPoint       mPosIfFloated;  // stored last position when bar was in "floated" state
+                                                                 // poistion is stored in parent-window's coordinates
+       
+       cbUpdateMgrData mUMgrData;    // info stored for updates-manager
+
+       cbBarInfo*    mpNext;         // next. bar in the row
+       cbBarInfo*    mpPrev;         // prev. bar in the row
+
+public:
+       cbBarInfo(void);
+
+       ~cbBarInfo();
+
+       inline bool IsFixed() const { return mDimInfo.mIsFixed; }
+
+       inline bool IsExpanded() const { return this == mpRow->mpExpandedBar; }
+};
+
+// used for storing original bar's postions in the row, when the "non-destructive-friction"
+// option is turned ON
+
+class cbBarShapeData : public wxObject
+{
+public:
+       wxRect mBounds;
+       double mLenRatio;
+};
+
+// used for traversing through all bars of all rows in the pane
+
+class wxBarIterator
+{
+       RowArrayT*  mpRows;
+       cbRowInfo*  mpRow;
+       cbBarInfo*  mpBar;
+
+public:
+       wxBarIterator( RowArrayT& rows );
+
+       void Reset();
+       bool Next(); // TRUE, if next bar is available
+       
+       cbBarInfo& BarInfo();
+
+       // returns reference to currently traversed row
+       cbRowInfo& RowInfo();
+};
+
+/* structure holds configuration options, 
+ * which are usually the same for all panes in
+ * frame layout
+ */
+
+class cbCommonPaneProperties : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbCommonPaneProperties )
+
+       // look-and-feel configuration
+
+       bool mRealTimeUpdatesOn;     // default: ON
+       bool mOutOfPaneDragOn;       // default: ON
+       bool mExactDockPredictionOn; // default: OFF
+       bool mNonDestructFirctionOn; // default: OFF
+
+       bool mShow3DPaneBorderOn;    // default: ON
+
+       // FOR NOW:: the below properties are reserved for the "future"
+
+       bool mBarFloatingOn;         // default: OFF
+       bool mRowProportionsOn;      // default: OFF
+       bool mColProportionsOn;      // default: ON
+       bool mBarCollapseIconsOn;    // default: OFF
+       bool mBarDragHintsOn;        // default: OFF
+
+       // minimal dimensions for not-fixed bars in this pane (16x16 default)
+
+       wxSize mMinCBarDim; 
+
+       // width/height of resizing sash
+       
+       int    mResizeHandleSize;
+
+       cbCommonPaneProperties(void);
+};
+
+/* class manages containment and control of control-bars 
+ * along one of the four edges of the parent frame
+ */
+
+class cbDockPane : public wxObject
+{
+public:
+       DECLARE_DYNAMIC_CLASS( cbDockPane )
+
+       // look-and-feel configuration for this pane
+       cbCommonPaneProperties mProps;
+
+       // pane margins (in frame's coordinate-syst. orientation)
+
+       int             mLeftMargin;     // default: 2 pixels
+       int             mRightMargin;    // default: 2 pixels
+       int             mTopMargin;              // default: 2 pixels
+       int             mBottomMargin;   // default: 2 pixels
+                                  
+public:
+       // position of the pane in frame's coordinates
+       wxRect          mBoundsInParent; 
+
+       // pane width and height in pane's coordinates
+       int             mPaneWidth;
+       int             mPaneHeight;
+
+       int                             mAlignment;
+
+       // info stored for updates-manager
+       cbUpdateMgrData mUMgrData;
+
+public: /* protected really */
+
+       RowArrayT           mRows;
+       wxFrameLayout*  mpLayout;                // back-ref
+
+       // transient properties
+
+       wxList          mRowShapeData;   // shapes of bars of recently modified row, 
+                                                                    // stored when in "non-destructive-firction" mode
+       cbRowInfo*      mpStoredRow;     // row-info for which the shapes are stored
+
+       friend class wxFrameLayout;
+
+public: /* protected really (accessed only by plugins) */
+
+       cbRowInfo* GetRow( int row );
+
+       int GetRowIndex( cbRowInfo* pRow );
+
+       // return -1, if row is not present at given vertical position
+       int     GetRowAt( int paneY );
+       int     GetRowAt( int upperY, int lowerY );
+
+       // re-setups flags in the row-information structure, so that 
+       // the would match the changed state of row-items correctly 
+       void SyncRowFlags( cbRowInfo* pRow );
+
+       // layout "AI" helpers:
+
+       bool IsFixedSize( cbBarInfo* pInfo );
+       int  GetNotFixedBarsCount( cbRowInfo* pRow );
+
+       int GetRowWidth( wxList* pRow );
+
+       int GetRowY( cbRowInfo* pRow );
+
+       bool HasNotFixedRowsAbove( cbRowInfo* pRow );
+       bool HasNotFixedRowsBelow( cbRowInfo* pRow );
+       bool HasNotFixedBarsLeft ( cbBarInfo* pBar );
+       bool HasNotFixedBarsRight( cbBarInfo* pBar );
+
+       virtual void CalcLengthRatios( cbRowInfo* pInRow );
+       virtual void RecalcRowLayout( cbRowInfo* pRow );
+
+       virtual void ExpandBar( cbBarInfo* pBar );
+       virtual void ContractBar( cbBarInfo* pBar );
+
+       void InitLinksForRow( cbRowInfo* pRow );
+       void InitLinksForRows();
+
+       // coordinate translation between parent's frame and this pane 
+
+       void FrameToPane( int* x, int* y );
+       void PaneToFrame( int* x, int* y );
+       void FrameToPane( wxRect* pRect );
+       void PaneToFrame( wxRect* pRect );
+
+       inline bool HasPoint( const wxPoint& pos, int x, int y, int width, int height );
+
+       int GetMinimalRowHeight( cbRowInfo* pRow );
+
+       // given row height includes height of row handles, if present
+       void SetRowHeight( cbRowInfo* pRow, int newHeight );
+
+       void DoInsertBar( cbBarInfo* pBar, int rowNo );
+
+public: /* protected really (accessed only by plugins) */
+
+       // methods for incramental on-screen refreshing of the pane 
+       // (simply, they are wrappers around corresponding plugin-events)
+
+       virtual void PaintBarDecorations( cbBarInfo* pBar, wxDC& dc );
+       virtual void PaintBarHandles( cbBarInfo* pBar, wxDC& dc );
+       virtual void PaintBar( cbBarInfo* pBar, wxDC& dc );
+       virtual void PaintRowHandles( cbRowInfo* pRow, wxDC& dc );
+       virtual void PaintRowBackground ( cbRowInfo* pRow, wxDC& dc );
+       virtual void PaintRowDecorations( cbRowInfo* pRow, wxDC& dc );
+       virtual void PaintRow( cbRowInfo* pRow, wxDC& dc );
+       virtual void PaintPaneBackground( wxDC& dc );
+       virtual void PaintPaneDecorations( wxDC& dc );
+       virtual void PaintPane( wxDC& dc );
+       virtual void SizeBar( cbBarInfo* pBar );
+       virtual void SizeRowObjects( cbRowInfo* pRow );
+       virtual void SizePaneObjects();
+
+       virtual wxDC* StartDrawInArea ( const wxRect& area );
+       virtual void  FinishDrawInArea( const wxRect& area );
+
+public: /* public members */
+
+       cbDockPane(void);
+
+       cbDockPane( int alignment, wxFrameLayout* pPanel );
+
+       // sets pane's margins in frame's coordinate orientations
+       void SetMargins( int top, int bottom, int left, int right );
+
+       virtual ~cbDockPane();
+
+       // does not destroys the info bar , only removes it's reference
+       // from this pane
+
+       virtual void RemoveBar( cbBarInfo* pBar );
+
+       // rect given in the parent frame's coordinates
+       
+       virtual void InsertBar( cbBarInfo* pBar, const wxRect& atRect );
+
+       // inserts bar into the given row, with dimensions and position
+       // stored in pBarInfo->mBounds. Returns the node of inserted bar
+
+       virtual void InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow );
+
+       // inserts bar, sets its position according to the preferred settings 
+       // given in (*pBarInfo) structure
+
+       virtual void InsertBar( cbBarInfo* pBarInfo );
+
+       // does not destroy the row object, only removes the corresponding
+       // node from this pane
+       virtual void RemoveRow( cbRowInfo* pRow );
+       
+       // does not refresh the inserted row immediately,
+       // if pBeforeRowNode arg. is NULL, row is appended to the end of pane's row list
+       virtual void InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow );
+
+       // sets pane's width in pane's coordinates (including margins)
+       void SetPaneWidth(int width);
+
+       // set the position and dims. of the pane in parent frame's coordinates
+       void SetBoundsInParent( const wxRect& rect );
+
+       inline wxRect& GetRealRect() { return mBoundsInParent; }
+
+       // used by updates-managers
+       inline RowArrayT& GetRowList() { return mRows; }
+
+       // convenience method
+
+       inline cbRowInfo* GetFirstRow() 
+       
+               { return mRows.GetCount() ? mRows[0] : NULL; }
+
+       // TRUE, if the given bar node presents in this pane
+
+       bool BarPresent( cbBarInfo* pBar );
+
+       // retuns height, in pane's coordinates
+       int GetPaneHeight();
+
+       int GetAlignment();
+
+       bool MatchesMask( int paneMask );
+
+       inline bool IsHorizontal()
+       {
+               return (mAlignment == FL_ALIGN_TOP ||
+                           mAlignment == FL_ALIGN_BOTTOM );
+       }
+
+       virtual void RecalcLayout();
+
+       virtual int GetDockingState();
+
+       // returns result of hit-testing items in the pane,
+       // see CB_HITTEST_RESULTS enumeration
+
+       virtual int HitTestPaneItems( const wxPoint& pos,   // position in pane's coordinates
+                                                                 cbRowInfo**    ppRow,
+                                                                 cbBarInfo**    ppBar
+                                                               );
+
+       void GetBarResizeRange( cbBarInfo* pBar, int* from, int *till, bool forLeftHandle );
+       void GetRowResizeRange( cbRowInfo* pRow, int* from, int* till, bool forUpperHandle );
+
+       cbBarInfo* GetBarInfoByWindow( wxWindow* pBarWnd );
+
+public: /* protected really (accessed only by plugins) */
+
+       // row/bar resizing related helper-methods
+
+       void DrawVertHandle ( wxDC& dc, int x, int y, int height );
+       void DrawHorizHandle( wxDC& dc, int x, int y, int width  );
+
+       void ResizeRow( cbRowInfo* pRow, int ofs, bool forUpperHandle );
+       void ResizeBar( cbBarInfo* pBar, int ofs, bool forLeftHandle );
+
+       // cbBarShapeData objects will be placed to given pLst (see comments on cbBarShapeData)
+
+       void GetRowShapeData( cbRowInfo* pRow, wxList* pLst );
+
+       // sets the shape to the given row, using the data provided in pLst
+       void SetRowShapeData( cbRowInfo* pRowNode, wxList* pLst );
+};
+
+/*
+ * class declares abstract interface for optimized logic, which should refresh
+ * areas of frame layout - that actually need to be updated. Should be extended,
+ * to implement custom updating strategy
+ */
+
+class cbUpdatesManagerBase : public wxObject
+{
+       DECLARE_ABSTRACT_CLASS( cbUpdatesManagerBase )
+
+public: /* protected really, accessed by serializer (if any) */
+
+       wxFrameLayout* mpLayout;
+
+public:
+       cbUpdatesManagerBase(void)
+               : mpLayout( 0 ) {}
+
+       cbUpdatesManagerBase( wxFrameLayout* pPanel )
+               : mpLayout( pPanel ) {}
+
+       void SetLayout( wxFrameLayout* pLayout ) { mpLayout = pLayout; }
+
+       // notificiactions received from frame-layout (in the order, in which
+       // they usually would be invoked). Custom updates-managers may utilize
+       // these notifications to implement more "fine-grained" updating strategy
+
+       virtual void OnStartChanges() = 0;
+
+       virtual void OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane ) {}
+       virtual void OnBarWillChange( cbBarInfo* pBar, cbRowInfo* pInRow, cbDockPane* pInPane ) {}
+       virtual void OnPaneMarginsWillChange( cbDockPane* pPane ) {}
+       virtual void OnPaneWillChange( cbDockPane* pPane ) {}
+
+       virtual void OnFinishChanges() {}
+
+       // refreshes parts of the frame layout, which need an update
+       virtual void UpdateNow() = 0;
+};
+
+/*------------------------------------------------------------
+ * "API" for developing custom plugins of Frame Layout Engine
+ * TODO:: documentation
+ *------------------------------------------------------------
+ */
+
+// base class for all control-bar plugin events
+
+class cbPluginEvent : public wxEvent
+{
+       // NOTE:: plugin-event does not need to be a dynamic class
+
+public:
+       cbDockPane* mpPane; // NULL, if event is not addressed to any specific pane
+
+       /* OLD STUFF::
+       // FOR NOW FOR NOW:: all-in-one plugin event structure 
+       wxNode* mpObjNode;
+       wxNode* mpObjNodeAux;
+       wxPoint mPos;
+       wxSize  mSize;
+       wxDC*   mpDC;
+       bool    mAuxBoolVal;
+       */
+
+#if wxCHECK_VERSION(2,3,0)
+       cbPluginEvent( wxEventType eventType, cbDockPane* pPane )
+               : mpPane( pPane )
+                 
+               { m_eventType = eventType; }
+#else
+       cbPluginEvent( int eventType, cbDockPane* pPane )
+               : mpPane( pPane )
+                 
+               { m_eventType = eventType; }
+#endif
+};
+
+// event types handled by plugins
+
+#if wxCHECK_VERSION(2,3,0)
+
+       extern wxEventType cbEVT_PL_LEFT_DOWN;
+       extern wxEventType cbEVT_PL_LEFT_UP;
+       extern wxEventType cbEVT_PL_RIGHT_DOWN;
+       extern wxEventType cbEVT_PL_RIGHT_UP;
+       extern wxEventType cbEVT_PL_MOTION;
+
+       extern wxEventType cbEVT_PL_LEFT_DCLICK;
+
+       extern wxEventType cbEVT_PL_LAYOUT_ROW;
+       extern wxEventType cbEVT_PL_RESIZE_ROW;
+       extern wxEventType cbEVT_PL_LAYOUT_ROWS;
+       extern wxEventType cbEVT_PL_INSERT_BAR;
+       extern wxEventType cbEVT_PL_RESIZE_BAR;
+       extern wxEventType cbEVT_PL_REMOVE_BAR;
+       extern wxEventType cbEVT_PL_SIZE_BAR_WND;
+
+       extern wxEventType cbEVT_PL_DRAW_BAR_DECOR;
+       extern wxEventType cbEVT_PL_DRAW_ROW_DECOR;
+       extern wxEventType cbEVT_PL_DRAW_PANE_DECOR;
+       extern wxEventType cbEVT_PL_DRAW_BAR_HANDLES;
+       extern wxEventType cbEVT_PL_DRAW_ROW_HANDLES;
+       extern wxEventType cbEVT_PL_DRAW_ROW_BKGROUND;
+       extern wxEventType cbEVT_PL_DRAW_PANE_BKGROUND;
+
+       extern wxEventType cbEVT_PL_START_BAR_DRAGGING;
+       extern wxEventType cbEVT_PL_DRAW_HINT_RECT;
+
+       extern wxEventType cbEVT_PL_START_DRAW_IN_AREA;
+       extern wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA;
+
+       extern wxEventType cbEVT_PL_CUSTOMIZE_BAR;
+       extern wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT;
+
+       extern wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT;
+
+#else
+
+       #define cbEVT_PL_LEFT_DOWN           0
+       #define cbEVT_PL_LEFT_UP                 1
+       #define cbEVT_PL_RIGHT_DOWN          2
+       #define cbEVT_PL_RIGHT_UP                3
+       #define cbEVT_PL_MOTION              4
+
+       #define cbEVT_PL_LEFT_DCLICK         5
+
+       #define cbEVT_PL_LAYOUT_ROW          6 
+       #define cbEVT_PL_RESIZE_ROW          7
+       #define cbEVT_PL_LAYOUT_ROWS         8
+       #define cbEVT_PL_INSERT_BAR          9
+       #define cbEVT_PL_RESIZE_BAR          10
+       #define cbEVT_PL_REMOVE_BAR          11
+       #define cbEVT_PL_SIZE_BAR_WND        12
+
+       #define cbEVT_PL_DRAW_BAR_DECOR      13
+       #define cbEVT_PL_DRAW_ROW_DECOR      14
+       #define cbEVT_PL_DRAW_PANE_DECOR     15
+       #define cbEVT_PL_DRAW_BAR_HANDLES    16
+       #define cbEVT_PL_DRAW_ROW_HANDLES    17
+       #define cbEVT_PL_DRAW_ROW_BKGROUND   18
+       #define cbEVT_PL_DRAW_PANE_BKGROUND  19
+
+       #define cbEVT_PL_START_BAR_DRAGGING  20
+       #define cbEVT_PL_DRAW_HINT_RECT      21
+
+       #define cbEVT_PL_START_DRAW_IN_AREA  22
+       #define cbEVT_PL_FINISH_DRAW_IN_AREA 23
+
+       #define cbEVT_PL_CUSTOMIZE_BAR       24
+       #define cbEVT_PL_CUSTOMIZE_LAYOUT    25
+
+       #define wxCUSTOM_CB_PLUGIN_EVENTS_START_AT 100
+
+#endif // wxCHECK_VERSION(2,3,0) else
+
+// forward decls, separated by categories
+
+class cbLeftDownEvent;
+class cbLeftUpEvent;
+class cbRightDownEvent;
+class cbRightUpEvent;
+class cbMotionEvent;
+class cbLeftDClickEvent;
+
+class cbLayoutRowEvent;
+class cbResizeRowEvent;
+class cbLayoutRowsEvent;
+class cbInsertBarEvent;
+class cbResizeBarEvent;
+class cbRemoveBarEvent;
+class cbSizeBarWndEvent;
+
+class cbDrawBarDecorEvent;
+class cbDrawRowDecorEvent;
+class cbDrawPaneDecorEvent;
+class cbDrawBarHandlesEvent;
+class cbDrawRowHandlesEvent;
+class cbDrawRowBkGroundEvent;
+class cbDrawPaneBkGroundEvent;
+
+class cbStartBarDraggingEvent;
+class cbDrawHintRectEvent;
+
+class cbStartDrawInAreaEvent;
+class cbFinishDrawInAreaEvent;
+
+class cbCustomizeBarEvent;
+class cbCustomizeLayoutEvent;
+
+// defs. for handler-methods
+typedef void (wxEvtHandler::*cbLeftDownHandler        )(cbLeftDownEvent&);
+typedef void (wxEvtHandler::*cbLeftUpHandler          )(cbLeftUpEvent&);
+typedef void (wxEvtHandler::*cbRightDownHandler       )(cbRightDownEvent&);
+typedef void (wxEvtHandler::*cbRightUpHandler         )(cbRightUpEvent&);
+typedef void (wxEvtHandler::*cbMotionHandler          )(cbMotionEvent&);
+typedef void (wxEvtHandler::*cbLeftDClickHandler      )(cbLeftDClickEvent&);
+
+typedef void (wxEvtHandler::*cbLayoutRowHandler       )(cbLayoutRowEvent&);
+typedef void (wxEvtHandler::*cbResizeRowHandler       )(cbResizeRowEvent&);
+typedef void (wxEvtHandler::*cbLayoutRowsHandler      )(cbLayoutRowsEvent&);
+typedef void (wxEvtHandler::*cbInsertBarHandler       )(cbInsertBarEvent&);
+typedef void (wxEvtHandler::*cbResizeBarHandler       )(cbResizeBarEvent&);
+typedef void (wxEvtHandler::*cbRemoveBarHandler       )(cbRemoveBarEvent&);
+typedef void (wxEvtHandler::*cbSizeBarWndHandler      )(cbSizeBarWndEvent&);
+
+typedef void (wxEvtHandler::*cbDrawBarDecorHandler    )(cbDrawBarDecorEvent&);
+typedef void (wxEvtHandler::*cbDrawRowDecorHandler    )(cbDrawRowDecorEvent&);
+typedef void (wxEvtHandler::*cbDrawPaneDecorHandler   )(cbDrawPaneDecorEvent&);
+typedef void (wxEvtHandler::*cbDrawBarHandlesHandler  )(cbDrawBarHandlesEvent&);
+typedef void (wxEvtHandler::*cbDrawRowHandlesHandler  )(cbDrawRowHandlesEvent&);
+typedef void (wxEvtHandler::*cbDrawRowBkGroundHandler )(cbDrawRowBkGroundEvent&);
+typedef void (wxEvtHandler::*cbDrawPaneBkGroundHandler)(cbDrawPaneBkGroundEvent&);
+
+typedef void (wxEvtHandler::*cbStartBarDraggingHandler )(cbStartBarDraggingEvent&);
+typedef void (wxEvtHandler::*cbDrawHintRectHandler     )(cbDrawHintRectEvent&);
+
+typedef void (wxEvtHandler::*cbStartDrawInAreaHandler )(cbStartDrawInAreaEvent&);
+typedef void (wxEvtHandler::*cbFinishDrawInAreaHandler)(cbFinishDrawInAreaEvent&);
+
+typedef void (wxEvtHandler::*cbCustomizeBarHandler    )(cbCustomizeBarEvent&);
+typedef void (wxEvtHandler::*cbCustomizeLayoutHandler )(cbCustomizeLayoutEvent&);
+
+// macros for creating event table entries for plugin-events
+
+#if wxCHECK_VERSION(2,3,0)
+       #define EVT_PL_LEFT_DOWN(func)               wxEventTableEntry( cbEVT_PL_LEFT_DOWN,                  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDownHandler        ) & func, (wxObject *) NULL ),
+       #define EVT_PL_LEFT_UP(func)                 wxEventTableEntry( cbEVT_PL_LEFT_UP,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftUpHandler          ) & func, (wxObject *) NULL ),
+       #define EVT_PL_RIGHT_DOWN(func)              wxEventTableEntry( cbEVT_PL_RIGHT_DOWN,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightDownHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_RIGHT_UP(func)                wxEventTableEntry( cbEVT_PL_RIGHT_UP,                   -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightUpHandler         ) & func, (wxObject *) NULL ),
+       #define EVT_PL_MOTION(func)                          wxEventTableEntry( cbEVT_PL_MOTION,                         -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbMotionHandler          ) & func, (wxObject *) NULL ),
+       #define EVT_PL_LEFT_DCLICK(func)             wxEventTableEntry( cbEVT_PL_LEFT_DCLICK,            -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDClickHandler      ) & func, (wxObject *) NULL ),
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_LAYOUT_ROW(func)              wxEventTableEntry( cbEVT_PL_LAYOUT_ROW,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_RESIZE_ROW(func)              wxEventTableEntry( cbEVT_PL_RESIZE_ROW,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeRowHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_LAYOUT_ROWS(func)             wxEventTableEntry( cbEVT_PL_LAYOUT_ROWS,        -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowsHandler      ) & func, (wxObject *) NULL ),
+       #define EVT_PL_INSERT_BAR(func)              wxEventTableEntry( cbEVT_PL_INSERT_BAR,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbInsertBarHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_RESIZE_BAR(func)              wxEventTableEntry( cbEVT_PL_RESIZE_BAR,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeBarHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_REMOVE_BAR(func)              wxEventTableEntry( cbEVT_PL_REMOVE_BAR,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRemoveBarHandler       ) & func, (wxObject *) NULL ),
+       #define EVT_PL_SIZE_BAR_WND(func)            wxEventTableEntry( cbEVT_PL_SIZE_BAR_WND,       -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbSizeBarWndHandler      ) & func, (wxObject *) NULL ),
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_DRAW_BAR_DECOR(func)      wxEventTableEntry( cbEVT_PL_DRAW_BAR_DECOR,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarDecorHandler    ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_ROW_DECOR(func)      wxEventTableEntry( cbEVT_PL_DRAW_ROW_DECOR,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowDecorHandler    ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_PANE_DECOR(func)     wxEventTableEntry( cbEVT_PL_DRAW_PANE_DECOR,     -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneDecorHandler   ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_BAR_HANDLES(func)    wxEventTableEntry( cbEVT_PL_DRAW_BAR_HANDLES,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarHandlesHandler  ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_ROW_HANDLES(func)    wxEventTableEntry( cbEVT_PL_DRAW_ROW_HANDLES,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowHandlesHandler  ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_ROW_BKGROUND(func)   wxEventTableEntry( cbEVT_PL_DRAW_ROW_BKGROUND,   -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowBkGroundHandler ) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_PANE_BKGROUND(func)  wxEventTableEntry( cbEVT_PL_DRAW_PANE_BKGROUND,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneBkGroundHandler) & func, (wxObject *) NULL ),
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_START_BAR_DRAGGING(func)  wxEventTableEntry( cbEVT_PL_START_BAR_DRAGGING,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartBarDraggingHandler) & func, (wxObject *) NULL ),
+       #define EVT_PL_DRAW_HINT_RECT(func)      wxEventTableEntry( cbEVT_PL_DRAW_HINT_RECT,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawHintRectHandler    ) & func, (wxObject *) NULL ),
+
+
+       #define EVT_PL_START_DRAW_IN_AREA(func)  wxEventTableEntry( cbEVT_PL_START_DRAW_IN_AREA,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartDrawInAreaHandler)  & func, (wxObject *) NULL ),
+       #define EVT_PL_FINISH_DRAW_IN_AREA(func) wxEventTableEntry( cbEVT_PL_FINISH_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbFinishDrawInAreaHandler) & func, (wxObject *) NULL ),
+
+       #define EVT_PL_CUSTOMIZE_BAR(func)       wxEventTableEntry( cbEVT_PL_CUSTOMIZE_BAR,       -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeBarHandler)     & func, (wxObject *) NULL ),
+       #define EVT_PL_CUSTOMIZE_LAYOUT(func)    wxEventTableEntry( cbEVT_PL_CUSTOMIZE_LAYOUT,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeLayoutHandler)  & func, (wxObject *) NULL ),
+#else
+       #define EVT_PL_LEFT_DOWN(func)               { cbEVT_PL_LEFT_DOWN,                   -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDownHandler        ) & func },
+       #define EVT_PL_LEFT_UP(func)                 { cbEVT_PL_LEFT_UP,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftUpHandler          ) & func },
+       #define EVT_PL_RIGHT_DOWN(func)              { cbEVT_PL_RIGHT_DOWN,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightDownHandler       ) & func },
+       #define EVT_PL_RIGHT_UP(func)                { cbEVT_PL_RIGHT_UP,                    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightUpHandler         ) & func },
+       #define EVT_PL_MOTION(func)                          { cbEVT_PL_MOTION,                  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbMotionHandler          ) & func },
+       #define EVT_PL_LEFT_DCLICK(func)             { cbEVT_PL_LEFT_DCLICK,             -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDClickHandler      ) & func },
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_LAYOUT_ROW(func)              { cbEVT_PL_LAYOUT_ROW,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowHandler       ) & func },
+       #define EVT_PL_RESIZE_ROW(func)              { cbEVT_PL_RESIZE_ROW,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeRowHandler       ) & func },
+       #define EVT_PL_LAYOUT_ROWS(func)             { cbEVT_PL_LAYOUT_ROWS,         -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowsHandler      ) & func },
+       #define EVT_PL_INSERT_BAR(func)              { cbEVT_PL_INSERT_BAR,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbInsertBarHandler       ) & func },
+       #define EVT_PL_RESIZE_BAR(func)              { cbEVT_PL_RESIZE_BAR,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeBarHandler       ) & func },
+       #define EVT_PL_REMOVE_BAR(func)              { cbEVT_PL_REMOVE_BAR,              -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRemoveBarHandler       ) & func },
+       #define EVT_PL_SIZE_BAR_WND(func)            { cbEVT_PL_SIZE_BAR_WND,        -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbSizeBarWndHandler      ) & func },
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_DRAW_BAR_DECOR(func)      { cbEVT_PL_DRAW_BAR_DECOR,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarDecorHandler    ) & func },
+       #define EVT_PL_DRAW_ROW_DECOR(func)      { cbEVT_PL_DRAW_ROW_DECOR,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowDecorHandler    ) & func },
+       #define EVT_PL_DRAW_PANE_DECOR(func)     { cbEVT_PL_DRAW_PANE_DECOR,     -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneDecorHandler   ) & func },
+       #define EVT_PL_DRAW_BAR_HANDLES(func)    { cbEVT_PL_DRAW_BAR_HANDLES,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarHandlesHandler  ) & func },
+       #define EVT_PL_DRAW_ROW_HANDLES(func)    { cbEVT_PL_DRAW_ROW_HANDLES,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowHandlesHandler  ) & func },
+       #define EVT_PL_DRAW_ROW_BKGROUND(func)   { cbEVT_PL_DRAW_ROW_BKGROUND,   -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowBkGroundHandler ) & func },
+       #define EVT_PL_DRAW_PANE_BKGROUND(func)  { cbEVT_PL_DRAW_PANE_BKGROUND,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneBkGroundHandler) & func },
+                                                                                                                                                                                                                                                                                                                
+       #define EVT_PL_START_BAR_DRAGGING(func)  { cbEVT_PL_START_BAR_DRAGGING,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartBarDraggingHandler) & func },
+       #define EVT_PL_DRAW_HINT_RECT(func)      { cbEVT_PL_DRAW_HINT_RECT,      -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawHintRectHandler    ) & func },
+
+       #define EVT_PL_START_DRAW_IN_AREA(func)  { cbEVT_PL_START_DRAW_IN_AREA,  -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartDrawInAreaHandler)  & func },
+       #define EVT_PL_FINISH_DRAW_IN_AREA(func) { cbEVT_PL_FINISH_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbFinishDrawInAreaHandler) & func },
+
+       #define EVT_PL_CUSTOMIZE_BAR(func)       { cbEVT_PL_CUSTOMIZE_BAR,       -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeBarHandler)     & func },
+       #define EVT_PL_CUSTOMIZE_LAYOUT(func)    { cbEVT_PL_CUSTOMIZE_LAYOUT,    -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeLayoutHandler)  & func },
+#endif
+/* 
+ * abstract base class for all control-bar related plugins 
+ */
+
+class cbPluginBase : public wxEvtHandler
+{
+       DECLARE_ABSTRACT_CLASS( cbPluginBase )
+public:
+
+       wxFrameLayout* mpLayout; // back-reference to the frame layout 
+
+       // specifies panes, for which this plugin receives events
+       // (see pane masks definitions)
+       int            mPaneMask; 
+
+       bool           mIsReady; // is TRUE, when plugin is ready to handle events
+
+public:
+       cbPluginBase(void) 
+
+               : mpLayout  ( 0 ),
+                 mPaneMask( wxALL_PANES ),
+                 mIsReady ( FALSE )
+       {}
+
+       cbPluginBase( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ) 
+
+               : mpLayout  ( pPanel ),
+                 mPaneMask( paneMask ),
+                 mIsReady ( FALSE )
+       {}
+
+       inline int GetPaneMask() { return mPaneMask; }
+
+       // NOTE:: pointer positions of mouse-events sent to plugins
+       //        are always in pane's coordinates (pane's to which
+       //        this plugin is hooked)
+
+       // destroys the whole plugin chain of connected plagins
+       virtual ~cbPluginBase();
+
+       // override this method to do plugin-specific initialization
+       // (at this point plugin is already attached to the frame layout,
+       //  and pane masks are set)
+       virtual void OnInitPlugin() { mIsReady = TRUE; }
+
+       bool IsReady() { return mIsReady; }
+
+       // overriden, to determine whether the target pane specified in the
+       // event, matches the pane mask of this plugin (specific plugins
+       // do not override this method)
+
+       virtual bool ProcessEvent(wxEvent& event);
+};
+
+/*** event classes, for each corresponding event type (24 currnetly...uhh) ***/
+
+// mouse-events category
+
+class cbLeftDownEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbLeftDownEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_LEFT_DOWN, pPane ),
+                 mPos( pos )
+       {}
+};
+
+class cbLeftUpEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbLeftUpEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_LEFT_UP, pPane ),
+                 mPos( pos )
+       {}
+};
+
+class cbRightDownEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbRightDownEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_RIGHT_DOWN, pPane ),
+                 mPos( pos )
+       {}
+};
+
+class cbRightUpEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbRightUpEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_RIGHT_UP, pPane ),
+                 mPos( pos )
+       {}
+};
+
+class cbMotionEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbMotionEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_MOTION, pPane ),
+                 mPos( pos )
+       {}
+};
+
+class cbLeftDClickEvent : public cbPluginEvent
+{
+public:
+       wxPoint mPos;
+
+       cbLeftDClickEvent( const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_LEFT_DCLICK, pPane ),
+                 mPos( pos )
+       {}
+};
+
+// bar/row events category
+
+class cbLayoutRowEvent : public cbPluginEvent
+{
+public:
+       cbRowInfo* mpRow;
+
+       cbLayoutRowEvent( cbRowInfo* pRow, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_LAYOUT_ROW, pPane ),
+                 mpRow( pRow )
+       {}
+};
+
+class cbResizeRowEvent : public cbPluginEvent
+{
+public:
+       cbRowInfo* mpRow;
+       int        mHandleOfs;
+       bool       mForUpperHandle;
+
+       cbResizeRowEvent( cbRowInfo* pRow, int handleOfs, bool forUpperHandle, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_RESIZE_ROW, pPane ),
+                 mpRow( pRow ),
+                 mHandleOfs( handleOfs ),
+                 mForUpperHandle( forUpperHandle )
+       {}
+};
+
+class cbLayoutRowsEvent : public cbPluginEvent
+{
+public:
+
+       cbLayoutRowsEvent( cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_LAYOUT_ROWS, pPane )
+       {}
+};
+
+class cbInsertBarEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo*  mpBar;
+       cbRowInfo*  mpRow;
+
+       cbInsertBarEvent( cbBarInfo* pBar, cbRowInfo* pIntoRow, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_INSERT_BAR, pPane ),
+
+                 mpBar( pBar     ),
+                 mpRow( pIntoRow )
+       {}
+};
+
+class cbResizeBarEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+       cbRowInfo* mpRow;
+
+       cbResizeBarEvent( cbBarInfo* pBar, cbRowInfo* pRow, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_RESIZE_BAR, pPane ),
+                 mpBar( pBar ),
+                 mpRow( pRow )
+       {}
+};
+
+class cbRemoveBarEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+
+       cbRemoveBarEvent( cbBarInfo* pBar, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_REMOVE_BAR, pPane ),
+                 mpBar( pBar )
+       {}
+};
+
+class cbSizeBarWndEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+       wxRect     mBoundsInParent;
+
+       cbSizeBarWndEvent( cbBarInfo* pBar, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_SIZE_BAR_WND, pPane ),
+                 mpBar( pBar ),
+                 mBoundsInParent( pBar->mBoundsInParent )
+       {}
+};
+
+class cbDrawBarDecorEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+       wxDC*      mpDc;
+       wxRect     mBoundsInParent;
+
+       cbDrawBarDecorEvent( cbBarInfo* pBar, wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_BAR_DECOR, pPane ),
+                 mpBar( pBar ),
+                 mpDc( &dc ),
+                 mBoundsInParent( pBar->mBoundsInParent )
+       {}
+};
+
+class cbDrawRowDecorEvent : public cbPluginEvent
+{
+public:
+       cbRowInfo* mpRow;
+       wxDC*      mpDc;
+
+       cbDrawRowDecorEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_ROW_DECOR, pPane ),
+                 mpRow( pRow ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbDrawPaneDecorEvent : public cbPluginEvent
+{
+public:
+       wxDC* mpDc;
+
+       cbDrawPaneDecorEvent( wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_PANE_DECOR, pPane ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbDrawBarHandlesEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+       wxDC*   mpDc;
+
+       cbDrawBarHandlesEvent( cbBarInfo* pBar, wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_BAR_HANDLES, pPane ),
+                 mpBar( pBar ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbDrawRowHandlesEvent : public cbPluginEvent
+{
+public:
+       cbRowInfo* mpRow;
+       wxDC*      mpDc;
+
+       cbDrawRowHandlesEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_ROW_HANDLES, pPane ),
+                 mpRow( pRow ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbDrawRowBkGroundEvent : public cbPluginEvent
+{
+public:
+       cbRowInfo* mpRow;
+       wxDC*   mpDc;
+
+       cbDrawRowBkGroundEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_ROW_BKGROUND, pPane ),
+                 mpRow( pRow ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbDrawPaneBkGroundEvent : public cbPluginEvent
+{
+public:
+       wxDC* mpDc;
+
+       cbDrawPaneBkGroundEvent( wxDC& dc, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_PANE_BKGROUND, pPane ),
+                 mpDc( &dc )
+       {}
+};
+
+class cbStartBarDraggingEvent : public cbPluginEvent
+{
+public:
+       cbBarInfo* mpBar;
+       wxPoint    mPos;  // is given in frame's coordinates
+
+       cbStartBarDraggingEvent( cbBarInfo* pBar, const wxPoint& pos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_START_BAR_DRAGGING, pPane ),
+                 mpBar( pBar ),
+                 mPos( pos )
+       {}
+};
+
+class cbDrawHintRectEvent : public cbPluginEvent
+{
+public:
+       wxRect mRect;      // is given in frame's coordinates
+
+
+       bool   mLastTime;  // indicates that this event finishes "session" of on-screen drawing,
+                                          // thus associated resources can be freed now
+       bool   mEraseRect; // does not have any impact, if recangle is drawn using XOR-mask
+
+       bool   mIsInClient;// in cleint area hint could be drawn differently,
+                          // e.g. with fat/hatched border
+
+
+       cbDrawHintRectEvent( const wxRect& rect, bool isInClient, bool eraseRect, bool lastTime )
+
+               : cbPluginEvent( cbEVT_PL_DRAW_HINT_RECT, 0 ),
+                 mRect      ( rect       ),
+                 mLastTime  ( lastTime   ),
+                 mEraseRect ( eraseRect  ),
+                 mIsInClient( isInClient )
+       {}
+};
+
+class cbStartDrawInAreaEvent : public cbPluginEvent
+{
+public:
+       wxRect mArea;
+       wxDC** mppDc; // points to pointer, where the reference
+                     // to the obtained buffer-context should be placed
+
+       cbStartDrawInAreaEvent( const wxRect& area, wxDC** ppDCForArea, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_START_DRAW_IN_AREA, pPane ),
+                 mArea( area ),
+                 mppDc( ppDCForArea )
+       {}
+};
+
+class cbFinishDrawInAreaEvent : public cbPluginEvent
+{
+public:
+       wxRect mArea;
+
+       cbFinishDrawInAreaEvent( const wxRect& area, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_FINISH_DRAW_IN_AREA, pPane ),
+                 mArea( area )
+       {}
+};
+
+class cbCustomizeBarEvent : public cbPluginEvent
+{
+public:
+       wxPoint    mClickPos; // in parent frame's coordinates
+       cbBarInfo* mpBar;
+
+       cbCustomizeBarEvent( cbBarInfo* pBar, const wxPoint& clickPos, cbDockPane* pPane )
+
+               : cbPluginEvent( cbEVT_PL_CUSTOMIZE_BAR, pPane ),
+                 mClickPos( clickPos ),
+                 mpBar( pBar )
+       {}
+};
+
+class cbCustomizeLayoutEvent : public cbPluginEvent
+{
+public:
+       wxPoint mClickPos; // in parent frame's coordinates
+
+       cbCustomizeLayoutEvent( const wxPoint& clickPos )
+
+               : cbPluginEvent( cbEVT_PL_CUSTOMIZE_LAYOUT, 0 ),
+                 mClickPos( clickPos )
+       {}
+};
+
+#endif /* __CONTROLBAR_G__ */
+
diff --git a/contrib/include/wx/fl/dynbarhnd.h b/contrib/include/wx/fl/dynbarhnd.h
new file mode 100644 (file)
index 0000000..9b2933c
--- /dev/null
@@ -0,0 +1,22 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     23/01/99
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DYNBARHND_G__
+#define __DYNBARHND_G__
+
+#ifdef __GNUG__
+    #pragma interface "dynbarhnd.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+#endif /* __DYNBARHND_G__ */
+
diff --git a/contrib/include/wx/fl/dyntbar.h b/contrib/include/wx/fl/dyntbar.h
new file mode 100644 (file)
index 0000000..942b496
--- /dev/null
@@ -0,0 +1,204 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     ??/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DYNTBAR_G__
+#define __DYNTBAR_G__
+
+#ifdef __GNUG__
+    #pragma interface "dyntbar.h"
+#endif
+
+#include "wx/tbarbase.h"
+#include "wx/dynarray.h"
+
+// layout item
+
+class wxToolLayoutItem : public wxObject
+{
+public:
+       wxRect    mRect;
+       bool      mIsSeparator;
+};
+
+class wxDynToolInfo;
+
+typedef wxToolLayoutItem* wxToolLayoutItemPtrT;
+typedef wxDynToolInfo*    wxDynToolInfoPtrT;
+
+
+WX_DEFINE_ARRAY( wxToolLayoutItemPtrT, wxLayoutItemArrayT  );
+WX_DEFINE_ARRAY( wxDynToolInfoPtrT,    wxDynToolInfoArrayT );
+
+// base class for layouting algorithm implementations
+
+class LayoutManagerBase
+{
+public:
+       virtual void Layout( const wxSize&       parentDim, 
+                                                wxSize&                 resultingDim,
+                                                wxLayoutItemArrayT& items,
+                                                int                     horizGap,
+                                int                     vertGap   ) = 0;
+
+       virtual ~LayoutManagerBase() {}
+};
+
+// layouts items in left-to-right order from
+// top towards bottom
+
+class BagLayout : public LayoutManagerBase
+{
+public:
+       virtual void Layout( const wxSize&       parentDim, 
+                                                wxSize&                 resultingDim,
+                                                wxLayoutItemArrayT& items,
+                                                int                     horizGap,
+                                int                     vertGap   );
+};
+
+class wxDynToolInfo : public wxToolLayoutItem
+{
+       DECLARE_DYNAMIC_CLASS(wxDynToolInfo)
+
+public:
+       wxWindow* mpToolWnd;
+       int       mIndex;
+       wxSize    mRealSize;
+};
+
+// layouting orientations for tools
+
+#define LO_HORIZONTAL    0
+#define LO_VERTICAL      1
+#define LO_FIT_TO_WINDOW 2
+
+// class manages containment and layouting of tool-windows
+
+class wxDynamicToolBar : public wxToolBarBase
+{
+       DECLARE_DYNAMIC_CLASS(wxDynamicToolBar)
+protected:
+
+       friend class wxDynamicToolBarSerializer;
+
+       wxDynToolInfoArrayT mTools;
+       LayoutManagerBase*  mpLayoutMan;
+
+protected:
+       virtual void SizeToolWindows();
+
+public: /* public properties */
+
+       int                mSepartorSize; // default: 8
+       int                mVertGap;      // default: 0
+       int                mHorizGap;     // default: 0
+       
+public:
+       wxDynamicToolBar();
+
+       wxDynamicToolBar(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+                    const long style = wxNO_BORDER, const int orientation = wxVERTICAL,
+                        const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr);
+
+       ~wxDynamicToolBar(void);
+
+       bool Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
+                               const long style = wxNO_BORDER, const int orientation = wxVERTICAL, const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr);
+
+       // overridables
+
+       virtual void AddTool( int toolIndex, 
+                                                 wxWindow* pToolWindow, 
+                                                 const wxSize& size = wxDefaultSize );
+
+       virtual void AddTool( int toolIndex, 
+                                                 const wxString& imageFileName,
+                                                 int imageFileType = wxBITMAP_TYPE_BMP,
+                                                 const wxString& labelText = "", bool alignTextRight = FALSE,
+                                                 bool isFlat = TRUE );
+       virtual void AddTool( int toolIndex, wxBitmap labelBmp,
+                                                 const wxString& labelText = "", bool alignTextRight = FALSE,
+                                                 bool isFlat = TRUE );
+
+       // method from wxToolBarBase (for compatibility), only
+       // first two arguments are valid
+
+  virtual wxToolBarToolBase *AddTool(const int toolIndex, const wxBitmap& bitmap, const wxBitmap& pushedBitmap = wxNullBitmap,
+               const bool toggle = FALSE, const long xPos = -1, const long yPos = -1, wxObject *clientData = NULL,
+               const wxString& helpString1 = "", const wxString& helpString2 = "");
+
+       virtual void AddSeparator( wxWindow* pSepartorWnd = NULL );
+
+       wxDynToolInfo* GetToolInfo( int toolIndex );
+
+       void RemveTool( int toolIndex );
+
+       // the default implementation draws shaded line
+       virtual void DrawSeparator( wxDynToolInfo& info, wxDC& dc );
+
+       // see definitions of orientation types
+       virtual bool Layout();
+
+       virtual void GetPreferredDim( const wxSize& givenDim, wxSize& prefDim );
+
+       virtual LayoutManagerBase* CreateDefaulLayout() { return new BagLayout(); }
+
+       virtual void SetLayout( LayoutManagerBase* pLayout );
+
+       virtual void EnableTool(const int toolIndex, const bool enable = TRUE);
+
+       // event handlers
+
+       void OnSize( wxSizeEvent& event );
+       void OnPaint( wxPaintEvent& event );
+       void OnEraseBackground( wxEraseEvent& event );
+
+       // overriden from wxToolBarBase
+
+       virtual bool Realize(void);
+
+       // stuff from the 2.1.15 
+
+    virtual wxToolBarToolBase *FindToolForPosition(wxCoord x,
+                                                   wxCoord y) const;
+
+
+    virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool);
+
+    // the tool is still in m_tools list when this function is called, it will
+    // only be deleted from it if it succeeds
+    virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool);
+
+    // called when the tools enabled flag changes
+    virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable);
+
+    // called when the tool is toggled
+    virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle);
+
+    // called when the tools "can be toggled" flag changes
+    virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle);
+
+    // the functions to create toolbar tools
+    virtual wxToolBarToolBase *CreateTool(int id,
+                                          const wxBitmap& bitmap1,
+                                          const wxBitmap& bitmap2,
+                                          bool toggle,
+                                          wxObject *clientData,
+                                          const wxString& shortHelpString,
+                                          const wxString& longHelpString);
+    virtual wxToolBarToolBase *CreateTool(wxControl *control);
+
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __DYNTBAR_G__ */
+
diff --git a/contrib/include/wx/fl/dyntbarhnd.h b/contrib/include/wx/fl/dyntbarhnd.h
new file mode 100644 (file)
index 0000000..1fed738
--- /dev/null
@@ -0,0 +1,31 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     23/01/99
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __DYNTBARHND_G__
+#define __DYNTBARHND_G__
+
+#ifdef __GNUG__
+    #pragma interface "dyntbarhnd.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+#include "wx/fl/dyntbar.h"
+
+class cbDynToolBarDimHandler : public cbBarDimHandlerBase
+{
+       DECLARE_DYNAMIC_CLASS( cbDynToolBarDimHandler )
+public:
+       void OnChangeBarState(cbBarInfo* pBar, int newState );
+       void OnResizeBar( cbBarInfo* pBar, const wxSize& given, wxSize& preferred );
+};
+
+#endif /* __DYNTBARHND_G__ */
+
diff --git a/contrib/include/wx/fl/frmview.h b/contrib/include/wx/fl/frmview.h
new file mode 100644 (file)
index 0000000..90f3370
--- /dev/null
@@ -0,0 +1,140 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     02/01/99
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __FRMVIEW_G__
+#define __FRMVIEW_G__
+
+#ifdef __GNUG__
+    #pragma interface "frmview.h"
+#endif
+
+#include "wx/module.h"
+
+#if 0
+#include "wx/fl/objstore.h"
+#endif
+
+class wxObjectStorage;
+
+#include "wx/fl/controlbar.h"
+
+class wxFrameManager;
+
+class wxFrameView : public wxEvtHandler
+{
+protected:
+       wxStringList    mTopMenus;
+       wxFrameLayout*  mpLayout;
+       wxFrameManager* mpFrameMgr;
+       bool            mDoToolUpdates;
+
+       friend class wxFrameManager;
+       friend class wxFrameViewSerializer;     
+
+protected:
+       void OnIdle( wxIdleEvent& event);
+       
+public:
+       wxFrameView();
+       ~wxFrameView();
+
+       virtual void Activate();
+       virtual void Deactivate();
+
+       wxFrame* GetParentFrame();
+       wxWindow* GetClientWindow();
+
+       wxFrameManager& GetFrameManager();
+
+       void RegisterMenu( const wxString& topMenuName );
+
+       void CreateLayout();
+       wxFrameLayout* GetLayout();
+       void SetLayout( wxFrameLayout* pLayout );
+       void SetToolUpdates( bool doToolUpdates = TRUE );
+
+
+       // hooks for specific frame-views
+
+       virtual void OnInit() {}
+
+       virtual void OnSerialize( wxObjectStorage& store ) {}
+       virtual void OnActiveate() {}
+       virtual void OnDeactivate() {}
+
+       // imp. is mandatory
+       virtual void OnRecreate() {}
+       virtual void OnInitMenus() {}
+
+       DECLARE_EVENT_TABLE()
+};
+
+class wxFrame;
+
+class wxFrameManager : wxObject
+{
+protected:
+       wxList       mViews;
+       wxWindow*    mpFrameWnd;
+       int          mActiveViewNo;
+       wxWindow*    mpClientWnd;
+
+#if 0
+       wxObjectStorage mStore;
+#endif
+
+       wxString        mSettingsFile;
+
+protected:
+       void DoSerialize( wxObjectStorage& store );
+       void DestroyViews();
+       int GetViewNo( wxFrameView* pView );
+       void EnableMenusForView( wxFrameView* pView, bool enable );
+       void SyncAllMenus();
+
+public:
+       wxFrameManager();
+       ~wxFrameManager();
+
+       // if file name is empty, views are are not saved/loaded
+
+       virtual void Init( wxWindow* pMainFrame, const wxString& settingsFile = "" );
+
+       // synonyms
+       wxFrame* GetParentFrame();
+       wxWindow* GetParentWindow();
+
+       int GetActiveViewNo();
+       wxFrameView* GetActiveView();
+       wxNode* GetActiveViewNode();
+
+       wxFrameView* GetView( int viewNo );
+
+       void SetClinetWindow( wxWindow* pFrameClient ); 
+       wxWindow* GetClientWindow();
+
+       void AddView( wxFrameView* pFrmView );
+       void RemoveView( wxFrameView* pFrmView );
+
+       void ActivateView( int viewNo );
+       void ActivateView( wxFrameView* pFrmView );
+       void DeactivateCurrentView();
+
+       wxObjectStorage& GetObjectStore();
+
+       void SaveViewsNow();
+       bool ReloadViews();
+
+       bool ViewsAreLoaded();
+};
+
+#endif /* __FRMVIEW_G__ */
+
diff --git a/contrib/include/wx/fl/garbagec.h b/contrib/include/wx/fl/garbagec.h
new file mode 100644 (file)
index 0000000..d710e9f
--- /dev/null
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas (@Lithuania)
+// Modified by:
+// Created:     ??/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GARBAGEC_G__
+#define __GARBAGEC_G__
+
+#ifdef __GNUG__
+    #pragma interface "garbagec.h"
+#endif
+
+#include "wx/list.h"
+
+struct GCItem
+{
+       void*     mpObj;
+       wxList    mRefs;   // references to other nodes
+};
+
+inline void* gc_node_to_obj( wxNode* pGCNode )
+{
+       return ( (GCItem*) (pGCNode->Data()) )->mpObj;
+}
+
+// class implements extremely slow, but probably one of the most simple GC algorithms
+
+class GarbageCollector
+{
+protected:
+       wxList mAllNodes;
+       wxList mRegularLst;
+       wxList mCycledLst;
+
+       wxNode* FindItemNode( void* pForObj );
+       void    ResolveReferences();
+
+       wxNode* FindReferenceFreeItemNode();
+       void    RemoveReferencesToNode( wxNode* pItemNode );
+       void    DestroyItemList( wxList& lst );
+
+public:
+
+       GarbageCollector() {}
+
+       virtual ~GarbageCollector();
+
+       // prepare data for GC alg.
+
+       virtual void AddObject( void* pObj, int refCnt = 1 );
+       virtual void AddDependency( void* pObj, void* pDependsOnObj );
+
+       // executes GC alg.
+
+       virtual void ArrangeCollection();
+
+       // access results of the alg.
+
+       wxList& GetRegularObjects();
+       wxList& GetCycledObjects();
+
+       // removes all data from GC
+
+       void Reset();
+};
+
+#endif /* __GARBAGEC_G__ */
+
diff --git a/contrib/include/wx/fl/gcupdatesmgr.h b/contrib/include/wx/fl/gcupdatesmgr.h
new file mode 100644 (file)
index 0000000..e8fabc5
--- /dev/null
@@ -0,0 +1,123 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     19/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __GCUPDATESMGR_G__
+#define __GCUPDATESMGR_G__
+
+#ifdef __GNUG__
+    #pragma interface "gcupdatesmgr.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+#include "wx/fl/updatesmgr.h"
+
+#include "wx/fl/garbagec.h"
+
+/*
+ * class implements optimized logic for refreshing
+ * areas of frame layout - which actually need to be updated. 
+ * Is used as default updates-manager by wxFrameLayout.
+ *
+ * it is called "Garbage Collecting" u.mgr for it's implementation
+ * tries to find out dependencies between bars, and to order
+ * them ito "hierarchy", this hierarchical sorting resembles
+ * implemenation of heap-garbage collectors, which resolve
+ * dependencies between references.
+ *
+ * Example: there are situations where the order of moving
+ *          the windows does matter:
+ *
+ *   case 1)                
+ *      ------             ---
+ *      | A     |                  |B|  
+ *             ------   --->   | |
+ *                     ---                     --- ------ 
+ *                     |B|                             | A  | 
+ *                     | |                             ------
+ *                     ---                             
+ *                                             (future)
+ *        (past)            
+ *
+ *  past/future positions of A and B windows completely overlapp, i.e.
+ *  depend on each other, and there is not solution for
+ *  moving the windows witout refreshing both of them,
+ *  -- we have cyclic dependency here. The gc. alg will
+ *  find this cyclic dependecy and will force "refresh"
+ *  after movement.
+ *
+ *   case 2)
+ *
+ *      ------                                 
+ *      | A     |                                      
+ *             ------   --->                       
+ *                     ---                               
+ *                     |B|                                        ------   
+ *                     | |                                        | A  |   
+ *                     ---                                        ------         
+ *                                              ---
+ *                                              |B|
+ *                                              | |
+ *                                          ---
+ *
+ *                                             (future)                
+ *        (past)       
+ *
+ *  in this case past/future positions do not overlapp, thus
+ *  it's enough only to move windows, without refreshing them.
+ *  GC will "notice" it.
+ *
+ *  there is also third case, when overlapping is partial
+ *  in this case the refershing can be also avoided by
+ *  moving windows in the order of "most-dependant" towards the
+ *  "least-dependent". GC handles this automatically, by
+ *  sorting windows by their dependency-level (or "hierarchy")
+ *
+ *  See garbagec.h for more details of this method, garbagec.h/cpp
+ *  implement sorting of generic-dependencies (does not deal
+ *  with graphical objects directly)
+ *
+ *  Summary: improves performance when complex/large windows are 
+ *           moved around, by reducing number of repaints. Also helps 
+ *           to avoid dirty non-client areas of moved windows
+ *           in some special cases of "overlapping anomalies"
+ */
+
+class cbGCUpdatesMgr : public cbSimpleUpdatesMgr
+{
+       DECLARE_DYNAMIC_CLASS( cbGCUpdatesMgr )
+protected:
+
+       GarbageCollector mGC;
+
+       void DoRepositionItems( wxList& items );
+
+       void AddItem( wxList&     itemList,
+                                 cbBarInfo*  pBar, 
+                         cbDockPane* pPane,
+                                 wxRect&     curBounds,
+                                 wxRect&     prevBounds );
+
+public:
+
+       cbGCUpdatesMgr(void) {}
+
+       cbGCUpdatesMgr( wxFrameLayout* pPanel );
+
+       // notificiactions received from Frame Layout :
+
+       virtual void OnStartChanges();
+
+       // refreshes parts of the frame layout, which need an update
+       virtual void UpdateNow();
+};
+
+#endif /* __GCUPDATESMGR_G__ */
+
diff --git a/contrib/include/wx/fl/hintanimpl.h b/contrib/include/wx/fl/hintanimpl.h
new file mode 100644 (file)
index 0000000..4d8d07a
--- /dev/null
@@ -0,0 +1,120 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     9/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __HINTANIMPL_G__
+#define __HINTANIMPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "hintanimpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+#include "wx/timer.h"
+
+class cbHintAnimTimer;
+
+class cbHintAnimationPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbHintAnimationPlugin )
+protected:
+       friend class cbHintAnimTimer;
+
+       wxScreenDC*      mpScrDc;     // created while tracking hint-rect
+       cbHintAnimTimer* mpAnimTimer;  
+
+       // FOR NOW:: try it without mutually exculisve locks
+       volatile wxRect  mCurRect;
+
+       // state variables
+
+       bool   mAnimStarted;
+       bool   mStopPending;
+
+       bool   mPrevInClient;
+       bool   mCurInClient;
+
+       wxRect mPrevRect;
+
+public:
+       int    mMorphDelay;         // delay between frames in miliseconds,     default: 20
+       int    mMaxFrames;          // number  of iterations for hint morphing, default: 30
+                                                           // (morph duration = mMorphDelay * mMaxFrames msec)
+
+       int    mInClientHintBorder; // default: 4 pixels
+
+       bool   mAccelerationOn;     // TRUE, if morph accelerates, otherwise morph
+                                                               // speed is constant. Default: TRUE
+
+       // TBD:: get/set methods for above members
+
+protected:
+       void StartTracking();
+
+       void DrawHintRect ( wxRect& rect, bool isInClientRect);
+       void EraseHintRect( wxRect& rect, bool isInClientRect);
+
+       void FinishTracking();
+
+       void DoDrawHintRect( wxRect& rect, bool isInClientRect);
+
+       void RectToScr( wxRect& frameRect, wxRect& scrRect );
+
+public:
+       cbHintAnimationPlugin(void);
+
+       ~cbHintAnimationPlugin();
+
+       cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       void OnDrawHintRect( cbDrawHintRectEvent& event );        
+
+       DECLARE_EVENT_TABLE()
+};
+
+
+// helper classes
+
+struct MorphInfoT
+{
+       wxPoint mFrom;
+       wxPoint mTill;
+};
+
+class cbHintAnimTimer : public wxTimer 
+{
+protected:
+
+       friend class cbHintAnimationPlugin;
+
+       wxRect      mPrevMorphed;
+
+       MorphInfoT  mUpperLeft;
+       MorphInfoT  mLowerRight;
+       int         mCurIter;
+
+       long        mLock;
+
+       cbHintAnimationPlugin* mpPl;
+
+       void MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point );
+
+public: 
+
+       cbHintAnimTimer(void);
+
+       virtual void Notify(void);
+
+       virtual bool Init( cbHintAnimationPlugin* pAnimPl, bool reinit );
+};
+
+#endif /* __HINTANIMPL_G__ */
+
diff --git a/contrib/include/wx/fl/newbmpbtn.h b/contrib/include/wx/fl/newbmpbtn.h
new file mode 100644 (file)
index 0000000..a386211
--- /dev/null
@@ -0,0 +1,165 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     ??/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __NEWBMPBTN_G__
+#define __NEWBMPBTN_G__
+
+#ifdef __GNUG__
+    #pragma interface "newbmpbtn.h"
+#endif
+
+#include "wx/button.h"
+#include "wx/string.h"
+
+// button lable-text alignment types
+
+#define NB_ALIGN_TEXT_RIGHT  0
+#define NB_ALIGN_TEXT_BOTTOM 1
+#define NB_NO_TEXT           2
+#define NB_NO_IMAGE          3
+
+// classes declared in this header file
+
+class wxNewBitmapButton;
+class wxBorderLessBitmapButton;
+
+// alternative class for wxBmpButton
+
+class wxNewBitmapButton: public wxPanel
+{
+       DECLARE_DYNAMIC_CLASS(wxNewBitmapButton)
+
+protected:
+
+       friend class wxNewBitmapButtonSerializer;
+
+       int      mTextToLabelGap;
+       int      mMarginX;
+       int      mMarginY;
+       int      mTextAlignment;
+       bool     mIsSticky;
+       bool     mIsFlat;
+
+       wxString mLabelText;
+       wxString mImageFileName;
+       int      mImageFileType;
+
+       wxBitmap mDepressedBmp; // source image for rendering
+                               // labels for particular state
+
+       wxBitmap mFocusedBmp;   // may not be always present -
+                                                       // only if mHasFocusedBmp is TRUE
+
+       wxBitmap* mpDepressedImg;
+       wxBitmap* mpPressedImg;
+       wxBitmap* mpDisabledImg;
+       wxBitmap* mpFocusedImg;
+
+       // button state variables;
+       bool      mDragStarted;
+       bool      mIsPressed; 
+       bool      mIsInFocus;
+       bool      mPrevPressedState;
+       bool      mPrevInFocusState;
+
+       bool      mHasFocusedBmp;
+
+       // type of event which is fired upon depression of this button
+       int       mFiredEventType;
+
+       // pens for drawing decorations (borders)
+       wxPen     mBlackPen;
+       wxPen     mDarkPen;
+       wxPen     mGrayPen;
+       wxPen     mLightPen;
+
+       bool      mIsCreated;
+       int       mSizeIsSet;
+
+protected:
+       void DestroyLabels();
+
+       // returns the label which match the current button state
+       virtual wxBitmap* GetStateLabel();
+
+       virtual void DrawShade( int outerLevel,
+                                                       wxDC&  dc,
+                                   wxPen& upperLeftSidePen,
+                                                   wxPen& lowerRightSidePen );
+
+       bool IsInWindow( int x,int y );
+
+public:
+
+       wxNewBitmapButton( const wxBitmap& labelBitmap = wxNullBitmap, 
+                                          const wxString& labelText   = "",
+                              int   alignText             = NB_ALIGN_TEXT_BOTTOM,
+                                          bool  isFlat                = TRUE,
+                                          // this is the default type of fired events
+                                          int firedEventType = wxEVT_COMMAND_MENU_SELECTED,
+                                          int marginX        = 2,
+                          int marginY        = 2,
+                                          int textToLabelGap = 2,
+                                          bool isSticky      = FALSE
+                            );
+
+       // use this constructor if buttons have to be persistant 
+        
+       wxNewBitmapButton( const wxString& bitmapFileName,
+                              const int       bitmapFileType = wxBITMAP_TYPE_BMP,
+                                          const wxString& labelText      = "",
+                              int alignText                  = NB_ALIGN_TEXT_BOTTOM,
+                                          bool  isFlat                   = TRUE,
+                                          // this is the default type of fired events
+                                          int firedEventType = wxEVT_COMMAND_MENU_SELECTED,
+                                          int marginX        = 2,
+                          int marginY        = 2,
+                                          int textToLabelGap = 2,
+                                          bool isSticky      = FALSE
+                            );
+
+       ~wxNewBitmapButton();
+
+       // should be called after Create();
+       virtual void Reshape();
+
+       // overridables
+       virtual void SetLabel(const wxBitmap& labelBitmap, const wxString& labelText = "" );
+       
+       virtual void SetAlignments( int alignText = NB_ALIGN_TEXT_BOTTOM,
+                                                               int marginX        = 2,
+                                                               int marginY        = 2,
+                                                               int textToLabelGap = 2);
+
+       virtual void DrawDecorations( wxDC& dc );
+       virtual void DrawLabel( wxDC& dc );
+
+       virtual void RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp, 
+                                                                  bool isEnabled = TRUE,
+                                                                  bool isPressed = FALSE);
+
+       virtual void RenderLabelImages();
+       virtual void RenderAllLabelImages();
+
+       // event handlers
+       void OnLButtonDown( wxMouseEvent& event );
+       void OnLButtonUp( wxMouseEvent& event );
+       void OnMouseMove( wxMouseEvent& event );
+       void OnSize( wxSizeEvent& event );
+       void OnPaint( wxPaintEvent& event );
+       void OnEraseBackground( wxEraseEvent& event );
+       void OnKillFocus( wxFocusEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __NEWBMPBTN_G__ */
+
diff --git a/contrib/include/wx/fl/panedrawpl.h b/contrib/include/wx/fl/panedrawpl.h
new file mode 100644 (file)
index 0000000..4fe1adb
--- /dev/null
@@ -0,0 +1,119 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Central header file for control-bar related classes
+//
+// Author:      Aleksandras Gluchovas <mailto:alex@soften.ktu.lt>
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __PANEDRAWPL_G__
+#define __PANEDRAWPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "panedrawpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+/*
+ * Simple, but all-in-one plugin implementation. Resembles look & feel of
+ * to MFC control-bars. Handles painting of pane and items in it.
+ * Fires bar/layout customization event, when user right-clicks bar/pane. 
+ * Hooking an instance of this and row-layouting plugins per each pane, 
+ * would be enough for the frame layout to function properly.
+ * (they are plugged in autimatically by wxFrameLayout class)
+ */
+
+class cbPaneDrawPlugin : public cbPluginBase
+{
+public:
+       DECLARE_DYNAMIC_CLASS( cbPaneDrawPlugin )
+protected:
+
+       // resizing bars/rows state variables
+       bool           mResizeStarted;
+       bool           mResizeCursorOn;
+       wxPoint        mDragOrigin;
+
+       cbBarInfo*     mpDraggedBar; // also used when in bar-drag action
+       cbRowInfo*     mpResizedRow;
+
+       bool           mRowHandleHitted;
+       bool           mIsUpperHandle;
+       bool           mBarHandleHitted;
+       bool           mIsLeftHandle;
+       bool           mBarContentHitted;
+
+       // contstraints for dragging the handle
+       wxRect         mHandleDragArea; 
+       bool           mHandleIsVertical;
+       int            mHandleOfs;
+       int            mDraggedDelta;
+       wxPoint        mPrevPos;
+
+       // used for handling, start-draw-in-area events
+       wxClientDC*    mpClntDc;      
+
+       cbDockPane*    mpPane; // is set up temorary short-cut, while handling event
+
+protected:
+       // helpers
+       void DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane );
+
+       virtual void DrawPaneShade( wxDC& dc, int alignment );
+       virtual void DrawPaneShadeForRow( cbRowInfo* pRow, wxDC& dc );
+
+       virtual void DrawUpperRowHandle( cbRowInfo* pRow, wxDC& dc );
+       virtual void DrawLowerRowHandle( cbRowInfo* pRow, wxDC& dc );
+
+       virtual void DrawUpperRowShades( cbRowInfo* pRow, wxDC& dc, int level );
+       virtual void DrawLowerRowShades( cbRowInfo* pRow, wxDC& dc, int level );
+
+       virtual void DrawBarInnerShadeRect( cbBarInfo* pBar, wxDC& dc );
+
+       virtual void DrawShade( int level, wxRect& rect, int alignment, wxDC& dc );
+       virtual void DrawShade1( int level, wxRect& rect, int alignment, wxDC& dc );
+
+       inline void SetLightPixel( int x, int y, wxDC& dc );
+       inline void SetDarkPixel ( int x, int y, wxDC& dc );
+
+public:
+       cbPaneDrawPlugin(void);
+
+       cbPaneDrawPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       virtual ~cbPaneDrawPlugin();
+
+       virtual cbPluginBase* Clone() { return new cbPaneDrawPlugin(0,0); }
+
+       // handlers for plugin-events
+
+       void OnLButtonDown( cbLeftDownEvent&   event );
+       void OnLDblClick  ( cbLeftDClickEvent& event );
+       void OnLButtonUp  ( cbLeftUpEvent&     event );
+       void OnRButtonUp  ( cbRightUpEvent&    event );
+       void OnMouseMove  ( cbMotionEvent&     event );
+
+       void OnDrawPaneBackground ( cbDrawPaneBkGroundEvent& event );
+       void OnDrawPaneDecorations( cbDrawPaneDecorEvent&    event );
+
+       void OnDrawRowDecorations ( cbDrawRowDecorEvent&     event );
+       void OnDrawRowHandles     ( cbDrawRowHandlesEvent&   event );
+       void OnDrawRowBackground  ( cbDrawRowBkGroundEvent&  event );
+                                                         
+       void OnSizeBarWindow      ( cbSizeBarWndEvent&       event );
+       void OnDrawBarDecorations ( cbDrawBarDecorEvent&     event );
+       void OnDrawBarHandles     ( cbDrawBarHandlesEvent&   event );
+
+       void OnStartDrawInArea    ( cbStartDrawInAreaEvent&  event );
+       void OnFinishDrawInArea   ( cbFinishDrawInAreaEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __PANEDRAWPL_G__ */
+
diff --git a/contrib/include/wx/fl/rowdragpl.h b/contrib/include/wx/fl/rowdragpl.h
new file mode 100644 (file)
index 0000000..6375d4f
--- /dev/null
@@ -0,0 +1,164 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ROWDRAGPL_G__
+#define __ROWDRAGPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "rowdragpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+/*
+ * Plugin adds row-dragging fuctionality to the pane.
+ * Handles mouse/movement and pane-background erasing plugin-events.
+ * Behaviour and appearence resembles drag & drop posotioning 
+ * of the toolbar-rows int Netscape Comunicator 4.xx.
+ */
+
+class cbRowDragPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbRowDragPlugin )
+public:
+       // background colours for the highlighted/unhighlighted icons
+
+       wxColour mHightColor;      // light-blue for NC-look
+       wxColour mLowColor;        // light-gray -/-
+       wxColour mTrianInnerColor; // blue       -/-
+       wxPen    mTrianInnerPen;   // black      -/-
+
+protected:
+       friend class cbRowDragPluginSerializer;
+
+       // drag & drop state variables
+       bool    mDragStarted;
+       bool    mDecisionMode;
+       wxPoint mDragOrigin;
+       int     mCurDragOfs;
+       bool    mCaptureIsOn;
+
+       // saved margins of the pane
+       int mSvTopMargin;
+       int mSvBottomMargin;
+       int mSvLeftMargin;
+       int mSvRightMargin;
+
+       //on-screen drawing state variables
+       wxBitmap* mpPaneImage;
+       wxBitmap* mpRowImage;
+       wxBitmap* mpCombinedImage;
+
+       wxScreenDC* mpScrDc;
+       wxRect    mCombRect;
+       wxSize    mRowImgDim;
+       int       mInitialRowOfs;
+
+       // NOTE:: if mpRowInFocus is not NULL, then mCollapsedIconInFocus is -1,
+       //        and v.v. (two different items cannot be in focus at the same time)
+
+       cbRowInfo* mpRowInFocus;
+       int        mCollapsedIconInFocus;
+
+       cbDockPane* mpPane; // is set up temorarely, while handling event
+
+       wxList      mHiddenBars;
+
+       wxBitmap* CaptureDCArea( wxDC& dc, wxRect& area );
+
+       // helpers for drag&drop
+
+       int GetHRowsCountForPane( cbDockPane* pPane );
+
+       void SetMouseCapture( bool captureOn );
+       void PrepareForRowDrag();
+       void ShowDraggedRow( int offset );
+       void ShowPaneImage();
+       void FinishOnScreenDraw();
+       void CollapseRow( cbRowInfo* pRow );
+       void ExpandRow( int collapsedIconIdx );
+       void InsertDraggedRowBefore( cbRowInfo* pBeforeRow );
+       bool ItemIsInFocus();
+       void CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx );
+       void UnhiglightItemInFocus();
+
+       cbRowInfo* GetFirstRow();
+
+       // "hard-coded metafile" for NN-look
+
+       virtual void DrawTrianUp( wxRect& inRect, wxDC& dc );
+       virtual void DrawTrianDown( wxRect& inRect, wxDC& dc );
+       virtual void DrawTrianRight( wxRect& inRect, wxDC& dc );
+       virtual void Draw3DPattern( wxRect& inRect, wxDC& dc );
+       virtual void DrawRombShades( wxPoint& p1, wxPoint& p2, wxPoint& p3, wxPoint& p4, wxDC& dc );
+       virtual void DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush );
+       virtual void DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush );
+       virtual void Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush );
+       virtual void DrawRectShade( wxRect& inRect, wxDC& dc, 
+                                                               int level, wxPen& upperPen, wxPen& lowerPen );
+
+       virtual void GetRowHintRect( cbRowInfo* pRow, wxRect& rect );
+       virtual void GetCollapsedInconRect( int iconIdx, wxRect& rect );
+
+       virtual int  GetCollapsedIconsPos();
+
+public:
+
+       cbRowDragPlugin(void);
+
+       cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask = wxALL_PANES );
+       virtual ~cbRowDragPlugin();
+
+       virtual cbPluginBase* Clone() { return new cbRowDragPlugin(NULL,0); }
+
+       virtual void OnInitPlugin();
+
+       // handlers for plugin events (appearence-independent logic)
+
+       void OnMouseMove  ( cbMotionEvent& event );
+       void OnLButtonDown( cbLeftDownEvent& event );
+       void OnLButtonUp  ( cbLeftUpEvent& event );
+       void OnDrawPaneBackground( cbDrawPaneDecorEvent& event );
+
+       // overridables (appearence-depedent)
+
+       virtual void DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted );
+       virtual void DrawCollapsedRowsBorder( wxDC& dc );
+       virtual void DrawRowsDragHintsBorder( wxDC& dc );
+       virtual void DrawRowDragHint( cbRowInfo* pRow, wxDC& dc, bool isHighlighted );
+       virtual void DrawEmptyRow( wxDC& dc, wxRect& rowBounds );
+
+       virtual int GetCollapsedRowIconHeight();
+       virtual int GetRowDragHintWidth();
+
+       virtual void SetPaneMargins();
+
+
+       virtual bool HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos );
+       virtual bool HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos );
+
+       DECLARE_EVENT_TABLE()
+};
+
+// internal helper-class
+
+class cbHiddenBarInfo : public wxObject
+{
+       DECLARE_DYNAMIC_CLASS( cbHiddenBarInfo )
+public:
+       cbBarInfo* mpBar;
+       int        mRowNo;
+       int        mIconNo;
+       int        mAlignment;
+};
+
+#endif /* __ROWDRAGPL_G__ */
+
diff --git a/contrib/include/wx/fl/rowlayoutpl.h b/contrib/include/wx/fl/rowlayoutpl.h
new file mode 100644 (file)
index 0000000..f44c74a
--- /dev/null
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     02/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __ROWLAYOUTPL_G__
+#define __ROWLAYOUTPL_G__
+
+#ifdef __GNUG__
+    #pragma interface "rowlayoutpl.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+/*
+ * Simple implementation of plugin, which handles row-layouting
+ * requests sent from Frame Layout
+ */
+
+class cbRowLayoutPlugin : public cbPluginBase
+{
+       DECLARE_DYNAMIC_CLASS( cbRowLayoutPlugin )
+protected:
+       cbDockPane* mpPane; // is set up temorarely, while handling event
+protected:
+
+       // not-fixed-bars layouting related helpers
+
+       void FitBarsToRange( int from, int till, cbBarInfo* pTheBar, cbRowInfo* pRow ); 
+       void RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow ); 
+       void MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve );
+       int  GetRowFreeSpace( cbRowInfo* pRow );
+       
+       void RecalcLengthRatios( cbRowInfo* pRow );
+       void ApplyLengthRatios( cbRowInfo* pRow );
+       void ExpandNotFixedBars( cbRowInfo* pRow );
+       void AdjustLengthOfInserted( cbRowInfo* pRow, cbBarInfo* pTheBar );
+
+       void DetectBarHandles( cbRowInfo* pRow );
+       void CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo );
+
+
+       // row-layouting helpers (simulate "bar-friction")
+
+       int  CalcRowHeight( cbRowInfo& row );
+       void LayoutItemsVertically( cbRowInfo& row );
+
+       void StickRightSideBars( cbBarInfo* pToBar );
+
+       void SlideLeftSideBars ( cbBarInfo* pTheBar );
+       void SlideRightSideBars( cbBarInfo* pTheBar );
+
+       void ShiftLeftTrashold ( cbBarInfo* pTheBar, cbRowInfo& row );
+       void ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row );
+
+       void InsertBefore( cbBarInfo* pBeforeBar, 
+                                          cbBarInfo* pTheBar,
+                                          cbRowInfo& row
+                                        );
+
+       void DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row );
+
+public:
+
+       cbRowLayoutPlugin(void);
+
+       cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES );
+
+       // event handlers
+
+       void OnResizeRow ( cbResizeRowEvent&  event );
+       void OnInsertBar ( cbInsertBarEvent&  event );
+       void OnRemoveBar ( cbRemoveBarEvent&  event );
+       void OnLayoutRow ( cbLayoutRowEvent&  event );
+       void OnLayoutRows( cbLayoutRowsEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __ROWLAYOUTPL_G__ */
+
diff --git a/contrib/include/wx/fl/toolwnd.h b/contrib/include/wx/fl/toolwnd.h
new file mode 100644 (file)
index 0000000..8f7fd5c
--- /dev/null
@@ -0,0 +1,216 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __TOOLWND_G__
+#define __TOOLWND_G__
+
+#ifdef __GNUG__
+    #pragma interface "toolwnd.h"
+#endif
+
+#include "wx/frame.h"
+#include "wx/dynarray.h"
+
+// fixed settings
+
+#define BTN_BOX_HEIGHT       12
+#define BTN_BOX_WIDTH        12
+#define BTN_X_WIEGHT         2
+
+class cbMiniButton;
+
+typedef cbMiniButton* cbMinitButtonPtrT;
+
+WX_DEFINE_ARRAY( cbMinitButtonPtrT, cbMiniButtonArrayT );
+
+class wxToolWindow : public wxFrame
+{
+       DECLARE_DYNAMIC_CLASS( wxToolWindow )
+
+public:        /** protected really, accessed only by serializers **/
+
+       cbMiniButtonArrayT mButtons;
+       wxWindow* mpClientWnd;
+
+       wxFont    mTitleFont;
+
+       int       mTitleHeight;
+       int       mClntHorizGap;
+       int       mClntVertGap;
+       int       mWndVertGap;
+       int       mWndHorizGap;
+       int       mButtonGap;
+       int       mInTitleMargin;
+       int       mHintBorder;
+
+       bool      mResizeStarted;
+       bool      mRealTimeUpdatesOn;
+
+       int       mMTolerance;
+
+       int       mCursorType;
+       bool      mMouseCaptured;
+
+       // drag&drop state variables
+
+       wxPoint     mDragOrigin;
+       wxRect      mInitialRect;
+       wxRect      mPrevHintRect;
+       wxScreenDC* mpScrDc;
+
+protected:
+       void GetScrWindowRect( wxRect& r );
+       void GetScrMousePos  ( wxMouseEvent& event, wxPoint& pos );
+       void SetHintCursor   ( int type );
+
+       void CalcResizedRect( wxRect& rect, wxPoint& delta, const wxSize& minDim );
+       void AdjustRectPos( const wxRect& original, const wxSize& newDim, wxRect& newRect );
+       wxSize GetMinimalWndDim();
+
+       void DrawHintRect( const wxRect& r );
+
+       int HitTestWindow( wxMouseEvent& event );
+
+       void LayoutMiniButtons();
+
+public:
+       
+       wxToolWindow();
+       ~wxToolWindow();
+
+       void SetClient( wxWindow* pWnd );
+       wxWindow* GetClient();
+
+       void SetTitleFont( wxFont& font );
+
+       // buttons are added in right-to-left order
+       void AddMiniButton( cbMiniButton* pBtn );
+
+       void OnPaint( wxPaintEvent& event );
+
+       void OnMotion( wxMouseEvent& event );
+       void OnLeftDown( wxMouseEvent& event );
+       void OnLeftUp( wxMouseEvent& event );
+       void OnSize( wxSizeEvent& event );
+
+       void OnEraseBackground( wxEraseEvent& event );
+
+       // overridables:
+
+       virtual wxSize GetPreferredSize( const wxSize& given );
+       virtual void OnMiniButtonClicked( int btnIdx ) {}
+       virtual bool HandleTitleClick( wxMouseEvent& event ) { return FALSE; }
+
+       DECLARE_EVENT_TABLE()
+};
+
+// FIXME:: the code below should be moved to a separate file
+
+#include "wx/fl/controlbar.h"
+
+class cbMiniButton : public wxObject
+{
+public:
+       wxPoint   mPos;
+       wxSize    mDim;
+       bool      mVisible;
+       bool      mEnabled;
+
+       wxFrameLayout* mpLayout;
+       cbDockPane*    mpPane;
+       cbPluginBase*  mpPlugin;
+
+       wxWindow*      mpWnd;
+
+       bool      mWasClicked;
+       bool      mDragStarted;
+
+       bool      mPressed;
+public:
+       cbMiniButton();
+
+       void SetPos( const wxPoint& pos );
+       bool HitTest( const wxPoint& pos );
+
+       void OnLeftDown( const wxPoint& pos );
+       void OnLeftUp( const wxPoint& pos );
+       void OnMotion( const wxPoint& pos );
+
+       void Refresh();
+       virtual void Draw( wxDC& dc );
+
+       bool WasClicked();
+       void Reset();
+
+       void Enable( bool enable ) { mEnabled = enable; }
+
+       bool IsPressed() { return mPressed; }
+};
+
+// classes specific to wxFrameLayout engine (FOR NOW in here...)
+
+class cbCloseBox : public cbMiniButton
+{
+public:
+       virtual void Draw( wxDC& dc );
+};
+
+class cbCollapseBox  : public cbMiniButton
+{
+public:
+       bool mIsAtLeft;
+
+       virtual void Draw( wxDC& dc );
+};
+
+class cbDockBox : public cbMiniButton
+{
+public:
+       virtual void Draw( wxDC& dc );
+};
+
+class cbFloatedBarWindow : public wxToolWindow
+{
+       DECLARE_DYNAMIC_CLASS( cbFloatedBarWindow )
+protected:
+       cbBarInfo*     mpBar;
+       wxFrameLayout* mpLayout;
+
+       friend class cbFloatedBarWindowSerializer;
+
+public:
+       cbFloatedBarWindow();
+
+       void SetBar( cbBarInfo* pBar );
+       void SetLayout( wxFrameLayout* pLayout );
+       cbBarInfo* GetBar();
+
+       // given coordinates are those of the bar itself
+       // floated container window's position and size
+       // are ajusted accordingly
+
+       void PositionFloatedWnd( int scrX,  int scrY,
+                                                        int width, int height );
+
+       // overriden methods of wxToolWindow
+
+       virtual wxSize GetPreferredSize( const wxSize& given );
+       virtual void OnMiniButtonClicked( int btnIdx );
+       virtual bool HandleTitleClick( wxMouseEvent& event );
+
+       void OnDblClick( wxMouseEvent& event );
+
+       DECLARE_EVENT_TABLE()
+};
+
+#endif /* __TOOLWND_G__ */
+
+
diff --git a/contrib/include/wx/fl/updatesmgr.h b/contrib/include/wx/fl/updatesmgr.h
new file mode 100644 (file)
index 0000000..e0e21c5
--- /dev/null
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas (@Lithuania)
+// Modified by:
+// Created:     19/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __UPDATESMGR_G__
+#define __UPDATESMGR_G__
+
+#ifdef __GNUG__
+    #pragma interface "updatesmgr.h"
+#endif
+
+#include "wx/fl/controlbar.h"
+
+/*
+ * class implements slightly optimized logic for refreshing
+ * areas of frame layout - which actually need to be updated. 
+ */
+
+class cbSimpleUpdatesMgr : public cbUpdatesManagerBase
+{
+       DECLARE_DYNAMIC_CLASS( cbSimpleUpdatesMgr )
+protected:
+
+       bool WasChanged( cbUpdateMgrData& data, wxRect& currentBounds );
+
+public:
+
+       cbSimpleUpdatesMgr(void) {}
+
+       cbSimpleUpdatesMgr( wxFrameLayout* pPanel );
+
+       // notificiactions received from Frame Layout (in the order, in which
+       // they usually would be invoked)
+
+       virtual void OnStartChanges();
+
+       virtual void OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane );
+       virtual void OnBarWillChange( cbBarInfo* pBar, cbRowInfo* pInRow, cbDockPane* pInPane );
+       virtual void OnPaneMarginsWillChange( cbDockPane* pPane );
+       virtual void OnPaneWillChange( cbDockPane* pPane );
+
+       virtual void OnFinishChanges();
+
+       // refreshes parts of the frame layout, which need an update
+       virtual void UpdateNow();
+};
+
+#endif /* __UPDATESMGR_G__ */
+
index 1133423958a98a6f1ca87ac503ec212f620d3358..2d1cd3a037a81be3f2ab6b545e7fbc8c3e4f186c 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
 # $Id$
 
-CONTRIB_SAMPLES=mmedia ogl stc gizmos canvas xrc plot applet
+CONTRIB_SAMPLES=mmedia ogl stc gizmos canvas xrc plot applet fl
 
 all:
        @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done
 
 all:
        @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done
diff --git a/contrib/samples/fl/Makefile.in b/contrib/samples/fl/Makefile.in
new file mode 100644 (file)
index 0000000..7d62d89
--- /dev/null
@@ -0,0 +1,10 @@
+# $Id$
+
+CONTRIB_SAMPLES=fl_demo1 fl_demo2 fl_sample1 fl_sample2 fl_sample3
+
+all:
+       @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done
+
+clean:
+       @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE) clean); done
+
diff --git a/contrib/samples/fl/bitmaps/bookmarks.bmp b/contrib/samples/fl/bitmaps/bookmarks.bmp
new file mode 100644 (file)
index 0000000..d6a3a79
Binary files /dev/null and b/contrib/samples/fl/bitmaps/bookmarks.bmp differ
diff --git a/contrib/samples/fl/bitmaps/class_icon.bmp b/contrib/samples/fl/bitmaps/class_icon.bmp
new file mode 100644 (file)
index 0000000..fe1a0c9
Binary files /dev/null and b/contrib/samples/fl/bitmaps/class_icon.bmp differ
diff --git a/contrib/samples/fl/bitmaps/class_icon1.bmp b/contrib/samples/fl/bitmaps/class_icon1.bmp
new file mode 100644 (file)
index 0000000..ef9846d
Binary files /dev/null and b/contrib/samples/fl/bitmaps/class_icon1.bmp differ
diff --git a/contrib/samples/fl/bitmaps/copy.bmp b/contrib/samples/fl/bitmaps/copy.bmp
new file mode 100644 (file)
index 0000000..5e66fc8
Binary files /dev/null and b/contrib/samples/fl/bitmaps/copy.bmp differ
diff --git a/contrib/samples/fl/bitmaps/cut.bmp b/contrib/samples/fl/bitmaps/cut.bmp
new file mode 100644 (file)
index 0000000..cf9247f
Binary files /dev/null and b/contrib/samples/fl/bitmaps/cut.bmp differ
diff --git a/contrib/samples/fl/bitmaps/file_icon.bmp b/contrib/samples/fl/bitmaps/file_icon.bmp
new file mode 100644 (file)
index 0000000..941b5cc
Binary files /dev/null and b/contrib/samples/fl/bitmaps/file_icon.bmp differ
diff --git a/contrib/samples/fl/bitmaps/folder_icon.bmp b/contrib/samples/fl/bitmaps/folder_icon.bmp
new file mode 100644 (file)
index 0000000..7e45f59
Binary files /dev/null and b/contrib/samples/fl/bitmaps/folder_icon.bmp differ
diff --git a/contrib/samples/fl/bitmaps/help_icon.bmp b/contrib/samples/fl/bitmaps/help_icon.bmp
new file mode 100644 (file)
index 0000000..cd1b362
Binary files /dev/null and b/contrib/samples/fl/bitmaps/help_icon.bmp differ
diff --git a/contrib/samples/fl/bitmaps/new.bmp b/contrib/samples/fl/bitmaps/new.bmp
new file mode 100644 (file)
index 0000000..1785f05
Binary files /dev/null and b/contrib/samples/fl/bitmaps/new.bmp differ
diff --git a/contrib/samples/fl/bitmaps/nextmark.bmp b/contrib/samples/fl/bitmaps/nextmark.bmp
new file mode 100644 (file)
index 0000000..ce916ee
Binary files /dev/null and b/contrib/samples/fl/bitmaps/nextmark.bmp differ
diff --git a/contrib/samples/fl/bitmaps/open.bmp b/contrib/samples/fl/bitmaps/open.bmp
new file mode 100644 (file)
index 0000000..8a2ac5c
Binary files /dev/null and b/contrib/samples/fl/bitmaps/open.bmp differ
diff --git a/contrib/samples/fl/bitmaps/paste.bmp b/contrib/samples/fl/bitmaps/paste.bmp
new file mode 100644 (file)
index 0000000..8c4b66b
Binary files /dev/null and b/contrib/samples/fl/bitmaps/paste.bmp differ
diff --git a/contrib/samples/fl/bitmaps/prevmark.bmp b/contrib/samples/fl/bitmaps/prevmark.bmp
new file mode 100644 (file)
index 0000000..4b2a12e
Binary files /dev/null and b/contrib/samples/fl/bitmaps/prevmark.bmp differ
diff --git a/contrib/samples/fl/bitmaps/res_icon.bmp b/contrib/samples/fl/bitmaps/res_icon.bmp
new file mode 100644 (file)
index 0000000..770cc35
Binary files /dev/null and b/contrib/samples/fl/bitmaps/res_icon.bmp differ
diff --git a/contrib/samples/fl/bitmaps/save.bmp b/contrib/samples/fl/bitmaps/save.bmp
new file mode 100644 (file)
index 0000000..02f8c7d
Binary files /dev/null and b/contrib/samples/fl/bitmaps/save.bmp differ
diff --git a/contrib/samples/fl/bitmaps/saveall.bmp b/contrib/samples/fl/bitmaps/saveall.bmp
new file mode 100644 (file)
index 0000000..bd04e1c
Binary files /dev/null and b/contrib/samples/fl/bitmaps/saveall.bmp differ
diff --git a/contrib/samples/fl/bitmaps/search.bmp b/contrib/samples/fl/bitmaps/search.bmp
new file mode 100644 (file)
index 0000000..dee7606
Binary files /dev/null and b/contrib/samples/fl/bitmaps/search.bmp differ
diff --git a/contrib/samples/fl/bitmaps/start95_dp.bmp b/contrib/samples/fl/bitmaps/start95_dp.bmp
new file mode 100644 (file)
index 0000000..d189435
Binary files /dev/null and b/contrib/samples/fl/bitmaps/start95_dp.bmp differ
diff --git a/contrib/samples/fl/bitmaps/start95_pr.bmp b/contrib/samples/fl/bitmaps/start95_pr.bmp
new file mode 100644 (file)
index 0000000..002c41d
Binary files /dev/null and b/contrib/samples/fl/bitmaps/start95_pr.bmp differ
diff --git a/contrib/samples/fl/bitmaps/tile.bmp b/contrib/samples/fl/bitmaps/tile.bmp
new file mode 100644 (file)
index 0000000..2269ce2
Binary files /dev/null and b/contrib/samples/fl/bitmaps/tile.bmp differ
diff --git a/contrib/samples/fl/fl_demo1/Makefile.in b/contrib/samples/fl/fl_demo1/Makefile.in
new file mode 100644 (file)
index 0000000..88f5502
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# "%W% %G%"
+#
+# Makefile : Builds sample on UNIX/Linux.
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../../..
+
+TARGET = fl_demo1
+
+program_dir = contrib/samples/fl/$(TARGET)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\"
+APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).o
+
+include $(top_builddir)/src/makeprog.env
diff --git a/contrib/samples/fl/fl_demo1/fl_demo.dsp b/contrib/samples/fl/fl_demo1/fl_demo.dsp
new file mode 100644 (file)
index 0000000..c4695b4
--- /dev/null
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="fl_demo1" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fl_demo1 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_demo1 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "fl_demo1 - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fl_demo1 - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "fl_demo1 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ELSEIF  "$(CFG)" == "fl_demo1 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "fl_demo1 - Win32 Release"
+# Name "fl_demo1 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\fl_demo1.cpp
+
+!IF  "$(CFG)" == "fl_demo1 - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "fl_demo1 - Win32 Debug"
+
+# ADD CPP /Yc"wx/wxprec.h"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\fl_demo1.rc
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/samples/fl/fl_demo1/fl_demo.dsw b/contrib/samples/fl/fl_demo1/fl_demo.dsw
new file mode 100644 (file)
index 0000000..f75328a
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "fl_demo1"=.\fl_demo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.cpp b/contrib/samples/fl/fl_demo1/fl_demo1.cpp
new file mode 100644 (file)
index 0000000..86641ce
--- /dev/null
@@ -0,0 +1,241 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+#pragma implementation "fl_demo1.h"
+#endif
+
+// 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"
+#endif
+
+#include "wx/textctrl.h"
+
+// fl headers
+#include "wx/fl/controlbar.h"     // core API
+
+// extra plugins
+#include "wx/fl/barhintspl.h"    // beveal for bars with "X"s and grooves
+#include "wx/fl/rowdragpl.h"     // NC-look with dragable rows
+#include "wx/fl/cbcustom.h"      // customization plugin
+#include "wx/fl/hintanimpl.h"
+
+// beuty-care
+#include "wx/fl/gcupdatesmgr.h"  // smooth d&d
+#include "wx/fl/antiflickpl.h"   // double-buffered repaint of decorations
+#include "wx/fl/dyntbar.h"       // auto-layouting toolbar
+#include "wx/fl/dyntbarhnd.h"    // control-bar dimension handler for it
+
+#include "fl_demo1.h"
+
+// comment it out if it breaks, (this is my workaround for MSDev 4.0 linker)
+
+char  wxDummyChar;
+
+
+IMPLEMENT_APP  (MyApp)
+
+bool MyApp::OnInit(void)
+{
+    MyFrame *frame = new MyFrame(NULL);
+    
+    frame->SetBackgroundColour( wxColour(192,192,192) );
+    
+    wxMenu *file_menu = new wxMenu;
+    
+    file_menu->Append( NEW_TEST_LOAD, "&Load layouts"  );
+    file_menu->Append( NEW_TEST_SAVE, "&Store layouts" );
+    file_menu->Append( NEW_TEST_EXIT, "E&xit" );
+    
+    wxMenuBar *menu_bar = new wxMenuBar;
+    
+    menu_bar->Append(file_menu,   "&File");
+    
+    frame->SetMenuBar(menu_bar);
+    
+    frame->CreateStatusBar(3);
+    
+    frame->Show(TRUE);
+    
+    frame->mpClientWnd->Refresh();
+    
+    SetTopWindow(frame);
+    
+    
+    wxMessageBox("Hello, this demo has a bunch of yet-not-fixed-bugs and misssing functionality\n" \
+                 "The ONLY purpose is to demostrate self-layouting toolbars,\nflat-bitmapped-buttons and 2-new FL-plugins" \
+                 "(cbRowDragPlugin & cbBarHintsPlugin)\n\n" \
+                 "BTW, disabled images and label-text are rendered at run-time" );
+    
+    return TRUE;
+}
+
+/***** Implementation for class MyFrame *****/
+
+BEGIN_EVENT_TABLE( MyFrame, wxFrame )
+    // EVT_CHAR_HOOK(MyFrame::OnKeyDown)
+    // EVT_PAINT( MyFrame::OnPaint )
+    EVT_MENU( NEW_TEST_SAVE, MyFrame::OnSave )
+    EVT_MENU( NEW_TEST_LOAD, MyFrame::OnLoad )
+    EVT_MENU( NEW_TEST_EXIT, MyFrame::OnExit )
+END_EVENT_TABLE()
+
+void MyFrame::OnLoad( wxCommandEvent& event )
+{                                              
+    wxMessageBox("Hey - you found a BIG question-mark !!");
+}
+
+void MyFrame::OnSave( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found another BIG question-mark !!");
+}
+
+void MyFrame::OnExit( wxCommandEvent& event )
+{
+    Destroy();
+}
+
+wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
+{
+    wxTextCtrl* pCtrl = 
+        
+        new wxTextCtrl( this, -1, value, 
+        wxDefaultPosition, wxSize(0,0), wxTE_MULTILINE );
+    
+    pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
+    
+    return pCtrl;
+}
+
+MyFrame::MyFrame(wxFrame *frame)
+    : wxFrame( frame, -1, "wxWindows 2.0 wxFrameLayout Test Application", wxDefaultPosition, 
+          wxSize( 700, 500 ), 
+          wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | 
+          wxTHICK_FRAME   | wxSYSTEM_MENU  | wxCAPTION, 
+          "freimas" )
+{
+    mpClientWnd = CreateTextCtrl( "Client window" );
+    
+    mpLayout = new wxFrameLayout( this, mpClientWnd );
+    
+#ifdef __WXGTK__
+    cbCommonPaneProperties props;
+    mpLayout->GetPaneProperties( props );
+    
+    props.mRealTimeUpdatesOn = FALSE; // real-time OFF!!!
+    
+    mpLayout->SetPaneProperties( props, wxALL_PANES );
+#endif
+    
+    mpLayout->SetUpdatesManager( new cbGCUpdatesMgr() );
+    
+    // this is now default...
+    //mpLayout->SetMargins( 1,1,1,1 ); // gaps for vertical/horizontal/right/left panes
+    
+    // setup plugins for testing
+    mpLayout->PushDefaultPlugins();
+    
+    mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for bars
+    mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
+    mpLayout->AddPlugin( CLASSINFO( cbRowDragPlugin  ) );
+    mpLayout->AddPlugin( CLASSINFO( cbAntiflickerPlugin ) );
+    mpLayout->AddPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) );
+    
+    // drop in some bars
+    cbDimInfo sizes0( 200,45, // when docked horizontally      
+                      200,85, // when docked vertically        
+                      175,35, // when floated                  
+                      FALSE,  // the bar is not fixed-size
+                      4,      // vertical gap (bar border)
+                      4       // horizontal gap (bar border)
+                    ); 
+    
+    cbDimInfo sizes1( 150,35, // when docked horizontally      
+                      150,85, // when docked vertically        
+                      175,35, // when floated                  
+                      TRUE,   // the bar is not fixed-size
+                      4,      // vertical gap (bar border)
+                      4       // horizontal gap (bar border)
+                    ); 
+    
+    cbDimInfo sizes2( 175,45, // when docked horizontally      
+                      175,37, // when docked vertically        
+                      170,35, // when floated                  
+                      TRUE,   // the bar is not fixed-size
+                      4,      // vertical gap (bar border)
+                      4,      // horizontal gap (bar border)
+                      new cbDynToolBarDimHandler()
+                    ); 
+    
+    mpLayout->AddBar( CreateTextCtrl("Hello"),  // bar window
+                      sizes0, FL_ALIGN_TOP,     // alignment ( 0-top,1-bottom, etc)
+                      0,                        // insert into 0th row (vert. position)
+                      0,                        // offset from the start of row (in pixels)
+                      "InfoViewer1",            // name to refere in customization pop-ups
+                      TRUE
+                    );
+    
+    mpLayout->AddBar( CreateTextCtrl("Bye"),    // bar window
+                      sizes0, FL_ALIGN_TOP,     // alignment ( 0-top,1-bottom, etc)
+                      1,                        // insert into 0th row (vert. position)
+                      0,                        // offset from the start of row (in pixels)
+                      "InfoViewer2",            // name to refere in customization pop-ups
+                      TRUE
+                    );
+    
+    mpLayout->AddBar( CreateTextCtrl("Fixed0"), // bar window
+                      sizes1, FL_ALIGN_TOP,     // alignment ( 0-top,1-bottom, etc)
+                      0,                        // insert into 0th row (vert. position)
+                      0,                        // offset from the start of row (in pixels)
+                      "ToolBar1",               // name to refere in customization pop-ups
+                      TRUE
+                    );
+    
+    wxDynamicToolBar* pToolBar = new wxDynamicToolBar();
+    
+    pToolBar->Create( this, -1 );
+    
+    // 1001-1006 ids of command events fired by added tool-buttons
+    
+    pToolBar->AddTool( 1001, BMP_DIR "new.bmp" );
+    pToolBar->AddTool( 1002, BMP_DIR "open.bmp" );
+    pToolBar->AddTool( 1003, BMP_DIR "save.bmp" );
+    
+    pToolBar->AddTool( 1004, BMP_DIR "cut.bmp" );
+    pToolBar->AddTool( 1005, BMP_DIR "copy.bmp" );
+    pToolBar->AddTool( 1006, BMP_DIR "paste.bmp" );
+    
+    
+    mpLayout->AddBar( pToolBar,             // bar window (can be NULL)
+                      sizes2, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc)
+                      0,                    // insert into 0th row (vert. position)
+                      0,                    // offset from the start of row (in pixels)
+                      "ToolBar2",           // name to refere in customization pop-ups
+                      FALSE
+                    );
+    
+    mpLayout->EnableFloating( TRUE ); // off, thinking bout wxGtk...
+}
+
+MyFrame::~MyFrame()
+{
+    if ( mpLayout) 
+        delete mpLayout; // should be destroyed manually
+}
+
diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.h b/contrib/samples/fl/fl_demo1/fl_demo1.h
new file mode 100644 (file)
index 0000000..8b0d02f
--- /dev/null
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __NEW_TEST_G__
+#define __NEW_TEST_G__
+
+#ifdef __GNUG__
+#pragma interface "fl_demo1.h"
+#endif
+
+#define NEW_TEST_SAVE 1101
+#define NEW_TEST_LOAD 1102
+#define NEW_TEST_EXIT 1103
+
+#include "wx/panel.h"
+
+// Define a new application type
+class MyApp: public wxApp
+{ 
+public:
+    bool OnInit(void);
+};
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ 
+public:
+    wxFrameLayout*  mpLayout;
+    wxTextCtrl*     mpClientWnd;
+    
+    wxTextCtrl* CreateTextCtrl( const wxString& value );
+    
+public:
+    MyFrame(wxFrame *frame);
+    virtual ~MyFrame();
+    
+    bool OnClose(void) { Show(FALSE); return TRUE; }
+    
+    void OnLoad( wxCommandEvent& event );
+    void OnSave( wxCommandEvent& event );
+    void OnExit( wxCommandEvent& event );
+    
+    DECLARE_EVENT_TABLE()
+};
+
+#endif
+
diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.rc b/contrib/samples/fl/fl_demo1/fl_demo1.rc
new file mode 100644 (file)
index 0000000..626b82f
--- /dev/null
@@ -0,0 +1,3 @@
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
diff --git a/contrib/samples/fl/fl_demo1/makefile.b32 b/contrib/samples/fl/fl_demo1/makefile.b32
new file mode 100644 (file)
index 0000000..710bb8d
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = ..\..\..\..
+TARGET = fl_demo1
+
+EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WSLIBDIR)\fl.lib
+!else
+EXTRALIBS = $(WSLIBDIR)\fld.lib
+!endif
+
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/contrib/samples/fl/fl_demo1/makefile.g95 b/contrib/samples/fl/fl_demo1/makefile.g95
new file mode 100644 (file)
index 0000000..27c8f17
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWorkshop for mingw & cygwin.
+
+WXDIR = ../../../..
+TARGET = fl_demo1
+
+EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\"
+EXTRALIBS     = $(WXDIR)/lib/libfl.a
+
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
diff --git a/contrib/samples/fl/fl_demo1/makefile.vc b/contrib/samples/fl/fl_demo1/makefile.vc
new file mode 100644 (file)
index 0000000..51eaae5
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds fl sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..\..
+TARGET = fl_demo1
+
+EXTRAINC = -DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WXDIR)\lib\fl.lib
+!else
+EXTRALIBS = $(WXDIR)\lib\fld.lib
+!endif
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.vc
diff --git a/contrib/samples/fl/fl_demo2/Makefile.in b/contrib/samples/fl/fl_demo2/Makefile.in
new file mode 100644 (file)
index 0000000..911f9b5
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# "%W% %G%"
+#
+# Makefile : Builds sample on UNIX/Linux.
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../../..
+
+TARGET = fl_demo2
+
+program_dir = contrib/samples/fl/$(TARGET)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\"
+APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).o
+
+include $(top_builddir)/src/makeprog.env
diff --git a/contrib/samples/fl/fl_demo2/fl_demo.dsp b/contrib/samples/fl/fl_demo2/fl_demo.dsp
new file mode 100644 (file)
index 0000000..a449ab0
--- /dev/null
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="fl_demo2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fl_demo2 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_demo2 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "fl_demo2 - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fl_demo2 - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "fl_demo2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ELSEIF  "$(CFG)" == "fl_demo2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "fl_demo2 - Win32 Release"
+# Name "fl_demo2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\fl_demo2.cpp
+
+!IF  "$(CFG)" == "fl_demo2 - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "fl_demo2 - Win32 Debug"
+
+# ADD CPP /Yc"wx/wxprec.h"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\fl_demo2.rc
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/samples/fl/fl_demo2/fl_demo.dsw b/contrib/samples/fl/fl_demo2/fl_demo.dsw
new file mode 100644 (file)
index 0000000..aadb7e2
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "fl_demo2"=.\fl_demo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.cpp b/contrib/samples/fl/fl_demo2/fl_demo2.cpp
new file mode 100644 (file)
index 0000000..d209ce6
--- /dev/null
@@ -0,0 +1,986 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "fl_demo2.h"
+#endif
+
+// 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"
+#endif
+
+// wxWindows headers.
+#include "wx/treectrl.h"
+#include "wx/imaglist.h"
+#include "wx/notebook.h" 
+
+// fl headers.
+#include "wx/fl/controlbar.h"
+#include "wx/fl/rowlayoutpl.h"
+#include "wx/fl/antiflickpl.h"
+#include "wx/fl/bardragpl.h"
+#include "wx/fl/cbcustom.h"
+#include "wx/fl/rowdragpl.h"
+
+// some extra fl plugins.
+#include "wx/fl/barhintspl.h"
+#include "wx/fl/hintanimpl.h"
+
+#include "wx/fl/dyntbar.h"
+#include "wx/fl/dyntbarhnd.h"  // fl-dimension-handler for dynamic toolbar
+
+#include "fl_demo2.h"
+
+/***** Implementation for class MyApp *****/
+
+// Create a new application object
+IMPLEMENT_APP    (MyApp)
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit(void)
+{
+    // Create the main frame window
+    MyFrame *frame = new MyFrame(NULL, "wxWindows 2.0 wxFrameLayout demo", 50, 50, 650, 540);
+    
+    // Give it an icon
+#ifdef __WINDOWS__
+    frame->SetIcon(wxIcon("mondrian"));
+#endif
+#ifdef __X__
+    frame->SetIcon(wxIcon("aiai.xbm"));
+#endif
+    
+    // Make a menubar
+    wxMenu *file_menu = new wxMenu;
+    wxMenu *active_menu = new wxMenu;
+    
+    file_menu->Append( ID_LOAD,  "&Load layouts"  );
+    file_menu->Append( ID_STORE, "&Store layouts" );
+    file_menu->AppendSeparator();
+    
+    file_menu->Append( ID_AUTOSAVE, "&Auto Save Layouts", "save layouts on exit", TRUE );
+    file_menu->AppendSeparator();
+    
+    file_menu->Append(MINIMAL_ABOUT, "A&bout !");
+    file_menu->Append(MINIMAL_QUIT, "E&xit\tTab");
+    
+    //active_menu->Append( ID_SETTINGS, "&Settings...\tCtrl" );
+    //active_menu->AppendSeparator();
+    
+    active_menu->Append( ID_REMOVE,    "&Remove Active" );
+    active_menu->Append( ID_REMOVEALL, "Remove &All" );
+    active_menu->Append( ID_RECREATE,  "Re&create" );
+    active_menu->AppendSeparator();
+    
+    active_menu->Append( ID_FIRST,  "Activate f&irst layout \tF1", "activate it", TRUE );
+    active_menu->Append( ID_SECOND, "Activate &second layout\tF2","activate it",  TRUE );
+    active_menu->Append( ID_THIRD,  "Activate &third layout\tF3","activate it",   TRUE );
+    
+    wxMenuBar *menu_bar = new wxMenuBar;
+    
+    menu_bar->Append(file_menu,   "&File");
+    menu_bar->Append(active_menu, "Active &Layout");
+    
+    frame->CreateStatusBar(3);
+    
+    frame->SetMenuBar(menu_bar);
+    
+    frame->SyncMenuBarItems();
+    
+    // Show the frame
+    frame->Show(TRUE);
+    
+    SetTopWindow(frame);
+    
+    return TRUE;
+}
+
+MyFrame::~MyFrame()
+{
+    // frame-layouts is not a windows (objects), thus should
+    // be cleaned up manually
+    
+    for( int i = 0; i != MAX_LAYOUTS; ++i )
+    {
+        if ( mLayouts[i] ) 
+            delete mLayouts[i];
+    }
+    
+    if ( mpNestedLayout   ) 
+        delete mpNestedLayout;
+    if ( mpAboutBoxLayout ) 
+        delete mpAboutBoxLayout;
+}
+
+/***** Implementation for class MyFrame *****/
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU( MINIMAL_QUIT,  MyFrame::OnQuit  )
+    EVT_MENU( MINIMAL_ABOUT, MyFrame::OnAbout )
+
+    EVT_MENU( ID_LOAD,      MyFrame::OnLoad      )
+    EVT_MENU( ID_STORE,     MyFrame::OnStore     )
+    EVT_MENU( ID_AUTOSAVE,  MyFrame::OnAutoSave  )
+    //EVT_MENU( ID_SETTINGS,  MyFrame::OnSettings  )
+    EVT_MENU( ID_REMOVE,    MyFrame::OnRemove    )
+    EVT_MENU( ID_REMOVEALL, MyFrame::OnRemoveAll )
+    EVT_MENU( ID_RECREATE,  MyFrame::OnRecreate  )
+    EVT_MENU( ID_FIRST,     MyFrame::OnFirst     )
+    EVT_MENU( ID_SECOND,    MyFrame::OnSecond    )
+    EVT_MENU( ID_THIRD,     MyFrame::OnThird     )
+
+    EVT_BUTTON( ID_SAY_ITSOK, MyFrame::OnSayItsOk )
+    EVT_BUTTON( ID_BTN_YES,   MyFrame::OnBtnYes )
+    EVT_BUTTON( ID_BTN_NO,    MyFrame::OnBtnNo )
+    EVT_BUTTON( ID_BTN_ESC,   MyFrame::OnBtnEsc )
+
+    EVT_CHAR_HOOK( MyFrame::OnChar )
+END_EVENT_TABLE()
+
+// My frame constructor
+
+MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
+    : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)),
+    mpNestedLayout( NULL ),
+    mpAboutBoxLayout( NULL ),
+
+    mActiveLayoutNo( FIRST_LAYOUT ),
+    mAutoSave( TRUE ),
+    mSavedAlready( FALSE ),
+    mpClntWindow( NULL ),
+
+    mImageList( 16,16, FALSE, 2 )
+{
+    mpInternalFrm = (wxPanel*)this;
+    
+    mAboutBox.Create( this, -1,  "About box in wxWindows style...",
+                      wxDefaultPosition,
+                      wxSize( 385,220),
+                      wxDIALOG_MODAL | wxDEFAULT_DIALOG_STYLE | wxTAB_TRAVERSAL );
+    
+    int i = 0;
+    for( i = 0; i != MAX_LAYOUTS; ++i ) 
+        mLayouts[i] = NULL;
+    
+    // image-list is one of the few objects which
+    // currently cannot be serialized, create it first 
+    // and use it as initial reference (IR)
+    
+    wxBitmap bmp1,bmp2;
+    
+    if ( wxFileExists( BMP_DIR "folder_icon.bmp" ) )
+        bmp1.LoadFile( BMP_DIR "folder_icon.bmp", wxBITMAP_TYPE_BMP );
+    
+    if ( wxFileExists( BMP_DIR "class_icon1.bmp" ) )
+        bmp2.LoadFile( BMP_DIR "class_icon1.bmp", wxBITMAP_TYPE_BMP );
+    
+    mImageList.Add( bmp1 );
+    mImageList.Add( bmp2 );
+    
+    InitAboutBox();
+    
+    // create multiple layouts
+    
+    mpNestedLayout = 0;
+    
+    mpClntWindow = CreateTxtCtrl("client window");
+    
+    // Create all layouts
+    for( i = 0; i != MAX_LAYOUTS; ++i )
+    {    
+        CreateLayout( i );
+    }
+    // hide others
+    for( i = SECOND_LAYOUT; i != MAX_LAYOUTS; ++i )
+    {
+        mLayouts[i]->HideBarWindows();
+    }
+    
+    // activate first one 
+    mLayouts[FIRST_LAYOUT]->Activate();
+    mActiveLayoutNo = FIRST_LAYOUT;
+}
+
+/*** event handlers ***/
+
+bool MyFrame::OnClose(void)
+{
+    //  USEFUL TRICK:: avoids flickering of application's frame 
+    //                 when closing NN windows on exit:
+    
+    this->Show(FALSE);
+    
+    if ( (mAutoSave && mSavedAlready) || !mAutoSave )
+    {
+    }
+    else
+    {
+        wxCommandEvent evt;
+        this->OnStore(evt);
+    }
+    
+    mAboutBox.Destroy();
+    this->Destroy();
+    
+    return TRUE;
+}
+
+void MyFrame::OnLoad( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found a BIG question-mark !!");
+}
+
+void MyFrame::OnStore( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found another BIG question-mark !!");
+}
+
+void MyFrame::OnAutoSave( wxCommandEvent& event )
+{
+    mAutoSave = !mAutoSave;
+    
+    wxCommandEvent evt;
+    this->OnStore(evt);
+    
+    SyncMenuBarItems();
+}
+
+void MyFrame::OnRemove( wxCommandEvent& event )
+{
+    RemoveLayout( mActiveLayoutNo );
+    
+    Refresh();
+}
+
+void MyFrame::OnRemoveAll( wxCommandEvent& event )
+{
+    for( int i = 0; i != MAX_LAYOUTS; ++i )
+    {    
+        RemoveLayout( i );
+    }
+
+    Refresh();
+}
+
+
+void MyFrame::OnRecreate( wxCommandEvent& event )
+{
+    OnRemove( event ); // first destroy active layout
+    
+    CreateLayout( mActiveLayoutNo );
+    
+    mLayouts[mActiveLayoutNo]->Activate();
+}
+
+void MyFrame::OnFirst( wxCommandEvent& event )
+{
+    ActivateLayout( FIRST_LAYOUT );
+}
+
+void MyFrame::OnSecond( wxCommandEvent& event )
+{
+    ActivateLayout( SECOND_LAYOUT );
+}
+
+void MyFrame::OnThird( wxCommandEvent& event )
+{
+    ActivateLayout( THIRD_LAYOUT );
+}
+
+void MyFrame::OnQuit( wxCommandEvent& event )
+{
+    //  USEFUL TRICK:: avoids flickering of application's frame 
+    //                 when closing NN windows on exit:
+    
+    this->Show(FALSE);
+    
+    if ( (mAutoSave && mSavedAlready) || !mAutoSave )
+    {
+    }
+    else
+    {
+        wxCommandEvent evt;
+        this->OnStore(evt);
+    }
+    
+    Destroy();
+}
+
+void MyFrame::OnAbout( wxCommandEvent& event )
+{
+    wxFont font;
+#ifdef __WXMSW__
+    font.SetFaceName("MS Sans Serif");
+#else
+    font.SetFamily( wxSWISS );
+#endif
+    
+    font.SetStyle( wxSLANT );
+    font.SetWeight( wxNORMAL );
+    font.SetPointSize( 8 );
+    
+#ifdef __WXMSW__
+    font.RealizeResource();
+#endif
+    
+    mAboutBox.Center( wxBOTH );
+    mAboutBox.Show(TRUE);
+    
+}
+
+void MyFrame::OnChar( wxKeyEvent& event )
+{
+    wxCommandEvent evt;
+    
+    if ( event.m_keyCode == WXK_F1 )
+    {
+        this->OnFirst( evt );
+    }
+    else
+    {
+        if ( event.m_keyCode == WXK_F2 )
+        {
+            this->OnSecond( evt );
+        }
+        else
+        {
+            if ( event.m_keyCode == WXK_F3 )
+            {   
+                this->OnThird( evt );
+            }
+            if ( event.m_keyCode == WXK_F4 && !event.AltDown() )
+            {   
+                // "AI" :-)
+                wxMessageBox("There are only 3 layouts in this demo :-(");
+            }
+            else
+            {
+                if ( event.m_keyCode == WXK_TAB )
+                {
+                    //  USEFUL TRICK:: avoids flickering of application's frame 
+                    //                 when closing NN windows on exit:
+                    
+                    this->Show(FALSE);
+                    
+                    if ( (mAutoSave && mSavedAlready) || !mAutoSave )
+                    {
+                    }
+                    else
+                    {
+                        wxCommandEvent evt;
+                        this->OnStore(evt);
+                    }
+                    
+                    Destroy();
+                }
+                else
+                {
+                    event.Skip();
+                }
+            }
+        }
+    }
+}
+
+void MyFrame::OnSayItsOk( wxCommandEvent& event )
+{
+    wxMessageBox("It's OK  :-)\n\n now click on the border around the button\n and try dragging it!" );
+}
+
+void MyFrame::OnBtnYes( wxCommandEvent& event )
+{
+    mAboutBox.Show(FALSE);
+}
+
+void MyFrame::OnBtnNo( wxCommandEvent& event )
+{
+    mAboutBox.Show(FALSE);
+}
+
+void MyFrame::OnBtnEsc( wxCommandEvent& event )
+{
+    mAboutBox.Show(FALSE);
+}
+
+/*** helper methods ***/
+
+void MyFrame::InitAboutBox()
+{
+    wxPanel* pArea = new wxPanel();
+    
+    pArea->Create( &mAboutBox, -1 );
+    
+    new wxStaticText(pArea, -1, "This is wxFrameLayout contribution demo.",
+        wxPoint(10, 10) );
+    
+    new wxStaticText(pArea, -1, "Aleksandras Gluchovas (c) 1998",
+        wxPoint(10, 30) );
+    
+    new wxStaticText(pArea, -1, "<mailto:alex@soften.ktu.lt>",
+        wxPoint(10, 50) );
+    
+    mpAboutBoxLayout = new wxFrameLayout( &mAboutBox, pArea, TRUE );
+    
+    wxFrameLayout& layout = *mpAboutBoxLayout;
+    
+    cbDimInfo sizes( 90,40,     // when docked horizontally
+                     45,55,     // when docked vertically
+                     90,40,     // when floated
+                     TRUE, 4, 4 // true - bar is fixed-size
+                   );  
+    
+    
+    wxButton* pYes = CreateButton("&Yes",   &mAboutBox, ID_SAY_ITSOK );
+    wxButton* pNo  = CreateButton("&No",    &mAboutBox, ID_BTN_NO );
+    wxButton* pEsc = CreateButton("Cancel", &mAboutBox, ID_BTN_ESC );
+    
+    layout.AddBar( pEsc, sizes,  FL_ALIGN_BOTTOM, 0, 20, "cancel button");
+    layout.AddBar( pNo,  sizes,  FL_ALIGN_BOTTOM, 0, 20, "no button");
+    layout.AddBar( pYes, sizes,  FL_ALIGN_BOTTOM, 0, 20, "yes button");
+    
+    layout.mBorderPen.SetColour( 192, 192, 192 );
+    layout.SetMargins( 15, 15, 15, 15, wxALL_PANES );
+    
+    cbCommonPaneProperties props;
+    
+    layout.GetPaneProperties( props, FL_ALIGN_TOP );
+    
+    props.mShow3DPaneBorderOn = FALSE;
+    
+    layout.SetPaneProperties( props, wxALL_PANES );
+    
+    layout.Activate();
+    
+    pYes->SetDefault();
+    pYes->SetFocus();
+}
+
+wxTextCtrl* MyFrame::CreateTxtCtrl( const wxString& txt, wxWindow* parent ) 
+{
+    return new wxTextCtrl( (parent != NULL ) ? parent : mpInternalFrm,
+                            -1, txt, wxDefaultPosition, wxDefaultSize,                                   
+                            wxTE_MULTILINE );
+}
+
+wxButton* MyFrame::CreateButton( const wxString& label,
+                                wxWindow* pParent, long id )
+{
+    return new wxButton( (pParent)?pParent : mpInternalFrm, id, 
+                            label, wxPoint( 0,0 ), wxSize( 0,0 ) );
+}
+
+wxTreeCtrl* MyFrame::CreateTreeCtrl( const wxString& label )
+{
+    wxTreeCtrl* pTree = new wxTreeCtrl( mpInternalFrm, -1 );
+    
+    int rootid = pTree->AppendItem( (long)0, label, 0);
+    
+    if ( label[0] != 'X' )
+    {
+        pTree->AppendItem(rootid, "Leaf1", 0);
+        pTree->AppendItem(rootid, "Leaf2", 0);
+    }
+    else
+    {
+        pTree->AppendItem(rootid, "Scully", 0);
+        pTree->AppendItem(rootid, "Mulder", 0);
+    }
+    
+    return pTree;
+}
+
+wxChoice* MyFrame::CreateChoice( const wxString& txt )
+{
+    wxString choice_strings[5];
+    
+    choice_strings[0] = txt;
+    choice_strings[1] = "Julian";
+    choice_strings[2] = "Hattie";
+    choice_strings[3] = "Ken";
+    choice_strings[4] = "Dick";
+    
+    wxChoice *choice = new wxChoice( mpInternalFrm, 301, wxDefaultPosition, 
+                                        wxDefaultSize, 5, choice_strings);
+    
+    choice->SetSelection(0);
+    
+    return choice;
+}
+
+// helper
+
+void MyFrame::AddSearchToolbars( wxFrameLayout& layout, wxWindow* pParent )
+{
+    cbDimInfo sizes2( 275,38,   // when docked horizontally      
+                      45,275,   // when docked vertically        
+                      80,30,    // when floated                  
+                      TRUE,     // the bar is fixed-size
+                      4,        // vertical gap (bar border)
+                      4,        // horizontal gap (bar border)
+                      new cbDynToolBarDimHandler()
+                    ); 
+    
+    cbDimInfo sizes3( 275,55,   // when docked horizontally      
+                      275,60,   // when docked vertically        
+                      45,130,   // when floated                  
+                      TRUE,     // the bar is fixed-size
+                      4,        // vertical gap (bar border)
+                      4,        // horizontal gap (bar border)
+                      new cbDynToolBarDimHandler()
+                    ); 
+    
+    cbDimInfo sizes4( 430,35,   // when docked horizontally      
+                      44,375,   // when docked vertically        
+                      80,100,   // when floated                  
+                      TRUE,     // the bar is fixed-size
+                      4,        // vertical gap (bar border)
+                      4,        // horizontal gap (bar border)
+                      new cbDynToolBarDimHandler()
+                    ); 
+    
+    wxDynamicToolBar* pTBar2 = new wxDynamicToolBar( mpInternalFrm, -1 );
+    
+    wxChoice* pChoice = new wxChoice( pTBar2, -1, wxDefaultPosition, wxSize( 140,25 ) );
+    
+    pTBar2->AddTool( 1, pChoice );
+    pTBar2->AddTool( 2, BMP_DIR "search.bmp" );
+    //pTBar2->AddSeparator();
+    pTBar2->AddTool( 3, BMP_DIR "bookmarks.bmp" );
+    pTBar2->AddTool( 4, BMP_DIR "nextmark.bmp" );
+    pTBar2->AddTool( 5, BMP_DIR "prevmark.bmp" );
+    
+    wxDynamicToolBar* pTBar3 = new wxDynamicToolBar( mpInternalFrm, -1 );
+    
+    pTBar3->AddTool( 1, BMP_DIR "open.bmp", wxBITMAP_TYPE_BMP, " Open " );
+    pTBar3->AddTool( 2, BMP_DIR "save.bmp", wxBITMAP_TYPE_BMP, " Save " );
+    pTBar3->AddTool( 3, BMP_DIR "saveall.bmp", wxBITMAP_TYPE_BMP, " Save All " );
+    //pTBar3->AddSeparator();
+    pTBar3->AddTool( 4, BMP_DIR "cut.bmp",   wxBITMAP_TYPE_BMP, " Open " );
+    pTBar3->AddTool( 5, BMP_DIR "copy.bmp",  wxBITMAP_TYPE_BMP, " Copy " );
+    pTBar3->AddTool( 6, BMP_DIR "paste.bmp", wxBITMAP_TYPE_BMP, " Paste " );
+    
+#ifdef __WXMSW__
+    pTBar3->EnableTool( 2, FALSE );
+#endif
+    
+    wxDynamicToolBar* pTBar4 = new wxDynamicToolBar( mpInternalFrm, -1 );
+    
+    pTBar4->AddTool( 1, BMP_DIR "bookmarks.bmp", wxBITMAP_TYPE_BMP, "Bookmarks ", TRUE );
+    pTBar4->AddTool( 2, BMP_DIR "nextmark.bmp",  wxBITMAP_TYPE_BMP, "Next bookmark ", TRUE );
+    pTBar4->AddTool( 3, BMP_DIR "prevmark.bmp",  wxBITMAP_TYPE_BMP, "Prev bookmark ", TRUE );
+    //pTBar4->AddSeparator();
+    pTBar4->AddTool( 4, BMP_DIR "search.bmp", wxBITMAP_TYPE_BMP, "Search ", TRUE );
+    
+#ifdef __WXMSW__
+    pTBar4->EnableTool( 4, FALSE );
+#endif
+    
+    layout.AddBar( pTBar2,              
+                   sizes2, FL_ALIGN_TOP,    
+                   0,                
+                   0,                
+                   "Search",       
+                   TRUE
+                 );
+    
+    layout.AddBar( pTBar3,              
+                   sizes3, FL_ALIGN_BOTTOM, 
+                   0,                
+                   0,                
+                   "Titled",       
+                   TRUE
+                 );
+    
+    layout.AddBar( pTBar4,              
+                   sizes4, FL_ALIGN_BOTTOM, 
+                   1,                
+                   0,                
+                   "Bookmarks",       
+                   TRUE
+                 );
+}
+
+wxWindow* MyFrame::CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent )
+{
+    bool isNested = (pParent != mpInternalFrm);
+    
+    // check if we're craeting nested layout
+    if ( isNested )
+    {
+        layout.mBorderPen.SetColour( 128,255,128 );
+        
+        // if so, than make border smaller
+        for( int i = 0; i != MAX_PANES; ++i  )
+        {
+            cbDockPane& pane = *layout.GetPane( i );
+            
+            pane.mTopMargin    = 5;
+            pane.mBottomMargin = 5;
+            pane.mLeftMargin   = 5;
+            pane.mRightMargin  = 5;
+        }
+    }
+    
+    int cbWidth  = 200;
+    int cbHeight = ( isNested ) ? 50 : 150;
+    
+    cbDimInfo sizes4( cbWidth,cbHeight,
+                      cbWidth,cbHeight,
+                      cbWidth,cbHeight, FALSE );
+    
+    cbWidth  = 75;
+    cbHeight = 31;
+    
+    cbDimInfo sizes5( cbWidth,cbHeight,
+                      42,65,
+                      cbWidth,cbHeight, TRUE,
+                      3,                       // vertical gap (bar border)
+                      3                        // horizontal gap (bar border)
+                    ); 
+    
+    // create "workplace" window in the third layout
+    // SEB: originally here was a wxpp (wxWorkshop) class demotrated
+    //    wxTabbedWindow* pMiniTabArea = new wxTabbedWindow();
+    //    pMiniTabArea->Create( pParent, -1 );
+    
+    
+    wxTreeCtrl* pClassView = new wxTreeCtrl( pParent, -1, 
+                wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS );
+    
+    pClassView->SetImageList( &mImageList );
+    
+    wxTreeItemId rootId = pClassView->AddRoot( "wxWindows 2.0 classes", 0 );
+    
+    pClassView->AppendItem( rootId, "wxWin Dynamic classes (grabbed at run-time)", 0 );
+    pClassView->AppendItem( rootId, "serializer-classes (grabbed at run-time)",    0 );
+    
+    // now create "output" window
+    wxNotebook*        pTabbedArea = new wxNotebook(pParent, -1);   
+    // SEB: originally here was a wxpp (wxWorkshop) class used
+    //    wxPaggedWindow* pTabbedArea = new wxPaggedWindow();
+    //    pTabbedArea->Create( pParent, -1 );
+    
+    wxPanel* pSheet3 = new wxPanel();
+    pSheet3->Create( pTabbedArea, -1 );
+    pSheet3->Show(FALSE);
+    
+    pTabbedArea->AddPage( CreateTxtCtrl("build", pTabbedArea), "Build");
+    pTabbedArea->AddPage( CreateTxtCtrl("debug", pTabbedArea), "Debug");
+    pTabbedArea->AddPage( pSheet3, "is THIS recursive - or what !?");
+    pTabbedArea->AddPage( CreateTxtCtrl("profile", pTabbedArea), "Profile");
+    
+    layout.AddBar( new StartButton95(pParent), sizes5, FL_ALIGN_TOP, 0, 0, "Start..." );
+    layout.AddBar( pClassView, sizes4, FL_ALIGN_LEFT, 0, 0, "Project Workplace" );
+    layout.AddBar( pTabbedArea, sizes4, FL_ALIGN_BOTTOM, 0, 50, "Output" );
+    
+    return pSheet3;
+}
+
+void MyFrame::DropInSomeBars( int layoutNo )
+{
+    /* create once... and forget! */
+    
+    // setup dimension infos for various bar shapes
+    
+    int cbWidth  = 90;
+    int cbHeight = 30;
+    
+    if ( layoutNo == SECOND_LAYOUT ) 
+        cbHeight = 60;
+    
+    wxFrameLayout& layout = *mLayouts[layoutNo];
+    
+    cbDimInfo sizes( cbWidth,cbHeight, // when docked horizontally
+                     cbWidth,cbHeight, // when docked vertically
+                     cbWidth,cbHeight, // when floated
+                     TRUE              // true - bar is fixed-size
+                   );  
+    
+    cbWidth  = 120;
+    
+    cbDimInfo sizes1( cbWidth,cbHeight,
+                      cbWidth,cbHeight,
+                      cbWidth,cbHeight, FALSE ); // false - bar is "flexible"
+
+    cbWidth  = 120;
+    cbHeight = 40;
+    
+    cbDimInfo sizes3( cbWidth,cbHeight,
+                      cbWidth,cbHeight,
+                      cbWidth,cbHeight, TRUE ); // -/-
+    
+    cbWidth  = 200;
+    cbHeight = 150;
+    
+    cbDimInfo sizes4( cbWidth,cbHeight,
+                      cbWidth,cbHeight,
+                      cbWidth,cbHeight, FALSE ); // -/-
+    
+    cbWidth  = 63;
+    cbHeight = 31;
+    
+    cbDimInfo sizes5( cbWidth,cbHeight,
+                      cbHeight,cbWidth,
+                      cbWidth,cbHeight, TRUE,
+                      3,                        // vertical gap (bar border)
+                      3                         // horizontal gap (bar border)
+                    ); // -/-
+    
+    
+    if ( layoutNo == FIRST_LAYOUT )
+    {
+        // add 4 fixed-size bars (`sizes' dim-info) and one "flexible" (with `sizes1' dim-info)
+        
+        wxWindow* pGreenOne    = new MyTestPanel(mpInternalFrm);
+        
+        pGreenOne->SetBackgroundColour( wxColour(128,255,128) );
+        
+        layout.AddBar( pGreenOne,                      sizes,  FL_ALIGN_TOP,         0, 50, "Bar1", TRUE );
+        layout.AddBar( new MyTestPanel(mpInternalFrm), sizes,  FL_ALIGN_TOP,         2, 50, "Bar2", TRUE );
+        layout.AddBar( new MyTestPanel(mpInternalFrm), sizes,  FL_ALIGN_BOTTOM,      2, 50, "Bar3", TRUE );
+        layout.AddBar( new MyTestPanel(mpInternalFrm), sizes,  FL_ALIGN_LEFT,        2, 50, "Bar4", TRUE );
+        layout.AddBar( new MyTestPanel(mpInternalFrm), sizes1, wxCBAR_HIDDEN, 2, 50, "Super-Bar", TRUE );
+    }
+    else
+    {
+        if ( layoutNo == SECOND_LAYOUT )
+        {
+            // show off various wx-controls in the second layout
+            
+            layout.AddBar( CreateTxtCtrl(),           sizes,  FL_ALIGN_TOP,    0, 50,  "Fixed text Area&0"     );
+            layout.AddBar( CreateButton("OK"),        sizes,  FL_ALIGN_TOP,    0, 100, "First Button"    );
+            layout.AddBar( CreateTxtCtrl(),           sizes1, FL_ALIGN_BOTTOM, 0, 50,  "First Tree"  );
+            layout.AddBar( CreateTreeCtrl("Root"),    sizes1, FL_ALIGN_LEFT,   0, 0,   "TreeCtrl Window" );
+            layout.AddBar( CreateChoice("Choice 1"),  sizes3, FL_ALIGN_TOP,    0, 0,   "Choice 1 (buggy)", FALSE, wxCBAR_HIDDEN );
+            layout.AddBar( CreateChoice("Choice 2"),  sizes3, FL_ALIGN_TOP,    0, 0,   "Choice 2 (buggy)", FALSE, wxCBAR_HIDDEN );
+            layout.AddBar( CreateTreeCtrl("X-Files"), sizes1, FL_ALIGN_RIGHT,  0, 100, "X-Files" );
+            layout.AddBar( CreateTxtCtrl("smaller1"), sizes3, FL_ALIGN_TOP,    0, 50,  "smaller Area1"     );
+            layout.AddBar( CreateTxtCtrl("smaller2"), sizes3, FL_ALIGN_TOP,    0, 50,  "sm&ller Area2"     );
+        }
+        else
+        {
+            if ( layoutNo == THIRD_LAYOUT  )
+            {
+#ifdef __WXGTK__
+                cbCommonPaneProperties props;
+                layout.GetPaneProperties( props );
+                props.mRealTimeUpdatesOn = FALSE; // real-time OFF for gtk!!!
+                layout.SetPaneProperties( props, wxALL_PANES );
+#endif
+                
+                layout.AddBar( CreateTxtCtrl("Tool1"), sizes3,  FL_ALIGN_TOP,  0, 50,  "Fixed text Area1" );
+                layout.AddBar( CreateTxtCtrl("Tool2"), sizes3,  FL_ALIGN_TOP,  0, 50,  "Fixed text Area2" );
+                layout.AddBar( CreateTxtCtrl("Tool3"), sizes3,  FL_ALIGN_TOP,  0, 50,  "Fixed text Area3" );
+                layout.AddBar( CreateTxtCtrl("Tool4"), sizes3,  FL_ALIGN_TOP,  1, 50,  "Fixed text Area4" );
+                layout.AddBar( CreateTxtCtrl("Tool5"), sizes3,  FL_ALIGN_TOP,  1, 50,  "Fixed text Area5" );
+                layout.AddBar( CreateTxtCtrl("Tool6"), sizes3,  FL_ALIGN_TOP,  1, 50,  "Fixed text Area6" );
+                layout.AddBar( CreateTxtCtrl("Tool7"), sizes3,  FL_ALIGN_TOP,  2,250,  "Fixed text Area7" );
+                
+                cbDimInfo sizes10( 175,35, // when docked horizontally      
+                                   175,38, // when docked vertically        
+                                   170,35, // when floated                  
+                                   TRUE,   // the bar is not fixed-size
+                                   4,      // vertical gap (bar border)
+                                   4,      // horizontal gap (bar border)
+                                   new cbDynToolBarDimHandler()
+                                 ); 
+                
+                wxDynamicToolBar* pToolBar = new wxDynamicToolBar();
+                
+                pToolBar->Create( mpInternalFrm, -1 );
+                
+                // 1001-1006 ids of command events fired by added tool-buttons
+                
+                pToolBar->AddTool( 1001, BMP_DIR "new.bmp" );
+                pToolBar->AddTool( 1002, BMP_DIR "open.bmp" );
+                pToolBar->AddTool( 1003, BMP_DIR "save.bmp" );
+                
+                pToolBar->AddTool( 1004, BMP_DIR "cut.bmp" );
+                pToolBar->AddTool( 1005, BMP_DIR "copy.bmp" );
+                pToolBar->AddTool( 1006, BMP_DIR "paste.bmp" );
+                
+                layout.AddBar( pToolBar,              // bar window (can be NULL)
+                               sizes10, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc)
+                               0,                     // insert into 0th row (vert. position)
+                               0,                     // offset from the start of row (in pixels)
+                               "Real-Toolbar",        // name to refere in customization pop-ups
+                               FALSE
+                             );
+                
+                // create first "developement" layout
+                AddSearchToolbars( layout, mpInternalFrm);
+                
+                wxWindow* pSheet3 = CreateDevLayout( layout, mpInternalFrm);
+                
+                // create another ***secreat developement*** layout inside
+                // the third sheet of the outter one's output bar
+                
+                mpNestedLayout = new wxFrameLayout( pSheet3, 
+                    CreateTxtCtrl("\"Mobils in Mobile\" --C.Nemo",pSheet3), FALSE );
+                
+                CreateDevLayout( *mpNestedLayout, pSheet3 );
+                
+                mpNestedLayout->Activate();
+            }
+        }
+    }
+}    
+
+void MyFrame::CreateLayout( int layoutNo )
+{
+    wxFrameLayout* pLayout = new wxFrameLayout( mpInternalFrm, mpClntWindow, FALSE );
+    
+    if ( layoutNo == THIRD_LAYOUT )
+    {
+        pLayout->PushDefaultPlugins();
+        pLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for bars
+#ifdef __WXGTK__
+        pLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
+#endif
+        pLayout->AddPlugin( CLASSINFO( cbRowDragPlugin ) ); 
+    }
+    
+    mLayouts[layoutNo] = pLayout;
+    
+    DropInSomeBars( layoutNo );
+}
+
+void MyFrame::RemoveLayout( int layoutNo )
+{
+    wxFrameLayout* pLayout = mLayouts[layoutNo];
+    
+    if ( !pLayout ) 
+        return;
+    
+    pLayout->HideBarWindows();
+    
+    // destroy nested layout first
+    
+    if ( layoutNo == THIRD_LAYOUT )
+    {
+        if ( mpNestedLayout ) 
+            delete mpNestedLayout;
+        mpNestedLayout = NULL;
+    }
+    
+    // NOTE:: bar windows are NOT destroyed automatically by frame-layout 
+    
+    pLayout->DestroyBarWindows();
+    
+    delete pLayout;
+    
+    mLayouts[layoutNo] = NULL;
+    
+    Refresh();
+}
+
+void MyFrame::SyncMenuBarItems()
+{
+    for( int i = 0; i != MAX_LAYOUTS; ++i )
+    {
+        GetMenuBar()->Check( ID_FIRST+i,  mActiveLayoutNo == FIRST_LAYOUT+i );
+    }
+    
+    GetMenuBar()->Check( ID_AUTOSAVE,  mAutoSave  );
+}
+
+void MyFrame::ActivateLayout( int layoutNo )
+{
+    if ( layoutNo == mActiveLayoutNo ) 
+        return;
+    
+    if ( mLayouts[mActiveLayoutNo] )
+        mLayouts[mActiveLayoutNo]->Deactivate();
+    
+    mActiveLayoutNo = layoutNo;
+    
+    if ( mLayouts[mActiveLayoutNo] ) 
+        mLayouts[mActiveLayoutNo]->Activate();
+    else
+        Refresh();
+    
+    SyncMenuBarItems();
+}
+
+/***** Implementation for class StartButton95 (just for fun) *****/
+
+IMPLEMENT_DYNAMIC_CLASS( StartButton95, wxPanel )
+
+BEGIN_EVENT_TABLE( StartButton95, wxPanel )
+    EVT_LEFT_DOWN( StartButton95::OnMouseDown )
+    EVT_LEFT_UP  ( StartButton95::OnMouseUp   )
+    EVT_PAINT    ( StartButton95::OnPaint     )
+END_EVENT_TABLE()
+
+void StartButton95::OnMouseDown( wxMouseEvent& event )
+{
+    m_bPressed = TRUE;
+    Refresh();
+    CaptureMouse();
+}
+
+void StartButton95::OnMouseUp( wxMouseEvent& event )
+{
+    // "this is not a bug"
+    
+    SetCursor( wxCURSOR_WAIT );
+    GetParent()->SetCursor( wxCURSOR_WAIT );
+    ::wxSetCursor( wxCURSOR_WAIT );    
+    wxSleep(1);
+    
+    int i = 0;
+    for( i = 1; i != 6; ++i ) 
+    { 
+        m_bPressed = (i % 2) != 0;
+        Refresh();
+        wxSleep(1);
+    }
+    GetParent()->Close();
+    //*((char*)(i)-3) = 'X'; // Aleks what's the meaning of this???
+}
+
+void StartButton95::OnPaint( wxPaintEvent& event )
+{
+    wxBitmap* pBmp = 0;
+    
+    if ( m_bPressed )
+    {
+        if ( !m_PBmp.Ok() && wxFileExists( BMP_DIR "start95_pr.bmp" ) )
+            
+            m_PBmp.LoadFile( BMP_DIR "start95_pr.bmp", wxBITMAP_TYPE_BMP );
+        
+        pBmp = &m_PBmp;
+    }
+    else
+    {
+        if ( !m_DBmp.Ok() && wxFileExists( BMP_DIR "start95_dp.bmp" ) )
+            
+            m_DBmp.LoadFile( BMP_DIR "start95_dp.bmp", wxBITMAP_TYPE_BMP );
+        
+        pBmp = &m_DBmp;
+    }
+    
+    if (!pBmp) return;
+    wxMemoryDC mdc;
+    wxPaintDC  dc(this);
+    mdc.SelectObject( *pBmp );
+    
+    dc.Blit( 0,0, pBmp->GetWidth(), pBmp->GetHeight(), &mdc, 0,0, wxCOPY );
+    
+    mdc.SelectObject( wxNullBitmap );
+}
diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.h b/contrib/samples/fl/fl_demo2/fl_demo2.h
new file mode 100644 (file)
index 0000000..c9cf31d
--- /dev/null
@@ -0,0 +1,160 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     04/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __FLDEMO_G__
+#define __FLDEMO_G__
+
+// ID for the menu commands
+
+#define MINIMAL_QUIT   1
+#define MINIMAL_ABOUT 102
+
+#define ID_LOAD      103
+#define ID_STORE     104
+#define ID_AUTOSAVE  105
+//#define ID_SETTINGS  106
+#define ID_REMOVE    107
+#define ID_REMOVEALL 108
+#define ID_RECREATE  109
+#define ID_ACTIVATE  110
+#define ID_FIRST        111
+#define ID_SECOND    112
+#define ID_THIRD     113
+
+#define ID_SAY_ITSOK 114
+#define ID_BTN_YES   115
+#define ID_BTN_NO    116
+#define ID_BTN_ESC   117
+
+#define MAX_LAYOUTS   3
+
+#define FIRST_LAYOUT  0
+#define SECOND_LAYOUT 1
+#define THIRD_LAYOUT  2
+
+class wxFrameLayout;
+class wxObjectStorage;
+
+// FOR NOW::
+typedef wxPanel MyTestPanel;
+
+// Define a new application type
+
+class MyApp: public wxApp
+{ 
+public:
+    bool OnInit(void);
+};
+
+// Define a new frame type
+
+class MyFrame: public wxFrame
+{ 
+protected:
+    
+    wxFrameLayout* mLayouts[MAX_LAYOUTS];
+    
+    wxFrameLayout* mpNestedLayout;
+    wxFrameLayout* mpAboutBoxLayout;
+    
+    int            mActiveLayoutNo;   
+    bool           mAutoSave;
+    bool           mSavedAlready;
+    
+    // container windows:
+    
+    wxTextCtrl*    mpClntWindow;
+    wxPanel*       mpInternalFrm;
+    
+    wxImageList    mImageList;
+    
+    wxFrame       mAboutBox;
+    
+    // helpers for control-creation
+    
+    wxTextCtrl* CreateTxtCtrl ( const wxString& txt = "wxTextCtrl", wxWindow* parent = NULL  );
+    wxTreeCtrl* CreateTreeCtrl( const wxString& label = "TreeCtrl" );
+    wxChoice*   CreateChoice  ( const wxString& txt = "Choice1" );
+    wxButton*   CreateButton  ( const wxString& label = "wxButton", wxWindow* pParent = NULL, long id = ID_SAY_ITSOK );
+    
+    // helpers for layout-creation
+    
+    void AddSearchToolbars( wxFrameLayout& layout, wxWindow* pParent );
+    wxWindow* CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent );
+    
+    void DropInSomeBars( int layoutNo );
+    void CreateLayout( int layoutNo );
+    void RemoveLayout( int layoutNo );
+    
+    void InitAboutBox();
+    
+    void ActivateLayout( int layoutNo );
+    
+public: /* public */
+    
+    MyFrame( wxFrame *frame, char *title, int x, int y, int w, int h);
+    
+    ~MyFrame();
+    
+    void SyncMenuBarItems();
+    
+    // event handlers
+    
+    bool OnClose(void);
+    
+    void OnLoad( wxCommandEvent& event );
+    void OnStore( wxCommandEvent& event );
+    void OnAutoSave( wxCommandEvent& event );
+    void OnQuit(wxCommandEvent& event);
+    void OnAbout(wxCommandEvent& event);
+    //void OnSettings( wxCommandEvent& event );
+    void OnRemove( wxCommandEvent& event );
+    void OnRemoveAll( wxCommandEvent& event );
+    void OnRecreate( wxCommandEvent& event );
+    void OnFirst( wxCommandEvent& event );
+    void OnSecond( wxCommandEvent& event );
+    void OnThird( wxCommandEvent& event );
+    
+    void OnSayItsOk( wxCommandEvent& event );
+    void OnBtnYes( wxCommandEvent& event );
+    void OnBtnNo( wxCommandEvent& event );
+    void OnBtnEsc( wxCommandEvent& event );
+    
+    void OnChar( wxKeyEvent& event );
+    
+    DECLARE_EVENT_TABLE()   
+};
+
+// Define a new button type, StartButton95 (Just for fun)
+
+class StartButton95 : public wxPanel
+{
+    DECLARE_DYNAMIC_CLASS( StartButton95 )
+        
+    bool m_bPressed;
+    wxBitmap m_PBmp;
+    wxBitmap m_DBmp;
+    
+public:
+    StartButton95(void) : m_bPressed(FALSE) {}
+    
+    StartButton95(wxWindow* parent) 
+        : m_bPressed(FALSE) { wxPanel::Create(parent,-1); }
+    
+    void OnMouseDown( wxMouseEvent& event );
+    void OnMouseUp( wxMouseEvent& event );
+    void OnPaint( wxPaintEvent& event );
+    
+    DECLARE_EVENT_TABLE();
+};
+
+#endif
+
diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.rc b/contrib/samples/fl/fl_demo2/fl_demo2.rc
new file mode 100644 (file)
index 0000000..626b82f
--- /dev/null
@@ -0,0 +1,3 @@
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
diff --git a/contrib/samples/fl/fl_demo2/makefile.b32 b/contrib/samples/fl/fl_demo2/makefile.b32
new file mode 100644 (file)
index 0000000..27524e7
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = ..\..\..\..
+TARGET = fl_demo2
+
+EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WSLIBDIR)\fl.lib
+!else
+EXTRALIBS = $(WSLIBDIR)\fld.lib
+!endif
+
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/contrib/samples/fl/fl_demo2/makefile.g95 b/contrib/samples/fl/fl_demo2/makefile.g95
new file mode 100644 (file)
index 0000000..ff6a16f
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWorkshop for mingw & cygwin.
+
+WXDIR = ../../../..
+TARGET = fl_demo2
+
+EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\"
+EXTRALIBS     = $(WXDIR)/lib/libfl.a
+
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
diff --git a/contrib/samples/fl/fl_demo2/makefile.vc b/contrib/samples/fl/fl_demo2/makefile.vc
new file mode 100644 (file)
index 0000000..e05c0d6
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds fl sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..\..
+TARGET = fl_demo2
+
+EXTRAINC = -DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WXDIR)\lib\fl.lib
+!else
+EXTRALIBS = $(WXDIR)\lib\fld.lib
+!endif
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.vc
diff --git a/contrib/samples/fl/fl_sample1/Makefile.in b/contrib/samples/fl/fl_sample1/Makefile.in
new file mode 100644 (file)
index 0000000..11d671a
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# "%W% %G%"
+#
+# Makefile : Builds sample on UNIX/Linux.
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../../..
+
+TARGET = fl_sample1
+
+program_dir = contrib/samples/fl/$(TARGET)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\"
+APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).o
+
+include $(top_builddir)/src/makeprog.env
diff --git a/contrib/samples/fl/fl_sample1/fl_demo.dsp b/contrib/samples/fl/fl_sample1/fl_demo.dsp
new file mode 100644 (file)
index 0000000..b73643d
--- /dev/null
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="fl_sample1" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fl_sample1 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample1 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "fl_sample1 - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fl_sample1 - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "fl_sample1 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ELSEIF  "$(CFG)" == "fl_sample1 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "fl_sample1 - Win32 Release"
+# Name "fl_sample1 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\fl_sample1.cpp
+
+!IF  "$(CFG)" == "fl_sample1 - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "fl_sample1 - Win32 Debug"
+
+# ADD CPP /Yc"wx/wxprec.h"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\fl_sample1.rc
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/samples/fl/fl_sample1/fl_demo.dsw b/contrib/samples/fl/fl_sample1/fl_demo.dsw
new file mode 100644 (file)
index 0000000..0ae6cf1
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "fl_sample1"=.\fl_demo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/samples/fl/fl_sample1/fl_sample1.cpp b/contrib/samples/fl/fl_sample1/fl_sample1.cpp
new file mode 100644 (file)
index 0000000..762b0f2
--- /dev/null
@@ -0,0 +1,196 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        fl_sample1.cpp
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     24/11/98     
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// 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"
+#endif
+
+#include "wx/textctrl.h"
+
+// fl headers
+#include "wx/fl/controlbar.h"
+
+// plugins used
+#include "wx/fl/barhintspl.h"
+#include "wx/fl/hintanimpl.h"
+
+#define ID_LOAD  102
+#define ID_STORE 103
+#define ID_QUIT  104
+
+class MyApp: public wxApp
+{ 
+public:
+    bool OnInit(void);
+};
+
+class MyFrame: public wxFrame
+{
+protected:
+    wxFrameLayout* mpLayout;
+    wxWindow*      mpClientWnd;
+    wxPanel*       mpInternalFrm;
+    
+    wxTextCtrl* CreateTextCtrl( const wxString& value );
+    
+public:
+    MyFrame( wxWindow* parent, char *title );
+    ~MyFrame();
+    
+    void OnLoad( wxCommandEvent& event );
+    void OnStore( wxCommandEvent& event );
+    void OnQuit( wxCommandEvent& event );
+    
+    bool OnClose(void) { return TRUE; }
+    
+    DECLARE_EVENT_TABLE()
+};
+
+/***** Implementation for class MyApp *****/
+
+IMPLEMENT_APP    (MyApp)
+
+bool MyApp::OnInit(void)
+{
+    // wxWindows boiler-plate:
+    
+    MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample");
+    
+    wxMenu *file_menu = new wxMenu;
+    
+    file_menu->Append( ID_LOAD,  "&Load layout"  );
+    file_menu->Append( ID_STORE, "&Store layout"  );
+    file_menu->AppendSeparator();
+    
+    file_menu->Append( ID_QUIT, "E&xit" );
+    
+    wxMenuBar *menu_bar = new wxMenuBar;
+    
+    menu_bar->Append(file_menu, "&File");
+    
+    frame->CreateStatusBar(3);
+    frame->SetMenuBar(menu_bar);
+    
+    frame->Show(TRUE);
+    
+    SetTopWindow(frame);
+    
+    return TRUE;
+}
+
+/***** Immlementation for class MyFrame *****/
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU( ID_LOAD,  MyFrame::OnLoad  )
+    EVT_MENU( ID_STORE, MyFrame::OnStore )
+    EVT_MENU( ID_QUIT,  MyFrame::OnQuit  )
+END_EVENT_TABLE()
+
+MyFrame::MyFrame( wxWindow* parent, char *title )
+    : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition,
+          wxSize( 700, 500 ),
+          wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
+          wxTHICK_FRAME   | wxSYSTEM_MENU  | wxCAPTION,
+          "freimas" )
+{
+    mpInternalFrm = (wxPanel*)this;
+    
+    mpClientWnd = CreateTextCtrl( "Client window" );
+    
+    // btw, creation of internal frame is needed for wxGtk version
+    // to act correctly (since menu-bar is a separate window there..)
+    
+    mpLayout = new wxFrameLayout( mpInternalFrm, mpClientWnd );
+    
+#ifdef __WXGTK__
+    // real-time dosn't work well under wxGtk yet
+    cbCommonPaneProperties props;
+    mpLayout->GetPaneProperties( props );
+    
+    props.mRealTimeUpdatesOn = FALSE; // off
+    
+    mpLayout->SetPaneProperties( props, wxALL_PANES );    
+#endif
+    
+    mpLayout->PushDefaultPlugins();
+    mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso
+    //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
+    
+    cbDimInfo sizes( 80,65, // when docked horizontally      
+                     80,65, // when docked vertically        
+                     80,30, // when floated                  
+                     TRUE,  // the bar is fixed-size
+                     5,     // vertical gap (bar border)
+                     5      // horizontal gap (bar border)
+                   ); 
+    
+    // drop-in 20 bars
+    for( int i = 1; i <= 20; ++i )
+    {
+        char buf[4];
+        sprintf( buf, "%d", i );
+        wxString name = wxString("Bar-");
+        name += buf;
+        
+        sizes.mIsFixed = i % 5 > 0; // every fifth bar is not fixed-size
+        
+        if ( !sizes.mIsFixed ) name += " (flexible)";
+        
+        mpLayout->AddBar( CreateTextCtrl(name),// bar window
+                          sizes, i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                          0,                   // insert into 0th row (vert. position)
+                          0,                   // offset from the start of row (in pixels)
+                          name                 // name to refere in customization pop-ups
+                        );
+    }
+}
+
+MyFrame::~MyFrame()
+{
+    // layout is not a window, should be released manually
+    if ( mpLayout ) 
+        delete mpLayout;
+}
+
+wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
+{
+    wxTextCtrl* pCtrl = new wxTextCtrl( mpInternalFrm, -1, value, 
+                                wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE );
+    
+    pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
+    
+    return pCtrl;
+}
+
+void MyFrame::OnLoad( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found a BIG question-mark !!");
+}
+
+void MyFrame::OnStore( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found another BIG question-mark !!");
+}
+
+void MyFrame::OnQuit( wxCommandEvent& event )
+{
+    Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction
+    
+    Close(TRUE);
+}
+
diff --git a/contrib/samples/fl/fl_sample1/fl_sample1.rc b/contrib/samples/fl/fl_sample1/fl_sample1.rc
new file mode 100644 (file)
index 0000000..626b82f
--- /dev/null
@@ -0,0 +1,3 @@
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
diff --git a/contrib/samples/fl/fl_sample1/makefile.b32 b/contrib/samples/fl/fl_sample1/makefile.b32
new file mode 100644 (file)
index 0000000..a521961
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample1
+
+EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WSLIBDIR)\fl.lib
+!else
+EXTRALIBS = $(WSLIBDIR)\fld.lib
+!endif
+
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/contrib/samples/fl/fl_sample1/makefile.g95 b/contrib/samples/fl/fl_sample1/makefile.g95
new file mode 100644 (file)
index 0000000..8c130d4
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWorkshop for mingw & cygwin.
+
+WXDIR = ../../../..
+TARGET = fl_sample1
+
+EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\"
+EXTRALIBS     = $(WXDIR)/lib/libfl.a
+
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
diff --git a/contrib/samples/fl/fl_sample1/makefile.vc b/contrib/samples/fl/fl_sample1/makefile.vc
new file mode 100644 (file)
index 0000000..50f4d6e
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds fl sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample1
+
+EXTRAINC = -DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WXDIR)\lib\fl.lib
+!else
+EXTRALIBS = $(WXDIR)\lib\fld.lib
+!endif
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.vc
diff --git a/contrib/samples/fl/fl_sample2/Makefile.in b/contrib/samples/fl/fl_sample2/Makefile.in
new file mode 100644 (file)
index 0000000..85b50b4
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# "%W% %G%"
+#
+# Makefile : Builds sample on UNIX/Linux.
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../../..
+
+TARGET = fl_sample2
+
+program_dir = contrib/samples/fl/$(TARGET)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\"
+APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).o
+
+include $(top_builddir)/src/makeprog.env
diff --git a/contrib/samples/fl/fl_sample2/fl_demo.dsp b/contrib/samples/fl/fl_sample2/fl_demo.dsp
new file mode 100644 (file)
index 0000000..34429e6
--- /dev/null
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="fl_sample2" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fl_sample2 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample2 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "fl_sample2 - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fl_sample2 - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "fl_sample2 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ELSEIF  "$(CFG)" == "fl_sample2 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "fl_sample2 - Win32 Release"
+# Name "fl_sample2 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\fl_sample2.cpp
+
+!IF  "$(CFG)" == "fl_sample2 - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "fl_sample2 - Win32 Debug"
+
+# ADD CPP /Yc"wx/wxprec.h"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\fl_sample2.rc
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/samples/fl/fl_sample2/fl_demo.dsw b/contrib/samples/fl/fl_sample2/fl_demo.dsw
new file mode 100644 (file)
index 0000000..ae31c36
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "fl_sample2"=.\fl_demo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/samples/fl/fl_sample2/fl_sample2.cpp b/contrib/samples/fl/fl_sample2/fl_sample2.cpp
new file mode 100644 (file)
index 0000000..281f49f
--- /dev/null
@@ -0,0 +1,194 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        fl_sample2.cpp
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     24/11/98     
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// 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"
+#endif
+
+#include "wx/textctrl.h"
+
+// fl headers
+#include "wx/fl/controlbar.h"
+
+// plugins used
+#include "wx/fl/barhintspl.h"
+#include "wx/fl/hintanimpl.h"
+
+#define ID_LOAD  102
+#define ID_STORE 103
+#define ID_QUIT  104
+
+
+class MyApp: public wxApp
+{ 
+public:
+    bool OnInit(void);
+};
+
+class MyFrame: public wxFrame
+{
+protected:
+    wxFrameLayout* mpLayout;
+    wxWindow*      mpClientWnd;
+    
+    wxTextCtrl* CreateTextCtrl( const wxString& value );
+        
+public:
+    MyFrame( wxWindow* parent, char *title );
+    ~MyFrame();
+    
+    void populateMyFrame();
+    void OnLoad( wxCommandEvent& event );
+    void OnStore( wxCommandEvent& event );
+    void OnQuit( wxCommandEvent& event );
+    
+    bool OnClose(void) { return TRUE; }
+    
+    DECLARE_EVENT_TABLE()
+};
+
+/***** Implementation for class MyApp *****/
+
+IMPLEMENT_APP    (MyApp)
+
+bool MyApp::OnInit(void)
+{
+    // wxWindows boiler-plate:
+    
+    MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample");
+    
+    wxMenu *file_menu = new wxMenu;
+    
+    file_menu->Append( ID_LOAD,  "&Load layout"  );
+    file_menu->Append( ID_STORE, "&Store layout"  );
+    file_menu->AppendSeparator();
+    
+    file_menu->Append( ID_QUIT, "E&xit" );
+    
+    wxMenuBar *menu_bar = new wxMenuBar;
+    
+    menu_bar->Append(file_menu, "&File");
+    
+    frame->CreateStatusBar(3);
+    frame->SetMenuBar(menu_bar);
+    
+    frame->Show(TRUE);
+    SetTopWindow(frame);
+    frame->populateMyFrame();
+    
+    return TRUE;
+}
+
+/***** Immlementation for class MyFrame *****/
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU( ID_LOAD,  MyFrame::OnLoad  )
+    EVT_MENU( ID_STORE, MyFrame::OnStore )
+    EVT_MENU( ID_QUIT,  MyFrame::OnQuit  )
+END_EVENT_TABLE()
+
+MyFrame::MyFrame( wxWindow* parent, char *title )
+    : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition,
+          wxSize( 700, 500 ),
+          wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
+          wxTHICK_FRAME   | wxSYSTEM_MENU  | wxCAPTION,
+          "freimas" )
+{
+}
+
+void MyFrame::populateMyFrame()
+{
+    mpClientWnd = CreateTextCtrl( "Client window" );
+    
+    mpLayout = new wxFrameLayout( this, mpClientWnd );
+        
+    ///  mpLayout->PushDefaultPlugins();
+    ///  mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso
+    ///  //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
+        
+    cbDimInfo sizes( 80,65,     // when docked horizontally      
+                     80,165,    // when docked vertically        
+                     180,30,    // when floated                  
+                     TRUE,      // the bar is fixed-size
+                     5,         // vertical gap (bar border)
+                     5          // horizontal gap (bar border)
+                   ); 
+        
+    // drop-in 20 bars    
+    for( int i = 1; i <= 10; ++i )
+    {
+        wxSleep(1);
+        wxYield(); // CHECK!
+        
+        char buf[4];
+        sprintf( buf, "%d", i );
+        wxString name = wxString("Bar-");
+        name += buf;
+        
+        //sizes.mIsFixed = i % 2 > 0; // every fifth bar is not fixed-size
+        
+        if ( !sizes.mIsFixed ) name += " (flexible)";
+        //      mpLayout->AddBar( CreateTextCtrl(name),// bar window
+        mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window
+                          sizes, i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                          0,                   // insert into 0th row (vert. position)
+                          0,                   // offset from the start of row (in pixels)
+                          name                 // name to refere in customization pop-ups
+                        );
+
+        mpLayout->RecalcLayout(true);
+        
+        // Layout();
+        // Refresh();
+    }
+}
+
+MyFrame::~MyFrame()
+{
+    // layout is not a window, should be released manually
+    if ( mpLayout ) 
+        delete mpLayout;
+}
+
+wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
+{
+    wxTextCtrl* pCtrl = new wxTextCtrl( this, -1, value, 
+                                wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE );
+    
+    pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
+    
+    return pCtrl;
+}
+
+void MyFrame::OnLoad( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found a BIG question-mark !!");
+}
+
+void MyFrame::OnStore( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found another BIG question-mark !!");
+}
+
+void MyFrame::OnQuit( wxCommandEvent& event )
+{
+    Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction
+    
+    Close(TRUE);
+}
+
diff --git a/contrib/samples/fl/fl_sample2/fl_sample2.rc b/contrib/samples/fl/fl_sample2/fl_sample2.rc
new file mode 100644 (file)
index 0000000..626b82f
--- /dev/null
@@ -0,0 +1,3 @@
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
diff --git a/contrib/samples/fl/fl_sample2/makefile.b32 b/contrib/samples/fl/fl_sample2/makefile.b32
new file mode 100644 (file)
index 0000000..f8093f4
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample2
+
+EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WSLIBDIR)\fl.lib
+!else
+EXTRALIBS = $(WSLIBDIR)\fld.lib
+!endif
+
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/contrib/samples/fl/fl_sample2/makefile.g95 b/contrib/samples/fl/fl_sample2/makefile.g95
new file mode 100644 (file)
index 0000000..e3ac853
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWorkshop for mingw & cygwin.
+
+WXDIR = ../../../..
+TARGET = fl_sample2
+
+EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\"
+EXTRALIBS     = $(WXDIR)/lib/libfl.a
+
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
diff --git a/contrib/samples/fl/fl_sample2/makefile.vc b/contrib/samples/fl/fl_sample2/makefile.vc
new file mode 100644 (file)
index 0000000..dabd566
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds fl sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample2
+
+EXTRAINC = -DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WXDIR)\lib\fl.lib
+!else
+EXTRALIBS = $(WXDIR)\lib\fld.lib
+!endif
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.vc
diff --git a/contrib/samples/fl/fl_sample3/Makefile.in b/contrib/samples/fl/fl_sample3/Makefile.in
new file mode 100644 (file)
index 0000000..b199988
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# "%W% %G%"
+#
+# Makefile : Builds sample on UNIX/Linux.
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../../..
+
+TARGET = fl_sample3
+
+program_dir = contrib/samples/fl/$(TARGET)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\"
+APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).o
+
+include $(top_builddir)/src/makeprog.env
diff --git a/contrib/samples/fl/fl_sample3/fl_demo.dsp b/contrib/samples/fl/fl_sample3/fl_demo.dsp
new file mode 100644 (file)
index 0000000..38bb6a7
--- /dev/null
@@ -0,0 +1,108 @@
+# Microsoft Developer Studio Project File - Name="fl_sample3" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=fl_sample3 - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample3 - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "fl_sample3 - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "fl_sample3 - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "fl_sample3 - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ELSEIF  "$(CFG)" == "fl_sample3 - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "fl_sample3 - Win32 Release"
+# Name "fl_sample3 - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\fl_sample3.cpp
+
+!IF  "$(CFG)" == "fl_sample3 - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "fl_sample3 - Win32 Debug"
+
+# ADD CPP /Yc"wx/wxprec.h"
+
+!ENDIF 
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\fl_sample3.rc
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/samples/fl/fl_sample3/fl_demo.dsw b/contrib/samples/fl/fl_sample3/fl_demo.dsw
new file mode 100644 (file)
index 0000000..573f82b
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "fl_sample3"=.\fl_demo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/samples/fl/fl_sample3/fl_sample3.cpp b/contrib/samples/fl/fl_sample3/fl_sample3.cpp
new file mode 100644 (file)
index 0000000..2cdde9f
--- /dev/null
@@ -0,0 +1,337 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        fl_sample3.cpp
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by: Sebastian Haase (June 21, 2001)
+// Created:     24/11/98     
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+// 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"
+#endif
+
+#include "wx/textctrl.h"
+
+// fl headers
+#include "wx/fl/controlbar.h"
+
+// plugins used
+#include "wx/fl/barhintspl.h"
+#include "wx/fl/hintanimpl.h"
+
+#define ID_LOAD  102
+#define ID_STORE 103
+#define ID_QUIT  104
+
+#define ID_BUTT 145
+#define ID_BUTT2 146
+
+class MyApp: public wxApp
+{ 
+public:
+    bool OnInit(void);
+};
+
+class MyFrame: public wxFrame
+{
+protected:
+    wxFrameLayout* mpLayout;
+    wxWindow*      mpClientWnd;
+    
+    wxButton * my_butt;
+    
+    wxTextCtrl* CreateTextCtrl( const wxString& value );
+public:
+    MyFrame( wxWindow* parent, char *title );
+    ~MyFrame();
+    
+    void OnLoad( wxCommandEvent& event );
+    void OnStore( wxCommandEvent& event );
+    void OnQuit( wxCommandEvent& event );
+    
+    void OnButt( wxCommandEvent& event );
+    void OnButt2( wxCommandEvent& event );
+    bool OnClose(void) { return TRUE; }
+    
+    DECLARE_EVENT_TABLE()
+};
+
+/***** Implementation for class MyApp *****/
+
+IMPLEMENT_APP    (MyApp)
+
+bool MyApp::OnInit(void)
+{
+    // wxWindows boiler-plate:
+    
+    MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample");
+    
+    wxMenu *file_menu = new wxMenu;
+    
+    file_menu->Append( ID_LOAD,  "&Load layout"  );
+    file_menu->Append( ID_STORE, "&Store layout"  );
+    file_menu->AppendSeparator();
+    
+    file_menu->Append( ID_QUIT, "E&xit" );
+    
+    wxMenuBar *menu_bar = new wxMenuBar;
+    
+    menu_bar->Append(file_menu, "&File");
+    
+    frame->CreateStatusBar(3);
+    frame->SetMenuBar(menu_bar);
+    
+    frame->Show(TRUE);
+    SetTopWindow(frame);
+    
+    return TRUE;
+}
+
+/***** Immlementation for class MyFrame *****/
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+    EVT_MENU( ID_LOAD,  MyFrame::OnLoad  )
+    EVT_MENU( ID_STORE, MyFrame::OnStore )
+    EVT_MENU( ID_QUIT,  MyFrame::OnQuit  )
+    EVT_BUTTON( ID_BUTT, MyFrame::OnButt )
+    EVT_BUTTON( ID_BUTT2, MyFrame::OnButt2 )
+END_EVENT_TABLE()
+
+MyFrame::MyFrame( wxWindow* parent, char *title )
+    : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition,
+          wxSize( 700, 500 ),
+          wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
+          wxTHICK_FRAME   | wxSYSTEM_MENU  | wxCAPTION,
+          "freimas" )
+{
+    
+    mpClientWnd = new wxWindow(this, -1);    
+    mpLayout = new wxFrameLayout( this, mpClientWnd );
+    
+    ///  mpLayout->PushDefaultPlugins();
+    ///  mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso
+    ///  //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) );
+    
+    cbDimInfo sizes( 80,65,     // when docked horizontally      
+                     80,165,    // when docked vertically        
+                     180,30,    // when floated                  
+                     TRUE,      // the bar is fixed-size
+                     5,         // vertical gap (bar border)
+                     5          // horizontal gap (bar border)
+                   ); 
+    
+    
+    // drop-in some bars
+    
+    for( int i = 1; i <= 11; ++i )
+    {
+        char buf[4];
+        sprintf( buf, "%d", i );
+        wxString name = wxString("Bar-");
+        name += buf;
+        
+        sizes.mIsFixed = (i !=3); // every fifth bar is not fixed-size
+        
+        if ( !sizes.mIsFixed ) name += " (flexible)";
+        //      mpLayout->AddBar( CreateTextCtrl(name),// bar window
+        if(i != 4 && i!= 5 && i!=11) {
+            mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window
+                              sizes, 
+                              i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                              0,            // insert into 0th row (vert. position)
+                              0,            // offset from the start of row (in pixels)
+                              name          // name to refere in customization pop-ups
+                            );
+        } else if(i==4){
+            mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window
+                              cbDimInfo( 100,100, 100,100, 100,100, TRUE, 5, 5), 
+                              i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                              0,            // insert into 0th row (vert. position)
+                              0,            // offset from the start of row (in pixels)
+                              name          // name to refere in customization pop-ups
+                            );
+        } else if(i==5) {
+            my_butt = new wxButton(this, ID_BUTT, name);
+            mpLayout->AddBar( my_butt,// bar window
+                              cbDimInfo( 100,100, 200,200, 400,400, TRUE, 5, 5), 
+                              i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                              0,            // insert into 0th row (vert. position)
+                              0,            // offset from the start of row (in pixels)
+                              name          // name to refere in customization pop-ups
+                            );
+        } else if(i==11) {
+            mpLayout->AddBar( new wxButton(this, ID_BUTT2, name+"_2"),
+                              cbDimInfo( 100,100, 200,200, 400,400, TRUE, 5, 5), 
+                              i % MAX_PANES,// alignment ( 0-top,1-bottom, etc)
+                              0,            // insert into 0th row (vert. position)
+                              0,            // offset from the start of row (in pixels)
+                              name          // name to refere in customization pop-ups
+                            );
+        }
+        
+        //      mpLayout->RecalcLayout(true);
+        //        Layout();
+        //        Refresh();
+    }
+}
+
+MyFrame::~MyFrame()
+{
+    // layout is not a window, should be released manually
+    if ( mpLayout ) 
+        delete mpLayout;
+}
+
+wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value )
+{
+    wxTextCtrl* pCtrl = new wxTextCtrl( this, -1, value, 
+                                wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE );
+    
+    pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) );
+    
+    return pCtrl;
+}
+
+void MyFrame::OnLoad( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found a BIG question-mark !!");
+}
+
+void MyFrame::OnStore( wxCommandEvent& event )
+{
+    wxMessageBox("Hey - you found another BIG question-mark !!");
+}
+
+void MyFrame::OnQuit( wxCommandEvent& event )
+{
+    Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction
+    
+    Close(TRUE);
+}
+
+void MyFrame::OnButt( wxCommandEvent& event )
+{
+    static int i =0;
+    
+    // cbBarInfo* FindBarByName( const wxString& name ); 
+    
+    switch(i % 2) {
+    case 0: 
+        {
+            cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-1"));
+            if(x) 
+                mpLayout->InverseVisibility(x); 
+            else    
+                wxBell();
+            break;
+        }
+    case 1:
+        {
+            cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-6"));
+            if(x) 
+            {
+                if(i % 4 == 1) 
+                {
+                    mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE);
+                    //mpLayout->RecalcLayout(true);
+                    mpLayout->RepositionFloatedBar(x);
+                } 
+                else 
+                {
+                    mpLayout->SetBarState(x, 0, TRUE);
+                    //mpLayout->RecalcLayout(true);
+                    //mpLayout->RepositionFloatedBar(x);
+                }
+                //  //  //             x->mState = wxCBAR_FLOATING;
+                //  //  //             mpLayout->ApplyBarProperties(x);
+            } 
+            else 
+            {
+                wxBell();
+            }
+            
+            break;
+        }
+    }
+    i++;
+}
+
+void MyFrame::OnButt2( wxCommandEvent& event )
+{
+    static int i =0;
+    
+    // cbBarInfo* FindBarByName( const wxString& name ); 
+    
+    switch(i % 2) {
+    case 0: 
+        {
+            cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-1"));
+            if(x) 
+            {
+                for(int a=0;a<MAX_BAR_STATES;a++)
+                {
+                    x->mDimInfo.mSizes[a].x = 200;
+                    x->mDimInfo.mSizes[a].y = 200;
+                }
+                x->mpBarWnd->SetSize(200,200);
+                mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE);  // HACK !!!
+                mpLayout->SetBarState(x, 0, TRUE);                   // HACK !!!
+                wxYield();                                        // HACK !!! needed to resize BEFORE redraw 
+                mpLayout->RefreshNow( TRUE );                     // HACK !!! needed to trigger redraw
+            }
+            else    
+            {
+                wxBell();
+            }
+
+            break;
+        }
+    case 1:
+        {
+            cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-1"));
+            if(x) 
+            {
+                //mpLayout->InverseVisibility(x); 
+                for(int a=0;a<MAX_BAR_STATES;a++)
+                {
+                    // see cbPaneDrawPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event ) 
+                    x->mDimInfo.mSizes[a].x = 10 + 2 + 2*x->mDimInfo.mHorizGap;
+                    x->mDimInfo.mSizes[a].y = 10 + 2 + 2*x->mDimInfo.mVertGap;
+                }
+                x->mpBarWnd->SetSize(10,10);
+                mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE);  // HACK !!!
+                mpLayout->SetBarState(x, 0, TRUE);                   // HACK !!!
+                wxYield();                                        // HACK !!! needed to resize BEFORE redraw 
+                mpLayout->RefreshNow( TRUE );                     // HACK !!! needed to trigger redraw
+                
+                //  //                 mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE);
+                //  //                 mpLayout->RecalcLayout(true);
+                //  //                 //              mpLayout->RepositionFloatedBar(x);
+                //  //                 mpLayout->RecalcLayout(true);
+                //  //                 mpLayout->RepositionFloatedBar(x);
+                //  //                   mpLayout->SetBarState(x, 0, TRUE);    
+                //  //                   wxYield();
+                //  //                   mpLayout->RefreshNow( TRUE );
+                //  //                   mpLayout->RecalcLayout(true);
+            }
+            else    
+            {
+                wxBell();
+            }
+
+            break;
+        }
+    }
+    i++;
+}
+
diff --git a/contrib/samples/fl/fl_sample3/fl_sample3.rc b/contrib/samples/fl/fl_sample3/fl_sample3.rc
new file mode 100644 (file)
index 0000000..626b82f
--- /dev/null
@@ -0,0 +1,3 @@
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
diff --git a/contrib/samples/fl/fl_sample3/makefile.b32 b/contrib/samples/fl/fl_sample3/makefile.b32
new file mode 100644 (file)
index 0000000..d243c38
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds sample for 32-bit BC++
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample3
+
+EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WSLIBDIR)\fl.lib
+!else
+EXTRALIBS = $(WSLIBDIR)\fld.lib
+!endif
+
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.b32
+
diff --git a/contrib/samples/fl/fl_sample3/makefile.g95 b/contrib/samples/fl/fl_sample3/makefile.g95
new file mode 100644 (file)
index 0000000..47e00c3
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWorkshop for mingw & cygwin.
+
+WXDIR = ../../../..
+TARGET = fl_sample3
+
+EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\"
+EXTRALIBS     = $(WXDIR)/lib/libfl.a
+
+OBJECTS = $(TARGET).o
+
+include $(WXDIR)/src/makeprog.g95
diff --git a/contrib/samples/fl/fl_sample3/makefile.vc b/contrib/samples/fl/fl_sample3/makefile.vc
new file mode 100644 (file)
index 0000000..699a66b
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile : Builds fl sample (VC++, WIN32)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..\..
+TARGET = fl_sample3
+
+EXTRAINC = -DBMP_DIR=\"../bitmaps/\"
+!if "$(FINAL)" == "1"
+EXTRALIBS = $(WXDIR)\lib\fl.lib
+!else
+EXTRALIBS = $(WXDIR)\lib\fld.lib
+!endif
+
+PROGRAM = $(TARGET)
+OBJECTS = $(TARGET).obj
+
+!include $(WXDIR)\src\makeprog.vc
index d0319448953c04fba6aac32ba0bf9d5aab618922..10c09135b85edd86885cb35192964fed3194f79d 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
 # $Id$
 
-CONTRIB_SUBDIRS=ogl mmedia stc xrc applet plot canvas animate
+CONTRIB_SUBDIRS=ogl mmedia stc xrc applet plot canvas animate fl
 
 all:
        @for d in $(CONTRIB_SUBDIRS); do (cd $$d && $(MAKE)); done
 
 all:
        @for d in $(CONTRIB_SUBDIRS); do (cd $$d && $(MAKE)); done
diff --git a/contrib/src/fl/Makefile.in b/contrib/src/fl/Makefile.in
new file mode 100644 (file)
index 0000000..19a7af9
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# File:         Makefile
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWindows FrameLayout library (Linux/wxGTK).
+
+top_srcdir = @top_srcdir@/..
+top_builddir = ../../..
+libsrc_dir = contrib/src/fl
+
+TARGET_LIBNAME = libfl
+OBJ_EXT        = o
+
+# Version Info.
+LIBVERSION_CURRENT=1
+LIBVERSION_REVISION=0
+LIBVERSION_AGE=0
+
+include ./files.lst
+
+OBJECTS = $(FL_OBJECTS)
+
+APPEXTRADEFS = -I$(top_srcdir)/contrib/include
+
+include $(top_builddir)/src/makelib.env
+
diff --git a/contrib/src/fl/antiflickpl.cpp b/contrib/src/fl/antiflickpl.cpp
new file mode 100644 (file)
index 0000000..419b186
--- /dev/null
@@ -0,0 +1,236 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas (@Lithuania)
+// Modified by:
+// Created:     23/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+    #pragma implementation "antiflickpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/antiflickpl.h"
+
+/***** Implementation for class cbAntiflickerPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbAntiflickerPlugin, cbPluginBase )
+
+       EVT_PL_START_DRAW_IN_AREA  ( cbAntiflickerPlugin::OnStartDrawInArea  )
+       EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea )
+
+END_EVENT_TABLE()
+
+// initialization of static members
+
+int cbAntiflickerPlugin::mRefCount    = 0;
+
+wxBitmap*   cbAntiflickerPlugin::mpVertBuf    = 0;
+wxBitmap*   cbAntiflickerPlugin::mpHorizBuf   = 0;
+wxMemoryDC* cbAntiflickerPlugin::mpVertBufDc  = 0;
+wxMemoryDC* cbAntiflickerPlugin::mpHorizBufDc = 0;
+
+// constructors
+
+cbAntiflickerPlugin::cbAntiflickerPlugin(void)
+       : mpLRUBufDc  ( NULL ),
+         mLRUArea    ( -1,-1, -1,-1 )
+{
+       ++mRefCount;
+}
+
+cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask ),
+         mpLRUBufDc  ( NULL ),
+         mLRUArea    ( -1,-1, -1,-1 )
+{
+       ++mRefCount;
+}
+
+cbAntiflickerPlugin::~cbAntiflickerPlugin()
+{
+       if ( --mRefCount == 0 )
+       {
+               if ( mpHorizBuf )
+               {
+                       mpHorizBufDc->SelectObject( wxNullBitmap );
+                       delete mpHorizBuf;
+                       delete mpHorizBufDc;
+                       mpHorizBuf   = 0;
+                       mpHorizBufDc = 0;
+               }
+
+               if ( mpVertBuf ) 
+               {
+                       mpVertBufDc->SelectObject( wxNullBitmap );
+                       delete mpVertBuf; 
+                       delete mpVertBufDc;
+                       mpVertBuf   = 0;
+                       mpVertBufDc = 0;
+               }
+       }
+}
+
+wxDC* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect& forArea )
+{
+       if ( mpVertBuf )
+       {
+               if ( mpVertBuf->GetHeight() >= forArea.height &&
+                        mpVertBuf->GetWidth()  >= forArea.width )
+
+                        return mpVertBufDc;
+       }
+       else
+       if ( mpHorizBuf )
+       {
+               if ( mpHorizBuf->GetHeight() >= forArea.height &&
+                        mpHorizBuf->GetWidth()  >= forArea.width )
+
+                        return mpHorizBufDc;
+       }
+
+       return 0;
+}
+
+wxDC* cbAntiflickerPlugin::AllocNewBuffer( const wxRect& forArea )
+{
+       // TBD:: preallocate bit larger bitmap at once, to avoid
+       //       excessive realocations later
+
+       // check whether the given area is oriented horizontally
+       // or verticallya and choose correspoinding bitmap to create or
+       // recreate
+
+       if ( forArea.height > forArea.width )
+       {
+               wxSize prevDim( 0,0 );
+
+               if ( mpVertBuf ) 
+               {
+                       prevDim.x = mpVertBuf->GetWidth();
+                       prevDim.y = mpVertBuf->GetHeight();
+
+                       mpVertBufDc->SelectObject( wxNullBitmap );
+                       delete mpVertBuf;
+               }
+               else
+                       mpVertBufDc = new wxMemoryDC();
+               
+               mpVertBuf = new wxBitmap( int( wxMax(forArea.width,  prevDim.x ) ), 
+                                                                 int( wxMax(forArea.height, prevDim.y ) )
+                                                               );
+
+               mpVertBufDc->SelectObject( *mpVertBuf );
+
+               return mpVertBufDc;
+       }
+       else
+       {
+               wxSize prevDim( 0,0 );
+
+               if ( mpHorizBuf ) 
+               {
+                       prevDim.x = mpHorizBuf->GetWidth();
+                       prevDim.y = mpHorizBuf->GetHeight();
+
+                       mpHorizBufDc->SelectObject( wxNullBitmap );
+                       delete mpHorizBuf;
+               }
+               else
+                       mpHorizBufDc = new wxMemoryDC();
+               
+               mpHorizBuf = new wxBitmap( int( wxMax(forArea.width,  prevDim.x ) ), 
+                                                                  int( wxMax(forArea.height, prevDim.y ) )
+                                                                );
+
+               mpHorizBufDc->SelectObject( *mpHorizBuf );
+
+               return mpHorizBufDc;
+       }
+}
+
+void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event )
+{
+       wxASSERT( mpLRUBufDc == NULL ); // DBG:: see comments in OnFinishDrawInArea(..) method
+
+       // short-cut
+       wxRect& area = event.mArea;
+
+       if ( event.mArea.width  < 0 || 
+                event.mArea.height < 0 ) return;
+
+       // memorize given area
+       mLRUArea.x      = area.x;
+       mLRUArea.y      = area.y;
+       mLRUArea.width  = area.width;
+       mLRUArea.height = area.height;
+
+       wxDC* pBufDc = FindSuitableBuffer( area );
+
+       if ( !pBufDc )
+       
+               pBufDc = AllocNewBuffer( area );
+
+       pBufDc->SetDeviceOrigin( -area.x, -area.y );
+
+       pBufDc->SetClippingRegion( area.x,     area.y,
+                                                          area.width, area.height );
+
+       wxClientDC clntDc( &mpLayout->GetParentFrame() );
+
+       (*event.mppDc) = pBufDc;
+
+       mpLRUBufDc = pBufDc; // memorize buffer, which will be flushed to screen
+                            // upon "commiting" the drawing
+
+       /*
+       // OLD STUFF::
+       mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y,
+                                     &clntDc, pos.x, pos.y, wxCOPY );
+                                       */
+}
+
+void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event )
+{
+       wxRect& area = event.mArea;
+
+       if ( event.mArea.width  < 0 || 
+                event.mArea.height < 0 ) return;
+
+       wxASSERT( mpLRUBufDc ); // DBG:: OnStartDrawInArea should be called first
+
+       // FOR NOW:: OnStartDrawInArea(..) should be immediately followed
+       //           by OnFinishDrawInArea(..) for the same area
+
+       wxASSERT( mLRUArea.x      == area.x      );
+       wxASSERT( mLRUArea.y      == area.y      );
+       wxASSERT( mLRUArea.width  == area.width  );
+       wxASSERT( mLRUArea.height == area.height );
+
+       wxClientDC clntDc( &mpLayout->GetParentFrame() );
+
+       // "commit" drawings in one-shot
+       clntDc.Blit( area.x, area.y, area.width, area.height,
+                                mpLRUBufDc, area.x, area.y, wxCOPY );
+
+       mpLRUBufDc->DestroyClippingRegion();
+       mpLRUBufDc = 0;
+}
+
diff --git a/contrib/src/fl/bardragpl.cpp b/contrib/src/fl/bardragpl.cpp
new file mode 100644 (file)
index 0000000..26b927e
--- /dev/null
@@ -0,0 +1,934 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     23/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "bardragpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/bardragpl.h"
+
+#define POS_UNDEFINED -32768
+
+// helpers, FOR NOW:: static
+
+static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
+{
+       if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
+                ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
+
+               if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
+                        ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
+                        
+                       return TRUE;
+
+       return FALSE;
+}
+
+static inline bool rect_contains_point( const wxRect& rect, int x, int y )
+{
+       return ( x >= rect.x &&
+                    y >= rect.y &&
+                        x <  rect.x + rect.width  &&
+                        y <  rect.y + rect.height );
+}
+
+/***** Implementation for class cbBarDragPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbBarDragPlugin, cbPluginBase )
+
+       //EVT_PL_LEFT_DOWN          ( cbBarDragPlugin::OnLButtonDown      )
+       EVT_PL_LEFT_UP                    ( cbBarDragPlugin::OnLButtonUp        )
+       EVT_PL_MOTION                     ( cbBarDragPlugin::OnMouseMove        )
+       EVT_PL_DRAW_HINT_RECT     ( cbBarDragPlugin::OnDrawHintRect     )
+       EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging )
+       EVT_PL_LEFT_DCLICK                ( cbBarDragPlugin::OnLDblClick                )
+
+END_EVENT_TABLE()
+
+cbBarDragPlugin::cbBarDragPlugin(void)
+
+       : mBarDragStarted    ( FALSE ),
+         mCanStick          ( TRUE ),
+         mpScrDc            ( NULL ),
+         mpCurCursor        ( NULL ),
+         mpDraggedBar       ( NULL ),
+         mInClientHintBorder( 4 )
+{}
+
+cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask ),
+               
+         mBarDragStarted    ( FALSE ),
+         mCanStick          ( TRUE ),
+         mpScrDc            ( NULL ),
+         mpCurCursor        ( NULL ),
+         mpDraggedBar       ( NULL ),
+         mInClientHintBorder( 4 )
+{}
+
+cbBarDragPlugin::~cbBarDragPlugin()
+{
+       // nothing
+}
+
+// helper methods (protected)
+
+// clips (top/bottom) or (right/left) edges against the frame's bounding rect.
+
+void do_clip_edges( int len, int& rectPos, int& rectLen )
+{
+       if ( rectPos < 0 )
+       {
+               rectLen += rectPos;
+               rectPos = 0;
+               if ( rectLen < 0 )
+            rectLen = 1;
+       }
+       else
+       if ( rectPos > len-1 )
+       {
+               rectPos = len-1;
+               rectLen = 1;
+       }
+       else
+       if ( rectPos + rectLen - 1 > len )
+       
+               rectLen -= (rectPos + rectLen) - len + 1;
+}
+
+void cbBarDragPlugin::ClipRectInFrame( wxRect& rect )
+{
+       int w, h;
+       mpLayout->GetParentFrame().GetClientSize( &w, &h );
+
+       do_clip_edges( w, rect.x, rect.width  );
+       do_clip_edges( h, rect.y, rect.height );
+}
+
+void cbBarDragPlugin::ClipPosInFrame( wxPoint& pos )
+{
+       int w, h;
+       mpLayout->GetParentFrame().GetClientSize( &w, &h );
+
+       if ( pos.x < 0 )
+        pos.x = 0;
+       if ( pos.y < 0 )
+        pos.y = 0;
+       if ( pos.x > w )
+        pos.x = w-1;
+       if ( pos.y > h )
+        pos.y = h-1;
+}
+
+void cbBarDragPlugin::AdjustHintRect( wxPoint& mousePos )
+{
+       mHintRect.x = mousePos.x - mMouseInRectX;
+       mHintRect.y = mousePos.y - mMouseInRectY;
+}
+
+cbDockPane* cbBarDragPlugin::HitTestPanes( wxRect& rect )
+{
+       //wxRect clipped = rect;
+
+       //ClipRectInFrame( clipped );
+
+       cbDockPane** pPanes = mpLayout->GetPanesArray();
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               if ( rect_hits_rect( pPanes[i]->mBoundsInParent, rect ) )
+
+                       return pPanes[i];
+
+       return NULL;
+}
+
+cbDockPane* cbBarDragPlugin::HitTestPanes( wxPoint& pos )
+{
+       wxPoint clipped = pos;
+
+       //ClipPosInFrame( pos );
+
+       cbDockPane** pPanes = mpLayout->GetPanesArray();
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               if ( rect_contains_point( pPanes[i]->mBoundsInParent, clipped.x, clipped.y ) )
+
+                       return pPanes[i];
+
+       return NULL;
+}
+
+bool cbBarDragPlugin::HitsPane( cbDockPane* pPane, wxRect& rect )
+{
+       return rect_hits_rect( pPane->mBoundsInParent, rect );
+}
+
+int cbBarDragPlugin::GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos )
+{
+       wxRect& bounds = pPane->mBoundsInParent;
+
+       switch( pPane->mAlignment )
+       {
+               case FL_ALIGN_TOP    : return mousePos.y - ( bounds.y + bounds.height );
+
+               case FL_ALIGN_BOTTOM : return bounds.y - mousePos.y;
+
+               case FL_ALIGN_LEFT   : return mousePos.x - ( bounds.x + bounds.width  );
+
+               case FL_ALIGN_RIGHT  : return bounds.x - mousePos.x;
+
+               default : return 0; // never reached
+       }
+
+//     return 0;
+}
+
+bool cbBarDragPlugin::IsInOtherPane( wxPoint& mousePos )
+{
+       cbDockPane* pPane = HitTestPanes( mousePos );
+
+       if ( pPane && pPane != mpCurPane ) return TRUE;
+                                                                 else return FALSE;
+}
+
+bool cbBarDragPlugin::IsInClientArea( wxPoint& mousePos )
+{
+       return  ( HitTestPanes( mousePos ) == NULL );
+}
+
+bool cbBarDragPlugin::IsInClientArea( wxRect& rect )
+{
+       return ( HitTestPanes( rect ) == NULL );
+}
+
+void cbBarDragPlugin::CalcOnScreenDims( wxRect& rect )
+{
+       if ( !mpCurPane || mpDraggedBar->IsFixed() ) return;
+
+       wxRect inPane = rect;
+
+       mpCurPane->FrameToPane( &inPane );
+
+       int rowNo = mpCurPane->GetRowAt( inPane.y, inPane.y + inPane.height );
+
+       bool isMaximized = ( rowNo >= (int)mpCurPane->GetRowList().Count() || rowNo < 0 );
+
+       if ( isMaximized )
+       {
+               inPane.x = 0;
+               inPane.width = mpCurPane->mPaneWidth;
+
+               mpCurPane->PaneToFrame( &inPane );
+
+               rect = inPane;
+       }
+}
+
+// helpers 
+
+static inline void check_upper_overrun( int& pos, int width, int mousePos )
+{
+       if ( mousePos >= pos + width )
+
+               pos = mousePos - width/2;
+}
+
+static inline void check_lower_overrun( int& pos, int width, int mousePos )
+{
+       if ( mousePos <= pos )
+
+               pos = mousePos - width/2;
+}
+
+void cbBarDragPlugin::StickToPane( cbDockPane* pPane, wxPoint& mousePos )
+{
+       int wInPane = GetBarWidthInPane ( pPane );
+       int hInPane = GetBarHeightInPane( pPane );
+
+       // adjsut hint-rect horizontally (in pane's orientation)
+       
+       if ( pPane->IsHorizontal() )
+       {
+               mHintRect.width  = wInPane;
+               mHintRect.height = hInPane;
+       }
+       else
+       {
+               mHintRect.height = wInPane;
+               mHintRect.width  = hInPane;
+       }
+
+       // adjsut hint-rect vertically (in pane's orientation)
+
+       wxRect& bounds = pPane->mBoundsInParent;
+
+       // TRUE, if hint enters the pane through it's lower edge
+
+       bool fromLowerEdge = ( pPane->IsHorizontal() ) 
+                                                ? mousePos.y > bounds.y
+                                                : mousePos.x > bounds.x;
+
+       // NOTE:: about all the below min/max things: they are meant to ensure
+       //        that mouse pointer doesn't overrun (leave) the hint-rectangle
+       //        when dimensions it's are recalculated upon sticking it to the pane
+
+       if ( pPane->IsHorizontal() && fromLowerEdge )
+       {
+               int paneBottomEdgeY = bounds.y + bounds.height;
+
+               mHintRect.y = wxMin( paneBottomEdgeY, mousePos.y );
+
+               check_lower_overrun( mHintRect.y, hInPane, mousePos.y );
+
+       }
+       else
+       if ( pPane->IsHorizontal() && !fromLowerEdge )
+       {
+               int paneTopEdgeY = bounds.y;
+
+               mHintRect.y = wxMax( paneTopEdgeY - hInPane, mousePos.y - hInPane );
+
+               check_upper_overrun( mHintRect.y, hInPane, mousePos.y );
+       }
+       else
+       if ( !pPane->IsHorizontal() && fromLowerEdge )
+       {
+               int paneRightEdgeX = bounds.x + bounds.width;
+
+               mHintRect.x = wxMin( paneRightEdgeX, mousePos.x );
+
+               check_lower_overrun( mHintRect.x, hInPane, mousePos.x );
+       }
+       else
+       if ( !pPane->IsHorizontal() && !fromLowerEdge )
+       {
+               int paneLeftEdgeX = bounds.x;
+
+               mHintRect.x = wxMax( paneLeftEdgeX - hInPane, mousePos.x - hInPane );
+
+               check_upper_overrun( mHintRect.x, hInPane, mousePos.x );
+       }
+
+       mMouseInRectX = mousePos.x - mHintRect.x;
+       mMouseInRectY = mousePos.y - mHintRect.y;
+
+       mpCurPane = pPane; // memorize pane to which the hint is currently sticked
+}
+
+void cbBarDragPlugin::UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos )
+{
+       // unsticking causes rectangle to get the shape, in which
+       // dragged control-bar would be when floated
+
+
+       int newWidth  = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
+       int newHeight = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
+
+       wxRect& flBounds = mpDraggedBar->mDimInfo.mBounds[wxCBAR_FLOATING];
+
+       if ( flBounds.width != -1 )
+       {
+               newWidth  = flBounds.width;
+               newHeight = flBounds.height;
+       }
+
+       mHintRect.width  = newWidth;
+       mHintRect.height = newHeight;
+
+       wxRect& bounds = pPane->mBoundsInParent;
+
+       // TRUE, if hint leaves the pane through it's lower edge
+
+       bool fromLowerEdge = ( pPane->IsHorizontal() ) 
+                                                ? mousePos.y > bounds.y
+                                                : mousePos.x > bounds.x;
+
+       // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..)
+
+       if ( pPane->IsHorizontal() && fromLowerEdge )
+       {       
+               bool fromLowerEdge = mousePos.y > bounds.y;
+
+               mHintRect.y = wxMax( bounds.y + bounds.height + 1, mousePos.y - newHeight );
+
+               check_upper_overrun( mHintRect.y, newHeight, mousePos.y );
+
+               // this is how MFC's hint behaves:
+
+               if ( mMouseInRectX > newWidth )
+               
+                       mHintRect.x = mousePos.x - ( newWidth / 2 );
+       }
+       else
+       if ( pPane->IsHorizontal() && !fromLowerEdge )
+       {
+               mHintRect.y = wxMin( bounds.y - newHeight - 1, mousePos.y );
+
+               // -/-
+
+               if ( mMouseInRectX > newWidth )
+               
+                       mHintRect.x = mousePos.x - ( newWidth / 2 );
+
+               check_lower_overrun( mHintRect.y, newHeight, mousePos.y );
+       }
+       else
+       if ( !pPane->IsHorizontal() && fromLowerEdge )
+       {
+               mHintRect.x = wxMax( bounds.x + bounds.width, mousePos.x - newWidth );
+
+               // -/-
+               
+               if ( mMouseInRectY > newHeight )
+
+                       mHintRect.y = mousePos.y - ( newHeight / 2 );
+
+               check_upper_overrun( mHintRect.x, newWidth, mousePos.x );
+       }
+       else
+       if ( !pPane->IsHorizontal() && !fromLowerEdge )
+       {
+               mHintRect.x = wxMin( bounds.x - newWidth - 1, mousePos.x );
+
+               // -/-
+               
+               if ( mMouseInRectY > newHeight )
+
+                       mHintRect.y = mousePos.y - ( newHeight / 2 );
+
+               check_lower_overrun( mHintRect.x, newWidth, mousePos.x );
+       }
+
+       mMouseInRectX = mousePos.x - mHintRect.x;
+       mMouseInRectY = mousePos.y - mHintRect.y;
+
+       mpCurPane = NULL;
+}                              
+
+int cbBarDragPlugin::GetBarWidthInPane( cbDockPane* pPane )
+{
+       if ( pPane == mpSrcPane )
+
+               return mBarWidthInSrcPane;
+
+       // this is how MFC's bars behave:
+
+       if ( pPane->IsHorizontal() )
+       
+               return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].x;
+       else
+               return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY  ].x;
+}
+
+int cbBarDragPlugin::GetBarHeightInPane( cbDockPane* pPane )
+{
+       if ( pPane->IsHorizontal() )
+       
+               return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].y;
+       else
+               return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY  ].y;
+}
+
+void cbBarDragPlugin::ShowHint( bool prevWasInClient )
+{
+       bool wasDocked = FALSE;
+
+       if ( mpDraggedBar->mState != wxCBAR_FLOATING && !mpCurPane )
+       {
+               mpLayout->SetBarState( mpDraggedBar, wxCBAR_FLOATING, TRUE );
+       }
+       else
+       if ( mpDraggedBar->mState == wxCBAR_FLOATING && mpCurPane )
+       {
+               mpLayout->SetBarState( mpDraggedBar, wxCBAR_DOCKED_HORIZONTALLY, FALSE );
+
+               wasDocked = TRUE;
+       }
+
+       if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
+       {
+               // do hevy calculations first
+
+               wxRect actualRect = mHintRect; // will be adjusted depending on drag-settings
+
+               if ( mpSrcPane->mProps.mExactDockPredictionOn && mpCurPane )
+               {
+                       bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
+
+                       wxASSERT( success ); // DBG::
+
+                       actualRect = mpDraggedBar->mBounds;
+
+                       mpCurPane->PaneToFrame( &actualRect );
+               }
+               else
+                       CalcOnScreenDims( actualRect );
+
+               // release previous hint
+
+               if ( mPrevHintRect.x != POS_UNDEFINED )
+               {
+                       // erase previous rectangle
+
+                       cbDrawHintRectEvent evt( mPrevHintRect, prevWasInClient, TRUE, FALSE );
+
+                       mpLayout->FirePluginEvent( evt );
+               }
+
+               // draw new hint
+
+               cbDrawHintRectEvent evt( actualRect, mpCurPane == NULL, FALSE, FALSE );
+
+               mpLayout->FirePluginEvent( evt );
+
+               mPrevHintRect = actualRect;
+       }
+       else 
+       {
+               // otherwise, if real-time updates option is ON
+
+               if ( mpCurPane )
+               {
+                       mpLayout->GetUpdatesManager().OnStartChanges();
+
+                       if ( wasDocked )
+
+                               mpDraggedBar->mUMgrData.SetDirty( TRUE );
+
+                       bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
+
+                       wxASSERT( success ); // DBG ::
+
+                       mpLayout->GetUpdatesManager().OnFinishChanges();
+                       mpLayout->GetUpdatesManager().UpdateNow();
+               }
+               else
+               {
+                       if ( mpLayout->mFloatingOn )
+                       {
+                               // move the top-most floated bar around as user drags the hint
+
+                               mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mHintRect;
+
+                               mpLayout->ApplyBarProperties( mpDraggedBar );
+                       }
+               }
+       }
+}
+
+/*** event handlers ***/
+
+void cbBarDragPlugin::OnMouseMove( cbMotionEvent& event )
+{
+       // calculate postion in frame's coordiantes
+
+       if ( !mBarDragStarted )
+       {
+               event.Skip(); // pass event to the next plugin
+               return;
+       }
+
+       wxPoint mousePos = event.mPos;
+
+       event.mpPane->PaneToFrame( &mousePos.x, &mousePos.y );
+
+       bool   prevIsInClient = ( mpCurPane == 0 );
+
+       AdjustHintRect( mousePos );
+
+       // if the hint-rect is not "tempted" to any pane yet
+
+       if ( mpCurPane == NULL )
+       {
+               cbDockPane* pPane = HitTestPanes( mHintRect );
+
+               if ( !pPane ) 
+                       
+                       // enable sticking again, if we've left the pane completely
+                       mCanStick = TRUE;
+
+               if ( mCanStick && pPane && 
+                        GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
+               
+                       StickToPane( pPane, mousePos );
+               else
+                       if ( pPane && HitTestPanes( mousePos ) == pPane && 0 ) // FOR NOW:: disabled
+
+                               StickToPane( pPane, mousePos );
+       }
+       else
+       {
+               // otherwise, when rect is now sticked to some of the panes
+               // check if it should still remain in this pane
+
+               mCanStick = TRUE;
+
+               bool mouseInOther = IsInOtherPane( mousePos );
+
+               if ( mouseInOther )
+               {
+                               cbDockPane* pPane = HitTestPanes( mousePos );
+
+                               StickToPane( pPane, mousePos );
+               }
+               else
+               {
+                       if ( IsInClientArea( mousePos ) )
+                       {
+                               cbDockPane* pPane = HitTestPanes( mHintRect );
+
+                               if ( pPane && 
+                                        pPane != mpCurPane &&
+                                        GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) )
+
+                                               StickToPane( pPane, mousePos );
+                               else
+                               if ( !pPane )
+                               {
+                                       UnstickFromPane( mpCurPane, mousePos );
+
+                                       // FOR NOW:: disabled, would cause some mess
+                                       //mCanStick = FALSE; // prevents from sticking to this
+                                                                        // pane again, flag is reset when hint-rect
+                                                                        // leaves the pane completely
+                               }
+                               else
+                               if ( GetDistanceToPane( pPane, mousePos ) > GetBarHeightInPane( pPane ) )
+                               {
+                                       if ( !HitsPane( mpCurPane, mHintRect ) )
+                                       {
+                                               UnstickFromPane( mpCurPane, mousePos );
+
+                                               // FOR NOW:: disabled, would cause some mess
+                                               //mCanStick = FALSE; // prevents from sticking to this
+                                                                                    // pane again, flag is reset when hint-rect
+                                                                                    // leaves the pane completely
+                                       }
+                               }
+
+                       }
+                       else
+                       {
+                       }
+               }
+       }
+
+       ShowHint( prevIsInClient );
+
+       wxCursor* pPrevCurs = mpCurCursor;
+
+       if ( mpCurPane )
+       
+               mpCurCursor = mpLayout->mpDragCursor;
+       else
+       {
+               if ( mpLayout->mFloatingOn && mpSrcPane->mProps.mRealTimeUpdatesOn )
+               
+                       mpCurCursor = mpLayout->mpDragCursor;
+               else
+                       mpCurCursor = mpLayout->mpNECursor;
+       }
+
+       if ( pPrevCurs != mpCurCursor )
+
+               mpLayout->GetParentFrame().SetCursor( *mpCurCursor );
+}
+
+void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
+{
+       if ( mBarDragStarted  )
+       {
+               wxMessageBox("DblClick!");
+       }
+
+       event.Skip();
+}
+
+void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent& event )
+{
+       if ( mBarDragStarted  )
+       {
+               if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE )
+               {
+                       // erase current rectangle, and finsih on-screen drawing session
+
+                       cbDrawHintRectEvent evt( mPrevHintRect, mpCurPane == NULL, TRUE, TRUE );
+
+                       mpLayout->FirePluginEvent( evt );
+
+                       if ( mpCurPane != NULL )
+                       {
+                               if ( mpSrcPane->mProps.mExactDockPredictionOn )
+                               {
+                                       mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE );
+
+                                       mpLayout->GetUpdatesManager().OnFinishChanges();
+                                       mpLayout->GetUpdatesManager().UpdateNow();
+                               }
+                               else
+                                       mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane );
+                       }
+               }
+       
+               mHintRect.width = -1;
+
+               mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
+
+               mpLayout->ReleaseEventsFromPane( event.mpPane );
+               mpLayout->ReleaseEventsFromPlugin( this );
+
+               mBarDragStarted = FALSE;
+
+               if ( mBarWasFloating && mpDraggedBar->mState != wxCBAR_FLOATING )
+               {
+                       // save bar's floating position before it was docked 
+
+                       mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mFloatedBarBounds;
+               }
+       }
+       else
+               event.Skip(); // pass event to the next plugin
+}
+
+void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent& event )
+{
+       int avoidCompilerWarning = 1;
+       if ( avoidCompilerWarning )
+       {
+               cbBarInfo* pHittedBar;
+               cbRowInfo* pRow;
+
+               if ( event.mpPane->HitTestPaneItems( event.mPos,          // in pane's coordiantes
+                                                                                    &pRow,
+                                                                                        &pHittedBar ) == CB_BAR_CONTENT_HITTED
+                  )
+                       {
+                               mpLayout->SetBarState( pHittedBar, wxCBAR_FLOATING, TRUE );
+
+                               mpLayout->RepositionFloatedBar( pHittedBar );
+
+                               return; // event is "eaten" by this plugin
+                       }
+
+               mBarDragStarted = FALSE;
+
+               event.Skip();
+       }
+
+       //wxMessageBox("Hi, dblclick arrived!");
+}
+
+void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent& event )
+{
+       mpDraggedBar = event.mpBar;
+       mpSrcPane    = event.mpPane; 
+
+       mpLayout->CaptureEventsForPane( event.mpPane );
+       mpLayout->CaptureEventsForPlugin( this );
+
+       mpLayout->GetParentFrame().SetCursor( *mpLayout->mpDragCursor );
+
+       mBarDragStarted = TRUE;
+
+       wxRect inParent = mpDraggedBar->mBounds;
+
+       mBarWasFloating = mpDraggedBar->mState == wxCBAR_FLOATING;
+               
+       if ( mBarWasFloating )
+       {       
+               inParent = mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ];
+               mFloatedBarBounds = inParent;
+       }
+       else
+               event.mpPane->PaneToFrame( &inParent );
+
+       mHintRect.x = POS_UNDEFINED;
+
+       mHintRect.width  = inParent.width;
+       mHintRect.height = inParent.height;
+
+       mMouseInRectX = event.mPos.x - inParent.x;
+       mMouseInRectY = event.mPos.y - inParent.y;
+
+       mpSrcPane = event.mpPane;
+
+       if ( mpDraggedBar->mState == wxCBAR_FLOATING )
+
+               mpCurPane = NULL;
+       else
+               mpCurPane = event.mpPane;
+
+       mPrevHintRect.x = POS_UNDEFINED;
+
+       mCanStick = FALSE; // we're not stuck into any pane now - 
+                                          // there's nowhere to "stick-twice"
+
+       mBarWidthInSrcPane = mpDraggedBar->mDimInfo.mSizes[ mpDraggedBar->mState ].x;
+
+       if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE && 
+                mpSrcPane->mProps.mExactDockPredictionOn  )
+       
+               mpLayout->GetUpdatesManager().OnStartChanges(); // capture initial state of layout
+       
+       // simulate the first mouse movement
+
+       int x = event.mPos.x, y = event.mPos.y;
+
+       mpSrcPane->FrameToPane( &x, &y );
+
+       cbMotionEvent motionEvt( wxPoint(x,y), event.mpPane );
+
+
+       this->OnMouseMove( motionEvt );
+
+       return; // event is "eaten" by this plugin
+}
+
+/*** on-screen hint-tracking related methods ***/
+
+void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
+{
+       if ( !mpScrDc ) StartTracking();
+
+       DoDrawHintRect( event.mRect, event.mIsInClient );
+
+       if ( event.mLastTime )
+
+               FinishTracking();
+}
+
+#define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
+#define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
+#define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.
+#define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.
+
+// FOR NOW:: static
+
+static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D
+                                                                                         };
+
+void cbBarDragPlugin::StartTracking()
+{
+       mpScrDc = new wxScreenDC;
+
+       wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
+}
+
+void cbBarDragPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
+{
+       wxRect scrRect;
+
+       RectToScr( rect, scrRect );
+
+       int prevLF = mpScrDc->GetLogicalFunction();
+
+       mpScrDc->SetLogicalFunction( wxINVERT );
+
+       if ( isInClientRect )
+       {
+               // BUG BUG BUG (wx):: somehow stippled brush works only  
+               //                                        when the bitmap created on stack, not
+               //                                        as a member of the class
+
+               wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
+
+               wxBrush checkerBrush( checker );
+
+               mpScrDc->SetPen( mpLayout->mNullPen );
+               mpScrDc->SetBrush( checkerBrush );
+
+               int half = mInClientHintBorder / 2;
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
+                                           scrRect.width + 2*half, mInClientHintBorder );
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
+                                           scrRect.width + 2*half, mInClientHintBorder );
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
+                                           mInClientHintBorder, scrRect.height - 2*half + 2);
+
+               mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
+                                                               scrRect.y + half - 1,
+                                           mInClientHintBorder, scrRect.height - 2*half + 2);
+
+               mpScrDc->SetBrush( wxNullBrush );
+       }
+       else
+       {
+               mpScrDc->SetPen( mpLayout->mBlackPen );
+
+               mpScrDc->DrawLine( scrRect.x, scrRect.y, 
+                                                  scrRect.x + scrRect.width, scrRect.y );
+
+               mpScrDc->DrawLine( scrRect.x, scrRect.y + 1, 
+                                                  scrRect.x, scrRect.y + scrRect.height );
+
+               mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height, 
+                                                  scrRect.x + scrRect.width, scrRect.y + scrRect.height );
+
+               mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y, 
+                                                  scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
+       }
+
+       mpScrDc->SetLogicalFunction( prevLF );
+}
+
+void cbBarDragPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
+{
+       DoDrawHintRect( rect, isInClientRect ); 
+}
+
+void cbBarDragPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
+{
+       DoDrawHintRect( rect, isInClientRect ); 
+}
+
+void cbBarDragPlugin::FinishTracking()
+{
+       wxScreenDC::EndDrawingOnTop();
+
+       delete mpScrDc;
+
+       mpScrDc = NULL;
+}
+
+void cbBarDragPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
+{
+       scrRect = frameRect;
+
+       int x = frameRect.x, y = frameRect.y;
+
+       mpLayout->GetParentFrame().ClientToScreen( &x, &y );
+
+       scrRect.x = x;
+       scrRect.y = y;
+}
+
diff --git a/contrib/src/fl/barhintspl.cpp b/contrib/src/fl/barhintspl.cpp
new file mode 100644 (file)
index 0000000..2a5b99c
--- /dev/null
@@ -0,0 +1,560 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     30/11/98 (my 22th birthday :-)
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+    #pragma implementation "barhintspl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/utils.h"
+#include "wx/fl/barhintspl.h"
+
+// fixed settings
+
+#define GROOVE_WIDTH         3  // left shade + middle line + right shade
+#define GROOVE_TO_GROOVE_GAP 1  
+#define BOX_T_BOX_GAP        2
+#define BOX_TO_GROOVE_GAP    3
+
+#define BOXES_IN_HINT        2
+#define CLOSE_BOX_IDX        0
+#define COLLAPSE_BOX_IDX     1
+
+// used interally 
+
+#define CLOSE_BOX_HITTED    1
+#define COLLAPSE_BOX_HITTED 2
+
+/***** Implementation fro class cbBarHintsPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbBarHintsPlugin, cbPluginBase )
+
+       EVT_PL_SIZE_BAR_WND  ( cbBarHintsPlugin::OnSizeBarWindow )
+       EVT_PL_DRAW_BAR_DECOR( cbBarHintsPlugin::OnDrawBarDecorations )
+
+       EVT_PL_LEFT_DOWN( cbBarHintsPlugin::OnLeftDown )
+       EVT_PL_LEFT_UP  ( cbBarHintsPlugin::OnLeftUp   )
+       EVT_PL_MOTION   ( cbBarHintsPlugin::OnMotion   )
+
+END_EVENT_TABLE()
+
+cbBarHintsPlugin::cbBarHintsPlugin(void)
+
+       : mpPane( 0 ),
+         mBtnPressed   ( FALSE ),
+         mCloseBoxOn   ( TRUE ),
+         mCollapseBoxOn( TRUE ),
+         mGrooveCount  ( 2 ),
+         mHintGap      ( 4 ),
+         mXWeight      ( 2 )
+{
+       mBoxes[CLOSE_BOX_IDX]    = NULL;
+       mBoxes[COLLAPSE_BOX_IDX] = NULL;
+}
+
+cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask )
+
+       : cbPluginBase( pLayout, paneMask ),
+         mpPane( 0 ),
+         mBtnPressed   ( FALSE ),
+         mCloseBoxOn   ( TRUE ),
+         mCollapseBoxOn( TRUE ),
+         mGrooveCount  ( 2 ),
+         mHintGap      ( 5 ),
+         mXWeight      ( 2 )
+{
+       mBoxes[CLOSE_BOX_IDX]    = NULL;
+       mBoxes[COLLAPSE_BOX_IDX] = NULL;
+}
+
+
+cbBarHintsPlugin::~cbBarHintsPlugin()
+{
+    if (mBoxes[CLOSE_BOX_IDX])
+        delete mBoxes[CLOSE_BOX_IDX];
+
+       if (mBoxes[COLLAPSE_BOX_IDX])
+        delete mBoxes[COLLAPSE_BOX_IDX];
+}  // cbBarHintsPlugin destructor
+
+
+void cbBarHintsPlugin::SetGrooveCount( int nGrooves )
+{
+       mGrooveCount = nGrooves;
+}
+
+void cbBarHintsPlugin::CreateBoxes()
+{
+       cbCloseBox*    box1 = new cbCloseBox();
+       cbCollapseBox* box2 = new cbCollapseBox();
+
+       mBoxes[CLOSE_BOX_IDX]    = box1;
+       mBoxes[COLLAPSE_BOX_IDX] = box2;
+
+   int i;
+       for( i = 0; i != BOXES_IN_HINT; ++i )
+       {
+               mBoxes[i]->mpLayout = mpLayout;
+               mBoxes[i]->mpPlugin = this;
+               mBoxes[i]->mpWnd    = NULL;
+       }
+}
+
+
+void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed )
+{
+}
+
+void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed )
+{
+}
+
+void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos, 
+                                                                               bool atLeft, bool disabled, bool pressed )
+{
+}
+
+void cbBarHintsPlugin::DrawGrooves( wxDC& dc, const wxPoint& pos, int length )
+{
+       int ofs = 0;
+
+   int i;
+       for( i = 0; i != mGrooveCount; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) )
+       
+               if ( mpPane->IsHorizontal() )
+               {
+                       dc.SetPen( mpLayout->mLightPen );
+                       dc.DrawLine( pos.x + ofs, pos.y, pos.x + ofs, pos.y + length - 1 );
+                       dc.DrawPoint( pos.x + ofs + 1, pos.y );
+
+                       dc.SetPen( mpLayout->mDarkPen );
+                       dc.DrawLine( pos.x + ofs + 2, pos.y, pos.x + ofs + 2, pos.y + length );
+                       dc.DrawPoint( pos.x + ofs + 1, pos.y + length - 1 );
+                       dc.DrawPoint( pos.x + ofs,     pos.y + length - 1 );
+               }
+               else
+               {
+                       dc.SetPen( mpLayout->mLightPen );
+                       dc.DrawLine( pos.x, pos.y + ofs, pos.x + length - 1, pos.y + ofs );
+                       dc.DrawPoint( pos.x, pos.y + ofs + 1 );
+
+                       dc.SetPen( mpLayout->mDarkPen );
+                       dc.DrawLine( pos.x, pos.y + ofs + 2, pos.x + length, pos.y + ofs + 2 );
+                       dc.DrawPoint( pos.x + length - 1, pos.y + ofs + 1 );
+                       dc.DrawPoint( pos.x + length - 1, pos.y + ofs );
+               }
+}
+
+void cbBarHintsPlugin::ExcludeHints( wxRect& rect, cbBarInfo& info )
+{
+       int boxHeight = BTN_BOX_HEIGHT;
+
+       // collapse and close box are not placed on fixed bars
+
+       if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
+
+               boxHeight = 0;
+
+       int height = wxMax( mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) 
+                               - GROOVE_TO_GROOVE_GAP, 
+                                               boxHeight 
+                                     );
+
+       if ( mpPane->IsHorizontal() )
+       {
+               rect.x     += ( mHintGap*2 + height );
+               rect.width -= (height + 2*mHintGap);
+
+               rect.x     -= info.mDimInfo.mHorizGap + 2;
+               rect.width += info.mDimInfo.mHorizGap + 2;
+       }
+       else
+       {
+               rect.y      += (mHintGap*2 + height);
+               rect.height -= (height + 2*mHintGap);
+
+               rect.y      -= info.mDimInfo.mVertGap + 2;
+               rect.height += info.mDimInfo.mVertGap + 2;
+       }
+}
+
+void cbBarHintsPlugin::DoDrawHint( wxDC& dc, wxRect& rect, 
+                                                                  int pos, int boxOfs, int grooveOfs,
+                                                                  bool isFixed )
+{
+       if ( !isFixed )
+       {
+               if ( mpPane->IsHorizontal() )
+               {
+                       if ( mCloseBoxOn )
+                       
+                               mBoxes[CLOSE_BOX_IDX]->Draw( dc );
+
+                       if ( mCollapseBoxOn )
+                       
+                               mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
+               }
+               else
+               {
+                       if ( mCloseBoxOn )
+                       
+                               mBoxes[CLOSE_BOX_IDX]->Draw( dc );
+
+                       if ( mCollapseBoxOn )
+                       
+                               mBoxes[COLLAPSE_BOX_IDX]->Draw( dc );
+               }
+       }
+
+       if ( mpPane->IsHorizontal() )
+       
+               DrawGrooves( dc, wxPoint( rect.x + mHintGap + grooveOfs, pos ), 
+                                        rect.height - (pos - rect.y) - mHintGap );
+       else
+               DrawGrooves( dc, wxPoint( rect.x + mHintGap, rect.y + mHintGap + grooveOfs ), 
+                                        (pos - rect.x) - mHintGap );
+}
+
+void cbBarHintsPlugin::GetHintsLayout( wxRect& rect, cbBarInfo& info, 
+                                                                          int& boxOfs, int& grooveOfs, int& pos )
+{
+       int boxHeight = BTN_BOX_HEIGHT;
+       int boxWidth  = BTN_BOX_WIDTH + BOX_TO_GROOVE_GAP + BTN_BOX_WIDTH;
+
+       // collapse and close box are not placed on fixed bars
+
+       if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) )
+       {
+               boxHeight = 0;
+               boxWidth = 0;
+       }
+       else
+       if ( !mCloseBoxOn || !mCollapseBoxOn ) 
+
+               boxWidth = BTN_BOX_WIDTH;
+
+       int grooveHeight = mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) 
+                              - GROOVE_TO_GROOVE_GAP;
+
+       int height = wxMax( grooveHeight, boxHeight );
+
+       // center boxs and groves with respect to each other
+
+       boxOfs    = ( height - boxHeight    ) / 2;
+       grooveOfs = ( height - grooveHeight ) / 2;
+
+       pos = ( mpPane->IsHorizontal() ) ? rect.y + mHintGap
+                                                                        : rect.x + rect.width - mHintGap;
+
+       // setup positions for boxes
+
+       if ( !info.IsFixed() )
+       {
+               // what direction "collapse-triangle" should look at?
+
+               bool& isAtLeft = ((cbCollapseBox*)(mBoxes[COLLAPSE_BOX_IDX]))->mIsAtLeft;
+                
+               isAtLeft= info.mBounds.x <= mpPane->mPaneWidth - ( info.mBounds.x + info.mBounds.width );
+
+               if ( info.IsExpanded() )
+               {
+                       isAtLeft = FALSE;
+
+                       cbBarInfo* pCur = info.mpPrev;
+
+                       while( pCur )
+                       {
+                               if ( !pCur->IsFixed() )
+                               {
+                                       isAtLeft = TRUE; break;
+                               }
+
+                               pCur = pCur->mpPrev;
+                       }
+               }
+
+               // collapse/expand works only when more not-fixed bars are present in the same row
+
+               mBoxes[COLLAPSE_BOX_IDX]->Enable( info.mpRow->mNotFixedBarsCnt > 1 );
+
+      int i;
+               for( i = 0; i != BOXES_IN_HINT; ++i )
+
+                       mBoxes[i]->mpPane = mpPane;
+
+
+               if ( mpPane->IsHorizontal() )
+               {
+                       if ( mCloseBoxOn )
+                       {
+                               mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
+
+                               pos += BTN_BOX_HEIGHT;
+                       }
+
+                       if ( mCollapseBoxOn )
+                       {
+                               if ( mCloseBoxOn ) pos += BOX_T_BOX_GAP;
+
+                               mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos );
+
+                               pos += BTN_BOX_HEIGHT;
+
+                               pos += BOX_TO_GROOVE_GAP;
+                       }
+               }
+               else
+               {
+                       if ( mCloseBoxOn )
+                       {
+                               pos -= BTN_BOX_WIDTH;
+
+                               mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( pos , rect.y + mHintGap + boxOfs );
+                       }
+
+                       if ( mCollapseBoxOn )
+                       {
+                               if ( mCloseBoxOn ) pos -= BOX_T_BOX_GAP;
+
+                               pos -= BTN_BOX_WIDTH;
+
+                               mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( pos, rect.y + mHintGap + boxOfs );
+
+                               pos -= BOX_TO_GROOVE_GAP;
+                       }
+               }
+       }
+}
+
+static inline bool is_in_box( const wxPoint& rectPos, const wxPoint& mousePos )
+{
+       return ( mousePos.x >= rectPos.x &&
+                        mousePos.y >= rectPos.y &&
+                        mousePos.x < rectPos.x + BTN_BOX_WIDTH &&
+                        mousePos.y < rectPos.y + BTN_BOX_HEIGHT );
+}
+
+int cbBarHintsPlugin::HitTestHints( cbBarInfo& info, const wxPoint& pos )
+{
+       wxPoint inPane = pos;
+       mpPane->PaneToFrame( &inPane.x, &inPane.y );
+
+       wxRect& rect = info.mBoundsInParent;
+
+       if ( info.IsFixed() ) return FALSE;
+
+       int boxOfs, grooveOfs, coord;
+
+       GetHintsLayout( rect, info, boxOfs, grooveOfs, coord );
+
+       if ( mpPane->IsHorizontal() )
+       {
+               if ( mCloseBoxOn )
+               {
+                       if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
+
+                               return CLOSE_BOX_HITTED;
+
+                       coord += BTN_BOX_HEIGHT;
+               }
+
+               if ( mCollapseBoxOn )
+               {
+                       if ( mCloseBoxOn ) coord += BOX_T_BOX_GAP;
+
+                       if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) )
+
+                               return COLLAPSE_BOX_HITTED;
+
+                       coord += BTN_BOX_HEIGHT;
+               }
+       }
+       else
+       {
+               if ( mCloseBoxOn )
+               {
+                       coord -= BTN_BOX_WIDTH;
+
+                       if ( is_in_box( wxPoint( coord , rect.y + mHintGap + boxOfs ), inPane ) )
+
+                               return CLOSE_BOX_HITTED;
+               }
+
+               if ( mCollapseBoxOn )
+               {
+                       if ( mCloseBoxOn ) coord -= BOX_T_BOX_GAP;
+                       coord -= BTN_BOX_WIDTH;
+
+                       if ( is_in_box( wxPoint( coord, rect.y + mHintGap + boxOfs ), inPane ) )
+
+                               return COLLAPSE_BOX_HITTED;
+               }
+       }
+
+       return FALSE;
+}
+
+// handlers for plugin-events
+
+void cbBarHintsPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event )
+{
+       wxRect& rect     = event.mBoundsInParent;
+       mpPane           = event.mpPane;
+
+       ExcludeHints( rect, *event.mpBar );
+
+       event.Skip(); // pass event to the next plugin in the chain
+}
+
+void cbBarHintsPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
+{
+       wxRect& rect     = event.mBoundsInParent;
+       mpPane           = event.mpPane;
+
+       int boxOfs, grooveOfs, pos;
+
+       GetHintsLayout( rect, *event.mpBar, boxOfs, grooveOfs, pos );
+
+       DoDrawHint( *event.mpDc, rect, pos, boxOfs, grooveOfs, event.mpBar->IsFixed() );
+
+       // let other plugins add on their decorations
+
+       event.Skip();
+}
+
+void cbBarHintsPlugin::OnLeftDown( cbLeftDownEvent& event )
+{
+       mpPane           = event.mpPane;
+
+       wxPoint inFrame = event.mPos;
+       mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
+
+       wxBarIterator iter( mpPane->GetRowList() );
+
+       mpClickedBar = NULL;
+
+       while ( iter.Next() )
+       {
+               cbBarInfo& bar = iter.BarInfo();
+
+               int boxOfs, grooveOfs, pos;
+
+               GetHintsLayout( bar.mBoundsInParent, bar, boxOfs, grooveOfs, pos );
+
+               if ( !bar.IsFixed() )
+      {
+         int i;
+                       for( i = 0; i != BOXES_IN_HINT; ++i )
+                       {
+                               mBoxes[i]->OnLeftDown( inFrame );
+
+                               if ( mBoxes[i]->mPressed )
+                               {
+                                       mBtnPressed = TRUE;
+                                       mpClickedBar = &bar;
+
+                                       return; // event handled
+                               }
+                       }
+      }
+       }
+
+       event.Skip();
+}
+
+void cbBarHintsPlugin::OnLeftUp( cbLeftUpEvent&   event )
+{
+       if ( mBtnPressed )
+       {
+               wxPoint inFrame = event.mPos;
+               mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
+
+               int boxOfs, grooveOfs, pos;
+
+               GetHintsLayout( mpClickedBar->mBoundsInParent, *mpClickedBar, boxOfs, grooveOfs, pos );
+
+               int result = HitTestHints( *mpClickedBar, event.mPos );
+
+        int i;
+               for( i = 0; i != BOXES_IN_HINT; ++i )
+               {
+                       mBoxes[i]->OnLeftUp( inFrame );
+
+                       if ( mBoxes[i]->WasClicked() )
+                       {
+                               if ( i == 0 )
+
+                                       mpLayout->SetBarState( mpClickedBar, wxCBAR_HIDDEN, TRUE );
+                               else
+                               {
+                                       if ( mpClickedBar->IsExpanded() )
+
+                                               mpPane->ContractBar( mpClickedBar );
+                                       else
+                                               mpPane->ExpandBar( mpClickedBar );
+                               }
+                       }
+               }
+
+               mBtnPressed = FALSE;
+               return;
+       }
+       else
+               event.Skip();
+}
+
+void cbBarHintsPlugin::OnMotion( cbMotionEvent&   event )
+{
+       if ( mBtnPressed )
+       {
+               wxPoint inFrame = event.mPos;
+               mpPane->PaneToFrame( &inFrame.x, &inFrame.y );
+
+               mpPane = event.mpPane;
+
+      int i;
+               for( i = 0; i != BOXES_IN_HINT; ++i )
+               
+                       mBoxes[i]->OnMotion( inFrame );
+       }
+       else
+               event.Skip();
+}
+
+void cbBarHintsPlugin::OnInitPlugin()
+{
+       cbPluginBase::OnInitPlugin();
+
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+   int i;
+       for( i = 0; i != MAX_PANES; ++i )
+   {   
+               if ( panes[i]->MatchesMask( mPaneMask ) )
+               {
+                       panes[i]->mProps.mMinCBarDim.x = 25;
+                       panes[i]->mProps.mMinCBarDim.y = 16;
+               }
+   }
+       CreateBoxes();
+}
diff --git a/contrib/src/fl/cbcustom.cpp b/contrib/src/fl/cbcustom.cpp
new file mode 100644 (file)
index 0000000..43f5683
--- /dev/null
@@ -0,0 +1,202 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "cbcustom.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/cbcustom.h"
+
+// helper class to receive menu customization event
+
+class cbContextMenuHandler : public wxEvtHandler
+{
+public:
+       cbSimpleCustomizationPlugin* mpBackRef;
+
+public:
+       void OnMenuCommand( wxCommandEvent& evt );
+
+       void OnCommandEvents( wxCommandEvent& evt );
+
+       DECLARE_EVENT_TABLE()
+};
+
+// FIXME:: is this "safe" ?
+
+#define CB_CUSTOMIZE_MENU_FIRST_ITEM_ID 17500
+
+/***** Implementation for helper class cbContextMenuHandler *****/
+
+BEGIN_EVENT_TABLE( cbContextMenuHandler, wxEvtHandler )
+
+       // FIXME:: what is the right range for these ids ? so that they 
+       //         would not collide with user commands?
+
+       EVT_COMMAND_RANGE( CB_CUSTOMIZE_MENU_FIRST_ITEM_ID,
+                                          CB_CUSTOMIZE_MENU_FIRST_ITEM_ID + 300, 
+                                          wxEVT_COMMAND_MENU_SELECTED,  
+                                          cbContextMenuHandler::OnCommandEvents )
+
+END_EVENT_TABLE()
+
+void cbContextMenuHandler::OnCommandEvents( wxCommandEvent& evt )
+{
+       //wxMessageBox("Wowwwww, Yeah!");
+
+       mpBackRef->OnMenuItemSelected( evt );
+}
+
+/***** Implementation for class cbSimpleCustomizationPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbSimpleCustomizationPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbSimpleCustomizationPlugin, cbPluginBase )
+
+       EVT_PL_CUSTOMIZE_BAR   ( cbSimpleCustomizationPlugin::OnCustomizeBar    )
+       EVT_PL_CUSTOMIZE_LAYOUT( cbSimpleCustomizationPlugin::OnCustomizeLayout )
+
+END_EVENT_TABLE()
+
+cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin(void)
+{}
+
+cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask )
+{}
+
+void cbSimpleCustomizationPlugin::OnCustomizeBar( cbCustomizeBarEvent& event )
+{
+       // ingnore bar customization, treat it
+       // as layout-customization...ugly, eh?
+
+       cbCustomizeLayoutEvent clEvt( event.mClickPos );
+
+       OnCustomizeLayout( clEvt );
+}
+
+void cbSimpleCustomizationPlugin::OnCustomizeLayout( cbCustomizeLayoutEvent& event )
+{
+       wxString helpStr1 = "Select this item to show the corresponding control bar";
+       wxString helpStr2 = "Select this itme to hide the corresponding control bar";
+
+       int id = CB_CUSTOMIZE_MENU_FIRST_ITEM_ID;
+
+       wxMenu* pMenu = new wxMenu();
+
+       BarArrayT& bars = mpLayout->GetBars();
+
+       for( size_t i = 0; i != bars.GetCount(); ++i )
+       {
+               cbBarInfo& bar = *bars[i];
+               
+               bool isHidden = ( bar.mState == wxCBAR_HIDDEN );
+
+               wxString* pHelpStr = ( isHidden ) ? &helpStr1 : &helpStr2;
+
+               pMenu->Append( id, bar.mName, *pHelpStr, TRUE );
+
+               pMenu->Check( id, (isHidden == FALSE) );
+
+               ++id;
+       }
+
+       pMenu->AppendSeparator();
+       pMenu->Append( id, "Customize...", "Show layout customization dialog", FALSE );
+       mCustMenuItemId = id;
+
+       cbContextMenuHandler* pHandler = new cbContextMenuHandler();
+       pHandler->mpBackRef            = this;
+
+       wxWindow* pFrm = &mpLayout->GetParentFrame();
+
+       // FOR NOW FOR NOW:: to work-around wxFrame's (MSW) nasty event-handling bugs!!!
+
+       wxWindow* pTmpWnd = new wxWindow( pFrm, -1, event.mClickPos, wxSize(0,0) );
+
+       pMenu->SetEventHandler( pHandler );
+
+       pTmpWnd->PopupMenu( pMenu, 0,0 );
+
+       pTmpWnd->Destroy();
+
+       delete pMenu;
+       delete pHandler;
+
+       // event is "eaten" by this plugin
+}
+
+void cbSimpleCustomizationPlugin::OnMenuItemSelected( wxCommandEvent& event )
+{
+       if ( event.GetId() == mCustMenuItemId )
+       {
+               wxMessageBox("Customization dialog box is not supported by this plugin yet");
+
+               return;
+       }
+       else
+       {
+               cbBarInfo* pBar = mpLayout->GetBars()[ event.GetId() - 
+                                                                                          CB_CUSTOMIZE_MENU_FIRST_ITEM_ID
+                                                        ];
+
+               wxASSERT( pBar ); // DBG::
+
+               // "inverse" bar-visibility of the selected bar
+
+               int newState = 0;
+
+               if ( pBar->mState == wxCBAR_HIDDEN )
+               {
+                       if ( pBar->mAlignment == -1 )
+                       {
+                               pBar->mAlignment = 0;       // just remove "-1" marking
+                               newState = wxCBAR_FLOATING;
+                       }
+                       else
+                       if ( pBar->mAlignment == FL_ALIGN_TOP ||
+                                pBar->mAlignment == FL_ALIGN_BOTTOM )
+
+                               newState = wxCBAR_DOCKED_HORIZONTALLY;
+                       else
+                               newState = wxCBAR_DOCKED_VERTICALLY;
+               }
+               else
+               {
+                       newState = wxCBAR_HIDDEN;
+
+                       if ( pBar->mState == wxCBAR_FLOATING )
+
+                               pBar->mAlignment = -1;
+               }
+
+               mpLayout->SetBarState( pBar, newState, TRUE );
+
+               if ( newState == wxCBAR_FLOATING )
+
+                       mpLayout->RepositionFloatedBar( pBar ); 
+       }
+
+       // menu-item-selected event is "eaten"
+}
+
diff --git a/contrib/src/fl/controlbar.cpp b/contrib/src/fl/controlbar.cpp
new file mode 100644 (file)
index 0000000..6e87a6e
--- /dev/null
@@ -0,0 +1,3524 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "controlbar.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "wx/string.h"
+#include "wx/utils.h"     // import wxMin,wxMax macros
+#include "wx/minifram.h"
+
+#include "wx/fl/controlbar.h"
+
+// import classes of default plugins
+
+#include "wx/fl/panedrawpl.h"
+#include "wx/fl/rowlayoutpl.h"
+#include "wx/fl/antiflickpl.h"
+#include "wx/fl/bardragpl.h"
+#include "wx/fl/cbcustom.h"
+
+#include "wx/fl/gcupdatesmgr.h"   // import default updates manager class ("garbage-collecting" one)
+#include "wx/fl/updatesmgr.h"
+
+#include "wx/fl/toolwnd.h"
+
+// These are the event IDs being initialized to a value to
+// meet the new event paradigm as of wx2.3.0.  Probably we
+// should find a way to make these be non-global, but this
+// works for right now.
+#if wxCHECK_VERSION(2,3,0)
+       wxEventType cbEVT_PL_LEFT_DOWN = wxNewEventType();
+       wxEventType cbEVT_PL_LEFT_UP = wxNewEventType();
+       wxEventType cbEVT_PL_RIGHT_DOWN = wxNewEventType();
+       wxEventType cbEVT_PL_RIGHT_UP = wxNewEventType();
+       wxEventType cbEVT_PL_MOTION = wxNewEventType();
+
+       wxEventType cbEVT_PL_LEFT_DCLICK = wxNewEventType();
+
+       wxEventType cbEVT_PL_LAYOUT_ROW = wxNewEventType();
+       wxEventType cbEVT_PL_RESIZE_ROW = wxNewEventType();
+       wxEventType cbEVT_PL_LAYOUT_ROWS = wxNewEventType();
+       wxEventType cbEVT_PL_INSERT_BAR = wxNewEventType();
+       wxEventType cbEVT_PL_RESIZE_BAR = wxNewEventType();
+       wxEventType cbEVT_PL_REMOVE_BAR = wxNewEventType();
+       wxEventType cbEVT_PL_SIZE_BAR_WND = wxNewEventType();
+
+       wxEventType cbEVT_PL_DRAW_BAR_DECOR = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_ROW_DECOR = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_PANE_DECOR = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_BAR_HANDLES = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_ROW_HANDLES = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_ROW_BKGROUND = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_PANE_BKGROUND = wxNewEventType();
+
+       wxEventType cbEVT_PL_START_BAR_DRAGGING = wxNewEventType();
+       wxEventType cbEVT_PL_DRAW_HINT_RECT = wxNewEventType();
+
+       wxEventType cbEVT_PL_START_DRAW_IN_AREA = wxNewEventType();
+       wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA = wxNewEventType();
+
+       wxEventType cbEVT_PL_CUSTOMIZE_BAR = wxNewEventType();
+       wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT = wxNewEventType();
+
+       wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT = wxNewEventType();
+#endif // #if wxCHECK_VERSION(2,3,0)
+
+// some ascii-art, still can't get these *nice* cursors working on wx... :-(
+
+static const char* _gHorizCursorImg[] = 
+{
+       "............XX....XX............",
+       "............XX....XX............",
+       "............XX....XX............",
+       "............XX....XX............",
+       "............XX....XX............",
+       "...X........XX....XX........X...",
+       "..XX........XX....XX........XX..",
+       ".XXX........XX....XX........XXX.",
+       "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX",
+       ".XXX........XX....XX........XXX.",
+       "..XX........XX....XX........XX..",
+       "...X........XX....XX........X...",
+       "............XX....XX............",
+       "............XX....XX............",
+       "............XX....XX............",
+       "............XX....XX............"
+};
+
+static const char* _gVertCursorImg[] = 
+{
+       "................X...............",
+       "...............XXX..............",
+       "..............XXXXX.............",
+       ".............XXXXXXX............",
+       "................X...............",
+       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+       "................................",
+       "................................",
+       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+       "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+       "................X...............",
+       ".............XXXXXXX............",
+       "..............XXXXX.............",
+       "...............XXX..............",
+       "................X..............."
+};
+
+// helper inline functions
+
+static inline bool rect_contains_point( const wxRect& rect, int x, int y )
+{
+       return ( x >= rect.x &&
+                    y >= rect.y &&
+                        x <  rect.x + rect.width  &&
+                        y <  rect.y + rect.height );
+}
+
+static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
+{
+       if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
+                ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
+
+               if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
+                        ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
+                        
+                       return 1;
+
+       return 0;
+}
+
+static inline void hide_rect( wxRect& r )
+{
+       r.x = 32768;
+       r.y = 32768;
+       r.width  = 1;
+       r.height = 1;
+}
+
+static inline void clip_rect_against_rect( wxRect& r1, const wxRect& r2 )
+{
+       if ( r1.x < r2.x                          || 
+                r1.y < r2.y                      ||
+                r1.x >= r2.x + r2.width  ||
+                r1.y >= r2.y + r2.height 
+          ) 
+       {
+               hide_rect( r1 );
+               return;
+       }
+       else
+       {
+               if ( r1.x + r1.width  > r2.x + r2.width )
+
+                       r1.width = r2.x + r2.width - r1.x;
+
+               if ( r1.y + r1.height > r2.y + r2.height )
+
+                       r1.height = r2.y + r2.height - r1.y;
+       }
+}
+
+/***** Implementation for class cbBarSpy *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbBarSpy, wxEvtHandler )
+
+cbBarSpy::cbBarSpy(void)
+       : mpLayout(0),
+         mpBarWnd(0)
+{}
+
+cbBarSpy::cbBarSpy( wxFrameLayout* pPanel ) 
+
+       : mpLayout(pPanel),
+         mpBarWnd(0)
+{}
+
+void cbBarSpy::SetBarWindow( wxWindow* pWnd )
+{
+       mpBarWnd = pWnd;
+}
+
+bool cbBarSpy::ProcessEvent(wxEvent& event)
+{
+       bool handled = wxEvtHandler::ProcessEvent( event );
+
+       int type = event.GetEventType();
+
+       if ( !handled && ( type == wxEVT_LEFT_DOWN ||
+                                      type == wxEVT_LEFT_DCLICK ) )
+       {
+               wxMouseEvent& mevent = *((wxMouseEvent*)&event);
+
+               int x = mevent.m_x;
+               int y = mevent.m_y;
+
+               mpBarWnd->ClientToScreen( &x, &y );
+               mpLayout->GetParentFrame().ScreenToClient( &x, &y );
+
+               mevent.m_x = x;
+               mevent.m_y = y;
+
+               // forwared not-handled event to frame-layout
+
+               if ( type == wxEVT_LEFT_DOWN )
+               {
+                       //mpLayout->OnLButtonDown( mevent );
+                       event.Skip();
+               }
+               else
+                       mpLayout->OnLDblClick( mevent );
+
+               //event.Skip(FALSE);
+       }
+
+       return handled;
+}
+
+/***** Implementation for class wxFrameLayout *****/
+
+IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout, wxEvtHandler )
+
+BEGIN_EVENT_TABLE( wxFrameLayout, wxEvtHandler )
+
+       EVT_PAINT      ( wxFrameLayout::OnPaint           )
+       EVT_SIZE       ( wxFrameLayout::OnSize            )
+       EVT_LEFT_DOWN  ( wxFrameLayout::OnLButtonDown )
+       EVT_LEFT_UP    ( wxFrameLayout::OnLButtonUp   )
+       EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown )
+       EVT_RIGHT_UP   ( wxFrameLayout::OnRButtonUp   )
+       EVT_MOTION     ( wxFrameLayout::OnMouseMove   )
+
+       EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick   )
+
+       EVT_IDLE       ( wxFrameLayout::OnIdle        )
+       EVT_SET_FOCUS  ( wxFrameLayout::OnSetFocus    )
+       EVT_KILL_FOCUS ( wxFrameLayout::OnKillFocus   )
+
+       EVT_ACTIVATE   ( wxFrameLayout::OnActivate    )
+
+       EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground )
+
+END_EVENT_TABLE()
+
+// FIXME:: how to eliminate these cut&pasted constructors?
+
+wxFrameLayout::wxFrameLayout(void)
+
+       : mpFrame      ( NULL ),
+         mpFrameClient( NULL ),
+
+         mDarkPen  ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
+         mLightPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
+         mGrayPen  ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+         mBlackPen ( wxColour(  0,  0,  0), 1, wxSOLID ),
+         mBorderPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+   
+         mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
+
+         mpPaneInFocus( NULL ),
+         mpLRUPane    ( NULL ),
+
+
+         mpTopPlugin   ( NULL ),
+         mpCaputesInput( NULL ),
+
+         mClientWndRefreshPending( FALSE ),
+         mRecalcPending( TRUE ),
+         mCheckFocusWhenIdle( FALSE )
+{
+       CreateCursors();
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               mPanes[i]  = NULL;
+
+       mFloatingOn = CanReparent();
+}
+
+wxFrameLayout::wxFrameLayout( wxWindow* pParentFrame, wxWindow* pFrameClient, bool activateNow )
+
+       : mpFrame( pParentFrame ),
+         mpFrameClient(pFrameClient),
+
+         mDarkPen  ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
+         mLightPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ),
+         mGrayPen  ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+         mBlackPen ( wxColour(  0,  0,  0), 1, wxSOLID ),
+         mBorderPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+      
+         mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ),
+
+         mpPaneInFocus( NULL ),
+         mpLRUPane    ( NULL ),
+      
+         mFloatingOn   ( TRUE ),
+                 
+         mpTopPlugin   ( NULL ),
+         mpCaputesInput( NULL ),
+         
+      mClientWndRefreshPending( FALSE ),
+      mRecalcPending( TRUE ),
+         mCheckFocusWhenIdle( FALSE ),
+         
+      mpUpdatesMgr( NULL )
+{
+       CreateCursors();
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               mPanes[i]  = new cbDockPane( i, this );
+
+       if ( activateNow )
+       {
+               HookUpToFrame();
+
+               // FOR NOW::
+               // DBG:: set RED color of frame's background for the
+               //       prurpose of tracking engine bugs "visually"
+
+               GetParentFrame().SetBackgroundColour( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) );
+       }
+
+       mFloatingOn = CanReparent();
+}
+
+// NOTE:: below are the only plaftorm-check "ifdef"s in the docking system!
+
+bool wxFrameLayout::CanReparent()
+{
+#ifdef __WXMSW__
+       return TRUE;
+#elif defined (__WXGTK__)
+       //return TRUE;
+       return FALSE;
+#else
+
+       return FALSE; // reparenting is not yet supported by Motif and others
+#endif
+}
+
+/*
+#ifdef __WXMSW__
+       #inlcude "windows.h"
+#endif
+*/
+
+void wxFrameLayout::ReparentWindow( wxWindow* pChild, wxWindow* pNewParent )
+{
+#ifdef __WXMSW__
+#if 0
+
+       if ( pChild->GetParent() )
+       {
+               bool success = pChild->GetParent()->GetChildren().DeleteObject( pChild );
+
+               wxASSERT( success ); // DBG::
+       }
+
+       ::SetParent( (HWND)pChild->m_hWnd, (HWND)pNewParent->m_hWnd  );
+
+       pNewParent->GetChildren().Append( pChild );
+
+       pChild->SetParent( pNewParent );
+#endif
+    pChild->Reparent(pNewParent);
+
+       return;
+#elif defined(__WXGTK__)
+       // FOR NOW:: floating with wxGtk still very buggy
+
+       return;
+
+       //pChild->ReParent( pNewParent );
+
+       //return;
+#else
+       wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" );
+#endif
+}
+
+void wxFrameLayout::DestroyBarWindows()
+{
+       wxNode* pSpy = mBarSpyList.First();
+
+       while( pSpy )
+       {
+               cbBarSpy& spy = *((cbBarSpy*)pSpy->Data());
+
+               if ( spy.mpBarWnd->GetEventHandler() == &spy )
+
+                       spy.mpBarWnd->PopEventHandler();
+
+               delete &spy;
+
+               pSpy = pSpy->Next();
+       }
+
+       mBarSpyList.Clear();
+
+       for( size_t i = 0; i != mAllBars.Count(); ++i )
+       {
+               if ( mAllBars[i]->mpBarWnd )
+               {
+                       mAllBars[i]->mpBarWnd->Destroy();
+                       mAllBars[i]->mpBarWnd = NULL;
+               }
+       }
+}
+
+void wxFrameLayout::ShowFloatedWindows( bool show )
+{
+       wxNode* pNode = mFloatedFrames.First();
+
+       while( pNode )
+       {
+               cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
+
+               pFFrm->Show( show );
+
+               pNode = pNode->Next();
+       }
+}
+
+wxFrameLayout::~wxFrameLayout()
+{
+       UnhookFromFrame();
+
+       if ( mpUpdatesMgr )
+        delete mpUpdatesMgr;
+
+    PopAllPlugins();
+
+       // destoy the chain of plugins from left to right
+
+       wxEvtHandler* pCur = mpTopPlugin;
+
+       if ( pCur )
+
+               while ( pCur->GetPreviousHandler() )
+
+                       pCur = pCur->GetPreviousHandler();
+
+       while ( pCur )
+       {
+               wxEvtHandler* pNext = pCur->GetNextHandler();
+
+               delete pCur;
+
+               pCur = pNext;
+       }
+
+       // destroy contents of arrays and lists
+
+       size_t i = 0;
+
+       for( i = 0; i != MAX_PANES; ++i )
+   {
+               if ( mPanes[i] ) 
+            delete mPanes[i];
+   }
+       if ( mpHorizCursor  ) 
+        delete mpHorizCursor;
+       if ( mpVertCursor   ) 
+        delete mpVertCursor;
+       if ( mpNormalCursor ) 
+        delete mpNormalCursor;
+       if ( mpDragCursor   ) 
+        delete mpDragCursor;
+       if ( mpNECursor     ) 
+        delete mpNECursor;
+
+       wxNode* pSpy = mBarSpyList.First();
+
+       while( pSpy )
+       {
+               cbBarSpy& spy = *((cbBarSpy*)pSpy->Data());
+
+               if ( spy.mpBarWnd->GetEventHandler() == &spy )
+
+                       spy.mpBarWnd->PopEventHandler();
+
+               delete &spy;
+
+               pSpy = pSpy->Next();
+       }
+
+       for( i = 0; i != mAllBars.Count(); ++i )
+       
+               delete mAllBars[i];
+}
+
+void wxFrameLayout::EnableFloating( bool enable )
+{
+       mFloatingOn = enable && CanReparent();
+}
+
+void wxFrameLayout::Activate()
+{
+       HookUpToFrame();
+
+       RefreshNow( TRUE );
+
+       ShowFloatedWindows( TRUE );
+}
+
+void wxFrameLayout::Deactivate()
+{
+       ShowFloatedWindows( FALSE );
+
+       UnhookFromFrame();
+
+       HideBarWindows();
+}
+
+void wxFrameLayout::SetFrameClient( wxWindow* pFrameClient )
+{
+       mpFrameClient = pFrameClient;
+}
+
+wxWindow* wxFrameLayout::GetFrameClient()
+{
+       return mpFrameClient;
+}
+
+cbUpdatesManagerBase& wxFrameLayout::GetUpdatesManager()
+{
+       if ( !mpUpdatesMgr )
+        mpUpdatesMgr = CreateUpdatesManager();
+
+       return *mpUpdatesMgr;
+}
+
+void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase* pUMgr )
+{
+       if ( mpUpdatesMgr )
+        delete mpUpdatesMgr;
+
+       mpUpdatesMgr = pUMgr;
+
+       mpUpdatesMgr->SetLayout( this );
+}
+
+cbUpdatesManagerBase* wxFrameLayout::CreateUpdatesManager()
+{
+       return new cbGCUpdatesMgr( this );
+       //return new cbSimpleUpdatesMgr( this );
+}
+
+void wxFrameLayout::AddBar( wxWindow*        pBarWnd, 
+                            const cbDimInfo& dimInfo,
+                            int              alignment,
+                            int              rowNo,
+                            int              columnPos,
+                            const wxString&  name,
+                            bool             spyEvents,
+                            int              state
+                                                 )
+{
+       if ( pBarWnd && spyEvents )
+       {
+               // hook up spy to bar window
+               cbBarSpy* pSpy = new cbBarSpy( this );
+
+               pSpy->SetBarWindow( pBarWnd );
+               pBarWnd->PushEventHandler( pSpy );
+
+               mBarSpyList.Append( pSpy );
+       }
+
+       cbBarInfo* pInfo = new cbBarInfo();
+
+       pInfo->mName      = name;
+       pInfo->mpBarWnd   = pBarWnd;
+       pInfo->mDimInfo   = dimInfo;
+       pInfo->mState     = state;
+       pInfo->mAlignment = alignment;
+       pInfo->mRowNo     = rowNo;
+       pInfo->mBounds.x  = columnPos;
+
+       mAllBars.Add( pInfo );
+
+       DoSetBarState( pInfo );
+}
+
+bool wxFrameLayout::RedockBar( cbBarInfo*    pBar, 
+                                                          const wxRect& shapeInParent,
+                                                          cbDockPane*   pToPane,
+                                                          bool          updateNow )
+{
+       if ( !pToPane )
+       
+               pToPane = HitTestPanes( shapeInParent, NULL );
+
+       if ( !pToPane ) 
+               
+               return FALSE; // bar's shape does not hit any pane 
+                                        // - redocking is NOT possible
+
+       cbDockPane* pBarPane = GetBarPane( pBar );
+
+       if ( updateNow )
+
+               GetUpdatesManager().OnStartChanges();
+
+       pBarPane->RemoveBar( pBar );
+
+       // FIXME FIXME:: the below recalc. may be a *huge* performance
+       //               hit, it could be eliminated though...
+       //               but first the "pane-postion-changed" problem 
+       //               have to be fixed 
+
+       RecalcLayout( FALSE );
+
+       pToPane->InsertBar( pBar, shapeInParent );
+
+       RecalcLayout( FALSE );
+
+       // finish update "transaction"
+
+       if ( updateNow )
+       {
+               GetUpdatesManager().OnFinishChanges();
+               GetUpdatesManager().UpdateNow();
+       }
+
+       return TRUE;
+}
+
+cbBarInfo* wxFrameLayout::FindBarByName( const wxString& name )
+{
+       for( size_t i = 0; i != mAllBars.Count(); ++i )
+
+               if ( mAllBars[i]->mName == name )
+
+                       return mAllBars[i];
+
+       return NULL;
+}
+
+cbBarInfo* wxFrameLayout::FindBarByWindow( const wxWindow* pWnd )
+{
+       for( size_t i = 0; i != mAllBars.Count(); ++i )
+
+               if ( mAllBars[i]->mpBarWnd == pWnd )
+
+                       return mAllBars[i];
+
+       return NULL;
+}
+
+BarArrayT& wxFrameLayout::GetBars()
+{
+       return mAllBars;
+}
+
+void wxFrameLayout::SetBarState( cbBarInfo* pBar, int newState, bool updateNow )
+{
+       if ( newState == wxCBAR_FLOATING && !mFloatingOn )
+
+               return;
+
+       if ( updateNow )
+
+               GetUpdatesManager().OnStartChanges();
+
+       pBar->mUMgrData.SetDirty(TRUE);
+
+       // check bar's previous state
+
+       if ( pBar->mState != wxCBAR_HIDDEN && pBar->mState != wxCBAR_FLOATING )
+       {
+               cbDockPane* pPane;
+               cbRowInfo*  pRow;
+
+               bool success = LocateBar( pBar, &pRow, &pPane );
+
+               wxASSERT( success ); // DBG::
+
+               // save LRU-dim info before removing bar
+
+               pBar->mDimInfo.mLRUPane = pPane->GetAlignment();
+               pBar->mDimInfo.mBounds[ pPane->GetAlignment() ] = pBar->mBounds;
+
+               // remove it from the pane it was docked on
+
+               pPane->RemoveBar( pBar );
+
+       }
+
+       if ( pBar->mState == wxCBAR_FLOATING && newState != wxCBAR_FLOATING )
+       {
+               // remove bar's window form the containing mini-frame
+               // and set it's parent to be layout's parent frame
+
+               if ( pBar->mpBarWnd )
+               {
+                       pBar->mpBarWnd->Show(FALSE); // to avoid flicker upon reparenting
+
+                       wxNode* pNode = mFloatedFrames.First();
+
+                       while( pNode )
+                       {
+                               cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
+
+                               if ( pFFrm->GetBar() == pBar )
+                               {
+                                       pFFrm->Show( FALSE ); // reduces flicker sligthly 
+
+                                       ReparentWindow( pBar->mpBarWnd, &GetParentFrame() );
+
+                                       pBar->mBounds = pBar->mDimInfo.mBounds[ pBar->mDimInfo.mLRUPane ];
+
+                                       if ( newState != wxCBAR_HIDDEN )
+
+                                               pBar->mAlignment = pBar->mDimInfo.mLRUPane;
+
+                                       mFloatedFrames.DeleteNode( pNode );
+
+                                       pFFrm->Show( FALSE );
+                                       pFFrm->Destroy(); break;
+                               }
+
+                               pNode = pNode->Next();
+                       }
+
+                       // FOR NOW:: excessive!
+                       //if ( mpFrameClient ) mpFrameClient->Refresh();
+                       if ( mpFrameClient )
+                mClientWndRefreshPending = TRUE;
+               }
+       }
+
+       pBar->mState = newState;
+
+       DoSetBarState( pBar );
+
+       if ( updateNow )
+       {
+               RecalcLayout(FALSE);
+
+               GetUpdatesManager().OnFinishChanges();
+               GetUpdatesManager().UpdateNow();
+       }
+}
+
+void wxFrameLayout::InverseVisibility( cbBarInfo* pBar )
+{
+       wxASSERT( pBar ); // DBG::
+
+       // "inverse" bar-visibility of the selected bar
+
+       int newState = 0;
+
+       if ( pBar->mState == wxCBAR_HIDDEN )
+       {
+               if ( pBar->mAlignment == -1 )
+               {
+                       pBar->mAlignment = 0;       // just remove "-1" marking
+                       newState = wxCBAR_FLOATING;
+               }
+               else
+               if ( pBar->mAlignment == FL_ALIGN_TOP ||
+                        pBar->mAlignment == FL_ALIGN_BOTTOM )
+
+                       newState = wxCBAR_DOCKED_HORIZONTALLY;
+               else
+                       newState = wxCBAR_DOCKED_VERTICALLY;
+       }
+       else
+       {
+               newState = wxCBAR_HIDDEN;
+
+               if ( pBar->mState == wxCBAR_FLOATING )
+
+                       pBar->mAlignment = -1;
+       }
+
+       this->SetBarState( pBar, newState, TRUE );
+
+       if ( newState == wxCBAR_FLOATING )
+
+               this->RepositionFloatedBar( pBar ); 
+}
+
+void wxFrameLayout::ApplyBarProperties( cbBarInfo* pBar )
+{
+       if ( pBar->mState == wxCBAR_FLOATING )
+       {
+               RepositionFloatedBar( pBar );
+       }
+       else
+       if ( pBar->mState == wxCBAR_DOCKED_HORIZONTALLY ||
+            pBar->mState == wxCBAR_DOCKED_VERTICALLY
+          )
+       {
+               // FOR NOW:: nothing
+       }
+
+}
+
+void wxFrameLayout::RepositionFloatedBar( cbBarInfo* pBar )
+{
+       if ( !mFloatingOn ) return;
+
+       wxNode* pNode = mFloatedFrames.First();
+
+       while( pNode )
+       {
+               cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data());
+
+               if ( pFFrm->GetBar() == pBar )
+               {
+                       wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];
+
+                       int x = bounds.x,
+                               y = bounds.y;
+
+                       GetParentFrame().ClientToScreen( &x, &y );
+
+                       pFFrm->PositionFloatedWnd( x,y, 
+                                                                          bounds.width,
+                                                                          bounds.height );
+
+                       break;
+               }
+
+               pNode = pNode->Next();
+       }
+}
+
+void wxFrameLayout::DoSetBarState( cbBarInfo* pBar )
+{
+       if ( pBar->mState != wxCBAR_FLOATING &&
+                pBar->mState != wxCBAR_HIDDEN )
+       
+               // dock it
+
+               mPanes[pBar->mAlignment]->InsertBar( pBar );
+       else
+       if ( pBar->mState == wxCBAR_HIDDEN )
+       {
+               // hide it
+
+               if ( pBar->mpBarWnd )
+
+                       pBar->mpBarWnd->Show( FALSE );
+       }
+       else
+       {                                       
+               if ( !mFloatingOn ) return;
+
+               // float it
+
+               if ( pBar->mpBarWnd == NULL || !CanReparent() )
+               {                                                               
+                       // FOR NOW:: just hide it
+
+                       if ( pBar->mpBarWnd )
+
+                               pBar->mpBarWnd->Show( FALSE );
+
+                       pBar->mState = wxCBAR_HIDDEN;
+
+                       return;
+               }
+
+               cbFloatedBarWindow* pMiniFrm = new cbFloatedBarWindow();
+
+               pMiniFrm->SetBar( pBar );
+               pMiniFrm->SetLayout( this );
+
+               pMiniFrm->Create( &GetParentFrame(), -1, pBar->mName, 
+                                                 wxPoint( 50,50 ),
+                                                 wxSize ( 0, 0  ),
+                          wxFRAME_FLOAT_ON_PARENT  |  wxFRAME_TOOL_WINDOW
+                                               );
+
+               pMiniFrm->SetClient( pBar->mpBarWnd );
+
+               ReparentWindow( pBar->mpBarWnd, pMiniFrm );
+
+               mFloatedFrames.Append( pMiniFrm );
+
+               wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING];
+
+               // check if it wasn't floated anytime before
+
+               if ( bounds.width == -1 )
+               {
+                       wxRect& clntRect = GetClientRect();
+
+                       // adjust position into which the next floated bar will be placed
+
+                       if ( mNextFloatedWndPos.x + bounds.width > clntRect.width )
+
+                               mNextFloatedWndPos.x = mFloatingPosStep.x;
+
+                       if ( mNextFloatedWndPos.y + bounds.height > clntRect.height )
+
+                               mNextFloatedWndPos.y = mFloatingPosStep.y;
+
+                       bounds.x = mNextFloatedWndPos.x + clntRect.x;
+                       bounds.y = mNextFloatedWndPos.y + clntRect.y;
+
+                       bounds.width  = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].x;
+                       bounds.height = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].y;
+
+                       mNextFloatedWndPos.x += mFloatingPosStep.x;
+                       mNextFloatedWndPos.y += mFloatingPosStep.y;
+               }
+
+               pMiniFrm->Show( TRUE );
+
+               // FIXME:: this is excessive
+               pBar->mpBarWnd->Show(TRUE);
+       }
+}
+
+void wxFrameLayout::RemoveBar( cbBarInfo* pBarInfo )
+{
+       // first, try to "guess" what was the perviouse state of the bar
+
+       cbDockPane* pPane;
+       cbRowInfo*  pRow;
+
+       if ( LocateBar( pBarInfo, &pRow, &pPane ) )
+       {
+               // ...aha, bar was docked into one of the panes,
+               // remove it from there
+
+               pPane->RemoveBar( pBarInfo );
+       }
+
+       for( size_t i = 0; i != mAllBars.Count(); ++i )
+       {
+               if ( mAllBars[i] == pBarInfo )
+               {
+#if wxCHECK_VERSION(2,3,2)
+                       mAllBars.RemoveAt(i); 
+#else
+                       mAllBars.Remove(i); 
+#endif
+                       if ( pBarInfo->mpBarWnd ) // hides it's window
+
+                               pBarInfo->mpBarWnd->Show( FALSE );
+
+                       delete pBarInfo;
+
+                       return;
+               }
+       }
+       int avoidCompilerWarning = 0;
+       wxASSERT(avoidCompilerWarning); // DBG:: bar info should be present in the list of all bars of all panes
+
+}
+
+bool wxFrameLayout::LocateBar( cbBarInfo* pBarInfo, 
+                                                          cbRowInfo**  ppRow,
+                                                          cbDockPane** ppPane )
+{
+       (*ppRow)  = NULL;
+       (*ppPane) = NULL;
+
+       for( int n = 0; n != MAX_PANES; ++n )
+       {
+               wxBarIterator i( mPanes[n]->GetRowList() );
+
+               while( i.Next() )
+               
+                       if ( &i.BarInfo() == pBarInfo )
+                       {
+                               (*ppPane) = mPanes[n];
+                               (*ppRow ) = &i.RowInfo();
+
+                               return TRUE;
+                       }
+       }
+
+       return FALSE;
+}
+
+void wxFrameLayout::RecalcLayout( bool repositionBarsNow )
+{
+       mRecalcPending = FALSE;
+
+       int frmWidth, frmHeight;
+       mpFrame->GetClientSize( &frmWidth, &frmHeight );
+       int paneHeight = 0;
+
+       int curY = 0;
+       int curX = 0;
+       wxRect rect;
+
+       // pane positioning priorities in decreasing order:
+       // top, bottom, left, right
+
+       // setup TOP pane
+
+       cbDockPane* pPane = mPanes[ FL_ALIGN_TOP ];
+
+       pPane->SetPaneWidth( frmWidth );
+       pPane->RecalcLayout();
+
+       paneHeight = pPane->GetPaneHeight();
+
+       rect.x          = curX;
+       rect.y          = curY;
+       rect.width  = frmWidth;
+       rect.height     = wxMin( paneHeight, frmHeight - curY );
+
+       pPane->SetBoundsInParent( rect );
+
+       curY += paneHeight;
+
+       // setup BOTTOM pane
+
+       pPane = mPanes[ FL_ALIGN_BOTTOM ];
+
+       pPane->SetPaneWidth( frmWidth );
+       pPane->RecalcLayout();
+
+       paneHeight = pPane->GetPaneHeight();
+
+       rect.x          = curX;
+       rect.y          = wxMax( frmHeight - paneHeight, curY );
+       rect.width  = frmWidth;
+       rect.height = frmHeight - rect.y;
+
+       pPane->SetBoundsInParent( rect );
+
+       // setup LEFT pane 
+
+       pPane = mPanes[ FL_ALIGN_LEFT ];
+
+                                                // bottom pane's y
+       pPane->SetPaneWidth( rect.y - curY );
+
+       pPane->RecalcLayout();
+       paneHeight = pPane->GetPaneHeight();
+
+                                 // bottom rect's y
+       rect.height = rect.y - curY;
+       rect.x = curX;
+       rect.y = curY;
+       rect.width  = wxMin( paneHeight, frmWidth );
+
+       pPane->SetBoundsInParent( rect );
+
+       curX += rect.width;
+
+       // setup RIGHT pane
+
+       pPane = mPanes[ FL_ALIGN_RIGHT ];
+
+                                                // left pane's height
+       pPane->SetPaneWidth( rect.height );
+
+       pPane->RecalcLayout();
+       paneHeight = pPane->GetPaneHeight();
+
+                                 // left pane's height
+       rect.height = rect.height;
+       rect.x = wxMax( frmWidth - paneHeight, curX );
+       rect.y = curY;
+       rect.width  = frmWidth - rect.x;
+
+       pPane->SetBoundsInParent( rect );
+
+       // recalc bounds of the client-window
+
+       mClntWndBounds.x = mPanes[FL_ALIGN_LEFT]->mBoundsInParent.x + 
+                                          mPanes[FL_ALIGN_LEFT]->mBoundsInParent.width;
+       mClntWndBounds.y = mPanes[FL_ALIGN_TOP ]->mBoundsInParent.y + 
+                                          mPanes[FL_ALIGN_TOP ]->mBoundsInParent.height;
+
+       mClntWndBounds.width  = mPanes[FL_ALIGN_RIGHT]->mBoundsInParent.x -
+                                               mClntWndBounds.x;
+       mClntWndBounds.height = mPanes[FL_ALIGN_BOTTOM]->mBoundsInParent.y -
+                                               mClntWndBounds.y;
+
+       if ( repositionBarsNow )
+
+               PositionPanes();
+}
+
+int wxFrameLayout::GetClientHeight()
+{
+       // for better portablility wxWindow::GetSzie() is not used here
+
+       return mClntWndBounds.height;
+}
+
+int wxFrameLayout::GetClientWidth()
+{
+       // for better portablility wxWindow::GetSzie() is not used here
+
+       return mClntWndBounds.width;
+}
+
+void wxFrameLayout::PositionClientWindow()
+{
+       if ( mpFrameClient )
+       {
+               if ( mClntWndBounds.width >= 1 && mClntWndBounds.height >= 1 )
+               {
+                       mpFrameClient->SetSize( mClntWndBounds.x,     mClntWndBounds.y, 
+                                                                       mClntWndBounds.width, mClntWndBounds.height, 0 );
+
+                       if ( !mpFrameClient->IsShown() )
+
+                               mpFrameClient->Show( TRUE );
+               }
+               else
+                       mpFrameClient->Show( FALSE );
+       }
+}
+
+void wxFrameLayout::PositionPanes()
+{
+       PositionClientWindow();
+
+       // FOR NOW:: excessive updates!
+       // reposition bars within all panes
+
+       for( int i = 0; i != MAX_PANES; ++i )
+               
+               mPanes[i]->SizePaneObjects();
+}
+
+void wxFrameLayout::OnSize( wxSizeEvent& event )
+{
+       if ( event.GetEventObject() == (wxObject*) mpFrame )
+       
+               RecalcLayout(TRUE);
+}
+
+/*** protected members ***/
+
+void wxFrameLayout::HideBarWindows()
+{
+       for( size_t i = 0; i != mAllBars.Count(); ++i )
+
+               if ( mAllBars[i]->mpBarWnd && mAllBars[i]->mState != wxCBAR_FLOATING )
+               
+                       mAllBars[i]->mpBarWnd->Show( FALSE );
+
+       // then floated frames
+
+       ShowFloatedWindows( FALSE );
+
+       if ( mpFrameClient )
+
+               mpFrameClient->Show( FALSE );
+}
+
+void wxFrameLayout::UnhookFromFrame()
+{
+       // NOTE:: the SetEvtHandlerEnabled() method is not used
+       //        here, since it is assumed, that unhooking layout
+       //        from window may result destroying of the layout itself
+       //       
+       //        BUG BUG BUG (wx):: this would not be a problem if 
+       //                                               wxEvtHandler's destructor would check if 
+       //                                                       this handler is currently the top-most 
+       //                                                       handler of some window, and additionally 
+       //                                                       to the reconnecting itself from the chain
+       //                                                       it would also re-setup current event handler 
+       //                                                       of the window using wxWindow::SetEventHandler()
+
+       // FOR NOW::
+
+       if ( mpFrame->GetEventHandler() == this )
+
+               mpFrame->PopEventHandler();
+
+       return;
+
+       // TBD ???:  Cannot reach this code
+       if ( mpFrame )
+       {
+               if ( this == mpFrame->GetEventHandler() )
+               
+                       mpFrame->SetEventHandler( this->GetNextHandler() );
+               else
+                       {
+                               wxEvtHandler* pCur = mpFrame->GetEventHandler();
+
+                               while( pCur )
+                               {
+                                       if ( pCur == this ) break;
+
+                                       pCur = pCur->GetNextHandler();
+                               }
+
+                               // do not try to unhook ourselves if we're not hooked yet
+                               if ( !pCur ) return;
+                       }
+
+               if ( GetPreviousHandler() )
+
+                       GetPreviousHandler()->SetNextHandler( GetNextHandler() );
+               else
+               {
+                       mpFrame->PopEventHandler();
+                       return;
+               }
+
+
+               if ( GetNextHandler() )
+
+                       GetNextHandler()->SetPreviousHandler( GetPreviousHandler() );
+
+               SetNextHandler( NULL );
+               SetPreviousHandler( NULL );
+       }
+}
+
+void wxFrameLayout::HookUpToFrame()
+{
+       // unhook us first, we're already hooked up
+
+       UnhookFromFrame();
+
+       // put ourselves on top
+
+       mpFrame->PushEventHandler( this );
+}
+
+cbDockPane* wxFrameLayout::GetBarPane( cbBarInfo* pBar )
+{
+       for( int i = 0; i != MAX_PANES; ++i )
+
+               if ( mPanes[i]->BarPresent( pBar ) ) return mPanes[i];
+
+       return NULL;
+}
+
+void wxFrameLayout::CreateCursors()
+{
+       /*
+       // FIXME:: The below code somehow doesn't work - cursors remain unchanged
+       char bits[64];
+       
+       set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
+
+       mpHorizCursor = new wxCursor( bits, 32, 16 );
+
+       set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
+
+       mpVertCursor  = new wxCursor( bits, 32, 16 );
+       */
+
+       // FOR NOW:: use standard ones
+
+    mpHorizCursor  = new wxCursor(wxCURSOR_SIZEWE);
+    mpVertCursor   = new wxCursor(wxCURSOR_SIZENS);
+       mpNormalCursor = new wxCursor(wxCURSOR_ARROW );
+       mpDragCursor   = new wxCursor(wxCURSOR_CROSS );
+       mpNECursor     = new wxCursor(wxCURSOR_NO_ENTRY);
+
+       mFloatingPosStep.x = 25;
+       mFloatingPosStep.y = 25;
+
+       mNextFloatedWndPos.x = mFloatingPosStep.x;
+       mNextFloatedWndPos.y = mFloatingPosStep.y;
+}
+
+bool wxFrameLayout::HitTestPane( cbDockPane* pPane, int x, int y )
+{
+       return rect_contains_point( pPane->GetRealRect(), x, y );
+}
+
+cbDockPane* wxFrameLayout::HitTestPanes( const wxRect& rect,
+                                                                                cbDockPane* pCurPane )
+{
+       // first, give the privilege to the current pane
+
+       if ( pCurPane && rect_hits_rect( pCurPane->GetRealRect(), rect ) ) 
+       
+               return pCurPane;
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               if ( pCurPane != mPanes[i] &&
+                    rect_hits_rect( mPanes[i]->GetRealRect(), rect ) ) 
+
+                       return mPanes[i];
+
+       return 0;
+}
+
+void wxFrameLayout::ForwardMouseEvent( wxMouseEvent& event, 
+                                                                                  cbDockPane*   pToPane,
+                                                                                  int           eventType )
+{
+       wxPoint pos( event.m_x, event.m_y );
+       pToPane->FrameToPane( &pos.x, &pos.y );
+
+#if wxCHECK_VERSION(2,3,0)
+       if ( eventType == cbEVT_PL_LEFT_DOWN )
+       {
+               cbLeftDownEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else if ( eventType == cbEVT_PL_LEFT_DCLICK )
+       {
+               cbLeftDClickEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else if ( eventType == cbEVT_PL_LEFT_UP )
+       {
+               cbLeftUpEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else if ( eventType == cbEVT_PL_RIGHT_DOWN )
+       {
+               cbRightDownEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else if ( eventType == cbEVT_PL_RIGHT_UP )
+       {
+               cbRightUpEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else if ( eventType == cbEVT_PL_MOTION )
+       {
+               cbMotionEvent evt( pos, pToPane );
+               FirePluginEvent( evt );
+       }
+       else 
+       {
+               int avoidCompilerWarning = 0;
+               wxASSERT(avoidCompilerWarning); // DBG::
+       }
+#else
+       switch ( eventType )
+       {
+               case cbEVT_PL_LEFT_DOWN : { cbLeftDownEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               case cbEVT_PL_LEFT_DCLICK:{ cbLeftDClickEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               case cbEVT_PL_LEFT_UP   : { cbLeftUpEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               case cbEVT_PL_RIGHT_DOWN: { cbRightDownEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               case cbEVT_PL_RIGHT_UP  : { cbRightUpEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               case cbEVT_PL_MOTION    : { cbMotionEvent evt( pos, pToPane );
+                                                                   FirePluginEvent( evt ); break;
+                                                                 }
+
+               default : wxASSERT(0); // DBG::
+       }
+#endif // #if wxCHECK_VERSION(2,3,0)
+}  // wxFrameLayout::ForwardMouseEvent()
+
+
+void wxFrameLayout::RouteMouseEvent( wxMouseEvent& event, int pluginEvtType )
+{
+       if ( mpPaneInFocus )
+
+               ForwardMouseEvent( event, mpPaneInFocus, pluginEvtType );
+       else
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
+               {
+                       ForwardMouseEvent( event, mPanes[i], pluginEvtType );
+
+                       return;
+               }
+}
+
+/*** event handlers ***/
+
+void wxFrameLayout::OnRButtonDown( wxMouseEvent& event )
+{
+       RouteMouseEvent( event, cbEVT_PL_RIGHT_DOWN );
+}
+
+void wxFrameLayout::OnRButtonUp( wxMouseEvent& event )
+{
+       RouteMouseEvent( event, cbEVT_PL_RIGHT_UP );
+}
+
+void wxFrameLayout::OnLButtonDown( wxMouseEvent& event )
+{
+       RouteMouseEvent( event, cbEVT_PL_LEFT_DOWN );
+}
+
+void wxFrameLayout::OnLDblClick( wxMouseEvent& event )
+{
+       RouteMouseEvent( event, cbEVT_PL_LEFT_DCLICK );
+}
+
+void wxFrameLayout::OnLButtonUp( wxMouseEvent& event )
+{
+       RouteMouseEvent( event, cbEVT_PL_LEFT_UP );
+}
+
+void wxFrameLayout::OnMouseMove( wxMouseEvent& event )
+{
+       if ( mpPaneInFocus )
+       
+               ForwardMouseEvent( event, mpPaneInFocus, cbEVT_PL_MOTION );
+       else
+               for( int i = 0; i != MAX_PANES; ++i )
+               
+                       if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) )
+                       {
+                               if ( mpLRUPane && mpLRUPane != mPanes[i] )
+                               {
+                                       // simulate "mouse-leave" event
+                                       ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
+                               }
+
+                               ForwardMouseEvent( event, mPanes[i], cbEVT_PL_MOTION );
+
+                               mpLRUPane = mPanes[i];
+
+                               return;
+                       }
+
+       if ( mpLRUPane )
+       {
+               // simulate "mouse-leave" event
+               ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION );
+               mpLRUPane = 0;
+       }
+}
+
+void wxFrameLayout::OnPaint( wxPaintEvent& event )
+{
+       if ( mRecalcPending  )
+       
+               RecalcLayout( TRUE );
+
+       wxPaintDC dc(mpFrame);
+
+       for( int i = 0; i != MAX_PANES; ++i )
+       {
+               wxRect& rect = mPanes[i]->mBoundsInParent;
+
+               dc.SetClippingRegion( rect.x, rect.y, rect.width, rect.height );
+
+               mPanes[i]->PaintPane(dc);
+
+               dc.DestroyClippingRegion();
+       }
+
+       event.Skip();
+}
+
+void wxFrameLayout::OnEraseBackground( wxEraseEvent& event )
+{
+       // do nothing
+}
+
+void wxFrameLayout::OnIdle( wxIdleEvent& event )
+{
+       wxWindow* focus = wxWindow::FindFocus();
+
+       if ( !focus && mCheckFocusWhenIdle )
+       {
+               wxMessageBox( "Hi, no more focus in this app!" );
+
+               mCheckFocusWhenIdle = FALSE;
+               //ShowFloatedWindows( FALSE );
+       }
+
+       mCheckFocusWhenIdle = FALSE;
+
+       event.Skip();
+}
+
+
+void wxFrameLayout::OnKillFocus( wxFocusEvent& event )
+{
+       //wxMessageBox( "wxFrameLayoutGot Kill Focus!" );
+       //ShowFloatedWindows( FALSE );
+}
+
+void wxFrameLayout::OnSetFocus( wxFocusEvent& event )
+{
+       //ShowFloatedWindows( TRUE );
+}
+
+void wxFrameLayout::OnActivate( wxActivateEvent& event )
+{
+#if 0
+       if ( event.GetActive() == FALSE )                               
+       {
+               wxWindow* focus = wxWindow::FindFocus();
+
+               if ( !focus || focus == &GetParentFrame() )
+               {
+                       mCheckFocusWhenIdle = TRUE;
+
+                       if ( !focus )
+
+                               wxMessageBox("Deactivated!" );
+
+               }
+       }
+#endif
+}
+
+void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties& props, int alignment )
+{
+       props = mPanes[alignment]->mProps;
+}
+
+void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties& props, int paneMask )
+{
+       for( int i = 0; i != MAX_PANES; ++i )
+       
+               if ( mPanes[i]->MatchesMask( paneMask ) )
+
+                       mPanes[i]->mProps = props;
+}
+
+void wxFrameLayout::SetMargins( int top, int bottom, int left, int right,
+                                       int paneMask )
+{
+       for( int i = 0; i != MAX_PANES; ++i )
+       {
+               cbDockPane& pane = *mPanes[i];
+
+               if ( pane.MatchesMask( paneMask ) )
+               {
+                       pane.mTopMargin = top;
+                       pane.mBottomMargin = bottom;
+                       pane.mLeftMargin = left;
+                       pane.mRightMargin = right;
+               }
+       }
+}
+
+void wxFrameLayout::SetPaneBackground( const wxColour& colour )
+{
+       mBorderPen.SetColour( colour );
+}
+
+void wxFrameLayout::RefreshNow( bool recalcLayout )
+{
+       if ( recalcLayout ) RecalcLayout( TRUE );
+
+       if ( mpFrame ) mpFrame->Refresh();
+}
+
+/*** plugin-related methods ***/
+
+void wxFrameLayout::FirePluginEvent( cbPluginEvent& event )
+{
+       // check state of input capture, before processing the event
+
+       if ( mpCaputesInput ) 
+       {
+               bool isInputEvt = TRUE;
+#if wxCHECK_VERSION(2,3,0)
+               if ( event.m_eventType != cbEVT_PL_LEFT_DOWN &&
+                        event.m_eventType != cbEVT_PL_LEFT_UP &&
+                        event.m_eventType != cbEVT_PL_RIGHT_DOWN &&
+                        event.m_eventType != cbEVT_PL_RIGHT_UP &&
+                        event.m_eventType != cbEVT_PL_MOTION )
+                       isInputEvt = FALSE;
+#else
+               switch ( event.m_eventType )
+               {
+                       case cbEVT_PL_LEFT_DOWN  : break;
+                       case cbEVT_PL_LEFT_UP    : break;
+                       case cbEVT_PL_RIGHT_DOWN : break;
+                       case cbEVT_PL_RIGHT_UP   : break;
+                       case cbEVT_PL_MOTION     : break;
+                       
+                       default : isInputEvt = FALSE; break;
+               }
+#endif  // #if wxCHECK_VERSION(2,3,0)
+
+               if ( isInputEvt )
+               {
+                       mpCaputesInput->ProcessEvent( event );
+                       return;
+               }
+       }
+
+       GetTopPlugin().ProcessEvent( event );
+}
+
+void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase* pPlugin )
+{
+       // cannot capture events for more than one plugin at a time
+       wxASSERT( mpCaputesInput == NULL );
+
+       mpCaputesInput = pPlugin;
+
+}
+
+void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase* pPlugin )
+{
+       // events should be captured first
+       wxASSERT( mpCaputesInput != NULL );
+
+       mpCaputesInput = NULL;
+}
+
+void wxFrameLayout::CaptureEventsForPane( cbDockPane* toPane )
+{
+       // cannot capture events twice (without releasing)
+       wxASSERT( mpPaneInFocus == NULL );
+
+       mpFrame->CaptureMouse();
+
+       mpPaneInFocus = toPane;
+}
+
+void wxFrameLayout::ReleaseEventsFromPane( cbDockPane* fromPane )
+{
+       // cannot release events without capturing them
+       wxASSERT( mpPaneInFocus != NULL );
+
+       mpFrame->ReleaseMouse();
+
+       mpPaneInFocus = NULL;
+}
+
+cbPluginBase& wxFrameLayout::GetTopPlugin()
+{
+       if ( !mpTopPlugin ) 
+       
+               PushDefaultPlugins(); // automatic configuration
+
+       return *mpTopPlugin;
+}
+
+void wxFrameLayout::SetTopPlugin( cbPluginBase* pPlugin ) 
+{ 
+       mpTopPlugin = pPlugin; 
+}
+
+bool wxFrameLayout::HasTopPlugin() 
+{ 
+       return ( mpTopPlugin != NULL ); 
+}
+
+void wxFrameLayout::PushPlugin( cbPluginBase* pPlugin )
+{
+       if ( !mpTopPlugin ) 
+               
+               mpTopPlugin = pPlugin;
+       else
+       {
+               pPlugin->SetNextHandler( mpTopPlugin );
+
+               mpTopPlugin->SetPreviousHandler( pPlugin );
+
+               mpTopPlugin = pPlugin;
+       }
+
+       mpTopPlugin->OnInitPlugin(); // notification
+}
+
+void wxFrameLayout::PopPlugin()
+{
+       wxASSERT( mpTopPlugin ); // DBG:: at least one plugin should be present
+
+       cbPluginBase* pPopped = mpTopPlugin;
+
+       mpTopPlugin = (cbPluginBase*)mpTopPlugin->GetNextHandler();
+
+       delete pPopped;
+}
+
+void wxFrameLayout::PopAllPlugins()
+{
+       while( mpTopPlugin ) PopPlugin();
+}
+
+void wxFrameLayout::PushDefaultPlugins()
+{
+       // FIXME:: to much of the stuff for the default...
+
+       AddPlugin( CLASSINFO( cbRowLayoutPlugin       ) );
+       AddPlugin( CLASSINFO( cbBarDragPlugin         ) );
+       AddPlugin( CLASSINFO( cbPaneDrawPlugin ) );
+}
+
+void wxFrameLayout::AddPlugin( wxClassInfo* pPlInfo, int paneMask )
+{
+       if ( FindPlugin ( pPlInfo ) ) return; // same type of plugin cannot be added twice
+
+       cbPluginBase* pObj = (cbPluginBase*)pPlInfo->CreateObject();
+
+       wxASSERT(pObj); // DBG:: plugin's class should be dynamic
+
+       pObj->mPaneMask = paneMask;
+       pObj->mpLayout  = this;
+
+       PushPlugin( pObj );
+}
+
+void wxFrameLayout::AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, 
+                                                                          int paneMask )
+{
+       wxASSERT( pNextPlInfo != pPlInfo ); // DBG:: no sence
+
+       cbPluginBase* pNextPl = FindPlugin( pNextPlInfo );
+
+       if ( !pNextPl )
+       {
+               AddPlugin( pPlInfo, paneMask );
+
+               return;
+       }
+
+       // remove existing one if present
+
+       cbPluginBase* pExistingPl = FindPlugin( pPlInfo );
+       
+       if ( pExistingPl ) RemovePlugin( pPlInfo );
+
+       // create an instance 
+
+       cbPluginBase* pNewPl = (cbPluginBase*)pPlInfo->CreateObject();
+
+       wxASSERT(pNewPl); // DBG:: plugin's class should be dynamic
+
+       // insert it to the chain
+
+       if ( pNextPl->GetPreviousHandler() )
+       
+               pNextPl->GetPreviousHandler()->SetNextHandler( pNewPl );
+       else
+               mpTopPlugin = pNewPl;
+
+       pNewPl->SetNextHandler( pNextPl );
+
+       pNewPl->SetPreviousHandler( pNextPl->GetPreviousHandler() );
+
+       pNextPl->SetPreviousHandler( pNewPl );
+
+       // set it up
+
+       pNewPl->mPaneMask = paneMask;
+       pNewPl->mpLayout  = this;
+
+       pNewPl->OnInitPlugin();
+}
+
+void wxFrameLayout::RemovePlugin( wxClassInfo* pPlInfo )
+{
+       cbPluginBase* pPlugin = FindPlugin( pPlInfo );
+
+       if ( !pPlugin ) return; // it's OK to remove not-existing plugin ;-)
+
+       if ( pPlugin->GetPreviousHandler() == NULL )
+
+               mpTopPlugin = (cbPluginBase*)pPlugin->GetNextHandler();
+
+       delete pPlugin;
+}
+
+cbPluginBase* wxFrameLayout::FindPlugin( wxClassInfo* pPlInfo )
+{
+       cbPluginBase *pCur = mpTopPlugin;
+
+       while( pCur )
+       {
+               // NOTE:: it might appear useful matching plugin
+               //        classes "polymorphically":
+
+               if ( pCur->GetClassInfo()->IsKindOf( pPlInfo ) )
+
+                       return pCur;
+
+               pCur = (cbPluginBase*)pCur->GetNextHandler();
+       }
+
+       return NULL;
+}
+
+/***** Implementation for class cbUpdateMgrData *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData, wxObject )
+
+cbUpdateMgrData::cbUpdateMgrData() 
+
+       : mPrevBounds( -1,-1,0,0 ),
+         mIsDirty( TRUE )           // inidicate initial change
+{}
+
+void cbUpdateMgrData::StoreItemState( const wxRect& boundsInParent )
+{ 
+       mPrevBounds = boundsInParent; 
+}
+
+void cbUpdateMgrData::SetDirty( bool isDirty )
+{
+       mIsDirty = isDirty;
+}
+
+void cbUpdateMgrData::SetCustomData( wxObject* pCustomData )
+{
+       mpCustomData = pCustomData;
+}
+
+/***** Implementation for class cbDockPane *****/
+
+void wxBarIterator::Reset()
+{
+       mpRow = ( mpRows->Count() ) ? (*mpRows)[0] : NULL;
+       mpBar = NULL;
+}
+
+wxBarIterator::wxBarIterator( RowArrayT& rows )
+
+       : mpRows( &rows ),
+         mpRow ( NULL  ),
+         mpBar ( NULL  )
+{
+       Reset();
+}
+
+bool wxBarIterator::Next()
+{         
+       if ( mpRow )
+       {
+               if ( mpBar )
+                       mpBar = mpBar->mpNext;
+               else
+               {
+                       if ( mpRow->mBars.GetCount() == 0 )
+                       {
+                               return FALSE; 
+                       }
+
+                       mpBar = mpRow->mBars[0];
+               }
+       
+               if ( !mpBar )
+               {       
+                       // skip to the next row
+
+                       mpRow = mpRow->mpNext;
+       
+                       if ( mpRow )
+       
+                               mpBar = mpRow->mBars[0];
+                       else
+                               return FALSE;
+               }
+       
+               return TRUE;
+       }
+       else
+               return FALSE;
+}
+
+cbBarInfo& wxBarIterator::BarInfo()
+{
+       return *mpBar;
+}
+
+cbRowInfo& wxBarIterator::RowInfo()
+{
+       return *mpRow;
+}
+
+/***** Implementation for class cbBarDimHandlerBase *****/
+
+IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase, wxObject )
+
+cbBarDimHandlerBase::cbBarDimHandlerBase()
+       : mRefCount(0)
+{}
+
+void cbBarDimHandlerBase::AddRef()
+{
+       ++mRefCount;
+}
+
+void cbBarDimHandlerBase::RemoveRef()
+{
+       if ( --mRefCount <= 0 ) delete this;
+}
+
+/***** Implementation for class cbDimInfo *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbDimInfo, wxObject )
+
+cbDimInfo::cbDimInfo() 
+
+       : mVertGap ( 0 ), 
+         mHorizGap( 0 ),
+
+         mIsFixed(TRUE),
+         mpHandler( NULL )
+{
+       for( size_t i = 0; i != MAX_BAR_STATES; ++i )
+       {
+               mSizes[i].x = 20;
+               mSizes[i].y = 20;
+
+               mBounds[i] = wxRect( -1,-1,-1,-1 );
+       }
+}
+
+cbDimInfo::cbDimInfo( cbBarDimHandlerBase* pDimHandler,
+                                         bool                 isFixed  )
+
+       : mVertGap ( 0 ),
+         mHorizGap( 0 ),
+         mIsFixed ( isFixed  ),
+
+         mpHandler( pDimHandler )
+{
+       if ( mpHandler )
+       {
+               // int vtad = *((int*)mpHandler);
+               mpHandler->AddRef();
+       }
+       
+       for( size_t i = 0; i != MAX_BAR_STATES; ++i )
+       {
+               mSizes[i].x = -1;
+               mSizes[i].y = -1;
+
+               mBounds[i] = wxRect( -1,-1,-1,-1 );
+       }
+}
+
+cbDimInfo::cbDimInfo( int dh_x, int dh_y,
+                                         int dv_x, int dv_y,
+                                         int f_x,  int f_y,
+
+                                         bool isFixed,
+                                         int horizGap,
+                                         int vertGap,
+
+                                     cbBarDimHandlerBase* pDimHandler
+                                   )
+       : mVertGap  ( vertGap   ),
+         mHorizGap ( horizGap  ),
+         mIsFixed  ( isFixed   ),
+         mpHandler( pDimHandler )
+{
+       if ( mpHandler )
+       {
+               // int vtad = *((int*)mpHandler);
+               mpHandler->AddRef();
+       }
+
+       mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = dh_x;
+       mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = dh_y;
+       mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = dv_x;
+       mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = dv_y;
+       mSizes[wxCBAR_FLOATING           ].x = f_x;
+       mSizes[wxCBAR_FLOATING           ].y = f_y;
+
+       for( size_t i = 0; i != MAX_BAR_STATES; ++i )
+               mBounds[i] = wxRect( -1,-1,-1,-1 );
+}       
+
+cbDimInfo::cbDimInfo( int x, int y,  
+                      bool isFixed, int gap, 
+                      cbBarDimHandlerBase* pDimHandler)
+  : mVertGap  ( gap ),
+    mHorizGap ( gap ),
+    mIsFixed  ( isFixed ),
+    mpHandler( pDimHandler )
+{
+    if ( mpHandler )
+    {
+        // int vtad = *((int*)mpHandler);
+        mpHandler->AddRef();
+    }
+
+    mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = x;
+    mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = y;
+    mSizes[wxCBAR_DOCKED_VERTICALLY  ].x = x;
+    mSizes[wxCBAR_DOCKED_VERTICALLY  ].y = y;
+    mSizes[wxCBAR_FLOATING           ].x = x;
+    mSizes[wxCBAR_FLOATING           ].y = y;
+       
+    for( size_t i = 0; i != MAX_BAR_STATES; ++i )
+        mBounds[i] = wxRect( -1,-1,-1,-1 );
+}
+
+cbDimInfo::~cbDimInfo()
+{
+       if ( mpHandler ) 
+               
+               mpHandler->RemoveRef();
+}
+
+const cbDimInfo& cbDimInfo::operator=( const cbDimInfo& other )
+{
+       if ( this == &other ) return *this;
+
+       for( int i = 0; i != MAX_BAR_STATES; ++i )
+
+               mSizes[i] = other.mSizes[i];
+
+       mIsFixed  = other.mIsFixed;
+       mpHandler = other.mpHandler;
+
+       mVertGap  = other.mVertGap;
+       mHorizGap = other.mHorizGap;
+
+       if ( mpHandler )
+
+               mpHandler->AddRef();
+
+       return *this;
+}
+
+/***** Implementation for structure cbCommonPaneProperties *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties, wxObject )
+
+cbCommonPaneProperties::cbCommonPaneProperties(void)
+
+       : mRealTimeUpdatesOn    ( TRUE  ),
+         mOutOfPaneDragOn      ( TRUE  ),
+         mExactDockPredictionOn( FALSE ),
+         mNonDestructFirctionOn( FALSE ),
+         mShow3DPaneBorderOn   ( TRUE  ),
+         mBarFloatingOn        ( FALSE ),
+         mRowProportionsOn     ( FALSE ),
+         mColProportionsOn     ( TRUE  ),
+         mBarCollapseIconsOn   ( FALSE ),
+         mBarDragHintsOn       ( FALSE ),
+
+         mMinCBarDim( 16, 16 ),
+         mResizeHandleSize( 4 )
+{}
+
+/***** Implementation for class cbRowInfo *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbRowInfo, wxObject )
+
+cbRowInfo::cbRowInfo(void)
+
+       : mNotFixedBarsCnt( FALSE ),
+         mpNext          ( NULL ),
+         mpPrev          ( NULL ),
+         mpExpandedBar   ( NULL )
+{}
+
+cbRowInfo::~cbRowInfo()
+{
+       // nothing! all bars are removed using global bar
+       // list in wxFrameLayout class
+}
+
+/***** Implementation for class cbBarInfo *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbBarInfo, wxObject )
+
+cbBarInfo::cbBarInfo(void)
+
+       : mpRow( NULL ),
+
+         mpNext( NULL ),
+         mpPrev( NULL )
+{}
+
+cbBarInfo::~cbBarInfo()
+{
+       // nothing
+}
+
+/***** Implementation for class cbDockPane *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbDockPane, wxObject )
+
+// FIXME:: how to eliminate these cut&pasted constructors?
+
+cbDockPane::cbDockPane(void)                                                    
+       : mLeftMargin  ( 1 ),
+         mRightMargin ( 1 ),
+         mTopMargin   ( 1 ),
+         mBottomMargin( 1 ),
+         mPaneWidth ( 32768     ), // fake-up very large pane dims,
+                                   // since the real dimensions of the pane may not 
+                                                           // be known, while inserting bars initially
+         mPaneHeight( 32768     ),
+         mAlignment ( -1   ),
+         mpLayout   ( 0 ),
+         mpStoredRow( NULL )
+{}
+
+cbDockPane::cbDockPane( int alignment, wxFrameLayout* pPanel )
+                                                        
+       :  mLeftMargin  ( 1 ),
+         mRightMargin ( 1 ),
+         mTopMargin   ( 1 ),
+         mBottomMargin( 1 ),
+         mPaneWidth ( 32768     ), // fake-up very large pane dims,
+                                   // since the real dimensions of the pane may not 
+                                                           // be known, while inserting bars initially
+         mPaneHeight( 32768     ),
+         mAlignment ( alignment ),
+         mpLayout   ( pPanel    ),
+      mpStoredRow( NULL )       
+{}
+
+cbDockPane::~cbDockPane()
+{
+       for( size_t i = 0; i != mRows.Count(); ++i )
+
+               delete mRows[i];
+
+       mRowShapeData.DeleteContents( TRUE );
+       
+       // NOTE:: control bar infromation structures are cleaned-up
+       //        in wxFrameLayout's destructor, using global control-bar list
+}
+
+void cbDockPane::SetMargins( int top, int bottom, int left, int right )
+{
+       mTopMargin    = top;
+       mBottomMargin = bottom;
+       mLeftMargin   = left;
+       mRightMargin  = right;
+}
+
+/*** helpers of cbDockPane ***/
+
+void cbDockPane::PaintBarDecorations( cbBarInfo* pBar, wxDC& dc )
+{
+       cbDrawBarDecorEvent evt( pBar, dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::PaintBarHandles( cbBarInfo* pBar, wxDC& dc )
+{
+       cbDrawBarHandlesEvent evt( pBar, dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::PaintBar( cbBarInfo* pBar, wxDC& dc )
+{
+       PaintBarDecorations( pBar, dc );
+       PaintBarHandles( pBar, dc );
+}
+
+void cbDockPane::PaintRowHandles( cbRowInfo* pRow, wxDC& dc )
+{
+       cbDrawRowHandlesEvent evt( pRow, dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+
+       cbDrawRowDecorEvent evt1( pRow, dc, this );
+
+       mpLayout->FirePluginEvent( evt1 );
+}
+
+void cbDockPane::PaintRowBackground ( cbRowInfo* pRow, wxDC& dc )
+{
+       cbDrawRowBkGroundEvent evt( pRow, dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::PaintRowDecorations( cbRowInfo* pRow, wxDC& dc )
+{
+       size_t i = 0;
+
+       // decorations first
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       
+               PaintBarDecorations( pRow->mBars[i], dc );
+
+       // then handles if present
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+
+               PaintBarHandles( pRow->mBars[i], dc );
+}
+
+void cbDockPane::PaintRow( cbRowInfo* pRow, wxDC& dc )
+{
+       PaintRowBackground ( pRow, dc );
+       PaintRowDecorations( pRow, dc );
+       PaintRowHandles    ( pRow, dc );
+}
+
+void cbDockPane::PaintPaneBackground( wxDC& dc )
+{
+       cbDrawPaneBkGroundEvent evt( dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::PaintPaneDecorations( wxDC& dc )
+{
+       cbDrawPaneDecorEvent evt( dc, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::PaintPane( wxDC& dc )
+{
+       PaintPaneBackground( dc );
+
+       size_t i = 0;
+
+       // first decorations
+       for( i = 0; i != mRows.Count(); ++i )
+       {
+               PaintRowBackground( mRows[i], dc );
+               PaintRowDecorations( mRows[i], dc );
+       }
+
+       // than handles
+       for( i = 0; i != mRows.Count(); ++i )
+       
+               PaintRowHandles( mRows[i], dc );
+
+       // and finally
+       PaintPaneDecorations( dc );
+}
+
+void cbDockPane::SizeBar( cbBarInfo* pBar )
+{
+       cbSizeBarWndEvent evt( pBar, this );
+
+       mpLayout->FirePluginEvent( evt );
+       return;
+}
+
+void cbDockPane::SizeRowObjects( cbRowInfo* pRow )
+{
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+
+               SizeBar( pRow->mBars[i] );
+}
+
+void cbDockPane::SizePaneObjects()
+{
+       for( size_t i = 0; i != mRows.Count(); ++i )
+
+               SizeRowObjects( mRows[i] );
+}
+
+wxDC* cbDockPane::StartDrawInArea( const wxRect& area )
+{
+       wxDC* pDc = 0;
+
+       cbStartDrawInAreaEvent evt( area, &pDc, this );
+
+       mpLayout->FirePluginEvent( evt );
+
+       return pDc;
+}
+
+void cbDockPane::FinishDrawInArea( const wxRect& area )
+{
+       cbFinishDrawInAreaEvent evt( area, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+bool cbDockPane::IsFixedSize( cbBarInfo* pInfo )
+{
+       return ( pInfo->mDimInfo.mIsFixed );
+}
+
+int cbDockPane::GetNotFixedBarsCount( cbRowInfo* pRow )
+{
+       int cnt = 0;
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+
+               if ( !pRow->mBars[i]->IsFixed() )  ++cnt;
+
+       return cnt;
+}
+
+void cbDockPane::RemoveBar( cbBarInfo* pBar )
+{
+       bool needsRestoring = mProps.mNonDestructFirctionOn && 
+                                                 mpStoredRow == pBar->mpRow;
+
+       cbRemoveBarEvent evt( pBar, this );
+
+       mpLayout->FirePluginEvent( evt );
+
+       if ( needsRestoring )
+       {
+               SetRowShapeData( mpStoredRow, &mRowShapeData );
+
+               mpStoredRow = NULL;
+       }
+}
+
+void cbDockPane::SyncRowFlags( cbRowInfo* pRow )
+{
+       // setup mHasOnlyFixedBars flag for the row information
+       pRow->mHasOnlyFixedBars = TRUE;
+
+       pRow->mNotFixedBarsCnt = 0;
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               bar.mpRow = pRow;
+
+               if ( !bar.IsFixed() )
+               {
+                       pRow->mHasOnlyFixedBars = FALSE;
+                       ++pRow->mNotFixedBarsCnt;
+               }
+       }
+}
+
+void cbDockPane::FrameToPane( int* x, int* y )
+{
+       *x -= mLeftMargin;
+       *y -= mTopMargin;
+
+       if ( mAlignment == FL_ALIGN_TOP ||
+                mAlignment == FL_ALIGN_BOTTOM 
+          )
+       {
+               *x -= mBoundsInParent.x;
+               *y -= mBoundsInParent.y;
+       }
+       else
+       {
+               int rx = *x, ry = *y;
+
+               *x = ry - mBoundsInParent.y;
+
+               *y = rx - mBoundsInParent.x;
+       }
+}
+
+void cbDockPane::PaneToFrame( int* x, int* y )
+{
+       if ( mAlignment == FL_ALIGN_TOP ||
+                mAlignment == FL_ALIGN_BOTTOM 
+          )
+       {
+               *x += mBoundsInParent.x;
+               *y += mBoundsInParent.y;
+       }
+       else
+       {
+               int rx = *x, ry = *y;
+
+               *x = ry + mBoundsInParent.x;
+
+               *y = mBoundsInParent.y + rx;
+       }
+
+       *x += mLeftMargin;
+       *y += mTopMargin;
+}
+
+void cbDockPane::FrameToPane( wxRect* pRect )
+{
+       wxPoint upperLeft ( pRect->x, pRect->y );
+       wxPoint lowerRight( pRect->x + pRect->width,
+                               pRect->y + pRect->height );
+
+       FrameToPane( &upperLeft.x,  &upperLeft.y  );
+       FrameToPane( &lowerRight.x, &lowerRight.y );
+
+       pRect->x = wxMin(upperLeft.x,lowerRight.x);
+       pRect->y = wxMin(upperLeft.y,lowerRight.y);
+
+       pRect->width  = abs( lowerRight.x - upperLeft.x );
+       pRect->height = abs( lowerRight.y - upperLeft.y );
+}
+
+void cbDockPane::PaneToFrame( wxRect* pRect )
+{
+       wxPoint upperLeft ( pRect->x, pRect->y );
+       wxPoint lowerRight( pRect->x + pRect->width,
+                               pRect->y + pRect->height );
+
+       PaneToFrame( &upperLeft.x,  &upperLeft.y  );
+       PaneToFrame( &lowerRight.x, &lowerRight.y );
+
+       //wxRect newRect = wxRect( upperLeft, lowerRight );
+
+       pRect->x = wxMin(upperLeft.x,lowerRight.x);
+       pRect->y = wxMin(upperLeft.y,lowerRight.y);
+
+       pRect->width  = abs( lowerRight.x - upperLeft.x );
+       pRect->height = abs( lowerRight.y - upperLeft.y );
+}
+
+int cbDockPane::GetRowAt( int paneY )
+{
+       if ( paneY < 0 ) return -1;
+
+       int curY = 0;
+
+       size_t i = 0;
+
+       for( ; i != mRows.Count(); ++i )
+       {
+               int rowHeight = mRows[i]->mRowHeight;
+
+               int third = rowHeight/3;
+               
+               if ( paneY >= curY && paneY < curY + third ) 
+                       return i-1;
+
+               if ( paneY >= curY + third && paneY < curY + rowHeight - third ) 
+                       return i;
+
+               curY += rowHeight;
+       }
+
+       return i;
+}
+
+int cbDockPane::GetRowAt( int upperY, int lowerY )
+{
+       /*
+       // OLD STUFF::
+       int range    = lowerY - upperY;
+       int oneThird = range / 3;
+
+       wxNode* pRow = mRows.First();
+       int row = 0;
+       int curY = 0;
+
+       if ( lowerY <= 0 ) return -1;
+
+       while( pRow )
+       {
+               int rowHeight = GetRowHeight( (wxList*)pRow->Data() );
+
+               if ( upperY >= curY &&
+                        lowerY < curY ) return row;
+
+               if ( upperY <= curY && 
+                        lowerY >= curY &&
+                        curY - upperY >= oneThird ) return row-1;
+
+               if ( ( upperY <  curY + rowHeight && 
+                          lowerY >= curY + rowHeight &&
+                          curY + rowHeight - lowerY >= oneThird ) 
+                  )
+                       return row+1;
+
+               if ( lowerY <= curY + rowHeight ) return row;
+
+               ++row;
+               curY += rowHeight;
+               pRow = pRow->Next();
+       }
+       */
+
+       int mid = upperY + (lowerY - upperY)/2;
+
+       if ( mid < 0 ) return -1;
+
+       int curY = 0;
+       size_t i = 0;
+
+       for( ; i != mRows.Count(); ++i )
+       {
+               int rowHeight = mRows[i]->mRowHeight;
+
+               if ( mid >= curY && mid < curY + rowHeight ) return i;
+
+               curY += rowHeight;
+       }
+
+       return i;
+}
+
+int cbDockPane::GetRowY( cbRowInfo* pRow )
+{
+       int curY = 0;
+
+       for( size_t i = 0; i != mRows.Count(); ++i )
+       {
+               if ( mRows[i] == pRow ) break;
+
+               curY += mRows[i]->mRowHeight;
+       }
+
+       return curY;
+}
+
+bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo* pRow )
+{
+       while ( pRow->mpPrev )
+       {
+               pRow = pRow->mpPrev;
+
+               if ( pRow->mHasOnlyFixedBars )
+
+                       return TRUE;
+       } 
+
+       return FALSE;
+}
+
+bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo* pRow )
+{
+       while( pRow->mpNext )
+       {
+               pRow = pRow->mpNext;
+
+               if ( pRow->mHasOnlyFixedBars )
+
+                       return TRUE;
+       }
+
+       return FALSE;
+}
+
+bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo* pBar )
+{
+       while( pBar->mpPrev )
+       {
+               pBar = pBar->mpPrev;
+
+               if ( pBar->IsFixed() )
+
+                       return TRUE;
+       }
+               
+       return FALSE;
+}
+
+bool cbDockPane::HasNotFixedBarsRight( cbBarInfo* pBar )
+{
+       while( pBar->mpNext )
+       {
+               pBar = pBar->mpNext;
+
+               if ( pBar->IsFixed() )
+
+                       return TRUE;
+       }
+               
+       return FALSE;
+}
+
+void cbDockPane::CalcLengthRatios( cbRowInfo* pInRow )
+{
+       int totalWidth = 0;
+
+       size_t i = 0;
+
+       // clac current-maximal-total-length of all maximized bars
+
+       for( i = 0; i != pInRow->mBars.GetCount(); ++i )
+       {
+               cbBarInfo& bar = *pInRow->mBars[i];
+
+               if ( !bar.IsFixed() )
+
+                       totalWidth += bar.mBounds.width;
+       }
+
+       // set up persentages of occupied space for each maximized bar
+
+       for( i = 0; i != pInRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pInRow->mBars[i];
+
+               if ( !bar.IsFixed() )
+
+                       bar.mLenRatio = double(bar.mBounds.width)/double(totalWidth);
+       }
+}
+
+void cbDockPane::RecalcRowLayout( cbRowInfo* pRow )
+{
+       cbLayoutRowEvent evt( pRow, this );
+       
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::ExpandBar( cbBarInfo* pBar )
+{
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       if ( !pBar->mpRow->mpExpandedBar )
+       {
+               // save ratios only when there arent any bars expanded yet
+
+               cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
+
+               ratios.Clear();
+               ratios.Alloc( pBar->mpRow->mNotFixedBarsCnt );
+
+               cbBarInfo* pCur = pBar->mpRow->mBars[0];
+
+               while( pCur )
+               {
+                       if ( !pCur->IsFixed() )
+                       {
+                               ratios.Add( 0.0 );
+                               ratios[ ratios.GetCount() - 1 ] = pCur->mLenRatio; 
+                       }
+
+                       pCur = pCur->mpNext;
+               }
+       }
+
+       cbBarInfo* pCur = pBar->mpRow->mBars[0];
+
+       while( pCur )
+       {
+               pCur->mLenRatio = 0.0; // minimize the rest
+
+               pCur = pCur->mpNext;
+       }
+
+       pBar->mLenRatio     = 1.0; // 100%
+       pBar->mBounds.width = 0;
+
+       pBar->mpRow->mpExpandedBar = pBar;
+
+       mpLayout->RecalcLayout( FALSE );
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+}
+
+void cbDockPane::ContractBar( cbBarInfo* pBar )
+{
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+    // FIXME: What's the purpose of this???
+    // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt );
+
+       // restore ratios which were present before expansion
+
+       cbBarInfo* pCur = pBar->mpRow->mBars[0];
+
+       cbArrayFloat& ratios = pBar->mpRow->mSavedRatios;
+
+       size_t i = 0;
+
+       while( pCur )
+       {
+               if ( !pCur->IsFixed() )
+               {
+                       pCur->mLenRatio = ratios[i];
+                       ++i;
+               }
+
+               pCur = pCur->mpNext;
+       }
+
+       ratios.Clear();
+       ratios.Shrink();
+
+       pBar->mpRow->mpExpandedBar = NULL;
+
+       mpLayout->RecalcLayout( FALSE );
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+}
+
+void cbDockPane::InitLinksForRow( cbRowInfo* pRow )
+{
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               if ( i == 0 )
+
+                       bar.mpPrev = NULL;
+               else
+                       bar.mpPrev = pRow->mBars[i-1];
+
+               if ( i == pRow->mBars.Count() - 1 )
+
+                       bar.mpNext = NULL;
+               else
+                       bar.mpNext = pRow->mBars[i+1];
+       }
+}
+
+void cbDockPane::InitLinksForRows()
+{
+       for( size_t i = 0; i != mRows.Count(); ++i )
+       {
+               cbRowInfo& row = *mRows[i];
+
+               if ( i == 0 )
+
+                       row.mpPrev = NULL;
+               else
+                       row.mpPrev = mRows[i-1];
+
+               if ( i == mRows.Count() - 1 )
+
+                       row.mpNext = NULL;
+               else
+                       row.mpNext = mRows[i+1];
+       }
+}
+
+void cbDockPane::DoInsertBar( cbBarInfo* pBar, int rowNo )
+{
+       cbRowInfo* pRow = NULL;
+
+       if ( rowNo == -1 || rowNo >= (int)mRows.Count() )
+       {
+               pRow = new cbRowInfo();
+
+               if ( rowNo == -1 && mRows.Count() )
+               
+                       mRows.Insert( pRow, 0 ); 
+               else
+                       mRows.Add( pRow );
+
+               InitLinksForRows();
+       }
+       else
+       {
+               pRow = mRows[rowNo];
+
+               if ( mProps.mNonDestructFirctionOn == TRUE )
+               {
+                       // store original shape of the row (before the bar is inserted)
+
+                       mpStoredRow = pRow;
+                       
+                       GetRowShapeData( mpStoredRow, &mRowShapeData );
+               }
+       }
+
+       if ( pRow->mBars.Count() )
+
+               pRow->mpExpandedBar = NULL;
+
+       cbInsertBarEvent insEvt( pBar, pRow, this );
+
+       mpLayout->FirePluginEvent( insEvt );
+
+       mpLayout->GetUpdatesManager().OnRowWillChange( pRow, this );
+}
+
+void cbDockPane::InsertBar( cbBarInfo* pBarInfo, const wxRect& atRect )
+{
+       wxRect rect = atRect;
+       FrameToPane( &rect );
+
+       pBarInfo->mBounds.x      = rect.x;
+       pBarInfo->mBounds.width  = rect.width;
+       pBarInfo->mBounds.height = rect.height;
+
+       int row = GetRowAt( rect.y, rect.y + rect.height );
+
+       DoInsertBar( pBarInfo, row );
+}
+
+void cbDockPane::InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow )
+{
+       cbInsertBarEvent insEvt( pBar, pIntoRow, this );
+
+       mpLayout->FirePluginEvent( insEvt );
+
+       mpLayout->GetUpdatesManager().OnRowWillChange( pIntoRow, this );
+}
+
+void cbDockPane::InsertBar( cbBarInfo* pBarInfo )
+{
+       // set transient properties
+
+       pBarInfo->mpRow           = NULL;
+       pBarInfo->mHasLeftHandle  = FALSE;
+       pBarInfo->mHasRightHandle = FALSE;
+       pBarInfo->mLenRatio       = 0.0;
+
+       // set preferred bar dimensions, according to the state in which
+       // the bar is being inserted
+
+       pBarInfo->mBounds.width   = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].x;
+       pBarInfo->mBounds.height  = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].y;
+
+       DoInsertBar( pBarInfo, pBarInfo->mRowNo );
+}
+
+void cbDockPane::RemoveRow( cbRowInfo* pRow )
+{
+       // first, hide all bar-windows in the removed row
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+
+               if ( pRow->mBars[i]->mpBarWnd )
+
+                       pRow->mBars[i]->mpBarWnd->Show( FALSE );
+
+       mRows.Remove( pRow );
+
+       pRow->mUMgrData.SetDirty(TRUE);
+}
+
+void cbDockPane::InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow )
+{
+       if ( !pBeforeRow )
+
+               mRows.Add( pRow );
+       else
+               mRows.Insert( pRow, mRows.Index( pBeforeRow ) );
+
+       InitLinksForRows();
+
+       pRow->mUMgrData.SetDirty(TRUE);
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+
+                       pRow->mBars[i]->mUMgrData.SetDirty( TRUE );
+
+       SyncRowFlags( pRow );
+}
+
+void cbDockPane::SetPaneWidth(int width)
+{
+       if ( IsHorizontal() )
+       
+               mPaneWidth = width - mLeftMargin - mRightMargin;
+       else
+               mPaneWidth = width - mTopMargin - mBottomMargin;
+}
+
+
+void cbDockPane::SetBoundsInParent( const wxRect& rect )
+{
+
+       mBoundsInParent = rect;
+
+       // set pane dimensions in local coordinates
+
+       if ( IsHorizontal() )
+       {
+               mPaneWidth  = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
+               mPaneHeight = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
+       }
+       else
+       {
+               mPaneWidth  = mBoundsInParent.height - ( mTopMargin   + mBottomMargin );
+               mPaneHeight = mBoundsInParent.width  - ( mRightMargin + mLeftMargin   );
+       }
+
+       // convert bounding rectangles of all pane items into parent frame's coordinates
+
+       wxBarIterator i( mRows );
+
+       wxRect noMarginsRect = mBoundsInParent;
+
+       noMarginsRect.x      += mLeftMargin;
+       noMarginsRect.y      += mTopMargin;
+       noMarginsRect.width  -= ( mLeftMargin + mRightMargin  );
+       noMarginsRect.height -= ( mTopMargin  + mBottomMargin );
+
+       // hide the whole pane, if it's bounds became reverted (i.e. pane vanished)
+
+       if ( mBoundsInParent.width < 0 ||
+                mBoundsInParent.height < 0 )
+
+                hide_rect( mBoundsInParent );
+
+       if ( noMarginsRect.width < 0 ||
+                noMarginsRect.height < 0 )
+       
+               hide_rect( noMarginsRect   );
+
+       // calculate mBoundsInParent for each item in the pane
+
+       while( i.Next() )
+       {
+               cbBarInfo& bar = i.BarInfo();
+
+               cbRowInfo* pRowInfo = bar.mpRow;
+
+               // set up row info, if this is first bar in the row
+
+               if ( pRowInfo && bar.mpPrev == NULL )
+               {
+                       pRowInfo->mBoundsInParent.y      = pRowInfo->mRowY;
+                       pRowInfo->mBoundsInParent.x      = 0;
+                       pRowInfo->mBoundsInParent.width  = mPaneWidth;
+                       pRowInfo->mBoundsInParent.height = pRowInfo->mRowHeight;
+
+                       PaneToFrame( &pRowInfo->mBoundsInParent );
+
+                       clip_rect_against_rect( pRowInfo->mBoundsInParent, noMarginsRect );
+               }
+
+               wxRect bounds = bar.mBounds;
+
+               // exclude dimensions of handles, when calculating
+               // bar's bounds in parent (i.e. "visual bounds")
+
+               if ( bar.mHasLeftHandle )
+               {
+                       bounds.x     += mProps.mResizeHandleSize;
+                       bounds.width -= mProps.mResizeHandleSize;
+               }
+
+               if ( bar.mHasRightHandle )
+               
+                       bounds.width -= mProps.mResizeHandleSize;
+
+               PaneToFrame( &bounds );
+
+               clip_rect_against_rect( bounds, noMarginsRect );
+
+               bar.mBoundsInParent = bounds;
+       }
+}
+
+bool cbDockPane::BarPresent( cbBarInfo* pBar )
+{
+       wxBarIterator iter( mRows );
+
+       while( iter.Next() )
+       
+               if ( &iter.BarInfo() == pBar ) return TRUE;
+
+       return FALSE;
+}
+
+cbRowInfo* cbDockPane::GetRow( int row )
+{
+       if ( row >= (int)mRows.Count() ) return NULL;
+
+       return mRows[ row ];
+}
+
+int cbDockPane::GetRowIndex( cbRowInfo* pRow )
+{
+       for( size_t i = 0; i != mRows.Count(); ++i )
+       {
+               if ( mRows[i] == pRow ) 
+                       return i;
+       }
+
+       int avoidCompilerWarning = 0;
+       wxASSERT(avoidCompilerWarning); // DBG:: row should be present
+
+       return 0;
+}
+
+int cbDockPane::GetPaneHeight()
+{
+       // first, recalculate row heights and the Y-positions
+
+       cbLayoutRowsEvent evt( this );
+       mpLayout->FirePluginEvent( evt );
+
+       int height = 0;
+
+       if ( IsHorizontal() )
+       
+               height += mTopMargin  + mBottomMargin;
+       else
+               height += mLeftMargin + mRightMargin;
+
+       int count = mRows.Count();
+
+       if ( count )
+       
+               height += mRows[count-1]->mRowY + mRows[count-1]->mRowHeight;
+
+       return height;
+}
+
+int cbDockPane::GetAlignment()
+{
+       return mAlignment;
+}
+
+bool cbDockPane::MatchesMask( int paneMask )
+{
+       int thisMask = 0;
+
+       // FIXME:: use array instead of switch()
+
+       switch (mAlignment)
+       {
+               case FL_ALIGN_TOP    : thisMask = FL_ALIGN_TOP_PANE;   break;
+               case FL_ALIGN_BOTTOM : thisMask = FL_ALIGN_BOTTOM_PANE;break;
+               case FL_ALIGN_LEFT   : thisMask = FL_ALIGN_LEFT_PANE;  break;
+               case FL_ALIGN_RIGHT  : thisMask = FL_ALIGN_RIGHT_PANE; break;
+
+               default:
+                       int avoidCompilerWarning = 0;
+                       wxASSERT(avoidCompilerWarning); // DBG:: bogus alignment type
+       }
+
+       return ( thisMask & paneMask ) != 0;
+}
+
+void cbDockPane::RecalcLayout()
+{
+       // first, reposition rows and items vertically
+
+       cbLayoutRowsEvent evt( this );
+       mpLayout->FirePluginEvent( evt );
+
+       // then horizontally in each row 
+
+       for( size_t i = 0; i != mRows.Count(); ++i )
+
+               RecalcRowLayout( mRows[i] );
+}
+
+int cbDockPane::GetDockingState()
+{
+       if ( mAlignment == FL_ALIGN_TOP || 
+                mAlignment == FL_ALIGN_BOTTOM )
+       {
+               return wxCBAR_DOCKED_HORIZONTALLY;
+       }
+       else
+               return wxCBAR_DOCKED_VERTICALLY;
+}
+
+inline bool cbDockPane::HasPoint( const wxPoint& pos, int x, int y, 
+                                                                 int width, int height )
+{
+       return ( pos.x >= x && 
+                        pos.y >= y &&
+                    pos.x < x + width &&
+                        pos.y < y + height   );
+}
+
+int cbDockPane::HitTestPaneItems( const wxPoint& pos,
+                                                                 cbRowInfo**    ppRow,
+                                                                 cbBarInfo**    ppBar
+                                                           )
+{
+       (*ppRow) = NULL;
+       (*ppBar) = NULL;
+
+       for( size_t i = 0; i != mRows.Count(); ++i )
+       {
+               cbRowInfo& row = *mRows[i];
+
+               *ppRow = &row;
+
+               // hit-test handles of the row, if present
+
+               if ( row.mHasUpperHandle )
+               {
+                       if ( HasPoint( pos, 0, row.mRowY,
+                                              row.mRowWidth, mProps.mResizeHandleSize ) )
+
+                               return CB_UPPER_ROW_HANDLE_HITTED;
+               }
+               else
+               if ( row.mHasLowerHandle )
+               {
+                       if ( HasPoint( pos, 0, row.mRowY + row.mRowHeight - mProps.mResizeHandleSize, 
+                                          row.mRowWidth, mProps.mResizeHandleSize ) )
+
+                                       return CB_LOWER_ROW_HANDLE_HITTED;
+               }
+
+               // hit-test bar handles and bar content
+
+               for( size_t k = 0; k != row.mBars.Count(); ++k )
+               {
+                       cbBarInfo& bar    = *row.mBars[k];
+                       wxRect&    bounds = bar.mBounds;
+
+                       *ppBar = &bar;
+
+                       if ( bar.mHasLeftHandle )
+                       {
+                               if ( HasPoint( pos, bounds.x, bounds.y,
+                                                  mProps.mResizeHandleSize, bounds.height ) )
+
+                                       return CB_LEFT_BAR_HANDLE_HITTED;
+                       }
+                       else
+                       if ( bar.mHasRightHandle )
+                       {
+                               if ( HasPoint( pos, bounds.x + bounds.width - mProps.mResizeHandleSize, bounds.y,
+                                              mProps.mResizeHandleSize, bounds.height ) )
+                               
+                                       return CB_RIGHT_BAR_HANDLE_HITTED;
+                       }
+
+                       if ( HasPoint( pos, bounds.x, bounds.y, bounds.width, bounds.height ) )
+                       
+                               return CB_BAR_CONTENT_HITTED;
+
+               } // hit-test next bar
+
+       } // next row
+
+       return CB_NO_ITEMS_HITTED;
+}
+
+void cbDockPane::GetBarResizeRange( cbBarInfo* pBar, int* from, int *till,
+                                                                   bool forLeftHandle )
+{
+       cbBarInfo* pGivenBar = pBar;
+
+       int notFree = 0;
+
+       // calc unavailable space from the left
+
+       while( pBar->mpPrev )
+       {
+               pBar = pBar->mpPrev;
+
+               if ( !pBar->IsFixed() ) notFree += mProps.mMinCBarDim.x;
+                                                       else notFree += pBar->mBounds.width;
+       }
+
+       *from = notFree;
+
+       pBar = pGivenBar;
+
+       notFree = 0;
+
+       // calc unavailable space from the right
+
+       while( pBar->mpNext )
+       {
+               pBar = pBar->mpNext;
+
+               if ( pBar->mBounds.x >= mPaneWidth ) break;
+
+               // treat not-fixed bars as minimized
+
+               if ( !pBar->IsFixed() ) 
+                       
+                       notFree += mProps.mMinCBarDim.x;
+               else 
+               {
+                       if ( pBar->mBounds.x + pBar->mBounds.width >= mPaneWidth )
+                       {
+                               notFree += mPaneWidth - pBar->mBounds.x;
+                               break;
+                       }
+                       else
+                               notFree += pBar->mBounds.width;
+               }
+
+       } 
+
+       *till = mPaneWidth - notFree;
+
+       // do not let resizing totally deform the bar itself
+
+       if ( forLeftHandle )
+       
+               (*till) -= mProps.mMinCBarDim.x;
+       else
+       
+               (*from) += mProps.mMinCBarDim.x;
+}
+
+int cbDockPane::GetMinimalRowHeight( cbRowInfo* pRow )
+{
+       int height = mProps.mMinCBarDim.y;
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+               
+               if ( pRow->mBars[i]->IsFixed() )
+
+                       height = wxMax( height, pRow->mBars[i]->mBounds.height );
+
+       if ( pRow->mHasUpperHandle )
+
+               height += mProps.mResizeHandleSize;
+
+       if ( pRow->mHasLowerHandle )
+
+               height += mProps.mResizeHandleSize;
+       
+       return height;
+}
+
+void cbDockPane::SetRowHeight( cbRowInfo* pRow, int newHeight )
+{
+       if ( pRow->mHasUpperHandle )
+
+               newHeight -= mProps.mResizeHandleSize;
+
+       if ( pRow->mHasLowerHandle )
+
+               newHeight -= mProps.mResizeHandleSize;
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+
+               if ( !pRow->mBars[i]->IsFixed() )
+               
+                       pRow->mBars[i]->mBounds.height = newHeight;
+}
+
+void cbDockPane::GetRowResizeRange( cbRowInfo* pRow, int* from, int* till,
+                                                                   bool forUpperHandle )
+{
+       cbRowInfo* pGivenRow = pRow;
+
+       // calc unavailable space from above
+
+       int notFree = 0;
+
+       while( pRow->mpPrev )
+       {
+               pRow = pRow->mpPrev;
+
+               notFree += GetMinimalRowHeight( pRow );
+
+       };
+
+       *from = notFree;        
+
+       // allow accupy the client window space by resizing pane rows
+       if ( mAlignment == FL_ALIGN_BOTTOM )
+
+               *from -= mpLayout->GetClientHeight();
+       else
+       if ( mAlignment == FL_ALIGN_RIGHT )
+
+               *from -= mpLayout->GetClientWidth();
+
+       // calc unavailable space from below
+
+       pRow = pGivenRow;
+
+       notFree = 0;
+
+       while( pRow->mpNext )
+       {
+               pRow = pRow->mpNext;
+
+               notFree += GetMinimalRowHeight( pRow );
+
+       }
+
+       *till = mPaneHeight - notFree;  
+
+       // allow adjustinig pane space vs. client window space by resizing pane row heights
+
+       if ( mAlignment == FL_ALIGN_TOP )
+
+               *till += mpLayout->GetClientHeight();
+       else
+       if ( mAlignment == FL_ALIGN_LEFT )
+
+               *till += mpLayout->GetClientWidth();
+
+       // do not let the resizing of the row totally squeeze the row itself
+
+       cbRowInfo& row = *pGivenRow;
+
+       if ( forUpperHandle )
+       {       
+               *till = row.mRowY + row.mRowHeight - GetMinimalRowHeight( pGivenRow );
+
+               if ( row.mHasUpperHandle )
+
+                       *till -= mProps.mResizeHandleSize;
+       }
+       else
+       {
+               *from += GetMinimalRowHeight( pGivenRow );
+
+               if ( row.mHasLowerHandle )
+
+                       *from -= mProps.mResizeHandleSize;
+       }
+}
+
+void cbDockPane::ResizeRow( cbRowInfo* pRow, int ofs, 
+                                                       bool forUpperHandle )
+{
+       cbResizeRowEvent evt( pRow, ofs, forUpperHandle, this );
+
+       mpLayout->FirePluginEvent( evt );
+}
+
+void cbDockPane::ResizeBar( cbBarInfo* pBar, int ofs, 
+                                                   bool forLeftHandle )
+{
+       pBar->mpRow->mpExpandedBar = NULL;
+
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       wxRect&  bounds = pBar->mBounds;
+
+       if ( forLeftHandle )
+       {
+               // do not allow bar width become less then minimal
+               if ( bounds.x + ofs > bounds.x + bounds.width - mProps.mMinCBarDim.x )
+               {
+                       bounds.width = mProps.mMinCBarDim.x;
+                       bounds.x += ofs;
+               }
+               else
+               {
+                       bounds.x     += ofs;
+                       bounds.width -= ofs;
+               }
+       }
+       else
+       {
+               // move bar left if necessary           
+               if ( bounds.width + ofs < mProps.mMinCBarDim.x )
+               {
+                       bounds.x     = bounds.x + bounds.width + ofs - mProps.mMinCBarDim.x;
+                       bounds.width = mProps.mMinCBarDim.x;
+               }
+               else
+                       // resize right border only
+                       bounds.width += ofs;
+       }
+
+
+       cbRowInfo* pToRow = pBar->mpRow;
+
+       this->RemoveBar( pBar );
+
+       InsertBar( pBar, pToRow );
+
+       mpLayout->RecalcLayout(FALSE);
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+}
+
+
+/*** row/bar resizing related methods ***/
+
+void cbDockPane::DrawVertHandle( wxDC& dc, int x, int y, int height )
+{
+       int lower = y + height;
+
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( x,y, x, lower );
+
+       dc.SetPen( mpLayout->mGrayPen );
+       for( int i = 0; i != mProps.mResizeHandleSize-1; ++i )
+       {
+               ++x;
+               dc.DrawLine( x,y, x, lower );
+       }
+
+       dc.SetPen( mpLayout->mDarkPen );
+       ++x;
+       dc.DrawLine( x,y, x, lower );
+
+       dc.SetPen( mpLayout->mBlackPen );
+       ++x;
+       dc.DrawLine( x,y, x, lower );
+}
+
+void cbDockPane::DrawHorizHandle( wxDC& dc, int x, int y, int width  )
+{
+       int right = x + width;
+
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( x,y, right, y );
+
+       dc.SetPen( mpLayout->mGrayPen );
+
+       for( int i = 0; i != mProps.mResizeHandleSize-1; ++i )
+       {
+               ++y;
+               dc.DrawLine( x,y, right, y );
+       }
+
+       dc.SetPen( mpLayout->mDarkPen );
+       dc.DrawLine( x,y, right, ++y );
+
+       dc.SetPen( mpLayout->mBlackPen );
+       dc.DrawLine( x,y, right, ++y );
+}
+
+cbBarInfo* cbDockPane::GetBarInfoByWindow( wxWindow* pBarWnd )
+{
+       wxBarIterator i( mRows );
+
+       while( i.Next() )
+       
+               if ( i.BarInfo().mpBarWnd == pBarWnd )
+
+                       return &i.BarInfo();
+
+       return NULL;
+}
+
+void cbDockPane::GetRowShapeData( cbRowInfo* pRow, wxList* pLst )
+{
+       pLst->DeleteContents( TRUE );
+       pLst->Clear();
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               cbBarShapeData* pData = new cbBarShapeData();
+
+               pLst->Append( (wxObject*)pData );
+
+               pData->mBounds   = bar.mBounds;
+               pData->mLenRatio = bar.mLenRatio;
+       }
+}
+
+void cbDockPane::SetRowShapeData( cbRowInfo* pRow, wxList* pLst )
+{
+       if ( pLst->First() == NULL ) return;
+
+       wxNode* pData = pLst->First();
+
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               wxASSERT( pData ); // DBG::
+
+               cbBarInfo& bar = *pRow->mBars[i];;
+
+               cbBarShapeData& data = *((cbBarShapeData*)pData->Data());
+
+               bar.mBounds   = data.mBounds;
+               bar.mLenRatio = data.mLenRatio;
+
+               pData = pData->Next();
+       }
+}
+
+/***** Implementation for class cbUpdatesManagerBase *****/
+
+IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase, wxObject )
+
+/***** Implementation for class cbPluginBase *****/
+
+IMPLEMENT_ABSTRACT_CLASS( cbPluginBase, wxEvtHandler )
+
+cbPluginBase::~cbPluginBase()
+{
+       // nothing
+}
+
+bool cbPluginBase::ProcessEvent(wxEvent& event)
+{
+       if ( mPaneMask == wxALL_PANES ) 
+
+               return wxEvtHandler::ProcessEvent( event );
+
+       // extract mask info. from received event
+
+       cbPluginEvent& evt = *( (cbPluginEvent*)&event );
+
+       if ( evt.mpPane == 0 &&
+                mPaneMask  == wxALL_PANES )
+
+                return wxEvtHandler::ProcessEvent( event );
+
+       int mask = 0;
+
+       switch ( evt.mpPane->mAlignment )
+       {
+               case FL_ALIGN_TOP    : mask = FL_ALIGN_TOP_PANE;   break;
+               case FL_ALIGN_BOTTOM : mask = FL_ALIGN_BOTTOM_PANE;break;
+               case FL_ALIGN_LEFT   : mask = FL_ALIGN_LEFT_PANE;  break;
+               case FL_ALIGN_RIGHT  : mask = FL_ALIGN_RIGHT_PANE; break;
+       }
+
+       // if event's pane maks matches the plugin's mask
+
+       if ( mPaneMask & mask ) 
+
+               return wxEvtHandler::ProcessEvent( event );
+
+       // otherwise pass to the next handler if present
+
+       if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event ) )
+
+               return TRUE;
+       else
+               return FALSE;
+}
+
diff --git a/contrib/src/fl/dyntbar.cpp b/contrib/src/fl/dyntbar.cpp
new file mode 100644 (file)
index 0000000..fe381fa
--- /dev/null
@@ -0,0 +1,517 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     ??/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "dyntbar.h"
+#endif
+
+// 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"
+#endif
+
+#include "wx/utils.h"     // import wxMin,wxMax macros
+
+#include "wx/fl/dyntbar.h"
+#include "wx/fl/newbmpbtn.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxControl )
+
+BEGIN_EVENT_TABLE( wxDynamicToolBar, wxControl )
+
+       EVT_SIZE ( wxDynamicToolBar::OnSize  )
+       EVT_PAINT( wxDynamicToolBar::OnPaint )
+       //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground )
+
+END_EVENT_TABLE()
+
+/***** Implementation for class wxDynToolInfo *****/
+               
+IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem)
+
+/***** Implementation for class wxDynamicToolBar *****/
+
+wxDynamicToolBar::wxDynamicToolBar()
+       : mpLayoutMan( NULL ),
+         mSepartorSize( 8 ),
+         mVertGap ( 0 ),
+         mHorizGap( 0 )
+{
+}
+
+wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id, 
+                                                                  const wxPoint& pos, const wxSize& size,
+                                                                  const long style, const int orientation,
+                                                                  const int RowsOrColumns, const wxString& name )
+       : mpLayoutMan( NULL ),
+         mSepartorSize( 8 ),
+         mVertGap ( 0 ),
+         mHorizGap( 0 )
+{
+       Create(parent, id, pos, size, style, orientation, RowsOrColumns, name);
+
+       SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE) );
+}
+
+bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id, 
+                                                     const wxPoint& pos, 
+                                                         const wxSize& size,
+                                                         const long style, 
+                                                         const int orientation, const int RowsOrColumns, 
+                                                         const wxString& name)
+{
+       // cut&pasted from wxtbatsmpl.h
+
+       if ( ! wxWindow::Create(parent, id, pos, size, style, name) )
+               return FALSE;
+
+       SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ));
+
+       return TRUE;
+}
+
+bool wxDynamicToolBar::Realize(void)
+{
+       // FOR NOW:: nothing
+       return TRUE;
+}
+
+wxDynamicToolBar::~wxDynamicToolBar(void)
+{
+       if ( mpLayoutMan )
+        delete mpLayoutMan;
+
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+    {
+               delete mTools[i];
+    }
+}
+
+void wxDynamicToolBar::AddTool( int toolIndex, 
+                                                               wxWindow* pToolWindow, 
+                                                               const wxSize& size
+                                                     )
+{
+       wxDynToolInfo* pInfo = new wxDynToolInfo();
+
+       pInfo->mpToolWnd    = pToolWindow;
+       pInfo->mIndex       = toolIndex;
+       pInfo->mIsSeparator     = FALSE;
+
+       int x,y;
+       pToolWindow->GetSize( &x, &y );
+       pInfo->mRealSize.x = x;
+       pInfo->mRealSize.y = y;
+       pInfo->mRect.width = x;
+       pInfo->mRect.height = y;
+
+       mTools.Add( pInfo );
+}
+
+void wxDynamicToolBar::AddTool( int toolIndex, 
+                                                               const wxString& imageFileName,
+                                                               int imageFileType, 
+                                                               const wxString& labelText, bool alignTextRight,
+                                                               bool isFlat )
+{
+       wxNewBitmapButton* pBtn =
+
+         new wxNewBitmapButton( imageFileName, imageFileType,
+                                                        labelText, 
+                                                        ( alignTextRight ) 
+                                                        ? NB_ALIGN_TEXT_RIGHT 
+                                                        : NB_ALIGN_TEXT_BOTTOM,
+                                                        isFlat
+                                                  );
+
+       pBtn->Create( this, toolIndex );
+
+       pBtn->Reshape();
+       
+       AddTool( toolIndex, pBtn );
+}
+void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp,
+                                                               const wxString& labelText, bool alignTextRight,
+                                                               bool isFlat )
+{
+       wxNewBitmapButton* pBtn =
+
+         new wxNewBitmapButton( labelBmp,
+                                                        labelText, 
+                                                        ( alignTextRight ) 
+                                                        ? NB_ALIGN_TEXT_RIGHT 
+                                                        : NB_ALIGN_TEXT_BOTTOM,
+                                                        isFlat
+                                                  );
+
+       pBtn->Create( this, toolIndex );
+
+       pBtn->Reshape();
+       
+       AddTool( toolIndex, pBtn );
+}
+
+
+  wxToolBarToolBase* 
+         wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap, 
+                                                               const wxBitmap& pushedBitmap,
+                                                               const bool toggle, const long xPos, 
+                                                               const long yPos, wxObject *clientData,
+                                                               const wxString& helpString1, const wxString& helpString2)
+{
+       wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap );
+
+       pBmpBtn->Create( this, toolIndex );
+
+       pBmpBtn->Reshape();
+
+       AddTool( toolIndex, pBmpBtn );
+
+       return NULL;
+}
+
+
+wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex )
+{
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+    {
+               if ( mTools[i]->mIndex == toolIndex )
+            return mTools[i];
+    }
+
+       return NULL;
+}
+
+void wxDynamicToolBar::RemveTool( int toolIndex )
+{
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+    {
+               if ( mTools[i]->mIndex == toolIndex ) 
+               {
+                   if ( mTools[i]->mpToolWnd )
+                   {
+                           mTools[i]->mpToolWnd->Destroy();
+                   }
+            delete mTools[i]; // HVL To be tested!!!
+#if wxCHECK_VERSION(2,3,2)
+                       mTools.RemoveAt(i);
+#else
+                       mTools.Remove(i);
+#endif
+                       Layout();
+
+                       return;
+               }
+    }
+       // TODO:: if not found, should it be an assertion?
+}
+
+void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd )
+{
+       wxDynToolInfo* pInfo = new wxDynToolInfo();
+
+       pInfo->mpToolWnd    = pSepartorWnd;
+       pInfo->mIndex       = -1;
+       pInfo->mIsSeparator     = TRUE;
+
+       if ( pSepartorWnd )
+       {
+               pSepartorWnd->Create( this, -1 );
+
+               int x,y;
+               pSepartorWnd->GetSize( &x, &y );
+               pInfo->mRealSize.x = x;
+               pInfo->mRealSize.y = y;
+
+               pInfo->mRect.width = x;
+               pInfo->mRect.height = y;
+       }
+       else
+       {
+               pInfo->mRealSize.x = mSepartorSize;
+               pInfo->mRealSize.y = 0;
+
+               pInfo->mRect.width  = mSepartorSize;
+               pInfo->mRect.height = 0;
+       }
+
+       mTools.Add( pInfo );
+}
+
+void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event )
+{
+       // FOR NOW:: nothing
+}
+
+void wxDynamicToolBar::OnSize( wxSizeEvent& event )
+{
+       //SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) );
+
+       Layout();
+}
+
+void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc )
+{
+       // check the orientation of separator
+       if ( info.mRect.width < info.mRect.height )
+       {
+               int midX = info.mRect.x + info.mRect.width/2 - 1;
+
+               dc.SetPen( *wxGREY_PEN );
+               dc.DrawLine( midX, info.mRect.y,
+                                midX, info.mRect.y + info.mRect.height+1 );
+
+               dc.SetPen( *wxWHITE_PEN );
+               dc.DrawLine( midX+1, info.mRect.y,
+                                midX+1, info.mRect.y + info.mRect.height+1 );
+       }
+       else
+       {
+               int midY = info.mRect.y + info.mRect.height/2 - 1;
+
+               dc.SetPen( *wxGREY_PEN );
+               dc.DrawLine( info.mRect.x, midY,
+                                info.mRect.x + info.mRect.width+1, midY );
+
+               dc.SetPen( *wxWHITE_PEN );
+               dc.DrawLine( info.mRect.x, midY + 1,
+                                info.mRect.x + info.mRect.width+1, midY + 1 );
+       }
+}
+
+void wxDynamicToolBar::OnPaint( wxPaintEvent& event )
+{
+       // draw separators if any
+
+       wxPaintDC dc(this);
+
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+       
+               if ( mTools[i]->mIsSeparator ) 
+               {
+                       // check if separator doesn't have it's own window
+                       // if so, then draw it using built-in drawing method
+
+                       if ( !mTools[i]->mpToolWnd )
+
+                               DrawSeparator( *mTools[i], dc );
+               }
+}
+
+// FOR NOW:: quick fix
+#include "wx/choice.h"
+
+void wxDynamicToolBar::SizeToolWindows()
+{
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+       {
+               wxDynToolInfo& info = *mTools[i];
+
+               if ( !info.mIsSeparator ) 
+               {
+
+                       // center real rectangle within the rectangle 
+                       // provided by the layout manager
+
+                       int x = info.mRect.x;
+                       int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2;
+
+                       // FOR NOW FOR NOW:: quick & dirty fix
+                       if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) )
+                       {
+                               info.mpToolWnd->SetSize( x,y, 
+                                                                               info.mRealSize.x - 3, 
+                                                                               info.mRealSize.y);
+                       }
+                       else
+                               info.mpToolWnd->SetSize( x,y, 
+                                                                               info.mRealSize.x, 
+                                                                               info.mRealSize.y );
+               }
+
+               // TBD:: size separator window if present
+       }
+}
+
+bool wxDynamicToolBar::Layout()
+{
+       if ( !mpLayoutMan )
+        mpLayoutMan = CreateDefaulLayout();
+
+       int x,y;
+       GetSize( &x, &y );
+       wxSize wndDim(x,y);
+       wxSize result;
+
+       wxLayoutItemArrayT items;
+
+       // safe conversion
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+        items.Add( mTools[i] );
+
+       mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );;
+
+       SizeToolWindows();
+    return TRUE;
+}
+
+void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim )
+{
+       if ( !mpLayoutMan )
+        mpLayoutMan = CreateDefaulLayout();
+
+       wxLayoutItemArrayT items;
+
+       // safe conversion
+    size_t i;
+       for( i = 0; i != mTools.Count(); ++i )
+        items.Add( mTools[i] );
+
+       mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );;
+}
+
+void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout )
+{
+       if ( mpLayoutMan )
+        delete mpLayoutMan;
+
+       mpLayoutMan = pLayout;
+
+       Layout();
+}
+
+void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable )
+{
+       wxDynToolInfo* pInfo = GetToolInfo( toolIndex );
+
+       if ( !pInfo )
+        return;
+
+       if ( pInfo->mIsSeparator || !pInfo->mpToolWnd )
+        return;
+
+       pInfo->mpToolWnd->Enable( enable );
+}
+
+/***** Implementation for class BagLayout *****/
+
+void BagLayout::Layout(  const wxSize&       parentDim, 
+                                                wxSize&                 resultingDim,
+                                                wxLayoutItemArrayT& items,
+                                                int                     horizGap,
+                                int                     vertGap  
+                                         )
+{
+       int maxWidth = 0;
+       int curY  = 0;
+       int nRows = 0;
+
+       size_t i = 0;
+
+       while( i < items.Count() )
+       {
+               int curX   = 0;
+               int height = 0;
+               // int nItems = 0;
+
+               // int firstItem  = i;
+               int itemsInRow = 0;
+
+               if ( nRows > 0 )
+            curY += vertGap;
+
+               // step #1 - arrange horizontal positions of items in the row
+
+               do
+               {
+                       if ( itemsInRow > 0 )
+                curX += horizGap;
+
+                       wxRect& r = items[i]->mRect;
+
+                       if ( curX + r.width > parentDim.x )
+            {
+                               if ( itemsInRow > 0 ) 
+                    break;
+            }
+                       r.x = curX;
+                       r.y = curY;
+
+                       curX += r.width;
+
+                       height = wxMax( height, r.height );
+
+                       ++itemsInRow;
+                       ++i;
+
+               } while( i < items.Count() );
+
+               curY += height;
+
+               maxWidth = wxMax( maxWidth, curX );
+       }
+
+       resultingDim.x = maxWidth;
+       resultingDim.y = curY;
+}
+
+//////// stuff from 2.1.15 ///////////
+
+wxToolBarToolBase* wxDynamicToolBar::FindToolForPosition( wxCoord x, wxCoord y ) const
+{
+       return NULL;
+}
+
+bool wxDynamicToolBar::DoInsertTool( size_t pos, wxToolBarToolBase* tool )
+{
+       return TRUE;
+}
+
+bool wxDynamicToolBar::DoDeleteTool( size_t pos, wxToolBarToolBase* tool )
+{
+       return TRUE;
+}
+
+void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase* tool, bool enable )
+{
+}
+
+void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase* tool, bool toggle )
+{
+}
+
+void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase* tool, bool toggle )
+{
+}
+
+wxToolBarToolBase* wxDynamicToolBar::CreateTool( int id, const wxBitmap& bitmap1, const wxBitmap& bitmap2, bool toggle, wxObject* clientData, const wxString& shortHelpString, const wxString& longHelpString )
+{
+       return NULL;
+}
+
+wxToolBarToolBase* wxDynamicToolBar::CreateTool( wxControl* control )
+{
+       return NULL;
+}
+
diff --git a/contrib/src/fl/dyntbarhnd.cpp b/contrib/src/fl/dyntbarhnd.cpp
new file mode 100644 (file)
index 0000000..e375851
--- /dev/null
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     23/01/99
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "dyntbarhnd.h"
+#endif
+
+// 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"
+#endif
+
+#include "wx/fl/dyntbarhnd.h"
+
+/***** Implementation for class cbDynToolBarDimHandler *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbDynToolBarDimHandler, cbBarDimHandlerBase )
+
+void cbDynToolBarDimHandler::OnChangeBarState(cbBarInfo* pBar, int newState )
+{
+       // nothing
+}
+
+void cbDynToolBarDimHandler::OnResizeBar( cbBarInfo* pBar, 
+                                                                                 const wxSize& given, 
+                                                                                 wxSize& preferred )
+{
+       wxASSERT( pBar->mpBarWnd ); // DBG:: should be present
+
+       wxDynamicToolBar* pTBar = (wxDynamicToolBar*)pBar->mpBarWnd;
+
+       pTBar->GetPreferredDim( given, preferred );
+}
+
diff --git a/contrib/src/fl/files.lst b/contrib/src/fl/files.lst
new file mode 100644 (file)
index 0000000..6627778
--- /dev/null
@@ -0,0 +1,20 @@
+
+FL_OBJECTS  = \
+   antiflickpl.$(OBJ_EXT) \
+   gcupdatesmgr.$(OBJ_EXT) \
+   rowlayoutpl.$(OBJ_EXT) \
+   bardragpl.$(OBJ_EXT) \
+   dyntbar.$(OBJ_EXT) \
+   hintanimpl.$(OBJ_EXT) \
+   toolwnd.$(OBJ_EXT) \
+   barhintspl.$(OBJ_EXT) \
+   dyntbarhnd.$(OBJ_EXT) \
+   newbmpbtn.$(OBJ_EXT) \
+   updatesmgr.$(OBJ_EXT) \
+   cbcustom.$(OBJ_EXT) \
+   frmview.$(OBJ_EXT) \
+   panedrawpl.$(OBJ_EXT) \
+   controlbar.$(OBJ_EXT) \
+   garbagec.$(OBJ_EXT) \
+   rowdragpl.$(OBJ_EXT)
+
diff --git a/contrib/src/fl/flVC.dsp b/contrib/src/fl/flVC.dsp
new file mode 100644 (file)
index 0000000..a51c68f
--- /dev/null
@@ -0,0 +1,230 @@
+# Microsoft Developer Studio Project File - Name="flVC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=flVC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "flVC.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "flVC.mak" CFG="flVC - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "flVC - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "flVC - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "flVC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__HACK_MY_MSDEV40__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\..\lib\fl.lib"
+
+!ELSEIF  "$(CFG)" == "flVC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../../include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x809
+# ADD RSC /l 0x809
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"..\..\..\lib\fld.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "flVC - Win32 Release"
+# Name "flVC - Win32 Debug"
+# Begin Group "Headers"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\antiflickpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\bardragpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\barhintspl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\cbcustom.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\controlbar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\dynbarhnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\dyntbar.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\dyntbarhnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\frmview.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\garbagec.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\gcupdatesmgr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\hintanimpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\newbmpbtn.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\panedrawpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\rowdragpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\rowlayoutpl.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\toolwnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\wx\fl\updatesmgr.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\antiflickpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\bardragpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\barhintspl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\cbcustom.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\controlbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyntbar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\dyntbarhnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\frmview.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\garbagec.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\gcupdatesmgr.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\hintanimpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\newbmpbtn.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\panedrawpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rowdragpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rowlayoutpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\toolwnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\updatesmgr.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/contrib/src/fl/flVC.dsw b/contrib/src/fl/flVC.dsw
new file mode 100644 (file)
index 0000000..4e76e8f
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "flVC"=.\flVC.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/contrib/src/fl/frmview.cpp b/contrib/src/fl/frmview.cpp
new file mode 100644 (file)
index 0000000..8b6763d
--- /dev/null
@@ -0,0 +1,451 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     02/01/99
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+    #pragma implementation "frmview.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/frmview.h"
+#include "wx/utils.h"
+
+/***** Implementation for class wxFrameView *****/
+
+BEGIN_EVENT_TABLE( wxFrameView, wxEvtHandler )
+
+       EVT_IDLE( wxFrameView::OnIdle )
+
+END_EVENT_TABLE()
+
+void wxFrameView::OnIdle( wxIdleEvent& event)
+{
+       event.Skip();
+
+       if ( mDoToolUpdates )
+       {
+               int o = 0;  //glt
+               ++o;
+
+               // TBD::
+       }
+}
+
+/*** public methods ***/
+
+wxFrameView::wxFrameView()
+
+       : mpLayout( NULL ),
+         mpFrameMgr( NULL )
+{}
+
+wxFrameView::~wxFrameView()
+{
+       if ( mpLayout ) delete mpLayout;
+}
+
+wxFrame* wxFrameView::GetParentFrame()
+{
+       return mpFrameMgr->GetParentFrame();
+}
+
+wxWindow* wxFrameView::GetClientWindow()
+{
+       return mpFrameMgr->GetClientWindow();
+}
+
+void wxFrameView::Activate()
+{
+       mpFrameMgr->ActivateView( this );
+}
+
+void wxFrameView::Deactivate()
+{
+       mpFrameMgr->DeactivateCurrentView();
+}
+
+void wxFrameView::CreateLayout()
+{
+       mpLayout = new wxFrameLayout( GetParentFrame(), mpFrameMgr->GetClientWindow(), FALSE );
+}
+
+wxFrameLayout* wxFrameView::GetLayout()
+{
+       return mpLayout;
+}
+
+void wxFrameView::SetToolUpdates( bool doToolUpdates )
+{
+       mDoToolUpdates = doToolUpdates;
+}
+
+void wxFrameView::SetLayout( wxFrameLayout* pLayout )
+{
+       if ( mpLayout ) delete mpLayout;
+
+       mpLayout = pLayout;
+}
+
+wxFrameManager& wxFrameView::GetFrameManager()
+{
+       return *mpFrameMgr;
+}
+
+void wxFrameView::RegisterMenu( const wxString& topMenuName )
+{
+       mTopMenus.Add( topMenuName );
+}
+
+#if 0
+
+/***** Implementation for class wxFrameViewSerializer *****/
+
+// NOTE:: currently "stipple" property of the brush is not serialized
+
+class wxFrameViewSerializer : public wxEvtHandlerSerializer
+{
+       DECLARE_SERIALIZER_CLASS( wxFrameViewSerializer );
+
+       static void Serialize( wxObject* pObj, wxObjectStorage& store );
+};
+
+IMPLEMENT_SERIALIZER_CLASS( wxFrameView, 
+                                                       wxFrameViewSerializer,
+                                                       wxFrameViewSerializer::Serialize,
+                                                       NO_CLASS_INIT )
+
+void wxFrameViewSerializer::Serialize( wxObject* pObj, wxObjectStorage& store )
+{
+       // wxFrameViewSerializer is a kind of wxEvtHandler - peform serialization of
+       // the base class first
+
+       info.SerializeInherited( pObj, store );
+
+       wxFrameView* pView = (wxFrameView*)pObj;
+
+       store.XchgObjPtr( (wxObject**) &pView->mpFrameMgr );
+       store.XchgObjPtr( (wxObject**) &pView->mpLayout );
+       store.XchgBool  ( pView->mDoToolUpdates );
+
+       // serialize members in derived classes
+
+       pView->OnSerialize( store );
+}
+
+#endif
+
+/***** Implementation for class wxFrameManager *****/
+
+void wxFrameManager::DoSerialize( wxObjectStorage& store )
+{
+#if 0
+       store.AddInitialRef( mpFrameWnd );
+       store.AddInitialRef( this );
+       if ( mpClientWnd ) store.AddInitialRef( mpClientWnd );
+
+       store.XchgObj( (wxObject*) &mViews );
+       store.XchgInt( mActiveViewNo );
+
+       store.Finalize(); // finish serialization
+#endif 
+}
+
+void wxFrameManager::DestroyViews()
+{
+       DeactivateCurrentView();
+
+       wxNode* pNode = mViews.First();
+
+       while( pNode )
+       {
+               delete (wxFrameView*)pNode->Data();
+
+               pNode = pNode->Next();
+       }
+
+       if ( mActiveViewNo != -1 && GetParentFrame() )
+
+               GetParentFrame()->SetNextHandler( NULL );
+}
+
+int wxFrameManager::GetViewNo( wxFrameView* pView )
+{
+       wxNode* pNode = mViews.First();
+       int n = 0;
+
+       while( pNode )
+       {
+               if ( (wxFrameView*)pNode->Data() == pView )
+
+                       return n;
+
+               ++n;
+               pNode = pNode->Next();
+       }
+
+       return -1;
+}
+
+void wxFrameManager::EnableMenusForView( wxFrameView* pView, bool enable )
+{
+       wxMenuBar* pMenuBar = GetParentFrame()->GetMenuBar();
+       int count = pMenuBar->GetMenuCount();
+
+       if ( !pMenuBar ) return;
+
+       wxStringListNode* pNode = pView->mTopMenus.GetFirst();
+
+       while( pNode )
+       {
+               for( int i = 0; i != count; ++i )
+               {
+                       if ( pMenuBar->GetMenu(i)->GetTitle() == pNode->GetData() )
+
+                               pMenuBar->EnableTop( i, enable );
+               }
+
+               pNode = pNode->GetNext();
+       }
+}
+
+void wxFrameManager::SyncAllMenus()
+{
+       wxNode* pNode = mViews.First();
+       int i = 0;
+
+       while( pNode )
+       {
+               if ( i != mActiveViewNo )
+
+                       EnableMenusForView( (wxFrameView*)pNode->GetData(), FALSE );
+
+               pNode = pNode->Next();
+       }
+
+       EnableMenusForView( GetView( mActiveViewNo ), TRUE );
+}
+
+/*** public methods ***/
+
+wxFrameManager::wxFrameManager()
+
+       : mpFrameWnd( NULL  ),
+         mActiveViewNo( -1 ),
+         mpClientWnd( NULL )
+{
+}
+
+wxFrameManager::~wxFrameManager()
+{
+       SaveViewsNow();
+       DestroyViews();
+}
+
+void wxFrameManager::Init( wxWindow* pMainFrame, const wxString& settingsFile )
+{
+       mSettingsFile = settingsFile;
+       mpFrameWnd    = pMainFrame;
+
+       wxNode* pNode = mViews.First();
+
+       while( pNode )
+       {
+               wxFrameView* pView = (wxFrameView*)pNode->Data();
+
+               pView->OnInit();
+               pView->OnInitMenus();
+
+               pNode = pNode->Next();
+       }
+
+       if ( !ReloadViews() )
+       {
+               // if loading of settings file failed (e.g. was not found), 
+               // do recreation of items in each view
+
+               pNode = mViews.First();
+
+               while( pNode )
+               {
+                       wxFrameView* pView = (wxFrameView*)pNode->Data();
+
+                       pView->OnRecreate();
+
+                       pNode = pNode->Next();
+               }
+       }
+
+       if ( mActiveViewNo >= mViews.Number() )
+       
+               mActiveViewNo = -1;
+
+       ActivateView( GetView( ( mActiveViewNo == -1 ) ? 0 : mActiveViewNo ) );
+
+       SyncAllMenus();
+}
+
+void wxFrameManager::AddView( wxFrameView* pFrmView )
+{
+       mViews.Append( pFrmView );
+
+       pFrmView->mpFrameMgr = this; // back ref.
+}
+
+void wxFrameManager::RemoveView( wxFrameView* pFrmView )
+{
+       // TBD::
+       int avoidCompilerWarning = 0;
+       wxASSERT(avoidCompilerWarning);
+}
+
+int wxFrameManager::GetActiveViewNo()
+{
+       return mActiveViewNo;
+}
+
+wxFrameView* wxFrameManager::GetActiveView()
+{
+       wxNode* pNode = mViews.Nth( mActiveViewNo );
+
+       if ( pNode ) return (wxFrameView*)pNode->Data();
+                       else return NULL;
+}
+
+wxNode* wxFrameManager::GetActiveViewNode()
+{
+       return mViews.Nth( mActiveViewNo );
+}
+
+wxFrame* wxFrameManager::GetParentFrame()
+{
+       return ((wxFrame*)mpFrameWnd);
+}
+
+wxWindow* wxFrameManager::GetParentWindow()
+{
+       return mpFrameWnd;
+}
+
+wxFrameView* wxFrameManager::GetView( int viewNo )
+{
+       wxNode* pNode = mViews.Nth( viewNo );
+
+       if ( pNode ) return (wxFrameView*)pNode->Data();
+                       else return NULL;
+}
+
+void wxFrameManager::ActivateView( int viewNo )
+{
+       ActivateView( GetView( viewNo ) );
+}
+
+void wxFrameManager::ActivateView( wxFrameView* pFrmView )
+{
+       DeactivateCurrentView();
+
+       mActiveViewNo = GetViewNo( pFrmView );
+
+       if ( pFrmView->mpLayout )
+
+               pFrmView->mpLayout->Activate();
+
+       // FIXME:: we would have used PushEventHandler(),
+       //         but wxFrame bypasses attached handlers when
+       //         handling wxCommand events!
+
+       GetParentFrame()->PushEventHandler( pFrmView );
+
+       EnableMenusForView( pFrmView, TRUE );
+}
+
+void wxFrameManager::SetClinetWindow( wxWindow* pFrameClient )
+{
+       if ( mpClientWnd ) mpClientWnd->Destroy();
+
+       mpClientWnd = pFrameClient;
+}
+
+wxWindow* wxFrameManager::GetClientWindow()
+{
+       if ( !mpClientWnd )
+
+               mpClientWnd = new wxWindow( GetParentFrame(), -1 );
+
+       return mpClientWnd;
+}
+
+void wxFrameManager::DeactivateCurrentView()
+{
+       if ( mActiveViewNo == -1 ) return;
+
+       wxFrameView* pView = GetActiveView();
+
+       // FOR NOW::
+       wxASSERT( GetParentFrame()->GetEventHandler() == pView );
+
+       GetParentFrame()->PopEventHandler();
+
+       if ( pView->mpLayout )
+
+               pView->mpLayout->Deactivate();
+
+       EnableMenusForView( pView, FALSE );
+}
+
+void wxFrameManager::SaveViewsNow()
+{
+#if 0
+       if ( mSettingsFile == "" ) return;
+
+    wxIOStreamWrapper stm;
+    stm.CreateForOutput( mSettingsFile );
+
+    mStore.SetDataStream( stm );
+    DoSerialize( mStore );
+#endif
+}
+
+bool wxFrameManager::ReloadViews()
+{
+       return FALSE;
+
+       // TBD: ????
+#if 0
+       if ( mSettingsFile == "" || !wxFileExists( mSettingsFile ) ) 
+               
+               return FALSE;
+
+       DestroyViews();
+
+    wxIOStreamWrapper stm;
+    stm.CreateForInput( mSettingsFile );
+
+    mStore.SetDataStream( stm );
+    DoSerialize( mStore );
+
+       return TRUE;
+#endif
+}
+
+bool wxFrameManager::ViewsAreLoaded()
+{
+       return ( mViews.Number() != 0 );
+}
+
diff --git a/contrib/src/fl/garbagec.cpp b/contrib/src/fl/garbagec.cpp
new file mode 100644 (file)
index 0000000..049f944
--- /dev/null
@@ -0,0 +1,224 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     18/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+
+#ifdef __GNUG__
+    #pragma implementation "garbagec.h"
+#endif
+
+// 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"
+#endif
+
+#include "wx/fl/garbagec.h"
+
+/***** Implementation for class GarbageCollector *****/
+
+inline static GCItem& node_to_item( wxNode* pNode )
+{
+       return *( (GCItem*)(pNode->Data()) );
+}
+
+GarbageCollector::~GarbageCollector()
+{
+       Reset();
+}
+
+/*** GC alg. helpers ***/
+
+void GarbageCollector::DestroyItemList( wxList& lst )
+{
+       wxNode* pNode = lst.First();
+
+       while( pNode )
+       {
+               delete &node_to_item( pNode );
+
+               pNode = pNode->Next();
+       }
+
+       lst.Clear();
+}
+
+wxNode* GarbageCollector::FindItemNode( void* pForObj )
+{
+       wxNode* pNode = mAllNodes.First();
+
+       while( pNode )
+       {
+               if ( node_to_item( pNode ).mpObj == pForObj )
+
+                       return pNode;
+
+               pNode = pNode->Next();
+       }
+
+       int avoidCompilerWarning = 0;
+       wxASSERT(avoidCompilerWarning); // DBG:: item should be present
+
+       return 0;
+}
+
+wxNode* GarbageCollector::FindReferenceFreeItemNode()
+{
+       wxNode* pNode = mAllNodes.First();
+
+       while( pNode )
+       {
+               if ( node_to_item( pNode ).mRefs.Number() == 0 ) 
+
+                       return pNode;
+
+               pNode = pNode->Next();
+       }
+
+       return 0;
+}
+
+void GarbageCollector::RemoveReferencesToNode( wxNode* pItemNode )
+{
+       wxNode* pNode = mAllNodes.First();
+
+       while( pNode )
+       {
+               wxList& refLst   = node_to_item( pNode ).mRefs;
+               wxNode* pRefNode = refLst.First();
+
+               while( pRefNode )
+               {
+                       if ( pRefNode->Data() == (wxObject*)pItemNode )
+                       {
+                               wxNode* pNext = pRefNode->Next();
+
+                               refLst.DeleteNode( pRefNode );
+
+                               pRefNode = pNext;
+
+                               continue;
+                       }
+                       else pRefNode = pRefNode->Next();
+               }
+
+               pNode = pNode->Next();
+       }
+}
+
+void GarbageCollector::ResolveReferences()
+{
+       wxNode* pNode = mAllNodes.First();
+
+       while( pNode )
+       {
+               GCItem& item = node_to_item( pNode );
+
+               wxNode* pRefNode = item.mRefs.First();
+
+               while( pRefNode )
+               {
+                       pRefNode->SetData( (wxObject*) FindItemNode( (void*)pRefNode->Data() ) );
+
+                       pRefNode = pRefNode->Next();
+               }
+
+               pNode = pNode->Next();
+       }
+}
+
+void GarbageCollector::AddObject( void* pObj, int refCnt )
+{
+       // FOR NOW:: initial ref-count is not used
+
+       GCItem* pItem = new GCItem();
+
+       pItem->mpObj  = pObj;
+
+       mAllNodes.Append( (wxObject*) pItem );
+}
+
+void GarbageCollector::AddDependency( void* pObj, void* pDependsOnObj )
+{
+       node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDependsOnObj );
+}
+
+/*** GC alg. implementation ***/
+
+void GarbageCollector::ArrangeCollection()
+{
+       ResolveReferences();
+
+       do
+       {
+               // find node, which does not depend on anything
+
+               wxNode* pItemNode = FindReferenceFreeItemNode();
+
+               if ( pItemNode )
+               {
+                       // append it to the list, where items are contained
+                       // in the increasing order of dependencies
+
+                       mRegularLst.Append( pItemNode->Data() );
+
+                       mAllNodes.DeleteNode( pItemNode );
+
+                       // remove references to this current "least-dependent" node
+                       // from reference lists of all the other nodes
+
+                       RemoveReferencesToNode( pItemNode );
+               }
+               else
+               {
+                       // otherwise, what is left - all nodes, which
+                       // are involved into cycled chains (rings)
+
+                       wxNode* pNode = mAllNodes.First();
+
+                       while( pNode )
+                       {
+                               mCycledLst.Append( pNode->Data() );
+
+                               pNode = pNode->Next();
+                       }
+
+                       break;
+               }
+
+               // continue search for "least-dependent" nodes
+
+       } while(1);
+}
+
+wxList& GarbageCollector::GetRegularObjects()
+{
+       return mRegularLst;
+}
+
+wxList& GarbageCollector::GetCycledObjects()
+{
+       return mCycledLst;
+}
+
+void GarbageCollector::Reset()
+{
+       DestroyItemList( mAllNodes   );
+
+       mRegularLst.Clear();
+       mCycledLst.Clear();
+}
+
diff --git a/contrib/src/fl/gcupdatesmgr.cpp b/contrib/src/fl/gcupdatesmgr.cpp
new file mode 100644 (file)
index 0000000..3da75df
--- /dev/null
@@ -0,0 +1,409 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     19/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas 
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "gcupdatesmgr.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/gcupdatesmgr.h"
+
+// helper function
+
+static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
+{
+       if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
+                ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
+
+               if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
+                        ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
+                        
+                       return 1;
+
+       return 0;
+}
+
+// helper structure
+
+struct cbRectInfo
+{
+       cbBarInfo*  mpBar;
+       cbDockPane* mpPane;
+       wxRect*     mpCurBounds;
+       wxRect*     mpPrevBounds;
+};
+
+static inline cbRectInfo& node_to_rect_info( wxNode* pNode )
+{
+       return *( (cbRectInfo*) (pNode->Data()) );
+}
+
+/***** Implementation for class cbSimpleUpdatesMgr *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr, cbSimpleUpdatesMgr )
+
+cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout* pPanel )
+       : cbSimpleUpdatesMgr( pPanel )
+{}
+
+void cbGCUpdatesMgr::AddItem( wxList&     itemList,
+                                                     cbBarInfo*  pBar, 
+                                                         cbDockPane* pPane,
+                                                         wxRect&     curBounds,
+                                                         wxRect&     prevBounds )
+{
+       cbRectInfo* pInfo = new cbRectInfo();
+
+       pInfo->mpBar     = pBar;
+       pInfo->mpPane       = pPane;
+       pInfo->mpCurBounds  = &curBounds;
+       pInfo->mpPrevBounds = &prevBounds;
+
+       itemList.Append( (wxObject*) pInfo );
+}
+
+void cbGCUpdatesMgr::OnStartChanges()
+{
+       // memorize states of ALL items in the layout -
+       // this is quite excessive, but OK for the decent 
+       // implementation of updates manager
+
+       mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
+
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+       for( int n = 0; n != MAX_PANES; ++n )
+       {
+               cbDockPane& pane = *(panes[n]);
+
+               // store pane state
+               pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
+               pane.mUMgrData.SetDirty( FALSE );
+
+               cbRowInfo* pRow = pane.GetFirstRow();
+
+               while ( pRow )
+               {
+                       cbBarInfo* pBar = pRow->GetFirstBar();
+
+                       // store row state
+                       pRow->mUMgrData.StoreItemState( pRow->mBoundsInParent );
+                       pRow->mUMgrData.SetDirty( FALSE );
+
+                       while( pBar )
+                       {
+                               // store bar state
+                               pBar->mUMgrData.StoreItemState( pBar->mBoundsInParent );
+                               pBar->mUMgrData.SetDirty( FALSE );
+
+                               pBar = pBar->mpNext;
+                       }
+
+                       pRow = pRow->mpNext;
+               }
+       }
+}
+
+void cbGCUpdatesMgr::UpdateNow()
+{
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+       wxRect& r1 = mpLayout->GetClientRect();
+       wxRect& r2 = mpLayout->GetPrevClientRect();
+
+       // detect changes in client window's area
+
+       bool clientWindowChanged = ( r1.x      != r2.x     ||
+                                        r1.y      != r2.y     ||
+                                                                r1.width  != r2.width ||
+                                                                r1.height != r2.height );
+
+       // step #1 - detect changes in each row of each pane,
+       //           and repaint decorations around changed windows
+
+       wxList mBarsToResize;
+
+       for( int n = 0; n != MAX_PANES; ++n )
+       {
+               cbDockPane& pane = *(panes[n]);
+
+               bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
+
+               if ( paneChanged )
+               {
+                       wxClientDC dc( &mpLayout->GetParentFrame() );
+                       pane.PaintPaneBackground( dc );
+               }
+
+               wxRect realBounds;
+
+               cbRowInfo* pRow = pane.GetFirstRow();
+
+               while ( pRow )
+               {
+                       wxDC* pDc = 0;
+
+                       cbBarInfo* pBar = pRow->GetFirstBar();
+
+                       bool rowChanged = FALSE;
+                       bool rowBkPainted  = FALSE;
+
+                       // FIXME:: the below should not be fixed
+                       cbBarInfo* barsToRepaint[128];
+                       // number of bars, that were changed in the current row
+                       int nBars = 0; 
+
+                       wxRect r1 = pRow->mUMgrData.mPrevBounds;
+                       wxRect r2 = pRow->mBoundsInParent;
+
+                       if ( WasChanged( pRow->mUMgrData, pRow->mBoundsInParent ) )
+                       
+                               rowChanged = TRUE;
+                       else
+                               while( pBar )
+                               {
+                                       if ( WasChanged( pBar->mUMgrData, pBar->mBoundsInParent ) )
+                                       
+                                               barsToRepaint[nBars++] = pBar;
+
+                                       pBar = pBar->mpNext;
+                               }
+
+                       if ( nBars || rowChanged )
+                       {
+                               realBounds = pRow->mBoundsInParent;
+
+                               // include 1-pixel thick shades around the row
+                               realBounds.x -= 1;
+                               realBounds.y -= 1;
+                               realBounds.width  += 2;
+                               realBounds.height += 2;
+
+                               pDc = pane.StartDrawInArea( realBounds );
+                       }
+
+                       if ( rowChanged )
+                       {
+                               // postphone the resizement and refreshing the changed
+                               // bar windows
+
+                               cbBarInfo* pCurBar = pRow->GetFirstBar();
+
+                               while( pCurBar )
+                               {
+                                       if ( WasChanged( pCurBar->mUMgrData, 
+                                                                        pCurBar->mBoundsInParent ) )
+
+                                               AddItem( mBarsToResize, pCurBar, &pane, 
+                                                                pCurBar->mBoundsInParent,
+                                                                pCurBar->mUMgrData.mPrevBounds );
+
+                                       pCurBar = pCurBar->mpNext;
+                               }
+
+                               // draw only their decorations now
+
+                               pane.PaintRow( pRow, *pDc );
+                       }
+                       else
+                       if ( nBars != 0 )
+                       {
+                               for( int i = 0; i != nBars; ++i )
+
+                                       // postphone the resizement and refreshing the changed
+                                       // bar windows
+
+                                       AddItem( mBarsToResize, 
+                                                        barsToRepaint[i], 
+                                                        &pane, 
+                                                    barsToRepaint[i]->mBoundsInParent,
+                                                        barsToRepaint[i]->mUMgrData.mPrevBounds );
+
+                               // redraw decorations of entire row, regardless of how much
+                               // of the bars were changed
+
+                               pane.PaintRow( pRow, *pDc );
+                       }
+
+                       if ( pDc )
+               
+                               pane.FinishDrawInArea( realBounds );
+
+                       pRow = pRow->mpNext;
+
+               } // end of while
+
+               if ( paneChanged )
+               {
+                       wxClientDC dc( &mpLayout->GetParentFrame() );
+                       pane.PaintPaneDecorations( dc );
+               }
+
+       } // end of for
+
+       if ( clientWindowChanged && !mpLayout->mClientWndRefreshPending )
+       {
+               // ptr to client-window object is "marked" as NULL
+
+               AddItem( mBarsToResize, NULL, NULL, 
+                            mpLayout->GetClientRect(),
+                                mpLayout->GetPrevClientRect() );
+       }
+
+       // step #2 - do ordered refreshing and resizing of bar window objects now
+
+       DoRepositionItems( mBarsToResize );
+}
+
+void cbGCUpdatesMgr::DoRepositionItems( wxList& items )
+{
+       wxNode* pNode1 = items.First();
+
+       while( pNode1 )
+       {
+               cbRectInfo& info = node_to_rect_info( pNode1 );
+
+               wxNode* pNode2 = items.First();
+
+               // and node itself
+
+               mGC.AddObject( &info );
+
+               while( pNode2 )
+               {
+                       if ( pNode2 != pNode1 ) // node should not depend on itself
+                       {
+                               // add references to objects, on which this object
+                               // depends. Dependecy here indicates intersection of current
+                               // bounds of this object with the initial bounds of the
+                               // other object
+
+                               cbRectInfo& otherInfo = node_to_rect_info( pNode2 );
+
+                               if ( rect_hits_rect( *info.mpCurBounds, *otherInfo.mpPrevBounds ) )
+                               
+                                                                       // the node    depends on node
+                                       mGC.AddDependency( &info,      &otherInfo      );
+                       }
+
+                       pNode2 = pNode2->Next();
+               }
+
+               pNode1 = pNode1->Next();
+       }
+
+       mGC.ArrangeCollection(); // order nodes according "least-dependency" rule,
+                                    // and find out cycled chains
+
+       // regular item nodes need to be resized, but not repainted (since
+       // they stand in linear (not cyclic) dependency with other
+       // regular nodes)
+
+       wxNode* pNode = mGC.GetRegularObjects().First();
+
+       while ( pNode )
+       {
+               cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
+
+               if ( info.mpBar == NULL ) 
+                       
+                       mpLayout->PositionClientWindow();
+               else
+                       info.mpPane->SizeBar( info.mpBar );
+
+               pNode = pNode->Next();
+       }
+
+       // cycled item nodes, need to be both resized and repainted
+
+       pNode = mGC.GetCycledObjects().First();
+
+       while ( pNode )
+       {
+               cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode));
+
+               if ( info.mpBar == NULL ) 
+               {
+                       wxWindow* pClntWnd = mpLayout->GetFrameClient();
+
+                       mpLayout->PositionClientWindow();
+
+                       // FIXME FIXME:: excessive!
+
+                       pClntWnd->Show( FALSE );
+                       pClntWnd->Show( TRUE  );
+
+                       // OLD STUFF:: mpLayout->PositionClientWindow();
+               }
+               else
+               if ( info.mpBar->mpBarWnd )
+               {
+                       wxWindow* pWnd = info.mpBar->mpBarWnd;
+
+                       // resize
+                       info.mpPane->SizeBar( info.mpBar );
+
+                       // repaint
+
+                       /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) );
+
+                       //#ifdef __WINDOWS__
+                       //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 );
+                       //#endif
+                       */
+
+                       // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!!
+                       //                               so we do *excessive* "hide 'n show"
+
+                       pWnd->Show(FALSE);
+                       pWnd->Show(TRUE);
+                               
+                       pWnd->Refresh();
+               }
+
+               pNode = pNode->Next();
+       }
+
+       // release data prepared for GC alg.
+
+       pNode = items.First();
+
+       while( pNode )
+       {
+               cbRectInfo* pInfo = (cbRectInfo*)(pNode->Data());
+
+               delete pInfo;
+
+               pNode = pNode->Next();
+       }
+
+       mGC.Reset(); // reinit GC
+
+       // FIXME:: this is a dirty-workaround for messy client-area,
+       //         as a result of docking bar out of floated-container window
+
+       if ( mpLayout->mClientWndRefreshPending )
+       {
+               mpLayout->PositionClientWindow();
+               mpLayout->GetFrameClient()->Refresh();
+       }
+}
+
diff --git a/contrib/src/fl/hintanimpl.cpp b/contrib/src/fl/hintanimpl.cpp
new file mode 100644 (file)
index 0000000..3453fe8
--- /dev/null
@@ -0,0 +1,397 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     9/11/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "hintanimpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/hintanimpl.h"
+
+#define POS_UNDEFINED -32768
+
+/***** Implementation for class cbHintAnimationPlugin *****/
+
+// FIXME:: some of the below code should be eliminated by 
+//         reusing parts of cbBarDragPlugin's implementation
+
+IMPLEMENT_DYNAMIC_CLASS( cbHintAnimationPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbHintAnimationPlugin, cbPluginBase )
+
+       EVT_PL_DRAW_HINT_RECT( cbHintAnimationPlugin::OnDrawHintRect )
+
+END_EVENT_TABLE()
+
+cbHintAnimationPlugin::cbHintAnimationPlugin(void)
+
+       : mpScrDc( NULL ),
+         mpAnimTimer( 0 ),
+         mAnimStarted( FALSE ),
+         
+         mMorphDelay    ( 5   ),
+         mMaxFrames     ( 20   ),
+      mInClientHintBorder( 4 ),
+         mAccelerationOn( TRUE )
+{}
+
+cbHintAnimationPlugin::cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask ),
+         mpScrDc( NULL ),
+         mpAnimTimer( 0 ),
+         mAnimStarted( FALSE ),
+
+         mMorphDelay    ( 5   ),
+         mMaxFrames     ( 20   ),
+         mInClientHintBorder( 4 ),
+         mAccelerationOn( TRUE )
+{}
+
+cbHintAnimationPlugin::~cbHintAnimationPlugin()
+{
+       if ( mpScrDc ) delete mpScrDc;
+}
+
+/*** rect-tracking related methods ***/
+
+void cbHintAnimationPlugin::OnDrawHintRect( cbDrawHintRectEvent& event )
+{
+       if ( !mAnimStarted && !mpScrDc ) 
+       {
+               StartTracking();
+
+               mPrevInClient = event.mIsInClient;
+
+               mPrevRect = event.mRect;
+
+               mStopPending = FALSE;
+       }
+
+       if ( !event.mEraseRect )
+       {
+               // pass on current hint-rect info to the animation "thread", in 
+               // order to make adjustments to the morph-target on-the-fly
+
+               mCurRect.x = event.mRect.x;
+               mCurRect.y = event.mRect.y;
+               mCurRect.width  = event.mRect.width;
+               mCurRect.height = event.mRect.height;
+       }
+
+       // check the amount of change in the shape of hint,
+       // and start morph-effect if change is "sufficient"
+
+       int change = abs( mCurRect.width  - mPrevRect.width  ) +
+                            abs( mCurRect.height - mPrevRect.height );
+
+       if ( change > 10 && !event.mLastTime && !event.mEraseRect )
+       {
+               if ( !mpAnimTimer )
+
+                       mpAnimTimer  = new cbHintAnimTimer();
+
+               // init the animation "thread", or reinit if already started
+
+               mpAnimTimer->Init( this, mAnimStarted );
+
+               mAnimStarted = TRUE;
+       }
+       else
+       if ( !mAnimStarted )
+       {
+               DoDrawHintRect( event.mRect, event.mIsInClient );
+
+               if ( event.mLastTime )
+
+                       FinishTracking();
+
+               mPrevInClient = event.mIsInClient;
+       }
+       else
+       {
+               mCurInClient = event.mIsInClient;
+
+               if ( event.mLastTime && mpAnimTimer ) 
+               {
+                       mStopPending = TRUE;
+
+                       if ( mpAnimTimer->mPrevMorphed.x != POS_UNDEFINED )
+
+                               // erase previous rect
+                               DoDrawHintRect( mpAnimTimer->mPrevMorphed, mPrevInClient );
+               }
+       }
+
+       mPrevRect = event.mRect;
+}
+
+#define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
+#define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
+#define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.
+#define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.
+
+static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D
+                                                                                         };
+
+void cbHintAnimationPlugin::StartTracking()
+{
+       mpScrDc = new wxScreenDC;
+
+       wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
+}
+
+void cbHintAnimationPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect)
+{
+       wxRect scrRect;
+
+       RectToScr( rect, scrRect );
+
+       int prevLF = mpScrDc->GetLogicalFunction();
+
+       mpScrDc->SetLogicalFunction( wxXOR );
+
+       if ( isInClientRect )
+       {
+               // BUG BUG BUG (wx):: somehow stippled brush works only  
+               //                                        when the bitmap created on stack, not
+               //                                        as a member of the class
+
+               wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
+
+               wxBrush checkerBrush( checker );
+
+               mpScrDc->SetPen( mpLayout->mNullPen );
+               mpScrDc->SetBrush( checkerBrush );
+
+               int half = mInClientHintBorder / 2;
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half,
+                                           scrRect.width + 2*half, mInClientHintBorder );
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half,
+                                           scrRect.width + 2*half, mInClientHintBorder );
+
+               mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1,
+                                           mInClientHintBorder, scrRect.height - 2*half + 2);
+
+               mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half,
+                                                               scrRect.y + half - 1,
+                                           mInClientHintBorder, scrRect.height - 2*half + 2);
+
+               mpScrDc->SetBrush( wxNullBrush );
+       }
+       else
+       {
+               // otherwise draw 1-pixel thin borders
+
+               mpScrDc->SetPen( mpLayout->mBlackPen );
+
+               mpScrDc->DrawLine( scrRect.x, scrRect.y, 
+                                                  scrRect.x + scrRect.width, scrRect.y );
+
+               mpScrDc->DrawLine( scrRect.x, scrRect.y + 1, 
+                                                  scrRect.x, scrRect.y + scrRect.height );
+
+               mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height, 
+                                                  scrRect.x + scrRect.width, scrRect.y + scrRect.height );
+
+               mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y, 
+                                                  scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1);
+       }
+
+       mpScrDc->SetLogicalFunction( prevLF );
+}
+
+void cbHintAnimationPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect)
+{
+       DoDrawHintRect( rect, isInClientRect ); 
+}
+
+void cbHintAnimationPlugin::EraseHintRect( wxRect& rect, bool isInClientRect)
+{
+       DoDrawHintRect( rect, isInClientRect ); 
+}
+
+void cbHintAnimationPlugin::FinishTracking()
+{
+       wxScreenDC::EndDrawingOnTop();
+
+       delete mpScrDc;
+
+       mpScrDc = NULL;
+}
+
+void cbHintAnimationPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect )
+{
+       scrRect = frameRect;
+
+       int x = frameRect.x, y = frameRect.y;
+
+       mpLayout->GetParentFrame().ClientToScreen( &x, &y );
+
+       scrRect.x = x;
+       scrRect.y = y;
+}
+
+/***** Implementation for class cbHintAnimTimer *****/
+
+cbHintAnimTimer::cbHintAnimTimer(void)
+{
+#ifdef __WINDOWS__
+       mLock = 0L;
+#endif
+
+       mPrevMorphed.x = POS_UNDEFINED;
+}
+
+void cbHintAnimTimer::MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point )
+{
+       // simulate lienar movement (FOR NOW:: without acceleration)
+
+       double k;
+       
+       if ( mpPl->mAccelerationOn )
+               
+               k = double( mCurIter*mCurIter ) / 
+                   double( (mpPl->mMaxFrames - 1)*(mpPl->mMaxFrames - 1) );
+       else
+               k = double( mCurIter ) / double( mpPl->mMaxFrames - 1 );
+
+       point.x = int ( double ( info.mFrom.x + double (info.mTill.x - info.mFrom.x) * k ) );
+
+       point.y = int ( double ( info.mFrom.y + double (info.mTill.y - info.mFrom.y) * k ) );
+
+       point.x += origin.x;
+       point.y += origin.y;
+}
+
+void cbHintAnimTimer::Notify(void)
+{
+       // FIXME:: "clean" implementation should use mutex to sync
+       //         between GUI and animation threads
+
+       if ( mpPl->mStopPending )
+       {
+               Stop(); // top timer
+
+               mpPl->FinishTracking();
+
+               mpPl->mStopPending = FALSE;
+               mpPl->mpAnimTimer  = NULL;
+               mpPl->mAnimStarted = FALSE;
+
+               mPrevMorphed.x = POS_UNDEFINED;
+
+               delete this;
+
+               return;
+       }
+
+       wxPoint origin( mpPl->mCurRect.x, mpPl->mCurRect.y );
+
+       wxPoint curUpper, curLower;
+
+       MorphPoint( origin, mUpperLeft,  curUpper  );
+       MorphPoint( origin, mLowerRight, curLower );
+
+       if ( mPrevMorphed.x != POS_UNDEFINED )
+
+               // erase previous rect
+               mpPl->DoDrawHintRect( mPrevMorphed, mpPl->mPrevInClient );
+
+       wxRect morphed( curUpper.x,  curUpper.y,
+                               curLower.x - curUpper.x,
+                                       curLower.y - curUpper.y );
+
+       // draw rect of current iteration
+       mpPl->DoDrawHintRect( morphed, 
+                                                 ( mCurIter != mpPl->mMaxFrames - 1 ) 
+                                                 ? mpPl->mPrevInClient : mpPl->mCurInClient );
+
+       mPrevMorphed = morphed;
+
+       if ( mCurIter == mpPl->mMaxFrames - 1 ) 
+       {
+               Stop(); // top timer
+               
+               mpPl->FinishTracking();
+               mpPl->mpAnimTimer  = NULL;
+               mpPl->mAnimStarted = FALSE;
+
+               mPrevMorphed.x = POS_UNDEFINED;
+
+               delete this;
+       }
+       else
+               ++mCurIter;
+}
+
+bool cbHintAnimTimer::Init( cbHintAnimationPlugin* pAnimPl, bool reinit )
+{
+
+       mpPl = pAnimPl;
+
+       // morph-points are set up relatively to the upper-left corner
+       // of the current hint-rectangle
+
+       if ( !reinit )
+       {
+               mUpperLeft.mFrom.x = mpPl->mPrevRect.x - mpPl->mCurRect.x;
+               mUpperLeft.mFrom.y = mpPl->mPrevRect.y - mpPl->mCurRect.y;
+
+               mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + mpPl->mPrevRect.width  );
+               mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + mpPl->mPrevRect.height );
+       }
+       else
+       {
+               wxPoint origin( mpPl->mPrevRect.x, mpPl->mPrevRect.y );
+
+               wxPoint curUpper, curLower;
+
+               MorphPoint( origin, mUpperLeft,  curUpper  );
+               MorphPoint( origin, mLowerRight, curLower );
+
+               mUpperLeft.mFrom.x = curUpper.x - mpPl->mCurRect.x;
+               mUpperLeft.mFrom.y = curUpper.y - mpPl->mCurRect.y;
+
+               mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + curLower.x - curUpper.x );
+               mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + curLower.y - curUpper.y );
+       }
+
+       mUpperLeft.mTill.x = 0;
+       mUpperLeft.mTill.y = 0;
+
+       mLowerRight.mTill.x = mpPl->mCurRect.width;
+       mLowerRight.mTill.y = mpPl->mCurRect.height;
+
+       mCurIter = 1;
+       
+       if ( !reinit )
+
+               Start( mpPl->mMorphDelay );
+
+       return TRUE;
+}
+
diff --git a/contrib/src/fl/makefile.b32 b/contrib/src/fl/makefile.b32
new file mode 100644 (file)
index 0000000..18b8f8a
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# File:         makefile.b32
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWindows FrameLayout library (32-bit BC++)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ../../..
+LIB_NAME = fl
+OBJ_EXT        = obj
+
+!include files.lst
+
+!if "$(FINAL)" == "1"
+LIBTARGET=$(WXDIR)/lib/$(LIB_NAME).lib
+!else
+LIBTARGET=$(WXDIR)/lib/$(LIB_NAME)d.lib
+!endif
+
+OBJECTS = $(FL_OBJECTS)
+
+!include $(WXDIR)/src/makelib.b32
+
diff --git a/contrib/src/fl/makefile.g95 b/contrib/src/fl/makefile.g95
new file mode 100644 (file)
index 0000000..e3d75b4
--- /dev/null
@@ -0,0 +1,20 @@
+#
+# File:         makefile.g95
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWindows FrameLayout library (Cygwin/Mingw32).
+
+WXDIR = ../../..
+LIB_NAME = fl
+OBJ_EXT        = o
+
+include files.lst
+
+LIBTARGET=$(WXDIR)/lib/lib$(LIB_NAME).a
+OBJECTS = $(FL_OBJECTS)
+
+include $(WXDIR)/src/makelib.g95
+
diff --git a/contrib/src/fl/makefile.vc b/contrib/src/fl/makefile.vc
new file mode 100644 (file)
index 0000000..86ab8ac
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# File:         makefile.vc
+# Author:       Hans Van Leemputten
+# Created:      2001
+# Updated:
+# Copyright:    (c) wxWorkshop team, 2001
+#
+# Makefile for wxWindows FrameLayout library (Microsoft VC++)
+# Use FINAL=1 argument to nmake to build final version with no debug info.
+
+WXDIR = ..\..\..
+LIB_NAME = fl
+OBJ_EXT        = obj
+
+!include files.lst
+
+!if "$(FINAL)" == "1"
+LIBTARGET=$(WXDIR)\lib\$(LIB_NAME).lib
+!else
+LIBTARGET=$(WXDIR)\lib\$(LIB_NAME)d.lib
+!endif
+
+OBJECTS = $(FL_OBJECTS)
+
+!include $(WXWIN)\src\makelib.vc
+
diff --git a/contrib/src/fl/newbmpbtn.cpp b/contrib/src/fl/newbmpbtn.cpp
new file mode 100644 (file)
index 0000000..be095bd
--- /dev/null
@@ -0,0 +1,832 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     ??/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "newbmpbtn.h"
+#endif
+
+// 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"
+#endif
+
+#include "wx/fl/newbmpbtn.h"
+#include "wx/utils.h"     // import wxMin,wxMax macros
+
+///////////// button-label rendering helpers //////////////////
+
+static int* create_array( int width, int height, int fill = 0 )
+{
+       int* array = new int[width*height];
+
+       int len = width*height;
+       for( int i = 0; i != len; ++i ) array[i] = fill;
+
+       return array;
+}
+
+#define GET_ELEM(array,x,y) (array[width*(y)+(x)])
+
+#define MIN_COLOR_DIFF 10
+
+#define IS_IN_ARRAY(x,y) ( (x) < width && (y) < height && (x) >= 0 && (y) >= 0 )
+
+#define GET_RED(col)    col        & 0xFF  
+#define GET_GREEN(col) (col >> 8)  & 0xFF        
+#define GET_BLUE(col)  (col >> 16) & 0xFF 
+
+#define MAKE_INT_COLOR(red,green,blue) (     (red)                      | \
+                                         ( ( (green) << 8 ) & 0xFF00  ) | \
+                                                                                ( ( (blue)  << 16) & 0xFF0000) \
+                                       )   
+
+#define IS_GREATER(col1,col2) ( ( (GET_RED(col1)  ) > (GET_RED(col2)  ) + MIN_COLOR_DIFF ) && \
+                                ( (GET_GREEN(col1)) > (GET_GREEN(col2)) + MIN_COLOR_DIFF ) &&  \
+                                                               ( (GET_BLUE(col1) ) > (GET_BLUE(col2) ) + MIN_COLOR_DIFF )         \
+                                                         )
+
+#define MASK_BG           0
+#define MASK_DARK  1
+#define MASK_LIGHT 2
+
+// helper function, used internally
+
+static void gray_out_pixmap( int* src, int* dest, int width, int height )
+{
+       // assuming the pixels along the edges are of the background color
+
+       int x = 0;
+       int y = 1;
+
+       do
+       {
+               int cur       = GET_ELEM(src,x,y);
+
+
+               if ( IS_IN_ARRAY(x-1,y-1) )
+               {
+                       int upperElem = GET_ELEM(src,x-1,y-1);
+
+                       // if the upper element is lighter than current
+                       if ( IS_GREATER(upperElem,cur) )
+                       {
+                               GET_ELEM(dest,x,y) = MASK_DARK;
+                       }
+                       else
+                       // if the current element is ligher than the upper
+                       if ( IS_GREATER(cur,upperElem) )
+                       {
+                               GET_ELEM(dest,x,y) = MASK_LIGHT;
+                       }
+                       else
+                       {
+                               if ( GET_ELEM(dest,x-1,y-1) == MASK_LIGHT )
+                                       
+                                       GET_ELEM(dest,x,y) = MASK_BG;
+
+                               if ( GET_ELEM(dest,x-1,y-1 ) == MASK_DARK )
+
+                                       GET_ELEM(dest,x,y) = MASK_DARK;
+                               else
+                                       GET_ELEM(dest,x,y) = MASK_BG;
+                       }
+               }
+
+               // go zig-zag
+
+               if ( IS_IN_ARRAY(x+1,y-1) ) 
+               {
+                       ++x;--y;
+               }
+               else
+               {
+                       while( IS_IN_ARRAY(x-1,y+1) ) 
+                       {
+                               --x;++y;
+                       }
+
+                       if ( IS_IN_ARRAY(x,y+1) )
+                       {
+                                       ++y; continue;
+                       }
+                       else
+                       {
+                               if ( IS_IN_ARRAY(x+1,y) )
+                               {
+                                       ++x; continue;
+                               }
+                               else break;
+                       }
+               }
+
+       } while(1);
+}
+
+// alg. for making the image look "grayed" (e.g. disabled button)
+// NOTE:: used GetPixel(), which is Windows-Only!
+
+void gray_out_image_on_dc( wxDC& dc, int width, int height )
+{
+       // assuming the pixels along the edges are of the background color
+       wxColour bgCol;
+       dc.GetPixel( 0, 0, &bgCol );
+
+       wxPen darkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW),1, wxSOLID );
+       wxPen lightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT),1, wxSOLID );
+       wxPen bgPen   ( bgCol,                1, wxSOLID );
+
+       int* src  = create_array( width, height, MASK_BG );
+       int* dest = create_array( width, height, MASK_BG );
+
+       int y = 0;
+       for( y = 0; y != height; ++y )
+
+               for( int x = 0; x != width; ++x )
+               {
+                       wxColour col;
+                       dc.GetPixel( x,y, &col );
+
+
+                       GET_ELEM(src,x,y) = MAKE_INT_COLOR( col.Red(), col.Green(), col.Blue() );
+               }
+
+       gray_out_pixmap( src, dest, width, height );
+
+       for( y = 0; y != height; ++y )
+
+               for( int x = 0; x != width; ++x )
+               {
+                       int mask = GET_ELEM(dest,x,y);
+
+                       switch (mask)
+                       {
+                               case MASK_BG    : { dc.SetPen( bgPen ); 
+                                                       dc.DrawPoint( x,y ); break;
+                                                             }
+                               case MASK_DARK  : { dc.SetPen( darkPen ); 
+                                                       dc.DrawPoint( x,y ); break;
+                                                             }
+                               case MASK_LIGHT : { dc.SetPen( lightPen ); 
+                                                       dc.DrawPoint( x,y ); break;
+                                                             }
+                               default : break;
+                       }
+               }
+
+       delete [] src;
+       delete [] dest;
+}
+
+///////////////////////////////
+
+/***** Impelementation for class wxNewBitmapButton *****/
+
+IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton, wxPanel)
+
+BEGIN_EVENT_TABLE( wxNewBitmapButton, wxPanel )
+
+       EVT_LEFT_DOWN( wxNewBitmapButton::OnLButtonDown )
+       EVT_LEFT_UP  ( wxNewBitmapButton::OnLButtonUp   )
+       EVT_MOTION   ( wxNewBitmapButton::OnMouseMove   )
+
+       EVT_SIZE ( wxNewBitmapButton::OnSize  )
+       EVT_PAINT( wxNewBitmapButton::OnPaint )
+
+       //EVT_KILL_FOCUS( wxNewBitmapButton::OnKillFocus )
+
+       EVT_ERASE_BACKGROUND( wxNewBitmapButton::OnEraseBackground )
+
+END_EVENT_TABLE()
+
+wxNewBitmapButton::wxNewBitmapButton( const wxBitmap& labelBitmap, 
+                                                                         const wxString& labelText,
+                                                                         int  alignText,
+                                                                         bool isFlat,
+                                                                         int  firedEventType, 
+                                                                         int  marginX,
+                                                                         int  marginY,
+                                                                         int  textToLabelGap,
+                                                                         bool isSticky)
+       :       mTextToLabelGap  ( textToLabelGap ),
+               mMarginX( marginX ),
+               mMarginY( marginY ),
+               mTextAlignment( alignText ),
+               mIsSticky( isSticky ),
+               mIsFlat( isFlat ),
+               mLabelText( labelText ),
+               mImageFileType( -1 ),
+               mDepressedBmp( labelBitmap ),
+
+               mpDepressedImg( NULL ),
+               mpPressedImg  ( NULL ),
+               mpDisabledImg ( NULL ),
+               mpFocusedImg  ( NULL ),
+
+
+               mDragStarted     ( FALSE ),
+               mIsPressed       ( FALSE ),
+               mIsInFocus( FALSE ),
+               mPrevPressedState( FALSE ),
+               mPrevInFocusState( FALSE ),
+               mHasFocusedBmp( FALSE ),
+               mFiredEventType( firedEventType ),
+
+               mBlackPen( wxColour(  0,  0,  0), 1, wxSOLID ),
+               mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
+               mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+               mLightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ),
+
+               mIsCreated( FALSE ),
+               mSizeIsSet( FALSE )
+
+{
+}
+
+wxNewBitmapButton::wxNewBitmapButton( const wxString& bitmapFileName,
+                                                                         const int       bitmapFileType,
+                                                                         const wxString& labelText,
+                                                                         int  alignText,
+                                                                         bool isFlat,
+                                                                         int  firedEventType, 
+                                                                         int  marginX,
+                                                                         int  marginY,
+                                                                         int  textToLabelGap,
+                                                                         bool isSticky)
+
+       :       mTextToLabelGap  ( 2 ),
+               mMarginX( 2 ),
+               mMarginY( 2 ),
+               mTextAlignment( alignText ),
+               mIsSticky( FALSE ),
+               mIsFlat( isFlat ),
+               mLabelText( labelText ),
+               mImageFileName( bitmapFileName ),
+               mImageFileType( bitmapFileType ),
+
+               mpDepressedImg( NULL ),
+               mpPressedImg  ( NULL ),
+               mpDisabledImg ( NULL ),
+               mpFocusedImg  ( NULL ),
+
+               mDragStarted     ( FALSE ),
+               mIsPressed       ( FALSE ),
+               mIsInFocus       ( FALSE ),
+               mPrevPressedState( FALSE ),
+               mPrevInFocusState( FALSE ),
+               mHasFocusedBmp( FALSE ),
+               mFiredEventType( wxEVT_COMMAND_MENU_SELECTED ),
+
+               mBlackPen( wxColour(  0,  0,  0), 1, wxSOLID ),
+               mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ),
+               mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ),
+               mLightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ),
+
+               mIsCreated( FALSE ),
+               mSizeIsSet( FALSE )
+
+{
+}
+
+wxNewBitmapButton::~wxNewBitmapButton(void) 
+{
+       DestroyLabels();
+}
+
+void wxNewBitmapButton::DrawShade( int outerLevel,
+                                                                  wxDC&  dc,
+                                                              wxPen& upperLeftSidePen,
+                                                                  wxPen& lowerRightSidePen )
+{
+       wxBitmap* pBmp = GetStateLabel();
+
+       int x = mMarginX - (outerLevel + 1);
+       int y = mMarginY - (outerLevel + 1);
+
+       int height = pBmp->GetHeight() + (outerLevel + 1)*2 - 1;
+       int width  = pBmp->GetWidth()  + (outerLevel + 1)*2 - 1;
+
+       dc.SetPen( upperLeftSidePen );
+       dc.DrawLine( x,y, x + width, y  );
+       dc.DrawLine( x,y, x, y + height );
+
+       dc.SetPen( lowerRightSidePen );
+       dc.DrawLine( x + width, y, x + width, y + height + 1  );
+       dc.DrawLine( x, y + height, x + width, y + height );
+}
+
+void wxNewBitmapButton::DestroyLabels()
+{
+       if ( mpDepressedImg ) delete mpDepressedImg;
+       if ( mpPressedImg   ) delete mpPressedImg;
+       if ( mpDisabledImg  ) delete mpDisabledImg;
+       if ( mpFocusedImg   ) delete mpFocusedImg;
+
+       mpDepressedImg = NULL;
+       mpPressedImg   = NULL;
+       mpDisabledImg  = NULL;
+       mpFocusedImg   = NULL;
+}
+
+wxBitmap* wxNewBitmapButton::GetStateLabel()
+{
+       if ( IsEnabled() )
+       {
+               if ( mIsPressed )
+               {
+                       return mpPressedImg;
+               }
+               else
+               {
+                       if ( mIsInFocus )
+                       {
+                               if ( mHasFocusedBmp )
+
+                                       return mpFocusedImg;
+                               else
+                                       return mpDepressedImg;
+                       }
+                       else
+                               return mpDepressedImg;
+               }
+       }
+       else
+               return mpDisabledImg;
+}
+
+static const unsigned char _gDisableImage[] = { 0x55,0xAA,0x55,0xAA,
+                                                                                     0x55,0xAA,0x55,0xAA,
+                                                                                     0x55,0xAA,0x55,0xAA,
+                                                                                     0x55,0xAA,0x55,0xAA
+                                                                                       };
+void wxNewBitmapButton::RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp,
+                                                                                 bool isEnabled, bool isPressed )
+{
+       if ( destBmp != 0 ) return;
+
+       // render lables on-demand
+
+       wxMemoryDC srcDc;
+       srcDc.SelectObject( *srcBmp );
+
+       bool hasText = ( mTextAlignment != NB_NO_TEXT ) &&
+                          ( mLabelText.length() != 0 );
+
+       bool hasImage = (mTextAlignment != NB_NO_IMAGE);
+
+       wxSize destDim;
+       wxPoint txtPos;
+       wxPoint imgPos;
+
+       if ( hasText )
+       {
+               long txtWidth, txtHeight;
+
+               srcDc.SetFont( wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT) );
+               srcDc.GetTextExtent( mLabelText, &txtWidth, &txtHeight );
+
+               if ( mTextAlignment == NB_ALIGN_TEXT_RIGHT )
+               {
+                       destDim.x = srcBmp->GetWidth() + 2*mTextToLabelGap + txtWidth;
+
+                       destDim.y = 
+                               wxMax( srcBmp->GetHeight(), txtHeight );
+
+                       txtPos.x = srcBmp->GetWidth() + mTextToLabelGap;
+                       txtPos.y = (destDim.y - txtHeight)/2;
+                       imgPos.x = 0;
+                       imgPos.y = (destDim.y - srcBmp->GetHeight())/2;
+               }
+               else
+               if ( mTextAlignment == NB_ALIGN_TEXT_BOTTOM )
+               {
+                       destDim.x = 
+                               wxMax( srcBmp->GetWidth(), txtWidth );
+
+                       destDim.y = srcBmp->GetHeight() + mTextToLabelGap + txtHeight;
+
+                       txtPos.x = (destDim.x - txtWidth)/2;
+                       txtPos.y = srcBmp->GetHeight() + mTextToLabelGap;
+                       imgPos.x = (destDim.x - srcBmp->GetWidth())/2;
+                       imgPos.y = 0;
+               }
+               else 
+               {
+                       int avoidCompilerWarning = 0;
+                       wxASSERT(avoidCompilerWarning);// unsupported alignment type
+               }
+       }
+       else
+       {
+               imgPos.x = 0;
+               imgPos.y = 0;
+               destDim.x = srcBmp->GetWidth();
+               destDim.y = srcBmp->GetHeight();
+       }
+
+       destBmp = new wxBitmap( int(destDim.x), int(destDim.y) );
+
+       wxMemoryDC destDc;
+       destDc.SelectObject( *destBmp );
+
+       wxBrush grayBrush( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE), wxSOLID );
+       wxPen   nullPen( wxColour(0,0,0), 1, wxTRANSPARENT );
+
+       destDc.SetBrush( grayBrush );
+       destDc.SetPen( nullPen );
+
+       destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 );
+
+       if ( isPressed )
+       {
+               ++imgPos.x; ++imgPos.y;
+               ++txtPos.x; ++txtPos.y;
+       }
+
+       if ( hasImage )
+       {
+
+               destDc.Blit( imgPos.x, imgPos.y, 
+                                srcBmp->GetWidth()+1,
+                                srcBmp->GetHeight()+1,
+                                &srcDc, 0,0, wxCOPY,TRUE );
+       }
+
+       if ( hasText )
+       {
+               wxWindow* pTopWnd = this;
+
+               do
+               {
+                       wxWindow* pParent = pTopWnd->GetParent();
+
+                       if ( pParent == 0 )
+                break;
+
+                       pTopWnd = pParent;
+               } while(1);
+
+               destDc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT) );
+
+               if ( isEnabled )
+        {
+                       destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT) );
+               }
+        else
+        {
+                       destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW) );
+               }
+               destDc.SetTextBackground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE) );
+
+               destDc.DrawText( mLabelText, txtPos.x, txtPos.y );
+       }
+
+
+       destDc.SetBrush( grayBrush );
+       destDc.SetPen( nullPen );
+
+       destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 );
+
+       if ( isPressed )
+       {
+               ++imgPos.x; ++imgPos.y;
+               ++txtPos.x; ++txtPos.y;
+       }
+
+       if ( hasImage )
+       {
+
+               destDc.Blit( imgPos.x, imgPos.y, 
+                                srcBmp->GetWidth()+1,
+                                srcBmp->GetHeight()+1,
+                                &srcDc, 0,0, wxCOPY,TRUE );
+       }
+
+       if ( hasText )
+       {
+               wxWindow* pTopWnd = this;
+
+               do
+               {
+                       wxWindow* pParent = pTopWnd->GetParent();
+
+                       if ( pParent == 0 )
+                break;
+
+                       pTopWnd = pParent;
+               } while(1);
+
+               destDc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT) );
+
+               if ( isEnabled )
+        {
+                       destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT) );
+               }
+        else
+        {
+                       destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW) );
+               }
+               destDc.SetTextBackground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE) );
+
+               destDc.DrawText( mLabelText, txtPos.x, txtPos.y );
+       }
+
+       if ( !isEnabled ){
+       
+#ifdef __WXMSW__ // This is currently MSW specific
+               gray_out_image_on_dc( destDc, destDim.x, destDim.y );
+#else
+               wxBrush checkerBrush( wxBitmap( (const char*)_gDisableImage,8,8) );
+               checkerBrush.SetColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ) );
+               destDc.SetBrush( checkerBrush );
+               destDc.DrawRectangle( imgPos.x, imgPos.y, srcBmp->GetWidth()+1, srcBmp->GetHeight()+1);
+#endif
+       }
+       // adjust button size to fit the new dimensions of the label
+       if ( !mSizeIsSet && 0 )
+       {
+               mSizeIsSet = TRUE; 
+               SetSize( -1,-1, 
+                                destBmp->GetWidth()  + mMarginX*2,
+                                destBmp->GetHeight() + mMarginY*2, 0 
+                       );
+       }
+}
+void wxNewBitmapButton::RenderAllLabelImages()
+{
+       if ( !mIsCreated )
+        return;
+       RenderLabelImage( mpDisabledImg, &mDepressedBmp, FALSE );
+       RenderLabelImage( mpPressedImg,   &mDepressedBmp, TRUE, TRUE );
+       RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE );
+       if ( mHasFocusedBmp )
+    {
+               RenderLabelImage( mpFocusedImg, &mFocusedBmp, TRUE, FALSE );
+       }
+}
+       
+
+void wxNewBitmapButton::RenderLabelImages()
+{
+       if ( !mIsCreated )
+        return;
+
+       if ( !IsEnabled() )
+       {
+               RenderLabelImage( mpDisabledImg, &mDepressedBmp, FALSE );
+       }
+       else
+
+       if ( mIsPressed ) 
+
+               RenderLabelImage( mpPressedImg,   &mDepressedBmp, TRUE, TRUE );
+       else
+       {
+               if ( mIsInFocus )
+               {
+                       if ( mHasFocusedBmp )
+                               RenderLabelImage( mpFocusedImg, &mFocusedBmp, TRUE, FALSE );
+                       else
+                               RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE );
+               }
+               else
+                       RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE );
+       }
+}
+
+void wxNewBitmapButton::DrawDecorations( wxDC& dc )
+{
+       if ( mIsFlat )
+       {
+               DrawShade( 1, dc, mGrayPen,  mGrayPen  );
+               
+               if ( mIsInFocus )
+               {
+                       if ( mIsPressed )
+                               DrawShade( 0, dc, mDarkPen,  mLightPen  );
+                       else
+                               DrawShade( 0, dc, mLightPen,  mDarkPen  );
+               }
+               else
+                       DrawShade( 0, dc, mGrayPen,  mGrayPen  );
+       }
+       else
+       {
+               if ( mIsPressed )
+               {
+                       DrawShade( 0, dc, mDarkPen,  mGrayPen  );
+                       DrawShade( 1, dc, mBlackPen, mLightPen );
+               }
+               else
+               {
+                       DrawShade( 0, dc, mGrayPen,  mDarkPen  );
+                       DrawShade( 1, dc, mLightPen, mBlackPen );
+               }
+       }
+}
+
+void wxNewBitmapButton::SetLabel(const wxBitmap& labelBitmap, 
+                                                                const wxString& labelText )
+{
+       DestroyLabels();
+
+       mLabelText    = labelText;
+       mDepressedBmp = labelBitmap;
+
+       //RenderLabelImages();
+       RenderAllLabelImages();
+}
+
+void wxNewBitmapButton::SetAlignments( int alignText,
+                                                                      int marginX,
+                                                                          int marginY,
+                                                                          int textToLabelGap)
+{
+       DestroyLabels();
+
+       mMarginX        = marginX;
+       mMarginY        = marginY;
+       mTextAlignment  = alignText;
+       mTextToLabelGap = textToLabelGap;
+
+       //RenderLabelImages();
+       RenderAllLabelImages();
+}
+
+// event handlers
+
+void wxNewBitmapButton::OnLButtonDown( wxMouseEvent& event )
+{
+       mPrevPressedState = FALSE;   
+       mDragStarted      = TRUE;
+       mIsPressed        = TRUE;
+       Refresh();
+
+       if ( !mIsInFocus )
+                       CaptureMouse();
+}
+
+void wxNewBitmapButton::OnLButtonUp( wxMouseEvent& event )
+{
+       if ( !mDragStarted )
+        return;
+
+       mDragStarted = FALSE;
+       mIsPressed   = FALSE;
+       mIsInFocus   = FALSE;
+       Refresh();
+
+       ReleaseMouse();
+
+       if ( IsInWindow( event.m_x, event.m_y ) ) 
+       {
+               // fire event, if mouse was released
+               // within the bounds of button
+               wxCommandEvent cmd( mFiredEventType, GetId() );
+               GetParent()->ProcessEvent( cmd );
+       }
+}
+
+bool wxNewBitmapButton::IsInWindow( int x, int y )
+{
+       int width, height;
+       GetSize( &width, &height );
+
+       return ( x >= 0 && y >= 0 &&
+                        x < width &&
+                        y < height );
+}
+
+void wxNewBitmapButton::OnMouseMove( wxMouseEvent& event )
+{
+       mPrevPressedState=mIsPressed;
+       mPrevInFocusState=mIsInFocus;
+       if ( !mIsInFocus && IsInWindow( event.m_x, event.m_y ) )
+       {
+               if ( !mDragStarted )
+                       CaptureMouse();
+
+               mIsInFocus = TRUE;
+       }
+       else
+       if ( mIsInFocus && !IsInWindow( event.m_x, event.m_y ) )
+       {
+               mIsInFocus = FALSE;
+
+               if ( !mDragStarted )
+                       ReleaseMouse();
+       }
+
+       if ( mDragStarted )
+       {
+               if ( IsInWindow( event.m_x, event.m_y ) )
+
+                       mIsPressed = TRUE;
+               else
+                       mIsPressed = FALSE;
+       }
+
+       if ((mIsPressed != mPrevPressedState) ||
+        (mIsInFocus!=mPrevInFocusState))
+    {
+               Refresh();
+       }
+}
+
+void wxNewBitmapButton::OnSize( wxSizeEvent& event )
+{
+               //Reshape();
+}
+
+void wxNewBitmapButton::Reshape( )
+{
+       
+       bool wasCreated = mIsCreated;
+       mIsCreated = TRUE;
+
+       if ( !wasCreated )
+       {
+               // in the case of loading button from stream, check if we
+               // have non-empty image-file name, load if possible 
+
+               if ( mImageFileName != "" )
+               {
+                       mDepressedBmp.LoadFile( mImageFileName, mImageFileType );
+
+                       //wxMessageBox("Image Loaded!!!");
+               }
+
+               //RenderLabelImages();
+               RenderAllLabelImages();
+
+               wxBitmap* pCurImg = GetStateLabel();
+
+               int w = pCurImg->GetWidth(),
+                       h = pCurImg->GetHeight();
+
+               SetSize( 0,0, w + mMarginX*2, h + mMarginY*2 , 0 );
+       }
+}
+
+void wxNewBitmapButton::DrawLabel( wxDC& dc )
+{
+       wxBitmap* pCurBmp = GetStateLabel();
+
+       if ( pCurBmp == NULL )
+       {
+               wxSizeEvent evt;
+               OnSize( evt ); // fake it up!
+
+               //RenderLabelImages();
+               pCurBmp = GetStateLabel();
+       }
+
+       wxMemoryDC mdc;
+       mdc.SelectObject( *pCurBmp );
+
+       dc.Blit( mMarginX, mMarginY, 
+                        pCurBmp->GetWidth(),
+                        pCurBmp->GetHeight(),
+                        &mdc, 0,0, wxCOPY 
+                  );
+
+       mdc.SelectObject( wxNullBitmap );
+}
+
+void wxNewBitmapButton::OnPaint( wxPaintEvent& event )
+{
+       wxPaintDC dc(this);
+
+       // first, make sure images for current state are prepared
+       //RenderLabelImages();
+
+       DrawLabel( dc );
+
+       DrawDecorations( dc );
+}
+
+void wxNewBitmapButton::OnEraseBackground( wxEraseEvent& event )
+{
+       // do nothing
+}
+
+void wxNewBitmapButton::OnKillFocus( wxFocusEvent& event )
+{
+       // useless
+
+       wxMessageBox("kill-focus for button!");
+}
+
diff --git a/contrib/src/fl/panedrawpl.cpp b/contrib/src/fl/panedrawpl.cpp
new file mode 100644 (file)
index 0000000..8a20e05
--- /dev/null
@@ -0,0 +1,1273 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "panedrawpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "wx/utils.h"     // import wxMin,wxMax macros
+
+#include "wx/fl/panedrawpl.h"
+
+// bitmap bits used by bar-resizing brush
+
+#define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
+#define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
+#define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.
+#define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.
+
+static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D
+                                                                                         };
+
+// FIXME:: The below code somehow doesn't work - cursors remain unchanged
+// Used: controlbar.cpp(1268): set_cursor_bits( _gHorizCursorImg, bits, 32, 16 );
+// Used: controlbar.cpp(1272): set_cursor_bits( _gVertCursorImg, bits, 32, 16 );
+/*
+static void set_cursor_bits( const char** img, char* bits, int width, int height )
+{
+       for( int i = 0; i != (width*height)/8; ++i )
+               bits[i] = 0;
+
+       for( int y = 0; y != height; ++y )
+       {
+               const char* row = img[0];
+
+               for( int x = 0; x != width; ++x )
+               {
+                       int bitNo = y*width + x;
+
+                       char value = ( row[x] != '.' ) ? 1 : 0;
+
+                       bits[ bitNo / sizeof(char) ] |= 
+                               ( ( bitNo %sizeof(char) ) << value );
+               }
+
+               ++img;
+       }
+}
+*/
+
+/***** Implementation for class cbPaneDrawPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbPaneDrawPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbPaneDrawPlugin, cbPluginBase )
+
+       EVT_PL_LEFT_DOWN                   ( cbPaneDrawPlugin::OnLButtonDown         )
+       EVT_PL_LEFT_UP                     ( cbPaneDrawPlugin::OnLButtonUp                 )
+//     EVT_PL_LEFT_DCLICK                 ( cbPaneDrawPlugin::OnLDblClick                 )
+       EVT_PL_RIGHT_UP                    ( cbPaneDrawPlugin::OnRButtonUp                 )
+       EVT_PL_MOTION                      ( cbPaneDrawPlugin::OnMouseMove                 )
+
+
+       EVT_PL_DRAW_PANE_BKGROUND  ( cbPaneDrawPlugin::OnDrawPaneBackground  )
+       EVT_PL_DRAW_PANE_DECOR     ( cbPaneDrawPlugin::OnDrawPaneDecorations )
+
+       EVT_PL_DRAW_ROW_DECOR      ( cbPaneDrawPlugin::OnDrawRowDecorations  )
+       EVT_PL_DRAW_ROW_HANDLES    ( cbPaneDrawPlugin::OnDrawRowHandles      )
+       EVT_PL_DRAW_ROW_BKGROUND   ( cbPaneDrawPlugin::OnDrawRowBackground   )
+
+       EVT_PL_SIZE_BAR_WND                ( cbPaneDrawPlugin::OnSizeBarWindow       )
+       EVT_PL_DRAW_BAR_DECOR      ( cbPaneDrawPlugin::OnDrawBarDecorations  )
+       EVT_PL_DRAW_BAR_HANDLES    ( cbPaneDrawPlugin::OnDrawBarHandles      )
+
+       EVT_PL_START_DRAW_IN_AREA  ( cbPaneDrawPlugin::OnStartDrawInArea     )
+       EVT_PL_FINISH_DRAW_IN_AREA ( cbPaneDrawPlugin::OnFinishDrawInArea    )
+
+END_EVENT_TABLE()
+
+cbPaneDrawPlugin::cbPaneDrawPlugin(void)
+
+       : mResizeStarted          ( FALSE ),
+
+         mResizeCursorOn         ( FALSE ),
+         mpDraggedBar                    ( NULL  ),
+         mpResizedRow            ( NULL  ),
+
+      mRowHandleHitted        ( FALSE ),
+         mIsUpperHandle          ( FALSE ),
+         mBarHandleHitted        ( FALSE ),
+         mIsLeftHandle           ( FALSE ),
+         mBarContentHitted       ( FALSE ),
+
+         mpClntDc ( NULL ),
+         mpPane   ( NULL )
+{}
+
+cbPaneDrawPlugin::cbPaneDrawPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask ),
+       
+         // bar-row resizing state varaibles
+
+         mResizeStarted          ( FALSE ),
+
+         mResizeCursorOn         ( FALSE ),
+         mpDraggedBar                    ( NULL ),
+         mpResizedRow            ( NULL ),
+
+         mRowHandleHitted        ( FALSE ),
+         mIsUpperHandle          ( FALSE ),
+         mBarHandleHitted        ( FALSE ),
+         mIsLeftHandle           ( FALSE ),
+         mBarContentHitted       ( FALSE ),
+
+         mpClntDc ( NULL ),
+         mpPane   ( NULL )
+{}
+
+cbPaneDrawPlugin::~cbPaneDrawPlugin()
+{
+       // DBG::
+       wxASSERT( mpClntDc == NULL );
+}
+
+void cbPaneDrawPlugin::DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane )
+{
+       wxScreenDC dc;
+       int ofsX = 0;
+       int ofsY = 0;
+
+       wxPoint fpos = pos;
+       pane.PaneToFrame( &fpos.x, &fpos.y );
+
+       // short-cut
+       int resizeHndSize = pane.mProps.mResizeHandleSize;
+
+    // "Required for X to specify that
+    // that we wish to draw on top of all windows
+    // - and we optimise by specifying the area
+    // for creating the overlap window." --J.S.
+
+       wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
+
+       mpLayout->GetParentFrame().ClientToScreen( &ofsX, &ofsY );
+
+       int prevLF = dc.GetLogicalFunction();
+
+       // BUG BUG BUG (wx):: somehow stippled brush works only  
+       //                                        when the bitmap created on stack, not
+       //                                        as a member of the class
+
+       wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
+
+       wxBrush checkerBrush( checker );
+
+       dc.SetPen( mpLayout->mNullPen );
+       dc.SetBrush( checkerBrush );
+       dc.SetLogicalFunction( wxXOR );
+
+       if ( mHandleIsVertical )
+       {
+               int delta = pos.x - mDragOrigin.x;
+
+               if ( !pane.IsHorizontal() )
+
+                       delta = pos.y - mDragOrigin.y;
+
+               int realHndOfs;
+               realHndOfs = pane.mBoundsInParent.x + pane.mLeftMargin + mHandleOfs;
+
+               int newX = realHndOfs + delta;
+
+               if ( newX + resizeHndSize > mHandleDragArea.x + mHandleDragArea.width )
+
+                       newX = mHandleDragArea.x + mHandleDragArea.width  - 1;
+
+               if ( newX < mHandleDragArea.x ) 
+
+                       newX = mHandleDragArea.x;
+
+               mDraggedDelta = newX - realHndOfs;
+
+               dc.DrawRectangle( newX + ofsX, mHandleDragArea.y + ofsY,
+                                     resizeHndSize + 1,
+                                                 mHandleDragArea.height+1 );
+       }
+       else
+       {
+               // otherwise, draw horizontal handle
+
+               int delta = pos.y - mDragOrigin.y;
+
+               if ( !pane.IsHorizontal() )
+
+                       delta = pos.x - mDragOrigin.x;
+
+               int realHndOfs;
+               realHndOfs = pane.mBoundsInParent.y + pane.mTopMargin + mHandleOfs;
+
+               int newY = realHndOfs + delta;
+
+               if ( newY + resizeHndSize > mHandleDragArea.y + mHandleDragArea.height )
+
+                       newY = mHandleDragArea.y + mHandleDragArea.height - 1;
+
+               if ( newY < mHandleDragArea.y ) 
+
+                       newY = mHandleDragArea.y;
+
+               mDraggedDelta = newY - realHndOfs;
+
+               dc.DrawRectangle( mHandleDragArea.x + ofsX, newY + ofsY,
+                                     mHandleDragArea.width + 1,
+                                                 resizeHndSize + 1 );
+       }
+
+       dc.SetLogicalFunction( prevLF );
+
+    // "End drawing on top (frees the window used for drawing
+    // over the screen)" --J.S.
+       wxScreenDC::EndDrawingOnTop();
+}
+
+void cbPaneDrawPlugin::OnMouseMove( cbMotionEvent& event ) 
+{
+       if ( !mResizeStarted )
+       {
+               // if nothing is started, do hit-tests
+
+               bool prevWasRowHandle = mRowHandleHitted;
+
+               mBarContentHitted = FALSE;
+               mBarHandleHitted  = FALSE;
+               mRowHandleHitted  = FALSE;
+
+               int testResult =  
+                       event.mpPane->HitTestPaneItems( event.mPos,         // in pane's coordiantes
+                                                                                   &mpResizedRow,
+                                                                                   &mpDraggedBar );
+
+               if ( testResult != CB_NO_ITEMS_HITTED )
+               {
+                       if ( testResult == CB_BAR_CONTENT_HITTED )
+                       {
+                               // restore cursor, if non of the handles were hit
+                               if ( mResizeCursorOn )
+                               {
+                                       // remove resizing hints
+
+                                       mpLayout->ReleaseEventsFromPane( event.mpPane );
+                                       mpLayout->ReleaseEventsFromPlugin( this );
+       
+                                       mResizeCursorOn = FALSE;
+
+                                       mBarContentHitted = TRUE;
+
+                                       mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
+                               }
+
+                               // TBD:: fire something like "mouse-over-bar" event
+
+                               event.Skip(); // pass event to the next handler in the chain
+                               return;
+                       }
+
+                       wxCursor* pCurs = NULL;
+
+                       if ( testResult == CB_UPPER_ROW_HANDLE_HITTED ||
+                                testResult == CB_LOWER_ROW_HANDLE_HITTED)
+                       {
+                               if ( event.mpPane->IsHorizontal() )
+
+                                       pCurs = mpLayout->mpVertCursor;
+                               else
+                                       pCurs = mpLayout->mpHorizCursor;
+
+                               mRowHandleHitted = TRUE;
+                               mIsUpperHandle    = ( testResult == CB_UPPER_ROW_HANDLE_HITTED );
+                       }
+                       else
+                       {
+                               // otherwise, if inter-bar handle was hitted
+
+                               if ( event.mpPane->IsHorizontal() )
+
+                                       pCurs = mpLayout->mpHorizCursor;
+                               else
+                                       pCurs = mpLayout->mpVertCursor;
+
+                               mBarHandleHitted = TRUE;
+                               mIsLeftHandle    = ( testResult == CB_LEFT_BAR_HANDLE_HITTED );
+                       }
+
+                       // avoid setting the same cursor twice
+
+                       if ( !mResizeCursorOn || prevWasRowHandle != mRowHandleHitted )
+                       {
+                               if ( !mResizeCursorOn )
+                               {
+                                       // caputre if not captured yet
+                                       mpLayout->CaptureEventsForPane( event.mpPane );
+                                       mpLayout->CaptureEventsForPlugin( this );
+                               }
+
+                               mpLayout->GetParentFrame().SetCursor( *pCurs );
+                       }
+
+                       mResizeCursorOn = TRUE;
+
+                       // handled is being dragged now, thus event is "eaten" by this plugin
+
+                       return;
+
+               } // end of if (HitTestBarHandles())
+
+               // restore cursor, if non of the handles were hit
+               if ( mResizeCursorOn )
+               {
+                       mpLayout->ReleaseEventsFromPane( event.mpPane );
+                       mpLayout->ReleaseEventsFromPlugin( this );
+
+                       mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
+
+                       mResizeCursorOn = FALSE;
+               }
+
+               event.Skip(); // pass event to the next plugin
+       }
+
+       // othewise series of actions, if something has already started
+
+       else
+       if ( mResizeStarted )
+       {
+               // apply xor-mask twice 
+               DrawDraggedHandle( mPrevPos,   *event.mpPane );
+
+               // draw handle in the new position
+               DrawDraggedHandle( event.mPos, *event.mpPane );
+               mPrevPos = event.mPos;
+
+               // handled is dragged, thus event is "eaten" by this plugin
+       }
+       else
+               event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnLDblClick( cbLeftDClickEvent& event )
+{
+       if ( !mResizeCursorOn )
+       {
+               cbBarInfo* pBarToFloat;
+
+               if ( event.mpPane->HitTestPaneItems( event.mPos,          // in pane's coordiantes
+                                                                                    &mpResizedRow,
+                                                                                        &pBarToFloat ) == CB_BAR_CONTENT_HITTED
+                  )
+                       {
+                               // TBD: ????
+                               return;
+
+                               mpLayout->SetBarState( pBarToFloat, wxCBAR_FLOATING, TRUE );
+
+                               mpLayout->RepositionFloatedBar( pBarToFloat );
+
+                               return; // event is "eaten" by this plugin
+                       }
+
+               event.Skip();
+       }
+}
+
+void cbPaneDrawPlugin::OnLButtonDown( cbLeftDownEvent& event ) 
+{
+       wxASSERT( !mResizeStarted );
+
+       if ( mResizeCursorOn )
+       {
+               mResizeStarted = TRUE;
+               mDragOrigin    = event.mPos;
+               
+               // setup constraints for the dragging handle
+
+               int from, till;
+               mHandleOfs        = 0;
+               mHandleIsVertical = FALSE;
+
+               if ( mRowHandleHitted )
+
+                       event.mpPane->GetRowResizeRange( mpResizedRow, &from, &till, mIsUpperHandle );
+               else
+                       // otherwise if bar handle was hitted
+                       event.mpPane->GetBarResizeRange( mpDraggedBar, &from, &till, mIsLeftHandle );
+                
+               if ( mRowHandleHitted )
+               {
+                       mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? FALSE : TRUE;
+
+                       mHandleDragArea.x      = 0;
+                       mHandleDragArea.width  = event.mpPane->mPaneWidth;
+
+                       mHandleDragArea.y      = from;
+                       mHandleDragArea.height = till - from;
+
+                       if ( mIsUpperHandle )
+
+                               mHandleOfs = mpResizedRow->mRowY;
+                       else
+                               mHandleOfs = mpResizedRow->mRowY + 
+                                            mpResizedRow->mRowHeight -
+                                                        event.mpPane->mProps.mResizeHandleSize;
+               }
+               else
+               {
+                       // otehrwise if bar handle dragged
+
+                       cbRowInfo& rowInfo     = *mpDraggedBar->mpRow;
+                       wxRect& bounds         = mpDraggedBar->mBounds;
+
+                       mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? TRUE : FALSE;
+
+                       mHandleDragArea.x      = from;
+                       mHandleDragArea.width  = till - from;
+
+
+                       mHandleDragArea.y      = bounds.y;
+                       mHandleDragArea.height = bounds.height;
+
+                       // left-side-handle mBounds
+                       if ( mIsLeftHandle )
+
+                               mHandleOfs = bounds.x;
+                       else
+                               mHandleOfs = bounds.x + 
+                                                        bounds.width - event.mpPane->mProps.mResizeHandleSize;
+
+               }
+
+               event.mpPane->PaneToFrame( &mHandleDragArea );
+               DrawDraggedHandle(mDragOrigin, *event.mpPane);
+
+               mPrevPos = mDragOrigin;
+
+               return;
+               // handled is dragged, thus event is "eaten" by this plugin
+       }
+       else
+       {
+               cbBarInfo* pDraggedBar;
+
+               if ( event.mpPane->HitTestPaneItems( event.mPos,          // in pane's coordiantes
+                                                                                    &mpResizedRow,
+                                                                                        &pDraggedBar ) == CB_BAR_CONTENT_HITTED 
+                  )
+               {
+                       int x = event.mPos.x,
+                           y = event.mPos.y;
+
+                       event.mpPane->PaneToFrame( &x, &y );
+
+                       cbStartBarDraggingEvent dragEvt( pDraggedBar, wxPoint(x,y), event.mpPane );
+
+                       mpLayout->FirePluginEvent( dragEvt );
+
+                       return; // event is "eaten" by this plugin
+               }
+       }
+
+       event.Skip(); // pass event to the next plugin in the chain
+}
+
+void cbPaneDrawPlugin::OnLButtonUp( cbLeftUpEvent& event ) 
+{
+       if ( mResizeStarted )
+       {
+               DrawDraggedHandle( event.mPos, *event.mpPane );
+
+               mResizeStarted  = FALSE;
+               mResizeCursorOn = FALSE;
+
+               mpLayout->ReleaseEventsFromPane( event.mpPane );
+               mpLayout->ReleaseEventsFromPlugin( this );
+
+               mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor );
+
+               if ( mRowHandleHitted )
+               {
+                       event.mpPane->ResizeRow( mpResizedRow, 
+                                                                        mDraggedDelta,
+                                                                        mIsUpperHandle );
+               }
+               else
+               {
+                       event.mpPane->ResizeBar( mpDraggedBar, 
+                                                                    mDraggedDelta,
+                                                                        mIsLeftHandle );
+               }
+
+               mpDraggedBar = NULL;
+               mpResizedRow = NULL;
+
+               // handled dragging action was finished by this mouse-up, 
+               // thus event is "eaten" by this plugin
+
+               return;
+       }
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnRButtonUp( cbRightUpEvent&   event )
+{
+       wxPoint fpos = event.mPos;
+       event.mpPane->PaneToFrame( &fpos.x, &fpos.y );
+
+       cbBarInfo* pDraggedBar;
+
+       // user clicks inside the bar contnet, fire bar-customization event
+
+       if ( event.mpPane->HitTestPaneItems( event.mPos,          // in pane's coordiantes
+                                                                                &mpResizedRow,
+                                                                                &pDraggedBar  ) == CB_BAR_CONTENT_HITTED
+          )
+       {
+               cbCustomizeBarEvent cbEvt( pDraggedBar, fpos, event.mpPane );
+
+               mpLayout->FirePluginEvent( cbEvt );
+
+               return; // event is "eaten" by this plugin
+       }
+
+       // otherwise fire whole-layout customization event
+
+       cbCustomizeLayoutEvent csEvt( fpos );
+
+       mpLayout->FirePluginEvent( csEvt );
+
+       // event is "eaten" by this plugin
+}
+
+void cbPaneDrawPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event ) 
+{
+       cbBarInfo& bar = *event.mpBar;
+       mpPane         = event.mpPane;
+
+       // it's possible that a bar does not have it's own window!
+       if ( !bar.mpBarWnd ) return;
+
+       wxRect& bounds = event.mBoundsInParent;
+
+       // check visibility
+       if ( bounds.height != 0 )
+       {
+               // size smaller than bounds, to leave space for shade lines
+
+               // FIXME:: +/- 1s
+
+               bar.mpBarWnd->wxWindow::SetSize( bounds.x      + 1 + bar.mDimInfo.mHorizGap,     
+                                                                                bounds.y      + 1 + bar.mDimInfo.mVertGap,
+                                                                                bounds.width  - 2 - bar.mDimInfo.mHorizGap*2,
+                                                                                bounds.height - 2 - bar.mDimInfo.mVertGap *2 , 
+                                                                                0 
+                                                                          );
+
+               if ( !bar.mpBarWnd->IsShown() )
+
+                       bar.mpBarWnd->Show( TRUE );
+       }
+       else
+               // hide bar if not visible
+               bar.mpBarWnd->Show( FALSE );
+
+       event.Skip(); // pass event to the next plugin in the chain
+}
+
+void cbPaneDrawPlugin::OnDrawRowDecorations( cbDrawRowDecorEvent& event )
+{
+       DrawPaneShadeForRow( event.mpRow, *event.mpDc );
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::DrawUpperRowHandle( cbRowInfo* pRow, wxDC& dc )
+{
+       wxRect& bounds = pRow->mBoundsInParent;
+
+       if ( mpPane->IsHorizontal() )
+       {
+                if ( pRow->mHasUpperHandle )
+               
+                       mpPane->DrawHorizHandle( dc, bounds.x, 
+                                                                        bounds.y-1, 
+                                                                        pRow->mRowWidth );
+       }
+       else
+       {
+               if ( pRow->mHasUpperHandle )
+
+                       mpPane->DrawVertHandle( dc, bounds.x-1, 
+                                                                       bounds.y, pRow->mRowWidth );
+       }
+}
+
+void cbPaneDrawPlugin::DrawLowerRowHandle( cbRowInfo* pRow, wxDC& dc )
+{
+       wxRect& bounds = pRow->mBoundsInParent;
+
+       // check if iter-row handles present
+
+       if ( mpPane->IsHorizontal() )
+       {
+               if ( pRow->mHasLowerHandle )
+               
+                       mpPane->DrawHorizHandle( dc, bounds.x, bounds.y + bounds.height - mpPane->mProps.mResizeHandleSize - 1, 
+                                                                        pRow->mRowWidth );
+       }
+       else
+       {
+               if ( pRow->mHasLowerHandle )
+
+                       mpPane->DrawVertHandle( dc, bounds.x + bounds.width - mpPane->mProps.mResizeHandleSize - 1, 
+                                                                       bounds.y, pRow->mRowWidth );
+       }
+}
+
+void cbPaneDrawPlugin::OnDrawRowHandles( cbDrawRowHandlesEvent& event )
+{
+       // short-cuts
+       cbRowInfo* pRow = event.mpRow;
+       wxDC&   dc      = *event.mpDc;
+       mpPane          = event.mpPane;
+
+       // draw handles of surrounding rows first
+
+       if ( pRow->mpPrev && pRow->mpPrev->mHasLowerHandle )
+
+                       DrawLowerRowHandle( pRow->mpPrev, dc );
+
+       if ( pRow->mpNext && pRow->mpNext->mHasUpperHandle )
+
+               DrawUpperRowHandle( pRow->mpNext, dc );
+
+       // draw handles of the given row
+
+       if ( pRow->mHasUpperHandle )
+       
+               DrawUpperRowHandle( pRow, dc );
+
+       if ( pRow->mHasLowerHandle )
+
+               DrawLowerRowHandle( pRow, dc );
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnDrawPaneBackground ( cbDrawPaneBkGroundEvent& event )
+{
+       wxDC& dc = *event.mpDc;
+       mpPane   = event.mpPane;
+
+       // FOR NOW:: hard-coded
+       wxBrush bkBrush( mpLayout->mBorderPen.GetColour(), wxSOLID );
+
+       dc.SetBrush( bkBrush );
+       dc.SetPen( mpLayout->mNullPen );
+
+       wxRect& bounds = mpPane->mBoundsInParent;
+
+       if ( mpPane->mTopMargin >= 1 )
+       
+               dc.DrawRectangle( bounds.x, bounds.y,
+                                                 bounds.width+1,
+                                                 mpPane->mTopMargin + 1);
+
+
+       if ( mpPane->mBottomMargin >= 1 )
+       
+               dc.DrawRectangle( bounds.x, 
+                                                 bounds.y + bounds.height - mpPane->mBottomMargin,
+                                                 bounds.width + 1,
+                                                 mpPane->mBottomMargin + 1);
+
+
+       if ( mpPane->mLeftMargin >= 1 )
+       
+               dc.DrawRectangle( bounds.x, 
+                                                 bounds.y + mpPane->mTopMargin - 1,
+                                                 mpPane->mLeftMargin + 1,
+                                                 bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2);
+
+
+       if ( mpPane->mRightMargin >= 1 )
+       
+               dc.DrawRectangle( bounds.x + bounds.width - mpPane->mRightMargin,
+                                                 bounds.y + mpPane->mTopMargin - 1,
+                                                 mpPane->mRightMargin + 1,
+                                                 bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2);
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnDrawRowBackground ( cbDrawRowBkGroundEvent& event )
+{
+       // short-cuts
+       cbRowInfo* pRow = event.mpRow;
+       wxDC&   dc      = *event.mpDc;
+       mpPane          = event.mpPane;
+
+       // get ready
+       wxRect     rowBounds    = pRow->mBoundsInParent;
+       bool       isHorizontal = event.mpPane->IsHorizontal();
+       
+       int prevPos;
+
+       if ( isHorizontal )
+       {
+               prevPos = rowBounds.x;
+               // include one line obove and below the row
+               --rowBounds.y;
+               rowBounds.height +=2;
+
+               --rowBounds.x;
+               rowBounds.width += 2;
+       }
+       else
+       {
+               prevPos = rowBounds.y;
+               // include one line obove and below the row
+               --rowBounds.x;
+               rowBounds.width += 2;
+
+               --rowBounds.y;
+               rowBounds.height +=2;
+       }
+
+//#define TEST_BK_ERASING
+
+#ifdef TEST_BK_ERASING
+
+       // DBG::
+       wxBrush br0( wxColour(0,160,160), wxSOLID );
+       dc.SetBrush(br0);
+       dc.SetPen  ( mpLayout->mNullPen );
+       dc.DrawRectangle( rowBounds.x, rowBounds.y,
+                                 rowBounds.width  + 1, 
+                                         rowBounds.height + 1  );
+#endif
+
+       wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID );
+
+       dc.SetPen  ( mpLayout->mNullPen );
+       dc.SetBrush( bkBrush );
+
+       // fill background-recatangle of entire row area
+       dc.DrawRectangle( rowBounds.x, rowBounds.y,
+                                 rowBounds.width  + 1, 
+                                         rowBounds.height + 1  );
+
+       dc.SetBrush( wxNullBrush );
+
+       // draw "shaded-side-bars" for each bar
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
+
+               if ( isHorizontal )
+               {
+                       DrawShade( 1, bounds, FL_ALIGN_LEFT, dc );
+                       DrawShade( 1, bounds, FL_ALIGN_RIGHT, dc );
+               }
+               else
+               {
+                       DrawShade( 1, bounds, FL_ALIGN_TOP, dc );
+                       DrawShade( 1, bounds, FL_ALIGN_BOTTOM, dc );
+               }
+       }
+
+       // draw extra shades to simulate "glued-bricks" effect
+
+       // TBD:: reduce exessive drawing of shades, when the
+       //       row handle is present, and shades will be overr-drawn anyway
+
+       DrawUpperRowShades( pRow, dc, 1 ); // outer shade
+
+       if ( pRow->mpPrev )
+       {
+               DrawLowerRowShades( pRow->mpPrev, dc, 1 ); // outter shade
+               DrawLowerRowShades( pRow->mpPrev, dc, 0 ); // inner shade
+       }
+
+       DrawLowerRowShades( pRow, dc, 1 );
+
+       if ( pRow->mpNext )
+       {
+               DrawUpperRowShades( pRow->mpNext, dc, 1 ); 
+               DrawUpperRowShades( pRow->mpNext, dc, 0 );
+       }
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::DrawUpperRowShades( cbRowInfo* pRow, wxDC& dc, int level )
+{
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
+
+               if ( mpPane->IsHorizontal() )
+               {               
+                       DrawShade( level, bounds, FL_ALIGN_TOP, dc );
+                       if ( level == 1 )
+                       {
+                               dc.SetPen( mpLayout->mDarkPen );
+                               dc.DrawPoint( bounds.x - 1, bounds.y );
+                               dc.SetPen( mpLayout->mLightPen );
+                               dc.DrawPoint( bounds.x + bounds.width , bounds.y );
+                       }
+               }
+               else
+               {
+                       DrawShade( level, bounds, FL_ALIGN_LEFT, dc );
+                       if ( level == 1 )
+                       {
+                               dc.SetPen( mpLayout->mDarkPen );
+                               dc.DrawPoint( bounds.x, bounds.y -1 );
+                               dc.SetPen( mpLayout->mLightPen );
+                               dc.DrawPoint( bounds.x, bounds.y + bounds.height );
+                       }
+               }
+       }
+}
+
+void cbPaneDrawPlugin::DrawLowerRowShades( cbRowInfo* pRow, wxDC& dc, int level )
+{
+       for( size_t i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               wxRect& bounds = pRow->mBars[i]->mBoundsInParent;
+
+               if ( mpPane->IsHorizontal() )
+               {
+                       DrawShade( level, bounds, FL_ALIGN_BOTTOM, dc );
+                       if ( level == 1 )
+                       {
+                               dc.SetPen( mpLayout->mDarkPen );
+                               dc.DrawPoint( bounds.x - 1, bounds.y + bounds.height -1 );
+                               dc.SetPen( mpLayout->mLightPen );
+                               dc.DrawPoint( bounds.x + bounds.width , bounds.y + bounds.height -1 );
+                       }
+               }
+               else
+               {
+                       DrawShade( level, bounds, FL_ALIGN_RIGHT, dc );
+                       if ( level == 1 )
+                       {
+                               dc.SetPen( mpLayout->mDarkPen );
+                               dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y -1 );
+                               dc.SetPen( mpLayout->mLightPen );
+                               dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y + bounds.height );
+                       }
+               }
+       }
+}
+
+void cbPaneDrawPlugin::DrawBarInnerShadeRect( cbBarInfo* pBar, wxDC& dc )
+{
+       wxRect& bounds = pBar->mBoundsInParent;
+
+       dc.SetPen( mpLayout->mDarkPen );
+       
+       dc.DrawLine( bounds.x + bounds.width - 1,
+                        bounds.y,
+                                bounds.x + bounds.width - 1,
+                                bounds.y + bounds.height );
+
+       dc.DrawLine( bounds.x,
+                                bounds.y + bounds.height - 1,
+                                bounds.x + bounds.width,
+                                bounds.y + bounds.height -1  );
+
+       dc.SetPen( mpLayout->mLightPen );
+
+       dc.DrawLine( bounds.x,
+                                bounds.y,
+                                bounds.x + bounds.width - 1,
+                                bounds.y );
+
+       dc.DrawLine( bounds.x,
+                        bounds.y,
+                                bounds.x,
+                                bounds.y + bounds.height - 1 );
+}
+
+void cbPaneDrawPlugin::DrawShade( int level, wxRect& rect, int alignment, wxDC& dc )
+{
+       // simulates "guled-bricks" appearence of control bars
+
+       if ( ( alignment == FL_ALIGN_TOP    && level == 1 ) ||
+                ( alignment == FL_ALIGN_BOTTOM && level == 0 ) ||
+                ( alignment == FL_ALIGN_LEFT   && level == 1 ) ||
+                ( alignment == FL_ALIGN_RIGHT  && level == 0 )
+          )
+       
+               dc.SetPen( mpLayout->mDarkPen  );
+       else
+               dc.SetPen( mpLayout->mLightPen );
+
+       if ( alignment == FL_ALIGN_TOP )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y,
+                                    rect.x + rect.width - 1,
+                                                rect.y );
+               else
+                       dc.DrawLine( rect.x - 1,
+                                    rect.y - 1,
+                                                rect.x + rect.width + 0,
+                                                rect.y - 1 );
+       }
+       else
+       if ( alignment == FL_ALIGN_BOTTOM )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y + rect.height - 1,
+                                    rect.x + rect.width,
+                                                rect.y + rect.height - 1 );
+               else
+                       dc.DrawLine( rect.x - 1,
+                                    rect.y + rect.height,
+                                                rect.x + rect.width + 1,
+                                                rect.y + rect.height );
+       }
+       else
+       if ( alignment == FL_ALIGN_LEFT )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y,
+                                    rect.x,
+                                                rect.y + rect.height - 1 );
+               else
+                       dc.DrawLine( rect.x - 1,
+                                    rect.y - 1,
+                                                rect.x - 1,
+                                                rect.y + rect.height );
+       }
+       else
+       if ( alignment == FL_ALIGN_RIGHT )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x + rect.width - 1, 
+                                                rect.y,
+                                    rect.x + rect.width - 1,
+                                                rect.y + rect.height );
+               else
+               {                                        
+                       dc.DrawLine( rect.x + rect.width,
+                                    rect.y - 1,
+                                                rect.x + rect.width,
+                                                rect.y + rect.height + 1  );
+               }
+       }
+}
+
+void cbPaneDrawPlugin::DrawShade1( int level, wxRect& rect, int alignment, wxDC& dc )
+{
+       // simulates "guled-bricks" appearence of control bars
+
+       if ( ( alignment == FL_ALIGN_TOP    && level == 1 ) ||
+                ( alignment == FL_ALIGN_BOTTOM && level == 0 ) ||
+                ( alignment == FL_ALIGN_LEFT   && level == 1 ) ||
+                ( alignment == FL_ALIGN_RIGHT  && level == 0 )
+          )
+       
+               dc.SetPen( mpLayout->mDarkPen  );
+       else
+               dc.SetPen( mpLayout->mLightPen );
+
+       if ( alignment == FL_ALIGN_TOP )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y,
+                                    rect.x + rect.width,
+                                                rect.y );
+               else
+                       dc.DrawLine( rect.x,
+                                    rect.y - 1,
+                                                rect.x + rect.width,
+                                                rect.y - 1 );
+       }
+       else
+       if ( alignment == FL_ALIGN_BOTTOM )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y + rect.height - 1,
+                                    rect.x + rect.width,
+                                                rect.y + rect.height - 1 );
+               else
+                       dc.DrawLine( rect.x,
+                                    rect.y + rect.height,
+                                                rect.x + rect.width,
+                                                rect.y + rect.height );
+       }
+       else
+       if ( alignment == FL_ALIGN_LEFT )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x, 
+                                                rect.y,
+                                    rect.x,
+                                                rect.y + rect.height );
+               else
+                       dc.DrawLine( rect.x - 1,
+                                    rect.y,
+                                                rect.x - 1,
+                                                rect.y + rect.height );
+       }
+       else
+       if ( alignment == FL_ALIGN_RIGHT )
+       {
+               if ( level == 0 )
+               
+                       dc.DrawLine( rect.x + rect.width - 1, 
+                                                rect.y,
+                                    rect.x + rect.width - 1,
+                                                rect.y + rect.height );
+               else
+               {                                        
+                       dc.DrawLine( rect.x + rect.width,
+                                    rect.y ,
+                                                rect.x + rect.width,
+                                                rect.y + rect.height );
+               }
+       }
+}
+
+void cbPaneDrawPlugin::DrawPaneShade( wxDC& dc, int alignment )
+{
+       if ( !mpPane->mProps.mShow3DPaneBorderOn ) return;
+
+       wxRect bounds = mpPane->mBoundsInParent;
+
+       bounds.x      += mpPane->mLeftMargin;
+       bounds.y      += mpPane->mTopMargin;
+       bounds.width  -= ( mpPane->mLeftMargin + mpPane->mRightMargin  );
+       bounds.height -= ( mpPane->mTopMargin  + mpPane->mBottomMargin );
+
+       DrawShade( 0, bounds, alignment, dc );
+       DrawShade( 1, bounds, alignment, dc );
+}
+
+void cbPaneDrawPlugin::DrawPaneShadeForRow( cbRowInfo* pRow, wxDC& dc )
+{
+       if ( !mpPane->mProps.mShow3DPaneBorderOn ) return;
+
+       // do not draw decoration, if pane has "vainished"
+       if ( mpPane->mPaneWidth  < 0 ||
+                mpPane->mPaneHeight < 0 )
+
+                return;
+
+       wxRect bounds = pRow->mBoundsInParent;
+
+       if ( mpPane->mAlignment == FL_ALIGN_TOP ||
+                mpPane->mAlignment == FL_ALIGN_BOTTOM )
+       {
+               --bounds.y;
+               bounds.height += 2;
+
+               DrawShade1( 0, bounds, FL_ALIGN_LEFT, dc );
+               DrawShade1( 1, bounds, FL_ALIGN_LEFT, dc );
+               DrawShade1( 0, bounds, FL_ALIGN_RIGHT, dc );
+               DrawShade1( 1, bounds, FL_ALIGN_RIGHT, dc );
+
+               if ( !pRow->mpNext )
+                       DrawPaneShade( dc, FL_ALIGN_BOTTOM );
+
+               if ( !pRow->mpPrev )
+                       DrawPaneShade( dc, FL_ALIGN_TOP );
+       }
+       else
+       {
+               --bounds.x;
+               bounds.width += 2;
+
+               DrawShade1( 0, bounds, FL_ALIGN_TOP, dc );
+               DrawShade1( 1, bounds, FL_ALIGN_TOP, dc );
+               DrawShade1( 0, bounds, FL_ALIGN_BOTTOM, dc );
+               DrawShade1( 1, bounds, FL_ALIGN_BOTTOM, dc );
+
+               if ( !pRow->mpNext )
+                       DrawPaneShade( dc, FL_ALIGN_RIGHT );
+
+               if ( !pRow->mpPrev )
+                       DrawPaneShade( dc, FL_ALIGN_LEFT );
+       }
+}
+
+void cbPaneDrawPlugin::OnDrawPaneDecorations( cbDrawPaneDecorEvent& event )
+{
+       wxDC& dc = *event.mpDc;
+
+       cbDockPane* pPane = event.mpPane;
+
+       RowArrayT& lst = pPane->GetRowList();
+       
+       // FIXME:: this is a workaround for some glitches
+
+       if ( lst.Count() )
+       {
+               cbRowInfo* pLastRow = lst[ lst.Count() - 1 ];
+
+               pPane->PaintRowBackground( pLastRow,  dc );
+               pPane->PaintRowDecorations( pLastRow, dc );
+               pPane->PaintRowHandles( pLastRow, dc );
+       }
+
+       if ( !pPane->mProps.mShow3DPaneBorderOn ) return;
+
+       // do not draw decoration, if pane is completely hidden
+       if ( event.mpPane->mPaneWidth  < 0 ||
+                event.mpPane->mPaneHeight < 0 )
+
+                return;
+
+       DrawPaneShade( dc, FL_ALIGN_TOP    );
+       DrawPaneShade( dc, FL_ALIGN_BOTTOM );
+       DrawPaneShade( dc, FL_ALIGN_LEFT   );
+       DrawPaneShade( dc, FL_ALIGN_RIGHT  );
+
+       event.Skip(); // pass event to the next plugin
+}
+
+// bar decoration/sizing handlers
+
+void cbPaneDrawPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event )
+{
+       cbBarInfo* pBar = event.mpBar;
+       wxDC&   dc      = *event.mpDc;
+
+       // draw brick borders
+
+       wxRect& rect = event.mBoundsInParent;
+
+       dc.SetPen( mpLayout->mLightPen );
+
+       // horiz
+       dc.DrawLine( rect.x, rect.y, 
+                        rect.x + rect.width-1, rect.y );
+
+       // vert
+       dc.DrawLine( rect.x, rect.y,
+                        rect.x, rect.y + rect.height-1 );
+
+
+       dc.SetPen( mpLayout->mDarkPen );
+
+       // vert
+       dc.DrawLine( rect.x + rect.width-1, rect.y,
+                        rect.x + rect.width-1, rect.y + rect.height-1 );
+
+       // horiz
+       dc.DrawLine( rect.x, rect.y + rect.height-1,
+                                rect.x + rect.width, rect.y + rect.height-1 );
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnDrawBarHandles( cbDrawBarHandlesEvent& event )
+{
+       // short-cuts
+       cbBarInfo* pBar = event.mpBar;
+       wxDC&   dc      = *event.mpDc;
+       mpPane          = event.mpPane;
+
+       // draw handles around the bar if present
+
+       if ( pBar->mHasLeftHandle ||
+                pBar->mHasRightHandle )
+       {
+               wxRect& bounds = pBar->mBoundsInParent;
+
+               if ( mpPane->IsHorizontal() )
+               {
+                       if ( pBar->mHasLeftHandle )
+
+                               mpPane->DrawVertHandle( dc, bounds.x - mpPane->mProps.mResizeHandleSize -1, 
+                                                                           bounds.y, bounds.height );
+
+                       if ( pBar->mHasRightHandle )
+
+                               mpPane->DrawVertHandle( dc, 
+                                                                           bounds.x + bounds.width -1, 
+                                                                           bounds.y, bounds.height );
+               }
+               else
+               {
+                       if ( pBar->mHasLeftHandle )
+
+                               mpPane->DrawHorizHandle( dc, bounds.x, 
+                                                                            bounds.y  - mpPane->mProps.mResizeHandleSize - 1, 
+                                                                                bounds.width );
+
+                       if ( pBar->mHasRightHandle )
+
+                               mpPane->DrawHorizHandle( dc, bounds.x, 
+                                                                                bounds.y + bounds.height - 1,
+                                                                                bounds.width );
+               }
+       }
+
+       event.Skip(); // pass event to the next plugin
+}
+
+void cbPaneDrawPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event )
+{
+       // DBG::
+       wxASSERT( mpClntDc == NULL );
+
+       // FOR NOW:: create/destroy client-dc upon each drawing
+       mpClntDc = new wxClientDC( &mpLayout->GetParentFrame() );
+
+       (*event.mppDc) = mpClntDc;
+
+       mpClntDc->SetClippingRegion( event.mArea.x,     event.mArea.y,
+                                        event.mArea.width, event.mArea.height );
+}
+
+void cbPaneDrawPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event )
+{
+       // DBG::
+       wxASSERT( mpClntDc );
+
+       delete mpClntDc;
+
+       mpClntDc = NULL;
+}
+
diff --git a/contrib/src/fl/rowdragpl.cpp b/contrib/src/fl/rowdragpl.cpp
new file mode 100644 (file)
index 0000000..e0ea5ad
--- /dev/null
@@ -0,0 +1,1465 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "rowdragpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/rowdragpl.h"
+
+#define MINIMAL_ROW_DRAG_OFS  5
+
+// parameters for row-hints of NC-look
+
+#define TRIANGLE_OFFSET       2
+#define TRIANGLE_TO_PAT_GAP   2
+#define PAT_OFFSET            2
+#define COLLAPSED_ICON_WIDTH  45
+#define COLLAPSED_ICON_HEIGHT 9
+#define ROW_DRAG_HINT_WIDTH   10
+#define ICON_TRIAN_WIDTH      6
+#define ICON_TRIAN_HEIGHT     3
+
+/***** Implementation for class cbHiddenBarInfo *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo, wxObject )
+
+/***** Implementation for class cbRowDragPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbRowDragPlugin, cbPluginBase )
+
+       EVT_PL_LEFT_DOWN                  ( cbRowDragPlugin::OnLButtonDown        )
+       EVT_PL_LEFT_UP                    ( cbRowDragPlugin::OnLButtonUp          )
+       EVT_PL_MOTION                     ( cbRowDragPlugin::OnMouseMove          )
+
+       EVT_PL_DRAW_PANE_DECOR    ( cbRowDragPlugin::OnDrawPaneBackground )
+
+END_EVENT_TABLE()
+
+// FIXME:: how to eliminated these cut&pasted constructors?
+
+cbRowDragPlugin::cbRowDragPlugin(void)
+
+       : mHightColor          ( 192, 192, 255 ),
+         mLowColor            ( 192, 192, 192 ),
+      mTrianInnerColor     ( 0,0,255 ),
+         mTrianInnerPen       ( mTrianInnerColor, 1, wxSOLID ),
+      mDragStarted         ( FALSE ),
+         mDecisionMode        ( FALSE ),
+         mCurDragOfs          ( 0 ),
+         mCaptureIsOn         ( FALSE ),
+      mSvTopMargin         ( -1 ),
+         mSvBottomMargin      ( -1 ),
+         mSvLeftMargin        ( -1 ),
+         mSvRightMargin       ( -1 ),
+   
+      mpPaneImage          ( NULL ),
+         mpRowImage           ( NULL ),
+         mpCombinedImage          ( NULL ),
+
+         mpRowInFocus         ( NULL ),
+         mCollapsedIconInFocus( -1 ),
+         
+         mpPane               ( NULL )
+{
+}
+
+cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask )
+
+       : cbPluginBase( pLayout, paneMask ),
+         
+         mHightColor          ( 192, 192, 255 ),
+         mLowColor            ( 192, 192, 192 ),
+      mTrianInnerColor     ( 0,0,255 ),
+         mTrianInnerPen       ( mTrianInnerColor, 1, wxSOLID ),
+   
+      mDragStarted         ( FALSE ),
+         mDecisionMode        ( FALSE ),
+         mCurDragOfs          ( 0 ),
+         mCaptureIsOn         ( FALSE ),
+         mSvTopMargin         ( -1 ),
+         mSvBottomMargin      ( -1 ),
+         mSvLeftMargin        ( -1 ),
+         mSvRightMargin       ( -1 ),
+      
+      mpPaneImage          ( NULL ),
+      mpRowImage           ( NULL ),
+         mpCombinedImage          ( NULL ),
+
+         mpRowInFocus         ( NULL ),
+         mCollapsedIconInFocus( -1 ),
+         
+         mpPane               ( NULL )
+{
+}
+
+cbRowDragPlugin::~cbRowDragPlugin()
+{
+}
+
+// handlers for plugin events
+void cbRowDragPlugin::OnMouseMove( cbMotionEvent& event )
+{
+       // short-cuts
+       wxPoint pos = event.mPos;
+       mpPane      = event.mpPane;
+
+       mpPane->PaneToFrame( &pos.x, &pos.y );
+
+       if ( !mDragStarted )
+       {
+               if ( mDecisionMode && mpRowInFocus )
+               {
+                       int ofs;
+
+                       if ( mpPane->IsHorizontal() )
+
+                               ofs = pos.y - mDragOrigin.y;
+                       else
+                               ofs = pos.x - mDragOrigin.x;
+
+                       // check if the item was dragged sufficeintly
+                       // far, enough to consider that user really intends 
+                       // to drag it
+
+                       if ( ofs >= MINIMAL_ROW_DRAG_OFS ||
+                                ofs <= -MINIMAL_ROW_DRAG_OFS )
+                       {
+                               // DBG::
+                               //.wxPoint pos = event.mPos;
+                               //wxPoint drg = mDragOrigin;
+                               //int dif = event.mPos.x - mDragOrigin.x;
+
+                               mDragStarted  = TRUE;
+                               mDecisionMode = FALSE;
+                               mDragOrigin   = pos;
+
+                               PrepareForRowDrag();
+                               return;
+                       }
+
+                       // this plugin "eats" all mouse input while item is dragged,
+                       return;
+               }
+
+               cbRowInfo* pRow = GetFirstRow();
+
+               bool focusFound = FALSE;
+
+               while( pRow )
+               {
+                       if ( HitTestRowDragHint( pRow, pos ) )
+                       {
+                               CheckPrevItemInFocus( pRow, -1 );
+                               SetMouseCapture( TRUE );
+
+                               focusFound = TRUE;
+
+                               mpRowInFocus          = pRow;
+                               mCollapsedIconInFocus = -1;
+                               break;
+                       }
+
+                       pRow = pRow->mpNext;
+               }
+
+               if ( !focusFound )
+               {
+                       int hrCnt = GetHRowsCountForPane( event.mpPane );
+
+                       for( int i = 0; i != hrCnt; ++i )
+                       {
+                               if ( HitTestCollapsedRowIcon( i, pos ) )
+                               {
+                                       CheckPrevItemInFocus( NULL, i );
+                                       SetMouseCapture( TRUE );
+
+                                       focusFound = TRUE;
+
+                                       mCollapsedIconInFocus = i;
+                                       mpRowInFocus          = NULL;
+                                       break;
+                               }
+                       }
+               }
+
+               if ( !focusFound && ItemIsInFocus() )
+               {
+                       // kill focus from item previously been in focus
+                       UnhiglightItemInFocus();
+
+                       mpRowInFocus          = NULL;
+                       mCollapsedIconInFocus = -1;
+                       SetMouseCapture( FALSE );
+               }
+
+               if ( !ItemIsInFocus() ) 
+
+                               // delegate it to other plugins
+                               event.Skip();
+       }
+       else
+       {
+               // otherwise mouse pointer moves, when dragging is started
+
+               if ( mpPane->IsHorizontal() )
+               {
+                       // DBG::
+                       wxPoint p = event.mPos;
+                       wxPoint d = mDragOrigin;
+                       int dif = event.mPos.x - mDragOrigin.x;
+
+                       // row is dragged up or down;
+                       ShowDraggedRow( pos.y - mDragOrigin.y );
+               }
+               else
+               {
+                       // DBG::
+                       wxPoint p = event.mPos;
+                       wxPoint d = mDragOrigin;
+                       int dif = event.mPos.x - mDragOrigin.x;
+
+                       // row is dragged left or right
+                       ShowDraggedRow( pos.x - mDragOrigin.x );
+               }
+
+               // this plugin "eats" all mouse input while item is dragged,
+       }
+}
+
+void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent& event )
+{
+       mpPane = event.mpPane;
+
+       // DBG::
+       wxASSERT( !mDragStarted && !mDecisionMode );
+
+       if ( ItemIsInFocus() )
+       {
+               mDecisionMode = TRUE;
+
+               wxPoint pos = event.mPos;
+               mpPane->PaneToFrame( &pos.x, &pos.y );
+
+               mDragOrigin = pos;
+
+               SetMouseCapture( TRUE );
+       }
+       else
+               // propagate event to other plugins
+               event.Skip();
+}
+
+void cbRowDragPlugin::OnLButtonUp  ( cbLeftUpEvent& event )
+{
+       if ( !mDragStarted && !mDecisionMode ) 
+       {
+               event.Skip();
+               return;
+       }
+
+       mpPane = event.mpPane;
+
+       if ( mDecisionMode )
+       {
+               cbDockPane* pPane = mpPane;
+
+               SetMouseCapture( FALSE );
+
+               mDecisionMode = FALSE;
+               mDragStarted  = FALSE;
+
+               wxPoint frmPos = event.mPos;
+               pPane->PaneToFrame( &frmPos.x, &frmPos.y );
+
+               if ( mpRowInFocus ) 
+               {
+                       CollapseRow( mpRowInFocus );
+                       mpRowInFocus = 0;
+               }
+               else
+               {
+                       ExpandRow( mCollapsedIconInFocus );
+                       mCollapsedIconInFocus = -1;
+               }
+
+               mpRowInFocus  = NULL;
+               mpPane = pPane;
+
+               pPane->FrameToPane( &frmPos.x, &frmPos.y );
+
+               // give it another try after relayouting bars
+
+               cbMotionEvent moveEvt( frmPos, pPane );
+               this->OnMouseMove( moveEvt );
+
+               // this plugin has "eaten" the mouse-up event
+
+               return;
+       }
+       else
+       {
+               // otherwise, the dragged row was dropped, determine
+               // where to insert it
+
+               // restore initial pane appearence
+               ShowPaneImage();
+               FinishOnScreenDraw();
+
+               cbRowInfo* pRow = GetFirstRow();
+
+               mpLayout->GetUpdatesManager().OnStartChanges();
+
+               pRow->mUMgrData.SetDirty(TRUE);
+
+               cbBarInfo* pBar = mpRowInFocus->mBars[0];
+
+               while ( pBar )
+               {
+                       pBar->mUMgrData.SetDirty(TRUE);
+
+                       if ( pBar->mpBarWnd )
+                       {
+                               // do complete refresh
+                               pBar->mpBarWnd->Show(FALSE);
+                               pBar->mpBarWnd->Show(TRUE);
+                       }
+
+                       pBar = pBar->mpNext;
+               }
+
+               while( pRow )
+               {
+                       if ( mCurDragOfs < pRow->mRowY )
+                       {
+                               InsertDraggedRowBefore( pRow );
+                               break;
+                       }
+
+                       pRow = pRow->mpNext;
+               }
+
+               if ( pRow == NULL ) InsertDraggedRowBefore( NULL );
+
+               mpRowInFocus = NULL;
+
+               mpLayout->RecalcLayout(FALSE);
+
+               // finish change "transaction"
+               mpLayout->GetUpdatesManager().OnFinishChanges();
+               mpLayout->GetUpdatesManager().UpdateNow();
+
+               // finish drag action
+               SetMouseCapture( FALSE );
+               mDragStarted = FALSE;
+       }
+}
+
+void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent& event )
+{
+       mpPane = event.mpPane;
+
+       // FIXME:: this may harm operation of other plugins
+
+       if ( GetNextHandler() && mpPane->GetRowList().GetCount() )
+       {
+               // first, let other plugins add their decorations now
+       
+               GetNextHandler()->ProcessEvent( event );
+               event.Skip(FALSE);
+       }
+
+       wxClientDC dc( &mpLayout->GetParentFrame() );
+
+       dc.SetClippingRegion( mpPane->mBoundsInParent.x,
+                                                 mpPane->mBoundsInParent.y,
+                                                 mpPane->mBoundsInParent.width,
+                                                 mpPane->mBoundsInParent.height );
+
+       int cnt = GetHRowsCountForPane( event.mpPane );
+
+       if ( cnt > 0 ) 
+
+               DrawCollapsedRowsBorder( dc );
+
+       if ( mpPane->GetRowList().GetCount() )
+       
+               DrawRowsDragHintsBorder( dc );
+
+       cbRowInfo* pRow = GetFirstRow();
+
+       while( pRow )
+       {
+               DrawRowDragHint( pRow, dc, FALSE );
+               pRow = pRow->mpNext;
+       }
+
+       for( int i = 0; i != cnt; ++i )
+
+               DrawCollapsedRowIcon(i, dc, FALSE );
+}
+
+int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane* pPane )
+{
+       wxNode* pNode = mHiddenBars.First();
+
+       int maxIconNo = -1;
+
+       while( pNode )
+       {
+               cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data();
+
+               if ( pHBInfo->mAlignment == pPane->mAlignment )
+
+                       maxIconNo = wxMax( maxIconNo, pHBInfo->mIconNo );
+
+               pNode = pNode->Next();
+       }
+
+       return ( maxIconNo + 1 );
+}
+
+int cbRowDragPlugin::GetCollapsedRowIconHeight()
+{
+       return COLLAPSED_ICON_HEIGHT;
+}
+
+int cbRowDragPlugin::GetRowDragHintWidth()
+{
+       return ROW_DRAG_HINT_WIDTH;
+}
+
+void cbRowDragPlugin::SetPaneMargins()
+{
+       int hiddenRowsCnt = GetHRowsCountForPane( mpPane );
+
+       if ( mSvTopMargin == -1 )
+       {
+               mSvTopMargin    = mpPane->mTopMargin;
+               mSvBottomMargin = mpPane->mBottomMargin;
+               mSvLeftMargin   = mpPane->mLeftMargin;
+               mSvRightMargin  = mpPane->mRightMargin;
+       }
+
+       if ( mpPane->IsHorizontal() )
+       {
+               mpPane->mTopMargin    = mSvTopMargin;
+               mpPane->mBottomMargin = ( hiddenRowsCnt == 0 ) 
+                                                               ?  mSvBottomMargin 
+                                                               :  mSvBottomMargin + GetCollapsedRowIconHeight();
+
+               mpPane->mLeftMargin   = mSvLeftMargin + GetRowDragHintWidth();
+               mpPane->mRightMargin  = mSvRightMargin;
+       }
+       else
+       {
+               mpPane->mTopMargin    = mSvTopMargin;
+               mpPane->mBottomMargin = mSvBottomMargin + GetRowDragHintWidth();
+
+               mpPane->mLeftMargin   = mSvLeftMargin;
+               mpPane->mRightMargin  = ( hiddenRowsCnt == 0 ) ?
+                                                               mSvRightMargin : mSvRightMargin + GetCollapsedRowIconHeight();
+       }
+}
+
+void cbRowDragPlugin::OnInitPlugin()
+{
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+       for( int i = 0; i != MAX_PANES; ++i )
+
+               if ( panes[i]->MatchesMask( mPaneMask ) )
+               {
+                       mpPane = panes[i];
+
+                       SetPaneMargins();
+               }
+}
+
+/*** helpers for drag&drop ***/
+
+void cbRowDragPlugin::SetMouseCapture( bool captureOn )
+{
+       if ( mCaptureIsOn == captureOn ) return;
+
+       if ( captureOn ) 
+       {
+               mpLayout->CaptureEventsForPane( mpPane );
+               mpLayout->CaptureEventsForPlugin( this );
+       }
+       else 
+       {
+               mpLayout->ReleaseEventsFromPane( mpPane );
+               mpLayout->ReleaseEventsFromPlugin( this );
+       }
+
+       mCaptureIsOn = captureOn;
+}
+
+void cbRowDragPlugin::UnhiglightItemInFocus()
+{
+       wxClientDC dc( &mpLayout->GetParentFrame() );
+
+       if ( mpRowInFocus ) 
+
+               DrawRowDragHint( mpRowInFocus, dc, FALSE );
+       else
+       if ( mCollapsedIconInFocus != - 1 )
+
+               DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, FALSE );
+}
+
+void cbRowDragPlugin::ShowDraggedRow( int offset )
+{
+       // create combined image of pane and dragged
+       // row on it, in the mpCombinedImage bitmap
+
+       if ( mpPane->IsHorizontal() )
+       {
+               if ( mInitialRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height )
+
+                       offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitialRowOfs;
+
+               if ( mInitialRowOfs + offset < mCombRect.y )
+
+                       offset = mCombRect.y - mInitialRowOfs;
+
+               int x, y = mInitialRowOfs + offset;
+               mpPane->FrameToPane( &x, &y );
+               mCurDragOfs = y;
+       }
+       else
+       {
+               if ( mInitialRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width )
+
+                       offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitialRowOfs;
+
+               if ( mInitialRowOfs + offset < mCombRect.x )
+
+                       offset = mCombRect.x - mInitialRowOfs;
+
+               int x = mInitialRowOfs + offset, y;
+               mpPane->FrameToPane( &x, &y );
+               mCurDragOfs = x;
+       }
+
+       wxMemoryDC rowImgDc;
+       rowImgDc.SelectObject ( *mpRowImage );
+
+       wxMemoryDC paneImgDc;
+       paneImgDc.SelectObject( *mpPaneImage );
+
+       wxMemoryDC combImgDc;
+       combImgDc.SelectObject( *mpCombinedImage );
+
+       combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height,
+                           &paneImgDc, 0,0, wxCOPY );
+
+       if ( mpPane->IsHorizontal() )
+       {       
+               combImgDc.Blit( 0, mInitialRowOfs + offset - mCombRect.y,
+                                               mCombRect.width, mRowImgDim.y,
+                                               &rowImgDc, 0,0, wxCOPY );
+       }
+       else
+       {
+               combImgDc.Blit( mInitialRowOfs + offset - mCombRect.x,
+                                   0,
+                                               mRowImgDim.x, mCombRect.height,
+                                               &rowImgDc, 0,0, wxCOPY );
+       }
+
+       int scrX = mCombRect.x,
+           scrY = mCombRect.y;
+
+       mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
+
+       mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height,
+                          &combImgDc, 0,0, wxCOPY );
+
+       rowImgDc .SelectObject( wxNullBitmap );
+       paneImgDc.SelectObject( wxNullBitmap );
+       combImgDc.SelectObject( wxNullBitmap );
+}
+
+wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area )
+{
+       wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) );
+
+       wxMemoryDC mdc;
+       mdc.SelectObject( *pBmp );
+
+       mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY );
+       mdc.SelectObject( wxNullBitmap );
+
+       return pBmp;
+}
+
+void cbRowDragPlugin::PrepareForRowDrag()
+{
+       wxRect rowBounds = mpRowInFocus->mBoundsInParent;
+
+       if ( mpPane->IsHorizontal() )
+       {
+               mCombRect         = mpPane->mBoundsInParent;
+
+               mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1;
+               mCombRect.y += mpPane->mTopMargin;
+
+               mCombRect.width  -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
+               mCombRect.height -= mpPane->mTopMargin  + mpPane->mBottomMargin;
+
+               mCombRect.height += 2*rowBounds.height;
+               mCombRect.y      -= rowBounds.height;
+               mInitialRowOfs     = rowBounds.y;
+
+               rowBounds.y      -= 1;
+               rowBounds.height += 2;
+               rowBounds.x      = mCombRect.x;
+               rowBounds.width  = mCombRect.width;
+
+               mRowImgDim.y     = rowBounds.height;
+       }
+       else
+       {
+               mCombRect = mpPane->mBoundsInParent;
+
+               mCombRect.y += mpPane->mTopMargin  - 1; 
+               mCombRect.x += mpPane->mLeftMargin - 1;
+                       ;
+               mCombRect.height -= mpPane->mTopMargin  + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1;
+               mCombRect.width  -= mpPane->mLeftMargin + mpPane->mRightMargin;
+
+               mCombRect.width += 2*rowBounds.width;
+               mCombRect.x     -= rowBounds.width;
+               mInitialRowOfs    = rowBounds.x;
+
+               rowBounds.x      -= 1;
+               rowBounds.width  += 2;
+               rowBounds.y      = mCombRect.y;
+               rowBounds.height = mCombRect.height;
+
+               mRowImgDim.x     = rowBounds.width;
+       }
+       // output cobination results onto frame's client area
+       wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame());
+       mpScrDc = new wxScreenDC();
+
+       int x = mCombRect.x, y = mCombRect.y;
+       mpLayout->GetParentFrame().ClientToScreen( &x, &y );
+
+       wxRect scrRect = mCombRect;
+       scrRect.x = x;
+       scrRect.y = y;
+
+       mpPaneImage = CaptureDCArea( *mpScrDc, scrRect );
+
+       wxMemoryDC mdc;
+       mdc.SelectObject( *mpPaneImage );
+       mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y );
+
+       DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen,  mpLayout->mDarkPen  );
+       DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen );
+
+       mpRowImage = CaptureDCArea( mdc, rowBounds );
+
+       // draw dark empty-row placeholder
+       DrawEmptyRow( mdc, rowBounds );
+
+       //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen,  mpLayout->mDarkPen  );
+       DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen );
+
+       mdc.SelectObject( wxNullBitmap );
+
+       mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) );
+
+       // show it for the first time
+       ShowDraggedRow( 0 );
+}
+
+void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds )
+{
+       wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID );
+
+       // paint the "dark" empty-row placeholder
+
+       dc.SetBrush( bkBrush );
+       dc.SetPen  ( mpLayout->mNullPen );
+
+       dc.DrawRectangle( rowBounds.x, rowBounds.y, 
+                                         rowBounds.width+1, rowBounds.height+1 );
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::ShowPaneImage()
+{
+       int scrX = 0, scrY = 0;
+
+       mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY );
+
+       wxMemoryDC mdc;
+       mdc.SelectObject( *mpPaneImage );
+
+       mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY, 
+                                  mCombRect.width, mCombRect.height,
+                              &mdc, 0,0, wxCOPY );
+
+       mdc.SelectObject( wxNullBitmap );
+}
+
+void cbRowDragPlugin::FinishOnScreenDraw()
+{
+       wxScreenDC::EndDrawingOnTop();
+
+       delete mpScrDc;
+       delete mpCombinedImage;
+       delete mpPaneImage;
+       delete mpRowImage;
+
+       mpScrDc = NULL;
+       
+       mpCombinedImage = mpPaneImage = mpRowImage = NULL;
+}
+
+void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow )
+{
+       int iconCnt = GetHRowsCountForPane( mpPane );
+
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       cbBarInfo* pBar = pRow->mBars[0];
+
+       int rowNo = 0;
+
+       cbRowInfo* pCur = pRow;
+       while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; }
+
+       while( pBar )
+       {
+               cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo();
+                                                   
+               pHBInfo->mpBar      = pBar;
+               pHBInfo->mRowNo     = rowNo;
+               pHBInfo->mIconNo    = iconCnt;
+               pHBInfo->mAlignment     = mpPane->mAlignment;
+
+               mHiddenBars.Append( (wxObject*) pHBInfo );
+
+               // hide it
+               if ( pBar->mpBarWnd )
+
+                       pBar->mpBarWnd->Show( FALSE );
+
+               pBar->mState = wxCBAR_HIDDEN;
+
+               cbBarInfo* pNext = pBar->mpNext;
+
+               pBar->mpRow  = NULL;
+               pBar->mpNext = NULL;
+               pBar->mpPrev = NULL;
+
+               pBar = pNext;
+       }
+
+       mpPane->GetRowList().Remove( pRow );
+       mpPane->InitLinksForRows();
+
+       delete pRow;
+
+       SetPaneMargins();
+
+       mpLayout->RecalcLayout(FALSE);
+
+       mpRowInFocus = NULL;
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+}
+
+void cbRowDragPlugin::ExpandRow( int collapsedIconIdx )
+{
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       cbRowInfo* pNewRow = new cbRowInfo();
+
+       wxNode* pNode = mHiddenBars.First();
+
+       int rowNo = 0;
+
+       // move bars from internal list to the newly expanded row 
+
+       while( pNode )
+       {
+               cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data();
+
+               if ( pHBInfo->mAlignment     == mpPane->mAlignment &&
+                        pHBInfo->mIconNo        == collapsedIconIdx   )
+               {
+                       rowNo = pHBInfo->mRowNo;
+
+                       if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN )
+                       {
+                               pNewRow->mBars.Add( pHBInfo->mpBar );
+
+                               pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() ) 
+                                                                                ? wxCBAR_DOCKED_HORIZONTALLY
+                                                                                : wxCBAR_DOCKED_VERTICALLY;
+                       }
+
+                       // remove bar info from internal list
+
+                       wxNode* pNext = pNode->Next();
+
+                       delete pHBInfo;
+                       mHiddenBars.DeleteNode( pNode );
+
+                       pNode = pNext;
+               }
+               else
+               {
+                       // decrease incon numbers with higher indicies, since this
+                       // row is now removed from the hidden-rows list
+
+                       if ( pHBInfo->mIconNo    > collapsedIconIdx &&
+                                pHBInfo->mAlignment == mpPane->mAlignment )
+
+                               --pHBInfo->mIconNo;
+
+                       pNode = pNode->Next();
+               }
+       }
+
+       mpPane->InitLinksForRow( pNewRow );
+
+       // insert row into pane at it's original position
+
+       if ( pNewRow->mBars.GetCount() )
+       {
+               cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo );
+
+               mpPane->InsertRow( pNewRow, beforeRowNode );
+       }
+       else
+               delete pNewRow;
+
+       SetPaneMargins();
+
+       mpLayout->RecalcLayout(FALSE);
+
+       mCollapsedIconInFocus = -1;
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+
+
+       /*
+       wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx );
+
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       // insert at the end of rows list
+       mpPane->InsertRow( pRowNode, NULL );
+
+       int success = mHiddenRows.DeleteNode( pRowNode );
+       // DBG::
+       wxASSERT( success );
+
+       SetPaneMargins();
+
+       mpLayout->RecalcLayout(FALSE);
+
+       mCollapsedIconInFocus = -1;
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+       */
+}
+
+void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow )
+{
+       if ( mpRowInFocus != pBeforeRow &&
+                mpRowInFocus->mpNext != pBeforeRow 
+          )
+       {
+               mpPane->GetRowList().Remove( mpRowInFocus );
+
+               mpPane->InsertRow( mpRowInFocus, pBeforeRow );
+       }
+       else 
+       {
+               // otherwise, nothing has happned (row positions do not change)
+
+               //wxClientDC dc( &mpLayout->GetParentFrame() );
+
+               //mpPane->PaintRow( mpRowInFocus, dc );
+               //DrawRowDragHint( mpRowInFocus, dc, FALSE );
+       }
+}
+
+bool cbRowDragPlugin::ItemIsInFocus()
+{
+       return ( mpRowInFocus || mCollapsedIconInFocus != - 1 );
+}
+
+void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx )
+{
+       wxClientDC dc( &mpLayout->GetParentFrame() );
+
+       if ( pRow != NULL && mpRowInFocus == pRow ) return;
+       if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return;
+
+       UnhiglightItemInFocus();
+
+       if ( iconIdx != - 1 )
+       
+               DrawCollapsedRowIcon( iconIdx, dc, TRUE );
+
+       else
+       if ( pRow != NULL )
+
+               DrawRowDragHint( pRow, dc, TRUE );
+}
+
+cbRowInfo* cbRowDragPlugin::GetFirstRow()
+{
+       return ( mpPane->GetRowList().GetCount() ) 
+                  ? mpPane->GetRowList()[0]
+                  : NULL;
+}
+
+/*** "hard-coded" metafile for NN-look ***/
+
+void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc )
+{
+       int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
+
+       wxBrush br( mTrianInnerColor, wxSOLID );
+
+       dc.SetBrush( br );
+       dc.SetPen( mpLayout->mBlackPen );
+
+       wxPoint points[3];
+       points[0].x = inRect.x + xOfs;
+       points[0].y = inRect.y + inRect.height - 1;
+       points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2 + 1;
+       points[1].y = inRect.y + inRect.height - 2 - ICON_TRIAN_HEIGHT;
+       points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH+1;
+       points[2].y = inRect.y + inRect.height - 1;
+
+       dc.DrawPolygon( 3, points );
+
+       // higlight upper-right edge of triangle
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( points[2].x, points[2].y,
+                        points[0].x, points[0].y );
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc )
+{
+       int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2;
+
+       wxBrush br( mTrianInnerColor, wxSOLID );
+
+       dc.SetBrush( br );
+       dc.SetPen( mpLayout->mBlackPen );
+
+       wxPoint points[3];
+       points[0].x = inRect.x + xOfs;
+       points[0].y = inRect.y;
+       points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH;
+       points[1].y = inRect.y;
+       points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2;
+       points[2].y = inRect.y + ICON_TRIAN_HEIGHT;
+
+       dc.DrawPolygon( 3, points );
+
+       // higlight upper-right edge of triangle
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( points[2].x, points[2].y,
+                        points[1].x, points[1].y );
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::DrawTrianRight( wxRect& inRect, wxDC& dc )
+{
+       int yOfs = (inRect.height - ICON_TRIAN_WIDTH)/2;
+
+       wxBrush br( mTrianInnerColor, wxSOLID );
+
+       dc.SetBrush( br );
+       dc.SetPen( mpLayout->mBlackPen );
+
+       wxPoint points[3];
+       points[0].x = inRect.x;
+       points[0].y = inRect.y + yOfs + ICON_TRIAN_WIDTH;
+       points[1].x = inRect.x;
+       points[1].y = inRect.y + yOfs;
+       points[2].x = inRect.x + ICON_TRIAN_HEIGHT;
+       points[2].y = inRect.y + yOfs + ICON_TRIAN_WIDTH/2;
+
+       dc.DrawPolygon( 3, points );
+
+       // higlight upper-right edge of triangle
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( points[0].x, points[0].y,
+                        points[2].x, points[2].y );
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::Draw3DPattern( wxRect& inRect, wxDC& dc )
+{
+       for( int y = inRect.y; y < inRect.y + inRect.height; y+=3 )
+       
+               for( int x = inRect.x; x < inRect.x + inRect.width; x+=3 )
+               {
+                       dc.SetPen( mpLayout->mLightPen );
+                       dc.DrawPoint( x,y );
+                       dc.SetPen( mpLayout->mBlackPen );
+                       dc.DrawPoint( x+1, y+1 );
+               }
+}
+
+void cbRowDragPlugin::DrawRombShades( wxPoint& p1, wxPoint& p2, 
+                                                                         wxPoint& p3, wxPoint& p4,
+                                                                         wxDC& dc )
+{
+       dc.SetPen( mpLayout->mLightPen );
+       dc.DrawLine( p1.x, p1.y, p2.x, p2.y );
+       dc.DrawLine( p2.x, p2.y, p3.x, p3.y );
+       dc.SetPen( mpLayout->mDarkPen );
+       dc.DrawLine( p3.x, p3.y, p4.x, p4.y );
+       dc.DrawLine( p4.x, p4.y, p1.x, p1.y );
+}
+
+void cbRowDragPlugin::DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
+{
+       dc.SetBrush( bkBrush );
+       dc.SetPen( mpLayout->mBlackPen );
+
+       wxPoint points[4];
+
+       if ( inRect.width > inRect.height )
+       {
+               // horizontal orienation
+               points[0].x = inRect.x;
+               points[0].y = inRect.y + inRect.height;
+               points[1].x = inRect.x;
+               points[1].y = inRect.y;
+               points[2].x = inRect.x + inRect.width;
+               points[2].y = inRect.y;
+               points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT;
+               points[3].y = inRect.y + inRect.height;
+
+               dc.DrawPolygon( 4, points );
+
+               // squeeze romb's bounds to create an inner-shade shape
+               ++points[0].x;
+               --points[0].y;
+               ++points[1].x;
+               ++points[1].y;
+               --points[2].x; --points[2].x;
+               ++points[2].y;
+               --points[3].y;
+
+               DrawRombShades( points[0], points[1], points[2], points[3], dc );
+       }
+       else
+       {
+               // vertical orientation
+               points[0].x = inRect.x + inRect.width;
+               points[0].y = inRect.y + inRect.height;
+               points[1].x = inRect.x;
+               points[1].y = inRect.y + inRect.height;
+               points[2].x = inRect.x;
+               points[2].y = inRect.y;
+               points[3].x = inRect.x + inRect.width;
+               points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT;
+
+               dc.DrawPolygon( 4, points );
+
+               // squeeze romb's bounds to create an inner-shade shape
+               --points[0].y ;
+               --points[0].x;
+               ++points[1].x;
+               --points[1].y;
+               ++points[2].y; ++points[2].y;
+               ++points[2].x;
+               --points[3].x;
+
+               DrawRombShades( points[1], points[2], points[3], points[0], dc );
+       }
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
+{
+       wxPoint points[4];
+
+       dc.SetBrush( bkBrush );
+       dc.SetPen( mpLayout->mBlackPen );
+
+       if ( inRect.width > inRect.height )
+       {
+               // horizontal orientation
+               points[0].x = inRect.x;
+               points[0].y = inRect.y + inRect.height;
+               points[1].x = inRect.x + COLLAPSED_ICON_HEIGHT;
+               points[1].y = inRect.y;
+               points[2].x = inRect.x + inRect.width;
+               points[2].y = inRect.y;
+               points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT;
+               points[3].y = inRect.y + inRect.height;
+
+               dc.DrawPolygon( 4, points );
+
+               // squeeze romb's bounds to create an inner-shade shape
+               ++points[0].x ;++points[0].x ;
+               --points[0].y;
+               ++points[1].y;
+               --points[2].x; --points[2].x;
+               ++points[2].y;
+               //--points[3].x ;
+               --points[3].y;
+
+               DrawRombShades( points[0], points[1], points[2], points[3], dc );
+
+       }
+       else
+       {
+               // vertical orientation
+               points[0].x = inRect.x + inRect.width;
+               points[0].y = inRect.y + inRect.height;
+               points[1].x = inRect.x;
+               points[1].y = inRect.y + inRect.height - COLLAPSED_ICON_HEIGHT;
+               points[2].x = inRect.x;
+               points[2].y = inRect.y;
+               points[3].x = inRect.x + inRect.width;
+               points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT;
+
+               dc.DrawPolygon( 4, points );
+
+               // squeeze romb's bounds to create an inner-shade shape
+               --points[0].y ;--points[0].y ;
+               --points[0].x;
+               ++points[1].x;
+               ++points[2].y; ++points[2].y;
+               ++points[2].x;
+               --points[3].x;
+
+               DrawRombShades( points[1], points[2], points[3], points[0], dc );
+       }
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::DrawRectShade( wxRect& inRect, wxDC& dc, 
+                                                                        int level, wxPen& upperPen, wxPen& lowerPen )
+{
+       // upper shade
+       dc.SetPen( upperPen );
+       dc.DrawLine( inRect.x - level, 
+                                inRect.y - level, 
+                        inRect.x + inRect.width - 1 + level, 
+                                inRect.y - level);
+       dc.DrawLine( inRect.x - level, inRect.y - level,
+                        inRect.x - level, inRect.y + inRect.height - 1 + level );
+
+       // lower shade
+       dc.SetPen( lowerPen );
+       dc.DrawLine( inRect.x - level, 
+                                inRect.y + inRect.height - 1 + level,
+                        inRect.x + inRect.width  + level,
+                            inRect.y + inRect.height - 1 + level);
+       dc.DrawLine( inRect.x + inRect.width - 1 + level,
+                        inRect.y - level,
+                                inRect.x + inRect.width - 1 + level,
+                                inRect.y + inRect.height + level);
+
+       dc.SetBrush( wxNullBrush );
+}
+
+void cbRowDragPlugin::Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush )
+{
+       dc.SetPen( mpLayout->mNullPen );
+       dc.SetBrush( bkBrush );
+
+       dc.DrawRectangle( inRect.x, inRect.y,
+                             inRect.width, inRect.height );
+
+       DrawRectShade( inRect, dc, 0, mpLayout->mLightPen, mpLayout->mDarkPen );
+}
+
+int  cbRowDragPlugin::GetCollapsedIconsPos()
+{
+       RowArrayT& rows = mpPane->GetRowList();
+
+       if ( rows.GetCount() == 0 ) 
+       {
+               if ( mpPane->IsHorizontal() )
+                       
+                       return mpPane->mBoundsInParent.y + mpPane->mTopMargin;
+               else
+                       return mpPane->mBoundsInParent.x + mpPane->mLeftMargin;
+       }
+
+       wxRect& bounds = rows[ rows.GetCount() - 1 ]->mBoundsInParent;
+
+       if ( mpPane->IsHorizontal() )
+
+               return bounds.y + bounds.height + 1;
+       else
+               return bounds.x + bounds.width  + 1;
+
+}
+
+void cbRowDragPlugin::GetRowHintRect( cbRowInfo* pRow, wxRect& rect )
+{
+       wxRect& bounds = pRow->mBoundsInParent;
+
+       if ( mpPane->IsHorizontal() )
+       {
+               rect.x = bounds.x - ROW_DRAG_HINT_WIDTH - 1;
+               rect.y = bounds.y;
+               rect.width = ROW_DRAG_HINT_WIDTH;
+               rect.height = bounds.height;
+       }
+       else
+       {
+               rect.x = bounds.x;
+               rect.y = bounds.y + bounds.height + 1;
+               rect.width = bounds.width;
+               rect.height = ROW_DRAG_HINT_WIDTH;
+       }
+}
+
+void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx, wxRect& rect )
+{
+       int upper = GetCollapsedIconsPos();
+
+       int right = (iconIdx == 0 ) 
+                               ? 0 : iconIdx * (COLLAPSED_ICON_WIDTH - COLLAPSED_ICON_HEIGHT);
+
+       if ( mpPane->IsHorizontal() )
+       {
+               rect.x = mpPane->mBoundsInParent.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1
+                                + right;
+
+               rect.y = upper;
+               rect.width  = COLLAPSED_ICON_WIDTH;
+               rect.height = COLLAPSED_ICON_HEIGHT;
+       }
+       else
+       {
+            rect.x = upper;
+                rect.y = mpPane->mBoundsInParent.y + mpPane->mBoundsInParent.height 
+                                - mpPane->mBottomMargin + ROW_DRAG_HINT_WIDTH + 1
+                                - right - COLLAPSED_ICON_WIDTH;
+
+               rect.height = COLLAPSED_ICON_WIDTH;
+               rect.width  = COLLAPSED_ICON_HEIGHT;
+       }
+}
+
+/*** overridables ***/
+
+void cbRowDragPlugin::DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted )
+{
+       wxRect rect;
+       GetCollapsedInconRect( index, rect );
+
+       wxBrush  hiBrush ( mHightColor, wxSOLID );
+       wxBrush  lowBrush( mLowColor,   wxSOLID );
+       wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
+
+       if ( mpPane->IsHorizontal() )
+       {                                
+               if ( index == 0 )
+
+                       DrawOrtoRomb( rect, dc, curBrush );
+               else
+                       DrawRomb( rect, dc, curBrush );
+
+               int triOfs = (index == 0) ? TRIANGLE_OFFSET : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT;
+
+               wxRect triRect;
+               triRect.x = triOfs + rect.x;
+
+               triRect.width = ICON_TRIAN_HEIGHT;
+               triRect.y = rect.y;
+               triRect.height = rect.height;
+
+               DrawTrianRight( triRect, dc );
+
+               wxRect patRect;
+               patRect.x      = triOfs + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP + rect.x;
+               patRect.y      = rect.y + PAT_OFFSET; 
+               patRect.width  = rect.width - (patRect.x - rect.x) - COLLAPSED_ICON_HEIGHT - PAT_OFFSET;
+               patRect.height = rect.height - PAT_OFFSET*2;
+
+               Draw3DPattern( patRect, dc );
+       }
+       else
+       {
+               if ( index == 0 )
+
+                       DrawOrtoRomb( rect, dc, curBrush );
+               else
+                       DrawRomb( rect, dc, curBrush );
+
+               int triOfs = (index == 0) 
+                                        ? TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT
+                                        : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT + ICON_TRIAN_HEIGHT;
+
+               wxRect triRect;
+               triRect.y      = rect.y + rect.height - triOfs;
+               triRect.x      = rect.x;
+               triRect.width  = rect.width;
+               triRect.height = ICON_TRIAN_HEIGHT;
+
+               DrawTrianUp( triRect, dc );
+
+               wxRect patRect;
+               patRect.y      = rect.y + COLLAPSED_ICON_HEIGHT + PAT_OFFSET;
+               patRect.x      = rect.x + PAT_OFFSET; 
+               patRect.width  = rect.width - 2*PAT_OFFSET ;
+               patRect.height = rect.height - triOfs - 2*PAT_OFFSET - COLLAPSED_ICON_HEIGHT;
+
+               Draw3DPattern( patRect, dc );
+       }
+}
+
+void cbRowDragPlugin::DrawRowDragHint( cbRowInfo* pRow , wxDC& dc, bool isHighlighted )
+{
+       wxRect rect;
+       GetRowHintRect( pRow, rect );
+
+       wxBrush  hiBrush ( mHightColor, wxSOLID );
+       wxBrush  lowBrush( mLowColor,   wxSOLID );
+       wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush;
+
+       Draw3DRect( rect, dc, curBrush );
+
+       if ( mpPane->IsHorizontal() )
+       {
+               wxRect triRect;
+               triRect.y          = rect.y + TRIANGLE_OFFSET;
+               triRect.x          = rect.x;
+               triRect.width  = rect.width;
+               triRect.height = ICON_TRIAN_HEIGHT;
+
+               DrawTrianDown( triRect, dc );
+
+               wxRect patRect;
+               patRect.x      = rect.x + PAT_OFFSET;
+               patRect.y      = rect.y + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP;
+               patRect.width  = rect.width - 2*PAT_OFFSET;
+               patRect.height = rect.height - ( patRect.y - rect.y ) - PAT_OFFSET;
+               Draw3DPattern( patRect, dc );
+
+               dc.SetPen( mpLayout->mLightPen );
+               dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height );
+       }
+       else
+       {
+               wxRect triRect;
+               triRect.x          = rect.x + TRIANGLE_OFFSET;
+               triRect.y          = rect.y;
+               triRect.height = rect.height;
+               triRect.width  = ICON_TRIAN_HEIGHT;
+
+               DrawTrianRight( triRect, dc );
+
+               wxRect patRect;
+               patRect.y      = rect.y + PAT_OFFSET;
+               patRect.x      = rect.x + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP;
+               patRect.height = rect.height - 2*PAT_OFFSET;
+               patRect.width  = rect.width - ( patRect.x - rect.x ) - PAT_OFFSET;
+               Draw3DPattern( patRect, dc );
+
+               dc.SetPen( mpLayout->mLightPen );
+               dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height );
+       }
+}
+
+void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC& dc )
+{
+       // FIXME:: what was that?
+}
+
+void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC& dc )
+{
+       int colRowOfs = GetCollapsedIconsPos();
+       wxRect& bounds = mpPane->mBoundsInParent;
+
+       wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID );
+       dc.SetBrush( bkBrush );
+       dc.SetPen( mpLayout->mDarkPen );
+
+       if ( mpPane->IsHorizontal() )
+       
+               dc.DrawRectangle( bounds.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1,
+                                                 colRowOfs,
+                                                 bounds.width - mpPane->mLeftMargin - mpPane->mRightMargin + 2 + ROW_DRAG_HINT_WIDTH,
+                                                 COLLAPSED_ICON_HEIGHT + 1);
+       else
+               dc.DrawRectangle( colRowOfs,
+                                                 bounds.y + mpPane->mTopMargin - 1,
+                                                 COLLAPSED_ICON_HEIGHT + 1,
+                                                 bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin 
+                                                 - ROW_DRAG_HINT_WIDTH - 2 );
+
+       dc.SetBrush( wxNullBrush );
+}
+
+static inline bool rect_contains_point( const wxRect& rect, int x, int y )
+{
+       return ( x >= rect.x &&
+                    y >= rect.y &&
+                        x <  rect.x + rect.width  &&
+                        y <  rect.y + rect.height );
+}
+
+bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos )
+{
+       wxRect bounds;
+       GetCollapsedInconRect( iconIdx, bounds );
+
+       return rect_contains_point( bounds, pos.x, pos.y );
+}
+
+bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos )
+{
+       wxRect bounds;
+       GetRowHintRect( pRow, bounds );
+
+       return rect_contains_point( bounds, pos.x, pos.y );
+}
+
diff --git a/contrib/src/fl/rowlayoutpl.cpp b/contrib/src/fl/rowlayoutpl.cpp
new file mode 100644 (file)
index 0000000..0ca0f45
--- /dev/null
@@ -0,0 +1,1220 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     09/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+    #pragma implementation "rowlayoutpl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/rowlayoutpl.h"
+
+// exerimental "features" are still buggy
+#undef __EXPERIMENTAL
+
+/***** Implementation for class cbRowLayoutPlugin *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbRowLayoutPlugin, cbPluginBase )
+
+BEGIN_EVENT_TABLE( cbRowLayoutPlugin, cbPluginBase )
+
+       EVT_PL_LAYOUT_ROW ( cbRowLayoutPlugin::OnLayoutRow  )
+       EVT_PL_LAYOUT_ROWS( cbRowLayoutPlugin::OnLayoutRows )
+       EVT_PL_RESIZE_ROW ( cbRowLayoutPlugin::OnResizeRow  )
+
+       EVT_PL_INSERT_BAR ( cbRowLayoutPlugin::OnInsertBar  )
+       EVT_PL_REMOVE_BAR ( cbRowLayoutPlugin::OnRemoveBar  )
+
+END_EVENT_TABLE()
+
+cbRowLayoutPlugin::cbRowLayoutPlugin(void)
+       : mpPane( 0 )
+{}
+
+cbRowLayoutPlugin::cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask )
+
+       : cbPluginBase( pPanel, paneMask ),
+         mpPane( 0 )
+{}
+
+void cbRowLayoutPlugin::CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo )
+{
+       // this method handles situation, when fixed bar is inserted
+       // into the row, where among fixed bars not-fixed ones are present.
+       // In this case we need to check if the pBarNode appears to be inserted
+       // chain of fixed-bars on the very right or left side of the row,
+       // then all the white-space, such chain should be eliminated,
+       // and the resulting chain justified to the right or the left 
+       // side of the row
+
+       if ( !pTheBar->IsFixed() || rowInfo.mHasOnlyFixedBars ) 
+
+               return;
+
+       cbBarInfo* pBar = rowInfo.mBars[ rowInfo.mBars.Count() - 1 ];
+
+       // slide fixed bars to the right on the right side relative to the pBarNode
+
+       int prevX = mpPane->mPaneWidth;
+
+       do
+       {
+               if ( !pBar->IsFixed() ) 
+                       break;
+
+               wxRect& bounds = pBar->mBounds;
+
+               bounds.x = prevX - bounds.width;
+
+               prevX = bounds.x;
+
+               if ( pBar == pTheBar ) break;
+
+               pBar = pBar->mpPrev;
+       }
+       while( 1 );
+
+       // slide fixed bars to the left on the left side relative to the pBarNode   
+
+       pBar = rowInfo.mBars[0];
+
+       prevX = 0;
+       
+       do
+       {
+               if ( pBar->IsFixed() ) 
+
+                       break;
+
+               wxRect& bounds = pBar->mBounds;
+
+               bounds.x = prevX;
+
+               prevX = bounds.x + bounds.width;
+
+               if ( pBar == pTheBar ) break;
+
+               pBar = pBar->mpNext;
+       }
+       while( 1 );
+}
+
+void cbRowLayoutPlugin::ExpandNotFixedBars( cbRowInfo* pRow )
+{
+       ApplyLengthRatios( pRow );
+
+               // FIXME:: something's wrong?
+               return;
+
+       double freeSpc = (double)GetRowFreeSpace( pRow );
+
+       // calculate sum of precents
+
+       double pcntSum = 0.0;
+
+       size_t i = 0;
+
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               if ( !pRow->mBars[i]->IsFixed() )
+                       pcntSum += pRow->mBars[i]->mLenRatio;
+       }
+
+       // setup bar lengths
+
+       int curX = 0;
+
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               if ( !bar.IsFixed() )
+               {
+                       bar.mLenRatio = bar.mLenRatio/(pcntSum);
+
+                       bar.mBounds.width = 
+                               
+                               wxMax( mpPane->mProps.mMinCBarDim.x, int( freeSpc*bar.mLenRatio ) );
+               }
+               
+               bar.mBounds.x = curX;
+               curX = bar.mBounds.x + bar.mBounds.width;
+       }
+}
+
+void cbRowLayoutPlugin::AdjustLengthOfInserted( cbRowInfo* pRow, cbBarInfo* pTheBar )
+{
+       return;
+
+       // pTheBar is not-fixed
+
+
+       // FIXME:: what is this for??
+
+#if 1
+
+       int totalLen = 0;
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() )
+                       totalLen += pRow->mBars[i]->mBounds.width;
+    }
+
+       double curWidth = pTheBar->mBounds.width;
+
+       if ( pRow->mBars.Count() )
+
+               pTheBar->mBounds.width = int( mpPane->mPaneWidth * (curWidth / double(totalLen)) );
+
+#else
+
+       double freeSpc = (double)GetRowFreeSpace( pRow );
+
+       double pcntSum = 0.0;
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() )
+                       pcntSum += pRow->mBars[i]->mLenRatio;
+    }
+
+       // if no longer "balanced", assume that `pTheBar' was previously
+       // removed from this row (kind of AI...)
+
+       if ( pcntSum < 0.98 )
+       
+               pTheBar->mBounds.width = freeSpc * (1.0 - pcntSum);
+#endif
+}
+
+void cbRowLayoutPlugin::FitBarsToRange( int from, int till, 
+                                                                               cbBarInfo* pTheBar, cbRowInfo* pRow )
+{
+       cbBarInfo* pFromBar = NULL;
+       cbBarInfo* pTillBar = NULL;
+
+       if ( pTheBar->mBounds.x > from )
+       {
+               // it's range from the left
+               pFromBar = pRow->mBars[0];
+               pTillBar = pTheBar;
+       }
+       else
+       {
+               pFromBar = pTheBar->mpNext;
+               pTillBar = NULL;
+       }
+
+       // calc free space in the range
+
+       cbBarInfo* pBar = pFromBar;
+       int     freeSpc = till-from;
+       double  pcntSum = 0;
+
+       while( pBar != pTillBar )
+       {
+               if ( pBar->IsFixed() )
+
+                       freeSpc -= pBar->mBounds.width;
+               else
+                       pcntSum += pBar->mLenRatio;
+
+               pBar = pBar->mpNext;
+       }
+
+       // adjust not-fixed bar sizes in the range
+
+       pBar = pFromBar;
+
+       while( pBar != pTillBar )
+       {
+               if ( !pBar->IsFixed() )
+               
+                       pBar->mBounds.width = 
+
+                               wxMax( mpPane->mProps.mMinCBarDim.x,
+                                      int( double(freeSpc) * (pBar->mLenRatio/pcntSum) ) 
+                                        );
+
+               pBar = pBar->mpNext;
+       }
+
+       // layout range, starting from the left-most bar
+
+       pBar      = pFromBar;
+       int prevX = from;
+       bool hasNotFixedBars = FALSE;
+
+       while ( pBar != pTillBar )
+       {
+               wxRect& bounds = pBar->mBounds;
+
+               if ( !pBar->IsFixed() )
+               {
+                       hasNotFixedBars = TRUE;
+
+                       freeSpc -= bounds.width;
+               }
+
+               bounds.x = prevX;
+
+               prevX = bounds.x + bounds.width;
+               
+               pBar = pBar->mpNext;
+       }
+
+       // make width adjustment for the right-most bar in the range, due to
+       // lost precision when seting widths using f.p. length-ratios
+
+       if ( hasNotFixedBars )
+       {
+               if ( pTheBar->mBounds.x > from )
+               {
+                       if ( pTillBar->mpPrev )
+                       {
+                               wxRect& tillBar = pTillBar->mpPrev->mBounds;
+
+                               //tillBar.width = bar.mBounds.x - tillBar.x;
+                               tillBar.width += freeSpc;
+                       }
+               }
+               else
+               {
+                       cbBarInfo* pLast = pRow->mBars[ pRow->mBars.Count() - 1 ];
+
+                       if ( pLast != pTheBar )
+                       {
+                               pTheBar->mBounds.width += freeSpc;
+
+                               SlideRightSideBars( pTheBar );
+                       }
+               }
+       }
+}
+
+void cbRowLayoutPlugin::MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve )
+{
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() && pRow->mBars[i] != pBarToPreserve )
+                       pRow->mBars[i]->mBounds.width = mpPane->mProps.mMinCBarDim.x;
+    }
+}
+
+int cbRowLayoutPlugin::GetRowFreeSpace( cbRowInfo* pRow )
+{
+       int freeSpc = mpPane->mPaneWidth;
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               // not-fixed bars variable length, thus their
+               // dimensions are ignored
+               if ( pRow->mBars[i]->IsFixed() )
+                       freeSpc -= pRow->mBars[i]->mBounds.width;
+    }
+
+       return freeSpc;
+}
+
+void cbRowLayoutPlugin::RecalcLengthRatios( cbRowInfo* pRow )
+{
+       double freeSpc = double( GetRowFreeSpace( pRow ) );
+
+       cbBarInfo* pBar          = pRow->mBars[0];
+       cbBarInfo* pLastNotFixed = NULL;
+
+       double pcntLeft = 1.0; // (100%)
+
+#ifdef __EXPERIMENTAL
+
+       int totalLen = 0;
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() )
+                       totalLen += pRow->mBars[i]->mBounds.width;
+    }
+#endif
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               if ( !bar.IsFixed() )
+               {
+
+#ifdef __EXPERIMENTAL
+
+                       bar.mLenRatio = double(bar.mBounds.width)/double(totalLen);
+#else
+                       bar.mLenRatio = double(bar.mBounds.width)/freeSpc;
+#endif
+
+                       pcntLeft      -= bar.mLenRatio;
+                       pLastNotFixed  = pBar;
+               }
+       }
+
+       // attach remainder (the result of lost precision) to the
+       // last not-fixed bar
+
+#if !defined(__EXPERIMENTAL)   
+
+       if ( pLastNotFixed )
+               
+               pLastNotFixed->mLenRatio += pcntLeft;
+#endif
+
+}
+
+void cbRowLayoutPlugin::ApplyLengthRatios( cbRowInfo* pRow )
+{
+       double pcntSum = 0;
+
+       // FOR NOW:: all-in-one
+
+       size_t i = 0;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() )
+                       pcntSum += pRow->mBars[i]->mLenRatio;
+    }
+
+       /*
+       pBar = node_to_first_bar_node( pRow );
+       
+       while( pBar )
+       {
+               cbBarInfo& bar = node_to_bar( pBar );
+
+               if ( !bar.IsFixed() )
+               
+                       bar.mLenRatio = pcntSum / bar.mLenRatio;
+
+               pBar = pBar->Next();
+       }
+       */
+
+       int    prevX   = 0;
+       double freeSpc = GetRowFreeSpace( pRow );
+
+       // tricky stuff (improtant!):
+       // when not-fixed bar is removed from the row and there are
+       // still some other not-fixed ones left in that row, then
+       // the sum of mLenRatio's is no longer 1.0 - this is left
+       // intintionally to handle the case when the removed bar
+       // is returned right back to the row - so that it would retain
+       // it's original dimensions in this row (this is kind of AI...)
+       //
+       // The problem is - when it's remvoed, the sum of 
+       // mLenRatio's is not in "balance", i.e. is < 1.0,
+       // it's possible to restore balance, but instead of that
+       // we artifically ajdust freeSpc value in a way that it would 
+       // look like total of mLetRatio's is 1.0, thus original
+       // len. ratios are _preserved_:
+
+       double unit = freeSpc / pcntSum;
+
+       bool haveSquished = FALSE;
+
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+    {
+               if ( !pRow->mBars[i]->IsFixed() )
+               {
+                       cbBarInfo& bar = *pRow->mBars[i];       
+                       
+                       if ( int( unit * bar.mLenRatio ) < mpPane->mProps.mMinCBarDim.x )
+                       {
+                               haveSquished = TRUE;
+
+                               bar.mBounds.width = -1; // mark as "squished"
+
+                               pcntSum -= bar.mLenRatio;
+
+                               freeSpc -= mpPane->mProps.mMinCBarDim.x;
+                       }
+               }
+    }  // for
+
+       if ( haveSquished )
+       
+               unit = freeSpc / pcntSum;
+
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+
+               bar.mBounds.x = prevX;
+
+               if ( !bar.IsFixed() )
+               {
+                       if ( bar.mBounds.width == -1 )
+
+                               bar.mBounds.width = mpPane->mProps.mMinCBarDim.x;
+                       else
+                               bar.mBounds.width = int( unit * bar.mLenRatio );
+
+                       // a little bit of AI: 
+                       // memorize bar's height and width, when docked in 
+                       // the current orientation - by making the current
+                       // dimensions to be "preffered" ones for this docking state
+
+                       if ( !bar.IsFixed() )
+                       {
+                               bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width;
+                               bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height;
+                       }
+               }
+
+               prevX = bar.mBounds.x + bar.mBounds.width;
+       }
+}
+
+void cbRowLayoutPlugin::DetectBarHandles( cbRowInfo* pRow )
+{
+       // first pass from left to right (detect left-side handles)
+
+       bool foundNotFixed = FALSE;
+
+    size_t i;
+       for( i = 0; i != pRow->mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *pRow->mBars[i];
+               
+               bar.mHasLeftHandle = FALSE;
+
+               if ( !bar.IsFixed() )
+               {
+                       if ( foundNotFixed )
+               
+                               if ( bar.mpPrev &&
+                                        bar.mpPrev->IsFixed() )
+                               
+                                       bar.mHasLeftHandle = TRUE;
+
+                       foundNotFixed = TRUE;
+               }
+       }
+
+       // pass from right to left (detect right-side handles)
+
+       foundNotFixed = FALSE;
+
+       cbBarInfo* pBar = pRow->mBars[ pRow->mBars.Count() - 1 ];
+
+       while( pBar )
+       {
+               pBar->mHasRightHandle = FALSE;
+
+               if ( !pBar->IsFixed() )
+               {
+                       if ( foundNotFixed )
+
+                               if ( pBar->mpNext )
+
+                                        pBar->mHasRightHandle = TRUE;
+
+                       foundNotFixed = TRUE;
+               }
+
+               pBar = pBar->mpPrev;
+       }
+}
+
+void cbRowLayoutPlugin::RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow )
+{
+       if ( !pTheBar->mpPrev )
+       {
+               if (  !pTheBar->IsFixed() )
+               {
+                       // this bar the first in the row, move it's 
+                       // left edge to the very left
+                       pTheBar->mBounds.width += pTheBar->mBounds.x;
+                       pTheBar->mBounds.x      = 0;
+               }
+       }
+       else
+               FitBarsToRange( 0, pTheBar->mBounds.x, pTheBar, pRow );
+
+       if ( !pTheBar->mpNext )
+       {
+               if ( !pTheBar->IsFixed() )
+               {
+                       // this bar is the last one, move it's 
+                       // right edge to the very right
+
+                       pTheBar->mBounds.width = mpPane->mPaneWidth - pTheBar->mBounds.x;
+               }
+       }
+       else
+               FitBarsToRange( pTheBar->mBounds.x + pTheBar->mBounds.width, mpPane->mPaneWidth,
+                               pTheBar, pRow
+                                         );
+}
+
+void cbRowLayoutPlugin::LayoutItemsVertically( cbRowInfo& row )
+{
+    size_t i;
+       for( i = 0; i != row.mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *row.mBars[i];
+
+               bar.mBounds.y = row.mRowY;
+
+               if ( !bar.IsFixed() )
+
+                       // make all not-fixed bars of equal height
+                       bar.mBounds.height = row.mRowHeight;
+
+               if ( row.mHasUpperHandle )
+
+                       bar.mBounds.y += mpPane->mProps.mResizeHandleSize;
+       }
+}
+
+int cbRowLayoutPlugin::CalcRowHeight( cbRowInfo& row )
+{
+       int maxHeight = 0;
+
+    size_t i;
+       for( i = 0; i != row.mBars.Count(); ++i )
+       
+               maxHeight = wxMax( maxHeight, row.mBars[i]->mBounds.height );
+
+       return maxHeight;
+}
+
+void cbRowLayoutPlugin::StickRightSideBars( cbBarInfo* pToBar )
+{
+       cbBarInfo* pBar  = pToBar->mpNext;
+       cbBarInfo* pPrev = pToBar;
+
+       while( pBar )
+       {
+               wxRect& cur  = pBar->mBounds;
+               wxRect& prev = pPrev->mBounds;
+
+               cur.x = prev.x + prev.width;
+
+               pPrev = pBar;
+               pBar  = pBar->mpNext;
+       }
+}
+
+void cbRowLayoutPlugin::SlideLeftSideBars( cbBarInfo* pTheBar )
+{
+       // shift left-side-bars to the left (with respect to "theBar"),
+       // so that they would not obscured by each other
+
+       cbBarInfo* pBar  = pTheBar->mpPrev;
+       cbBarInfo* pPrev = pTheBar;
+
+       while( pBar )
+       {
+               wxRect& cur  = pBar->mBounds;
+               wxRect& prev = pPrev->mBounds;
+
+               if ( cur.x + cur.width > prev.x )
+
+                       cur.x = prev.x - cur.width;
+
+               pPrev = pBar;
+               pBar  = pBar->mpPrev;
+       }
+}
+
+void cbRowLayoutPlugin::SlideRightSideBars( cbBarInfo* pTheBar )
+{
+       // shift right-side-bars to the right (with respect to "theBar"),
+       // so that they would not be obscured by each other
+
+       cbBarInfo* pBar  = pTheBar->mpNext;
+       cbBarInfo* pPrev = pTheBar;
+
+       while( pBar )
+       {
+               wxRect& cur  = pBar->mBounds;
+               wxRect& prev = pPrev->mBounds;
+
+               if ( cur.x < prev.x + prev.width )
+
+                       cur.x = prev.x + prev.width;
+
+               pPrev = pBar;
+               pBar  = pBar->mpNext;
+       }
+}
+
+void cbRowLayoutPlugin::ShiftLeftTrashold( cbBarInfo* pTheBar, cbRowInfo& row )
+{
+       wxRect& first = row.mBars[0]->mBounds;
+
+       if ( first.x < 0 )
+       {
+               row.mBars[0]->mBounds.x = 0;
+
+               SlideRightSideBars( row.mBars[0] );
+       }
+}
+
+void cbRowLayoutPlugin::ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row )
+{
+       wxRect& theBar = pTheBar->mBounds;
+
+       do
+       {
+               cbBarInfo* pBar = pTheBar;
+
+               // calculate free spece on the left side
+
+               int leftFreeSpc = 0;
+
+               while( pBar )
+               {
+                       wxRect& cur = pBar->mBounds;
+
+                       if ( pBar->mpPrev )
+                       {
+                               wxRect& prev = pBar->mpPrev->mBounds;
+
+                               leftFreeSpc += cur.x - prev.x - prev.width;
+                       }
+                       else
+                               leftFreeSpc += cur.x;
+
+                       if ( cur.x < 0 )
+                       {
+                               leftFreeSpc = 0;
+                               break;
+                       }
+
+                       pBar = pBar->mpPrev;
+               }
+
+               pBar = pTheBar;
+
+               int rightOverflow = 0;
+
+               if ( pTheBar->IsFixed() )
+
+                       while( pBar )
+                       {
+                               if ( !pBar->mpNext )
+                               {
+                                       wxRect& cur = pBar->mBounds;
+
+                                       if ( cur.x + cur.width > mpPane->mPaneWidth )
+
+                                               rightOverflow = cur.x + cur.width - mpPane->mPaneWidth;
+                               }
+
+                               pBar = pBar->mpNext;
+                       }
+
+               if ( rightOverflow > 0 )
+               {
+                       if ( leftFreeSpc <= 0 ) return;
+
+                       if ( pTheBar->mpNext )
+                       {
+                               wxRect& next = pTheBar->mpNext->mBounds;
+
+                               // if there's enough space on the left, move over one half-obscured
+                               // bar from the right to the left side with respect to "theBar"
+
+                               if ( next.width < leftFreeSpc )
+                               {
+                                       cbBarInfo* pNext = pTheBar->mpNext;
+
+                                       row.mBars.Remove( pNext );
+
+                                       row.mBars.Insert( pNext, row.mBars.Index( pTheBar ) );
+
+                                       next.x = theBar.x - next.width;
+
+                                       // re-setup mpPrev/mpNext references after insertion
+
+                                       mpPane->InitLinksForRow( &row );
+
+                                       // tighten things
+
+                                       StickRightSideBars( pTheBar );
+                                       SlideLeftSideBars ( pTheBar );
+
+                                       continue;
+                               }
+                       }
+
+                       int leftShift = ( rightOverflow > leftFreeSpc ) 
+                                                       ? leftFreeSpc 
+                                                       : rightOverflow;
+
+                       theBar.x -= leftShift;
+
+                       StickRightSideBars( pTheBar );
+                       SlideLeftSideBars ( pTheBar );
+
+                       break;
+
+               } // end of if ( rightOverflow )
+               else
+                       break;
+
+       } while(1);
+}
+
+void cbRowLayoutPlugin::InsertBefore( cbBarInfo* pBeforeBar, 
+                                                                         cbBarInfo* pTheBar,
+                                                                         cbRowInfo& row        )
+{
+       if ( pBeforeBar )
+
+               row.mBars.Insert( pTheBar, row.mBars.Index( pBeforeBar ) );
+       else
+               row.mBars.Add( pTheBar );
+
+       pTheBar->mpRow = &row;
+}
+
+void cbRowLayoutPlugin::DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row )
+{
+       wxRect& theBar = pTheBar->mBounds;
+
+       /* OLD STUFF::
+       if ( theBar.x < 0 && !node_to_bar( pTheBar ).IsFixed() )
+       {
+               // AI::
+               theBar.width += theBar.x;
+               theBar.x = 0;
+       } */
+
+    size_t i;
+       for( i = 0; i != row.mBars.Count(); ++i )
+       {
+               cbBarInfo& bar = *row.mBars[i];
+
+               wxRect& cur = bar.mBounds;
+
+               // if bar hits the left edge
+               if ( theBar.x <= cur.x )
+               {
+                       InsertBefore( &bar, pTheBar, row );
+                       return;
+               }
+               
+               else
+               // if bar hits the right edge
+               if ( theBar.x <= cur.x + cur.width )
+               {
+                       if ( theBar.x + theBar.width > cur.x + cur.width )
+                       {
+                               InsertBefore( bar.mpNext, pTheBar, row );
+                               return;
+                       }
+
+                       // otherwise the bar lies within the bounds of current bar
+
+                       int leftDist  = theBar.x - cur.x;
+                       int rightDist = cur.x + cur.width - (theBar.x + theBar.width);
+
+                       if ( leftDist < rightDist )
+
+                               InsertBefore( &bar, pTheBar, row );
+                       else
+                               InsertBefore( bar.mpNext, pTheBar, row );
+
+                       return;
+               }
+       }
+
+       InsertBefore( NULL, pTheBar, row ); // insert at the end
+}
+
+// evnet handlers
+
+void cbRowLayoutPlugin::OnInsertBar( cbInsertBarEvent& event )
+{
+       cbBarInfo* pBarToInsert = event.mpBar;
+       cbRowInfo* pIntoRow     = event.mpRow;
+       mpPane                  = event.mpPane;
+
+       if ( !pBarToInsert->IsFixed() )
+
+               AdjustLengthOfInserted( pIntoRow, pBarToInsert );
+
+       DoInsertBar( pBarToInsert, *pIntoRow );
+
+       mpPane->InitLinksForRow( pIntoRow ); // relink "mpNext/mpPrev"s
+
+       // perform relayouting of the bars after insertion
+
+       // init bar location info
+       pBarToInsert->mAlignment = event.mpPane->mAlignment;
+       pBarToInsert->mRowNo     = event.mpPane->GetRowIndex( pIntoRow );
+
+#ifdef __EXPERIMENTAL
+
+       if ( !pIntoRow->mHasOnlyFixedBars || !pBarToInsert->IsFixed() )
+
+               RecalcLengthRatios( pIntoRow );
+
+#endif
+
+       MinimzeNotFixedBars( pIntoRow, pBarToInsert );
+
+       SlideLeftSideBars ( pBarToInsert );
+       SlideRightSideBars( pBarToInsert );
+
+       ShiftLeftTrashold ( pBarToInsert, *pIntoRow );
+       ShiftRightTrashold( pBarToInsert, *pIntoRow );
+
+       mpPane->SyncRowFlags( pIntoRow );
+
+       CheckIfAtTheBoundary( pBarToInsert, *pIntoRow );
+
+       if ( event.mpPane->IsHorizontal() )
+
+               pBarToInsert->mState = wxCBAR_DOCKED_HORIZONTALLY;
+       else
+               pBarToInsert->mState = wxCBAR_DOCKED_VERTICALLY;
+
+       if ( !pIntoRow->mHasOnlyFixedBars )
+       {
+
+#ifdef __EXPERIMENTAL
+
+               ExpandNotFixedBars( pIntoRow );
+#else
+
+               RelayoutNotFixedBarsAround( pBarToInsert, pIntoRow );
+           RecalcLengthRatios( pIntoRow );
+
+#endif
+
+               DetectBarHandles( pIntoRow );
+
+               // do proportional resizing of not-fixed bars 
+               ApplyLengthRatios( pIntoRow );
+       }
+
+       // adjust the bar's docking state
+
+       // a little bit of AI: 
+       // memorize bar's height and width, when docked in 
+       // the current orientation - by making the current
+       // dimensions to be "preferred" ones for this docking state
+
+       if ( !pBarToInsert->IsFixed() )
+       {
+               cbBarInfo& bar = *pBarToInsert;
+
+               bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width;
+               bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height;
+       }
+}
+
+void cbRowLayoutPlugin::OnRemoveBar ( cbRemoveBarEvent& event )
+{
+       cbBarInfo* pBar = event.mpBar;
+       mpPane          = event.mpPane;
+
+       cbRowInfo* pRow = pBar->mpRow;
+
+       mpLayout->GetUpdatesManager().OnBarWillChange( pBar, pRow, event.mpPane );
+
+       // invalidate the whole row
+       //pFirst->mpRowInfo->mMgrData.mPrevBounds.x = -1;
+
+       pRow->mBars.Remove( pBar );
+
+       // rest bar information after removing it from the row
+       pBar->mpRow           = NULL;
+       pBar->mHasLeftHandle  = FALSE;
+       pBar->mHasRightHandle = FALSE;
+
+       mpPane->InitLinksForRow( pRow ); // relink "mpNext/mpPrev"s
+
+       if ( pRow->mBars.Count() == 0 )
+       {
+               // empty rows should not exist
+
+               event.mpPane->GetRowList().Remove( pRow );
+
+               delete pRow;
+
+               mpPane->InitLinksForRows();
+       }
+       else
+       {
+               // force repainting of bars, in the row, from which the bar was removed
+
+               // FIXME:: really needed?
+               pRow->mBars[0]->mUMgrData.SetDirty(TRUE);
+
+               // re-setup mHasOnlyFixedBars flag for the row information
+               event.mpPane->SyncRowFlags( pRow );
+
+               DetectBarHandles( pRow );
+
+               if ( !pRow->mHasOnlyFixedBars )
+
+                       ExpandNotFixedBars( pRow );
+       }
+}
+
+void cbRowLayoutPlugin::OnLayoutRow( cbLayoutRowEvent& event )
+{
+       cbRowInfo* pRow = event.mpRow;
+       mpPane          = event.mpPane;
+
+       MinimzeNotFixedBars( pRow, NULL );
+
+       if ( !pRow->mHasOnlyFixedBars )
+       {
+               // do proportional resizing of not-fixed bars 
+               ApplyLengthRatios( pRow );
+       }
+
+       cbBarInfo& lastBar  = *pRow->mBars[ pRow->mBars.Count() - 1 ];
+       cbBarInfo& firstBar = *pRow->mBars[ 0 ];
+
+       // FIXME:: Next line not used
+    // wxRect& bounds = lastBar.mBounds;
+
+       if ( lastBar.mBounds.x + lastBar.mBounds.width > mpPane->mPaneWidth )
+       {
+               lastBar.mBounds.x = mpPane->mPaneWidth - lastBar.mBounds.width;
+
+               // first simulate left-row-edge friction
+
+               SlideLeftSideBars( &lastBar );
+
+               if ( firstBar.mBounds.x < 0 )
+            firstBar.mBounds.x = 0;
+
+               // then left-row-edge function, though this
+               // may cause some of the right-side bars going
+               // out of row bounds, but left-side always
+               // has the highest "priority"
+
+               SlideRightSideBars( &firstBar );
+       }
+
+       event.Skip(); // pass event to the next handler
+}
+
+void cbRowLayoutPlugin::OnLayoutRows( cbLayoutRowsEvent& event )
+{
+       mpPane       = event.mpPane;
+
+       int curY = 0;
+
+    // FIXME:: Next line not used.
+       // RowArrayT& arr = mpPane->GetRowList();
+
+    size_t i;
+       for( i = 0; i != mpPane->GetRowList().Count(); ++i )
+       {
+               cbRowInfo& row = *mpPane->GetRowList()[ i ];
+
+               // setup "has-handle" flags for rows, which depend on the existance 
+               // of not-fixed bars in the row
+
+               if ( !row.mHasOnlyFixedBars )
+               {
+                       if ( mpPane->mAlignment == FL_ALIGN_TOP ||
+                                mpPane->mAlignment == FL_ALIGN_LEFT   )
+                       {
+                               row.mHasLowerHandle = TRUE;
+
+                               row.mHasUpperHandle = FALSE; 
+                       }
+                       else
+                       {
+                               row.mHasUpperHandle = TRUE;
+
+                               row.mHasLowerHandle = FALSE; 
+                       }
+               }
+               else
+               {
+                       // otherwise, rows with fixed-bars only, have no height-resizing handles
+                       row.mHasUpperHandle = FALSE; 
+                       row.mHasLowerHandle = FALSE; 
+               }
+
+               // setup vertical positions for items in the row
+
+               row.mRowY = curY;
+
+               row.mRowWidth  = mpPane->mPaneWidth;
+               row.mRowHeight = CalcRowHeight( row );
+
+               LayoutItemsVertically( row );
+
+               if ( row.mHasUpperHandle )
+            row.mRowHeight += mpPane->mProps.mResizeHandleSize;
+               if ( row.mHasLowerHandle )
+            row.mRowHeight += mpPane->mProps.mResizeHandleSize;
+
+               curY += row.mRowHeight;
+       }
+
+       event.Skip(); // pass event to the next handler - other hookeds plugin
+                                 // may also add some "refinements" to the layout now
+}
+
+void cbRowLayoutPlugin::OnResizeRow( cbResizeRowEvent& event )
+{
+       // extract resize-event info
+       int     ofs            = event.mHandleOfs;
+       bool    forUpperHandle = event.mForUpperHandle;
+       cbRowInfo* pTheRow     = event.mpRow;
+               mpPane         = event.mpPane;
+
+    // FIXME:: Next line not used.
+       //int     newHeight      = pTheRow->mRowHeight;
+
+       int     freeSpc        = 0;
+
+       if ( forUpperHandle )
+       {
+               // calculate available free space from above,
+               // which can be obtained by squeezing not-fixed height rows
+
+               cbRowInfo* pRow = pTheRow->mpPrev;
+
+               while( pRow ) 
+               {
+                       freeSpc += pRow->mRowHeight - event.mpPane->GetMinimalRowHeight( pRow );
+
+                       pRow = pRow->mpPrev;
+               }
+       }
+       else
+       {
+               // calculate available free space from below,
+               // which can be obtained by squeezing not-fixed height rows
+
+               cbRowInfo* pRow = pTheRow->mpNext;
+
+               while( pRow ) 
+               {
+                       freeSpc += pRow->mRowHeight - mpPane->GetMinimalRowHeight( pRow );
+
+                       pRow = pRow->mpNext;
+               }
+       }
+
+       mpLayout->GetUpdatesManager().OnStartChanges();
+
+       int clientSize;
+
+       // allow user adjusting pane vs. client-area space, for upper-handle
+
+       if ( mpPane->IsHorizontal() )
+
+               clientSize = mpLayout->GetClientHeight();
+       else
+               clientSize = mpLayout->GetClientWidth();
+
+       if ( forUpperHandle && ofs < -clientSize )
+       {
+               int needed = -(ofs + clientSize);
+
+               cbRowInfo* pRow = mpPane->GetRowList()[ 0 ];
+
+               // start squeezing rows from the top row towards bottom
+
+               while( pRow != pTheRow && needed )
+               {
+                       // only not-fixed rows can be squeezed
+
+                       if ( !pRow->mHasOnlyFixedBars )
+                       {
+                               int prevHeight = pRow->mRowHeight;
+
+                               int newHeight  = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), 
+                                                                               prevHeight - needed );
+
+                               if ( newHeight != prevHeight )
+                               {
+                                       event.mpPane->SetRowHeight( pRow, newHeight );
+
+                                       needed -= prevHeight - pRow->mRowHeight;
+                               }
+                       }
+
+                       pRow = pRow->mpNext;
+               }
+       }
+
+       // allow user adjusting pane vs. client-area space, for lower-handle
+
+       if ( !forUpperHandle && ofs > clientSize )
+       {
+               int needed = ofs - clientSize;
+
+               cbRowInfo* pRow = mpPane->GetRowList()[ mpPane->GetRowList().Count() - 1 ];
+
+               // start squeezing rows from the bottom towards the top row
+
+               while( pRow && needed )
+               {
+                       // only not-fixed rows can be squeezed
+
+                       if ( !pRow->mHasOnlyFixedBars )
+                       {
+                               int prevHeight = pRow->mRowHeight;
+
+                               int newHeight  = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), 
+                                                                               prevHeight - needed );
+
+                               if ( newHeight != prevHeight )
+                               {
+                                       event.mpPane->SetRowHeight( pRow, newHeight );
+
+                                       needed -= prevHeight - pRow->mRowHeight;
+                               }
+                       }
+
+                       pRow = pRow->mpPrev;
+               }
+       }
+
+       if ( forUpperHandle )
+       
+               event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + (-ofs) );
+       else
+               event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight +   ofs  );
+
+       mpLayout->RecalcLayout(FALSE);
+
+       mpLayout->GetUpdatesManager().OnFinishChanges();
+       mpLayout->GetUpdatesManager().UpdateNow();
+}
+
diff --git a/contrib/src/fl/toolwnd.cpp b/contrib/src/fl/toolwnd.cpp
new file mode 100644 (file)
index 0000000..c59831d
--- /dev/null
@@ -0,0 +1,1146 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     06/09/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "toolwnd.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/toolwnd.h"
+
+#define _IMG_A  0xAA    // Note: modified from _A to _IMG_A, _A was already defined (cygwin)
+#define _IMG_B  0x00    // Note: modified from _B to _IMG_A, _B was already defined (cygwin)
+#define _IMG_C  0x55    // Note: modified from _C to _IMG_C, for consistency reasons.
+#define _IMG_D  0x00    // Note: modified from _D to _IMG_D, for consistency reasons.
+
+// FOR NOW:: static
+
+static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D,
+                                                                                           _IMG_A,_IMG_B,_IMG_C,_IMG_D
+                                                                                         };
+
+/***** Implementation for class wxToolWindow *****/
+
+IMPLEMENT_DYNAMIC_CLASS( wxToolWindow, wxWindow )
+
+BEGIN_EVENT_TABLE( wxToolWindow, wxWindow )
+
+       EVT_PAINT    ( wxToolWindow::OnPaint )
+       EVT_MOTION   ( wxToolWindow::OnMotion )
+       EVT_LEFT_DOWN( wxToolWindow::OnLeftDown )
+       EVT_LEFT_UP  ( wxToolWindow::OnLeftUp )
+       EVT_SIZE     ( wxToolWindow::OnSize )
+
+
+       EVT_ERASE_BACKGROUND( wxToolWindow::OnEraseBackground )
+
+END_EVENT_TABLE()
+
+enum INTERNAL_HIT_CODES
+{
+       HITS_WND_NOTHING,
+       HITS_WND_CLIENT,
+       HITS_WND_TITLE,
+
+       HITS_WND_LEFT_EDGE,
+       HITS_WND_RIGHT_EDGE,
+       HITS_WND_TOP_EDGE,
+       HITS_WND_BOTTOM_EDGE,
+
+       HITS_WND_TOP_LEFT_CORNER,
+       HITS_WND_BOTTOM_RIGHT_CORNER,
+       HITS_WND_TOP_RIGHT_CORNER,
+       HITS_WND_BOTTOM_LEFT_CORNER
+};
+
+wxToolWindow::wxToolWindow()
+
+       : mpClientWnd   ( NULL ),
+         
+#ifndef __WXMSW__
+         mTitleFont( 8, wxSWISS,  wxNORMAL, wxNORMAL ),
+#else
+         // just to simulate MS-Dev style
+         mTitleFont( 8, wxSWISS,  wxNORMAL, wxNORMAL, FALSE, "MS Sans Serif" ),
+#endif
+
+      mTitleHeight  ( 16 ),
+         mClntHorizGap ( 2 ),
+         mClntVertGap  ( 2 ),
+         mWndVertGap   ( 4 ),
+         mWndHorizGap  ( 4 ),
+
+         mButtonGap    ( 2 ),
+         mInTitleMargin( 4 ),
+         mHintBorder   ( 4 ),
+
+         mResizeStarted( FALSE ),
+         mRealTimeUpdatesOn( TRUE ),
+   
+      mMTolerance   ( 5 ), // mouse-resizing tollerance
+
+         mCursorType( HITS_WND_NOTHING ),
+         mMouseCaptured( FALSE ),
+         
+         mpScrDc( NULL )
+
+{
+}
+
+wxToolWindow::~wxToolWindow()
+{
+       if ( mpScrDc ) delete mpScrDc; 
+
+       for( size_t i = 0; i != mButtons.Count(); ++i )
+               
+               delete mButtons[i];
+}
+
+void wxToolWindow::LayoutMiniButtons()
+{                                        
+       int w,h;
+
+       GetSize( &w, &h );
+
+       int x = w - mWndHorizGap - mInTitleMargin - BTN_BOX_WIDTH; 
+       int y = mWndVertGap + 2;
+
+       for( size_t i = 0; i != mButtons.Count(); ++i )
+       {
+               mButtons[i]->SetPos( wxPoint( x,y ) );
+               x-= BTN_BOX_WIDTH + mButtonGap;
+       }
+}
+
+void wxToolWindow::SetClient( wxWindow* pWnd )
+{
+       mpClientWnd = pWnd;
+}
+
+wxWindow* wxToolWindow::GetClient()
+{
+       return mpClientWnd;
+}
+
+void wxToolWindow::SetTitleFont( wxFont& font )
+{
+       mTitleFont = font;
+}
+
+void wxToolWindow::AddMiniButton( cbMiniButton* pBtn )
+{
+       pBtn->mpWnd = this;
+
+       mButtons.Add( pBtn );
+
+       // not necesserely now..
+       //LayoutMiniButtons();
+}
+
+void wxToolWindow::OnPaint( wxPaintEvent& event )
+{
+    wxPaintDC pdc( this );
+       wxWindowDC dc( this );
+
+       int w,h;
+       GetSize( &w, &h );
+
+       dc.SetBrush( *wxLIGHT_GREY_BRUSH );
+       dc.SetPen( *wxTRANSPARENT_PEN );
+
+       int y = mWndVertGap + mTitleHeight + mClntVertGap + 1;
+       dc.DrawRectangle( 0,0, w, y );
+       dc.DrawRectangle( 0,y-1, mWndHorizGap + mClntHorizGap + 1, h - y );
+       dc.DrawRectangle( w - ( mWndHorizGap + mClntHorizGap ), y-1,
+                                         mWndHorizGap + mClntHorizGap, h - y );
+       dc.DrawRectangle( 0, h - mWndVertGap - mClntVertGap, w, mWndVertGap + mClntVertGap );
+
+       // draw shades
+       dc.SetPen( *wxLIGHT_GREY_PEN );
+
+       dc.DrawLine( 0,0, w, 0 );
+       dc.DrawLine( 0,0, 0, h );
+
+       dc.SetPen( *wxWHITE_PEN );
+
+       dc.DrawLine( 1,1, w, 1 );
+       dc.DrawLine( 1,2, 1, h );
+
+       dc.SetPen( *wxGREY_PEN );
+
+       dc.DrawLine( w - 2, 1, w - 2, h - 1 );
+       dc.DrawLine( 1, h - 2, w - 2, h - 2 );
+
+       dc.SetPen( *wxBLACK_PEN );
+
+       dc.DrawLine( 0, h - 1, w, h - 1 );
+       dc.DrawLine( w-1, 0, w-1, h );
+
+       // fill inner area
+
+       dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( wxColour( 0,0,128 ), wxSOLID ) );
+
+       dc.DrawRectangle( mWndHorizGap, mWndVertGap, w - mWndHorizGap*2, mTitleHeight );
+
+       dc.SetFont( mTitleFont );
+
+       for( size_t i = 0; i != mButtons.Count(); ++i )
+
+               mButtons[i]->Draw( dc );
+
+       int x1 = mWndHorizGap + mClntHorizGap;
+       int x2 = mButtons[ mButtons.GetCount() - 1 ]->mPos.x - mClntHorizGap*2;
+
+       dc.SetClippingRegion( x1, mWndVertGap + mClntVertGap, x2 - x1, mTitleHeight );
+
+       dc.SetTextForeground( *wxWHITE );
+       dc.SetBackgroundMode(  wxTRANSPARENT );
+       dc.DrawText( GetTitle(), mWndHorizGap + 2, mWndVertGap + 1 );
+}
+
+void wxToolWindow::GetScrWindowRect( wxRect& r )
+{
+       int x,y;
+       GetPosition(&x,&y);
+       int w,h;
+       GetSize( &w, &h );
+
+       r.x = x; r.y = y;
+       r.width = w; r.height = h;
+}
+
+void wxToolWindow::GetScrMousePos( wxMouseEvent& event, wxPoint& pos )
+{
+       int x = event.m_x, y = event.m_y;
+
+       ClientToScreen( &x, &y );
+
+       pos.x = x; pos.y = y;
+}
+
+int wxToolWindow::HitTestWindow( wxMouseEvent& event )
+{
+       wxPoint pos;
+       wxRect r;
+
+       GetScrMousePos( event, pos );
+       GetScrWindowRect( r );
+
+       int k = mMTolerance;
+
+       if ( !( pos.x >= r.x && pos.y >= r.y &&
+                   pos.x < r.x + r.width &&
+                   pos.y < r.y + r.height ) 
+          )
+          return HITS_WND_NOTHING; 
+
+       if ( pos.y <= r.y + k )
+       {
+               if ( pos.x < r.x + k*2 )
+
+                       return HITS_WND_TOP_LEFT_CORNER;
+               else
+               if ( pos.x >= r.x + r.width - k*2 )
+
+                       return HITS_WND_TOP_RIGHT_CORNER;
+               else
+                       return HITS_WND_TOP_EDGE;
+       }
+       else
+       if ( pos.y >= r.y + r.height - k )
+       {
+               if ( pos.x < r.x + k*2 )
+
+                       return HITS_WND_BOTTOM_LEFT_CORNER;
+               else
+               if ( pos.x > r.x + r.width - k*2 )
+
+                       return HITS_WND_BOTTOM_RIGHT_CORNER;
+               else
+                       return HITS_WND_BOTTOM_EDGE;
+       }
+       else
+       if ( pos.x <= r.x + k )
+       
+               return HITS_WND_LEFT_EDGE;
+       else
+       if ( pos.x >= r.x + r.width - k )
+
+               return HITS_WND_RIGHT_EDGE;
+       else
+       {
+               if ( pos.y <= r.y + mWndVertGap + mTitleHeight + mClntVertGap )
+
+                       return HITS_WND_TITLE;
+               else
+                       return HITS_WND_CLIENT;
+       }
+}
+
+void wxToolWindow::DrawHintRect( const wxRect& r )
+{
+       // BUG BUG BUG (wx):: somehow stippled brush works only  
+       //                                        when the bitmap created on stack, not
+       //                                        as a member of the class
+
+       int prevLF = mpScrDc->GetLogicalFunction();
+
+       mpScrDc->SetLogicalFunction( wxXOR );
+
+       wxBitmap checker( (const char*)_gCheckerImg, 8,8 );
+
+       wxBrush checkerBrush( checker );
+
+       mpScrDc->SetPen( *wxTRANSPARENT_PEN );
+       mpScrDc->SetBrush( checkerBrush );
+
+       int half = mHintBorder / 2;
+
+       mpScrDc->DrawRectangle( r.x - half, r.y - half,
+                                       r.width + 2*half, mHintBorder );
+
+       mpScrDc->DrawRectangle( r.x - half, r.y + r.height - half,
+                                       r.width + 2*half, mHintBorder );
+
+       mpScrDc->DrawRectangle( r.x - half, r.y + half - 1,
+                                       mHintBorder, r.height - 2*half + 2);
+
+       mpScrDc->DrawRectangle( r.x + r.width - half,
+                                                       r.y + half - 1,
+                                       mHintBorder, r.height - 2*half + 2);
+
+       mpScrDc->SetBrush( wxNullBrush );
+
+       mpScrDc->SetLogicalFunction( prevLF );
+}
+
+void wxToolWindow::SetHintCursor( int type )
+{
+       if ( mResizeStarted ) return;
+
+       if ( type == HITS_WND_NOTHING || type == HITS_WND_CLIENT )
+       {
+               // the cursor is out of window - reset to arrow
+
+               if ( mMouseCaptured && !mResizeStarted )
+               {
+                       ReleaseMouse();
+                       mMouseCaptured = FALSE;
+               }
+
+               if ( mCursorType == HITS_WND_NOTHING && !mResizeStarted )
+
+                       SetCursor( wxCURSOR_ARROW );
+
+               mCursorType = type;
+
+               return;
+       }
+
+       if ( !mMouseCaptured )
+       {
+               mMouseCaptured = TRUE;
+               CaptureMouse();
+       }
+
+       // did the cursor actually changed?
+       
+       if ( type != mCursorType )
+       {
+               mCursorType = type;
+
+               switch ( type )
+               {
+                       case HITS_WND_LEFT_EDGE   : SetCursor( wxCURSOR_SIZEWE ); break;
+                       case HITS_WND_RIGHT_EDGE  : SetCursor( wxCURSOR_SIZEWE ); break;
+                       case HITS_WND_TOP_EDGE    : SetCursor( wxCURSOR_SIZENS ); break;
+                       case HITS_WND_BOTTOM_EDGE : SetCursor( wxCURSOR_SIZENS ); break;
+
+                       case HITS_WND_TOP_LEFT_CORNER     : SetCursor( wxCURSOR_SIZENWSE ); break;
+                       case HITS_WND_BOTTOM_RIGHT_CORNER : SetCursor( wxCURSOR_SIZENWSE ); break;
+                       case HITS_WND_TOP_RIGHT_CORNER    : SetCursor( wxCURSOR_SIZENESW ); break;
+                       case HITS_WND_BOTTOM_LEFT_CORNER  : SetCursor( wxCURSOR_SIZENESW ); break;
+
+                       case HITS_WND_TITLE  : SetCursor( wxCURSOR_ARROW ); break;
+                       case HITS_WND_CLIENT : SetCursor( wxCURSOR_ARROW ); break;
+
+                       default: break; 
+               }
+       }
+}
+
+#define INFINITY 32768
+
+static inline void clip_to( int& value, long from, long till )
+{
+       if ( value < from ) 
+               value = from;
+
+       if ( value > till ) 
+               value = till;
+}
+
+void wxToolWindow::AdjustRectPos( const wxRect& original, const wxSize& newDim, wxRect& newRect )
+{
+       if ( mCursorType == HITS_WND_TOP_EDGE || 
+                mCursorType == HITS_WND_TOP_LEFT_CORNER )
+       {
+               newRect.x = original.x + original.width  - newDim.x;
+               newRect.y = original.y + original.height - newDim.y;
+       }
+       else
+       if ( mCursorType == HITS_WND_LEFT_EDGE || 
+                mCursorType == HITS_WND_BOTTOM_LEFT_CORNER )
+       {
+               newRect.x = original.x + original.width  - newDim.x;
+               newRect.y = original.y;
+       }
+       else
+       if ( mCursorType == HITS_WND_RIGHT_EDGE || 
+                mCursorType == HITS_WND_TOP_RIGHT_CORNER )
+       {
+               newRect.x = original.x;
+               newRect.y = original.y + original.height - newDim.y;
+       }
+       else
+       if ( mCursorType == HITS_WND_BOTTOM_EDGE || 
+                mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER )
+       {
+               newRect.x = original.x;
+               newRect.y = original.y;
+       }
+
+       newRect.width  = newDim.x;
+       newRect.height = newDim.y;
+}
+
+void wxToolWindow::CalcResizedRect( wxRect& rect, wxPoint& delta, const wxSize& minDim )
+{
+       // Microsoft's rect-coordinates are best suited
+       // for the case of corner-clipping
+       
+       int left   = mInitialRect.x;
+       int top    = mInitialRect.y;
+       int right  = mInitialRect.x + mInitialRect.width;
+       int bottom = mInitialRect.y + mInitialRect.height;
+
+       // constraint delta edge is dragged
+
+       switch ( mCursorType )
+       {
+               case HITS_WND_LEFT_EDGE   : delta.y = 0; break;
+               case HITS_WND_RIGHT_EDGE  : delta.y = 0; break;
+               case HITS_WND_TOP_EDGE    : delta.x = 0; break;
+               case HITS_WND_BOTTOM_EDGE : delta.x = 0; break;
+               default: break;
+       }
+
+       if ( mCursorType == HITS_WND_TOP_EDGE || 
+                mCursorType == HITS_WND_TOP_LEFT_CORNER )
+       {
+               left += delta.x;
+               top  += delta.y;
+
+               clip_to( left, -INFINITY, mInitialRect.x + mInitialRect.width  - minDim.x  );
+               clip_to( top,  -INFINITY, mInitialRect.y + mInitialRect.height - minDim.y );
+       }
+       else
+       if ( mCursorType == HITS_WND_LEFT_EDGE || 
+                mCursorType == HITS_WND_BOTTOM_LEFT_CORNER )
+       {
+               left   += delta.x;
+               bottom += delta.y;
+
+               clip_to( left,    -INFINITY, mInitialRect.x + mInitialRect.width  - minDim.x  );
+               clip_to( bottom,  mInitialRect.y + minDim.y, INFINITY );
+       }
+       else
+       if ( mCursorType == HITS_WND_RIGHT_EDGE || 
+                mCursorType == HITS_WND_TOP_RIGHT_CORNER )
+       {
+               right += delta.x;
+               top   += delta.y;
+
+               clip_to( right, mInitialRect.x + minDim.x, INFINITY );
+               clip_to( top,   -INFINITY, mInitialRect.y + mInitialRect.height - minDim.y );
+       }
+       else
+       if ( mCursorType == HITS_WND_BOTTOM_EDGE || 
+                mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER )
+       {
+               right  += delta.x;
+               bottom += delta.y;
+
+               clip_to( right,  mInitialRect.x + minDim.x,  INFINITY );
+               clip_to( bottom, mInitialRect.y + minDim.y, INFINITY );
+       }
+       else
+       {
+               int avoidCompilerWarning = 0;
+               wxASSERT(avoidCompilerWarning); // DBG::
+       }
+
+       rect.x = left;
+       rect.y = top;
+       rect.width  = right - left;
+       rect.height = bottom - top;
+}
+
+wxSize wxToolWindow::GetMinimalWndDim()
+{
+       return wxSize( (mWndHorizGap + mClntHorizGap)*2 + BTN_BOX_WIDTH*4,
+                          (mWndVertGap  + mClntVertGap )*2 + mTitleHeight );
+}
+
+void wxToolWindow::OnMotion( wxMouseEvent& event )
+{
+       if ( !mResizeStarted )
+       {
+               for( size_t i = 0; i != mButtons.Count(); ++i )
+               
+                       mButtons[i]->OnMotion( wxPoint( event.m_x, event.m_y ) );
+
+               SetHintCursor( HitTestWindow( event ) );
+               return;
+       }
+
+       wxPoint pos;
+       GetScrMousePos( event, pos );
+
+       if ( mCursorType == HITS_WND_TITLE )
+       {
+               int w,h;
+               GetSize( &w, &h );
+
+               SetSize( mInitialRect.x + pos.x - mDragOrigin.x,
+                                mInitialRect.y + pos.y - mDragOrigin.y,
+                                w,h, 0 );
+       }
+
+       else
+       {
+               wxPoint delta( pos.x - mDragOrigin.x, pos.y - mDragOrigin.y );
+
+               wxRect newRect;
+
+               wxSize minDim = GetMinimalWndDim();
+
+               CalcResizedRect( newRect, delta, minDim );
+
+               wxSize borderDim( ( mWndHorizGap + mClntHorizGap )*2,
+                                     ( mWndVertGap  + mClntVertGap  )*2 + mTitleHeight );
+
+               wxSize preferred = GetPreferredSize( wxSize( newRect.width  - borderDim.x, 
+                                                                newRect.height - borderDim.y ) );
+
+               preferred.x += borderDim.x;
+               preferred.y += borderDim.y;
+
+               //CalcResizedRect( newRect, delta, preferred );
+
+               wxRect finalRect = newRect;
+
+               AdjustRectPos( newRect, preferred, finalRect );
+
+               if ( mRealTimeUpdatesOn )
+               {
+                               SetSize( finalRect.x, finalRect.y,
+                                                finalRect.width, finalRect.height, 0 );
+               }
+               else
+               {
+                       DrawHintRect( mPrevHintRect );
+                       DrawHintRect( finalRect );
+               }
+
+               mPrevHintRect = finalRect;
+       }
+}
+
+void wxToolWindow::OnLeftDown( wxMouseEvent& event )
+{
+       int result = HitTestWindow( event );
+
+       for( size_t i = 0; i != mButtons.Count(); ++i )
+       {
+               mButtons[i]->OnLeftDown( wxPoint( event.m_x, event.m_y ) );
+
+               if ( mButtons[i]->IsPressed() ) 
+
+                       return; // button hitted, 
+       }
+
+       if ( result >= HITS_WND_LEFT_EDGE || result == HITS_WND_TITLE )
+       {
+               GetScrMousePos( event, mDragOrigin );
+
+               /*
+               if ( mMouseCaptured `)
+               {
+                       ReleaseMouse();
+                       mMouseCaptured = FALSE;
+               }*/
+
+               if ( result == HITS_WND_TITLE && 
+                        HandleTitleClick( event )
+                  )
+               {
+
+                  return;
+               }
+
+               mResizeStarted = TRUE;
+
+               int x,y;
+               GetPosition( &x, &y );
+
+               mInitialRect.x = x;
+               mInitialRect.y = y;
+
+               GetSize( &x, &y );
+               mInitialRect.width  = x;
+               mInitialRect.height = y;
+
+               mPrevHintRect = mInitialRect;
+
+               if ( mCursorType != HITS_WND_TITLE && !mRealTimeUpdatesOn )
+               {
+                       mpScrDc = new wxScreenDC();
+
+                       wxScreenDC::StartDrawingOnTop( (wxRect*)NULL );
+
+                       DrawHintRect( mInitialRect );
+               }
+       }
+}
+
+void wxToolWindow::OnLeftUp( wxMouseEvent& event )
+{
+       for( size_t i = 0; i != mButtons.Count(); ++i )
+       {
+               mButtons[i]->OnLeftUp( wxPoint( event.m_x, event.m_y ) );
+
+               if ( mButtons[i]->WasClicked() )
+               {
+                       OnMiniButtonClicked( i ); // notify derived classes
+                       mButtons[i]->Reset();
+               }
+       }
+
+       if ( mResizeStarted ) 
+       {
+               mResizeStarted = FALSE;
+
+               if ( mCursorType != HITS_WND_TITLE )
+               {
+                       if ( !mRealTimeUpdatesOn )
+                       {
+                               DrawHintRect( mPrevHintRect );
+
+                               wxScreenDC::EndDrawingOnTop();
+
+                               delete mpScrDc;
+
+                               mpScrDc = NULL;
+
+                               SetSize( mPrevHintRect.x, mPrevHintRect.y,
+                                                mPrevHintRect.width, mPrevHintRect.height, 0 );
+                       }
+               }
+       }
+}
+
+void wxToolWindow::OnSize( wxSizeEvent& event )
+{
+       if ( mpClientWnd )
+       {
+               int w,h;
+               GetSize( &w, &h );
+
+               int x = mWndHorizGap + mClntHorizGap;
+               int y = mWndVertGap  + mTitleHeight + mClntVertGap;
+
+#if 1
+               mpClientWnd->SetSize( x -1, y -1, 
+                                                         w - 2*(mWndHorizGap + mClntHorizGap),
+                                                         h - y - mClntVertGap - mWndVertGap, 
+                                                         0  
+                                                       );
+#endif
+       }
+
+       LayoutMiniButtons();
+}
+
+wxSize wxToolWindow::GetPreferredSize( const wxSize& given )
+{
+       return given;
+}
+
+void wxToolWindow::OnEraseBackground( wxEraseEvent& event )
+{
+       // nothing
+}
+
+/***** Implementation for class cbMiniButton *****/
+
+cbMiniButton::cbMiniButton()
+
+       : mVisible( TRUE ),
+         mEnabled( TRUE ),
+
+         mpLayout( NULL ),
+         mpPane  ( NULL ),
+         mpPlugin( NULL ),
+         mpWnd   ( NULL ),
+
+         mWasClicked( FALSE ),
+         mDragStarted( FALSE ),
+         mPressed( FALSE )
+{}
+
+void cbMiniButton::SetPos( const wxPoint& pos )
+{
+       mPos = pos;
+}
+
+bool cbMiniButton::HitTest( const wxPoint& pos )
+{
+       if ( !mVisible ) return FALSE;
+
+       return ( pos.x >= mPos.x && pos.y >= mPos.y &&
+                    pos.x < mPos.x + BTN_BOX_WIDTH     &&
+                        pos.y < mPos.y + BTN_BOX_HEIGHT );
+}
+
+void cbMiniButton::OnLeftDown( const wxPoint& pos )
+{
+       if ( !mVisible || mDragStarted ) return;
+
+       if ( HitTest( pos ) && mEnabled )
+       {
+               if ( mpPlugin )
+               {
+                       mpLayout->CaptureEventsForPane( mpPane );
+                       mpLayout->CaptureEventsForPlugin( mpPlugin );
+               }
+               else
+                       mpWnd->CaptureMouse();
+
+               mDragStarted = TRUE;
+               mPressed     = TRUE;
+               mWasClicked  = FALSE;
+
+               Refresh();
+       }
+}
+
+void cbMiniButton::OnLeftUp( const wxPoint& pos )
+{
+       if ( !mVisible || !mDragStarted ) return;
+
+       if ( mpPlugin )
+       {
+               mpLayout->ReleaseEventsFromPane( mpPane );
+               mpLayout->ReleaseEventsFromPlugin( mpPlugin );
+       }
+       else
+               mpWnd->ReleaseMouse();
+
+       mWasClicked  = mPressed;
+       mDragStarted = FALSE;
+
+       mPressed = FALSE;
+       Refresh();
+}
+
+void cbMiniButton::OnMotion( const wxPoint& pos )
+{
+       if ( !mVisible ) return;
+
+       if ( mDragStarted )
+       {
+               mPressed = HitTest( pos );
+
+               Refresh();
+       }
+}
+
+void cbMiniButton::Refresh()
+{
+       if ( mpLayout )
+       {
+               wxClientDC dc( &mpLayout->GetParentFrame() );
+
+               Draw( dc );
+       }
+       else
+       {
+               wxWindowDC dc( mpWnd );
+
+               Draw( dc );
+       }
+}
+
+void cbMiniButton::Draw( wxDC& dc )
+{
+       if ( !mVisible ) return;
+
+       dc.SetPen( *wxTRANSPARENT_PEN );
+
+       dc.SetBrush( *wxLIGHT_GREY_BRUSH );
+
+       dc.DrawRectangle( mPos.x + 1, mPos.y + 1, BTN_BOX_WIDTH - 2, BTN_BOX_HEIGHT - 2 );
+
+       // "hard-code" metafile
+
+       if ( !mPressed )
+
+               dc.SetPen( *wxWHITE_PEN );
+       else
+               dc.SetPen( *wxBLACK_PEN );
+
+       dc.DrawLine( mPos.x, mPos.y, mPos.x + BTN_BOX_WIDTH, mPos.y );
+       dc.DrawLine( mPos.x, mPos.y, mPos.x, mPos.y + BTN_BOX_HEIGHT );
+
+       dc.SetPen( *wxGREY_PEN );
+
+       if ( !mPressed )
+       {
+               dc.DrawLine( mPos.x + 1, mPos.y + BTN_BOX_HEIGHT - 2, 
+                                        mPos.x + BTN_BOX_WIDTH - 1, mPos.y + BTN_BOX_HEIGHT - 2 );
+               
+               dc.DrawLine( mPos.x + BTN_BOX_WIDTH - 2, mPos.y + 1, 
+                                        mPos.x + BTN_BOX_WIDTH - 2, mPos.y + BTN_BOX_HEIGHT - 1 );
+       }
+       else
+       {
+               dc.DrawLine( mPos.x + 1, mPos.y + 1, 
+                                mPos.x + BTN_BOX_WIDTH - 2, mPos.y + 1 );
+                                        
+               dc.DrawLine( mPos.x + 1, mPos.y + 1,
+                                mPos.x + 1, mPos.y + BTN_BOX_HEIGHT - 2 );
+       }
+
+       if ( !mPressed )
+
+               dc.SetPen( *wxBLACK_PEN );
+       else
+               dc.SetPen( *wxWHITE_PEN );
+
+       dc.DrawLine( mPos.x, mPos.y + BTN_BOX_HEIGHT - 1,  
+                        mPos.x + BTN_BOX_WIDTH, mPos.y + BTN_BOX_HEIGHT - 1 );
+
+       dc.DrawLine( mPos.x + BTN_BOX_WIDTH - 1, mPos.y ,
+                        mPos.x + BTN_BOX_WIDTH - 1, mPos.y + BTN_BOX_HEIGHT );
+}
+
+bool cbMiniButton::WasClicked() 
+{ 
+       return mWasClicked; 
+}
+
+void cbMiniButton::Reset() 
+{ 
+       mWasClicked = FALSE; 
+}
+
+/***** Implementation fro class cbCloseBox *****/
+
+void cbCloseBox::Draw( wxDC& dc )
+{
+#ifdef __WXGTK__
+
+    cbMiniButton::Draw( dc );
+    
+    wxPen pen( wxColour( 64,64,64 ) ,1, wxSOLID );
+    
+    dc.SetPen( pen );
+    
+    int width = BTN_BOX_WIDTH - 7;
+    
+    int xOfs = (mPressed) ? 4 : 3;
+    int yOfs = (mPressed) ? 4 : 3;     
+
+    int one = 1;
+    for( int i = 0; i != BTN_X_WIEGHT; ++i )
+    {
+        dc.DrawLine( mPos.x + xOfs + i - one,
+                     mPos.y + yOfs - one,
+                     mPos.x + xOfs + i + width,
+                     mPos.y + yOfs + width  + one);
+    
+        dc.DrawLine( mPos.x + xOfs + i + width ,
+                     mPos.y + yOfs - one - one,
+                     mPos.x + xOfs + i - one,
+                     mPos.y + yOfs + width );
+    }
+    
+#else
+
+       cbMiniButton::Draw( dc );
+
+       dc.SetPen( *wxBLACK_PEN );
+
+       int width = BTN_BOX_WIDTH - 7;
+
+       int xOfs = (mPressed) ? 4 : 3;
+       int yOfs = (mPressed) ? 4 : 3;
+
+       for( int i = 0; i != BTN_X_WIEGHT; ++i )
+       {
+               dc.DrawLine( mPos.x + xOfs + i,
+                                mPos.y + yOfs,
+                                        mPos.x + xOfs + i + width,
+                                        mPos.y + yOfs + width );
+
+               dc.DrawLine( mPos.x + xOfs + i + width - 1,
+                                mPos.y + yOfs,
+                                        mPos.x + xOfs + i - 1,
+                                        mPos.y + yOfs + width );
+       }
+
+#endif
+
+}
+
+/***** Implementation fro class cbCollapseBox *****/
+
+inline static void my_swap( int& a, int& b )
+{
+       long tmp = a;
+       a = b;
+       b = tmp;
+}
+
+void cbCollapseBox::Draw( wxDC& dc )
+{
+       cbMiniButton::Draw( dc );
+
+       dc.SetPen( *wxTRANSPARENT_PEN );
+
+       wxPoint arr[3];
+
+       int yOfs  = (mPressed) ? 3 : 2;
+       int xOfs  = (mPressed) ? 5 : 4;
+       int width = BTN_BOX_WIDTH - 8;
+
+       // rotating/shifting triangle inside collapse box
+
+       arr[0].x = xOfs;
+       arr[0].y = yOfs-1;
+       arr[2].x = xOfs;
+       arr[2].y = BTN_BOX_HEIGHT - yOfs - 1;
+       arr[1].x = xOfs + width;
+       arr[1].y = (arr[2].y + arr[0].y)/2;
+
+       if ( !mIsAtLeft )
+       {
+               arr[0].x = BTN_BOX_WIDTH - arr[0].x;
+               arr[1].x = BTN_BOX_WIDTH - arr[1].x;
+               arr[2].x = BTN_BOX_WIDTH - arr[2].x;
+       }
+
+       if ( !mpPane->IsHorizontal() )
+       {
+               my_swap( arr[0].y, arr[0].x );
+               my_swap( arr[1].y, arr[1].x );
+               my_swap( arr[2].y, arr[2].x );
+
+               arr[0].x += 1;
+               arr[1].x += 1;
+               arr[2].x += 1;
+
+               //arr[1].y -= 1;
+       }
+
+       arr[0].x += mPos.x;
+       arr[0].y += mPos.y;
+       arr[1].x += mPos.x;
+       arr[1].y += mPos.y;
+       arr[2].x += mPos.x;
+       arr[2].y += mPos.y;
+
+       if ( !mEnabled ) dc.SetBrush( *wxGREY_BRUSH );
+                               else dc.SetBrush( *wxBLACK_BRUSH );
+
+       dc.DrawPolygon( 3, arr );
+       dc.SetBrush( wxNullBrush );
+}
+
+/***** Implementation for class cbDockBoxBox *****/
+
+void cbDockBox::Draw( wxDC& dc )
+{
+       cbMiniButton::Draw( dc );
+
+       int width = BTN_BOX_WIDTH - 7;
+
+       int xOfs = (mPressed) ? 4 : 3;
+       int yOfs = (mPressed) ? 4 : 3;
+
+       dc.SetPen( *wxBLACK_PEN );
+       dc.SetBrush( *wxBLACK_BRUSH );
+
+       dc.DrawRectangle( mPos.x + xOfs, mPos.y + yOfs, width, width );
+
+       xOfs += 1;
+       yOfs += 1;
+
+       dc.SetBrush( *wxWHITE_BRUSH );
+
+       dc.DrawRectangle( mPos.x + xOfs, mPos.y + yOfs, width-2, width-2 );
+}
+
+/***** Implementation for class wxToolWindow *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbFloatedBarWindow, wxToolWindow )
+
+BEGIN_EVENT_TABLE( cbFloatedBarWindow, wxToolWindow )
+
+       EVT_LEFT_DCLICK( cbFloatedBarWindow::OnDblClick )
+
+END_EVENT_TABLE()
+
+cbFloatedBarWindow::cbFloatedBarWindow()
+
+       : mpBar( NULL )
+{
+       AddMiniButton( new cbCloseBox() );
+       AddMiniButton( new cbDockBox()  );
+}
+
+void cbFloatedBarWindow::SetBar( cbBarInfo* pBar )
+{
+       mpBar = pBar;
+}
+
+cbBarInfo* cbFloatedBarWindow::GetBar()
+{
+       return mpBar;
+}
+
+void cbFloatedBarWindow::SetLayout( wxFrameLayout* pLayout )
+{
+       mpLayout = pLayout;
+}
+
+void cbFloatedBarWindow::PositionFloatedWnd( int scrX,  int scrY,
+                                                                                        int width, int height )
+{
+       wxSize minDim = GetMinimalWndDim();
+
+       SetSize( scrX - mWndHorizGap - mClntHorizGap, 
+                    scrY - mClntVertGap - mTitleHeight - mWndVertGap, 
+                        width + minDim.x, height + minDim.y, 0 );
+}
+
+wxSize cbFloatedBarWindow::GetPreferredSize( const wxSize& given )
+{
+       if ( mpBar->mDimInfo.GetDimHandler() )
+       {
+
+               cbBarDimHandlerBase* pHandler = mpBar->mDimInfo.GetDimHandler();
+
+               wxSize prefDim;
+
+               // int vtad = *((int*)pHandler);
+
+               pHandler->OnResizeBar( mpBar, given, prefDim );
+
+               return prefDim;
+       }
+       else
+       {
+               if ( mpBar->IsFixed() ) 
+
+                       return mpBar->mDimInfo.mSizes[ wxCBAR_FLOATING ];
+               else
+                       return given; // not-fixed bars are resized exactly the way user wants
+       }
+}
+
+void cbFloatedBarWindow::OnMiniButtonClicked( int btnIdx )
+{
+       // #1 - close mini-button
+       // #0 - dock mini-button
+
+       if ( btnIdx == 0 )
+       {
+               mpBar->mAlignment = -1; // sepcial "marking" for hidden bars out of floated state
+               mpLayout->SetBarState( mpBar, wxCBAR_HIDDEN, TRUE );
+       }
+       else
+               mpLayout->SetBarState( mpBar, wxCBAR_DOCKED_HORIZONTALLY, TRUE );
+}
+
+bool cbFloatedBarWindow::HandleTitleClick( wxMouseEvent& event )
+{
+       ReleaseMouse();
+       mMouseCaptured = FALSE;
+
+       wxPoint scrPos;
+       GetScrMousePos( event, scrPos );
+
+       int msX = scrPos.x,
+               msY = scrPos.y;
+
+       mpLayout->GetParentFrame().ScreenToClient( &msX, &msY );
+
+       int x,y;
+       GetPosition(&x,&y);
+       int w,h;
+       GetSize( &w, &h );
+
+       wxSize minDim = GetMinimalWndDim();
+
+       w -= minDim.x;
+       h -= minDim.y;
+
+       x += mWndHorizGap + mClntHorizGap;
+       y += mWndVertGap  + mTitleHeight + mClntVertGap;
+
+       mpLayout->GetParentFrame().ScreenToClient( &x, &y );
+
+       wxRect& bounds = mpBar->mDimInfo.mBounds[ wxCBAR_FLOATING ];
+
+       bounds.x = x;
+       bounds.y = y;
+       bounds.width  = w;
+       bounds.height = h;
+
+       cbStartBarDraggingEvent dragEvt( mpBar, wxPoint(msX,msY), 
+                                            mpLayout->GetPanesArray()[FL_ALIGN_TOP] );
+                       
+       mpLayout->FirePluginEvent( dragEvt );
+
+       return TRUE;
+}
+
+void cbFloatedBarWindow::OnDblClick( wxMouseEvent& event )
+{
+       mpLayout->SetBarState( mpBar, wxCBAR_DOCKED_HORIZONTALLY, TRUE );
+
+       //wxMessageBox("toolWnd - dblClick!");
+}
+
diff --git a/contrib/src/fl/updatesmgr.cpp b/contrib/src/fl/updatesmgr.cpp
new file mode 100644 (file)
index 0000000..c742670
--- /dev/null
@@ -0,0 +1,291 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        No names yet.
+// Purpose:     Contrib. demo
+// Author:      Aleksandras Gluchovas
+// Modified by:
+// Created:     19/10/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Aleksandras Gluchovas 
+// Licence:    wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+    #pragma implementation "updatesmgr.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+#include "wx/fl/updatesmgr.h"
+
+// helper function
+
+static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 )
+{
+       if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) ||
+                ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) )
+
+               if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) ||
+                        ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) )
+                        
+                       return 1;
+
+       return 0;
+}
+
+/***** Implementation for class cbSimpleUpdatesMgr *****/
+
+IMPLEMENT_DYNAMIC_CLASS( cbSimpleUpdatesMgr, cbUpdatesManagerBase )
+
+cbSimpleUpdatesMgr::cbSimpleUpdatesMgr( wxFrameLayout* pPanel )
+       : cbUpdatesManagerBase( pPanel )
+{}
+
+bool cbSimpleUpdatesMgr::WasChanged( cbUpdateMgrData& data, wxRect& currentBounds )
+{
+       return (   data.IsDirty() ||
+
+                    ( data.mPrevBounds.x      != currentBounds.x     ||
+                      data.mPrevBounds.y      != currentBounds.y     ||
+                          data.mPrevBounds.width  != currentBounds.width ||
+                          data.mPrevBounds.height != currentBounds.height  )
+                  );
+}
+
+void cbSimpleUpdatesMgr::OnStartChanges()
+{
+       // memorize states of ALL items in the layout -
+       // this is quite excessive, but OK for the simple 
+       // implementation of updates manager
+
+       mpLayout->GetPrevClientRect() = mpLayout->GetClientRect();
+
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+       for( int n = 0; n != MAX_PANES; ++n )
+       {
+               cbDockPane& pane = *panes[n];
+               // store pane state
+               pane.mUMgrData.StoreItemState( pane.mBoundsInParent );
+               pane.mUMgrData.SetDirty( FALSE );
+
+               for( size_t i = 0; i != pane.GetRowList().Count(); ++i )
+               {
+                       cbRowInfo& row = *pane.GetRowList()[ i ];
+
+                       // store row state
+                       row.mUMgrData.StoreItemState( row.mBoundsInParent );
+                       row.mUMgrData.SetDirty( FALSE );
+
+                       for( size_t k = 0; k != row.mBars.Count(); ++k )
+                       {
+                               cbBarInfo& bar = *row.mBars[ k ];
+
+                               // store bar state
+                               bar.mUMgrData.StoreItemState( bar.mBoundsInParent );
+                               bar.mUMgrData.SetDirty( FALSE );
+                       }
+               }
+       }
+}
+
+void cbSimpleUpdatesMgr::OnFinishChanges()
+{
+       // nothing here, could be overriden by more sophisticated updates-managers
+}
+
+void cbSimpleUpdatesMgr::OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane )
+{
+       // -/-
+}
+
+void cbSimpleUpdatesMgr::OnBarWillChange( cbBarInfo* pBar, 
+                                                                                 cbRowInfo* pInRow, cbDockPane* pInPane )
+{
+       // -/-
+}
+
+void cbSimpleUpdatesMgr::OnPaneMarginsWillChange( cbDockPane* pPane )
+{
+       // -/-
+}
+
+void cbSimpleUpdatesMgr::OnPaneWillChange( cbDockPane* pPane )
+{
+       // -/-
+}
+
+void cbSimpleUpdatesMgr::UpdateNow()
+{
+       cbDockPane** panes = mpLayout->GetPanesArray();
+
+       wxRect& r1 = mpLayout->GetClientRect();
+       wxRect& r2 = mpLayout->GetPrevClientRect();
+
+       // detect changes in client window's area
+
+       bool clientWindowChanged = ( r1.x      != r2.x     ||
+                                        r1.y      != r2.y     ||
+                                                                r1.width  != r2.width ||
+                                                                r1.height != r2.height );
+
+       // step #1 - detect changes in each row of each pane,
+       //           and repaint decorations around changed windows
+
+       wxList mBarsToRefresh;
+       wxList mPanesList;
+
+       for( int n = 0; n != MAX_PANES; ++n )
+       {
+               cbDockPane& pane = *(panes[n]);
+
+               bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent );
+
+               if ( paneChanged )
+               {
+                       wxClientDC dc( &mpLayout->GetParentFrame() );
+                       pane.PaintPaneBackground( dc );
+               }
+
+               wxRect realBounds;
+
+               for( size_t i = 0; i != pane.GetRowList().Count(); ++i )
+               {
+                       cbRowInfo& row = *pane.GetRowList()[ i ];
+
+                       wxDC* pDc = NULL;
+
+                       bool rowChanged = FALSE;
+
+                       // FIXME:: the below should not be fixed
+                       cbBarInfo* barsToRepaint[256];
+
+                       // number of bars, that were changed in the current row
+                       int nBars = 0; 
+
+                       if ( WasChanged( row.mUMgrData, row.mBoundsInParent ) )
+                       
+                               rowChanged = TRUE;
+                       else
+                               for( size_t k = 0; k != row.mBars.Count(); ++k )
+
+                                       if ( WasChanged( row.mBars[k]->mUMgrData, 
+                                                row.mBars[k]->mBoundsInParent ) 
+                                          )
+                                       
+                                               barsToRepaint[nBars++] = row.mBars[k];
+
+                       if ( nBars || rowChanged )
+                       {
+                               realBounds = row.mBoundsInParent;
+
+                               // include 1-pixel thick shades around the row
+                               realBounds.x -= 1;
+                               realBounds.y -= 1;
+                               realBounds.width  += 2;
+                               realBounds.height += 2;
+
+                               pDc = pane.StartDrawInArea( realBounds );
+                       }
+
+                       if ( rowChanged )
+                       {
+                               // postphone the resizing and refreshing the changed
+                               // bar windows
+
+                               for( size_t k = 0; k != row.mBars.Count(); ++k )
+                               {
+                                       mBarsToRefresh.Append( (wxObject*)row.mBars[k] );
+                                       mPanesList.Append( &pane );
+                               }
+
+                               // draw only their decorations now
+
+                               pane.PaintRow( &row, *pDc );
+                       }
+                       else
+                       if ( nBars != 0 )
+                       {
+                               for( int i = 0; i != nBars; ++i )
+                               {
+                                       // postphone the resizement and refreshing the changed
+                                       // bar windows
+
+                                       mBarsToRefresh.Append( (wxObject*)barsToRepaint[i] );
+                                       mPanesList.Append( &pane );
+                               }
+
+                               // redraw decorations of entire row, regardless of how much
+                               // of the bars were changed
+                               pane.PaintRow( &row, *pDc );
+                       }
+
+                       if ( pDc )
+               
+                               pane.FinishDrawInArea( realBounds );
+               } // end of while
+
+               if ( paneChanged )
+               {
+                       wxClientDC dc( &mpLayout->GetParentFrame() );
+                       pane.PaintPaneDecorations( dc );
+               }
+
+       } // end of for
+
+       if ( clientWindowChanged )
+       {
+               mpLayout->PositionClientWindow();
+               // ptr to client-window object is "marked" as 0
+       }
+
+       // step #2 - do ordered refreshing and resizing of bar window objects now
+
+       wxNode* pNode     = mBarsToRefresh.First();
+       wxNode* pPaneNode = mPanesList.First();
+
+       while( pNode )
+       {
+               cbBarInfo*  pBar  = (cbBarInfo*) pNode->Data();
+               cbDockPane* pPane = (cbDockPane*)pPaneNode->Data();
+
+               pPane->SizeBar( pBar );
+
+               pNode     = pNode->Next();
+               pPaneNode = pPaneNode->Next();
+       }
+
+       pNode = mBarsToRefresh.First();
+
+       while( pNode )
+       {
+               cbBarInfo* pBar = (cbBarInfo*)pNode->Data();
+
+               if ( pBar->mpBarWnd ) 
+               {
+                       pBar->mpBarWnd->Refresh();
+
+                       // FIXME::
+                       //info.mpBarWnd->Show(FALSE);
+                       //info.mpBarWnd->Show(TRUE);
+               }
+
+               pNode  = pNode->Next();
+       }
+
+       if ( clientWindowChanged )
+       {
+               // FIXME:: excessive?
+
+               mpLayout->GetFrameClient()->Refresh();
+       }
+}
+