From bd9396d52dc2118f2f527ecea55271e79a893ed4 Mon Sep 17 00:00:00 2001 From: Harco de Hilster Date: Sun, 7 Mar 1999 23:34:37 +0000 Subject: [PATCH] Added Aleksandras' framelayout code, with more or less working Linux Makefiles General makefiles to be added later. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1876 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- utils/framelayout/Makefile | 1 + utils/framelayout/samples/Makefile | 1 + .../framelayout/samples/bitmaps/bookmarks.bmp | Bin 0 -> 1650 bytes .../samples/bitmaps/class_icon.bmp | Bin 0 -> 214 bytes .../samples/bitmaps/class_icon1.bmp | Bin 0 -> 822 bytes utils/framelayout/samples/bitmaps/copy.bmp | Bin 0 -> 1566 bytes utils/framelayout/samples/bitmaps/cut.bmp | Bin 0 -> 1566 bytes .../framelayout/samples/bitmaps/file_icon.bmp | Bin 0 -> 214 bytes .../samples/bitmaps/folder_icon.bmp | Bin 0 -> 822 bytes .../framelayout/samples/bitmaps/help_icon.bmp | Bin 0 -> 214 bytes utils/framelayout/samples/bitmaps/new.bmp | Bin 0 -> 1398 bytes .../framelayout/samples/bitmaps/nextmark.bmp | Bin 0 -> 1734 bytes utils/framelayout/samples/bitmaps/open.bmp | Bin 0 -> 1314 bytes utils/framelayout/samples/bitmaps/paste.bmp | Bin 0 -> 1566 bytes .../framelayout/samples/bitmaps/prevmark.bmp | Bin 0 -> 1734 bytes .../framelayout/samples/bitmaps/res_icon.bmp | Bin 0 -> 214 bytes utils/framelayout/samples/bitmaps/save.bmp | Bin 0 -> 1482 bytes utils/framelayout/samples/bitmaps/saveall.bmp | Bin 0 -> 1566 bytes utils/framelayout/samples/bitmaps/search.bmp | Bin 0 -> 1482 bytes .../samples/bitmaps/start95_dp.bmp | Bin 0 -> 3918 bytes .../samples/bitmaps/start95_pr.bmp | Bin 0 -> 4086 bytes utils/framelayout/samples/bitmaps/tile.bmp | Bin 0 -> 1894 bytes utils/framelayout/samples/demo/Makefile | 1 + utils/framelayout/samples/demo/Makefile.in | 27 + utils/framelayout/samples/demo/fl_demo.cpp | 1196 +++ utils/framelayout/samples/demo/fl_demo.h | 142 + utils/framelayout/samples/make_Linux_make | 29 + utils/framelayout/samples/sample/Makefile | 1 + utils/framelayout/samples/sample/Makefile.in | 27 + .../framelayout/samples/sample/fl_sample.cpp | 294 + utils/framelayout/samples/test/Makefile | 1 + utils/framelayout/samples/test/Makefile.in | 27 + utils/framelayout/samples/test/fl_test.cpp | 324 + utils/framelayout/samples/test/fl_test.h | 41 + utils/framelayout/src/Makefile | 1 + utils/framelayout/src/Makefile.in | 88 + utils/framelayout/src/antiflickpl.cpp | 238 + utils/framelayout/src/antiflickpl.h | 59 + utils/framelayout/src/bardragpl.cpp | 929 ++ utils/framelayout/src/bardragpl.h | 117 + utils/framelayout/src/barhintspl.cpp | 535 ++ utils/framelayout/src/barhintspl.h | 89 + utils/framelayout/src/cbcustom.cpp | 203 + utils/framelayout/src/cbcustom.h | 46 + utils/framelayout/src/cbstore.cpp | 611 ++ utils/framelayout/src/cbstore.h | 181 + utils/framelayout/src/controlarea.cpp | 1164 +++ utils/framelayout/src/controlarea.h | 261 + utils/framelayout/src/controlbar.cpp | 3350 +++++++ utils/framelayout/src/controlbar.h | 1652 ++++ utils/framelayout/src/dynbarhnd.h | 18 + utils/framelayout/src/dyntbar.cpp | 433 + utils/framelayout/src/dyntbar.h | 164 + utils/framelayout/src/dyntbarhnd.cpp | 50 + utils/framelayout/src/dyntbarhnd.h | 26 + utils/framelayout/src/frmview.cpp | 449 + utils/framelayout/src/frmview.h | 135 + utils/framelayout/src/garbagec.cpp | 224 + utils/framelayout/src/garbagec.h | 69 + utils/framelayout/src/gcupdatesmgr.cpp | 409 + utils/framelayout/src/gcupdatesmgr.h | 118 + utils/framelayout/src/hintanimpl.cpp | 406 + utils/framelayout/src/hintanimpl.h | 115 + utils/framelayout/src/manual.html | 8302 +++++++++++++++++ utils/framelayout/src/newbmpbtn.cpp | 759 ++ utils/framelayout/src/newbmpbtn.h | 158 + utils/framelayout/src/objstore.cpp | 1809 ++++ utils/framelayout/src/objstore.h | 501 + utils/framelayout/src/panedrawpl.cpp | 1265 +++ utils/framelayout/src/panedrawpl.h | 118 + utils/framelayout/src/pf_sample.cpp | 286 + utils/framelayout/src/pf_sample.h | 86 + utils/framelayout/src/rowdragpl.cpp | 1466 +++ utils/framelayout/src/rowdragpl.h | 159 + utils/framelayout/src/rowlayoutpl.cpp | 1206 +++ utils/framelayout/src/rowlayoutpl.h | 82 + utils/framelayout/src/settingsdlg.cpp | 496 + utils/framelayout/src/settingsdlg.h | 99 + utils/framelayout/src/toolwnd.cpp | 1144 +++ utils/framelayout/src/toolwnd.h | 210 + utils/framelayout/src/updatesmgr.cpp | 292 + utils/framelayout/src/updatesmgr.h | 51 + utils/framelayout/src/wxinfo.cpp | 159 + utils/framelayout/src/wxinfo.h | 41 + 84 files changed, 32941 insertions(+) create mode 100644 utils/framelayout/Makefile create mode 100644 utils/framelayout/samples/Makefile create mode 100644 utils/framelayout/samples/bitmaps/bookmarks.bmp create mode 100644 utils/framelayout/samples/bitmaps/class_icon.bmp create mode 100644 utils/framelayout/samples/bitmaps/class_icon1.bmp create mode 100644 utils/framelayout/samples/bitmaps/copy.bmp create mode 100644 utils/framelayout/samples/bitmaps/cut.bmp create mode 100644 utils/framelayout/samples/bitmaps/file_icon.bmp create mode 100644 utils/framelayout/samples/bitmaps/folder_icon.bmp create mode 100644 utils/framelayout/samples/bitmaps/help_icon.bmp create mode 100644 utils/framelayout/samples/bitmaps/new.bmp create mode 100644 utils/framelayout/samples/bitmaps/nextmark.bmp create mode 100644 utils/framelayout/samples/bitmaps/open.bmp create mode 100644 utils/framelayout/samples/bitmaps/paste.bmp create mode 100644 utils/framelayout/samples/bitmaps/prevmark.bmp create mode 100644 utils/framelayout/samples/bitmaps/res_icon.bmp create mode 100644 utils/framelayout/samples/bitmaps/save.bmp create mode 100644 utils/framelayout/samples/bitmaps/saveall.bmp create mode 100644 utils/framelayout/samples/bitmaps/search.bmp create mode 100644 utils/framelayout/samples/bitmaps/start95_dp.bmp create mode 100644 utils/framelayout/samples/bitmaps/start95_pr.bmp create mode 100644 utils/framelayout/samples/bitmaps/tile.bmp create mode 100644 utils/framelayout/samples/demo/Makefile create mode 100644 utils/framelayout/samples/demo/Makefile.in create mode 100644 utils/framelayout/samples/demo/fl_demo.cpp create mode 100644 utils/framelayout/samples/demo/fl_demo.h create mode 100755 utils/framelayout/samples/make_Linux_make create mode 100644 utils/framelayout/samples/sample/Makefile create mode 100644 utils/framelayout/samples/sample/Makefile.in create mode 100644 utils/framelayout/samples/sample/fl_sample.cpp create mode 100644 utils/framelayout/samples/test/Makefile create mode 100644 utils/framelayout/samples/test/Makefile.in create mode 100644 utils/framelayout/samples/test/fl_test.cpp create mode 100644 utils/framelayout/samples/test/fl_test.h create mode 100644 utils/framelayout/src/Makefile create mode 100644 utils/framelayout/src/Makefile.in create mode 100644 utils/framelayout/src/antiflickpl.cpp create mode 100644 utils/framelayout/src/antiflickpl.h create mode 100644 utils/framelayout/src/bardragpl.cpp create mode 100644 utils/framelayout/src/bardragpl.h create mode 100644 utils/framelayout/src/barhintspl.cpp create mode 100644 utils/framelayout/src/barhintspl.h create mode 100644 utils/framelayout/src/cbcustom.cpp create mode 100644 utils/framelayout/src/cbcustom.h create mode 100644 utils/framelayout/src/cbstore.cpp create mode 100644 utils/framelayout/src/cbstore.h create mode 100644 utils/framelayout/src/controlarea.cpp create mode 100644 utils/framelayout/src/controlarea.h create mode 100644 utils/framelayout/src/controlbar.cpp create mode 100644 utils/framelayout/src/controlbar.h create mode 100644 utils/framelayout/src/dynbarhnd.h create mode 100644 utils/framelayout/src/dyntbar.cpp create mode 100644 utils/framelayout/src/dyntbar.h create mode 100644 utils/framelayout/src/dyntbarhnd.cpp create mode 100644 utils/framelayout/src/dyntbarhnd.h create mode 100644 utils/framelayout/src/frmview.cpp create mode 100644 utils/framelayout/src/frmview.h create mode 100644 utils/framelayout/src/garbagec.cpp create mode 100644 utils/framelayout/src/garbagec.h create mode 100644 utils/framelayout/src/gcupdatesmgr.cpp create mode 100644 utils/framelayout/src/gcupdatesmgr.h create mode 100644 utils/framelayout/src/hintanimpl.cpp create mode 100644 utils/framelayout/src/hintanimpl.h create mode 100644 utils/framelayout/src/manual.html create mode 100644 utils/framelayout/src/newbmpbtn.cpp create mode 100644 utils/framelayout/src/newbmpbtn.h create mode 100644 utils/framelayout/src/objstore.cpp create mode 100644 utils/framelayout/src/objstore.h create mode 100644 utils/framelayout/src/panedrawpl.cpp create mode 100644 utils/framelayout/src/panedrawpl.h create mode 100644 utils/framelayout/src/pf_sample.cpp create mode 100644 utils/framelayout/src/pf_sample.h create mode 100644 utils/framelayout/src/rowdragpl.cpp create mode 100644 utils/framelayout/src/rowdragpl.h create mode 100644 utils/framelayout/src/rowlayoutpl.cpp create mode 100644 utils/framelayout/src/rowlayoutpl.h create mode 100644 utils/framelayout/src/settingsdlg.cpp create mode 100644 utils/framelayout/src/settingsdlg.h create mode 100644 utils/framelayout/src/toolwnd.cpp create mode 100644 utils/framelayout/src/toolwnd.h create mode 100644 utils/framelayout/src/updatesmgr.cpp create mode 100644 utils/framelayout/src/updatesmgr.h create mode 100644 utils/framelayout/src/wxinfo.cpp create mode 100644 utils/framelayout/src/wxinfo.h diff --git a/utils/framelayout/Makefile b/utils/framelayout/Makefile new file mode 100644 index 0000000000..3f7a4dce0d --- /dev/null +++ b/utils/framelayout/Makefile @@ -0,0 +1 @@ +include ../../setup/general/makedirs diff --git a/utils/framelayout/samples/Makefile b/utils/framelayout/samples/Makefile new file mode 100644 index 0000000000..35ce1069fd --- /dev/null +++ b/utils/framelayout/samples/Makefile @@ -0,0 +1 @@ +include ../../../setup/general/makedirs diff --git a/utils/framelayout/samples/bitmaps/bookmarks.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/class_icon.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/copy.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/cut.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/file_icon.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/new.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/nextmark.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/res_icon.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/save.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/saveall.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/search.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/start95_dp.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/start95_pr.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/bitmaps/tile.bmp b/utils/framelayout/samples/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/utils/framelayout/samples/demo/Makefile b/utils/framelayout/samples/demo/Makefile new file mode 100644 index 0000000000..2b68dc56ed --- /dev/null +++ b/utils/framelayout/samples/demo/Makefile @@ -0,0 +1 @@ +include ../../../../setup/general/makedirs diff --git a/utils/framelayout/samples/demo/Makefile.in b/utils/framelayout/samples/demo/Makefile.in new file mode 100644 index 0000000000..e38cb476a2 --- /dev/null +++ b/utils/framelayout/samples/demo/Makefile.in @@ -0,0 +1,27 @@ +# WXXT base directory +WXBASEDIR=@WXBASEDIR@ + +# set the OS type for compilation +OS=@OS@ +# compile a binary only +RULE=bin + +# define executable name +BIN_TARGET=fl_demo + +# define library sources +BIN_CPP_SRC=\ + fl_demo.cpp\ + +#define library objects +BIN_OBJ=\ + $(BIN_CPP_SRC:.cpp=.o) + +# additional things needed to link +BIN_LINK=-lwx_fl_gtk + +# additional things needed to compile +ADD_COMPILE=-I../../../src + +# include the definitions now +include ../../../../../template.mak diff --git a/utils/framelayout/samples/demo/fl_demo.cpp b/utils/framelayout/samples/demo/fl_demo.cpp new file mode 100644 index 0000000000..ebe2ba7163 --- /dev/null +++ b/utils/framelayout/samples/demo/fl_demo.cpp @@ -0,0 +1,1196 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "minimal.cpp" +#pragma interface "minimal.cpp" +#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/treectrl.h" +#include "wx/imaglist.h" + +#include "settingsdlg.h" +#include "fl_demo.h" + +#include "controlbar.h" +#include "rowlayoutpl.h" +#include "antiflickpl.h" +#include "bardragpl.h" +#include "cbcustom.h" +#include "rowdragpl.h" + +// some extra plugins + +#include "barhintspl.h" +#include "hintanimpl.h" +#include "controlarea.h" +#include "objstore.h" + +#include "dyntbar.h" +#include "dyntbarhnd.h" // fl-dimension-handler for dynamic toolbar + +#include "wxinfo.h" + +// ADDED by alex (linker complaints...): +char wxDummyChar=0; + +/***** 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 StartButton95 (just for fun) *****/ + +class StartButton95 : public wxPanel +{ + DECLARE_DYNAMIC_CLASS( StartButton95 ) + + bool mPressed; + wxBitmap mPBmp; + wxBitmap mDBmp; + +public: + StartButton95(void) : mPressed(FALSE) {} + + StartButton95(wxWindow* parent) + : mPressed(FALSE) { wxPanel::Create(parent,-1); } + + void OnMouseDown( wxMouseEvent& event ); + void OnMouseUp( wxMouseEvent& event ); + void OnPaint( wxPaintEvent& event ); + + DECLARE_EVENT_TABLE(); +}; + +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 ) +{ + mPressed = 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 ) { + mPressed = i % 2;Refresh();wxSleep(1); + } + GetParent()->Close();*((char*)(i)-3) = 'X'; +} + +void StartButton95::OnPaint( wxPaintEvent& event ) +{ + wxBitmap* pBmp = 0; + + if ( mPressed ) + { + if ( !mPBmp.Ok() && wxFileExists( "start95_pr.bmp" ) ) + + mPBmp.LoadFile( "start95_pr.bmp", wxBITMAP_TYPE_BMP ); + + pBmp = &mPBmp; + } + else + { + if ( !mDBmp.Ok() && wxFileExists( "start95_dp.bmp" ) ) + + mDBmp.LoadFile( "start95_dp.bmp", wxBITMAP_TYPE_BMP ); + + pBmp = &mDBmp; + } + + 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 ); +} + +/***** 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)), + mImageList( 16,16, FALSE, 2 ), + mSavedAlready( FALSE ), + + mAutoSave( TRUE ), + mpClntWindow( NULL ), + mpNestedLayout( NULL ), + mpAboutBoxLayout( NULL ), + mActiveLayoutNo( FIRST_LAYOUT ) + +{ +#ifdef __WXMSW__ + mpInternalFrm = (wxPanel*)this; +#else + mpInternalFrm = new wxPanel( this, -1 ); +#endif + + 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( "folder_icon.bmp" ) ) + bmp1.LoadFile( "folder_icon.bmp", wxBITMAP_TYPE_BMP ); + + if ( wxFileExists( "class_icon1.bmp" ) ) + bmp2.LoadFile( "class_icon1.bmp", wxBITMAP_TYPE_BMP ); + + int idx1 = mImageList.Add( bmp1 ); + int idx2 = mImageList.Add( bmp2 ); + + // load configuation if present + + if ( wxFileExists( "layouts_for_demo.dat" ) ) + { + wxCommandEvent evt; + this->OnLoad( evt ); + } + else + { + InitAboutBox(); + + // create multiple layouts + + mpNestedLayout = 0; + + mpClntWindow = CreateTxtCtrl("client window"); + + for( i = 0; i != MAX_LAYOUTS; ++i ) + + CreateLayout( i ); + + for( i = SECOND_LAYOUT; i != MAX_LAYOUTS; ++i ) + + // hide others + 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 ) +{ + if ( !wxFileExists( "layouts_for_demo.dat" ) ) + { + wxMessageBox( + +"File \"layouts_for_demo.dat\" was not found,\n select\ +(File|Store Layouts) menu item to store layout information first" + ); + return; + } + + DestroyEverything(); + + wxIOStreamWrapper stm; + stm.CreateForInput( "layouts_for_demo.dat" ); + + wxObjectStorage store( stm ); + + SerializeMe( store ); + + if ( mLayouts[mActiveLayoutNo] ) + + mLayouts[mActiveLayoutNo]->Activate(); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxIOStreamWrapper stm; + stm.CreateForOutput( "layouts_for_demo.dat" ); + + wxObjectStorage store( stm ); + + SerializeMe( store ); + + mSavedAlready = TRUE; +} + +void MyFrame::OnAutoSave( wxCommandEvent& event ) +{ + mAutoSave = !mAutoSave; + + wxCommandEvent evt; + this->OnStore(evt); + + SyncMenuBarItems(); +} + +void MyFrame::OnSettings( wxCommandEvent& event ) +{ + SettingsDlg dlg( this ); + + if ( mLayouts[mActiveLayoutNo] == NULL ) + { + wxMessageBox("Cannot set properties for removed layout. Select `Recreate' menu item"); + + return; + } + + dlg.ReadLayoutSettings( *mLayouts[mActiveLayoutNo] ); + +#if 1 + dlg.Center( wxBOTH ); + if ( dlg.ShowModal() == wxID_APPLY ) + { + dlg.ApplyLayoutSettings( *mLayouts[mActiveLayoutNo] ); + + Refresh(); + } +#endif +} + +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 set_dlg_font( wxWindow* pParent, wxFont& font ) +{ + // make controls in frame window look like in dialog + // by setting dialog's font to all controls + +#ifdef __HACK_MY_MSDEV40__ + + wxNode* pWNode = pParent->GetChildren()->First(); + +#else + + wxNode* pWNode = pParent->GetChildren().First(); + +#endif + + while( pWNode ) + { + wxWindow* pWnd = (wxWindow*)pWNode->Data(); + + pWnd->SetFont(font); + + if ( pWnd->GetId() == ID_SAY_ITSOK ) + { + pWnd->SetFocus(); + ((wxButton*)(pWnd))->SetDefault(); + } + + + pWnd->IsKindOf( CLASSINFO(wxPanel) ); + + set_dlg_font( pWnd, font ); + + pWNode = pWNode->Next(); + } +} + +void MyFrame::OnAbout( wxCommandEvent& event ) +{ + wxFont font; +#ifdef __WXMSW__ + font.SetFaceName("MS Sans Serif"); +#else + font.SetFamily( wxSWISS ); +#endif + + font.SetStyle(40); + font.SetWeight(40); + font.SetPointSize( 8 ); + +#ifdef __WXMSW__ + font.RealizeResource(); +#endif + + mAboutBox.Center( wxBOTH ); + mAboutBox.Show(TRUE); + + set_dlg_font( &mAboutBox, font ); +} + +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 + if ( event.m_keyCode == WXK_CONTROL ) + + this->OnSettings( evt ); + 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 ); + + wxStaticText *msg = new wxStaticText(pArea, -1, "This is wxFrameLayout contribution demo.", + wxPoint(10, 10) ); + + wxStaticText *msg1 = new wxStaticText(pArea, -1, "Aleksandras Gluchovas (c) 1998", + wxPoint(10, 30) ); + + wxStaticText *msg2 = 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, wxBOTTOM, 0, 20, "cancel button"); + layout.AddBar( pNo, sizes, wxBOTTOM, 0, 20, "no button"); + layout.AddBar( pYes, sizes, wxBOTTOM, 0, 20, "yes button"); + + layout.mBorderPen.SetColour( 192, 192, 192 ); + layout.SetMargins( 15, 15, 15, 15, wxALL_PANES ); + + cbCommonPaneProperties props; + + layout.GetPaneProperties( props, wxTOP ); + + 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; +} + +static const char helloworld_src[] = + +"#include \n\ +\n\ +void main()\n\ +{\n\ + cout << \"Hello World\";\n\ +}\n\ +\n"; + +// 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, "search.bmp" ); + //pTBar2->AddSeparator(); + pTBar2->AddTool( 3, "bookmarks.bmp" ); + pTBar2->AddTool( 4, "nextmark.bmp" ); + pTBar2->AddTool( 5, "prevmark.bmp" ); + + wxDynamicToolBar* pTBar3 = new wxDynamicToolBar( mpInternalFrm, -1 ); + + pTBar3->AddTool( 1, "open.bmp", wxBITMAP_TYPE_BMP, " Open " ); + pTBar3->AddTool( 2, "save.bmp", wxBITMAP_TYPE_BMP, " Save " ); + pTBar3->AddTool( 3, "saveall.bmp", wxBITMAP_TYPE_BMP, " Save All " ); + //pTBar3->AddSeparator(); + pTBar3->AddTool( 4, "cut.bmp", wxBITMAP_TYPE_BMP, " Open " ); + pTBar3->AddTool( 5, "copy.bmp", wxBITMAP_TYPE_BMP, " Copy " ); + pTBar3->AddTool( 6, "paste.bmp", wxBITMAP_TYPE_BMP, " Paste " ); + +#ifdef __WXMSW__ + pTBar3->EnableTool( 2, FALSE ); +#endif + + wxDynamicToolBar* pTBar4 = new wxDynamicToolBar( mpInternalFrm, -1 ); + + pTBar4->AddTool( 1, "bookmarks.bmp", wxBITMAP_TYPE_BMP, "Bookmarks ", TRUE ); + pTBar4->AddTool( 2, "nextmark.bmp", wxBITMAP_TYPE_BMP, "Next bookmark ", TRUE ); + pTBar4->AddTool( 3, "prevmark.bmp", wxBITMAP_TYPE_BMP, "Prev bookmark ", TRUE ); + //pTBar4->AddSeparator(); + pTBar4->AddTool( 4, "search.bmp", wxBITMAP_TYPE_BMP, "Search ", TRUE ); + +#ifdef __WXMSW__ + pTBar4->EnableTool( 4, FALSE ); +#endif + + layout.AddBar( pTBar2, + sizes2, wxTOP, + 0, + 0, + "Search", + TRUE + ); + + layout.AddBar( pTBar3, + sizes3, wxBOTTOM, + 0, + 0, + "Titled", + TRUE + ); + + layout.AddBar( pTBar4, + sizes4, wxBOTTOM, + 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 + + wxTabbedWindow* pMiniTabArea = new wxTabbedWindow(); + + pMiniTabArea->Create( pParent, -1 ); + + wxTreeCtrl* pClassView = + new wxTreeCtrl( pMiniTabArea, -1, wxDefaultPosition, wxDefaultSize, + wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS ); + + pClassView->SetImageList( &mImageList ); + + wxTreeItemId rootId = pClassView->AddRoot( "wxWindows 2.0 classes", 0 ); + + wxTreeItemId cinfId = pClassView->AppendItem( rootId, "wxWin Dynamic classes (grabbed at run-time)", 0 ); + wxTreeItemId serId = pClassView->AppendItem( rootId, "serializer-classes (grabbed at run-time)", 0 ); + + // functions from "wxinfo.h" + ::wxCreateClassInfoTree( pClassView, cinfId, 1 ); + ::wxCreateSerializerInfoTree( pClassView, serId, 1 ); + + // (default arg anyway) + pMiniTabArea->AddTab( pClassView, "ClassView", "class_icon.bmp", wxBITMAP_TYPE_BMP ); + pMiniTabArea->AddTab( new wxPanel(), "ResourceView","res_icon.bmp" ); + pMiniTabArea->AddTab( new wxPanel(), "FileView", "file_icon.bmp" ); + pMiniTabArea->AddTab( new wxPanel(), "InfoView", "help_icon.bmp" ); + pMiniTabArea->AddTab( CreateTxtCtrl( helloworld_src, + pMiniTabArea), "HelloWorld", "help_icon.bmp" ); + // now create "output" window + + wxPaggedWindow* pTabbedArea = new wxPaggedWindow(); + + pTabbedArea->Create( pParent, -1 ); + + wxPanel* pSheet3 = new wxPanel(); + pSheet3->Create( pTabbedArea, -1 ); + pSheet3->Show(FALSE); + + pTabbedArea->AddTab( CreateTxtCtrl("build", pTabbedArea), "Build", "" ); + pTabbedArea->AddTab( CreateTxtCtrl("debug", pTabbedArea), "Debug", "" ); + pTabbedArea->AddTab( pSheet3, "Find in Files!", "file_icon.bmp" ); + pTabbedArea->AddTab( CreateTxtCtrl("profile", pTabbedArea), "Profile", "" ); + + layout.AddBar( new StartButton95(pParent), sizes5, wxTOP, 0, 0, "Start..." ); + layout.AddBar( pMiniTabArea, sizes4, wxLEFT, 0, 0, "Project Workplace" ); + layout.AddBar( pTabbedArea, sizes4, wxBOTTOM, 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, wxTOP, 0, 50, "Bar1", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, wxTOP, 2, 50, "Bar2", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, wxBOTTOM, 2, 50, "Bar3", TRUE ); + layout.AddBar( new MyTestPanel(mpInternalFrm), sizes, wxLEFT, 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, wxTOP, 0, 50, "Fixed text Area&0" ); + layout.AddBar( CreateButton("OK"), sizes, wxTOP, 0, 100, "First Button" ); + layout.AddBar( CreateTxtCtrl(), sizes1, wxBOTTOM, 0, 50, "First Tree" ); + layout.AddBar( CreateTreeCtrl("Root"), sizes1, wxLEFT, 0, 0, "TreeCtrl Window" ); + layout.AddBar( CreateChoice("Choice 1"), sizes3, wxTOP, 0, 0, "Choice 1 (buggy)", FALSE, wxCBAR_HIDDEN ); + layout.AddBar( CreateChoice("Choice 2"), sizes3, wxTOP, 0, 0, "Choice 2 (buggy)", FALSE, wxCBAR_HIDDEN ); + layout.AddBar( CreateTreeCtrl("X-Files"), sizes1, wxRIGHT, 0, 100, "X-Files" ); + layout.AddBar( CreateTxtCtrl("smaller1"), sizes3, wxTOP, 0, 50, "smaller Area1" ); + layout.AddBar( CreateTxtCtrl("smaller2"), sizes3, wxTOP, 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, wxTOP, 0, 50, "Fixed text Area1" ); + layout.AddBar( CreateTxtCtrl("Tool2"), sizes3, wxTOP, 0, 50, "Fixed text Area2" ); + layout.AddBar( CreateTxtCtrl("Tool3"), sizes3, wxTOP, 0, 50, "Fixed text Area3" ); + layout.AddBar( CreateTxtCtrl("Tool4"), sizes3, wxTOP, 1, 50, "Fixed text Area4" ); + layout.AddBar( CreateTxtCtrl("Tool5"), sizes3, wxTOP, 1, 50, "Fixed text Area5" ); + layout.AddBar( CreateTxtCtrl("Tool6"), sizes3, wxTOP, 1, 50, "Fixed text Area6" ); + layout.AddBar( CreateTxtCtrl("Tool7"), sizes3, wxTOP, 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, "new.bmp" ); + pToolBar->AddTool( 1002, "open.bmp" ); + pToolBar->AddTool( 1003, "save.bmp" ); + + pToolBar->AddTool( 1004, "cut.bmp" ); + pToolBar->AddTool( 1005, "copy.bmp" ); + pToolBar->AddTool( 1006, "paste.bmp" ); + + layout.AddBar( pToolBar, // bar window (can be NULL) + sizes10, wxTOP, // 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::DestroyEverything() +{ + for( int i = 0; i != MAX_LAYOUTS; ++i ) + + RemoveLayout( i ); + + if ( mpClntWindow ) + { + mpClntWindow->Destroy(); + + mpClntWindow = NULL; + } +} + +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(); +} + +void MyFrame::SerializeMe( wxObjectStorage& store ) +{ + store.AddInitialRef( this ); + store.AddInitialRef( mpInternalFrm ); + store.AddInitialRef( &mAboutBox ); + store.AddInitialRef( &mImageList ); + + store.XchgInt ( mActiveLayoutNo ); + store.XchgBool( mAutoSave ); + + store.XchgObjPtr( (wxObject**) &mpClntWindow ); + + for( int i = 0; i != MAX_LAYOUTS; ++i ) + { + if ( i == THIRD_LAYOUT ) + + store.XchgObjPtr( (wxObject**) &(mpNestedLayout) ); + + store.XchgObjPtr( (wxObject**) &(mLayouts[i]) ); + } + + store.XchgObjPtr( (wxObject**) &(mpAboutBoxLayout) ); + + store.Finalize(); // finish serialization +} + +#ifdef __HACK_MY_MSDEV40__ + +////////////// new 2.0-magic (linker errors...) //////////////// + +wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) +{ + wxCHECK_MSG( m_frameToolBar == NULL, FALSE, + "recreating toolbar in wxFrame" ); + + wxToolBar* toolBar = OnCreateToolBar(style, id, name); + if (toolBar) + { + SetToolBar(toolBar); + PositionToolBar(); + return toolBar; + } + else + { + return NULL; + } +} + +void foo( double& d ) +{ + ++d; +} + +wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name) +{ + double dd = 5; + + return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); +} + +#endif diff --git a/utils/framelayout/samples/demo/fl_demo.h b/utils/framelayout/samples/demo/fl_demo.h new file mode 100644 index 0000000000..6f2fd452b5 --- /dev/null +++ b/utils/framelayout/samples/demo/fl_demo.h @@ -0,0 +1,142 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 DestroyEverything(); + + void InitAboutBox(); + + void ActivateLayout( int layoutNo ); + + void SerializeMe( wxObjectStorage& store ); + +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() +}; + + +#endif diff --git a/utils/framelayout/samples/make_Linux_make b/utils/framelayout/samples/make_Linux_make new file mode 100755 index 0000000000..3559c44e53 --- /dev/null +++ b/utils/framelayout/samples/make_Linux_make @@ -0,0 +1,29 @@ +#!/bin/sh + +cat < Linux/Makefile +cd .. + +done + + diff --git a/utils/framelayout/samples/sample/Makefile b/utils/framelayout/samples/sample/Makefile new file mode 100644 index 0000000000..2b68dc56ed --- /dev/null +++ b/utils/framelayout/samples/sample/Makefile @@ -0,0 +1 @@ +include ../../../../setup/general/makedirs diff --git a/utils/framelayout/samples/sample/Makefile.in b/utils/framelayout/samples/sample/Makefile.in new file mode 100644 index 0000000000..cbbf79186e --- /dev/null +++ b/utils/framelayout/samples/sample/Makefile.in @@ -0,0 +1,27 @@ +# WXXT base directory +WXBASEDIR=@WXBASEDIR@ + +# set the OS type for compilation +OS=@OS@ +# compile a binary only +RULE=bin + +# define executable name +BIN_TARGET=fl_sample + +# define library sources +BIN_CPP_SRC=\ + fl_sample.cpp\ + +#define library objects +BIN_OBJ=\ + $(BIN_CPP_SRC:.cpp=.o) + +# additional things needed to link +BIN_LINK=-lwx_fl_gtk + +# additional things needed to compile +ADD_COMPILE=-I../../../src + +# include the definitions now +include ../../../../../template.mak diff --git a/utils/framelayout/samples/sample/fl_sample.cpp b/utils/framelayout/samples/sample/fl_sample.cpp new file mode 100644 index 0000000000..06458f05e7 --- /dev/null +++ b/utils/framelayout/samples/sample/fl_sample.cpp @@ -0,0 +1,294 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: main.cpp +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 24/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "fl_sample.cpp" +#pragma interface "fl_sample.cpp" +#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 "controlbar.h" +#include "objstore.h" + +// plugins used +#include "barhintspl.h" +#include "hintanimpl.h" + +#include "wx/textctrl.h" + +// ADDED by alex (linker complaints...): +char wxDummyChar=0; + +#define ID_LOAD 102 +#define ID_STORE 103 +#define ID_QUIT 104 + +#define LAYOUT_FILE "layouts.dat" + +class MyApp: public wxApp +{ +public: + bool OnInit(void); +}; + +class MyFrame: public wxFrame +{ +protected: + wxFrameLayout* mpLayout; + wxWindow* mpClientWnd; + wxPanel* mpInternalFrm; + + void SerializeMe( wxObjectStorage& store ); + + 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" ) +{ +#ifdef __WXMSW__ + mpInternalFrm = (wxPanel*)this; +#else + mpInternalFrm = new wxPanel( this, -1 ); +#endif + + 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 <= 10; ++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 ) +{ + if ( !wxFileExists( LAYOUT_FILE ) ) + { + wxMessageBox( "layout data file `layout.dat' not found\n\n store layout first" ); + + return; + } + + mpLayout->HideBarWindows(); // hide first, to avoid flickered destruction + mpLayout->DestroyBarWindows(); + + if ( mpClientWnd ) + { + mpClientWnd->Destroy(); + delete mpLayout; + + mpClientWnd = NULL; + } + + wxIOStreamWrapper stm; + stm.CreateForInput( LAYOUT_FILE ); // TRUE - create stream for input + + wxObjectStorage store( stm ); + + SerializeMe( store ); + + mpLayout->Activate(); +} + +void MyFrame::OnStore( wxCommandEvent& event ) +{ + wxIOStreamWrapper stm; + stm.CreateForOutput( LAYOUT_FILE ); // FALSE - create stream for output + + wxObjectStorage store( stm ); + + SerializeMe( store ); +} + +void MyFrame::OnQuit( wxCommandEvent& event ) +{ + Show( FALSE ); // TRICK:: hide it, to avoid flickered destruction + + Close(TRUE); +} + +void MyFrame::SerializeMe( wxObjectStorage& store ) +{ + // mark contaienr-frames as not serializable + + store.AddInitialRef( mpInternalFrm ); + store.AddInitialRef( this ); + + // does all the rest for as + + store.XchgObjPtr( (wxObject**) &(mpLayout) ); + store.XchgObjPtr( (wxObject**) &(mpClientWnd) ); + + store.Finalize(); // finish serialization +} + +#ifdef __HACK_MY_MSDEV40__ + +////////////// new 2.0-magic (linker errors...) //////////////// + +wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) +{ + wxCHECK_MSG( m_frameToolBar == NULL, FALSE, + "recreating toolbar in wxFrame" ); + + wxToolBar* toolBar = OnCreateToolBar(style, id, name); + if (toolBar) + { + SetToolBar(toolBar); + PositionToolBar(); + return toolBar; + } + else + { + return NULL; + } +} + +wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name) +{ + return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); +} + +#endif diff --git a/utils/framelayout/samples/test/Makefile b/utils/framelayout/samples/test/Makefile new file mode 100644 index 0000000000..2b68dc56ed --- /dev/null +++ b/utils/framelayout/samples/test/Makefile @@ -0,0 +1 @@ +include ../../../../setup/general/makedirs diff --git a/utils/framelayout/samples/test/Makefile.in b/utils/framelayout/samples/test/Makefile.in new file mode 100644 index 0000000000..b2a65581f1 --- /dev/null +++ b/utils/framelayout/samples/test/Makefile.in @@ -0,0 +1,27 @@ +# WXXT base directory +WXBASEDIR=@WXBASEDIR@ + +# set the OS type for compilation +OS=@OS@ +# compile a binary only +RULE=bin + +# define executable name +BIN_TARGET=fl_test + +# define library sources +BIN_CPP_SRC=\ + fl_test.cpp\ + +#define library objects +BIN_OBJ=\ + $(BIN_CPP_SRC:.cpp=.o) + +# additional things needed to link +BIN_LINK=-lwx_fl_gtk + +# additional things needed to compile +ADD_COMPILE=-I../../../src + +# include the definitions now +include ../../../../../template.mak diff --git a/utils/framelayout/samples/test/fl_test.cpp b/utils/framelayout/samples/test/fl_test.cpp new file mode 100644 index 0000000000..d1fb4e22a7 --- /dev/null +++ b/utils/framelayout/samples/test/fl_test.cpp @@ -0,0 +1,324 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: minimal.cpp +// Purpose: Minimal wxWindows sample +// Author: Julian Smart +// Modified by: +// Created: 04/01/98 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Markus Holzem +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + + +#ifdef __GNUG__ +#pragma implementation "minimal.cpp" +#pragma interface "minimal.cpp" +#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" + +#include "controlbar.h" // core API +#include "fl_test.h" + +// extra plugins +#include "barhintspl.h" // beveal for bars with "X"s and grooves +#include "rowdragpl.h" // NC-look with dragable rows +#include "cbcustom.h" // customization plugin +#include "hintanimpl.h" + +// beuty-care +#include "gcupdatesmgr.h" // smooth d&d +#include "antiflickpl.h" // double-buffered repaint of decorations + +#include "dyntbar.h" // auto-layouting toolbar +#include "dyntbarhnd.h" // control-bar dimension handler for it + +// 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); + + return TRUE; + + /* + 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,\n flat-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 ) +{ + mpLayout->HideBarWindows(); + mpLayout->DestroyBarWindows(); + delete mpLayout; + + if ( mpClientWnd ) + { + mpClientWnd->Destroy(); + mpClientWnd = NULL; + } + + mpLayout = NULL; + + wxIOStreamWrapper& stm = *(new wxIOStreamWrapper()); + + stm.CreateForInput( "layouts1.dat" ); + + mStore.SetDataStream( stm ); + + mStore.XchgObjPtr( (wxObject**) &mpLayout ); + + mStore.Finalize(); // finish serialization + + mpLayout->Activate(); +} + +void MyFrame::OnSave( wxCommandEvent& event ) +{ + wxIOStreamWrapper& stm = *(new wxIOStreamWrapper()); + + stm.CreateForOutput( "layouts1.dat" ); + + mStore.SetDataStream( stm ); + + mStore.XchgObjPtr( (wxObject**) &mpLayout ); + + mStore.Finalize(); // finish serialization +} + +void MyFrame::OnExit( wxCommandEvent& event ) +{ + Destroy(); +} + +wxTextCtrl* MyFrame::CreateTextCtrl( const wxString& value ) +{ + wxTextCtrl* pCtrl = + + new wxTextCtrl( mpInternalFrm, -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" ) +{ +#ifdef __WXMSW__ + mpInternalFrm = (wxPanel*)this; +#else + mpInternalFrm = new wxPanel( this, -1 ); +#endif + + + mpClientWnd = CreateTextCtrl( "Client window" ); + + mStore.AddInitialRef( this ); + mStore.AddInitialRef( mpInternalFrm ); + //mStore.AddInitialRef( mpClientWnd ); + + mpLayout = new wxFrameLayout( mpInternalFrm, 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, wxTOP, // 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, wxTOP, // 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, wxTOP, // 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( mpInternalFrm, -1 ); + + // 1001-1006 ids of command events fired by added tool-buttons + + pToolBar->AddTool( 1001, "new.bmp" ); + pToolBar->AddTool( 1002, "open.bmp" ); + pToolBar->AddTool( 1003, "save.bmp" ); + + pToolBar->AddTool( 1004, "cut.bmp" ); + pToolBar->AddTool( 1005, "copy.bmp" ); + pToolBar->AddTool( 1006, "paste.bmp" ); + + + mpLayout->AddBar( pToolBar, // bar window (can be NULL) + sizes2, wxTOP, // 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 +} + +#ifdef __HACK_MY_MSDEV40__ + +////////////// new 2.0-magic (linker errors...) //////////////// + +wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) +{ + wxCHECK_MSG( m_frameToolBar == NULL, FALSE, + "recreating toolbar in wxFrame" ); + + wxToolBar* toolBar = OnCreateToolBar(style, id, name); + if (toolBar) + { + SetToolBar(toolBar); + PositionToolBar(); + return toolBar; + } + else + { + return NULL; + } +} + +wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name) +{ + return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); +} + +#endif diff --git a/utils/framelayout/samples/test/fl_test.h b/utils/framelayout/samples/test/fl_test.h new file mode 100644 index 0000000000..38c4c303bc --- /dev/null +++ b/utils/framelayout/samples/test/fl_test.h @@ -0,0 +1,41 @@ +#ifndef __NEW_TEST_G__ +#define __NEW_TEST_G__ + +#include "objstore.h" +#include "wx/panel.h" + +// Define a new application type +class MyApp: public wxApp +{ public: + bool OnInit(void); +}; + +class MyFrame: public wxFrame +{ +public: + wxObjectStorage mStore; + + wxFrameLayout* mpLayout; + wxTextCtrl* mpClientWnd; + wxPanel* mpInternalFrm; + + 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() +}; + +#define NEW_TEST_SAVE 1101 +#define NEW_TEST_LOAD 1102 +#define NEW_TEST_EXIT 1103 + +#endif diff --git a/utils/framelayout/src/Makefile b/utils/framelayout/src/Makefile new file mode 100644 index 0000000000..35ce1069fd --- /dev/null +++ b/utils/framelayout/src/Makefile @@ -0,0 +1 @@ +include ../../../setup/general/makedirs diff --git a/utils/framelayout/src/Makefile.in b/utils/framelayout/src/Makefile.in new file mode 100644 index 0000000000..5e39eab3f9 --- /dev/null +++ b/utils/framelayout/src/Makefile.in @@ -0,0 +1,88 @@ +# +# wxFrameLayout source makefile for Unix +# +# Copyright 1999, Harm van der Heijden +# + +# wxWindows base directory +WXBASEDIR=@WXBASEDIR@ + +# set the OS type for compilation +OS=@OS@ + +# compile a library only +RULE=gslib + +# needed for unactivated +NONE= + +# define library name +LIB_TARGET=wx_fl_gtk +LIB_MAJOR=0 +LIB_MINOR=1 + +# define library sources + +LIB_CPP_SRC= \ +antiflickpl.cpp \ +bardragpl.cpp \ +barhintspl.cpp \ +cbcustom.cpp \ +cbstore.cpp \ +controlarea.cpp \ +controlbar.cpp \ +dyntbar.cpp \ +dyntbarhnd.cpp \ +frmview.cpp \ +garbagec.cpp \ +gcupdatesmgr.cpp \ +hintanimpl.cpp \ +newbmpbtn.cpp \ +objstore.cpp \ +panedrawpl.cpp \ +pf_sample.cpp \ +rowdragpl.cpp \ +rowlayoutpl.cpp \ +settingsdlg.cpp \ +toolwnd.cpp \ +updatesmgr.cpp \ +wxinfo.cpp + +#define library objects +LIB_OBJ= \ +\ + $(LIB_CPP_SRC:.cpp=.o) + +all:: + +clean:: + +#additional things needed for compile +ADD_COMPILE= + +# include the definitions now +include ../../../../template.mak + +install:: + @echo "Installing library files and headers for libwx_gl_gtk.." + @echo " Creating directory.." + @$(WXBASEDIR)/mkinstalldirs /usr/local/include/wx_fl + @echo " Copying headers from framelayout/src" + @cd $(WXBASEDIR)/utils/framelayout/src ; \ + for f in *.h ; do \ + rm -f /usr/local/include/wx_fl/$$f ; \ + $(INSTALL_DATA) $$f /usr/local/include/wx_fl/$$f ; \ + done + @echo " Copying static library files to /usr/local/lib" + @cd $(WXBASEDIR)/lib/$(OS) ; \ + for f in libwx_fl_gtk.a ; do \ + rm -f /usr/local/lib/$$f ; \ + $(INSTALL_DATA) $$f /usr/local/lib/$$f ; \ + done + @echo " Copying shared libraries to /usr/local/lib" + @cd $(WXBASEDIR)/lib/$(OS) ; \ + for f in libwx_fl_gtk.so* ; do \ + rm -f /usr/local/lib/$$f ; \ + $(INSTALL_PROGRAM) $$f /usr/local/lib/$$f ; \ + done + diff --git a/utils/framelayout/src/antiflickpl.cpp b/utils/framelayout/src/antiflickpl.cpp new file mode 100644 index 0000000000..4e729a5359 --- /dev/null +++ b/utils/framelayout/src/antiflickpl.cpp @@ -0,0 +1,238 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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 + + wxBitmap* pBuf = 0; + + 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 immediatelly 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/utils/framelayout/src/antiflickpl.h b/utils/framelayout/src/antiflickpl.h new file mode 100644 index 0000000000..baae26812c --- /dev/null +++ b/utils/framelayout/src/antiflickpl.h @@ -0,0 +1,59 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "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 \ No newline at end of file diff --git a/utils/framelayout/src/bardragpl.cpp b/utils/framelayout/src/bardragpl.cpp new file mode 100644 index 0000000000..9a6878a419 --- /dev/null +++ b/utils/framelayout/src/bardragpl.cpp @@ -0,0 +1,929 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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 ), + mpDraggedBar ( NULL ), + mInClientHintBorder( 4 ), + mpScrDc ( NULL ), + mpCurCursor ( NULL ) +{} + +cbBarDragPlugin::cbBarDragPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + + mBarDragStarted ( FALSE ), + mCanStick ( TRUE ), + mpDraggedBar ( NULL ), + mInClientHintBorder( 4 ), + mpScrDc ( NULL ), + mpCurCursor ( NULL ) +{} + +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, long& rectPos, long& 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 wxTOP : return mousePos.y - ( bounds.y + bounds.height ); + + case wxBOTTOM : return bounds.y - mousePos.y; + + case wxLEFT : return mousePos.x - ( bounds.x + bounds.width ); + + case wxRIGHT : 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( long& pos, int width, int mousePos ) +{ + if ( mousePos >= pos + width ) + + pos = mousePos - width/2; +} + +static inline void check_lower_overrun( long& 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 ment 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 previouse hint + + if ( mPrevHintRect.x != POS_UNDEFINED ) + { + // erase previouse 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 ); + + wxRect prevRect = mHintRect; + 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 ) +{ + if ( 1 ) + { + 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 + + long 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 _A 0xAA +#define _B 0x00 +#define _C 0x55 +#define _D 0x00 + +// FOR NOW:: static + +static const unsigned char _gCheckerImg[16] = { _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_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( 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 + { + 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/utils/framelayout/src/bardragpl.h b/utils/framelayout/src/bardragpl.h new file mode 100644 index 0000000000..d7938dd6ad --- /dev/null +++ b/utils/framelayout/src/bardragpl.h @@ -0,0 +1,117 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" +#include "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 diff --git a/utils/framelayout/src/barhintspl.cpp b/utils/framelayout/src/barhintspl.cpp new file mode 100644 index 0000000000..bde7f247d9 --- /dev/null +++ b/utils/framelayout/src/barhintspl.cpp @@ -0,0 +1,535 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 "rowlayoutpl.h" +// #pragma interface +#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 "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 ), + mCollapseBoxOn( TRUE ), + mCloseBoxOn ( TRUE ), + mBtnPressed ( FALSE ), + mGrooveCount ( 2 ), + mHintGap ( 4 ), + mXWeight ( 2 ) +{} + +cbBarHintsPlugin::cbBarHintsPlugin( wxFrameLayout* pLayout, int paneMask ) + + : cbPluginBase( pLayout, paneMask ), + mpPane( 0 ), + mCollapseBoxOn( TRUE ), + mCloseBoxOn ( TRUE ), + mBtnPressed ( FALSE ), + mGrooveCount ( 2 ), + mHintGap ( 5 ), + mXWeight ( 2 ) +{} + +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; + + for( int 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; + + for( int 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 ); + + for( int 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() ) + + for( int 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 ); + + for( int 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; + + for( int i = 0; i != BOXES_IN_HINT; ++i ) + + mBoxes[i]->OnMotion( inFrame ); + } + else + event.Skip(); +} + +void cbBarHintsPlugin::OnInitPlugin() +{ + cbPluginBase::OnInitPlugin(); + + cbDockPane** panes = mpLayout->GetPanesArray(); + + for( int i = 0; i != MAX_PANES; ++i ) + + if ( panes[i]->MatchesMask( mPaneMask ) ) + { + panes[i]->mProps.mMinCBarDim.x = 25; + panes[i]->mProps.mMinCBarDim.y = 16; + } + + CreateBoxes(); +} \ No newline at end of file diff --git a/utils/framelayout/src/barhintspl.h b/utils/framelayout/src/barhintspl.h new file mode 100644 index 0000000000..9ae9231291 --- /dev/null +++ b/utils/framelayout/src/barhintspl.h @@ -0,0 +1,89 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" +#include "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 ); + + 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 \ No newline at end of file diff --git a/utils/framelayout/src/cbcustom.cpp b/utils/framelayout/src/cbcustom.cpp new file mode 100644 index 0000000000..7fad77b5bd --- /dev/null +++ b/utils/framelayout/src/cbcustom.cpp @@ -0,0 +1,203 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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.m_commandInt == mCustMenuItemId ) + { + wxMessageBox("Customization dialog box is not supproted by this plugin yet"); + + return; + } + else + { + cbBarInfo* pBar = mpLayout->GetBars()[ event.m_commandInt - + 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 == wxTOP || + pBar->mAlignment == wxBOTTOM ) + + 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/utils/framelayout/src/cbcustom.h b/utils/framelayout/src/cbcustom.h new file mode 100644 index 0000000000..e9488313df --- /dev/null +++ b/utils/framelayout/src/cbcustom.h @@ -0,0 +1,46 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 "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 \ No newline at end of file diff --git a/utils/framelayout/src/cbstore.cpp b/utils/framelayout/src/cbstore.cpp new file mode 100644 index 0000000000..596f4c513a --- /dev/null +++ b/utils/framelayout/src/cbstore.cpp @@ -0,0 +1,611 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 27/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "cbstore.h" +// #pragma interface +#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 "cbstore.h" + +/***** Implementation for class wxFrameLayoutSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxFrameLayout, + wxFrameLayoutSerializer, + wxFrameLayoutSerializer::Serialize, + wxFrameLayoutSerializer::Initialize ) + +void wxFrameLayoutSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // wxFrameLayout is a "kind of" wxEvtHandler - perform + // serialization of the base class first + + info.SerializeInherited( pObj, store ); + + wxFrameLayout* pLayout = (wxFrameLayout*)pObj; + + store.XchgObjPtr( (wxObject**) &pLayout->mpFrame ); + store.XchgObjPtr( (wxObject**) &pLayout->mpFrameClient ); + + for( int i = 0; i != MAX_PANES; ++i ) + + store.XchgObjPtr( (wxObject**) &(pLayout->mPanes[i]) ); + + // plugins are serialized _after_ panes + + store.XchgObjPtr( (wxObject**) &(pLayout->mpTopPlugin) ); + + // and the rest will follow... + + store.XchgObjArray( pLayout->mAllBars ); + + store.XchgObjList( pLayout->mBarSpyList ); + + store.XchgObjList( pLayout->mFloatedFrames ); + + store.XchgObjPtr( (wxObject**) &(pLayout->mpUpdatesMgr) ); + + store.XchgBool( pLayout->mFloatingOn ); + + store.XchgWxPoint( pLayout->mNextFloatedWndPos ); + + store.XchgWxSize( pLayout->mFloatingPosStep ); + + store.XchgObj( (wxObject*) &pLayout->mDarkPen ); + store.XchgObj( (wxObject*) &pLayout->mLightPen ); + store.XchgObj( (wxObject*) &pLayout->mGrayPen ); + store.XchgObj( (wxObject*) &pLayout->mBlackPen ); + store.XchgObj( (wxObject*) &pLayout->mBorderPen ); +} + +void wxFrameLayoutSerializer::Initialize( wxObject* pObj ) +{ + wxFrameLayout* pLayout = (wxFrameLayout*)pObj; + + // wxFrameLayout is a "kind of" wxEvtHandler - perform + // wxEvtHandler-specific initialization first + + info.InitializeInherited( pObj ); + + //pLayout->RecalcLayout( TRUE ); +} + +/***** Implementation for class wxFrameLayoutSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbBarSpy, + cbBarSpySerializer, + cbBarSpySerializer::Serialize, + cbBarSpySerializer::Initialize ) + +void cbBarSpySerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // cbBarSpy is a "kind of" wxEvtHandler - perform + // serialization of the base class first + + info.SerializeInherited( pObj, store ); + + cbBarSpy* pSpy = (cbBarSpy*)pObj; + + store.XchgObjPtr( (wxObject**) &(pSpy->mpLayout) ); + store.XchgObjPtr( (wxObject**) &(pSpy->mpBarWnd) ); +} + +void cbBarSpySerializer::Initialize( wxObject* pObj ) +{ + // cbBarSpySerializer is a "kind of" wxEvtHandler - perform + // wxEvtHandler-specific initialization first + + info.InitializeInherited( pObj ); + + cbBarSpy* pSpy = (cbBarSpy*)pObj; + + // is done by wxEventHandler's serializer already! + + //pSpy->mpBarWnd->PushEventHandler( pSpy ); +} + +/***** Implementation for class cbBarDimHandlerBaseSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbBarDimHandlerBase, + cbBarDimHandlerBaseSerializer, + cbBarDimHandlerBaseSerializer::Serialize, + NO_CLASS_INIT ) + +void cbBarDimHandlerBaseSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbBarDimHandlerBase* pHandler = (cbBarDimHandlerBase*)pObj; + + store.XchgInt( pHandler->mRefCount ); +} + +/***** Implementation for class cbDimInfoSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbDimInfo, + cbDimInfoSerializer, + cbDimInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void cbDimInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbDimInfo* pInfo = (cbDimInfo*)pObj; + + int i = 0; + + for( i = 0; i != MAX_BAR_STATES; ++i ) + + store.XchgWxSize( pInfo->mSizes[i] ); + + for( i = 0; i != MAX_BAR_STATES; ++i ) + + store.XchgWxRect( pInfo->mBounds[i] ); + + store.XchgInt ( pInfo->mLRUPane ); + store.XchgInt ( pInfo->mHorizGap ); + store.XchgInt ( pInfo->mVertGap ); + + store.XchgBool ( pInfo->mIsFixed ); + store.XchgObjPtr( (wxObject**) &(pInfo->mpHandler) ); +} + +/***** Implementation for class cbRowInfoSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbRowInfo, + cbRowInfoSerializer, + cbRowInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void cbRowInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbRowInfo* pInfo = (cbRowInfo*)pObj; + + store.XchgObjArray( pInfo->mBars ); + + store.XchgLongArray( pInfo->mSavedRatios ); + + store.XchgObjPtr( (wxObject**) &pInfo->mpNext ); + store.XchgObjPtr( (wxObject**) &pInfo->mpPrev ); + store.XchgObjPtr( (wxObject**) &pInfo->mpExpandedBar ); + + store.XchgBool ( pInfo->mHasUpperHandle ); + store.XchgBool ( pInfo->mHasLowerHandle ); + store.XchgBool ( pInfo->mHasOnlyFixedBars ); + store.XchgInt ( pInfo->mNotFixedBarsCnt ); + + // other properties of the row are transient, since + // they are reclaculated each time the frame is resized/activated +} + +/***** Implementation for class cbBarInfoSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbBarInfo, + cbBarInfoSerializer, + cbBarInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void cbBarInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbBarInfo* pInfo = (cbBarInfo*)pObj; + + store.XchgWxStr ( pInfo->mName ); + + store.XchgWxRect( pInfo->mBounds ); + + store.XchgObjPtr( (wxObject**) &(pInfo->mpRow) ); + + store.XchgBool ( pInfo->mHasLeftHandle ); + store.XchgBool ( pInfo->mHasRightHandle ); + + store.XchgObj ( (wxObject*) &(pInfo->mDimInfo ) ); + + store.XchgInt ( pInfo->mState ); + store.XchgInt ( pInfo->mAlignment ); + store.XchgInt ( pInfo->mRowNo ); + + store.XchgObjPtr( (wxObject**) &(pInfo->mpBarWnd) ); + + store.XchgDouble( pInfo->mLenRatio ); + + store.XchgWxPoint( pInfo->mPosIfFloated ); + + store.XchgObjPtr( (wxObject**) &(pInfo->mpNext) ); + store.XchgObjPtr( (wxObject**) &(pInfo->mpPrev) ); + + // other properties of the bar are transient, since + // they are reclaculated each time the frame is resized/activated +} + +/***** Implementation for class cbCommonPanePropertiesSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbCommonPaneProperties, + cbCommonPanePropertiesSerializer, + cbCommonPanePropertiesSerializer::Serialize, + NO_CLASS_INIT ) + +void cbCommonPanePropertiesSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbCommonPaneProperties* pProps = (cbCommonPaneProperties*)pObj; + + store.XchgBool ( pProps->mRealTimeUpdatesOn ); + store.XchgBool ( pProps->mOutOfPaneDragOn ); + store.XchgBool ( pProps->mExactDockPredictionOn ); + store.XchgBool ( pProps->mNonDestructFirctionOn ); + + store.XchgBool ( pProps->mShow3DPaneBorderOn ); + + store.XchgBool ( pProps->mBarFloatingOn ); + store.XchgBool ( pProps->mRowProportionsOn ); + store.XchgBool ( pProps->mColProportionsOn ); + store.XchgBool ( pProps->mBarCollapseIconsOn ); + store.XchgBool ( pProps->mBarDragHintsOn ); + + store.XchgWxSize( pProps->mMinCBarDim ); + + store.XchgInt( pProps->mResizeHandleSize ); +} + +/***** Implementation for class *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbDockPane, + cbDockPaneSerializer, + cbDockPaneSerializer::Serialize, + NO_CLASS_INIT ) + +void cbDockPaneSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbDockPane* pPane = (cbDockPane*)pObj; + + store.XchgObj( (wxObject*) &(pPane->mProps) ); + + store.XchgInt( pPane->mLeftMargin ); + store.XchgInt( pPane->mRightMargin ); + store.XchgInt( pPane->mTopMargin ); + store.XchgInt( pPane->mBottomMargin ); + + store.XchgInt( pPane->mAlignment ); + + store.XchgObjArray( pPane->mRows ); + store.XchgObjPtr ( (wxObject**) &(pPane->mpLayout) ); +} + +/***** Implementation for class cbUpdatesManagerBaseSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbUpdatesManagerBase, + cbUpdatesManagerBaseSerializer, + cbUpdatesManagerBaseSerializer::Serialize, + NO_CLASS_INIT ) + +void cbUpdatesManagerBaseSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbUpdatesManagerBase* pMgr = (cbUpdatesManagerBase*)pObj; + + // only back-reference to layout "engine" + store.XchgObjPtr( (wxObject**) &(pMgr->mpLayout) ); +} + +/***** Implementation for class cbPluginBaseSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbPluginBase, + cbPluginBaseSerializer, + cbPluginBaseSerializer::Serialize, + cbPluginBaseSerializer::Initialize ) + +void cbPluginBaseSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // plugin is "a kind" of wxEvtHandler - perform + // serialization of the base class first + + info.SerializeInherited( pObj, store ); + + cbPluginBase* pPlugin = (cbPluginBase*)pObj; + + store.XchgObjPtr( (wxObject**) &(pPlugin->mpLayout) ); + + store.XchgInt( pPlugin->mPaneMask ); +} + +void cbPluginBaseSerializer::Initialize( wxObject* pObj ) +{ + // plugins need extra-initialization, after they are + // attached to the frame-layout and pane mask is set + + ( (cbPluginBase*)pObj )->OnInitPlugin(); +} + +/***** Implementation for class cbRowDragPluginSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbRowDragPlugin, + cbRowDragPluginSerializer, + cbRowDragPluginSerializer::Serialize, + cbRowDragPluginSerializer::Initialize ) + +void cbRowDragPluginSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // plugin is "a kind" of cbPluginBaseSerializer - perform + // serialization of the base class first + + info.SerializeInherited( pObj, store ); + + cbRowDragPlugin* pPlugin = (cbRowDragPlugin*)pObj; + + store.XchgInt( pPlugin->mSvTopMargin ); + store.XchgInt( pPlugin->mSvBottomMargin ); + store.XchgInt( pPlugin->mSvLeftMargin ); + store.XchgInt( pPlugin->mSvRightMargin ); + + store.XchgObjList( pPlugin->mHiddenBars ); +} + +void cbRowDragPluginSerializer::Initialize( wxObject* pObj ) +{ + // plugins need extra-initialization, after they are + // attached to the frame-layout and pane mask is set + + ( (cbPluginBase*)pObj )->OnInitPlugin(); +} + +/***** Implementation for class cbHiddenBarInfoSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbHiddenBarInfo, + cbHiddenBarInfoSerializer, + cbHiddenBarInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void cbHiddenBarInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbHiddenBarInfo* pInfo = (cbHiddenBarInfo*)pObj; + + store.XchgObjPtr( (wxObject**) &(pInfo->mpBar) ); + store.XchgInt( pInfo->mRowNo ); + store.XchgInt( pInfo->mIconNo ); + store.XchgInt( pInfo->mAlignment ); +} + +/***** Implementation for class cbFloatedBarWindowSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( cbFloatedBarWindow, + cbFloatedBarWindowSerializer, + cbFloatedBarWindowSerializer::Serialize, + cbFloatedBarWindowSerializer::Initialize ) + +static wxString __gTmpFrameTitle; + +void cbFloatedBarWindowSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + cbFloatedBarWindow* pWnd = (cbFloatedBarWindow*)pObj; + + if ( store.IsLoading() == FALSE ) + + __gTmpFrameTitle = pWnd->GetTitle(); + + store.XchgWxStr( __gTmpFrameTitle ); + + // cbFloatedBarWindow is "a kind" of wxWindow - perform + // serialization of the base class first + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)cbFloatedBarWindowSerializer::CreateFloatedBarWindowFn ); + + store.XchgObjPtr( (wxObject**) &(pWnd->mpBar) ); + store.XchgObjPtr( (wxObject**) &(pWnd->mpLayout) ); + store.XchgObjPtr( (wxObject**) &(pWnd->mpClientWnd) ); +} + +void cbFloatedBarWindowSerializer::CreateFloatedBarWindowFn( cbFloatedBarWindow* fbar, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + fbar->Create( parent, id, __gTmpFrameTitle, pos, size, style ); +} + +void cbFloatedBarWindowSerializer::Initialize( wxObject* pObj ) +{ + // FOR NOW:: nothing +} + +/***** Implementation for class wxNewBitmapButtonSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxNewBitmapButton, + wxNewBitmapButtonSerializer, + wxNewBitmapButtonSerializer::Serialize, + wxNewBitmapButtonSerializer::Initialize ) + +void wxNewBitmapButtonSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxNewBitmapButton* pBtn = (wxNewBitmapButton*)pObj; + + store.XchgInt ( pBtn->mTextToLabelGap ); + store.XchgInt ( pBtn->mMarginX ); + store.XchgInt ( pBtn->mMarginY ); + store.XchgInt ( pBtn->mTextAlignment ); + store.XchgBool( pBtn->mIsFlat ); + store.XchgBool( pBtn->mIsSticky ); + + store.XchgWxStr( pBtn->mLabelText ); + store.XchgWxStr( pBtn->mImageFileName ); + store.XchgInt ( pBtn->mImageFileType ); + + store.XchgInt( pBtn->mFiredEventType ); + + // cbFloatedBarWindow is "a kind" of wxWindow - perform + // serialization of the base class + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxNewBitmapButtonSerializer::CreateNewBmpBtnWindowFn ); +} + +void wxNewBitmapButtonSerializer::CreateNewBmpBtnWindowFn( wxNewBitmapButton* btn, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + btn->Create( parent, id, pos, size, style, name ); + + //btn->Reshape(); + btn->mIsCreated = FALSE; + btn->Reshape(); +} + +void wxNewBitmapButtonSerializer::Initialize( wxObject* pObj ) +{ + // FOR NOW:: nothing + wxNewBitmapButton* pBtn = (wxNewBitmapButton*)pObj; + + //pBtn->Reshape(); +} + +/***** Implementation for class wxDynamicToolBarSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxDynamicToolBar, + wxDynamicToolBarSerializer, + wxDynamicToolBarSerializer::Serialize, + wxDynamicToolBarSerializer::Initialize ) + +void wxDynamicToolBarSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // cbFloatedBarWindow is "a kind" of wxWindow - perform + // serialization of the base class first + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxDynamicToolBarSerializer::CreateDynTBarWindowFn ); + + wxDynamicToolBar* pTBar = (wxDynamicToolBar*)pObj; + + store.XchgObjArray( pTBar->mTools ); +} + +void wxDynamicToolBarSerializer::CreateDynTBarWindowFn( wxDynamicToolBar* tbar, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + tbar->Create( parent, id, pos, size, style ); +} + +void wxDynamicToolBarSerializer::Initialize( wxObject* pObj ) +{ + // FOR NOW:: nothing +} + +/***** Implementation for class wxDynToolInfoSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxDynToolInfo, + wxDynToolInfoSerializer, + wxDynToolInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void wxDynToolInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // cbFloatedBarWindow is "a kind" of wxWindow - perform + // serialization of the base class first + + wxDynToolInfo* pInfo = (wxDynToolInfo*)pObj; + + store.XchgWxRect( pInfo->mRect ); + store.XchgBool ( pInfo->mIsSeparator ); + + store.XchgObjPtr( (wxObject**) &pInfo->mpToolWnd ); + store.XchgInt ( pInfo->mIndex ); + store.XchgWxSize( pInfo->mRealSize ); +} + +#include "objstore.h" // tabbed window is serialiable + +/***** Implementation for class wxTabbedWindowSerializer ****/ + +IMPLEMENT_SERIALIZER_CLASS( wxTabbedWindow, + wxTabbedWindowSerializer, + wxTabbedWindowSerializer::Serialize, + wxTabbedWindowSerializer::Initialize) + +void wxTabbedWindowSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxTabbedWindow* pWnd = (wxTabbedWindow*)pObj; + + // we're kind of window - serialize it first + + if ( store.IsLoading() ) + + // FOR NOW::workaround for the mistery + + pWnd->mpTabScroll = (wxScrollBar*)(-1); + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxWindowSerializer::CreateWindowFn, + FALSE ); + + store.XchgObjList( pWnd->mTabs ); + + store.XchgInt( pWnd->mActiveTab ); + store.XchgInt( pWnd->mTitleHeight ); + store.XchgInt( pWnd->mLayoutType ); + store.XchgInt( pWnd->mTitleHeight ); + + store.XchgObj( (wxObject*) &(pWnd->mWhitePen) ); + store.XchgObj( (wxObject*) &(pWnd->mGrayPen) ); + store.XchgObj( (wxObject*) &(pWnd->mDarkPen) ); + store.XchgObj( (wxObject*) &(pWnd->mBlackPen) ); + + store.XchgObjPtr( (wxObject**) &(pWnd->mpTabScroll ) ); + store.XchgObjPtr( (wxObject**) &(pWnd->mpHorizScroll) ); + store.XchgObjPtr( (wxObject**) &(pWnd->mpVertScroll ) ); + + store.XchgInt( pWnd->mVertGap ); + store.XchgInt( pWnd->mHorizGap ); + store.XchgInt( pWnd->mTitleVertGap ); + store.XchgInt( pWnd->mTitleHorizGap ); + store.XchgInt( pWnd->mImageTextGap ); + store.XchgInt( pWnd->mFirstTitleGap ); + store.XchgInt( pWnd->mBorderOnlyWidth ); +} + +void wxTabbedWindowSerializer::Initialize( wxObject* pObj ) +{ + wxTabbedWindow* pWnd = (wxTabbedWindow*)pObj; + + pWnd->RecalcLayout(TRUE); +} + +/***** Implementation for class twTabInfoSerializer ****/ + +IMPLEMENT_SERIALIZER_CLASS( twTabInfo, + twTabInfoSerializer, + twTabInfoSerializer::Serialize, + NO_CLASS_INIT ) + +void twTabInfoSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + twTabInfo* pInfo = (twTabInfo*)pObj; + + store.XchgObjPtr( (wxObject**) &(pInfo->mpContent) ); + + // NOTE:: wxSize is NOT a dynamic class unfortunately ... + + store.XchgWxSize( pInfo->mDims ); + + store.XchgWxStr ( pInfo->mText ); + store.XchgWxStr( pInfo->mImageFile ); + + store.XchgLong( pInfo->mImageType ); + + if ( store.IsLoading() && wxFileExists( pInfo->mImageFile ) ) + + pInfo->mBitMap.LoadFile( pInfo->mImageFile, pInfo->mImageType ); +} + diff --git a/utils/framelayout/src/cbstore.h b/utils/framelayout/src/cbstore.h new file mode 100644 index 0000000000..26c64ea501 --- /dev/null +++ b/utils/framelayout/src/cbstore.h @@ -0,0 +1,181 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 __CBSTORE_G__ +#define __CBSTORE_G__ + +#include "controlbar.h" +#include "objstore.h" // used for persistance of control-bars + +// serializers for some additional classes placed here +#include "rowdragpl.h" +#include "toolwnd.h" +#include "newbmpbtn.h" +#include "dyntbar.h" +#include "controlarea.h" + +// serialziers for common components of frame-layout engine + +class wxFrameLayoutSerializer : public wxEvtHandlerSerializer +{ + DECLARE_SERIALIZER_CLASS( wxFrameLayoutSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +class cbBarSpySerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbBarSpySerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +class cbBarDimHandlerBaseSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbBarDimHandlerBaseSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbDimInfoSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbDimInfoSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbRowInfoSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbRowInfoSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; +class cbBarInfoSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbBarInfoSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; +class cbCommonPanePropertiesSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbCommonPanePropertiesSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbDockPaneSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbDockPaneSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbUpdatesManagerBaseSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbUpdatesManagerBaseSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbPluginBaseSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbPluginBaseSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +class cbRowDragPluginSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbRowDragPluginSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +class cbHiddenBarInfoSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( cbHiddenBarInfoSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class cbFloatedBarWindowSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( cbFloatedBarWindowSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); + + static void CreateFloatedBarWindowFn( cbFloatedBarWindow* fbar, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, + const wxString& name ); +}; + +/*** serializers for some additional classes (FOR NOW:: also placed here) ***/ + +class wxNewBitmapButtonSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxNewBitmapButtonSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); + + static void CreateNewBmpBtnWindowFn( wxNewBitmapButton* btn, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, + const wxString& name ); +}; + +class wxDynamicToolBarSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxDynamicToolBarSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); + + static void CreateDynTBarWindowFn( wxDynamicToolBar* btn, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, + const wxString& name ); +}; + +class wxDynToolInfoSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxDynToolInfoSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +class wxTabbedWindowSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxTabbedWindowSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +class twTabInfoSerializer : wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( twTabInfoSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +#endif \ No newline at end of file diff --git a/utils/framelayout/src/controlarea.cpp b/utils/framelayout/src/controlarea.cpp new file mode 100644 index 0000000000..b960b1c6db --- /dev/null +++ b/utils/framelayout/src/controlarea.cpp @@ -0,0 +1,1164 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 07/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "controlarea.h" +// #pragma interface +#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 and wxFileExist(..) + +#include "controlarea.h" + + +/***** Implementation for class twTabInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( twTabInfo, wxObject ) + +twTabInfo::twTabInfo() + : mpContent( 0 ) +{} + +twTabInfo::~twTabInfo() +{ + // FOR NOW:: nothing +} + +int twTabInfo::ImgWidth() +{ + if ( mBitMap.Ok() ) return mBitMap.GetWidth(); + else return 0; +} + +int twTabInfo::ImgHeight() +{ + if ( mBitMap.Ok() ) return mBitMap.GetHeight(); + else return 0; +} + +int twTabInfo::ImageToTxtGap( int prefGap ) +{ + if ( mBitMap.Ok() ) return prefGap; + else return 0; +} + +bool twTabInfo::HasImg() +{ + return mBitMap.Ok(); +} + +bool twTabInfo::HasText() +{ + return mText.Length(); +} + +wxBitmap& twTabInfo::GetImg() +{ + return mBitMap; +} + +wxString& twTabInfo::GetText() +{ + return mText; +} + +wxWindow& twTabInfo::GetContent() +{ + return *mpContent; +} + +/***** Implementation for class wxTabbedWindow *****/ + +IMPLEMENT_DYNAMIC_CLASS( wxTabbedWindow, wxPanel ) + +BEGIN_EVENT_TABLE( wxTabbedWindow, wxPanel ) + + EVT_SIZE ( wxTabbedWindow::OnSize ) + EVT_PAINT( wxTabbedWindow::OnPaint ) + EVT_LEFT_DOWN( wxTabbedWindow::OnLButtonDown ) + +// TDB:: filciker reduction +// EVT_ERASE_BACKGROUND( wxTabbedWindow::OnBkErase ) + +END_EVENT_TABLE() + +wxTabbedWindow::wxTabbedWindow() + + : mpTabScroll ( NULL ), + mpHorizScroll( NULL ), + mpVertScroll ( NULL ), + + mVertGap ( 0 ), + mHorizGap( 0 ), + + mTitleVertGap ( 3 ), + mTitleHorizGap( 4 ), + mImageTextGap ( 2 ), + mFirstTitleGap( 11 ), + + mBorderOnlyWidth( 8 ), + + mWhitePen( wxColour(255,255,255), 1, wxSOLID ), + mGrayPen ( wxColour(192,192,192), 1, wxSOLID ), + mDarkPen ( wxColour(128,128,128), 1, wxSOLID ), + mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ), + + // state variables + + mActiveTab ( 0 ), + mTitleHeight( 0 ), + mLayoutType( wxTITLE_IMG_AND_TEXT ) +{} + +wxTabbedWindow::~wxTabbedWindow() +{ + wxNode* pTab = mTabs.First(); + + while( pTab ) + { + delete ((twTabInfo*)pTab->Data()); + + pTab = pTab->Next(); + } +} + +void wxTabbedWindow::SizeTabs(int x,int y, int width, int height, bool repant) +{ + wxNode* pTabNode = mTabs.First(); + int n = 0; + + while( pTabNode ) + { + twTabInfo& info = *((twTabInfo*)pTabNode->Data()); + + if ( n == mActiveTab ) + { + //wxSizeEvent evt; + //info.mpContent->GetEventHandler()->ProcessEvent( evt ); + + info.mpContent->SetSize( x, y, width, height, 0 ); + info.mpContent->Show(TRUE); + info.mpContent->Refresh(); + + } + else + { + info.mpContent->Show(FALSE); + } + + pTabNode = pTabNode->Next(); + ++n; + } +} + +void wxTabbedWindow::AddTab( wxWindow* pContent, + wxString tabText, + wxString imageFileName, + long imageType ) +{ + twTabInfo* pTab = new twTabInfo(); + + pTab->mpContent = pContent; + pTab->mText = tabText; + + if ( wxFileExists( imageFileName ) && + + pTab->mBitMap.LoadFile( imageFileName, imageType ) ) + { + pTab->mImageFile = imageFileName; + pTab->mImageType = imageType; + } + + bool ok = pTab->mBitMap.Ok(); + + if ( pContent->GetParent() == NULL ) + + pContent->Create( this, -1 ); + + mTabs.Append( (wxObject*)pTab ); + + RecalcLayout(TRUE); + + OnTabAdded( pTab ); +} + +void wxTabbedWindow::AddTab( wxWindow* pContent, + wxString tabText, + wxBitmap* pImage ) +{ + twTabInfo* pTab = new twTabInfo(); + + pTab->mpContent = pContent; + pTab->mText = tabText; + + if ( pImage ) pTab->mBitMap = *pImage; + + if ( pContent->GetParent() == NULL ) + + pContent->Create( this, -1 ); + + mTabs.Append( (wxObject*)pTab ); + + RecalcLayout(TRUE); + + OnTabAdded( pTab ); +} + + + +void wxTabbedWindow::RemoveTab( int tabNo ) +{ + twTabInfo* pTab = ((twTabInfo*)(mTabs.Nth( tabNo )->Data())); + + pTab->mpContent->Destroy(); + + delete pTab; + + mTabs.DeleteNode( mTabs.Nth( tabNo ) ); + + if ( mActiveTab >= mTabs.Number() ); + + mActiveTab = mTabs.Number() - 1; + + SetActiveTab( mActiveTab ); +} + +int wxTabbedWindow::GetTabCount() +{ + return mTabs.Number(); +} + +wxWindow* wxTabbedWindow::GetTab( int tabNo ) +{ + return ((twTabInfo*)(mTabs.Nth( tabNo )->Data()))->mpContent; +} + +wxWindow* wxTabbedWindow::GetActiveTab() +{ + // FIMXE:: this is lame + + return GetTab( mActiveTab ); +} + +void wxTabbedWindow::SetActiveTab( int tabNo ) +{ + mActiveTab = tabNo; + + RecalcLayout(TRUE); + + Refresh(); +} + +// width of the decorations border (4 shade-lines), should not be changed + +#define BORDER_SZ 4 + +void wxTabbedWindow::DrawShadedRect( int x, int y, int width, int height, + wxPen& upperPen, wxPen& lowerPen, wxDC& dc + ) +{ + // darw the lightened upper-left sides of the rectangle + + dc.SetPen( upperPen ); + dc.DrawLine( x,y, x, y + height - 1 ); // vert + dc.DrawLine( x,y, x + width - 1, y ); // horiz + + // draw the unenlightened lower-right sides of the rectangle + + dc.SetPen( lowerPen ); + dc.DrawLine( x + width - 1, y, x + width - 1, y + height - 1 ); // vert + dc.DrawLine( x, y + height - 1, x + width, y + height - 1 ); // horiz +} + +void wxTabbedWindow::DrawDecorations( wxDC& dc ) +{ + // Protability NOTE::: DrawLine(..) draws a line from the first position, + // but not including the point specified by last position. + // This way Windows draws lines, not sure how Motif and Gtk + // prots behave... + + int width, height; + GetClientSize( &width, &height ); + + // check if there's at least a bit of space to draw things + + if ( width < mHorizGap*2 + BORDER_SZ*2+1 || + height < mVertGap*2 + BORDER_SZ*2+1 + mTitleHeight + ) + return; + + // step #1 - draw border around the tab content area + + // setup position for kind of "pencil" + int curX = mHorizGap; + int curY = mVertGap; + + int xSize = width - mHorizGap*2; + int ySize = height - mVertGap *2 - mTitleHeight; + + // layer 1 (upper white) + DrawShadedRect( curX+0, curY+0, xSize-0, ySize-0, + mWhitePen, mBlackPen, dc ); + + // layer 2 (upper gray) + DrawShadedRect( curX+1, curY+1, xSize-2-1, ySize-2-1, + mGrayPen, mGrayPen, dc ); + + // layer 3 (upper darkGray) + DrawShadedRect( curX+2, curY+2, xSize-3-2, ySize-3-2, + mDarkPen, mWhitePen, dc ); + + // layer 4 (upper black) + DrawShadedRect( curX+3, curY+3, xSize-4-3, ySize-4-3, + mBlackPen, mGrayPen, dc ); + + // add non-siemtric layer from the lower-right side (confroming to MFC-look) + + dc.SetPen( mDarkPen ); + dc.DrawLine( curX+1, curY + ySize - 2, curX + xSize - 1, curY + ySize - 2 ); // horiz + dc.DrawLine( curX + xSize - 2, curY + 1, curX + xSize - 2, curY + ySize - 2 ); // vert + + // step #2 - draw tab title bars + + curX = mFirstTitleGap; + curY = height - mVertGap - mTitleHeight; + + int tabNo = 0; + wxNode* pNode = mTabs.First(); + + while( pNode ) + { + // "hard-coded metafile" for decorations + + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + xSize = tab.mDims.x; + ySize = mTitleHeight; + + if ( tabNo == mActiveTab ) + { + dc.SetPen( mGrayPen ); + dc.DrawLine( curX+1, curY-2, curX+xSize-2, curY-2 ); + dc.DrawLine( curX+1, curY-1, curX+xSize-2, curY-1 ); + } + + dc.SetPen( mWhitePen ); + + if ( tabNo == mActiveTab ) + dc.DrawLine( curX, curY-2, curX, curY+ySize-2 ); + else + dc.DrawLine( curX, curY, curX, curY+ySize-2 ); + + dc.SetPen( mDarkPen ); + dc.DrawLine( curX+1, curY+ySize-3, curX+1, curY+ySize-1 ); // to pix down + dc.DrawLine( curX+2, curY+ySize-2, curX+xSize-2, curY+ySize-2 ); + dc.DrawLine( curX+xSize-3, curY+ySize-3, curX+xSize-2, curY+ySize-3 ); + if ( tabNo == mActiveTab ) + dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-3 ); + else + dc.DrawLine( curX+xSize-2, curY+ySize-3, curX+xSize-2, curY-1 ); + + dc.SetPen( mBlackPen ); + dc.DrawLine( curX+xSize-1, curY, curX+xSize-1, curY+ySize-2 ); + dc.DrawLine( curX+xSize-2, curY+ySize-2, curX+xSize-3, curY+ySize-2 ); + dc.DrawLine( curX+xSize-3, curY+ySize-1, curX+1, curY+ySize-1 ); + + pNode = pNode->Next(); + ++tabNo; + + // darw image and (or without) text centered within the + // title bar rectangle + + if ( mLayoutType != wxTITLE_BORDER_ONLY && tab.HasImg() ) + { + wxMemoryDC tmpDc; + tmpDc.SelectObject( tab.GetImg() ); + + dc.Blit( curX + mTitleHorizGap, + curY + ( ySize - tab.ImgHeight() ) / 2, + tab.ImgWidth(), + tab.ImgHeight(), + &tmpDc, 0, 0, wxCOPY + ); + } + + if ( mLayoutType == wxTITLE_IMG_AND_TEXT && tab.HasText() ) + { + long x,w,h; + + // set select default font of the window into it's device context + dc.SetFont( GetLabelingFont() ); + + dc.SetTextBackground( GetBackgroundColour() ); + + dc.GetTextExtent(tab.mText, &w, &h ); + + x = curX + mTitleHorizGap + + tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap); + + dc.DrawText( tab.GetText(), x, curY + ( ySize - h ) / 2 ); + } + curX += xSize; + + } // end of `while (pNode)' +} + +int wxTabbedWindow::HitTest( const wxPoint& pos ) +{ + int width, height; + GetClientSize( &width, &height ); + + int curX = mFirstTitleGap; + int curY = height - mVertGap - mTitleHeight; + + int tabNo = 0; + wxNode* pNode = mTabs.First(); + + int x = pos.x; + int y = pos.y; + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + int w,h; + w = tab.mDims.x; + h = tab.mDims.y; + // hit test rectangle of the currnet tab title bar + if ( pos.x >= curX && pos.x < curX + tab.mDims.x && + pos.y >= curY && pos.y < curY + tab.mDims.y + ) + { + return tabNo; + } + + curX += tab.mDims.x; + + pNode = pNode->Next(); + ++tabNo; + } + + return -1; +} + +void wxTabbedWindow::HideInactiveTabs( bool andRepaint ) +{ + if ( !andRepaint ) + return; + + wxNode* pNode = mTabs.First(); + int tabNo = 0; + + while( pNode ) + { + if ( tabNo != mActiveTab ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + tab.mpContent->Show(FALSE); + } + + pNode = pNode->Next(); + ++tabNo; + } +} + +wxFont wxTabbedWindow::GetLabelingFont() +{ + wxFont font; +#ifdef __WINDOWS__ + font.SetFaceName("MS Sans Serif"); +#else + font.SetFamily( wxSWISS ); +#endif + + font.SetStyle(40); + font.SetWeight(40); + font.SetPointSize( 8 ); + +#ifdef __WINDOWS__ + font.RealizeResource(); +#endif + + return font; +} + +void wxTabbedWindow::RecalcLayout(bool andRepaint) +{ + HideInactiveTabs(andRepaint); + + // resetup position of the active tab + + int width, height; + GetClientSize( &width, &height ); + + int curX = mHorizGap + BORDER_SZ; + int curY = mVertGap + BORDER_SZ; + + int xSize = width - mHorizGap*2 - BORDER_SZ*2-1; + int ySize = height - mVertGap*2 - BORDER_SZ*2-1 - mTitleHeight; + + SizeTabs( curX, curY, xSize, ySize, andRepaint ); + + // pass #1 - try to layout assuming it's wxTITLE_IMG_AND_TEXT + + mLayoutType = wxTITLE_IMG_AND_TEXT; + + wxNode* pNode = mTabs.First(); + + curX = mFirstTitleGap; // the left-side gap + mTitleHeight = 0; + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + wxWindowDC dc(this); + + long w,h; + + // set select default font of the window into it's device context + dc.SetFont( GetLabelingFont() ); + + dc.GetTextExtent(tab.mText, &w, &h ); + + tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) + + tab.ImgWidth() + mTitleHorizGap*2; + + tab.mDims.y = wxMax( h, tab.ImgHeight() ) + mTitleVertGap*2; + mTitleHeight = wxMax( mTitleHeight, tab.mDims.y ); + + curX += tab.mDims.x; + + pNode = pNode->Next(); + } + + curX += mHorizGap; // the right-side gap + + // make all title bars of equel height + + pNode = mTabs.First(); + + while( pNode ) + { + ((twTabInfo*)(pNode->Data()))->mDims.y = mTitleHeight;; + pNode = pNode->Next(); + } + + // if curX has'nt ran out of bounds, leave TITLE_IMG layout and return + if ( curX < width - mHorizGap ) + return; + + // pass #2 - try to layout assuming wxTITLE_IMG_ONLY + + mLayoutType = wxTITLE_IMG_ONLY; + + pNode = mTabs.First(); + + curX = mFirstTitleGap; // the left-side gap + + int denomiator = mTabs.Number(); + if ( denomiator == 0 ) ++denomiator; + + mBorderOnlyWidth = (width - mFirstTitleGap - mHorizGap) / denomiator; + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + if ( tab.HasImg() ) + { + tab.mDims.x = tab.ImgWidth() + mTitleHorizGap*2; + tab.mDims.y = tab.ImgHeight() + mTitleVertGap*2; + } + else + { + tab.mDims.x = mBorderOnlyWidth; + tab.mDims.y = mTitleHeight; + } + + curX += tab.mDims.x; + + pNode = pNode->Next(); + } + + curX += mHorizGap; // the right-side gap + + // if curX has'nt ran out of bounds, leave IMG_ONLY layout and return + if ( curX < width - mHorizGap ) + return; + + // pass #3 - set the narrowest layout wxTITLE_BORDER_ONLY + + mLayoutType = wxTITLE_BORDER_ONLY; + + pNode = mTabs.First(); + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + tab.mDims.x = mBorderOnlyWidth; + tab.mDims.y = mTitleHeight; + + pNode = pNode->Next(); + } +} + +// wx event handlers + +void wxTabbedWindow::OnPaint( wxPaintEvent& event ) +{ + wxPaintDC dc(this); + DrawDecorations( dc ); +} + +void wxTabbedWindow::OnSize ( wxSizeEvent& event ) +{ + SetBackgroundColour( wxColour( 192,192,192 ) ); + RecalcLayout(TRUE); +} + +void wxTabbedWindow::OnBkErase( wxEraseEvent& event ) +{ + // do nothing +} + +void wxTabbedWindow::OnLButtonDown( wxMouseEvent& event ) +{ + // floats, why? + int x = (int)event.m_x; + int y = (int)event.m_y; + + int tabNo = HitTest( wxPoint(x,y) ); + + if ( tabNo != -1 ) + { + SetActiveTab( tabNo ); + } +} + +/***** Implementation for class wxPaggedWindow *****/ + +IMPLEMENT_DYNAMIC_CLASS( wxPaggedWindow, wxTabbedWindow ) + +BEGIN_EVENT_TABLE( wxPaggedWindow, wxTabbedWindow ) + EVT_SIZE ( wxPaggedWindow::OnSize ) + EVT_PAINT ( wxPaggedWindow::OnPaint ) + EVT_LEFT_DOWN( wxPaggedWindow::OnLButtonDown ) + EVT_LEFT_UP ( wxPaggedWindow::OnLButtonUp ) + EVT_MOTION ( wxPaggedWindow::OnMouseMove ) + EVT_SCROLL ( wxPaggedWindow::OnScroll ) +END_EVENT_TABLE() + +// border for pagged-window is 2 shaded-lines + +#undef BORDER_SZ +#define BORDER_SZ 2 + +wxPaggedWindow::wxPaggedWindow() + + : mScrollEventInProgress( FALSE ), + + mTabTrianGap(4), + + mWhiteBrush( wxColour(255,255,255), wxSOLID ), + mGrayBrush ( wxColour(192,192,192), wxSOLID ), + + mCurentRowOfs( 0 ), + mAdjustableTitleRowLen( 300 ), + + mIsDragged ( FALSE ), + mDagOrigin ( 0 ), + mCursorChanged( FALSE ), + mResizeCursor ( wxCURSOR_SIZEWE ), + mNormalCursor ( wxCURSOR_ARROW ) +{ + mTitleVertGap = 2; + mTitleHorizGap = 10; +} + +wxPaggedWindow::~wxPaggedWindow() +{ + // nothing (base class handles destruction) +} + +wxFont wxPaggedWindow::GetLabelingFont() +{ + wxFont font; + +#ifdef __WINDOWS__ + font.SetFaceName("Arial"); +#else + font.SetFamily( wxSWISS ); +#endif + + font.SetStyle(40); + font.SetWeight(40); + font.SetPointSize( 8 ); + +#ifdef __WINDOWS__ + bool success = font.RealizeResource(); +#endif + + return font; +} + +void wxPaggedWindow::OnTabAdded( twTabInfo* pInfo ) +{ + int units = GetWholeTabRowLen() / 20; + + mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE ); +} + +wxScrollBar& wxPaggedWindow::GetVerticalScrollBar() +{ + return *mpVertScroll; +} + +wxScrollBar& wxPaggedWindow::GetHorizontalScrollBar() +{ + return *mpHorizScroll; +} + + +int wxPaggedWindow::GetWholeTabRowLen() +{ + wxNode* pNode = mTabs.First(); + + int len = 0; + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + len += tab.mDims.x; + pNode = pNode->Next(); + } + + return len; +} + +void wxPaggedWindow::DrawPaperBar( twTabInfo& tab, int x, int y, + wxBrush& brush, wxPen& pen, wxDC& dc ) +{ + wxPoint poly[4]; + + // draw organizer-style paper outlet + + poly[0].x = x - mTabTrianGap; + poly[0].y = y; + + poly[1].x = x + mTabTrianGap; + poly[1].y = y + tab.mDims.y-1; + + poly[2].x = x + tab.mDims.x - mTabTrianGap; + poly[2].y = y + tab.mDims.y-1; + + poly[3].x = x + tab.mDims.x + mTabTrianGap; + poly[3].y = y; + + dc.SetPen( pen ); + dc.SetBrush( brush ); + + dc.DrawPolygon( 4, poly ); + + long w,h; + + // set select default font of the window into it's device context + dc.SetFont( GetLabelingFont() ); + + dc.SetTextBackground( brush.GetColour() ); + + dc.GetTextExtent(tab.mText, &w, &h ); + + if ( tab.HasImg() ) + { + wxMemoryDC tmpDc; + tmpDc.SelectObject( tab.GetImg() ); + + dc.Blit( x + mTitleHorizGap, + y + ( tab.mDims.y - tab.ImgHeight() ) / 2, + tab.ImgWidth(), + tab.ImgHeight(), + &tmpDc, 0, 0, wxCOPY + ); + } + + if ( tab.HasText() ) + { + int tx = x + mTitleHorizGap + + tab.ImgWidth() + tab.ImageToTxtGap(mImageTextGap); + + dc.DrawText( tab.GetText(), tx, y + ( tab.mDims.y - h ) / 2 ); + } +} + +void wxPaggedWindow::DrawDecorations( wxDC& dc ) +{ + // FIXME:: the is big body have to be split! + + int width, height; + GetClientSize( &width, &height ); + + int curX = mHorizGap; + int curY = mVertGap; + + int xSize = width - mHorizGap*2; + int ySize = height - mVertGap*2; + + DrawShadedRect( curX, curY, xSize, ySize, + mDarkPen, mWhitePen, dc ); + + DrawShadedRect( curX+1, curY+1, xSize-2, ySize-2, + mBlackPen, mGrayPen, dc ); + + // draw inactive tab title bars frist (left-to-right) + + wxNode* pNode = mTabs.First(); + int tabNo = 0; + + /* OLD STUFF:: + curX = mTitleRowStart; + curY = height - mVertGap - BORDER_SZ - mTitleHeight; + */ + + curX = mTabTrianGap; + curY = 0; + + // FOR NOW:: avoid creating bitmap with invalid dimensions + + if ( mTitleRowLen < 1 || mTitleHeight < 1 ) return; + + wxMemoryDC tmpDc; + wxBitmap tmpBmp( mTitleRowLen, mTitleHeight ); + + tmpDc.SelectObject( tmpBmp ); + tmpDc.SetPen( mGrayPen ); + tmpDc.SetBrush( mGrayBrush ); + tmpDc.DrawRectangle( 0,0, mTitleRowLen, mTitleHeight ); + + tmpDc.SetDeviceOrigin( mCurentRowOfs, 0 ); + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + if ( tabNo != mActiveTab ) + + DrawPaperBar( tab, curX, curY, mGrayBrush, mBlackPen, tmpDc ); + + curX += tab.mDims.x; + + pNode = pNode->Next(); + ++tabNo; + } + + // finally, draw the active tab (white-filled) + + pNode = mTabs.First(); + tabNo = 0; + + curX = mTabTrianGap; + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + if ( tabNo == mActiveTab ) + { + DrawPaperBar( tab, curX, curY, mWhiteBrush, mBlackPen, tmpDc ); + + tmpDc.SetPen( mWhitePen ); + + tmpDc.DrawLine( curX - mTabTrianGap+1, curY, + curX + tab.mDims.x + mTabTrianGap, curY ); + break; + } + curX += tab.mDims.x; + + pNode = pNode->Next(); + ++tabNo; + } + + // back to initial device origin + + tmpDc.SetDeviceOrigin( 0, 0 ); + + // draw resize-hint-stick + + curX = mTitleRowLen - 6; + + DrawShadedRect( curX+0, 0+0, 6, mTitleHeight, mGrayPen, mBlackPen, tmpDc ); + DrawShadedRect( curX+1, 0+1, 6-2, mTitleHeight-2, mWhitePen, mDarkPen, tmpDc ); + DrawShadedRect( curX+2, 0+2, 6-4, mTitleHeight-4, mGrayPen, mGrayPen, tmpDc ); + + + + dc.Blit( mTitleRowStart, + height - mVertGap - BORDER_SZ - mTitleHeight, + mTitleRowLen, mTitleHeight, + &tmpDc, 0,0, wxCOPY ); +} + +int wxPaggedWindow::HitTest( const wxPoint& pos ) +{ + return wxTabbedWindow::HitTest( pos ); +} + +void wxPaggedWindow::RecalcLayout(bool andRepaint) +{ + mTitleRowLen = mAdjustableTitleRowLen; + + if ( int(mpTabScroll) == -1 ) return; + + // scroll bars should be created after Create() for this window is called + if ( !mpTabScroll ) + { + mpTabScroll = + new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL ); + + mpHorizScroll = + new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_HORIZONTAL ); + + mpVertScroll = + new wxScrollBar( this, -1, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL ); + } + + { + int units = GetWholeTabRowLen() / 20; + + mpTabScroll->SetScrollbar( 0, 1, units, 1, FALSE ); + } + + // resetup position of the active tab + + int thumbLen = 16; // FOR NOW:: hardcoded + + int width, height; + GetClientSize( &width, &height ); + + mTitleHeight = thumbLen; + + int curX = mHorizGap + BORDER_SZ; + int curY = mVertGap + BORDER_SZ; + + int xSize = width - mHorizGap*2 - BORDER_SZ*2 - thumbLen; + + int ySize = height - mVertGap*2 - BORDER_SZ*2 - mTitleHeight; + + SizeTabs( curX, curY, xSize, ySize, andRepaint ); + + // setup title bar LINES's horizontal scroll bar + + curY = height - mVertGap - BORDER_SZ - thumbLen; + + mpTabScroll->SetSize( curX, curY, thumbLen*2, thumbLen ); + + // setup view's HORIZONTAL scroll bar + + curX += thumbLen*2; + + mTitleRowStart = curX; + mFirstTitleGap = curX + mCurentRowOfs + mTabTrianGap; + + mTitleRowLen = wxMin( mAdjustableTitleRowLen, + width - mHorizGap - BORDER_SZ - thumbLen*4 - curX ); + + curX += mTitleRowLen; + + mpHorizScroll->SetSize( curX, curY, + width - curX - mHorizGap - BORDER_SZ - thumbLen, + thumbLen + ); + + // setup view's VERTICAL scroll bar + + curX = width - mHorizGap - BORDER_SZ - thumbLen; + + curY = mVertGap + BORDER_SZ; + + mpVertScroll->SetSize( curX, curY, thumbLen, + height - curY - mVertGap - BORDER_SZ - thumbLen + ); + + // layout tab title bars + + mLayoutType = wxTITLE_IMG_AND_TEXT; + + wxNode* pNode = mTabs.First(); + + while( pNode ) + { + twTabInfo& tab = *((twTabInfo*)(pNode->Data())); + + wxWindowDC dc(this); + + long w,h; + + // set select default font of the window into it's device context + dc.SetFont( GetLabelingFont() ); + dc.GetTextExtent(tab.mText, &w, &h ); + + tab.mDims.x = w + tab.ImageToTxtGap(mImageTextGap) + + tab.ImgWidth() + mTitleHorizGap*2; + + tab.mDims.y = mTitleHeight; + + pNode = pNode->Next(); + } + + // disable title-bar scroller if there's nowhere to scroll to + + mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 ); +} + +// event handlers + +void wxPaggedWindow::OnPaint( wxPaintEvent& event ) +{ + wxPaintDC dc(this); + DrawDecorations( dc ); +} + +void wxPaggedWindow::OnSize ( wxSizeEvent& event ) +{ + wxTabbedWindow::OnSize(event); +} + +void wxPaggedWindow::OnLButtonDown( wxMouseEvent& event ) +{ + if ( mCursorChanged ) + { + mIsDragged = TRUE; + mDagOrigin = event.m_x; + + mOriginalTitleRowLen = mAdjustableTitleRowLen; + + CaptureMouse(); + } + else + { + wxTabbedWindow::OnLButtonDown( event ); + } +} + +void wxPaggedWindow::OnLButtonUp( wxMouseEvent& event ) +{ + if ( mIsDragged ) + { + mIsDragged = FALSE; + mCursorChanged = FALSE; + SetCursor( mNormalCursor ); + + ReleaseMouse(); + } +} + +void wxPaggedWindow::OnMouseMove( wxMouseEvent& event ) +{ + int width, height; + GetClientSize( &width, &height ); + + if ( !mIsDragged ) + { + int y = height - mVertGap - BORDER_SZ - mTitleHeight; + int x = mTitleRowStart + mTitleRowLen - 6; + + if ( event.m_x >= x && event.m_y >= y && + event.m_x < x + 6 && + event.m_y < y + mTitleHeight + ) + { + if ( !mCursorChanged ) + { + SetCursor( mResizeCursor ); + + mCursorChanged = TRUE; + } + } + else + if ( mCursorChanged ) + { + SetCursor( mNormalCursor ); + + mCursorChanged = FALSE; + } + } + else + if ( mIsDragged ) + { + mAdjustableTitleRowLen = mOriginalTitleRowLen + ( event.m_x - mDagOrigin ); + + // FOR NOW:: fixed + if ( mAdjustableTitleRowLen < 6 ) mAdjustableTitleRowLen = 6; + + wxWindowDC dc(this); + DrawDecorations( dc ); + + RecalcLayout(FALSE); + + //Refresh(); + } +} + +void wxPaggedWindow::OnScroll( wxScrollEvent& event ) +{ + int cmd = event.m_commandInt; + + wxScrollBar* pSender = (wxScrollBar*)event.GetEventObject(); + + if ( pSender == mpTabScroll ) + { + int maxLen = GetWholeTabRowLen(); + + int maxUnits = GetWholeTabRowLen() / 20; + + mCurentRowOfs = -event.GetPosition()*maxUnits; + + mFirstTitleGap = mTitleRowStart + mCurentRowOfs + mTabTrianGap; + + // let' it automatically disable itself if it's time + mpTabScroll->Enable( mTitleRowLen < GetWholeTabRowLen() || mCurentRowOfs < 0 ); + + // repaint title bars + wxWindowDC dc(this); + DrawDecorations( dc ); + } + else + if ( !mScrollEventInProgress ) + { + mScrollEventInProgress = TRUE; + + GetActiveTab()->GetEventHandler()->ProcessEvent( event ); + } + else + { + // event bounced back to us, from here we + // know that it has traveled the loop - thus it's processed! + + mScrollEventInProgress = FALSE; + } +} diff --git a/utils/framelayout/src/controlarea.h b/utils/framelayout/src/controlarea.h new file mode 100644 index 0000000000..69f9343807 --- /dev/null +++ b/utils/framelayout/src/controlarea.h @@ -0,0 +1,261 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 07/09/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __CONTROLAREA_G__ +#define __CONTROLAREA_G__ + +#ifdef __GNUG__ +#pragma interface "controlarea.h" +#endif + +#include "wx/defs.h" +#include "wx/window.h" +#include "wx/string.h" + +#define WXCONTROLAREA_VERSION 1.0 + +// layout types for title bars of the tabs +// (are selected up by evaluating the available free space ) + +class twTabInfo; // forward decl. + +#define wxTITLE_IMG_AND_TEXT 0 +#define wxTITLE_IMG_ONLY 1 +#define wxTITLE_BORDER_ONLY 2 + +/* + * class manages and decorates contained "tab"-windows. + * Draws decorations similar to those in "Project Workplace" + * of Microsoft Developer Studio 4.xx + */ + +class wxTabbedWindow : public wxPanel +{ + DECLARE_DYNAMIC_CLASS( wxTabbedWindow ) + +public: + + friend class wxTabbedWindowSerializer; + + wxList mTabs; + int mActiveTab; + int mTitleHeight; + int mLayoutType; + + void HideInactiveTabs( bool andRepaint ); + + // overrride,to provide different font for tab-labels + + virtual wxFont GetLabelingFont(); + + // FOR NOW:: scrollbars are actually related to wxPaggedWindow + + wxScrollBar* mpTabScroll; + wxScrollBar* mpHorizScroll; + wxScrollBar* mpVertScroll; + +public: + + // public properties (invoke ReclaclLayout(TRUE) to apply changes) + + wxPen mWhitePen; // default: RGB(255,255,255) + wxPen mGrayPen; // default: RGB(192,192,192) + wxPen mDarkPen; // default: RGB(128,128,128) + wxPen mBlackPen; // default: RGB( 0, 0, 0) + + int mVertGap; // default: 3 + int mHorizGap; // default: 5 + int mTitleVertGap; // default: 3 + int mTitleHorizGap; // default: 4 + int mImageTextGap; // default: 2 + int mFirstTitleGap; // default: 11 + int mBorderOnlyWidth; // default: 8 + + // notifications (can be handled by derivatives) + + virtual void OnTabAdded( twTabInfo* pInfo ) {} + + virtual void SizeTabs(int x,int y, int width, int height, bool repant); + +public: + wxTabbedWindow(); + virtual ~wxTabbedWindow(); + + // tabs can be also added when the window is + // already displayed - "on the fly" + + virtual void AddTab( wxWindow* pContent, // contained window + wxString tabText, // tab label + wxString imageFileName = "", // if "", only text label is displayed + long imageType = wxBITMAP_TYPE_BMP ); + + // NOTE:: if this AddTab(..) overload is called, the + // image bitmap will not be serialized (if performed), + // use the above method instead, so that images could + // be restored using the given file names + + virtual void AddTab( wxWindow* pContent, + wxString tabText, + wxBitmap* pImage = NULL ); + + + virtual void RemoveTab( int tabNo ); + + /* misc accessors */ + + virtual int GetTabCount(); + virtual wxWindow* GetTab( int tabNo ); + virtual wxWindow* GetActiveTab(); + virtual void SetActiveTab( int tabNo ); + + void DrawShadedRect( int x, int y, int width, int height, + wxPen& upperPen, wxPen& lowerPen, wxDC& dc ); + + virtual void DrawDecorations( wxDC& dc ); + + // return -1, if non of the title bars was hitted, + // otherwise the index of the hitted tab title bar + + virtual int HitTest( const wxPoint& pos ); + + // should be invoked to redisplay window with changed properties + + virtual void RecalcLayout( bool andRepaint = TRUE ); + + // event handlers + + void OnPaint( wxPaintEvent& event ); + void OnSize ( wxSizeEvent& event ); + + void OnBkErase( wxEraseEvent& event ); + void OnLButtonDown( wxMouseEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +/* + * class manages and decorates contained "sheets" (or pages). + * Draws decorations similar to those in "Output window" + * of Microsoft Developer Studio 4.xx + */ + +class wxPaggedWindow : public wxTabbedWindow +{ + DECLARE_DYNAMIC_CLASS( wxPaggedWindow ) +protected: + + bool mScrollEventInProgress; + + // drag&drop state variables + + bool mIsDragged; + int mDagOrigin; + wxCursor mResizeCursor; + wxCursor mNormalCursor; + bool mCursorChanged; + int mOriginalTitleRowLen; + + void DrawPaperBar( twTabInfo& tab, int x, int y, + wxBrush& brush, wxPen& pen, wxDC& dc ); + + int GetWholeTabRowLen(); + + // adjusts scorllbars to fit around tabs + + virtual void OnTabAdded( twTabInfo* pInfo ); + + // sets smaller font for page-labels + + virtual wxFont GetLabelingFont(); + +public: + int mTitleRowStart; + int mResizeNailGap; + int mTabTrianGap; + int mTitleRowLen; // actual title row length + int mAdjustableTitleRowLen; // setup by dragging mini-sash + // with the mosue pointer + int mCurentRowOfs; + + wxBrush mGrayBrush; + wxBrush mWhiteBrush; + +public: + wxPaggedWindow(); + ~wxPaggedWindow(); + + // NOTE:: use public methods of the base class + // to add "pages" to this window + + /* misc accessors */ + + // below two methods should be called after + // the tabs were added (AddTab(..)). Set up + // these scrollbars to match the needs of the + // tabs added into this area + + wxScrollBar& GetVerticalScrollBar(); + wxScrollBar& GetHorizontalScrollBar(); + + virtual void DrawDecorations( wxDC& dc ); + + // return -1, if non of the title bars was hitted, + // otherwise the index of the hitted tab title bar + + virtual int HitTest( const wxPoint& pos ); + + virtual void RecalcLayout( bool andRepaint = TRUE ); + + // event handlers + + void OnPaint( wxPaintEvent& event ); + void OnSize ( wxSizeEvent& event ); + void OnLButtonDown( wxMouseEvent& event ); + void OnLButtonUp ( wxMouseEvent& event ); + void OnMouseMove ( wxMouseEvent& event ); + void OnScroll ( wxScrollEvent& event ); + + DECLARE_EVENT_TABLE() +}; + +// helper structure of wxTabbedWindow + +class twTabInfo : public wxObject +{ + DECLARE_DYNAMIC_CLASS( twTabInfo ) +public: + twTabInfo(); + ~twTabInfo(); + + int ImgWidth(); + int ImgHeight(); + int ImageToTxtGap( int prefGap ); + + bool HasImg(); + wxBitmap& GetImg(); + bool HasText(); + wxString& GetText(); + wxWindow& GetContent(); + +public: + wxWindow* mpContent; + wxBitmap mBitMap; + + wxString mText; + wxSize mDims; + + // used for serialization + wxString mImageFile; + long mImageType; + +}; + +#endif diff --git a/utils/framelayout/src/controlbar.cpp b/utils/framelayout/src/controlbar.cpp new file mode 100644 index 0000000000..9dcd33dea2 --- /dev/null +++ b/utils/framelayout/src/controlbar.cpp @@ -0,0 +1,3350 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "controlbar.h" + +// import classes of default plugins + +#include "panedrawpl.h" +#include "rowlayoutpl.h" +#include "antiflickpl.h" +#include "bardragpl.h" +#include "cbcustom.h" + +#include "gcupdatesmgr.h" // import default updates manager class ("garbage-collecting" one) +#include "updatesmgr.h" + +#include "toolwnd.h" + +// 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 ( wxColour(128,128,128), 1, wxSOLID ), + mLightPen ( wxColour(255,255,255), 1, wxSOLID ), + mGrayPen ( wxColour(192,192,192), 1, wxSOLID ), + mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ), + mBorderPen( wxColour(192,192,192), 1, wxSOLID ), + + mpPaneInFocus( NULL ), + mpLRUPane ( NULL ), + + mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ), + + mpTopPlugin ( NULL ), + mpCaputesInput( NULL ), + mRecalcPending( TRUE ), + + mCheckFocusWhenIdle( FALSE ), + mClientWndRefreshPending( 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 ( wxColour(128,128,128), 1, wxSOLID ), + mLightPen ( wxColour(255,255,255), 1, wxSOLID ), + mGrayPen ( wxColour(192,192,192), 1, wxSOLID ), + mBlackPen ( wxColour( 0, 0, 0), 1, wxSOLID ), + mBorderPen( wxColour(192,192,192), 1, wxSOLID ), + + mpPaneInFocus( NULL ), + mpLRUPane ( NULL ), + + mNullPen( wxColour(0,0,0), 1, wxTRANSPARENT ), + + mpUpdatesMgr( NULL ), + + mpTopPlugin ( NULL ), + mpCaputesInput( NULL ), + + mRecalcPending( TRUE ), + + mFloatingOn ( TRUE ), + + mCheckFocusWhenIdle( FALSE ), + mClientWndRefreshPending( FALSE ) +{ + 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( wxColour(192,192,192) ); + } + + mFloatingOn = CanReparent(); +} + +// NOTE:: below are the only plaftorm-check "ifdef"s in the docking system! + +bool wxFrameLayout::CanReparent() +{ +#ifdef __WXMSW__ + return TRUE; +#endif + +#ifdef __WXGTK__ + //return TRUE; +#endif + + return FALSE; // reparenting is not yet supported by Motif and others +} + +/* +#ifdef __WXMSW__ + #inlcude "windows.h" +#endif +*/ + +void wxFrameLayout::ReparentWindow( wxWindow* pChild, wxWindow* pNewParent ) +{ +#ifdef __WXMSW__ + + 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 ); + + return; +#endif + + // FOR NOW:: floating with wxGtk still very buggy + +#ifdef __WXGTK__ + + return; + + pChild->ReParent( pNewParent ); + + return; +#endif + + wxMessageBox( "Sorry, docking is not supported for ports other than MSW and wxGTK" ); +} + +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; + + // 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 ( mpDragCursor ) 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, + 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 posssible + + 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; +} + +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::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 ), + wxSTAY_ON_TOP //| wxTHICK_FRAME + ); + + 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 ) + { + mAllBars.Remove( i ); + + if ( pBarInfo->mpBarWnd ) // hides it's window + + pBarInfo->mpBarWnd->Show( FALSE ); + + delete pBarInfo; + + return; + } + + wxASSERT(0); // 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[ wxTOP ]; + wxSize paneSize; + + 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[ wxBOTTOM ]; + + 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[ wxLEFT ]; + + // 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[ wxRIGHT ]; + + // 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[wxLEFT]->mBoundsInParent.x + + mPanes[wxLEFT]->mBoundsInParent.width; + mClntWndBounds.y = mPanes[wxTOP ]->mBoundsInParent.y + + mPanes[wxTOP ]->mBoundsInParent.height; + + mClntWndBounds.width = mPanes[wxRIGHT]->mBoundsInParent.x - + mClntWndBounds.x; + mClntWndBounds.height = mPanes[wxBOTTOM]->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; + + 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 - curosors ramain unchaged + 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 ); + + 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:: + } +} + + +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; + + 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; + } + + 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( cbSimpleCustomizationPlugin ) ); + AddPlugin( CLASSINFO( cbRowLayoutPlugin ) ); + AddPlugin( CLASSINFO( cbBarDragPlugin ) ); + AddPlugin( CLASSINFO( cbPaneDrawPlugin ) ); + AddPlugin( CLASSINFO( cbAntiflickerPlugin ) ); +} + +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 usefull 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 ) + + : mpRow ( NULL ), + mpBar ( NULL ), + mpRows( &rows ) +{ + 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() + + : mIsFixed(TRUE), + mpHandler( NULL ), + + mHorizGap( 0 ), + mVertGap ( 0 ) +{ + 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 ) + + : mHorizGap( 0 ), + mVertGap ( 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 + ) + : mHorizGap ( horizGap ), + mVertGap ( vertGap ), + 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() +{ + if ( mpHandler ) + + mpHandler->RemoveRef(); +} + +const cbDimInfo& cbDimInfo::operator=( 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) + + : mpNext ( NULL ), + mpPrev ( NULL ), + mNotFixedBarsCnt( FALSE ), + 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) + + : mpLayout ( 0 ), + 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 ), + mpStoredRow( NULL ), + mLeftMargin ( 1 ), + mRightMargin ( 1 ), + mTopMargin ( 1 ), + mBottomMargin( 1 ) +{} + +cbDockPane::cbDockPane( int alignment, wxFrameLayout* pPanel ) + + : mpLayout ( pPanel ), + 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 ), + mpStoredRow( NULL ), + + mLeftMargin ( 1 ), + mRightMargin ( 1 ), + mTopMargin ( 1 ), + mBottomMargin( 1 ) +{} + +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( long* x, long* y ) +{ + *x -= mLeftMargin; + *y -= mTopMargin; + + if ( mAlignment == wxTOP || + mAlignment == wxBOTTOM + ) + { + *x -= mBoundsInParent.x; + *y -= mBoundsInParent.y; + } + else + { + int rx = *x, ry = *y; + + *x = ry - mBoundsInParent.y; + + *y = rx - mBoundsInParent.x; + } +} + +void cbDockPane::PaneToFrame( long* x, long* y ) +{ + if ( mAlignment == wxTOP || + mAlignment == wxBOTTOM + ) + { + *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::CalcLenghtRatios( 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(); + + 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 demensions, 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; + + wxASSERT(0); // 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 wxTOP : thisMask = wxTOP_PANE; break; + case wxBOTTOM : thisMask = wxBOTTOM_PANE;break; + case wxLEFT : thisMask = wxLEFT_PANE; break; + case wxRIGHT : thisMask = wxRIGHT_PANE; break; + + default: wxASSERT(0); // DBG:: bogous alignment type + } + + return ( thisMask & paneMask ); +} + +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 == wxTOP || + mAlignment == wxBOTTOM ) + { + 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 == wxBOTTOM ) + + *from -= mpLayout->GetClientHeight(); + else + if ( mAlignment == wxRIGHT ) + + *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 == wxTOP ) + + *till += mpLayout->GetClientHeight(); + else + if ( mAlignment == wxLEFT ) + + *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 wxTOP : mask = wxTOP_PANE; break; + case wxBOTTOM : mask = wxBOTTOM_PANE;break; + case wxLEFT : mask = wxLEFT_PANE; break; + case wxRIGHT : mask = wxRIGHT_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/utils/framelayout/src/controlbar.h b/utils/framelayout/src/controlbar.h new file mode 100644 index 0000000000..9169024d49 --- /dev/null +++ b/utils/framelayout/src/controlbar.h @@ -0,0 +1,1652 @@ +///////////////////////////////////////////////////////////////////////////// +// 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(wxTOP) + +#define wxTOP 0 +#define wxBOTTOM 1 +#define wxLEFT 2 +#define wxRIGHT 3 + +#endif + +// one pane for each alignment +#define MAX_PANES 4 + +// masks for each pane + +#define wxTOP_PANE 0x0001 +#define wxBOTTOM_PANE 0x0002 +#define wxLEFT_PANE 0x0004 +#define wxRIGHT_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: + 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 wxColour(128,128,128) + wxPen mLightPen; // default white + wxPen mGrayPen; // default wxColour(192,192,192) + wxPen mBlackPen; // default wxColour( 0, 0, 0) + wxPen mBorderPen; // default wxColour(128,192,192) + + wxPen mNullPen; // transparent pen + + // pane to which the all mouse input is currently directed (caputred) + + cbDockPane* mpPaneInFocus; + + // pane, from which mouse pointer had just leaft + + 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 caputred 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(); + +public: /* public members */ + + wxFrameLayout(void); // used only while serializing + + wxFrameLayout( wxWindow* pParentFrame, + wxWindow* pFrameClient = NULL, + bool activateNow = TRUE ); + + // (doesn't destory 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. + // + // Effectivelly 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 dimesnions + // 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 + // immediatelly, 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, + cbDimInfo& dimInfo, + + // defaults: + + int alignment = wxTOP, + 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 costumization 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 ); + + BarArrayT& GetBars(); + + // changes bar's docking state (see possible control bar states) + + void SetBarState( cbBarInfo* pBar, int newStatem, bool updateNow ); + + // 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 = wxTOP ); + + 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(); +}; + +/* 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-previouse 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 inteface 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 asigned + // to multiple bars, it's instance is + // refernce-counted +public: + + // inital refernce 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 demensions + +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 + // (wxTOP,wxBOTTOM,..) + + // 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 + ); + + const cbDimInfo& operator=( 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-costumization 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 CalcLenghtRatios( 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( long* x, long* y ); + void PaneToFrame( long* x, long* 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 immediatelly, + // 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 upadates-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 == wxTOP || + mAlignment == wxBOTTOM ); + } + + 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 coorinates + 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 extanded, + * to implemnet 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-on plugin event structure + wxNode* mpObjNode; + wxNode* mpObjNodeAux; + wxPoint mPos; + wxSize mSize; + wxDC* mpDC; + bool mAuxBoolVal; + */ + + cbPluginEvent( int eventType, cbDockPane* pPane ) + : mpPane( pPane ) + + { m_eventType = eventType; } +}; + +// event types handled by plugins + +#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 + +// 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 + +#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 }, + +/* + * 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 diff --git a/utils/framelayout/src/dynbarhnd.h b/utils/framelayout/src/dynbarhnd.h new file mode 100644 index 0000000000..ca96c4507c --- /dev/null +++ b/utils/framelayout/src/dynbarhnd.h @@ -0,0 +1,18 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" +#include " + +#endif \ No newline at end of file diff --git a/utils/framelayout/src/dyntbar.cpp b/utils/framelayout/src/dyntbar.cpp new file mode 100644 index 0000000000..cc5aa166bc --- /dev/null +++ b/utils/framelayout/src/dyntbar.cpp @@ -0,0 +1,433 @@ +///////////////////////////////////////////////////////////////////////////// +// 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.cpp" +#pragma interface "dyntbar.cpp" +#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 "dyntbar.h" +#include "newbmpbtn.h" + +IMPLEMENT_DYNAMIC_CLASS(wxDynamicToolBar, wxToolBarBase) + +BEGIN_EVENT_TABLE( wxDynamicToolBar, wxToolBarBase ) + + 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( wxColour(192,192,192) ); +} + +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( wxColour( 192,192,192 ) ); + + return TRUE; +} + +bool wxDynamicToolBar::Realize(void) +{ + // FOR NOW:: nothing + return TRUE; +} + +wxDynamicToolBar::~wxDynamicToolBar(void) +{ + if ( mpLayoutMan ) delete mpLayoutMan; + + for( size_t 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 ); +} + + + wxToolBarTool* + 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 ) +{ + for( size_t i = 0; i != mTools.Count(); ++i ) + + if ( mTools[i]->mIndex == toolIndex ) return mTools[i]; + + return NULL; +} + +void wxDynamicToolBar::RemveTool( int toolIndex ) +{ + for( size_t i = 0; i != mTools.Count(); ++i ) + + if ( mTools[i]->mIndex == toolIndex ) + { + if ( mTools[i]->mpToolWnd ) + + mTools[i]->mpToolWnd->Destroy(); + + mTools.Remove( i ); + + 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); + + for( size_t 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() +{ + for( size_t 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 + } +} + +void wxDynamicToolBar::Layout() +{ + if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout(); + + int x,y; + GetSize( &x, &y ); + wxSize wndDim(x,y); + wxSize result; + + wxLayoutItemArrayT items; + + // safe conversion + for( size_t i = 0; i != mTools.Count(); ++i ) items.Add( mTools[i] ); + + mpLayoutMan->Layout( wndDim, result, items, mVertGap, mHorizGap );; + + SizeToolWindows(); +} + +void wxDynamicToolBar::GetPreferredDim( const wxSize& givenDim, wxSize& prefDim ) +{ + if ( !mpLayoutMan ) mpLayoutMan = CreateDefaulLayout(); + + wxLayoutItemArrayT items; + + // safe conversion + for( size_t 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; +} diff --git a/utils/framelayout/src/dyntbar.h b/utils/framelayout/src/dyntbar.h new file mode 100644 index 0000000000..c2815632b3 --- /dev/null +++ b/utils/framelayout/src/dyntbar.h @@ -0,0 +1,164 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#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 ); + + // method from wxToolBarBase (for compatibility), only + // first two arguments are valid + + virtual wxToolBarTool *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 void 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); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/utils/framelayout/src/dyntbarhnd.cpp b/utils/framelayout/src/dyntbarhnd.cpp new file mode 100644 index 0000000000..fdfe32d2c9 --- /dev/null +++ b/utils/framelayout/src/dyntbarhnd.cpp @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 "dyntbar.cpp" +#pragma interface "dyntbar.cpp" +#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 "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/utils/framelayout/src/dyntbarhnd.h b/utils/framelayout/src/dyntbarhnd.h new file mode 100644 index 0000000000..ca1aa6247b --- /dev/null +++ b/utils/framelayout/src/dyntbarhnd.h @@ -0,0 +1,26 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" +#include "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 \ No newline at end of file diff --git a/utils/framelayout/src/frmview.cpp b/utils/framelayout/src/frmview.cpp new file mode 100644 index 0000000000..690bca3eed --- /dev/null +++ b/utils/framelayout/src/frmview.cpp @@ -0,0 +1,449 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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; + ++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:: + wxASSERT(0); +} + +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; + +#if 0 + if ( mSettingsFile == "" || !wxFileExists( mSettingsFile ) ) + + return FALSE; + + DestroyViews(); + + wxIOStreamWrapper stm; + stm.CreateForInput( mSettingsFile ); + + mStore.SetDataStream( stm ); + DoSerialize( mStore ); +#endif + + return TRUE; +} + +bool wxFrameManager::ViewsAreLoaded() +{ + return ( mViews.Number() != 0 ); +} \ No newline at end of file diff --git a/utils/framelayout/src/frmview.h b/utils/framelayout/src/frmview.h new file mode 100644 index 0000000000..8b49be36aa --- /dev/null +++ b/utils/framelayout/src/frmview.h @@ -0,0 +1,135 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "wx/module.h" + +#if 0 +#include "objstore.h" +#endif + +class wxObjectStorage; + +#include "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 \ No newline at end of file diff --git a/utils/framelayout/src/garbagec.cpp b/utils/framelayout/src/garbagec.cpp new file mode 100644 index 0000000000..afb41e7ae8 --- /dev/null +++ b/utils/framelayout/src/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.cpp" +#pragma interface "garbagec.cpp" +#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 "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(); + } + + wxASSERT(0); // DBG:: item should be presnet + + return 0; +} + +wxNode* GarbageCollector::FindRefernceFreeItemNode() +{ + 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:: inital ref-count is not used + + GCItem* pItem = new GCItem(); + + pItem->mpObj = pObj; + + mAllNodes.Append( (wxObject*) pItem ); +} + +void GarbageCollector::AddDependency( void* pObj, void* pDepnedsOnObj ) +{ + node_to_item( FindItemNode( pObj ) ).mRefs.Append( (wxObject*)pDepnedsOnObj ); +} + +/*** GC alg. implementation ***/ + +void GarbageCollector::ArrangeCollection() +{ + ResolveReferences(); + + do + { + // find node, which does not depend on anything + + wxNode* pItemNode = FindRefernceFreeItemNode(); + + 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/utils/framelayout/src/garbagec.h b/utils/framelayout/src/garbagec.h new file mode 100644 index 0000000000..58a9548e0a --- /dev/null +++ b/utils/framelayout/src/garbagec.h @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#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 extreamly slow, but probably one of the most simple GC alogrithms + +class GarbageCollector +{ +protected: + wxList mAllNodes; + wxList mRegularLst; + wxList mCycledLst; + + wxNode* FindItemNode( void* pForObj ); + void ResolveReferences(); + + wxNode* FindRefernceFreeItemNode(); + 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* pDepnedsOnObj ); + + // executes GC alg. + + virtual void ArrangeCollection(); + + // acces results of the alg. + + wxList& GetRegularObjects(); + wxList& GetCycledObjects(); + + // removes all date form GC + + void Reset(); +}; + +#endif diff --git a/utils/framelayout/src/gcupdatesmgr.cpp b/utils/framelayout/src/gcupdatesmgr.cpp new file mode 100644 index 0000000000..33fee9e27d --- /dev/null +++ b/utils/framelayout/src/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 "updatesmgr.h" +// #pragma interface +#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 "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(); + } +} \ No newline at end of file diff --git a/utils/framelayout/src/gcupdatesmgr.h b/utils/framelayout/src/gcupdatesmgr.h new file mode 100644 index 0000000000..a03c0044e0 --- /dev/null +++ b/utils/framelayout/src/gcupdatesmgr.h @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" +#include "updatesmgr.h" + +#include "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 impelmentation + * tries to find out dependencies between bars, and to order + * them ito "hierarchy", this hierarchical sorting resembles + * impelmenation of heap-garbage collectors, which resolve + * dependencies between referencs. + * + * 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 refereshing 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-depenencies (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 sepcal 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 \ No newline at end of file diff --git a/utils/framelayout/src/hintanimpl.cpp b/utils/framelayout/src/hintanimpl.cpp new file mode 100644 index 0000000000..4f8a14a1ec --- /dev/null +++ b/utils/framelayout/src/hintanimpl.cpp @@ -0,0 +1,406 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 "bardragpl.h" +// #pragma interface +#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 "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 ), + mInClientHintBorder( 4 ), + mAnimStarted( FALSE ), + mpAnimTimer( 0 ), + + mMorphDelay ( 5 ), + mMaxFrames ( 20 ), + mAccelerationOn( TRUE ) +{} + +cbHintAnimationPlugin::cbHintAnimationPlugin( wxFrameLayout* pPanel, int paneMask ) + + : cbPluginBase( pPanel, paneMask ), + mpScrDc( NULL ), + mInClientHintBorder( 4 ), + mAnimStarted( FALSE ), + mpAnimTimer( 0 ), + + mMorphDelay ( 5 ), + mMaxFrames ( 20 ), + 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 + + if ( mAnimStarted ) + { + int o; + ++o; + } + + 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 previouse rect + DoDrawHintRect( mpAnimTimer->mPrevMorphed, mPrevInClient ); + } + } + + mPrevRect = event.mRect; +} + +#define _A 0xAA +#define _B 0x00 +#define _C 0x55 +#define _D 0x00 + +static const unsigned char _gCheckerImg[] = { _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_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 = NULL; +#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 previouse 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; + int o; + ++o; + ++o; + + // 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/utils/framelayout/src/hintanimpl.h b/utils/framelayout/src/hintanimpl.h new file mode 100644 index 0000000000..075cca58f9 --- /dev/null +++ b/utils/framelayout/src/hintanimpl.h @@ -0,0 +1,115 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "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 \ No newline at end of file diff --git a/utils/framelayout/src/manual.html b/utils/framelayout/src/manual.html new file mode 100644 index 0000000000..7b2ea500e1 --- /dev/null +++ b/utils/framelayout/src/manual.html @@ -0,0 +1,8302 @@ + + +

FrameLayout window-docking system (WDS) for wxWindows-2.0

+ +(doc-v1.0.1, mailto:alex@soften.ktu.lt) + +

+1. Overview
+2. Main components
+3. Persistance framework
+4. Generated Source Code docs (useless)
+
+
+1. Overview
+===========
+
+Docking is a relatively new method of layouting GUI
+components. It allows user to customize his/her workplace
+by simply dragging around and resizing contents within 
+applications main window. These contents (further refered
+as control-bars) can be docked along top, bottom, left and
+right sides of the frame, positioning workplace's client area 
+window (e.g. current document) in the center of the frame.
+
+2. Main components.
+===================
+
+  * parent frame
+  * four docking panes
+  * control-bars
+  * client area
+
+  Parent frame is usually application's main window.
+  Frame-Layout system (FL) allows layout compnents
+  to be placed into any kind of window such as dialog, 
+  panel or modeless-frame.
+
+  Docking panes are rectangluar areas which surround the client
+  window along top, bottom, left and right edges. Control-bars
+  are docked into these panes.
+
+  Cotrol-bars are named so, because the usually embed common 
+  GUI controls such as toolbars, choices, text/tree controls.
+  Control-bars can be fixed-size or flexible. For the later 
+  ones FL automaticlly places resizing handles along those edges 
+  of flexible-bar, which actually can be moved, e.g. edge which 
+  is in touch with the client are will have handle to allow 
+  ajusting the client's area vs. pane's area.
+
+  Client area can be any provided window such as panel or MDI parent
+  window.  FL will resize and position this window to fit the free
+  space, which is not occupied by surrounding panes.
+
+  (the rest is "under construction" at the moment)
+
+---------------------------------------------------------------------
+
+Persistance-Framework for wxWindows, 1998 (c) Aleksandras Gluchovas
+
+Contents
+========
+
+ 1. Abstract
+ 2. Extending wxWindows object system
+ 3. Common scenario for making classes persistent
+ 4. Kinds of persistent objects
+ 5. PF behavior
+ 6. Transient objects
+ 7. Object versioning
+ 8. Polymorphic persistence
+ 9. Serializers for common wxWindows classes
+10. Class/Macro Reference
+
+1. Abstract
+===========
+
+  The persistence-framework (PF) aims to provide
+  an easier means of making C++ objects persistent.
+  It is solely specialized to store/load (i.e. serialize)
+  objects, but not to manipulate their data, therefore
+  it cannot act as a real object-database. This PF also could
+  be used for implementing undo-able operations on object-
+  systems (to some extent). It handles most common specialties 
+  of run-time data:
+
+    1) Not-storable (transient) objects
+    2) Differences in object structure among different builds
+    3) Not-data characteristics of objects - dynamic types
+       of class instances
+
+2. "Extending" wxWindows object system
+======================================
+
+  PF does not require any modification to existing 
+  not-persistent classes. It uses meta-information 
+  held in derivatives of wxObject for 
+  the purpose of RTTI, thus only the later
+  classes can be made persistent. Information
+  about classÂ’s persistence is captured into
+  static structures, using similar techniques as
+  wxWindows system of dynamic-classes is implemented.
+
+3. Common scenario for making classes persistent
+================================================
+
+  1) For each persistent class, corresponding serializer-
+     class have to be written. Name for the serializer 
+     class contains class-name of the traget class
+     with "Serializer" appended at the end, e.g. for 
+     wxRect there would be wxRectSerializer. 
+
+  2) Two macros DECLARE_SERIALIZER_CLASS(..) and
+     IMPLEMENT_SERIALIZER_CLASS(..) have to be placed
+     into header and implementation files. These macros will
+     "inject" static data about serializer, so as to compose
+     a chain of run-time serializer information structures.
+   
+  3) Declare and implement methods for serialization and
+     initialization of the target-class (i.e. the 
+     one for which serializer is written). These
+     methods should be declared as static in the
+     serializer class, and pointers to them are
+     passed to IMPLEMENT_SERIALIZER_CLASS(..) macro
+     - to complete static information about serializer.
+
+  The above three steps accomplish the "declarative"
+  part of making object persistent. For actual storing/loading
+  of objects, instances of 'wxObjectStorage' and 
+  'wxDataStreamBase' derivative classes have to
+  be created. Then references to objects are 
+  iterativelly passed to corresponding 'Xchg...' 
+  methods of this 'wxObjectStorage' (further referred
+  as storage manager) to perform string/loding using 
+  the given byte-stream.
+
+  (note: the later approach is overly general,
+         thus in the future, improvements will be made
+         in order to provide some practical defaults)
+
+4. Kinds of persistent objects
+==============================
+
+  There are following data of C++ applications
+  can be made persistent:
+
+    1) basic types (int, double, etc)
+    2) classes/structures
+    3) pointers to objects, objects here
+       referred as instances of a class, i.e.
+       which can have "wx-run-time-information".
+    4) pointers to transient objects,
+       also referred as "initial references".
+
+5. PF behavior
+===============       
+
+  Basic types are stored in their binary
+  representation. Derivatives of 'wxDataStreamBase' 
+  may implement storing of basic-types in 
+  machine-independent format.
+
+  Serialization of classes proceeds with
+  storing of basic types, aggregated objects and
+  references (pointers really) to external 
+  objects. 
+
+  When reference to other object is encountered,
+  it is encoded in the form which does not 
+  depend on the current in-memory address of 
+  referred object, thus upon loading, 
+  it can be restored correctly. After
+  serializing reference, storage manager
+  immediately performs serialization of the
+  object which is referred. Technically, this
+  approach allows using streams which cannot
+  perform bi-directional read/write operations
+  - cannot 'seek', e.g. socket-streams.
+
+  It is not necessary to iterativelly pass
+  each persistent object to object storage
+  in order to serialize them. Usually run-time
+  object structures are "self-contained", i.e.
+  objects contain other objects or at least have
+  cross-references. Therefore it's enough to
+  serialize the "root" object in the system's
+  hierarchy, and all the referred objects
+  will be automatically serialized.
+
+6. Transient objects
+====================
+
+  The objects which are not intended to be
+  persistent are referred as transient.
+  To prevent serialization of such objects,
+  initial references (IRs) to them should be 
+  passed to the storage manager, before any  
+  loading/storing can proceed. The Order in 
+  which they are passed should be the same for loading 
+  and storing - since there is a 'sequence-number' for
+  each IR which is  generated when serializing the pointer 
+  which was identified as be an initial-reference 
+  (automatically recognized using hash-tables). 
+
+  Simple example of transient object could be a
+  printer object, to which other persistent 
+  objects may refer, but the printer itself 
+  cannot be serialized. Also in wx-frame-layout
+  system, a reference to application's frame window 
+  is registered as IR.
+
+7.Object versioning
+===================
+
+  NOTE:: implementation of versioning is prototypical -
+         not well tested yet.
+   
+  PF attempts to reduce the burden needed to program
+  support for loading/storing multiple versions
+  of persistant objects. 
+
+  The versioning of objects is not enforced by PF,
+  it is provided as additional possibility. 
+
+  For each distinct version of a class separate 
+  serializer have to be written. Implementing such
+  serializers is similar to the above described
+  not-versioned serializers impl., except that
+  different macros should be used - extended
+  with "FOR_VERSION" postfix, e.g.
+  IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION(..) used instead
+  IMPLEMENT_SERIALIZER_CLASS(..), where the version name
+  string is additionally passed to the former macro.
+
+  Storage manager will store version information to the 
+  the output stream, and read it upon loading - to find 
+  matching serializer. An error (for now: exception) will 
+  occur when no matching serializer was found. 
+
+  When storing, serializer for the latest version of
+  object is used, following the assumption that usually
+  the newest object versions exist at run-time. Only
+  when staying in files they are "getting older", thus
+  it is possible to load older data into newer objects
+  (backwards-compatibility), but not to store newer objects
+  in the "old format".
+  
+8. "Polymorphic" persistence
+============================
+
+  This mechanism is meant for reducing number of serializers 
+  required to write for classes with the same base 
+  class and same persistent data that base class, 
+  but different behavior.
+
+  The "poliymorphic" persistence is enabled by default, 
+  allowing the storage manager to search for serializers 
+  of base classes, if the ones for the derived classes were
+  not found. 
+
+  This can by disabled by calling SetStrictMatching(TRUE), 
+  forcing the manager to abort serialization, if no 
+  serializer found, which match the object's class exactly.
+
+  This does not mean however, that instance of the 
+  base class is created even if no 'CLASSINFO' data for the 
+  derived class were found, in such cases the serialization 
+  will be aborted also, i.e. dynamic type of object should
+  be always restored preciselly.
+
+  Concrete example: having base class Employee, which has
+  info common to all employees. Other classes 'Secretary',
+  'Manager', etc are derivatives of 'Employee' and do not
+  contain any additional data members. Thus they only
+  specify different behavior and can be safely serialized
+  by 'EmployeeSerializer' class.
+
+  For wxWindows I've written serializer for wxWindow class, 
+  and it can be used to serialize generic wxPanel and other
+  derivtives of wxWindow which do not add any additional members.
+
+9. Serializers for common wxWindows objects
+==========================================
+
+  There may appear some difficulties to find out
+  for which classes serializers are already written
+  and for which aren't. because serializer is actually
+  a pair of static methods, which can reside (scattered) 
+  anywhere among implementation files. In future storage
+  manager will be modified to check for duplicated
+  serializers (only possible at run-time). Currently 
+  serializers the following common wxWindows classes 
+  are present:
+
+  wxNode (is serialized "in it's entirely"),
+  wxList, wxPoint, wxSize, wxRect, wxColour, wxPen,
+  wxBrush, wxEvtHandler, wxWindow, wxTextCtrl,
+  wxTreeCtrl (serializes structure and item states),
+  wxStaticText, wxScrollBar
+
+  Serializers for these classes are placed in objstore.cpp.
+  Serializers for other already-exiting wxWin classes could
+  be also placed into this file. For the new (future) 
+  wxWin classes which would have advantage of
+  being persistent, serializers could be placed into
+  their corresponding implementation files (.cpp).
+
+10. Class/Macro Reference
+=========================
+
+  >>>> UNDER CONSTRUCTION <<<<
+
+  for now, you may look at comments in the source 
+  code (headers especially), the sample and also
+  one "Real-World" example of "wx-frame-layout"
+  system, where serializers for various classes
+  are placed in cbstore.cpp and cbstore.h, serialization
+  is performed in MyFrame::SerializeMe(). 
+
+--------------misc. notes, just in case...------------
+
+   When object does not need any extra
+   initialization after it is serialized.
+   In the case of loading, `Initialize()'
+   method can be omitted and `NO_CLASS_INIT'
+   constant passed instead of a pointer to the method.
+
+   Since wxString may be configured to be 
+   not-wxObject-derivative, extra method is
+   included:  wxObjectStorage::XchgWxStr(..)
+   to serialize "any-wxString".
+
+   The provided initialization functions are invoked
+   only after all objects (i.e. entire "network")
+   is loaded into memory, since sometimes initialization
+   of one object depend on existence of another.
+
+   "Recommended" that these two methods would 
+   be called `Serialize(..)' and `Initialize(..)'
+   respectively. They also should conform
+   to definitions of `wxObjectSerializationFn'
+   and `wxObjectInitializationFn'.
+
+   The body of initialization function (method)
+   usually contains invocations to given
+   instance of wxObjectStorage, for each
+   persistent member of the target class,
+   e.g. 
+
+     store.XchgLong( pRect->width  );
+   or
+     store.XchgObj( (wxObject*) pWnd->GetChildren() );     
+
+   Macro IMPLEMENT_SERIALIZER_FUNCTIONS(..) is not meant
+   for implementing static methods of serializer class,
+   instead it could be used when it is considered a 
+   better way to place serialization functions into global scope,
+   rather than in-serializer-class. These macros make
+   such approach possible.
+
+
+
+ + + + +

Source Code Contents

+

+ + +


+

Classes Reference

+ + +


+

cbAntiflickerPlugin

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbAntiflickerPlugin::cbAntiflickerPlugin +
  • cbAntiflickerPlugin::cbAntiflickerPlugin +
  • cbAntiflickerPlugin::~cbAntiflickerPlugin +
  • cbAntiflickerPlugin::OnStartDrawInArea +
  • cbAntiflickerPlugin::OnFinishDrawInArea +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbAntiflickerPlugin::mpVertBuf

wxBitmap* mpVertBuf

double-buffers are shared "resource" among all instances of antiflicker plugin within the application

TODO:: locking should be implemented, for multithreaded GUIs

+
+


+

cbAntiflickerPlugin::mpLRUBufDc

wxDC* mpLRUBufDc

last-reacently-used buffer

+
+


+

cbAntiflickerPlugin::mLRUArea

wxRect mLRUArea

last-reacently-used area

+
+


+

cbAntiflickerPlugin::FindSuitableBuffer

wxDC* FindSuitableBuffer( const wxRect& forArea )

returns NULL, if sutable buffer is not present

+
+


+

cbAntiflickerPlugin::OnStartDrawInArea

void OnStartDrawInArea( cbStartDrawInAreaEvent& event )

handlers for plugin events

+
+


+

cbFloatedWindow

+

+Derived from +

    +
  • wxWindow +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

wxFrameView

+

+Derived from +

    +
  • wxEvtHandler +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • wxFrameView::OnIdle +
+ +

+Attributes +

    +
  • wxFrameView::mTopMenus +
  • wxFrameView::mpLayout +
  • wxFrameView::mpFrameMgr +
  • wxFrameView::mDoToolUpdates +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxFrameView::OnInit

void OnInit( )

hooks for specific frame-views

+
+


+

wxFrameView::OnRecreate

void OnRecreate( )

imp. is mandatory

+
+


+

wxFrameManager

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
  • wxFrameManager::wxFrameManager +
  • wxFrameManager::~wxFrameManager +
  • wxFrameManager::Init +
  • wxFrameManager::GetParentFrame +
  • wxFrameManager::GetParentWindow +
  • wxFrameManager::GetActiveViewNo +
  • wxFrameManager::GetActiveView +
  • wxFrameManager::GetActiveViewNode +
  • wxFrameManager::GetView +
  • wxFrameManager::SetClinetWindow +
  • wxFrameManager::GetClientWindow +
  • wxFrameManager::AddView +
  • wxFrameManager::RemoveView +
  • wxFrameManager::ActivateView +
  • wxFrameManager::ActivateView +
  • wxFrameManager::DeactivateCurrentView +
  • wxFrameManager::GetObjectStore +
  • wxFrameManager::SaveViewsNow +
  • wxFrameManager::ReloadViews +
  • wxFrameManager::ViewsAreLoaded +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • wxFrameManager::DoSerialize +
  • wxFrameManager::DestroyViews +
  • wxFrameManager::GetViewNo +
  • wxFrameManager::EnableMenusForView +
  • wxFrameManager::SyncAllMenus +
+ +

+Attributes +

    +
  • wxFrameManager::mViews +
  • wxFrameManager::mpFrameWnd +
  • wxFrameManager::mActiveViewNo +
  • wxFrameManager::mpClientWnd +
  • wxFrameManager::mStore +
  • wxFrameManager::mSettingsFile +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxFrameManager::Init

void Init( wxWindow* pMainFrame, const wxString& settingsFile = "" )

if file name is empty, views are are not saved/loaded

+
+


+

wxFrameManager::GetParentFrame

wxFrame* GetParentFrame( )

synonyms

+
+


+

wxToolLayoutItem

layout item

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • wxToolLayoutItem::mRect +
  • wxToolLayoutItem::mIsSeparator +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

LayoutManagerBase

base class for layouting algorithm implementations

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

    +
  • LayoutManagerBase::Layout +
  • LayoutManagerBase::~LayoutManagerBase +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

BagLayout

layouts items in left-to-right order from top towards bottom

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • BagLayout::Layout +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxDynToolInfo

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • wxDynToolInfo::mpToolWnd +
  • wxDynToolInfo::mIndex +
  • wxDynToolInfo::mRealSize +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxDynamicToolBar

class manages containment and layouting of tool-windows

+

+Derived from +

    +
  • wxToolBarBase +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • wxDynamicToolBar::SizeToolWindows +
+ +

+Attributes +

    +
  • wxDynamicToolBar::mTools +
  • wxDynamicToolBar::mpLayoutMan +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxDynamicToolBar::mSepartorSize

int mSepartorSize

public properties

default: 8

+
+


+

wxDynamicToolBar::mVertGap

int mVertGap

default: 0

+
+


+

wxDynamicToolBar::mHorizGap

int mHorizGap

default: 0

+
+


+

wxDynamicToolBar::AddTool

void AddTool( int toolIndex, wxWindow* pToolWindow, const wxSize& size = wxDefaultSize )

overridables

+
+


+

wxDynamicToolBar::AddTool

wxToolBarTool* 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 = "" )

method from wxToolBarBase (for compatibility), only first two arguments are valid

+
+


+

wxDynamicToolBar::DrawSeparator

void DrawSeparator( wxDynToolInfo& info, wxDC& dc )

the default implementation draws shaded line

+
+


+

wxDynamicToolBar::Layout

void Layout( )

see definitions of orientation types

+
+


+

wxDynamicToolBar::OnSize

void OnSize( wxSizeEvent& event )

event handlers

+
+


+

wxDynamicToolBar::Realize

bool Realize( )

overriden from wxToolBarBase

+
+


+

wxToolWindow

+

+Derived from +

    +
  • wxFrame +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
  • wxToolWindow::mButtons +
  • wxToolWindow::mpClientWnd +
  • wxToolWindow::mTitleFont +
  • wxToolWindow::mTitleHeight +
  • wxToolWindow::mClntHorizGap +
  • wxToolWindow::mClntVertGap +
  • wxToolWindow::mWndVertGap +
  • wxToolWindow::mWndHorizGap +
  • wxToolWindow::mButtonGap +
  • wxToolWindow::mInTitleMargin +
  • wxToolWindow::mHintBorder +
  • wxToolWindow::mResizeStarted +
  • wxToolWindow::mRealTimeUpdatesOn +
  • wxToolWindow::mMTolerance +
  • wxToolWindow::mCursorType +
  • wxToolWindow::mMouseCaptured +
  • wxToolWindow::mDragOrigin +
  • wxToolWindow::mInitialRect +
  • wxToolWindow::mPrevHintRect +
  • wxToolWindow::mpScrDc +
+ +

+Protected members

+

+Operations +

    +
  • wxToolWindow::GetScrWindowRect +
  • wxToolWindow::GetScrMousePos +
  • wxToolWindow::SetHintCursor +
  • wxToolWindow::CalcResizedRect +
  • wxToolWindow::AdjustRectPos +
  • wxToolWindow::GetMinimalWndDim +
  • wxToolWindow::DrawHintRect +
  • wxToolWindow::HitTestWindow +
  • wxToolWindow::LayoutMiniButtons +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxToolWindow::mButtons

cbMiniButtonArrayT mButtons

protected really, accesssed only by serializers *

+
+


+

wxToolWindow::mDragOrigin

wxPoint mDragOrigin

drag&drop state variables

+
+


+

wxToolWindow::AddMiniButton

void AddMiniButton( cbMiniButton* pBtn )

buttons are added in right-to-left order

+
+


+

wxToolWindow::GetPreferredSize

wxSize GetPreferredSize( const wxSize& given )

overridables:

+
+


+

cbMiniButton

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
  • cbMiniButton::cbMiniButton +
  • cbMiniButton::SetPos +
  • cbMiniButton::HitTest +
  • cbMiniButton::OnLeftDown +
  • cbMiniButton::OnLeftUp +
  • cbMiniButton::OnMotion +
  • cbMiniButton::Refresh +
  • cbMiniButton::Draw +
  • cbMiniButton::WasClicked +
  • cbMiniButton::Reset +
  • cbMiniButton::Enable +
  • cbMiniButton::IsPressed +
+ +

+Attributes +

    +
  • cbMiniButton::mPos +
  • cbMiniButton::mDim +
  • cbMiniButton::mVisible +
  • cbMiniButton::mEnabled +
  • cbMiniButton::mpLayout +
  • cbMiniButton::mpPane +
  • cbMiniButton::mpPlugin +
  • cbMiniButton::mpWnd +
  • cbMiniButton::mWasClicked +
  • cbMiniButton::mDragStarted +
  • cbMiniButton::mPressed +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

cbCloseBox

classes specific to wxFrameLayout engine (FOR NOW in here...)

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbCloseBox::Draw +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbCollapseBox

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbCollapseBox::Draw +
+ +

+Attributes +

    +
  • cbCollapseBox::mIsAtLeft +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDockBox

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDockBox::Draw +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbFloatedBarWindow

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
  • cbFloatedBarWindow::mpBar +
  • cbFloatedBarWindow::mpLayout +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbFloatedBarWindow::PositionFloatedWnd

void PositionFloatedWnd( int scrX, int scrY, int width, int height )

given coordinates are those of the bar itself floated container window's position and size are ajusted accordingly

+
+


+

cbFloatedBarWindow::GetPreferredSize

wxSize GetPreferredSize( const wxSize& given )

overriden methods of wxToolWindow

+
+


+

MyApp

Define a new application type

+

+Derived from +

    +
  • wxApp +
+ +

+Public members

+

+Operations +

    +
  • MyApp::OnInit +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

MyFrame

+

+Derived from +

    +
  • wxFrame +
+ +

+Public members

+

+Operations +

    +
  • MyFrame::CreateTextCtrl +
  • MyFrame::MyFrame +
  • MyFrame::~MyFrame +
  • MyFrame::OnClose +
  • MyFrame::OnLoad +
  • MyFrame::OnSave +
  • MyFrame::OnExit +
+ +

+Attributes +

    +
  • MyFrame::mStore +
  • MyFrame::mpLayout +
  • MyFrame::mpClientWnd +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

wxTabbedWindow

class manages and decorates contained "tab"-windows. Draws decorations similar to those in "Project Workplace" of Microsoft Developer Studio 4.xx

+

+Derived from +

    +
  • wxPanel +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxTabbedWindow::GetLabelFont

wxFont GetLabelFont( )

overrride,to provide different font for tab-labels

+
+


+

wxTabbedWindow::mpTabScroll

wxScrollBar* mpTabScroll

FOR NOW:: scrollbars are actually related to wxPaggedWindow

+
+


+

wxTabbedWindow::mWhitePen

wxPen mWhitePen

public properties (invoke ReclaclLayout(TRUE) to apply changes)

default: RGB(255,255,255)

+
+


+

wxTabbedWindow::mGrayPen

wxPen mGrayPen

default: RGB(192,192,192)

+
+


+

wxTabbedWindow::mDarkPen

wxPen mDarkPen

default: RGB(128,128,128)

+
+


+

wxTabbedWindow::mBlackPen

wxPen mBlackPen

default: RGB( 0, 0, 0)

+
+


+

wxTabbedWindow::mVertGap

int mVertGap

default: 3

+
+


+

wxTabbedWindow::mHorizGap

int mHorizGap

default: 5

+
+


+

wxTabbedWindow::mTitleVertGap

int mTitleVertGap

default: 3

+
+


+

wxTabbedWindow::mTitleHorizGap

int mTitleHorizGap

default: 4

+
+


+

wxTabbedWindow::mImageTextGap

int mImageTextGap

default: 2

+
+


+

wxTabbedWindow::mFirstTitleGap

int mFirstTitleGap

default: 11

+
+


+

wxTabbedWindow::mBorderOnlyWidth

int mBorderOnlyWidth

default: 8

+
+


+

wxTabbedWindow::OnTabAdded

void OnTabAdded( twTabInfo* pInfo )

notifications (can be handled by derivatives)

+
+


+

wxTabbedWindow::AddTab

void AddTab( wxWindow* pContent, wxString tabText, wxString imageFileName = "", long imageType = wxBITMAP_TYPE_BMP )

tabs can be also added when the window is already displayed - "on the fly"

contained window

+
+


+

wxTabbedWindow::AddTab

void AddTab( wxWindow* pContent, wxString tabText, wxBitmap* pImage = NULL )

NOTE:: if this AddTab(..) overload is called, the image bitmap will not be serialized (if performed), use the above method instead, so that images could be restored using the given file names

+
+


+

wxTabbedWindow::GetTabCount

int GetTabCount( )

misc accessors

+
+


+

wxTabbedWindow::HitTest

int HitTest( const wxPoint& pos )

return -1, if non of the title bars was hitted, otherwise the index of the hitted tab title bar

+
+


+

wxTabbedWindow::RecalcLayout

void RecalcLayout( bool andRepaint = TRUE )

should be invoked to redisplay window with changed properties

+
+


+

wxTabbedWindow::OnPaint

void OnPaint( wxPaintEvent& event )

event handlers

+
+


+

wxPaggedWindow

class manages and decorates contained "sheets" (or pages). Draws decorations similar to those in "Output window" of Microsoft Developer Studio 4.xx

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

+ +

+Attributes +

    +
  • wxPaggedWindow::mScrollEventInProgress +
  • wxPaggedWindow::mIsDragged +
  • wxPaggedWindow::mDagOrigin +
  • wxPaggedWindow::mResizeCursor +
  • wxPaggedWindow::mNormalCursor +
  • wxPaggedWindow::mCursorChanged +
  • wxPaggedWindow::mOriginalTitleRowLen +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxPaggedWindow::mIsDragged

bool mIsDragged

drag&drop state variables

+
+


+

wxPaggedWindow::OnTabAdded

void OnTabAdded( twTabInfo* pInfo )

adjusts scorllbars to fit around tabs

+
+


+

wxPaggedWindow::GetLabelFont

wxFont GetLabelFont( )

sets smaller font for page-labels

+
+


+

wxPaggedWindow::mTitleRowLen

int mTitleRowLen

actual title row length

+
+


+

wxPaggedWindow::mAdjustableTitleRowLen

int mAdjustableTitleRowLen

setup by dragging mini-sash

+
+


+

wxPaggedWindow::mCurentRowOfs

int mCurentRowOfs

with the mosue pointer

+
+


+

wxPaggedWindow::GetVerticalScrollBar

wxScrollBar& GetVerticalScrollBar( )

NOTE:: use public methods of the base class to add "pages" to this window

misc accessors

below two methods should be called after the tabs were added (AddTab(..)). Set up these scrollbars to match the needs of the tabs added into this area

+
+


+

wxPaggedWindow::HitTest

int HitTest( const wxPoint& pos )

return -1, if non of the title bars was hitted, otherwise the index of the hitted tab title bar

+
+


+

wxPaggedWindow::OnPaint

void OnPaint( wxPaintEvent& event )

event handlers

+
+


+

twTabInfo

helper structure of wxTabbedWindow

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
  • twTabInfo::twTabInfo +
  • twTabInfo::~twTabInfo +
  • twTabInfo::ImgWidth +
  • twTabInfo::ImgHeight +
  • twTabInfo::ImageToTxtGap +
  • twTabInfo::HasImg +
  • twTabInfo::GetImg +
  • twTabInfo::HasText +
  • twTabInfo::GetText +
  • twTabInfo::GetContent +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

twTabInfo::mImageFile

wxString mImageFile

used for serialization

+
+


+

MyApp

Define a new application type

+

+Derived from +

    +
  • wxApp +
+ +

+Public members

+

+Operations +

    +
  • MyApp::OnInit +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

MyFrame

Define a new frame type

+

+Derived from +

    +
  • wxFrame +
+ +

+Public members

+

+Operations +

    +
  • MyFrame::MyFrame +
  • MyFrame::~MyFrame +
  • MyFrame::SyncMenuBarItems +
  • MyFrame::OnClose +
  • MyFrame::OnLoad +
  • MyFrame::OnStore +
  • MyFrame::OnAutoSave +
  • MyFrame::OnQuit +
  • MyFrame::OnAbout +
  • MyFrame::OnSettings +
  • MyFrame::OnRemove +
  • MyFrame::OnRemoveAll +
  • MyFrame::OnRecreate +
  • MyFrame::OnFirst +
  • MyFrame::OnSecond +
  • MyFrame::OnThird +
  • MyFrame::OnSayItsOk +
  • MyFrame::OnBtnYes +
  • MyFrame::OnBtnNo +
  • MyFrame::OnBtnEsc +
  • MyFrame::OnChar +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • MyFrame::CreateTxtCtrl +
  • MyFrame::CreateTreeCtrl +
  • MyFrame::CreateChoice +
  • MyFrame::CreateButton +
  • MyFrame::CreateDevLayout +
  • MyFrame::DropInSomeBars +
  • MyFrame::CreateLayout +
  • MyFrame::RemoveLayout +
  • MyFrame::DestroyEverything +
  • MyFrame::InitAboutBox +
  • MyFrame::ActivateLayout +
  • MyFrame::SerializeMe +
+ +

+Attributes +

    +
  • MyFrame::mLayouts[MAX_LAYOUTS] +
  • MyFrame::mpNestedLayout +
  • MyFrame::mpAboutBoxLayout +
  • MyFrame::mActiveLayoutNo +
  • MyFrame::mAutoSave +
  • MyFrame::mSavedAlready +
  • MyFrame::mpClntWindow +
  • MyFrame::mImageList +
  • MyFrame::mAboutBox +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

MyFrame::CreateTxtCtrl

wxTextCtrl* CreateTxtCtrl( const wxString& txt = "wxTextCtrl", wxWindow* parent = NULL )

helpers for control-creation

+
+


+

MyFrame::CreateDevLayout

wxWindow* CreateDevLayout( wxFrameLayout& layout, wxWindow* pParent )

helpers for layout-creation

+
+


+

MyFrame::MyFrame

MyFrame( wxFrame *frame, char *title, int x, int y, int w, int h )

public

+
+


+

MyFrame::OnClose

bool OnClose( )

event handlers

+
+


+

cbSimpleCustomizationPlugin

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
  • cbSimpleCustomizationPlugin::mCustMenuItemId +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbSimpleCustomizationPlugin::OnCustomizeBar

void OnCustomizeBar( cbCustomizeBarEvent& event )

plugin-event handlers

+
+


+

cbSimpleCustomizationPlugin::OnMenuItemSelected

void OnMenuItemSelected( wxCommandEvent& event )

menu-event handler

+
+


+

wxSerializerInfo

class conceptually simiar to wxClassInfo, execpt that it's static instances hold information about class-serializers rather then about the classes themselves.

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxSerializerInfo::classInfo

wxClassInfo* classInfo

link to corresponding class-info object,

+
+


+

wxSerializerInfo::serFn

wxObjectSerializationFn serFn

established upon invocation of InitializeSerializers()

+
+


+

wxSerializerInfo::serInfoHash

wxHashTable serInfoHash

classInfo <=> serializerInfo

+
+


+

wxSerializerInfo::SerializeInherited

void SerializeInherited( wxObject* pObj, wxObjectStorage& store )

looks up for serializers of the base classes (base1 and base2) of the given object invokes them if present

+
+


+

wxSerializerInfo::InitializeSerializers

void InitializeSerializers( )

static methods

+
+


+

wxSerializerBase

formal base class for all serializers, implemented as classes with static serialization/initialization methods

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

wxDataStreamBase

defines abstract inferface for data-stream objects, can be implemented as a wrapper class for already existing stream classes

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
  • wxDataStreamBase::StoreChar +
  • wxDataStreamBase::StoreInt +
  • wxDataStreamBase::StoreLong +
  • wxDataStreamBase::StoreDouble +
  • wxDataStreamBase::StoreBytes +
  • wxDataStreamBase::LoadChar +
  • wxDataStreamBase::LoadInt +
  • wxDataStreamBase::LoadLong +
  • wxDataStreamBase::LoadDouble +
  • wxDataStreamBase::LoadBytes +
  • wxDataStreamBase::Flush +
  • wxDataStreamBase::GetStreamPos +
  • wxDataStreamBase::IsForInput +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
  • wxDataStreamBase::mIsForInput +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

wxObjectStorage

class provides stream-based persistance service for classes derivated from wxObject, which are declared as dynamic classes. Relies on the presence of appropriate serializers for objects, which are being stored/loaded.

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • wxObjectStorage::FindSerializer +
  • wxObjectStorage::ClearHashesAndLists +
  • wxObjectStorage::VersionsMatch +
  • wxObjectStorage::FindSrzInfoForClass +
  • wxObjectStorage::DoExchangeObject +
  • wxObjectStorage::ExchangeObjectInfo +
  • wxObjectStorage::GetLatestSrzForObj +
+ +

+Attributes +

    +
  • wxObjectStorage::mpStm +
  • wxObjectStorage::mIsLoading +
  • wxObjectStorage::mRefHash +
  • wxObjectStorage::mInitialRefs +
  • wxObjectStorage::mInitialRefsHash +
  • wxObjectStorage::mInitialRefsCnt +
  • wxObjectStorage::mNewObjs +
  • wxObjectStorage::mSerializersForNewObjs +
  • wxObjectStorage::mFinalizePending +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxObjectStorage::mVerSepartorCh

char mVerSepartorCh

can be changed (with countion!)

default: '#'

+
+


+

wxObjectStorage::mMinorMajorSepartorCh

char mMinorMajorSepartorCh

default: '-'

+
+


+

wxObjectStorage::AddInitialRef

void AddInitialRef( wxObject* pObjRef )

adds initial reference, objects referred by such reference are not serialized when storing. When loading, pointers which refere to these "inital objects" are set up to refere to objects provided in by AddInitailRef() method.

NOTE:: initial references should be added always in the same order, since the seq-# of the reference is used as an alias to the real object while storing/loading

+
+


+

wxObjectStorage::SetDataStream

void SetDataStream( wxDataStreamBase& stm )

init/reinit of object-storage

+
+


+

wxObjectStorage::Finalize

void Finalize( )

performs linkng of in-memory references after loading, or links in-stream references after storing has proceeded

+
+


+

wxObjectStorage::XchgChar

void XchgChar( char& chObj )

storage methods for basic types

+
+


+

wxObjectStorage::XchgObj

void XchgObj( wxObject* pWxObj )

storage methods for objects and pointers to objects

+
+


+

wxObjectStorage::XchgWxStr

void XchgWxStr( wxString& str )

storage methods for common wxWindows classes, which may or may not be dymaic, therefor use the below methods instead of XchgObj(..)

+
+


+

wxColourSerializer

The below classes provide "curde" serialization for most common wxWindows objects, i.e. they discard the information which may be contained in the subclassed versions of these classes However, more "fine-grainded" serializers could be written to match these subclasses exactly.

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxColourSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

wxPenSerializer

NOTE:: currently "stipple" and "dashes" properties of the pen are not serialized

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxPenSerializer::Serialize +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxBrushSerializer

NOTE:: currently "stipple" property of the brush is not serialized

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxBrushSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

wxObjectListSerializer

serializer for wxList, assuming that the list holds derivatives of wxObject.

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxObjectListSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

wxEvtHandlerSerializer

generic serializer for classes derived from wxEvtHandler handler, assuming that they do not add any new properties to wxEvtHandler or these properties are transient

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxEvtHandlerSerializer::Serialize +
  • wxEvtHandlerSerializer::Initialize +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxWindowSerializer

serializer for generic wxWindow. Serializes position, size, id, reference to parent, list of children, style flags and name string. Could be used for serializing wxWindow and generic wxPanel objects. Separate serializers have to be written for control classes.

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxWindowSerializer::Serialize +
  • wxWindowSerializer::DoSerialize +
  • wxWindowSerializer::CreateWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxTextCtrlSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxTextCtrlSerializer::Serialize +
  • wxTextCtrlSerializer::CreateTextCtrlWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxButtonSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxButtonSerializer::Serialize +
  • wxButtonSerializer::CreateButtonWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxStaticTextSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxStaticTextSerializer::Serialize +
  • wxStaticTextSerializer::CreateSTextWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxScrollBarSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxScrollBarSerializer::Serialize +
  • wxScrollBarSerializer::CreateScollBarWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxTreeCtrlSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxTreeCtrlSerializer::Serialize +
  • wxTreeCtrlSerializer::CreateTreeCtrlWindowFn +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • wxTreeCtrlSerializer::SerializeBranch +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxIOStreamWrapper

default implementations of interfaces, used by wxObjectStorage class

FOR NOW:: methods do not yet perform byte-swaps for outputting/reading words in machine-independent format. Better solution would be to write wrapper around the "promissed" protable-data-stream class of wxWindows

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxIOStreamWrapper::wxIOStreamWrapper +
  • wxIOStreamWrapper::wxIOStreamWrapper +
  • wxIOStreamWrapper::Create +
  • wxIOStreamWrapper::CreateForInput +
  • wxIOStreamWrapper::CreateForOutput +
  • wxIOStreamWrapper::Attach +
  • wxIOStreamWrapper::~wxIOStreamWrapper +
  • wxIOStreamWrapper::StoreChar +
  • wxIOStreamWrapper::StoreInt +
  • wxIOStreamWrapper::StoreLong +
  • wxIOStreamWrapper::StoreDouble +
  • wxIOStreamWrapper::StoreBytes +
  • wxIOStreamWrapper::LoadChar +
  • wxIOStreamWrapper::LoadInt +
  • wxIOStreamWrapper::LoadLong +
  • wxIOStreamWrapper::LoadDouble +
  • wxIOStreamWrapper::LoadBytes +
  • wxIOStreamWrapper::Flush +
  • wxIOStreamWrapper::GetStreamPos +
  • wxIOStreamWrapper::Good +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxIOStreamWrapper::mStreamPos

long mStreamPos

precalcualted stream postion,

+
+


+

wxIOStreamWrapper::Close

void Close( )

assuming that the actual stream object is not capable of telling postion of current get/put pointer (e.g. socket-stream)

+
+


+

wxIOStreamWrapper::wxIOStreamWrapper

wxIOStreamWrapper( )

default constructor

+
+


+

wxIOStreamWrapper::wxIOStreamWrapper

wxIOStreamWrapper( iostream& stm, bool forInput = TRUE )

attach this wrapper to already exiting iostream object

+
+


+

wxIOStreamWrapper::Create

bool Create( const char* fileName, bool forInput = TRUE )

creates "fstream" object with the given file name in binary mode, returns FALSE, if stream creation failed

The created fstream object is "owned" by this wrapper, thus it is destored during destruction of this object

+
+


+

wxIOStreamWrapper::Attach

void Attach( iostream& stm, bool forInput = TRUE )

the same as in the second constructor, previousely used stream object is flushed and destroyed (if owned). The attached stream is not "owned" by this wrapper object

+
+


+

GCItem

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

+ + +


+

GCItem::mRefs

wxList mRefs

references to other nodes

+
+


+

GarbageCollector

class implements extreamly slow, but probably one of the most simple GC alogrithms

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • GarbageCollector::FindItemNode +
  • GarbageCollector::ResolveReferences +
  • GarbageCollector::FindRefernceFreeItemNode +
  • GarbageCollector::RemoveReferencesToNode +
  • GarbageCollector::DestroyItemList +
+ +

+Attributes +

    +
  • GarbageCollector::mAllNodes +
  • GarbageCollector::mRegularLst +
  • GarbageCollector::mCycledLst +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

GarbageCollector::AddObject

void AddObject( void* pObj, int refCnt = 1 )

prepare data for GC alg.

+
+


+

GarbageCollector::ArrangeCollection

void ArrangeCollection( )

executes GC alg.

+
+


+

GarbageCollector::GetRegularObjects

wxList& GetRegularObjects( )

acces results of the alg.

+
+


+

GarbageCollector::Reset

void Reset( )

removes all date form GC

+
+


+

cbSimpleUpdatesMgr

class implements slightly optimized logic for refreshing areas of frame layout - which actually need to be updated.

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbSimpleUpdatesMgr::cbSimpleUpdatesMgr +
  • cbSimpleUpdatesMgr::cbSimpleUpdatesMgr +
  • cbSimpleUpdatesMgr::OnStartChanges +
  • cbSimpleUpdatesMgr::OnRowWillChange +
  • cbSimpleUpdatesMgr::OnBarWillChange +
  • cbSimpleUpdatesMgr::OnPaneMarginsWillChange +
  • cbSimpleUpdatesMgr::OnPaneWillChange +
  • cbSimpleUpdatesMgr::OnFinishChanges +
  • cbSimpleUpdatesMgr::UpdateNow +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • cbSimpleUpdatesMgr::WasChanged +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbSimpleUpdatesMgr::OnStartChanges

void OnStartChanges( )

notificiactions received from Frame Layout (in the order, in which they usually would be invoked)

+
+


+

cbSimpleUpdatesMgr::UpdateNow

void UpdateNow( )

refreshes parts of the frame layout, which need an update

+
+


+

wxFrameLayoutSerializer

serialziers for common components of frame-layout engine

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxFrameLayoutSerializer::Serialize +
  • wxFrameLayoutSerializer::Initialize +
+ +

+Attributes +

    +
+ + +


+

cbBarSpySerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbBarSpySerializer::Serialize +
  • cbBarSpySerializer::Initialize +
+ +

+Attributes +

    +
+ + +


+

cbBarDimHandlerBaseSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbBarDimHandlerBaseSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbDimInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbDimInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbRowInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbRowInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbBarInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbBarInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbCommonPanePropertiesSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbCommonPanePropertiesSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbDockPaneSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbDockPaneSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbUpdatesManagerBaseSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbUpdatesManagerBaseSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbPluginBaseSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbPluginBaseSerializer::Serialize +
  • cbPluginBaseSerializer::Initialize +
+ +

+Attributes +

    +
+ + +


+

cbRowDragPluginSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbRowDragPluginSerializer::Serialize +
  • cbRowDragPluginSerializer::Initialize +
+ +

+Attributes +

    +
+ + +


+

cbHiddenBarInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbHiddenBarInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbFloatedBarWindowSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbFloatedBarWindowSerializer::Serialize +
  • cbFloatedBarWindowSerializer::Initialize +
  • cbFloatedBarWindowSerializer::CreateFloatedBarWindowFn +
+ +

+Attributes +

    +
+ + +


+

wxNewBitmapButtonSerializer

serializers for some additional classes (FOR NOW:: also placed here) **

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxNewBitmapButtonSerializer::Serialize +
  • wxNewBitmapButtonSerializer::Initialize +
  • wxNewBitmapButtonSerializer::CreateNewBmpBtnWindowFn +
+ +

+Attributes +

    +
+ + +


+

wxDynamicToolBarSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxDynamicToolBarSerializer::Serialize +
  • wxDynamicToolBarSerializer::Initialize +
  • wxDynamicToolBarSerializer::CreateDynTBarWindowFn +
+ +

+Attributes +

    +
+ + +


+

wxDynToolInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • wxDynToolInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

wxTabbedWindowSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • wxTabbedWindowSerializer::Serialize +
  • wxTabbedWindowSerializer::Initialize +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

twTabInfoSerializer

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • twTabInfoSerializer::Serialize +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarSpy

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

+

+Derived from +

    +
  • wxEvtHandler +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
  • cbBarSpy::mpLayout +
  • cbBarSpy::mpBarWnd +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarSpy::ProcessEvent

bool ProcessEvent( wxEvent& event )

overriden

+
+


+

wxFrameLayout

wxFrameLayout manages containment and docking of control bars. which can be docked along top, bottom, righ, or left side of the parent frame

+

+Derived from +

    +
  • wxEvtHandler +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxFrameLayout::mpFrame

wxWindow* mpFrame

protected really, acessed only by plugins and serializers

parent frame

+
+


+

wxFrameLayout::mpFrameClient

wxWindow* mpFrameClient

client window

+
+


+

wxFrameLayout::mPanes[MAX_PANES]

cbDockPane* mPanes[MAX_PANES]

panes in the panel

+
+


+

wxFrameLayout::mpHorizCursor

wxCursor* mpHorizCursor

misc. cursors

+
+


+

wxFrameLayout::mpNECursor

wxCursor* mpNECursor

no-entry cursor

+
+


+

wxFrameLayout::mDarkPen

wxPen mDarkPen

pens for decoration and shades

default wxColour(128,128,128)

+
+


+

wxFrameLayout::mLightPen

wxPen mLightPen

default white

+
+


+

wxFrameLayout::mGrayPen

wxPen mGrayPen

default wxColour(192,192,192)

+
+


+

wxFrameLayout::mBlackPen

wxPen mBlackPen

default wxColour( 0, 0, 0)

+
+


+

wxFrameLayout::mBorderPen

wxPen mBorderPen

default wxColour(128,192,192)

+
+


+

wxFrameLayout::mNullPen

wxPen mNullPen

transparent pen

+
+


+

wxFrameLayout::mpPaneInFocus

cbDockPane* mpPaneInFocus

pane to which the all mouse input is currently directed (caputred)

+
+


+

wxFrameLayout::mpLRUPane

cbDockPane* mpLRUPane

pane, from which mouse pointer had just leaft

+
+


+

wxFrameLayout::mClntWndBounds

wxRect mClntWndBounds

bounds of client window in parent frame's coordinates

+
+


+

wxFrameLayout::mpTopPlugin

cbPluginBase* mpTopPlugin

current plugin (right-most) plugin which receives events first

+
+


+

wxFrameLayout::mpCaputesInput

cbPluginBase* mpCaputesInput

plugin, which currently has caputred all input events, otherwise NULL

+
+


+

wxFrameLayout::mBarSpyList

wxList mBarSpyList

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

+
+


+

wxFrameLayout::mFloatedFrames

wxList mFloatedFrames

list of top-most frames which contain floated bars

+
+


+

wxFrameLayout::mAllBars

BarArrayT mAllBars

linked list of references to all bars (docked/floated/hidden)

+
+


+

wxFrameLayout::mClientWndRefreshPending

bool mClientWndRefreshPending

FOR NOW:: dirty stuff...

+
+


+

wxFrameLayout::mpUpdatesMgr

cbUpdatesManagerBase* mpUpdatesMgr

protected really (accessed only by plugins)

refrence to custom updates manager

+
+


+

wxFrameLayout::PositionClientWindow

void PositionClientWindow( )

called to set calculated layout to window objects

+
+


+

wxFrameLayout::GetBarPane

cbDockPane* GetBarPane( cbBarInfo* pBar )

returns panes, to which the given bar belongs

+
+


+

wxFrameLayout::ForwardMouseEvent

void ForwardMouseEvent( wxMouseEvent& event, cbDockPane* pToPane, int eventType )

delegated from "bar-spy"

+
+


+

wxFrameLayout::CanReparent

bool CanReparent( )

NOTE:: reparenting of windows may NOT work on all platforms (reparenting allows control-bars to be floated)

+
+


+

wxFrameLayout::CreateUpdatesManager

cbUpdatesManagerBase* CreateUpdatesManager( )

factory method

+
+


+

wxFrameLayout::wxFrameLayout

wxFrameLayout( )

public members

used only while serializing

+
+


+

wxFrameLayout::~wxFrameLayout

~wxFrameLayout( )

(doesn't destory bar windows)

+
+


+

wxFrameLayout::EnableFloating

void EnableFloating( bool enable = TRUE )

(by default floating of control-bars is ON)

+
+


+

wxFrameLayout::Activate

void Activate( )

Can be called after some other layout has been deactivated, and this one must "take over" the current contents of frame window.

Effectivelly hooks itself to the frame window, re-displays all not-hidden bar-windows and repaints decorations

+
+


+

wxFrameLayout::Deactivate

void Deactivate( )

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

+
+


+

wxFrameLayout::HideBarWindows

void HideBarWindows( )

also hides the client window if presents

+
+


+

wxFrameLayout::SetFrameClient

void SetFrameClient( wxWindow* pFrameClient )

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 dimesnions of control panes change

+
+


+

wxFrameLayout::GetPanesArray

cbDockPane** GetPanesArray( )

used by updates-managers

+
+


+

wxFrameLayout::GetPane

cbDockPane* GetPane( int alignment )

see pane alignment types

+
+


+

wxFrameLayout::AddBar

void AddBar( wxWindow* pBarWnd, cbDimInfo& dimInfo, int alignment = wxTOP, int rowNo = 0, int columnPos = 0, const wxString& name = "bar", bool spyEvents = FALSE, int state = wxCBAR_DOCKED_HORIZONTALLY )

Adds bar information to frame-layout, appearence of layout is not refreshed immediatelly, 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!)

+
+


+

wxFrameLayout::RedockBar

bool RedockBar( cbBarInfo* pBar, const wxRect& shapeInParent, cbDockPane* pToPane = NULL, bool updateNow = TRUE )

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

+
+


+

wxFrameLayout::FindBarByName

cbBarInfo* FindBarByName( const wxString& name )

methods for access and modification of bars in frame layout

+
+


+

wxFrameLayout::SetBarState

void SetBarState( cbBarInfo* pBar, int newStatem, bool updateNow )

changes bar's docking state (see possible control bar states)

+
+


+

wxFrameLayout::ApplyBarProperties

void ApplyBarProperties( cbBarInfo* pBar )

reflects changes in bar information structure visually (e.g. moves bar, changes it's dimension info, pane to which it is docked)

+
+


+

wxFrameLayout::RemoveBar

void RemoveBar( cbBarInfo* pBar )

removes bar from layout permanently, hides it's corresponding window if present

+
+


+

wxFrameLayout::RecalcLayout

void RecalcLayout( bool repositionBarsNow = FALSE )

recalcualtes layout of panes, and all bars/rows in each pane

+
+


+

wxFrameLayout::GetUpdatesManager

cbUpdatesManagerBase& GetUpdatesManager( )

NOTE:: in future ubdates-manager will become a normal plugin

+
+


+

wxFrameLayout::SetUpdatesManager

void SetUpdatesManager( cbUpdatesManagerBase* pUMgr )

destroys the previous manager if any, set the new one

+
+


+

wxFrameLayout::GetPaneProperties

void GetPaneProperties( cbCommonPaneProperties& props, int alignment = wxTOP )

NOTE:: changing properties of panes, does not result immediate on-screen update

+
+


+

wxFrameLayout::SetMargins

void SetMargins( int top, int bottom, int left, int right, 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

+
+


+

wxFrameLayout::RefreshNow

void RefreshNow( bool recalcLayout = TRUE )

recalculates layoute and performs on-screen update of all panes

+
+


+

wxFrameLayout::OnSize

void OnSize( wxSizeEvent& event )

event handlers

+
+


+

wxFrameLayout::FirePluginEvent

void FirePluginEvent( cbPluginEvent& 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.

+
+


+

wxFrameLayout::CaptureEventsForPlugin

void CaptureEventsForPlugin( cbPluginBase* pPlugin )

captures/releases user-input event's for the given plugin Input events are: mouse movement, mouse clicks, keyboard input

+
+


+

wxFrameLayout::CaptureEventsForPane

void CaptureEventsForPane( cbDockPane* toPane )

called by plugins ( also captures/releases mouse in parent frame)

+
+


+

wxFrameLayout::GetTopPlugin

cbPluginBase& GetTopPlugin( )

returns current top-level plugin (the one which receives events first, with an exception if input-events are currently captured by some other plugin)

+
+


+

wxFrameLayout::SetTopPlugin

void SetTopPlugin( cbPluginBase* pPlugin )

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

+
+


+

wxFrameLayout::PushPlugin

void PushPlugin( cbPluginBase* pPugin )

similar to wxWindow's "push/pop-event-handler" methods, execept that plugin is *deleted* upon "popping"

+
+


+

wxFrameLayout::PushDefaultPlugins

void PushDefaultPlugins( )

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

+
+


+

wxFrameLayout::AddPlugin

void AddPlugin( wxClassInfo* pPlInfo, int paneMask = wxALL_PANES )

"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

+
+


+

wxFrameLayout::AddPluginBefore

void AddPluginBefore( wxClassInfo* pNextPlInfo, 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

+
+


+

wxFrameLayout::RemovePlugin

void RemovePlugin( wxClassInfo* pPlInfo )

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

+
+


+

wxFrameLayout::FindPlugin

cbPluginBase* FindPlugin( wxClassInfo* pPlInfo )

returns NULL, if plugin of the given class is not hooked

+
+


+

cbUpdateMgrData

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

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbUpdateMgrData::mPrevBounds

wxRect mPrevBounds

previous state of layout item (in parent frame's coordinates)

+
+


+

cbUpdateMgrData::mIsDirty

bool mIsDirty

overrides result of current-against-previouse bounds comparison,

+
+


+

cbUpdateMgrData::mpCustomData

wxObject* mpCustomData

i.e. requires item to be updated, regardless of it's current area

any custom data stored by specific updates mgr.

+
+


+

cbUpdateMgrData::cbUpdateMgrData

cbUpdateMgrData( )

is-dirty flag is set TRUE initially

+
+


+

cbBarDimHandlerBase

Abstract inteface 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.

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarDimHandlerBase::mRefCount

int mRefCount

since one dim-handler can be asigned

+
+


+

cbBarDimHandlerBase::cbBarDimHandlerBase

cbBarDimHandlerBase( )

to multiple bars, it's instance is refernce-counted

inital refernce count is 0, since handler is not used, until the first invocation of AddRef()

+
+


+

cbBarDimHandlerBase::OnChangeBarState

void OnChangeBarState( cbBarInfo* pBar, int newState )

"bar-state-changes" notification

+
+


+

cbDimInfo

helper classes (used internally by wxFrameLayout class)

holds and manages information about bar demensions

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDimInfo::mSizes[MAX_BAR_STATES]

wxSize mSizes[MAX_BAR_STATES]

preferred sizes for each possible bar state

+
+


+

cbDimInfo::mBounds[MAX_BAR_STATES]

wxRect mBounds[MAX_BAR_STATES]

saved positions and sizes for each

+
+


+

cbDimInfo::mLRUPane

int mLRUPane

possible state, values contain (-1)s if not initialized yet

pane to which this bar was docked before it was floated

+
+


+

cbDimInfo::mVertGap

int mVertGap

(wxTOP,wxBOTTOM,..)

top/bottom gap, separates decorations from the bar's actual window, filled with frame's beckground color, default: 0

+
+


+

cbDimInfo::mHorizGap

int mHorizGap

left/right gap, separates decorations from the bar's actual window, filled with frame's beckground colour, default: 0

NOTE:: gaps are given in frame's coord. orientation

+
+


+

cbDimInfo::mIsFixed

bool mIsFixed

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

+
+


+

cbDimInfo::mpHandler

cbBarDimHandlerBase* mpHandler

NULL, if no handler present

+
+


+

cbDimInfo::cbDimInfo

cbDimInfo( int dh_x, int dh_y, int dv_x, int dv_y, int f_x, int f_y, bool isFixed = TRUE, int horizGap = 6, int vertGap = 6, cbBarDimHandlerBase* pDimHandler = NULL )

dims when docked horizontally

+
+


+

cbDimInfo::~cbDimInfo

~cbDimInfo( )

destroys handler automatically, if present

+
+


+

cbRowInfo

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRowInfo::mBars

BarArrayT mBars

row content

+
+


+

cbRowInfo::mHasUpperHandle

bool mHasUpperHandle

row flags (set up according to row-relations)

+
+


+

cbRowInfo::mBoundsInParent

wxRect mBoundsInParent

stores precalculated row's bounds in parent frame's coordinates

+
+


+

cbRowInfo::mUMgrData

cbUpdateMgrData mUMgrData

info stored for updates-manager

+
+


+

cbRowInfo::mpExpandedBar

cbBarInfo* mpExpandedBar

NULL, if non of the bars is currently expanded

+
+


+

cbRowInfo::mSavedRatios

cbArrayFloat mSavedRatios

length-ratios bofore some of the bars was expanded

+
+


+

cbRowInfo::GetFirstBar

cbBarInfo* GetFirstBar( )

convenience method

+
+


+

cbBarInfo

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
  • cbBarInfo::cbBarInfo +
  • cbBarInfo::~cbBarInfo +
  • cbBarInfo::IsFixed +
  • cbBarInfo::IsExpanded +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarInfo::mName

wxString mName

textual name, by which this bar is refered in layout-costumization dialogs

+
+


+

cbBarInfo::mBounds

wxRect mBounds

stores bar's bounds in pane's coordinates

+
+


+

cbBarInfo::mBoundsInParent

wxRect mBoundsInParent

stores precalculated bar's bounds in parent frame's coordinates

+
+


+

cbBarInfo::mpRow

cbRowInfo* mpRow

back-ref to the row, which contains this bar

+
+


+

cbBarInfo::mHasLeftHandle

bool mHasLeftHandle

are set up according to the types of the surrounding bars in the row

+
+


+

cbBarInfo::mDimInfo

cbDimInfo mDimInfo

preferred sizes for each, control bar state

+
+


+

cbBarInfo::mState

int mState

(see definition of controlbar states)

+
+


+

cbBarInfo::mAlignment

int mAlignment

alignment of the pane to which this

+
+


+

cbBarInfo::mRowNo

int mRowNo

bar is currently placed

row, into which this bar would be placed,

+
+


+

cbBarInfo::mpBarWnd

wxWindow* mpBarWnd

when in the docking state

the actual window object, NULL if no window

+
+


+

cbBarInfo::mLenRatio

double mLenRatio

is attached to the control bar (possible!)

length ratio among not-fixed-size bars

+
+


+

cbBarInfo::mPosIfFloated

wxPoint mPosIfFloated

stored last position when bar was in "floated" state

+
+


+

cbBarInfo::mUMgrData

cbUpdateMgrData mUMgrData

poistion is stored in parent-window's coordinates

info stored for updates-manager

+
+


+

cbBarInfo::mpNext

cbBarInfo* mpNext

next. bar in the row

+
+


+

cbBarInfo::mpPrev

cbBarInfo* mpPrev

prev. bar in the row

+
+


+

cbBarShapeData

used for storing original bar's postions in the row, when the "non-destructive-friction" option is turned ON

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • cbBarShapeData::mBounds +
  • cbBarShapeData::mLenRatio +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

wxBarIterator

used for traversing through all bars of all rows in the pane

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
  • wxBarIterator::mpRows +
  • wxBarIterator::mpRow +
  • wxBarIterator::mpBar +
+ + +


+

wxBarIterator::Next

bool Next( )

TRUE, if next bar is available

+
+


+

wxBarIterator::RowInfo

cbRowInfo& RowInfo( )

returns reference to currently traversed row

+
+


+

cbCommonPaneProperties

structure holds configuration options, which are usually the same for all panes in frame layout

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • cbCommonPaneProperties::cbCommonPaneProperties +
+ +

+Attributes +

+ + +


+

cbCommonPaneProperties::mRealTimeUpdatesOn

bool mRealTimeUpdatesOn

look-and-feel configuration

default: ON

+
+


+

cbCommonPaneProperties::mOutOfPaneDragOn

bool mOutOfPaneDragOn

default: ON

+
+


+

cbCommonPaneProperties::mExactDockPredictionOn

bool mExactDockPredictionOn

default: OFF

+
+


+

cbCommonPaneProperties::mNonDestructFirctionOn

bool mNonDestructFirctionOn

default: OFF

+
+


+

cbCommonPaneProperties::mShow3DPaneBorderOn

bool mShow3DPaneBorderOn

default: ON

+
+


+

cbCommonPaneProperties::mBarFloatingOn

bool mBarFloatingOn

FOR NOW:: the below properties are reserved for the "future"

default: OFF

+
+


+

cbCommonPaneProperties::mRowProportionsOn

bool mRowProportionsOn

default: OFF

+
+


+

cbCommonPaneProperties::mColProportionsOn

bool mColProportionsOn

default: ON

+
+


+

cbCommonPaneProperties::mBarCollapseIconsOn

bool mBarCollapseIconsOn

default: OFF

+
+


+

cbCommonPaneProperties::mBarDragHintsOn

bool mBarDragHintsOn

default: OFF

+
+


+

cbCommonPaneProperties::mMinCBarDim

wxSize mMinCBarDim

minimal dimensions for not-fixed bars in this pane (16x16 default)

+
+


+

cbCommonPaneProperties::mResizeHandleSize

int mResizeHandleSize

width/height of resizing sash

+
+


+

cbDockPane

class manages containment and control of control-bars along one of the four edges of the parent frame

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDockPane::mProps

cbCommonPaneProperties mProps

look-and-feel configuration for this pane

+
+


+

cbDockPane::mLeftMargin

int mLeftMargin

pane margins (in frame's coordinate-syst. orientation)

default: 2 pixels

+
+


+

cbDockPane::mRightMargin

int mRightMargin

default: 2 pixels

+
+


+

cbDockPane::mTopMargin

int mTopMargin

default: 2 pixels

+
+


+

cbDockPane::mBottomMargin

int mBottomMargin

default: 2 pixels

+
+


+

cbDockPane::mBoundsInParent

wxRect mBoundsInParent

position of the pane in frame's coordinates

+
+


+

cbDockPane::mPaneWidth

int mPaneWidth

pane width and height in pane's coordinates

+
+


+

cbDockPane::mUMgrData

cbUpdateMgrData mUMgrData

info stored for updates-manager

+
+


+

cbDockPane::mRows

RowArrayT mRows

protected really

+
+


+

cbDockPane::mpLayout

wxFrameLayout* mpLayout

back-ref

+
+


+

cbDockPane::mRowShapeData

wxList mRowShapeData

transient properties

shapes of bars of recently modified row,

+
+


+

cbDockPane::mpStoredRow

cbRowInfo* mpStoredRow

stored when in "non-destructive-firction" mode

row-info for which the shapes are stored

+
+


+

cbDockPane::GetRow

cbRowInfo* GetRow( int row )

protected really (accessed only by plugins)

+
+


+

cbDockPane::GetRowAt

int GetRowAt( int paneY )

return -1, if row is not present at given vertical position

+
+


+

cbDockPane::SyncRowFlags

void SyncRowFlags( cbRowInfo* pRow )

re-setups flags in the row-information structure, so that the would match the changed state of row-items correctly

+
+


+

cbDockPane::IsFixedSize

bool IsFixedSize( cbBarInfo* pInfo )

layout "AI" helpers:

+
+


+

cbDockPane::FrameToPane

void FrameToPane( long* x, long* y )

coordinate translation between parent's frame and this pane

+
+


+

cbDockPane::SetRowHeight

void SetRowHeight( cbRowInfo* pRow, int newHeight )

given row height includes height of row handles, if present

+
+


+

cbDockPane::PaintBarDecorations

void PaintBarDecorations( cbBarInfo* pBar, wxDC& dc )

protected really (accessed only by plugins)

methods for incramental on-screen refreshing of the pane (simply, they are wrappers around corresponding plugin-events)

+
+


+

cbDockPane::cbDockPane

cbDockPane( )

public members

+
+


+

cbDockPane::SetMargins

void SetMargins( int top, int bottom, int left, int right )

sets pane's margins in frame's coordinate orientations

+
+


+

cbDockPane::RemoveBar

void RemoveBar( cbBarInfo* pBar )

does not destroys the info bar , only removes it's reference from this pane

+
+


+

cbDockPane::InsertBar

void InsertBar( cbBarInfo* pBar, const wxRect& atRect )

rect given in the parent frame's coordinates

+
+


+

cbDockPane::InsertBar

void InsertBar( cbBarInfo* pBar, cbRowInfo* pIntoRow )

inserts bar into the given row, with dimensions and position stored in pBarInfo->mBounds. Returns the node of inserted bar

+
+


+

cbDockPane::InsertBar

void InsertBar( cbBarInfo* pBarInfo )

inserts bar, sets its position according to the preferred settings given in (*pBarInfo) structure

+
+


+

cbDockPane::RemoveRow

void RemoveRow( cbRowInfo* pRow )

does not destroy the row object, only removes the corresponding node from this pane

+
+


+

cbDockPane::InsertRow

void InsertRow( cbRowInfo* pRow, cbRowInfo* pBeforeRow )

does not refresh the inserted row immediatelly, if pBeforeRowNode arg. is NULL, row is appended to the end of pane's row list

+
+


+

cbDockPane::SetPaneWidth

void SetPaneWidth( int width )

sets pane's width in pane's coordinates (including margins)

+
+


+

cbDockPane::SetBoundsInParent

void SetBoundsInParent( const wxRect& rect )

set the position and dims. of the pane in parent frame's coordinates

+
+


+

cbDockPane::GetRowList

RowArrayT& GetRowList( )

used by upadates-managers

+
+


+

cbDockPane::GetFirstRow

cbRowInfo* GetFirstRow( )

convenience method

+
+


+

cbDockPane::BarPresent

bool BarPresent( cbBarInfo* pBar )

TRUE, if the given bar node presents in this pane

+
+


+

cbDockPane::GetPaneHeight

int GetPaneHeight( )

retuns height, in pane's coordinates

+
+


+

cbDockPane::HitTestPaneItems

int HitTestPaneItems( const wxPoint& pos, cbRowInfo** ppRow, cbBarInfo** ppBar )

returns result of hit-testing items in the pane, see CB_HITTEST_RESULTS enumeration

position in pane's coorinates

+
+


+

cbDockPane::DrawVertHandle

void DrawVertHandle( wxDC& dc, int x, int y, int height )

protected really (accessed only by plugins)

row/bar resizing related helper-methods

+
+


+

cbDockPane::GetRowShapeData

void GetRowShapeData( cbRowInfo* pRow, wxList* pLst )

cbBarShapeData objects will be placed to given pLst (see comments on cbBarShapeData)

+
+


+

cbDockPane::SetRowShapeData

void SetRowShapeData( cbRowInfo* pRowNode, wxList* pLst )

sets the shape to the given row, using the data provided in pLst

+
+


+

cbUpdatesManagerBase

class declares abstract interface for optimized logic, which should refresh areas of frame layout - that actually need to be updated. Should be extanded, to implemnet custom updating strategy

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbUpdatesManagerBase::mpLayout

wxFrameLayout* mpLayout

protected really, accessed by serializer (if any)

+
+


+

cbUpdatesManagerBase::OnStartChanges

void OnStartChanges( )

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

+
+


+

cbUpdatesManagerBase::UpdateNow

void UpdateNow( )

refreshes parts of the frame layout, which need an update

+
+


+

cbPluginEvent

------------------------------------------------------------ "API" for developing custom plugins of Frame Layout Engine TODO:: documentation ------------------------------------------------------------

base class for all control-bar plugin events

+

+Derived from +

    +
  • wxEvent +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbPluginEvent::mpPane

cbDockPane* mpPane

NOTE:: plugin-event does not need to be a dynamic class

NULL, if event is not addressed to any specific pane

+
+


+

cbPluginEvent::cbPluginEvent

cbPluginEvent( int eventType, cbDockPane* pPane )

OLD STUFF:: // FOR NOW FOR NOW:: all-in-on plugin event structure wxNode* mpObjNode; wxNode* mpObjNodeAux; wxPoint mPos; wxSize mSize; wxDC* mpDC; bool mAuxBoolVal;

+
+


+

cbPluginBase

abstract base class for all control-bar related plugins

+

+Derived from +

    +
  • wxEvtHandler +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbPluginBase::mpLayout

wxFrameLayout* mpLayout

back-reference to the frame layout

+
+


+

cbPluginBase::mIsReady

bool mIsReady

is TRUE, when plugin is ready to handle events

+
+


+

cbPluginBase::mPaneMask

int mPaneMask

specifies panes, for which this plugin receives events (see pane masks definitions)

+
+


+

cbPluginBase::~cbPluginBase

~cbPluginBase( )

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

+
+


+

cbPluginBase::OnInitPlugin

void OnInitPlugin( )

override this method to do plugin-specific initialization (at this point plugin is already attached to the frame layout, and pane masks are set)

+
+


+

cbPluginBase::ProcessEvent

bool ProcessEvent( wxEvent& event )

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)

+
+


+

cbLeftDownEvent

event classes, for each corresponding event type (24 currnetly...uhh) **

mouse-events category

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbLeftDownEvent::cbLeftDownEvent +
+ +

+Attributes +

    +
  • cbLeftDownEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbLeftUpEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbLeftUpEvent::cbLeftUpEvent +
+ +

+Attributes +

    +
  • cbLeftUpEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRightDownEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbRightDownEvent::cbRightDownEvent +
+ +

+Attributes +

    +
  • cbRightDownEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRightUpEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbRightUpEvent::cbRightUpEvent +
+ +

+Attributes +

    +
  • cbRightUpEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbMotionEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbMotionEvent::cbMotionEvent +
+ +

+Attributes +

    +
  • cbMotionEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbLeftDClickEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbLeftDClickEvent::cbLeftDClickEvent +
+ +

+Attributes +

    +
  • cbLeftDClickEvent::mPos +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbLayoutRowEvent

bar/row events category

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbLayoutRowEvent::cbLayoutRowEvent +
+ +

+Attributes +

    +
  • cbLayoutRowEvent::mpRow +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbResizeRowEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbResizeRowEvent::cbResizeRowEvent +
+ +

+Attributes +

    +
  • cbResizeRowEvent::mpRow +
  • cbResizeRowEvent::mHandleOfs +
  • cbResizeRowEvent::mForUpperHandle +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbLayoutRowsEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbLayoutRowsEvent::cbLayoutRowsEvent +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbInsertBarEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbInsertBarEvent::cbInsertBarEvent +
+ +

+Attributes +

    +
  • cbInsertBarEvent::mpBar +
  • cbInsertBarEvent::mpRow +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbResizeBarEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbResizeBarEvent::cbResizeBarEvent +
+ +

+Attributes +

    +
  • cbResizeBarEvent::mpBar +
  • cbResizeBarEvent::mpRow +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRemoveBarEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbRemoveBarEvent::cbRemoveBarEvent +
+ +

+Attributes +

    +
  • cbRemoveBarEvent::mpBar +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbSizeBarWndEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbSizeBarWndEvent::cbSizeBarWndEvent +
+ +

+Attributes +

    +
  • cbSizeBarWndEvent::mpBar +
  • cbSizeBarWndEvent::mBoundsInParent +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawBarDecorEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawBarDecorEvent::cbDrawBarDecorEvent +
+ +

+Attributes +

    +
  • cbDrawBarDecorEvent::mpBar +
  • cbDrawBarDecorEvent::mpDc +
  • cbDrawBarDecorEvent::mBoundsInParent +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawRowDecorEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawRowDecorEvent::cbDrawRowDecorEvent +
+ +

+Attributes +

    +
  • cbDrawRowDecorEvent::mpRow +
  • cbDrawRowDecorEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawPaneDecorEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawPaneDecorEvent::cbDrawPaneDecorEvent +
+ +

+Attributes +

    +
  • cbDrawPaneDecorEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawBarHandlesEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawBarHandlesEvent::cbDrawBarHandlesEvent +
+ +

+Attributes +

    +
  • cbDrawBarHandlesEvent::mpBar +
  • cbDrawBarHandlesEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawRowHandlesEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawRowHandlesEvent::cbDrawRowHandlesEvent +
+ +

+Attributes +

    +
  • cbDrawRowHandlesEvent::mpRow +
  • cbDrawRowHandlesEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawRowBkGroundEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawRowBkGroundEvent::cbDrawRowBkGroundEvent +
+ +

+Attributes +

    +
  • cbDrawRowBkGroundEvent::mpRow +
  • cbDrawRowBkGroundEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawPaneBkGroundEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDrawPaneBkGroundEvent::cbDrawPaneBkGroundEvent +
+ +

+Attributes +

    +
  • cbDrawPaneBkGroundEvent::mpDc +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbStartBarDraggingEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbStartBarDraggingEvent::cbStartBarDraggingEvent +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbStartBarDraggingEvent::mPos

wxPoint mPos

is given in frame's coordinates

+
+


+

cbDrawHintRectEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbDrawHintRectEvent::mRect

wxRect mRect

is given in frame's coordinates

+
+


+

cbDrawHintRectEvent::mIsInClient

bool mIsInClient

in cleint area hint could be drawn differently,

+
+


+

cbDrawHintRectEvent::mEraseRect

bool mEraseRect

e.g. with fat/hatched border

does not have any impact, if recangle is drawn using XOR-mask

+
+


+

cbDrawHintRectEvent::mLastTime

bool mLastTime

indicates that this event finishes "session" of on-screen drawing,

+
+


+

cbDrawHintRectEvent::cbDrawHintRectEvent

cbDrawHintRectEvent( const wxRect& rect, bool isInClient, bool eraseRect, bool lastTime )

thus associated resources can be freed now

+
+


+

cbStartDrawInAreaEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbStartDrawInAreaEvent::mppDc

wxDC** mppDc

points to pointer, where the reference

+
+


+

cbStartDrawInAreaEvent::cbStartDrawInAreaEvent

cbStartDrawInAreaEvent( const wxRect& area, wxDC** ppDCForArea, cbDockPane* pPane )

to the obtained buffer-context should be placed

+
+


+

cbFinishDrawInAreaEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbFinishDrawInAreaEvent::cbFinishDrawInAreaEvent +
+ +

+Attributes +

    +
  • cbFinishDrawInAreaEvent::mArea +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbCustomizeBarEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbCustomizeBarEvent::cbCustomizeBarEvent +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbCustomizeBarEvent::mClickPos

wxPoint mClickPos

in parent frame's coordinates

+
+


+

cbCustomizeLayoutEvent

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbCustomizeLayoutEvent::cbCustomizeLayoutEvent +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbCustomizeLayoutEvent::mClickPos

wxPoint mClickPos

in parent frame's coordinates

+
+


+

cbHintAnimationPlugin

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbHintAnimationPlugin::cbHintAnimationPlugin +
  • cbHintAnimationPlugin::~cbHintAnimationPlugin +
  • cbHintAnimationPlugin::cbHintAnimationPlugin +
  • cbHintAnimationPlugin::OnDrawHintRect +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • cbHintAnimationPlugin::StartTracking +
  • cbHintAnimationPlugin::DrawHintRect +
  • cbHintAnimationPlugin::EraseHintRect +
  • cbHintAnimationPlugin::FinishTracking +
  • cbHintAnimationPlugin::DoDrawHintRect +
  • cbHintAnimationPlugin::RectToScr +
+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbHintAnimationPlugin::mpScrDc

wxScreenDC* mpScrDc

created while tracking hint-rect

+
+


+

cbHintAnimationPlugin::mCurRect

wxRect mCurRect

FOR NOW:: try it without mutually exculisve locks

+
+


+

cbHintAnimationPlugin::mAnimStarted

bool mAnimStarted

state variables

+
+


+

cbHintAnimationPlugin::mMorphDelay

int mMorphDelay

delay between frames in miliseconds, default: 20

+
+


+

cbHintAnimationPlugin::mMaxFrames

int mMaxFrames

number of iterations for hint morphing, default: 30

+
+


+

cbHintAnimationPlugin::mInClientHintBorder

int mInClientHintBorder

(morph duration = mMorphDelay * mMaxFrames msec)

default: 4 pixels

+
+


+

cbHintAnimationPlugin::mAccelerationOn

bool mAccelerationOn

TRUE, if morph accelerates, otherwise morph

+
+


+

cbHintAnimationPlugin::StartTracking

void StartTracking( )

speed is constant. Default: TRUE

TBD:: get/set methods for above members

+
+


+

MorphInfoT

helper classes

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
  • MorphInfoT::mFrom +
  • MorphInfoT::mTill +
+ +
+


+

cbHintAnimTimer

+

+Derived from +

    +
  • wxTimer +
+ +

+Public members

+

+Operations +

    +
  • cbHintAnimTimer::cbHintAnimTimer +
  • cbHintAnimTimer::Notify +
  • cbHintAnimTimer::Init +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • cbHintAnimTimer::MorphPoint +
+ +

+Attributes +

    +
  • cbHintAnimTimer::mPrevMorphed +
  • cbHintAnimTimer::mUpperLeft +
  • cbHintAnimTimer::mLowerRight +
  • cbHintAnimTimer::mCurIter +
  • cbHintAnimTimer::mLock +
  • cbHintAnimTimer::mpPl +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

cbBarDragPlugin

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbBarDragPlugin::cbBarDragPlugin +
  • cbBarDragPlugin::cbBarDragPlugin +
  • cbBarDragPlugin::~cbBarDragPlugin +
  • cbBarDragPlugin::OnMouseMove +
  • cbBarDragPlugin::OnLButtonUp +
  • cbBarDragPlugin::OnLButtonDown +
  • cbBarDragPlugin::OnLDblClick +
  • cbBarDragPlugin::OnDrawHintRect +
  • cbBarDragPlugin::OnStartBarDragging +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • cbBarDragPlugin::AdjustHintRect +
  • cbBarDragPlugin::ClipRectInFrame +
  • cbBarDragPlugin::ClipPosInFrame +
  • cbBarDragPlugin::HitTestPanes +
  • cbBarDragPlugin::HitTestPanes +
  • cbBarDragPlugin::HitsPane +
  • cbBarDragPlugin::CalcOnScreenDims +
  • cbBarDragPlugin::GetDistanceToPane +
  • cbBarDragPlugin::IsInOtherPane +
  • cbBarDragPlugin::IsInClientArea +
  • cbBarDragPlugin::IsInClientArea +
  • cbBarDragPlugin::StickToPane +
  • cbBarDragPlugin::UnstickFromPane +
  • cbBarDragPlugin::GetBarWidthInPane +
  • cbBarDragPlugin::GetBarHeightInPane +
  • cbBarDragPlugin::StartTracking +
  • cbBarDragPlugin::DrawHintRect +
  • cbBarDragPlugin::EraseHintRect +
  • cbBarDragPlugin::FinishTracking +
  • cbBarDragPlugin::DoDrawHintRect +
  • cbBarDragPlugin::RectToScr +
  • cbBarDragPlugin::ShowHint +
+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarDragPlugin::mBarDragStarted

bool mBarDragStarted

plugin is active only in bar-dragging state

+
+


+

cbBarDragPlugin::mpScrDc

wxScreenDC* mpScrDc

created while tracking hint-rect

+
+


+

cbBarDragPlugin::mPrevHintRect

wxRect mPrevHintRect

rectnagle shows the position/dimensions of the bar, if it would be docked now

+
+


+

cbBarDragPlugin::mCanStick

bool mCanStick

flag used to prevent "bouncing" of hint-rectangle

+
+


+

cbBarDragPlugin::mpSrcPane

cbDockPane* mpSrcPane

pane, from which the bar was originally taken

+
+


+

cbBarDragPlugin::mpDraggedBar

cbBarInfo* mpDraggedBar

bar, which is being dragged

+
+


+

cbBarDragPlugin::mInClientHintBorder

int mInClientHintBorder

public properties **

when hint-rect moves within client window area,

+
+


+

cbBarDragPlugin::AdjustHintRect

void AdjustHintRect( wxPoint& mousePos )

the thicker rectangle is drawn using hatched brush, the default border width for this rectangle is 8 pix.

+
+


+

cbBarDragPlugin::StartTracking

void StartTracking( )

on-screen hint-tracking related methods

+
+


+

cbBarDragPlugin::OnMouseMove

void OnMouseMove( cbMotionEvent& event )

handlers for plugin events

+
+


+

cbBarDragPlugin::OnDrawHintRect

void OnDrawHintRect( cbDrawHintRectEvent& event )

handles event, which oriniates from itself

+
+


+

cbRowDragPlugin

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.

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbRowDragPlugin::cbRowDragPlugin +
  • cbRowDragPlugin::cbRowDragPlugin +
  • cbRowDragPlugin::~cbRowDragPlugin +
  • cbRowDragPlugin::Clone +
  • cbRowDragPlugin::OnInitPlugin +
  • cbRowDragPlugin::OnMouseMove +
  • cbRowDragPlugin::OnLButtonDown +
  • cbRowDragPlugin::OnLButtonUp +
  • cbRowDragPlugin::OnDrawPaneBackground +
  • cbRowDragPlugin::DrawCollapsedRowIcon +
  • cbRowDragPlugin::DrawCollapsedRowsBorder +
  • cbRowDragPlugin::DrawRowsDragHintsBorder +
  • cbRowDragPlugin::DrawRowDragHint +
  • cbRowDragPlugin::DrawEmptyRow +
  • cbRowDragPlugin::GetCollapsedRowIconHeight +
  • cbRowDragPlugin::GetRowDragHintWidth +
  • cbRowDragPlugin::SetPaneMargins +
  • cbRowDragPlugin::HitTestCollapsedRowIcon +
  • cbRowDragPlugin::HitTestRowDragHint +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • cbRowDragPlugin::CaptureDCArea +
  • cbRowDragPlugin::GetHRowsCountForPane +
  • cbRowDragPlugin::SetMouseCapture +
  • cbRowDragPlugin::PrepareForRowDrag +
  • cbRowDragPlugin::ShowDraggedRow +
  • cbRowDragPlugin::ShowPaneImage +
  • cbRowDragPlugin::FinishOnScreenDraw +
  • cbRowDragPlugin::CollapseRow +
  • cbRowDragPlugin::ExpandRow +
  • cbRowDragPlugin::InsertDraggedRowBefore +
  • cbRowDragPlugin::ItemIsInFocus +
  • cbRowDragPlugin::CheckPrevItemInFocus +
  • cbRowDragPlugin::UnhiglightItemInFocus +
  • cbRowDragPlugin::GetFirstRow +
  • cbRowDragPlugin::DrawTrianUp +
  • cbRowDragPlugin::DrawTrianDown +
  • cbRowDragPlugin::DrawTrianRight +
  • cbRowDragPlugin::Draw3DPattern +
  • cbRowDragPlugin::DrawRombShades +
  • cbRowDragPlugin::DrawOrtoRomb +
  • cbRowDragPlugin::DrawRomb +
  • cbRowDragPlugin::Draw3DRect +
  • cbRowDragPlugin::DrawRectShade +
  • cbRowDragPlugin::GetRowHintRect +
  • cbRowDragPlugin::GetCollapsedInconRect +
  • cbRowDragPlugin::GetCollapsedIconsPos +
+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRowDragPlugin::mHightColor

wxColour mHightColor

background colours for the highlighted/unhighlighted icons

light-blue for NC-look

+
+


+

cbRowDragPlugin::mLowColor

wxColour mLowColor

light-gray -/-

+
+


+

cbRowDragPlugin::mTrianInnerColor

wxColour mTrianInnerColor

blue -/-

+
+


+

cbRowDragPlugin::mTrianInnerPen

wxPen mTrianInnerPen

black -/-

+
+


+

cbRowDragPlugin::mDragStarted

bool mDragStarted

drag & drop state variables

+
+


+

cbRowDragPlugin::mSvTopMargin

int mSvTopMargin

saved margins of the pane

+
+


+

cbRowDragPlugin::mpPaneImage

wxBitmap* mpPaneImage

on-screen drawing state variables

+
+


+

cbRowDragPlugin::mpRowInFocus

cbRowInfo* mpRowInFocus

NOTE:: if mpRowInFocus is not NULL, then mCollapsedIconInFocus is -1, and v.v. (two different items cannot be in focus at the same time)

+
+


+

cbRowDragPlugin::mpPane

cbDockPane* mpPane

is set up temorarely, while handling event

+
+


+

cbRowDragPlugin::GetHRowsCountForPane

int GetHRowsCountForPane( cbDockPane* pPane )

helpers for drag&drop

+
+


+

cbRowDragPlugin::DrawTrianUp

void DrawTrianUp( wxRect& inRect, wxDC& dc )

"hard-coded metafile" for NN-look

+
+


+

cbRowDragPlugin::OnMouseMove

void OnMouseMove( cbMotionEvent& event )

handlers for plugin events (appearence-independent logic)

+
+


+

cbRowDragPlugin::DrawCollapsedRowIcon

void DrawCollapsedRowIcon( int index, wxDC& dc, bool isHighlighted )

overridables (appearence-depedent)

+
+


+

cbHiddenBarInfo

internal helper-class

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • cbHiddenBarInfo::mpBar +
  • cbHiddenBarInfo::mRowNo +
  • cbHiddenBarInfo::mIconNo +
  • cbHiddenBarInfo::mAlignment +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

notStorableClass

forward decl.

sample classes

+

+Derived from +

    +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

classA

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • classA::x +
  • classA::mpBObj +
  • classA::mpBackRef +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

classB

+

+Derived from +

    +
  • wxObject +
+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
  • classB::y +
  • classB::mpAObj +
  • classB::mpBackRef +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +
+


+

classASerializer

serialization handlers for the above classes

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • classASerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

classBSerializer

cast

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
  • classBSerializer::Serialize +
+ +

+Attributes +

    +
+ + +


+

cbDynToolBarDimHandler

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbDynToolBarDimHandler::OnChangeBarState +
  • cbDynToolBarDimHandler::OnResizeBar +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
+ +

+Attributes +

    +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRowLayoutPlugin

Simple implementaiton of plugin, which handles row-layouting requests sent from Frame Layout

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbRowLayoutPlugin::cbRowLayoutPlugin +
  • cbRowLayoutPlugin::cbRowLayoutPlugin +
  • cbRowLayoutPlugin::OnResizeRow +
  • cbRowLayoutPlugin::OnInsertBar +
  • cbRowLayoutPlugin::OnRemoveBar +
  • cbRowLayoutPlugin::OnLayoutRow +
  • cbRowLayoutPlugin::OnLayoutRows +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • cbRowLayoutPlugin::FitBarsToRange +
  • cbRowLayoutPlugin::RelayoutNotFixedBarsAround +
  • cbRowLayoutPlugin::MinimzeNotFixedBars +
  • cbRowLayoutPlugin::GetRowFreeSpace +
  • cbRowLayoutPlugin::RecalcLenghtRatios +
  • cbRowLayoutPlugin::ApplyLenghtRatios +
  • cbRowLayoutPlugin::ExpandNotFixedBars +
  • cbRowLayoutPlugin::AdjustLenghtOfInserted +
  • cbRowLayoutPlugin::DetectBarHandles +
  • cbRowLayoutPlugin::CheckIfAtTheBoundary +
  • cbRowLayoutPlugin::CalcRowHeight +
  • cbRowLayoutPlugin::LayoutItemsVertically +
  • cbRowLayoutPlugin::StickRightSideBars +
  • cbRowLayoutPlugin::SlideLeftSideBars +
  • cbRowLayoutPlugin::SlideRightSideBars +
  • cbRowLayoutPlugin::ShiftLeftTrashold +
  • cbRowLayoutPlugin::ShiftRightTrashold +
  • cbRowLayoutPlugin::InsertBefore +
  • cbRowLayoutPlugin::DoInsertBar +
+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbRowLayoutPlugin::mpPane

cbDockPane* mpPane

is set up temorarely, while handling event

+
+


+

cbRowLayoutPlugin::FitBarsToRange

void FitBarsToRange( int from, int till, cbBarInfo* pTheBar, cbRowInfo* pRow )

not-fixed-bars layouting related helpers

+
+


+

cbRowLayoutPlugin::CalcRowHeight

int CalcRowHeight( cbRowInfo& row )

row-layouting helpers (simulate "bar-friction")

+
+


+

cbRowLayoutPlugin::OnResizeRow

void OnResizeRow( cbResizeRowEvent& event )

event handlers

+
+


+

SettingsDlg

+

+Derived from +

    +
  • wxDialog +
+ +

+Public members

+

+Operations +

    +
  • SettingsDlg::SettingsDlg +
  • SettingsDlg::ReadLayoutSettings +
  • SettingsDlg::ApplyLayoutSettings +
  • SettingsDlg::ExchangeFields +
  • SettingsDlg::OnApply +
  • SettingsDlg::OnNotes +
  • SettingsDlg::OnHintAnimCheck +
  • SettingsDlg::OnRTUpdatesCheck +
  • SettingsDlg::DECLARE_EVENT_TABLE +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • SettingsDlg::ExchgCheck +
  • SettingsDlg::ExchgIntField +
  • SettingsDlg::ExchgColourField +
  • SettingsDlg::TransferDataToWindow +
  • SettingsDlg::TransferDataFromWindow +
+ +

+Attributes +

    +
  • SettingsDlg::mpRTU_Check +
  • SettingsDlg::mpOPD_Check +
  • SettingsDlg::mpEDP_Check +
  • SettingsDlg::mpNDF_Check +
  • SettingsDlg::mpSPB_Check +
  • SettingsDlg::mpHAP_Check +
  • SettingsDlg::mpGCU_Check +
  • SettingsDlg::mpAFP_Check +
  • SettingsDlg::mpCSP_Check +
  • SettingsDlg::mpRWInput +
  • SettingsDlg::mpRWLabel +
  • SettingsDlg::mpPTMInput +
  • SettingsDlg::mpPTMLabel +
  • SettingsDlg::mpPBMInput +
  • SettingsDlg::mpPBMLabel +
  • SettingsDlg::mpPLMInput +
  • SettingsDlg::mpPLMLabel +
  • SettingsDlg::mpPRMInput +
  • SettingsDlg::mpPRMLabel +
  • SettingsDlg::mpDCInput +
  • SettingsDlg::mpDCLabel +
  • SettingsDlg::mpLCInput +
  • SettingsDlg::mpLCLabel +
  • SettingsDlg::mpGCInput +
  • SettingsDlg::mpGCLabel +
  • SettingsDlg::mpBCInput +
  • SettingsDlg::mpBCLabel +
  • SettingsDlg::mRealTimeUpdatesOn +
  • SettingsDlg::mOutOfPaneDragOn +
  • SettingsDlg::mExactDockingPredictionOn +
  • SettingsDlg::mNonDestructFrictionOn +
  • SettingsDlg::m3DShadesOn +
  • SettingsDlg::mHintRectAnimationOn +
  • SettingsDlg::mGCUpdatesMgrOn +
  • SettingsDlg::mAntiflickerPluginOn +
  • SettingsDlg::mCustomizationPluginOn +
  • SettingsDlg::mSashWidth +
  • SettingsDlg::mTopMargin +
  • SettingsDlg::mBottomMargin +
  • SettingsDlg::mLeftMargin +
  • SettingsDlg::mRightMargin +
  • SettingsDlg::mDarkCol +
  • SettingsDlg::mLightCol +
  • SettingsDlg::mGrayCol +
  • SettingsDlg::mBorderCol +
  • SettingsDlg::mToDlg +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

SettingsDlg::mpRTU_Check

wxCheckBox* mpRTU_Check

"nice thing" about wxWindows:

+
+


+

SettingsDlg::mRealTimeUpdatesOn

bool mRealTimeUpdatesOn

fields/properties

+
+


+

SettingsDlg::ExchgCheck

void ExchgCheck( wxCheckBox* pChk, bool& value )

helpers

+
+


+

cbBarHintsPlugin

Intercepts bar-decoration and sizing events, draws 3d-hints around fixed and flexible bars, similar to those in Microsoft DevStudio 6.x

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbBarHintsPlugin::cbBarHintsPlugin +
  • cbBarHintsPlugin::cbBarHintsPlugin +
  • cbBarHintsPlugin::SetGrooveCount +
  • cbBarHintsPlugin::OnInitPlugin +
  • cbBarHintsPlugin::OnSizeBarWindow +
  • cbBarHintsPlugin::OnDrawBarDecorations +
  • cbBarHintsPlugin::OnLeftDown +
  • cbBarHintsPlugin::OnLeftUp +
  • cbBarHintsPlugin::OnMotion +
+ +

+Attributes +

+ +

+Protected members

+

+Operations +

    +
  • cbBarHintsPlugin::Draw3DBox +
  • cbBarHintsPlugin::DrawCloseBox +
  • cbBarHintsPlugin::DrawCollapseBox +
  • cbBarHintsPlugin::DrawGrooves +
  • cbBarHintsPlugin::DoDrawHint +
  • cbBarHintsPlugin::GetHintsLayout +
  • cbBarHintsPlugin::HitTestHints +
  • cbBarHintsPlugin::ExcludeHints +
  • cbBarHintsPlugin::CreateBoxes +
+ +

+Attributes +

    +
  • cbBarHintsPlugin::mpPane +
  • cbBarHintsPlugin::mBoxes[2] +
  • cbBarHintsPlugin::mBtnPressed +
  • cbBarHintsPlugin::mClosePressed +
  • cbBarHintsPlugin::mpClickedBar +
  • cbBarHintsPlugin::mDepressed +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbBarHintsPlugin::mpPane

cbDockPane* mpPane

is set up temorarely, while handling event

+
+


+

cbBarHintsPlugin::Draw3DBox

void Draw3DBox( wxDC& dc, const wxPoint& pos, bool pressed )

drawing helpers

+
+


+

cbBarHintsPlugin::mCloseBoxOn

bool mCloseBoxOn

public properties

default: ON

+
+


+

cbBarHintsPlugin::mCollapseBoxOn

bool mCollapseBoxOn

default: ON

+
+


+

cbBarHintsPlugin::mGrooveCount

int mGrooveCount

default: 2 (two shaded bars)

+
+


+

cbBarHintsPlugin::mHintGap

int mHintGap

default: 5 (pixels from above, below, right and left)

+
+


+

cbBarHintsPlugin::mXWeight

int mXWeight

default: 2 (width in pixels of lines which used for drawing cross)

+
+


+

cbBarHintsPlugin::OnSizeBarWindow

void OnSizeBarWindow( cbSizeBarWndEvent& event )

handlers of plugin-events

+
+


+

wxNewBitmapButton

classes declared in this header file

alternative class for wxBmpButton

+

+Derived from +

    +
  • wxPanel +
+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

wxNewBitmapButton::mDepressedBmp

wxBitmap mDepressedBmp

source image for rendering

+
+


+

wxNewBitmapButton::mFocusedBmp

wxBitmap mFocusedBmp

labels for particular state

may not be always present -

+
+


+

wxNewBitmapButton::mpDepressedImg

wxBitmap* mpDepressedImg

only if mHasFocusedBmp is TRUE

+
+


+

wxNewBitmapButton::mDragStarted

bool mDragStarted

button state variables;

+
+


+

wxNewBitmapButton::mFiredEventType

int mFiredEventType

type of event which is fired upon depression of this button

+
+


+

wxNewBitmapButton::mBlackPen

wxPen mBlackPen

pens for drawing decorations (borders)

+
+


+

wxNewBitmapButton::GetStateLabel

wxBitmap* GetStateLabel( )

returns the label which match the current button state

+
+


+

wxNewBitmapButton::wxNewBitmapButton

wxNewBitmapButton( const wxString& bitmapFileName, const int bitmapFileType = wxBITMAP_TYPE_BMP, const wxString& labelText = "", int alignText = NB_ALIGN_TEXT_BOTTOM, bool isFlat = TRUE, 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::SetLabel

void SetLabel( const wxBitmap& labelBitmap, const wxString& labelText = "" )

overridables

+
+


+

wxNewBitmapButton::OnLButtonDown

void OnLButtonDown( wxMouseEvent& event )

event handlers

+
+


+

cbPaneDrawPlugin

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)

+

+Derived from +

+ +

+Public members

+

+Operations +

    +
  • cbPaneDrawPlugin::cbPaneDrawPlugin +
  • cbPaneDrawPlugin::cbPaneDrawPlugin +
  • cbPaneDrawPlugin::~cbPaneDrawPlugin +
  • cbPaneDrawPlugin::Clone +
  • cbPaneDrawPlugin::OnLButtonDown +
  • cbPaneDrawPlugin::OnLDblClick +
  • cbPaneDrawPlugin::OnLButtonUp +
  • cbPaneDrawPlugin::OnRButtonUp +
  • cbPaneDrawPlugin::OnMouseMove +
  • cbPaneDrawPlugin::OnDrawPaneBackground +
  • cbPaneDrawPlugin::OnDrawPaneDecorations +
  • cbPaneDrawPlugin::OnDrawRowDecorations +
  • cbPaneDrawPlugin::OnDrawRowHandles +
  • cbPaneDrawPlugin::OnDrawRowBackground +
  • cbPaneDrawPlugin::OnSizeBarWindow +
  • cbPaneDrawPlugin::OnDrawBarDecorations +
  • cbPaneDrawPlugin::OnDrawBarHandles +
  • cbPaneDrawPlugin::OnStartDrawInArea +
  • cbPaneDrawPlugin::OnFinishDrawInArea +
+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • cbPaneDrawPlugin::DrawDraggedHandle +
  • cbPaneDrawPlugin::DrawPaneShade +
  • cbPaneDrawPlugin::DrawPaneShadeForRow +
  • cbPaneDrawPlugin::DrawUpperRowHandle +
  • cbPaneDrawPlugin::DrawLowerRowHandle +
  • cbPaneDrawPlugin::DrawUpperRowShades +
  • cbPaneDrawPlugin::DrawLowerRowShades +
  • cbPaneDrawPlugin::DrawBarInnerShadeRect +
  • cbPaneDrawPlugin::DrawShade +
  • cbPaneDrawPlugin::DrawShade1 +
  • cbPaneDrawPlugin::SetLightPixel +
  • cbPaneDrawPlugin::SetDarkPixel +
+ +

+Attributes +

+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbPaneDrawPlugin::mResizeStarted

bool mResizeStarted

resizing bars/rows state variables

+
+


+

cbPaneDrawPlugin::mpDraggedBar

cbBarInfo* mpDraggedBar

also used when in bar-drag action

+
+


+

cbPaneDrawPlugin::mHandleDragArea

wxRect mHandleDragArea

contstraints for dragging the handle

+
+


+

cbPaneDrawPlugin::mpClntDc

wxClientDC* mpClntDc

used for handling, start-draw-in-area events

+
+


+

cbPaneDrawPlugin::mpPane

cbDockPane* mpPane

is set up temorary short-cut, while handling event

+
+


+

cbPaneDrawPlugin::DrawDraggedHandle

void DrawDraggedHandle( const wxPoint& pos, cbDockPane& pane )

helpers

+
+


+

cbPaneDrawPlugin::OnLButtonDown

void OnLButtonDown( cbLeftDownEvent& event )

handlers for plugin-events

+
+


+

cbGCUpdatesMgr

+ 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 impelmentation tries to find out dependencies between bars, and to order them ito "hierarchy", this hierarchical sorting resembles impelmenation of heap-garbage collectors, which resolve dependencies between referencs. 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 refereshing 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-depenencies (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 sepcal cases of "overlapping anomalies" +

+

+Derived from +

+ +

+Public members

+

+Operations +

+ +

+Attributes +

    +
+ +

+Protected members

+

+Operations +

    +
  • cbGCUpdatesMgr::DoRepositionItems +
  • cbGCUpdatesMgr::AddItem +
+ +

+Attributes +

    +
  • cbGCUpdatesMgr::mGC +
+ +

+Private members

+

+Operations +

    +
+ +

+Attributes +

    +
+ + +


+

cbGCUpdatesMgr::OnStartChanges

void OnStartChanges( )

notificiactions received from Frame Layout :

+
+


+

cbGCUpdatesMgr::UpdateNow

void UpdateNow( )

refreshes parts of the frame layout, which need an update

+
+


+

Enumerations Reference

+ + +


+

CB_HITTEST_RESULT

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
+}

enumeration of hittest results, see cbDockPane::HitTestPaneItems(..)

+
+


+

Type Definitions Reference

    +
  • wxToolLayoutItemPtrT +
  • wxDynToolInfoPtrT +
  • cbMinitButtonPtrT +
  • MyTestPanel +
  • wxObjectSerializationFn +
  • wxObjectInitializationFn +
  • wndCreationFn +
  • BarInfoPtrT +
  • RowInfoPtrT +
  • wxEvtHandler::*cbLeftDownHandler +
  • wxEvtHandler::*cbLeftUpHandler +
  • wxEvtHandler::*cbRightDownHandler +
  • wxEvtHandler::*cbRightUpHandler +
  • wxEvtHandler::*cbMotionHandler +
  • wxEvtHandler::*cbLeftDClickHandler +
  • wxEvtHandler::*cbLayoutRowHandler +
  • wxEvtHandler::*cbResizeRowHandler +
  • wxEvtHandler::*cbLayoutRowsHandler +
  • wxEvtHandler::*cbInsertBarHandler +
  • wxEvtHandler::*cbResizeBarHandler +
  • wxEvtHandler::*cbRemoveBarHandler +
  • wxEvtHandler::*cbSizeBarWndHandler +
  • wxEvtHandler::*cbDrawBarDecorHandler +
  • wxEvtHandler::*cbDrawRowDecorHandler +
  • wxEvtHandler::*cbDrawPaneDecorHandler +
  • wxEvtHandler::*cbDrawBarHandlesHandler +
  • wxEvtHandler::*cbDrawRowHandlesHandler +
  • wxEvtHandler::*cbDrawRowBkGroundHandler +
  • wxEvtHandler::*cbDrawPaneBkGroundHandler +
  • wxEvtHandler::*cbStartBarDraggingHandler +
  • wxEvtHandler::*cbDrawHintRectHandler +
  • wxEvtHandler::*cbStartDrawInAreaHandler +
  • wxEvtHandler::*cbFinishDrawInAreaHandler +
  • wxEvtHandler::*cbCustomizeBarHandler +
  • wxEvtHandler::*cbCustomizeLayoutHandler +

+ + +


+

MyTestPanel

wxPanel
wxPanel MyTestPanel

FOR NOW::

+
+


+

wxObjectSerializationFn

void (*wxObjectSerializationFn) (wxObject*, wxObjectStorage& )
void (*wxObjectSerializationFn) (wxObject*, wxObjectStorage& ) wxObjectSerializationFn

abstract classes declared

classes which implement the above interfaces

prototypes for serialzatoin/initialization functions

+
+


+

wndCreationFn

(*wndCreationFn)(wxWindow*, wxWindow*, const wxWindowID, 
+							 const wxPoint&, const wxSize&, long, const wxString&  )
(*wndCreationFn)(wxWindow*, wxWindow*, const wxWindowID, + const wxPoint&, const wxSize&, long, const wxString& ) wndCreationFn

helpers, to ease the creation of serializers for derivatives of wxWindow

+
+


+

BarInfoPtrT

cbBarInfo*
cbBarInfo* BarInfoPtrT

forward declarations

+
+


+

wxEvtHandler::*cbLeftDownHandler

void (wxEvtHandler::*cbLeftDownHandler        )(cbLeftDownEvent&)
void (wxEvtHandler::*cbLeftDownHandler )(cbLeftDownEvent&) wxEvtHandler::*cbLeftDownHandler

forward decls, separated by categories

defs. for handler-methods

+
+


+

Macros Reference

    +
  • LO_HORIZONTAL +
  • LO_VERTICAL +
  • LO_FIT_TO_WINDOW +
  • BTN_BOX_HEIGHT +
  • BTN_BOX_WIDTH +
  • BTN_X_WIEGHT +
  • NEW_TEST_SAVE +
  • NEW_TEST_LOAD +
  • NEW_TEST_EXIT +
  • WXCONTROLAREA_VERSION +
  • wxTITLE_IMG_AND_TEXT +
  • wxTITLE_IMG_ONLY +
  • wxTITLE_BORDER_ONLY +
  • MINIMAL_QUIT +
  • MINIMAL_ABOUT +
  • ID_LOAD +
  • ID_STORE +
  • ID_AUTOSAVE +
  • ID_SETTINGS +
  • ID_REMOVE +
  • ID_REMOVEALL +
  • ID_RECREATE +
  • ID_ACTIVATE +
  • ID_FIRST +
  • ID_SECOND +
  • ID_THIRD +
  • ID_SAY_ITSOK +
  • ID_BTN_YES +
  • ID_BTN_NO +
  • ID_BTN_ESC +
  • MAX_LAYOUTS +
  • FIRST_LAYOUT +
  • SECOND_LAYOUT +
  • THIRD_LAYOUT +
  • NO_CLASS_VER +
  • NO_CLASS_INIT +
  • DECLARE_SERIALIZER_CLASS +
  • IMPLEMENT_SERIALIZER_CLASS +
  • IMPLEMENT_SERIALIZER_FUNCTIONS +
  • IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION +
  • IMPLEMENT_SERIALIZER_FUNCTIONS_FOR_VERSION +
  • WXCONTROLBAR_VERSION +
  • wxCBAR_DOCKED_HORIZONTALLY +
  • wxCBAR_DOCKED_VERTICALLY +
  • wxCBAR_FLOATING +
  • wxCBAR_HIDDEN +
  • MAX_BAR_STATES +
  • wxTOP +
  • wxBOTTOM +
  • wxLEFT +
  • wxRIGHT +
  • MAX_PANES +
  • wxTOP_PANE +
  • wxBOTTOM_PANE +
  • wxLEFT_PANE +
  • wxRIGHT_PANE +
  • wxALL_PANES +
  • cbEVT_PL_LEFT_DOWN +
  • cbEVT_PL_LEFT_UP +
  • cbEVT_PL_RIGHT_DOWN +
  • cbEVT_PL_RIGHT_UP +
  • cbEVT_PL_MOTION +
  • cbEVT_PL_LEFT_DCLICK +
  • cbEVT_PL_LAYOUT_ROW +
  • cbEVT_PL_RESIZE_ROW +
  • cbEVT_PL_LAYOUT_ROWS +
  • cbEVT_PL_INSERT_BAR +
  • cbEVT_PL_RESIZE_BAR +
  • cbEVT_PL_REMOVE_BAR +
  • cbEVT_PL_SIZE_BAR_WND +
  • cbEVT_PL_DRAW_BAR_DECOR +
  • cbEVT_PL_DRAW_ROW_DECOR +
  • cbEVT_PL_DRAW_PANE_DECOR +
  • cbEVT_PL_DRAW_BAR_HANDLES +
  • cbEVT_PL_DRAW_ROW_HANDLES +
  • cbEVT_PL_DRAW_ROW_BKGROUND +
  • cbEVT_PL_DRAW_PANE_BKGROUND +
  • cbEVT_PL_START_BAR_DRAGGING +
  • cbEVT_PL_DRAW_HINT_RECT +
  • cbEVT_PL_START_DRAW_IN_AREA +
  • cbEVT_PL_FINISH_DRAW_IN_AREA +
  • cbEVT_PL_CUSTOMIZE_BAR +
  • cbEVT_PL_CUSTOMIZE_LAYOUT +
  • wxCUSTOM_CB_PLUGIN_EVENTS_START_AT +
  • EVT_PL_LEFT_DOWN +
  • EVT_PL_LEFT_UP +
  • EVT_PL_RIGHT_DOWN +
  • EVT_PL_RIGHT_UP +
  • EVT_PL_MOTION +
  • EVT_PL_LEFT_DCLICK +
  • EVT_PL_LAYOUT_ROW +
  • EVT_PL_RESIZE_ROW +
  • EVT_PL_LAYOUT_ROWS +
  • EVT_PL_INSERT_BAR +
  • EVT_PL_RESIZE_BAR +
  • EVT_PL_REMOVE_BAR +
  • EVT_PL_SIZE_BAR_WND +
  • EVT_PL_DRAW_BAR_DECOR +
  • EVT_PL_DRAW_ROW_DECOR +
  • EVT_PL_DRAW_PANE_DECOR +
  • EVT_PL_DRAW_BAR_HANDLES +
  • EVT_PL_DRAW_ROW_HANDLES +
  • EVT_PL_DRAW_ROW_BKGROUND +
  • EVT_PL_DRAW_PANE_BKGROUND +
  • EVT_PL_START_BAR_DRAGGING +
  • EVT_PL_DRAW_HINT_RECT +
  • EVT_PL_START_DRAW_IN_AREA +
  • EVT_PL_FINISH_DRAW_IN_AREA +
  • EVT_PL_CUSTOMIZE_BAR +
  • EVT_PL_CUSTOMIZE_LAYOUT +
  • NB_ALIGN_TEXT_RIGHT +
  • NB_ALIGN_TEXT_BOTTOM +
  • NB_NO_TEXT +
  • NB_NO_IMAGE +

+ + +


+

LO_HORIZONTAL

#define LO_HORIZONTAL    0

layouting orientations for tools

+
+


+

BTN_BOX_HEIGHT

#define BTN_BOX_HEIGHT       12

fixed settings

+
+


+

wxTITLE_IMG_AND_TEXT

#define wxTITLE_IMG_AND_TEXT 0

layout types for title bars of the tabs (are selected up by evaluating the available free space )

forward decl.

+
+


+

MINIMAL_QUIT

#define MINIMAL_QUIT 	1

ID for the menu commands

+
+


+

DECLARE_SERIALIZER_CLASS

#define DECLARE_SERIALIZER_CLASS(serializerName) \
+ public:\
+  static wxSerializerInfo info;;

macros for declaring and implementing serializers both as classes and as a pair of (serialize/init) functions

+
+


+

IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION

#define IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION( name, serializerName, serFn, initFn, versionName) \
+	wxSerializerInfo 													             \
+		serializerName::info( #name, serFn, initFn, #versionName );

for serializers, which are dedicated for specific versions of persistant classes (further referred as "versioned" serializers)

+
+


+

wxCBAR_DOCKED_HORIZONTALLY

#define wxCBAR_DOCKED_HORIZONTALLY 0

control bar states

+
+


+

MAX_BAR_STATES

#define MAX_BAR_STATES             4

the states are enumerated above

+
+


+

MAX_PANES

#define MAX_PANES      4

one pane for each alignment

+
+


+

wxTOP_PANE

#define wxTOP_PANE 	   0x0001

masks for each pane

+
+


+

cbEVT_PL_LEFT_DOWN

#define cbEVT_PL_LEFT_DOWN           0

event types handled by plugins

+
+


+

EVT_PL_LEFT_DOWN

#define EVT_PL_LEFT_DOWN(func)		     { cbEVT_PL_LEFT_DOWN,		     -1, -1, (wxObjectEventFunction) (wxEventFunction) (cbLeftDownHandler        ) & func },

macros for creating event table entries for plugin-events

+
+


+

NB_ALIGN_TEXT_RIGHT

#define NB_ALIGN_TEXT_RIGHT  0

button lable-text alignment types

+
+


+

Global Variables Reference

    +

+ + +


+

Global Functions Reference

+ + +


+

wxCreateClassInfoTree

void wxCreateClassInfoTree( wxTreeCtrl* pTree, long parentBranchId = 0, long classImageNo = -1 )

creates tree with hierarchically cauptured information about wxWindows dynamic classes (at "current run-time")

existing tree control

+
+


+

wxCreateSerializerInfoTree

void wxCreateSerializerInfoTree( wxTreeCtrl* pTree, long parentBranchId = 0, long classImageNo = -1 )

creates tree with information about serializer-classes (at current run-time) NOTE:: "objstore.cpp" should be compiled in

existing tree control

+
+


+

test_obj_storage

void test_obj_storage( )

cast

---------------------------

Main testing function

---------------------------

include this header and .cpp file into any of your wxWindows projects, and invoke the below function to peform tests

+
+


+

Constants Reference

    +

+ diff --git a/utils/framelayout/src/newbmpbtn.cpp b/utils/framelayout/src/newbmpbtn.cpp new file mode 100644 index 0000000000..6ca0afb099 --- /dev/null +++ b/utils/framelayout/src/newbmpbtn.cpp @@ -0,0 +1,759 @@ +///////////////////////////////////////////////////////////////////////////// +// 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.cpp" +#pragma interface "newbmpbtn.cpp" +#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 "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 bgCol = GET_ELEM(src,0,0); + + int x = 0; + int y = 1; + + do + { + int cur = GET_ELEM(src,x,y); + + int r = GET_RED(cur); + int g = GET_GREEN(cur); + int b = GET_BLUE(cur); + + 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 greay_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 ( wxColour(128,128,128),1, wxSOLID ); + wxPen lightPen( wxColour(255,255,255),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 ); + + int r = col.Red(), + g = col.Green(), + b = col.Blue(); + + int o = MAKE_INT_COLOR( r,g,b ); + + 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) + : mpDepressedImg( NULL ), + mpPressedImg ( NULL ), + mpDisabledImg ( NULL ), + mpFocusedImg ( NULL ), + + mMarginX( marginX ), + mMarginY( marginY ), + mTextAlignment( alignText ), + mIsFlat( isFlat ), + + mIsPressed ( FALSE ), + mDragStarted ( FALSE ), + mPrevPressedState( FALSE ), + mTextToLabelGap ( textToLabelGap ), + + mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ), + mDarkPen ( wxColour(128,128,128), 1, wxSOLID ), + mGrayPen ( wxColour(192,192,192), + 1, wxSOLID ), + mLightPen( wxColour(255,255,255), 1, wxSOLID ), + + mFiredEventType( firedEventType ), + mIsSticky( isSticky ), + mIsCreated( FALSE ), + mSizeIsSet( FALSE ), + + mHasFocusedBmp( FALSE ), + mIsInFocus( FALSE ), + + mDepressedBmp( labelBitmap ), + mLabelText( labelText ), + mImageFileType( -1 ) +{ +} + +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) + + : mpDepressedImg( NULL ), + mpPressedImg ( NULL ), + mpDisabledImg ( NULL ), + mpFocusedImg ( NULL ), + + mMarginX( 2 ), + mMarginY( 2 ), + mTextAlignment( alignText ), + mIsFlat( isFlat ), + + mIsPressed ( FALSE ), + mDragStarted ( FALSE ), + mPrevPressedState( FALSE ), + mTextToLabelGap ( 2 ), + + mBlackPen( wxColour( 0, 0, 0), 1, wxSOLID ), + mDarkPen ( wxColour(128,128,128), 1, wxSOLID ), + mGrayPen ( wxColour(192,192,192), + 1, wxSOLID ), + mLightPen( wxColour(255,255,255), 1, wxSOLID ), + + mFiredEventType( wxEVT_COMMAND_MENU_SELECTED ), + mIsSticky( FALSE ), + mIsCreated( FALSE ), + mSizeIsSet( FALSE ), + + mHasFocusedBmp( FALSE ), + mIsInFocus( FALSE ), + + mLabelText( labelText ), + mImageFileName( bitmapFileName ), + mImageFileType( bitmapFileType ) +{ + //mDepressedBmp.LoadFile( bitmapFileName, bitmapFileType ); +} + +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; +} + +void wxNewBitmapButton::RenderLabelImage( wxBitmap*& destBmp, wxBitmap* srcBmp, + bool isEnabled, bool isPressed ) +{ + if ( destBmp != 0 ) return; + + // render lables on-demand + + wxMemoryDC srcDc; + srcDc.SelectObject( *srcBmp ); + wxFont fnt( 9, wxDECORATIVE , wxNORMAL, wxNORMAL ); + + 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( fnt ); + 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 wxASSERT(0);// 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 ); + + // FOR NOW:: hard-coded label background + wxBrush grayBrush( wxColour(192,192,192), 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 ); + } + + if ( hasText ) + { + wxWindow* pTopWnd = this; + + do + { + wxWindow* pParent = pTopWnd->GetParent(); + + if ( pParent == 0 ) break; + + pTopWnd = pParent; + } while(1); + + destDc.SetFont( fnt ); + + // FOR NOW:: hard-coded text colors + destDc.SetTextForeground( wxColour( 0, 0, 0) ); + destDc.SetTextBackground( wxColour(192,192,192) ); + + destDc.DrawText( mLabelText, txtPos.x, txtPos.y ); + } + + if ( !isEnabled ) + + greay_out_image_on_dc( destDc, destDim.x, destDim.y ); + + // 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::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(); +} + +void wxNewBitmapButton::SetAlignments( int alignText, + int marginX, + int marginY, + int textToLabelGap) +{ + DestroyLabels(); + + mMarginX = marginX; + mMarginY = marginY; + mTextAlignment = alignText; + mTextToLabelGap = textToLabelGap; + + RenderLabelImages(); +} + +// 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 ) +{ + 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 ) + + Refresh(); + + mPrevPressedState = mIsPressed; + } + + // FOR NOW:: + 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(); + + 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/utils/framelayout/src/newbmpbtn.h b/utils/framelayout/src/newbmpbtn.h new file mode 100644 index 0000000000..df25a45752 --- /dev/null +++ b/utils/framelayout/src/newbmpbtn.h @@ -0,0 +1,158 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#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; + + wxString mLabelText; + wxString mImageFileName; + int mImageFileType; + bool mIsFlat; + + 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 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(); + + // 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 diff --git a/utils/framelayout/src/objstore.cpp b/utils/framelayout/src/objstore.cpp new file mode 100644 index 0000000000..1cd0779558 --- /dev/null +++ b/utils/framelayout/src/objstore.cpp @@ -0,0 +1,1809 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 26/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "objstore.h" +// #pragma interface +#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 "objstore.h" +#include + +// FIXME:: +// BUG?:: somehow assertion statements with oritinal wxASSERT do not get compiled in + +//#undef wxASSERT +//#define wxASSERT(x) if ( !(x) ) throw; + +/***** Implementation for class wxSerializerInfo *****/ + +bool wxSerializerInfo::alreadyInitialized = FALSE; +wxSerializerInfo *wxSerializerInfo::first = NULL; +wxHashTable wxSerializerInfo::serInfoHash; + +wxSerializerInfo::wxSerializerInfo( char* theClassName, + wxObjectSerializationFn serializationFun, + wxObjectInitializationFn initializationFun, + char* classVersionName + ) + : classInfo ( NULL ), + next ( NULL ), + nextByVersion( NULL ), + className ( theClassName ), + serFn ( serializationFun ), + initFn ( initializationFun ), + classVersion ( classVersionName ) +{ + next = first; + + first = this; +} + +int serializer_ver_cmp_fun( const void* arg1, const void* arg2 ) +{ + // "no-version" is considered being the highest version + + if ( ((wxSerializerInfo*)arg1)->classVersion == NO_CLASS_VER ) + { + // DBG:: two serializers for the same version of the class should not be present! + wxASSERT( ((wxSerializerInfo*)arg1)->classVersion != NO_CLASS_VER ); + + return -1; // (inverted already) + } + + if ( ((wxSerializerInfo*)arg2)->classVersion == NO_CLASS_VER ) + { + // DBG:: two serializers for the same version of the class should not be present! + wxASSERT( ((wxSerializerInfo*)arg1)->classVersion != NO_CLASS_VER ); + + return 1; // (inverted already) + } + + // versions are compared lexicographically ignoring the char-case + + wxString v1( ((wxSerializerInfo*)arg1)->classVersion ); + wxString v2( ((wxSerializerInfo*)arg2)->classVersion ); + + bool result = v1.CompareTo( v2, wxString::ignoreCase ); + + // DBG:: two serializers for the same version of the class should not be present! + wxASSERT( result == FALSE ); + + // invert the sense of "greater than" for storting in decreasing order + + return ( result > 0 ) ? -1 : 1; +} + +void wxSerializerInfo::InitializeSerializers(void) +{ + if ( alreadyInitialized ) return; + + alreadyInitialized = TRUE; + + wxSerializerInfo* pCur = first; + + // first resolve references to class information structures + + while( pCur ) + { + pCur->classInfo = wxClassInfo::FindClass( pCur->className ); + + wxASSERT( pCur->classInfo ); // DBG:: class info should already be present somewhere! + + // check if serializer for the class is already present, + + wxSerializerInfo* pFound = (wxSerializerInfo*)serInfoHash.Get( (long)pCur->classInfo ); + + if ( pFound ) + { + // if present, then it must be serializer for the certain version of that class, + // put it at the end of the chain of versioned serializers for that class + + // go to the end of chain + + while( pFound->nextByVersion ) pFound = pFound->nextByVersion; + + // append it + + pFound->nextByVersion = pCur; + + pCur->next = (wxSerializerInfo*)(-1); // label it as member of local chain + // of "versioned" serializers + + pCur->nextByVersion = NULL; + } + else + { + // otherwise, serializer for the class found for the first time - + // hash it + + serInfoHash.Put( (long)pCur->classInfo, (wxObject*)pCur ); + + // and include it to the list of serializers for the highest-versions + pCur = pCur->next; + } + } + + // sort chains of "versioned" serializers in the order of decreasing version + // + // (since, when loading, the newest version of an object + // is expected first, rather then the older one) + + wxSerializerInfo* pPrev = NULL; + pCur = first; + + while ( pCur ) + { + // chain present? + + if ( pCur->nextByVersion ) + { + // sort it + + wxSerializerInfo* pStart = pCur; + wxSerializerInfo* pNext = pCur->next; + + // let wxList do the sorting, we're too lazy :) + + wxList sorted; + + while( pCur ) + { + sorted.Append( (wxObject*) pCur ); + + pCur = pCur->nextByVersion; + } + + sorted.Sort( serializer_ver_cmp_fun ); + + wxNode* pNode = sorted.First(); + + while( pNode ) + { + wxSerializerInfo* pInfo = (wxSerializerInfo*)pNode->Data(); + + if ( pNode == sorted.First() ) + { + // make node with the highest version, a member of the global + // list of serializers + + if ( pPrev ) pPrev->next = pInfo; + else first = pInfo; + + pInfo->next = pNext; + } + else + pInfo->next = (wxSerializerInfo*)(-1); // otherwise label it as a member of local + // chain of "versioned" serializers + + if ( pNode->Next() ) + { + pInfo->nextByVersion = (wxSerializerInfo*)( pNode->Next()->Data() ); + } + else + pInfo->nextByVersion = 0; + + pNode = pNode->Next(); + } + + } // end of if ( nextByVersion ) + + pPrev = pCur; + pCur = pCur->next; + + } // end of while(...) +} + +wxSerializerInfo* wxSerializerInfo::FindSerializer( char* className ) +{ + wxSerializerInfo::InitializeSerializers(); + + wxSerializerInfo* pInfo = (wxSerializerInfo*) + + serInfoHash.Get( (long)wxClassInfo::FindClass( className ) ); + + return pInfo; +} + +static void invoke_for_inherited( wxObject* pObj, wxClassInfo* pCInfo, wxObjectStorage* pStore, bool invokeSerFn ) +{ + wxSerializerInfo* pSrzInfo = (wxSerializerInfo*) + + wxSerializerInfo::serInfoHash.Get( (long)wxClassInfo::FindClass( pCInfo->GetClassName() ) ); + + if ( pSrzInfo ) + { + // if found, serialize/initialize and don't go "any higher" + + if ( invokeSerFn ) + + (*pSrzInfo->serFn) ( pObj, *pStore ); + else + (*pSrzInfo->initFn)( pObj ); + + } + else + { + // go up the hierarchy, if no serializer present for the current class + + if ( pCInfo->GetBaseClass1() ) + + invoke_for_inherited( pObj, pCInfo->GetBaseClass1(), pStore, invokeSerFn ); + + if ( pCInfo->GetBaseClass2() ) + + invoke_for_inherited( pObj, pCInfo->GetBaseClass2(), pStore, invokeSerFn ); + } +} + +void wxSerializerInfo::SerializeInherited( wxObject* pObj, wxObjectStorage& store ) +{ + // search recursivelly up the hierarchy for serializers of base + // classes, and invoke serialization function for the given object + + if ( classInfo->GetBaseClass1() ) + + invoke_for_inherited( pObj, classInfo->GetBaseClass1(), &store, TRUE ); + + if ( classInfo->GetBaseClass2() ) + + invoke_for_inherited( pObj, classInfo->GetBaseClass2(), &store, TRUE ); +} + +void wxSerializerInfo::InitializeInherited( wxObject* pObj ) +{ + // search recursivelly up the hierarchy for serializers of base + // classes, and invoke initialization function for the given object + + if ( classInfo->GetBaseClass1() ) + + invoke_for_inherited( pObj, classInfo->GetBaseClass1(), NULL, FALSE ); + + if ( classInfo->GetBaseClass2() ) + + invoke_for_inherited( pObj, classInfo->GetBaseClass2(), NULL, FALSE ); +} + +/***** Implementation for class wxDataStreamBase *****/ + +IMPLEMENT_ABSTRACT_CLASS( wxDataStreamBase, wxObject ) + +/***** Implementation for class wxObjectStorage *****/ + +// codes, used as tokens written/read from the stream + +enum STORED_OBJ_TYPES +{ + SOT_NULL_POINTER = 'N', + SOT_POINTER_TO_OBJ = 'P', + SOT_INITIAL_REF = 'I', + SOT_OBJ_DATA = 'D' +}; + +// veraion-encoding in object-name string fromat defaults: + +char wxObjectStorage::mVerSepartorCh = '#'; +char wxObjectStorage::mMinorMajorSepartorCh = '-'; + +IMPLEMENT_DYNAMIC_CLASS( wxObjectStorage, wxObject ) + +wxObjectStorage::wxObjectStorage() + : mpStm ( 0 ), + mIsLoading ( TRUE ), + mInitialRefsCnt ( 0 ), + mFinalizePending( FALSE ) +{} + +wxObjectStorage::wxObjectStorage( wxDataStreamBase& stm ) + : mpStm ( &stm ), + mIsLoading ( stm.IsForInput() ), + mInitialRefsCnt ( 0 ), + mFinalizePending( FALSE ) +{ + wxSerializerInfo::InitializeSerializers(); + + mFinalizePending = TRUE; // stream object was given - store/load is + // started +} + +wxObjectStorage::~wxObjectStorage() +{ + if ( mFinalizePending ) + + Finalize(); // <- do it now, if "user" forgot about it +} + +/*** protected members ***/ + +void wxObjectStorage::ClearHashesAndLists() +{ + mNewObjs.Clear(); + mSerializersForNewObjs.Clear(); + mRefHash.Clear(); +} + +/*** public members ***/ + +void wxObjectStorage::SetDataStream( wxDataStreamBase& stm ) +{ + if ( mFinalizePending ) + + Finalize(); + + wxSerializerInfo::InitializeSerializers(); + + ClearHashesAndLists(); + + mpStm = &stm; + + mIsLoading = stm.IsForInput(); + + mFinalizePending = TRUE; +} + +void wxObjectStorage::Finalize() +{ + wxASSERT( mpStm ); // DBG:: finalize should called be after loading/storing has proceeded + + mFinalizePending = FALSE; + + if ( mIsLoading ) + { + // initializaiton is performed after all objects successfully + // loaded, and references among them are established + + wxNode* pObjNode = mNewObjs.First(); + wxNode* pSrzNode = mSerializersForNewObjs.First(); + + while( pObjNode ) + { + wxSerializerInfo* pSrzInfo = (wxSerializerInfo*)(pSrzNode->Data()); + + if ( pSrzInfo->HasInitializer() ) + + (*pSrzInfo->initFn)( pObjNode->Data() ); + + pObjNode = pObjNode->Next(); + pSrzNode = pSrzNode->Next(); + } + } + else + // otherwise, nothing's need to be done after storing of objects is proceeded + mpStm->Flush(); +} + +// storage methods for basic types + +void wxObjectStorage::XchgChar( char& chObj ) +{ + if ( mIsLoading ) mpStm->LoadChar( &chObj ); + else mpStm->StoreChar( chObj ); +} + +void wxObjectStorage::XchgInt( int& intObj ) +{ + if ( mIsLoading ) mpStm->LoadInt( &intObj ); + else mpStm->StoreInt( intObj ); +} + +void wxObjectStorage::XchgSizeType( size_t& szObj ) +{ + int i = int(szObj); + + if ( mIsLoading ) + { + mpStm->LoadInt( &i ); + szObj = (size_t)i; + } + else + mpStm->StoreInt( i ); +} + +void wxObjectStorage::XchgLong( long& longObj ) +{ + if ( mIsLoading ) mpStm->LoadLong( &longObj ); + else mpStm->StoreLong( longObj ); +} + +void wxObjectStorage::XchgBool( bool& boolObj ) +{ + // bools are stored as ints + + if ( mIsLoading ) + { + int bVal = (int)boolObj; + mpStm->LoadInt( &bVal ); + boolObj = bVal; + } + else + mpStm->StoreInt( (int)boolObj ); +} + +void wxObjectStorage::XchgUInt ( unsigned int& uI ) +{ + if ( mIsLoading ) + { + int uiVal = (int)uI; + mpStm->LoadInt( &uiVal ); + uI = (unsigned int)uiVal; + } + else + mpStm->StoreInt( (int)uI ); +} + +void wxObjectStorage::XchgObjList( wxList& objList ) +{ + int count = 0; + + if ( mIsLoading ) + { + XchgInt( count ); + + if ( count == 0 ) return; + + objList.Clear(); + } + else + { + count = objList.GetCount(); + + XchgInt( count ); + } + + // work-around for assessing operator[] which is protected in wxArrayBase + + if ( mIsLoading ) + + for( int i = 0; i != count; ++i ) + { + wxObject* pObj = NULL; + + XchgObjPtr( &pObj ); + + objList.Append( pObj ); + } + else + { + wxNode* pNode = objList.First(); + + while( pNode ) + { + wxObject* pObj = pNode->Data(); + + XchgObjPtr( &pObj ); + + pNode = pNode->Next(); + } + } +} + +void wxObjectStorage::XchgObjArray ( wxBaseArray& objArr ) +{ + int count = 0; + + if ( mIsLoading ) + { + XchgInt( count ); + + if ( count == 0 ) return; + + objArr.Clear(); + objArr.Alloc( count ); + } + else + { + count = objArr.GetCount(); + + XchgInt( count ); + } + + // work-around for assessing operator[] which is protected in wxArrayBase + + wxArrayLong& longArr = *( (wxArrayLong*) (&objArr) ); + + if ( mIsLoading ) + + for( int i = 0; i != count; ++i ) + { + wxObject* pObj = NULL; + + XchgObjPtr( &pObj ); + + longArr.Add( (long) pObj ); + } + else + for( int i = 0; i != count; ++i ) + { + wxObject* pObj = (wxObject*)longArr[i]; + + XchgObjPtr( &pObj ); + } +} + +void wxObjectStorage::XchgLongArray( wxBaseArray& longArr ) +{ + int count = 0; + + if ( mIsLoading ) + { + XchgInt( count ); + + if ( count == 0 ) return; + + longArr.Clear(); + longArr.Alloc( count ); + } + else + { + count = longArr.GetCount(); + + XchgInt( count ); + } + + // work-around for assessing operator[] which is protected in wxArrayBase + + wxArrayLong& realLongArr = *( (wxArrayLong*) (&longArr) ); + + if ( mIsLoading ) + + for( int i = 0; i != count; ++i ) + { + long l = 0; + XchgLong( l ); + + realLongArr.Add( l ); + } + else + for( int i = 0; i != count; ++i ) + + XchgLong( realLongArr[i] ); +} + +void wxObjectStorage::XchgDouble( double& doubleObj ) +{ + if ( mIsLoading ) mpStm->LoadDouble( &doubleObj ); + else mpStm->StoreDouble( doubleObj ); +} + +void wxObjectStorage::XchgCStr( char* pCStrObj ) +{ + if ( mIsLoading ) + { + int len; + mpStm->LoadInt( &len ); + mpStm->LoadBytes( pCStrObj, len ); + } + else + { + int len = strlen( pCStrObj ) + 1; // include terminating zero + mpStm->StoreInt( len ); + mpStm->StoreBytes( pCStrObj, len ); + } +} + +wxSerializerInfo* wxObjectStorage::FindSrzInfoForClass( wxClassInfo* pInfo ) +{ + wxSerializerInfo* pSrz = (wxSerializerInfo*) + + wxSerializerInfo::serInfoHash.Get( (long)pInfo ); + + if ( !pSrz ) + { + // look up recursivelly for serializers for of the base classes + + if ( pInfo->GetBaseClass1() ) + + return FindSrzInfoForClass( pInfo->GetBaseClass1() ); + else + if ( pInfo->GetBaseClass2() ) + + return FindSrzInfoForClass( pInfo->GetBaseClass2() ); + else + { + wxASSERT(0); // DBG:: no serializers present for the given class, + // serialization cannot proceed + return 0; + } + } + else + return pSrz; +} + +bool wxObjectStorage::VersionsMatch( char* v1, char* v2 ) +{ + while( *v1 && *v2 ) + { + if ( *v1 == mMinorMajorSepartorCh || + *v2 == mMinorMajorSepartorCh ) + + // minor versions are ignored + + return TRUE; + + if ( wxToUpper(*v1) != wxToUpper(*v2) ) + + return FALSE; + + ++v1; ++v2; + } + + return ( *v1 == '\0' && *v2 == '\0' ); +} + +bool wxObjectStorage::ExchangeObjectInfo( wxClassInfo** ppCInfo, wxSerializerInfo** ppSrz ) +{ + char objInfoStr[512]; // FOR NOW:: fixed? + + if ( mIsLoading == FALSE ) + { + strcpy( objInfoStr, (*ppCInfo)->GetClassName() ); + + if ( (*ppSrz)->HasVersion() ) + { + char separator[2]; + separator[2] = mVerSepartorCh; + separator[1] = '\0'; + + strcat( objInfoStr, separator ); + + strcat( objInfoStr, (*ppSrz)->classVersion ); + } + + XchgCStr( objInfoStr ); + + return TRUE; + } + + // otherwise if loading... + + XchgCStr( objInfoStr ); // read string + + (*ppCInfo) = NULL; + (*ppSrz) = NULL; + + // formal description of objInfoStr format is following (if '#' and '-' are set + // as version and minor/major separators): + // + // object objInfoStr = { class_name_str , [version] } + // + // version = { '#', simple_version_str | major_and_minor_version_str } + // + // simple_version_str = any_literal + // + // major_and_minro_version_str = { major_version_str, '-', minro_version_str } + // + // major_version_str = any_literal + // + // inor_version_str = any_literal + // + // any_literal = "any string not containing '#' and '-' characters" + // + + char* cur = objInfoStr; + + while( *cur && *cur != mVerSepartorCh ) ++cur; + + char last = *cur; + + if ( last == mVerSepartorCh ) + + *cur = '\0'; + + (*ppCInfo) = wxClassInfo::FindClass( objInfoStr ); + + if ( !(*ppCInfo) ) return FALSE; + + // get the bigining of the chain of serializers for (*ppCInfo) + + wxSerializerInfo* pSrz = FindSrzInfoForClass( (*ppCInfo ) ); + + if ( last == mVerSepartorCh ) *cur = last; // restore from temprary "termination" + + // find serializer which matches the version, or the serializer + // with no version, if version is not attached to the objInfoStr + + if ( *cur == '\0' ) + { + // there's no version trailing, the "not-versioned" + // serializer can be present only at the begining of + // the chain + + if ( pSrz->HasVersion() == FALSE ) + { + (*ppSrz) = pSrz; + + return TRUE; + } + else + return FALSE; + } + + ++cur; // skip className<->version separator + + // version present, search for matching serializer down the chain + + if ( pSrz->HasVersion() == FALSE ) pSrz = pSrz->nextByVersion; + + while( pSrz ) + { + if ( VersionsMatch( pSrz->classVersion, cur ) ) + { + (*ppSrz) = pSrz; + + return TRUE; + } + + pSrz = pSrz->nextByVersion; + } + + return FALSE; // no serializers matching given version found +} + +wxSerializerInfo* wxObjectStorage::GetLatestSrzForObj( wxObject* pWxObj ) +{ + wxClassInfo* pCInfo = pWxObj->GetClassInfo(); + + wxASSERT( pCInfo ); // DBG:: object's class should be dynamic + + // find first serializer for (*pCInfo) in the chain + + wxSerializerInfo* pSrz = FindSrzInfoForClass( pCInfo ); + + wxASSERT( pSrz ); // DBG:: there should be at least one serializer of + // the object's class, at least for it's base classes + + // skip not-versioned serializer at the beginng of the chain if present + + if ( !pSrz->HasVersion() && pSrz->nextByVersion ) + + pSrz = pSrz->nextByVersion; // the reminding ones are "vesioned", + // starting from the highest version + + return pSrz; +} + +void wxObjectStorage::DoExchangeObject( wxObject* pInstance, wxSerializerInfo& srzInfo ) +{ + if ( mIsLoading ) + + // put info about already (partially) loaded object (stream-offset <=> object-ptr ) + + mRefHash.Put( (long)mpStm->GetStreamPos(), (wxObject*)pInstance ); + else + // put info about already (partially) stored object (object-ptr <=> stream-offset) + + mRefHash.Put( (long)(pInstance), (wxObject*)mpStm->GetStreamPos() ); + + if ( mIsLoading ) + { + mNewObjs.Append( pInstance ); + mSerializersForNewObjs.Append( (wxObject*)&srzInfo ); + } + + // now, perform actual serialization of the object + + (srzInfo.serFn)( pInstance, *this ); +} + +// storage methods for objects and object-references + +void wxObjectStorage::XchgObj( wxObject* pWxObj ) +{ + wxClassInfo* pCInfo = pWxObj->GetClassInfo(); + + wxASSERT( pCInfo ); // DBG:: if this fails, the object which is passed to + // XchgObj(..) has not it's class information + // i.e. is not a wxWindows dynamic class + + wxSerializerInfo* pSrz = ( mIsLoading == FALSE ) ? GetLatestSrzForObj( pWxObj ) + : NULL; + + bool success = ExchangeObjectInfo( &pCInfo, &pSrz ); + + wxASSERT( success ); // DBG:: all info about object should be present i.e. class + // info, serializer which matches the object's version + // (see source of ExchangeObjectInfo() for more info) + + DoExchangeObject( pWxObj, *pSrz ); +} + +void wxObjectStorage::XchgObjPtr( wxObject** ppWxObj ) +{ + if ( mIsLoading ) + { + char token; + mpStm->LoadChar( &token ); + + if ( token == (char)SOT_NULL_POINTER ) + + (*ppWxObj) = NULL; + else + if ( token == (char)SOT_POINTER_TO_OBJ ) + { + long ofs; // stream-offset + + mpStm->LoadLong( &ofs ); + + wxObject* pObj = (wxObject*) mRefHash.Get( ofs ); + + wxASSERT( pObj ); // DBG:: object (at the given stream-offset) + // must be already loaded + + (*ppWxObj) = pObj; + } + else + if ( token == (char)SOT_INITIAL_REF ) + { + long refNo; + + mpStm->LoadLong( &refNo ); + + wxASSERT( mInitialRefsCnt >= refNo ); // DBG:: inital refernce should be already added + + // refNo is 1-based + (*ppWxObj) = mInitialRefs.Nth( refNo-1 )->Data(); + } + else + { + wxASSERT( token == (char)SOT_OBJ_DATA );// DBG:: other types of tokens are + // bogous! If this happens you're + // probably trying to load the data + // which was stored by defferent. + // perhaps out-dated serializers + // + // Use versioning mechanizm to + // privide backwards compatiblity + // option, among different versions + // stored data-format + + + int stmPos = mpStm->GetStreamPos(); + + wxClassInfo* pCInfo = 0; + wxSerializerInfo* pSrz = 0; + + bool success = ExchangeObjectInfo( &pCInfo, &pSrz ); + + wxASSERT( success ); // DBG:: all info about object should be present + // i.e. class info, serializer which matches the object's + // version (see source of ExchangeObjectInfo() for more info) + + (*ppWxObj) = pCInfo->CreateObject(); + + DoExchangeObject( (*ppWxObj), *pSrz ); + } + } + else + { + // otherwise if storing the pointer to an object + + // first, check if it's an initial reference + + long refNo = (long)mInitialRefsHash.Get( (long)(*ppWxObj) ); + + if ( refNo != 0 ) + { + mpStm->StoreChar( (char)SOT_INITIAL_REF ); + mpStm->StoreLong( refNo ); + + return; + } + + long streamPos = (long) mRefHash.Get( (long)(*ppWxObj) ); + + // check if object is already stored + if ( streamPos != 0 ) + { + // store only reference to the object (in the form of stream-offset) + + mpStm->StoreChar( (char)SOT_POINTER_TO_OBJ ); + mpStm->StoreLong( streamPos ); + } + else + { + // otherwise store the entire referenced object + + if ( (*ppWxObj) == NULL ) + { + mpStm->StoreChar( (char)SOT_NULL_POINTER ); // token + return; + } + + mpStm->StoreChar( (char)SOT_OBJ_DATA ); // token + + // store object's info and data + XchgObj( *ppWxObj ); + } + } +} + +// storage methods for common wxWindows objects + +void wxObjectStorage::XchgWxStr( wxString& str ) +{ + if ( mIsLoading ) + { + long len = 0; + mpStm->LoadLong( &len ); + + str = ""; + str.Append( (char)1, len ); + + mpStm->LoadBytes( (char*)str.c_str(), len ); + } + else + XchgCStr( (char*)str.c_str() ); +} + +void wxObjectStorage::XchgWxSize( wxSize& size ) +{ + XchgLong( size.x ); + XchgLong( size.y ); +} + +void wxObjectStorage::XchgWxPoint( wxPoint& point ) +{ + XchgLong( point.x ); + XchgLong( point.y ); +} + +void wxObjectStorage::XchgWxRect( wxRect& rect ) +{ + XchgLong( rect.x ); + XchgLong( rect.y ); + XchgLong( rect.width ); + XchgLong( rect.height ); +} + +void wxObjectStorage::AddInitialRef( wxObject* pObjRef ) +{ + // duplicates are not accepted + + if ( mInitialRefsHash.Get( (long)pObjRef ) != NULL ) + + return; + + ++mInitialRefsCnt; + + // NOTE:: reference number is 1-based (zero is "reserved" by wxHashTable) + + mInitialRefs.Append( pObjRef ); + mInitialRefsHash.Put( (long)pObjRef, (wxObject*)mInitialRefsCnt ); +} + +void wxObjectStorage::ClearInitalRefs() +{ + mInitialRefsCnt = 0; + + mInitialRefsHash.Clear(); + mInitialRefsHash.Clear(); +} + +/***** Implementation for class wxColourSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxColour, + wxColourSerializer, + wxColourSerializer::Serialize, + NO_CLASS_INIT ) + +void wxColourSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxColour* pCol = (wxColour*)pObj; + + // slightly optimized + + if ( store.IsLoading() ) + { + long rgb; + store.XchgLong( rgb ); + + *pCol = wxColour( rgb & 0xFF, + ( rgb >> 8 ) & 0xFF, + ( rgb >> 16 ) & 0xFF ); + + } + else + { + long rgb = 0; + + unsigned char r = pCol->Red(),g = pCol->Green(), b = pCol->Blue(); + + rgb = ( long(r) & 0x0000FF ) | + ( ( long(g) << 8 ) & 0x00FF00 ) | + ( ( long(b) << 16 ) & 0xFF0000 ); + + store.XchgLong( rgb ); + } +} + +/***** Implementation for class wxPenSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxPen, + wxPenSerializer, + wxPenSerializer::Serialize, + NO_CLASS_INIT ) + +void wxPenSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxPen* pPen = (wxPen*)pObj; + + int cap; + wxColour col; + int join; + int style; + int width; + + if ( store.IsLoading() == FALSE ) + { + cap = pPen->GetCap(); + col = pPen->GetColour(); + join = pPen->GetJoin(); + style = pPen->GetStyle(); + width = pPen->GetWidth(); + } + + store.XchgInt( cap ); + store.XchgObj( (wxObject*) &col ); + store.XchgInt( join ); + store.XchgInt( style ); + store.XchgInt( width ); + + if ( store.IsLoading() ) + { + pPen->SetCap ( cap ); + pPen->SetColour( col ); + pPen->SetJoin ( join ); + pPen->SetStyle ( style ); + pPen->SetWidth ( width ); + } +} + +/***** Implementation for class wxBrushSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxBrush, + wxBrushSerializer, + wxBrushSerializer::Serialize, + NO_CLASS_INIT ) + +void wxBrushSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxBrush* pBrush = (wxBrush*)pObj; + + wxColour col; + int style; + + if ( store.IsLoading() == FALSE ) + { + col = pBrush->GetColour(); + style = pBrush->GetStyle(); + } + + store.XchgObj( (wxObject*) &col ); + store.XchgInt( style ); + + if ( store.IsLoading() ) + { + pBrush->SetColour( col ); + pBrush->SetStyle ( style ); + } +} + +/***** Implementation for class wxEvtHandlerSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxEvtHandler, + wxEvtHandlerSerializer, + wxEvtHandlerSerializer::Serialize, + wxEvtHandlerSerializer::Initialize ) + +void wxEvtHandlerSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxEvtHandler* pHnd = ( wxEvtHandler*) pObj; + + wxEvtHandler* pPrevHnd; + wxEvtHandler* pNextHnd; + + if ( store.IsLoading() == FALSE ) + { + // extract properties when storing + + pPrevHnd = pHnd->GetPreviousHandler(); + pNextHnd = pHnd->GetNextHandler(); + } + + // serialize properties + + store.XchgObjPtr( (wxObject**) &pPrevHnd ); + store.XchgObjPtr( (wxObject**) &pNextHnd ); + + if ( store.IsLoading() ) + { + // set properties when loading + + pHnd->SetPreviousHandler( pPrevHnd ); + pHnd->SetNextHandler ( pNextHnd ); + } +} + +void wxEvtHandlerSerializer::Initialize( wxObject* pObj ) +{ + wxEvtHandler* pHnd = ( wxEvtHandler*) pObj; + + // if we're on top + if ( pHnd->GetPreviousHandler() == NULL ) + { + // then check if we're in the chain which is + // attached to wxWindow object + + wxEvtHandler* pCur = pHnd->GetNextHandler(); + + while( pCur ) + { + if ( pCur->IsKindOf( CLASSINFO(wxWindow) ) ) + { + // since we are the the right-most event handler + // in the chain, then we must be the first + // receiver of events sent to the window obj. - + // therefore "make it happen": + + ((wxWindow*)pCur)->SetEventHandler( pHnd ); + + // but if wxWindow is persistant, then why + // we're setting "manually" the property + // which is serialized anyway? + // + // The *PROBLEM* is that, it's not always good idea + // to serialize a window (e.g. main frame), instead + // they could be referred by "inital-refernces". To + // handle the later case, we additionally make sure + // that serialized evt. handlers are "glued" to the + // window correctly,even if the window is transient + // itself + + return; + } + + // keep on searching for wxWindows down the chain + + pCur = pCur->GetNextHandler(); + } + } +} + +/***** Implementation for class wxWindowSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxWindow, + wxWindowSerializer, + wxWindowSerializer::Serialize, + NO_CLASS_INIT ) + +void wxWindowSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + DoSerialize( pObj, store, (wndCreationFn)wxWindowSerializer::CreateWindowFn ); +} + +void wxWindowSerializer::DoSerialize( wxObject* pObj, wxObjectStorage& store, + wndCreationFn creationFn, bool refreshNow ) +{ + // wxWindow is a kind of wxEvtHandler - peform serialization of + // the base class first + + info.SerializeInherited( pObj, store ); + + wxWindow* pWnd = (wxWindow*)pObj; + + long id; + long style; + wxString name; + wxPoint pos; + wxSize size; + wxColour bkCol; + wxWindow* pParent; + wxList* pCldLst; + wxEvtHandler* pEvtHandler; + + wxList tmpCldLst; + + if ( store.IsLoading() == FALSE ) + { + // extract properties from window object + + name = pWnd->GetName(); + id = pWnd->GetId(); + style = pWnd->GetWindowStyleFlag(); + + // workaround for long/int inconsitency of wxWin2.0a + int x,y,w,h; + pWnd->GetPosition( &x, &y ); + pWnd->GetSize ( &w, &h ); + bkCol = pWnd->GetBackgroundColour(); + + pos.x = x; pos.y = y; + size.x = w; size.y = h; + + pEvtHandler = pWnd->GetEventHandler(); + pParent = pWnd->GetParent(); + +#ifdef __HACK_MY_MSDEV40__ + pCldLst = pWnd->GetChildren(); +#else + pCldLst = &pWnd->GetChildren(); +#endif + + } + + // serialize properties + + store.XchgWxStr ( name ); + store.XchgLong ( id ); + store.XchgLong ( style ); + store.XchgLong ( pos.x ); + store.XchgLong ( pos.y ); + store.XchgLong ( size.x ); + store.XchgLong ( size.y ); + store.XchgObj ( (wxObject* ) &bkCol ); + store.XchgObjPtr( (wxObject**) &pParent ); + store.XchgObjPtr( (wxObject**) &pEvtHandler ); + + if ( store.IsLoading() ) + { + + // serialize to on-stack list object, since children will + // automatically add themselves to parent's list + + pCldLst = &tmpCldLst; + + // first create window (when loading), then serialize it's children + + (*creationFn)( pWnd, pParent, id, pos, size, style, name ); + + //pWnd->SetBackgroundColour( bkCol ); + + //pWnd->SetBackgroundColour( bkCol ); + + if ( refreshNow && 0 ) pWnd->Refresh(); + } + + store.XchgObjList( *pCldLst ); +} + +void wxWindowSerializer::CreateWindowFn( wxWindow* wnd, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + wnd->Create( parent, id, pos, size, style, name ); +} + +/***** Implementation for class wxTextCtrlSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxTextCtrl, + wxTextCtrlSerializer, + wxTextCtrlSerializer::Serialize, + NO_CLASS_INIT ) + +void wxTextCtrlSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxTextCtrl* pCtrl = (wxTextCtrl*)pObj; + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxTextCtrlSerializer::CreateTextCtrlWindowFn ); + + wxString text; + + if ( store.IsLoading() == FALSE ) + + text = pCtrl->GetValue(); + + store.XchgWxStr( text ); + + if ( store.IsLoading() ) + + pCtrl->SetValue( text ); +} + +void wxTextCtrlSerializer::CreateTextCtrlWindowFn( wxTextCtrl* wnd, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + wnd->Create( parent, id, "", pos, size, style ); + + // FIXME:: quick-hack + wnd->SetBackgroundColour( wxColour(255,255,255) ); +} + +/***** Implementation for class wxButtonSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxButton, + wxButtonSerializer, + wxButtonSerializer::Serialize, + NO_CLASS_INIT ) + +void wxButtonSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxButton* pBtn = (wxButton*)pObj; + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxButtonSerializer::CreateButtonWindowFn ); + + wxString label; + + if ( store.IsLoading() == FALSE ) + + label = pBtn->GetLabel(); + + store.XchgWxStr( label ); + + if ( store.IsLoading() ) + + pBtn->SetLabel( label ); +} + +void wxButtonSerializer::CreateButtonWindowFn( wxButton* btn, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + btn->Create( parent, id, "", pos, size, style ); +} + +/***** Implementation for class wxStaticTextSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxStaticText, + wxStaticTextSerializer, + wxStaticTextSerializer::Serialize, + NO_CLASS_INIT ) + +void wxStaticTextSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxStaticText* pSTxt = (wxStaticText*)pObj; + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxStaticTextSerializer::CreateSTextWindowFn ); + + wxString label; + + if ( store.IsLoading() == FALSE ) + + label = pSTxt->GetLabel(); + + store.XchgWxStr( label ); + + if ( store.IsLoading() ) + + pSTxt->SetLabel( label ); +} + +void wxStaticTextSerializer::CreateSTextWindowFn( wxStaticText* pSTxt, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + pSTxt->Create( parent, id, "", pos, size, style ); +} + +/***** Implementation for class wxScrollBarSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxScrollBar, + wxScrollBarSerializer, + wxScrollBarSerializer::Serialize, + NO_CLASS_INIT ) + +void wxScrollBarSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxScrollBarSerializer::CreateScollBarWindowFn ); +} + +void wxScrollBarSerializer::CreateScollBarWindowFn( wxScrollBar* sbar, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + sbar->Create( parent, id, pos, size, style ); +} + +// FIXME:: serialization of tree control causes bunch of assertions on wxGtk + +#if 0 + +/***** Implementation for class wxTreeCtrlSerializer *****/ + +IMPLEMENT_SERIALIZER_CLASS( wxTreeCtrl, + wxTreeCtrlSerializer, + wxTreeCtrlSerializer::Serialize, + NO_CLASS_INIT ) + +static bool get_child_count( wxTreeItemId itemId, wxTreeCtrl* pTree ) +{ + long cookie; + + if ( !pTree->ItemHasChildren( itemId ) ) return 0; + + wxTreeItemId curId = pTree->GetFirstChild( itemId, cookie ); + + int cnt = 0; + + do + { + ++cnt; + + curId = pTree->GetNextChild( itemId, cookie ); + + } while( curId ); + + return cnt; +} + +void wxTreeCtrlSerializer::SerializeBranch( wxTreeItemId parentId, wxTreeCtrl* pTree, + wxObjectStorage& store, wxTreeItemId nextVisId, + int depth ) +{ + wxString text; + int childCnt; + int img; + bool isExpanded; + bool isVisible; + + if ( store.IsLoading() ) + { + store.XchgWxStr( text ); + store.XchgInt ( childCnt ); + store.XchgInt ( img ); + store.XchgBool ( isExpanded ); + store.XchgBool ( isVisible ); + + wxTreeItemId subBranchId = + ( depth == 0 ) + ? pTree->AddRoot( text, img ) + : pTree->AppendItem( parentId, text, img); + + // check if the item was labeled as first-visible + + if ( isVisible ) + + nextVisId = subBranchId; + + while ( childCnt-- ) + + SerializeBranch( subBranchId, pTree, store, nextVisId, depth+1 ); + + if ( isExpanded ) pTree->Expand( subBranchId ); + else pTree->Collapse( subBranchId ); + + } + else + { + // otherwise storing children of the branch + + text = pTree->GetItemText( parentId ); + childCnt = get_child_count( parentId, pTree ); + img = pTree->GetItemImage( parentId ); + isExpanded = pTree->IsExpanded( parentId ); + + if ( parentId == nextVisId ) + + isVisible = TRUE; + else + isVisible = FALSE; + + store.XchgWxStr( text ); + store.XchgInt ( childCnt ); + store.XchgInt ( img ); + store.XchgBool ( isExpanded ); + store.XchgBool ( isVisible ); + + long cookie; + + wxTreeItemId curId = pTree->GetFirstChild( parentId, cookie ); + + while ( childCnt-- ) + { + SerializeBranch( curId, pTree, store, nextVisId, -1 ); + + curId = pTree->GetNextChild( parentId, cookie ); + } + } +} + +void wxTreeCtrlSerializer::Serialize( wxObject* pObj, wxObjectStorage& store ) +{ + // FOR NOW::image id's and image list are not serialized! + // it should be provided as a initial reference (IR) + // if it presents. Currently only normal image list + // for normal items-states is set up + + wxTreeCtrl* pTree = (wxTreeCtrl*)pObj; + + wxWindowSerializer::DoSerialize( pObj, store, + (wndCreationFn)wxTreeCtrlSerializer::CreateTreeCtrlWindowFn ); + + wxTreeItemId nextVisId = (long)0; + int indent = 0; + int childCnt; + wxImageList* pILst; + + if ( store.IsLoading() ) + { + store.XchgInt( indent ); + + store.XchgObjPtr( (wxObject**) &(pILst) ); + + if ( pILst ) + + pTree->SetImageList( pILst ); + + store.XchgInt( childCnt ); + + while ( childCnt-- ) + + SerializeBranch( pTree->GetRootItem() , pTree, store, nextVisId, 0 ); + + // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0 + // pTree->ScrollTo( nextVisId ); + + pTree->SetIndent( indent ); + } + else + { + indent = pTree->GetIndent(); + + // FIXME:: somehow this is no longer inmplemented in latest wxWin-2.0 + // nextVisId = pTree->GetFirstVisibleItem(); + + nextVisId = pTree->GetRootItem(); + + pILst = pTree->GetImageList(); + + store.XchgInt( indent ); + + store.XchgObjPtr( (wxObject**) &(pILst) ); + + // otherwise storing children of the branch + + childCnt = get_child_count( pTree->GetRootItem(), pTree ); + + store.XchgInt( childCnt ); + + long cookie; + wxTreeItemId parent = pTree->GetRootItem(); + wxTreeItemId curId = pTree->GetFirstChild( parent, cookie ); + + while ( childCnt-- ) + { + SerializeBranch( curId, pTree, store, nextVisId, -1 ); + + curId = pTree->GetNextChild( parent, cookie ); + } + } +} + +void wxTreeCtrlSerializer::CreateTreeCtrlWindowFn( wxTreeCtrl* tree, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ) +{ + tree->Create( parent, id, pos, size, style ); +} + +#endif + +/***** Implementation for class wxIOStreamWrapper *****/ + +IMPLEMENT_DYNAMIC_CLASS( wxIOStreamWrapper, wxDataStreamBase ) + +void wxIOStreamWrapper::Close() +{ + // close previous stream if any + if ( mpStm ) + { + mpStm->flush(); + + if ( mOwnsStmObject ) + + delete mpStm; + + mOwnsStmObject = FALSE; + + mpStm = NULL; + } + + mStreamPos = 0; +} + +wxIOStreamWrapper::wxIOStreamWrapper() + : mpStm( NULL ), + mOwnsStmObject( FALSE ), + mStreamPos(0) +{ + mIsForInput = TRUE; // just a defaul +} + +bool wxIOStreamWrapper::Create( const char* fileName, bool forInput ) +{ + Close(); + + // FIXME:: if using default value of the last arg, linking breaks complaining + // about duplicated symbols + +#ifdef __WXMSW__ + mpStm = new fstream( fileName, + ( ( forInput == FALSE ) ? ios::out : ios::in ) | ios::binary, + 0 + ); +#else + mpStm = new fstream( fileName, + ( ( forInput == FALSE ) ? ios::out : ios::in ) | ios::binary + ); +#endif + + //((fstream*)mpStm)->close(); + + //delete ((fstream*)mpStm); + + mOwnsStmObject = TRUE; + + if ( !Good() ) + { + Close(); + return FALSE; + } + + mIsForInput = forInput; + + return TRUE; +} + +wxIOStreamWrapper::wxIOStreamWrapper( iostream& stm, bool forInput ) + : mOwnsStmObject( FALSE ) +{ + mpStm = &stm; + + // FIXME:: what about actual stream postion of attached stream? + mStreamPos = 0; + + mIsForInput = forInput; +} + +void wxIOStreamWrapper::Attach( iostream& stm, bool forInput ) +{ + Close(); + + mOwnsStmObject = FALSE; + + mpStm = &stm; + + // FIXME:: what about actual stream postion of attached stream? + mStreamPos = 0; + + mIsForInput = forInput; +} + +wxIOStreamWrapper::~wxIOStreamWrapper() +{ + Close(); +} + +bool wxIOStreamWrapper::StoreChar( char ch ) +{ + mpStm->write( &ch, sizeof(char) ); + + mStreamPos += sizeof(char); + + return Good(); +} + +bool wxIOStreamWrapper::StoreInt( int i ) +{ + mpStm->write( (char*)&i, sizeof(int) ); + + mStreamPos += sizeof(int); + + return Good(); +} + +bool wxIOStreamWrapper::StoreLong( long l ) +{ + mpStm->write( (char*)&l, sizeof(long) ); + + mStreamPos += sizeof(long); + + return Good(); +} + +bool wxIOStreamWrapper::StoreDouble( double d ) +{ + mpStm->write( (char*)&d, sizeof(double) ); + + mStreamPos += sizeof(double); + + return Good(); +} + +bool wxIOStreamWrapper::StoreBytes( void* bytes, int count ) +{ + mpStm->write( (char*)bytes, count ); + + mStreamPos += count; + + return Good(); +} + +bool wxIOStreamWrapper::LoadChar( char* pCh ) +{ + mpStm->read( pCh, sizeof(char) ); + + mStreamPos += sizeof(char); + + return Good(); +} + +bool wxIOStreamWrapper::LoadInt( int* pI ) +{ + mpStm->read( (char*)pI, sizeof(int) ); + + mStreamPos += sizeof(int); + + return Good(); +} + +bool wxIOStreamWrapper::LoadLong( long* pL ) +{ + mpStm->read( (char*)pL, sizeof(long) ); + + mStreamPos += sizeof(long); + + return Good(); +} + +bool wxIOStreamWrapper::LoadDouble( double* pD ) +{ + mpStm->read( (char*)pD, sizeof(double) ); + + mStreamPos += sizeof(double); + + return Good(); +} + +bool wxIOStreamWrapper::LoadBytes ( void* pBytes, int count ) +{ + mpStm->read( (char*)pBytes, count ); + + mStreamPos += count; + + return Good(); +} + +bool wxIOStreamWrapper::Flush() +{ + mpStm->flush(); + + return Good(); +} + +long wxIOStreamWrapper::GetStreamPos() +{ + return mStreamPos; +} + +bool wxIOStreamWrapper::Good() +{ + // FIXME FIXME:: somehow, when using ios::good/ios::bad, linking breaks complaining + // about "ios::bad" already defined in this object file... + + return TRUE; +} diff --git a/utils/framelayout/src/objstore.h b/utils/framelayout/src/objstore.h new file mode 100644 index 0000000000..86616bd9ac --- /dev/null +++ b/utils/framelayout/src/objstore.h @@ -0,0 +1,501 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 26/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __OBJSTORE_G__ +#define __OBJSTORE_G__ + +#include "wx/object.h" +#include "wx/string.h" +#include "wx/list.h" +#include "wx/hash.h" + +#include "wx/window.h" +#include "wx/button.h" +#include "wx/textctrl.h" +#include "wx/treectrl.h" +#include "wx/dynarray.h" + +// abstract classes declared + +class wxDataStreamBase; +class wxSerializerBase; +class wxObjectStorage; + +// classes which implement the above interfaces + +class wxPointSerializer; +class wxSizeSerializer; +class wxRectSerializer; +class wxPenSerializer; +class wxBrushSerializer; + +class wxObjectListSerializer; + +class wxEvtHandlerSerializer; +class wxWindowSerializer; +class wxButtonSerializer; +class wxScrollBarSerializer; +class wxChoiceSerializer; +class wxTextCtrlSerializer; +class wxTreeCtrlSerializer; + + +class wxIOStreamWrapper; + +// prototypes for serialzatoin/initialization functions + +typedef void (*wxObjectSerializationFn) (wxObject*, wxObjectStorage& ); +typedef void (*wxObjectInitializationFn)(wxObject*); + +#define NO_CLASS_VER NULL +#define NO_CLASS_INIT NULL + +/* + * class conceptually simiar to wxClassInfo, execpt that it's static + * instances hold information about class-serializers rather then + * about the classes themselves. + */ + +class wxSerializerInfo +{ +public: + char* className; + + wxClassInfo* classInfo; // link to corresponding class-info object, + // established upon invocation of InitializeSerializers() + + wxObjectSerializationFn serFn; + wxObjectInitializationFn initFn; + + char* classVersion; + + static bool alreadyInitialized; + static wxSerializerInfo* first; + static wxHashTable serInfoHash; // classInfo <=> serializerInfo + + wxSerializerInfo* next; + wxSerializerInfo* nextByVersion; + + wxSerializerInfo( char* theClassName, + wxObjectSerializationFn serializationFun, + wxObjectInitializationFn initializationFun, + char* classVersionName + ); + + // looks up for serializers of the base classes (base1 and base2) + // of the given object invokes them if present + + void SerializeInherited ( wxObject* pObj, wxObjectStorage& store ); + void InitializeInherited( wxObject* pObj ); + + bool HasVersion() { return classVersion != NO_CLASS_VER; } + + bool HasInitializer() { return initFn != NO_CLASS_INIT; } + + // static methods + + static void InitializeSerializers(void); + + static wxSerializerInfo* FindSerializer( char* className ); +}; + +/* + * formal base class for all serializers, implemented as + * classes with static serialization/initialization methods + */ + +class wxSerializerBase {}; + +// macros for declaring and implementing serializers both as +// classes and as a pair of (serialize/init) functions + +#define DECLARE_SERIALIZER_CLASS(serializerName) \ + public:\ + static wxSerializerInfo info;; + +#define IMPLEMENT_SERIALIZER_CLASS( name, serializerName, serFn, initFn) \ + wxSerializerInfo \ + serializerName::info( #name, serFn, initFn, NO_CLASS_VER ); + +#define IMPLEMENT_SERIALIZER_FUNCTIONS( name, serFn, initFn) \ + wxSerializerInfo \ + static __gSerFnInfoFor##name( #name, serFn, initFn, NO_CLASS_VER ); + +// for serializers, which are dedicated for specific versions of persistant classes +// (further referred as "versioned" serializers) + +#define IMPLEMENT_SERIALIZER_CLASS_FOR_VERSION( name, serializerName, serFn, initFn, versionName) \ + wxSerializerInfo \ + serializerName::info( #name, serFn, initFn, #versionName ); + +#define IMPLEMENT_SERIALIZER_FUNCTIONS_FOR_VERSION( name, serializerName, serFn, initFn, versionName) \ + wxSerializerInfo \ + static __gSerFnInfoFor##name( #name, serFn, initFn, #versionName ); + +/* + * defines abstract inferface for data-stream objects, + * can be implemented as a wrapper class for already + * existing stream classes + */ + +class wxDataStreamBase : public wxObject +{ + DECLARE_ABSTRACT_CLASS( wxDataStreamBase ) +protected: + bool mIsForInput; + +public: + virtual bool StoreChar ( char ch ) = 0; + virtual bool StoreInt ( int i ) = 0; + virtual bool StoreLong ( long l ) = 0; + virtual bool StoreDouble( double d ) = 0; + virtual bool StoreBytes ( void* bytes, int count ) = 0; + + virtual bool LoadChar ( char *pCh ) = 0; + virtual bool LoadInt ( int *pI ) = 0; + virtual bool LoadLong ( long *pL ) = 0; + virtual bool LoadDouble( double *pD ) = 0; + virtual bool LoadBytes ( void *pBytes, int count ) = 0; + + virtual bool Flush() = 0; + + virtual long GetStreamPos() = 0; + + bool IsForInput() { return mIsForInput; } +}; + +/* + * class provides stream-based persistance service for + * classes derivated from wxObject, which are declared + * as dynamic classes. Relies on the presence of appropriate + * serializers for objects, which are being stored/loaded. + */ + +class wxObjectStorage : public wxObject +{ + DECLARE_DYNAMIC_CLASS( wxObjectStorage ) +protected: + wxDataStreamBase* mpStm; + bool mIsLoading; + + wxHashTable mRefHash; + + wxList mInitialRefs; + wxHashTable mInitialRefsHash; + long mInitialRefsCnt; + + wxList mNewObjs; + wxList mSerializersForNewObjs; + + bool mFinalizePending; + +protected: + wxSerializerBase* FindSerializer( wxObject* pForObj ); + + void ClearHashesAndLists(); + + virtual bool VersionsMatch( char* v1, char* v2 ); + + virtual wxSerializerInfo* FindSrzInfoForClass( wxClassInfo* pInfo ); + + void DoExchangeObject( wxObject* pInstance, wxSerializerInfo& srzInfo ); + + bool ExchangeObjectInfo( wxClassInfo** ppCInfo, wxSerializerInfo** ppSrz ); + + wxSerializerInfo* GetLatestSrzForObj( wxObject* pWxObj ); + +public: + // can be changed (with countion!) + + static char mVerSepartorCh; // default: '#' + static char mMinorMajorSepartorCh; // default: '-' + +public: + + wxObjectStorage(); + + wxObjectStorage( wxDataStreamBase& stm ); + + virtual ~wxObjectStorage(); + + // adds initial reference, objects referred by such reference + // are not serialized when storing. When loading, pointers which + // refere to these "inital objects" are set up to refere to + // objects provided in by AddInitailRef() method. + // + // NOTE:: initial references should be added always in the + // same order, since the seq-# of the reference is used + // as an alias to the real object while storing/loading + + void AddInitialRef( wxObject* pObjRef ); + + void ClearInitalRefs(); + + // init/reinit of object-storage + + void SetDataStream( wxDataStreamBase& stm ); + + // performs linkng of in-memory references after loading, or + // links in-stream references after storing has proceeded + + void Finalize(); + + // storage methods for basic types + + void XchgChar ( char& chObj ); + void XchgInt ( int& intObj ); + void XchgLong ( long& longObj ); + void XchgBool ( bool& boolObj ); + void XchgDouble ( double& doubleObj ); + void XchgCStr ( char* pCStrObj ); + void XchgUInt ( unsigned int& uI ); + void XchgSizeType( size_t& szObj ); + + void XchgObjList ( wxList& objList ); + void XchgObjArray ( wxBaseArray& objArr ); + void XchgLongArray( wxBaseArray& longArr ); + + // storage methods for objects and pointers to objects + + void XchgObj ( wxObject* pWxObj ); + void XchgObjPtr( wxObject** ppWxObj ); + + bool IsLoading() { return mIsLoading; } + + // storage methods for common wxWindows classes, + // which may or may not be dymaic, therefor use the + // below methods instead of XchgObj(..) + + void XchgWxStr ( wxString& str ); + void XchgWxSize ( wxSize& size ); + void XchgWxPoint( wxPoint& point ); + void XchgWxRect ( wxRect& rect ); +}; + +/* + * The below classes provide "curde" serialization for most + * common wxWindows objects, i.e. they discard the information + * which may be contained in the subclassed versions of these classes + * However, more "fine-grainded" serializers could be written + * to match these subclasses exactly. + */ + +class wxColourSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxColourSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +// NOTE:: currently "stipple" and "dashes" properties of the pen +// are not serialized + +class wxPenSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxPenSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +// NOTE:: currently "stipple" property of the brush is not serialized + +class wxBrushSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxBrushSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +// serializer for wxList, assuming that the list +// holds derivatives of wxObject. + +class wxObjectListSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxObjectListSerializer ); + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); +}; + +// generic serializer for classes derived from wxEvtHandler handler, +// assuming that they do not add any new properties to wxEvtHandler +// or these properties are transient + +class wxEvtHandlerSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( wxEvtHandlerSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void Initialize( wxObject* pObj ); +}; + +// serializer for generic wxWindow. Serializes position, size, id, +// reference to parent, list of children, style flags and name string. +// Could be used for serializing wxWindow and generic wxPanel objects. +// Separate serializers have to be written for control classes. + +class wxWindowSerializer : public wxEvtHandlerSerializer +{ + DECLARE_SERIALIZER_CLASS( wxWindowSerializer ); +public: + + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + // helpers, to ease the creation of serializers for derivatives of wxWindow + + typedef (*wndCreationFn)(wxWindow*, wxWindow*, const wxWindowID, + const wxPoint&, const wxSize&, long, const wxString& ); + + + static void DoSerialize( wxObject* pObj, wxObjectStorage& store, + wndCreationFn creationFn, bool refreshNow = TRUE + ); + + + static void CreateWindowFn( wxWindow* wnd, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); + +}; + +class wxTextCtrlSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxTextCtrlSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void CreateTextCtrlWindowFn( wxTextCtrl* wnd, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); +}; + +class wxButtonSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxButtonSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void CreateButtonWindowFn( wxButton* btn, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); +}; + +class wxStaticTextSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxStaticTextSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void CreateSTextWindowFn( wxStaticText* pSTxt, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); +}; + + +class wxScrollBarSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxScrollBarSerializer ); +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void CreateScollBarWindowFn( wxScrollBar* sbar, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); +}; + +class wxTreeCtrlSerializer : public wxWindowSerializer +{ + DECLARE_SERIALIZER_CLASS( wxTreeCtrlSerializer ); + +protected: + static void SerializeBranch( wxTreeItemId parentId, wxTreeCtrl* pTree, + wxObjectStorage& store, wxTreeItemId nextVisId, + int depth ); + +public: + static void Serialize( wxObject* pObj, wxObjectStorage& store ); + + static void CreateTreeCtrlWindowFn( wxTreeCtrl* tree, wxWindow* parent, const wxWindowID id, + const wxPoint& pos, const wxSize& size, long style , + const wxString& name ); +}; + +// default implementations of interfaces, used by wxObjectStorage class +// +// FOR NOW:: methods do not yet perform byte-swaps for outputting/reading words in +// machine-independent format. Better solution would be to write wrapper +// around the "promissed" protable-data-stream class of wxWindows + +class wxIOStreamWrapper : public wxDataStreamBase +{ + DECLARE_DYNAMIC_CLASS( wxIOStreamWrapper ) +protected: + iostream* mpStm; + bool mOwnsStmObject; + long mStreamPos; // precalcualted stream postion, + // assuming that the actual stream object is not + // capable of telling postion of current get/put pointer + // (e.g. socket-stream) + void Close(); + +public: + + // default constructor + wxIOStreamWrapper(); + + // attach this wrapper to already exiting iostream object + + wxIOStreamWrapper( iostream& stm, bool forInput = TRUE ); + + // creates "fstream" object with the given file name in binary mode, + // returns FALSE, if stream creation failed + // + // The created fstream object is "owned" by this wrapper, + // thus it is destored during destruction of this object + + bool Create( const char* fileName, bool forInput = TRUE ); + + inline bool CreateForInput( const char* fileName ) + + { return Create( fileName, TRUE ); } + + inline bool CreateForOutput( const char* fileName ) + + { return Create( fileName, FALSE ); } + + // the same as in the second constructor, previousely used + // stream object is flushed and destroyed (if owned). + // The attached stream is not "owned" by this wrapper object + + void Attach( iostream& stm, bool forInput = TRUE ); + + virtual ~wxIOStreamWrapper(); + + virtual bool StoreChar ( char ch ); + virtual bool StoreInt ( int i ); + virtual bool StoreLong ( long l ); + virtual bool StoreDouble( double d ); + virtual bool StoreBytes ( void* bytes, int count ); + + virtual bool LoadChar ( char* pCh ); + virtual bool LoadInt ( int* pI ); + virtual bool LoadLong ( long* pL ); + virtual bool LoadDouble( double* pD ); + virtual bool LoadBytes ( void* pBytes, int count ); + + virtual bool Flush(); + + virtual long GetStreamPos(); + + bool Good(); +}; + +#endif diff --git a/utils/framelayout/src/panedrawpl.cpp b/utils/framelayout/src/panedrawpl.cpp new file mode 100644 index 0000000000..a393c0649d --- /dev/null +++ b/utils/framelayout/src/panedrawpl.cpp @@ -0,0 +1,1265 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "panedrawpl.h" + +// bitmap bits used by bar-resizing brush + +#define _A 0xAA +#define _B 0x00 +#define _C 0x55 +#define _D 0x00 + +static const unsigned char _gCheckerImg[16] = { _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_D + }; + +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 ), + + 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 + ) + { + 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; + + cbBarInfo* pInfo = NULL; + + // 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 + ) + { + long 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 visable + 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, wxLEFT, dc ); + DrawShade( 1, bounds, wxRIGHT, dc ); + } + else + { + DrawShade( 1, bounds, wxTOP, dc ); + DrawShade( 1, bounds, wxBOTTOM, 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, wxTOP, 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, wxLEFT, 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 ) +{ + int prevX = 0; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + { + wxRect& bounds = pRow->mBars[i]->mBoundsInParent; + + if ( mpPane->IsHorizontal() ) + { + DrawShade( level, bounds, wxBOTTOM, 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, wxRIGHT, 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 == wxTOP && level == 1 ) || + ( alignment == wxBOTTOM && level == 0 ) || + ( alignment == wxLEFT && level == 1 ) || + ( alignment == wxRIGHT && level == 0 ) + ) + + dc.SetPen( mpLayout->mDarkPen ); + else + dc.SetPen( mpLayout->mLightPen ); + + if ( alignment == wxTOP ) + { + 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 == wxBOTTOM ) + { + 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 == wxLEFT ) + { + 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 == wxRIGHT ) + { + 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 == wxTOP && level == 1 ) || + ( alignment == wxBOTTOM && level == 0 ) || + ( alignment == wxLEFT && level == 1 ) || + ( alignment == wxRIGHT && level == 0 ) + ) + + dc.SetPen( mpLayout->mDarkPen ); + else + dc.SetPen( mpLayout->mLightPen ); + + if ( alignment == wxTOP ) + { + 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 == wxBOTTOM ) + { + 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 == wxLEFT ) + { + 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 == wxRIGHT ) + { + 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 == wxTOP || + mpPane->mAlignment == wxBOTTOM ) + { + --bounds.y; + bounds.height += 2; + + DrawShade1( 0, bounds, wxLEFT, dc ); + DrawShade1( 1, bounds, wxLEFT, dc ); + DrawShade1( 0, bounds, wxRIGHT, dc ); + DrawShade1( 1, bounds, wxRIGHT, dc ); + + if ( !pRow->mpNext ) + DrawPaneShade( dc, wxBOTTOM ); + + if ( !pRow->mpPrev ) + DrawPaneShade( dc, wxTOP ); + } + else + { + --bounds.x; + bounds.width += 2; + + DrawShade1( 0, bounds, wxTOP, dc ); + DrawShade1( 1, bounds, wxTOP, dc ); + DrawShade1( 0, bounds, wxBOTTOM, dc ); + DrawShade1( 1, bounds, wxBOTTOM, dc ); + + if ( !pRow->mpNext ) + DrawPaneShade( dc, wxRIGHT ); + + if ( !pRow->mpPrev ) + DrawPaneShade( dc, wxLEFT ); + } +} + +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, wxTOP ); + DrawPaneShade( dc, wxBOTTOM ); + DrawPaneShade( dc, wxLEFT ); + DrawPaneShade( dc, wxRIGHT ); + + 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/destory 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/utils/framelayout/src/panedrawpl.h b/utils/framelayout/src/panedrawpl.h new file mode 100644 index 0000000000..addfe19134 --- /dev/null +++ b/utils/framelayout/src/panedrawpl.h @@ -0,0 +1,118 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 "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; + + bool mRowHandleHitted; + bool mIsUpperHandle; + bool mBarHandleHitted; + bool mIsLeftHandle; + bool mBarContentHitted; + + cbBarInfo* mpDraggedBar; // also used when in bar-drag action + cbRowInfo* mpResizedRow; + + // 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 \ No newline at end of file diff --git a/utils/framelayout/src/pf_sample.cpp b/utils/framelayout/src/pf_sample.cpp new file mode 100644 index 0000000000..e0dcf9ee5e --- /dev/null +++ b/utils/framelayout/src/pf_sample.cpp @@ -0,0 +1,286 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 26/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "pf_sample.h" +// #pragma interface +#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 "pf_sample.h" + +IMPLEMENT_DYNAMIC_CLASS( classA, wxObject ) +IMPLEMENT_DYNAMIC_CLASS( classB, wxObject ) + +IMPLEMENT_SERIALIZER_CLASS( classA, + classASerializer, + classASerializer::Serialize, + NO_CLASS_INIT ) + +IMPLEMENT_SERIALIZER_CLASS( classB, + classBSerializer, + classBSerializer::Serialize, + NO_CLASS_INIT ) + +// somehow original wxASSERT(0) statements get not compiled in... + +#undef wxASSERT +#define wxASSERT(x) if ( !(x) ) throw; + +extern notStorableClass gNotStorable; + +typedef notStorableClass* BackRefType; + +void test_storing( const char* fname, wxObjectStorage& store ) +{ + // create objects + + classA* pA = new classA(); + pA->x = 1; + + classB* pB = new classB(); + + pB->y = 2; + + // put cross-references + + pB->mpAObj = pA; + + pA->mpBObj = pB; + + // put back-references to not-storable obj + + pA->mpBackRef = &gNotStorable; + pB->mpBackRef = &gNotStorable; + + // create stream object for output + + wxIOStreamWrapper outFile; + + bool success = outFile.Create( fname, FALSE ); + + wxASSERT( success ); + + store.SetDataStream( outFile ); + + // store everything starting from "pA" object + + store.XchgObjPtr( (wxObject**) &pA ); + + // flushes stream + store.Finalize(); +} + +void test_loading( const char* fname, wxObjectStorage& store ) +{ + classA* pA = 0; + + // create stream-object for input + + wxIOStreamWrapper inFile; + + bool success = inFile.Create( fname, TRUE ); + + wxASSERT( success ); + + store.SetDataStream( inFile ); + + // load everything + + store.XchgObjPtr( (wxObject**) &pA ); + + // calls initializing procedures for serializer + // which provide them + + store.Finalize(); + + // short-cut + + classB* pB = pA->mpBObj; + + // assertain correctness of class members + + wxASSERT( pA->x == 1 ); + wxASSERT( pB->y == 2 ); + + // assertain correctness of cross-references + + wxASSERT( pA->mpBObj == pB ); + wxASSERT( pB->mpAObj == pA ); + + // asssertain correctness of inital references + + wxASSERT( pA->mpBackRef == &gNotStorable ); + wxASSERT( pB->mpBackRef == &gNotStorable ); +} + +void setup_inital_refs( wxObjectStorage& store ) +{ + store.AddInitialRef( (wxObject*) &gNotStorable ); +} + +// global instance of the object, which we do not want to store/load for +// some reason, even though other stored/loaded objects have refernces to it + +notStorableClass gNotStorable; + +void test_storing_of_list( const char* fname, wxObjectStorage& store ); +void test_loading_of_list( const char* fname, wxObjectStorage& store ); + +/*---------------------------*/ +/* Main testing function */ +/*---------------------------*/ + +void test_obj_storage() +{ + // NOTE:: for brevity, the heap clean-ups are omitted in the tests + + wxObjectStorage store; + + setup_inital_refs( store ); + + test_storing( "testdata.dat", store ); + test_loading( "testdata.dat", store ); + + test_storing_of_list( "testdata.dat", store ); + test_loading_of_list( "testdata.dat", store ); +} + +void test_storing_of_list( const char* fname, wxObjectStorage& store ) +{ + // create objects + + classA* pA = new classA(); + pA->x = 1; + + classB* pB = new classB(); + + pB->y = 2; + + // put cross-references + + pB->mpAObj = pA; + + pA->mpBObj = pB; + + // create list object + + wxList* pLst = new wxList; + + // put objects to the list + + wxNode* pNode = pLst->Append( pA ); + + pA->mpBackRef = (BackRefType)pNode; + + pNode = pLst->Append( pB ); + + pB->mpBackRef = (BackRefType)pNode; + + // create stream object for output + + wxIOStreamWrapper outFile; + + bool success = outFile.Create( fname, FALSE ); + + wxASSERT( success ); + + store.SetDataStream( outFile ); + + // store everything starting from "pLst" object + + store.XchgObjPtr( (wxObject**) &pLst ); + + // flushes stream + store.Finalize(); +} + +void test_loading_of_list( const char* fname, wxObjectStorage& store ) +{ + // create stream-object for input + + wxIOStreamWrapper inFile; + + bool success = inFile.Create( fname, TRUE ); + + wxASSERT( success ); + + store.SetDataStream( inFile ); + + // load everything + + wxList* pLst; + + // (NOTE:: serializers for wxList/wxNode is file objstore.cpp) + + store.XchgObjPtr( (wxObject**) &pLst ); + + // assertain correctness of list and it's contents + + wxASSERT( pLst->Number() == 2 ); + + int n = 0; + wxNode* pNode = pLst->First(); + + while( pNode ) + { + if ( n == 0 ) + { + classA* pA = (classA*)pNode->Data(); + + // assertain correctness of class members + + wxASSERT( pA->x == 1 ); + + // assertain correctness of cross-references + + wxASSERT( pA->mpBObj == (classB*)pNode->Next()->Data() ); + + // asssertain correctness of inital references + + wxASSERT( (wxNode*)pA->mpBackRef == pNode ) + } + if ( n == 1 ) + { + classB* pB = (classB*)pNode->Data(); + + // assertain correctness of class members + + wxASSERT( pB->y == 2 ); + + // assertain correctness of cross-references + + wxASSERT( pB->mpAObj == (classA*)pNode->Previous()->Data() ); + + // asssertain correctness of inital references + + wxASSERT( (wxNode*)pB->mpBackRef == pNode ) + } + + pNode = pNode->Next(); + ++n; + } + + // calls initializing procedures for serializer + // which provide them + + store.Finalize(); +} diff --git a/utils/framelayout/src/pf_sample.h b/utils/framelayout/src/pf_sample.h new file mode 100644 index 0000000000..12bec2e7d5 --- /dev/null +++ b/utils/framelayout/src/pf_sample.h @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 26/10/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __PF_SAMPLE_G__ +#define __PF_SAMPLE_G__ + +#include "objstore.h" + +// forward decl. +class classA; +class classB; + +// sample classes + +class notStorableClass +{}; + +class classA : public wxObject +{ + DECLARE_DYNAMIC_CLASS( classA ) +public: + + int x; + classB* mpBObj; + notStorableClass* mpBackRef; +}; + +class classB : public wxObject +{ + DECLARE_DYNAMIC_CLASS( classB ) +public: + + int y; + classA* mpAObj; + notStorableClass* mpBackRef; +}; + +// serialization handlers for the above classes + +class classASerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( classASerializer ) + + static void Serialize( wxObject* pObj, wxObjectStorage& store ) + { + classA* pA = (classA*)pObj; // cast + + store.XchgInt ( pA->x ); + store.XchgObjPtr( (wxObject**) &(pA->mpBObj) ); + store.XchgObjPtr( (wxObject**) &(pA->mpBackRef) ); + } +}; + +class classBSerializer : public wxSerializerBase +{ + DECLARE_SERIALIZER_CLASS( classBSerializer ) + + static void Serialize( wxObject* pObj, wxObjectStorage& store ) + { + classB* pB = (classB*)pObj; // cast + + store.XchgInt ( pB->y ); + store.XchgObjPtr( (wxObject**) &(pB->mpAObj) ); + store.XchgObjPtr( (wxObject**) &(pB->mpBackRef) ); + } +}; + +/*---------------------------*/ +/* Main testing function */ +/*---------------------------*/ + +// include this header and .cpp file into any of your +// wxWindows projects, and invoke the below function +// to peform tests + +void test_obj_storage(); + +#endif \ No newline at end of file diff --git a/utils/framelayout/src/rowdragpl.cpp b/utils/framelayout/src/rowdragpl.cpp new file mode 100644 index 0000000000..d158a19cf1 --- /dev/null +++ b/utils/framelayout/src/rowdragpl.cpp @@ -0,0 +1,1466 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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 + +/***** Implementaiton for class cbHiddenBarInfo *****/ + +IMPLEMENT_DYNAMIC_CLASS( cbHiddenBarInfo, wxObject ) + +/***** Implementaiton 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) + + : mDragStarted ( FALSE ), + mDecisionMode ( FALSE ), + mCurDragOfs ( 0 ), + mpPaneImage ( NULL ), + mpRowImage ( NULL ), + mpCombinedImage ( NULL ), + + mpRowInFocus ( NULL ), + mCollapsedIconInFocus( -1 ), + + mCaptureIsOn ( FALSE ), + + mTrianInnerColor ( 0,0,255 ), + mHightColor ( 192, 192, 255 ), + mLowColor ( 192, 192, 192 ), + mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), + + mSvTopMargin ( -1 ), + mSvBottomMargin ( -1 ), + mSvLeftMargin ( -1 ), + mSvRightMargin ( -1 ), + mpPane ( NULL ) +{ +} + +cbRowDragPlugin::cbRowDragPlugin( wxFrameLayout* pLayout, int paneMask ) + + : cbPluginBase( pLayout, paneMask ), + + mDragStarted ( FALSE ), + mDecisionMode ( FALSE ), + mCurDragOfs ( 0 ), + mpPaneImage ( NULL ), + mpRowImage ( NULL ), + mpCombinedImage ( NULL ), + + mpRowInFocus ( NULL ), + mCollapsedIconInFocus( -1 ), + + mCaptureIsOn ( FALSE ), + + mTrianInnerColor ( 0,0,255 ), + mHightColor ( 192, 192, 255 ), + mLowColor ( 192, 192, 192 ), + mTrianInnerPen ( mTrianInnerColor, 1, wxSOLID ), + + mSvTopMargin ( -1 ), + mSvBottomMargin ( -1 ), + mSvLeftMargin ( -1 ), + mSvRightMargin ( -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 previousely 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 ( mInitalRowOfs + offset + mRowImgDim.y > mCombRect.y + mCombRect.height ) + + offset = mCombRect.y + mCombRect.height - mRowImgDim.y - mInitalRowOfs; + + if ( mInitalRowOfs + offset < mCombRect.y ) + + offset = mCombRect.y - mInitalRowOfs; + + long x, y = mInitalRowOfs + offset; + mpPane->FrameToPane( &x, &y ); + mCurDragOfs = y; + } + else + { + if ( mInitalRowOfs + offset + mRowImgDim.x > mCombRect.x + mCombRect.width ) + + offset = mCombRect.x + mCombRect.width - mRowImgDim.x - mInitalRowOfs; + + if ( mInitalRowOfs + offset < mCombRect.x ) + + offset = mCombRect.x - mInitalRowOfs; + + long x = mInitalRowOfs + 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, mInitalRowOfs + offset - mCombRect.y, + mCombRect.width, mRowImgDim.y, + &rowImgDc, 0,0, wxCOPY ); + } + else + { + combImgDc.Blit( mInitalRowOfs + 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; + mInitalRowOfs = 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; + mInitalRowOfs = 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/utils/framelayout/src/rowdragpl.h b/utils/framelayout/src/rowdragpl.h new file mode 100644 index 0000000000..6100592522 --- /dev/null +++ b/utils/framelayout/src/rowdragpl.h @@ -0,0 +1,159 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "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 mInitalRowOfs; + + // 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 \ No newline at end of file diff --git a/utils/framelayout/src/rowlayoutpl.cpp b/utils/framelayout/src/rowlayoutpl.cpp new file mode 100644 index 0000000000..4a4fd3ca1e --- /dev/null +++ b/utils/framelayout/src/rowlayoutpl.cpp @@ -0,0 +1,1206 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "rowlayoutpl.h" + +// exerimental "features" are still buggy +#undef __EXPERIMENTAL + +/***** Implementaiton 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 ) +{ + ApplyLenghtRatios( 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::AdjustLenghtOfInserted( cbRowInfo* pRow, cbBarInfo* pTheBar ) +{ + return; + + // pTheBar is not-fixed + + + // FIXME:: what is this for?? + +#if 1 + + int totalLen = 0; + + for( size_t 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; + + for( size_t 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 previousely + // 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 ) +{ + for( size_t 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 prevX = 0; + int freeSpc = mpPane->mPaneWidth; + + for( size_t 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::RecalcLenghtRatios( 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; + + for( size_t i = 0; i != pRow->mBars.Count(); ++i ) + + if ( !pRow->mBars[i]->IsFixed() ) + + totalLen += pRow->mBars[i]->mBounds.width; +#endif + + for( size_t 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::ApplyLenghtRatios( 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; + } + } + + 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; + + for( size_t 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 ) +{ + for( size_t 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; + + for( size_t 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; + } */ + + for( size_t 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() ) + + AdjustLenghtOfInserted( 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() ) + + RecalcLenghtRatios( 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 ); + RecalcLenghtRatios( pIntoRow ); + +#endif + + DetectBarHandles( pIntoRow ); + + // do proportional resizing of not-fixed bars + ApplyLenghtRatios( 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 + + ApplyLenghtRatios( pRow ); + + cbBarInfo& lastBar = *pRow->mBars[ pRow->mBars.Count() - 1 ]; + cbBarInfo& firstBar = *pRow->mBars[ 0 ]; + + 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 firciton,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; + + RowArrayT& arr = mpPane->GetRowList(); + + for( size_t 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 == wxTOP || + mpPane->mAlignment == wxLEFT ) + { + 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; + + 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/utils/framelayout/src/rowlayoutpl.h b/utils/framelayout/src/rowlayoutpl.h new file mode 100644 index 0000000000..901bf448f5 --- /dev/null +++ b/utils/framelayout/src/rowlayoutpl.h @@ -0,0 +1,82 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "controlbar.h" + +/* + * Simple implementaiton 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 RecalcLenghtRatios( cbRowInfo* pRow ); + void ApplyLenghtRatios( cbRowInfo* pRow ); + void ExpandNotFixedBars( cbRowInfo* pRow ); + void AdjustLenghtOfInserted( 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 \ No newline at end of file diff --git a/utils/framelayout/src/settingsdlg.cpp b/utils/framelayout/src/settingsdlg.cpp new file mode 100644 index 0000000000..c1a861679a --- /dev/null +++ b/utils/framelayout/src/settingsdlg.cpp @@ -0,0 +1,496 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: settingsdlg.cpp +// Purpose: Settings dialog for Frame Layout +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 05/11/98 +// RCS-ID: $Id$ +// Copyright: (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "settingsdlg.cpp" +#pragma interface "settingsdlg.cpp" +#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 +#include "settingsdlg.h" + +/***** Implementation for class SettingsDlg *****/ + +#define ID_NOTES ( wxEVT_FIRST + 1000 ) +#define ID_HINTANIM_CHECK ( ID_NOTES + 1 ) +#define ID_RTUPDATES_CHECK ( ID_NOTES + 2 ) + +BEGIN_EVENT_TABLE( SettingsDlg, wxDialog ) + + EVT_BUTTON( wxID_APPLY, SettingsDlg::OnApply ) + EVT_BUTTON( ID_NOTES, SettingsDlg::OnNotes ) + + EVT_CHECKBOX( ID_HINTANIM_CHECK, SettingsDlg::OnHintAnimCheck ) + EVT_CHECKBOX( ID_RTUPDATES_CHECK, SettingsDlg::OnRTUpdatesCheck ) + +END_EVENT_TABLE() + +SettingsDlg::SettingsDlg( wxWindow* pParent ) + + : wxDialog( pParent, -1, "Active Layout Settings...", + wxDefaultPosition, + wxSize( 325,585), + wxDIALOG_MODAL | wxCAPTION ) +{ + int curY = 10; + int lMargin = 50; + int lBoxMargin = lMargin - 20; + int checkHeight = 20; + int labelHeight = 20; + int boxWidth = 260; + int interBoxGap = 10; + int lastItemGap = 10; + + int topY = curY; + + curY += labelHeight; + + mpRTU_Check = new wxCheckBox( this, ID_RTUPDATES_CHECK, + "&Real-time updates", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpOPD_Check = new wxCheckBox( this, -1, "&Out of Pane drag", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpEDP_Check = new wxCheckBox( this, -1, "&Exact docking prediction", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpNDF_Check = new wxCheckBox( this, -1, "Non-destructive bar &friction", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpSPB_Check = new wxCheckBox( this, -1, "&Shaded pane borders", + wxPoint( lMargin, curY ) ); + + curY += checkHeight + lastItemGap; + + wxStaticBox* pDNDBox = new wxStaticBox( this, -1, "Drag && Drop settings", + wxPoint( lBoxMargin, topY ), + wxSize( boxWidth, curY - topY ) ); + + curY += interBoxGap; + + //////////////////////////////////////////////////////////////////// + + topY = curY; + + curY += labelHeight; + + mpHAP_Check = new wxCheckBox( this, ID_HINTANIM_CHECK, + "&Hint-Rect animation plugin", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpGCU_Check = new wxCheckBox( this, -1, "\"Garbage collecting\" &Updates-Mgr.", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpAFP_Check = new wxCheckBox( this, -1, "&Antiflicker plugin", + wxPoint( lMargin, curY ) ); + + curY += checkHeight; + + mpCSP_Check = new wxCheckBox( this, -1, "C&ustomization plugin", + wxPoint( lMargin, curY ) ); + + curY += checkHeight + lastItemGap; + + wxStaticBox* pPBox = new wxStaticBox( this, -1, "Plugins", + wxPoint( lBoxMargin, topY ), + wxSize( boxWidth, curY - topY ) ); + + curY += interBoxGap; + + //////////////////////////////////////////////////////////////////// + + wxSize fieldSz( 30,20 ); + int fieldHeight = 20; + int fieldCapMargin = lMargin + fieldSz.x + 5; + int fieldCapOfs = 4; + + topY = curY; + + curY += labelHeight; + + mpRWInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpRWLabel = new wxStaticText ( this, -1, "Resizing sash width(height)", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + + curY += fieldHeight; + + mpPTMInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpPTMLabel = new wxStaticText( this, -1, "Pene's top margin", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + + curY += fieldHeight; + + + mpPBMInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpPBMLabel = new wxStaticText( this, -1, "Pene's bottom margin", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + + curY += fieldHeight; + + + mpPLMInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpPLMLabel = new wxStaticText( this, -1, "Pane's left margin", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + + curY += fieldHeight; + + + mpPRMInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpPRMLabel = new wxStaticText( this, -1, "Pane's right margin", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + curY += fieldHeight + lastItemGap; + + wxStaticBox* pCPPBox = new wxStaticBox( this, -1, "Common Pane properties", + wxPoint( lBoxMargin, topY ), + wxSize( boxWidth, curY - topY ) ); + + curY += interBoxGap; + + //////////////////////////////////////////////////////////////////// + + topY = curY; + + curY += labelHeight; + + fieldSz.x = 65; + fieldCapMargin = lMargin + fieldSz.x + 10; + + mpDCInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpDCLabel = new wxStaticText ( this, -1, "Dark Color (hex-RGB)", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + curY += fieldHeight; + + mpLCInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpLCLabel = new wxStaticText ( this, -1, "Light Color (hex-RGB)", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + curY += fieldHeight; + + mpGCInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpGCLabel = new wxStaticText ( this, -1, "Gray Color (hex-RGB)", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + curY += fieldHeight; + + mpBCInput = new wxTextCtrl ( this, -1, "", + wxPoint( lMargin, curY ), + fieldSz ); + + mpBCLabel = new wxStaticText ( this, -1, "Pane border Color (hex-RGB)", + wxPoint( fieldCapMargin, curY + fieldCapOfs ) ); + + curY += fieldHeight + lastItemGap; + + wxStaticBox* pCSPBox = new wxStaticBox( this, -1, "Coluor sheme properties", + wxPoint( lBoxMargin, topY ), + wxSize( boxWidth, curY - topY ) ); + + curY += interBoxGap; /*button ofs*/; + + //////////////////////////////////////////////////////////////////////////////// + + int lBtnMargin = 35; + int btnGap = 20; + int btnHeight = 22; + int btnWidth = 70; + + wxButton* mpApplyBtn = new wxButton( this, wxID_APPLY, "A&pply", + wxPoint( lBtnMargin, curY ), + wxSize( btnWidth, btnHeight ) ); + + wxButton* mpCancelBtn = new wxButton( this, wxID_CANCEL, "&Cancel", + wxPoint( lBtnMargin + btnWidth + btnGap, curY ), + wxSize( btnWidth, btnHeight ) ); + + wxButton* mpNotesBtn = new wxButton( this, ID_NOTES, "&Notes...", + wxPoint( lBtnMargin + 2*btnWidth + 2*btnGap, curY ), + wxSize( btnWidth, btnHeight ) ); + + mpApplyBtn->SetDefault(); + mpApplyBtn->SetFocus(); + + Center( wxBOTH ); +} + +void SettingsDlg::ExchangeFields( bool toDialog ) +{ + mToDlg = toDialog; + + ExchgCheck( mpRTU_Check, mRealTimeUpdatesOn ); + ExchgCheck( mpOPD_Check, mOutOfPaneDragOn ); + ExchgCheck( mpEDP_Check, mExactDockingPredictionOn ); + ExchgCheck( mpNDF_Check, mNonDestructFrictionOn ); + ExchgCheck( mpSPB_Check, m3DShadesOn ); + + ExchgCheck( mpHAP_Check, mHintRectAnimationOn ); + ExchgCheck( mpGCU_Check, mGCUpdatesMgrOn ); + ExchgCheck( mpAFP_Check, mAntiflickerPluginOn ); + ExchgCheck( mpCSP_Check, mCustomizationPluginOn ); + + ExchgIntField( mpRWInput, mSashWidth ); + ExchgIntField( mpPTMInput, mTopMargin ); + ExchgIntField( mpPBMInput, mBottomMargin ); + ExchgIntField( mpPLMInput, mLeftMargin ); + ExchgIntField( mpPRMInput, mRightMargin ); + + ExchgColourField( mpDCInput, mDarkCol ); + ExchgColourField( mpLCInput, mLightCol ); + ExchgColourField( mpGCInput, mGrayCol ); + ExchgColourField( mpBCInput, mBorderCol ); +} + +void SettingsDlg::OnApply( wxCommandEvent& event ) +{ + ExchangeFields( FALSE ); + EndModal( wxID_APPLY ); +} + +void SettingsDlg::OnNotes( wxCommandEvent& event ) +{ + wxMessageBox("Notes go here...(TBD)"); +} + +void SettingsDlg::OnRTUpdatesCheck( wxCommandEvent& event ) +{ + if ( mpRTU_Check->GetValue() == TRUE ) + { + // user probably wants to see how the real-time drag & drop + // works -- so we "let 'im know" that animation is N/A when + // real-time option is on + + mpHAP_Check->SetValue(FALSE); + mpHAP_Check->Refresh(); + } +} + +void SettingsDlg::OnHintAnimCheck( wxCommandEvent& event ) +{ + if ( mpHAP_Check->GetValue() == TRUE ) + { + // user probably wants to see some animation effects, + // but he/she forgot to turn off "real-time updates" + // setting -- so we do it for you :-) + + mpRTU_Check->SetValue(FALSE); + mpRTU_Check->Refresh(); + } +} + +void SettingsDlg::ExchgCheck( wxCheckBox* pChk, bool& value ) +{ + if ( mToDlg ) pChk->SetValue( value ); + + else value = pChk->GetValue(); +} + +void SettingsDlg::ExchgIntField( wxTextCtrl* pFld, int& value ) +{ + if ( mToDlg ) + { + char buf[32]; + + sprintf( buf, "%d", value ); + pFld->SetValue( buf ); + } + else + { + wxString txt = pFld->GetLineText( 0 ); + value = atoi( txt ); + } +} + +void SettingsDlg::ExchgColourField( wxTextCtrl* pFld, wxColour& value ) +{ + int rgbVal; + + if ( mToDlg ) + { + rgbVal = ( value.Red() & 0x0000FF ) | + ( (value.Green() << 8 ) & 0x00FF00 ) | + ( (value.Blue() << 16 ) & 0xFF0000 ); + + char buf[32]; + + sprintf( buf, "0x%06X", rgbVal ); + + pFld->SetValue( buf ); + } + else + { + wxString txt = pFld->GetLineText( 0 ); + + sscanf( txt, "0x%06X", &rgbVal ); + + value.Set( rgbVal & 0xFF, + ( rgbVal >> 8 ) & 0xFF, + ( rgbVal >> 16 ) & 0xFF ); + } +} + +bool SettingsDlg::TransferDataToWindow() +{ + ExchangeFields( TRUE ); + + return TRUE; +} + +bool SettingsDlg::TransferDataFromWindow() +{ + ExchangeFields( FALSE ); + + return TRUE; +} + +#include "controlbar.h" +#include "rowlayoutpl.h" +#include "antiflickpl.h" +#include "bardragpl.h" +#include "cbcustom.h" + +#include "gcupdatesmgr.h" +#include "hintanimpl.h" + +void SettingsDlg::ReadLayoutSettings( wxFrameLayout& fl ) +{ + cbDockPane& pane = *fl.GetPane( wxTOP ); + cbCommonPaneProperties& props = pane.mProps; + + mRealTimeUpdatesOn = props.mRealTimeUpdatesOn; + mOutOfPaneDragOn = props.mOutOfPaneDragOn; + mExactDockingPredictionOn = props.mExactDockPredictionOn; + mNonDestructFrictionOn = props.mNonDestructFirctionOn; + m3DShadesOn = props.mShow3DPaneBorderOn; + + mHintRectAnimationOn = fl.FindPlugin( CLASSINFO( cbHintAnimationPlugin ) ) != NULL; + mAntiflickerPluginOn = fl.FindPlugin( CLASSINFO( cbAntiflickerPlugin ) ) != NULL; + mCustomizationPluginOn = fl.FindPlugin( CLASSINFO( cbSimpleCustomizationPlugin ) ) != NULL; + mGCUpdatesMgrOn = fl.GetUpdatesManager().GetClassInfo() + == CLASSINFO( cbGCUpdatesMgr ); + + mSashWidth = props.mResizeHandleSize; + + mTopMargin = pane.mTopMargin; + mBottomMargin = pane.mBottomMargin; + mLeftMargin = pane.mLeftMargin; + mRightMargin = pane.mRightMargin; + + mDarkCol = fl.mDarkPen.GetColour(); + mLightCol = fl.mLightPen.GetColour(); + mGrayCol = fl.mGrayPen.GetColour(); + mBorderCol = fl.mBorderPen.GetColour(); +} + +void SettingsDlg::ApplyLayoutSettings( wxFrameLayout& fl ) +{ + cbCommonPaneProperties props; + + props.mRealTimeUpdatesOn = mRealTimeUpdatesOn; + props.mOutOfPaneDragOn = mOutOfPaneDragOn; + props.mExactDockPredictionOn = mExactDockingPredictionOn; + props.mNonDestructFirctionOn = mNonDestructFrictionOn; + props.mShow3DPaneBorderOn = m3DShadesOn; + + props.mResizeHandleSize = mSashWidth; + + fl.SetPaneProperties( props, wxALL_PANES ); + + if ( mHintRectAnimationOn ) fl.AddPlugin ( CLASSINFO( cbHintAnimationPlugin ) ); + else fl.RemovePlugin( CLASSINFO( cbHintAnimationPlugin ) ); + + if ( mAntiflickerPluginOn ) fl.AddPlugin ( CLASSINFO( cbAntiflickerPlugin ) ); + else fl.RemovePlugin( CLASSINFO( cbAntiflickerPlugin ) ); + + if ( mCustomizationPluginOn ) fl.AddPlugin ( CLASSINFO( cbSimpleCustomizationPlugin ) ); + else fl.RemovePlugin( CLASSINFO( cbSimpleCustomizationPlugin ) ); + + // FOR NOW:: unfortunatelly, currently pane marin-information is currently + // placed into cbDockPane, instead of cbCommonPaneProperties + + fl.SetMargins( mTopMargin, mBottomMargin, + mLeftMargin, mRightMargin, wxALL_PANES ); + + fl.mDarkPen.SetColour( mDarkCol ); + fl.mLightPen.SetColour( mLightCol ); + fl.mGrayPen.SetColour( mGrayCol ); + fl.mBorderPen.SetColour( mBorderCol ); + + fl.RecalcLayout( TRUE ); + + // NOTE:: currently it's bit tricky changing updates-manager + // in future, updates-manager will become a normal plugin + // and more convenient methods (Add/FindPlugin) will be used + + if ( mGCUpdatesMgrOn && + fl.GetUpdatesManager().GetClassInfo() != CLASSINFO( cbGCUpdatesMgr ) + ) + + fl.SetUpdatesManager( new cbGCUpdatesMgr( &fl ) ); + else + if ( !mGCUpdatesMgrOn && + fl.GetUpdatesManager().GetClassInfo() == CLASSINFO( cbGCUpdatesMgr ) + ) + + fl.SetUpdatesManager( new cbSimpleUpdatesMgr( &fl ) ); +} diff --git a/utils/framelayout/src/settingsdlg.h b/utils/framelayout/src/settingsdlg.h new file mode 100644 index 0000000000..7ea1d4f847 --- /dev/null +++ b/utils/framelayout/src/settingsdlg.h @@ -0,0 +1,99 @@ +#ifndef __SETTINGSDLG_G__ +#define __SETTINGSDLG_G__ + +#include "wx/dialog.h" + +class wxFrameLayout; + +class SettingsDlg : public wxDialog +{ +protected: + + // "nice thing" about wxWindows: + + wxCheckBox* mpRTU_Check; + wxCheckBox* mpOPD_Check; + wxCheckBox* mpEDP_Check; + wxCheckBox* mpNDF_Check; + wxCheckBox* mpSPB_Check; + + wxCheckBox* mpHAP_Check; + wxCheckBox* mpGCU_Check; + wxCheckBox* mpAFP_Check; + wxCheckBox* mpCSP_Check; + + wxTextCtrl* mpRWInput; + wxStaticText* mpRWLabel; + wxTextCtrl* mpPTMInput; + wxStaticText* mpPTMLabel; + wxTextCtrl* mpPBMInput; + wxStaticText* mpPBMLabel; + wxTextCtrl* mpPLMInput; + wxStaticText* mpPLMLabel; + wxTextCtrl* mpPRMInput; + wxStaticText* mpPRMLabel; + + wxTextCtrl* mpDCInput; + wxStaticText* mpDCLabel; + wxTextCtrl* mpLCInput; + wxStaticText* mpLCLabel; + wxTextCtrl* mpGCInput; + wxStaticText* mpGCLabel; + wxTextCtrl* mpBCInput; + wxStaticText* mpBCLabel; + + // fields/properties + + bool mRealTimeUpdatesOn; + bool mOutOfPaneDragOn; + bool mExactDockingPredictionOn; + bool mNonDestructFrictionOn; + bool m3DShadesOn; + bool mHintRectAnimationOn; + bool mGCUpdatesMgrOn; + bool mAntiflickerPluginOn; + bool mCustomizationPluginOn; + + int mSashWidth; + int mTopMargin; + int mBottomMargin; + int mLeftMargin; + int mRightMargin; + + wxColour mDarkCol; + wxColour mLightCol; + wxColour mGrayCol; + wxColour mBorderCol; + +protected: + + bool mToDlg; + + // helpers + + void ExchgCheck( wxCheckBox* pChk, bool& value ); + void ExchgIntField( wxTextCtrl* pFld, int& value ); + void ExchgColourField( wxTextCtrl* pFld, wxColour& value ); + + virtual bool TransferDataToWindow(); + virtual bool TransferDataFromWindow(); + +public: + + SettingsDlg( wxWindow* pParent ); + + void ReadLayoutSettings( wxFrameLayout& fl ); + void ApplyLayoutSettings( wxFrameLayout& fl ); + + void ExchangeFields( bool toDialog ); + + void OnApply( wxCommandEvent& event ); + void OnNotes( wxCommandEvent& event ); + + void OnHintAnimCheck( wxCommandEvent& event ); + void OnRTUpdatesCheck( wxCommandEvent& event ); + + DECLARE_EVENT_TABLE(); +}; + +#endif \ No newline at end of file diff --git a/utils/framelayout/src/toolwnd.cpp b/utils/framelayout/src/toolwnd.cpp new file mode 100644 index 0000000000..2cb14b99f0 --- /dev/null +++ b/utils/framelayout/src/toolwnd.cpp @@ -0,0 +1,1144 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "toolwnd.h" + +#define _A 0xAA +#define _B 0x00 +#define _C 0x55 +#define _D 0x00 + +// FOR NOW:: static + +static const unsigned char _gCheckerImg[16] = { _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_D, + _A,_B,_C,_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 ), + mTitleHeight ( 16 ), + + mClntHorizGap ( 2 ), + mClntVertGap ( 2 ), + mWndVertGap ( 4 ), + mWndHorizGap ( 4 ), + + mButtonGap ( 2 ), + mInTitleMargin( 4 ), + mHintBorder ( 4 ), + + mMTolerance ( 5 ), // mouse-resizing tollerance + + mCursorType( HITS_WND_NOTHING ), + mMouseCaptured( FALSE ), + + mResizeStarted( FALSE ), + mRealTimeUpdatesOn( TRUE ), + +#ifndef __WXMSW__ + mTitleFont( 8, wxSWISS, wxNORMAL, wxNORMAL ), +#else + // just to simulate MS-Dev style + mTitleFont( 8, wxSWISS, wxNORMAL, wxNORMAL, FALSE, "MS Sans Serif" ), +#endif + + 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 ) +{ + 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 + { + wxASSERT(0); // 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, GetMinimalWndDim() ); + + 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( long& a, long& 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()[wxTOP] ); + + mpLayout->FirePluginEvent( dragEvt ); + + return TRUE; +} + +void cbFloatedBarWindow::OnDblClick( wxMouseEvent& event ) +{ + mpLayout->SetBarState( mpBar, wxCBAR_DOCKED_HORIZONTALLY, TRUE ); + + //wxMessageBox("toolWnd - dblClick!"); +} diff --git a/utils/framelayout/src/toolwnd.h b/utils/framelayout/src/toolwnd.h new file mode 100644 index 0000000000..55f9bf8789 --- /dev/null +++ b/utils/framelayout/src/toolwnd.h @@ -0,0 +1,210 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#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, accesssed 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 "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 diff --git a/utils/framelayout/src/updatesmgr.cpp b/utils/framelayout/src/updatesmgr.cpp new file mode 100644 index 0000000000..6bc3c5d54c --- /dev/null +++ b/utils/framelayout/src/updatesmgr.cpp @@ -0,0 +1,292 @@ +///////////////////////////////////////////////////////////////////////////// +// 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" +// #pragma interface +#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 "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; + bool rowBkPainted = 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(); + } +} diff --git a/utils/framelayout/src/updatesmgr.h b/utils/framelayout/src/updatesmgr.h new file mode 100644 index 0000000000..a30b847508 --- /dev/null +++ b/utils/framelayout/src/updatesmgr.h @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////// +// 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__ + +#include "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 \ No newline at end of file diff --git a/utils/framelayout/src/wxinfo.cpp b/utils/framelayout/src/wxinfo.cpp new file mode 100644 index 0000000000..5f4d3ab8cd --- /dev/null +++ b/utils/framelayout/src/wxinfo.cpp @@ -0,0 +1,159 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/11/98 +// RCS-ID: $Id$ +// Copyright: 1998 (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifdef __GNUG__ +#pragma implementation "wxinifo.cpp" +#pragma interface "wxinifo.cpp" +#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/hash.h" +#include "wxinfo.h" + +inline static void expand_item( wxTreeCtrl* pTree, wxTreeItemId& itemId ) +{ + pTree->Expand( itemId ); +} + +void wxCreateClassInfoTree( wxTreeCtrl* pTree, + wxTreeItemId parentBranchId, + long classImageNo + ) +{ + expand_item( pTree, parentBranchId ); + + wxHashTable hash; + + wxList lst; + + // collect all classes into list + + { + wxClassInfo* pCur = wxClassInfo::GetFirst(); + + wxClassInfo::InitializeClasses(); + + while( pCur ) + { + lst.Append( (wxObject*)pCur ); + + pCur = pCur->GetNext(); + } + } + + wxClassInfo::InitializeClasses(); + + // reflect class-hierarchy into the tree nodes + + int nHanged; + + do + { + nHanged = 0; + + wxNode* pCur = lst.First(); + + // repeat passes through class list, untill all of + // the class items are "hanged" onto their parent-items in the tree + + while( pCur ) + { + wxClassInfo& info = *((wxClassInfo*)pCur->Data()); + + if ( info.GetBaseClass1() == NULL ) + { + // parentless classes are put into the root branch + + wxTreeItemId* pId = new wxTreeItemId(); + *pId = pTree->AppendItem( parentBranchId, info.GetClassName(), classImageNo ); + + expand_item( pTree, *pId ); + + // "remember" it + hash.Put( long(&info), (wxObject*)pId ); + + // class is "hanged", remove it from the list + wxNode* pTmp = pCur; + + pCur = pCur->Next(); + + delete pTmp; + + ++nHanged; + } + else + { + wxTreeItemId* pParentId = (wxTreeItemId*)hash.Get( (long)info.GetBaseClass1() ); + + if ( pParentId != NULL ) + { + wxTreeItemId* pId = new wxTreeItemId(); + + *pId = pTree->AppendItem( *pParentId, info.GetClassName(), classImageNo ); + + expand_item( pTree, *pId ); + + hash.Put( long(&info), (wxObject*)pId ); + + wxNode* pTmp = pCur; + + pCur = pCur->Next(); + + // class is "hanged", remove it from the list + delete pTmp; + + ++nHanged; + } + else + { + // otherwise there's a parent, but it's not in the tree yet... + // hope to "hang" it in the subsequent passes + + pCur = pCur->Next(); + } + } + } + + } while( nHanged != 0 ); +} + +void wxCreateSerializerInfoTree( wxTreeCtrl* pTree, + wxTreeItemId parentBranchId, + long classImageNo + ) +{ + expand_item( pTree, parentBranchId ); + + wxSerializerInfo::InitializeSerializers(); + + // FOR NOW:: no hierarchy - one branch + + wxSerializerInfo* pCur = wxSerializerInfo::first; + + while( pCur ) + { + wxString fullName = pCur->className + wxString( "Serializer" ); + + pTree->AppendItem( parentBranchId, fullName, classImageNo ); + + pCur = pCur->next; + } +} diff --git a/utils/framelayout/src/wxinfo.h b/utils/framelayout/src/wxinfo.h new file mode 100644 index 0000000000..9e9d135ab4 --- /dev/null +++ b/utils/framelayout/src/wxinfo.h @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: No names yet. +// Purpose: Contrib. demo +// Author: Aleksandras Gluchovas +// Modified by: +// Created: 23/11/98 +// RCS-ID: $Id$ +// Copyright: 1998 (c) Aleksandras Gluchovas +// Licence: wxWindows license +///////////////////////////////////////////////////////////////////////////// + +#ifndef __WXINFO_G__ +#define __WXINFO_G__ + +#include "wx/object.h" +#include "wx/treectrl.h" + +#include "objstore.h" + +/* + * creates tree with hierarchically cauptured + * information about wxWindows dynamic classes (at "current run-time") + */ + +void wxCreateClassInfoTree( wxTreeCtrl* pTree, + wxTreeItemId parentBranchId, + long classImageNo = -1 + ); + +/* + * creates tree with information about + * serializer-classes (at current run-time) + * NOTE:: "objstore.cpp" should be compiled in + */ + +void wxCreateSerializerInfoTree( wxTreeCtrl* pTree, // existing tree control + wxTreeItemId parentBranchId, + long classImageNo = -1 // (-1) - text only + ); + +#endif -- 2.45.2