ac_given_srcdir=$srcdir
trap 'rm -fr `echo "
- Makefile
src/Makefile
src/ogl/Makefile
src/mmedia/Makefile
src/gizmos/Makefile
src/plot/Makefile
src/applet/Makefile
+ src/fl/Makefile
samples/Makefile
samples/mmedia/Makefile
samples/ogl/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
src/gizmos/Makefile
src/plot/Makefile
src/applet/Makefile
+ src/fl/Makefile
samples/Makefile
samples/mmedia/Makefile
samples/ogl/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
AC_OUTPUT([
- Makefile
src/Makefile
src/ogl/Makefile
src/mmedia/Makefile
src/gizmos/Makefile
src/plot/Makefile
src/applet/Makefile
+ src/fl/Makefile
samples/Makefile
samples/mmedia/Makefile
samples/ogl/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
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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__ */
+
# $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
--- /dev/null
+# $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
+
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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
+
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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 );
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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
+
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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);
+}
+
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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);
+}
+
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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++;
+}
+
--- /dev/null
+/* mondrian ICON "mondrian.ico" */
+#include "wx/msw/wx.rc"
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
--- /dev/null
+#
+# 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
# $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
--- /dev/null
+#
+# 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
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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();
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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"
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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 );
+}
+
--- /dev/null
+
+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)
+
--- /dev/null
+# 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
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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 );
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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();
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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();
+ }
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+#
+# 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
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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!");
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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 );
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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();
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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!");
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// 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();
+ }
+}
+