From 8e08b761b0c5ecb6df295785b78f1f3637331887 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Tue, 24 Jul 2001 15:27:12 +0000 Subject: [PATCH] Added fl (frame layout) to wxWindows, from source tidied by Hans Van Leemputten . git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11170 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- contrib/configure | 13 +- contrib/configure.in | 7 +- contrib/include/wx/fl/antiflickpl.h | 64 + contrib/include/wx/fl/bardragpl.h | 122 + contrib/include/wx/fl/barhintspl.h | 96 + contrib/include/wx/fl/cbcustom.h | 47 + contrib/include/wx/fl/controlbar.h | 1740 +++++++++ contrib/include/wx/fl/dynbarhnd.h | 22 + contrib/include/wx/fl/dyntbar.h | 204 + contrib/include/wx/fl/dyntbarhnd.h | 31 + contrib/include/wx/fl/frmview.h | 140 + contrib/include/wx/fl/garbagec.h | 74 + contrib/include/wx/fl/gcupdatesmgr.h | 123 + contrib/include/wx/fl/hintanimpl.h | 120 + contrib/include/wx/fl/newbmpbtn.h | 165 + contrib/include/wx/fl/panedrawpl.h | 119 + contrib/include/wx/fl/rowdragpl.h | 164 + contrib/include/wx/fl/rowlayoutpl.h | 87 + contrib/include/wx/fl/toolwnd.h | 216 ++ contrib/include/wx/fl/updatesmgr.h | 56 + contrib/samples/Makefile.in | 2 +- contrib/samples/fl/Makefile.in | 10 + contrib/samples/fl/bitmaps/bookmarks.bmp | Bin 0 -> 1650 bytes contrib/samples/fl/bitmaps/class_icon.bmp | Bin 0 -> 214 bytes contrib/samples/fl/bitmaps/class_icon1.bmp | Bin 0 -> 822 bytes contrib/samples/fl/bitmaps/copy.bmp | Bin 0 -> 1566 bytes contrib/samples/fl/bitmaps/cut.bmp | Bin 0 -> 1566 bytes contrib/samples/fl/bitmaps/file_icon.bmp | Bin 0 -> 214 bytes contrib/samples/fl/bitmaps/folder_icon.bmp | Bin 0 -> 822 bytes contrib/samples/fl/bitmaps/help_icon.bmp | Bin 0 -> 214 bytes contrib/samples/fl/bitmaps/new.bmp | Bin 0 -> 1398 bytes contrib/samples/fl/bitmaps/nextmark.bmp | Bin 0 -> 1734 bytes contrib/samples/fl/bitmaps/open.bmp | Bin 0 -> 1314 bytes contrib/samples/fl/bitmaps/paste.bmp | Bin 0 -> 1566 bytes contrib/samples/fl/bitmaps/prevmark.bmp | Bin 0 -> 1734 bytes contrib/samples/fl/bitmaps/res_icon.bmp | Bin 0 -> 214 bytes contrib/samples/fl/bitmaps/save.bmp | Bin 0 -> 1482 bytes contrib/samples/fl/bitmaps/saveall.bmp | Bin 0 -> 1566 bytes contrib/samples/fl/bitmaps/search.bmp | Bin 0 -> 1482 bytes contrib/samples/fl/bitmaps/start95_dp.bmp | Bin 0 -> 3918 bytes contrib/samples/fl/bitmaps/start95_pr.bmp | Bin 0 -> 4086 bytes contrib/samples/fl/bitmaps/tile.bmp | Bin 0 -> 1894 bytes contrib/samples/fl/fl_demo1/Makefile.in | 25 + contrib/samples/fl/fl_demo1/fl_demo.dsp | 108 + contrib/samples/fl/fl_demo1/fl_demo.dsw | 29 + contrib/samples/fl/fl_demo1/fl_demo1.cpp | 241 ++ contrib/samples/fl/fl_demo1/fl_demo1.h | 55 + contrib/samples/fl/fl_demo1/fl_demo1.rc | 3 + contrib/samples/fl/fl_demo1/makefile.b32 | 23 + contrib/samples/fl/fl_demo1/makefile.g95 | 18 + contrib/samples/fl/fl_demo1/makefile.vc | 24 + contrib/samples/fl/fl_demo2/Makefile.in | 25 + contrib/samples/fl/fl_demo2/fl_demo.dsp | 108 + contrib/samples/fl/fl_demo2/fl_demo.dsw | 29 + contrib/samples/fl/fl_demo2/fl_demo2.cpp | 986 +++++ contrib/samples/fl/fl_demo2/fl_demo2.h | 160 + contrib/samples/fl/fl_demo2/fl_demo2.rc | 3 + contrib/samples/fl/fl_demo2/makefile.b32 | 23 + contrib/samples/fl/fl_demo2/makefile.g95 | 18 + contrib/samples/fl/fl_demo2/makefile.vc | 24 + contrib/samples/fl/fl_sample1/Makefile.in | 25 + contrib/samples/fl/fl_sample1/fl_demo.dsp | 108 + contrib/samples/fl/fl_sample1/fl_demo.dsw | 29 + contrib/samples/fl/fl_sample1/fl_sample1.cpp | 196 + contrib/samples/fl/fl_sample1/fl_sample1.rc | 3 + contrib/samples/fl/fl_sample1/makefile.b32 | 23 + contrib/samples/fl/fl_sample1/makefile.g95 | 18 + contrib/samples/fl/fl_sample1/makefile.vc | 24 + contrib/samples/fl/fl_sample2/Makefile.in | 25 + contrib/samples/fl/fl_sample2/fl_demo.dsp | 108 + contrib/samples/fl/fl_sample2/fl_demo.dsw | 29 + contrib/samples/fl/fl_sample2/fl_sample2.cpp | 194 + contrib/samples/fl/fl_sample2/fl_sample2.rc | 3 + contrib/samples/fl/fl_sample2/makefile.b32 | 23 + contrib/samples/fl/fl_sample2/makefile.g95 | 18 + contrib/samples/fl/fl_sample2/makefile.vc | 24 + contrib/samples/fl/fl_sample3/Makefile.in | 25 + contrib/samples/fl/fl_sample3/fl_demo.dsp | 108 + contrib/samples/fl/fl_sample3/fl_demo.dsw | 29 + contrib/samples/fl/fl_sample3/fl_sample3.cpp | 337 ++ contrib/samples/fl/fl_sample3/fl_sample3.rc | 3 + contrib/samples/fl/fl_sample3/makefile.b32 | 23 + contrib/samples/fl/fl_sample3/makefile.g95 | 18 + contrib/samples/fl/fl_sample3/makefile.vc | 24 + contrib/src/Makefile.in | 2 +- contrib/src/fl/Makefile.in | 29 + contrib/src/fl/antiflickpl.cpp | 236 ++ contrib/src/fl/bardragpl.cpp | 934 +++++ contrib/src/fl/barhintspl.cpp | 560 +++ contrib/src/fl/cbcustom.cpp | 202 + contrib/src/fl/controlbar.cpp | 3524 ++++++++++++++++++ contrib/src/fl/dyntbar.cpp | 517 +++ contrib/src/fl/dyntbarhnd.cpp | 49 + contrib/src/fl/files.lst | 20 + contrib/src/fl/flVC.dsp | 230 ++ contrib/src/fl/flVC.dsw | 29 + contrib/src/fl/frmview.cpp | 451 +++ contrib/src/fl/garbagec.cpp | 224 ++ contrib/src/fl/gcupdatesmgr.cpp | 409 ++ contrib/src/fl/hintanimpl.cpp | 397 ++ contrib/src/fl/makefile.b32 | 26 + contrib/src/fl/makefile.g95 | 20 + contrib/src/fl/makefile.vc | 26 + contrib/src/fl/newbmpbtn.cpp | 832 +++++ contrib/src/fl/panedrawpl.cpp | 1273 +++++++ contrib/src/fl/rowdragpl.cpp | 1465 ++++++++ contrib/src/fl/rowlayoutpl.cpp | 1220 ++++++ contrib/src/fl/toolwnd.cpp | 1146 ++++++ contrib/src/fl/updatesmgr.cpp | 291 ++ 109 files changed, 21049 insertions(+), 4 deletions(-) create mode 100644 contrib/include/wx/fl/antiflickpl.h create mode 100644 contrib/include/wx/fl/bardragpl.h create mode 100644 contrib/include/wx/fl/barhintspl.h create mode 100644 contrib/include/wx/fl/cbcustom.h create mode 100644 contrib/include/wx/fl/controlbar.h create mode 100644 contrib/include/wx/fl/dynbarhnd.h create mode 100644 contrib/include/wx/fl/dyntbar.h create mode 100644 contrib/include/wx/fl/dyntbarhnd.h create mode 100644 contrib/include/wx/fl/frmview.h create mode 100644 contrib/include/wx/fl/garbagec.h create mode 100644 contrib/include/wx/fl/gcupdatesmgr.h create mode 100644 contrib/include/wx/fl/hintanimpl.h create mode 100644 contrib/include/wx/fl/newbmpbtn.h create mode 100644 contrib/include/wx/fl/panedrawpl.h create mode 100644 contrib/include/wx/fl/rowdragpl.h create mode 100644 contrib/include/wx/fl/rowlayoutpl.h create mode 100644 contrib/include/wx/fl/toolwnd.h create mode 100644 contrib/include/wx/fl/updatesmgr.h create mode 100644 contrib/samples/fl/Makefile.in create mode 100644 contrib/samples/fl/bitmaps/bookmarks.bmp create mode 100644 contrib/samples/fl/bitmaps/class_icon.bmp create mode 100644 contrib/samples/fl/bitmaps/class_icon1.bmp create mode 100644 contrib/samples/fl/bitmaps/copy.bmp create mode 100644 contrib/samples/fl/bitmaps/cut.bmp create mode 100644 contrib/samples/fl/bitmaps/file_icon.bmp create mode 100644 contrib/samples/fl/bitmaps/folder_icon.bmp create mode 100644 contrib/samples/fl/bitmaps/help_icon.bmp create mode 100644 contrib/samples/fl/bitmaps/new.bmp create mode 100644 contrib/samples/fl/bitmaps/nextmark.bmp create mode 100644 contrib/samples/fl/bitmaps/open.bmp create mode 100644 contrib/samples/fl/bitmaps/paste.bmp create mode 100644 contrib/samples/fl/bitmaps/prevmark.bmp create mode 100644 contrib/samples/fl/bitmaps/res_icon.bmp create mode 100644 contrib/samples/fl/bitmaps/save.bmp create mode 100644 contrib/samples/fl/bitmaps/saveall.bmp create mode 100644 contrib/samples/fl/bitmaps/search.bmp create mode 100644 contrib/samples/fl/bitmaps/start95_dp.bmp create mode 100644 contrib/samples/fl/bitmaps/start95_pr.bmp create mode 100644 contrib/samples/fl/bitmaps/tile.bmp create mode 100644 contrib/samples/fl/fl_demo1/Makefile.in create mode 100644 contrib/samples/fl/fl_demo1/fl_demo.dsp create mode 100644 contrib/samples/fl/fl_demo1/fl_demo.dsw create mode 100644 contrib/samples/fl/fl_demo1/fl_demo1.cpp create mode 100644 contrib/samples/fl/fl_demo1/fl_demo1.h create mode 100644 contrib/samples/fl/fl_demo1/fl_demo1.rc create mode 100644 contrib/samples/fl/fl_demo1/makefile.b32 create mode 100644 contrib/samples/fl/fl_demo1/makefile.g95 create mode 100644 contrib/samples/fl/fl_demo1/makefile.vc create mode 100644 contrib/samples/fl/fl_demo2/Makefile.in create mode 100644 contrib/samples/fl/fl_demo2/fl_demo.dsp create mode 100644 contrib/samples/fl/fl_demo2/fl_demo.dsw create mode 100644 contrib/samples/fl/fl_demo2/fl_demo2.cpp create mode 100644 contrib/samples/fl/fl_demo2/fl_demo2.h create mode 100644 contrib/samples/fl/fl_demo2/fl_demo2.rc create mode 100644 contrib/samples/fl/fl_demo2/makefile.b32 create mode 100644 contrib/samples/fl/fl_demo2/makefile.g95 create mode 100644 contrib/samples/fl/fl_demo2/makefile.vc create mode 100644 contrib/samples/fl/fl_sample1/Makefile.in create mode 100644 contrib/samples/fl/fl_sample1/fl_demo.dsp create mode 100644 contrib/samples/fl/fl_sample1/fl_demo.dsw create mode 100644 contrib/samples/fl/fl_sample1/fl_sample1.cpp create mode 100644 contrib/samples/fl/fl_sample1/fl_sample1.rc create mode 100644 contrib/samples/fl/fl_sample1/makefile.b32 create mode 100644 contrib/samples/fl/fl_sample1/makefile.g95 create mode 100644 contrib/samples/fl/fl_sample1/makefile.vc create mode 100644 contrib/samples/fl/fl_sample2/Makefile.in create mode 100644 contrib/samples/fl/fl_sample2/fl_demo.dsp create mode 100644 contrib/samples/fl/fl_sample2/fl_demo.dsw create mode 100644 contrib/samples/fl/fl_sample2/fl_sample2.cpp create mode 100644 contrib/samples/fl/fl_sample2/fl_sample2.rc create mode 100644 contrib/samples/fl/fl_sample2/makefile.b32 create mode 100644 contrib/samples/fl/fl_sample2/makefile.g95 create mode 100644 contrib/samples/fl/fl_sample2/makefile.vc create mode 100644 contrib/samples/fl/fl_sample3/Makefile.in create mode 100644 contrib/samples/fl/fl_sample3/fl_demo.dsp create mode 100644 contrib/samples/fl/fl_sample3/fl_demo.dsw create mode 100644 contrib/samples/fl/fl_sample3/fl_sample3.cpp create mode 100644 contrib/samples/fl/fl_sample3/fl_sample3.rc create mode 100644 contrib/samples/fl/fl_sample3/makefile.b32 create mode 100644 contrib/samples/fl/fl_sample3/makefile.g95 create mode 100644 contrib/samples/fl/fl_sample3/makefile.vc create mode 100644 contrib/src/fl/Makefile.in create mode 100644 contrib/src/fl/antiflickpl.cpp create mode 100644 contrib/src/fl/bardragpl.cpp create mode 100644 contrib/src/fl/barhintspl.cpp create mode 100644 contrib/src/fl/cbcustom.cpp create mode 100644 contrib/src/fl/controlbar.cpp create mode 100644 contrib/src/fl/dyntbar.cpp create mode 100644 contrib/src/fl/dyntbarhnd.cpp create mode 100644 contrib/src/fl/files.lst create mode 100644 contrib/src/fl/flVC.dsp create mode 100644 contrib/src/fl/flVC.dsw create mode 100644 contrib/src/fl/frmview.cpp create mode 100644 contrib/src/fl/garbagec.cpp create mode 100644 contrib/src/fl/gcupdatesmgr.cpp create mode 100644 contrib/src/fl/hintanimpl.cpp create mode 100644 contrib/src/fl/makefile.b32 create mode 100644 contrib/src/fl/makefile.g95 create mode 100644 contrib/src/fl/makefile.vc create mode 100644 contrib/src/fl/newbmpbtn.cpp create mode 100644 contrib/src/fl/panedrawpl.cpp create mode 100644 contrib/src/fl/rowdragpl.cpp create mode 100644 contrib/src/fl/rowlayoutpl.cpp create mode 100644 contrib/src/fl/toolwnd.cpp create mode 100644 contrib/src/fl/updatesmgr.cpp diff --git a/contrib/configure b/contrib/configure index 5f5ab2decd..9cb5da925f 100755 --- a/contrib/configure +++ b/contrib/configure @@ -812,7 +812,6 @@ done ac_given_srcdir=$srcdir trap 'rm -fr `echo " - Makefile src/Makefile src/ogl/Makefile src/mmedia/Makefile @@ -822,6 +821,7 @@ trap 'rm -fr `echo " src/gizmos/Makefile src/plot/Makefile src/applet/Makefile + src/fl/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile @@ -838,6 +838,11 @@ trap 'rm -fr `echo " samples/xrc/Makefile samples/plot/Makefile samples/applet/Makefile + samples/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 @@ -930,6 +935,7 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile src/gizmos/Makefile src/plot/Makefile src/applet/Makefile + src/fl/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile @@ -946,6 +952,11 @@ CONFIG_FILES=\${CONFIG_FILES-"Makefile samples/xrc/Makefile samples/plot/Makefile samples/applet/Makefile + samples/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 diff --git a/contrib/configure.in b/contrib/configure.in index bf39a34e41..4f65ed0b03 100644 --- a/contrib/configure.in +++ b/contrib/configure.in @@ -37,7 +37,6 @@ dnl File output AC_OUTPUT([ - Makefile src/Makefile src/ogl/Makefile src/mmedia/Makefile @@ -47,6 +46,7 @@ AC_OUTPUT([ src/gizmos/Makefile src/plot/Makefile src/applet/Makefile + src/fl/Makefile samples/Makefile samples/mmedia/Makefile samples/ogl/Makefile @@ -63,6 +63,11 @@ AC_OUTPUT([ samples/xrc/Makefile samples/plot/Makefile samples/applet/Makefile + samples/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 diff --git a/contrib/include/wx/fl/antiflickpl.h b/contrib/include/wx/fl/antiflickpl.h new file mode 100644 index 0000000000..9b44d8508c --- /dev/null +++ b/contrib/include/wx/fl/antiflickpl.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas (@Lithuania) +// Modified by: +// Created: 23/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __ANTIFLICKPL_G__ +#define __ANTIFLICKPL_G__ + +#ifdef __GNUG__ + #pragma interface "antiflickpl.h" +#endif + +#include "wx/fl/controlbar.h" + +class cbAntiflickerPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbAntiflickerPlugin ) +protected: + // double-buffers are shared "resource" among all instances of + // antiflicker plugin within the application + // + // TODO:: locking should be implemented, for multithreaded GUIs + + static wxBitmap* mpVertBuf; + static wxBitmap* mpHorizBuf; + static wxMemoryDC* mpVertBufDc; + static wxMemoryDC* mpHorizBufDc; + + static int mRefCount; + + wxDC* mpLRUBufDc; // last-reacently-used buffer + wxRect mLRUArea; // last-reacently-used area + +protected: + // returns NULL, if sutable buffer is not present + wxDC* FindSuitableBuffer( const wxRect& forArea ); + wxDC* AllocNewBuffer( const wxRect& forArea ); + wxDC& GetWindowDC(); + + wxDC& GetClientDC(); +public: + + cbAntiflickerPlugin(void); + + cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + virtual ~cbAntiflickerPlugin(); + + // handlers for plugin events + + void OnStartDrawInArea ( cbStartDrawInAreaEvent& event ); + void OnFinishDrawInArea( cbFinishDrawInAreaEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __ANTIFLICKPL_G__ */ + diff --git a/contrib/include/wx/fl/bardragpl.h b/contrib/include/wx/fl/bardragpl.h new file mode 100644 index 0000000000..a9df99acf8 --- /dev/null +++ b/contrib/include/wx/fl/bardragpl.h @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __BARDRAGPL_G__ +#define __BARDRAGPL_G__ + +#ifdef __GNUG__ + #pragma interface "bardragpl.h" +#endif + +#include "wx/fl/controlbar.h" +#include "wx/fl/toolwnd.h" + +class cbBarDragPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbBarDragPlugin ) +protected: + + // plugin is active only in bar-dragging state + bool mBarDragStarted; + bool mCanStick; // flag used to prevent "bouncing" of hint-rectangle + wxScreenDC* mpScrDc; // created while tracking hint-rect + wxCursor* mpCurCursor; + + // rectnagle shows the position/dimensions of the bar, + // if it would be docked now + + wxRect mPrevHintRect; + wxRect mHintRect; + + + int mMouseInRectX; + int mMouseInRectY; + + cbDockPane* mpSrcPane; // pane, from which the bar was originally taken + int mBarWidthInSrcPane; + + cbDockPane* mpCurPane; + + cbBarInfo* mpDraggedBar; // bar, which is being dragged + bool mBarWasFloating; + wxRect mFloatedBarBounds; + +public: /*** public properties ***/ + + int mInClientHintBorder; // when hint-rect moves within client window area, + // the thicker rectangle is drawn using hatched brush, + // the default border width for this rectangle is 8 pix. + +protected: + + + void AdjustHintRect( wxPoint& mousePos ); + + void ClipRectInFrame( wxRect& rect ); + void ClipPosInFrame( wxPoint& pos ); + + cbDockPane* HitTestPanes( wxRect& rect ); + cbDockPane* HitTestPanes( wxPoint& pos ); + bool HitsPane( cbDockPane* pPane, wxRect& rect ); + + void CalcOnScreenDims( wxRect& rect ); + + int GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos ); + + bool IsInOtherPane ( wxPoint& mousePos ); + bool IsInClientArea( wxPoint& mousePos ); + bool IsInClientArea( wxRect& rect ); + + void StickToPane( cbDockPane* pPane, wxPoint& mousePos ); + void UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos ); + + int GetBarWidthInPane( cbDockPane* pPane ); + int GetBarHeightInPane( cbDockPane* pPane ); + + // on-screen hint-tracking related methods + + void StartTracking(); + + void DrawHintRect ( wxRect& rect, bool isInClientRect); + void EraseHintRect( wxRect& rect, bool isInClientRect); + + void FinishTracking(); + + void DoDrawHintRect( wxRect& rect, bool isInClientRect); + + void RectToScr( wxRect& frameRect, wxRect& scrRect ); + + void ShowHint( bool prevWasInClient ); + +public: + cbBarDragPlugin(void); + + cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + virtual ~cbBarDragPlugin(); + + // handlers for plugin events + + void OnMouseMove( cbMotionEvent& event ); + void OnLButtonUp( cbLeftUpEvent& event ); + void OnLButtonDown( cbLeftDownEvent& event ); + void OnLDblClick( cbLeftDClickEvent& event ); + + // handles event, which oriniates from itself + void OnDrawHintRect( cbDrawHintRectEvent& event ); + + void OnStartBarDragging( cbStartBarDraggingEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __BARDRAGPL_G__ */ + diff --git a/contrib/include/wx/fl/barhintspl.h b/contrib/include/wx/fl/barhintspl.h new file mode 100644 index 0000000000..809b101d91 --- /dev/null +++ b/contrib/include/wx/fl/barhintspl.h @@ -0,0 +1,96 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 30/11/98 (my 22th birthday :-) +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __DRAGHINTSPL_G__ +#define __DRAGHINTSPL_G__ + +#ifdef __GNUG__ + #pragma interface "barhintspl.h" +#endif + +#include "wx/fl/controlbar.h" +#include "wx/fl/toolwnd.h" + +/* + * Intercepts bar-decoration and sizing events, draws 3d-hints + * around fixed and flexible bars, similar to those in Microsoft DevStudio 6.x + */ + +class cbBarHintsPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbBarHintsPlugin ) + +protected: + cbDockPane* mpPane; // is set up temorarely, while handling event + + cbMiniButton* mBoxes[2]; + + bool mBtnPressed; + bool mClosePressed; + cbBarInfo* mpClickedBar; + bool mDepressed; + +protected: + // drawing helpers + + void Draw3DBox ( wxDC& dc, const wxPoint& pos, bool pressed ); + void DrawCloseBox ( wxDC& dc, const wxPoint& pos, bool pressed ); + void DrawCollapseBox( wxDC& dc, const wxPoint& pos, + bool atLeft, bool disabled, bool pressed ); + + void DrawGrooves ( wxDC& dc, const wxPoint& pos, int length ); + + void DoDrawHint( wxDC& dc, wxRect& rect, int pos, int boxOfs, int grooveOfs, bool isFixed ); + + void GetHintsLayout( wxRect& rect, cbBarInfo& info, + int& boxOfs, int& grooveOfs, int& pos ); + + int HitTestHints( cbBarInfo& info, const wxPoint& pos ); + + void ExcludeHints( wxRect& rect, cbBarInfo& info ); + + void CreateBoxes(); + +public: + /* public properties */ + + bool mCloseBoxOn; // default: ON + bool mCollapseBoxOn; // default: ON + int mGrooveCount; // default: 2 (two shaded bars) + int mHintGap; // default: 5 (pixels from above, below, right and left) + int mXWeight; // default: 2 (width in pixels of lines which used for drawing cross) + +public: + + cbBarHintsPlugin(void); + + cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask = wxALL_PANES ); + + ~cbBarHintsPlugin(); + + void SetGrooveCount( int nGrooves ); + + void OnInitPlugin(); + + // handlers of plugin-events + + void OnSizeBarWindow( cbSizeBarWndEvent& event ); + void OnDrawBarDecorations( cbDrawBarDecorEvent& event ); + + void OnLeftDown( cbLeftDownEvent& event ); + void OnLeftUp ( cbLeftUpEvent& event ); + void OnMotion ( cbMotionEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __DRAGHINTSPL_G__ */ + diff --git a/contrib/include/wx/fl/cbcustom.h b/contrib/include/wx/fl/cbcustom.h new file mode 100644 index 0000000000..ff0c3446ce --- /dev/null +++ b/contrib/include/wx/fl/cbcustom.h @@ -0,0 +1,47 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 28/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __CBCUSTOM_G__ +#define __CBCUSTOM_G__ + +#ifdef __GNUG__ + #pragma interface "cbcustom.h" +#endif + +#include "wx/fl/controlbar.h" + +class cbSimpleCustomizationPlugin : public cbPluginBase +{ +public: + DECLARE_DYNAMIC_CLASS( cbSimpleCustomizationPlugin ) + + int mCustMenuItemId; +public: + + cbSimpleCustomizationPlugin(void); + + cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + // plugin-event handlers + + void OnCustomizeBar( cbCustomizeBarEvent& event ); + + void OnCustomizeLayout( cbCustomizeLayoutEvent& event ); + + // menu-event handler + + void OnMenuItemSelected( wxCommandEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __CBCUSTOM_G__ */ + diff --git a/contrib/include/wx/fl/controlbar.h b/contrib/include/wx/fl/controlbar.h new file mode 100644 index 0000000000..d67be75021 --- /dev/null +++ b/contrib/include/wx/fl/controlbar.h @@ -0,0 +1,1740 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Central header file for control-bar related classes +// +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __CONTROLBAR_G__ +#define __CONTROLBAR_G__ + +#ifdef __GNUG__ + #pragma interface "controlbar.h" +#endif + +#include "wx/defs.h" +#include "wx/string.h" +#include "wx/window.h" +#include "wx/dynarray.h" + +#define WXCONTROLBAR_VERSION 1.3 + +// forward declarations + +class wxFrameLayout; + +class cbDockPane; +class cbUpdatesManagerBase; +class cbBarDimHandlerBase; +class cbPluginBase; +class cbPluginEvent; +class cbPaneDrawPlugin; + +class cbBarInfo; +class cbRowInfo; +class cbDimInfo; +class cbCommonPaneProperties; + +typedef cbBarInfo* BarInfoPtrT; +typedef cbRowInfo* RowInfoPtrT; + +WX_DEFINE_ARRAY( BarInfoPtrT, BarArrayT ); +WX_DEFINE_ARRAY( RowInfoPtrT, RowArrayT ); + +// control bar states + +#define wxCBAR_DOCKED_HORIZONTALLY 0 +#define wxCBAR_DOCKED_VERTICALLY 1 +#define wxCBAR_FLOATING 2 +#define wxCBAR_HIDDEN 3 + +// the states are enumerated above +#define MAX_BAR_STATES 4 + +// control bar alignments + +#if !defined(FL_ALIGN_TOP) + +#define FL_ALIGN_TOP 0 +#define FL_ALIGN_BOTTOM 1 +#define FL_ALIGN_LEFT 2 +#define FL_ALIGN_RIGHT 3 + +#endif + +// one pane for each alignment +#define MAX_PANES 4 + +// masks for each pane + +#define FL_ALIGN_TOP_PANE 0x0001 +#define FL_ALIGN_BOTTOM_PANE 0x0002 +#define FL_ALIGN_LEFT_PANE 0x0004 +#define FL_ALIGN_RIGHT_PANE 0x0008 + +#define wxALL_PANES 0x000F + +// enumeration of hittest results, see cbDockPane::HitTestPaneItems(..) + +enum CB_HITTEST_RESULT +{ + CB_NO_ITEMS_HITTED, + + CB_UPPER_ROW_HANDLE_HITTED, + CB_LOWER_ROW_HANDLE_HITTED, + CB_LEFT_BAR_HANDLE_HITTED, + CB_RIGHT_BAR_HANDLE_HITTED, + CB_BAR_CONTENT_HITTED +}; + +// FIXME:: somehow in debug v. originall wxASSERT's are not compiled in... + +//#undef wxASSERT +//#define wxASSERT(x) if ( !(x) ) throw; + +// helper class, used for spying for not-handled mouse events on control-bars +// and forwarding them to the frame layout + +class cbBarSpy : public wxEvtHandler +{ +public: + DECLARE_DYNAMIC_CLASS( cbBarSpy ) + + wxFrameLayout* mpLayout; + wxWindow* mpBarWnd; + +public: + cbBarSpy(void); + + cbBarSpy( wxFrameLayout* pPanel ); + + void SetBarWindow( wxWindow* pWnd ); + + // overriden + + virtual bool ProcessEvent(wxEvent& event); +}; + +/* wxFrameLayout manages containment and docking of control bars. + * which can be docked along top, bottom, righ, or left side of the + * parent frame + */ + +class wxFrameLayout : public wxEvtHandler +{ +public: + wxFrameLayout(void); // used only while serializing + + wxFrameLayout( wxWindow* pParentFrame, + wxWindow* pFrameClient = NULL, + bool activateNow = TRUE ); + + // (doesn't destroy bar windows) + virtual ~wxFrameLayout(); + + // (by default floating of control-bars is ON) + virtual void EnableFloating( bool enable = TRUE ); + + // Can be called after some other layout has been deactivated, + // and this one must "take over" the current contents of frame window. + // + // Effectively hooks itself to the frame window, re-displays all not-hidden + // bar-windows and repaints decorations + + virtual void Activate(); + + // unhooks itself from frame window, and hides all not-hidden windows + // + // NOTE:: two frame-layouts should not be active at the same time in the + // same frame window, it would cause messy overlapping of bar windows + // from both layouts + + virtual void Deactivate(); + + // also hides the client window if presents + + void HideBarWindows(); + + virtual void DestroyBarWindows(); + + // passes the client window (e.g. MDI-client frame) to be controled by + // frame layout, the size and position of which should be adjusted to be + // surrounded by controlbar panes, whenever frame is resized, or dimensions + // of control panes change + + void SetFrameClient( wxWindow* pFrameClient ); + + wxWindow* GetFrameClient(); + + wxWindow& GetParentFrame() { return *mpFrame; } + + // used by updates-managers + cbDockPane** GetPanesArray() { return mPanes; } + + // see pane alignment types + cbDockPane* GetPane( int alignment ) + + { return mPanes[alignment]; } + + // Adds bar information to frame-layout, appearence of layout is not refreshed + // immediately, RefreshNow() can be called if necessary. + // + // NOTES:: argument pBarWnd can by NULL, resulting bar decorations to be drawn + // around the empty rectangle (filled with default background colour). + // Argument dimInfo, can be re-used for adding any number of bars, since + // it is not used directly, instead it's members are copied. If dimensions- + // handler is present, it's instance shared (reference counted). Dimension + // handler should always be allocated on the heap!) + + virtual void AddBar( wxWindow* pBarWnd, + const cbDimInfo& dimInfo, + + // defaults: + int alignment = FL_ALIGN_TOP, + int rowNo = 0, // vert. position - row in the pane (if docked state) + int columnPos = 0, // horiz. position in the row in pixels (if docked state) + const wxString& name="bar",// name, by which the bar could be referred + // in layout customization dialogs + + bool spyEvents = FALSE, // if TRUE - input events for the bar should + // be "spyed" in order to forward not-handled + // mouse clicks to frame layout (e.g. to enable + // easy-draggablity of toolbars just by clicking + // on their interior regions). For widgets like + // text/tree control this value should be FALSE + // (since there's _no_ certain way to detect + // whether the event was actually handled...) + + int state = wxCBAR_DOCKED_HORIZONTALLY // e.g. wxCBAR_FLOATING + // or wxCBAR_HIDDEN + ); + + // can be used for repositioning already existing bars. The given bar is first removed + // from the pane it currently belongs to, and inserted into the pane, which "matches" + // the given recantular area. If pToPane is not NULL, bar is docked to this given pane + + // to dock the bar which is floated, use wxFrameLayout::DockBar(..) method + + virtual bool RedockBar( cbBarInfo* pBar, const wxRect& shapeInParent, + cbDockPane* pToPane = NULL, bool updateNow = TRUE ); + + // methods for access and modification of bars in frame layout + + cbBarInfo* FindBarByName( const wxString& name ); + + cbBarInfo* FindBarByWindow( const wxWindow* pWnd ); + + BarArrayT& GetBars(); + + // changes bar's docking state (see possible control bar states) + + void SetBarState( cbBarInfo* pBar, int newStatem, bool updateNow ); + + void InverseVisibility( cbBarInfo* pBar ); + + // reflects changes in bar information structure visually + // (e.g. moves bar, changes it's dimension info, pane to which it is docked) + + void ApplyBarProperties( cbBarInfo* pBar ); + + // removes bar from layout permanently, hides it's corresponding window if present + + void RemoveBar( cbBarInfo* pBar ); + + // recalcualtes layout of panes, and all bars/rows in each pane + + virtual void RecalcLayout( bool repositionBarsNow = FALSE ); + + int GetClientHeight(); + int GetClientWidth(); + wxRect& GetClientRect() { return mClntWndBounds; } + + // NOTE:: in future ubdates-manager will become a normal plugin + + cbUpdatesManagerBase& GetUpdatesManager(); + + // destroys the previous manager if any, set the new one + + void SetUpdatesManager( cbUpdatesManagerBase* pUMgr ); + + // NOTE:: changing properties of panes, does not result immediate on-screen update + + virtual void GetPaneProperties( cbCommonPaneProperties& props, int alignment = FL_ALIGN_TOP ); + + virtual void SetPaneProperties( const cbCommonPaneProperties& props, + int paneMask = wxALL_PANES ); + + // TODO:: margins should go into cbCommonPaneProperties in the future + // + // NOTE:: this method should be called before any custom plugins are attached + + virtual void SetMargins( int top, int bottom, int left, int right, + int paneMask = wxALL_PANES ); + + virtual void SetPaneBackground( const wxColour& colour ); + + // recalculates layoute and performs on-screen update of all panes + + void RefreshNow( bool recalcLayout = TRUE ); + + // event handlers + + void OnSize ( wxSizeEvent& event ); + void OnLButtonDown( wxMouseEvent& event ); + void OnLDblClick ( wxMouseEvent& event ); + void OnLButtonUp ( wxMouseEvent& event ); + void OnRButtonDown( wxMouseEvent& event ); + void OnRButtonUp ( wxMouseEvent& event ); + void OnMouseMove ( wxMouseEvent& event ); + + /*** plugin-related methods ***/ + + // should be used, instead of passing the event to ProcessEvent(..) method + // of the top-plugin directly. This method checks if events are currently + // captured and ensures that plugin-event is routed correctly. + + virtual void FirePluginEvent( cbPluginEvent& event ); + + // captures/releases user-input event's for the given plugin + // Input events are: mouse movement, mouse clicks, keyboard input + + virtual void CaptureEventsForPlugin ( cbPluginBase* pPlugin ); + virtual void ReleaseEventsFromPlugin( cbPluginBase* pPlugin ); + + // called by plugins ( also captures/releases mouse in parent frame) + void CaptureEventsForPane( cbDockPane* toPane ); + void ReleaseEventsFromPane( cbDockPane* fromPane ); + + // returns current top-level plugin (the one which receives events first, + // with an exception if input-events are currently captured by some other plugin) + + virtual cbPluginBase& GetTopPlugin(); + + // hooking custom plugins to frame layout + // + // NOTE:: when hooking one plugin on top of the other - + // use SetNextHandler(..) or similar methods + // of wxEvtHandler class to compose the chain of plugins, + // than pass the left-most handler in this chain to + // the above methods (assuming that events are delegated + // from left-most towards right-most handler) + // + // NOTE2:: this secenario is very inconvenient and "low-level", + // use Add/Push/PopPlugin methods instead + + virtual void SetTopPlugin( cbPluginBase* pPlugin ); + + // similar to wxWindow's "push/pop-event-handler" methods, execept + // that plugin is *deleted* upon "popping" + + virtual void PushPlugin( cbPluginBase* pPugin ); + virtual void PopPlugin(); + + virtual void PopAllPlugins(); + + // default plugins are : cbPaneDrawPlugin, cbRowLayoutPlugin, cbBarDragPlugin, + // cbAntiflickerPlugin, cbSimpleCustomizePlugin + // + // this method is automatically invoked, if no plugins were found upon + // fireing of the first plugin-event, i.e. wxFrameLayout *CONFIGURES* itself + + virtual void PushDefaultPlugins(); + + /* "Advanced" methods for plugin-configuration using their */ + /* dynamic class information (e.g. CLASSINFO(pluginClass) ) */ + + // first checks if plugin of the given class is already "hooked up", + // if not, adds it to the top of plugins chain + + virtual void AddPlugin( wxClassInfo* pPlInfo, int paneMask = wxALL_PANES ); + + // first checks if plugin of the givne class already hooked, + // if so, removes it, and then inserts it to the chain + // before plugin of the class given by "pNextPlInfo" + // + // NOTE:: this method is "handy" in some cases, where the order + // of plugin-chain could be important, e.g. one plugin overrides + // some functionallity of the other already hooked plugin, + // thefore the former should be hooked before the one + // who's functionality is being overriden + + virtual void AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, + int paneMask = wxALL_PANES ); + + // checks if plugin of the given class is hooked, removes + // it if found + // + // @param pPlInfo class information structure for the plugin + // @note + // @see wxFrameLayout::Method + + + virtual void RemovePlugin( wxClassInfo* pPlInfo ); + + // returns NULL, if plugin of the given class is not hooked + + virtual cbPluginBase* FindPlugin( wxClassInfo* pPlInfo ); + + bool HasTopPlugin(); + + DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS( wxFrameLayout ) + +public: /* protected really, acessed only by plugins and serializers */ + + friend class cbDockPane; + friend class wxBarHandler; + + wxWindow* mpFrame; // parent frame + wxWindow* mpFrameClient; // client window + cbDockPane* mPanes[MAX_PANES]; // panes in the panel + + // misc. cursors + wxCursor* mpHorizCursor; + wxCursor* mpVertCursor; + wxCursor* mpNormalCursor; + wxCursor* mpDragCursor; + wxCursor* mpNECursor; // no-entry cursor + + // pens for decoration and shades + + wxPen mDarkPen; // default wxSYS_COLOUR_3DSHADOW + wxPen mLightPen; // default wxSYS_COLOUR_3DHILIGHT + wxPen mGrayPen; // default wxSYS_COLOUR_3DFACE + wxPen mBlackPen; // default wxColour( 0, 0, 0) + wxPen mBorderPen; // default wxSYS_COLOUR_3DFACE + + wxPen mNullPen; // transparent pen + + // pane to which the all mouse input is currently directed (caputred) + + cbDockPane* mpPaneInFocus; + + // pane, from which mouse pointer had just left + + cbDockPane* mpLRUPane; + + // bounds of client window in parent frame's coordinates + + wxRect mClntWndBounds; + wxRect mPrevClntWndBounds; + + bool mFloatingOn; + wxPoint mNextFloatedWndPos; + wxSize mFloatingPosStep; + + // current plugin (right-most) plugin which receives events first + + cbPluginBase* mpTopPlugin; + + // plugin, which currently has captured all input events, otherwise NULL + + cbPluginBase* mpCaputesInput; + + // list of event handlers which are "pushed" onto each bar, to catch + // mouse events which are not handled by bars, and froward them to the , + // frome-layout and further to plugins + + wxList mBarSpyList; + + // list of top-most frames which contain floated bars + + wxList mFloatedFrames; + + // linked list of references to all bars (docked/floated/hidden) + + BarArrayT mAllBars; + + // FOR NOW:: dirty stuff... + bool mClientWndRefreshPending; + bool mRecalcPending; + bool mCheckFocusWhenIdle; + +public: /* protected really (accessed only by plugins) */ + + // refrence to custom updates manager + cbUpdatesManagerBase* mpUpdatesMgr; + + // called to set calculated layout to window objects + void PositionClientWindow(); + void PositionPanes(); + void CreateCursors(); + + void RepositionFloatedBar( cbBarInfo* pBar ); + void DoSetBarState( cbBarInfo* pBar ); + + bool LocateBar( cbBarInfo* pBarInfo, + cbRowInfo** ppRow, + cbDockPane** ppPane ); + + + bool HitTestPane( cbDockPane* pPane, int x, int y ); + cbDockPane* HitTestPanes( const wxRect& rect, cbDockPane* pCurPane ); + + // returns panes, to which the given bar belongs + + cbDockPane* GetBarPane( cbBarInfo* pBar ); + + // delegated from "bar-spy" + void ForwardMouseEvent( wxMouseEvent& event, + cbDockPane* pToPane, + int eventType ); + + void RouteMouseEvent( wxMouseEvent& event, int pluginEvtType ); + + void ShowFloatedWindows( bool show ); + + void UnhookFromFrame(); + void HookUpToFrame(); + + // NOTE:: reparenting of windows may NOT work on all platforms + // (reparenting allows control-bars to be floated) + + bool CanReparent(); + void ReparentWindow( wxWindow* pChild, wxWindow* pNewParent ); + + wxRect& GetPrevClientRect() { return mPrevClntWndBounds; } + + void OnPaint( wxPaintEvent& event ); + void OnEraseBackground( wxEraseEvent& event ); + void OnKillFocus( wxFocusEvent& event ); + void OnSetFocus( wxFocusEvent& event ); + void OnActivate( wxActivateEvent& event ); + void OnIdle( wxIdleEvent& event ); + + // factory method + virtual cbUpdatesManagerBase* CreateUpdatesManager(); +}; + +/* structure, which is present in each item of layout, + * it used by any specific updates-manager to store + * auxilary information to be used by it's specific + * updating algorithm + */ + +class cbUpdateMgrData : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbUpdateMgrData ) +public: + wxRect mPrevBounds; // previous state of layout item (in parent frame's coordinates) + + bool mIsDirty; // overrides result of current-against-previous bounds comparison, + // i.e. requires item to be updated, regardless of it's current area + + wxObject* mpCustomData; // any custom data stored by specific updates mgr. + + cbUpdateMgrData(); // is-dirty flag is set TRUE initially + + void StoreItemState( const wxRect& boundsInParent ); + + void SetDirty( bool isDirty = TRUE ); + + void SetCustomData( wxObject* pCustomData ); + + inline bool IsDirty() { return mIsDirty; } +}; + +/* Abstract interface for bar-size handler classes. + * These objects receive notifications, whenever the docking + * state of the bar is changed, thus they have a possibility + * to adjust the values in cbDimInfo::mSizes accordingly. + * Specific handlers can be hooked to specific types of bars. + */ + +class cbBarDimHandlerBase : public wxObject +{ + DECLARE_ABSTRACT_CLASS( cbBarDimHandlerBase ) + +public: + int mRefCount; // since one dim-handler can be assigned + // to multiple bars, it's instance is + // reference-counted +public: + + // initial reference count is 0, since handler is not used, until the + // first invocation of AddRef() + + cbBarDimHandlerBase(); + + void AddRef(); + void RemoveRef(); + + // "bar-state-changes" notification + virtual void OnChangeBarState(cbBarInfo* pBar, int newState ) = 0; + virtual void OnResizeBar( cbBarInfo* pBar, const wxSize& given, wxSize& preferred ) = 0; +}; + +/* helper classes (used internally by wxFrameLayout class) */ + +// holds and manages information about bar dimensions + +class cbDimInfo : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbDimInfo ) +public: + wxSize mSizes[MAX_BAR_STATES]; // preferred sizes for each possible bar state + + wxRect mBounds[MAX_BAR_STATES]; // saved positions and sizes for each + // possible state, values contain (-1)s if + // not initialized yet + + int mLRUPane; // pane to which this bar was docked before it was floated + // (FL_ALIGN_TOP,FL_ALIGN_BOTTOM,..) + + // top/bottom gap, separates decorations + // from the bar's actual window, filled + // with frame's beckground color, default: 0 + + int mVertGap; + + // left/right gap, separates decorations + // from the bar's actual window, filled + // with frame's beckground colour, default: 0 + + int mHorizGap; // NOTE:: gaps are given in frame's coord. orientation + + // TRUE, if vertical/horizotal dimensions cannot be mannualy adjusted + // by user using resizing handles. If FALSE, the frame-layout + // *automatically* places resizing handles among not-fixed bars + + bool mIsFixed; + + cbBarDimHandlerBase* mpHandler; // NULL, if no handler present + +public: + + cbDimInfo(void); + + cbDimInfo( cbBarDimHandlerBase* pDimHandler, + bool isFixed // (see comments on mIsFixed member) + ); + + cbDimInfo( int dh_x, int dh_y, // dims when docked horizontally + int dv_x, int dv_y, // dims when docked vertically + int f_x, int f_y, // dims when floating + + bool isFixed = TRUE,// (see comments on mIsFixed member) + int horizGap = 6, // (see comments on mHorizGap member) + int vertGap = 6, // -/- + + cbBarDimHandlerBase* pDimHandler = NULL + ); + + cbDimInfo( int x, int y, + bool isFixed = TRUE, + int gap = 6, + cbBarDimHandlerBase* pDimHandler = NULL + ); + + const cbDimInfo& operator=( const cbDimInfo& other ); + + // destroys handler automatically, if present + ~cbDimInfo(); + + inline cbBarDimHandlerBase* GetDimHandler() { return mpHandler; } +}; + +WX_DEFINE_ARRAY(float, cbArrayFloat); + +class cbRowInfo : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbRowInfo ) +public: + + BarArrayT mBars; // row content + + // row flags (set up according to row-relations) + + bool mHasUpperHandle; + bool mHasLowerHandle; + bool mHasOnlyFixedBars; + int mNotFixedBarsCnt; + + int mRowWidth; + int mRowHeight; + int mRowY; + + // stores precalculated row's bounds in parent frame's coordinates + wxRect mBoundsInParent; + + // info stored for updates-manager + cbUpdateMgrData mUMgrData; + + cbRowInfo* mpNext; + cbRowInfo* mpPrev; + + cbBarInfo* mpExpandedBar; // NULL, if non of the bars is currently expanded + + cbArrayFloat mSavedRatios; // length-ratios bofore some of the bars was expanded + +public: + cbRowInfo(void); + + ~cbRowInfo(); + + // convenience method + + inline cbBarInfo* GetFirstBar() + + { return mBars.GetCount() ? mBars[0] : NULL; } +}; + +class cbBarInfo : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbBarInfo ) +public: + // textual name, by which this bar is refered in layout-customization dialogs + wxString mName; + + // stores bar's bounds in pane's coordinates + wxRect mBounds; + + // stores precalculated bar's bounds in parent frame's coordinates + wxRect mBoundsInParent; + + // back-ref to the row, which contains this bar + cbRowInfo* mpRow; + + // are set up according to the types of the surrounding bars in the row + bool mHasLeftHandle; + bool mHasRightHandle; + + cbDimInfo mDimInfo; // preferred sizes for each, control bar state + + int mState; // (see definition of controlbar states) + + int mAlignment; // alignment of the pane to which this + // bar is currently placed + + int mRowNo; // row, into which this bar would be placed, + // when in the docking state + + wxWindow* mpBarWnd; // the actual window object, NULL if no window + // is attached to the control bar (possible!) + + double mLenRatio; // length ratio among not-fixed-size bars + + wxPoint mPosIfFloated; // stored last position when bar was in "floated" state + // poistion is stored in parent-window's coordinates + + cbUpdateMgrData mUMgrData; // info stored for updates-manager + + cbBarInfo* mpNext; // next. bar in the row + cbBarInfo* mpPrev; // prev. bar in the row + +public: + cbBarInfo(void); + + ~cbBarInfo(); + + inline bool IsFixed() const { return mDimInfo.mIsFixed; } + + inline bool IsExpanded() const { return this == mpRow->mpExpandedBar; } +}; + +// used for storing original bar's postions in the row, when the "non-destructive-friction" +// option is turned ON + +class cbBarShapeData : public wxObject +{ +public: + wxRect mBounds; + double mLenRatio; +}; + +// used for traversing through all bars of all rows in the pane + +class wxBarIterator +{ + RowArrayT* mpRows; + cbRowInfo* mpRow; + cbBarInfo* mpBar; + +public: + wxBarIterator( RowArrayT& rows ); + + void Reset(); + bool Next(); // TRUE, if next bar is available + + cbBarInfo& BarInfo(); + + // returns reference to currently traversed row + cbRowInfo& RowInfo(); +}; + +/* structure holds configuration options, + * which are usually the same for all panes in + * frame layout + */ + +class cbCommonPaneProperties : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbCommonPaneProperties ) + + // look-and-feel configuration + + bool mRealTimeUpdatesOn; // default: ON + bool mOutOfPaneDragOn; // default: ON + bool mExactDockPredictionOn; // default: OFF + bool mNonDestructFirctionOn; // default: OFF + + bool mShow3DPaneBorderOn; // default: ON + + // FOR NOW:: the below properties are reserved for the "future" + + bool mBarFloatingOn; // default: OFF + bool mRowProportionsOn; // default: OFF + bool mColProportionsOn; // default: ON + bool mBarCollapseIconsOn; // default: OFF + bool mBarDragHintsOn; // default: OFF + + // minimal dimensions for not-fixed bars in this pane (16x16 default) + + wxSize mMinCBarDim; + + // width/height of resizing sash + + int mResizeHandleSize; + + cbCommonPaneProperties(void); +}; + +/* class manages containment and control of control-bars + * along one of the four edges of the parent frame + */ + +class cbDockPane : public wxObject +{ +public: + DECLARE_DYNAMIC_CLASS( cbDockPane ) + + // look-and-feel configuration for this pane + cbCommonPaneProperties mProps; + + // pane margins (in frame's coordinate-syst. orientation) + + int mLeftMargin; // default: 2 pixels + int mRightMargin; // default: 2 pixels + int mTopMargin; // default: 2 pixels + int mBottomMargin; // default: 2 pixels + +public: + // position of the pane in frame's coordinates + wxRect mBoundsInParent; + + // pane width and height in pane's coordinates + int mPaneWidth; + int mPaneHeight; + + int mAlignment; + + // info stored for updates-manager + cbUpdateMgrData mUMgrData; + +public: /* protected really */ + + RowArrayT mRows; + wxFrameLayout* mpLayout; // back-ref + + // transient properties + + wxList mRowShapeData; // shapes of bars of recently modified row, + // stored when in "non-destructive-firction" mode + cbRowInfo* mpStoredRow; // row-info for which the shapes are stored + + friend class wxFrameLayout; + +public: /* protected really (accessed only by plugins) */ + + cbRowInfo* GetRow( int row ); + + int GetRowIndex( cbRowInfo* pRow ); + + // return -1, if row is not present at given vertical position + int GetRowAt( int paneY ); + int GetRowAt( int upperY, int lowerY ); + + // re-setups flags in the row-information structure, so that + // the would match the changed state of row-items correctly + void SyncRowFlags( cbRowInfo* pRow ); + + // layout "AI" helpers: + + bool IsFixedSize( cbBarInfo* pInfo ); + int GetNotFixedBarsCount( cbRowInfo* pRow ); + + int GetRowWidth( wxList* pRow ); + + int GetRowY( cbRowInfo* pRow ); + + bool HasNotFixedRowsAbove( cbRowInfo* pRow ); + bool HasNotFixedRowsBelow( cbRowInfo* pRow ); + bool HasNotFixedBarsLeft ( cbBarInfo* pBar ); + bool HasNotFixedBarsRight( cbBarInfo* pBar ); + + virtual void CalcLengthRatios( cbRowInfo* pInRow ); + virtual void RecalcRowLayout( cbRowInfo* pRow ); + + virtual void ExpandBar( cbBarInfo* pBar ); + virtual void ContractBar( cbBarInfo* pBar ); + + void InitLinksForRow( cbRowInfo* pRow ); + void InitLinksForRows(); + + // coordinate translation between parent's frame and this pane + + void FrameToPane( int* x, int* y ); + void PaneToFrame( int* x, int* y ); + void FrameToPane( wxRect* pRect ); + void PaneToFrame( wxRect* pRect ); + + inline bool HasPoint( const wxPoint& pos, int x, int y, int width, int height ); + + int GetMinimalRowHeight( cbRowInfo* pRow ); + + // given row height includes height of row handles, if present + void SetRowHeight( cbRowInfo* pRow, int newHeight ); + + void DoInsertBar( cbBarInfo* pBar, int rowNo ); + +public: /* protected really (accessed only by plugins) */ + + // methods for incramental on-screen refreshing of the pane + // (simply, they are wrappers around corresponding plugin-events) + + virtual void PaintBarDecorations( cbBarInfo* pBar, wxDC& dc ); + virtual void PaintBarHandles( cbBarInfo* pBar, wxDC& dc ); + virtual void PaintBar( cbBarInfo* pBar, wxDC& dc ); + virtual void PaintRowHandles( cbRowInfo* pRow, wxDC& dc ); + virtual void PaintRowBackground ( cbRowInfo* pRow, wxDC& dc ); + virtual void PaintRowDecorations( cbRowInfo* pRow, wxDC& dc ); + virtual void PaintRow( cbRowInfo* pRow, wxDC& dc ); + virtual void PaintPaneBackground( wxDC& dc ); + virtual void PaintPaneDecorations( wxDC& dc ); + virtual void PaintPane( wxDC& dc ); + virtual void SizeBar( cbBarInfo* pBar ); + virtual void SizeRowObjects( cbRowInfo* pRow ); + virtual void SizePaneObjects(); + + virtual wxDC* StartDrawInArea ( const wxRect& area ); + virtual void FinishDrawInArea( const wxRect& area ); + +public: /* public members */ + + cbDockPane(void); + + cbDockPane( int alignment, wxFrameLayout* pPanel ); + + // sets pane's margins in frame's coordinate orientations + void SetMargins( int top, int bottom, int left, int right ); + + virtual ~cbDockPane(); + + // does not destroys the info bar , only removes it's reference + // from this pane + + virtual void RemoveBar( cbBarInfo* pBar ); + + // rect given in the parent frame's coordinates + + virtual void InsertBar( cbBarInfo* pBar, const wxRect& atRect ); + + // inserts bar into the given row, with dimensions and position + // stored in pBarInfo->mBounds. Returns the node of inserted bar + + virtual void InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow ); + + // inserts bar, sets its position according to the preferred settings + // given in (*pBarInfo) structure + + virtual void InsertBar( cbBarInfo* pBarInfo ); + + // does not destroy the row object, only removes the corresponding + // node from this pane + virtual void RemoveRow( cbRowInfo* pRow ); + + // does not refresh the inserted row immediately, + // if pBeforeRowNode arg. is NULL, row is appended to the end of pane's row list + virtual void InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow ); + + // sets pane's width in pane's coordinates (including margins) + void SetPaneWidth(int width); + + // set the position and dims. of the pane in parent frame's coordinates + void SetBoundsInParent( const wxRect& rect ); + + inline wxRect& GetRealRect() { return mBoundsInParent; } + + // used by updates-managers + inline RowArrayT& GetRowList() { return mRows; } + + // convenience method + + inline cbRowInfo* GetFirstRow() + + { return mRows.GetCount() ? mRows[0] : NULL; } + + // TRUE, if the given bar node presents in this pane + + bool BarPresent( cbBarInfo* pBar ); + + // retuns height, in pane's coordinates + int GetPaneHeight(); + + int GetAlignment(); + + bool MatchesMask( int paneMask ); + + inline bool IsHorizontal() + { + return (mAlignment == FL_ALIGN_TOP || + mAlignment == FL_ALIGN_BOTTOM ); + } + + virtual void RecalcLayout(); + + virtual int GetDockingState(); + + // returns result of hit-testing items in the pane, + // see CB_HITTEST_RESULTS enumeration + + virtual int HitTestPaneItems( const wxPoint& pos, // position in pane's coordinates + cbRowInfo** ppRow, + cbBarInfo** ppBar + ); + + void GetBarResizeRange( cbBarInfo* pBar, int* from, int *till, bool forLeftHandle ); + void GetRowResizeRange( cbRowInfo* pRow, int* from, int* till, bool forUpperHandle ); + + cbBarInfo* GetBarInfoByWindow( wxWindow* pBarWnd ); + +public: /* protected really (accessed only by plugins) */ + + // row/bar resizing related helper-methods + + void DrawVertHandle ( wxDC& dc, int x, int y, int height ); + void DrawHorizHandle( wxDC& dc, int x, int y, int width ); + + void ResizeRow( cbRowInfo* pRow, int ofs, bool forUpperHandle ); + void ResizeBar( cbBarInfo* pBar, int ofs, bool forLeftHandle ); + + // cbBarShapeData objects will be placed to given pLst (see comments on cbBarShapeData) + + void GetRowShapeData( cbRowInfo* pRow, wxList* pLst ); + + // sets the shape to the given row, using the data provided in pLst + void SetRowShapeData( cbRowInfo* pRowNode, wxList* pLst ); +}; + +/* + * class declares abstract interface for optimized logic, which should refresh + * areas of frame layout - that actually need to be updated. Should be extended, + * to implement custom updating strategy + */ + +class cbUpdatesManagerBase : public wxObject +{ + DECLARE_ABSTRACT_CLASS( cbUpdatesManagerBase ) + +public: /* protected really, accessed by serializer (if any) */ + + wxFrameLayout* mpLayout; + +public: + cbUpdatesManagerBase(void) + : mpLayout( 0 ) {} + + cbUpdatesManagerBase( wxFrameLayout* pPanel ) + : mpLayout( pPanel ) {} + + void SetLayout( wxFrameLayout* pLayout ) { mpLayout = pLayout; } + + // notificiactions received from frame-layout (in the order, in which + // they usually would be invoked). Custom updates-managers may utilize + // these notifications to implement more "fine-grained" updating strategy + + virtual void OnStartChanges() = 0; + + virtual void OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane ) {} + virtual void OnBarWillChange( cbBarInfo* pBar, cbRowInfo* pInRow, cbDockPane* pInPane ) {} + virtual void OnPaneMarginsWillChange( cbDockPane* pPane ) {} + virtual void OnPaneWillChange( cbDockPane* pPane ) {} + + virtual void OnFinishChanges() {} + + // refreshes parts of the frame layout, which need an update + virtual void UpdateNow() = 0; +}; + +/*------------------------------------------------------------ + * "API" for developing custom plugins of Frame Layout Engine + * TODO:: documentation + *------------------------------------------------------------ + */ + +// base class for all control-bar plugin events + +class cbPluginEvent : public wxEvent +{ + // NOTE:: plugin-event does not need to be a dynamic class + +public: + cbDockPane* mpPane; // NULL, if event is not addressed to any specific pane + + /* OLD STUFF:: + // FOR NOW FOR NOW:: all-in-one plugin event structure + wxNode* mpObjNode; + wxNode* mpObjNodeAux; + wxPoint mPos; + wxSize mSize; + wxDC* mpDC; + bool mAuxBoolVal; + */ + +#if wxCHECK_VERSION(2,3,0) + cbPluginEvent( wxEventType eventType, cbDockPane* pPane ) + : mpPane( pPane ) + + { m_eventType = eventType; } +#else + cbPluginEvent( int eventType, cbDockPane* pPane ) + : mpPane( pPane ) + + { m_eventType = eventType; } +#endif +}; + +// event types handled by plugins + +#if wxCHECK_VERSION(2,3,0) + + extern wxEventType cbEVT_PL_LEFT_DOWN; + extern wxEventType cbEVT_PL_LEFT_UP; + extern wxEventType cbEVT_PL_RIGHT_DOWN; + extern wxEventType cbEVT_PL_RIGHT_UP; + extern wxEventType cbEVT_PL_MOTION; + + extern wxEventType cbEVT_PL_LEFT_DCLICK; + + extern wxEventType cbEVT_PL_LAYOUT_ROW; + extern wxEventType cbEVT_PL_RESIZE_ROW; + extern wxEventType cbEVT_PL_LAYOUT_ROWS; + extern wxEventType cbEVT_PL_INSERT_BAR; + extern wxEventType cbEVT_PL_RESIZE_BAR; + extern wxEventType cbEVT_PL_REMOVE_BAR; + extern wxEventType cbEVT_PL_SIZE_BAR_WND; + + extern wxEventType cbEVT_PL_DRAW_BAR_DECOR; + extern wxEventType cbEVT_PL_DRAW_ROW_DECOR; + extern wxEventType cbEVT_PL_DRAW_PANE_DECOR; + extern wxEventType cbEVT_PL_DRAW_BAR_HANDLES; + extern wxEventType cbEVT_PL_DRAW_ROW_HANDLES; + extern wxEventType cbEVT_PL_DRAW_ROW_BKGROUND; + extern wxEventType cbEVT_PL_DRAW_PANE_BKGROUND; + + extern wxEventType cbEVT_PL_START_BAR_DRAGGING; + extern wxEventType cbEVT_PL_DRAW_HINT_RECT; + + extern wxEventType cbEVT_PL_START_DRAW_IN_AREA; + extern wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA; + + extern wxEventType cbEVT_PL_CUSTOMIZE_BAR; + extern wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT; + + extern wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT; + +#else + + #define cbEVT_PL_LEFT_DOWN 0 + #define cbEVT_PL_LEFT_UP 1 + #define cbEVT_PL_RIGHT_DOWN 2 + #define cbEVT_PL_RIGHT_UP 3 + #define cbEVT_PL_MOTION 4 + + #define cbEVT_PL_LEFT_DCLICK 5 + + #define cbEVT_PL_LAYOUT_ROW 6 + #define cbEVT_PL_RESIZE_ROW 7 + #define cbEVT_PL_LAYOUT_ROWS 8 + #define cbEVT_PL_INSERT_BAR 9 + #define cbEVT_PL_RESIZE_BAR 10 + #define cbEVT_PL_REMOVE_BAR 11 + #define cbEVT_PL_SIZE_BAR_WND 12 + + #define cbEVT_PL_DRAW_BAR_DECOR 13 + #define cbEVT_PL_DRAW_ROW_DECOR 14 + #define cbEVT_PL_DRAW_PANE_DECOR 15 + #define cbEVT_PL_DRAW_BAR_HANDLES 16 + #define cbEVT_PL_DRAW_ROW_HANDLES 17 + #define cbEVT_PL_DRAW_ROW_BKGROUND 18 + #define cbEVT_PL_DRAW_PANE_BKGROUND 19 + + #define cbEVT_PL_START_BAR_DRAGGING 20 + #define cbEVT_PL_DRAW_HINT_RECT 21 + + #define cbEVT_PL_START_DRAW_IN_AREA 22 + #define cbEVT_PL_FINISH_DRAW_IN_AREA 23 + + #define cbEVT_PL_CUSTOMIZE_BAR 24 + #define cbEVT_PL_CUSTOMIZE_LAYOUT 25 + + #define wxCUSTOM_CB_PLUGIN_EVENTS_START_AT 100 + +#endif // wxCHECK_VERSION(2,3,0) else + +// forward decls, separated by categories + +class cbLeftDownEvent; +class cbLeftUpEvent; +class cbRightDownEvent; +class cbRightUpEvent; +class cbMotionEvent; +class cbLeftDClickEvent; + +class cbLayoutRowEvent; +class cbResizeRowEvent; +class cbLayoutRowsEvent; +class cbInsertBarEvent; +class cbResizeBarEvent; +class cbRemoveBarEvent; +class cbSizeBarWndEvent; + +class cbDrawBarDecorEvent; +class cbDrawRowDecorEvent; +class cbDrawPaneDecorEvent; +class cbDrawBarHandlesEvent; +class cbDrawRowHandlesEvent; +class cbDrawRowBkGroundEvent; +class cbDrawPaneBkGroundEvent; + +class cbStartBarDraggingEvent; +class cbDrawHintRectEvent; + +class cbStartDrawInAreaEvent; +class cbFinishDrawInAreaEvent; + +class cbCustomizeBarEvent; +class cbCustomizeLayoutEvent; + +// defs. for handler-methods + +typedef void (wxEvtHandler::*cbLeftDownHandler )(cbLeftDownEvent&); +typedef void (wxEvtHandler::*cbLeftUpHandler )(cbLeftUpEvent&); +typedef void (wxEvtHandler::*cbRightDownHandler )(cbRightDownEvent&); +typedef void (wxEvtHandler::*cbRightUpHandler )(cbRightUpEvent&); +typedef void (wxEvtHandler::*cbMotionHandler )(cbMotionEvent&); +typedef void (wxEvtHandler::*cbLeftDClickHandler )(cbLeftDClickEvent&); + +typedef void (wxEvtHandler::*cbLayoutRowHandler )(cbLayoutRowEvent&); +typedef void (wxEvtHandler::*cbResizeRowHandler )(cbResizeRowEvent&); +typedef void (wxEvtHandler::*cbLayoutRowsHandler )(cbLayoutRowsEvent&); +typedef void (wxEvtHandler::*cbInsertBarHandler )(cbInsertBarEvent&); +typedef void (wxEvtHandler::*cbResizeBarHandler )(cbResizeBarEvent&); +typedef void (wxEvtHandler::*cbRemoveBarHandler )(cbRemoveBarEvent&); +typedef void (wxEvtHandler::*cbSizeBarWndHandler )(cbSizeBarWndEvent&); + +typedef void (wxEvtHandler::*cbDrawBarDecorHandler )(cbDrawBarDecorEvent&); +typedef void (wxEvtHandler::*cbDrawRowDecorHandler )(cbDrawRowDecorEvent&); +typedef void (wxEvtHandler::*cbDrawPaneDecorHandler )(cbDrawPaneDecorEvent&); +typedef void (wxEvtHandler::*cbDrawBarHandlesHandler )(cbDrawBarHandlesEvent&); +typedef void (wxEvtHandler::*cbDrawRowHandlesHandler )(cbDrawRowHandlesEvent&); +typedef void (wxEvtHandler::*cbDrawRowBkGroundHandler )(cbDrawRowBkGroundEvent&); +typedef void (wxEvtHandler::*cbDrawPaneBkGroundHandler)(cbDrawPaneBkGroundEvent&); + +typedef void (wxEvtHandler::*cbStartBarDraggingHandler )(cbStartBarDraggingEvent&); +typedef void (wxEvtHandler::*cbDrawHintRectHandler )(cbDrawHintRectEvent&); + +typedef void (wxEvtHandler::*cbStartDrawInAreaHandler )(cbStartDrawInAreaEvent&); +typedef void (wxEvtHandler::*cbFinishDrawInAreaHandler)(cbFinishDrawInAreaEvent&); + +typedef void (wxEvtHandler::*cbCustomizeBarHandler )(cbCustomizeBarEvent&); +typedef void (wxEvtHandler::*cbCustomizeLayoutHandler )(cbCustomizeLayoutEvent&); + +// macros for creating event table entries for plugin-events + +#if wxCHECK_VERSION(2,3,0) + #define EVT_PL_LEFT_DOWN(func) wxEventTableEntry( cbEVT_PL_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDownHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_LEFT_UP(func) wxEventTableEntry( cbEVT_PL_LEFT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftUpHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_RIGHT_DOWN(func) wxEventTableEntry( cbEVT_PL_RIGHT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightDownHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_RIGHT_UP(func) wxEventTableEntry( cbEVT_PL_RIGHT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightUpHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_MOTION(func) wxEventTableEntry( cbEVT_PL_MOTION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbMotionHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_LEFT_DCLICK(func) wxEventTableEntry( cbEVT_PL_LEFT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDClickHandler ) & func, (wxObject *) NULL ), + + #define EVT_PL_LAYOUT_ROW(func) wxEventTableEntry( cbEVT_PL_LAYOUT_ROW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_RESIZE_ROW(func) wxEventTableEntry( cbEVT_PL_RESIZE_ROW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeRowHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_LAYOUT_ROWS(func) wxEventTableEntry( cbEVT_PL_LAYOUT_ROWS, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowsHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_INSERT_BAR(func) wxEventTableEntry( cbEVT_PL_INSERT_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbInsertBarHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_RESIZE_BAR(func) wxEventTableEntry( cbEVT_PL_RESIZE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeBarHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_REMOVE_BAR(func) wxEventTableEntry( cbEVT_PL_REMOVE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRemoveBarHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_SIZE_BAR_WND(func) wxEventTableEntry( cbEVT_PL_SIZE_BAR_WND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbSizeBarWndHandler ) & func, (wxObject *) NULL ), + + #define EVT_PL_DRAW_BAR_DECOR(func) wxEventTableEntry( cbEVT_PL_DRAW_BAR_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarDecorHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_ROW_DECOR(func) wxEventTableEntry( cbEVT_PL_DRAW_ROW_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowDecorHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_PANE_DECOR(func) wxEventTableEntry( cbEVT_PL_DRAW_PANE_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneDecorHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_BAR_HANDLES(func) wxEventTableEntry( cbEVT_PL_DRAW_BAR_HANDLES, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarHandlesHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_ROW_HANDLES(func) wxEventTableEntry( cbEVT_PL_DRAW_ROW_HANDLES, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowHandlesHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_ROW_BKGROUND(func) wxEventTableEntry( cbEVT_PL_DRAW_ROW_BKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowBkGroundHandler ) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_PANE_BKGROUND(func) wxEventTableEntry( cbEVT_PL_DRAW_PANE_BKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneBkGroundHandler) & func, (wxObject *) NULL ), + + #define EVT_PL_START_BAR_DRAGGING(func) wxEventTableEntry( cbEVT_PL_START_BAR_DRAGGING, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartBarDraggingHandler) & func, (wxObject *) NULL ), + #define EVT_PL_DRAW_HINT_RECT(func) wxEventTableEntry( cbEVT_PL_DRAW_HINT_RECT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawHintRectHandler ) & func, (wxObject *) NULL ), + + + #define EVT_PL_START_DRAW_IN_AREA(func) wxEventTableEntry( cbEVT_PL_START_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartDrawInAreaHandler) & func, (wxObject *) NULL ), + #define EVT_PL_FINISH_DRAW_IN_AREA(func) wxEventTableEntry( cbEVT_PL_FINISH_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbFinishDrawInAreaHandler) & func, (wxObject *) NULL ), + + #define EVT_PL_CUSTOMIZE_BAR(func) wxEventTableEntry( cbEVT_PL_CUSTOMIZE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeBarHandler) & func, (wxObject *) NULL ), + #define EVT_PL_CUSTOMIZE_LAYOUT(func) wxEventTableEntry( cbEVT_PL_CUSTOMIZE_LAYOUT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeLayoutHandler) & func, (wxObject *) NULL ), +#else + #define EVT_PL_LEFT_DOWN(func) { cbEVT_PL_LEFT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDownHandler ) & func }, + #define EVT_PL_LEFT_UP(func) { cbEVT_PL_LEFT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftUpHandler ) & func }, + #define EVT_PL_RIGHT_DOWN(func) { cbEVT_PL_RIGHT_DOWN, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightDownHandler ) & func }, + #define EVT_PL_RIGHT_UP(func) { cbEVT_PL_RIGHT_UP, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRightUpHandler ) & func }, + #define EVT_PL_MOTION(func) { cbEVT_PL_MOTION, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbMotionHandler ) & func }, + #define EVT_PL_LEFT_DCLICK(func) { cbEVT_PL_LEFT_DCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDClickHandler ) & func }, + + #define EVT_PL_LAYOUT_ROW(func) { cbEVT_PL_LAYOUT_ROW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowHandler ) & func }, + #define EVT_PL_RESIZE_ROW(func) { cbEVT_PL_RESIZE_ROW, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeRowHandler ) & func }, + #define EVT_PL_LAYOUT_ROWS(func) { cbEVT_PL_LAYOUT_ROWS, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLayoutRowsHandler ) & func }, + #define EVT_PL_INSERT_BAR(func) { cbEVT_PL_INSERT_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbInsertBarHandler ) & func }, + #define EVT_PL_RESIZE_BAR(func) { cbEVT_PL_RESIZE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbResizeBarHandler ) & func }, + #define EVT_PL_REMOVE_BAR(func) { cbEVT_PL_REMOVE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbRemoveBarHandler ) & func }, + #define EVT_PL_SIZE_BAR_WND(func) { cbEVT_PL_SIZE_BAR_WND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbSizeBarWndHandler ) & func }, + + #define EVT_PL_DRAW_BAR_DECOR(func) { cbEVT_PL_DRAW_BAR_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarDecorHandler ) & func }, + #define EVT_PL_DRAW_ROW_DECOR(func) { cbEVT_PL_DRAW_ROW_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowDecorHandler ) & func }, + #define EVT_PL_DRAW_PANE_DECOR(func) { cbEVT_PL_DRAW_PANE_DECOR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneDecorHandler ) & func }, + #define EVT_PL_DRAW_BAR_HANDLES(func) { cbEVT_PL_DRAW_BAR_HANDLES, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawBarHandlesHandler ) & func }, + #define EVT_PL_DRAW_ROW_HANDLES(func) { cbEVT_PL_DRAW_ROW_HANDLES, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowHandlesHandler ) & func }, + #define EVT_PL_DRAW_ROW_BKGROUND(func) { cbEVT_PL_DRAW_ROW_BKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawRowBkGroundHandler ) & func }, + #define EVT_PL_DRAW_PANE_BKGROUND(func) { cbEVT_PL_DRAW_PANE_BKGROUND, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawPaneBkGroundHandler) & func }, + + #define EVT_PL_START_BAR_DRAGGING(func) { cbEVT_PL_START_BAR_DRAGGING, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartBarDraggingHandler) & func }, + #define EVT_PL_DRAW_HINT_RECT(func) { cbEVT_PL_DRAW_HINT_RECT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbDrawHintRectHandler ) & func }, + + #define EVT_PL_START_DRAW_IN_AREA(func) { cbEVT_PL_START_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbStartDrawInAreaHandler) & func }, + #define EVT_PL_FINISH_DRAW_IN_AREA(func) { cbEVT_PL_FINISH_DRAW_IN_AREA, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbFinishDrawInAreaHandler) & func }, + + #define EVT_PL_CUSTOMIZE_BAR(func) { cbEVT_PL_CUSTOMIZE_BAR, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeBarHandler) & func }, + #define EVT_PL_CUSTOMIZE_LAYOUT(func) { cbEVT_PL_CUSTOMIZE_LAYOUT, -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbCustomizeLayoutHandler) & func }, +#endif +/* + * abstract base class for all control-bar related plugins + */ + +class cbPluginBase : public wxEvtHandler +{ + DECLARE_ABSTRACT_CLASS( cbPluginBase ) +public: + + wxFrameLayout* mpLayout; // back-reference to the frame layout + + // specifies panes, for which this plugin receives events + // (see pane masks definitions) + int mPaneMask; + + bool mIsReady; // is TRUE, when plugin is ready to handle events + +public: + cbPluginBase(void) + + : mpLayout ( 0 ), + mPaneMask( wxALL_PANES ), + mIsReady ( FALSE ) + {} + + cbPluginBase( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ) + + : mpLayout ( pPanel ), + mPaneMask( paneMask ), + mIsReady ( FALSE ) + {} + + inline int GetPaneMask() { return mPaneMask; } + + // NOTE:: pointer positions of mouse-events sent to plugins + // are always in pane's coordinates (pane's to which + // this plugin is hooked) + + // destroys the whole plugin chain of connected plagins + virtual ~cbPluginBase(); + + // override this method to do plugin-specific initialization + // (at this point plugin is already attached to the frame layout, + // and pane masks are set) + virtual void OnInitPlugin() { mIsReady = TRUE; } + + bool IsReady() { return mIsReady; } + + // overriden, to determine whether the target pane specified in the + // event, matches the pane mask of this plugin (specific plugins + // do not override this method) + + virtual bool ProcessEvent(wxEvent& event); +}; + +/*** event classes, for each corresponding event type (24 currnetly...uhh) ***/ + +// mouse-events category + +class cbLeftDownEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbLeftDownEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_LEFT_DOWN, pPane ), + mPos( pos ) + {} +}; + +class cbLeftUpEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbLeftUpEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_LEFT_UP, pPane ), + mPos( pos ) + {} +}; + +class cbRightDownEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbRightDownEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_RIGHT_DOWN, pPane ), + mPos( pos ) + {} +}; + +class cbRightUpEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbRightUpEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_RIGHT_UP, pPane ), + mPos( pos ) + {} +}; + +class cbMotionEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbMotionEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_MOTION, pPane ), + mPos( pos ) + {} +}; + +class cbLeftDClickEvent : public cbPluginEvent +{ +public: + wxPoint mPos; + + cbLeftDClickEvent( const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_LEFT_DCLICK, pPane ), + mPos( pos ) + {} +}; + +// bar/row events category + +class cbLayoutRowEvent : public cbPluginEvent +{ +public: + cbRowInfo* mpRow; + + cbLayoutRowEvent( cbRowInfo* pRow, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_LAYOUT_ROW, pPane ), + mpRow( pRow ) + {} +}; + +class cbResizeRowEvent : public cbPluginEvent +{ +public: + cbRowInfo* mpRow; + int mHandleOfs; + bool mForUpperHandle; + + cbResizeRowEvent( cbRowInfo* pRow, int handleOfs, bool forUpperHandle, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_RESIZE_ROW, pPane ), + mpRow( pRow ), + mHandleOfs( handleOfs ), + mForUpperHandle( forUpperHandle ) + {} +}; + +class cbLayoutRowsEvent : public cbPluginEvent +{ +public: + + cbLayoutRowsEvent( cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_LAYOUT_ROWS, pPane ) + {} +}; + +class cbInsertBarEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + cbRowInfo* mpRow; + + cbInsertBarEvent( cbBarInfo* pBar, cbRowInfo* pIntoRow, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_INSERT_BAR, pPane ), + + mpBar( pBar ), + mpRow( pIntoRow ) + {} +}; + +class cbResizeBarEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + cbRowInfo* mpRow; + + cbResizeBarEvent( cbBarInfo* pBar, cbRowInfo* pRow, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_RESIZE_BAR, pPane ), + mpBar( pBar ), + mpRow( pRow ) + {} +}; + +class cbRemoveBarEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + + cbRemoveBarEvent( cbBarInfo* pBar, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_REMOVE_BAR, pPane ), + mpBar( pBar ) + {} +}; + +class cbSizeBarWndEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + wxRect mBoundsInParent; + + cbSizeBarWndEvent( cbBarInfo* pBar, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_SIZE_BAR_WND, pPane ), + mpBar( pBar ), + mBoundsInParent( pBar->mBoundsInParent ) + {} +}; + +class cbDrawBarDecorEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + wxDC* mpDc; + wxRect mBoundsInParent; + + cbDrawBarDecorEvent( cbBarInfo* pBar, wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_BAR_DECOR, pPane ), + mpBar( pBar ), + mpDc( &dc ), + mBoundsInParent( pBar->mBoundsInParent ) + {} +}; + +class cbDrawRowDecorEvent : public cbPluginEvent +{ +public: + cbRowInfo* mpRow; + wxDC* mpDc; + + cbDrawRowDecorEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_ROW_DECOR, pPane ), + mpRow( pRow ), + mpDc( &dc ) + {} +}; + +class cbDrawPaneDecorEvent : public cbPluginEvent +{ +public: + wxDC* mpDc; + + cbDrawPaneDecorEvent( wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_PANE_DECOR, pPane ), + mpDc( &dc ) + {} +}; + +class cbDrawBarHandlesEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + wxDC* mpDc; + + cbDrawBarHandlesEvent( cbBarInfo* pBar, wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_BAR_HANDLES, pPane ), + mpBar( pBar ), + mpDc( &dc ) + {} +}; + +class cbDrawRowHandlesEvent : public cbPluginEvent +{ +public: + cbRowInfo* mpRow; + wxDC* mpDc; + + cbDrawRowHandlesEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_ROW_HANDLES, pPane ), + mpRow( pRow ), + mpDc( &dc ) + {} +}; + +class cbDrawRowBkGroundEvent : public cbPluginEvent +{ +public: + cbRowInfo* mpRow; + wxDC* mpDc; + + cbDrawRowBkGroundEvent( cbRowInfo* pRow, wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_ROW_BKGROUND, pPane ), + mpRow( pRow ), + mpDc( &dc ) + {} +}; + +class cbDrawPaneBkGroundEvent : public cbPluginEvent +{ +public: + wxDC* mpDc; + + cbDrawPaneBkGroundEvent( wxDC& dc, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_DRAW_PANE_BKGROUND, pPane ), + mpDc( &dc ) + {} +}; + +class cbStartBarDraggingEvent : public cbPluginEvent +{ +public: + cbBarInfo* mpBar; + wxPoint mPos; // is given in frame's coordinates + + cbStartBarDraggingEvent( cbBarInfo* pBar, const wxPoint& pos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_START_BAR_DRAGGING, pPane ), + mpBar( pBar ), + mPos( pos ) + {} +}; + +class cbDrawHintRectEvent : public cbPluginEvent +{ +public: + wxRect mRect; // is given in frame's coordinates + + + bool mLastTime; // indicates that this event finishes "session" of on-screen drawing, + // thus associated resources can be freed now + bool mEraseRect; // does not have any impact, if recangle is drawn using XOR-mask + + bool mIsInClient;// in cleint area hint could be drawn differently, + // e.g. with fat/hatched border + + + cbDrawHintRectEvent( const wxRect& rect, bool isInClient, bool eraseRect, bool lastTime ) + + : cbPluginEvent( cbEVT_PL_DRAW_HINT_RECT, 0 ), + mRect ( rect ), + mLastTime ( lastTime ), + mEraseRect ( eraseRect ), + mIsInClient( isInClient ) + {} +}; + +class cbStartDrawInAreaEvent : public cbPluginEvent +{ +public: + wxRect mArea; + wxDC** mppDc; // points to pointer, where the reference + // to the obtained buffer-context should be placed + + cbStartDrawInAreaEvent( const wxRect& area, wxDC** ppDCForArea, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_START_DRAW_IN_AREA, pPane ), + mArea( area ), + mppDc( ppDCForArea ) + {} +}; + +class cbFinishDrawInAreaEvent : public cbPluginEvent +{ +public: + wxRect mArea; + + cbFinishDrawInAreaEvent( const wxRect& area, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_FINISH_DRAW_IN_AREA, pPane ), + mArea( area ) + {} +}; + +class cbCustomizeBarEvent : public cbPluginEvent +{ +public: + wxPoint mClickPos; // in parent frame's coordinates + cbBarInfo* mpBar; + + cbCustomizeBarEvent( cbBarInfo* pBar, const wxPoint& clickPos, cbDockPane* pPane ) + + : cbPluginEvent( cbEVT_PL_CUSTOMIZE_BAR, pPane ), + mClickPos( clickPos ), + mpBar( pBar ) + {} +}; + +class cbCustomizeLayoutEvent : public cbPluginEvent +{ +public: + wxPoint mClickPos; // in parent frame's coordinates + + cbCustomizeLayoutEvent( const wxPoint& clickPos ) + + : cbPluginEvent( cbEVT_PL_CUSTOMIZE_LAYOUT, 0 ), + mClickPos( clickPos ) + {} +}; + +#endif /* __CONTROLBAR_G__ */ + diff --git a/contrib/include/wx/fl/dynbarhnd.h b/contrib/include/wx/fl/dynbarhnd.h new file mode 100644 index 0000000000..9b2933c054 --- /dev/null +++ b/contrib/include/wx/fl/dynbarhnd.h @@ -0,0 +1,22 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/01/99 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __DYNBARHND_G__ +#define __DYNBARHND_G__ + +#ifdef __GNUG__ + #pragma interface "dynbarhnd.h" +#endif + +#include "wx/fl/controlbar.h" + +#endif /* __DYNBARHND_G__ */ + diff --git a/contrib/include/wx/fl/dyntbar.h b/contrib/include/wx/fl/dyntbar.h new file mode 100644 index 0000000000..942b496aec --- /dev/null +++ b/contrib/include/wx/fl/dyntbar.h @@ -0,0 +1,204 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: ??/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __DYNTBAR_G__ +#define __DYNTBAR_G__ + +#ifdef __GNUG__ + #pragma interface "dyntbar.h" +#endif + +#include "wx/tbarbase.h" +#include "wx/dynarray.h" + +// layout item + +class wxToolLayoutItem : public wxObject +{ +public: + wxRect mRect; + bool mIsSeparator; +}; + +class wxDynToolInfo; + +typedef wxToolLayoutItem* wxToolLayoutItemPtrT; +typedef wxDynToolInfo* wxDynToolInfoPtrT; + + +WX_DEFINE_ARRAY( wxToolLayoutItemPtrT, wxLayoutItemArrayT ); +WX_DEFINE_ARRAY( wxDynToolInfoPtrT, wxDynToolInfoArrayT ); + +// base class for layouting algorithm implementations + +class LayoutManagerBase +{ +public: + virtual void Layout( const wxSize& parentDim, + wxSize& resultingDim, + wxLayoutItemArrayT& items, + int horizGap, + int vertGap ) = 0; + + virtual ~LayoutManagerBase() {} +}; + +// layouts items in left-to-right order from +// top towards bottom + +class BagLayout : public LayoutManagerBase +{ +public: + virtual void Layout( const wxSize& parentDim, + wxSize& resultingDim, + wxLayoutItemArrayT& items, + int horizGap, + int vertGap ); +}; + +class wxDynToolInfo : public wxToolLayoutItem +{ + DECLARE_DYNAMIC_CLASS(wxDynToolInfo) + +public: + wxWindow* mpToolWnd; + int mIndex; + wxSize mRealSize; +}; + +// layouting orientations for tools + +#define LO_HORIZONTAL 0 +#define LO_VERTICAL 1 +#define LO_FIT_TO_WINDOW 2 + +// class manages containment and layouting of tool-windows + +class wxDynamicToolBar : public wxToolBarBase +{ + DECLARE_DYNAMIC_CLASS(wxDynamicToolBar) +protected: + + friend class wxDynamicToolBarSerializer; + + wxDynToolInfoArrayT mTools; + LayoutManagerBase* mpLayoutMan; + +protected: + virtual void SizeToolWindows(); + +public: /* public properties */ + + int mSepartorSize; // default: 8 + int mVertGap; // default: 0 + int mHorizGap; // default: 0 + +public: + wxDynamicToolBar(); + + wxDynamicToolBar(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + const long style = wxNO_BORDER, const int orientation = wxVERTICAL, + const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr); + + ~wxDynamicToolBar(void); + + bool Create(wxWindow *parent, const wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, + const long style = wxNO_BORDER, const int orientation = wxVERTICAL, const int RowsOrColumns = 1, const wxString& name = wxToolBarNameStr); + + // overridables + + virtual void AddTool( int toolIndex, + wxWindow* pToolWindow, + const wxSize& size = wxDefaultSize ); + + virtual void AddTool( int toolIndex, + const wxString& imageFileName, + int imageFileType = wxBITMAP_TYPE_BMP, + const wxString& labelText = "", bool alignTextRight = FALSE, + bool isFlat = TRUE ); + virtual void AddTool( int toolIndex, wxBitmap labelBmp, + const wxString& labelText = "", bool alignTextRight = FALSE, + bool isFlat = TRUE ); + + // method from wxToolBarBase (for compatibility), only + // first two arguments are valid + + virtual wxToolBarToolBase *AddTool(const int toolIndex, const wxBitmap& bitmap, const wxBitmap& pushedBitmap = wxNullBitmap, + const bool toggle = FALSE, const long xPos = -1, const long yPos = -1, wxObject *clientData = NULL, + const wxString& helpString1 = "", const wxString& helpString2 = ""); + + virtual void AddSeparator( wxWindow* pSepartorWnd = NULL ); + + wxDynToolInfo* GetToolInfo( int toolIndex ); + + void RemveTool( int toolIndex ); + + // the default implementation draws shaded line + virtual void DrawSeparator( wxDynToolInfo& info, wxDC& dc ); + + // see definitions of orientation types + virtual bool Layout(); + + virtual void GetPreferredDim( const wxSize& givenDim, wxSize& prefDim ); + + virtual LayoutManagerBase* CreateDefaulLayout() { return new BagLayout(); } + + virtual void SetLayout( LayoutManagerBase* pLayout ); + + virtual void EnableTool(const int toolIndex, const bool enable = TRUE); + + // event handlers + + void OnSize( wxSizeEvent& event ); + void OnPaint( wxPaintEvent& event ); + void OnEraseBackground( wxEraseEvent& event ); + + // overriden from wxToolBarBase + + virtual bool Realize(void); + + // stuff from the 2.1.15 + + virtual wxToolBarToolBase *FindToolForPosition(wxCoord x, + wxCoord y) const; + + + virtual bool DoInsertTool(size_t pos, wxToolBarToolBase *tool); + + // the tool is still in m_tools list when this function is called, it will + // only be deleted from it if it succeeds + virtual bool DoDeleteTool(size_t pos, wxToolBarToolBase *tool); + + // called when the tools enabled flag changes + virtual void DoEnableTool(wxToolBarToolBase *tool, bool enable); + + // called when the tool is toggled + virtual void DoToggleTool(wxToolBarToolBase *tool, bool toggle); + + // called when the tools "can be toggled" flag changes + virtual void DoSetToggle(wxToolBarToolBase *tool, bool toggle); + + // the functions to create toolbar tools + virtual wxToolBarToolBase *CreateTool(int id, + const wxBitmap& bitmap1, + const wxBitmap& bitmap2, + bool toggle, + wxObject *clientData, + const wxString& shortHelpString, + const wxString& longHelpString); + virtual wxToolBarToolBase *CreateTool(wxControl *control); + + + DECLARE_EVENT_TABLE() +}; + +#endif /* __DYNTBAR_G__ */ + diff --git a/contrib/include/wx/fl/dyntbarhnd.h b/contrib/include/wx/fl/dyntbarhnd.h new file mode 100644 index 0000000000..1fed738ccf --- /dev/null +++ b/contrib/include/wx/fl/dyntbarhnd.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/01/99 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __DYNTBARHND_G__ +#define __DYNTBARHND_G__ + +#ifdef __GNUG__ + #pragma interface "dyntbarhnd.h" +#endif + +#include "wx/fl/controlbar.h" +#include "wx/fl/dyntbar.h" + +class cbDynToolBarDimHandler : public cbBarDimHandlerBase +{ + DECLARE_DYNAMIC_CLASS( cbDynToolBarDimHandler ) +public: + void OnChangeBarState(cbBarInfo* pBar, int newState ); + void OnResizeBar( cbBarInfo* pBar, const wxSize& given, wxSize& preferred ); +}; + +#endif /* __DYNTBARHND_G__ */ + diff --git a/contrib/include/wx/fl/frmview.h b/contrib/include/wx/fl/frmview.h new file mode 100644 index 0000000000..90f33702f6 --- /dev/null +++ b/contrib/include/wx/fl/frmview.h @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 02/01/99 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMVIEW_G__ +#define __FRMVIEW_G__ + +#ifdef __GNUG__ + #pragma interface "frmview.h" +#endif + +#include "wx/module.h" + +#if 0 +#include "wx/fl/objstore.h" +#endif + +class wxObjectStorage; + +#include "wx/fl/controlbar.h" + +class wxFrameManager; + +class wxFrameView : public wxEvtHandler +{ +protected: + wxStringList mTopMenus; + wxFrameLayout* mpLayout; + wxFrameManager* mpFrameMgr; + bool mDoToolUpdates; + + friend class wxFrameManager; + friend class wxFrameViewSerializer; + +protected: + void OnIdle( wxIdleEvent& event); + +public: + wxFrameView(); + ~wxFrameView(); + + virtual void Activate(); + virtual void Deactivate(); + + wxFrame* GetParentFrame(); + wxWindow* GetClientWindow(); + + wxFrameManager& GetFrameManager(); + + void RegisterMenu( const wxString& topMenuName ); + + void CreateLayout(); + wxFrameLayout* GetLayout(); + void SetLayout( wxFrameLayout* pLayout ); + void SetToolUpdates( bool doToolUpdates = TRUE ); + + + // hooks for specific frame-views + + virtual void OnInit() {} + + virtual void OnSerialize( wxObjectStorage& store ) {} + virtual void OnActiveate() {} + virtual void OnDeactivate() {} + + // imp. is mandatory + virtual void OnRecreate() {} + virtual void OnInitMenus() {} + + DECLARE_EVENT_TABLE() +}; + +class wxFrame; + +class wxFrameManager : wxObject +{ +protected: + wxList mViews; + wxWindow* mpFrameWnd; + int mActiveViewNo; + wxWindow* mpClientWnd; + +#if 0 + wxObjectStorage mStore; +#endif + + wxString mSettingsFile; + +protected: + void DoSerialize( wxObjectStorage& store ); + void DestroyViews(); + int GetViewNo( wxFrameView* pView ); + void EnableMenusForView( wxFrameView* pView, bool enable ); + void SyncAllMenus(); + +public: + wxFrameManager(); + ~wxFrameManager(); + + // if file name is empty, views are are not saved/loaded + + virtual void Init( wxWindow* pMainFrame, const wxString& settingsFile = "" ); + + // synonyms + wxFrame* GetParentFrame(); + wxWindow* GetParentWindow(); + + int GetActiveViewNo(); + wxFrameView* GetActiveView(); + wxNode* GetActiveViewNode(); + + wxFrameView* GetView( int viewNo ); + + void SetClinetWindow( wxWindow* pFrameClient ); + wxWindow* GetClientWindow(); + + void AddView( wxFrameView* pFrmView ); + void RemoveView( wxFrameView* pFrmView ); + + void ActivateView( int viewNo ); + void ActivateView( wxFrameView* pFrmView ); + void DeactivateCurrentView(); + + wxObjectStorage& GetObjectStore(); + + void SaveViewsNow(); + bool ReloadViews(); + + bool ViewsAreLoaded(); +}; + +#endif /* __FRMVIEW_G__ */ + diff --git a/contrib/include/wx/fl/garbagec.h b/contrib/include/wx/fl/garbagec.h new file mode 100644 index 0000000000..d710e9f7a3 --- /dev/null +++ b/contrib/include/wx/fl/garbagec.h @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas (@Lithuania) +// Modified by: +// Created: ??/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __GARBAGEC_G__ +#define __GARBAGEC_G__ + +#ifdef __GNUG__ + #pragma interface "garbagec.h" +#endif + +#include "wx/list.h" + +struct GCItem +{ + void* mpObj; + wxList mRefs; // references to other nodes +}; + +inline void* gc_node_to_obj( wxNode* pGCNode ) +{ + return ( (GCItem*) (pGCNode->Data()) )->mpObj; +} + +// class implements extremely slow, but probably one of the most simple GC algorithms + +class GarbageCollector +{ +protected: + wxList mAllNodes; + wxList mRegularLst; + wxList mCycledLst; + + wxNode* FindItemNode( void* pForObj ); + void ResolveReferences(); + + wxNode* FindReferenceFreeItemNode(); + void RemoveReferencesToNode( wxNode* pItemNode ); + void DestroyItemList( wxList& lst ); + +public: + + GarbageCollector() {} + + virtual ~GarbageCollector(); + + // prepare data for GC alg. + + virtual void AddObject( void* pObj, int refCnt = 1 ); + virtual void AddDependency( void* pObj, void* pDependsOnObj ); + + // executes GC alg. + + virtual void ArrangeCollection(); + + // access results of the alg. + + wxList& GetRegularObjects(); + wxList& GetCycledObjects(); + + // removes all data from GC + + void Reset(); +}; + +#endif /* __GARBAGEC_G__ */ + diff --git a/contrib/include/wx/fl/gcupdatesmgr.h b/contrib/include/wx/fl/gcupdatesmgr.h new file mode 100644 index 0000000000..e8fabc5acc --- /dev/null +++ b/contrib/include/wx/fl/gcupdatesmgr.h @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 19/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __GCUPDATESMGR_G__ +#define __GCUPDATESMGR_G__ + +#ifdef __GNUG__ + #pragma interface "gcupdatesmgr.h" +#endif + +#include "wx/fl/controlbar.h" +#include "wx/fl/updatesmgr.h" + +#include "wx/fl/garbagec.h" + +/* + * class implements optimized logic for refreshing + * areas of frame layout - which actually need to be updated. + * Is used as default updates-manager by wxFrameLayout. + * + * it is called "Garbage Collecting" u.mgr for it's implementation + * tries to find out dependencies between bars, and to order + * them ito "hierarchy", this hierarchical sorting resembles + * implemenation of heap-garbage collectors, which resolve + * dependencies between references. + * + * Example: there are situations where the order of moving + * the windows does matter: + * + * case 1) + * ------ --- + * | A | |B| + * ------ ---> | | + * --- --- ------ + * |B| | A | + * | | ------ + * --- + * (future) + * (past) + * + * past/future positions of A and B windows completely overlapp, i.e. + * depend on each other, and there is not solution for + * moving the windows witout refreshing both of them, + * -- we have cyclic dependency here. The gc. alg will + * find this cyclic dependecy and will force "refresh" + * after movement. + * + * case 2) + * + * ------ + * | A | + * ------ ---> + * --- + * |B| ------ + * | | | A | + * --- ------ + * --- + * |B| + * | | + * --- + * + * (future) + * (past) + * + * in this case past/future positions do not overlapp, thus + * it's enough only to move windows, without refreshing them. + * GC will "notice" it. + * + * there is also third case, when overlapping is partial + * in this case the refershing can be also avoided by + * moving windows in the order of "most-dependant" towards the + * "least-dependent". GC handles this automatically, by + * sorting windows by their dependency-level (or "hierarchy") + * + * See garbagec.h for more details of this method, garbagec.h/cpp + * implement sorting of generic-dependencies (does not deal + * with graphical objects directly) + * + * Summary: improves performance when complex/large windows are + * moved around, by reducing number of repaints. Also helps + * to avoid dirty non-client areas of moved windows + * in some special cases of "overlapping anomalies" + */ + +class cbGCUpdatesMgr : public cbSimpleUpdatesMgr +{ + DECLARE_DYNAMIC_CLASS( cbGCUpdatesMgr ) +protected: + + GarbageCollector mGC; + + void DoRepositionItems( wxList& items ); + + void AddItem( wxList& itemList, + cbBarInfo* pBar, + cbDockPane* pPane, + wxRect& curBounds, + wxRect& prevBounds ); + +public: + + cbGCUpdatesMgr(void) {} + + cbGCUpdatesMgr( wxFrameLayout* pPanel ); + + // notificiactions received from Frame Layout : + + virtual void OnStartChanges(); + + // refreshes parts of the frame layout, which need an update + virtual void UpdateNow(); +}; + +#endif /* __GCUPDATESMGR_G__ */ + diff --git a/contrib/include/wx/fl/hintanimpl.h b/contrib/include/wx/fl/hintanimpl.h new file mode 100644 index 0000000000..4d8d07a648 --- /dev/null +++ b/contrib/include/wx/fl/hintanimpl.h @@ -0,0 +1,120 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 9/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __HINTANIMPL_G__ +#define __HINTANIMPL_G__ + +#ifdef __GNUG__ + #pragma interface "hintanimpl.h" +#endif + +#include "wx/fl/controlbar.h" + +#include "wx/timer.h" + +class cbHintAnimTimer; + +class cbHintAnimationPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbHintAnimationPlugin ) +protected: + friend class cbHintAnimTimer; + + wxScreenDC* mpScrDc; // created while tracking hint-rect + cbHintAnimTimer* mpAnimTimer; + + // FOR NOW:: try it without mutually exculisve locks + volatile wxRect mCurRect; + + // state variables + + bool mAnimStarted; + bool mStopPending; + + bool mPrevInClient; + bool mCurInClient; + + wxRect mPrevRect; + +public: + int mMorphDelay; // delay between frames in miliseconds, default: 20 + int mMaxFrames; // number of iterations for hint morphing, default: 30 + // (morph duration = mMorphDelay * mMaxFrames msec) + + int mInClientHintBorder; // default: 4 pixels + + bool mAccelerationOn; // TRUE, if morph accelerates, otherwise morph + // speed is constant. Default: TRUE + + // TBD:: get/set methods for above members + +protected: + void StartTracking(); + + void DrawHintRect ( wxRect& rect, bool isInClientRect); + void EraseHintRect( wxRect& rect, bool isInClientRect); + + void FinishTracking(); + + void DoDrawHintRect( wxRect& rect, bool isInClientRect); + + void RectToScr( wxRect& frameRect, wxRect& scrRect ); + +public: + cbHintAnimationPlugin(void); + + ~cbHintAnimationPlugin(); + + cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + void OnDrawHintRect( cbDrawHintRectEvent& event ); + + DECLARE_EVENT_TABLE() +}; + + +// helper classes + +struct MorphInfoT +{ + wxPoint mFrom; + wxPoint mTill; +}; + +class cbHintAnimTimer : public wxTimer +{ +protected: + + friend class cbHintAnimationPlugin; + + wxRect mPrevMorphed; + + MorphInfoT mUpperLeft; + MorphInfoT mLowerRight; + int mCurIter; + + long mLock; + + cbHintAnimationPlugin* mpPl; + + void MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point ); + +public: + + cbHintAnimTimer(void); + + virtual void Notify(void); + + virtual bool Init( cbHintAnimationPlugin* pAnimPl, bool reinit ); +}; + +#endif /* __HINTANIMPL_G__ */ + diff --git a/contrib/include/wx/fl/newbmpbtn.h b/contrib/include/wx/fl/newbmpbtn.h new file mode 100644 index 0000000000..a386211513 --- /dev/null +++ b/contrib/include/wx/fl/newbmpbtn.h @@ -0,0 +1,165 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: ??/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __NEWBMPBTN_G__ +#define __NEWBMPBTN_G__ + +#ifdef __GNUG__ + #pragma interface "newbmpbtn.h" +#endif + +#include "wx/button.h" +#include "wx/string.h" + +// button lable-text alignment types + +#define NB_ALIGN_TEXT_RIGHT 0 +#define NB_ALIGN_TEXT_BOTTOM 1 +#define NB_NO_TEXT 2 +#define NB_NO_IMAGE 3 + +// classes declared in this header file + +class wxNewBitmapButton; +class wxBorderLessBitmapButton; + +// alternative class for wxBmpButton + +class wxNewBitmapButton: public wxPanel +{ + DECLARE_DYNAMIC_CLASS(wxNewBitmapButton) + +protected: + + friend class wxNewBitmapButtonSerializer; + + int mTextToLabelGap; + int mMarginX; + int mMarginY; + int mTextAlignment; + bool mIsSticky; + bool mIsFlat; + + wxString mLabelText; + wxString mImageFileName; + int mImageFileType; + + wxBitmap mDepressedBmp; // source image for rendering + // labels for particular state + + wxBitmap mFocusedBmp; // may not be always present - + // only if mHasFocusedBmp is TRUE + + wxBitmap* mpDepressedImg; + wxBitmap* mpPressedImg; + wxBitmap* mpDisabledImg; + wxBitmap* mpFocusedImg; + + // button state variables; + bool mDragStarted; + bool mIsPressed; + bool mIsInFocus; + bool mPrevPressedState; + bool mPrevInFocusState; + + bool mHasFocusedBmp; + + // type of event which is fired upon depression of this button + int mFiredEventType; + + // pens for drawing decorations (borders) + wxPen mBlackPen; + wxPen mDarkPen; + wxPen mGrayPen; + wxPen mLightPen; + + bool mIsCreated; + int mSizeIsSet; + +protected: + void DestroyLabels(); + + // returns the label which match the current button state + virtual wxBitmap* GetStateLabel(); + + virtual void DrawShade( int outerLevel, + wxDC& dc, + wxPen& upperLeftSidePen, + wxPen& lowerRightSidePen ); + + bool IsInWindow( int x,int y ); + +public: + + wxNewBitmapButton( const wxBitmap& labelBitmap = wxNullBitmap, + const wxString& labelText = "", + int alignText = NB_ALIGN_TEXT_BOTTOM, + bool isFlat = TRUE, + // this is the default type of fired events + int firedEventType = wxEVT_COMMAND_MENU_SELECTED, + int marginX = 2, + int marginY = 2, + int textToLabelGap = 2, + bool isSticky = FALSE + ); + + // use this constructor if buttons have to be persistant + + wxNewBitmapButton( const wxString& bitmapFileName, + const int bitmapFileType = wxBITMAP_TYPE_BMP, + const wxString& labelText = "", + int alignText = NB_ALIGN_TEXT_BOTTOM, + bool isFlat = TRUE, + // this is the default type of fired events + int firedEventType = wxEVT_COMMAND_MENU_SELECTED, + int marginX = 2, + int marginY = 2, + int textToLabelGap = 2, + bool isSticky = FALSE + ); + + ~wxNewBitmapButton(); + + // should be called after Create(); + virtual void Reshape(); + + // overridables + virtual void SetLabel(const wxBitmap& labelBitmap, const wxString& labelText = "" ); + + virtual void SetAlignments( int alignText = NB_ALIGN_TEXT_BOTTOM, + int marginX = 2, + int marginY = 2, + int textToLabelGap = 2); + + virtual void DrawDecorations( wxDC& dc ); + virtual void DrawLabel( wxDC& dc ); + + virtual void RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp, + bool isEnabled = TRUE, + bool isPressed = FALSE); + + virtual void RenderLabelImages(); + virtual void RenderAllLabelImages(); + + // event handlers + void OnLButtonDown( wxMouseEvent& event ); + void OnLButtonUp( wxMouseEvent& event ); + void OnMouseMove( wxMouseEvent& event ); + void OnSize( wxSizeEvent& event ); + void OnPaint( wxPaintEvent& event ); + void OnEraseBackground( wxEraseEvent& event ); + void OnKillFocus( wxFocusEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __NEWBMPBTN_G__ */ + diff --git a/contrib/include/wx/fl/panedrawpl.h b/contrib/include/wx/fl/panedrawpl.h new file mode 100644 index 0000000000..4fe1adbdee --- /dev/null +++ b/contrib/include/wx/fl/panedrawpl.h @@ -0,0 +1,119 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Central header file for control-bar related classes +// +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __PANEDRAWPL_G__ +#define __PANEDRAWPL_G__ + +#ifdef __GNUG__ + #pragma interface "panedrawpl.h" +#endif + +#include "wx/fl/controlbar.h" + +/* + * Simple, but all-in-one plugin implementation. Resembles look & feel of + * to MFC control-bars. Handles painting of pane and items in it. + * Fires bar/layout customization event, when user right-clicks bar/pane. + * Hooking an instance of this and row-layouting plugins per each pane, + * would be enough for the frame layout to function properly. + * (they are plugged in autimatically by wxFrameLayout class) + */ + +class cbPaneDrawPlugin : public cbPluginBase +{ +public: + DECLARE_DYNAMIC_CLASS( cbPaneDrawPlugin ) +protected: + + // resizing bars/rows state variables + bool mResizeStarted; + bool mResizeCursorOn; + wxPoint mDragOrigin; + + cbBarInfo* mpDraggedBar; // also used when in bar-drag action + cbRowInfo* mpResizedRow; + + bool mRowHandleHitted; + bool mIsUpperHandle; + bool mBarHandleHitted; + bool mIsLeftHandle; + bool mBarContentHitted; + + // contstraints for dragging the handle + wxRect mHandleDragArea; + bool mHandleIsVertical; + int mHandleOfs; + int mDraggedDelta; + wxPoint mPrevPos; + + // used for handling, start-draw-in-area events + wxClientDC* mpClntDc; + + cbDockPane* mpPane; // is set up temorary short-cut, while handling event + +protected: + // helpers + void DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane ); + + virtual void DrawPaneShade( wxDC& dc, int alignment ); + virtual void DrawPaneShadeForRow( cbRowInfo* pRow, wxDC& dc ); + + virtual void DrawUpperRowHandle( cbRowInfo* pRow, wxDC& dc ); + virtual void DrawLowerRowHandle( cbRowInfo* pRow, wxDC& dc ); + + virtual void DrawUpperRowShades( cbRowInfo* pRow, wxDC& dc, int level ); + virtual void DrawLowerRowShades( cbRowInfo* pRow, wxDC& dc, int level ); + + virtual void DrawBarInnerShadeRect( cbBarInfo* pBar, wxDC& dc ); + + virtual void DrawShade( int level, wxRect& rect, int alignment, wxDC& dc ); + virtual void DrawShade1( int level, wxRect& rect, int alignment, wxDC& dc ); + + inline void SetLightPixel( int x, int y, wxDC& dc ); + inline void SetDarkPixel ( int x, int y, wxDC& dc ); + +public: + cbPaneDrawPlugin(void); + + cbPaneDrawPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + virtual ~cbPaneDrawPlugin(); + + virtual cbPluginBase* Clone() { return new cbPaneDrawPlugin(0,0); } + + // handlers for plugin-events + + void OnLButtonDown( cbLeftDownEvent& event ); + void OnLDblClick ( cbLeftDClickEvent& event ); + void OnLButtonUp ( cbLeftUpEvent& event ); + void OnRButtonUp ( cbRightUpEvent& event ); + void OnMouseMove ( cbMotionEvent& event ); + + void OnDrawPaneBackground ( cbDrawPaneBkGroundEvent& event ); + void OnDrawPaneDecorations( cbDrawPaneDecorEvent& event ); + + void OnDrawRowDecorations ( cbDrawRowDecorEvent& event ); + void OnDrawRowHandles ( cbDrawRowHandlesEvent& event ); + void OnDrawRowBackground ( cbDrawRowBkGroundEvent& event ); + + void OnSizeBarWindow ( cbSizeBarWndEvent& event ); + void OnDrawBarDecorations ( cbDrawBarDecorEvent& event ); + void OnDrawBarHandles ( cbDrawBarHandlesEvent& event ); + + void OnStartDrawInArea ( cbStartDrawInAreaEvent& event ); + void OnFinishDrawInArea ( cbFinishDrawInAreaEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __PANEDRAWPL_G__ */ + diff --git a/contrib/include/wx/fl/rowdragpl.h b/contrib/include/wx/fl/rowdragpl.h new file mode 100644 index 0000000000..6375d4f526 --- /dev/null +++ b/contrib/include/wx/fl/rowdragpl.h @@ -0,0 +1,164 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __ROWDRAGPL_G__ +#define __ROWDRAGPL_G__ + +#ifdef __GNUG__ + #pragma interface "rowdragpl.h" +#endif + +#include "wx/fl/controlbar.h" + +/* + * Plugin adds row-dragging fuctionality to the pane. + * Handles mouse/movement and pane-background erasing plugin-events. + * Behaviour and appearence resembles drag & drop posotioning + * of the toolbar-rows int Netscape Comunicator 4.xx. + */ + +class cbRowDragPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbRowDragPlugin ) +public: + // background colours for the highlighted/unhighlighted icons + + wxColour mHightColor; // light-blue for NC-look + wxColour mLowColor; // light-gray -/- + wxColour mTrianInnerColor; // blue -/- + wxPen mTrianInnerPen; // black -/- + +protected: + friend class cbRowDragPluginSerializer; + + // drag & drop state variables + bool mDragStarted; + bool mDecisionMode; + wxPoint mDragOrigin; + int mCurDragOfs; + bool mCaptureIsOn; + + // saved margins of the pane + int mSvTopMargin; + int mSvBottomMargin; + int mSvLeftMargin; + int mSvRightMargin; + + //on-screen drawing state variables + wxBitmap* mpPaneImage; + wxBitmap* mpRowImage; + wxBitmap* mpCombinedImage; + + wxScreenDC* mpScrDc; + wxRect mCombRect; + wxSize mRowImgDim; + int mInitialRowOfs; + + // NOTE:: if mpRowInFocus is not NULL, then mCollapsedIconInFocus is -1, + // and v.v. (two different items cannot be in focus at the same time) + + cbRowInfo* mpRowInFocus; + int mCollapsedIconInFocus; + + cbDockPane* mpPane; // is set up temorarely, while handling event + + wxList mHiddenBars; + + wxBitmap* CaptureDCArea( wxDC& dc, wxRect& area ); + + // helpers for drag&drop + + int GetHRowsCountForPane( cbDockPane* pPane ); + + void SetMouseCapture( bool captureOn ); + void PrepareForRowDrag(); + void ShowDraggedRow( int offset ); + void ShowPaneImage(); + void FinishOnScreenDraw(); + void CollapseRow( cbRowInfo* pRow ); + void ExpandRow( int collapsedIconIdx ); + void InsertDraggedRowBefore( cbRowInfo* pBeforeRow ); + bool ItemIsInFocus(); + void CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx ); + void UnhiglightItemInFocus(); + + cbRowInfo* GetFirstRow(); + + // "hard-coded metafile" for NN-look + + virtual void DrawTrianUp( wxRect& inRect, wxDC& dc ); + virtual void DrawTrianDown( wxRect& inRect, wxDC& dc ); + virtual void DrawTrianRight( wxRect& inRect, wxDC& dc ); + virtual void Draw3DPattern( wxRect& inRect, wxDC& dc ); + virtual void DrawRombShades( wxPoint& p1, wxPoint& p2, wxPoint& p3, wxPoint& p4, wxDC& dc ); + virtual void DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ); + virtual void DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ); + virtual void Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ); + virtual void DrawRectShade( wxRect& inRect, wxDC& dc, + int level, wxPen& upperPen, wxPen& lowerPen ); + + virtual void GetRowHintRect( cbRowInfo* pRow, wxRect& rect ); + virtual void GetCollapsedInconRect( int iconIdx, wxRect& rect ); + + virtual int GetCollapsedIconsPos(); + +public: + + cbRowDragPlugin(void); + + cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask = wxALL_PANES ); + virtual ~cbRowDragPlugin(); + + virtual cbPluginBase* Clone() { return new cbRowDragPlugin(NULL,0); } + + virtual void OnInitPlugin(); + + // handlers for plugin events (appearence-independent logic) + + void OnMouseMove ( cbMotionEvent& event ); + void OnLButtonDown( cbLeftDownEvent& event ); + void OnLButtonUp ( cbLeftUpEvent& event ); + void OnDrawPaneBackground( cbDrawPaneDecorEvent& event ); + + // overridables (appearence-depedent) + + virtual void DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted ); + virtual void DrawCollapsedRowsBorder( wxDC& dc ); + virtual void DrawRowsDragHintsBorder( wxDC& dc ); + virtual void DrawRowDragHint( cbRowInfo* pRow, wxDC& dc, bool isHighlighted ); + virtual void DrawEmptyRow( wxDC& dc, wxRect& rowBounds ); + + virtual int GetCollapsedRowIconHeight(); + virtual int GetRowDragHintWidth(); + + virtual void SetPaneMargins(); + + + virtual bool HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos ); + virtual bool HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos ); + + DECLARE_EVENT_TABLE() +}; + +// internal helper-class + +class cbHiddenBarInfo : public wxObject +{ + DECLARE_DYNAMIC_CLASS( cbHiddenBarInfo ) +public: + cbBarInfo* mpBar; + int mRowNo; + int mIconNo; + int mAlignment; +}; + +#endif /* __ROWDRAGPL_G__ */ + diff --git a/contrib/include/wx/fl/rowlayoutpl.h b/contrib/include/wx/fl/rowlayoutpl.h new file mode 100644 index 0000000000..f44c74a9d8 --- /dev/null +++ b/contrib/include/wx/fl/rowlayoutpl.h @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 02/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __ROWLAYOUTPL_G__ +#define __ROWLAYOUTPL_G__ + +#ifdef __GNUG__ + #pragma interface "rowlayoutpl.h" +#endif + +#include "wx/fl/controlbar.h" + +/* + * Simple implementation of plugin, which handles row-layouting + * requests sent from Frame Layout + */ + +class cbRowLayoutPlugin : public cbPluginBase +{ + DECLARE_DYNAMIC_CLASS( cbRowLayoutPlugin ) +protected: + cbDockPane* mpPane; // is set up temorarely, while handling event +protected: + + // not-fixed-bars layouting related helpers + + void FitBarsToRange( int from, int till, cbBarInfo* pTheBar, cbRowInfo* pRow ); + void RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow ); + void MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve ); + int GetRowFreeSpace( cbRowInfo* pRow ); + + void RecalcLengthRatios( cbRowInfo* pRow ); + void ApplyLengthRatios( cbRowInfo* pRow ); + void ExpandNotFixedBars( cbRowInfo* pRow ); + void AdjustLengthOfInserted( cbRowInfo* pRow, cbBarInfo* pTheBar ); + + void DetectBarHandles( cbRowInfo* pRow ); + void CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo ); + + + // row-layouting helpers (simulate "bar-friction") + + int CalcRowHeight( cbRowInfo& row ); + void LayoutItemsVertically( cbRowInfo& row ); + + void StickRightSideBars( cbBarInfo* pToBar ); + + void SlideLeftSideBars ( cbBarInfo* pTheBar ); + void SlideRightSideBars( cbBarInfo* pTheBar ); + + void ShiftLeftTrashold ( cbBarInfo* pTheBar, cbRowInfo& row ); + void ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row ); + + void InsertBefore( cbBarInfo* pBeforeBar, + cbBarInfo* pTheBar, + cbRowInfo& row + ); + + void DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row ); + +public: + + cbRowLayoutPlugin(void); + + cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask = wxALL_PANES ); + + // event handlers + + void OnResizeRow ( cbResizeRowEvent& event ); + void OnInsertBar ( cbInsertBarEvent& event ); + void OnRemoveBar ( cbRemoveBarEvent& event ); + void OnLayoutRow ( cbLayoutRowEvent& event ); + void OnLayoutRows( cbLayoutRowsEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __ROWLAYOUTPL_G__ */ + diff --git a/contrib/include/wx/fl/toolwnd.h b/contrib/include/wx/fl/toolwnd.h new file mode 100644 index 0000000000..8f7fd5cf18 --- /dev/null +++ b/contrib/include/wx/fl/toolwnd.h @@ -0,0 +1,216 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __TOOLWND_G__ +#define __TOOLWND_G__ + +#ifdef __GNUG__ + #pragma interface "toolwnd.h" +#endif + +#include "wx/frame.h" +#include "wx/dynarray.h" + +// fixed settings + +#define BTN_BOX_HEIGHT 12 +#define BTN_BOX_WIDTH 12 +#define BTN_X_WIEGHT 2 + +class cbMiniButton; + +typedef cbMiniButton* cbMinitButtonPtrT; + +WX_DEFINE_ARRAY( cbMinitButtonPtrT, cbMiniButtonArrayT ); + +class wxToolWindow : public wxFrame +{ + DECLARE_DYNAMIC_CLASS( wxToolWindow ) + +public: /** protected really, accessed only by serializers **/ + + cbMiniButtonArrayT mButtons; + wxWindow* mpClientWnd; + + wxFont mTitleFont; + + int mTitleHeight; + int mClntHorizGap; + int mClntVertGap; + int mWndVertGap; + int mWndHorizGap; + int mButtonGap; + int mInTitleMargin; + int mHintBorder; + + bool mResizeStarted; + bool mRealTimeUpdatesOn; + + int mMTolerance; + + int mCursorType; + bool mMouseCaptured; + + // drag&drop state variables + + wxPoint mDragOrigin; + wxRect mInitialRect; + wxRect mPrevHintRect; + wxScreenDC* mpScrDc; + +protected: + void GetScrWindowRect( wxRect& r ); + void GetScrMousePos ( wxMouseEvent& event, wxPoint& pos ); + void SetHintCursor ( int type ); + + void CalcResizedRect( wxRect& rect, wxPoint& delta, const wxSize& minDim ); + void AdjustRectPos( const wxRect& original, const wxSize& newDim, wxRect& newRect ); + wxSize GetMinimalWndDim(); + + void DrawHintRect( const wxRect& r ); + + int HitTestWindow( wxMouseEvent& event ); + + void LayoutMiniButtons(); + +public: + + wxToolWindow(); + ~wxToolWindow(); + + void SetClient( wxWindow* pWnd ); + wxWindow* GetClient(); + + void SetTitleFont( wxFont& font ); + + // buttons are added in right-to-left order + void AddMiniButton( cbMiniButton* pBtn ); + + void OnPaint( wxPaintEvent& event ); + + void OnMotion( wxMouseEvent& event ); + void OnLeftDown( wxMouseEvent& event ); + void OnLeftUp( wxMouseEvent& event ); + void OnSize( wxSizeEvent& event ); + + void OnEraseBackground( wxEraseEvent& event ); + + // overridables: + + virtual wxSize GetPreferredSize( const wxSize& given ); + virtual void OnMiniButtonClicked( int btnIdx ) {} + virtual bool HandleTitleClick( wxMouseEvent& event ) { return FALSE; } + + DECLARE_EVENT_TABLE() +}; + +// FIXME:: the code below should be moved to a separate file + +#include "wx/fl/controlbar.h" + +class cbMiniButton : public wxObject +{ +public: + wxPoint mPos; + wxSize mDim; + bool mVisible; + bool mEnabled; + + wxFrameLayout* mpLayout; + cbDockPane* mpPane; + cbPluginBase* mpPlugin; + + wxWindow* mpWnd; + + bool mWasClicked; + bool mDragStarted; + + bool mPressed; +public: + cbMiniButton(); + + void SetPos( const wxPoint& pos ); + bool HitTest( const wxPoint& pos ); + + void OnLeftDown( const wxPoint& pos ); + void OnLeftUp( const wxPoint& pos ); + void OnMotion( const wxPoint& pos ); + + void Refresh(); + virtual void Draw( wxDC& dc ); + + bool WasClicked(); + void Reset(); + + void Enable( bool enable ) { mEnabled = enable; } + + bool IsPressed() { return mPressed; } +}; + +// classes specific to wxFrameLayout engine (FOR NOW in here...) + +class cbCloseBox : public cbMiniButton +{ +public: + virtual void Draw( wxDC& dc ); +}; + +class cbCollapseBox : public cbMiniButton +{ +public: + bool mIsAtLeft; + + virtual void Draw( wxDC& dc ); +}; + +class cbDockBox : public cbMiniButton +{ +public: + virtual void Draw( wxDC& dc ); +}; + +class cbFloatedBarWindow : public wxToolWindow +{ + DECLARE_DYNAMIC_CLASS( cbFloatedBarWindow ) +protected: + cbBarInfo* mpBar; + wxFrameLayout* mpLayout; + + friend class cbFloatedBarWindowSerializer; + +public: + cbFloatedBarWindow(); + + void SetBar( cbBarInfo* pBar ); + void SetLayout( wxFrameLayout* pLayout ); + cbBarInfo* GetBar(); + + // given coordinates are those of the bar itself + // floated container window's position and size + // are ajusted accordingly + + void PositionFloatedWnd( int scrX, int scrY, + int width, int height ); + + // overriden methods of wxToolWindow + + virtual wxSize GetPreferredSize( const wxSize& given ); + virtual void OnMiniButtonClicked( int btnIdx ); + virtual bool HandleTitleClick( wxMouseEvent& event ); + + void OnDblClick( wxMouseEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif /* __TOOLWND_G__ */ + + diff --git a/contrib/include/wx/fl/updatesmgr.h b/contrib/include/wx/fl/updatesmgr.h new file mode 100644 index 0000000000..e0e21c500b --- /dev/null +++ b/contrib/include/wx/fl/updatesmgr.h @@ -0,0 +1,56 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas (@Lithuania) +// Modified by: +// Created: 19/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __UPDATESMGR_G__ +#define __UPDATESMGR_G__ + +#ifdef __GNUG__ + #pragma interface "updatesmgr.h" +#endif + +#include "wx/fl/controlbar.h" + +/* + * class implements slightly optimized logic for refreshing + * areas of frame layout - which actually need to be updated. + */ + +class cbSimpleUpdatesMgr : public cbUpdatesManagerBase +{ + DECLARE_DYNAMIC_CLASS( cbSimpleUpdatesMgr ) +protected: + + bool WasChanged( cbUpdateMgrData& data, wxRect& currentBounds ); + +public: + + cbSimpleUpdatesMgr(void) {} + + cbSimpleUpdatesMgr( wxFrameLayout* pPanel ); + + // notificiactions received from Frame Layout (in the order, in which + // they usually would be invoked) + + virtual void OnStartChanges(); + + virtual void OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane ); + virtual void OnBarWillChange( cbBarInfo* pBar, cbRowInfo* pInRow, cbDockPane* pInPane ); + virtual void OnPaneMarginsWillChange( cbDockPane* pPane ); + virtual void OnPaneWillChange( cbDockPane* pPane ); + + virtual void OnFinishChanges(); + + // refreshes parts of the frame layout, which need an update + virtual void UpdateNow(); +}; + +#endif /* __UPDATESMGR_G__ */ + diff --git a/contrib/samples/Makefile.in b/contrib/samples/Makefile.in index 1133423958..2d1cd3a037 100644 --- a/contrib/samples/Makefile.in +++ b/contrib/samples/Makefile.in @@ -1,6 +1,6 @@ # $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 diff --git a/contrib/samples/fl/Makefile.in b/contrib/samples/fl/Makefile.in new file mode 100644 index 0000000000..7d62d89b7f --- /dev/null +++ b/contrib/samples/fl/Makefile.in @@ -0,0 +1,10 @@ +# $Id$ + +CONTRIB_SAMPLES=fl_demo1 fl_demo2 fl_sample1 fl_sample2 fl_sample3 + +all: + @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE)); done + +clean: + @for d in $(CONTRIB_SAMPLES); do (cd $$d && $(MAKE) clean); done + diff --git a/contrib/samples/fl/bitmaps/bookmarks.bmp b/contrib/samples/fl/bitmaps/bookmarks.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d6a3a7977c3e617d4a9935ccea2db82b0204ce5f GIT binary patch literal 1650 zcmd6lF%H5o3`Nbt$c6+r-~>!e>|BN;pxzABYlYvq`gWZVh{RCKNuBTH)lPf8-M5nM zjQNCd#MonOEab4i zWGN+yz+nNwWhH^#zQ<{qU0DrWg%#=|3&b|Ak40RyQ)3}bV`)(Iytav1jd$b&V?iZC z?@PZXYf+Ft9Aab5Z_Iy#XF+dY6N$!BiKY2pj5q{5Sq7Gy>v9jjTV=15v9ZcrP})Ud gv$0%3CU)UI9t)ITmd5gReQl?THdZy=C9anB2DAwZasU7T literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/class_icon.bmp b/contrib/samples/fl/bitmaps/class_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..fe1a0c9d875f0738f4092ffb3ba246d7e30edda0 GIT binary patch literal 214 zcmX|*F%p0v3c7N}fewNnvH}Pw;XuhTLt)QLt{0v^szV@?C?B z40iYxnz;B)MbM(!0LKWaz z$WRY58Vqon{{KJRd^9yMttd254IcGCuOK6!PD<1xTMRS@WEv_0ia2V|%RYJmWtAuuKi4L2N<0RSD{B6I)% literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/copy.bmp b/contrib/samples/fl/bitmaps/copy.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5e66fc8dfee60523cd6463a3082ea45718f8ba61 GIT binary patch literal 1566 zcmd^6K@P$&3=0Q#p_ zAvef1a$#Gb*=1=qteB+$7|-M9>koBKX00`yXEGm%Tx)^)44ubcy?-H`>x6zB=lKCK zJc2qw{}n&z@vLw7p$#Z=C3EJx5>dytaAe&vE7vb literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/cut.bmp b/contrib/samples/fl/bitmaps/cut.bmp new file mode 100644 index 0000000000000000000000000000000000000000..cf9247f2ea214b307cc1357171e62ac93a47405c GIT binary patch literal 1566 zcmdUqK?=h#3pO16$ERRBS_)M}2bwwpF_yEP5y+O1t7i)9{>OV literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/file_icon.bmp b/contrib/samples/fl/bitmaps/file_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..941b5ccabf832c16f8ae8bd5fd57b0826860868f GIT binary patch literal 214 zcmZ?ry~Y3mWk5;;hg8*4+8O GymtfV4>MN) literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/new.bmp b/contrib/samples/fl/bitmaps/new.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1785f051bbbf21dc29ca1c483608ea13605f4ade GIT binary patch literal 1398 zcmds#!41P83`OaoBSgvwouKC`_pFlvs%%y%Yb8H?V=U?rRkW8zfE?pze*?ofT|@lt zSZ|n}%uDE_{~`PFN0#Naw2aUKgZ(ydTRXC?XVD0=+ne}N<1&>`bTIae=}{KNktjb#!gjTqnZ;J7 oEj%%}SdfNxLH+MAJi;TC+nPvHq}E+H^GDmK{@nj*s2kACZ;(-pJOBUy literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/nextmark.bmp b/contrib/samples/fl/bitmaps/nextmark.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ce916ee63d8457dd3f38949996a5084594337dfa GIT binary patch literal 1734 zcmdUt!41MN3`Na_BR3?(1WdpH+*t~B0CuA4TIDBS`k2J7D#QUICvu$l)!*smI&H0v zGu9L45p$2Zu>)4KJI==)XANMP9@7`?A9-xTa2sr%VZIwBSceaKKhcYvo=4Jb2E*_e z`AHb($N&wh&lM-X&apsnNb``S=(}657Qg)BMZgV4+>2utV~GWSwMEW m*6^AV{I=)4H_yutKjmTYJ04h(=5j zhfg7ffGoh&0uupBqS=MaMX?uT5IR6sjLC+p#*~7H5LAFmBeHhYggXHLKY*tt}dn}K>3ZV_JN{J62(AXP{ZHBREjpP${{?tMpL zTwyPmC(I+}j?S<|uRYQ8z%w{t#>cq*`8$pyT6$zRbX}=!aRtO%1O64x6g)ULxMBmR zk_2#*GlPKn9X+gs<*nD%)WZs!b(PL=msDL^41}Stl{~G71EsB^Oirywe!IM%XE!;l zXZiuGk>AQHOit9JGVEFWZ}|HYS2184KEsal?|JNK_v&mMF@0+%V;SBUbgh55lX)bKW|$ZO zqvL`HH-N-s;B+jLyasZC7xEJi)HZTEPsnQ3iKjA^BJMFKmW-W4J@cZ*Oyc literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/res_icon.bmp b/contrib/samples/fl/bitmaps/res_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..770cc355472d0e985b113dc2632587ad215da096 GIT binary patch literal 214 zcmX|(%MAiC3`7Tn6b@+9LXI4_2JZAg2}mo!HKnYmfD&?`2HHp}AUrz=$1~5L$fxsL zBW~b`4nJ+Q^Th>!O+!BTTb4-WJb+W8tWpY#?y26bLOdH`e3SMhO>a`ThB+ALv@Av? c$=Fh@#_ePJIM*0`zP6{a#_Ii@;3(;LzZ$SL1^@s6 literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/save.bmp b/contrib/samples/fl/bitmaps/save.bmp new file mode 100644 index 0000000000000000000000000000000000000000..02f8c7d5cbf1ad9e921f35c3afbe77d9db6f2f88 GIT binary patch literal 1482 zcmZ?rJ;llZ24+A~1Bk_dSQLmE86JEshM3{l01nzR; t<7MQS0S;Yw2;qubyx{@V1T+P|8PG^1K;bq6O@??bhQo;03Rg)TGXRV%60HCL literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/saveall.bmp b/contrib/samples/fl/bitmaps/saveall.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd04e1c10fb9bce710c20e08f075f2fa26a1c788 GIT binary patch literal 1566 zcmd^+F%H5o3`NaAM>YggXHLKY*trzqW<@;RM517j<{9 literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/search.bmp b/contrib/samples/fl/bitmaps/search.bmp new file mode 100644 index 0000000000000000000000000000000000000000..dee760613260859f911adb8cea00b9585afa90f9 GIT binary patch literal 1482 zcmd5(!4bkR3=0pw{NNaY2^fGsOK}~6jp+5kQbCT+s%esb;L%>=Q*24GliU5hPvyHJ zUa(GBN32~sBc}93eLQfL1j6*1e*CxW;ZrWh?C0yt;3d^p)z3FQc;xUHR0U?T(g zxIG{yLF-+3QZxW}v5hu=^N6#?^LjWoQCei57IQWcW02P;bUb80GaAcM+l89jav$It zD`!S~MDNBj&LN;KM%BL!D20e-+D56cdl)Ncc0fGG!jYl|?x8_usdv^JL1ykjY5fE+ ZKvMK3@IGzy@-@c}6#D^LIc literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/start95_dp.bmp b/contrib/samples/fl/bitmaps/start95_dp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d18943575de6a4716ef5e8b43e32fc0b89b2e03d GIT binary patch literal 3918 zcmeH~QBK1!5JbZX_-v2B3E-c9I27v5ka{gM_1MG2&bn&lN)aMTwzHe@?yDO`>ifs% z^OBEO#1~v|xDL3UmLuY_9LxQjlyLq&@Beh*-D+$j*iuTTuhVW%5Q=lRzdLsC4{$aQ zYP8$@rqSIg^=Ln}$(S;r)vYNogC=86Unrza;m$|sh?BDtUIO(b9@5p3O2OIO(AQaU z4>XFb$ls(9C&pumqVOQ3@glpN`Pl65x322Qz|Lb%O^0BgtDOB3Rw4}5B{a)hMVz%c zxz=>-h*&oh(tAn|MyrQB5?Jn<-6BpvWPgeNYd0hMo^IG=Rxyvb*j+T5<}oKdjCFc> zAWK>^IayaKQJ0sUR|>K2|I4gfFhrcqT5D_1fXRkOsRTPH9gE%^aq_z;a$$}JXHs+N zWEyFiBjF3_8FP9cuFVmAt4}0>b5(cGtvce|>{IZ%k4^L3;!T_!?U-|62Ho!99CUl! Ut$)tBd)w?M{vz%6;9CXp2kE1mr2qf` literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/start95_pr.bmp b/contrib/samples/fl/bitmaps/start95_pr.bmp new file mode 100644 index 0000000000000000000000000000000000000000..002c41da140fc135f57edc80337b853270a69056 GIT binary patch literal 4086 zcmdT`K~4iP5DPEh$`g12;>?{-p*{==sZZj%xbeny*9{BRvI^1e)NwpB?gUl5ynf!7 zx}Fdp@jl~yzx5Kbj(9&}oOP?CAcdSO{K!Idro!k)fE2Cig5ZmR^w1%;7i*dc&vHTX zWLyIbl8p2ckV&7+LVE}lWe-5Oz-0LJcE7?sanI+>$Ile&tomd+W3Tm9zDM?aLa$zS z?KVYLL~O(K6y*X?NXD^_NHX08j+vhK-pZbSS7C+GZ(GG3FstRBPsC?y7X!OM7=W_$ z$s;;c7u8uBZex~GEyNIzS6^+Dv0mq!O`l%ht2JzYp$3&jnYIEwUIGUa1CURjJX%C1 z)@bGostc9e_OQe~;EB|vPqkPSVQ!7^ckzjhi|5n&;rtC)mD8t=vaB0$oXX9a^tsw% xPlp;>`qa^?;XMWE6WwWboCr%-eeOA^ANE@K#J}_dK8tzcqK92R&tXl<*cXO}TAKg> literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/bitmaps/tile.bmp b/contrib/samples/fl/bitmaps/tile.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2269ce2f5feb7c86278efdc3e61a1ad92a118dc6 GIT binary patch literal 1894 zcmds%Q3}E^42I*AM^HS0k3M+--@S$hk=;z#wdzm*5keP2>WYG;4QaA{`;(U4?vK6H zafLl&ov;pAJ2}FNT$X&@EM|Vq1E(dA@k=SwbJ{YYLm}1OQZIy%N61%s_;N5Qs7D`Q zXpB3M`Ws%*Gn-1+t8JrW8P@-ZX911h&s(1?ki@7B?@Ob=-6|=e4*+OVJC5g)80^=# pZW~26q+GpuWjP+DxYXb4a}~tF@czZGx>=9s9%w$u|2>}_{pS5E){ literal 0 HcmV?d00001 diff --git a/contrib/samples/fl/fl_demo1/Makefile.in b/contrib/samples/fl/fl_demo1/Makefile.in new file mode 100644 index 0000000000..88f55027f9 --- /dev/null +++ b/contrib/samples/fl/fl_demo1/Makefile.in @@ -0,0 +1,25 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# "%W% %G%" +# +# Makefile : Builds sample on UNIX/Linux. + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. + +TARGET = fl_demo1 + +program_dir = contrib/samples/fl/$(TARGET) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\" +APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@ + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).o + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/fl/fl_demo1/fl_demo.dsp b/contrib/samples/fl/fl_demo1/fl_demo.dsp new file mode 100644 index 0000000000..c4695b4cd3 --- /dev/null +++ b/contrib/samples/fl/fl_demo1/fl_demo.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fl_demo1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=fl_demo1 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_demo1 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fl_demo1 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "fl_demo1 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fl_demo1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ELSEIF "$(CFG)" == "fl_demo1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ENDIF + +# Begin Target + +# Name "fl_demo1 - Win32 Release" +# Name "fl_demo1 - Win32 Debug" +# Begin Source File + +SOURCE=.\fl_demo1.cpp + +!IF "$(CFG)" == "fl_demo1 - Win32 Release" + +!ELSEIF "$(CFG)" == "fl_demo1 - Win32 Debug" + +# ADD CPP /Yc"wx/wxprec.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\fl_demo1.rc +# End Source File +# End Target +# End Project diff --git a/contrib/samples/fl/fl_demo1/fl_demo.dsw b/contrib/samples/fl/fl_demo1/fl_demo.dsw new file mode 100644 index 0000000000..f75328ad21 --- /dev/null +++ b/contrib/samples/fl/fl_demo1/fl_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fl_demo1"=.\fl_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.cpp b/contrib/samples/fl/fl_demo1/fl_demo1.cpp new file mode 100644 index 0000000000..86641ceab3 --- /dev/null +++ b/contrib/samples/fl/fl_demo1/fl_demo1.cpp @@ -0,0 +1,241 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 04/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + + +#ifdef __GNUG__ +#pragma implementation "fl_demo1.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/textctrl.h" + +// fl headers +#include "wx/fl/controlbar.h" // core API + +// extra plugins +#include "wx/fl/barhintspl.h" // beveal for bars with "X"s and grooves +#include "wx/fl/rowdragpl.h" // NC-look with dragable rows +#include "wx/fl/cbcustom.h" // customization plugin +#include "wx/fl/hintanimpl.h" + +// beuty-care +#include "wx/fl/gcupdatesmgr.h" // smooth d&d +#include "wx/fl/antiflickpl.h" // double-buffered repaint of decorations +#include "wx/fl/dyntbar.h" // auto-layouting toolbar +#include "wx/fl/dyntbarhnd.h" // control-bar dimension handler for it + +#include "fl_demo1.h" + +// comment it out if it breaks, (this is my workaround for MSDev 4.0 linker) + +char wxDummyChar; + + +IMPLEMENT_APP (MyApp) + +bool MyApp::OnInit(void) +{ + MyFrame *frame = new MyFrame(NULL); + + frame->SetBackgroundColour( wxColour(192,192,192) ); + + wxMenu *file_menu = new wxMenu; + + file_menu->Append( NEW_TEST_LOAD, "&Load layouts" ); + file_menu->Append( NEW_TEST_SAVE, "&Store layouts" ); + file_menu->Append( NEW_TEST_EXIT, "E&xit" ); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + + frame->SetMenuBar(menu_bar); + + frame->CreateStatusBar(3); + + frame->Show(TRUE); + + frame->mpClientWnd->Refresh(); + + SetTopWindow(frame); + + + wxMessageBox("Hello, this demo has a bunch of yet-not-fixed-bugs and misssing functionality\n" \ + "The ONLY purpose is to demostrate self-layouting toolbars,\nflat-bitmapped-buttons and 2-new FL-plugins" \ + "(cbRowDragPlugin & cbBarHintsPlugin)\n\n" \ + "BTW, disabled images and label-text are rendered at run-time" ); + + return TRUE; +} + +/***** Implementation for class MyFrame *****/ + +BEGIN_EVENT_TABLE( MyFrame, wxFrame ) + // EVT_CHAR_HOOK(MyFrame::OnKeyDown) + // EVT_PAINT( MyFrame::OnPaint ) + EVT_MENU( NEW_TEST_SAVE, MyFrame::OnSave ) + EVT_MENU( NEW_TEST_LOAD, MyFrame::OnLoad ) + EVT_MENU( NEW_TEST_EXIT, MyFrame::OnExit ) +END_EVENT_TABLE() + +void MyFrame::OnLoad( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found a BIG question-mark !!"); +} + +void MyFrame::OnSave( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found another BIG question-mark !!"); +} + +void MyFrame::OnExit( wxCommandEvent& event ) +{ + Destroy(); +} + +wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value ) +{ + wxTextCtrl* pCtrl = + + new wxTextCtrl( this, -1, value, + wxDefaultPosition, wxSize(0,0), wxTE_MULTILINE ); + + pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) ); + + return pCtrl; +} + +MyFrame::MyFrame(wxFrame *frame) + : wxFrame( frame, -1, "wxWindows 2.0 wxFrameLayout Test Application", wxDefaultPosition, + wxSize( 700, 500 ), + wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION, + "freimas" ) +{ + mpClientWnd = CreateTextCtrl( "Client window" ); + + mpLayout = new wxFrameLayout( this, mpClientWnd ); + +#ifdef __WXGTK__ + cbCommonPaneProperties props; + mpLayout->GetPaneProperties( props ); + + props.mRealTimeUpdatesOn = FALSE; // real-time OFF!!! + + mpLayout->SetPaneProperties( props, wxALL_PANES ); +#endif + + mpLayout->SetUpdatesManager( new cbGCUpdatesMgr() ); + + // this is now default... + //mpLayout->SetMargins( 1,1,1,1 ); // gaps for vertical/horizontal/right/left panes + + // setup plugins for testing + mpLayout->PushDefaultPlugins(); + + mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for bars + mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) ); + mpLayout->AddPlugin( CLASSINFO( cbRowDragPlugin ) ); + mpLayout->AddPlugin( CLASSINFO( cbAntiflickerPlugin ) ); + mpLayout->AddPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) ); + + // drop in some bars + cbDimInfo sizes0( 200,45, // when docked horizontally + 200,85, // when docked vertically + 175,35, // when floated + FALSE, // the bar is not fixed-size + 4, // vertical gap (bar border) + 4 // horizontal gap (bar border) + ); + + cbDimInfo sizes1( 150,35, // when docked horizontally + 150,85, // when docked vertically + 175,35, // when floated + TRUE, // the bar is not fixed-size + 4, // vertical gap (bar border) + 4 // horizontal gap (bar border) + ); + + cbDimInfo sizes2( 175,45, // when docked horizontally + 175,37, // when docked vertically + 170,35, // when floated + TRUE, // the bar is not fixed-size + 4, // vertical gap (bar border) + 4, // horizontal gap (bar border) + new cbDynToolBarDimHandler() + ); + + mpLayout->AddBar( CreateTextCtrl("Hello"), // bar window + sizes0, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + "InfoViewer1", // name to refere in customization pop-ups + TRUE + ); + + mpLayout->AddBar( CreateTextCtrl("Bye"), // bar window + sizes0, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc) + 1, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + "InfoViewer2", // name to refere in customization pop-ups + TRUE + ); + + mpLayout->AddBar( CreateTextCtrl("Fixed0"), // bar window + sizes1, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + "ToolBar1", // name to refere in customization pop-ups + TRUE + ); + + wxDynamicToolBar* pToolBar = new wxDynamicToolBar(); + + pToolBar->Create( this, -1 ); + + // 1001-1006 ids of command events fired by added tool-buttons + + pToolBar->AddTool( 1001, BMP_DIR "new.bmp" ); + pToolBar->AddTool( 1002, BMP_DIR "open.bmp" ); + pToolBar->AddTool( 1003, BMP_DIR "save.bmp" ); + + pToolBar->AddTool( 1004, BMP_DIR "cut.bmp" ); + pToolBar->AddTool( 1005, BMP_DIR "copy.bmp" ); + pToolBar->AddTool( 1006, BMP_DIR "paste.bmp" ); + + + mpLayout->AddBar( pToolBar, // bar window (can be NULL) + sizes2, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + "ToolBar2", // name to refere in customization pop-ups + FALSE + ); + + mpLayout->EnableFloating( TRUE ); // off, thinking bout wxGtk... +} + +MyFrame::~MyFrame() +{ + if ( mpLayout) + delete mpLayout; // should be destroyed manually +} + diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.h b/contrib/samples/fl/fl_demo1/fl_demo1.h new file mode 100644 index 0000000000..8b0d02ffab --- /dev/null +++ b/contrib/samples/fl/fl_demo1/fl_demo1.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 04/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __NEW_TEST_G__ +#define __NEW_TEST_G__ + +#ifdef __GNUG__ +#pragma interface "fl_demo1.h" +#endif + +#define NEW_TEST_SAVE 1101 +#define NEW_TEST_LOAD 1102 +#define NEW_TEST_EXIT 1103 + +#include "wx/panel.h" + +// Define a new application type +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +// Define a new frame type +class MyFrame: public wxFrame +{ +public: + wxFrameLayout* mpLayout; + wxTextCtrl* mpClientWnd; + + wxTextCtrl* CreateTextCtrl( const wxString& value ); + +public: + MyFrame(wxFrame *frame); + virtual ~MyFrame(); + + bool OnClose(void) { Show(FALSE); return TRUE; } + + void OnLoad( wxCommandEvent& event ); + void OnSave( wxCommandEvent& event ); + void OnExit( wxCommandEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/contrib/samples/fl/fl_demo1/fl_demo1.rc b/contrib/samples/fl/fl_demo1/fl_demo1.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/contrib/samples/fl/fl_demo1/fl_demo1.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/contrib/samples/fl/fl_demo1/makefile.b32 b/contrib/samples/fl/fl_demo1/makefile.b32 new file mode 100644 index 0000000000..710bb8d2b6 --- /dev/null +++ b/contrib/samples/fl/fl_demo1/makefile.b32 @@ -0,0 +1,23 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = ..\..\..\.. +TARGET = fl_demo1 + +EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WSLIBDIR)\fl.lib +!else +EXTRALIBS = $(WSLIBDIR)\fld.lib +!endif + +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/contrib/samples/fl/fl_demo1/makefile.g95 b/contrib/samples/fl/fl_demo1/makefile.g95 new file mode 100644 index 0000000000..27c8f178bc --- /dev/null +++ b/contrib/samples/fl/fl_demo1/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWorkshop for mingw & cygwin. + +WXDIR = ../../../.. +TARGET = fl_demo1 + +EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\" +EXTRALIBS = $(WXDIR)/lib/libfl.a + +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 diff --git a/contrib/samples/fl/fl_demo1/makefile.vc b/contrib/samples/fl/fl_demo1/makefile.vc new file mode 100644 index 0000000000..51eaae55ca --- /dev/null +++ b/contrib/samples/fl/fl_demo1/makefile.vc @@ -0,0 +1,24 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds fl sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\..\.. +TARGET = fl_demo1 + +EXTRAINC = -DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WXDIR)\lib\fl.lib +!else +EXTRALIBS = $(WXDIR)\lib\fld.lib +!endif + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.vc diff --git a/contrib/samples/fl/fl_demo2/Makefile.in b/contrib/samples/fl/fl_demo2/Makefile.in new file mode 100644 index 0000000000..911f9b5b42 --- /dev/null +++ b/contrib/samples/fl/fl_demo2/Makefile.in @@ -0,0 +1,25 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# "%W% %G%" +# +# Makefile : Builds sample on UNIX/Linux. + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. + +TARGET = fl_demo2 + +program_dir = contrib/samples/fl/$(TARGET) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\" +APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@ + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).o + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/fl/fl_demo2/fl_demo.dsp b/contrib/samples/fl/fl_demo2/fl_demo.dsp new file mode 100644 index 0000000000..a449ab04b2 --- /dev/null +++ b/contrib/samples/fl/fl_demo2/fl_demo.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fl_demo2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=fl_demo2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_demo2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fl_demo2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "fl_demo2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fl_demo2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ELSEIF "$(CFG)" == "fl_demo2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ENDIF + +# Begin Target + +# Name "fl_demo2 - Win32 Release" +# Name "fl_demo2 - Win32 Debug" +# Begin Source File + +SOURCE=.\fl_demo2.cpp + +!IF "$(CFG)" == "fl_demo2 - Win32 Release" + +!ELSEIF "$(CFG)" == "fl_demo2 - Win32 Debug" + +# ADD CPP /Yc"wx/wxprec.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\fl_demo2.rc +# End Source File +# End Target +# End Project diff --git a/contrib/samples/fl/fl_demo2/fl_demo.dsw b/contrib/samples/fl/fl_demo2/fl_demo.dsw new file mode 100644 index 0000000000..aadb7e2ca2 --- /dev/null +++ b/contrib/samples/fl/fl_demo2/fl_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fl_demo2"=.\fl_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.cpp b/contrib/samples/fl/fl_demo2/fl_demo2.cpp new file mode 100644 index 0000000000..d209ce6e3d --- /dev/null +++ b/contrib/samples/fl/fl_demo2/fl_demo2.cpp @@ -0,0 +1,986 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 04/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "fl_demo2.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +// wxWindows headers. +#include "wx/treectrl.h" +#include "wx/imaglist.h" +#include "wx/notebook.h" + +// fl headers. +#include "wx/fl/controlbar.h" +#include "wx/fl/rowlayoutpl.h" +#include "wx/fl/antiflickpl.h" +#include "wx/fl/bardragpl.h" +#include "wx/fl/cbcustom.h" +#include "wx/fl/rowdragpl.h" + +// some extra fl plugins. +#include "wx/fl/barhintspl.h" +#include "wx/fl/hintanimpl.h" + +#include "wx/fl/dyntbar.h" +#include "wx/fl/dyntbarhnd.h" // fl-dimension-handler for dynamic toolbar + +#include "fl_demo2.h" + +/***** Implementation for class MyApp *****/ + +// Create a new application object +IMPLEMENT_APP (MyApp) + +// `Main program' equivalent, creating windows and returning main app frame +bool MyApp::OnInit(void) +{ + // Create the main frame window + MyFrame *frame = new MyFrame(NULL, "wxWindows 2.0 wxFrameLayout demo", 50, 50, 650, 540); + + // Give it an icon +#ifdef __WINDOWS__ + frame->SetIcon(wxIcon("mondrian")); +#endif +#ifdef __X__ + frame->SetIcon(wxIcon("aiai.xbm")); +#endif + + // Make a menubar + wxMenu *file_menu = new wxMenu; + wxMenu *active_menu = new wxMenu; + + file_menu->Append( ID_LOAD, "&Load layouts" ); + file_menu->Append( ID_STORE, "&Store layouts" ); + file_menu->AppendSeparator(); + + file_menu->Append( ID_AUTOSAVE, "&Auto Save Layouts", "save layouts on exit", TRUE ); + file_menu->AppendSeparator(); + + file_menu->Append(MINIMAL_ABOUT, "A&bout !"); + file_menu->Append(MINIMAL_QUIT, "E&xit\tTab"); + + //active_menu->Append( ID_SETTINGS, "&Settings...\tCtrl" ); + //active_menu->AppendSeparator(); + + active_menu->Append( ID_REMOVE, "&Remove Active" ); + active_menu->Append( ID_REMOVEALL, "Remove &All" ); + active_menu->Append( ID_RECREATE, "Re&create" ); + active_menu->AppendSeparator(); + + active_menu->Append( ID_FIRST, "Activate f&irst layout \tF1", "activate it", TRUE ); + active_menu->Append( ID_SECOND, "Activate &second layout\tF2","activate it", TRUE ); + active_menu->Append( ID_THIRD, "Activate &third layout\tF3","activate it", TRUE ); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + menu_bar->Append(active_menu, "Active &Layout"); + + frame->CreateStatusBar(3); + + frame->SetMenuBar(menu_bar); + + frame->SyncMenuBarItems(); + + // Show the frame + frame->Show(TRUE); + + SetTopWindow(frame); + + return TRUE; +} + +MyFrame::~MyFrame() +{ + // frame-layouts is not a windows (objects), thus should + // be cleaned up manually + + for( int i = 0; i != MAX_LAYOUTS; ++i ) + { + if ( mLayouts[i] ) + delete mLayouts[i]; + } + + if ( mpNestedLayout ) + delete mpNestedLayout; + if ( mpAboutBoxLayout ) + delete mpAboutBoxLayout; +} + +/***** Implementation for class MyFrame *****/ + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU( MINIMAL_QUIT, MyFrame::OnQuit ) + EVT_MENU( MINIMAL_ABOUT, MyFrame::OnAbout ) + + EVT_MENU( ID_LOAD, MyFrame::OnLoad ) + EVT_MENU( ID_STORE, MyFrame::OnStore ) + EVT_MENU( ID_AUTOSAVE, MyFrame::OnAutoSave ) + //EVT_MENU( ID_SETTINGS, MyFrame::OnSettings ) + EVT_MENU( ID_REMOVE, MyFrame::OnRemove ) + EVT_MENU( ID_REMOVEALL, MyFrame::OnRemoveAll ) + EVT_MENU( ID_RECREATE, MyFrame::OnRecreate ) + EVT_MENU( ID_FIRST, MyFrame::OnFirst ) + EVT_MENU( ID_SECOND, MyFrame::OnSecond ) + EVT_MENU( ID_THIRD, MyFrame::OnThird ) + + EVT_BUTTON( ID_SAY_ITSOK, MyFrame::OnSayItsOk ) + EVT_BUTTON( ID_BTN_YES, MyFrame::OnBtnYes ) + EVT_BUTTON( ID_BTN_NO, MyFrame::OnBtnNo ) + EVT_BUTTON( ID_BTN_ESC, MyFrame::OnBtnEsc ) + + EVT_CHAR_HOOK( MyFrame::OnChar ) +END_EVENT_TABLE() + +// My frame constructor + +MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h) + : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h)), + mpNestedLayout( NULL ), + mpAboutBoxLayout( NULL ), + + mActiveLayoutNo( FIRST_LAYOUT ), + mAutoSave( TRUE ), + mSavedAlready( FALSE ), + mpClntWindow( NULL ), + + mImageList( 16,16, FALSE, 2 ) +{ + mpInternalFrm = (wxPanel*)this; + + mAboutBox.Create( this, -1, "About box in wxWindows style...", + wxDefaultPosition, + wxSize( 385,220), + wxDIALOG_MODAL | wxDEFAULT_DIALOG_STYLE | wxTAB_TRAVERSAL ); + + int i = 0; + for( i = 0; i != MAX_LAYOUTS; ++i ) + mLayouts[i] = NULL; + + // image-list is one of the few objects which + // currently cannot be serialized, create it first + // and use it as initial reference (IR) + + wxBitmap bmp1,bmp2; + + if ( wxFileExists( BMP_DIR "folder_icon.bmp" ) ) + bmp1.LoadFile( BMP_DIR "folder_icon.bmp", wxBITMAP_TYPE_BMP ); + + if ( wxFileExists( BMP_DIR "class_icon1.bmp" ) ) + bmp2.LoadFile( BMP_DIR "class_icon1.bmp", wxBITMAP_TYPE_BMP ); + + mImageList.Add( bmp1 ); + mImageList.Add( bmp2 ); + + InitAboutBox(); + + // create multiple layouts + + mpNestedLayout = 0; + + mpClntWindow = CreateTxtCtrl("client window"); + + // Create all layouts + for( i = 0; i != MAX_LAYOUTS; ++i ) + { + CreateLayout( i ); + } + // hide others + for( i = SECOND_LAYOUT; i != MAX_LAYOUTS; ++i ) + { + mLayouts[i]->HideBarWindows(); + } + + // activate first one + mLayouts[FIRST_LAYOUT]->Activate(); + mActiveLayoutNo = FIRST_LAYOUT; +} + +/*** event handlers ***/ + +bool MyFrame::OnClose(void) +{ + // USEFUL TRICK:: avoids flickering of application's frame + // when closing NN windows on exit: + + this->Show(FALSE); + + if ( (mAutoSave && mSavedAlready) || !mAutoSave ) + { + } + else + { + wxCommandEvent evt; + this->OnStore(evt); + } + + mAboutBox.Destroy(); + this->Destroy(); + + return TRUE; +} + +void MyFrame::OnLoad( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found a BIG question-mark !!"); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found another BIG question-mark !!"); +} + +void MyFrame::OnAutoSave( wxCommandEvent& event ) +{ + mAutoSave = !mAutoSave; + + wxCommandEvent evt; + this->OnStore(evt); + + SyncMenuBarItems(); +} + +void MyFrame::OnRemove( wxCommandEvent& event ) +{ + RemoveLayout( mActiveLayoutNo ); + + Refresh(); +} + +void MyFrame::OnRemoveAll( wxCommandEvent& event ) +{ + for( int i = 0; i != MAX_LAYOUTS; ++i ) + { + RemoveLayout( i ); + } + + Refresh(); +} + + +void MyFrame::OnRecreate( wxCommandEvent& event ) +{ + OnRemove( event ); // first destroy active layout + + CreateLayout( mActiveLayoutNo ); + + mLayouts[mActiveLayoutNo]->Activate(); +} + +void MyFrame::OnFirst( wxCommandEvent& event ) +{ + ActivateLayout( FIRST_LAYOUT ); +} + +void MyFrame::OnSecond( wxCommandEvent& event ) +{ + ActivateLayout( SECOND_LAYOUT ); +} + +void MyFrame::OnThird( wxCommandEvent& event ) +{ + ActivateLayout( THIRD_LAYOUT ); +} + +void MyFrame::OnQuit( wxCommandEvent& event ) +{ + // USEFUL TRICK:: avoids flickering of application's frame + // when closing NN windows on exit: + + this->Show(FALSE); + + if ( (mAutoSave && mSavedAlready) || !mAutoSave ) + { + } + else + { + wxCommandEvent evt; + this->OnStore(evt); + } + + Destroy(); +} + +void MyFrame::OnAbout( wxCommandEvent& event ) +{ + wxFont font; +#ifdef __WXMSW__ + font.SetFaceName("MS Sans Serif"); +#else + font.SetFamily( wxSWISS ); +#endif + + font.SetStyle( wxSLANT ); + font.SetWeight( wxNORMAL ); + font.SetPointSize( 8 ); + +#ifdef __WXMSW__ + font.RealizeResource(); +#endif + + mAboutBox.Center( wxBOTH ); + mAboutBox.Show(TRUE); + +} + +void MyFrame::OnChar( wxKeyEvent& event ) +{ + wxCommandEvent evt; + + if ( event.m_keyCode == WXK_F1 ) + { + this->OnFirst( evt ); + } + else + { + if ( event.m_keyCode == WXK_F2 ) + { + this->OnSecond( evt ); + } + else + { + if ( event.m_keyCode == WXK_F3 ) + { + this->OnThird( evt ); + } + if ( event.m_keyCode == WXK_F4 && !event.AltDown() ) + { + // "AI" :-) + wxMessageBox("There are only 3 layouts in this demo :-("); + } + else + { + if ( event.m_keyCode == WXK_TAB ) + { + // USEFUL TRICK:: avoids flickering of application's frame + // when closing NN windows on exit: + + this->Show(FALSE); + + if ( (mAutoSave && mSavedAlready) || !mAutoSave ) + { + } + else + { + wxCommandEvent evt; + this->OnStore(evt); + } + + Destroy(); + } + else + { + event.Skip(); + } + } + } + } +} + +void MyFrame::OnSayItsOk( wxCommandEvent& event ) +{ + wxMessageBox("It's OK :-)\n\n now click on the border around the button\n and try dragging it!" ); +} + +void MyFrame::OnBtnYes( wxCommandEvent& event ) +{ + mAboutBox.Show(FALSE); +} + +void MyFrame::OnBtnNo( wxCommandEvent& event ) +{ + mAboutBox.Show(FALSE); +} + +void MyFrame::OnBtnEsc( wxCommandEvent& event ) +{ + mAboutBox.Show(FALSE); +} + +/*** helper methods ***/ + +void MyFrame::InitAboutBox() +{ + wxPanel* pArea = new wxPanel(); + + pArea->Create( &mAboutBox, -1 ); + + new wxStaticText(pArea, -1, "This is wxFrameLayout contribution demo.", + wxPoint(10, 10) ); + + new wxStaticText(pArea, -1, "Aleksandras Gluchovas (c) 1998", + wxPoint(10, 30) ); + + new wxStaticText(pArea, -1, "", + wxPoint(10, 50) ); + + mpAboutBoxLayout = new wxFrameLayout( &mAboutBox, pArea, TRUE ); + + wxFrameLayout& layout = *mpAboutBoxLayout; + + cbDimInfo sizes( 90,40, // when docked horizontally + 45,55, // when docked vertically + 90,40, // when floated + TRUE, 4, 4 // true - bar is fixed-size + ); + + + wxButton* pYes = CreateButton("&Yes", &mAboutBox, ID_SAY_ITSOK ); + wxButton* pNo = CreateButton("&No", &mAboutBox, ID_BTN_NO ); + wxButton* pEsc = CreateButton("Cancel", &mAboutBox, ID_BTN_ESC ); + + layout.AddBar( pEsc, sizes, FL_ALIGN_BOTTOM, 0, 20, "cancel button"); + layout.AddBar( pNo, sizes, FL_ALIGN_BOTTOM, 0, 20, "no button"); + layout.AddBar( pYes, sizes, FL_ALIGN_BOTTOM, 0, 20, "yes button"); + + layout.mBorderPen.SetColour( 192, 192, 192 ); + layout.SetMargins( 15, 15, 15, 15, wxALL_PANES ); + + cbCommonPaneProperties props; + + layout.GetPaneProperties( props, FL_ALIGN_TOP ); + + props.mShow3DPaneBorderOn = FALSE; + + layout.SetPaneProperties( props, wxALL_PANES ); + + layout.Activate(); + + pYes->SetDefault(); + pYes->SetFocus(); +} + +wxTextCtrl* MyFrame::CreateTxtCtrl( const wxString& txt, wxWindow* parent ) +{ + return new wxTextCtrl( (parent != NULL ) ? parent : mpInternalFrm, + -1, txt, wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE ); +} + +wxButton* MyFrame::CreateButton( const wxString& label, + wxWindow* pParent, long id ) +{ + return new wxButton( (pParent)?pParent : mpInternalFrm, id, + label, wxPoint( 0,0 ), wxSize( 0,0 ) ); +} + +wxTreeCtrl* MyFrame::CreateTreeCtrl( const wxString& label ) +{ + wxTreeCtrl* pTree = new wxTreeCtrl( mpInternalFrm, -1 ); + + int rootid = pTree->AppendItem( (long)0, label, 0); + + if ( label[0] != 'X' ) + { + pTree->AppendItem(rootid, "Leaf1", 0); + pTree->AppendItem(rootid, "Leaf2", 0); + } + else + { + pTree->AppendItem(rootid, "Scully", 0); + pTree->AppendItem(rootid, "Mulder", 0); + } + + return pTree; +} + +wxChoice* MyFrame::CreateChoice( const wxString& txt ) +{ + wxString choice_strings[5]; + + choice_strings[0] = txt; + choice_strings[1] = "Julian"; + choice_strings[2] = "Hattie"; + choice_strings[3] = "Ken"; + choice_strings[4] = "Dick"; + + wxChoice *choice = new wxChoice( mpInternalFrm, 301, wxDefaultPosition, + wxDefaultSize, 5, choice_strings); + + choice->SetSelection(0); + + return choice; +} + +// helper + +void MyFrame::AddSearchToolbars( wxFrameLayout& layout, wxWindow* pParent ) +{ + cbDimInfo sizes2( 275,38, // when docked horizontally + 45,275, // when docked vertically + 80,30, // when floated + TRUE, // the bar is fixed-size + 4, // vertical gap (bar border) + 4, // horizontal gap (bar border) + new cbDynToolBarDimHandler() + ); + + cbDimInfo sizes3( 275,55, // when docked horizontally + 275,60, // when docked vertically + 45,130, // when floated + TRUE, // the bar is fixed-size + 4, // vertical gap (bar border) + 4, // horizontal gap (bar border) + new cbDynToolBarDimHandler() + ); + + cbDimInfo sizes4( 430,35, // when docked horizontally + 44,375, // when docked vertically + 80,100, // when floated + TRUE, // the bar is fixed-size + 4, // vertical gap (bar border) + 4, // horizontal gap (bar border) + new cbDynToolBarDimHandler() + ); + + wxDynamicToolBar* pTBar2 = new wxDynamicToolBar( mpInternalFrm, -1 ); + + wxChoice* pChoice = new wxChoice( pTBar2, -1, wxDefaultPosition, wxSize( 140,25 ) ); + + pTBar2->AddTool( 1, pChoice ); + pTBar2->AddTool( 2, BMP_DIR "search.bmp" ); + //pTBar2->AddSeparator(); + pTBar2->AddTool( 3, BMP_DIR "bookmarks.bmp" ); + pTBar2->AddTool( 4, BMP_DIR "nextmark.bmp" ); + pTBar2->AddTool( 5, BMP_DIR "prevmark.bmp" ); + + wxDynamicToolBar* pTBar3 = new wxDynamicToolBar( mpInternalFrm, -1 ); + + pTBar3->AddTool( 1, BMP_DIR "open.bmp", wxBITMAP_TYPE_BMP, " Open " ); + pTBar3->AddTool( 2, BMP_DIR "save.bmp", wxBITMAP_TYPE_BMP, " Save " ); + pTBar3->AddTool( 3, BMP_DIR "saveall.bmp", wxBITMAP_TYPE_BMP, " Save All " ); + //pTBar3->AddSeparator(); + pTBar3->AddTool( 4, BMP_DIR "cut.bmp", wxBITMAP_TYPE_BMP, " Open " ); + pTBar3->AddTool( 5, BMP_DIR "copy.bmp", wxBITMAP_TYPE_BMP, " Copy " ); + pTBar3->AddTool( 6, BMP_DIR "paste.bmp", wxBITMAP_TYPE_BMP, " Paste " ); + +#ifdef __WXMSW__ + pTBar3->EnableTool( 2, FALSE ); +#endif + + wxDynamicToolBar* pTBar4 = new wxDynamicToolBar( mpInternalFrm, -1 ); + + pTBar4->AddTool( 1, BMP_DIR "bookmarks.bmp", wxBITMAP_TYPE_BMP, "Bookmarks ", TRUE ); + pTBar4->AddTool( 2, BMP_DIR "nextmark.bmp", wxBITMAP_TYPE_BMP, "Next bookmark ", TRUE ); + pTBar4->AddTool( 3, BMP_DIR "prevmark.bmp", wxBITMAP_TYPE_BMP, "Prev bookmark ", TRUE ); + //pTBar4->AddSeparator(); + pTBar4->AddTool( 4, BMP_DIR "search.bmp", wxBITMAP_TYPE_BMP, "Search ", TRUE ); + +#ifdef __WXMSW__ + pTBar4->EnableTool( 4, FALSE ); +#endif + + layout.AddBar( pTBar2, + sizes2, FL_ALIGN_TOP, + 0, + 0, + "Search", + TRUE + ); + + layout.AddBar( pTBar3, + sizes3, FL_ALIGN_BOTTOM, + 0, + 0, + "Titled", + TRUE + ); + + layout.AddBar( pTBar4, + sizes4, FL_ALIGN_BOTTOM, + 1, + 0, + "Bookmarks", + TRUE + ); +} + +wxWindow* MyFrame::CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent ) +{ + bool isNested = (pParent != mpInternalFrm); + + // check if we're craeting nested layout + if ( isNested ) + { + layout.mBorderPen.SetColour( 128,255,128 ); + + // if so, than make border smaller + for( int i = 0; i != MAX_PANES; ++i ) + { + cbDockPane& pane = *layout.GetPane( i ); + + pane.mTopMargin = 5; + pane.mBottomMargin = 5; + pane.mLeftMargin = 5; + pane.mRightMargin = 5; + } + } + + int cbWidth = 200; + int cbHeight = ( isNested ) ? 50 : 150; + + cbDimInfo sizes4( cbWidth,cbHeight, + cbWidth,cbHeight, + cbWidth,cbHeight, FALSE ); + + cbWidth = 75; + cbHeight = 31; + + cbDimInfo sizes5( cbWidth,cbHeight, + 42,65, + cbWidth,cbHeight, TRUE, + 3, // vertical gap (bar border) + 3 // horizontal gap (bar border) + ); + + // create "workplace" window in the third layout + // SEB: originally here was a wxpp (wxWorkshop) class demotrated + // wxTabbedWindow* pMiniTabArea = new wxTabbedWindow(); + // pMiniTabArea->Create( pParent, -1 ); + + + wxTreeCtrl* pClassView = new wxTreeCtrl( pParent, -1, + wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS ); + + pClassView->SetImageList( &mImageList ); + + wxTreeItemId rootId = pClassView->AddRoot( "wxWindows 2.0 classes", 0 ); + + pClassView->AppendItem( rootId, "wxWin Dynamic classes (grabbed at run-time)", 0 ); + pClassView->AppendItem( rootId, "serializer-classes (grabbed at run-time)", 0 ); + + // now create "output" window + wxNotebook* pTabbedArea = new wxNotebook(pParent, -1); + // SEB: originally here was a wxpp (wxWorkshop) class used + // wxPaggedWindow* pTabbedArea = new wxPaggedWindow(); + // pTabbedArea->Create( pParent, -1 ); + + wxPanel* pSheet3 = new wxPanel(); + pSheet3->Create( pTabbedArea, -1 ); + pSheet3->Show(FALSE); + + pTabbedArea->AddPage( CreateTxtCtrl("build", pTabbedArea), "Build"); + pTabbedArea->AddPage( CreateTxtCtrl("debug", pTabbedArea), "Debug"); + pTabbedArea->AddPage( pSheet3, "is THIS recursive - or what !?"); + pTabbedArea->AddPage( CreateTxtCtrl("profile", pTabbedArea), "Profile"); + + layout.AddBar( new StartButton95(pParent), sizes5, FL_ALIGN_TOP, 0, 0, "Start..." ); + layout.AddBar( pClassView, sizes4, FL_ALIGN_LEFT, 0, 0, "Project Workplace" ); + layout.AddBar( pTabbedArea, sizes4, FL_ALIGN_BOTTOM, 0, 50, "Output" ); + + return pSheet3; +} + +void MyFrame::DropInSomeBars( int layoutNo ) +{ + /* create once... and forget! */ + + // setup dimension infos for various bar shapes + + int cbWidth = 90; + int cbHeight = 30; + + if ( layoutNo == SECOND_LAYOUT ) + cbHeight = 60; + + wxFrameLayout& layout = *mLayouts[layoutNo]; + + cbDimInfo sizes( cbWidth,cbHeight, // when docked horizontally + cbWidth,cbHeight, // when docked vertically + cbWidth,cbHeight, // when floated + TRUE // true - bar is fixed-size + ); + + cbWidth = 120; + + cbDimInfo sizes1( cbWidth,cbHeight, + cbWidth,cbHeight, + cbWidth,cbHeight, FALSE ); // false - bar is "flexible" + + cbWidth = 120; + cbHeight = 40; + + cbDimInfo sizes3( cbWidth,cbHeight, + cbWidth,cbHeight, + cbWidth,cbHeight, TRUE ); // -/- + + cbWidth = 200; + cbHeight = 150; + + cbDimInfo sizes4( cbWidth,cbHeight, + cbWidth,cbHeight, + cbWidth,cbHeight, FALSE ); // -/- + + cbWidth = 63; + cbHeight = 31; + + cbDimInfo sizes5( cbWidth,cbHeight, + cbHeight,cbWidth, + cbWidth,cbHeight, TRUE, + 3, // vertical gap (bar border) + 3 // horizontal gap (bar border) + ); // -/- + + + if ( layoutNo == FIRST_LAYOUT ) + { + // add 4 fixed-size bars (`sizes' dim-info) and one "flexible" (with `sizes1' dim-info) + + wxWindow* pGreenOne = new MyTestPanel(mpInternalFrm); + + pGreenOne->SetBackgroundColour( wxColour(128,255,128) ); + + layout.AddBar( pGreenOne, sizes, FL_ALIGN_TOP, 0, 50, "Bar1", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, FL_ALIGN_TOP, 2, 50, "Bar2", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, FL_ALIGN_BOTTOM, 2, 50, "Bar3", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, FL_ALIGN_LEFT, 2, 50, "Bar4", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes1, wxCBAR_HIDDEN, 2, 50, "Super-Bar", TRUE ); + } + else + { + if ( layoutNo == SECOND_LAYOUT ) + { + // show off various wx-controls in the second layout + + layout.AddBar( CreateTxtCtrl(), sizes, FL_ALIGN_TOP, 0, 50, "Fixed text Area&0" ); + layout.AddBar( CreateButton("OK"), sizes, FL_ALIGN_TOP, 0, 100, "First Button" ); + layout.AddBar( CreateTxtCtrl(), sizes1, FL_ALIGN_BOTTOM, 0, 50, "First Tree" ); + layout.AddBar( CreateTreeCtrl("Root"), sizes1, FL_ALIGN_LEFT, 0, 0, "TreeCtrl Window" ); + layout.AddBar( CreateChoice("Choice 1"), sizes3, FL_ALIGN_TOP, 0, 0, "Choice 1 (buggy)", FALSE, wxCBAR_HIDDEN ); + layout.AddBar( CreateChoice("Choice 2"), sizes3, FL_ALIGN_TOP, 0, 0, "Choice 2 (buggy)", FALSE, wxCBAR_HIDDEN ); + layout.AddBar( CreateTreeCtrl("X-Files"), sizes1, FL_ALIGN_RIGHT, 0, 100, "X-Files" ); + layout.AddBar( CreateTxtCtrl("smaller1"), sizes3, FL_ALIGN_TOP, 0, 50, "smaller Area1" ); + layout.AddBar( CreateTxtCtrl("smaller2"), sizes3, FL_ALIGN_TOP, 0, 50, "sm&ller Area2" ); + } + else + { + if ( layoutNo == THIRD_LAYOUT ) + { +#ifdef __WXGTK__ + cbCommonPaneProperties props; + layout.GetPaneProperties( props ); + props.mRealTimeUpdatesOn = FALSE; // real-time OFF for gtk!!! + layout.SetPaneProperties( props, wxALL_PANES ); +#endif + + layout.AddBar( CreateTxtCtrl("Tool1"), sizes3, FL_ALIGN_TOP, 0, 50, "Fixed text Area1" ); + layout.AddBar( CreateTxtCtrl("Tool2"), sizes3, FL_ALIGN_TOP, 0, 50, "Fixed text Area2" ); + layout.AddBar( CreateTxtCtrl("Tool3"), sizes3, FL_ALIGN_TOP, 0, 50, "Fixed text Area3" ); + layout.AddBar( CreateTxtCtrl("Tool4"), sizes3, FL_ALIGN_TOP, 1, 50, "Fixed text Area4" ); + layout.AddBar( CreateTxtCtrl("Tool5"), sizes3, FL_ALIGN_TOP, 1, 50, "Fixed text Area5" ); + layout.AddBar( CreateTxtCtrl("Tool6"), sizes3, FL_ALIGN_TOP, 1, 50, "Fixed text Area6" ); + layout.AddBar( CreateTxtCtrl("Tool7"), sizes3, FL_ALIGN_TOP, 2,250, "Fixed text Area7" ); + + cbDimInfo sizes10( 175,35, // when docked horizontally + 175,38, // when docked vertically + 170,35, // when floated + TRUE, // the bar is not fixed-size + 4, // vertical gap (bar border) + 4, // horizontal gap (bar border) + new cbDynToolBarDimHandler() + ); + + wxDynamicToolBar* pToolBar = new wxDynamicToolBar(); + + pToolBar->Create( mpInternalFrm, -1 ); + + // 1001-1006 ids of command events fired by added tool-buttons + + pToolBar->AddTool( 1001, BMP_DIR "new.bmp" ); + pToolBar->AddTool( 1002, BMP_DIR "open.bmp" ); + pToolBar->AddTool( 1003, BMP_DIR "save.bmp" ); + + pToolBar->AddTool( 1004, BMP_DIR "cut.bmp" ); + pToolBar->AddTool( 1005, BMP_DIR "copy.bmp" ); + pToolBar->AddTool( 1006, BMP_DIR "paste.bmp" ); + + layout.AddBar( pToolBar, // bar window (can be NULL) + sizes10, FL_ALIGN_TOP, // alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + "Real-Toolbar", // name to refere in customization pop-ups + FALSE + ); + + // create first "developement" layout + AddSearchToolbars( layout, mpInternalFrm); + + wxWindow* pSheet3 = CreateDevLayout( layout, mpInternalFrm); + + // create another ***secreat developement*** layout inside + // the third sheet of the outter one's output bar + + mpNestedLayout = new wxFrameLayout( pSheet3, + CreateTxtCtrl("\"Mobils in Mobile\" --C.Nemo",pSheet3), FALSE ); + + CreateDevLayout( *mpNestedLayout, pSheet3 ); + + mpNestedLayout->Activate(); + } + } + } +} + +void MyFrame::CreateLayout( int layoutNo ) +{ + wxFrameLayout* pLayout = new wxFrameLayout( mpInternalFrm, mpClntWindow, FALSE ); + + if ( layoutNo == THIRD_LAYOUT ) + { + pLayout->PushDefaultPlugins(); + pLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for bars +#ifdef __WXGTK__ + pLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) ); +#endif + pLayout->AddPlugin( CLASSINFO( cbRowDragPlugin ) ); + } + + mLayouts[layoutNo] = pLayout; + + DropInSomeBars( layoutNo ); +} + +void MyFrame::RemoveLayout( int layoutNo ) +{ + wxFrameLayout* pLayout = mLayouts[layoutNo]; + + if ( !pLayout ) + return; + + pLayout->HideBarWindows(); + + // destroy nested layout first + + if ( layoutNo == THIRD_LAYOUT ) + { + if ( mpNestedLayout ) + delete mpNestedLayout; + mpNestedLayout = NULL; + } + + // NOTE:: bar windows are NOT destroyed automatically by frame-layout + + pLayout->DestroyBarWindows(); + + delete pLayout; + + mLayouts[layoutNo] = NULL; + + Refresh(); +} + +void MyFrame::SyncMenuBarItems() +{ + for( int i = 0; i != MAX_LAYOUTS; ++i ) + { + GetMenuBar()->Check( ID_FIRST+i, mActiveLayoutNo == FIRST_LAYOUT+i ); + } + + GetMenuBar()->Check( ID_AUTOSAVE, mAutoSave ); +} + +void MyFrame::ActivateLayout( int layoutNo ) +{ + if ( layoutNo == mActiveLayoutNo ) + return; + + if ( mLayouts[mActiveLayoutNo] ) + mLayouts[mActiveLayoutNo]->Deactivate(); + + mActiveLayoutNo = layoutNo; + + if ( mLayouts[mActiveLayoutNo] ) + mLayouts[mActiveLayoutNo]->Activate(); + else + Refresh(); + + SyncMenuBarItems(); +} + +/***** Implementation for class StartButton95 (just for fun) *****/ + +IMPLEMENT_DYNAMIC_CLASS( StartButton95, wxPanel ) + +BEGIN_EVENT_TABLE( StartButton95, wxPanel ) + EVT_LEFT_DOWN( StartButton95::OnMouseDown ) + EVT_LEFT_UP ( StartButton95::OnMouseUp ) + EVT_PAINT ( StartButton95::OnPaint ) +END_EVENT_TABLE() + +void StartButton95::OnMouseDown( wxMouseEvent& event ) +{ + m_bPressed = TRUE; + Refresh(); + CaptureMouse(); +} + +void StartButton95::OnMouseUp( wxMouseEvent& event ) +{ + // "this is not a bug" + + SetCursor( wxCURSOR_WAIT ); + GetParent()->SetCursor( wxCURSOR_WAIT ); + ::wxSetCursor( wxCURSOR_WAIT ); + wxSleep(1); + + int i = 0; + for( i = 1; i != 6; ++i ) + { + m_bPressed = (i % 2) != 0; + Refresh(); + wxSleep(1); + } + GetParent()->Close(); + //*((char*)(i)-3) = 'X'; // Aleks what's the meaning of this??? +} + +void StartButton95::OnPaint( wxPaintEvent& event ) +{ + wxBitmap* pBmp = 0; + + if ( m_bPressed ) + { + if ( !m_PBmp.Ok() && wxFileExists( BMP_DIR "start95_pr.bmp" ) ) + + m_PBmp.LoadFile( BMP_DIR "start95_pr.bmp", wxBITMAP_TYPE_BMP ); + + pBmp = &m_PBmp; + } + else + { + if ( !m_DBmp.Ok() && wxFileExists( BMP_DIR "start95_dp.bmp" ) ) + + m_DBmp.LoadFile( BMP_DIR "start95_dp.bmp", wxBITMAP_TYPE_BMP ); + + pBmp = &m_DBmp; + } + + if (!pBmp) return; + wxMemoryDC mdc; + wxPaintDC dc(this); + mdc.SelectObject( *pBmp ); + + dc.Blit( 0,0, pBmp->GetWidth(), pBmp->GetHeight(), &mdc, 0,0, wxCOPY ); + + mdc.SelectObject( wxNullBitmap ); +} diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.h b/contrib/samples/fl/fl_demo2/fl_demo2.h new file mode 100644 index 0000000000..c9cf31d06a --- /dev/null +++ b/contrib/samples/fl/fl_demo2/fl_demo2.h @@ -0,0 +1,160 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 04/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __FLDEMO_G__ +#define __FLDEMO_G__ + +// ID for the menu commands + +#define MINIMAL_QUIT 1 +#define MINIMAL_ABOUT 102 + +#define ID_LOAD 103 +#define ID_STORE 104 +#define ID_AUTOSAVE 105 +//#define ID_SETTINGS 106 +#define ID_REMOVE 107 +#define ID_REMOVEALL 108 +#define ID_RECREATE 109 +#define ID_ACTIVATE 110 +#define ID_FIRST 111 +#define ID_SECOND 112 +#define ID_THIRD 113 + +#define ID_SAY_ITSOK 114 +#define ID_BTN_YES 115 +#define ID_BTN_NO 116 +#define ID_BTN_ESC 117 + +#define MAX_LAYOUTS 3 + +#define FIRST_LAYOUT 0 +#define SECOND_LAYOUT 1 +#define THIRD_LAYOUT 2 + +class wxFrameLayout; +class wxObjectStorage; + +// FOR NOW:: +typedef wxPanel MyTestPanel; + +// Define a new application type + +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +// Define a new frame type + +class MyFrame: public wxFrame +{ +protected: + + wxFrameLayout* mLayouts[MAX_LAYOUTS]; + + wxFrameLayout* mpNestedLayout; + wxFrameLayout* mpAboutBoxLayout; + + int mActiveLayoutNo; + bool mAutoSave; + bool mSavedAlready; + + // container windows: + + wxTextCtrl* mpClntWindow; + wxPanel* mpInternalFrm; + + wxImageList mImageList; + + wxFrame mAboutBox; + + // helpers for control-creation + + wxTextCtrl* CreateTxtCtrl ( const wxString& txt = "wxTextCtrl", wxWindow* parent = NULL ); + wxTreeCtrl* CreateTreeCtrl( const wxString& label = "TreeCtrl" ); + wxChoice* CreateChoice ( const wxString& txt = "Choice1" ); + wxButton* CreateButton ( const wxString& label = "wxButton", wxWindow* pParent = NULL, long id = ID_SAY_ITSOK ); + + // helpers for layout-creation + + void AddSearchToolbars( wxFrameLayout& layout, wxWindow* pParent ); + wxWindow* CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent ); + + void DropInSomeBars( int layoutNo ); + void CreateLayout( int layoutNo ); + void RemoveLayout( int layoutNo ); + + void InitAboutBox(); + + void ActivateLayout( int layoutNo ); + +public: /* public */ + + MyFrame( wxFrame *frame, char *title, int x, int y, int w, int h); + + ~MyFrame(); + + void SyncMenuBarItems(); + + // event handlers + + bool OnClose(void); + + void OnLoad( wxCommandEvent& event ); + void OnStore( wxCommandEvent& event ); + void OnAutoSave( wxCommandEvent& event ); + void OnQuit(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + //void OnSettings( wxCommandEvent& event ); + void OnRemove( wxCommandEvent& event ); + void OnRemoveAll( wxCommandEvent& event ); + void OnRecreate( wxCommandEvent& event ); + void OnFirst( wxCommandEvent& event ); + void OnSecond( wxCommandEvent& event ); + void OnThird( wxCommandEvent& event ); + + void OnSayItsOk( wxCommandEvent& event ); + void OnBtnYes( wxCommandEvent& event ); + void OnBtnNo( wxCommandEvent& event ); + void OnBtnEsc( wxCommandEvent& event ); + + void OnChar( wxKeyEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +// Define a new button type, StartButton95 (Just for fun) + +class StartButton95 : public wxPanel +{ + DECLARE_DYNAMIC_CLASS( StartButton95 ) + + bool m_bPressed; + wxBitmap m_PBmp; + wxBitmap m_DBmp; + +public: + StartButton95(void) : m_bPressed(FALSE) {} + + StartButton95(wxWindow* parent) + : m_bPressed(FALSE) { wxPanel::Create(parent,-1); } + + void OnMouseDown( wxMouseEvent& event ); + void OnMouseUp( wxMouseEvent& event ); + void OnPaint( wxPaintEvent& event ); + + DECLARE_EVENT_TABLE(); +}; + +#endif + diff --git a/contrib/samples/fl/fl_demo2/fl_demo2.rc b/contrib/samples/fl/fl_demo2/fl_demo2.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/contrib/samples/fl/fl_demo2/fl_demo2.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/contrib/samples/fl/fl_demo2/makefile.b32 b/contrib/samples/fl/fl_demo2/makefile.b32 new file mode 100644 index 0000000000..27524e7d2c --- /dev/null +++ b/contrib/samples/fl/fl_demo2/makefile.b32 @@ -0,0 +1,23 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = ..\..\..\.. +TARGET = fl_demo2 + +EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WSLIBDIR)\fl.lib +!else +EXTRALIBS = $(WSLIBDIR)\fld.lib +!endif + +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/contrib/samples/fl/fl_demo2/makefile.g95 b/contrib/samples/fl/fl_demo2/makefile.g95 new file mode 100644 index 0000000000..ff6a16f291 --- /dev/null +++ b/contrib/samples/fl/fl_demo2/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWorkshop for mingw & cygwin. + +WXDIR = ../../../.. +TARGET = fl_demo2 + +EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\" +EXTRALIBS = $(WXDIR)/lib/libfl.a + +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 diff --git a/contrib/samples/fl/fl_demo2/makefile.vc b/contrib/samples/fl/fl_demo2/makefile.vc new file mode 100644 index 0000000000..e05c0d699c --- /dev/null +++ b/contrib/samples/fl/fl_demo2/makefile.vc @@ -0,0 +1,24 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds fl sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\..\.. +TARGET = fl_demo2 + +EXTRAINC = -DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WXDIR)\lib\fl.lib +!else +EXTRALIBS = $(WXDIR)\lib\fld.lib +!endif + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.vc diff --git a/contrib/samples/fl/fl_sample1/Makefile.in b/contrib/samples/fl/fl_sample1/Makefile.in new file mode 100644 index 0000000000..11d671a280 --- /dev/null +++ b/contrib/samples/fl/fl_sample1/Makefile.in @@ -0,0 +1,25 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# "%W% %G%" +# +# Makefile : Builds sample on UNIX/Linux. + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. + +TARGET = fl_sample1 + +program_dir = contrib/samples/fl/$(TARGET) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\" +APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@ + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).o + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/fl/fl_sample1/fl_demo.dsp b/contrib/samples/fl/fl_sample1/fl_demo.dsp new file mode 100644 index 0000000000..b73643d59a --- /dev/null +++ b/contrib/samples/fl/fl_sample1/fl_demo.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fl_sample1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=fl_sample1 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample1 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fl_sample1 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "fl_sample1 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fl_sample1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ELSEIF "$(CFG)" == "fl_sample1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ENDIF + +# Begin Target + +# Name "fl_sample1 - Win32 Release" +# Name "fl_sample1 - Win32 Debug" +# Begin Source File + +SOURCE=.\fl_sample1.cpp + +!IF "$(CFG)" == "fl_sample1 - Win32 Release" + +!ELSEIF "$(CFG)" == "fl_sample1 - Win32 Debug" + +# ADD CPP /Yc"wx/wxprec.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\fl_sample1.rc +# End Source File +# End Target +# End Project diff --git a/contrib/samples/fl/fl_sample1/fl_demo.dsw b/contrib/samples/fl/fl_sample1/fl_demo.dsw new file mode 100644 index 0000000000..0ae6cf10be --- /dev/null +++ b/contrib/samples/fl/fl_sample1/fl_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fl_sample1"=.\fl_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/samples/fl/fl_sample1/fl_sample1.cpp b/contrib/samples/fl/fl_sample1/fl_sample1.cpp new file mode 100644 index 0000000000..762b0f2d11 --- /dev/null +++ b/contrib/samples/fl/fl_sample1/fl_sample1.cpp @@ -0,0 +1,196 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: fl_sample1.cpp +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 24/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/textctrl.h" + +// fl headers +#include "wx/fl/controlbar.h" + +// plugins used +#include "wx/fl/barhintspl.h" +#include "wx/fl/hintanimpl.h" + +#define ID_LOAD 102 +#define ID_STORE 103 +#define ID_QUIT 104 + +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +class MyFrame: public wxFrame +{ +protected: + wxFrameLayout* mpLayout; + wxWindow* mpClientWnd; + wxPanel* mpInternalFrm; + + wxTextCtrl* CreateTextCtrl( const wxString& value ); + +public: + MyFrame( wxWindow* parent, char *title ); + ~MyFrame(); + + void OnLoad( wxCommandEvent& event ); + void OnStore( wxCommandEvent& event ); + void OnQuit( wxCommandEvent& event ); + + bool OnClose(void) { return TRUE; } + + DECLARE_EVENT_TABLE() +}; + +/***** Implementation for class MyApp *****/ + +IMPLEMENT_APP (MyApp) + +bool MyApp::OnInit(void) +{ + // wxWindows boiler-plate: + + MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample"); + + wxMenu *file_menu = new wxMenu; + + file_menu->Append( ID_LOAD, "&Load layout" ); + file_menu->Append( ID_STORE, "&Store layout" ); + file_menu->AppendSeparator(); + + file_menu->Append( ID_QUIT, "E&xit" ); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + + frame->CreateStatusBar(3); + frame->SetMenuBar(menu_bar); + + frame->Show(TRUE); + + SetTopWindow(frame); + + return TRUE; +} + +/***** Immlementation for class MyFrame *****/ + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU( ID_LOAD, MyFrame::OnLoad ) + EVT_MENU( ID_STORE, MyFrame::OnStore ) + EVT_MENU( ID_QUIT, MyFrame::OnQuit ) +END_EVENT_TABLE() + +MyFrame::MyFrame( wxWindow* parent, char *title ) + : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition, + wxSize( 700, 500 ), + wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION, + "freimas" ) +{ + mpInternalFrm = (wxPanel*)this; + + mpClientWnd = CreateTextCtrl( "Client window" ); + + // btw, creation of internal frame is needed for wxGtk version + // to act correctly (since menu-bar is a separate window there..) + + mpLayout = new wxFrameLayout( mpInternalFrm, mpClientWnd ); + +#ifdef __WXGTK__ + // real-time dosn't work well under wxGtk yet + cbCommonPaneProperties props; + mpLayout->GetPaneProperties( props ); + + props.mRealTimeUpdatesOn = FALSE; // off + + mpLayout->SetPaneProperties( props, wxALL_PANES ); +#endif + + mpLayout->PushDefaultPlugins(); + mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso + //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) ); + + cbDimInfo sizes( 80,65, // when docked horizontally + 80,65, // when docked vertically + 80,30, // when floated + TRUE, // the bar is fixed-size + 5, // vertical gap (bar border) + 5 // horizontal gap (bar border) + ); + + // drop-in 20 bars + for( int i = 1; i <= 20; ++i ) + { + char buf[4]; + sprintf( buf, "%d", i ); + wxString name = wxString("Bar-"); + name += buf; + + sizes.mIsFixed = i % 5 > 0; // every fifth bar is not fixed-size + + if ( !sizes.mIsFixed ) name += " (flexible)"; + + mpLayout->AddBar( CreateTextCtrl(name),// bar window + sizes, i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + } +} + +MyFrame::~MyFrame() +{ + // layout is not a window, should be released manually + if ( mpLayout ) + delete mpLayout; +} + +wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value ) +{ + wxTextCtrl* pCtrl = new wxTextCtrl( mpInternalFrm, -1, value, + wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE ); + + pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) ); + + return pCtrl; +} + +void MyFrame::OnLoad( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found a BIG question-mark !!"); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found another BIG question-mark !!"); +} + +void MyFrame::OnQuit( wxCommandEvent& event ) +{ + Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction + + Close(TRUE); +} + diff --git a/contrib/samples/fl/fl_sample1/fl_sample1.rc b/contrib/samples/fl/fl_sample1/fl_sample1.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/contrib/samples/fl/fl_sample1/fl_sample1.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/contrib/samples/fl/fl_sample1/makefile.b32 b/contrib/samples/fl/fl_sample1/makefile.b32 new file mode 100644 index 0000000000..a521961fcf --- /dev/null +++ b/contrib/samples/fl/fl_sample1/makefile.b32 @@ -0,0 +1,23 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = ..\..\..\.. +TARGET = fl_sample1 + +EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WSLIBDIR)\fl.lib +!else +EXTRALIBS = $(WSLIBDIR)\fld.lib +!endif + +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/contrib/samples/fl/fl_sample1/makefile.g95 b/contrib/samples/fl/fl_sample1/makefile.g95 new file mode 100644 index 0000000000..8c130d4c6e --- /dev/null +++ b/contrib/samples/fl/fl_sample1/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWorkshop for mingw & cygwin. + +WXDIR = ../../../.. +TARGET = fl_sample1 + +EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\" +EXTRALIBS = $(WXDIR)/lib/libfl.a + +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 diff --git a/contrib/samples/fl/fl_sample1/makefile.vc b/contrib/samples/fl/fl_sample1/makefile.vc new file mode 100644 index 0000000000..50f4d6e26b --- /dev/null +++ b/contrib/samples/fl/fl_sample1/makefile.vc @@ -0,0 +1,24 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds fl sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\..\.. +TARGET = fl_sample1 + +EXTRAINC = -DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WXDIR)\lib\fl.lib +!else +EXTRALIBS = $(WXDIR)\lib\fld.lib +!endif + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.vc diff --git a/contrib/samples/fl/fl_sample2/Makefile.in b/contrib/samples/fl/fl_sample2/Makefile.in new file mode 100644 index 0000000000..85b50b407c --- /dev/null +++ b/contrib/samples/fl/fl_sample2/Makefile.in @@ -0,0 +1,25 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# "%W% %G%" +# +# Makefile : Builds sample on UNIX/Linux. + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. + +TARGET = fl_sample2 + +program_dir = contrib/samples/fl/$(TARGET) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\" +APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@ + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).o + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/fl/fl_sample2/fl_demo.dsp b/contrib/samples/fl/fl_sample2/fl_demo.dsp new file mode 100644 index 0000000000..34429e6703 --- /dev/null +++ b/contrib/samples/fl/fl_sample2/fl_demo.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fl_sample2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=fl_sample2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fl_sample2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "fl_sample2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fl_sample2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ELSEIF "$(CFG)" == "fl_sample2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ENDIF + +# Begin Target + +# Name "fl_sample2 - Win32 Release" +# Name "fl_sample2 - Win32 Debug" +# Begin Source File + +SOURCE=.\fl_sample2.cpp + +!IF "$(CFG)" == "fl_sample2 - Win32 Release" + +!ELSEIF "$(CFG)" == "fl_sample2 - Win32 Debug" + +# ADD CPP /Yc"wx/wxprec.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\fl_sample2.rc +# End Source File +# End Target +# End Project diff --git a/contrib/samples/fl/fl_sample2/fl_demo.dsw b/contrib/samples/fl/fl_sample2/fl_demo.dsw new file mode 100644 index 0000000000..ae31c3663b --- /dev/null +++ b/contrib/samples/fl/fl_sample2/fl_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fl_sample2"=.\fl_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/samples/fl/fl_sample2/fl_sample2.cpp b/contrib/samples/fl/fl_sample2/fl_sample2.cpp new file mode 100644 index 0000000000..281f49fa14 --- /dev/null +++ b/contrib/samples/fl/fl_sample2/fl_sample2.cpp @@ -0,0 +1,194 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: fl_sample2.cpp +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 24/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/textctrl.h" + +// fl headers +#include "wx/fl/controlbar.h" + +// plugins used +#include "wx/fl/barhintspl.h" +#include "wx/fl/hintanimpl.h" + +#define ID_LOAD 102 +#define ID_STORE 103 +#define ID_QUIT 104 + + +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +class MyFrame: public wxFrame +{ +protected: + wxFrameLayout* mpLayout; + wxWindow* mpClientWnd; + + wxTextCtrl* CreateTextCtrl( const wxString& value ); + +public: + MyFrame( wxWindow* parent, char *title ); + ~MyFrame(); + + void populateMyFrame(); + void OnLoad( wxCommandEvent& event ); + void OnStore( wxCommandEvent& event ); + void OnQuit( wxCommandEvent& event ); + + bool OnClose(void) { return TRUE; } + + DECLARE_EVENT_TABLE() +}; + +/***** Implementation for class MyApp *****/ + +IMPLEMENT_APP (MyApp) + +bool MyApp::OnInit(void) +{ + // wxWindows boiler-plate: + + MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample"); + + wxMenu *file_menu = new wxMenu; + + file_menu->Append( ID_LOAD, "&Load layout" ); + file_menu->Append( ID_STORE, "&Store layout" ); + file_menu->AppendSeparator(); + + file_menu->Append( ID_QUIT, "E&xit" ); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + + frame->CreateStatusBar(3); + frame->SetMenuBar(menu_bar); + + frame->Show(TRUE); + SetTopWindow(frame); + frame->populateMyFrame(); + + return TRUE; +} + +/***** Immlementation for class MyFrame *****/ + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU( ID_LOAD, MyFrame::OnLoad ) + EVT_MENU( ID_STORE, MyFrame::OnStore ) + EVT_MENU( ID_QUIT, MyFrame::OnQuit ) +END_EVENT_TABLE() + +MyFrame::MyFrame( wxWindow* parent, char *title ) + : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition, + wxSize( 700, 500 ), + wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION, + "freimas" ) +{ +} + +void MyFrame::populateMyFrame() +{ + mpClientWnd = CreateTextCtrl( "Client window" ); + + mpLayout = new wxFrameLayout( this, mpClientWnd ); + + /// mpLayout->PushDefaultPlugins(); + /// mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso + /// //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) ); + + cbDimInfo sizes( 80,65, // when docked horizontally + 80,165, // when docked vertically + 180,30, // when floated + TRUE, // the bar is fixed-size + 5, // vertical gap (bar border) + 5 // horizontal gap (bar border) + ); + + // drop-in 20 bars + for( int i = 1; i <= 10; ++i ) + { + wxSleep(1); + wxYield(); // CHECK! + + char buf[4]; + sprintf( buf, "%d", i ); + wxString name = wxString("Bar-"); + name += buf; + + //sizes.mIsFixed = i % 2 > 0; // every fifth bar is not fixed-size + + if ( !sizes.mIsFixed ) name += " (flexible)"; + // mpLayout->AddBar( CreateTextCtrl(name),// bar window + mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window + sizes, i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + + mpLayout->RecalcLayout(true); + + // Layout(); + // Refresh(); + } +} + +MyFrame::~MyFrame() +{ + // layout is not a window, should be released manually + if ( mpLayout ) + delete mpLayout; +} + +wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value ) +{ + wxTextCtrl* pCtrl = new wxTextCtrl( this, -1, value, + wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE ); + + pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) ); + + return pCtrl; +} + +void MyFrame::OnLoad( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found a BIG question-mark !!"); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found another BIG question-mark !!"); +} + +void MyFrame::OnQuit( wxCommandEvent& event ) +{ + Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction + + Close(TRUE); +} + diff --git a/contrib/samples/fl/fl_sample2/fl_sample2.rc b/contrib/samples/fl/fl_sample2/fl_sample2.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/contrib/samples/fl/fl_sample2/fl_sample2.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/contrib/samples/fl/fl_sample2/makefile.b32 b/contrib/samples/fl/fl_sample2/makefile.b32 new file mode 100644 index 0000000000..f8093f4a26 --- /dev/null +++ b/contrib/samples/fl/fl_sample2/makefile.b32 @@ -0,0 +1,23 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = ..\..\..\.. +TARGET = fl_sample2 + +EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WSLIBDIR)\fl.lib +!else +EXTRALIBS = $(WSLIBDIR)\fld.lib +!endif + +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/contrib/samples/fl/fl_sample2/makefile.g95 b/contrib/samples/fl/fl_sample2/makefile.g95 new file mode 100644 index 0000000000..e3ac85358d --- /dev/null +++ b/contrib/samples/fl/fl_sample2/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWorkshop for mingw & cygwin. + +WXDIR = ../../../.. +TARGET = fl_sample2 + +EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\" +EXTRALIBS = $(WXDIR)/lib/libfl.a + +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 diff --git a/contrib/samples/fl/fl_sample2/makefile.vc b/contrib/samples/fl/fl_sample2/makefile.vc new file mode 100644 index 0000000000..dabd5660e5 --- /dev/null +++ b/contrib/samples/fl/fl_sample2/makefile.vc @@ -0,0 +1,24 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds fl sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\..\.. +TARGET = fl_sample2 + +EXTRAINC = -DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WXDIR)\lib\fl.lib +!else +EXTRALIBS = $(WXDIR)\lib\fld.lib +!endif + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.vc diff --git a/contrib/samples/fl/fl_sample3/Makefile.in b/contrib/samples/fl/fl_sample3/Makefile.in new file mode 100644 index 0000000000..b19998869b --- /dev/null +++ b/contrib/samples/fl/fl_sample3/Makefile.in @@ -0,0 +1,25 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# "%W% %G%" +# +# Makefile : Builds sample on UNIX/Linux. + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../../.. + +TARGET = fl_sample3 + +program_dir = contrib/samples/fl/$(TARGET) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include -DBMP_DIR=\"../bitmaps/\" +APPEXTRALIBS = $(top_builddir)/lib/libfl.@WX_TARGET_LIBRARY_TYPE@ + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).o + +include $(top_builddir)/src/makeprog.env diff --git a/contrib/samples/fl/fl_sample3/fl_demo.dsp b/contrib/samples/fl/fl_sample3/fl_demo.dsp new file mode 100644 index 0000000000..38bb6a74bf --- /dev/null +++ b/contrib/samples/fl/fl_sample3/fl_demo.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="fl_sample3" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=fl_sample3 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "fl_demo.mak" CFG="fl_sample3 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "fl_sample3 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "fl_sample3 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "fl_sample3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../../include" /I "../../../../contrib/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "NDEBUG" +# ADD RSC /l 0x809 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wx.lib png.lib zlib.lib jpeg.lib tiff.lib fl.lib /nologo /subsystem:windows /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libci.lib" /nodefaultlib:"msvcrtd.lib" /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ELSEIF "$(CFG)" == "fl_sample3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../../include" /I "../../../../contrib/include" /D "_DEBUG" /D DEBUG=1 /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /Yu"wx/wxprec.h" /FD /D BMP_DIR=\"../bitmaps/\" /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD BASE RSC /l 0x809 /d "_DEBUG" +# ADD RSC /l 0x809 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib winmm.lib wxd.lib pngd.lib zlibd.lib jpegd.lib tiffd.lib fld.lib /nologo /subsystem:windows /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcid.lib" /nodefaultlib:"msvcrt.lib" /pdbtype:sept /libpath:"../../lib" /libpath:"../../contrib/lib" + +!ENDIF + +# Begin Target + +# Name "fl_sample3 - Win32 Release" +# Name "fl_sample3 - Win32 Debug" +# Begin Source File + +SOURCE=.\fl_sample3.cpp + +!IF "$(CFG)" == "fl_sample3 - Win32 Release" + +!ELSEIF "$(CFG)" == "fl_sample3 - Win32 Debug" + +# ADD CPP /Yc"wx/wxprec.h" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\fl_sample3.rc +# End Source File +# End Target +# End Project diff --git a/contrib/samples/fl/fl_sample3/fl_demo.dsw b/contrib/samples/fl/fl_sample3/fl_demo.dsw new file mode 100644 index 0000000000..573f82b017 --- /dev/null +++ b/contrib/samples/fl/fl_sample3/fl_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "fl_sample3"=.\fl_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/samples/fl/fl_sample3/fl_sample3.cpp b/contrib/samples/fl/fl_sample3/fl_sample3.cpp new file mode 100644 index 0000000000..2cdde9fbf3 --- /dev/null +++ b/contrib/samples/fl/fl_sample3/fl_sample3.cpp @@ -0,0 +1,337 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: fl_sample3.cpp +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: Sebastian Haase (June 21, 2001) +// Created: 24/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/textctrl.h" + +// fl headers +#include "wx/fl/controlbar.h" + +// plugins used +#include "wx/fl/barhintspl.h" +#include "wx/fl/hintanimpl.h" + +#define ID_LOAD 102 +#define ID_STORE 103 +#define ID_QUIT 104 + +#define ID_BUTT 145 +#define ID_BUTT2 146 + +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +class MyFrame: public wxFrame +{ +protected: + wxFrameLayout* mpLayout; + wxWindow* mpClientWnd; + + wxButton * my_butt; + + wxTextCtrl* CreateTextCtrl( const wxString& value ); +public: + MyFrame( wxWindow* parent, char *title ); + ~MyFrame(); + + void OnLoad( wxCommandEvent& event ); + void OnStore( wxCommandEvent& event ); + void OnQuit( wxCommandEvent& event ); + + void OnButt( wxCommandEvent& event ); + void OnButt2( wxCommandEvent& event ); + bool OnClose(void) { return TRUE; } + + DECLARE_EVENT_TABLE() +}; + +/***** Implementation for class MyApp *****/ + +IMPLEMENT_APP (MyApp) + +bool MyApp::OnInit(void) +{ + // wxWindows boiler-plate: + + MyFrame *frame = new MyFrame(NULL, "wxFrameLayout sample"); + + wxMenu *file_menu = new wxMenu; + + file_menu->Append( ID_LOAD, "&Load layout" ); + file_menu->Append( ID_STORE, "&Store layout" ); + file_menu->AppendSeparator(); + + file_menu->Append( ID_QUIT, "E&xit" ); + + wxMenuBar *menu_bar = new wxMenuBar; + + menu_bar->Append(file_menu, "&File"); + + frame->CreateStatusBar(3); + frame->SetMenuBar(menu_bar); + + frame->Show(TRUE); + SetTopWindow(frame); + + return TRUE; +} + +/***** Immlementation for class MyFrame *****/ + +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU( ID_LOAD, MyFrame::OnLoad ) + EVT_MENU( ID_STORE, MyFrame::OnStore ) + EVT_MENU( ID_QUIT, MyFrame::OnQuit ) + EVT_BUTTON( ID_BUTT, MyFrame::OnButt ) + EVT_BUTTON( ID_BUTT2, MyFrame::OnButt2 ) +END_EVENT_TABLE() + +MyFrame::MyFrame( wxWindow* parent, char *title ) + : wxFrame( parent, -1, "NewTest-II", wxDefaultPosition, + wxSize( 700, 500 ), + wxCLIP_CHILDREN | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | + wxTHICK_FRAME | wxSYSTEM_MENU | wxCAPTION, + "freimas" ) +{ + + mpClientWnd = new wxWindow(this, -1); + mpLayout = new wxFrameLayout( this, mpClientWnd ); + + /// mpLayout->PushDefaultPlugins(); + /// mpLayout->AddPlugin( CLASSINFO( cbBarHintsPlugin ) ); // facny "X"es and beveal for barso + /// //mpLayout->AddPlugin( CLASSINFO( cbHintAnimationPlugin ) ); + + cbDimInfo sizes( 80,65, // when docked horizontally + 80,165, // when docked vertically + 180,30, // when floated + TRUE, // the bar is fixed-size + 5, // vertical gap (bar border) + 5 // horizontal gap (bar border) + ); + + + // drop-in some bars + + for( int i = 1; i <= 11; ++i ) + { + char buf[4]; + sprintf( buf, "%d", i ); + wxString name = wxString("Bar-"); + name += buf; + + sizes.mIsFixed = (i !=3); // every fifth bar is not fixed-size + + if ( !sizes.mIsFixed ) name += " (flexible)"; + // mpLayout->AddBar( CreateTextCtrl(name),// bar window + if(i != 4 && i!= 5 && i!=11) { + mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window + sizes, + i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + } else if(i==4){ + mpLayout->AddBar( new wxTextCtrl(this, -1, name),// bar window + cbDimInfo( 100,100, 100,100, 100,100, TRUE, 5, 5), + i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + } else if(i==5) { + my_butt = new wxButton(this, ID_BUTT, name); + mpLayout->AddBar( my_butt,// bar window + cbDimInfo( 100,100, 200,200, 400,400, TRUE, 5, 5), + i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + } else if(i==11) { + mpLayout->AddBar( new wxButton(this, ID_BUTT2, name+"_2"), + cbDimInfo( 100,100, 200,200, 400,400, TRUE, 5, 5), + i % MAX_PANES,// alignment ( 0-top,1-bottom, etc) + 0, // insert into 0th row (vert. position) + 0, // offset from the start of row (in pixels) + name // name to refere in customization pop-ups + ); + } + + // mpLayout->RecalcLayout(true); + // Layout(); + // Refresh(); + } +} + +MyFrame::~MyFrame() +{ + // layout is not a window, should be released manually + if ( mpLayout ) + delete mpLayout; +} + +wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value ) +{ + wxTextCtrl* pCtrl = new wxTextCtrl( this, -1, value, + wxPoint(0,0), wxSize(1,1), wxTE_MULTILINE ); + + pCtrl->SetBackgroundColour( wxColour( 255,255,255 ) ); + + return pCtrl; +} + +void MyFrame::OnLoad( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found a BIG question-mark !!"); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxMessageBox("Hey - you found another BIG question-mark !!"); +} + +void MyFrame::OnQuit( wxCommandEvent& event ) +{ + Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction + + Close(TRUE); +} + +void MyFrame::OnButt( wxCommandEvent& event ) +{ + static int i =0; + + // cbBarInfo* FindBarByName( const wxString& name ); + + switch(i % 2) { + case 0: + { + cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-1")); + if(x) + mpLayout->InverseVisibility(x); + else + wxBell(); + break; + } + case 1: + { + cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-6")); + if(x) + { + if(i % 4 == 1) + { + mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE); + //mpLayout->RecalcLayout(true); + mpLayout->RepositionFloatedBar(x); + } + else + { + mpLayout->SetBarState(x, 0, TRUE); + //mpLayout->RecalcLayout(true); + //mpLayout->RepositionFloatedBar(x); + } + // // // x->mState = wxCBAR_FLOATING; + // // // mpLayout->ApplyBarProperties(x); + } + else + { + wxBell(); + } + + break; + } + } + i++; +} + +void MyFrame::OnButt2( wxCommandEvent& event ) +{ + static int i =0; + + // cbBarInfo* FindBarByName( const wxString& name ); + + switch(i % 2) { + case 0: + { + cbBarInfo* x = mpLayout->FindBarByName(wxString("Bar-1")); + if(x) + { + for(int a=0;amDimInfo.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;amDimInfo.mSizes[a].x = 10 + 2 + 2*x->mDimInfo.mHorizGap; + x->mDimInfo.mSizes[a].y = 10 + 2 + 2*x->mDimInfo.mVertGap; + } + x->mpBarWnd->SetSize(10,10); + mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE); // HACK !!! + mpLayout->SetBarState(x, 0, TRUE); // HACK !!! + wxYield(); // HACK !!! needed to resize BEFORE redraw + mpLayout->RefreshNow( TRUE ); // HACK !!! needed to trigger redraw + + // // mpLayout->SetBarState(x, wxCBAR_FLOATING, TRUE); + // // mpLayout->RecalcLayout(true); + // // // mpLayout->RepositionFloatedBar(x); + // // mpLayout->RecalcLayout(true); + // // mpLayout->RepositionFloatedBar(x); + // // mpLayout->SetBarState(x, 0, TRUE); + // // wxYield(); + // // mpLayout->RefreshNow( TRUE ); + // // mpLayout->RecalcLayout(true); + } + else + { + wxBell(); + } + + break; + } + } + i++; +} + diff --git a/contrib/samples/fl/fl_sample3/fl_sample3.rc b/contrib/samples/fl/fl_sample3/fl_sample3.rc new file mode 100644 index 0000000000..626b82f58a --- /dev/null +++ b/contrib/samples/fl/fl_sample3/fl_sample3.rc @@ -0,0 +1,3 @@ +/* mondrian ICON "mondrian.ico" */ +#include "wx/msw/wx.rc" + diff --git a/contrib/samples/fl/fl_sample3/makefile.b32 b/contrib/samples/fl/fl_sample3/makefile.b32 new file mode 100644 index 0000000000..d243c38bef --- /dev/null +++ b/contrib/samples/fl/fl_sample3/makefile.b32 @@ -0,0 +1,23 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds sample for 32-bit BC++ + +WXDIR = ..\..\..\.. +TARGET = fl_sample3 + +EXTRACPPFLAGS =-DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WSLIBDIR)\fl.lib +!else +EXTRALIBS = $(WSLIBDIR)\fld.lib +!endif + +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.b32 + diff --git a/contrib/samples/fl/fl_sample3/makefile.g95 b/contrib/samples/fl/fl_sample3/makefile.g95 new file mode 100644 index 0000000000..47e00c3722 --- /dev/null +++ b/contrib/samples/fl/fl_sample3/makefile.g95 @@ -0,0 +1,18 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWorkshop for mingw & cygwin. + +WXDIR = ../../../.. +TARGET = fl_sample3 + +EXTRACPPFLAGS = -DBMP_DIR=\"../bitmaps/\" +EXTRALIBS = $(WXDIR)/lib/libfl.a + +OBJECTS = $(TARGET).o + +include $(WXDIR)/src/makeprog.g95 diff --git a/contrib/samples/fl/fl_sample3/makefile.vc b/contrib/samples/fl/fl_sample3/makefile.vc new file mode 100644 index 0000000000..699a66babc --- /dev/null +++ b/contrib/samples/fl/fl_sample3/makefile.vc @@ -0,0 +1,24 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile : Builds fl sample (VC++, WIN32) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\..\.. +TARGET = fl_sample3 + +EXTRAINC = -DBMP_DIR=\"../bitmaps/\" +!if "$(FINAL)" == "1" +EXTRALIBS = $(WXDIR)\lib\fl.lib +!else +EXTRALIBS = $(WXDIR)\lib\fld.lib +!endif + +PROGRAM = $(TARGET) +OBJECTS = $(TARGET).obj + +!include $(WXDIR)\src\makeprog.vc diff --git a/contrib/src/Makefile.in b/contrib/src/Makefile.in index d031944895..10c09135b8 100644 --- a/contrib/src/Makefile.in +++ b/contrib/src/Makefile.in @@ -1,6 +1,6 @@ # $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 diff --git a/contrib/src/fl/Makefile.in b/contrib/src/fl/Makefile.in new file mode 100644 index 0000000000..19a7af90bf --- /dev/null +++ b/contrib/src/fl/Makefile.in @@ -0,0 +1,29 @@ +# +# File: Makefile +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWindows FrameLayout library (Linux/wxGTK). + +top_srcdir = @top_srcdir@/.. +top_builddir = ../../.. +libsrc_dir = contrib/src/fl + +TARGET_LIBNAME = libfl +OBJ_EXT = o + +# Version Info. +LIBVERSION_CURRENT=1 +LIBVERSION_REVISION=0 +LIBVERSION_AGE=0 + +include ./files.lst + +OBJECTS = $(FL_OBJECTS) + +APPEXTRADEFS = -I$(top_srcdir)/contrib/include + +include $(top_builddir)/src/makelib.env + diff --git a/contrib/src/fl/antiflickpl.cpp b/contrib/src/fl/antiflickpl.cpp new file mode 100644 index 0000000000..419b186756 --- /dev/null +++ b/contrib/src/fl/antiflickpl.cpp @@ -0,0 +1,236 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas (@Lithuania) +// Modified by: +// Created: 23/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "antiflickpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/antiflickpl.h" + +/***** Implementation for class cbAntiflickerPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbAntiflickerPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbAntiflickerPlugin, cbPluginBase ) + + EVT_PL_START_DRAW_IN_AREA ( cbAntiflickerPlugin::OnStartDrawInArea ) + EVT_PL_FINISH_DRAW_IN_AREA ( cbAntiflickerPlugin::OnFinishDrawInArea ) + +END_EVENT_TABLE() + +// initialization of static members + +int cbAntiflickerPlugin::mRefCount = 0; + +wxBitmap* cbAntiflickerPlugin::mpVertBuf = 0; +wxBitmap* cbAntiflickerPlugin::mpHorizBuf = 0; +wxMemoryDC* cbAntiflickerPlugin::mpVertBufDc = 0; +wxMemoryDC* cbAntiflickerPlugin::mpHorizBufDc = 0; + +// constructors + +cbAntiflickerPlugin::cbAntiflickerPlugin(void) + : mpLRUBufDc ( NULL ), + mLRUArea ( -1,-1, -1,-1 ) +{ + ++mRefCount; +} + +cbAntiflickerPlugin::cbAntiflickerPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + mpLRUBufDc ( NULL ), + mLRUArea ( -1,-1, -1,-1 ) +{ + ++mRefCount; +} + +cbAntiflickerPlugin::~cbAntiflickerPlugin() +{ + if ( --mRefCount == 0 ) + { + if ( mpHorizBuf ) + { + mpHorizBufDc->SelectObject( wxNullBitmap ); + delete mpHorizBuf; + delete mpHorizBufDc; + mpHorizBuf = 0; + mpHorizBufDc = 0; + } + + if ( mpVertBuf ) + { + mpVertBufDc->SelectObject( wxNullBitmap ); + delete mpVertBuf; + delete mpVertBufDc; + mpVertBuf = 0; + mpVertBufDc = 0; + } + } +} + +wxDC* cbAntiflickerPlugin::FindSuitableBuffer( const wxRect& forArea ) +{ + if ( mpVertBuf ) + { + if ( mpVertBuf->GetHeight() >= forArea.height && + mpVertBuf->GetWidth() >= forArea.width ) + + return mpVertBufDc; + } + else + if ( mpHorizBuf ) + { + if ( mpHorizBuf->GetHeight() >= forArea.height && + mpHorizBuf->GetWidth() >= forArea.width ) + + return mpHorizBufDc; + } + + return 0; +} + +wxDC* cbAntiflickerPlugin::AllocNewBuffer( const wxRect& forArea ) +{ + // TBD:: preallocate bit larger bitmap at once, to avoid + // excessive realocations later + + // check whether the given area is oriented horizontally + // or verticallya and choose correspoinding bitmap to create or + // recreate + + if ( forArea.height > forArea.width ) + { + wxSize prevDim( 0,0 ); + + if ( mpVertBuf ) + { + prevDim.x = mpVertBuf->GetWidth(); + prevDim.y = mpVertBuf->GetHeight(); + + mpVertBufDc->SelectObject( wxNullBitmap ); + delete mpVertBuf; + } + else + mpVertBufDc = new wxMemoryDC(); + + mpVertBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ), + int( wxMax(forArea.height, prevDim.y ) ) + ); + + mpVertBufDc->SelectObject( *mpVertBuf ); + + return mpVertBufDc; + } + else + { + wxSize prevDim( 0,0 ); + + if ( mpHorizBuf ) + { + prevDim.x = mpHorizBuf->GetWidth(); + prevDim.y = mpHorizBuf->GetHeight(); + + mpHorizBufDc->SelectObject( wxNullBitmap ); + delete mpHorizBuf; + } + else + mpHorizBufDc = new wxMemoryDC(); + + mpHorizBuf = new wxBitmap( int( wxMax(forArea.width, prevDim.x ) ), + int( wxMax(forArea.height, prevDim.y ) ) + ); + + mpHorizBufDc->SelectObject( *mpHorizBuf ); + + return mpHorizBufDc; + } +} + +void cbAntiflickerPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event ) +{ + wxASSERT( mpLRUBufDc == NULL ); // DBG:: see comments in OnFinishDrawInArea(..) method + + // short-cut + wxRect& area = event.mArea; + + if ( event.mArea.width < 0 || + event.mArea.height < 0 ) return; + + // memorize given area + mLRUArea.x = area.x; + mLRUArea.y = area.y; + mLRUArea.width = area.width; + mLRUArea.height = area.height; + + wxDC* pBufDc = FindSuitableBuffer( area ); + + if ( !pBufDc ) + + pBufDc = AllocNewBuffer( area ); + + pBufDc->SetDeviceOrigin( -area.x, -area.y ); + + pBufDc->SetClippingRegion( area.x, area.y, + area.width, area.height ); + + wxClientDC clntDc( &mpLayout->GetParentFrame() ); + + (*event.mppDc) = pBufDc; + + mpLRUBufDc = pBufDc; // memorize buffer, which will be flushed to screen + // upon "commiting" the drawing + + /* + // OLD STUFF:: + mpLRUBufDc->Blit( pos.x, pos.y, size.x, size.y, + &clntDc, pos.x, pos.y, wxCOPY ); + */ +} + +void cbAntiflickerPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event ) +{ + wxRect& area = event.mArea; + + if ( event.mArea.width < 0 || + event.mArea.height < 0 ) return; + + wxASSERT( mpLRUBufDc ); // DBG:: OnStartDrawInArea should be called first + + // FOR NOW:: OnStartDrawInArea(..) should be immediately followed + // by OnFinishDrawInArea(..) for the same area + + wxASSERT( mLRUArea.x == area.x ); + wxASSERT( mLRUArea.y == area.y ); + wxASSERT( mLRUArea.width == area.width ); + wxASSERT( mLRUArea.height == area.height ); + + wxClientDC clntDc( &mpLayout->GetParentFrame() ); + + // "commit" drawings in one-shot + clntDc.Blit( area.x, area.y, area.width, area.height, + mpLRUBufDc, area.x, area.y, wxCOPY ); + + mpLRUBufDc->DestroyClippingRegion(); + mpLRUBufDc = 0; +} + diff --git a/contrib/src/fl/bardragpl.cpp b/contrib/src/fl/bardragpl.cpp new file mode 100644 index 0000000000..26b927e93a --- /dev/null +++ b/contrib/src/fl/bardragpl.cpp @@ -0,0 +1,934 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "bardragpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/bardragpl.h" + +#define POS_UNDEFINED -32768 + +// helpers, FOR NOW:: static + +static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 ) +{ + if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) || + ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) ) + + if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) || + ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) ) + + return TRUE; + + return FALSE; +} + +static inline bool rect_contains_point( const wxRect& rect, int x, int y ) +{ + return ( x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height ); +} + +/***** Implementation for class cbBarDragPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbBarDragPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbBarDragPlugin, cbPluginBase ) + + //EVT_PL_LEFT_DOWN ( cbBarDragPlugin::OnLButtonDown ) + EVT_PL_LEFT_UP ( cbBarDragPlugin::OnLButtonUp ) + EVT_PL_MOTION ( cbBarDragPlugin::OnMouseMove ) + EVT_PL_DRAW_HINT_RECT ( cbBarDragPlugin::OnDrawHintRect ) + EVT_PL_START_BAR_DRAGGING ( cbBarDragPlugin::OnStartBarDragging ) + EVT_PL_LEFT_DCLICK ( cbBarDragPlugin::OnLDblClick ) + +END_EVENT_TABLE() + +cbBarDragPlugin::cbBarDragPlugin(void) + + : mBarDragStarted ( FALSE ), + mCanStick ( TRUE ), + mpScrDc ( NULL ), + mpCurCursor ( NULL ), + mpDraggedBar ( NULL ), + mInClientHintBorder( 4 ) +{} + +cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + + mBarDragStarted ( FALSE ), + mCanStick ( TRUE ), + mpScrDc ( NULL ), + mpCurCursor ( NULL ), + mpDraggedBar ( NULL ), + mInClientHintBorder( 4 ) +{} + +cbBarDragPlugin::~cbBarDragPlugin() +{ + // nothing +} + +// helper methods (protected) + +// clips (top/bottom) or (right/left) edges against the frame's bounding rect. + +void do_clip_edges( int len, int& rectPos, int& rectLen ) +{ + if ( rectPos < 0 ) + { + rectLen += rectPos; + rectPos = 0; + if ( rectLen < 0 ) + rectLen = 1; + } + else + if ( rectPos > len-1 ) + { + rectPos = len-1; + rectLen = 1; + } + else + if ( rectPos + rectLen - 1 > len ) + + rectLen -= (rectPos + rectLen) - len + 1; +} + +void cbBarDragPlugin::ClipRectInFrame( wxRect& rect ) +{ + int w, h; + mpLayout->GetParentFrame().GetClientSize( &w, &h ); + + do_clip_edges( w, rect.x, rect.width ); + do_clip_edges( h, rect.y, rect.height ); +} + +void cbBarDragPlugin::ClipPosInFrame( wxPoint& pos ) +{ + int w, h; + mpLayout->GetParentFrame().GetClientSize( &w, &h ); + + if ( pos.x < 0 ) + pos.x = 0; + if ( pos.y < 0 ) + pos.y = 0; + if ( pos.x > w ) + pos.x = w-1; + if ( pos.y > h ) + pos.y = h-1; +} + +void cbBarDragPlugin::AdjustHintRect( wxPoint& mousePos ) +{ + mHintRect.x = mousePos.x - mMouseInRectX; + mHintRect.y = mousePos.y - mMouseInRectY; +} + +cbDockPane* cbBarDragPlugin::HitTestPanes( wxRect& rect ) +{ + //wxRect clipped = rect; + + //ClipRectInFrame( clipped ); + + cbDockPane** pPanes = mpLayout->GetPanesArray(); + + for( int i = 0; i != MAX_PANES; ++i ) + + if ( rect_hits_rect( pPanes[i]->mBoundsInParent, rect ) ) + + return pPanes[i]; + + return NULL; +} + +cbDockPane* cbBarDragPlugin::HitTestPanes( wxPoint& pos ) +{ + wxPoint clipped = pos; + + //ClipPosInFrame( pos ); + + cbDockPane** pPanes = mpLayout->GetPanesArray(); + + for( int i = 0; i != MAX_PANES; ++i ) + + if ( rect_contains_point( pPanes[i]->mBoundsInParent, clipped.x, clipped.y ) ) + + return pPanes[i]; + + return NULL; +} + +bool cbBarDragPlugin::HitsPane( cbDockPane* pPane, wxRect& rect ) +{ + return rect_hits_rect( pPane->mBoundsInParent, rect ); +} + +int cbBarDragPlugin::GetDistanceToPane( cbDockPane* pPane, wxPoint& mousePos ) +{ + wxRect& bounds = pPane->mBoundsInParent; + + switch( pPane->mAlignment ) + { + case FL_ALIGN_TOP : return mousePos.y - ( bounds.y + bounds.height ); + + case FL_ALIGN_BOTTOM : return bounds.y - mousePos.y; + + case FL_ALIGN_LEFT : return mousePos.x - ( bounds.x + bounds.width ); + + case FL_ALIGN_RIGHT : return bounds.x - mousePos.x; + + default : return 0; // never reached + } + +// return 0; +} + +bool cbBarDragPlugin::IsInOtherPane( wxPoint& mousePos ) +{ + cbDockPane* pPane = HitTestPanes( mousePos ); + + if ( pPane && pPane != mpCurPane ) return TRUE; + else return FALSE; +} + +bool cbBarDragPlugin::IsInClientArea( wxPoint& mousePos ) +{ + return ( HitTestPanes( mousePos ) == NULL ); +} + +bool cbBarDragPlugin::IsInClientArea( wxRect& rect ) +{ + return ( HitTestPanes( rect ) == NULL ); +} + +void cbBarDragPlugin::CalcOnScreenDims( wxRect& rect ) +{ + if ( !mpCurPane || mpDraggedBar->IsFixed() ) return; + + wxRect inPane = rect; + + mpCurPane->FrameToPane( &inPane ); + + int rowNo = mpCurPane->GetRowAt( inPane.y, inPane.y + inPane.height ); + + bool isMaximized = ( rowNo >= (int)mpCurPane->GetRowList().Count() || rowNo < 0 ); + + if ( isMaximized ) + { + inPane.x = 0; + inPane.width = mpCurPane->mPaneWidth; + + mpCurPane->PaneToFrame( &inPane ); + + rect = inPane; + } +} + +// helpers + +static inline void check_upper_overrun( int& pos, int width, int mousePos ) +{ + if ( mousePos >= pos + width ) + + pos = mousePos - width/2; +} + +static inline void check_lower_overrun( int& pos, int width, int mousePos ) +{ + if ( mousePos <= pos ) + + pos = mousePos - width/2; +} + +void cbBarDragPlugin::StickToPane( cbDockPane* pPane, wxPoint& mousePos ) +{ + int wInPane = GetBarWidthInPane ( pPane ); + int hInPane = GetBarHeightInPane( pPane ); + + // adjsut hint-rect horizontally (in pane's orientation) + + if ( pPane->IsHorizontal() ) + { + mHintRect.width = wInPane; + mHintRect.height = hInPane; + } + else + { + mHintRect.height = wInPane; + mHintRect.width = hInPane; + } + + // adjsut hint-rect vertically (in pane's orientation) + + wxRect& bounds = pPane->mBoundsInParent; + + // TRUE, if hint enters the pane through it's lower edge + + bool fromLowerEdge = ( pPane->IsHorizontal() ) + ? mousePos.y > bounds.y + : mousePos.x > bounds.x; + + // NOTE:: about all the below min/max things: they are meant to ensure + // that mouse pointer doesn't overrun (leave) the hint-rectangle + // when dimensions it's are recalculated upon sticking it to the pane + + if ( pPane->IsHorizontal() && fromLowerEdge ) + { + int paneBottomEdgeY = bounds.y + bounds.height; + + mHintRect.y = wxMin( paneBottomEdgeY, mousePos.y ); + + check_lower_overrun( mHintRect.y, hInPane, mousePos.y ); + + } + else + if ( pPane->IsHorizontal() && !fromLowerEdge ) + { + int paneTopEdgeY = bounds.y; + + mHintRect.y = wxMax( paneTopEdgeY - hInPane, mousePos.y - hInPane ); + + check_upper_overrun( mHintRect.y, hInPane, mousePos.y ); + } + else + if ( !pPane->IsHorizontal() && fromLowerEdge ) + { + int paneRightEdgeX = bounds.x + bounds.width; + + mHintRect.x = wxMin( paneRightEdgeX, mousePos.x ); + + check_lower_overrun( mHintRect.x, hInPane, mousePos.x ); + } + else + if ( !pPane->IsHorizontal() && !fromLowerEdge ) + { + int paneLeftEdgeX = bounds.x; + + mHintRect.x = wxMax( paneLeftEdgeX - hInPane, mousePos.x - hInPane ); + + check_upper_overrun( mHintRect.x, hInPane, mousePos.x ); + } + + mMouseInRectX = mousePos.x - mHintRect.x; + mMouseInRectY = mousePos.y - mHintRect.y; + + mpCurPane = pPane; // memorize pane to which the hint is currently sticked +} + +void cbBarDragPlugin::UnstickFromPane( cbDockPane* pPane, wxPoint& mousePos ) +{ + // unsticking causes rectangle to get the shape, in which + // dragged control-bar would be when floated + + + int newWidth = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].x; + int newHeight = mpDraggedBar->mDimInfo.mSizes[wxCBAR_FLOATING].y; + + wxRect& flBounds = mpDraggedBar->mDimInfo.mBounds[wxCBAR_FLOATING]; + + if ( flBounds.width != -1 ) + { + newWidth = flBounds.width; + newHeight = flBounds.height; + } + + mHintRect.width = newWidth; + mHintRect.height = newHeight; + + wxRect& bounds = pPane->mBoundsInParent; + + // TRUE, if hint leaves the pane through it's lower edge + + bool fromLowerEdge = ( pPane->IsHorizontal() ) + ? mousePos.y > bounds.y + : mousePos.x > bounds.x; + + // NOTE:: ...all the below min/max things - see comments about it in StickToPane(..) + + if ( pPane->IsHorizontal() && fromLowerEdge ) + { + bool fromLowerEdge = mousePos.y > bounds.y; + + mHintRect.y = wxMax( bounds.y + bounds.height + 1, mousePos.y - newHeight ); + + check_upper_overrun( mHintRect.y, newHeight, mousePos.y ); + + // this is how MFC's hint behaves: + + if ( mMouseInRectX > newWidth ) + + mHintRect.x = mousePos.x - ( newWidth / 2 ); + } + else + if ( pPane->IsHorizontal() && !fromLowerEdge ) + { + mHintRect.y = wxMin( bounds.y - newHeight - 1, mousePos.y ); + + // -/- + + if ( mMouseInRectX > newWidth ) + + mHintRect.x = mousePos.x - ( newWidth / 2 ); + + check_lower_overrun( mHintRect.y, newHeight, mousePos.y ); + } + else + if ( !pPane->IsHorizontal() && fromLowerEdge ) + { + mHintRect.x = wxMax( bounds.x + bounds.width, mousePos.x - newWidth ); + + // -/- + + if ( mMouseInRectY > newHeight ) + + mHintRect.y = mousePos.y - ( newHeight / 2 ); + + check_upper_overrun( mHintRect.x, newWidth, mousePos.x ); + } + else + if ( !pPane->IsHorizontal() && !fromLowerEdge ) + { + mHintRect.x = wxMin( bounds.x - newWidth - 1, mousePos.x ); + + // -/- + + if ( mMouseInRectY > newHeight ) + + mHintRect.y = mousePos.y - ( newHeight / 2 ); + + check_lower_overrun( mHintRect.x, newWidth, mousePos.x ); + } + + mMouseInRectX = mousePos.x - mHintRect.x; + mMouseInRectY = mousePos.y - mHintRect.y; + + mpCurPane = NULL; +} + +int cbBarDragPlugin::GetBarWidthInPane( cbDockPane* pPane ) +{ + if ( pPane == mpSrcPane ) + + return mBarWidthInSrcPane; + + // this is how MFC's bars behave: + + if ( pPane->IsHorizontal() ) + + return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].x; + else + return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].x; +} + +int cbBarDragPlugin::GetBarHeightInPane( cbDockPane* pPane ) +{ + if ( pPane->IsHorizontal() ) + + return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_HORIZONTALLY].y; + else + return mpDraggedBar->mDimInfo.mSizes[wxCBAR_DOCKED_VERTICALLY ].y; +} + +void cbBarDragPlugin::ShowHint( bool prevWasInClient ) +{ + bool wasDocked = FALSE; + + if ( mpDraggedBar->mState != wxCBAR_FLOATING && !mpCurPane ) + { + mpLayout->SetBarState( mpDraggedBar, wxCBAR_FLOATING, TRUE ); + } + else + if ( mpDraggedBar->mState == wxCBAR_FLOATING && mpCurPane ) + { + mpLayout->SetBarState( mpDraggedBar, wxCBAR_DOCKED_HORIZONTALLY, FALSE ); + + wasDocked = TRUE; + } + + if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE ) + { + // do hevy calculations first + + wxRect actualRect = mHintRect; // will be adjusted depending on drag-settings + + if ( mpSrcPane->mProps.mExactDockPredictionOn && mpCurPane ) + { + bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE ); + + wxASSERT( success ); // DBG:: + + actualRect = mpDraggedBar->mBounds; + + mpCurPane->PaneToFrame( &actualRect ); + } + else + CalcOnScreenDims( actualRect ); + + // release previous hint + + if ( mPrevHintRect.x != POS_UNDEFINED ) + { + // erase previous rectangle + + cbDrawHintRectEvent evt( mPrevHintRect, prevWasInClient, TRUE, FALSE ); + + mpLayout->FirePluginEvent( evt ); + } + + // draw new hint + + cbDrawHintRectEvent evt( actualRect, mpCurPane == NULL, FALSE, FALSE ); + + mpLayout->FirePluginEvent( evt ); + + mPrevHintRect = actualRect; + } + else + { + // otherwise, if real-time updates option is ON + + if ( mpCurPane ) + { + mpLayout->GetUpdatesManager().OnStartChanges(); + + if ( wasDocked ) + + mpDraggedBar->mUMgrData.SetDirty( TRUE ); + + bool success = mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE ); + + wxASSERT( success ); // DBG :: + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); + } + else + { + if ( mpLayout->mFloatingOn ) + { + // move the top-most floated bar around as user drags the hint + + mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mHintRect; + + mpLayout->ApplyBarProperties( mpDraggedBar ); + } + } + } +} + +/*** event handlers ***/ + +void cbBarDragPlugin::OnMouseMove( cbMotionEvent& event ) +{ + // calculate postion in frame's coordiantes + + if ( !mBarDragStarted ) + { + event.Skip(); // pass event to the next plugin + return; + } + + wxPoint mousePos = event.mPos; + + event.mpPane->PaneToFrame( &mousePos.x, &mousePos.y ); + + bool prevIsInClient = ( mpCurPane == 0 ); + + AdjustHintRect( mousePos ); + + // if the hint-rect is not "tempted" to any pane yet + + if ( mpCurPane == NULL ) + { + cbDockPane* pPane = HitTestPanes( mHintRect ); + + if ( !pPane ) + + // enable sticking again, if we've left the pane completely + mCanStick = TRUE; + + if ( mCanStick && pPane && + GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) ) + + StickToPane( pPane, mousePos ); + else + if ( pPane && HitTestPanes( mousePos ) == pPane && 0 ) // FOR NOW:: disabled + + StickToPane( pPane, mousePos ); + } + else + { + // otherwise, when rect is now sticked to some of the panes + // check if it should still remain in this pane + + mCanStick = TRUE; + + bool mouseInOther = IsInOtherPane( mousePos ); + + if ( mouseInOther ) + { + cbDockPane* pPane = HitTestPanes( mousePos ); + + StickToPane( pPane, mousePos ); + } + else + { + if ( IsInClientArea( mousePos ) ) + { + cbDockPane* pPane = HitTestPanes( mHintRect ); + + if ( pPane && + pPane != mpCurPane && + GetDistanceToPane( pPane, mousePos ) < GetBarHeightInPane( pPane ) ) + + StickToPane( pPane, mousePos ); + else + if ( !pPane ) + { + UnstickFromPane( mpCurPane, mousePos ); + + // FOR NOW:: disabled, would cause some mess + //mCanStick = FALSE; // prevents from sticking to this + // pane again, flag is reset when hint-rect + // leaves the pane completely + } + else + if ( GetDistanceToPane( pPane, mousePos ) > GetBarHeightInPane( pPane ) ) + { + if ( !HitsPane( mpCurPane, mHintRect ) ) + { + UnstickFromPane( mpCurPane, mousePos ); + + // FOR NOW:: disabled, would cause some mess + //mCanStick = FALSE; // prevents from sticking to this + // pane again, flag is reset when hint-rect + // leaves the pane completely + } + } + + } + else + { + } + } + } + + ShowHint( prevIsInClient ); + + wxCursor* pPrevCurs = mpCurCursor; + + if ( mpCurPane ) + + mpCurCursor = mpLayout->mpDragCursor; + else + { + if ( mpLayout->mFloatingOn && mpSrcPane->mProps.mRealTimeUpdatesOn ) + + mpCurCursor = mpLayout->mpDragCursor; + else + mpCurCursor = mpLayout->mpNECursor; + } + + if ( pPrevCurs != mpCurCursor ) + + mpLayout->GetParentFrame().SetCursor( *mpCurCursor ); +} + +void cbBarDragPlugin::OnLButtonDown( cbLeftDownEvent& event ) +{ + if ( mBarDragStarted ) + { + wxMessageBox("DblClick!"); + } + + event.Skip(); +} + +void cbBarDragPlugin::OnLButtonUp( cbLeftUpEvent& event ) +{ + if ( mBarDragStarted ) + { + if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE ) + { + // erase current rectangle, and finsih on-screen drawing session + + cbDrawHintRectEvent evt( mPrevHintRect, mpCurPane == NULL, TRUE, TRUE ); + + mpLayout->FirePluginEvent( evt ); + + if ( mpCurPane != NULL ) + { + if ( mpSrcPane->mProps.mExactDockPredictionOn ) + { + mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane, FALSE ); + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); + } + else + mpLayout->RedockBar( mpDraggedBar, mHintRect, mpCurPane ); + } + } + + mHintRect.width = -1; + + mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor ); + + mpLayout->ReleaseEventsFromPane( event.mpPane ); + mpLayout->ReleaseEventsFromPlugin( this ); + + mBarDragStarted = FALSE; + + if ( mBarWasFloating && mpDraggedBar->mState != wxCBAR_FLOATING ) + { + // save bar's floating position before it was docked + + mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ] = mFloatedBarBounds; + } + } + else + event.Skip(); // pass event to the next plugin +} + +void cbBarDragPlugin::OnLDblClick( cbLeftDClickEvent& event ) +{ + int avoidCompilerWarning = 1; + if ( avoidCompilerWarning ) + { + cbBarInfo* pHittedBar; + cbRowInfo* pRow; + + if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes + &pRow, + &pHittedBar ) == CB_BAR_CONTENT_HITTED + ) + { + mpLayout->SetBarState( pHittedBar, wxCBAR_FLOATING, TRUE ); + + mpLayout->RepositionFloatedBar( pHittedBar ); + + return; // event is "eaten" by this plugin + } + + mBarDragStarted = FALSE; + + event.Skip(); + } + + //wxMessageBox("Hi, dblclick arrived!"); +} + +void cbBarDragPlugin::OnStartBarDragging( cbStartBarDraggingEvent& event ) +{ + mpDraggedBar = event.mpBar; + mpSrcPane = event.mpPane; + + mpLayout->CaptureEventsForPane( event.mpPane ); + mpLayout->CaptureEventsForPlugin( this ); + + mpLayout->GetParentFrame().SetCursor( *mpLayout->mpDragCursor ); + + mBarDragStarted = TRUE; + + wxRect inParent = mpDraggedBar->mBounds; + + mBarWasFloating = mpDraggedBar->mState == wxCBAR_FLOATING; + + if ( mBarWasFloating ) + { + inParent = mpDraggedBar->mDimInfo.mBounds[ wxCBAR_FLOATING ]; + mFloatedBarBounds = inParent; + } + else + event.mpPane->PaneToFrame( &inParent ); + + mHintRect.x = POS_UNDEFINED; + + mHintRect.width = inParent.width; + mHintRect.height = inParent.height; + + mMouseInRectX = event.mPos.x - inParent.x; + mMouseInRectY = event.mPos.y - inParent.y; + + mpSrcPane = event.mpPane; + + if ( mpDraggedBar->mState == wxCBAR_FLOATING ) + + mpCurPane = NULL; + else + mpCurPane = event.mpPane; + + mPrevHintRect.x = POS_UNDEFINED; + + mCanStick = FALSE; // we're not stuck into any pane now - + // there's nowhere to "stick-twice" + + mBarWidthInSrcPane = mpDraggedBar->mDimInfo.mSizes[ mpDraggedBar->mState ].x; + + if ( mpSrcPane->mProps.mRealTimeUpdatesOn == FALSE && + mpSrcPane->mProps.mExactDockPredictionOn ) + + mpLayout->GetUpdatesManager().OnStartChanges(); // capture initial state of layout + + // simulate the first mouse movement + + int x = event.mPos.x, y = event.mPos.y; + + mpSrcPane->FrameToPane( &x, &y ); + + cbMotionEvent motionEvt( wxPoint(x,y), event.mpPane ); + + + this->OnMouseMove( motionEvt ); + + return; // event is "eaten" by this plugin +} + +/*** on-screen hint-tracking related methods ***/ + +void cbBarDragPlugin::OnDrawHintRect( cbDrawHintRectEvent& event ) +{ + if ( !mpScrDc ) StartTracking(); + + DoDrawHintRect( event.mRect, event.mIsInClient ); + + if ( event.mLastTime ) + + FinishTracking(); +} + +#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin) +#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin) +#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons. +#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons. + +// FOR NOW:: static + +static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D + }; + +void cbBarDragPlugin::StartTracking() +{ + mpScrDc = new wxScreenDC; + + wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame()); +} + +void cbBarDragPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect) +{ + wxRect scrRect; + + RectToScr( rect, scrRect ); + + int prevLF = mpScrDc->GetLogicalFunction(); + + mpScrDc->SetLogicalFunction( wxINVERT ); + + if ( isInClientRect ) + { + // BUG BUG BUG (wx):: somehow stippled brush works only + // when the bitmap created on stack, not + // as a member of the class + + wxBitmap checker( (const char*)_gCheckerImg, 8,8 ); + + wxBrush checkerBrush( checker ); + + mpScrDc->SetPen( mpLayout->mNullPen ); + mpScrDc->SetBrush( checkerBrush ); + + int half = mInClientHintBorder / 2; + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half, + scrRect.width + 2*half, mInClientHintBorder ); + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half, + scrRect.width + 2*half, mInClientHintBorder ); + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1, + mInClientHintBorder, scrRect.height - 2*half + 2); + + mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half, + scrRect.y + half - 1, + mInClientHintBorder, scrRect.height - 2*half + 2); + + mpScrDc->SetBrush( wxNullBrush ); + } + else + { + mpScrDc->SetPen( mpLayout->mBlackPen ); + + mpScrDc->DrawLine( scrRect.x, scrRect.y, + scrRect.x + scrRect.width, scrRect.y ); + + mpScrDc->DrawLine( scrRect.x, scrRect.y + 1, + scrRect.x, scrRect.y + scrRect.height ); + + mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height, + scrRect.x + scrRect.width, scrRect.y + scrRect.height ); + + mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y, + scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1); + } + + mpScrDc->SetLogicalFunction( prevLF ); +} + +void cbBarDragPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect) +{ + DoDrawHintRect( rect, isInClientRect ); +} + +void cbBarDragPlugin::EraseHintRect( wxRect& rect, bool isInClientRect) +{ + DoDrawHintRect( rect, isInClientRect ); +} + +void cbBarDragPlugin::FinishTracking() +{ + wxScreenDC::EndDrawingOnTop(); + + delete mpScrDc; + + mpScrDc = NULL; +} + +void cbBarDragPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect ) +{ + scrRect = frameRect; + + int x = frameRect.x, y = frameRect.y; + + mpLayout->GetParentFrame().ClientToScreen( &x, &y ); + + scrRect.x = x; + scrRect.y = y; +} + diff --git a/contrib/src/fl/barhintspl.cpp b/contrib/src/fl/barhintspl.cpp new file mode 100644 index 0000000000..2a5b99ca03 --- /dev/null +++ b/contrib/src/fl/barhintspl.cpp @@ -0,0 +1,560 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 30/11/98 (my 22th birthday :-) +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "barhintspl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/utils.h" +#include "wx/fl/barhintspl.h" + +// fixed settings + +#define GROOVE_WIDTH 3 // left shade + middle line + right shade +#define GROOVE_TO_GROOVE_GAP 1 +#define BOX_T_BOX_GAP 2 +#define BOX_TO_GROOVE_GAP 3 + +#define BOXES_IN_HINT 2 +#define CLOSE_BOX_IDX 0 +#define COLLAPSE_BOX_IDX 1 + +// used interally + +#define CLOSE_BOX_HITTED 1 +#define COLLAPSE_BOX_HITTED 2 + +/***** Implementation fro class cbBarHintsPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbBarHintsPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbBarHintsPlugin, cbPluginBase ) + + EVT_PL_SIZE_BAR_WND ( cbBarHintsPlugin::OnSizeBarWindow ) + EVT_PL_DRAW_BAR_DECOR( cbBarHintsPlugin::OnDrawBarDecorations ) + + EVT_PL_LEFT_DOWN( cbBarHintsPlugin::OnLeftDown ) + EVT_PL_LEFT_UP ( cbBarHintsPlugin::OnLeftUp ) + EVT_PL_MOTION ( cbBarHintsPlugin::OnMotion ) + +END_EVENT_TABLE() + +cbBarHintsPlugin::cbBarHintsPlugin(void) + + : mpPane( 0 ), + mBtnPressed ( FALSE ), + mCloseBoxOn ( TRUE ), + mCollapseBoxOn( TRUE ), + mGrooveCount ( 2 ), + mHintGap ( 4 ), + mXWeight ( 2 ) +{ + mBoxes[CLOSE_BOX_IDX] = NULL; + mBoxes[COLLAPSE_BOX_IDX] = NULL; +} + +cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask ) + + : cbPluginBase( pLayout, paneMask ), + mpPane( 0 ), + mBtnPressed ( FALSE ), + mCloseBoxOn ( TRUE ), + mCollapseBoxOn( TRUE ), + mGrooveCount ( 2 ), + mHintGap ( 5 ), + mXWeight ( 2 ) +{ + mBoxes[CLOSE_BOX_IDX] = NULL; + mBoxes[COLLAPSE_BOX_IDX] = NULL; +} + + +cbBarHintsPlugin::~cbBarHintsPlugin() +{ + if (mBoxes[CLOSE_BOX_IDX]) + delete mBoxes[CLOSE_BOX_IDX]; + + if (mBoxes[COLLAPSE_BOX_IDX]) + delete mBoxes[COLLAPSE_BOX_IDX]; +} // cbBarHintsPlugin destructor + + +void cbBarHintsPlugin::SetGrooveCount( int nGrooves ) +{ + mGrooveCount = nGrooves; +} + +void cbBarHintsPlugin::CreateBoxes() +{ + cbCloseBox* box1 = new cbCloseBox(); + cbCollapseBox* box2 = new cbCollapseBox(); + + mBoxes[CLOSE_BOX_IDX] = box1; + mBoxes[COLLAPSE_BOX_IDX] = box2; + + int i; + for( i = 0; i != BOXES_IN_HINT; ++i ) + { + mBoxes[i]->mpLayout = mpLayout; + mBoxes[i]->mpPlugin = this; + mBoxes[i]->mpWnd = NULL; + } +} + + +void cbBarHintsPlugin::Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed ) +{ +} + +void cbBarHintsPlugin::DrawCloseBox( wxDC& dc, const wxPoint& pos, bool pressed ) +{ +} + +void cbBarHintsPlugin::DrawCollapseBox( wxDC& dc, const wxPoint& pos, + bool atLeft, bool disabled, bool pressed ) +{ +} + +void cbBarHintsPlugin::DrawGrooves( wxDC& dc, const wxPoint& pos, int length ) +{ + int ofs = 0; + + int i; + for( i = 0; i != mGrooveCount; ++i, ofs += ( GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP ) ) + + if ( mpPane->IsHorizontal() ) + { + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( pos.x + ofs, pos.y, pos.x + ofs, pos.y + length - 1 ); + dc.DrawPoint( pos.x + ofs + 1, pos.y ); + + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawLine( pos.x + ofs + 2, pos.y, pos.x + ofs + 2, pos.y + length ); + dc.DrawPoint( pos.x + ofs + 1, pos.y + length - 1 ); + dc.DrawPoint( pos.x + ofs, pos.y + length - 1 ); + } + else + { + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( pos.x, pos.y + ofs, pos.x + length - 1, pos.y + ofs ); + dc.DrawPoint( pos.x, pos.y + ofs + 1 ); + + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawLine( pos.x, pos.y + ofs + 2, pos.x + length, pos.y + ofs + 2 ); + dc.DrawPoint( pos.x + length - 1, pos.y + ofs + 1 ); + dc.DrawPoint( pos.x + length - 1, pos.y + ofs ); + } +} + +void cbBarHintsPlugin::ExcludeHints( wxRect& rect, cbBarInfo& info ) +{ + int boxHeight = BTN_BOX_HEIGHT; + + // collapse and close box are not placed on fixed bars + + if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) ) + + boxHeight = 0; + + int height = wxMax( mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) + - GROOVE_TO_GROOVE_GAP, + boxHeight + ); + + if ( mpPane->IsHorizontal() ) + { + rect.x += ( mHintGap*2 + height ); + rect.width -= (height + 2*mHintGap); + + rect.x -= info.mDimInfo.mHorizGap + 2; + rect.width += info.mDimInfo.mHorizGap + 2; + } + else + { + rect.y += (mHintGap*2 + height); + rect.height -= (height + 2*mHintGap); + + rect.y -= info.mDimInfo.mVertGap + 2; + rect.height += info.mDimInfo.mVertGap + 2; + } +} + +void cbBarHintsPlugin::DoDrawHint( wxDC& dc, wxRect& rect, + int pos, int boxOfs, int grooveOfs, + bool isFixed ) +{ + if ( !isFixed ) + { + if ( mpPane->IsHorizontal() ) + { + if ( mCloseBoxOn ) + + mBoxes[CLOSE_BOX_IDX]->Draw( dc ); + + if ( mCollapseBoxOn ) + + mBoxes[COLLAPSE_BOX_IDX]->Draw( dc ); + } + else + { + if ( mCloseBoxOn ) + + mBoxes[CLOSE_BOX_IDX]->Draw( dc ); + + if ( mCollapseBoxOn ) + + mBoxes[COLLAPSE_BOX_IDX]->Draw( dc ); + } + } + + if ( mpPane->IsHorizontal() ) + + DrawGrooves( dc, wxPoint( rect.x + mHintGap + grooveOfs, pos ), + rect.height - (pos - rect.y) - mHintGap ); + else + DrawGrooves( dc, wxPoint( rect.x + mHintGap, rect.y + mHintGap + grooveOfs ), + (pos - rect.x) - mHintGap ); +} + +void cbBarHintsPlugin::GetHintsLayout( wxRect& rect, cbBarInfo& info, + int& boxOfs, int& grooveOfs, int& pos ) +{ + int boxHeight = BTN_BOX_HEIGHT; + int boxWidth = BTN_BOX_WIDTH + BOX_TO_GROOVE_GAP + BTN_BOX_WIDTH; + + // collapse and close box are not placed on fixed bars + + if ( info.IsFixed() || ( !mCloseBoxOn && !mCollapseBoxOn ) ) + { + boxHeight = 0; + boxWidth = 0; + } + else + if ( !mCloseBoxOn || !mCollapseBoxOn ) + + boxWidth = BTN_BOX_WIDTH; + + int grooveHeight = mGrooveCount*(GROOVE_WIDTH + GROOVE_TO_GROOVE_GAP) + - GROOVE_TO_GROOVE_GAP; + + int height = wxMax( grooveHeight, boxHeight ); + + // center boxs and groves with respect to each other + + boxOfs = ( height - boxHeight ) / 2; + grooveOfs = ( height - grooveHeight ) / 2; + + pos = ( mpPane->IsHorizontal() ) ? rect.y + mHintGap + : rect.x + rect.width - mHintGap; + + // setup positions for boxes + + if ( !info.IsFixed() ) + { + // what direction "collapse-triangle" should look at? + + bool& isAtLeft = ((cbCollapseBox*)(mBoxes[COLLAPSE_BOX_IDX]))->mIsAtLeft; + + isAtLeft= info.mBounds.x <= mpPane->mPaneWidth - ( info.mBounds.x + info.mBounds.width ); + + if ( info.IsExpanded() ) + { + isAtLeft = FALSE; + + cbBarInfo* pCur = info.mpPrev; + + while( pCur ) + { + if ( !pCur->IsFixed() ) + { + isAtLeft = TRUE; break; + } + + pCur = pCur->mpPrev; + } + } + + // collapse/expand works only when more not-fixed bars are present in the same row + + mBoxes[COLLAPSE_BOX_IDX]->Enable( info.mpRow->mNotFixedBarsCnt > 1 ); + + int i; + for( i = 0; i != BOXES_IN_HINT; ++i ) + + mBoxes[i]->mpPane = mpPane; + + + if ( mpPane->IsHorizontal() ) + { + if ( mCloseBoxOn ) + { + mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos ); + + pos += BTN_BOX_HEIGHT; + } + + if ( mCollapseBoxOn ) + { + if ( mCloseBoxOn ) pos += BOX_T_BOX_GAP; + + mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( rect.x + mHintGap + boxOfs, pos ); + + pos += BTN_BOX_HEIGHT; + + pos += BOX_TO_GROOVE_GAP; + } + } + else + { + if ( mCloseBoxOn ) + { + pos -= BTN_BOX_WIDTH; + + mBoxes[CLOSE_BOX_IDX]->mPos = wxPoint( pos , rect.y + mHintGap + boxOfs ); + } + + if ( mCollapseBoxOn ) + { + if ( mCloseBoxOn ) pos -= BOX_T_BOX_GAP; + + pos -= BTN_BOX_WIDTH; + + mBoxes[COLLAPSE_BOX_IDX]->mPos = wxPoint( pos, rect.y + mHintGap + boxOfs ); + + pos -= BOX_TO_GROOVE_GAP; + } + } + } +} + +static inline bool is_in_box( const wxPoint& rectPos, const wxPoint& mousePos ) +{ + return ( mousePos.x >= rectPos.x && + mousePos.y >= rectPos.y && + mousePos.x < rectPos.x + BTN_BOX_WIDTH && + mousePos.y < rectPos.y + BTN_BOX_HEIGHT ); +} + +int cbBarHintsPlugin::HitTestHints( cbBarInfo& info, const wxPoint& pos ) +{ + wxPoint inPane = pos; + mpPane->PaneToFrame( &inPane.x, &inPane.y ); + + wxRect& rect = info.mBoundsInParent; + + if ( info.IsFixed() ) return FALSE; + + int boxOfs, grooveOfs, coord; + + GetHintsLayout( rect, info, boxOfs, grooveOfs, coord ); + + if ( mpPane->IsHorizontal() ) + { + if ( mCloseBoxOn ) + { + if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) ) + + return CLOSE_BOX_HITTED; + + coord += BTN_BOX_HEIGHT; + } + + if ( mCollapseBoxOn ) + { + if ( mCloseBoxOn ) coord += BOX_T_BOX_GAP; + + if ( is_in_box( wxPoint( rect.x + mHintGap + boxOfs, coord ), inPane ) ) + + return COLLAPSE_BOX_HITTED; + + coord += BTN_BOX_HEIGHT; + } + } + else + { + if ( mCloseBoxOn ) + { + coord -= BTN_BOX_WIDTH; + + if ( is_in_box( wxPoint( coord , rect.y + mHintGap + boxOfs ), inPane ) ) + + return CLOSE_BOX_HITTED; + } + + if ( mCollapseBoxOn ) + { + if ( mCloseBoxOn ) coord -= BOX_T_BOX_GAP; + coord -= BTN_BOX_WIDTH; + + if ( is_in_box( wxPoint( coord, rect.y + mHintGap + boxOfs ), inPane ) ) + + return COLLAPSE_BOX_HITTED; + } + } + + return FALSE; +} + +// handlers for plugin-events + +void cbBarHintsPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event ) +{ + wxRect& rect = event.mBoundsInParent; + mpPane = event.mpPane; + + ExcludeHints( rect, *event.mpBar ); + + event.Skip(); // pass event to the next plugin in the chain +} + +void cbBarHintsPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event ) +{ + wxRect& rect = event.mBoundsInParent; + mpPane = event.mpPane; + + int boxOfs, grooveOfs, pos; + + GetHintsLayout( rect, *event.mpBar, boxOfs, grooveOfs, pos ); + + DoDrawHint( *event.mpDc, rect, pos, boxOfs, grooveOfs, event.mpBar->IsFixed() ); + + // let other plugins add on their decorations + + event.Skip(); +} + +void cbBarHintsPlugin::OnLeftDown( cbLeftDownEvent& event ) +{ + mpPane = event.mpPane; + + wxPoint inFrame = event.mPos; + mpPane->PaneToFrame( &inFrame.x, &inFrame.y ); + + wxBarIterator iter( mpPane->GetRowList() ); + + mpClickedBar = NULL; + + while ( iter.Next() ) + { + cbBarInfo& bar = iter.BarInfo(); + + int boxOfs, grooveOfs, pos; + + GetHintsLayout( bar.mBoundsInParent, bar, boxOfs, grooveOfs, pos ); + + if ( !bar.IsFixed() ) + { + int i; + for( i = 0; i != BOXES_IN_HINT; ++i ) + { + mBoxes[i]->OnLeftDown( inFrame ); + + if ( mBoxes[i]->mPressed ) + { + mBtnPressed = TRUE; + mpClickedBar = &bar; + + return; // event handled + } + } + } + } + + event.Skip(); +} + +void cbBarHintsPlugin::OnLeftUp( cbLeftUpEvent& event ) +{ + if ( mBtnPressed ) + { + wxPoint inFrame = event.mPos; + mpPane->PaneToFrame( &inFrame.x, &inFrame.y ); + + int boxOfs, grooveOfs, pos; + + GetHintsLayout( mpClickedBar->mBoundsInParent, *mpClickedBar, boxOfs, grooveOfs, pos ); + + int result = HitTestHints( *mpClickedBar, event.mPos ); + + int i; + for( i = 0; i != BOXES_IN_HINT; ++i ) + { + mBoxes[i]->OnLeftUp( inFrame ); + + if ( mBoxes[i]->WasClicked() ) + { + if ( i == 0 ) + + mpLayout->SetBarState( mpClickedBar, wxCBAR_HIDDEN, TRUE ); + else + { + if ( mpClickedBar->IsExpanded() ) + + mpPane->ContractBar( mpClickedBar ); + else + mpPane->ExpandBar( mpClickedBar ); + } + } + } + + mBtnPressed = FALSE; + return; + } + else + event.Skip(); +} + +void cbBarHintsPlugin::OnMotion( cbMotionEvent& event ) +{ + if ( mBtnPressed ) + { + wxPoint inFrame = event.mPos; + mpPane->PaneToFrame( &inFrame.x, &inFrame.y ); + + mpPane = event.mpPane; + + int i; + for( i = 0; i != BOXES_IN_HINT; ++i ) + + mBoxes[i]->OnMotion( inFrame ); + } + else + event.Skip(); +} + +void cbBarHintsPlugin::OnInitPlugin() +{ + cbPluginBase::OnInitPlugin(); + + cbDockPane** panes = mpLayout->GetPanesArray(); + + int i; + for( i = 0; i != MAX_PANES; ++i ) + { + if ( panes[i]->MatchesMask( mPaneMask ) ) + { + panes[i]->mProps.mMinCBarDim.x = 25; + panes[i]->mProps.mMinCBarDim.y = 16; + } + } + CreateBoxes(); +} diff --git a/contrib/src/fl/cbcustom.cpp b/contrib/src/fl/cbcustom.cpp new file mode 100644 index 0000000000..43f5683ff3 --- /dev/null +++ b/contrib/src/fl/cbcustom.cpp @@ -0,0 +1,202 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "cbcustom.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/cbcustom.h" + +// helper class to receive menu customization event + +class cbContextMenuHandler : public wxEvtHandler +{ +public: + cbSimpleCustomizationPlugin* mpBackRef; + +public: + void OnMenuCommand( wxCommandEvent& evt ); + + void OnCommandEvents( wxCommandEvent& evt ); + + DECLARE_EVENT_TABLE() +}; + +// FIXME:: is this "safe" ? + +#define CB_CUSTOMIZE_MENU_FIRST_ITEM_ID 17500 + +/***** Implementation for helper class cbContextMenuHandler *****/ + +BEGIN_EVENT_TABLE( cbContextMenuHandler, wxEvtHandler ) + + // FIXME:: what is the right range for these ids ? so that they + // would not collide with user commands? + + EVT_COMMAND_RANGE( CB_CUSTOMIZE_MENU_FIRST_ITEM_ID, + CB_CUSTOMIZE_MENU_FIRST_ITEM_ID + 300, + wxEVT_COMMAND_MENU_SELECTED, + cbContextMenuHandler::OnCommandEvents ) + +END_EVENT_TABLE() + +void cbContextMenuHandler::OnCommandEvents( wxCommandEvent& evt ) +{ + //wxMessageBox("Wowwwww, Yeah!"); + + mpBackRef->OnMenuItemSelected( evt ); +} + +/***** Implementation for class cbSimpleCustomizationPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbSimpleCustomizationPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbSimpleCustomizationPlugin, cbPluginBase ) + + EVT_PL_CUSTOMIZE_BAR ( cbSimpleCustomizationPlugin::OnCustomizeBar ) + EVT_PL_CUSTOMIZE_LAYOUT( cbSimpleCustomizationPlugin::OnCustomizeLayout ) + +END_EVENT_TABLE() + +cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin(void) +{} + +cbSimpleCustomizationPlugin::cbSimpleCustomizationPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ) +{} + +void cbSimpleCustomizationPlugin::OnCustomizeBar( cbCustomizeBarEvent& event ) +{ + // ingnore bar customization, treat it + // as layout-customization...ugly, eh? + + cbCustomizeLayoutEvent clEvt( event.mClickPos ); + + OnCustomizeLayout( clEvt ); +} + +void cbSimpleCustomizationPlugin::OnCustomizeLayout( cbCustomizeLayoutEvent& event ) +{ + wxString helpStr1 = "Select this item to show the corresponding control bar"; + wxString helpStr2 = "Select this itme to hide the corresponding control bar"; + + int id = CB_CUSTOMIZE_MENU_FIRST_ITEM_ID; + + wxMenu* pMenu = new wxMenu(); + + BarArrayT& bars = mpLayout->GetBars(); + + for( size_t i = 0; i != bars.GetCount(); ++i ) + { + cbBarInfo& bar = *bars[i]; + + bool isHidden = ( bar.mState == wxCBAR_HIDDEN ); + + wxString* pHelpStr = ( isHidden ) ? &helpStr1 : &helpStr2; + + pMenu->Append( id, bar.mName, *pHelpStr, TRUE ); + + pMenu->Check( id, (isHidden == FALSE) ); + + ++id; + } + + pMenu->AppendSeparator(); + pMenu->Append( id, "Customize...", "Show layout customization dialog", FALSE ); + mCustMenuItemId = id; + + cbContextMenuHandler* pHandler = new cbContextMenuHandler(); + pHandler->mpBackRef = this; + + wxWindow* pFrm = &mpLayout->GetParentFrame(); + + // FOR NOW FOR NOW:: to work-around wxFrame's (MSW) nasty event-handling bugs!!! + + wxWindow* pTmpWnd = new wxWindow( pFrm, -1, event.mClickPos, wxSize(0,0) ); + + pMenu->SetEventHandler( pHandler ); + + pTmpWnd->PopupMenu( pMenu, 0,0 ); + + pTmpWnd->Destroy(); + + delete pMenu; + delete pHandler; + + // event is "eaten" by this plugin +} + +void cbSimpleCustomizationPlugin::OnMenuItemSelected( wxCommandEvent& event ) +{ + if ( event.GetId() == mCustMenuItemId ) + { + wxMessageBox("Customization dialog box is not supported by this plugin yet"); + + return; + } + else + { + cbBarInfo* pBar = mpLayout->GetBars()[ event.GetId() - + CB_CUSTOMIZE_MENU_FIRST_ITEM_ID + ]; + + wxASSERT( pBar ); // DBG:: + + // "inverse" bar-visibility of the selected bar + + int newState = 0; + + if ( pBar->mState == wxCBAR_HIDDEN ) + { + if ( pBar->mAlignment == -1 ) + { + pBar->mAlignment = 0; // just remove "-1" marking + newState = wxCBAR_FLOATING; + } + else + if ( pBar->mAlignment == FL_ALIGN_TOP || + pBar->mAlignment == FL_ALIGN_BOTTOM ) + + newState = wxCBAR_DOCKED_HORIZONTALLY; + else + newState = wxCBAR_DOCKED_VERTICALLY; + } + else + { + newState = wxCBAR_HIDDEN; + + if ( pBar->mState == wxCBAR_FLOATING ) + + pBar->mAlignment = -1; + } + + mpLayout->SetBarState( pBar, newState, TRUE ); + + if ( newState == wxCBAR_FLOATING ) + + mpLayout->RepositionFloatedBar( pBar ); + } + + // menu-item-selected event is "eaten" +} + diff --git a/contrib/src/fl/controlbar.cpp b/contrib/src/fl/controlbar.cpp new file mode 100644 index 0000000000..6e87a6ed33 --- /dev/null +++ b/contrib/src/fl/controlbar.cpp @@ -0,0 +1,3524 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "controlbar.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include + +#include "wx/string.h" +#include "wx/utils.h" // import wxMin,wxMax macros +#include "wx/minifram.h" + +#include "wx/fl/controlbar.h" + +// import classes of default plugins + +#include "wx/fl/panedrawpl.h" +#include "wx/fl/rowlayoutpl.h" +#include "wx/fl/antiflickpl.h" +#include "wx/fl/bardragpl.h" +#include "wx/fl/cbcustom.h" + +#include "wx/fl/gcupdatesmgr.h" // import default updates manager class ("garbage-collecting" one) +#include "wx/fl/updatesmgr.h" + +#include "wx/fl/toolwnd.h" + +// These are the event IDs being initialized to a value to +// meet the new event paradigm as of wx2.3.0. Probably we +// should find a way to make these be non-global, but this +// works for right now. +#if wxCHECK_VERSION(2,3,0) + wxEventType cbEVT_PL_LEFT_DOWN = wxNewEventType(); + wxEventType cbEVT_PL_LEFT_UP = wxNewEventType(); + wxEventType cbEVT_PL_RIGHT_DOWN = wxNewEventType(); + wxEventType cbEVT_PL_RIGHT_UP = wxNewEventType(); + wxEventType cbEVT_PL_MOTION = wxNewEventType(); + + wxEventType cbEVT_PL_LEFT_DCLICK = wxNewEventType(); + + wxEventType cbEVT_PL_LAYOUT_ROW = wxNewEventType(); + wxEventType cbEVT_PL_RESIZE_ROW = wxNewEventType(); + wxEventType cbEVT_PL_LAYOUT_ROWS = wxNewEventType(); + wxEventType cbEVT_PL_INSERT_BAR = wxNewEventType(); + wxEventType cbEVT_PL_RESIZE_BAR = wxNewEventType(); + wxEventType cbEVT_PL_REMOVE_BAR = wxNewEventType(); + wxEventType cbEVT_PL_SIZE_BAR_WND = wxNewEventType(); + + wxEventType cbEVT_PL_DRAW_BAR_DECOR = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_ROW_DECOR = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_PANE_DECOR = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_BAR_HANDLES = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_ROW_HANDLES = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_ROW_BKGROUND = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_PANE_BKGROUND = wxNewEventType(); + + wxEventType cbEVT_PL_START_BAR_DRAGGING = wxNewEventType(); + wxEventType cbEVT_PL_DRAW_HINT_RECT = wxNewEventType(); + + wxEventType cbEVT_PL_START_DRAW_IN_AREA = wxNewEventType(); + wxEventType cbEVT_PL_FINISH_DRAW_IN_AREA = wxNewEventType(); + + wxEventType cbEVT_PL_CUSTOMIZE_BAR = wxNewEventType(); + wxEventType cbEVT_PL_CUSTOMIZE_LAYOUT = wxNewEventType(); + + wxEventType wxCUSTOM_CB_PLUGIN_EVENTS_START_AT = wxNewEventType(); +#endif // #if wxCHECK_VERSION(2,3,0) + +// some ascii-art, still can't get these *nice* cursors working on wx... :-( + +static const char* _gHorizCursorImg[] = +{ + "............XX....XX............", + "............XX....XX............", + "............XX....XX............", + "............XX....XX............", + "............XX....XX............", + "...X........XX....XX........X...", + "..XX........XX....XX........XX..", + ".XXX........XX....XX........XXX.", + "XXXXXXXXXXXXXX....XXXXXXXXXXXXXX", + ".XXX........XX....XX........XXX.", + "..XX........XX....XX........XX..", + "...X........XX....XX........X...", + "............XX....XX............", + "............XX....XX............", + "............XX....XX............", + "............XX....XX............" +}; + +static const char* _gVertCursorImg[] = +{ + "................X...............", + "...............XXX..............", + "..............XXXXX.............", + ".............XXXXXXX............", + "................X...............", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "................................", + "................................", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "................X...............", + ".............XXXXXXX............", + "..............XXXXX.............", + "...............XXX..............", + "................X..............." +}; + +// helper inline functions + +static inline bool rect_contains_point( const wxRect& rect, int x, int y ) +{ + return ( x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height ); +} + +static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 ) +{ + if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) || + ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) ) + + if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) || + ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) ) + + return 1; + + return 0; +} + +static inline void hide_rect( wxRect& r ) +{ + r.x = 32768; + r.y = 32768; + r.width = 1; + r.height = 1; +} + +static inline void clip_rect_against_rect( wxRect& r1, const wxRect& r2 ) +{ + if ( r1.x < r2.x || + r1.y < r2.y || + r1.x >= r2.x + r2.width || + r1.y >= r2.y + r2.height + ) + { + hide_rect( r1 ); + return; + } + else + { + if ( r1.x + r1.width > r2.x + r2.width ) + + r1.width = r2.x + r2.width - r1.x; + + if ( r1.y + r1.height > r2.y + r2.height ) + + r1.height = r2.y + r2.height - r1.y; + } +} + +/***** Implementation for class cbBarSpy *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbBarSpy, wxEvtHandler ) + +cbBarSpy::cbBarSpy(void) + : mpLayout(0), + mpBarWnd(0) +{} + +cbBarSpy::cbBarSpy( wxFrameLayout* pPanel ) + + : mpLayout(pPanel), + mpBarWnd(0) +{} + +void cbBarSpy::SetBarWindow( wxWindow* pWnd ) +{ + mpBarWnd = pWnd; +} + +bool cbBarSpy::ProcessEvent(wxEvent& event) +{ + bool handled = wxEvtHandler::ProcessEvent( event ); + + int type = event.GetEventType(); + + if ( !handled && ( type == wxEVT_LEFT_DOWN || + type == wxEVT_LEFT_DCLICK ) ) + { + wxMouseEvent& mevent = *((wxMouseEvent*)&event); + + int x = mevent.m_x; + int y = mevent.m_y; + + mpBarWnd->ClientToScreen( &x, &y ); + mpLayout->GetParentFrame().ScreenToClient( &x, &y ); + + mevent.m_x = x; + mevent.m_y = y; + + // forwared not-handled event to frame-layout + + if ( type == wxEVT_LEFT_DOWN ) + { + //mpLayout->OnLButtonDown( mevent ); + event.Skip(); + } + else + mpLayout->OnLDblClick( mevent ); + + //event.Skip(FALSE); + } + + return handled; +} + +/***** Implementation for class wxFrameLayout *****/ + +IMPLEMENT_DYNAMIC_CLASS( wxFrameLayout, wxEvtHandler ) + +BEGIN_EVENT_TABLE( wxFrameLayout, wxEvtHandler ) + + EVT_PAINT ( wxFrameLayout::OnPaint ) + EVT_SIZE ( wxFrameLayout::OnSize ) + EVT_LEFT_DOWN ( wxFrameLayout::OnLButtonDown ) + EVT_LEFT_UP ( wxFrameLayout::OnLButtonUp ) + EVT_RIGHT_DOWN ( wxFrameLayout::OnRButtonDown ) + EVT_RIGHT_UP ( wxFrameLayout::OnRButtonUp ) + EVT_MOTION ( wxFrameLayout::OnMouseMove ) + + EVT_LEFT_DCLICK( wxFrameLayout::OnLDblClick ) + + EVT_IDLE ( wxFrameLayout::OnIdle ) + EVT_SET_FOCUS ( wxFrameLayout::OnSetFocus ) + EVT_KILL_FOCUS ( wxFrameLayout::OnKillFocus ) + + EVT_ACTIVATE ( wxFrameLayout::OnActivate ) + + EVT_ERASE_BACKGROUND( wxFrameLayout::OnEraseBackground ) + +END_EVENT_TABLE() + +// FIXME:: how to eliminate these cut&pasted constructors? + +wxFrameLayout::wxFrameLayout(void) + + : mpFrame ( NULL ), + mpFrameClient( NULL ), + + mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ), + mLightPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ), + mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ), + mBorderPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + + mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ), + + mpPaneInFocus( NULL ), + mpLRUPane ( NULL ), + + + mpTopPlugin ( NULL ), + mpCaputesInput( NULL ), + + mClientWndRefreshPending( FALSE ), + mRecalcPending( TRUE ), + mCheckFocusWhenIdle( FALSE ) +{ + CreateCursors(); + + for( int i = 0; i != MAX_PANES; ++i ) + + mPanes[i] = NULL; + + mFloatingOn = CanReparent(); +} + +wxFrameLayout::wxFrameLayout( wxWindow* pParentFrame, wxWindow* pFrameClient, bool activateNow ) + + : mpFrame( pParentFrame ), + mpFrameClient(pFrameClient), + + mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ), + mLightPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHILIGHT), 1, wxSOLID ), + mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ), + mBorderPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + + mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ), + + mpPaneInFocus( NULL ), + mpLRUPane ( NULL ), + + mFloatingOn ( TRUE ), + + mpTopPlugin ( NULL ), + mpCaputesInput( NULL ), + + mClientWndRefreshPending( FALSE ), + mRecalcPending( TRUE ), + mCheckFocusWhenIdle( FALSE ), + + mpUpdatesMgr( NULL ) +{ + CreateCursors(); + + for( int i = 0; i != MAX_PANES; ++i ) + + mPanes[i] = new cbDockPane( i, this ); + + if ( activateNow ) + { + HookUpToFrame(); + + // FOR NOW:: + // DBG:: set RED color of frame's background for the + // prurpose of tracking engine bugs "visually" + + GetParentFrame().SetBackgroundColour( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ); + } + + mFloatingOn = CanReparent(); +} + +// NOTE:: below are the only plaftorm-check "ifdef"s in the docking system! + +bool wxFrameLayout::CanReparent() +{ +#ifdef __WXMSW__ + return TRUE; +#elif defined (__WXGTK__) + //return TRUE; + return FALSE; +#else + + return FALSE; // reparenting is not yet supported by Motif and others +#endif +} + +/* +#ifdef __WXMSW__ + #inlcude "windows.h" +#endif +*/ + +void wxFrameLayout::ReparentWindow( wxWindow* pChild, wxWindow* pNewParent ) +{ +#ifdef __WXMSW__ +#if 0 + + if ( pChild->GetParent() ) + { + bool success = pChild->GetParent()->GetChildren().DeleteObject( pChild ); + + wxASSERT( success ); // DBG:: + } + + ::SetParent( (HWND)pChild->m_hWnd, (HWND)pNewParent->m_hWnd ); + + pNewParent->GetChildren().Append( pChild ); + + pChild->SetParent( pNewParent ); +#endif + pChild->Reparent(pNewParent); + + return; +#elif defined(__WXGTK__) + // FOR NOW:: floating with wxGtk still very buggy + + return; + + //pChild->ReParent( pNewParent ); + + //return; +#else + wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" ); +#endif +} + +void wxFrameLayout::DestroyBarWindows() +{ + wxNode* pSpy = mBarSpyList.First(); + + while( pSpy ) + { + cbBarSpy& spy = *((cbBarSpy*)pSpy->Data()); + + if ( spy.mpBarWnd->GetEventHandler() == &spy ) + + spy.mpBarWnd->PopEventHandler(); + + delete &spy; + + pSpy = pSpy->Next(); + } + + mBarSpyList.Clear(); + + for( size_t i = 0; i != mAllBars.Count(); ++i ) + { + if ( mAllBars[i]->mpBarWnd ) + { + mAllBars[i]->mpBarWnd->Destroy(); + mAllBars[i]->mpBarWnd = NULL; + } + } +} + +void wxFrameLayout::ShowFloatedWindows( bool show ) +{ + wxNode* pNode = mFloatedFrames.First(); + + while( pNode ) + { + cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data()); + + pFFrm->Show( show ); + + pNode = pNode->Next(); + } +} + +wxFrameLayout::~wxFrameLayout() +{ + UnhookFromFrame(); + + if ( mpUpdatesMgr ) + delete mpUpdatesMgr; + + PopAllPlugins(); + + // destoy the chain of plugins from left to right + + wxEvtHandler* pCur = mpTopPlugin; + + if ( pCur ) + + while ( pCur->GetPreviousHandler() ) + + pCur = pCur->GetPreviousHandler(); + + while ( pCur ) + { + wxEvtHandler* pNext = pCur->GetNextHandler(); + + delete pCur; + + pCur = pNext; + } + + // destroy contents of arrays and lists + + size_t i = 0; + + for( i = 0; i != MAX_PANES; ++i ) + { + if ( mPanes[i] ) + delete mPanes[i]; + } + if ( mpHorizCursor ) + delete mpHorizCursor; + if ( mpVertCursor ) + delete mpVertCursor; + if ( mpNormalCursor ) + delete mpNormalCursor; + if ( mpDragCursor ) + delete mpDragCursor; + if ( mpNECursor ) + delete mpNECursor; + + wxNode* pSpy = mBarSpyList.First(); + + while( pSpy ) + { + cbBarSpy& spy = *((cbBarSpy*)pSpy->Data()); + + if ( spy.mpBarWnd->GetEventHandler() == &spy ) + + spy.mpBarWnd->PopEventHandler(); + + delete &spy; + + pSpy = pSpy->Next(); + } + + for( i = 0; i != mAllBars.Count(); ++i ) + + delete mAllBars[i]; +} + +void wxFrameLayout::EnableFloating( bool enable ) +{ + mFloatingOn = enable && CanReparent(); +} + +void wxFrameLayout::Activate() +{ + HookUpToFrame(); + + RefreshNow( TRUE ); + + ShowFloatedWindows( TRUE ); +} + +void wxFrameLayout::Deactivate() +{ + ShowFloatedWindows( FALSE ); + + UnhookFromFrame(); + + HideBarWindows(); +} + +void wxFrameLayout::SetFrameClient( wxWindow* pFrameClient ) +{ + mpFrameClient = pFrameClient; +} + +wxWindow* wxFrameLayout::GetFrameClient() +{ + return mpFrameClient; +} + +cbUpdatesManagerBase& wxFrameLayout::GetUpdatesManager() +{ + if ( !mpUpdatesMgr ) + mpUpdatesMgr = CreateUpdatesManager(); + + return *mpUpdatesMgr; +} + +void wxFrameLayout::SetUpdatesManager( cbUpdatesManagerBase* pUMgr ) +{ + if ( mpUpdatesMgr ) + delete mpUpdatesMgr; + + mpUpdatesMgr = pUMgr; + + mpUpdatesMgr->SetLayout( this ); +} + +cbUpdatesManagerBase* wxFrameLayout::CreateUpdatesManager() +{ + return new cbGCUpdatesMgr( this ); + //return new cbSimpleUpdatesMgr( this ); +} + +void wxFrameLayout::AddBar( wxWindow* pBarWnd, + const cbDimInfo& dimInfo, + int alignment, + int rowNo, + int columnPos, + const wxString& name, + bool spyEvents, + int state + ) +{ + if ( pBarWnd && spyEvents ) + { + // hook up spy to bar window + cbBarSpy* pSpy = new cbBarSpy( this ); + + pSpy->SetBarWindow( pBarWnd ); + pBarWnd->PushEventHandler( pSpy ); + + mBarSpyList.Append( pSpy ); + } + + cbBarInfo* pInfo = new cbBarInfo(); + + pInfo->mName = name; + pInfo->mpBarWnd = pBarWnd; + pInfo->mDimInfo = dimInfo; + pInfo->mState = state; + pInfo->mAlignment = alignment; + pInfo->mRowNo = rowNo; + pInfo->mBounds.x = columnPos; + + mAllBars.Add( pInfo ); + + DoSetBarState( pInfo ); +} + +bool wxFrameLayout::RedockBar( cbBarInfo* pBar, + const wxRect& shapeInParent, + cbDockPane* pToPane, + bool updateNow ) +{ + if ( !pToPane ) + + pToPane = HitTestPanes( shapeInParent, NULL ); + + if ( !pToPane ) + + return FALSE; // bar's shape does not hit any pane + // - redocking is NOT possible + + cbDockPane* pBarPane = GetBarPane( pBar ); + + if ( updateNow ) + + GetUpdatesManager().OnStartChanges(); + + pBarPane->RemoveBar( pBar ); + + // FIXME FIXME:: the below recalc. may be a *huge* performance + // hit, it could be eliminated though... + // but first the "pane-postion-changed" problem + // have to be fixed + + RecalcLayout( FALSE ); + + pToPane->InsertBar( pBar, shapeInParent ); + + RecalcLayout( FALSE ); + + // finish update "transaction" + + if ( updateNow ) + { + GetUpdatesManager().OnFinishChanges(); + GetUpdatesManager().UpdateNow(); + } + + return TRUE; +} + +cbBarInfo* wxFrameLayout::FindBarByName( const wxString& name ) +{ + for( size_t i = 0; i != mAllBars.Count(); ++i ) + + if ( mAllBars[i]->mName == name ) + + return mAllBars[i]; + + return NULL; +} + +cbBarInfo* wxFrameLayout::FindBarByWindow( const wxWindow* pWnd ) +{ + for( size_t i = 0; i != mAllBars.Count(); ++i ) + + if ( mAllBars[i]->mpBarWnd == pWnd ) + + return mAllBars[i]; + + return NULL; +} + +BarArrayT& wxFrameLayout::GetBars() +{ + return mAllBars; +} + +void wxFrameLayout::SetBarState( cbBarInfo* pBar, int newState, bool updateNow ) +{ + if ( newState == wxCBAR_FLOATING && !mFloatingOn ) + + return; + + if ( updateNow ) + + GetUpdatesManager().OnStartChanges(); + + pBar->mUMgrData.SetDirty(TRUE); + + // check bar's previous state + + if ( pBar->mState != wxCBAR_HIDDEN && pBar->mState != wxCBAR_FLOATING ) + { + cbDockPane* pPane; + cbRowInfo* pRow; + + bool success = LocateBar( pBar, &pRow, &pPane ); + + wxASSERT( success ); // DBG:: + + // save LRU-dim info before removing bar + + pBar->mDimInfo.mLRUPane = pPane->GetAlignment(); + pBar->mDimInfo.mBounds[ pPane->GetAlignment() ] = pBar->mBounds; + + // remove it from the pane it was docked on + + pPane->RemoveBar( pBar ); + + } + + if ( pBar->mState == wxCBAR_FLOATING && newState != wxCBAR_FLOATING ) + { + // remove bar's window form the containing mini-frame + // and set it's parent to be layout's parent frame + + if ( pBar->mpBarWnd ) + { + pBar->mpBarWnd->Show(FALSE); // to avoid flicker upon reparenting + + wxNode* pNode = mFloatedFrames.First(); + + while( pNode ) + { + cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data()); + + if ( pFFrm->GetBar() == pBar ) + { + pFFrm->Show( FALSE ); // reduces flicker sligthly + + ReparentWindow( pBar->mpBarWnd, &GetParentFrame() ); + + pBar->mBounds = pBar->mDimInfo.mBounds[ pBar->mDimInfo.mLRUPane ]; + + if ( newState != wxCBAR_HIDDEN ) + + pBar->mAlignment = pBar->mDimInfo.mLRUPane; + + mFloatedFrames.DeleteNode( pNode ); + + pFFrm->Show( FALSE ); + pFFrm->Destroy(); break; + } + + pNode = pNode->Next(); + } + + // FOR NOW:: excessive! + //if ( mpFrameClient ) mpFrameClient->Refresh(); + if ( mpFrameClient ) + mClientWndRefreshPending = TRUE; + } + } + + pBar->mState = newState; + + DoSetBarState( pBar ); + + if ( updateNow ) + { + RecalcLayout(FALSE); + + GetUpdatesManager().OnFinishChanges(); + GetUpdatesManager().UpdateNow(); + } +} + +void wxFrameLayout::InverseVisibility( cbBarInfo* pBar ) +{ + wxASSERT( pBar ); // DBG:: + + // "inverse" bar-visibility of the selected bar + + int newState = 0; + + if ( pBar->mState == wxCBAR_HIDDEN ) + { + if ( pBar->mAlignment == -1 ) + { + pBar->mAlignment = 0; // just remove "-1" marking + newState = wxCBAR_FLOATING; + } + else + if ( pBar->mAlignment == FL_ALIGN_TOP || + pBar->mAlignment == FL_ALIGN_BOTTOM ) + + newState = wxCBAR_DOCKED_HORIZONTALLY; + else + newState = wxCBAR_DOCKED_VERTICALLY; + } + else + { + newState = wxCBAR_HIDDEN; + + if ( pBar->mState == wxCBAR_FLOATING ) + + pBar->mAlignment = -1; + } + + this->SetBarState( pBar, newState, TRUE ); + + if ( newState == wxCBAR_FLOATING ) + + this->RepositionFloatedBar( pBar ); +} + +void wxFrameLayout::ApplyBarProperties( cbBarInfo* pBar ) +{ + if ( pBar->mState == wxCBAR_FLOATING ) + { + RepositionFloatedBar( pBar ); + } + else + if ( pBar->mState == wxCBAR_DOCKED_HORIZONTALLY || + pBar->mState == wxCBAR_DOCKED_VERTICALLY + ) + { + // FOR NOW:: nothing + } + +} + +void wxFrameLayout::RepositionFloatedBar( cbBarInfo* pBar ) +{ + if ( !mFloatingOn ) return; + + wxNode* pNode = mFloatedFrames.First(); + + while( pNode ) + { + cbFloatedBarWindow* pFFrm = ((cbFloatedBarWindow*)pNode->Data()); + + if ( pFFrm->GetBar() == pBar ) + { + wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING]; + + int x = bounds.x, + y = bounds.y; + + GetParentFrame().ClientToScreen( &x, &y ); + + pFFrm->PositionFloatedWnd( x,y, + bounds.width, + bounds.height ); + + break; + } + + pNode = pNode->Next(); + } +} + +void wxFrameLayout::DoSetBarState( cbBarInfo* pBar ) +{ + if ( pBar->mState != wxCBAR_FLOATING && + pBar->mState != wxCBAR_HIDDEN ) + + // dock it + + mPanes[pBar->mAlignment]->InsertBar( pBar ); + else + if ( pBar->mState == wxCBAR_HIDDEN ) + { + // hide it + + if ( pBar->mpBarWnd ) + + pBar->mpBarWnd->Show( FALSE ); + } + else + { + if ( !mFloatingOn ) return; + + // float it + + if ( pBar->mpBarWnd == NULL || !CanReparent() ) + { + // FOR NOW:: just hide it + + if ( pBar->mpBarWnd ) + + pBar->mpBarWnd->Show( FALSE ); + + pBar->mState = wxCBAR_HIDDEN; + + return; + } + + cbFloatedBarWindow* pMiniFrm = new cbFloatedBarWindow(); + + pMiniFrm->SetBar( pBar ); + pMiniFrm->SetLayout( this ); + + pMiniFrm->Create( &GetParentFrame(), -1, pBar->mName, + wxPoint( 50,50 ), + wxSize ( 0, 0 ), + wxFRAME_FLOAT_ON_PARENT | wxFRAME_TOOL_WINDOW + ); + + pMiniFrm->SetClient( pBar->mpBarWnd ); + + ReparentWindow( pBar->mpBarWnd, pMiniFrm ); + + mFloatedFrames.Append( pMiniFrm ); + + wxRect& bounds = pBar->mDimInfo.mBounds[wxCBAR_FLOATING]; + + // check if it wasn't floated anytime before + + if ( bounds.width == -1 ) + { + wxRect& clntRect = GetClientRect(); + + // adjust position into which the next floated bar will be placed + + if ( mNextFloatedWndPos.x + bounds.width > clntRect.width ) + + mNextFloatedWndPos.x = mFloatingPosStep.x; + + if ( mNextFloatedWndPos.y + bounds.height > clntRect.height ) + + mNextFloatedWndPos.y = mFloatingPosStep.y; + + bounds.x = mNextFloatedWndPos.x + clntRect.x; + bounds.y = mNextFloatedWndPos.y + clntRect.y; + + bounds.width = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].x; + bounds.height = pBar->mDimInfo.mSizes[wxCBAR_FLOATING].y; + + mNextFloatedWndPos.x += mFloatingPosStep.x; + mNextFloatedWndPos.y += mFloatingPosStep.y; + } + + pMiniFrm->Show( TRUE ); + + // FIXME:: this is excessive + pBar->mpBarWnd->Show(TRUE); + } +} + +void wxFrameLayout::RemoveBar( cbBarInfo* pBarInfo ) +{ + // first, try to "guess" what was the perviouse state of the bar + + cbDockPane* pPane; + cbRowInfo* pRow; + + if ( LocateBar( pBarInfo, &pRow, &pPane ) ) + { + // ...aha, bar was docked into one of the panes, + // remove it from there + + pPane->RemoveBar( pBarInfo ); + } + + for( size_t i = 0; i != mAllBars.Count(); ++i ) + { + if ( mAllBars[i] == pBarInfo ) + { +#if wxCHECK_VERSION(2,3,2) + mAllBars.RemoveAt(i); +#else + mAllBars.Remove(i); +#endif + if ( pBarInfo->mpBarWnd ) // hides it's window + + pBarInfo->mpBarWnd->Show( FALSE ); + + delete pBarInfo; + + return; + } + } + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: bar info should be present in the list of all bars of all panes + +} + +bool wxFrameLayout::LocateBar( cbBarInfo* pBarInfo, + cbRowInfo** ppRow, + cbDockPane** ppPane ) +{ + (*ppRow) = NULL; + (*ppPane) = NULL; + + for( int n = 0; n != MAX_PANES; ++n ) + { + wxBarIterator i( mPanes[n]->GetRowList() ); + + while( i.Next() ) + + if ( &i.BarInfo() == pBarInfo ) + { + (*ppPane) = mPanes[n]; + (*ppRow ) = &i.RowInfo(); + + return TRUE; + } + } + + return FALSE; +} + +void wxFrameLayout::RecalcLayout( bool repositionBarsNow ) +{ + mRecalcPending = FALSE; + + int frmWidth, frmHeight; + mpFrame->GetClientSize( &frmWidth, &frmHeight ); + int paneHeight = 0; + + int curY = 0; + int curX = 0; + wxRect rect; + + // pane positioning priorities in decreasing order: + // top, bottom, left, right + + // setup TOP pane + + cbDockPane* pPane = mPanes[ FL_ALIGN_TOP ]; + + pPane->SetPaneWidth( frmWidth ); + pPane->RecalcLayout(); + + paneHeight = pPane->GetPaneHeight(); + + rect.x = curX; + rect.y = curY; + rect.width = frmWidth; + rect.height = wxMin( paneHeight, frmHeight - curY ); + + pPane->SetBoundsInParent( rect ); + + curY += paneHeight; + + // setup BOTTOM pane + + pPane = mPanes[ FL_ALIGN_BOTTOM ]; + + pPane->SetPaneWidth( frmWidth ); + pPane->RecalcLayout(); + + paneHeight = pPane->GetPaneHeight(); + + rect.x = curX; + rect.y = wxMax( frmHeight - paneHeight, curY ); + rect.width = frmWidth; + rect.height = frmHeight - rect.y; + + pPane->SetBoundsInParent( rect ); + + // setup LEFT pane + + pPane = mPanes[ FL_ALIGN_LEFT ]; + + // bottom pane's y + pPane->SetPaneWidth( rect.y - curY ); + + pPane->RecalcLayout(); + paneHeight = pPane->GetPaneHeight(); + + // bottom rect's y + rect.height = rect.y - curY; + rect.x = curX; + rect.y = curY; + rect.width = wxMin( paneHeight, frmWidth ); + + pPane->SetBoundsInParent( rect ); + + curX += rect.width; + + // setup RIGHT pane + + pPane = mPanes[ FL_ALIGN_RIGHT ]; + + // left pane's height + pPane->SetPaneWidth( rect.height ); + + pPane->RecalcLayout(); + paneHeight = pPane->GetPaneHeight(); + + // left pane's height + rect.height = rect.height; + rect.x = wxMax( frmWidth - paneHeight, curX ); + rect.y = curY; + rect.width = frmWidth - rect.x; + + pPane->SetBoundsInParent( rect ); + + // recalc bounds of the client-window + + mClntWndBounds.x = mPanes[FL_ALIGN_LEFT]->mBoundsInParent.x + + mPanes[FL_ALIGN_LEFT]->mBoundsInParent.width; + mClntWndBounds.y = mPanes[FL_ALIGN_TOP ]->mBoundsInParent.y + + mPanes[FL_ALIGN_TOP ]->mBoundsInParent.height; + + mClntWndBounds.width = mPanes[FL_ALIGN_RIGHT]->mBoundsInParent.x - + mClntWndBounds.x; + mClntWndBounds.height = mPanes[FL_ALIGN_BOTTOM]->mBoundsInParent.y - + mClntWndBounds.y; + + if ( repositionBarsNow ) + + PositionPanes(); +} + +int wxFrameLayout::GetClientHeight() +{ + // for better portablility wxWindow::GetSzie() is not used here + + return mClntWndBounds.height; +} + +int wxFrameLayout::GetClientWidth() +{ + // for better portablility wxWindow::GetSzie() is not used here + + return mClntWndBounds.width; +} + +void wxFrameLayout::PositionClientWindow() +{ + if ( mpFrameClient ) + { + if ( mClntWndBounds.width >= 1 && mClntWndBounds.height >= 1 ) + { + mpFrameClient->SetSize( mClntWndBounds.x, mClntWndBounds.y, + mClntWndBounds.width, mClntWndBounds.height, 0 ); + + if ( !mpFrameClient->IsShown() ) + + mpFrameClient->Show( TRUE ); + } + else + mpFrameClient->Show( FALSE ); + } +} + +void wxFrameLayout::PositionPanes() +{ + PositionClientWindow(); + + // FOR NOW:: excessive updates! + // reposition bars within all panes + + for( int i = 0; i != MAX_PANES; ++i ) + + mPanes[i]->SizePaneObjects(); +} + +void wxFrameLayout::OnSize( wxSizeEvent& event ) +{ + if ( event.GetEventObject() == (wxObject*) mpFrame ) + + RecalcLayout(TRUE); +} + +/*** protected members ***/ + +void wxFrameLayout::HideBarWindows() +{ + for( size_t i = 0; i != mAllBars.Count(); ++i ) + + if ( mAllBars[i]->mpBarWnd && mAllBars[i]->mState != wxCBAR_FLOATING ) + + mAllBars[i]->mpBarWnd->Show( FALSE ); + + // then floated frames + + ShowFloatedWindows( FALSE ); + + if ( mpFrameClient ) + + mpFrameClient->Show( FALSE ); +} + +void wxFrameLayout::UnhookFromFrame() +{ + // NOTE:: the SetEvtHandlerEnabled() method is not used + // here, since it is assumed, that unhooking layout + // from window may result destroying of the layout itself + // + // BUG BUG BUG (wx):: this would not be a problem if + // wxEvtHandler's destructor would check if + // this handler is currently the top-most + // handler of some window, and additionally + // to the reconnecting itself from the chain + // it would also re-setup current event handler + // of the window using wxWindow::SetEventHandler() + + // FOR NOW:: + + if ( mpFrame->GetEventHandler() == this ) + + mpFrame->PopEventHandler(); + + return; + + // TBD ???: Cannot reach this code + if ( mpFrame ) + { + if ( this == mpFrame->GetEventHandler() ) + + mpFrame->SetEventHandler( this->GetNextHandler() ); + else + { + wxEvtHandler* pCur = mpFrame->GetEventHandler(); + + while( pCur ) + { + if ( pCur == this ) break; + + pCur = pCur->GetNextHandler(); + } + + // do not try to unhook ourselves if we're not hooked yet + if ( !pCur ) return; + } + + if ( GetPreviousHandler() ) + + GetPreviousHandler()->SetNextHandler( GetNextHandler() ); + else + { + mpFrame->PopEventHandler(); + return; + } + + + if ( GetNextHandler() ) + + GetNextHandler()->SetPreviousHandler( GetPreviousHandler() ); + + SetNextHandler( NULL ); + SetPreviousHandler( NULL ); + } +} + +void wxFrameLayout::HookUpToFrame() +{ + // unhook us first, we're already hooked up + + UnhookFromFrame(); + + // put ourselves on top + + mpFrame->PushEventHandler( this ); +} + +cbDockPane* wxFrameLayout::GetBarPane( cbBarInfo* pBar ) +{ + for( int i = 0; i != MAX_PANES; ++i ) + + if ( mPanes[i]->BarPresent( pBar ) ) return mPanes[i]; + + return NULL; +} + +void wxFrameLayout::CreateCursors() +{ + /* + // FIXME:: The below code somehow doesn't work - cursors remain unchanged + char bits[64]; + + set_cursor_bits( _gHorizCursorImg, bits, 32, 16 ); + + mpHorizCursor = new wxCursor( bits, 32, 16 ); + + set_cursor_bits( _gVertCursorImg, bits, 32, 16 ); + + mpVertCursor = new wxCursor( bits, 32, 16 ); + */ + + // FOR NOW:: use standard ones + + mpHorizCursor = new wxCursor(wxCURSOR_SIZEWE); + mpVertCursor = new wxCursor(wxCURSOR_SIZENS); + mpNormalCursor = new wxCursor(wxCURSOR_ARROW ); + mpDragCursor = new wxCursor(wxCURSOR_CROSS ); + mpNECursor = new wxCursor(wxCURSOR_NO_ENTRY); + + mFloatingPosStep.x = 25; + mFloatingPosStep.y = 25; + + mNextFloatedWndPos.x = mFloatingPosStep.x; + mNextFloatedWndPos.y = mFloatingPosStep.y; +} + +bool wxFrameLayout::HitTestPane( cbDockPane* pPane, int x, int y ) +{ + return rect_contains_point( pPane->GetRealRect(), x, y ); +} + +cbDockPane* wxFrameLayout::HitTestPanes( const wxRect& rect, + cbDockPane* pCurPane ) +{ + // first, give the privilege to the current pane + + if ( pCurPane && rect_hits_rect( pCurPane->GetRealRect(), rect ) ) + + return pCurPane; + + for( int i = 0; i != MAX_PANES; ++i ) + + if ( pCurPane != mPanes[i] && + rect_hits_rect( mPanes[i]->GetRealRect(), rect ) ) + + return mPanes[i]; + + return 0; +} + +void wxFrameLayout::ForwardMouseEvent( wxMouseEvent& event, + cbDockPane* pToPane, + int eventType ) +{ + wxPoint pos( event.m_x, event.m_y ); + pToPane->FrameToPane( &pos.x, &pos.y ); + +#if wxCHECK_VERSION(2,3,0) + if ( eventType == cbEVT_PL_LEFT_DOWN ) + { + cbLeftDownEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else if ( eventType == cbEVT_PL_LEFT_DCLICK ) + { + cbLeftDClickEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else if ( eventType == cbEVT_PL_LEFT_UP ) + { + cbLeftUpEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else if ( eventType == cbEVT_PL_RIGHT_DOWN ) + { + cbRightDownEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else if ( eventType == cbEVT_PL_RIGHT_UP ) + { + cbRightUpEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else if ( eventType == cbEVT_PL_MOTION ) + { + cbMotionEvent evt( pos, pToPane ); + FirePluginEvent( evt ); + } + else + { + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: + } +#else + switch ( eventType ) + { + case cbEVT_PL_LEFT_DOWN : { cbLeftDownEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + case cbEVT_PL_LEFT_DCLICK:{ cbLeftDClickEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + case cbEVT_PL_LEFT_UP : { cbLeftUpEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + case cbEVT_PL_RIGHT_DOWN: { cbRightDownEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + case cbEVT_PL_RIGHT_UP : { cbRightUpEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + case cbEVT_PL_MOTION : { cbMotionEvent evt( pos, pToPane ); + FirePluginEvent( evt ); break; + } + + default : wxASSERT(0); // DBG:: + } +#endif // #if wxCHECK_VERSION(2,3,0) +} // wxFrameLayout::ForwardMouseEvent() + + +void wxFrameLayout::RouteMouseEvent( wxMouseEvent& event, int pluginEvtType ) +{ + if ( mpPaneInFocus ) + + ForwardMouseEvent( event, mpPaneInFocus, pluginEvtType ); + else + for( int i = 0; i != MAX_PANES; ++i ) + + if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) ) + { + ForwardMouseEvent( event, mPanes[i], pluginEvtType ); + + return; + } +} + +/*** event handlers ***/ + +void wxFrameLayout::OnRButtonDown( wxMouseEvent& event ) +{ + RouteMouseEvent( event, cbEVT_PL_RIGHT_DOWN ); +} + +void wxFrameLayout::OnRButtonUp( wxMouseEvent& event ) +{ + RouteMouseEvent( event, cbEVT_PL_RIGHT_UP ); +} + +void wxFrameLayout::OnLButtonDown( wxMouseEvent& event ) +{ + RouteMouseEvent( event, cbEVT_PL_LEFT_DOWN ); +} + +void wxFrameLayout::OnLDblClick( wxMouseEvent& event ) +{ + RouteMouseEvent( event, cbEVT_PL_LEFT_DCLICK ); +} + +void wxFrameLayout::OnLButtonUp( wxMouseEvent& event ) +{ + RouteMouseEvent( event, cbEVT_PL_LEFT_UP ); +} + +void wxFrameLayout::OnMouseMove( wxMouseEvent& event ) +{ + if ( mpPaneInFocus ) + + ForwardMouseEvent( event, mpPaneInFocus, cbEVT_PL_MOTION ); + else + for( int i = 0; i != MAX_PANES; ++i ) + + if ( HitTestPane( mPanes[i], event.m_x, event.m_y ) ) + { + if ( mpLRUPane && mpLRUPane != mPanes[i] ) + { + // simulate "mouse-leave" event + ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION ); + } + + ForwardMouseEvent( event, mPanes[i], cbEVT_PL_MOTION ); + + mpLRUPane = mPanes[i]; + + return; + } + + if ( mpLRUPane ) + { + // simulate "mouse-leave" event + ForwardMouseEvent( event, mpLRUPane, cbEVT_PL_MOTION ); + mpLRUPane = 0; + } +} + +void wxFrameLayout::OnPaint( wxPaintEvent& event ) +{ + if ( mRecalcPending ) + + RecalcLayout( TRUE ); + + wxPaintDC dc(mpFrame); + + for( int i = 0; i != MAX_PANES; ++i ) + { + wxRect& rect = mPanes[i]->mBoundsInParent; + + dc.SetClippingRegion( rect.x, rect.y, rect.width, rect.height ); + + mPanes[i]->PaintPane(dc); + + dc.DestroyClippingRegion(); + } + + event.Skip(); +} + +void wxFrameLayout::OnEraseBackground( wxEraseEvent& event ) +{ + // do nothing +} + +void wxFrameLayout::OnIdle( wxIdleEvent& event ) +{ + wxWindow* focus = wxWindow::FindFocus(); + + if ( !focus && mCheckFocusWhenIdle ) + { + wxMessageBox( "Hi, no more focus in this app!" ); + + mCheckFocusWhenIdle = FALSE; + //ShowFloatedWindows( FALSE ); + } + + mCheckFocusWhenIdle = FALSE; + + event.Skip(); +} + + +void wxFrameLayout::OnKillFocus( wxFocusEvent& event ) +{ + //wxMessageBox( "wxFrameLayoutGot Kill Focus!" ); + //ShowFloatedWindows( FALSE ); +} + +void wxFrameLayout::OnSetFocus( wxFocusEvent& event ) +{ + //ShowFloatedWindows( TRUE ); +} + +void wxFrameLayout::OnActivate( wxActivateEvent& event ) +{ +#if 0 + if ( event.GetActive() == FALSE ) + { + wxWindow* focus = wxWindow::FindFocus(); + + if ( !focus || focus == &GetParentFrame() ) + { + mCheckFocusWhenIdle = TRUE; + + if ( !focus ) + + wxMessageBox("Deactivated!" ); + + } + } +#endif +} + +void wxFrameLayout::GetPaneProperties( cbCommonPaneProperties& props, int alignment ) +{ + props = mPanes[alignment]->mProps; +} + +void wxFrameLayout::SetPaneProperties( const cbCommonPaneProperties& props, int paneMask ) +{ + for( int i = 0; i != MAX_PANES; ++i ) + + if ( mPanes[i]->MatchesMask( paneMask ) ) + + mPanes[i]->mProps = props; +} + +void wxFrameLayout::SetMargins( int top, int bottom, int left, int right, + int paneMask ) +{ + for( int i = 0; i != MAX_PANES; ++i ) + { + cbDockPane& pane = *mPanes[i]; + + if ( pane.MatchesMask( paneMask ) ) + { + pane.mTopMargin = top; + pane.mBottomMargin = bottom; + pane.mLeftMargin = left; + pane.mRightMargin = right; + } + } +} + +void wxFrameLayout::SetPaneBackground( const wxColour& colour ) +{ + mBorderPen.SetColour( colour ); +} + +void wxFrameLayout::RefreshNow( bool recalcLayout ) +{ + if ( recalcLayout ) RecalcLayout( TRUE ); + + if ( mpFrame ) mpFrame->Refresh(); +} + +/*** plugin-related methods ***/ + +void wxFrameLayout::FirePluginEvent( cbPluginEvent& event ) +{ + // check state of input capture, before processing the event + + if ( mpCaputesInput ) + { + bool isInputEvt = TRUE; +#if wxCHECK_VERSION(2,3,0) + if ( event.m_eventType != cbEVT_PL_LEFT_DOWN && + event.m_eventType != cbEVT_PL_LEFT_UP && + event.m_eventType != cbEVT_PL_RIGHT_DOWN && + event.m_eventType != cbEVT_PL_RIGHT_UP && + event.m_eventType != cbEVT_PL_MOTION ) + isInputEvt = FALSE; +#else + switch ( event.m_eventType ) + { + case cbEVT_PL_LEFT_DOWN : break; + case cbEVT_PL_LEFT_UP : break; + case cbEVT_PL_RIGHT_DOWN : break; + case cbEVT_PL_RIGHT_UP : break; + case cbEVT_PL_MOTION : break; + + default : isInputEvt = FALSE; break; + } +#endif // #if wxCHECK_VERSION(2,3,0) + + if ( isInputEvt ) + { + mpCaputesInput->ProcessEvent( event ); + return; + } + } + + GetTopPlugin().ProcessEvent( event ); +} + +void wxFrameLayout::CaptureEventsForPlugin ( cbPluginBase* pPlugin ) +{ + // cannot capture events for more than one plugin at a time + wxASSERT( mpCaputesInput == NULL ); + + mpCaputesInput = pPlugin; + +} + +void wxFrameLayout::ReleaseEventsFromPlugin( cbPluginBase* pPlugin ) +{ + // events should be captured first + wxASSERT( mpCaputesInput != NULL ); + + mpCaputesInput = NULL; +} + +void wxFrameLayout::CaptureEventsForPane( cbDockPane* toPane ) +{ + // cannot capture events twice (without releasing) + wxASSERT( mpPaneInFocus == NULL ); + + mpFrame->CaptureMouse(); + + mpPaneInFocus = toPane; +} + +void wxFrameLayout::ReleaseEventsFromPane( cbDockPane* fromPane ) +{ + // cannot release events without capturing them + wxASSERT( mpPaneInFocus != NULL ); + + mpFrame->ReleaseMouse(); + + mpPaneInFocus = NULL; +} + +cbPluginBase& wxFrameLayout::GetTopPlugin() +{ + if ( !mpTopPlugin ) + + PushDefaultPlugins(); // automatic configuration + + return *mpTopPlugin; +} + +void wxFrameLayout::SetTopPlugin( cbPluginBase* pPlugin ) +{ + mpTopPlugin = pPlugin; +} + +bool wxFrameLayout::HasTopPlugin() +{ + return ( mpTopPlugin != NULL ); +} + +void wxFrameLayout::PushPlugin( cbPluginBase* pPlugin ) +{ + if ( !mpTopPlugin ) + + mpTopPlugin = pPlugin; + else + { + pPlugin->SetNextHandler( mpTopPlugin ); + + mpTopPlugin->SetPreviousHandler( pPlugin ); + + mpTopPlugin = pPlugin; + } + + mpTopPlugin->OnInitPlugin(); // notification +} + +void wxFrameLayout::PopPlugin() +{ + wxASSERT( mpTopPlugin ); // DBG:: at least one plugin should be present + + cbPluginBase* pPopped = mpTopPlugin; + + mpTopPlugin = (cbPluginBase*)mpTopPlugin->GetNextHandler(); + + delete pPopped; +} + +void wxFrameLayout::PopAllPlugins() +{ + while( mpTopPlugin ) PopPlugin(); +} + +void wxFrameLayout::PushDefaultPlugins() +{ + // FIXME:: to much of the stuff for the default... + + AddPlugin( CLASSINFO( cbRowLayoutPlugin ) ); + AddPlugin( CLASSINFO( cbBarDragPlugin ) ); + AddPlugin( CLASSINFO( cbPaneDrawPlugin ) ); +} + +void wxFrameLayout::AddPlugin( wxClassInfo* pPlInfo, int paneMask ) +{ + if ( FindPlugin ( pPlInfo ) ) return; // same type of plugin cannot be added twice + + cbPluginBase* pObj = (cbPluginBase*)pPlInfo->CreateObject(); + + wxASSERT(pObj); // DBG:: plugin's class should be dynamic + + pObj->mPaneMask = paneMask; + pObj->mpLayout = this; + + PushPlugin( pObj ); +} + +void wxFrameLayout::AddPluginBefore( wxClassInfo* pNextPlInfo, wxClassInfo* pPlInfo, + int paneMask ) +{ + wxASSERT( pNextPlInfo != pPlInfo ); // DBG:: no sence + + cbPluginBase* pNextPl = FindPlugin( pNextPlInfo ); + + if ( !pNextPl ) + { + AddPlugin( pPlInfo, paneMask ); + + return; + } + + // remove existing one if present + + cbPluginBase* pExistingPl = FindPlugin( pPlInfo ); + + if ( pExistingPl ) RemovePlugin( pPlInfo ); + + // create an instance + + cbPluginBase* pNewPl = (cbPluginBase*)pPlInfo->CreateObject(); + + wxASSERT(pNewPl); // DBG:: plugin's class should be dynamic + + // insert it to the chain + + if ( pNextPl->GetPreviousHandler() ) + + pNextPl->GetPreviousHandler()->SetNextHandler( pNewPl ); + else + mpTopPlugin = pNewPl; + + pNewPl->SetNextHandler( pNextPl ); + + pNewPl->SetPreviousHandler( pNextPl->GetPreviousHandler() ); + + pNextPl->SetPreviousHandler( pNewPl ); + + // set it up + + pNewPl->mPaneMask = paneMask; + pNewPl->mpLayout = this; + + pNewPl->OnInitPlugin(); +} + +void wxFrameLayout::RemovePlugin( wxClassInfo* pPlInfo ) +{ + cbPluginBase* pPlugin = FindPlugin( pPlInfo ); + + if ( !pPlugin ) return; // it's OK to remove not-existing plugin ;-) + + if ( pPlugin->GetPreviousHandler() == NULL ) + + mpTopPlugin = (cbPluginBase*)pPlugin->GetNextHandler(); + + delete pPlugin; +} + +cbPluginBase* wxFrameLayout::FindPlugin( wxClassInfo* pPlInfo ) +{ + cbPluginBase *pCur = mpTopPlugin; + + while( pCur ) + { + // NOTE:: it might appear useful matching plugin + // classes "polymorphically": + + if ( pCur->GetClassInfo()->IsKindOf( pPlInfo ) ) + + return pCur; + + pCur = (cbPluginBase*)pCur->GetNextHandler(); + } + + return NULL; +} + +/***** Implementation for class cbUpdateMgrData *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbUpdateMgrData, wxObject ) + +cbUpdateMgrData::cbUpdateMgrData() + + : mPrevBounds( -1,-1,0,0 ), + mIsDirty( TRUE ) // inidicate initial change +{} + +void cbUpdateMgrData::StoreItemState( const wxRect& boundsInParent ) +{ + mPrevBounds = boundsInParent; +} + +void cbUpdateMgrData::SetDirty( bool isDirty ) +{ + mIsDirty = isDirty; +} + +void cbUpdateMgrData::SetCustomData( wxObject* pCustomData ) +{ + mpCustomData = pCustomData; +} + +/***** Implementation for class cbDockPane *****/ + +void wxBarIterator::Reset() +{ + mpRow = ( mpRows->Count() ) ? (*mpRows)[0] : NULL; + mpBar = NULL; +} + +wxBarIterator::wxBarIterator( RowArrayT& rows ) + + : mpRows( &rows ), + mpRow ( NULL ), + mpBar ( NULL ) +{ + Reset(); +} + +bool wxBarIterator::Next() +{ + if ( mpRow ) + { + if ( mpBar ) + mpBar = mpBar->mpNext; + else + { + if ( mpRow->mBars.GetCount() == 0 ) + { + return FALSE; + } + + mpBar = mpRow->mBars[0]; + } + + if ( !mpBar ) + { + // skip to the next row + + mpRow = mpRow->mpNext; + + if ( mpRow ) + + mpBar = mpRow->mBars[0]; + else + return FALSE; + } + + return TRUE; + } + else + return FALSE; +} + +cbBarInfo& wxBarIterator::BarInfo() +{ + return *mpBar; +} + +cbRowInfo& wxBarIterator::RowInfo() +{ + return *mpRow; +} + +/***** Implementation for class cbBarDimHandlerBase *****/ + +IMPLEMENT_ABSTRACT_CLASS( cbBarDimHandlerBase, wxObject ) + +cbBarDimHandlerBase::cbBarDimHandlerBase() + : mRefCount(0) +{} + +void cbBarDimHandlerBase::AddRef() +{ + ++mRefCount; +} + +void cbBarDimHandlerBase::RemoveRef() +{ + if ( --mRefCount <= 0 ) delete this; +} + +/***** Implementation for class cbDimInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbDimInfo, wxObject ) + +cbDimInfo::cbDimInfo() + + : mVertGap ( 0 ), + mHorizGap( 0 ), + + mIsFixed(TRUE), + mpHandler( NULL ) +{ + for( size_t i = 0; i != MAX_BAR_STATES; ++i ) + { + mSizes[i].x = 20; + mSizes[i].y = 20; + + mBounds[i] = wxRect( -1,-1,-1,-1 ); + } +} + +cbDimInfo::cbDimInfo( cbBarDimHandlerBase* pDimHandler, + bool isFixed ) + + : mVertGap ( 0 ), + mHorizGap( 0 ), + mIsFixed ( isFixed ), + + mpHandler( pDimHandler ) +{ + if ( mpHandler ) + { + // int vtad = *((int*)mpHandler); + mpHandler->AddRef(); + } + + for( size_t i = 0; i != MAX_BAR_STATES; ++i ) + { + mSizes[i].x = -1; + mSizes[i].y = -1; + + mBounds[i] = wxRect( -1,-1,-1,-1 ); + } +} + +cbDimInfo::cbDimInfo( int dh_x, int dh_y, + int dv_x, int dv_y, + int f_x, int f_y, + + bool isFixed, + int horizGap, + int vertGap, + + cbBarDimHandlerBase* pDimHandler + ) + : mVertGap ( vertGap ), + mHorizGap ( horizGap ), + mIsFixed ( isFixed ), + mpHandler( pDimHandler ) +{ + if ( mpHandler ) + { + // int vtad = *((int*)mpHandler); + mpHandler->AddRef(); + } + + mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = dh_x; + mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = dh_y; + mSizes[wxCBAR_DOCKED_VERTICALLY ].x = dv_x; + mSizes[wxCBAR_DOCKED_VERTICALLY ].y = dv_y; + mSizes[wxCBAR_FLOATING ].x = f_x; + mSizes[wxCBAR_FLOATING ].y = f_y; + + for( size_t i = 0; i != MAX_BAR_STATES; ++i ) + mBounds[i] = wxRect( -1,-1,-1,-1 ); +} + +cbDimInfo::cbDimInfo( int x, int y, + bool isFixed, int gap, + cbBarDimHandlerBase* pDimHandler) + : mVertGap ( gap ), + mHorizGap ( gap ), + mIsFixed ( isFixed ), + mpHandler( pDimHandler ) +{ + if ( mpHandler ) + { + // int vtad = *((int*)mpHandler); + mpHandler->AddRef(); + } + + mSizes[wxCBAR_DOCKED_HORIZONTALLY].x = x; + mSizes[wxCBAR_DOCKED_HORIZONTALLY].y = y; + mSizes[wxCBAR_DOCKED_VERTICALLY ].x = x; + mSizes[wxCBAR_DOCKED_VERTICALLY ].y = y; + mSizes[wxCBAR_FLOATING ].x = x; + mSizes[wxCBAR_FLOATING ].y = y; + + for( size_t i = 0; i != MAX_BAR_STATES; ++i ) + mBounds[i] = wxRect( -1,-1,-1,-1 ); +} + +cbDimInfo::~cbDimInfo() +{ + if ( mpHandler ) + + mpHandler->RemoveRef(); +} + +const cbDimInfo& cbDimInfo::operator=( const cbDimInfo& other ) +{ + if ( this == &other ) return *this; + + for( int i = 0; i != MAX_BAR_STATES; ++i ) + + mSizes[i] = other.mSizes[i]; + + mIsFixed = other.mIsFixed; + mpHandler = other.mpHandler; + + mVertGap = other.mVertGap; + mHorizGap = other.mHorizGap; + + if ( mpHandler ) + + mpHandler->AddRef(); + + return *this; +} + +/***** Implementation for structure cbCommonPaneProperties *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbCommonPaneProperties, wxObject ) + +cbCommonPaneProperties::cbCommonPaneProperties(void) + + : mRealTimeUpdatesOn ( TRUE ), + mOutOfPaneDragOn ( TRUE ), + mExactDockPredictionOn( FALSE ), + mNonDestructFirctionOn( FALSE ), + mShow3DPaneBorderOn ( TRUE ), + mBarFloatingOn ( FALSE ), + mRowProportionsOn ( FALSE ), + mColProportionsOn ( TRUE ), + mBarCollapseIconsOn ( FALSE ), + mBarDragHintsOn ( FALSE ), + + mMinCBarDim( 16, 16 ), + mResizeHandleSize( 4 ) +{} + +/***** Implementation for class cbRowInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbRowInfo, wxObject ) + +cbRowInfo::cbRowInfo(void) + + : mNotFixedBarsCnt( FALSE ), + mpNext ( NULL ), + mpPrev ( NULL ), + mpExpandedBar ( NULL ) +{} + +cbRowInfo::~cbRowInfo() +{ + // nothing! all bars are removed using global bar + // list in wxFrameLayout class +} + +/***** Implementation for class cbBarInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbBarInfo, wxObject ) + +cbBarInfo::cbBarInfo(void) + + : mpRow( NULL ), + + mpNext( NULL ), + mpPrev( NULL ) +{} + +cbBarInfo::~cbBarInfo() +{ + // nothing +} + +/***** Implementation for class cbDockPane *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbDockPane, wxObject ) + +// FIXME:: how to eliminate these cut&pasted constructors? + +cbDockPane::cbDockPane(void) + : mLeftMargin ( 1 ), + mRightMargin ( 1 ), + mTopMargin ( 1 ), + mBottomMargin( 1 ), + mPaneWidth ( 32768 ), // fake-up very large pane dims, + // since the real dimensions of the pane may not + // be known, while inserting bars initially + mPaneHeight( 32768 ), + mAlignment ( -1 ), + mpLayout ( 0 ), + mpStoredRow( NULL ) +{} + +cbDockPane::cbDockPane( int alignment, wxFrameLayout* pPanel ) + + : mLeftMargin ( 1 ), + mRightMargin ( 1 ), + mTopMargin ( 1 ), + mBottomMargin( 1 ), + mPaneWidth ( 32768 ), // fake-up very large pane dims, + // since the real dimensions of the pane may not + // be known, while inserting bars initially + mPaneHeight( 32768 ), + mAlignment ( alignment ), + mpLayout ( pPanel ), + mpStoredRow( NULL ) +{} + +cbDockPane::~cbDockPane() +{ + for( size_t i = 0; i != mRows.Count(); ++i ) + + delete mRows[i]; + + mRowShapeData.DeleteContents( TRUE ); + + // NOTE:: control bar infromation structures are cleaned-up + // in wxFrameLayout's destructor, using global control-bar list +} + +void cbDockPane::SetMargins( int top, int bottom, int left, int right ) +{ + mTopMargin = top; + mBottomMargin = bottom; + mLeftMargin = left; + mRightMargin = right; +} + +/*** helpers of cbDockPane ***/ + +void cbDockPane::PaintBarDecorations( cbBarInfo* pBar, wxDC& dc ) +{ + cbDrawBarDecorEvent evt( pBar, dc, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::PaintBarHandles( cbBarInfo* pBar, wxDC& dc ) +{ + cbDrawBarHandlesEvent evt( pBar, dc, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::PaintBar( cbBarInfo* pBar, wxDC& dc ) +{ + PaintBarDecorations( pBar, dc ); + PaintBarHandles( pBar, dc ); +} + +void cbDockPane::PaintRowHandles( cbRowInfo* pRow, wxDC& dc ) +{ + cbDrawRowHandlesEvent evt( pRow, dc, this ); + + mpLayout->FirePluginEvent( evt ); + + cbDrawRowDecorEvent evt1( pRow, dc, this ); + + mpLayout->FirePluginEvent( evt1 ); +} + +void cbDockPane::PaintRowBackground ( cbRowInfo* pRow, wxDC& dc ) +{ + cbDrawRowBkGroundEvent evt( pRow, dc, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::PaintRowDecorations( cbRowInfo* pRow, wxDC& dc ) +{ + size_t i = 0; + + // decorations first + for( i = 0; i != pRow->mBars.Count(); ++i ) + + PaintBarDecorations( pRow->mBars[i], dc ); + + // then handles if present + for( i = 0; i != pRow->mBars.Count(); ++i ) + + PaintBarHandles( pRow->mBars[i], dc ); +} + +void cbDockPane::PaintRow( cbRowInfo* pRow, wxDC& dc ) +{ + PaintRowBackground ( pRow, dc ); + PaintRowDecorations( pRow, dc ); + PaintRowHandles ( pRow, dc ); +} + +void cbDockPane::PaintPaneBackground( wxDC& dc ) +{ + cbDrawPaneBkGroundEvent evt( dc, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::PaintPaneDecorations( wxDC& dc ) +{ + cbDrawPaneDecorEvent evt( dc, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::PaintPane( wxDC& dc ) +{ + PaintPaneBackground( dc ); + + size_t i = 0; + + // first decorations + for( i = 0; i != mRows.Count(); ++i ) + { + PaintRowBackground( mRows[i], dc ); + PaintRowDecorations( mRows[i], dc ); + } + + // than handles + for( i = 0; i != mRows.Count(); ++i ) + + PaintRowHandles( mRows[i], dc ); + + // and finally + PaintPaneDecorations( dc ); +} + +void cbDockPane::SizeBar( cbBarInfo* pBar ) +{ + cbSizeBarWndEvent evt( pBar, this ); + + mpLayout->FirePluginEvent( evt ); + return; +} + +void cbDockPane::SizeRowObjects( cbRowInfo* pRow ) +{ + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + SizeBar( pRow->mBars[i] ); +} + +void cbDockPane::SizePaneObjects() +{ + for( size_t i = 0; i != mRows.Count(); ++i ) + + SizeRowObjects( mRows[i] ); +} + +wxDC* cbDockPane::StartDrawInArea( const wxRect& area ) +{ + wxDC* pDc = 0; + + cbStartDrawInAreaEvent evt( area, &pDc, this ); + + mpLayout->FirePluginEvent( evt ); + + return pDc; +} + +void cbDockPane::FinishDrawInArea( const wxRect& area ) +{ + cbFinishDrawInAreaEvent evt( area, this ); + + mpLayout->FirePluginEvent( evt ); +} + +bool cbDockPane::IsFixedSize( cbBarInfo* pInfo ) +{ + return ( pInfo->mDimInfo.mIsFixed ); +} + +int cbDockPane::GetNotFixedBarsCount( cbRowInfo* pRow ) +{ + int cnt = 0; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + if ( !pRow->mBars[i]->IsFixed() ) ++cnt; + + return cnt; +} + +void cbDockPane::RemoveBar( cbBarInfo* pBar ) +{ + bool needsRestoring = mProps.mNonDestructFirctionOn && + mpStoredRow == pBar->mpRow; + + cbRemoveBarEvent evt( pBar, this ); + + mpLayout->FirePluginEvent( evt ); + + if ( needsRestoring ) + { + SetRowShapeData( mpStoredRow, &mRowShapeData ); + + mpStoredRow = NULL; + } +} + +void cbDockPane::SyncRowFlags( cbRowInfo* pRow ) +{ + // setup mHasOnlyFixedBars flag for the row information + pRow->mHasOnlyFixedBars = TRUE; + + pRow->mNotFixedBarsCnt = 0; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + bar.mpRow = pRow; + + if ( !bar.IsFixed() ) + { + pRow->mHasOnlyFixedBars = FALSE; + ++pRow->mNotFixedBarsCnt; + } + } +} + +void cbDockPane::FrameToPane( int* x, int* y ) +{ + *x -= mLeftMargin; + *y -= mTopMargin; + + if ( mAlignment == FL_ALIGN_TOP || + mAlignment == FL_ALIGN_BOTTOM + ) + { + *x -= mBoundsInParent.x; + *y -= mBoundsInParent.y; + } + else + { + int rx = *x, ry = *y; + + *x = ry - mBoundsInParent.y; + + *y = rx - mBoundsInParent.x; + } +} + +void cbDockPane::PaneToFrame( int* x, int* y ) +{ + if ( mAlignment == FL_ALIGN_TOP || + mAlignment == FL_ALIGN_BOTTOM + ) + { + *x += mBoundsInParent.x; + *y += mBoundsInParent.y; + } + else + { + int rx = *x, ry = *y; + + *x = ry + mBoundsInParent.x; + + *y = mBoundsInParent.y + rx; + } + + *x += mLeftMargin; + *y += mTopMargin; +} + +void cbDockPane::FrameToPane( wxRect* pRect ) +{ + wxPoint upperLeft ( pRect->x, pRect->y ); + wxPoint lowerRight( pRect->x + pRect->width, + pRect->y + pRect->height ); + + FrameToPane( &upperLeft.x, &upperLeft.y ); + FrameToPane( &lowerRight.x, &lowerRight.y ); + + pRect->x = wxMin(upperLeft.x,lowerRight.x); + pRect->y = wxMin(upperLeft.y,lowerRight.y); + + pRect->width = abs( lowerRight.x - upperLeft.x ); + pRect->height = abs( lowerRight.y - upperLeft.y ); +} + +void cbDockPane::PaneToFrame( wxRect* pRect ) +{ + wxPoint upperLeft ( pRect->x, pRect->y ); + wxPoint lowerRight( pRect->x + pRect->width, + pRect->y + pRect->height ); + + PaneToFrame( &upperLeft.x, &upperLeft.y ); + PaneToFrame( &lowerRight.x, &lowerRight.y ); + + //wxRect newRect = wxRect( upperLeft, lowerRight ); + + pRect->x = wxMin(upperLeft.x,lowerRight.x); + pRect->y = wxMin(upperLeft.y,lowerRight.y); + + pRect->width = abs( lowerRight.x - upperLeft.x ); + pRect->height = abs( lowerRight.y - upperLeft.y ); +} + +int cbDockPane::GetRowAt( int paneY ) +{ + if ( paneY < 0 ) return -1; + + int curY = 0; + + size_t i = 0; + + for( ; i != mRows.Count(); ++i ) + { + int rowHeight = mRows[i]->mRowHeight; + + int third = rowHeight/3; + + if ( paneY >= curY && paneY < curY + third ) + return i-1; + + if ( paneY >= curY + third && paneY < curY + rowHeight - third ) + return i; + + curY += rowHeight; + } + + return i; +} + +int cbDockPane::GetRowAt( int upperY, int lowerY ) +{ + /* + // OLD STUFF:: + int range = lowerY - upperY; + int oneThird = range / 3; + + wxNode* pRow = mRows.First(); + int row = 0; + int curY = 0; + + if ( lowerY <= 0 ) return -1; + + while( pRow ) + { + int rowHeight = GetRowHeight( (wxList*)pRow->Data() ); + + if ( upperY >= curY && + lowerY < curY ) return row; + + if ( upperY <= curY && + lowerY >= curY && + curY - upperY >= oneThird ) return row-1; + + if ( ( upperY < curY + rowHeight && + lowerY >= curY + rowHeight && + curY + rowHeight - lowerY >= oneThird ) + ) + return row+1; + + if ( lowerY <= curY + rowHeight ) return row; + + ++row; + curY += rowHeight; + pRow = pRow->Next(); + } + */ + + int mid = upperY + (lowerY - upperY)/2; + + if ( mid < 0 ) return -1; + + int curY = 0; + size_t i = 0; + + for( ; i != mRows.Count(); ++i ) + { + int rowHeight = mRows[i]->mRowHeight; + + if ( mid >= curY && mid < curY + rowHeight ) return i; + + curY += rowHeight; + } + + return i; +} + +int cbDockPane::GetRowY( cbRowInfo* pRow ) +{ + int curY = 0; + + for( size_t i = 0; i != mRows.Count(); ++i ) + { + if ( mRows[i] == pRow ) break; + + curY += mRows[i]->mRowHeight; + } + + return curY; +} + +bool cbDockPane::HasNotFixedRowsAbove( cbRowInfo* pRow ) +{ + while ( pRow->mpPrev ) + { + pRow = pRow->mpPrev; + + if ( pRow->mHasOnlyFixedBars ) + + return TRUE; + } + + return FALSE; +} + +bool cbDockPane::HasNotFixedRowsBelow( cbRowInfo* pRow ) +{ + while( pRow->mpNext ) + { + pRow = pRow->mpNext; + + if ( pRow->mHasOnlyFixedBars ) + + return TRUE; + } + + return FALSE; +} + +bool cbDockPane::HasNotFixedBarsLeft( cbBarInfo* pBar ) +{ + while( pBar->mpPrev ) + { + pBar = pBar->mpPrev; + + if ( pBar->IsFixed() ) + + return TRUE; + } + + return FALSE; +} + +bool cbDockPane::HasNotFixedBarsRight( cbBarInfo* pBar ) +{ + while( pBar->mpNext ) + { + pBar = pBar->mpNext; + + if ( pBar->IsFixed() ) + + return TRUE; + } + + return FALSE; +} + +void cbDockPane::CalcLengthRatios( cbRowInfo* pInRow ) +{ + int totalWidth = 0; + + size_t i = 0; + + // clac current-maximal-total-length of all maximized bars + + for( i = 0; i != pInRow->mBars.GetCount(); ++i ) + { + cbBarInfo& bar = *pInRow->mBars[i]; + + if ( !bar.IsFixed() ) + + totalWidth += bar.mBounds.width; + } + + // set up persentages of occupied space for each maximized bar + + for( i = 0; i != pInRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pInRow->mBars[i]; + + if ( !bar.IsFixed() ) + + bar.mLenRatio = double(bar.mBounds.width)/double(totalWidth); + } +} + +void cbDockPane::RecalcRowLayout( cbRowInfo* pRow ) +{ + cbLayoutRowEvent evt( pRow, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::ExpandBar( cbBarInfo* pBar ) +{ + mpLayout->GetUpdatesManager().OnStartChanges(); + + if ( !pBar->mpRow->mpExpandedBar ) + { + // save ratios only when there arent any bars expanded yet + + cbArrayFloat& ratios = pBar->mpRow->mSavedRatios; + + ratios.Clear(); + ratios.Alloc( pBar->mpRow->mNotFixedBarsCnt ); + + cbBarInfo* pCur = pBar->mpRow->mBars[0]; + + while( pCur ) + { + if ( !pCur->IsFixed() ) + { + ratios.Add( 0.0 ); + ratios[ ratios.GetCount() - 1 ] = pCur->mLenRatio; + } + + pCur = pCur->mpNext; + } + } + + cbBarInfo* pCur = pBar->mpRow->mBars[0]; + + while( pCur ) + { + pCur->mLenRatio = 0.0; // minimize the rest + + pCur = pCur->mpNext; + } + + pBar->mLenRatio = 1.0; // 100% + pBar->mBounds.width = 0; + + pBar->mpRow->mpExpandedBar = pBar; + + mpLayout->RecalcLayout( FALSE ); + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); +} + +void cbDockPane::ContractBar( cbBarInfo* pBar ) +{ + mpLayout->GetUpdatesManager().OnStartChanges(); + + // FIXME: What's the purpose of this??? + // double ratio = 1.0/ double( pBar->mpRow->mNotFixedBarsCnt ); + + // restore ratios which were present before expansion + + cbBarInfo* pCur = pBar->mpRow->mBars[0]; + + cbArrayFloat& ratios = pBar->mpRow->mSavedRatios; + + size_t i = 0; + + while( pCur ) + { + if ( !pCur->IsFixed() ) + { + pCur->mLenRatio = ratios[i]; + ++i; + } + + pCur = pCur->mpNext; + } + + ratios.Clear(); + ratios.Shrink(); + + pBar->mpRow->mpExpandedBar = NULL; + + mpLayout->RecalcLayout( FALSE ); + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); +} + +void cbDockPane::InitLinksForRow( cbRowInfo* pRow ) +{ + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + if ( i == 0 ) + + bar.mpPrev = NULL; + else + bar.mpPrev = pRow->mBars[i-1]; + + if ( i == pRow->mBars.Count() - 1 ) + + bar.mpNext = NULL; + else + bar.mpNext = pRow->mBars[i+1]; + } +} + +void cbDockPane::InitLinksForRows() +{ + for( size_t i = 0; i != mRows.Count(); ++i ) + { + cbRowInfo& row = *mRows[i]; + + if ( i == 0 ) + + row.mpPrev = NULL; + else + row.mpPrev = mRows[i-1]; + + if ( i == mRows.Count() - 1 ) + + row.mpNext = NULL; + else + row.mpNext = mRows[i+1]; + } +} + +void cbDockPane::DoInsertBar( cbBarInfo* pBar, int rowNo ) +{ + cbRowInfo* pRow = NULL; + + if ( rowNo == -1 || rowNo >= (int)mRows.Count() ) + { + pRow = new cbRowInfo(); + + if ( rowNo == -1 && mRows.Count() ) + + mRows.Insert( pRow, 0 ); + else + mRows.Add( pRow ); + + InitLinksForRows(); + } + else + { + pRow = mRows[rowNo]; + + if ( mProps.mNonDestructFirctionOn == TRUE ) + { + // store original shape of the row (before the bar is inserted) + + mpStoredRow = pRow; + + GetRowShapeData( mpStoredRow, &mRowShapeData ); + } + } + + if ( pRow->mBars.Count() ) + + pRow->mpExpandedBar = NULL; + + cbInsertBarEvent insEvt( pBar, pRow, this ); + + mpLayout->FirePluginEvent( insEvt ); + + mpLayout->GetUpdatesManager().OnRowWillChange( pRow, this ); +} + +void cbDockPane::InsertBar( cbBarInfo* pBarInfo, const wxRect& atRect ) +{ + wxRect rect = atRect; + FrameToPane( &rect ); + + pBarInfo->mBounds.x = rect.x; + pBarInfo->mBounds.width = rect.width; + pBarInfo->mBounds.height = rect.height; + + int row = GetRowAt( rect.y, rect.y + rect.height ); + + DoInsertBar( pBarInfo, row ); +} + +void cbDockPane::InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow ) +{ + cbInsertBarEvent insEvt( pBar, pIntoRow, this ); + + mpLayout->FirePluginEvent( insEvt ); + + mpLayout->GetUpdatesManager().OnRowWillChange( pIntoRow, this ); +} + +void cbDockPane::InsertBar( cbBarInfo* pBarInfo ) +{ + // set transient properties + + pBarInfo->mpRow = NULL; + pBarInfo->mHasLeftHandle = FALSE; + pBarInfo->mHasRightHandle = FALSE; + pBarInfo->mLenRatio = 0.0; + + // set preferred bar dimensions, according to the state in which + // the bar is being inserted + + pBarInfo->mBounds.width = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].x; + pBarInfo->mBounds.height = pBarInfo->mDimInfo.mSizes[ pBarInfo->mState ].y; + + DoInsertBar( pBarInfo, pBarInfo->mRowNo ); +} + +void cbDockPane::RemoveRow( cbRowInfo* pRow ) +{ + // first, hide all bar-windows in the removed row + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + if ( pRow->mBars[i]->mpBarWnd ) + + pRow->mBars[i]->mpBarWnd->Show( FALSE ); + + mRows.Remove( pRow ); + + pRow->mUMgrData.SetDirty(TRUE); +} + +void cbDockPane::InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow ) +{ + if ( !pBeforeRow ) + + mRows.Add( pRow ); + else + mRows.Insert( pRow, mRows.Index( pBeforeRow ) ); + + InitLinksForRows(); + + pRow->mUMgrData.SetDirty(TRUE); + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + pRow->mBars[i]->mUMgrData.SetDirty( TRUE ); + + SyncRowFlags( pRow ); +} + +void cbDockPane::SetPaneWidth(int width) +{ + if ( IsHorizontal() ) + + mPaneWidth = width - mLeftMargin - mRightMargin; + else + mPaneWidth = width - mTopMargin - mBottomMargin; +} + + +void cbDockPane::SetBoundsInParent( const wxRect& rect ) +{ + + mBoundsInParent = rect; + + // set pane dimensions in local coordinates + + if ( IsHorizontal() ) + { + mPaneWidth = mBoundsInParent.width - ( mRightMargin + mLeftMargin ); + mPaneHeight = mBoundsInParent.height - ( mTopMargin + mBottomMargin ); + } + else + { + mPaneWidth = mBoundsInParent.height - ( mTopMargin + mBottomMargin ); + mPaneHeight = mBoundsInParent.width - ( mRightMargin + mLeftMargin ); + } + + // convert bounding rectangles of all pane items into parent frame's coordinates + + wxBarIterator i( mRows ); + + wxRect noMarginsRect = mBoundsInParent; + + noMarginsRect.x += mLeftMargin; + noMarginsRect.y += mTopMargin; + noMarginsRect.width -= ( mLeftMargin + mRightMargin ); + noMarginsRect.height -= ( mTopMargin + mBottomMargin ); + + // hide the whole pane, if it's bounds became reverted (i.e. pane vanished) + + if ( mBoundsInParent.width < 0 || + mBoundsInParent.height < 0 ) + + hide_rect( mBoundsInParent ); + + if ( noMarginsRect.width < 0 || + noMarginsRect.height < 0 ) + + hide_rect( noMarginsRect ); + + // calculate mBoundsInParent for each item in the pane + + while( i.Next() ) + { + cbBarInfo& bar = i.BarInfo(); + + cbRowInfo* pRowInfo = bar.mpRow; + + // set up row info, if this is first bar in the row + + if ( pRowInfo && bar.mpPrev == NULL ) + { + pRowInfo->mBoundsInParent.y = pRowInfo->mRowY; + pRowInfo->mBoundsInParent.x = 0; + pRowInfo->mBoundsInParent.width = mPaneWidth; + pRowInfo->mBoundsInParent.height = pRowInfo->mRowHeight; + + PaneToFrame( &pRowInfo->mBoundsInParent ); + + clip_rect_against_rect( pRowInfo->mBoundsInParent, noMarginsRect ); + } + + wxRect bounds = bar.mBounds; + + // exclude dimensions of handles, when calculating + // bar's bounds in parent (i.e. "visual bounds") + + if ( bar.mHasLeftHandle ) + { + bounds.x += mProps.mResizeHandleSize; + bounds.width -= mProps.mResizeHandleSize; + } + + if ( bar.mHasRightHandle ) + + bounds.width -= mProps.mResizeHandleSize; + + PaneToFrame( &bounds ); + + clip_rect_against_rect( bounds, noMarginsRect ); + + bar.mBoundsInParent = bounds; + } +} + +bool cbDockPane::BarPresent( cbBarInfo* pBar ) +{ + wxBarIterator iter( mRows ); + + while( iter.Next() ) + + if ( &iter.BarInfo() == pBar ) return TRUE; + + return FALSE; +} + +cbRowInfo* cbDockPane::GetRow( int row ) +{ + if ( row >= (int)mRows.Count() ) return NULL; + + return mRows[ row ]; +} + +int cbDockPane::GetRowIndex( cbRowInfo* pRow ) +{ + for( size_t i = 0; i != mRows.Count(); ++i ) + { + if ( mRows[i] == pRow ) + return i; + } + + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: row should be present + + return 0; +} + +int cbDockPane::GetPaneHeight() +{ + // first, recalculate row heights and the Y-positions + + cbLayoutRowsEvent evt( this ); + mpLayout->FirePluginEvent( evt ); + + int height = 0; + + if ( IsHorizontal() ) + + height += mTopMargin + mBottomMargin; + else + height += mLeftMargin + mRightMargin; + + int count = mRows.Count(); + + if ( count ) + + height += mRows[count-1]->mRowY + mRows[count-1]->mRowHeight; + + return height; +} + +int cbDockPane::GetAlignment() +{ + return mAlignment; +} + +bool cbDockPane::MatchesMask( int paneMask ) +{ + int thisMask = 0; + + // FIXME:: use array instead of switch() + + switch (mAlignment) + { + case FL_ALIGN_TOP : thisMask = FL_ALIGN_TOP_PANE; break; + case FL_ALIGN_BOTTOM : thisMask = FL_ALIGN_BOTTOM_PANE;break; + case FL_ALIGN_LEFT : thisMask = FL_ALIGN_LEFT_PANE; break; + case FL_ALIGN_RIGHT : thisMask = FL_ALIGN_RIGHT_PANE; break; + + default: + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: bogus alignment type + } + + return ( thisMask & paneMask ) != 0; +} + +void cbDockPane::RecalcLayout() +{ + // first, reposition rows and items vertically + + cbLayoutRowsEvent evt( this ); + mpLayout->FirePluginEvent( evt ); + + // then horizontally in each row + + for( size_t i = 0; i != mRows.Count(); ++i ) + + RecalcRowLayout( mRows[i] ); +} + +int cbDockPane::GetDockingState() +{ + if ( mAlignment == FL_ALIGN_TOP || + mAlignment == FL_ALIGN_BOTTOM ) + { + return wxCBAR_DOCKED_HORIZONTALLY; + } + else + return wxCBAR_DOCKED_VERTICALLY; +} + +inline bool cbDockPane::HasPoint( const wxPoint& pos, int x, int y, + int width, int height ) +{ + return ( pos.x >= x && + pos.y >= y && + pos.x < x + width && + pos.y < y + height ); +} + +int cbDockPane::HitTestPaneItems( const wxPoint& pos, + cbRowInfo** ppRow, + cbBarInfo** ppBar + ) +{ + (*ppRow) = NULL; + (*ppBar) = NULL; + + for( size_t i = 0; i != mRows.Count(); ++i ) + { + cbRowInfo& row = *mRows[i]; + + *ppRow = &row; + + // hit-test handles of the row, if present + + if ( row.mHasUpperHandle ) + { + if ( HasPoint( pos, 0, row.mRowY, + row.mRowWidth, mProps.mResizeHandleSize ) ) + + return CB_UPPER_ROW_HANDLE_HITTED; + } + else + if ( row.mHasLowerHandle ) + { + if ( HasPoint( pos, 0, row.mRowY + row.mRowHeight - mProps.mResizeHandleSize, + row.mRowWidth, mProps.mResizeHandleSize ) ) + + return CB_LOWER_ROW_HANDLE_HITTED; + } + + // hit-test bar handles and bar content + + for( size_t k = 0; k != row.mBars.Count(); ++k ) + { + cbBarInfo& bar = *row.mBars[k]; + wxRect& bounds = bar.mBounds; + + *ppBar = &bar; + + if ( bar.mHasLeftHandle ) + { + if ( HasPoint( pos, bounds.x, bounds.y, + mProps.mResizeHandleSize, bounds.height ) ) + + return CB_LEFT_BAR_HANDLE_HITTED; + } + else + if ( bar.mHasRightHandle ) + { + if ( HasPoint( pos, bounds.x + bounds.width - mProps.mResizeHandleSize, bounds.y, + mProps.mResizeHandleSize, bounds.height ) ) + + return CB_RIGHT_BAR_HANDLE_HITTED; + } + + if ( HasPoint( pos, bounds.x, bounds.y, bounds.width, bounds.height ) ) + + return CB_BAR_CONTENT_HITTED; + + } // hit-test next bar + + } // next row + + return CB_NO_ITEMS_HITTED; +} + +void cbDockPane::GetBarResizeRange( cbBarInfo* pBar, int* from, int *till, + bool forLeftHandle ) +{ + cbBarInfo* pGivenBar = pBar; + + int notFree = 0; + + // calc unavailable space from the left + + while( pBar->mpPrev ) + { + pBar = pBar->mpPrev; + + if ( !pBar->IsFixed() ) notFree += mProps.mMinCBarDim.x; + else notFree += pBar->mBounds.width; + } + + *from = notFree; + + pBar = pGivenBar; + + notFree = 0; + + // calc unavailable space from the right + + while( pBar->mpNext ) + { + pBar = pBar->mpNext; + + if ( pBar->mBounds.x >= mPaneWidth ) break; + + // treat not-fixed bars as minimized + + if ( !pBar->IsFixed() ) + + notFree += mProps.mMinCBarDim.x; + else + { + if ( pBar->mBounds.x + pBar->mBounds.width >= mPaneWidth ) + { + notFree += mPaneWidth - pBar->mBounds.x; + break; + } + else + notFree += pBar->mBounds.width; + } + + } + + *till = mPaneWidth - notFree; + + // do not let resizing totally deform the bar itself + + if ( forLeftHandle ) + + (*till) -= mProps.mMinCBarDim.x; + else + + (*from) += mProps.mMinCBarDim.x; +} + +int cbDockPane::GetMinimalRowHeight( cbRowInfo* pRow ) +{ + int height = mProps.mMinCBarDim.y; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + if ( pRow->mBars[i]->IsFixed() ) + + height = wxMax( height, pRow->mBars[i]->mBounds.height ); + + if ( pRow->mHasUpperHandle ) + + height += mProps.mResizeHandleSize; + + if ( pRow->mHasLowerHandle ) + + height += mProps.mResizeHandleSize; + + return height; +} + +void cbDockPane::SetRowHeight( cbRowInfo* pRow, int newHeight ) +{ + if ( pRow->mHasUpperHandle ) + + newHeight -= mProps.mResizeHandleSize; + + if ( pRow->mHasLowerHandle ) + + newHeight -= mProps.mResizeHandleSize; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + if ( !pRow->mBars[i]->IsFixed() ) + + pRow->mBars[i]->mBounds.height = newHeight; +} + +void cbDockPane::GetRowResizeRange( cbRowInfo* pRow, int* from, int* till, + bool forUpperHandle ) +{ + cbRowInfo* pGivenRow = pRow; + + // calc unavailable space from above + + int notFree = 0; + + while( pRow->mpPrev ) + { + pRow = pRow->mpPrev; + + notFree += GetMinimalRowHeight( pRow ); + + }; + + *from = notFree; + + // allow accupy the client window space by resizing pane rows + if ( mAlignment == FL_ALIGN_BOTTOM ) + + *from -= mpLayout->GetClientHeight(); + else + if ( mAlignment == FL_ALIGN_RIGHT ) + + *from -= mpLayout->GetClientWidth(); + + // calc unavailable space from below + + pRow = pGivenRow; + + notFree = 0; + + while( pRow->mpNext ) + { + pRow = pRow->mpNext; + + notFree += GetMinimalRowHeight( pRow ); + + } + + *till = mPaneHeight - notFree; + + // allow adjustinig pane space vs. client window space by resizing pane row heights + + if ( mAlignment == FL_ALIGN_TOP ) + + *till += mpLayout->GetClientHeight(); + else + if ( mAlignment == FL_ALIGN_LEFT ) + + *till += mpLayout->GetClientWidth(); + + // do not let the resizing of the row totally squeeze the row itself + + cbRowInfo& row = *pGivenRow; + + if ( forUpperHandle ) + { + *till = row.mRowY + row.mRowHeight - GetMinimalRowHeight( pGivenRow ); + + if ( row.mHasUpperHandle ) + + *till -= mProps.mResizeHandleSize; + } + else + { + *from += GetMinimalRowHeight( pGivenRow ); + + if ( row.mHasLowerHandle ) + + *from -= mProps.mResizeHandleSize; + } +} + +void cbDockPane::ResizeRow( cbRowInfo* pRow, int ofs, + bool forUpperHandle ) +{ + cbResizeRowEvent evt( pRow, ofs, forUpperHandle, this ); + + mpLayout->FirePluginEvent( evt ); +} + +void cbDockPane::ResizeBar( cbBarInfo* pBar, int ofs, + bool forLeftHandle ) +{ + pBar->mpRow->mpExpandedBar = NULL; + + mpLayout->GetUpdatesManager().OnStartChanges(); + + wxRect& bounds = pBar->mBounds; + + if ( forLeftHandle ) + { + // do not allow bar width become less then minimal + if ( bounds.x + ofs > bounds.x + bounds.width - mProps.mMinCBarDim.x ) + { + bounds.width = mProps.mMinCBarDim.x; + bounds.x += ofs; + } + else + { + bounds.x += ofs; + bounds.width -= ofs; + } + } + else + { + // move bar left if necessary + if ( bounds.width + ofs < mProps.mMinCBarDim.x ) + { + bounds.x = bounds.x + bounds.width + ofs - mProps.mMinCBarDim.x; + bounds.width = mProps.mMinCBarDim.x; + } + else + // resize right border only + bounds.width += ofs; + } + + + cbRowInfo* pToRow = pBar->mpRow; + + this->RemoveBar( pBar ); + + InsertBar( pBar, pToRow ); + + mpLayout->RecalcLayout(FALSE); + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); +} + + +/*** row/bar resizing related methods ***/ + +void cbDockPane::DrawVertHandle( wxDC& dc, int x, int y, int height ) +{ + int lower = y + height; + + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( x,y, x, lower ); + + dc.SetPen( mpLayout->mGrayPen ); + for( int i = 0; i != mProps.mResizeHandleSize-1; ++i ) + { + ++x; + dc.DrawLine( x,y, x, lower ); + } + + dc.SetPen( mpLayout->mDarkPen ); + ++x; + dc.DrawLine( x,y, x, lower ); + + dc.SetPen( mpLayout->mBlackPen ); + ++x; + dc.DrawLine( x,y, x, lower ); +} + +void cbDockPane::DrawHorizHandle( wxDC& dc, int x, int y, int width ) +{ + int right = x + width; + + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( x,y, right, y ); + + dc.SetPen( mpLayout->mGrayPen ); + + for( int i = 0; i != mProps.mResizeHandleSize-1; ++i ) + { + ++y; + dc.DrawLine( x,y, right, y ); + } + + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawLine( x,y, right, ++y ); + + dc.SetPen( mpLayout->mBlackPen ); + dc.DrawLine( x,y, right, ++y ); +} + +cbBarInfo* cbDockPane::GetBarInfoByWindow( wxWindow* pBarWnd ) +{ + wxBarIterator i( mRows ); + + while( i.Next() ) + + if ( i.BarInfo().mpBarWnd == pBarWnd ) + + return &i.BarInfo(); + + return NULL; +} + +void cbDockPane::GetRowShapeData( cbRowInfo* pRow, wxList* pLst ) +{ + pLst->DeleteContents( TRUE ); + pLst->Clear(); + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + cbBarShapeData* pData = new cbBarShapeData(); + + pLst->Append( (wxObject*)pData ); + + pData->mBounds = bar.mBounds; + pData->mLenRatio = bar.mLenRatio; + } +} + +void cbDockPane::SetRowShapeData( cbRowInfo* pRow, wxList* pLst ) +{ + if ( pLst->First() == NULL ) return; + + wxNode* pData = pLst->First(); + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + wxASSERT( pData ); // DBG:: + + cbBarInfo& bar = *pRow->mBars[i];; + + cbBarShapeData& data = *((cbBarShapeData*)pData->Data()); + + bar.mBounds = data.mBounds; + bar.mLenRatio = data.mLenRatio; + + pData = pData->Next(); + } +} + +/***** Implementation for class cbUpdatesManagerBase *****/ + +IMPLEMENT_ABSTRACT_CLASS( cbUpdatesManagerBase, wxObject ) + +/***** Implementation for class cbPluginBase *****/ + +IMPLEMENT_ABSTRACT_CLASS( cbPluginBase, wxEvtHandler ) + +cbPluginBase::~cbPluginBase() +{ + // nothing +} + +bool cbPluginBase::ProcessEvent(wxEvent& event) +{ + if ( mPaneMask == wxALL_PANES ) + + return wxEvtHandler::ProcessEvent( event ); + + // extract mask info. from received event + + cbPluginEvent& evt = *( (cbPluginEvent*)&event ); + + if ( evt.mpPane == 0 && + mPaneMask == wxALL_PANES ) + + return wxEvtHandler::ProcessEvent( event ); + + int mask = 0; + + switch ( evt.mpPane->mAlignment ) + { + case FL_ALIGN_TOP : mask = FL_ALIGN_TOP_PANE; break; + case FL_ALIGN_BOTTOM : mask = FL_ALIGN_BOTTOM_PANE;break; + case FL_ALIGN_LEFT : mask = FL_ALIGN_LEFT_PANE; break; + case FL_ALIGN_RIGHT : mask = FL_ALIGN_RIGHT_PANE; break; + } + + // if event's pane maks matches the plugin's mask + + if ( mPaneMask & mask ) + + return wxEvtHandler::ProcessEvent( event ); + + // otherwise pass to the next handler if present + + if ( GetNextHandler() && GetNextHandler()->ProcessEvent( event ) ) + + return TRUE; + else + return FALSE; +} + diff --git a/contrib/src/fl/dyntbar.cpp b/contrib/src/fl/dyntbar.cpp new file mode 100644 index 0000000000..fe381fa590 --- /dev/null +++ b/contrib/src/fl/dyntbar.cpp @@ -0,0 +1,517 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: ??/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "dyntbar.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/utils.h" // import wxMin,wxMax macros + +#include "wx/fl/dyntbar.h" +#include "wx/fl/newbmpbtn.h" + +IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxControl ) + +BEGIN_EVENT_TABLE( wxDynamicToolBar, wxControl ) + + EVT_SIZE ( wxDynamicToolBar::OnSize ) + EVT_PAINT( wxDynamicToolBar::OnPaint ) + //EVT_ERASE_BACKGROUND( wxDynamicToolBar::OnEraseBackground ) + +END_EVENT_TABLE() + +/***** Implementation for class wxDynToolInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS(wxDynToolInfo, wxToolLayoutItem) + +/***** Implementation for class wxDynamicToolBar *****/ + +wxDynamicToolBar::wxDynamicToolBar() + : mpLayoutMan( NULL ), + mSepartorSize( 8 ), + mVertGap ( 0 ), + mHorizGap( 0 ) +{ +} + +wxDynamicToolBar::wxDynamicToolBar(wxWindow *parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, + const long style, const int orientation, + const int RowsOrColumns, const wxString& name ) + : mpLayoutMan( NULL ), + mSepartorSize( 8 ), + mVertGap ( 0 ), + mHorizGap( 0 ) +{ + Create(parent, id, pos, size, style, orientation, RowsOrColumns, name); + + SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE) ); +} + +bool wxDynamicToolBar::Create(wxWindow *parent, const wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const long style, + const int orientation, const int RowsOrColumns, + const wxString& name) +{ + // cut&pasted from wxtbatsmpl.h + + if ( ! wxWindow::Create(parent, id, pos, size, style, name) ) + return FALSE; + + SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE )); + + return TRUE; +} + +bool wxDynamicToolBar::Realize(void) +{ + // FOR NOW:: nothing + return TRUE; +} + +wxDynamicToolBar::~wxDynamicToolBar(void) +{ + if ( mpLayoutMan ) + delete mpLayoutMan; + + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + { + delete mTools[i]; + } +} + +void wxDynamicToolBar::AddTool( int toolIndex, + wxWindow* pToolWindow, + const wxSize& size + ) +{ + wxDynToolInfo* pInfo = new wxDynToolInfo(); + + pInfo->mpToolWnd = pToolWindow; + pInfo->mIndex = toolIndex; + pInfo->mIsSeparator = FALSE; + + int x,y; + pToolWindow->GetSize( &x, &y ); + pInfo->mRealSize.x = x; + pInfo->mRealSize.y = y; + pInfo->mRect.width = x; + pInfo->mRect.height = y; + + mTools.Add( pInfo ); +} + +void wxDynamicToolBar::AddTool( int toolIndex, + const wxString& imageFileName, + int imageFileType, + const wxString& labelText, bool alignTextRight, + bool isFlat ) +{ + wxNewBitmapButton* pBtn = + + new wxNewBitmapButton( imageFileName, imageFileType, + labelText, + ( alignTextRight ) + ? NB_ALIGN_TEXT_RIGHT + : NB_ALIGN_TEXT_BOTTOM, + isFlat + ); + + pBtn->Create( this, toolIndex ); + + pBtn->Reshape(); + + AddTool( toolIndex, pBtn ); +} +void wxDynamicToolBar::AddTool( int toolIndex, wxBitmap labelBmp, + const wxString& labelText, bool alignTextRight, + bool isFlat ) +{ + wxNewBitmapButton* pBtn = + + new wxNewBitmapButton( labelBmp, + labelText, + ( alignTextRight ) + ? NB_ALIGN_TEXT_RIGHT + : NB_ALIGN_TEXT_BOTTOM, + isFlat + ); + + pBtn->Create( this, toolIndex ); + + pBtn->Reshape(); + + AddTool( toolIndex, pBtn ); +} + + + wxToolBarToolBase* + wxDynamicToolBar::AddTool(const int toolIndex, const wxBitmap& bitmap, + const wxBitmap& pushedBitmap, + const bool toggle, const long xPos, + const long yPos, wxObject *clientData, + const wxString& helpString1, const wxString& helpString2) +{ + wxNewBitmapButton* pBmpBtn = new wxNewBitmapButton( bitmap ); + + pBmpBtn->Create( this, toolIndex ); + + pBmpBtn->Reshape(); + + AddTool( toolIndex, pBmpBtn ); + + return NULL; +} + + +wxDynToolInfo* wxDynamicToolBar::GetToolInfo( int toolIndex ) +{ + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + { + if ( mTools[i]->mIndex == toolIndex ) + return mTools[i]; + } + + return NULL; +} + +void wxDynamicToolBar::RemveTool( int toolIndex ) +{ + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + { + if ( mTools[i]->mIndex == toolIndex ) + { + if ( mTools[i]->mpToolWnd ) + { + mTools[i]->mpToolWnd->Destroy(); + } + delete mTools[i]; // HVL To be tested!!! +#if wxCHECK_VERSION(2,3,2) + mTools.RemoveAt(i); +#else + mTools.Remove(i); +#endif + Layout(); + + return; + } + } + // TODO:: if not found, should it be an assertion? +} + +void wxDynamicToolBar::AddSeparator( wxWindow* pSepartorWnd ) +{ + wxDynToolInfo* pInfo = new wxDynToolInfo(); + + pInfo->mpToolWnd = pSepartorWnd; + pInfo->mIndex = -1; + pInfo->mIsSeparator = TRUE; + + if ( pSepartorWnd ) + { + pSepartorWnd->Create( this, -1 ); + + int x,y; + pSepartorWnd->GetSize( &x, &y ); + pInfo->mRealSize.x = x; + pInfo->mRealSize.y = y; + + pInfo->mRect.width = x; + pInfo->mRect.height = y; + } + else + { + pInfo->mRealSize.x = mSepartorSize; + pInfo->mRealSize.y = 0; + + pInfo->mRect.width = mSepartorSize; + pInfo->mRect.height = 0; + } + + mTools.Add( pInfo ); +} + +void wxDynamicToolBar::OnEraseBackground( wxEraseEvent& event ) +{ + // FOR NOW:: nothing +} + +void wxDynamicToolBar::OnSize( wxSizeEvent& event ) +{ + //SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE ) ); + + Layout(); +} + +void wxDynamicToolBar::DrawSeparator( wxDynToolInfo& info, wxDC& dc ) +{ + // check the orientation of separator + if ( info.mRect.width < info.mRect.height ) + { + int midX = info.mRect.x + info.mRect.width/2 - 1; + + dc.SetPen( *wxGREY_PEN ); + dc.DrawLine( midX, info.mRect.y, + midX, info.mRect.y + info.mRect.height+1 ); + + dc.SetPen( *wxWHITE_PEN ); + dc.DrawLine( midX+1, info.mRect.y, + midX+1, info.mRect.y + info.mRect.height+1 ); + } + else + { + int midY = info.mRect.y + info.mRect.height/2 - 1; + + dc.SetPen( *wxGREY_PEN ); + dc.DrawLine( info.mRect.x, midY, + info.mRect.x + info.mRect.width+1, midY ); + + dc.SetPen( *wxWHITE_PEN ); + dc.DrawLine( info.mRect.x, midY + 1, + info.mRect.x + info.mRect.width+1, midY + 1 ); + } +} + +void wxDynamicToolBar::OnPaint( wxPaintEvent& event ) +{ + // draw separators if any + + wxPaintDC dc(this); + + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + + if ( mTools[i]->mIsSeparator ) + { + // check if separator doesn't have it's own window + // if so, then draw it using built-in drawing method + + if ( !mTools[i]->mpToolWnd ) + + DrawSeparator( *mTools[i], dc ); + } +} + +// FOR NOW:: quick fix +#include "wx/choice.h" + +void wxDynamicToolBar::SizeToolWindows() +{ + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + { + wxDynToolInfo& info = *mTools[i]; + + if ( !info.mIsSeparator ) + { + + // center real rectangle within the rectangle + // provided by the layout manager + + int x = info.mRect.x; + int y = info.mRect.y + (info.mRect.height - info.mRealSize.y)/2; + + // FOR NOW FOR NOW:: quick & dirty fix + if ( info.mpToolWnd->IsKindOf( CLASSINFO( wxChoice ) ) ) + { + info.mpToolWnd->SetSize( x,y, + info.mRealSize.x - 3, + info.mRealSize.y); + } + else + info.mpToolWnd->SetSize( x,y, + info.mRealSize.x, + info.mRealSize.y ); + } + + // TBD:: size separator window if present + } +} + +bool wxDynamicToolBar::Layout() +{ + if ( !mpLayoutMan ) + mpLayoutMan = CreateDefaulLayout(); + + int x,y; + GetSize( &x, &y ); + wxSize wndDim(x,y); + wxSize result; + + wxLayoutItemArrayT items; + + // safe conversion + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + items.Add( mTools[i] ); + + mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );; + + SizeToolWindows(); + return TRUE; +} + +void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim ) +{ + if ( !mpLayoutMan ) + mpLayoutMan = CreateDefaulLayout(); + + wxLayoutItemArrayT items; + + // safe conversion + size_t i; + for( i = 0; i != mTools.Count(); ++i ) + items.Add( mTools[i] ); + + mpLayoutMan->Layout( givenDim, prefDim, items, mVertGap, mHorizGap );; +} + +void wxDynamicToolBar::SetLayout( LayoutManagerBase* pLayout ) +{ + if ( mpLayoutMan ) + delete mpLayoutMan; + + mpLayoutMan = pLayout; + + Layout(); +} + +void wxDynamicToolBar::EnableTool(const int toolIndex, const bool enable ) +{ + wxDynToolInfo* pInfo = GetToolInfo( toolIndex ); + + if ( !pInfo ) + return; + + if ( pInfo->mIsSeparator || !pInfo->mpToolWnd ) + return; + + pInfo->mpToolWnd->Enable( enable ); +} + +/***** Implementation for class BagLayout *****/ + +void BagLayout::Layout( const wxSize& parentDim, + wxSize& resultingDim, + wxLayoutItemArrayT& items, + int horizGap, + int vertGap + ) +{ + int maxWidth = 0; + int curY = 0; + int nRows = 0; + + size_t i = 0; + + while( i < items.Count() ) + { + int curX = 0; + int height = 0; + // int nItems = 0; + + // int firstItem = i; + int itemsInRow = 0; + + if ( nRows > 0 ) + curY += vertGap; + + // step #1 - arrange horizontal positions of items in the row + + do + { + if ( itemsInRow > 0 ) + curX += horizGap; + + wxRect& r = items[i]->mRect; + + if ( curX + r.width > parentDim.x ) + { + if ( itemsInRow > 0 ) + break; + } + r.x = curX; + r.y = curY; + + curX += r.width; + + height = wxMax( height, r.height ); + + ++itemsInRow; + ++i; + + } while( i < items.Count() ); + + curY += height; + + maxWidth = wxMax( maxWidth, curX ); + } + + resultingDim.x = maxWidth; + resultingDim.y = curY; +} + +//////// stuff from 2.1.15 /////////// + +wxToolBarToolBase* wxDynamicToolBar::FindToolForPosition( wxCoord x, wxCoord y ) const +{ + return NULL; +} + +bool wxDynamicToolBar::DoInsertTool( size_t pos, wxToolBarToolBase* tool ) +{ + return TRUE; +} + +bool wxDynamicToolBar::DoDeleteTool( size_t pos, wxToolBarToolBase* tool ) +{ + return TRUE; +} + +void wxDynamicToolBar::DoEnableTool( wxToolBarToolBase* tool, bool enable ) +{ +} + +void wxDynamicToolBar::DoToggleTool( wxToolBarToolBase* tool, bool toggle ) +{ +} + +void wxDynamicToolBar::DoSetToggle( wxToolBarToolBase* tool, bool toggle ) +{ +} + +wxToolBarToolBase* wxDynamicToolBar::CreateTool( int id, const wxBitmap& bitmap1, const wxBitmap& bitmap2, bool toggle, wxObject* clientData, const wxString& shortHelpString, const wxString& longHelpString ) +{ + return NULL; +} + +wxToolBarToolBase* wxDynamicToolBar::CreateTool( wxControl* control ) +{ + return NULL; +} + diff --git a/contrib/src/fl/dyntbarhnd.cpp b/contrib/src/fl/dyntbarhnd.cpp new file mode 100644 index 0000000000..e375851436 --- /dev/null +++ b/contrib/src/fl/dyntbarhnd.cpp @@ -0,0 +1,49 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/01/99 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "dyntbarhnd.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/dyntbarhnd.h" + +/***** Implementation for class cbDynToolBarDimHandler *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbDynToolBarDimHandler, cbBarDimHandlerBase ) + +void cbDynToolBarDimHandler::OnChangeBarState(cbBarInfo* pBar, int newState ) +{ + // nothing +} + +void cbDynToolBarDimHandler::OnResizeBar( cbBarInfo* pBar, + const wxSize& given, + wxSize& preferred ) +{ + wxASSERT( pBar->mpBarWnd ); // DBG:: should be present + + wxDynamicToolBar* pTBar = (wxDynamicToolBar*)pBar->mpBarWnd; + + pTBar->GetPreferredDim( given, preferred ); +} + diff --git a/contrib/src/fl/files.lst b/contrib/src/fl/files.lst new file mode 100644 index 0000000000..662777828e --- /dev/null +++ b/contrib/src/fl/files.lst @@ -0,0 +1,20 @@ + +FL_OBJECTS = \ + antiflickpl.$(OBJ_EXT) \ + gcupdatesmgr.$(OBJ_EXT) \ + rowlayoutpl.$(OBJ_EXT) \ + bardragpl.$(OBJ_EXT) \ + dyntbar.$(OBJ_EXT) \ + hintanimpl.$(OBJ_EXT) \ + toolwnd.$(OBJ_EXT) \ + barhintspl.$(OBJ_EXT) \ + dyntbarhnd.$(OBJ_EXT) \ + newbmpbtn.$(OBJ_EXT) \ + updatesmgr.$(OBJ_EXT) \ + cbcustom.$(OBJ_EXT) \ + frmview.$(OBJ_EXT) \ + panedrawpl.$(OBJ_EXT) \ + controlbar.$(OBJ_EXT) \ + garbagec.$(OBJ_EXT) \ + rowdragpl.$(OBJ_EXT) + diff --git a/contrib/src/fl/flVC.dsp b/contrib/src/fl/flVC.dsp new file mode 100644 index 0000000000..a51c68f829 --- /dev/null +++ b/contrib/src/fl/flVC.dsp @@ -0,0 +1,230 @@ +# Microsoft Developer Studio Project File - Name="flVC" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=flVC - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "flVC.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "flVC.mak" CFG="flVC - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "flVC - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "flVC - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "flVC - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /I "../../../include" /I "../../include" /D "WIN32" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__HACK_MY_MSDEV40__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\..\lib\fl.lib" + +!ELSEIF "$(CFG)" == "flVC - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "../../../include" /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D DEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x809 +# ADD RSC /l 0x809 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"..\..\..\lib\fld.lib" + +!ENDIF + +# Begin Target + +# Name "flVC - Win32 Release" +# Name "flVC - Win32 Debug" +# Begin Group "Headers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\include\wx\fl\antiflickpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\bardragpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\barhintspl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\cbcustom.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\controlbar.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\dynbarhnd.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\dyntbar.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\dyntbarhnd.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\frmview.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\garbagec.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\gcupdatesmgr.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\hintanimpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\newbmpbtn.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\panedrawpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\rowdragpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\rowlayoutpl.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\toolwnd.h +# End Source File +# Begin Source File + +SOURCE=..\..\include\wx\fl\updatesmgr.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\antiflickpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\bardragpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\barhintspl.cpp +# End Source File +# Begin Source File + +SOURCE=.\cbcustom.cpp +# End Source File +# Begin Source File + +SOURCE=.\controlbar.cpp +# End Source File +# Begin Source File + +SOURCE=.\dyntbar.cpp +# End Source File +# Begin Source File + +SOURCE=.\dyntbarhnd.cpp +# End Source File +# Begin Source File + +SOURCE=.\frmview.cpp +# End Source File +# Begin Source File + +SOURCE=.\garbagec.cpp +# End Source File +# Begin Source File + +SOURCE=.\gcupdatesmgr.cpp +# End Source File +# Begin Source File + +SOURCE=.\hintanimpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\newbmpbtn.cpp +# End Source File +# Begin Source File + +SOURCE=.\panedrawpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\rowdragpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\rowlayoutpl.cpp +# End Source File +# Begin Source File + +SOURCE=.\toolwnd.cpp +# End Source File +# Begin Source File + +SOURCE=.\updatesmgr.cpp +# End Source File +# End Target +# End Project diff --git a/contrib/src/fl/flVC.dsw b/contrib/src/fl/flVC.dsw new file mode 100644 index 0000000000..4e76e8f02a --- /dev/null +++ b/contrib/src/fl/flVC.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "flVC"=.\flVC.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/src/fl/frmview.cpp b/contrib/src/fl/frmview.cpp new file mode 100644 index 0000000000..8b6763d4d3 --- /dev/null +++ b/contrib/src/fl/frmview.cpp @@ -0,0 +1,451 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 02/01/99 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "frmview.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/frmview.h" +#include "wx/utils.h" + +/***** Implementation for class wxFrameView *****/ + +BEGIN_EVENT_TABLE( wxFrameView, wxEvtHandler ) + + EVT_IDLE( wxFrameView::OnIdle ) + +END_EVENT_TABLE() + +void wxFrameView::OnIdle( wxIdleEvent& event) +{ + event.Skip(); + + if ( mDoToolUpdates ) + { + int o = 0; //glt + ++o; + + // TBD:: + } +} + +/*** public methods ***/ + +wxFrameView::wxFrameView() + + : mpLayout( NULL ), + mpFrameMgr( NULL ) +{} + +wxFrameView::~wxFrameView() +{ + if ( mpLayout ) delete mpLayout; +} + +wxFrame* wxFrameView::GetParentFrame() +{ + return mpFrameMgr->GetParentFrame(); +} + +wxWindow* wxFrameView::GetClientWindow() +{ + return mpFrameMgr->GetClientWindow(); +} + +void wxFrameView::Activate() +{ + mpFrameMgr->ActivateView( this ); +} + +void wxFrameView::Deactivate() +{ + mpFrameMgr->DeactivateCurrentView(); +} + +void wxFrameView::CreateLayout() +{ + mpLayout = new wxFrameLayout( GetParentFrame(), mpFrameMgr->GetClientWindow(), FALSE ); +} + +wxFrameLayout* wxFrameView::GetLayout() +{ + return mpLayout; +} + +void wxFrameView::SetToolUpdates( bool doToolUpdates ) +{ + mDoToolUpdates = doToolUpdates; +} + +void wxFrameView::SetLayout( wxFrameLayout* pLayout ) +{ + if ( mpLayout ) delete mpLayout; + + mpLayout = pLayout; +} + +wxFrameManager& wxFrameView::GetFrameManager() +{ + return *mpFrameMgr; +} + +void wxFrameView::RegisterMenu( const wxString& topMenuName ) +{ + mTopMenus.Add( topMenuName ); +} + +#if 0 + +/***** Implementation for class wxFrameViewSerializer *****/ + +// NOTE:: currently "stipple" property of the brush is not serialized + +class wxFrameViewSerializer : public wxEvtHandlerSerializer +{ + DECLARE_SERIALIZER_CLASS( wxFrameViewSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +IMPLEMENT_SERIALIZER_CLASS( wxFrameView, + wxFrameViewSerializer, + wxFrameViewSerializer::Serialize, + NO_CLASS_INIT ) + +void wxFrameViewSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // wxFrameViewSerializer is a kind of wxEvtHandler - peform serialization of + // the base class first + + info.SerializeInherited( pObj, store ); + + wxFrameView* pView = (wxFrameView*)pObj; + + store.XchgObjPtr( (wxObject**) &pView->mpFrameMgr ); + store.XchgObjPtr( (wxObject**) &pView->mpLayout ); + store.XchgBool ( pView->mDoToolUpdates ); + + // serialize members in derived classes + + pView->OnSerialize( store ); +} + +#endif + +/***** Implementation for class wxFrameManager *****/ + +void wxFrameManager::DoSerialize( wxObjectStorage& store ) +{ +#if 0 + store.AddInitialRef( mpFrameWnd ); + store.AddInitialRef( this ); + if ( mpClientWnd ) store.AddInitialRef( mpClientWnd ); + + store.XchgObj( (wxObject*) &mViews ); + store.XchgInt( mActiveViewNo ); + + store.Finalize(); // finish serialization +#endif +} + +void wxFrameManager::DestroyViews() +{ + DeactivateCurrentView(); + + wxNode* pNode = mViews.First(); + + while( pNode ) + { + delete (wxFrameView*)pNode->Data(); + + pNode = pNode->Next(); + } + + if ( mActiveViewNo != -1 && GetParentFrame() ) + + GetParentFrame()->SetNextHandler( NULL ); +} + +int wxFrameManager::GetViewNo( wxFrameView* pView ) +{ + wxNode* pNode = mViews.First(); + int n = 0; + + while( pNode ) + { + if ( (wxFrameView*)pNode->Data() == pView ) + + return n; + + ++n; + pNode = pNode->Next(); + } + + return -1; +} + +void wxFrameManager::EnableMenusForView( wxFrameView* pView, bool enable ) +{ + wxMenuBar* pMenuBar = GetParentFrame()->GetMenuBar(); + int count = pMenuBar->GetMenuCount(); + + if ( !pMenuBar ) return; + + wxStringListNode* pNode = pView->mTopMenus.GetFirst(); + + while( pNode ) + { + for( int i = 0; i != count; ++i ) + { + if ( pMenuBar->GetMenu(i)->GetTitle() == pNode->GetData() ) + + pMenuBar->EnableTop( i, enable ); + } + + pNode = pNode->GetNext(); + } +} + +void wxFrameManager::SyncAllMenus() +{ + wxNode* pNode = mViews.First(); + int i = 0; + + while( pNode ) + { + if ( i != mActiveViewNo ) + + EnableMenusForView( (wxFrameView*)pNode->GetData(), FALSE ); + + pNode = pNode->Next(); + } + + EnableMenusForView( GetView( mActiveViewNo ), TRUE ); +} + +/*** public methods ***/ + +wxFrameManager::wxFrameManager() + + : mpFrameWnd( NULL ), + mActiveViewNo( -1 ), + mpClientWnd( NULL ) +{ +} + +wxFrameManager::~wxFrameManager() +{ + SaveViewsNow(); + DestroyViews(); +} + +void wxFrameManager::Init( wxWindow* pMainFrame, const wxString& settingsFile ) +{ + mSettingsFile = settingsFile; + mpFrameWnd = pMainFrame; + + wxNode* pNode = mViews.First(); + + while( pNode ) + { + wxFrameView* pView = (wxFrameView*)pNode->Data(); + + pView->OnInit(); + pView->OnInitMenus(); + + pNode = pNode->Next(); + } + + if ( !ReloadViews() ) + { + // if loading of settings file failed (e.g. was not found), + // do recreation of items in each view + + pNode = mViews.First(); + + while( pNode ) + { + wxFrameView* pView = (wxFrameView*)pNode->Data(); + + pView->OnRecreate(); + + pNode = pNode->Next(); + } + } + + if ( mActiveViewNo >= mViews.Number() ) + + mActiveViewNo = -1; + + ActivateView( GetView( ( mActiveViewNo == -1 ) ? 0 : mActiveViewNo ) ); + + SyncAllMenus(); +} + +void wxFrameManager::AddView( wxFrameView* pFrmView ) +{ + mViews.Append( pFrmView ); + + pFrmView->mpFrameMgr = this; // back ref. +} + +void wxFrameManager::RemoveView( wxFrameView* pFrmView ) +{ + // TBD:: + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); +} + +int wxFrameManager::GetActiveViewNo() +{ + return mActiveViewNo; +} + +wxFrameView* wxFrameManager::GetActiveView() +{ + wxNode* pNode = mViews.Nth( mActiveViewNo ); + + if ( pNode ) return (wxFrameView*)pNode->Data(); + else return NULL; +} + +wxNode* wxFrameManager::GetActiveViewNode() +{ + return mViews.Nth( mActiveViewNo ); +} + +wxFrame* wxFrameManager::GetParentFrame() +{ + return ((wxFrame*)mpFrameWnd); +} + +wxWindow* wxFrameManager::GetParentWindow() +{ + return mpFrameWnd; +} + +wxFrameView* wxFrameManager::GetView( int viewNo ) +{ + wxNode* pNode = mViews.Nth( viewNo ); + + if ( pNode ) return (wxFrameView*)pNode->Data(); + else return NULL; +} + +void wxFrameManager::ActivateView( int viewNo ) +{ + ActivateView( GetView( viewNo ) ); +} + +void wxFrameManager::ActivateView( wxFrameView* pFrmView ) +{ + DeactivateCurrentView(); + + mActiveViewNo = GetViewNo( pFrmView ); + + if ( pFrmView->mpLayout ) + + pFrmView->mpLayout->Activate(); + + // FIXME:: we would have used PushEventHandler(), + // but wxFrame bypasses attached handlers when + // handling wxCommand events! + + GetParentFrame()->PushEventHandler( pFrmView ); + + EnableMenusForView( pFrmView, TRUE ); +} + +void wxFrameManager::SetClinetWindow( wxWindow* pFrameClient ) +{ + if ( mpClientWnd ) mpClientWnd->Destroy(); + + mpClientWnd = pFrameClient; +} + +wxWindow* wxFrameManager::GetClientWindow() +{ + if ( !mpClientWnd ) + + mpClientWnd = new wxWindow( GetParentFrame(), -1 ); + + return mpClientWnd; +} + +void wxFrameManager::DeactivateCurrentView() +{ + if ( mActiveViewNo == -1 ) return; + + wxFrameView* pView = GetActiveView(); + + // FOR NOW:: + wxASSERT( GetParentFrame()->GetEventHandler() == pView ); + + GetParentFrame()->PopEventHandler(); + + if ( pView->mpLayout ) + + pView->mpLayout->Deactivate(); + + EnableMenusForView( pView, FALSE ); +} + +void wxFrameManager::SaveViewsNow() +{ +#if 0 + if ( mSettingsFile == "" ) return; + + wxIOStreamWrapper stm; + stm.CreateForOutput( mSettingsFile ); + + mStore.SetDataStream( stm ); + DoSerialize( mStore ); +#endif +} + +bool wxFrameManager::ReloadViews() +{ + return FALSE; + + // TBD: ???? +#if 0 + if ( mSettingsFile == "" || !wxFileExists( mSettingsFile ) ) + + return FALSE; + + DestroyViews(); + + wxIOStreamWrapper stm; + stm.CreateForInput( mSettingsFile ); + + mStore.SetDataStream( stm ); + DoSerialize( mStore ); + + return TRUE; +#endif +} + +bool wxFrameManager::ViewsAreLoaded() +{ + return ( mViews.Number() != 0 ); +} + diff --git a/contrib/src/fl/garbagec.cpp b/contrib/src/fl/garbagec.cpp new file mode 100644 index 0000000000..049f944e93 --- /dev/null +++ b/contrib/src/fl/garbagec.cpp @@ -0,0 +1,224 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 18/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + + +#ifdef __GNUG__ + #pragma implementation "garbagec.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/garbagec.h" + +/***** Implementation for class GarbageCollector *****/ + +inline static GCItem& node_to_item( wxNode* pNode ) +{ + return *( (GCItem*)(pNode->Data()) ); +} + +GarbageCollector::~GarbageCollector() +{ + Reset(); +} + +/*** GC alg. helpers ***/ + +void GarbageCollector::DestroyItemList( wxList& lst ) +{ + wxNode* pNode = lst.First(); + + while( pNode ) + { + delete &node_to_item( pNode ); + + pNode = pNode->Next(); + } + + lst.Clear(); +} + +wxNode* GarbageCollector::FindItemNode( void* pForObj ) +{ + wxNode* pNode = mAllNodes.First(); + + while( pNode ) + { + if ( node_to_item( pNode ).mpObj == pForObj ) + + return pNode; + + pNode = pNode->Next(); + } + + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: item should be present + + return 0; +} + +wxNode* GarbageCollector::FindReferenceFreeItemNode() +{ + wxNode* pNode = mAllNodes.First(); + + while( pNode ) + { + if ( node_to_item( pNode ).mRefs.Number() == 0 ) + + return pNode; + + pNode = pNode->Next(); + } + + return 0; +} + +void GarbageCollector::RemoveReferencesToNode( wxNode* pItemNode ) +{ + wxNode* pNode = mAllNodes.First(); + + while( pNode ) + { + wxList& refLst = node_to_item( pNode ).mRefs; + wxNode* pRefNode = refLst.First(); + + while( pRefNode ) + { + if ( pRefNode->Data() == (wxObject*)pItemNode ) + { + wxNode* pNext = pRefNode->Next(); + + refLst.DeleteNode( pRefNode ); + + pRefNode = pNext; + + continue; + } + else pRefNode = pRefNode->Next(); + } + + pNode = pNode->Next(); + } +} + +void GarbageCollector::ResolveReferences() +{ + wxNode* pNode = mAllNodes.First(); + + while( pNode ) + { + GCItem& item = node_to_item( pNode ); + + wxNode* pRefNode = item.mRefs.First(); + + while( pRefNode ) + { + pRefNode->SetData( (wxObject*) FindItemNode( (void*)pRefNode->Data() ) ); + + pRefNode = pRefNode->Next(); + } + + pNode = pNode->Next(); + } +} + +void GarbageCollector::AddObject( void* pObj, int refCnt ) +{ + // FOR NOW:: initial ref-count is not used + + GCItem* pItem = new GCItem(); + + pItem->mpObj = pObj; + + mAllNodes.Append( (wxObject*) pItem ); +} + +void GarbageCollector::AddDependency( void* pObj, void* pDependsOnObj ) +{ + node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDependsOnObj ); +} + +/*** GC alg. implementation ***/ + +void GarbageCollector::ArrangeCollection() +{ + ResolveReferences(); + + do + { + // find node, which does not depend on anything + + wxNode* pItemNode = FindReferenceFreeItemNode(); + + if ( pItemNode ) + { + // append it to the list, where items are contained + // in the increasing order of dependencies + + mRegularLst.Append( pItemNode->Data() ); + + mAllNodes.DeleteNode( pItemNode ); + + // remove references to this current "least-dependent" node + // from reference lists of all the other nodes + + RemoveReferencesToNode( pItemNode ); + } + else + { + // otherwise, what is left - all nodes, which + // are involved into cycled chains (rings) + + wxNode* pNode = mAllNodes.First(); + + while( pNode ) + { + mCycledLst.Append( pNode->Data() ); + + pNode = pNode->Next(); + } + + break; + } + + // continue search for "least-dependent" nodes + + } while(1); +} + +wxList& GarbageCollector::GetRegularObjects() +{ + return mRegularLst; +} + +wxList& GarbageCollector::GetCycledObjects() +{ + return mCycledLst; +} + +void GarbageCollector::Reset() +{ + DestroyItemList( mAllNodes ); + + mRegularLst.Clear(); + mCycledLst.Clear(); +} + diff --git a/contrib/src/fl/gcupdatesmgr.cpp b/contrib/src/fl/gcupdatesmgr.cpp new file mode 100644 index 0000000000..3da75dff21 --- /dev/null +++ b/contrib/src/fl/gcupdatesmgr.cpp @@ -0,0 +1,409 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 19/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "gcupdatesmgr.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/gcupdatesmgr.h" + +// helper function + +static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 ) +{ + if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) || + ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) ) + + if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) || + ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) ) + + return 1; + + return 0; +} + +// helper structure + +struct cbRectInfo +{ + cbBarInfo* mpBar; + cbDockPane* mpPane; + wxRect* mpCurBounds; + wxRect* mpPrevBounds; +}; + +static inline cbRectInfo& node_to_rect_info( wxNode* pNode ) +{ + return *( (cbRectInfo*) (pNode->Data()) ); +} + +/***** Implementation for class cbSimpleUpdatesMgr *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbGCUpdatesMgr, cbSimpleUpdatesMgr ) + +cbGCUpdatesMgr::cbGCUpdatesMgr( wxFrameLayout* pPanel ) + : cbSimpleUpdatesMgr( pPanel ) +{} + +void cbGCUpdatesMgr::AddItem( wxList& itemList, + cbBarInfo* pBar, + cbDockPane* pPane, + wxRect& curBounds, + wxRect& prevBounds ) +{ + cbRectInfo* pInfo = new cbRectInfo(); + + pInfo->mpBar = pBar; + pInfo->mpPane = pPane; + pInfo->mpCurBounds = &curBounds; + pInfo->mpPrevBounds = &prevBounds; + + itemList.Append( (wxObject*) pInfo ); +} + +void cbGCUpdatesMgr::OnStartChanges() +{ + // memorize states of ALL items in the layout - + // this is quite excessive, but OK for the decent + // implementation of updates manager + + mpLayout->GetPrevClientRect() = mpLayout->GetClientRect(); + + cbDockPane** panes = mpLayout->GetPanesArray(); + + for( int n = 0; n != MAX_PANES; ++n ) + { + cbDockPane& pane = *(panes[n]); + + // store pane state + pane.mUMgrData.StoreItemState( pane.mBoundsInParent ); + pane.mUMgrData.SetDirty( FALSE ); + + cbRowInfo* pRow = pane.GetFirstRow(); + + while ( pRow ) + { + cbBarInfo* pBar = pRow->GetFirstBar(); + + // store row state + pRow->mUMgrData.StoreItemState( pRow->mBoundsInParent ); + pRow->mUMgrData.SetDirty( FALSE ); + + while( pBar ) + { + // store bar state + pBar->mUMgrData.StoreItemState( pBar->mBoundsInParent ); + pBar->mUMgrData.SetDirty( FALSE ); + + pBar = pBar->mpNext; + } + + pRow = pRow->mpNext; + } + } +} + +void cbGCUpdatesMgr::UpdateNow() +{ + cbDockPane** panes = mpLayout->GetPanesArray(); + + wxRect& r1 = mpLayout->GetClientRect(); + wxRect& r2 = mpLayout->GetPrevClientRect(); + + // detect changes in client window's area + + bool clientWindowChanged = ( r1.x != r2.x || + r1.y != r2.y || + r1.width != r2.width || + r1.height != r2.height ); + + // step #1 - detect changes in each row of each pane, + // and repaint decorations around changed windows + + wxList mBarsToResize; + + for( int n = 0; n != MAX_PANES; ++n ) + { + cbDockPane& pane = *(panes[n]); + + bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent ); + + if ( paneChanged ) + { + wxClientDC dc( &mpLayout->GetParentFrame() ); + pane.PaintPaneBackground( dc ); + } + + wxRect realBounds; + + cbRowInfo* pRow = pane.GetFirstRow(); + + while ( pRow ) + { + wxDC* pDc = 0; + + cbBarInfo* pBar = pRow->GetFirstBar(); + + bool rowChanged = FALSE; + bool rowBkPainted = FALSE; + + // FIXME:: the below should not be fixed + cbBarInfo* barsToRepaint[128]; + // number of bars, that were changed in the current row + int nBars = 0; + + wxRect r1 = pRow->mUMgrData.mPrevBounds; + wxRect r2 = pRow->mBoundsInParent; + + if ( WasChanged( pRow->mUMgrData, pRow->mBoundsInParent ) ) + + rowChanged = TRUE; + else + while( pBar ) + { + if ( WasChanged( pBar->mUMgrData, pBar->mBoundsInParent ) ) + + barsToRepaint[nBars++] = pBar; + + pBar = pBar->mpNext; + } + + if ( nBars || rowChanged ) + { + realBounds = pRow->mBoundsInParent; + + // include 1-pixel thick shades around the row + realBounds.x -= 1; + realBounds.y -= 1; + realBounds.width += 2; + realBounds.height += 2; + + pDc = pane.StartDrawInArea( realBounds ); + } + + if ( rowChanged ) + { + // postphone the resizement and refreshing the changed + // bar windows + + cbBarInfo* pCurBar = pRow->GetFirstBar(); + + while( pCurBar ) + { + if ( WasChanged( pCurBar->mUMgrData, + pCurBar->mBoundsInParent ) ) + + AddItem( mBarsToResize, pCurBar, &pane, + pCurBar->mBoundsInParent, + pCurBar->mUMgrData.mPrevBounds ); + + pCurBar = pCurBar->mpNext; + } + + // draw only their decorations now + + pane.PaintRow( pRow, *pDc ); + } + else + if ( nBars != 0 ) + { + for( int i = 0; i != nBars; ++i ) + + // postphone the resizement and refreshing the changed + // bar windows + + AddItem( mBarsToResize, + barsToRepaint[i], + &pane, + barsToRepaint[i]->mBoundsInParent, + barsToRepaint[i]->mUMgrData.mPrevBounds ); + + // redraw decorations of entire row, regardless of how much + // of the bars were changed + + pane.PaintRow( pRow, *pDc ); + } + + if ( pDc ) + + pane.FinishDrawInArea( realBounds ); + + pRow = pRow->mpNext; + + } // end of while + + if ( paneChanged ) + { + wxClientDC dc( &mpLayout->GetParentFrame() ); + pane.PaintPaneDecorations( dc ); + } + + } // end of for + + if ( clientWindowChanged && !mpLayout->mClientWndRefreshPending ) + { + // ptr to client-window object is "marked" as NULL + + AddItem( mBarsToResize, NULL, NULL, + mpLayout->GetClientRect(), + mpLayout->GetPrevClientRect() ); + } + + // step #2 - do ordered refreshing and resizing of bar window objects now + + DoRepositionItems( mBarsToResize ); +} + +void cbGCUpdatesMgr::DoRepositionItems( wxList& items ) +{ + wxNode* pNode1 = items.First(); + + while( pNode1 ) + { + cbRectInfo& info = node_to_rect_info( pNode1 ); + + wxNode* pNode2 = items.First(); + + // and node itself + + mGC.AddObject( &info ); + + while( pNode2 ) + { + if ( pNode2 != pNode1 ) // node should not depend on itself + { + // add references to objects, on which this object + // depends. Dependecy here indicates intersection of current + // bounds of this object with the initial bounds of the + // other object + + cbRectInfo& otherInfo = node_to_rect_info( pNode2 ); + + if ( rect_hits_rect( *info.mpCurBounds, *otherInfo.mpPrevBounds ) ) + + // the node depends on node + mGC.AddDependency( &info, &otherInfo ); + } + + pNode2 = pNode2->Next(); + } + + pNode1 = pNode1->Next(); + } + + mGC.ArrangeCollection(); // order nodes according "least-dependency" rule, + // and find out cycled chains + + // regular item nodes need to be resized, but not repainted (since + // they stand in linear (not cyclic) dependency with other + // regular nodes) + + wxNode* pNode = mGC.GetRegularObjects().First(); + + while ( pNode ) + { + cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode)); + + if ( info.mpBar == NULL ) + + mpLayout->PositionClientWindow(); + else + info.mpPane->SizeBar( info.mpBar ); + + pNode = pNode->Next(); + } + + // cycled item nodes, need to be both resized and repainted + + pNode = mGC.GetCycledObjects().First(); + + while ( pNode ) + { + cbRectInfo& info = *((cbRectInfo*)gc_node_to_obj(pNode)); + + if ( info.mpBar == NULL ) + { + wxWindow* pClntWnd = mpLayout->GetFrameClient(); + + mpLayout->PositionClientWindow(); + + // FIXME FIXME:: excessive! + + pClntWnd->Show( FALSE ); + pClntWnd->Show( TRUE ); + + // OLD STUFF:: mpLayout->PositionClientWindow(); + } + else + if ( info.mpBar->mpBarWnd ) + { + wxWindow* pWnd = info.mpBar->mpBarWnd; + + // resize + info.mpPane->SizeBar( info.mpBar ); + + // repaint + + /* OLD STUFF:: bool isChoice = info.mpBar->IsKindOf( CLASSINFO( wxChoice ) ); + + //#ifdef __WINDOWS__ + //int result = ::SendMessage( (HWND)pWnd->m_hWnd, WM_NCPAINT, 0, 0 ); + //#endif + */ + + // FIXME FIXME:: there's no other way to repaint non-client area of the wxWindow!! + // so we do *excessive* "hide 'n show" + + pWnd->Show(FALSE); + pWnd->Show(TRUE); + + pWnd->Refresh(); + } + + pNode = pNode->Next(); + } + + // release data prepared for GC alg. + + pNode = items.First(); + + while( pNode ) + { + cbRectInfo* pInfo = (cbRectInfo*)(pNode->Data()); + + delete pInfo; + + pNode = pNode->Next(); + } + + mGC.Reset(); // reinit GC + + // FIXME:: this is a dirty-workaround for messy client-area, + // as a result of docking bar out of floated-container window + + if ( mpLayout->mClientWndRefreshPending ) + { + mpLayout->PositionClientWindow(); + mpLayout->GetFrameClient()->Refresh(); + } +} + diff --git a/contrib/src/fl/hintanimpl.cpp b/contrib/src/fl/hintanimpl.cpp new file mode 100644 index 0000000000..3453fe877f --- /dev/null +++ b/contrib/src/fl/hintanimpl.cpp @@ -0,0 +1,397 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 9/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "hintanimpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/hintanimpl.h" + +#define POS_UNDEFINED -32768 + +/***** Implementation for class cbHintAnimationPlugin *****/ + +// FIXME:: some of the below code should be eliminated by +// reusing parts of cbBarDragPlugin's implementation + +IMPLEMENT_DYNAMIC_CLASS( cbHintAnimationPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbHintAnimationPlugin, cbPluginBase ) + + EVT_PL_DRAW_HINT_RECT( cbHintAnimationPlugin::OnDrawHintRect ) + +END_EVENT_TABLE() + +cbHintAnimationPlugin::cbHintAnimationPlugin(void) + + : mpScrDc( NULL ), + mpAnimTimer( 0 ), + mAnimStarted( FALSE ), + + mMorphDelay ( 5 ), + mMaxFrames ( 20 ), + mInClientHintBorder( 4 ), + mAccelerationOn( TRUE ) +{} + +cbHintAnimationPlugin::cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + mpScrDc( NULL ), + mpAnimTimer( 0 ), + mAnimStarted( FALSE ), + + mMorphDelay ( 5 ), + mMaxFrames ( 20 ), + mInClientHintBorder( 4 ), + mAccelerationOn( TRUE ) +{} + +cbHintAnimationPlugin::~cbHintAnimationPlugin() +{ + if ( mpScrDc ) delete mpScrDc; +} + +/*** rect-tracking related methods ***/ + +void cbHintAnimationPlugin::OnDrawHintRect( cbDrawHintRectEvent& event ) +{ + if ( !mAnimStarted && !mpScrDc ) + { + StartTracking(); + + mPrevInClient = event.mIsInClient; + + mPrevRect = event.mRect; + + mStopPending = FALSE; + } + + if ( !event.mEraseRect ) + { + // pass on current hint-rect info to the animation "thread", in + // order to make adjustments to the morph-target on-the-fly + + mCurRect.x = event.mRect.x; + mCurRect.y = event.mRect.y; + mCurRect.width = event.mRect.width; + mCurRect.height = event.mRect.height; + } + + // check the amount of change in the shape of hint, + // and start morph-effect if change is "sufficient" + + int change = abs( mCurRect.width - mPrevRect.width ) + + abs( mCurRect.height - mPrevRect.height ); + + if ( change > 10 && !event.mLastTime && !event.mEraseRect ) + { + if ( !mpAnimTimer ) + + mpAnimTimer = new cbHintAnimTimer(); + + // init the animation "thread", or reinit if already started + + mpAnimTimer->Init( this, mAnimStarted ); + + mAnimStarted = TRUE; + } + else + if ( !mAnimStarted ) + { + DoDrawHintRect( event.mRect, event.mIsInClient ); + + if ( event.mLastTime ) + + FinishTracking(); + + mPrevInClient = event.mIsInClient; + } + else + { + mCurInClient = event.mIsInClient; + + if ( event.mLastTime && mpAnimTimer ) + { + mStopPending = TRUE; + + if ( mpAnimTimer->mPrevMorphed.x != POS_UNDEFINED ) + + // erase previous rect + DoDrawHintRect( mpAnimTimer->mPrevMorphed, mPrevInClient ); + } + } + + mPrevRect = event.mRect; +} + +#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin) +#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin) +#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons. +#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons. + +static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D + }; + +void cbHintAnimationPlugin::StartTracking() +{ + mpScrDc = new wxScreenDC; + + wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame()); +} + +void cbHintAnimationPlugin::DoDrawHintRect( wxRect& rect, bool isInClientRect) +{ + wxRect scrRect; + + RectToScr( rect, scrRect ); + + int prevLF = mpScrDc->GetLogicalFunction(); + + mpScrDc->SetLogicalFunction( wxXOR ); + + if ( isInClientRect ) + { + // BUG BUG BUG (wx):: somehow stippled brush works only + // when the bitmap created on stack, not + // as a member of the class + + wxBitmap checker( (const char*)_gCheckerImg, 8,8 ); + + wxBrush checkerBrush( checker ); + + mpScrDc->SetPen( mpLayout->mNullPen ); + mpScrDc->SetBrush( checkerBrush ); + + int half = mInClientHintBorder / 2; + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y - half, + scrRect.width + 2*half, mInClientHintBorder ); + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + scrRect.height - half, + scrRect.width + 2*half, mInClientHintBorder ); + + mpScrDc->DrawRectangle( scrRect.x - half, scrRect.y + half - 1, + mInClientHintBorder, scrRect.height - 2*half + 2); + + mpScrDc->DrawRectangle( scrRect.x + scrRect.width - half, + scrRect.y + half - 1, + mInClientHintBorder, scrRect.height - 2*half + 2); + + mpScrDc->SetBrush( wxNullBrush ); + } + else + { + // otherwise draw 1-pixel thin borders + + mpScrDc->SetPen( mpLayout->mBlackPen ); + + mpScrDc->DrawLine( scrRect.x, scrRect.y, + scrRect.x + scrRect.width, scrRect.y ); + + mpScrDc->DrawLine( scrRect.x, scrRect.y + 1, + scrRect.x, scrRect.y + scrRect.height ); + + mpScrDc->DrawLine( scrRect.x+1, scrRect.y + scrRect.height, + scrRect.x + scrRect.width, scrRect.y + scrRect.height ); + + mpScrDc->DrawLine( scrRect.x + scrRect.width , scrRect.y, + scrRect.x + scrRect.width, scrRect.y + scrRect.height + 1); + } + + mpScrDc->SetLogicalFunction( prevLF ); +} + +void cbHintAnimationPlugin::DrawHintRect ( wxRect& rect, bool isInClientRect) +{ + DoDrawHintRect( rect, isInClientRect ); +} + +void cbHintAnimationPlugin::EraseHintRect( wxRect& rect, bool isInClientRect) +{ + DoDrawHintRect( rect, isInClientRect ); +} + +void cbHintAnimationPlugin::FinishTracking() +{ + wxScreenDC::EndDrawingOnTop(); + + delete mpScrDc; + + mpScrDc = NULL; +} + +void cbHintAnimationPlugin::RectToScr( wxRect& frameRect, wxRect& scrRect ) +{ + scrRect = frameRect; + + int x = frameRect.x, y = frameRect.y; + + mpLayout->GetParentFrame().ClientToScreen( &x, &y ); + + scrRect.x = x; + scrRect.y = y; +} + +/***** Implementation for class cbHintAnimTimer *****/ + +cbHintAnimTimer::cbHintAnimTimer(void) +{ +#ifdef __WINDOWS__ + mLock = 0L; +#endif + + mPrevMorphed.x = POS_UNDEFINED; +} + +void cbHintAnimTimer::MorphPoint( wxPoint& origin, MorphInfoT& info, wxPoint& point ) +{ + // simulate lienar movement (FOR NOW:: without acceleration) + + double k; + + if ( mpPl->mAccelerationOn ) + + k = double( mCurIter*mCurIter ) / + double( (mpPl->mMaxFrames - 1)*(mpPl->mMaxFrames - 1) ); + else + k = double( mCurIter ) / double( mpPl->mMaxFrames - 1 ); + + point.x = int ( double ( info.mFrom.x + double (info.mTill.x - info.mFrom.x) * k ) ); + + point.y = int ( double ( info.mFrom.y + double (info.mTill.y - info.mFrom.y) * k ) ); + + point.x += origin.x; + point.y += origin.y; +} + +void cbHintAnimTimer::Notify(void) +{ + // FIXME:: "clean" implementation should use mutex to sync + // between GUI and animation threads + + if ( mpPl->mStopPending ) + { + Stop(); // top timer + + mpPl->FinishTracking(); + + mpPl->mStopPending = FALSE; + mpPl->mpAnimTimer = NULL; + mpPl->mAnimStarted = FALSE; + + mPrevMorphed.x = POS_UNDEFINED; + + delete this; + + return; + } + + wxPoint origin( mpPl->mCurRect.x, mpPl->mCurRect.y ); + + wxPoint curUpper, curLower; + + MorphPoint( origin, mUpperLeft, curUpper ); + MorphPoint( origin, mLowerRight, curLower ); + + if ( mPrevMorphed.x != POS_UNDEFINED ) + + // erase previous rect + mpPl->DoDrawHintRect( mPrevMorphed, mpPl->mPrevInClient ); + + wxRect morphed( curUpper.x, curUpper.y, + curLower.x - curUpper.x, + curLower.y - curUpper.y ); + + // draw rect of current iteration + mpPl->DoDrawHintRect( morphed, + ( mCurIter != mpPl->mMaxFrames - 1 ) + ? mpPl->mPrevInClient : mpPl->mCurInClient ); + + mPrevMorphed = morphed; + + if ( mCurIter == mpPl->mMaxFrames - 1 ) + { + Stop(); // top timer + + mpPl->FinishTracking(); + mpPl->mpAnimTimer = NULL; + mpPl->mAnimStarted = FALSE; + + mPrevMorphed.x = POS_UNDEFINED; + + delete this; + } + else + ++mCurIter; +} + +bool cbHintAnimTimer::Init( cbHintAnimationPlugin* pAnimPl, bool reinit ) +{ + + mpPl = pAnimPl; + + // morph-points are set up relatively to the upper-left corner + // of the current hint-rectangle + + if ( !reinit ) + { + mUpperLeft.mFrom.x = mpPl->mPrevRect.x - mpPl->mCurRect.x; + mUpperLeft.mFrom.y = mpPl->mPrevRect.y - mpPl->mCurRect.y; + + mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + mpPl->mPrevRect.width ); + mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + mpPl->mPrevRect.height ); + } + else + { + wxPoint origin( mpPl->mPrevRect.x, mpPl->mPrevRect.y ); + + wxPoint curUpper, curLower; + + MorphPoint( origin, mUpperLeft, curUpper ); + MorphPoint( origin, mLowerRight, curLower ); + + mUpperLeft.mFrom.x = curUpper.x - mpPl->mCurRect.x; + mUpperLeft.mFrom.y = curUpper.y - mpPl->mCurRect.y; + + mLowerRight.mFrom.x = ( mUpperLeft.mFrom.x + curLower.x - curUpper.x ); + mLowerRight.mFrom.y = ( mUpperLeft.mFrom.y + curLower.y - curUpper.y ); + } + + mUpperLeft.mTill.x = 0; + mUpperLeft.mTill.y = 0; + + mLowerRight.mTill.x = mpPl->mCurRect.width; + mLowerRight.mTill.y = mpPl->mCurRect.height; + + mCurIter = 1; + + if ( !reinit ) + + Start( mpPl->mMorphDelay ); + + return TRUE; +} + diff --git a/contrib/src/fl/makefile.b32 b/contrib/src/fl/makefile.b32 new file mode 100644 index 0000000000..18b8f8a83e --- /dev/null +++ b/contrib/src/fl/makefile.b32 @@ -0,0 +1,26 @@ +# +# File: makefile.b32 +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWindows FrameLayout library (32-bit BC++) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ../../.. +LIB_NAME = fl +OBJ_EXT = obj + +!include files.lst + +!if "$(FINAL)" == "1" +LIBTARGET=$(WXDIR)/lib/$(LIB_NAME).lib +!else +LIBTARGET=$(WXDIR)/lib/$(LIB_NAME)d.lib +!endif + +OBJECTS = $(FL_OBJECTS) + +!include $(WXDIR)/src/makelib.b32 + diff --git a/contrib/src/fl/makefile.g95 b/contrib/src/fl/makefile.g95 new file mode 100644 index 0000000000..e3d75b483c --- /dev/null +++ b/contrib/src/fl/makefile.g95 @@ -0,0 +1,20 @@ +# +# File: makefile.g95 +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWindows FrameLayout library (Cygwin/Mingw32). + +WXDIR = ../../.. +LIB_NAME = fl +OBJ_EXT = o + +include files.lst + +LIBTARGET=$(WXDIR)/lib/lib$(LIB_NAME).a +OBJECTS = $(FL_OBJECTS) + +include $(WXDIR)/src/makelib.g95 + diff --git a/contrib/src/fl/makefile.vc b/contrib/src/fl/makefile.vc new file mode 100644 index 0000000000..86ab8acd40 --- /dev/null +++ b/contrib/src/fl/makefile.vc @@ -0,0 +1,26 @@ +# +# File: makefile.vc +# Author: Hans Van Leemputten +# Created: 2001 +# Updated: +# Copyright: (c) wxWorkshop team, 2001 +# +# Makefile for wxWindows FrameLayout library (Microsoft VC++) +# Use FINAL=1 argument to nmake to build final version with no debug info. + +WXDIR = ..\..\.. +LIB_NAME = fl +OBJ_EXT = obj + +!include files.lst + +!if "$(FINAL)" == "1" +LIBTARGET=$(WXDIR)\lib\$(LIB_NAME).lib +!else +LIBTARGET=$(WXDIR)\lib\$(LIB_NAME)d.lib +!endif + +OBJECTS = $(FL_OBJECTS) + +!include $(WXWIN)\src\makelib.vc + diff --git a/contrib/src/fl/newbmpbtn.cpp b/contrib/src/fl/newbmpbtn.cpp new file mode 100644 index 0000000000..be095bd915 --- /dev/null +++ b/contrib/src/fl/newbmpbtn.cpp @@ -0,0 +1,832 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: ??/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "newbmpbtn.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/newbmpbtn.h" +#include "wx/utils.h" // import wxMin,wxMax macros + +///////////// button-label rendering helpers ////////////////// + +static int* create_array( int width, int height, int fill = 0 ) +{ + int* array = new int[width*height]; + + int len = width*height; + for( int i = 0; i != len; ++i ) array[i] = fill; + + return array; +} + +#define GET_ELEM(array,x,y) (array[width*(y)+(x)]) + +#define MIN_COLOR_DIFF 10 + +#define IS_IN_ARRAY(x,y) ( (x) < width && (y) < height && (x) >= 0 && (y) >= 0 ) + +#define GET_RED(col) col & 0xFF +#define GET_GREEN(col) (col >> 8) & 0xFF +#define GET_BLUE(col) (col >> 16) & 0xFF + +#define MAKE_INT_COLOR(red,green,blue) ( (red) | \ + ( ( (green) << 8 ) & 0xFF00 ) | \ + ( ( (blue) << 16) & 0xFF0000) \ + ) + +#define IS_GREATER(col1,col2) ( ( (GET_RED(col1) ) > (GET_RED(col2) ) + MIN_COLOR_DIFF ) && \ + ( (GET_GREEN(col1)) > (GET_GREEN(col2)) + MIN_COLOR_DIFF ) && \ + ( (GET_BLUE(col1) ) > (GET_BLUE(col2) ) + MIN_COLOR_DIFF ) \ + ) + +#define MASK_BG 0 +#define MASK_DARK 1 +#define MASK_LIGHT 2 + +// helper function, used internally + +static void gray_out_pixmap( int* src, int* dest, int width, int height ) +{ + // assuming the pixels along the edges are of the background color + + int x = 0; + int y = 1; + + do + { + int cur = GET_ELEM(src,x,y); + + + if ( IS_IN_ARRAY(x-1,y-1) ) + { + int upperElem = GET_ELEM(src,x-1,y-1); + + // if the upper element is lighter than current + if ( IS_GREATER(upperElem,cur) ) + { + GET_ELEM(dest,x,y) = MASK_DARK; + } + else + // if the current element is ligher than the upper + if ( IS_GREATER(cur,upperElem) ) + { + GET_ELEM(dest,x,y) = MASK_LIGHT; + } + else + { + if ( GET_ELEM(dest,x-1,y-1) == MASK_LIGHT ) + + GET_ELEM(dest,x,y) = MASK_BG; + + if ( GET_ELEM(dest,x-1,y-1 ) == MASK_DARK ) + + GET_ELEM(dest,x,y) = MASK_DARK; + else + GET_ELEM(dest,x,y) = MASK_BG; + } + } + + // go zig-zag + + if ( IS_IN_ARRAY(x+1,y-1) ) + { + ++x;--y; + } + else + { + while( IS_IN_ARRAY(x-1,y+1) ) + { + --x;++y; + } + + if ( IS_IN_ARRAY(x,y+1) ) + { + ++y; continue; + } + else + { + if ( IS_IN_ARRAY(x+1,y) ) + { + ++x; continue; + } + else break; + } + } + + } while(1); +} + +// alg. for making the image look "grayed" (e.g. disabled button) +// NOTE:: used GetPixel(), which is Windows-Only! + +void gray_out_image_on_dc( wxDC& dc, int width, int height ) +{ + // assuming the pixels along the edges are of the background color + wxColour bgCol; + dc.GetPixel( 0, 0, &bgCol ); + + wxPen darkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW),1, wxSOLID ); + wxPen lightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT),1, wxSOLID ); + wxPen bgPen ( bgCol, 1, wxSOLID ); + + int* src = create_array( width, height, MASK_BG ); + int* dest = create_array( width, height, MASK_BG ); + + int y = 0; + for( y = 0; y != height; ++y ) + + for( int x = 0; x != width; ++x ) + { + wxColour col; + dc.GetPixel( x,y, &col ); + + + GET_ELEM(src,x,y) = MAKE_INT_COLOR( col.Red(), col.Green(), col.Blue() ); + } + + gray_out_pixmap( src, dest, width, height ); + + for( y = 0; y != height; ++y ) + + for( int x = 0; x != width; ++x ) + { + int mask = GET_ELEM(dest,x,y); + + switch (mask) + { + case MASK_BG : { dc.SetPen( bgPen ); + dc.DrawPoint( x,y ); break; + } + case MASK_DARK : { dc.SetPen( darkPen ); + dc.DrawPoint( x,y ); break; + } + case MASK_LIGHT : { dc.SetPen( lightPen ); + dc.DrawPoint( x,y ); break; + } + default : break; + } + } + + delete [] src; + delete [] dest; +} + +/////////////////////////////// + +/***** Impelementation for class wxNewBitmapButton *****/ + +IMPLEMENT_DYNAMIC_CLASS(wxNewBitmapButton, wxPanel) + +BEGIN_EVENT_TABLE( wxNewBitmapButton, wxPanel ) + + EVT_LEFT_DOWN( wxNewBitmapButton::OnLButtonDown ) + EVT_LEFT_UP ( wxNewBitmapButton::OnLButtonUp ) + EVT_MOTION ( wxNewBitmapButton::OnMouseMove ) + + EVT_SIZE ( wxNewBitmapButton::OnSize ) + EVT_PAINT( wxNewBitmapButton::OnPaint ) + + //EVT_KILL_FOCUS( wxNewBitmapButton::OnKillFocus ) + + EVT_ERASE_BACKGROUND( wxNewBitmapButton::OnEraseBackground ) + +END_EVENT_TABLE() + +wxNewBitmapButton::wxNewBitmapButton( const wxBitmap& labelBitmap, + const wxString& labelText, + int alignText, + bool isFlat, + int firedEventType, + int marginX, + int marginY, + int textToLabelGap, + bool isSticky) + : mTextToLabelGap ( textToLabelGap ), + mMarginX( marginX ), + mMarginY( marginY ), + mTextAlignment( alignText ), + mIsSticky( isSticky ), + mIsFlat( isFlat ), + mLabelText( labelText ), + mImageFileType( -1 ), + mDepressedBmp( labelBitmap ), + + mpDepressedImg( NULL ), + mpPressedImg ( NULL ), + mpDisabledImg ( NULL ), + mpFocusedImg ( NULL ), + + + mDragStarted ( FALSE ), + mIsPressed ( FALSE ), + mIsInFocus( FALSE ), + mPrevPressedState( FALSE ), + mPrevInFocusState( FALSE ), + mHasFocusedBmp( FALSE ), + mFiredEventType( firedEventType ), + + mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ), + mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ), + mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + mLightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ), + + mIsCreated( FALSE ), + mSizeIsSet( FALSE ) + +{ +} + +wxNewBitmapButton::wxNewBitmapButton( const wxString& bitmapFileName, + const int bitmapFileType, + const wxString& labelText, + int alignText, + bool isFlat, + int firedEventType, + int marginX, + int marginY, + int textToLabelGap, + bool isSticky) + + : mTextToLabelGap ( 2 ), + mMarginX( 2 ), + mMarginY( 2 ), + mTextAlignment( alignText ), + mIsSticky( FALSE ), + mIsFlat( isFlat ), + mLabelText( labelText ), + mImageFileName( bitmapFileName ), + mImageFileType( bitmapFileType ), + + mpDepressedImg( NULL ), + mpPressedImg ( NULL ), + mpDisabledImg ( NULL ), + mpFocusedImg ( NULL ), + + mDragStarted ( FALSE ), + mIsPressed ( FALSE ), + mIsInFocus ( FALSE ), + mPrevPressedState( FALSE ), + mPrevInFocusState( FALSE ), + mHasFocusedBmp( FALSE ), + mFiredEventType( wxEVT_COMMAND_MENU_SELECTED ), + + mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ), + mDarkPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID ), + mGrayPen ( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE), 1, wxSOLID ), + mLightPen( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DHIGHLIGHT), 1, wxSOLID ), + + mIsCreated( FALSE ), + mSizeIsSet( FALSE ) + +{ +} + +wxNewBitmapButton::~wxNewBitmapButton(void) +{ + DestroyLabels(); +} + +void wxNewBitmapButton::DrawShade( int outerLevel, + wxDC& dc, + wxPen& upperLeftSidePen, + wxPen& lowerRightSidePen ) +{ + wxBitmap* pBmp = GetStateLabel(); + + int x = mMarginX - (outerLevel + 1); + int y = mMarginY - (outerLevel + 1); + + int height = pBmp->GetHeight() + (outerLevel + 1)*2 - 1; + int width = pBmp->GetWidth() + (outerLevel + 1)*2 - 1; + + dc.SetPen( upperLeftSidePen ); + dc.DrawLine( x,y, x + width, y ); + dc.DrawLine( x,y, x, y + height ); + + dc.SetPen( lowerRightSidePen ); + dc.DrawLine( x + width, y, x + width, y + height + 1 ); + dc.DrawLine( x, y + height, x + width, y + height ); +} + +void wxNewBitmapButton::DestroyLabels() +{ + if ( mpDepressedImg ) delete mpDepressedImg; + if ( mpPressedImg ) delete mpPressedImg; + if ( mpDisabledImg ) delete mpDisabledImg; + if ( mpFocusedImg ) delete mpFocusedImg; + + mpDepressedImg = NULL; + mpPressedImg = NULL; + mpDisabledImg = NULL; + mpFocusedImg = NULL; +} + +wxBitmap* wxNewBitmapButton::GetStateLabel() +{ + if ( IsEnabled() ) + { + if ( mIsPressed ) + { + return mpPressedImg; + } + else + { + if ( mIsInFocus ) + { + if ( mHasFocusedBmp ) + + return mpFocusedImg; + else + return mpDepressedImg; + } + else + return mpDepressedImg; + } + } + else + return mpDisabledImg; +} + +static const unsigned char _gDisableImage[] = { 0x55,0xAA,0x55,0xAA, + 0x55,0xAA,0x55,0xAA, + 0x55,0xAA,0x55,0xAA, + 0x55,0xAA,0x55,0xAA + }; +void wxNewBitmapButton::RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp, + bool isEnabled, bool isPressed ) +{ + if ( destBmp != 0 ) return; + + // render lables on-demand + + wxMemoryDC srcDc; + srcDc.SelectObject( *srcBmp ); + + bool hasText = ( mTextAlignment != NB_NO_TEXT ) && + ( mLabelText.length() != 0 ); + + bool hasImage = (mTextAlignment != NB_NO_IMAGE); + + wxSize destDim; + wxPoint txtPos; + wxPoint imgPos; + + if ( hasText ) + { + long txtWidth, txtHeight; + + srcDc.SetFont( wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT) ); + srcDc.GetTextExtent( mLabelText, &txtWidth, &txtHeight ); + + if ( mTextAlignment == NB_ALIGN_TEXT_RIGHT ) + { + destDim.x = srcBmp->GetWidth() + 2*mTextToLabelGap + txtWidth; + + destDim.y = + wxMax( srcBmp->GetHeight(), txtHeight ); + + txtPos.x = srcBmp->GetWidth() + mTextToLabelGap; + txtPos.y = (destDim.y - txtHeight)/2; + imgPos.x = 0; + imgPos.y = (destDim.y - srcBmp->GetHeight())/2; + } + else + if ( mTextAlignment == NB_ALIGN_TEXT_BOTTOM ) + { + destDim.x = + wxMax( srcBmp->GetWidth(), txtWidth ); + + destDim.y = srcBmp->GetHeight() + mTextToLabelGap + txtHeight; + + txtPos.x = (destDim.x - txtWidth)/2; + txtPos.y = srcBmp->GetHeight() + mTextToLabelGap; + imgPos.x = (destDim.x - srcBmp->GetWidth())/2; + imgPos.y = 0; + } + else + { + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning);// unsupported alignment type + } + } + else + { + imgPos.x = 0; + imgPos.y = 0; + destDim.x = srcBmp->GetWidth(); + destDim.y = srcBmp->GetHeight(); + } + + destBmp = new wxBitmap( int(destDim.x), int(destDim.y) ); + + wxMemoryDC destDc; + destDc.SelectObject( *destBmp ); + + wxBrush grayBrush( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_3DFACE), wxSOLID ); + wxPen nullPen( wxColour(0,0,0), 1, wxTRANSPARENT ); + + destDc.SetBrush( grayBrush ); + destDc.SetPen( nullPen ); + + destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 ); + + if ( isPressed ) + { + ++imgPos.x; ++imgPos.y; + ++txtPos.x; ++txtPos.y; + } + + if ( hasImage ) + { + + destDc.Blit( imgPos.x, imgPos.y, + srcBmp->GetWidth()+1, + srcBmp->GetHeight()+1, + &srcDc, 0,0, wxCOPY,TRUE ); + } + + if ( hasText ) + { + wxWindow* pTopWnd = this; + + do + { + wxWindow* pParent = pTopWnd->GetParent(); + + if ( pParent == 0 ) + break; + + pTopWnd = pParent; + } while(1); + + destDc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT) ); + + if ( isEnabled ) + { + destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT) ); + } + else + { + destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW) ); + } + destDc.SetTextBackground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE) ); + + destDc.DrawText( mLabelText, txtPos.x, txtPos.y ); + } + + + destDc.SetBrush( grayBrush ); + destDc.SetPen( nullPen ); + + destDc.DrawRectangle( 0,0, destDim.x+1, destDim.y+1 ); + + if ( isPressed ) + { + ++imgPos.x; ++imgPos.y; + ++txtPos.x; ++txtPos.y; + } + + if ( hasImage ) + { + + destDc.Blit( imgPos.x, imgPos.y, + srcBmp->GetWidth()+1, + srcBmp->GetHeight()+1, + &srcDc, 0,0, wxCOPY,TRUE ); + } + + if ( hasText ) + { + wxWindow* pTopWnd = this; + + do + { + wxWindow* pParent = pTopWnd->GetParent(); + + if ( pParent == 0 ) + break; + + pTopWnd = pParent; + } while(1); + + destDc.SetFont( wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT) ); + + if ( isEnabled ) + { + destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT) ); + } + else + { + destDc.SetTextForeground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DSHADOW) ); + } + destDc.SetTextBackground( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE) ); + + destDc.DrawText( mLabelText, txtPos.x, txtPos.y ); + } + + if ( !isEnabled ){ + +#ifdef __WXMSW__ // This is currently MSW specific + gray_out_image_on_dc( destDc, destDim.x, destDim.y ); +#else + wxBrush checkerBrush( wxBitmap( (const char*)_gDisableImage,8,8) ); + checkerBrush.SetColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ) ); + destDc.SetBrush( checkerBrush ); + destDc.DrawRectangle( imgPos.x, imgPos.y, srcBmp->GetWidth()+1, srcBmp->GetHeight()+1); +#endif + } + // adjust button size to fit the new dimensions of the label + if ( !mSizeIsSet && 0 ) + { + mSizeIsSet = TRUE; + SetSize( -1,-1, + destBmp->GetWidth() + mMarginX*2, + destBmp->GetHeight() + mMarginY*2, 0 + ); + } +} +void wxNewBitmapButton::RenderAllLabelImages() +{ + if ( !mIsCreated ) + return; + RenderLabelImage( mpDisabledImg, &mDepressedBmp, FALSE ); + RenderLabelImage( mpPressedImg, &mDepressedBmp, TRUE, TRUE ); + RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE ); + if ( mHasFocusedBmp ) + { + RenderLabelImage( mpFocusedImg, &mFocusedBmp, TRUE, FALSE ); + } +} + + +void wxNewBitmapButton::RenderLabelImages() +{ + if ( !mIsCreated ) + return; + + if ( !IsEnabled() ) + { + RenderLabelImage( mpDisabledImg, &mDepressedBmp, FALSE ); + } + else + + if ( mIsPressed ) + + RenderLabelImage( mpPressedImg, &mDepressedBmp, TRUE, TRUE ); + else + { + if ( mIsInFocus ) + { + if ( mHasFocusedBmp ) + RenderLabelImage( mpFocusedImg, &mFocusedBmp, TRUE, FALSE ); + else + RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE ); + } + else + RenderLabelImage( mpDepressedImg, &mDepressedBmp, TRUE, FALSE ); + } +} + +void wxNewBitmapButton::DrawDecorations( wxDC& dc ) +{ + if ( mIsFlat ) + { + DrawShade( 1, dc, mGrayPen, mGrayPen ); + + if ( mIsInFocus ) + { + if ( mIsPressed ) + DrawShade( 0, dc, mDarkPen, mLightPen ); + else + DrawShade( 0, dc, mLightPen, mDarkPen ); + } + else + DrawShade( 0, dc, mGrayPen, mGrayPen ); + } + else + { + if ( mIsPressed ) + { + DrawShade( 0, dc, mDarkPen, mGrayPen ); + DrawShade( 1, dc, mBlackPen, mLightPen ); + } + else + { + DrawShade( 0, dc, mGrayPen, mDarkPen ); + DrawShade( 1, dc, mLightPen, mBlackPen ); + } + } +} + +void wxNewBitmapButton::SetLabel(const wxBitmap& labelBitmap, + const wxString& labelText ) +{ + DestroyLabels(); + + mLabelText = labelText; + mDepressedBmp = labelBitmap; + + //RenderLabelImages(); + RenderAllLabelImages(); +} + +void wxNewBitmapButton::SetAlignments( int alignText, + int marginX, + int marginY, + int textToLabelGap) +{ + DestroyLabels(); + + mMarginX = marginX; + mMarginY = marginY; + mTextAlignment = alignText; + mTextToLabelGap = textToLabelGap; + + //RenderLabelImages(); + RenderAllLabelImages(); +} + +// event handlers + +void wxNewBitmapButton::OnLButtonDown( wxMouseEvent& event ) +{ + mPrevPressedState = FALSE; + mDragStarted = TRUE; + mIsPressed = TRUE; + Refresh(); + + if ( !mIsInFocus ) + CaptureMouse(); +} + +void wxNewBitmapButton::OnLButtonUp( wxMouseEvent& event ) +{ + if ( !mDragStarted ) + return; + + mDragStarted = FALSE; + mIsPressed = FALSE; + mIsInFocus = FALSE; + Refresh(); + + ReleaseMouse(); + + if ( IsInWindow( event.m_x, event.m_y ) ) + { + // fire event, if mouse was released + // within the bounds of button + wxCommandEvent cmd( mFiredEventType, GetId() ); + GetParent()->ProcessEvent( cmd ); + } +} + +bool wxNewBitmapButton::IsInWindow( int x, int y ) +{ + int width, height; + GetSize( &width, &height ); + + return ( x >= 0 && y >= 0 && + x < width && + y < height ); +} + +void wxNewBitmapButton::OnMouseMove( wxMouseEvent& event ) +{ + mPrevPressedState=mIsPressed; + mPrevInFocusState=mIsInFocus; + if ( !mIsInFocus && IsInWindow( event.m_x, event.m_y ) ) + { + if ( !mDragStarted ) + CaptureMouse(); + + mIsInFocus = TRUE; + } + else + if ( mIsInFocus && !IsInWindow( event.m_x, event.m_y ) ) + { + mIsInFocus = FALSE; + + if ( !mDragStarted ) + ReleaseMouse(); + } + + if ( mDragStarted ) + { + if ( IsInWindow( event.m_x, event.m_y ) ) + + mIsPressed = TRUE; + else + mIsPressed = FALSE; + } + + if ((mIsPressed != mPrevPressedState) || + (mIsInFocus!=mPrevInFocusState)) + { + Refresh(); + } +} + +void wxNewBitmapButton::OnSize( wxSizeEvent& event ) +{ + //Reshape(); +} + +void wxNewBitmapButton::Reshape( ) +{ + + bool wasCreated = mIsCreated; + mIsCreated = TRUE; + + if ( !wasCreated ) + { + // in the case of loading button from stream, check if we + // have non-empty image-file name, load if possible + + if ( mImageFileName != "" ) + { + mDepressedBmp.LoadFile( mImageFileName, mImageFileType ); + + //wxMessageBox("Image Loaded!!!"); + } + + //RenderLabelImages(); + RenderAllLabelImages(); + + wxBitmap* pCurImg = GetStateLabel(); + + int w = pCurImg->GetWidth(), + h = pCurImg->GetHeight(); + + SetSize( 0,0, w + mMarginX*2, h + mMarginY*2 , 0 ); + } +} + +void wxNewBitmapButton::DrawLabel( wxDC& dc ) +{ + wxBitmap* pCurBmp = GetStateLabel(); + + if ( pCurBmp == NULL ) + { + wxSizeEvent evt; + OnSize( evt ); // fake it up! + + //RenderLabelImages(); + pCurBmp = GetStateLabel(); + } + + wxMemoryDC mdc; + mdc.SelectObject( *pCurBmp ); + + dc.Blit( mMarginX, mMarginY, + pCurBmp->GetWidth(), + pCurBmp->GetHeight(), + &mdc, 0,0, wxCOPY + ); + + mdc.SelectObject( wxNullBitmap ); +} + +void wxNewBitmapButton::OnPaint( wxPaintEvent& event ) +{ + wxPaintDC dc(this); + + // first, make sure images for current state are prepared + //RenderLabelImages(); + + DrawLabel( dc ); + + DrawDecorations( dc ); +} + +void wxNewBitmapButton::OnEraseBackground( wxEraseEvent& event ) +{ + // do nothing +} + +void wxNewBitmapButton::OnKillFocus( wxFocusEvent& event ) +{ + // useless + + wxMessageBox("kill-focus for button!"); +} + diff --git a/contrib/src/fl/panedrawpl.cpp b/contrib/src/fl/panedrawpl.cpp new file mode 100644 index 0000000000..8a20e05737 --- /dev/null +++ b/contrib/src/fl/panedrawpl.cpp @@ -0,0 +1,1273 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "panedrawpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include +#include + +#include "wx/utils.h" // import wxMin,wxMax macros + +#include "wx/fl/panedrawpl.h" + +// bitmap bits used by bar-resizing brush + +#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin) +#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin) +#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons. +#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons. + +static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D + }; + +// FIXME:: The below code somehow doesn't work - cursors remain unchanged +// Used: controlbar.cpp(1268): set_cursor_bits( _gHorizCursorImg, bits, 32, 16 ); +// Used: controlbar.cpp(1272): set_cursor_bits( _gVertCursorImg, bits, 32, 16 ); +/* +static void set_cursor_bits( const char** img, char* bits, int width, int height ) +{ + for( int i = 0; i != (width*height)/8; ++i ) + bits[i] = 0; + + for( int y = 0; y != height; ++y ) + { + const char* row = img[0]; + + for( int x = 0; x != width; ++x ) + { + int bitNo = y*width + x; + + char value = ( row[x] != '.' ) ? 1 : 0; + + bits[ bitNo / sizeof(char) ] |= + ( ( bitNo %sizeof(char) ) << value ); + } + + ++img; + } +} +*/ + +/***** Implementation for class cbPaneDrawPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbPaneDrawPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbPaneDrawPlugin, cbPluginBase ) + + EVT_PL_LEFT_DOWN ( cbPaneDrawPlugin::OnLButtonDown ) + EVT_PL_LEFT_UP ( cbPaneDrawPlugin::OnLButtonUp ) +// EVT_PL_LEFT_DCLICK ( cbPaneDrawPlugin::OnLDblClick ) + EVT_PL_RIGHT_UP ( cbPaneDrawPlugin::OnRButtonUp ) + EVT_PL_MOTION ( cbPaneDrawPlugin::OnMouseMove ) + + + EVT_PL_DRAW_PANE_BKGROUND ( cbPaneDrawPlugin::OnDrawPaneBackground ) + EVT_PL_DRAW_PANE_DECOR ( cbPaneDrawPlugin::OnDrawPaneDecorations ) + + EVT_PL_DRAW_ROW_DECOR ( cbPaneDrawPlugin::OnDrawRowDecorations ) + EVT_PL_DRAW_ROW_HANDLES ( cbPaneDrawPlugin::OnDrawRowHandles ) + EVT_PL_DRAW_ROW_BKGROUND ( cbPaneDrawPlugin::OnDrawRowBackground ) + + EVT_PL_SIZE_BAR_WND ( cbPaneDrawPlugin::OnSizeBarWindow ) + EVT_PL_DRAW_BAR_DECOR ( cbPaneDrawPlugin::OnDrawBarDecorations ) + EVT_PL_DRAW_BAR_HANDLES ( cbPaneDrawPlugin::OnDrawBarHandles ) + + EVT_PL_START_DRAW_IN_AREA ( cbPaneDrawPlugin::OnStartDrawInArea ) + EVT_PL_FINISH_DRAW_IN_AREA ( cbPaneDrawPlugin::OnFinishDrawInArea ) + +END_EVENT_TABLE() + +cbPaneDrawPlugin::cbPaneDrawPlugin(void) + + : mResizeStarted ( FALSE ), + + mResizeCursorOn ( FALSE ), + mpDraggedBar ( NULL ), + mpResizedRow ( NULL ), + + mRowHandleHitted ( FALSE ), + mIsUpperHandle ( FALSE ), + mBarHandleHitted ( FALSE ), + mIsLeftHandle ( FALSE ), + mBarContentHitted ( FALSE ), + + mpClntDc ( NULL ), + mpPane ( NULL ) +{} + +cbPaneDrawPlugin::cbPaneDrawPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + + // bar-row resizing state varaibles + + mResizeStarted ( FALSE ), + + mResizeCursorOn ( FALSE ), + mpDraggedBar ( NULL ), + mpResizedRow ( NULL ), + + mRowHandleHitted ( FALSE ), + mIsUpperHandle ( FALSE ), + mBarHandleHitted ( FALSE ), + mIsLeftHandle ( FALSE ), + mBarContentHitted ( FALSE ), + + mpClntDc ( NULL ), + mpPane ( NULL ) +{} + +cbPaneDrawPlugin::~cbPaneDrawPlugin() +{ + // DBG:: + wxASSERT( mpClntDc == NULL ); +} + +void cbPaneDrawPlugin::DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane ) +{ + wxScreenDC dc; + int ofsX = 0; + int ofsY = 0; + + wxPoint fpos = pos; + pane.PaneToFrame( &fpos.x, &fpos.y ); + + // short-cut + int resizeHndSize = pane.mProps.mResizeHandleSize; + + // "Required for X to specify that + // that we wish to draw on top of all windows + // - and we optimise by specifying the area + // for creating the overlap window." --J.S. + + wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame()); + + mpLayout->GetParentFrame().ClientToScreen( &ofsX, &ofsY ); + + int prevLF = dc.GetLogicalFunction(); + + // BUG BUG BUG (wx):: somehow stippled brush works only + // when the bitmap created on stack, not + // as a member of the class + + wxBitmap checker( (const char*)_gCheckerImg, 8,8 ); + + wxBrush checkerBrush( checker ); + + dc.SetPen( mpLayout->mNullPen ); + dc.SetBrush( checkerBrush ); + dc.SetLogicalFunction( wxXOR ); + + if ( mHandleIsVertical ) + { + int delta = pos.x - mDragOrigin.x; + + if ( !pane.IsHorizontal() ) + + delta = pos.y - mDragOrigin.y; + + int realHndOfs; + realHndOfs = pane.mBoundsInParent.x + pane.mLeftMargin + mHandleOfs; + + int newX = realHndOfs + delta; + + if ( newX + resizeHndSize > mHandleDragArea.x + mHandleDragArea.width ) + + newX = mHandleDragArea.x + mHandleDragArea.width - 1; + + if ( newX < mHandleDragArea.x ) + + newX = mHandleDragArea.x; + + mDraggedDelta = newX - realHndOfs; + + dc.DrawRectangle( newX + ofsX, mHandleDragArea.y + ofsY, + resizeHndSize + 1, + mHandleDragArea.height+1 ); + } + else + { + // otherwise, draw horizontal handle + + int delta = pos.y - mDragOrigin.y; + + if ( !pane.IsHorizontal() ) + + delta = pos.x - mDragOrigin.x; + + int realHndOfs; + realHndOfs = pane.mBoundsInParent.y + pane.mTopMargin + mHandleOfs; + + int newY = realHndOfs + delta; + + if ( newY + resizeHndSize > mHandleDragArea.y + mHandleDragArea.height ) + + newY = mHandleDragArea.y + mHandleDragArea.height - 1; + + if ( newY < mHandleDragArea.y ) + + newY = mHandleDragArea.y; + + mDraggedDelta = newY - realHndOfs; + + dc.DrawRectangle( mHandleDragArea.x + ofsX, newY + ofsY, + mHandleDragArea.width + 1, + resizeHndSize + 1 ); + } + + dc.SetLogicalFunction( prevLF ); + + // "End drawing on top (frees the window used for drawing + // over the screen)" --J.S. + wxScreenDC::EndDrawingOnTop(); +} + +void cbPaneDrawPlugin::OnMouseMove( cbMotionEvent& event ) +{ + if ( !mResizeStarted ) + { + // if nothing is started, do hit-tests + + bool prevWasRowHandle = mRowHandleHitted; + + mBarContentHitted = FALSE; + mBarHandleHitted = FALSE; + mRowHandleHitted = FALSE; + + int testResult = + event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes + &mpResizedRow, + &mpDraggedBar ); + + if ( testResult != CB_NO_ITEMS_HITTED ) + { + if ( testResult == CB_BAR_CONTENT_HITTED ) + { + // restore cursor, if non of the handles were hit + if ( mResizeCursorOn ) + { + // remove resizing hints + + mpLayout->ReleaseEventsFromPane( event.mpPane ); + mpLayout->ReleaseEventsFromPlugin( this ); + + mResizeCursorOn = FALSE; + + mBarContentHitted = TRUE; + + mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor ); + } + + // TBD:: fire something like "mouse-over-bar" event + + event.Skip(); // pass event to the next handler in the chain + return; + } + + wxCursor* pCurs = NULL; + + if ( testResult == CB_UPPER_ROW_HANDLE_HITTED || + testResult == CB_LOWER_ROW_HANDLE_HITTED) + { + if ( event.mpPane->IsHorizontal() ) + + pCurs = mpLayout->mpVertCursor; + else + pCurs = mpLayout->mpHorizCursor; + + mRowHandleHitted = TRUE; + mIsUpperHandle = ( testResult == CB_UPPER_ROW_HANDLE_HITTED ); + } + else + { + // otherwise, if inter-bar handle was hitted + + if ( event.mpPane->IsHorizontal() ) + + pCurs = mpLayout->mpHorizCursor; + else + pCurs = mpLayout->mpVertCursor; + + mBarHandleHitted = TRUE; + mIsLeftHandle = ( testResult == CB_LEFT_BAR_HANDLE_HITTED ); + } + + // avoid setting the same cursor twice + + if ( !mResizeCursorOn || prevWasRowHandle != mRowHandleHitted ) + { + if ( !mResizeCursorOn ) + { + // caputre if not captured yet + mpLayout->CaptureEventsForPane( event.mpPane ); + mpLayout->CaptureEventsForPlugin( this ); + } + + mpLayout->GetParentFrame().SetCursor( *pCurs ); + } + + mResizeCursorOn = TRUE; + + // handled is being dragged now, thus event is "eaten" by this plugin + + return; + + } // end of if (HitTestBarHandles()) + + // restore cursor, if non of the handles were hit + if ( mResizeCursorOn ) + { + mpLayout->ReleaseEventsFromPane( event.mpPane ); + mpLayout->ReleaseEventsFromPlugin( this ); + + mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor ); + + mResizeCursorOn = FALSE; + } + + event.Skip(); // pass event to the next plugin + } + + // othewise series of actions, if something has already started + + else + if ( mResizeStarted ) + { + // apply xor-mask twice + DrawDraggedHandle( mPrevPos, *event.mpPane ); + + // draw handle in the new position + DrawDraggedHandle( event.mPos, *event.mpPane ); + mPrevPos = event.mPos; + + // handled is dragged, thus event is "eaten" by this plugin + } + else + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnLDblClick( cbLeftDClickEvent& event ) +{ + if ( !mResizeCursorOn ) + { + cbBarInfo* pBarToFloat; + + if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes + &mpResizedRow, + &pBarToFloat ) == CB_BAR_CONTENT_HITTED + ) + { + // TBD: ???? + return; + + mpLayout->SetBarState( pBarToFloat, wxCBAR_FLOATING, TRUE ); + + mpLayout->RepositionFloatedBar( pBarToFloat ); + + return; // event is "eaten" by this plugin + } + + event.Skip(); + } +} + +void cbPaneDrawPlugin::OnLButtonDown( cbLeftDownEvent& event ) +{ + wxASSERT( !mResizeStarted ); + + if ( mResizeCursorOn ) + { + mResizeStarted = TRUE; + mDragOrigin = event.mPos; + + // setup constraints for the dragging handle + + int from, till; + mHandleOfs = 0; + mHandleIsVertical = FALSE; + + if ( mRowHandleHitted ) + + event.mpPane->GetRowResizeRange( mpResizedRow, &from, &till, mIsUpperHandle ); + else + // otherwise if bar handle was hitted + event.mpPane->GetBarResizeRange( mpDraggedBar, &from, &till, mIsLeftHandle ); + + if ( mRowHandleHitted ) + { + mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? FALSE : TRUE; + + mHandleDragArea.x = 0; + mHandleDragArea.width = event.mpPane->mPaneWidth; + + mHandleDragArea.y = from; + mHandleDragArea.height = till - from; + + if ( mIsUpperHandle ) + + mHandleOfs = mpResizedRow->mRowY; + else + mHandleOfs = mpResizedRow->mRowY + + mpResizedRow->mRowHeight - + event.mpPane->mProps.mResizeHandleSize; + } + else + { + // otehrwise if bar handle dragged + + cbRowInfo& rowInfo = *mpDraggedBar->mpRow; + wxRect& bounds = mpDraggedBar->mBounds; + + mHandleIsVertical = ( event.mpPane->IsHorizontal() ) ? TRUE : FALSE; + + mHandleDragArea.x = from; + mHandleDragArea.width = till - from; + + + mHandleDragArea.y = bounds.y; + mHandleDragArea.height = bounds.height; + + // left-side-handle mBounds + if ( mIsLeftHandle ) + + mHandleOfs = bounds.x; + else + mHandleOfs = bounds.x + + bounds.width - event.mpPane->mProps.mResizeHandleSize; + + } + + event.mpPane->PaneToFrame( &mHandleDragArea ); + DrawDraggedHandle(mDragOrigin, *event.mpPane); + + mPrevPos = mDragOrigin; + + return; + // handled is dragged, thus event is "eaten" by this plugin + } + else + { + cbBarInfo* pDraggedBar; + + if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes + &mpResizedRow, + &pDraggedBar ) == CB_BAR_CONTENT_HITTED + ) + { + int x = event.mPos.x, + y = event.mPos.y; + + event.mpPane->PaneToFrame( &x, &y ); + + cbStartBarDraggingEvent dragEvt( pDraggedBar, wxPoint(x,y), event.mpPane ); + + mpLayout->FirePluginEvent( dragEvt ); + + return; // event is "eaten" by this plugin + } + } + + event.Skip(); // pass event to the next plugin in the chain +} + +void cbPaneDrawPlugin::OnLButtonUp( cbLeftUpEvent& event ) +{ + if ( mResizeStarted ) + { + DrawDraggedHandle( event.mPos, *event.mpPane ); + + mResizeStarted = FALSE; + mResizeCursorOn = FALSE; + + mpLayout->ReleaseEventsFromPane( event.mpPane ); + mpLayout->ReleaseEventsFromPlugin( this ); + + mpLayout->GetParentFrame().SetCursor( *mpLayout->mpNormalCursor ); + + if ( mRowHandleHitted ) + { + event.mpPane->ResizeRow( mpResizedRow, + mDraggedDelta, + mIsUpperHandle ); + } + else + { + event.mpPane->ResizeBar( mpDraggedBar, + mDraggedDelta, + mIsLeftHandle ); + } + + mpDraggedBar = NULL; + mpResizedRow = NULL; + + // handled dragging action was finished by this mouse-up, + // thus event is "eaten" by this plugin + + return; + } + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnRButtonUp( cbRightUpEvent& event ) +{ + wxPoint fpos = event.mPos; + event.mpPane->PaneToFrame( &fpos.x, &fpos.y ); + + cbBarInfo* pDraggedBar; + + // user clicks inside the bar contnet, fire bar-customization event + + if ( event.mpPane->HitTestPaneItems( event.mPos, // in pane's coordiantes + &mpResizedRow, + &pDraggedBar ) == CB_BAR_CONTENT_HITTED + ) + { + cbCustomizeBarEvent cbEvt( pDraggedBar, fpos, event.mpPane ); + + mpLayout->FirePluginEvent( cbEvt ); + + return; // event is "eaten" by this plugin + } + + // otherwise fire whole-layout customization event + + cbCustomizeLayoutEvent csEvt( fpos ); + + mpLayout->FirePluginEvent( csEvt ); + + // event is "eaten" by this plugin +} + +void cbPaneDrawPlugin::OnSizeBarWindow( cbSizeBarWndEvent& event ) +{ + cbBarInfo& bar = *event.mpBar; + mpPane = event.mpPane; + + // it's possible that a bar does not have it's own window! + if ( !bar.mpBarWnd ) return; + + wxRect& bounds = event.mBoundsInParent; + + // check visibility + if ( bounds.height != 0 ) + { + // size smaller than bounds, to leave space for shade lines + + // FIXME:: +/- 1s + + bar.mpBarWnd->wxWindow::SetSize( bounds.x + 1 + bar.mDimInfo.mHorizGap, + bounds.y + 1 + bar.mDimInfo.mVertGap, + bounds.width - 2 - bar.mDimInfo.mHorizGap*2, + bounds.height - 2 - bar.mDimInfo.mVertGap *2 , + 0 + ); + + if ( !bar.mpBarWnd->IsShown() ) + + bar.mpBarWnd->Show( TRUE ); + } + else + // hide bar if not visible + bar.mpBarWnd->Show( FALSE ); + + event.Skip(); // pass event to the next plugin in the chain +} + +void cbPaneDrawPlugin::OnDrawRowDecorations( cbDrawRowDecorEvent& event ) +{ + DrawPaneShadeForRow( event.mpRow, *event.mpDc ); + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::DrawUpperRowHandle( cbRowInfo* pRow, wxDC& dc ) +{ + wxRect& bounds = pRow->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + if ( pRow->mHasUpperHandle ) + + mpPane->DrawHorizHandle( dc, bounds.x, + bounds.y-1, + pRow->mRowWidth ); + } + else + { + if ( pRow->mHasUpperHandle ) + + mpPane->DrawVertHandle( dc, bounds.x-1, + bounds.y, pRow->mRowWidth ); + } +} + +void cbPaneDrawPlugin::DrawLowerRowHandle( cbRowInfo* pRow, wxDC& dc ) +{ + wxRect& bounds = pRow->mBoundsInParent; + + // check if iter-row handles present + + if ( mpPane->IsHorizontal() ) + { + if ( pRow->mHasLowerHandle ) + + mpPane->DrawHorizHandle( dc, bounds.x, bounds.y + bounds.height - mpPane->mProps.mResizeHandleSize - 1, + pRow->mRowWidth ); + } + else + { + if ( pRow->mHasLowerHandle ) + + mpPane->DrawVertHandle( dc, bounds.x + bounds.width - mpPane->mProps.mResizeHandleSize - 1, + bounds.y, pRow->mRowWidth ); + } +} + +void cbPaneDrawPlugin::OnDrawRowHandles( cbDrawRowHandlesEvent& event ) +{ + // short-cuts + cbRowInfo* pRow = event.mpRow; + wxDC& dc = *event.mpDc; + mpPane = event.mpPane; + + // draw handles of surrounding rows first + + if ( pRow->mpPrev && pRow->mpPrev->mHasLowerHandle ) + + DrawLowerRowHandle( pRow->mpPrev, dc ); + + if ( pRow->mpNext && pRow->mpNext->mHasUpperHandle ) + + DrawUpperRowHandle( pRow->mpNext, dc ); + + // draw handles of the given row + + if ( pRow->mHasUpperHandle ) + + DrawUpperRowHandle( pRow, dc ); + + if ( pRow->mHasLowerHandle ) + + DrawLowerRowHandle( pRow, dc ); + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnDrawPaneBackground ( cbDrawPaneBkGroundEvent& event ) +{ + wxDC& dc = *event.mpDc; + mpPane = event.mpPane; + + // FOR NOW:: hard-coded + wxBrush bkBrush( mpLayout->mBorderPen.GetColour(), wxSOLID ); + + dc.SetBrush( bkBrush ); + dc.SetPen( mpLayout->mNullPen ); + + wxRect& bounds = mpPane->mBoundsInParent; + + if ( mpPane->mTopMargin >= 1 ) + + dc.DrawRectangle( bounds.x, bounds.y, + bounds.width+1, + mpPane->mTopMargin + 1); + + + if ( mpPane->mBottomMargin >= 1 ) + + dc.DrawRectangle( bounds.x, + bounds.y + bounds.height - mpPane->mBottomMargin, + bounds.width + 1, + mpPane->mBottomMargin + 1); + + + if ( mpPane->mLeftMargin >= 1 ) + + dc.DrawRectangle( bounds.x, + bounds.y + mpPane->mTopMargin - 1, + mpPane->mLeftMargin + 1, + bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2); + + + if ( mpPane->mRightMargin >= 1 ) + + dc.DrawRectangle( bounds.x + bounds.width - mpPane->mRightMargin, + bounds.y + mpPane->mTopMargin - 1, + mpPane->mRightMargin + 1, + bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + 2); + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnDrawRowBackground ( cbDrawRowBkGroundEvent& event ) +{ + // short-cuts + cbRowInfo* pRow = event.mpRow; + wxDC& dc = *event.mpDc; + mpPane = event.mpPane; + + // get ready + wxRect rowBounds = pRow->mBoundsInParent; + bool isHorizontal = event.mpPane->IsHorizontal(); + + int prevPos; + + if ( isHorizontal ) + { + prevPos = rowBounds.x; + // include one line obove and below the row + --rowBounds.y; + rowBounds.height +=2; + + --rowBounds.x; + rowBounds.width += 2; + } + else + { + prevPos = rowBounds.y; + // include one line obove and below the row + --rowBounds.x; + rowBounds.width += 2; + + --rowBounds.y; + rowBounds.height +=2; + } + +//#define TEST_BK_ERASING + +#ifdef TEST_BK_ERASING + + // DBG:: + wxBrush br0( wxColour(0,160,160), wxSOLID ); + dc.SetBrush(br0); + dc.SetPen ( mpLayout->mNullPen ); + dc.DrawRectangle( rowBounds.x, rowBounds.y, + rowBounds.width + 1, + rowBounds.height + 1 ); +#endif + + wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID ); + + dc.SetPen ( mpLayout->mNullPen ); + dc.SetBrush( bkBrush ); + + // fill background-recatangle of entire row area + dc.DrawRectangle( rowBounds.x, rowBounds.y, + rowBounds.width + 1, + rowBounds.height + 1 ); + + dc.SetBrush( wxNullBrush ); + + // draw "shaded-side-bars" for each bar + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + wxRect& bounds = pRow->mBars[i]->mBoundsInParent; + + if ( isHorizontal ) + { + DrawShade( 1, bounds, FL_ALIGN_LEFT, dc ); + DrawShade( 1, bounds, FL_ALIGN_RIGHT, dc ); + } + else + { + DrawShade( 1, bounds, FL_ALIGN_TOP, dc ); + DrawShade( 1, bounds, FL_ALIGN_BOTTOM, dc ); + } + } + + // draw extra shades to simulate "glued-bricks" effect + + // TBD:: reduce exessive drawing of shades, when the + // row handle is present, and shades will be overr-drawn anyway + + DrawUpperRowShades( pRow, dc, 1 ); // outer shade + + if ( pRow->mpPrev ) + { + DrawLowerRowShades( pRow->mpPrev, dc, 1 ); // outter shade + DrawLowerRowShades( pRow->mpPrev, dc, 0 ); // inner shade + } + + DrawLowerRowShades( pRow, dc, 1 ); + + if ( pRow->mpNext ) + { + DrawUpperRowShades( pRow->mpNext, dc, 1 ); + DrawUpperRowShades( pRow->mpNext, dc, 0 ); + } + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::DrawUpperRowShades( cbRowInfo* pRow, wxDC& dc, int level ) +{ + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + wxRect& bounds = pRow->mBars[i]->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + DrawShade( level, bounds, FL_ALIGN_TOP, dc ); + if ( level == 1 ) + { + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawPoint( bounds.x - 1, bounds.y ); + dc.SetPen( mpLayout->mLightPen ); + dc.DrawPoint( bounds.x + bounds.width , bounds.y ); + } + } + else + { + DrawShade( level, bounds, FL_ALIGN_LEFT, dc ); + if ( level == 1 ) + { + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawPoint( bounds.x, bounds.y -1 ); + dc.SetPen( mpLayout->mLightPen ); + dc.DrawPoint( bounds.x, bounds.y + bounds.height ); + } + } + } +} + +void cbPaneDrawPlugin::DrawLowerRowShades( cbRowInfo* pRow, wxDC& dc, int level ) +{ + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + wxRect& bounds = pRow->mBars[i]->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + DrawShade( level, bounds, FL_ALIGN_BOTTOM, dc ); + if ( level == 1 ) + { + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawPoint( bounds.x - 1, bounds.y + bounds.height -1 ); + dc.SetPen( mpLayout->mLightPen ); + dc.DrawPoint( bounds.x + bounds.width , bounds.y + bounds.height -1 ); + } + } + else + { + DrawShade( level, bounds, FL_ALIGN_RIGHT, dc ); + if ( level == 1 ) + { + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y -1 ); + dc.SetPen( mpLayout->mLightPen ); + dc.DrawPoint( bounds.x + bounds.width - 1, bounds.y + bounds.height ); + } + } + } +} + +void cbPaneDrawPlugin::DrawBarInnerShadeRect( cbBarInfo* pBar, wxDC& dc ) +{ + wxRect& bounds = pBar->mBoundsInParent; + + dc.SetPen( mpLayout->mDarkPen ); + + dc.DrawLine( bounds.x + bounds.width - 1, + bounds.y, + bounds.x + bounds.width - 1, + bounds.y + bounds.height ); + + dc.DrawLine( bounds.x, + bounds.y + bounds.height - 1, + bounds.x + bounds.width, + bounds.y + bounds.height -1 ); + + dc.SetPen( mpLayout->mLightPen ); + + dc.DrawLine( bounds.x, + bounds.y, + bounds.x + bounds.width - 1, + bounds.y ); + + dc.DrawLine( bounds.x, + bounds.y, + bounds.x, + bounds.y + bounds.height - 1 ); +} + +void cbPaneDrawPlugin::DrawShade( int level, wxRect& rect, int alignment, wxDC& dc ) +{ + // simulates "guled-bricks" appearence of control bars + + if ( ( alignment == FL_ALIGN_TOP && level == 1 ) || + ( alignment == FL_ALIGN_BOTTOM && level == 0 ) || + ( alignment == FL_ALIGN_LEFT && level == 1 ) || + ( alignment == FL_ALIGN_RIGHT && level == 0 ) + ) + + dc.SetPen( mpLayout->mDarkPen ); + else + dc.SetPen( mpLayout->mLightPen ); + + if ( alignment == FL_ALIGN_TOP ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y, + rect.x + rect.width - 1, + rect.y ); + else + dc.DrawLine( rect.x - 1, + rect.y - 1, + rect.x + rect.width + 0, + rect.y - 1 ); + } + else + if ( alignment == FL_ALIGN_BOTTOM ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y + rect.height - 1, + rect.x + rect.width, + rect.y + rect.height - 1 ); + else + dc.DrawLine( rect.x - 1, + rect.y + rect.height, + rect.x + rect.width + 1, + rect.y + rect.height ); + } + else + if ( alignment == FL_ALIGN_LEFT ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y, + rect.x, + rect.y + rect.height - 1 ); + else + dc.DrawLine( rect.x - 1, + rect.y - 1, + rect.x - 1, + rect.y + rect.height ); + } + else + if ( alignment == FL_ALIGN_RIGHT ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x + rect.width - 1, + rect.y, + rect.x + rect.width - 1, + rect.y + rect.height ); + else + { + dc.DrawLine( rect.x + rect.width, + rect.y - 1, + rect.x + rect.width, + rect.y + rect.height + 1 ); + } + } +} + +void cbPaneDrawPlugin::DrawShade1( int level, wxRect& rect, int alignment, wxDC& dc ) +{ + // simulates "guled-bricks" appearence of control bars + + if ( ( alignment == FL_ALIGN_TOP && level == 1 ) || + ( alignment == FL_ALIGN_BOTTOM && level == 0 ) || + ( alignment == FL_ALIGN_LEFT && level == 1 ) || + ( alignment == FL_ALIGN_RIGHT && level == 0 ) + ) + + dc.SetPen( mpLayout->mDarkPen ); + else + dc.SetPen( mpLayout->mLightPen ); + + if ( alignment == FL_ALIGN_TOP ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y, + rect.x + rect.width, + rect.y ); + else + dc.DrawLine( rect.x, + rect.y - 1, + rect.x + rect.width, + rect.y - 1 ); + } + else + if ( alignment == FL_ALIGN_BOTTOM ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y + rect.height - 1, + rect.x + rect.width, + rect.y + rect.height - 1 ); + else + dc.DrawLine( rect.x, + rect.y + rect.height, + rect.x + rect.width, + rect.y + rect.height ); + } + else + if ( alignment == FL_ALIGN_LEFT ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x, + rect.y, + rect.x, + rect.y + rect.height ); + else + dc.DrawLine( rect.x - 1, + rect.y, + rect.x - 1, + rect.y + rect.height ); + } + else + if ( alignment == FL_ALIGN_RIGHT ) + { + if ( level == 0 ) + + dc.DrawLine( rect.x + rect.width - 1, + rect.y, + rect.x + rect.width - 1, + rect.y + rect.height ); + else + { + dc.DrawLine( rect.x + rect.width, + rect.y , + rect.x + rect.width, + rect.y + rect.height ); + } + } +} + +void cbPaneDrawPlugin::DrawPaneShade( wxDC& dc, int alignment ) +{ + if ( !mpPane->mProps.mShow3DPaneBorderOn ) return; + + wxRect bounds = mpPane->mBoundsInParent; + + bounds.x += mpPane->mLeftMargin; + bounds.y += mpPane->mTopMargin; + bounds.width -= ( mpPane->mLeftMargin + mpPane->mRightMargin ); + bounds.height -= ( mpPane->mTopMargin + mpPane->mBottomMargin ); + + DrawShade( 0, bounds, alignment, dc ); + DrawShade( 1, bounds, alignment, dc ); +} + +void cbPaneDrawPlugin::DrawPaneShadeForRow( cbRowInfo* pRow, wxDC& dc ) +{ + if ( !mpPane->mProps.mShow3DPaneBorderOn ) return; + + // do not draw decoration, if pane has "vainished" + if ( mpPane->mPaneWidth < 0 || + mpPane->mPaneHeight < 0 ) + + return; + + wxRect bounds = pRow->mBoundsInParent; + + if ( mpPane->mAlignment == FL_ALIGN_TOP || + mpPane->mAlignment == FL_ALIGN_BOTTOM ) + { + --bounds.y; + bounds.height += 2; + + DrawShade1( 0, bounds, FL_ALIGN_LEFT, dc ); + DrawShade1( 1, bounds, FL_ALIGN_LEFT, dc ); + DrawShade1( 0, bounds, FL_ALIGN_RIGHT, dc ); + DrawShade1( 1, bounds, FL_ALIGN_RIGHT, dc ); + + if ( !pRow->mpNext ) + DrawPaneShade( dc, FL_ALIGN_BOTTOM ); + + if ( !pRow->mpPrev ) + DrawPaneShade( dc, FL_ALIGN_TOP ); + } + else + { + --bounds.x; + bounds.width += 2; + + DrawShade1( 0, bounds, FL_ALIGN_TOP, dc ); + DrawShade1( 1, bounds, FL_ALIGN_TOP, dc ); + DrawShade1( 0, bounds, FL_ALIGN_BOTTOM, dc ); + DrawShade1( 1, bounds, FL_ALIGN_BOTTOM, dc ); + + if ( !pRow->mpNext ) + DrawPaneShade( dc, FL_ALIGN_RIGHT ); + + if ( !pRow->mpPrev ) + DrawPaneShade( dc, FL_ALIGN_LEFT ); + } +} + +void cbPaneDrawPlugin::OnDrawPaneDecorations( cbDrawPaneDecorEvent& event ) +{ + wxDC& dc = *event.mpDc; + + cbDockPane* pPane = event.mpPane; + + RowArrayT& lst = pPane->GetRowList(); + + // FIXME:: this is a workaround for some glitches + + if ( lst.Count() ) + { + cbRowInfo* pLastRow = lst[ lst.Count() - 1 ]; + + pPane->PaintRowBackground( pLastRow, dc ); + pPane->PaintRowDecorations( pLastRow, dc ); + pPane->PaintRowHandles( pLastRow, dc ); + } + + if ( !pPane->mProps.mShow3DPaneBorderOn ) return; + + // do not draw decoration, if pane is completely hidden + if ( event.mpPane->mPaneWidth < 0 || + event.mpPane->mPaneHeight < 0 ) + + return; + + DrawPaneShade( dc, FL_ALIGN_TOP ); + DrawPaneShade( dc, FL_ALIGN_BOTTOM ); + DrawPaneShade( dc, FL_ALIGN_LEFT ); + DrawPaneShade( dc, FL_ALIGN_RIGHT ); + + event.Skip(); // pass event to the next plugin +} + +// bar decoration/sizing handlers + +void cbPaneDrawPlugin::OnDrawBarDecorations( cbDrawBarDecorEvent& event ) +{ + cbBarInfo* pBar = event.mpBar; + wxDC& dc = *event.mpDc; + + // draw brick borders + + wxRect& rect = event.mBoundsInParent; + + dc.SetPen( mpLayout->mLightPen ); + + // horiz + dc.DrawLine( rect.x, rect.y, + rect.x + rect.width-1, rect.y ); + + // vert + dc.DrawLine( rect.x, rect.y, + rect.x, rect.y + rect.height-1 ); + + + dc.SetPen( mpLayout->mDarkPen ); + + // vert + dc.DrawLine( rect.x + rect.width-1, rect.y, + rect.x + rect.width-1, rect.y + rect.height-1 ); + + // horiz + dc.DrawLine( rect.x, rect.y + rect.height-1, + rect.x + rect.width, rect.y + rect.height-1 ); + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnDrawBarHandles( cbDrawBarHandlesEvent& event ) +{ + // short-cuts + cbBarInfo* pBar = event.mpBar; + wxDC& dc = *event.mpDc; + mpPane = event.mpPane; + + // draw handles around the bar if present + + if ( pBar->mHasLeftHandle || + pBar->mHasRightHandle ) + { + wxRect& bounds = pBar->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + if ( pBar->mHasLeftHandle ) + + mpPane->DrawVertHandle( dc, bounds.x - mpPane->mProps.mResizeHandleSize -1, + bounds.y, bounds.height ); + + if ( pBar->mHasRightHandle ) + + mpPane->DrawVertHandle( dc, + bounds.x + bounds.width -1, + bounds.y, bounds.height ); + } + else + { + if ( pBar->mHasLeftHandle ) + + mpPane->DrawHorizHandle( dc, bounds.x, + bounds.y - mpPane->mProps.mResizeHandleSize - 1, + bounds.width ); + + if ( pBar->mHasRightHandle ) + + mpPane->DrawHorizHandle( dc, bounds.x, + bounds.y + bounds.height - 1, + bounds.width ); + } + } + + event.Skip(); // pass event to the next plugin +} + +void cbPaneDrawPlugin::OnStartDrawInArea( cbStartDrawInAreaEvent& event ) +{ + // DBG:: + wxASSERT( mpClntDc == NULL ); + + // FOR NOW:: create/destroy client-dc upon each drawing + mpClntDc = new wxClientDC( &mpLayout->GetParentFrame() ); + + (*event.mppDc) = mpClntDc; + + mpClntDc->SetClippingRegion( event.mArea.x, event.mArea.y, + event.mArea.width, event.mArea.height ); +} + +void cbPaneDrawPlugin::OnFinishDrawInArea( cbFinishDrawInAreaEvent& event ) +{ + // DBG:: + wxASSERT( mpClntDc ); + + delete mpClntDc; + + mpClntDc = NULL; +} + diff --git a/contrib/src/fl/rowdragpl.cpp b/contrib/src/fl/rowdragpl.cpp new file mode 100644 index 0000000000..e0ea5ad12f --- /dev/null +++ b/contrib/src/fl/rowdragpl.cpp @@ -0,0 +1,1465 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "rowdragpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/rowdragpl.h" + +#define MINIMAL_ROW_DRAG_OFS 5 + +// parameters for row-hints of NC-look + +#define TRIANGLE_OFFSET 2 +#define TRIANGLE_TO_PAT_GAP 2 +#define PAT_OFFSET 2 +#define COLLAPSED_ICON_WIDTH 45 +#define COLLAPSED_ICON_HEIGHT 9 +#define ROW_DRAG_HINT_WIDTH 10 +#define ICON_TRIAN_WIDTH 6 +#define ICON_TRIAN_HEIGHT 3 + +/***** Implementation for class cbHiddenBarInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo, wxObject ) + +/***** Implementation for class cbRowDragPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbRowDragPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbRowDragPlugin, cbPluginBase ) + + EVT_PL_LEFT_DOWN ( cbRowDragPlugin::OnLButtonDown ) + EVT_PL_LEFT_UP ( cbRowDragPlugin::OnLButtonUp ) + EVT_PL_MOTION ( cbRowDragPlugin::OnMouseMove ) + + EVT_PL_DRAW_PANE_DECOR ( cbRowDragPlugin::OnDrawPaneBackground ) + +END_EVENT_TABLE() + +// FIXME:: how to eliminated these cut&pasted constructors? + +cbRowDragPlugin::cbRowDragPlugin(void) + + : mHightColor ( 192, 192, 255 ), + mLowColor ( 192, 192, 192 ), + mTrianInnerColor ( 0,0,255 ), + mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), + + mDragStarted ( FALSE ), + mDecisionMode ( FALSE ), + mCurDragOfs ( 0 ), + mCaptureIsOn ( FALSE ), + mSvTopMargin ( -1 ), + mSvBottomMargin ( -1 ), + mSvLeftMargin ( -1 ), + mSvRightMargin ( -1 ), + + mpPaneImage ( NULL ), + mpRowImage ( NULL ), + mpCombinedImage ( NULL ), + + mpRowInFocus ( NULL ), + mCollapsedIconInFocus( -1 ), + + mpPane ( NULL ) +{ +} + +cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask ) + + : cbPluginBase( pLayout, paneMask ), + + mHightColor ( 192, 192, 255 ), + mLowColor ( 192, 192, 192 ), + mTrianInnerColor ( 0,0,255 ), + mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), + + mDragStarted ( FALSE ), + mDecisionMode ( FALSE ), + mCurDragOfs ( 0 ), + mCaptureIsOn ( FALSE ), + mSvTopMargin ( -1 ), + mSvBottomMargin ( -1 ), + mSvLeftMargin ( -1 ), + mSvRightMargin ( -1 ), + + mpPaneImage ( NULL ), + mpRowImage ( NULL ), + mpCombinedImage ( NULL ), + + mpRowInFocus ( NULL ), + mCollapsedIconInFocus( -1 ), + + mpPane ( NULL ) +{ +} + +cbRowDragPlugin::~cbRowDragPlugin() +{ +} + +// handlers for plugin events +void cbRowDragPlugin::OnMouseMove( cbMotionEvent& event ) +{ + // short-cuts + wxPoint pos = event.mPos; + mpPane = event.mpPane; + + mpPane->PaneToFrame( &pos.x, &pos.y ); + + if ( !mDragStarted ) + { + if ( mDecisionMode && mpRowInFocus ) + { + int ofs; + + if ( mpPane->IsHorizontal() ) + + ofs = pos.y - mDragOrigin.y; + else + ofs = pos.x - mDragOrigin.x; + + // check if the item was dragged sufficeintly + // far, enough to consider that user really intends + // to drag it + + if ( ofs >= MINIMAL_ROW_DRAG_OFS || + ofs <= -MINIMAL_ROW_DRAG_OFS ) + { + // DBG:: + //.wxPoint pos = event.mPos; + //wxPoint drg = mDragOrigin; + //int dif = event.mPos.x - mDragOrigin.x; + + mDragStarted = TRUE; + mDecisionMode = FALSE; + mDragOrigin = pos; + + PrepareForRowDrag(); + return; + } + + // this plugin "eats" all mouse input while item is dragged, + return; + } + + cbRowInfo* pRow = GetFirstRow(); + + bool focusFound = FALSE; + + while( pRow ) + { + if ( HitTestRowDragHint( pRow, pos ) ) + { + CheckPrevItemInFocus( pRow, -1 ); + SetMouseCapture( TRUE ); + + focusFound = TRUE; + + mpRowInFocus = pRow; + mCollapsedIconInFocus = -1; + break; + } + + pRow = pRow->mpNext; + } + + if ( !focusFound ) + { + int hrCnt = GetHRowsCountForPane( event.mpPane ); + + for( int i = 0; i != hrCnt; ++i ) + { + if ( HitTestCollapsedRowIcon( i, pos ) ) + { + CheckPrevItemInFocus( NULL, i ); + SetMouseCapture( TRUE ); + + focusFound = TRUE; + + mCollapsedIconInFocus = i; + mpRowInFocus = NULL; + break; + } + } + } + + if ( !focusFound && ItemIsInFocus() ) + { + // kill focus from item previously been in focus + UnhiglightItemInFocus(); + + mpRowInFocus = NULL; + mCollapsedIconInFocus = -1; + SetMouseCapture( FALSE ); + } + + if ( !ItemIsInFocus() ) + + // delegate it to other plugins + event.Skip(); + } + else + { + // otherwise mouse pointer moves, when dragging is started + + if ( mpPane->IsHorizontal() ) + { + // DBG:: + wxPoint p = event.mPos; + wxPoint d = mDragOrigin; + int dif = event.mPos.x - mDragOrigin.x; + + // row is dragged up or down; + ShowDraggedRow( pos.y - mDragOrigin.y ); + } + else + { + // DBG:: + wxPoint p = event.mPos; + wxPoint d = mDragOrigin; + int dif = event.mPos.x - mDragOrigin.x; + + // row is dragged left or right + ShowDraggedRow( pos.x - mDragOrigin.x ); + } + + // this plugin "eats" all mouse input while item is dragged, + } +} + +void cbRowDragPlugin::OnLButtonDown( cbLeftDownEvent& event ) +{ + mpPane = event.mpPane; + + // DBG:: + wxASSERT( !mDragStarted && !mDecisionMode ); + + if ( ItemIsInFocus() ) + { + mDecisionMode = TRUE; + + wxPoint pos = event.mPos; + mpPane->PaneToFrame( &pos.x, &pos.y ); + + mDragOrigin = pos; + + SetMouseCapture( TRUE ); + } + else + // propagate event to other plugins + event.Skip(); +} + +void cbRowDragPlugin::OnLButtonUp ( cbLeftUpEvent& event ) +{ + if ( !mDragStarted && !mDecisionMode ) + { + event.Skip(); + return; + } + + mpPane = event.mpPane; + + if ( mDecisionMode ) + { + cbDockPane* pPane = mpPane; + + SetMouseCapture( FALSE ); + + mDecisionMode = FALSE; + mDragStarted = FALSE; + + wxPoint frmPos = event.mPos; + pPane->PaneToFrame( &frmPos.x, &frmPos.y ); + + if ( mpRowInFocus ) + { + CollapseRow( mpRowInFocus ); + mpRowInFocus = 0; + } + else + { + ExpandRow( mCollapsedIconInFocus ); + mCollapsedIconInFocus = -1; + } + + mpRowInFocus = NULL; + mpPane = pPane; + + pPane->FrameToPane( &frmPos.x, &frmPos.y ); + + // give it another try after relayouting bars + + cbMotionEvent moveEvt( frmPos, pPane ); + this->OnMouseMove( moveEvt ); + + // this plugin has "eaten" the mouse-up event + + return; + } + else + { + // otherwise, the dragged row was dropped, determine + // where to insert it + + // restore initial pane appearence + ShowPaneImage(); + FinishOnScreenDraw(); + + cbRowInfo* pRow = GetFirstRow(); + + mpLayout->GetUpdatesManager().OnStartChanges(); + + pRow->mUMgrData.SetDirty(TRUE); + + cbBarInfo* pBar = mpRowInFocus->mBars[0]; + + while ( pBar ) + { + pBar->mUMgrData.SetDirty(TRUE); + + if ( pBar->mpBarWnd ) + { + // do complete refresh + pBar->mpBarWnd->Show(FALSE); + pBar->mpBarWnd->Show(TRUE); + } + + pBar = pBar->mpNext; + } + + while( pRow ) + { + if ( mCurDragOfs < pRow->mRowY ) + { + InsertDraggedRowBefore( pRow ); + break; + } + + pRow = pRow->mpNext; + } + + if ( pRow == NULL ) InsertDraggedRowBefore( NULL ); + + mpRowInFocus = NULL; + + mpLayout->RecalcLayout(FALSE); + + // finish change "transaction" + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); + + // finish drag action + SetMouseCapture( FALSE ); + mDragStarted = FALSE; + } +} + +void cbRowDragPlugin::OnDrawPaneBackground ( cbDrawPaneDecorEvent& event ) +{ + mpPane = event.mpPane; + + // FIXME:: this may harm operation of other plugins + + if ( GetNextHandler() && mpPane->GetRowList().GetCount() ) + { + // first, let other plugins add their decorations now + + GetNextHandler()->ProcessEvent( event ); + event.Skip(FALSE); + } + + wxClientDC dc( &mpLayout->GetParentFrame() ); + + dc.SetClippingRegion( mpPane->mBoundsInParent.x, + mpPane->mBoundsInParent.y, + mpPane->mBoundsInParent.width, + mpPane->mBoundsInParent.height ); + + int cnt = GetHRowsCountForPane( event.mpPane ); + + if ( cnt > 0 ) + + DrawCollapsedRowsBorder( dc ); + + if ( mpPane->GetRowList().GetCount() ) + + DrawRowsDragHintsBorder( dc ); + + cbRowInfo* pRow = GetFirstRow(); + + while( pRow ) + { + DrawRowDragHint( pRow, dc, FALSE ); + pRow = pRow->mpNext; + } + + for( int i = 0; i != cnt; ++i ) + + DrawCollapsedRowIcon(i, dc, FALSE ); +} + +int cbRowDragPlugin::GetHRowsCountForPane( cbDockPane* pPane ) +{ + wxNode* pNode = mHiddenBars.First(); + + int maxIconNo = -1; + + while( pNode ) + { + cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data(); + + if ( pHBInfo->mAlignment == pPane->mAlignment ) + + maxIconNo = wxMax( maxIconNo, pHBInfo->mIconNo ); + + pNode = pNode->Next(); + } + + return ( maxIconNo + 1 ); +} + +int cbRowDragPlugin::GetCollapsedRowIconHeight() +{ + return COLLAPSED_ICON_HEIGHT; +} + +int cbRowDragPlugin::GetRowDragHintWidth() +{ + return ROW_DRAG_HINT_WIDTH; +} + +void cbRowDragPlugin::SetPaneMargins() +{ + int hiddenRowsCnt = GetHRowsCountForPane( mpPane ); + + if ( mSvTopMargin == -1 ) + { + mSvTopMargin = mpPane->mTopMargin; + mSvBottomMargin = mpPane->mBottomMargin; + mSvLeftMargin = mpPane->mLeftMargin; + mSvRightMargin = mpPane->mRightMargin; + } + + if ( mpPane->IsHorizontal() ) + { + mpPane->mTopMargin = mSvTopMargin; + mpPane->mBottomMargin = ( hiddenRowsCnt == 0 ) + ? mSvBottomMargin + : mSvBottomMargin + GetCollapsedRowIconHeight(); + + mpPane->mLeftMargin = mSvLeftMargin + GetRowDragHintWidth(); + mpPane->mRightMargin = mSvRightMargin; + } + else + { + mpPane->mTopMargin = mSvTopMargin; + mpPane->mBottomMargin = mSvBottomMargin + GetRowDragHintWidth(); + + mpPane->mLeftMargin = mSvLeftMargin; + mpPane->mRightMargin = ( hiddenRowsCnt == 0 ) ? + mSvRightMargin : mSvRightMargin + GetCollapsedRowIconHeight(); + } +} + +void cbRowDragPlugin::OnInitPlugin() +{ + cbDockPane** panes = mpLayout->GetPanesArray(); + + for( int i = 0; i != MAX_PANES; ++i ) + + if ( panes[i]->MatchesMask( mPaneMask ) ) + { + mpPane = panes[i]; + + SetPaneMargins(); + } +} + +/*** helpers for drag&drop ***/ + +void cbRowDragPlugin::SetMouseCapture( bool captureOn ) +{ + if ( mCaptureIsOn == captureOn ) return; + + if ( captureOn ) + { + mpLayout->CaptureEventsForPane( mpPane ); + mpLayout->CaptureEventsForPlugin( this ); + } + else + { + mpLayout->ReleaseEventsFromPane( mpPane ); + mpLayout->ReleaseEventsFromPlugin( this ); + } + + mCaptureIsOn = captureOn; +} + +void cbRowDragPlugin::UnhiglightItemInFocus() +{ + wxClientDC dc( &mpLayout->GetParentFrame() ); + + if ( mpRowInFocus ) + + DrawRowDragHint( mpRowInFocus, dc, FALSE ); + else + if ( mCollapsedIconInFocus != - 1 ) + + DrawCollapsedRowIcon( mCollapsedIconInFocus, dc, FALSE ); +} + +void cbRowDragPlugin::ShowDraggedRow( int offset ) +{ + // create combined image of pane and dragged + // row on it, in the mpCombinedImage bitmap + + if ( mpPane->IsHorizontal() ) + { + if ( mInitialRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height ) + + offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitialRowOfs; + + if ( mInitialRowOfs + offset < mCombRect.y ) + + offset = mCombRect.y - mInitialRowOfs; + + int x, y = mInitialRowOfs + offset; + mpPane->FrameToPane( &x, &y ); + mCurDragOfs = y; + } + else + { + if ( mInitialRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width ) + + offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitialRowOfs; + + if ( mInitialRowOfs + offset < mCombRect.x ) + + offset = mCombRect.x - mInitialRowOfs; + + int x = mInitialRowOfs + offset, y; + mpPane->FrameToPane( &x, &y ); + mCurDragOfs = x; + } + + wxMemoryDC rowImgDc; + rowImgDc.SelectObject ( *mpRowImage ); + + wxMemoryDC paneImgDc; + paneImgDc.SelectObject( *mpPaneImage ); + + wxMemoryDC combImgDc; + combImgDc.SelectObject( *mpCombinedImage ); + + combImgDc.Blit( 0,0, mCombRect.width, mCombRect.height, + &paneImgDc, 0,0, wxCOPY ); + + if ( mpPane->IsHorizontal() ) + { + combImgDc.Blit( 0, mInitialRowOfs + offset - mCombRect.y, + mCombRect.width, mRowImgDim.y, + &rowImgDc, 0,0, wxCOPY ); + } + else + { + combImgDc.Blit( mInitialRowOfs + offset - mCombRect.x, + 0, + mRowImgDim.x, mCombRect.height, + &rowImgDc, 0,0, wxCOPY ); + } + + int scrX = mCombRect.x, + scrY = mCombRect.y; + + mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY ); + + mpScrDc->Blit( scrX, scrY, mCombRect.width, mCombRect.height, + &combImgDc, 0,0, wxCOPY ); + + rowImgDc .SelectObject( wxNullBitmap ); + paneImgDc.SelectObject( wxNullBitmap ); + combImgDc.SelectObject( wxNullBitmap ); +} + +wxBitmap* cbRowDragPlugin::CaptureDCArea( wxDC& dc, wxRect& area ) +{ + wxBitmap* pBmp = new wxBitmap( int(area.width), int(area.height) ); + + wxMemoryDC mdc; + mdc.SelectObject( *pBmp ); + + mdc.Blit( 0,0, area.width, area.height, &dc, area.x, area.y, wxCOPY ); + mdc.SelectObject( wxNullBitmap ); + + return pBmp; +} + +void cbRowDragPlugin::PrepareForRowDrag() +{ + wxRect rowBounds = mpRowInFocus->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + mCombRect = mpPane->mBoundsInParent; + + mCombRect.x += mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1; + mCombRect.y += mpPane->mTopMargin; + + mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin - ROW_DRAG_HINT_WIDTH - 1 - 1; + mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin; + + mCombRect.height += 2*rowBounds.height; + mCombRect.y -= rowBounds.height; + mInitialRowOfs = rowBounds.y; + + rowBounds.y -= 1; + rowBounds.height += 2; + rowBounds.x = mCombRect.x; + rowBounds.width = mCombRect.width; + + mRowImgDim.y = rowBounds.height; + } + else + { + mCombRect = mpPane->mBoundsInParent; + + mCombRect.y += mpPane->mTopMargin - 1; + mCombRect.x += mpPane->mLeftMargin - 1; + ; + mCombRect.height -= mpPane->mTopMargin + mpPane->mBottomMargin - ROW_DRAG_HINT_WIDTH - 1 - 1; + mCombRect.width -= mpPane->mLeftMargin + mpPane->mRightMargin; + + mCombRect.width += 2*rowBounds.width; + mCombRect.x -= rowBounds.width; + mInitialRowOfs = rowBounds.x; + + rowBounds.x -= 1; + rowBounds.width += 2; + rowBounds.y = mCombRect.y; + rowBounds.height = mCombRect.height; + + mRowImgDim.x = rowBounds.width; + } + // output cobination results onto frame's client area + wxScreenDC::StartDrawingOnTop(&mpLayout->GetParentFrame()); + mpScrDc = new wxScreenDC(); + + int x = mCombRect.x, y = mCombRect.y; + mpLayout->GetParentFrame().ClientToScreen( &x, &y ); + + wxRect scrRect = mCombRect; + scrRect.x = x; + scrRect.y = y; + + mpPaneImage = CaptureDCArea( *mpScrDc, scrRect ); + + wxMemoryDC mdc; + mdc.SelectObject( *mpPaneImage ); + mdc.SetDeviceOrigin( -mCombRect.x, -mCombRect.y ); + + DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mDarkPen ); + DrawRectShade( rowBounds, mdc, 0, mpLayout->mLightPen, mpLayout->mBlackPen ); + + mpRowImage = CaptureDCArea( mdc, rowBounds ); + + // draw dark empty-row placeholder + DrawEmptyRow( mdc, rowBounds ); + + //DrawRectShade( rowBounds, mdc, 0, mpLayout->mGrayPen, mpLayout->mDarkPen ); + DrawRectShade( rowBounds, mdc, -1, mpLayout->mGrayPen, mpLayout->mGrayPen ); + + mdc.SelectObject( wxNullBitmap ); + + mpCombinedImage = new wxBitmap( int(mCombRect.width), int(mCombRect.height) ); + + // show it for the first time + ShowDraggedRow( 0 ); +} + +void cbRowDragPlugin::DrawEmptyRow( wxDC& dc, wxRect& rowBounds ) +{ + wxBrush bkBrush( mpLayout->mDarkPen.GetColour(), wxSOLID ); + + // paint the "dark" empty-row placeholder + + dc.SetBrush( bkBrush ); + dc.SetPen ( mpLayout->mNullPen ); + + dc.DrawRectangle( rowBounds.x, rowBounds.y, + rowBounds.width+1, rowBounds.height+1 ); + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::ShowPaneImage() +{ + int scrX = 0, scrY = 0; + + mpLayout->GetParentFrame().ClientToScreen( &scrX, &scrY ); + + wxMemoryDC mdc; + mdc.SelectObject( *mpPaneImage ); + + mpScrDc->Blit( mCombRect.x + scrX, mCombRect.y + scrY, + mCombRect.width, mCombRect.height, + &mdc, 0,0, wxCOPY ); + + mdc.SelectObject( wxNullBitmap ); +} + +void cbRowDragPlugin::FinishOnScreenDraw() +{ + wxScreenDC::EndDrawingOnTop(); + + delete mpScrDc; + delete mpCombinedImage; + delete mpPaneImage; + delete mpRowImage; + + mpScrDc = NULL; + + mpCombinedImage = mpPaneImage = mpRowImage = NULL; +} + +void cbRowDragPlugin::CollapseRow( cbRowInfo* pRow ) +{ + int iconCnt = GetHRowsCountForPane( mpPane ); + + mpLayout->GetUpdatesManager().OnStartChanges(); + + cbBarInfo* pBar = pRow->mBars[0]; + + int rowNo = 0; + + cbRowInfo* pCur = pRow; + while( pCur->mpPrev ) { ++rowNo; pCur = pCur->mpPrev; } + + while( pBar ) + { + cbHiddenBarInfo* pHBInfo = new cbHiddenBarInfo(); + + pHBInfo->mpBar = pBar; + pHBInfo->mRowNo = rowNo; + pHBInfo->mIconNo = iconCnt; + pHBInfo->mAlignment = mpPane->mAlignment; + + mHiddenBars.Append( (wxObject*) pHBInfo ); + + // hide it + if ( pBar->mpBarWnd ) + + pBar->mpBarWnd->Show( FALSE ); + + pBar->mState = wxCBAR_HIDDEN; + + cbBarInfo* pNext = pBar->mpNext; + + pBar->mpRow = NULL; + pBar->mpNext = NULL; + pBar->mpPrev = NULL; + + pBar = pNext; + } + + mpPane->GetRowList().Remove( pRow ); + mpPane->InitLinksForRows(); + + delete pRow; + + SetPaneMargins(); + + mpLayout->RecalcLayout(FALSE); + + mpRowInFocus = NULL; + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); +} + +void cbRowDragPlugin::ExpandRow( int collapsedIconIdx ) +{ + mpLayout->GetUpdatesManager().OnStartChanges(); + + cbRowInfo* pNewRow = new cbRowInfo(); + + wxNode* pNode = mHiddenBars.First(); + + int rowNo = 0; + + // move bars from internal list to the newly expanded row + + while( pNode ) + { + cbHiddenBarInfo* pHBInfo = (cbHiddenBarInfo*)pNode->Data(); + + if ( pHBInfo->mAlignment == mpPane->mAlignment && + pHBInfo->mIconNo == collapsedIconIdx ) + { + rowNo = pHBInfo->mRowNo; + + if ( pHBInfo->mpBar->mState == wxCBAR_HIDDEN ) + { + pNewRow->mBars.Add( pHBInfo->mpBar ); + + pHBInfo->mpBar->mState = ( mpPane->IsHorizontal() ) + ? wxCBAR_DOCKED_HORIZONTALLY + : wxCBAR_DOCKED_VERTICALLY; + } + + // remove bar info from internal list + + wxNode* pNext = pNode->Next(); + + delete pHBInfo; + mHiddenBars.DeleteNode( pNode ); + + pNode = pNext; + } + else + { + // decrease incon numbers with higher indicies, since this + // row is now removed from the hidden-rows list + + if ( pHBInfo->mIconNo > collapsedIconIdx && + pHBInfo->mAlignment == mpPane->mAlignment ) + + --pHBInfo->mIconNo; + + pNode = pNode->Next(); + } + } + + mpPane->InitLinksForRow( pNewRow ); + + // insert row into pane at it's original position + + if ( pNewRow->mBars.GetCount() ) + { + cbRowInfo* beforeRowNode = mpPane->GetRow( rowNo ); + + mpPane->InsertRow( pNewRow, beforeRowNode ); + } + else + delete pNewRow; + + SetPaneMargins(); + + mpLayout->RecalcLayout(FALSE); + + mCollapsedIconInFocus = -1; + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); + + + /* + wxNode* pRowNode = mHiddenRows.Nth( collapsedIconIdx ); + + mpLayout->GetUpdatesManager().OnStartChanges(); + + // insert at the end of rows list + mpPane->InsertRow( pRowNode, NULL ); + + int success = mHiddenRows.DeleteNode( pRowNode ); + // DBG:: + wxASSERT( success ); + + SetPaneMargins(); + + mpLayout->RecalcLayout(FALSE); + + mCollapsedIconInFocus = -1; + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); + */ +} + +void cbRowDragPlugin::InsertDraggedRowBefore( cbRowInfo* pBeforeRow ) +{ + if ( mpRowInFocus != pBeforeRow && + mpRowInFocus->mpNext != pBeforeRow + ) + { + mpPane->GetRowList().Remove( mpRowInFocus ); + + mpPane->InsertRow( mpRowInFocus, pBeforeRow ); + } + else + { + // otherwise, nothing has happned (row positions do not change) + + //wxClientDC dc( &mpLayout->GetParentFrame() ); + + //mpPane->PaintRow( mpRowInFocus, dc ); + //DrawRowDragHint( mpRowInFocus, dc, FALSE ); + } +} + +bool cbRowDragPlugin::ItemIsInFocus() +{ + return ( mpRowInFocus || mCollapsedIconInFocus != - 1 ); +} + +void cbRowDragPlugin::CheckPrevItemInFocus( cbRowInfo* pRow, int iconIdx ) +{ + wxClientDC dc( &mpLayout->GetParentFrame() ); + + if ( pRow != NULL && mpRowInFocus == pRow ) return; + if ( iconIdx != -1 && mCollapsedIconInFocus == iconIdx ) return; + + UnhiglightItemInFocus(); + + if ( iconIdx != - 1 ) + + DrawCollapsedRowIcon( iconIdx, dc, TRUE ); + + else + if ( pRow != NULL ) + + DrawRowDragHint( pRow, dc, TRUE ); +} + +cbRowInfo* cbRowDragPlugin::GetFirstRow() +{ + return ( mpPane->GetRowList().GetCount() ) + ? mpPane->GetRowList()[0] + : NULL; +} + +/*** "hard-coded" metafile for NN-look ***/ + +void cbRowDragPlugin::DrawTrianUp( wxRect& inRect, wxDC& dc ) +{ + int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2; + + wxBrush br( mTrianInnerColor, wxSOLID ); + + dc.SetBrush( br ); + dc.SetPen( mpLayout->mBlackPen ); + + wxPoint points[3]; + points[0].x = inRect.x + xOfs; + points[0].y = inRect.y + inRect.height - 1; + points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2 + 1; + points[1].y = inRect.y + inRect.height - 2 - ICON_TRIAN_HEIGHT; + points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH+1; + points[2].y = inRect.y + inRect.height - 1; + + dc.DrawPolygon( 3, points ); + + // higlight upper-right edge of triangle + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( points[2].x, points[2].y, + points[0].x, points[0].y ); + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::DrawTrianDown( wxRect& inRect, wxDC& dc ) +{ + int xOfs = (inRect.width - ICON_TRIAN_WIDTH)/2; + + wxBrush br( mTrianInnerColor, wxSOLID ); + + dc.SetBrush( br ); + dc.SetPen( mpLayout->mBlackPen ); + + wxPoint points[3]; + points[0].x = inRect.x + xOfs; + points[0].y = inRect.y; + points[1].x = inRect.x + xOfs + ICON_TRIAN_WIDTH; + points[1].y = inRect.y; + points[2].x = inRect.x + xOfs + ICON_TRIAN_WIDTH/2; + points[2].y = inRect.y + ICON_TRIAN_HEIGHT; + + dc.DrawPolygon( 3, points ); + + // higlight upper-right edge of triangle + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( points[2].x, points[2].y, + points[1].x, points[1].y ); + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::DrawTrianRight( wxRect& inRect, wxDC& dc ) +{ + int yOfs = (inRect.height - ICON_TRIAN_WIDTH)/2; + + wxBrush br( mTrianInnerColor, wxSOLID ); + + dc.SetBrush( br ); + dc.SetPen( mpLayout->mBlackPen ); + + wxPoint points[3]; + points[0].x = inRect.x; + points[0].y = inRect.y + yOfs + ICON_TRIAN_WIDTH; + points[1].x = inRect.x; + points[1].y = inRect.y + yOfs; + points[2].x = inRect.x + ICON_TRIAN_HEIGHT; + points[2].y = inRect.y + yOfs + ICON_TRIAN_WIDTH/2; + + dc.DrawPolygon( 3, points ); + + // higlight upper-right edge of triangle + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( points[0].x, points[0].y, + points[2].x, points[2].y ); + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::Draw3DPattern( wxRect& inRect, wxDC& dc ) +{ + for( int y = inRect.y; y < inRect.y + inRect.height; y+=3 ) + + for( int x = inRect.x; x < inRect.x + inRect.width; x+=3 ) + { + dc.SetPen( mpLayout->mLightPen ); + dc.DrawPoint( x,y ); + dc.SetPen( mpLayout->mBlackPen ); + dc.DrawPoint( x+1, y+1 ); + } +} + +void cbRowDragPlugin::DrawRombShades( wxPoint& p1, wxPoint& p2, + wxPoint& p3, wxPoint& p4, + wxDC& dc ) +{ + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( p1.x, p1.y, p2.x, p2.y ); + dc.DrawLine( p2.x, p2.y, p3.x, p3.y ); + dc.SetPen( mpLayout->mDarkPen ); + dc.DrawLine( p3.x, p3.y, p4.x, p4.y ); + dc.DrawLine( p4.x, p4.y, p1.x, p1.y ); +} + +void cbRowDragPlugin::DrawOrtoRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) +{ + dc.SetBrush( bkBrush ); + dc.SetPen( mpLayout->mBlackPen ); + + wxPoint points[4]; + + if ( inRect.width > inRect.height ) + { + // horizontal orienation + points[0].x = inRect.x; + points[0].y = inRect.y + inRect.height; + points[1].x = inRect.x; + points[1].y = inRect.y; + points[2].x = inRect.x + inRect.width; + points[2].y = inRect.y; + points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT; + points[3].y = inRect.y + inRect.height; + + dc.DrawPolygon( 4, points ); + + // squeeze romb's bounds to create an inner-shade shape + ++points[0].x; + --points[0].y; + ++points[1].x; + ++points[1].y; + --points[2].x; --points[2].x; + ++points[2].y; + --points[3].y; + + DrawRombShades( points[0], points[1], points[2], points[3], dc ); + } + else + { + // vertical orientation + points[0].x = inRect.x + inRect.width; + points[0].y = inRect.y + inRect.height; + points[1].x = inRect.x; + points[1].y = inRect.y + inRect.height; + points[2].x = inRect.x; + points[2].y = inRect.y; + points[3].x = inRect.x + inRect.width; + points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT; + + dc.DrawPolygon( 4, points ); + + // squeeze romb's bounds to create an inner-shade shape + --points[0].y ; + --points[0].x; + ++points[1].x; + --points[1].y; + ++points[2].y; ++points[2].y; + ++points[2].x; + --points[3].x; + + DrawRombShades( points[1], points[2], points[3], points[0], dc ); + } + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::DrawRomb( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) +{ + wxPoint points[4]; + + dc.SetBrush( bkBrush ); + dc.SetPen( mpLayout->mBlackPen ); + + if ( inRect.width > inRect.height ) + { + // horizontal orientation + points[0].x = inRect.x; + points[0].y = inRect.y + inRect.height; + points[1].x = inRect.x + COLLAPSED_ICON_HEIGHT; + points[1].y = inRect.y; + points[2].x = inRect.x + inRect.width; + points[2].y = inRect.y; + points[3].x = inRect.x + inRect.width - COLLAPSED_ICON_HEIGHT; + points[3].y = inRect.y + inRect.height; + + dc.DrawPolygon( 4, points ); + + // squeeze romb's bounds to create an inner-shade shape + ++points[0].x ;++points[0].x ; + --points[0].y; + ++points[1].y; + --points[2].x; --points[2].x; + ++points[2].y; + //--points[3].x ; + --points[3].y; + + DrawRombShades( points[0], points[1], points[2], points[3], dc ); + + } + else + { + // vertical orientation + points[0].x = inRect.x + inRect.width; + points[0].y = inRect.y + inRect.height; + points[1].x = inRect.x; + points[1].y = inRect.y + inRect.height - COLLAPSED_ICON_HEIGHT; + points[2].x = inRect.x; + points[2].y = inRect.y; + points[3].x = inRect.x + inRect.width; + points[3].y = inRect.y + COLLAPSED_ICON_HEIGHT; + + dc.DrawPolygon( 4, points ); + + // squeeze romb's bounds to create an inner-shade shape + --points[0].y ;--points[0].y ; + --points[0].x; + ++points[1].x; + ++points[2].y; ++points[2].y; + ++points[2].x; + --points[3].x; + + DrawRombShades( points[1], points[2], points[3], points[0], dc ); + } + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::DrawRectShade( wxRect& inRect, wxDC& dc, + int level, wxPen& upperPen, wxPen& lowerPen ) +{ + // upper shade + dc.SetPen( upperPen ); + dc.DrawLine( inRect.x - level, + inRect.y - level, + inRect.x + inRect.width - 1 + level, + inRect.y - level); + dc.DrawLine( inRect.x - level, inRect.y - level, + inRect.x - level, inRect.y + inRect.height - 1 + level ); + + // lower shade + dc.SetPen( lowerPen ); + dc.DrawLine( inRect.x - level, + inRect.y + inRect.height - 1 + level, + inRect.x + inRect.width + level, + inRect.y + inRect.height - 1 + level); + dc.DrawLine( inRect.x + inRect.width - 1 + level, + inRect.y - level, + inRect.x + inRect.width - 1 + level, + inRect.y + inRect.height + level); + + dc.SetBrush( wxNullBrush ); +} + +void cbRowDragPlugin::Draw3DRect( wxRect& inRect, wxDC& dc, wxBrush& bkBrush ) +{ + dc.SetPen( mpLayout->mNullPen ); + dc.SetBrush( bkBrush ); + + dc.DrawRectangle( inRect.x, inRect.y, + inRect.width, inRect.height ); + + DrawRectShade( inRect, dc, 0, mpLayout->mLightPen, mpLayout->mDarkPen ); +} + +int cbRowDragPlugin::GetCollapsedIconsPos() +{ + RowArrayT& rows = mpPane->GetRowList(); + + if ( rows.GetCount() == 0 ) + { + if ( mpPane->IsHorizontal() ) + + return mpPane->mBoundsInParent.y + mpPane->mTopMargin; + else + return mpPane->mBoundsInParent.x + mpPane->mLeftMargin; + } + + wxRect& bounds = rows[ rows.GetCount() - 1 ]->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + + return bounds.y + bounds.height + 1; + else + return bounds.x + bounds.width + 1; + +} + +void cbRowDragPlugin::GetRowHintRect( cbRowInfo* pRow, wxRect& rect ) +{ + wxRect& bounds = pRow->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + rect.x = bounds.x - ROW_DRAG_HINT_WIDTH - 1; + rect.y = bounds.y; + rect.width = ROW_DRAG_HINT_WIDTH; + rect.height = bounds.height; + } + else + { + rect.x = bounds.x; + rect.y = bounds.y + bounds.height + 1; + rect.width = bounds.width; + rect.height = ROW_DRAG_HINT_WIDTH; + } +} + +void cbRowDragPlugin::GetCollapsedInconRect( int iconIdx, wxRect& rect ) +{ + int upper = GetCollapsedIconsPos(); + + int right = (iconIdx == 0 ) + ? 0 : iconIdx * (COLLAPSED_ICON_WIDTH - COLLAPSED_ICON_HEIGHT); + + if ( mpPane->IsHorizontal() ) + { + rect.x = mpPane->mBoundsInParent.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1 + + right; + + rect.y = upper; + rect.width = COLLAPSED_ICON_WIDTH; + rect.height = COLLAPSED_ICON_HEIGHT; + } + else + { + rect.x = upper; + rect.y = mpPane->mBoundsInParent.y + mpPane->mBoundsInParent.height + - mpPane->mBottomMargin + ROW_DRAG_HINT_WIDTH + 1 + - right - COLLAPSED_ICON_WIDTH; + + rect.height = COLLAPSED_ICON_WIDTH; + rect.width = COLLAPSED_ICON_HEIGHT; + } +} + +/*** overridables ***/ + +void cbRowDragPlugin::DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted ) +{ + wxRect rect; + GetCollapsedInconRect( index, rect ); + + wxBrush hiBrush ( mHightColor, wxSOLID ); + wxBrush lowBrush( mLowColor, wxSOLID ); + wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush; + + if ( mpPane->IsHorizontal() ) + { + if ( index == 0 ) + + DrawOrtoRomb( rect, dc, curBrush ); + else + DrawRomb( rect, dc, curBrush ); + + int triOfs = (index == 0) ? TRIANGLE_OFFSET : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT; + + wxRect triRect; + triRect.x = triOfs + rect.x; + + triRect.width = ICON_TRIAN_HEIGHT; + triRect.y = rect.y; + triRect.height = rect.height; + + DrawTrianRight( triRect, dc ); + + wxRect patRect; + patRect.x = triOfs + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP + rect.x; + patRect.y = rect.y + PAT_OFFSET; + patRect.width = rect.width - (patRect.x - rect.x) - COLLAPSED_ICON_HEIGHT - PAT_OFFSET; + patRect.height = rect.height - PAT_OFFSET*2; + + Draw3DPattern( patRect, dc ); + } + else + { + if ( index == 0 ) + + DrawOrtoRomb( rect, dc, curBrush ); + else + DrawRomb( rect, dc, curBrush ); + + int triOfs = (index == 0) + ? TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + : TRIANGLE_OFFSET + COLLAPSED_ICON_HEIGHT + ICON_TRIAN_HEIGHT; + + wxRect triRect; + triRect.y = rect.y + rect.height - triOfs; + triRect.x = rect.x; + triRect.width = rect.width; + triRect.height = ICON_TRIAN_HEIGHT; + + DrawTrianUp( triRect, dc ); + + wxRect patRect; + patRect.y = rect.y + COLLAPSED_ICON_HEIGHT + PAT_OFFSET; + patRect.x = rect.x + PAT_OFFSET; + patRect.width = rect.width - 2*PAT_OFFSET ; + patRect.height = rect.height - triOfs - 2*PAT_OFFSET - COLLAPSED_ICON_HEIGHT; + + Draw3DPattern( patRect, dc ); + } +} + +void cbRowDragPlugin::DrawRowDragHint( cbRowInfo* pRow , wxDC& dc, bool isHighlighted ) +{ + wxRect rect; + GetRowHintRect( pRow, rect ); + + wxBrush hiBrush ( mHightColor, wxSOLID ); + wxBrush lowBrush( mLowColor, wxSOLID ); + wxBrush& curBrush = ( isHighlighted ) ? hiBrush : lowBrush; + + Draw3DRect( rect, dc, curBrush ); + + if ( mpPane->IsHorizontal() ) + { + wxRect triRect; + triRect.y = rect.y + TRIANGLE_OFFSET; + triRect.x = rect.x; + triRect.width = rect.width; + triRect.height = ICON_TRIAN_HEIGHT; + + DrawTrianDown( triRect, dc ); + + wxRect patRect; + patRect.x = rect.x + PAT_OFFSET; + patRect.y = rect.y + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP; + patRect.width = rect.width - 2*PAT_OFFSET; + patRect.height = rect.height - ( patRect.y - rect.y ) - PAT_OFFSET; + Draw3DPattern( patRect, dc ); + + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( rect.x, rect.y + rect.height, rect.x + rect.width, rect.y + rect.height ); + } + else + { + wxRect triRect; + triRect.x = rect.x + TRIANGLE_OFFSET; + triRect.y = rect.y; + triRect.height = rect.height; + triRect.width = ICON_TRIAN_HEIGHT; + + DrawTrianRight( triRect, dc ); + + wxRect patRect; + patRect.y = rect.y + PAT_OFFSET; + patRect.x = rect.x + TRIANGLE_OFFSET + ICON_TRIAN_HEIGHT + TRIANGLE_TO_PAT_GAP; + patRect.height = rect.height - 2*PAT_OFFSET; + patRect.width = rect.width - ( patRect.x - rect.x ) - PAT_OFFSET; + Draw3DPattern( patRect, dc ); + + dc.SetPen( mpLayout->mLightPen ); + dc.DrawLine( rect.x + rect.width, rect.y, rect.x + rect.width, rect.y + rect.height ); + } +} + +void cbRowDragPlugin::DrawRowsDragHintsBorder( wxDC& dc ) +{ + // FIXME:: what was that? +} + +void cbRowDragPlugin::DrawCollapsedRowsBorder( wxDC& dc ) +{ + int colRowOfs = GetCollapsedIconsPos(); + wxRect& bounds = mpPane->mBoundsInParent; + + wxBrush bkBrush( mpLayout->mGrayPen.GetColour(), wxSOLID ); + dc.SetBrush( bkBrush ); + dc.SetPen( mpLayout->mDarkPen ); + + if ( mpPane->IsHorizontal() ) + + dc.DrawRectangle( bounds.x + mpPane->mLeftMargin - ROW_DRAG_HINT_WIDTH - 1, + colRowOfs, + bounds.width - mpPane->mLeftMargin - mpPane->mRightMargin + 2 + ROW_DRAG_HINT_WIDTH, + COLLAPSED_ICON_HEIGHT + 1); + else + dc.DrawRectangle( colRowOfs, + bounds.y + mpPane->mTopMargin - 1, + COLLAPSED_ICON_HEIGHT + 1, + bounds.height - mpPane->mTopMargin - mpPane->mBottomMargin + - ROW_DRAG_HINT_WIDTH - 2 ); + + dc.SetBrush( wxNullBrush ); +} + +static inline bool rect_contains_point( const wxRect& rect, int x, int y ) +{ + return ( x >= rect.x && + y >= rect.y && + x < rect.x + rect.width && + y < rect.y + rect.height ); +} + +bool cbRowDragPlugin::HitTestCollapsedRowIcon( int iconIdx, const wxPoint& pos ) +{ + wxRect bounds; + GetCollapsedInconRect( iconIdx, bounds ); + + return rect_contains_point( bounds, pos.x, pos.y ); +} + +bool cbRowDragPlugin::HitTestRowDragHint( cbRowInfo* pRow, const wxPoint& pos ) +{ + wxRect bounds; + GetRowHintRect( pRow, bounds ); + + return rect_contains_point( bounds, pos.x, pos.y ); +} + diff --git a/contrib/src/fl/rowlayoutpl.cpp b/contrib/src/fl/rowlayoutpl.cpp new file mode 100644 index 0000000000..0ca0f45181 --- /dev/null +++ b/contrib/src/fl/rowlayoutpl.cpp @@ -0,0 +1,1220 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 09/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "rowlayoutpl.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/rowlayoutpl.h" + +// exerimental "features" are still buggy +#undef __EXPERIMENTAL + +/***** Implementation for class cbRowLayoutPlugin *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbRowLayoutPlugin, cbPluginBase ) + +BEGIN_EVENT_TABLE( cbRowLayoutPlugin, cbPluginBase ) + + EVT_PL_LAYOUT_ROW ( cbRowLayoutPlugin::OnLayoutRow ) + EVT_PL_LAYOUT_ROWS( cbRowLayoutPlugin::OnLayoutRows ) + EVT_PL_RESIZE_ROW ( cbRowLayoutPlugin::OnResizeRow ) + + EVT_PL_INSERT_BAR ( cbRowLayoutPlugin::OnInsertBar ) + EVT_PL_REMOVE_BAR ( cbRowLayoutPlugin::OnRemoveBar ) + +END_EVENT_TABLE() + +cbRowLayoutPlugin::cbRowLayoutPlugin(void) + : mpPane( 0 ) +{} + +cbRowLayoutPlugin::cbRowLayoutPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + mpPane( 0 ) +{} + +void cbRowLayoutPlugin::CheckIfAtTheBoundary( cbBarInfo* pTheBar, cbRowInfo& rowInfo ) +{ + // this method handles situation, when fixed bar is inserted + // into the row, where among fixed bars not-fixed ones are present. + // In this case we need to check if the pBarNode appears to be inserted + // chain of fixed-bars on the very right or left side of the row, + // then all the white-space, such chain should be eliminated, + // and the resulting chain justified to the right or the left + // side of the row + + if ( !pTheBar->IsFixed() || rowInfo.mHasOnlyFixedBars ) + + return; + + cbBarInfo* pBar = rowInfo.mBars[ rowInfo.mBars.Count() - 1 ]; + + // slide fixed bars to the right on the right side relative to the pBarNode + + int prevX = mpPane->mPaneWidth; + + do + { + if ( !pBar->IsFixed() ) + break; + + wxRect& bounds = pBar->mBounds; + + bounds.x = prevX - bounds.width; + + prevX = bounds.x; + + if ( pBar == pTheBar ) break; + + pBar = pBar->mpPrev; + } + while( 1 ); + + // slide fixed bars to the left on the left side relative to the pBarNode + + pBar = rowInfo.mBars[0]; + + prevX = 0; + + do + { + if ( pBar->IsFixed() ) + + break; + + wxRect& bounds = pBar->mBounds; + + bounds.x = prevX; + + prevX = bounds.x + bounds.width; + + if ( pBar == pTheBar ) break; + + pBar = pBar->mpNext; + } + while( 1 ); +} + +void cbRowLayoutPlugin::ExpandNotFixedBars( cbRowInfo* pRow ) +{ + ApplyLengthRatios( pRow ); + + // FIXME:: something's wrong? + return; + + double freeSpc = (double)GetRowFreeSpace( pRow ); + + // calculate sum of precents + + double pcntSum = 0.0; + + size_t i = 0; + + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + pcntSum += pRow->mBars[i]->mLenRatio; + } + + // setup bar lengths + + int curX = 0; + + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + if ( !bar.IsFixed() ) + { + bar.mLenRatio = bar.mLenRatio/(pcntSum); + + bar.mBounds.width = + + wxMax( mpPane->mProps.mMinCBarDim.x, int( freeSpc*bar.mLenRatio ) ); + } + + bar.mBounds.x = curX; + curX = bar.mBounds.x + bar.mBounds.width; + } +} + +void cbRowLayoutPlugin::AdjustLengthOfInserted( cbRowInfo* pRow, cbBarInfo* pTheBar ) +{ + return; + + // pTheBar is not-fixed + + + // FIXME:: what is this for?? + +#if 1 + + int totalLen = 0; + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + totalLen += pRow->mBars[i]->mBounds.width; + } + + double curWidth = pTheBar->mBounds.width; + + if ( pRow->mBars.Count() ) + + pTheBar->mBounds.width = int( mpPane->mPaneWidth * (curWidth / double(totalLen)) ); + +#else + + double freeSpc = (double)GetRowFreeSpace( pRow ); + + double pcntSum = 0.0; + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + pcntSum += pRow->mBars[i]->mLenRatio; + } + + // if no longer "balanced", assume that `pTheBar' was previously + // removed from this row (kind of AI...) + + if ( pcntSum < 0.98 ) + + pTheBar->mBounds.width = freeSpc * (1.0 - pcntSum); +#endif +} + +void cbRowLayoutPlugin::FitBarsToRange( int from, int till, + cbBarInfo* pTheBar, cbRowInfo* pRow ) +{ + cbBarInfo* pFromBar = NULL; + cbBarInfo* pTillBar = NULL; + + if ( pTheBar->mBounds.x > from ) + { + // it's range from the left + pFromBar = pRow->mBars[0]; + pTillBar = pTheBar; + } + else + { + pFromBar = pTheBar->mpNext; + pTillBar = NULL; + } + + // calc free space in the range + + cbBarInfo* pBar = pFromBar; + int freeSpc = till-from; + double pcntSum = 0; + + while( pBar != pTillBar ) + { + if ( pBar->IsFixed() ) + + freeSpc -= pBar->mBounds.width; + else + pcntSum += pBar->mLenRatio; + + pBar = pBar->mpNext; + } + + // adjust not-fixed bar sizes in the range + + pBar = pFromBar; + + while( pBar != pTillBar ) + { + if ( !pBar->IsFixed() ) + + pBar->mBounds.width = + + wxMax( mpPane->mProps.mMinCBarDim.x, + int( double(freeSpc) * (pBar->mLenRatio/pcntSum) ) + ); + + pBar = pBar->mpNext; + } + + // layout range, starting from the left-most bar + + pBar = pFromBar; + int prevX = from; + bool hasNotFixedBars = FALSE; + + while ( pBar != pTillBar ) + { + wxRect& bounds = pBar->mBounds; + + if ( !pBar->IsFixed() ) + { + hasNotFixedBars = TRUE; + + freeSpc -= bounds.width; + } + + bounds.x = prevX; + + prevX = bounds.x + bounds.width; + + pBar = pBar->mpNext; + } + + // make width adjustment for the right-most bar in the range, due to + // lost precision when seting widths using f.p. length-ratios + + if ( hasNotFixedBars ) + { + if ( pTheBar->mBounds.x > from ) + { + if ( pTillBar->mpPrev ) + { + wxRect& tillBar = pTillBar->mpPrev->mBounds; + + //tillBar.width = bar.mBounds.x - tillBar.x; + tillBar.width += freeSpc; + } + } + else + { + cbBarInfo* pLast = pRow->mBars[ pRow->mBars.Count() - 1 ]; + + if ( pLast != pTheBar ) + { + pTheBar->mBounds.width += freeSpc; + + SlideRightSideBars( pTheBar ); + } + } + } +} + +void cbRowLayoutPlugin::MinimzeNotFixedBars( cbRowInfo* pRow, cbBarInfo* pBarToPreserve ) +{ + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() && pRow->mBars[i] != pBarToPreserve ) + pRow->mBars[i]->mBounds.width = mpPane->mProps.mMinCBarDim.x; + } +} + +int cbRowLayoutPlugin::GetRowFreeSpace( cbRowInfo* pRow ) +{ + int freeSpc = mpPane->mPaneWidth; + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + // not-fixed bars variable length, thus their + // dimensions are ignored + if ( pRow->mBars[i]->IsFixed() ) + freeSpc -= pRow->mBars[i]->mBounds.width; + } + + return freeSpc; +} + +void cbRowLayoutPlugin::RecalcLengthRatios( cbRowInfo* pRow ) +{ + double freeSpc = double( GetRowFreeSpace( pRow ) ); + + cbBarInfo* pBar = pRow->mBars[0]; + cbBarInfo* pLastNotFixed = NULL; + + double pcntLeft = 1.0; // (100%) + +#ifdef __EXPERIMENTAL + + int totalLen = 0; + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + totalLen += pRow->mBars[i]->mBounds.width; + } +#endif + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + if ( !bar.IsFixed() ) + { + +#ifdef __EXPERIMENTAL + + bar.mLenRatio = double(bar.mBounds.width)/double(totalLen); +#else + bar.mLenRatio = double(bar.mBounds.width)/freeSpc; +#endif + + pcntLeft -= bar.mLenRatio; + pLastNotFixed = pBar; + } + } + + // attach remainder (the result of lost precision) to the + // last not-fixed bar + +#if !defined(__EXPERIMENTAL) + + if ( pLastNotFixed ) + + pLastNotFixed->mLenRatio += pcntLeft; +#endif + +} + +void cbRowLayoutPlugin::ApplyLengthRatios( cbRowInfo* pRow ) +{ + double pcntSum = 0; + + // FOR NOW:: all-in-one + + size_t i = 0; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + pcntSum += pRow->mBars[i]->mLenRatio; + } + + /* + pBar = node_to_first_bar_node( pRow ); + + while( pBar ) + { + cbBarInfo& bar = node_to_bar( pBar ); + + if ( !bar.IsFixed() ) + + bar.mLenRatio = pcntSum / bar.mLenRatio; + + pBar = pBar->Next(); + } + */ + + int prevX = 0; + double freeSpc = GetRowFreeSpace( pRow ); + + // tricky stuff (improtant!): + // when not-fixed bar is removed from the row and there are + // still some other not-fixed ones left in that row, then + // the sum of mLenRatio's is no longer 1.0 - this is left + // intintionally to handle the case when the removed bar + // is returned right back to the row - so that it would retain + // it's original dimensions in this row (this is kind of AI...) + // + // The problem is - when it's remvoed, the sum of + // mLenRatio's is not in "balance", i.e. is < 1.0, + // it's possible to restore balance, but instead of that + // we artifically ajdust freeSpc value in a way that it would + // look like total of mLetRatio's is 1.0, thus original + // len. ratios are _preserved_: + + double unit = freeSpc / pcntSum; + + bool haveSquished = FALSE; + + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + if ( !pRow->mBars[i]->IsFixed() ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + if ( int( unit * bar.mLenRatio ) < mpPane->mProps.mMinCBarDim.x ) + { + haveSquished = TRUE; + + bar.mBounds.width = -1; // mark as "squished" + + pcntSum -= bar.mLenRatio; + + freeSpc -= mpPane->mProps.mMinCBarDim.x; + } + } + } // for + + if ( haveSquished ) + + unit = freeSpc / pcntSum; + + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + bar.mBounds.x = prevX; + + if ( !bar.IsFixed() ) + { + if ( bar.mBounds.width == -1 ) + + bar.mBounds.width = mpPane->mProps.mMinCBarDim.x; + else + bar.mBounds.width = int( unit * bar.mLenRatio ); + + // a little bit of AI: + // memorize bar's height and width, when docked in + // the current orientation - by making the current + // dimensions to be "preffered" ones for this docking state + + if ( !bar.IsFixed() ) + { + bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width; + bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height; + } + } + + prevX = bar.mBounds.x + bar.mBounds.width; + } +} + +void cbRowLayoutPlugin::DetectBarHandles( cbRowInfo* pRow ) +{ + // first pass from left to right (detect left-side handles) + + bool foundNotFixed = FALSE; + + size_t i; + for( i = 0; i != pRow->mBars.Count(); ++i ) + { + cbBarInfo& bar = *pRow->mBars[i]; + + bar.mHasLeftHandle = FALSE; + + if ( !bar.IsFixed() ) + { + if ( foundNotFixed ) + + if ( bar.mpPrev && + bar.mpPrev->IsFixed() ) + + bar.mHasLeftHandle = TRUE; + + foundNotFixed = TRUE; + } + } + + // pass from right to left (detect right-side handles) + + foundNotFixed = FALSE; + + cbBarInfo* pBar = pRow->mBars[ pRow->mBars.Count() - 1 ]; + + while( pBar ) + { + pBar->mHasRightHandle = FALSE; + + if ( !pBar->IsFixed() ) + { + if ( foundNotFixed ) + + if ( pBar->mpNext ) + + pBar->mHasRightHandle = TRUE; + + foundNotFixed = TRUE; + } + + pBar = pBar->mpPrev; + } +} + +void cbRowLayoutPlugin::RelayoutNotFixedBarsAround( cbBarInfo* pTheBar, cbRowInfo* pRow ) +{ + if ( !pTheBar->mpPrev ) + { + if ( !pTheBar->IsFixed() ) + { + // this bar the first in the row, move it's + // left edge to the very left + pTheBar->mBounds.width += pTheBar->mBounds.x; + pTheBar->mBounds.x = 0; + } + } + else + FitBarsToRange( 0, pTheBar->mBounds.x, pTheBar, pRow ); + + if ( !pTheBar->mpNext ) + { + if ( !pTheBar->IsFixed() ) + { + // this bar is the last one, move it's + // right edge to the very right + + pTheBar->mBounds.width = mpPane->mPaneWidth - pTheBar->mBounds.x; + } + } + else + FitBarsToRange( pTheBar->mBounds.x + pTheBar->mBounds.width, mpPane->mPaneWidth, + pTheBar, pRow + ); +} + +void cbRowLayoutPlugin::LayoutItemsVertically( cbRowInfo& row ) +{ + size_t i; + for( i = 0; i != row.mBars.Count(); ++i ) + { + cbBarInfo& bar = *row.mBars[i]; + + bar.mBounds.y = row.mRowY; + + if ( !bar.IsFixed() ) + + // make all not-fixed bars of equal height + bar.mBounds.height = row.mRowHeight; + + if ( row.mHasUpperHandle ) + + bar.mBounds.y += mpPane->mProps.mResizeHandleSize; + } +} + +int cbRowLayoutPlugin::CalcRowHeight( cbRowInfo& row ) +{ + int maxHeight = 0; + + size_t i; + for( i = 0; i != row.mBars.Count(); ++i ) + + maxHeight = wxMax( maxHeight, row.mBars[i]->mBounds.height ); + + return maxHeight; +} + +void cbRowLayoutPlugin::StickRightSideBars( cbBarInfo* pToBar ) +{ + cbBarInfo* pBar = pToBar->mpNext; + cbBarInfo* pPrev = pToBar; + + while( pBar ) + { + wxRect& cur = pBar->mBounds; + wxRect& prev = pPrev->mBounds; + + cur.x = prev.x + prev.width; + + pPrev = pBar; + pBar = pBar->mpNext; + } +} + +void cbRowLayoutPlugin::SlideLeftSideBars( cbBarInfo* pTheBar ) +{ + // shift left-side-bars to the left (with respect to "theBar"), + // so that they would not obscured by each other + + cbBarInfo* pBar = pTheBar->mpPrev; + cbBarInfo* pPrev = pTheBar; + + while( pBar ) + { + wxRect& cur = pBar->mBounds; + wxRect& prev = pPrev->mBounds; + + if ( cur.x + cur.width > prev.x ) + + cur.x = prev.x - cur.width; + + pPrev = pBar; + pBar = pBar->mpPrev; + } +} + +void cbRowLayoutPlugin::SlideRightSideBars( cbBarInfo* pTheBar ) +{ + // shift right-side-bars to the right (with respect to "theBar"), + // so that they would not be obscured by each other + + cbBarInfo* pBar = pTheBar->mpNext; + cbBarInfo* pPrev = pTheBar; + + while( pBar ) + { + wxRect& cur = pBar->mBounds; + wxRect& prev = pPrev->mBounds; + + if ( cur.x < prev.x + prev.width ) + + cur.x = prev.x + prev.width; + + pPrev = pBar; + pBar = pBar->mpNext; + } +} + +void cbRowLayoutPlugin::ShiftLeftTrashold( cbBarInfo* pTheBar, cbRowInfo& row ) +{ + wxRect& first = row.mBars[0]->mBounds; + + if ( first.x < 0 ) + { + row.mBars[0]->mBounds.x = 0; + + SlideRightSideBars( row.mBars[0] ); + } +} + +void cbRowLayoutPlugin::ShiftRightTrashold( cbBarInfo* pTheBar, cbRowInfo& row ) +{ + wxRect& theBar = pTheBar->mBounds; + + do + { + cbBarInfo* pBar = pTheBar; + + // calculate free spece on the left side + + int leftFreeSpc = 0; + + while( pBar ) + { + wxRect& cur = pBar->mBounds; + + if ( pBar->mpPrev ) + { + wxRect& prev = pBar->mpPrev->mBounds; + + leftFreeSpc += cur.x - prev.x - prev.width; + } + else + leftFreeSpc += cur.x; + + if ( cur.x < 0 ) + { + leftFreeSpc = 0; + break; + } + + pBar = pBar->mpPrev; + } + + pBar = pTheBar; + + int rightOverflow = 0; + + if ( pTheBar->IsFixed() ) + + while( pBar ) + { + if ( !pBar->mpNext ) + { + wxRect& cur = pBar->mBounds; + + if ( cur.x + cur.width > mpPane->mPaneWidth ) + + rightOverflow = cur.x + cur.width - mpPane->mPaneWidth; + } + + pBar = pBar->mpNext; + } + + if ( rightOverflow > 0 ) + { + if ( leftFreeSpc <= 0 ) return; + + if ( pTheBar->mpNext ) + { + wxRect& next = pTheBar->mpNext->mBounds; + + // if there's enough space on the left, move over one half-obscured + // bar from the right to the left side with respect to "theBar" + + if ( next.width < leftFreeSpc ) + { + cbBarInfo* pNext = pTheBar->mpNext; + + row.mBars.Remove( pNext ); + + row.mBars.Insert( pNext, row.mBars.Index( pTheBar ) ); + + next.x = theBar.x - next.width; + + // re-setup mpPrev/mpNext references after insertion + + mpPane->InitLinksForRow( &row ); + + // tighten things + + StickRightSideBars( pTheBar ); + SlideLeftSideBars ( pTheBar ); + + continue; + } + } + + int leftShift = ( rightOverflow > leftFreeSpc ) + ? leftFreeSpc + : rightOverflow; + + theBar.x -= leftShift; + + StickRightSideBars( pTheBar ); + SlideLeftSideBars ( pTheBar ); + + break; + + } // end of if ( rightOverflow ) + else + break; + + } while(1); +} + +void cbRowLayoutPlugin::InsertBefore( cbBarInfo* pBeforeBar, + cbBarInfo* pTheBar, + cbRowInfo& row ) +{ + if ( pBeforeBar ) + + row.mBars.Insert( pTheBar, row.mBars.Index( pBeforeBar ) ); + else + row.mBars.Add( pTheBar ); + + pTheBar->mpRow = &row; +} + +void cbRowLayoutPlugin::DoInsertBar( cbBarInfo* pTheBar, cbRowInfo& row ) +{ + wxRect& theBar = pTheBar->mBounds; + + /* OLD STUFF:: + if ( theBar.x < 0 && !node_to_bar( pTheBar ).IsFixed() ) + { + // AI:: + theBar.width += theBar.x; + theBar.x = 0; + } */ + + size_t i; + for( i = 0; i != row.mBars.Count(); ++i ) + { + cbBarInfo& bar = *row.mBars[i]; + + wxRect& cur = bar.mBounds; + + // if bar hits the left edge + if ( theBar.x <= cur.x ) + { + InsertBefore( &bar, pTheBar, row ); + return; + } + + else + // if bar hits the right edge + if ( theBar.x <= cur.x + cur.width ) + { + if ( theBar.x + theBar.width > cur.x + cur.width ) + { + InsertBefore( bar.mpNext, pTheBar, row ); + return; + } + + // otherwise the bar lies within the bounds of current bar + + int leftDist = theBar.x - cur.x; + int rightDist = cur.x + cur.width - (theBar.x + theBar.width); + + if ( leftDist < rightDist ) + + InsertBefore( &bar, pTheBar, row ); + else + InsertBefore( bar.mpNext, pTheBar, row ); + + return; + } + } + + InsertBefore( NULL, pTheBar, row ); // insert at the end +} + +// evnet handlers + +void cbRowLayoutPlugin::OnInsertBar( cbInsertBarEvent& event ) +{ + cbBarInfo* pBarToInsert = event.mpBar; + cbRowInfo* pIntoRow = event.mpRow; + mpPane = event.mpPane; + + if ( !pBarToInsert->IsFixed() ) + + AdjustLengthOfInserted( pIntoRow, pBarToInsert ); + + DoInsertBar( pBarToInsert, *pIntoRow ); + + mpPane->InitLinksForRow( pIntoRow ); // relink "mpNext/mpPrev"s + + // perform relayouting of the bars after insertion + + // init bar location info + pBarToInsert->mAlignment = event.mpPane->mAlignment; + pBarToInsert->mRowNo = event.mpPane->GetRowIndex( pIntoRow ); + +#ifdef __EXPERIMENTAL + + if ( !pIntoRow->mHasOnlyFixedBars || !pBarToInsert->IsFixed() ) + + RecalcLengthRatios( pIntoRow ); + +#endif + + MinimzeNotFixedBars( pIntoRow, pBarToInsert ); + + SlideLeftSideBars ( pBarToInsert ); + SlideRightSideBars( pBarToInsert ); + + ShiftLeftTrashold ( pBarToInsert, *pIntoRow ); + ShiftRightTrashold( pBarToInsert, *pIntoRow ); + + mpPane->SyncRowFlags( pIntoRow ); + + CheckIfAtTheBoundary( pBarToInsert, *pIntoRow ); + + if ( event.mpPane->IsHorizontal() ) + + pBarToInsert->mState = wxCBAR_DOCKED_HORIZONTALLY; + else + pBarToInsert->mState = wxCBAR_DOCKED_VERTICALLY; + + if ( !pIntoRow->mHasOnlyFixedBars ) + { + +#ifdef __EXPERIMENTAL + + ExpandNotFixedBars( pIntoRow ); +#else + + RelayoutNotFixedBarsAround( pBarToInsert, pIntoRow ); + RecalcLengthRatios( pIntoRow ); + +#endif + + DetectBarHandles( pIntoRow ); + + // do proportional resizing of not-fixed bars + ApplyLengthRatios( pIntoRow ); + } + + // adjust the bar's docking state + + // a little bit of AI: + // memorize bar's height and width, when docked in + // the current orientation - by making the current + // dimensions to be "preferred" ones for this docking state + + if ( !pBarToInsert->IsFixed() ) + { + cbBarInfo& bar = *pBarToInsert; + + bar.mDimInfo.mSizes[ bar.mState ].x = bar.mBounds.width; + bar.mDimInfo.mSizes[ bar.mState ].y = bar.mBounds.height; + } +} + +void cbRowLayoutPlugin::OnRemoveBar ( cbRemoveBarEvent& event ) +{ + cbBarInfo* pBar = event.mpBar; + mpPane = event.mpPane; + + cbRowInfo* pRow = pBar->mpRow; + + mpLayout->GetUpdatesManager().OnBarWillChange( pBar, pRow, event.mpPane ); + + // invalidate the whole row + //pFirst->mpRowInfo->mMgrData.mPrevBounds.x = -1; + + pRow->mBars.Remove( pBar ); + + // rest bar information after removing it from the row + pBar->mpRow = NULL; + pBar->mHasLeftHandle = FALSE; + pBar->mHasRightHandle = FALSE; + + mpPane->InitLinksForRow( pRow ); // relink "mpNext/mpPrev"s + + if ( pRow->mBars.Count() == 0 ) + { + // empty rows should not exist + + event.mpPane->GetRowList().Remove( pRow ); + + delete pRow; + + mpPane->InitLinksForRows(); + } + else + { + // force repainting of bars, in the row, from which the bar was removed + + // FIXME:: really needed? + pRow->mBars[0]->mUMgrData.SetDirty(TRUE); + + // re-setup mHasOnlyFixedBars flag for the row information + event.mpPane->SyncRowFlags( pRow ); + + DetectBarHandles( pRow ); + + if ( !pRow->mHasOnlyFixedBars ) + + ExpandNotFixedBars( pRow ); + } +} + +void cbRowLayoutPlugin::OnLayoutRow( cbLayoutRowEvent& event ) +{ + cbRowInfo* pRow = event.mpRow; + mpPane = event.mpPane; + + MinimzeNotFixedBars( pRow, NULL ); + + if ( !pRow->mHasOnlyFixedBars ) + { + // do proportional resizing of not-fixed bars + ApplyLengthRatios( pRow ); + } + + cbBarInfo& lastBar = *pRow->mBars[ pRow->mBars.Count() - 1 ]; + cbBarInfo& firstBar = *pRow->mBars[ 0 ]; + + // FIXME:: Next line not used + // wxRect& bounds = lastBar.mBounds; + + if ( lastBar.mBounds.x + lastBar.mBounds.width > mpPane->mPaneWidth ) + { + lastBar.mBounds.x = mpPane->mPaneWidth - lastBar.mBounds.width; + + // first simulate left-row-edge friction + + SlideLeftSideBars( &lastBar ); + + if ( firstBar.mBounds.x < 0 ) + firstBar.mBounds.x = 0; + + // then left-row-edge function, though this + // may cause some of the right-side bars going + // out of row bounds, but left-side always + // has the highest "priority" + + SlideRightSideBars( &firstBar ); + } + + event.Skip(); // pass event to the next handler +} + +void cbRowLayoutPlugin::OnLayoutRows( cbLayoutRowsEvent& event ) +{ + mpPane = event.mpPane; + + int curY = 0; + + // FIXME:: Next line not used. + // RowArrayT& arr = mpPane->GetRowList(); + + size_t i; + for( i = 0; i != mpPane->GetRowList().Count(); ++i ) + { + cbRowInfo& row = *mpPane->GetRowList()[ i ]; + + // setup "has-handle" flags for rows, which depend on the existance + // of not-fixed bars in the row + + if ( !row.mHasOnlyFixedBars ) + { + if ( mpPane->mAlignment == FL_ALIGN_TOP || + mpPane->mAlignment == FL_ALIGN_LEFT ) + { + row.mHasLowerHandle = TRUE; + + row.mHasUpperHandle = FALSE; + } + else + { + row.mHasUpperHandle = TRUE; + + row.mHasLowerHandle = FALSE; + } + } + else + { + // otherwise, rows with fixed-bars only, have no height-resizing handles + row.mHasUpperHandle = FALSE; + row.mHasLowerHandle = FALSE; + } + + // setup vertical positions for items in the row + + row.mRowY = curY; + + row.mRowWidth = mpPane->mPaneWidth; + row.mRowHeight = CalcRowHeight( row ); + + LayoutItemsVertically( row ); + + if ( row.mHasUpperHandle ) + row.mRowHeight += mpPane->mProps.mResizeHandleSize; + if ( row.mHasLowerHandle ) + row.mRowHeight += mpPane->mProps.mResizeHandleSize; + + curY += row.mRowHeight; + } + + event.Skip(); // pass event to the next handler - other hookeds plugin + // may also add some "refinements" to the layout now +} + +void cbRowLayoutPlugin::OnResizeRow( cbResizeRowEvent& event ) +{ + // extract resize-event info + int ofs = event.mHandleOfs; + bool forUpperHandle = event.mForUpperHandle; + cbRowInfo* pTheRow = event.mpRow; + mpPane = event.mpPane; + + // FIXME:: Next line not used. + //int newHeight = pTheRow->mRowHeight; + + int freeSpc = 0; + + if ( forUpperHandle ) + { + // calculate available free space from above, + // which can be obtained by squeezing not-fixed height rows + + cbRowInfo* pRow = pTheRow->mpPrev; + + while( pRow ) + { + freeSpc += pRow->mRowHeight - event.mpPane->GetMinimalRowHeight( pRow ); + + pRow = pRow->mpPrev; + } + } + else + { + // calculate available free space from below, + // which can be obtained by squeezing not-fixed height rows + + cbRowInfo* pRow = pTheRow->mpNext; + + while( pRow ) + { + freeSpc += pRow->mRowHeight - mpPane->GetMinimalRowHeight( pRow ); + + pRow = pRow->mpNext; + } + } + + mpLayout->GetUpdatesManager().OnStartChanges(); + + int clientSize; + + // allow user adjusting pane vs. client-area space, for upper-handle + + if ( mpPane->IsHorizontal() ) + + clientSize = mpLayout->GetClientHeight(); + else + clientSize = mpLayout->GetClientWidth(); + + if ( forUpperHandle && ofs < -clientSize ) + { + int needed = -(ofs + clientSize); + + cbRowInfo* pRow = mpPane->GetRowList()[ 0 ]; + + // start squeezing rows from the top row towards bottom + + while( pRow != pTheRow && needed ) + { + // only not-fixed rows can be squeezed + + if ( !pRow->mHasOnlyFixedBars ) + { + int prevHeight = pRow->mRowHeight; + + int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), + prevHeight - needed ); + + if ( newHeight != prevHeight ) + { + event.mpPane->SetRowHeight( pRow, newHeight ); + + needed -= prevHeight - pRow->mRowHeight; + } + } + + pRow = pRow->mpNext; + } + } + + // allow user adjusting pane vs. client-area space, for lower-handle + + if ( !forUpperHandle && ofs > clientSize ) + { + int needed = ofs - clientSize; + + cbRowInfo* pRow = mpPane->GetRowList()[ mpPane->GetRowList().Count() - 1 ]; + + // start squeezing rows from the bottom towards the top row + + while( pRow && needed ) + { + // only not-fixed rows can be squeezed + + if ( !pRow->mHasOnlyFixedBars ) + { + int prevHeight = pRow->mRowHeight; + + int newHeight = wxMax( event.mpPane->GetMinimalRowHeight( pRow ), + prevHeight - needed ); + + if ( newHeight != prevHeight ) + { + event.mpPane->SetRowHeight( pRow, newHeight ); + + needed -= prevHeight - pRow->mRowHeight; + } + } + + pRow = pRow->mpPrev; + } + } + + if ( forUpperHandle ) + + event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + (-ofs) ); + else + event.mpPane->SetRowHeight( pTheRow, pTheRow->mRowHeight + ofs ); + + mpLayout->RecalcLayout(FALSE); + + mpLayout->GetUpdatesManager().OnFinishChanges(); + mpLayout->GetUpdatesManager().UpdateNow(); +} + diff --git a/contrib/src/fl/toolwnd.cpp b/contrib/src/fl/toolwnd.cpp new file mode 100644 index 0000000000..c59831d2bc --- /dev/null +++ b/contrib/src/fl/toolwnd.cpp @@ -0,0 +1,1146 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 06/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "toolwnd.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/toolwnd.h" + +#define _IMG_A 0xAA // Note: modified from _A to _IMG_A, _A was already defined (cygwin) +#define _IMG_B 0x00 // Note: modified from _B to _IMG_A, _B was already defined (cygwin) +#define _IMG_C 0x55 // Note: modified from _C to _IMG_C, for consistency reasons. +#define _IMG_D 0x00 // Note: modified from _D to _IMG_D, for consistency reasons. + +// FOR NOW:: static + +static const unsigned char _gCheckerImg[16] = { _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D, + _IMG_A,_IMG_B,_IMG_C,_IMG_D + }; + +/***** Implementation for class wxToolWindow *****/ + +IMPLEMENT_DYNAMIC_CLASS( wxToolWindow, wxWindow ) + +BEGIN_EVENT_TABLE( wxToolWindow, wxWindow ) + + EVT_PAINT ( wxToolWindow::OnPaint ) + EVT_MOTION ( wxToolWindow::OnMotion ) + EVT_LEFT_DOWN( wxToolWindow::OnLeftDown ) + EVT_LEFT_UP ( wxToolWindow::OnLeftUp ) + EVT_SIZE ( wxToolWindow::OnSize ) + + + EVT_ERASE_BACKGROUND( wxToolWindow::OnEraseBackground ) + +END_EVENT_TABLE() + +enum INTERNAL_HIT_CODES +{ + HITS_WND_NOTHING, + HITS_WND_CLIENT, + HITS_WND_TITLE, + + HITS_WND_LEFT_EDGE, + HITS_WND_RIGHT_EDGE, + HITS_WND_TOP_EDGE, + HITS_WND_BOTTOM_EDGE, + + HITS_WND_TOP_LEFT_CORNER, + HITS_WND_BOTTOM_RIGHT_CORNER, + HITS_WND_TOP_RIGHT_CORNER, + HITS_WND_BOTTOM_LEFT_CORNER +}; + +wxToolWindow::wxToolWindow() + + : mpClientWnd ( NULL ), + +#ifndef __WXMSW__ + mTitleFont( 8, wxSWISS, wxNORMAL, wxNORMAL ), +#else + // just to simulate MS-Dev style + mTitleFont( 8, wxSWISS, wxNORMAL, wxNORMAL, FALSE, "MS Sans Serif" ), +#endif + + mTitleHeight ( 16 ), + mClntHorizGap ( 2 ), + mClntVertGap ( 2 ), + mWndVertGap ( 4 ), + mWndHorizGap ( 4 ), + + mButtonGap ( 2 ), + mInTitleMargin( 4 ), + mHintBorder ( 4 ), + + mResizeStarted( FALSE ), + mRealTimeUpdatesOn( TRUE ), + + mMTolerance ( 5 ), // mouse-resizing tollerance + + mCursorType( HITS_WND_NOTHING ), + mMouseCaptured( FALSE ), + + mpScrDc( NULL ) + +{ +} + +wxToolWindow::~wxToolWindow() +{ + if ( mpScrDc ) delete mpScrDc; + + for( size_t i = 0; i != mButtons.Count(); ++i ) + + delete mButtons[i]; +} + +void wxToolWindow::LayoutMiniButtons() +{ + int w,h; + + GetSize( &w, &h ); + + int x = w - mWndHorizGap - mInTitleMargin - BTN_BOX_WIDTH; + int y = mWndVertGap + 2; + + for( size_t i = 0; i != mButtons.Count(); ++i ) + { + mButtons[i]->SetPos( wxPoint( x,y ) ); + x-= BTN_BOX_WIDTH + mButtonGap; + } +} + +void wxToolWindow::SetClient( wxWindow* pWnd ) +{ + mpClientWnd = pWnd; +} + +wxWindow* wxToolWindow::GetClient() +{ + return mpClientWnd; +} + +void wxToolWindow::SetTitleFont( wxFont& font ) +{ + mTitleFont = font; +} + +void wxToolWindow::AddMiniButton( cbMiniButton* pBtn ) +{ + pBtn->mpWnd = this; + + mButtons.Add( pBtn ); + + // not necesserely now.. + //LayoutMiniButtons(); +} + +void wxToolWindow::OnPaint( wxPaintEvent& event ) +{ + wxPaintDC pdc( this ); + wxWindowDC dc( this ); + + int w,h; + GetSize( &w, &h ); + + dc.SetBrush( *wxLIGHT_GREY_BRUSH ); + dc.SetPen( *wxTRANSPARENT_PEN ); + + int y = mWndVertGap + mTitleHeight + mClntVertGap + 1; + dc.DrawRectangle( 0,0, w, y ); + dc.DrawRectangle( 0,y-1, mWndHorizGap + mClntHorizGap + 1, h - y ); + dc.DrawRectangle( w - ( mWndHorizGap + mClntHorizGap ), y-1, + mWndHorizGap + mClntHorizGap, h - y ); + dc.DrawRectangle( 0, h - mWndVertGap - mClntVertGap, w, mWndVertGap + mClntVertGap ); + + // draw shades + dc.SetPen( *wxLIGHT_GREY_PEN ); + + dc.DrawLine( 0,0, w, 0 ); + dc.DrawLine( 0,0, 0, h ); + + dc.SetPen( *wxWHITE_PEN ); + + dc.DrawLine( 1,1, w, 1 ); + dc.DrawLine( 1,2, 1, h ); + + dc.SetPen( *wxGREY_PEN ); + + dc.DrawLine( w - 2, 1, w - 2, h - 1 ); + dc.DrawLine( 1, h - 2, w - 2, h - 2 ); + + dc.SetPen( *wxBLACK_PEN ); + + dc.DrawLine( 0, h - 1, w, h - 1 ); + dc.DrawLine( w-1, 0, w-1, h ); + + // fill inner area + + dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( wxColour( 0,0,128 ), wxSOLID ) ); + + dc.DrawRectangle( mWndHorizGap, mWndVertGap, w - mWndHorizGap*2, mTitleHeight ); + + dc.SetFont( mTitleFont ); + + for( size_t i = 0; i != mButtons.Count(); ++i ) + + mButtons[i]->Draw( dc ); + + int x1 = mWndHorizGap + mClntHorizGap; + int x2 = mButtons[ mButtons.GetCount() - 1 ]->mPos.x - mClntHorizGap*2; + + dc.SetClippingRegion( x1, mWndVertGap + mClntVertGap, x2 - x1, mTitleHeight ); + + dc.SetTextForeground( *wxWHITE ); + dc.SetBackgroundMode( wxTRANSPARENT ); + dc.DrawText( GetTitle(), mWndHorizGap + 2, mWndVertGap + 1 ); +} + +void wxToolWindow::GetScrWindowRect( wxRect& r ) +{ + int x,y; + GetPosition(&x,&y); + int w,h; + GetSize( &w, &h ); + + r.x = x; r.y = y; + r.width = w; r.height = h; +} + +void wxToolWindow::GetScrMousePos( wxMouseEvent& event, wxPoint& pos ) +{ + int x = event.m_x, y = event.m_y; + + ClientToScreen( &x, &y ); + + pos.x = x; pos.y = y; +} + +int wxToolWindow::HitTestWindow( wxMouseEvent& event ) +{ + wxPoint pos; + wxRect r; + + GetScrMousePos( event, pos ); + GetScrWindowRect( r ); + + int k = mMTolerance; + + if ( !( pos.x >= r.x && pos.y >= r.y && + pos.x < r.x + r.width && + pos.y < r.y + r.height ) + ) + return HITS_WND_NOTHING; + + if ( pos.y <= r.y + k ) + { + if ( pos.x < r.x + k*2 ) + + return HITS_WND_TOP_LEFT_CORNER; + else + if ( pos.x >= r.x + r.width - k*2 ) + + return HITS_WND_TOP_RIGHT_CORNER; + else + return HITS_WND_TOP_EDGE; + } + else + if ( pos.y >= r.y + r.height - k ) + { + if ( pos.x < r.x + k*2 ) + + return HITS_WND_BOTTOM_LEFT_CORNER; + else + if ( pos.x > r.x + r.width - k*2 ) + + return HITS_WND_BOTTOM_RIGHT_CORNER; + else + return HITS_WND_BOTTOM_EDGE; + } + else + if ( pos.x <= r.x + k ) + + return HITS_WND_LEFT_EDGE; + else + if ( pos.x >= r.x + r.width - k ) + + return HITS_WND_RIGHT_EDGE; + else + { + if ( pos.y <= r.y + mWndVertGap + mTitleHeight + mClntVertGap ) + + return HITS_WND_TITLE; + else + return HITS_WND_CLIENT; + } +} + +void wxToolWindow::DrawHintRect( const wxRect& r ) +{ + // BUG BUG BUG (wx):: somehow stippled brush works only + // when the bitmap created on stack, not + // as a member of the class + + int prevLF = mpScrDc->GetLogicalFunction(); + + mpScrDc->SetLogicalFunction( wxXOR ); + + wxBitmap checker( (const char*)_gCheckerImg, 8,8 ); + + wxBrush checkerBrush( checker ); + + mpScrDc->SetPen( *wxTRANSPARENT_PEN ); + mpScrDc->SetBrush( checkerBrush ); + + int half = mHintBorder / 2; + + mpScrDc->DrawRectangle( r.x - half, r.y - half, + r.width + 2*half, mHintBorder ); + + mpScrDc->DrawRectangle( r.x - half, r.y + r.height - half, + r.width + 2*half, mHintBorder ); + + mpScrDc->DrawRectangle( r.x - half, r.y + half - 1, + mHintBorder, r.height - 2*half + 2); + + mpScrDc->DrawRectangle( r.x + r.width - half, + r.y + half - 1, + mHintBorder, r.height - 2*half + 2); + + mpScrDc->SetBrush( wxNullBrush ); + + mpScrDc->SetLogicalFunction( prevLF ); +} + +void wxToolWindow::SetHintCursor( int type ) +{ + if ( mResizeStarted ) return; + + if ( type == HITS_WND_NOTHING || type == HITS_WND_CLIENT ) + { + // the cursor is out of window - reset to arrow + + if ( mMouseCaptured && !mResizeStarted ) + { + ReleaseMouse(); + mMouseCaptured = FALSE; + } + + if ( mCursorType == HITS_WND_NOTHING && !mResizeStarted ) + + SetCursor( wxCURSOR_ARROW ); + + mCursorType = type; + + return; + } + + if ( !mMouseCaptured ) + { + mMouseCaptured = TRUE; + CaptureMouse(); + } + + // did the cursor actually changed? + + if ( type != mCursorType ) + { + mCursorType = type; + + switch ( type ) + { + case HITS_WND_LEFT_EDGE : SetCursor( wxCURSOR_SIZEWE ); break; + case HITS_WND_RIGHT_EDGE : SetCursor( wxCURSOR_SIZEWE ); break; + case HITS_WND_TOP_EDGE : SetCursor( wxCURSOR_SIZENS ); break; + case HITS_WND_BOTTOM_EDGE : SetCursor( wxCURSOR_SIZENS ); break; + + case HITS_WND_TOP_LEFT_CORNER : SetCursor( wxCURSOR_SIZENWSE ); break; + case HITS_WND_BOTTOM_RIGHT_CORNER : SetCursor( wxCURSOR_SIZENWSE ); break; + case HITS_WND_TOP_RIGHT_CORNER : SetCursor( wxCURSOR_SIZENESW ); break; + case HITS_WND_BOTTOM_LEFT_CORNER : SetCursor( wxCURSOR_SIZENESW ); break; + + case HITS_WND_TITLE : SetCursor( wxCURSOR_ARROW ); break; + case HITS_WND_CLIENT : SetCursor( wxCURSOR_ARROW ); break; + + default: break; + } + } +} + +#define INFINITY 32768 + +static inline void clip_to( int& value, long from, long till ) +{ + if ( value < from ) + value = from; + + if ( value > till ) + value = till; +} + +void wxToolWindow::AdjustRectPos( const wxRect& original, const wxSize& newDim, wxRect& newRect ) +{ + if ( mCursorType == HITS_WND_TOP_EDGE || + mCursorType == HITS_WND_TOP_LEFT_CORNER ) + { + newRect.x = original.x + original.width - newDim.x; + newRect.y = original.y + original.height - newDim.y; + } + else + if ( mCursorType == HITS_WND_LEFT_EDGE || + mCursorType == HITS_WND_BOTTOM_LEFT_CORNER ) + { + newRect.x = original.x + original.width - newDim.x; + newRect.y = original.y; + } + else + if ( mCursorType == HITS_WND_RIGHT_EDGE || + mCursorType == HITS_WND_TOP_RIGHT_CORNER ) + { + newRect.x = original.x; + newRect.y = original.y + original.height - newDim.y; + } + else + if ( mCursorType == HITS_WND_BOTTOM_EDGE || + mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER ) + { + newRect.x = original.x; + newRect.y = original.y; + } + + newRect.width = newDim.x; + newRect.height = newDim.y; +} + +void wxToolWindow::CalcResizedRect( wxRect& rect, wxPoint& delta, const wxSize& minDim ) +{ + // Microsoft's rect-coordinates are best suited + // for the case of corner-clipping + + int left = mInitialRect.x; + int top = mInitialRect.y; + int right = mInitialRect.x + mInitialRect.width; + int bottom = mInitialRect.y + mInitialRect.height; + + // constraint delta edge is dragged + + switch ( mCursorType ) + { + case HITS_WND_LEFT_EDGE : delta.y = 0; break; + case HITS_WND_RIGHT_EDGE : delta.y = 0; break; + case HITS_WND_TOP_EDGE : delta.x = 0; break; + case HITS_WND_BOTTOM_EDGE : delta.x = 0; break; + default: break; + } + + if ( mCursorType == HITS_WND_TOP_EDGE || + mCursorType == HITS_WND_TOP_LEFT_CORNER ) + { + left += delta.x; + top += delta.y; + + clip_to( left, -INFINITY, mInitialRect.x + mInitialRect.width - minDim.x ); + clip_to( top, -INFINITY, mInitialRect.y + mInitialRect.height - minDim.y ); + } + else + if ( mCursorType == HITS_WND_LEFT_EDGE || + mCursorType == HITS_WND_BOTTOM_LEFT_CORNER ) + { + left += delta.x; + bottom += delta.y; + + clip_to( left, -INFINITY, mInitialRect.x + mInitialRect.width - minDim.x ); + clip_to( bottom, mInitialRect.y + minDim.y, INFINITY ); + } + else + if ( mCursorType == HITS_WND_RIGHT_EDGE || + mCursorType == HITS_WND_TOP_RIGHT_CORNER ) + { + right += delta.x; + top += delta.y; + + clip_to( right, mInitialRect.x + minDim.x, INFINITY ); + clip_to( top, -INFINITY, mInitialRect.y + mInitialRect.height - minDim.y ); + } + else + if ( mCursorType == HITS_WND_BOTTOM_EDGE || + mCursorType == HITS_WND_BOTTOM_RIGHT_CORNER ) + { + right += delta.x; + bottom += delta.y; + + clip_to( right, mInitialRect.x + minDim.x, INFINITY ); + clip_to( bottom, mInitialRect.y + minDim.y, INFINITY ); + } + else + { + int avoidCompilerWarning = 0; + wxASSERT(avoidCompilerWarning); // DBG:: + } + + rect.x = left; + rect.y = top; + rect.width = right - left; + rect.height = bottom - top; +} + +wxSize wxToolWindow::GetMinimalWndDim() +{ + return wxSize( (mWndHorizGap + mClntHorizGap)*2 + BTN_BOX_WIDTH*4, + (mWndVertGap + mClntVertGap )*2 + mTitleHeight ); +} + +void wxToolWindow::OnMotion( wxMouseEvent& event ) +{ + if ( !mResizeStarted ) + { + for( size_t i = 0; i != mButtons.Count(); ++i ) + + mButtons[i]->OnMotion( wxPoint( event.m_x, event.m_y ) ); + + SetHintCursor( HitTestWindow( event ) ); + return; + } + + wxPoint pos; + GetScrMousePos( event, pos ); + + if ( mCursorType == HITS_WND_TITLE ) + { + int w,h; + GetSize( &w, &h ); + + SetSize( mInitialRect.x + pos.x - mDragOrigin.x, + mInitialRect.y + pos.y - mDragOrigin.y, + w,h, 0 ); + } + + else + { + wxPoint delta( pos.x - mDragOrigin.x, pos.y - mDragOrigin.y ); + + wxRect newRect; + + wxSize minDim = GetMinimalWndDim(); + + CalcResizedRect( newRect, delta, minDim ); + + wxSize borderDim( ( mWndHorizGap + mClntHorizGap )*2, + ( mWndVertGap + mClntVertGap )*2 + mTitleHeight ); + + wxSize preferred = GetPreferredSize( wxSize( newRect.width - borderDim.x, + newRect.height - borderDim.y ) ); + + preferred.x += borderDim.x; + preferred.y += borderDim.y; + + //CalcResizedRect( newRect, delta, preferred ); + + wxRect finalRect = newRect; + + AdjustRectPos( newRect, preferred, finalRect ); + + if ( mRealTimeUpdatesOn ) + { + SetSize( finalRect.x, finalRect.y, + finalRect.width, finalRect.height, 0 ); + } + else + { + DrawHintRect( mPrevHintRect ); + DrawHintRect( finalRect ); + } + + mPrevHintRect = finalRect; + } +} + +void wxToolWindow::OnLeftDown( wxMouseEvent& event ) +{ + int result = HitTestWindow( event ); + + for( size_t i = 0; i != mButtons.Count(); ++i ) + { + mButtons[i]->OnLeftDown( wxPoint( event.m_x, event.m_y ) ); + + if ( mButtons[i]->IsPressed() ) + + return; // button hitted, + } + + if ( result >= HITS_WND_LEFT_EDGE || result == HITS_WND_TITLE ) + { + GetScrMousePos( event, mDragOrigin ); + + /* + if ( mMouseCaptured `) + { + ReleaseMouse(); + mMouseCaptured = FALSE; + }*/ + + if ( result == HITS_WND_TITLE && + HandleTitleClick( event ) + ) + { + + return; + } + + mResizeStarted = TRUE; + + int x,y; + GetPosition( &x, &y ); + + mInitialRect.x = x; + mInitialRect.y = y; + + GetSize( &x, &y ); + mInitialRect.width = x; + mInitialRect.height = y; + + mPrevHintRect = mInitialRect; + + if ( mCursorType != HITS_WND_TITLE && !mRealTimeUpdatesOn ) + { + mpScrDc = new wxScreenDC(); + + wxScreenDC::StartDrawingOnTop( (wxRect*)NULL ); + + DrawHintRect( mInitialRect ); + } + } +} + +void wxToolWindow::OnLeftUp( wxMouseEvent& event ) +{ + for( size_t i = 0; i != mButtons.Count(); ++i ) + { + mButtons[i]->OnLeftUp( wxPoint( event.m_x, event.m_y ) ); + + if ( mButtons[i]->WasClicked() ) + { + OnMiniButtonClicked( i ); // notify derived classes + mButtons[i]->Reset(); + } + } + + if ( mResizeStarted ) + { + mResizeStarted = FALSE; + + if ( mCursorType != HITS_WND_TITLE ) + { + if ( !mRealTimeUpdatesOn ) + { + DrawHintRect( mPrevHintRect ); + + wxScreenDC::EndDrawingOnTop(); + + delete mpScrDc; + + mpScrDc = NULL; + + SetSize( mPrevHintRect.x, mPrevHintRect.y, + mPrevHintRect.width, mPrevHintRect.height, 0 ); + } + } + } +} + +void wxToolWindow::OnSize( wxSizeEvent& event ) +{ + if ( mpClientWnd ) + { + int w,h; + GetSize( &w, &h ); + + int x = mWndHorizGap + mClntHorizGap; + int y = mWndVertGap + mTitleHeight + mClntVertGap; + +#if 1 + mpClientWnd->SetSize( x -1, y -1, + w - 2*(mWndHorizGap + mClntHorizGap), + h - y - mClntVertGap - mWndVertGap, + 0 + ); +#endif + } + + LayoutMiniButtons(); +} + +wxSize wxToolWindow::GetPreferredSize( const wxSize& given ) +{ + return given; +} + +void wxToolWindow::OnEraseBackground( wxEraseEvent& event ) +{ + // nothing +} + +/***** Implementation for class cbMiniButton *****/ + +cbMiniButton::cbMiniButton() + + : mVisible( TRUE ), + mEnabled( TRUE ), + + mpLayout( NULL ), + mpPane ( NULL ), + mpPlugin( NULL ), + mpWnd ( NULL ), + + mWasClicked( FALSE ), + mDragStarted( FALSE ), + mPressed( FALSE ) +{} + +void cbMiniButton::SetPos( const wxPoint& pos ) +{ + mPos = pos; +} + +bool cbMiniButton::HitTest( const wxPoint& pos ) +{ + if ( !mVisible ) return FALSE; + + return ( pos.x >= mPos.x && pos.y >= mPos.y && + pos.x < mPos.x + BTN_BOX_WIDTH && + pos.y < mPos.y + BTN_BOX_HEIGHT ); +} + +void cbMiniButton::OnLeftDown( const wxPoint& pos ) +{ + if ( !mVisible || mDragStarted ) return; + + if ( HitTest( pos ) && mEnabled ) + { + if ( mpPlugin ) + { + mpLayout->CaptureEventsForPane( mpPane ); + mpLayout->CaptureEventsForPlugin( mpPlugin ); + } + else + mpWnd->CaptureMouse(); + + mDragStarted = TRUE; + mPressed = TRUE; + mWasClicked = FALSE; + + Refresh(); + } +} + +void cbMiniButton::OnLeftUp( const wxPoint& pos ) +{ + if ( !mVisible || !mDragStarted ) return; + + if ( mpPlugin ) + { + mpLayout->ReleaseEventsFromPane( mpPane ); + mpLayout->ReleaseEventsFromPlugin( mpPlugin ); + } + else + mpWnd->ReleaseMouse(); + + mWasClicked = mPressed; + mDragStarted = FALSE; + + mPressed = FALSE; + Refresh(); +} + +void cbMiniButton::OnMotion( const wxPoint& pos ) +{ + if ( !mVisible ) return; + + if ( mDragStarted ) + { + mPressed = HitTest( pos ); + + Refresh(); + } +} + +void cbMiniButton::Refresh() +{ + if ( mpLayout ) + { + wxClientDC dc( &mpLayout->GetParentFrame() ); + + Draw( dc ); + } + else + { + wxWindowDC dc( mpWnd ); + + Draw( dc ); + } +} + +void cbMiniButton::Draw( wxDC& dc ) +{ + if ( !mVisible ) return; + + dc.SetPen( *wxTRANSPARENT_PEN ); + + dc.SetBrush( *wxLIGHT_GREY_BRUSH ); + + dc.DrawRectangle( mPos.x + 1, mPos.y + 1, BTN_BOX_WIDTH - 2, BTN_BOX_HEIGHT - 2 ); + + // "hard-code" metafile + + if ( !mPressed ) + + dc.SetPen( *wxWHITE_PEN ); + else + dc.SetPen( *wxBLACK_PEN ); + + dc.DrawLine( mPos.x, mPos.y, mPos.x + BTN_BOX_WIDTH, mPos.y ); + dc.DrawLine( mPos.x, mPos.y, mPos.x, mPos.y + BTN_BOX_HEIGHT ); + + dc.SetPen( *wxGREY_PEN ); + + if ( !mPressed ) + { + dc.DrawLine( mPos.x + 1, mPos.y + BTN_BOX_HEIGHT - 2, + mPos.x + BTN_BOX_WIDTH - 1, mPos.y + BTN_BOX_HEIGHT - 2 ); + + dc.DrawLine( mPos.x + BTN_BOX_WIDTH - 2, mPos.y + 1, + mPos.x + BTN_BOX_WIDTH - 2, mPos.y + BTN_BOX_HEIGHT - 1 ); + } + else + { + dc.DrawLine( mPos.x + 1, mPos.y + 1, + mPos.x + BTN_BOX_WIDTH - 2, mPos.y + 1 ); + + dc.DrawLine( mPos.x + 1, mPos.y + 1, + mPos.x + 1, mPos.y + BTN_BOX_HEIGHT - 2 ); + } + + if ( !mPressed ) + + dc.SetPen( *wxBLACK_PEN ); + else + dc.SetPen( *wxWHITE_PEN ); + + dc.DrawLine( mPos.x, mPos.y + BTN_BOX_HEIGHT - 1, + mPos.x + BTN_BOX_WIDTH, mPos.y + BTN_BOX_HEIGHT - 1 ); + + dc.DrawLine( mPos.x + BTN_BOX_WIDTH - 1, mPos.y , + mPos.x + BTN_BOX_WIDTH - 1, mPos.y + BTN_BOX_HEIGHT ); +} + +bool cbMiniButton::WasClicked() +{ + return mWasClicked; +} + +void cbMiniButton::Reset() +{ + mWasClicked = FALSE; +} + +/***** Implementation fro class cbCloseBox *****/ + +void cbCloseBox::Draw( wxDC& dc ) +{ +#ifdef __WXGTK__ + + cbMiniButton::Draw( dc ); + + wxPen pen( wxColour( 64,64,64 ) ,1, wxSOLID ); + + dc.SetPen( pen ); + + int width = BTN_BOX_WIDTH - 7; + + int xOfs = (mPressed) ? 4 : 3; + int yOfs = (mPressed) ? 4 : 3; + + int one = 1; + for( int i = 0; i != BTN_X_WIEGHT; ++i ) + { + dc.DrawLine( mPos.x + xOfs + i - one, + mPos.y + yOfs - one, + mPos.x + xOfs + i + width, + mPos.y + yOfs + width + one); + + dc.DrawLine( mPos.x + xOfs + i + width , + mPos.y + yOfs - one - one, + mPos.x + xOfs + i - one, + mPos.y + yOfs + width ); + } + +#else + + cbMiniButton::Draw( dc ); + + dc.SetPen( *wxBLACK_PEN ); + + int width = BTN_BOX_WIDTH - 7; + + int xOfs = (mPressed) ? 4 : 3; + int yOfs = (mPressed) ? 4 : 3; + + for( int i = 0; i != BTN_X_WIEGHT; ++i ) + { + dc.DrawLine( mPos.x + xOfs + i, + mPos.y + yOfs, + mPos.x + xOfs + i + width, + mPos.y + yOfs + width ); + + dc.DrawLine( mPos.x + xOfs + i + width - 1, + mPos.y + yOfs, + mPos.x + xOfs + i - 1, + mPos.y + yOfs + width ); + } + +#endif + +} + +/***** Implementation fro class cbCollapseBox *****/ + +inline static void my_swap( int& a, int& b ) +{ + long tmp = a; + a = b; + b = tmp; +} + +void cbCollapseBox::Draw( wxDC& dc ) +{ + cbMiniButton::Draw( dc ); + + dc.SetPen( *wxTRANSPARENT_PEN ); + + wxPoint arr[3]; + + int yOfs = (mPressed) ? 3 : 2; + int xOfs = (mPressed) ? 5 : 4; + int width = BTN_BOX_WIDTH - 8; + + // rotating/shifting triangle inside collapse box + + arr[0].x = xOfs; + arr[0].y = yOfs-1; + arr[2].x = xOfs; + arr[2].y = BTN_BOX_HEIGHT - yOfs - 1; + arr[1].x = xOfs + width; + arr[1].y = (arr[2].y + arr[0].y)/2; + + if ( !mIsAtLeft ) + { + arr[0].x = BTN_BOX_WIDTH - arr[0].x; + arr[1].x = BTN_BOX_WIDTH - arr[1].x; + arr[2].x = BTN_BOX_WIDTH - arr[2].x; + } + + if ( !mpPane->IsHorizontal() ) + { + my_swap( arr[0].y, arr[0].x ); + my_swap( arr[1].y, arr[1].x ); + my_swap( arr[2].y, arr[2].x ); + + arr[0].x += 1; + arr[1].x += 1; + arr[2].x += 1; + + //arr[1].y -= 1; + } + + arr[0].x += mPos.x; + arr[0].y += mPos.y; + arr[1].x += mPos.x; + arr[1].y += mPos.y; + arr[2].x += mPos.x; + arr[2].y += mPos.y; + + if ( !mEnabled ) dc.SetBrush( *wxGREY_BRUSH ); + else dc.SetBrush( *wxBLACK_BRUSH ); + + dc.DrawPolygon( 3, arr ); + dc.SetBrush( wxNullBrush ); +} + +/***** Implementation for class cbDockBoxBox *****/ + +void cbDockBox::Draw( wxDC& dc ) +{ + cbMiniButton::Draw( dc ); + + int width = BTN_BOX_WIDTH - 7; + + int xOfs = (mPressed) ? 4 : 3; + int yOfs = (mPressed) ? 4 : 3; + + dc.SetPen( *wxBLACK_PEN ); + dc.SetBrush( *wxBLACK_BRUSH ); + + dc.DrawRectangle( mPos.x + xOfs, mPos.y + yOfs, width, width ); + + xOfs += 1; + yOfs += 1; + + dc.SetBrush( *wxWHITE_BRUSH ); + + dc.DrawRectangle( mPos.x + xOfs, mPos.y + yOfs, width-2, width-2 ); +} + +/***** Implementation for class wxToolWindow *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbFloatedBarWindow, wxToolWindow ) + +BEGIN_EVENT_TABLE( cbFloatedBarWindow, wxToolWindow ) + + EVT_LEFT_DCLICK( cbFloatedBarWindow::OnDblClick ) + +END_EVENT_TABLE() + +cbFloatedBarWindow::cbFloatedBarWindow() + + : mpBar( NULL ) +{ + AddMiniButton( new cbCloseBox() ); + AddMiniButton( new cbDockBox() ); +} + +void cbFloatedBarWindow::SetBar( cbBarInfo* pBar ) +{ + mpBar = pBar; +} + +cbBarInfo* cbFloatedBarWindow::GetBar() +{ + return mpBar; +} + +void cbFloatedBarWindow::SetLayout( wxFrameLayout* pLayout ) +{ + mpLayout = pLayout; +} + +void cbFloatedBarWindow::PositionFloatedWnd( int scrX, int scrY, + int width, int height ) +{ + wxSize minDim = GetMinimalWndDim(); + + SetSize( scrX - mWndHorizGap - mClntHorizGap, + scrY - mClntVertGap - mTitleHeight - mWndVertGap, + width + minDim.x, height + minDim.y, 0 ); +} + +wxSize cbFloatedBarWindow::GetPreferredSize( const wxSize& given ) +{ + if ( mpBar->mDimInfo.GetDimHandler() ) + { + + cbBarDimHandlerBase* pHandler = mpBar->mDimInfo.GetDimHandler(); + + wxSize prefDim; + + // int vtad = *((int*)pHandler); + + pHandler->OnResizeBar( mpBar, given, prefDim ); + + return prefDim; + } + else + { + if ( mpBar->IsFixed() ) + + return mpBar->mDimInfo.mSizes[ wxCBAR_FLOATING ]; + else + return given; // not-fixed bars are resized exactly the way user wants + } +} + +void cbFloatedBarWindow::OnMiniButtonClicked( int btnIdx ) +{ + // #1 - close mini-button + // #0 - dock mini-button + + if ( btnIdx == 0 ) + { + mpBar->mAlignment = -1; // sepcial "marking" for hidden bars out of floated state + mpLayout->SetBarState( mpBar, wxCBAR_HIDDEN, TRUE ); + } + else + mpLayout->SetBarState( mpBar, wxCBAR_DOCKED_HORIZONTALLY, TRUE ); +} + +bool cbFloatedBarWindow::HandleTitleClick( wxMouseEvent& event ) +{ + ReleaseMouse(); + mMouseCaptured = FALSE; + + wxPoint scrPos; + GetScrMousePos( event, scrPos ); + + int msX = scrPos.x, + msY = scrPos.y; + + mpLayout->GetParentFrame().ScreenToClient( &msX, &msY ); + + int x,y; + GetPosition(&x,&y); + int w,h; + GetSize( &w, &h ); + + wxSize minDim = GetMinimalWndDim(); + + w -= minDim.x; + h -= minDim.y; + + x += mWndHorizGap + mClntHorizGap; + y += mWndVertGap + mTitleHeight + mClntVertGap; + + mpLayout->GetParentFrame().ScreenToClient( &x, &y ); + + wxRect& bounds = mpBar->mDimInfo.mBounds[ wxCBAR_FLOATING ]; + + bounds.x = x; + bounds.y = y; + bounds.width = w; + bounds.height = h; + + cbStartBarDraggingEvent dragEvt( mpBar, wxPoint(msX,msY), + mpLayout->GetPanesArray()[FL_ALIGN_TOP] ); + + mpLayout->FirePluginEvent( dragEvt ); + + return TRUE; +} + +void cbFloatedBarWindow::OnDblClick( wxMouseEvent& event ) +{ + mpLayout->SetBarState( mpBar, wxCBAR_DOCKED_HORIZONTALLY, TRUE ); + + //wxMessageBox("toolWnd - dblClick!"); +} + diff --git a/contrib/src/fl/updatesmgr.cpp b/contrib/src/fl/updatesmgr.cpp new file mode 100644 index 0000000000..c742670ca7 --- /dev/null +++ b/contrib/src/fl/updatesmgr.cpp @@ -0,0 +1,291 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 19/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ + #pragma implementation "updatesmgr.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "wx/fl/updatesmgr.h" + +// helper function + +static inline bool rect_hits_rect( const wxRect& r1, const wxRect& r2 ) +{ + if ( ( r2.x >= r1.x && r2.x <= r1.x + r1.width ) || + ( r1.x >= r2.x && r1.x <= r2.x + r2.width ) ) + + if ( ( r2.y >= r1.y && r2.y <= r1.y + r1.height ) || + ( r1.y >= r2.y && r1.y <= r2.y + r2.height ) ) + + return 1; + + return 0; +} + +/***** Implementation for class cbSimpleUpdatesMgr *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbSimpleUpdatesMgr, cbUpdatesManagerBase ) + +cbSimpleUpdatesMgr::cbSimpleUpdatesMgr( wxFrameLayout* pPanel ) + : cbUpdatesManagerBase( pPanel ) +{} + +bool cbSimpleUpdatesMgr::WasChanged( cbUpdateMgrData& data, wxRect& currentBounds ) +{ + return ( data.IsDirty() || + + ( data.mPrevBounds.x != currentBounds.x || + data.mPrevBounds.y != currentBounds.y || + data.mPrevBounds.width != currentBounds.width || + data.mPrevBounds.height != currentBounds.height ) + ); +} + +void cbSimpleUpdatesMgr::OnStartChanges() +{ + // memorize states of ALL items in the layout - + // this is quite excessive, but OK for the simple + // implementation of updates manager + + mpLayout->GetPrevClientRect() = mpLayout->GetClientRect(); + + cbDockPane** panes = mpLayout->GetPanesArray(); + + for( int n = 0; n != MAX_PANES; ++n ) + { + cbDockPane& pane = *panes[n]; + // store pane state + pane.mUMgrData.StoreItemState( pane.mBoundsInParent ); + pane.mUMgrData.SetDirty( FALSE ); + + for( size_t i = 0; i != pane.GetRowList().Count(); ++i ) + { + cbRowInfo& row = *pane.GetRowList()[ i ]; + + // store row state + row.mUMgrData.StoreItemState( row.mBoundsInParent ); + row.mUMgrData.SetDirty( FALSE ); + + for( size_t k = 0; k != row.mBars.Count(); ++k ) + { + cbBarInfo& bar = *row.mBars[ k ]; + + // store bar state + bar.mUMgrData.StoreItemState( bar.mBoundsInParent ); + bar.mUMgrData.SetDirty( FALSE ); + } + } + } +} + +void cbSimpleUpdatesMgr::OnFinishChanges() +{ + // nothing here, could be overriden by more sophisticated updates-managers +} + +void cbSimpleUpdatesMgr::OnRowWillChange( cbRowInfo* pRow, cbDockPane* pInPane ) +{ + // -/- +} + +void cbSimpleUpdatesMgr::OnBarWillChange( cbBarInfo* pBar, + cbRowInfo* pInRow, cbDockPane* pInPane ) +{ + // -/- +} + +void cbSimpleUpdatesMgr::OnPaneMarginsWillChange( cbDockPane* pPane ) +{ + // -/- +} + +void cbSimpleUpdatesMgr::OnPaneWillChange( cbDockPane* pPane ) +{ + // -/- +} + +void cbSimpleUpdatesMgr::UpdateNow() +{ + cbDockPane** panes = mpLayout->GetPanesArray(); + + wxRect& r1 = mpLayout->GetClientRect(); + wxRect& r2 = mpLayout->GetPrevClientRect(); + + // detect changes in client window's area + + bool clientWindowChanged = ( r1.x != r2.x || + r1.y != r2.y || + r1.width != r2.width || + r1.height != r2.height ); + + // step #1 - detect changes in each row of each pane, + // and repaint decorations around changed windows + + wxList mBarsToRefresh; + wxList mPanesList; + + for( int n = 0; n != MAX_PANES; ++n ) + { + cbDockPane& pane = *(panes[n]); + + bool paneChanged = WasChanged( pane.mUMgrData, pane.mBoundsInParent ); + + if ( paneChanged ) + { + wxClientDC dc( &mpLayout->GetParentFrame() ); + pane.PaintPaneBackground( dc ); + } + + wxRect realBounds; + + for( size_t i = 0; i != pane.GetRowList().Count(); ++i ) + { + cbRowInfo& row = *pane.GetRowList()[ i ]; + + wxDC* pDc = NULL; + + bool rowChanged = FALSE; + + // FIXME:: the below should not be fixed + cbBarInfo* barsToRepaint[256]; + + // number of bars, that were changed in the current row + int nBars = 0; + + if ( WasChanged( row.mUMgrData, row.mBoundsInParent ) ) + + rowChanged = TRUE; + else + for( size_t k = 0; k != row.mBars.Count(); ++k ) + + if ( WasChanged( row.mBars[k]->mUMgrData, + row.mBars[k]->mBoundsInParent ) + ) + + barsToRepaint[nBars++] = row.mBars[k]; + + if ( nBars || rowChanged ) + { + realBounds = row.mBoundsInParent; + + // include 1-pixel thick shades around the row + realBounds.x -= 1; + realBounds.y -= 1; + realBounds.width += 2; + realBounds.height += 2; + + pDc = pane.StartDrawInArea( realBounds ); + } + + if ( rowChanged ) + { + // postphone the resizing and refreshing the changed + // bar windows + + for( size_t k = 0; k != row.mBars.Count(); ++k ) + { + mBarsToRefresh.Append( (wxObject*)row.mBars[k] ); + mPanesList.Append( &pane ); + } + + // draw only their decorations now + + pane.PaintRow( &row, *pDc ); + } + else + if ( nBars != 0 ) + { + for( int i = 0; i != nBars; ++i ) + { + // postphone the resizement and refreshing the changed + // bar windows + + mBarsToRefresh.Append( (wxObject*)barsToRepaint[i] ); + mPanesList.Append( &pane ); + } + + // redraw decorations of entire row, regardless of how much + // of the bars were changed + pane.PaintRow( &row, *pDc ); + } + + if ( pDc ) + + pane.FinishDrawInArea( realBounds ); + } // end of while + + if ( paneChanged ) + { + wxClientDC dc( &mpLayout->GetParentFrame() ); + pane.PaintPaneDecorations( dc ); + } + + } // end of for + + if ( clientWindowChanged ) + { + mpLayout->PositionClientWindow(); + // ptr to client-window object is "marked" as 0 + } + + // step #2 - do ordered refreshing and resizing of bar window objects now + + wxNode* pNode = mBarsToRefresh.First(); + wxNode* pPaneNode = mPanesList.First(); + + while( pNode ) + { + cbBarInfo* pBar = (cbBarInfo*) pNode->Data(); + cbDockPane* pPane = (cbDockPane*)pPaneNode->Data(); + + pPane->SizeBar( pBar ); + + pNode = pNode->Next(); + pPaneNode = pPaneNode->Next(); + } + + pNode = mBarsToRefresh.First(); + + while( pNode ) + { + cbBarInfo* pBar = (cbBarInfo*)pNode->Data(); + + if ( pBar->mpBarWnd ) + { + pBar->mpBarWnd->Refresh(); + + // FIXME:: + //info.mpBarWnd->Show(FALSE); + //info.mpBarWnd->Show(TRUE); + } + + pNode = pNode->Next(); + } + + if ( clientWindowChanged ) + { + // FIXME:: excessive? + + mpLayout->GetFrameClient()->Refresh(); + } +} + -- 2.45.2