PageRenderTime 96ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 1ms

/vcl/source/window/toolbox.cxx

https://bitbucket.org/mst/ooo340
C++ | 6336 lines | 4948 code | 840 blank | 548 comment | 1285 complexity | 2d38d34c54a5464c50efa1bc8961fb0d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. /*************************************************************************
  2. *
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * Copyright 2000, 2010 Oracle and/or its affiliates.
  6. *
  7. * OpenOffice.org - a multi-platform office productivity suite
  8. *
  9. * This file is part of OpenOffice.org.
  10. *
  11. * OpenOffice.org is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Lesser General Public License version 3
  13. * only, as published by the Free Software Foundation.
  14. *
  15. * OpenOffice.org is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License version 3 for more details
  19. * (a copy is included in the LICENSE file that accompanied this code).
  20. *
  21. * You should have received a copy of the GNU Lesser General Public License
  22. * version 3 along with OpenOffice.org. If not, see
  23. * <http://www.openoffice.org/license.html>
  24. * for a copy of the LGPLv3 License.
  25. *
  26. ************************************************************************/
  27. // MARKER(update_precomp.py): autogen include statement, do not remove
  28. #include "precompiled_vcl.hxx"
  29. #ifndef _SV_SVSYS_HXX
  30. #include <svsys.h>
  31. #endif
  32. #include <rtl/logfile.hxx>
  33. #include <tools/list.hxx>
  34. #include <tools/debug.hxx>
  35. #ifndef _SV_RC_H
  36. #include <tools/rc.h>
  37. #endif
  38. #include <vcl/svdata.hxx>
  39. #include <vcl/event.hxx>
  40. #include <vcl/decoview.hxx>
  41. #include <vcl/accel.hxx>
  42. #include <vcl/svapp.hxx>
  43. #include <vcl/help.hxx>
  44. #include <vcl/sound.hxx>
  45. #include <vcl/virdev.hxx>
  46. #include <vcl/spin.h>
  47. #include <vcl/toolbox.hxx>
  48. #include <vcl/toolbox.h>
  49. #include <vcl/bitmap.hxx>
  50. #include <tools/poly.hxx>
  51. #include <vcl/salframe.hxx>
  52. #include <vcl/mnemonic.hxx>
  53. #include <vcl/gradient.hxx>
  54. #include <vcl/menu.hxx>
  55. #include <vcl/window.h>
  56. #include <string.h>
  57. #include <vector>
  58. #include <math.h>
  59. // =======================================================================
  60. DBG_NAMEEX( Window )
  61. // =======================================================================
  62. #define SMALLBUTTON_HSIZE 7
  63. #define SMALLBUTTON_VSIZE 7
  64. #define SMALLBUTTON_OFF_NORMAL_X 3
  65. #define SMALLBUTTON_OFF_NORMAL_Y 3
  66. #define SMALLBUTTON_OFF_CHECKED_X 4
  67. #define SMALLBUTTON_OFF_CHECKED_Y 4
  68. #define SMALLBUTTON_OFF_PRESSED_X 5
  69. #define SMALLBUTTON_OFF_PRESSED_Y 5
  70. #define OUTBUTTON_SIZE 6
  71. #define OUTBUTTON_BORDER 4
  72. #define OUTBUTTON_OFF_NORMAL_X 1
  73. #define OUTBUTTON_OFF_NORMAL_Y 1
  74. // -----------------------------------------------------------------------
  75. #define DEF_MIN_WIDTH 8
  76. #define DEF_MIN_HEIGHT 8
  77. #define DEF_TEXT_WIDTH 40
  78. #define TB_TEXTOFFSET 2
  79. #define TB_IMAGETEXTOFFSET 3
  80. #define TB_LINESPACING 3
  81. #define TB_SPIN_SIZE 14
  82. #define TB_SPIN_OFFSET 2
  83. #define TB_NEXT_SIZE 22
  84. #define TB_NEXT_OFFSET 2
  85. #define TB_BORDER_OFFSET1 4
  86. #define TB_BORDER_OFFSET2 2
  87. #define TB_CUSTOMIZE_OFFSET 2
  88. #define TB_RESIZE_OFFSET 3
  89. #define TB_MAXLINES 5
  90. #define TB_MAXNOSCROLL 32765
  91. #define TB_MIN_WIN_WIDTH 20
  92. #define TB_CALCMODE_HORZ 1
  93. #define TB_CALCMODE_VERT 2
  94. #define TB_CALCMODE_FLOAT 3
  95. #define TB_WBLINESIZING (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
  96. #define TB_MAX_GROUPS 100
  97. #define DOCK_LINEHSIZE ((USHORT)0x0001)
  98. #define DOCK_LINEVSIZE ((USHORT)0x0002)
  99. #define DOCK_LINERIGHT ((USHORT)0x1000)
  100. #define DOCK_LINEBOTTOM ((USHORT)0x2000)
  101. #define DOCK_LINELEFT ((USHORT)0x4000)
  102. #define DOCK_LINETOP ((USHORT)0x8000)
  103. #define DOCK_LINEOFFSET 3
  104. // -----------------------------------------------------------------------
  105. static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, USHORT highlight, BOOL bChecked, BOOL bEnabled, BOOL bIsWindow );
  106. // -----------------------------------------------------------------------
  107. struct ImplToolSize
  108. {
  109. long mnWidth;
  110. long mnHeight;
  111. USHORT mnLines;
  112. };
  113. struct ImplToolSizeArray
  114. {
  115. long mnLength;
  116. long mnLastEntry;
  117. ImplToolSize* mpSize;
  118. ImplToolSizeArray() { mpSize = NULL; mnLength = 0; mnLastEntry = 0; }
  119. ~ImplToolSizeArray() { if( mpSize ) delete [] mpSize; mnLength = 0; }
  120. };
  121. // -----------------------------------------------------------------------
  122. DECLARE_LIST( ImplTBList, ToolBox* )
  123. class ImplTBDragMgr
  124. {
  125. private:
  126. ImplTBList* mpBoxList;
  127. ToolBox* mpDragBox;
  128. Point maMouseOff;
  129. Rectangle maRect;
  130. Rectangle maStartRect;
  131. Accelerator maAccel;
  132. long mnMinWidth;
  133. long mnMaxWidth;
  134. USHORT mnLineMode;
  135. USHORT mnStartLines;
  136. void* mpCustomizeData;
  137. BOOL mbCustomizeMode;
  138. BOOL mbResizeMode;
  139. BOOL mbShowDragRect;
  140. public:
  141. ImplTBDragMgr();
  142. ~ImplTBDragMgr();
  143. void Insert( ToolBox* pBox )
  144. { mpBoxList->Insert( pBox ); }
  145. void Remove( ToolBox* pBox )
  146. { mpBoxList->Remove( pBox ); }
  147. ULONG Count() const
  148. { return mpBoxList->Count(); }
  149. ToolBox* FindToolBox( const Rectangle& rRect );
  150. void StartDragging( ToolBox* pDragBox,
  151. const Point& rPos, const Rectangle& rRect,
  152. USHORT nLineMode, BOOL bResizeItem,
  153. void* pData = NULL );
  154. void Dragging( const Point& rPos );
  155. void EndDragging( BOOL bOK = TRUE );
  156. void HideDragRect() { if ( mbShowDragRect ) mpDragBox->HideTracking(); }
  157. void UpdateDragRect();
  158. DECL_LINK( SelectHdl, Accelerator* );
  159. void StartCustomizeMode();
  160. void EndCustomizeMode();
  161. BOOL IsCustomizeMode() { return mbCustomizeMode; }
  162. BOOL IsResizeMode() { return mbResizeMode; }
  163. };
  164. // -----------------------------------------------------------------------
  165. static ImplTBDragMgr* ImplGetTBDragMgr()
  166. {
  167. ImplSVData* pSVData = ImplGetSVData();
  168. if ( !pSVData->maCtrlData.mpTBDragMgr )
  169. pSVData->maCtrlData.mpTBDragMgr = new ImplTBDragMgr;
  170. return pSVData->maCtrlData.mpTBDragMgr;
  171. }
  172. // -----------------------------------------------------------------------
  173. int ToolBox::ImplGetDragWidth( ToolBox* pThis )
  174. {
  175. #define TB_DRAGWIDTH 8 // the default width of the grip
  176. int width = TB_DRAGWIDTH;
  177. if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) )
  178. {
  179. ImplControlValue aControlValue;
  180. Point aPoint;
  181. Region aContent, aBound;
  182. Region aArea( Rectangle(aPoint, pThis->GetOutputSizePixel()) );
  183. if ( pThis->GetNativeControlRegion(CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
  184. aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
  185. {
  186. width = pThis->mbHorz ? aContent.GetBoundRect().GetWidth() : aContent.GetBoundRect().GetHeight();
  187. }
  188. }
  189. return width;
  190. }
  191. ButtonType determineButtonType( ImplToolItem* pItem, ButtonType defaultType )
  192. {
  193. ButtonType tmpButtonType = defaultType;
  194. ToolBoxItemBits nBits( pItem->mnBits & 0x300 );
  195. if ( nBits & TIB_TEXTICON ) // item has custom setting
  196. {
  197. tmpButtonType = BUTTON_SYMBOLTEXT;
  198. if ( nBits == TIB_TEXT_ONLY )
  199. tmpButtonType = BUTTON_TEXT;
  200. else if ( nBits == TIB_ICON_ONLY )
  201. tmpButtonType = BUTTON_SYMBOL;
  202. }
  203. return tmpButtonType;
  204. }
  205. // -----------------------------------------------------------------------
  206. void ToolBox::ImplUpdateDragArea( ToolBox *pThis )
  207. {
  208. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  209. if( pWrapper )
  210. {
  211. if ( pThis->ImplIsFloatingMode() || pWrapper->IsLocked() )
  212. pWrapper->SetDragArea( Rectangle() );
  213. else
  214. {
  215. if( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
  216. pWrapper->SetDragArea( Rectangle( 0, 0, ImplGetDragWidth( pThis ), pThis->GetOutputSizePixel().Height() ) );
  217. else
  218. pWrapper->SetDragArea( Rectangle( 0, 0, pThis->GetOutputSizePixel().Width(), ImplGetDragWidth( pThis ) ) );
  219. }
  220. }
  221. }
  222. // -----------------------------------------------------------------------
  223. void ToolBox::ImplCalcBorder( WindowAlign eAlign, long& rLeft, long& rTop,
  224. long& rRight, long& rBottom, const ToolBox *pThis )
  225. {
  226. if( pThis->ImplIsFloatingMode() || !(pThis->mnWinStyle & WB_BORDER) )
  227. {
  228. // no border in floating mode
  229. rLeft = rTop = rRight = rBottom = 0;
  230. return;
  231. }
  232. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  233. // reserve dragarea only for dockable toolbars
  234. int dragwidth = ( pWrapper && !pWrapper->IsLocked() ) ? ImplGetDragWidth( (ToolBox*)pThis ) : 0;
  235. // no shadow border for dockable toolbars
  236. int borderwidth = pWrapper ? 0: 2;
  237. if ( eAlign == WINDOWALIGN_TOP )
  238. {
  239. rLeft = borderwidth+dragwidth;
  240. rTop = borderwidth;
  241. rRight = borderwidth;
  242. rBottom = 0;
  243. }
  244. else if ( eAlign == WINDOWALIGN_LEFT )
  245. {
  246. rLeft = borderwidth;
  247. rTop = borderwidth+dragwidth;
  248. rRight = 0;
  249. rBottom = borderwidth;
  250. }
  251. else if ( eAlign == WINDOWALIGN_BOTTOM )
  252. {
  253. rLeft = borderwidth+dragwidth;
  254. rTop = 0;
  255. rRight = borderwidth;
  256. rBottom = borderwidth;
  257. }
  258. else
  259. {
  260. rLeft = 0;
  261. rTop = borderwidth+dragwidth;
  262. rRight = borderwidth;
  263. rBottom = borderwidth;
  264. }
  265. }
  266. // -----------------------------------------------------------------------
  267. static void ImplCheckUpdate( ToolBox *pThis )
  268. {
  269. // remove any pending invalidates to avoid
  270. // have them triggered when paint is locked (see mpData->mbIsPaintLocked)
  271. // which would result in erasing the background only and not painting any items
  272. // this must not be done when we're already in Paint()
  273. // this is only required for transparent toolbars (see ImplDrawTransparentBackground() )
  274. if( !pThis->IsBackground() && pThis->HasPaintEvent() && !pThis->IsInPaint() )
  275. pThis->Update();
  276. }
  277. // -----------------------------------------------------------------------
  278. void ToolBox::ImplDrawGrip( ToolBox* pThis )
  279. {
  280. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  281. if( pWrapper && !pWrapper->GetDragArea().IsEmpty() )
  282. {
  283. // execute pending paint requests
  284. ImplCheckUpdate( pThis );
  285. BOOL bNativeOk = FALSE;
  286. if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_HORZ : PART_THUMB_VERT ) )
  287. {
  288. ImplControlValue aControlValue;
  289. ToolbarValue aToolbarValue;
  290. aToolbarValue.maGripRect = pWrapper->GetDragArea();
  291. aControlValue.setOptionalVal( (void *)(&aToolbarValue) );
  292. Point aPt;
  293. Region aCtrlRegion( Rectangle( aPt, pThis->GetOutputSizePixel() ) );
  294. ControlState nState = CTRL_STATE_ENABLED;
  295. bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
  296. aCtrlRegion, nState, aControlValue, rtl::OUString() );
  297. }
  298. if( bNativeOk )
  299. return;
  300. const StyleSettings& rStyleSettings = pThis->GetSettings().GetStyleSettings();
  301. pThis->SetLineColor( rStyleSettings.GetShadowColor() );
  302. Size aSz ( pThis->GetOutputSizePixel() );
  303. if ( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
  304. {
  305. int height = (int) (0.6 * aSz.Height() + 0.5);
  306. int i = (aSz.Height() - height) / 2;
  307. height += i;
  308. while( i <= height )
  309. {
  310. int x = ImplGetDragWidth( pThis ) / 2;
  311. pThis->DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
  312. pThis->DrawPixel( Point(x+1, i), rStyleSettings.GetShadowColor() );
  313. pThis->DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
  314. pThis->DrawPixel( Point(x+1, i+1), rStyleSettings.GetFaceColor() );
  315. pThis->DrawPixel( Point(x+2, i+1), Color(COL_WHITE) );
  316. pThis->DrawPixel( Point(x+1, i+2), Color(COL_WHITE) );
  317. pThis->DrawPixel( Point(x+2, i+2), Color(COL_WHITE) );
  318. i+=4;
  319. }
  320. }
  321. else
  322. {
  323. int width = (int) (0.6 * aSz.Width() + 0.5);
  324. int i = (aSz.Width() - width) / 2;
  325. width += i;
  326. while( i <= width )
  327. {
  328. int y = ImplGetDragWidth(pThis) / 2;
  329. pThis->DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
  330. pThis->DrawPixel( Point(i+1, y), rStyleSettings.GetShadowColor() );
  331. pThis->DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
  332. pThis->DrawPixel( Point(i+1, y+1), rStyleSettings.GetFaceColor() );
  333. pThis->DrawPixel( Point(i+2, y+1), Color(COL_WHITE) );
  334. pThis->DrawPixel( Point(i+1, y+2), Color(COL_WHITE) );
  335. pThis->DrawPixel( Point(i+2, y+2), Color(COL_WHITE) );
  336. i+=4;
  337. }
  338. }
  339. }
  340. }
  341. void ToolBox::ImplDrawGradientBackground( ToolBox* pThis, ImplDockingWindowWrapper * )
  342. {
  343. // draw a nice gradient
  344. Color startCol, endCol;
  345. startCol = pThis->GetSettings().GetStyleSettings().GetFaceGradientColor();
  346. endCol = pThis->GetSettings().GetStyleSettings().GetFaceColor();
  347. if( pThis->GetSettings().GetStyleSettings().GetHighContrastMode() )
  348. // no 'extreme' gradient when high contrast
  349. startCol = endCol;
  350. Gradient g;
  351. g.SetAngle( pThis->mbHorz ? 0 : 900 );
  352. g.SetStyle( GRADIENT_LINEAR );
  353. g.SetStartColor( startCol );
  354. g.SetEndColor( endCol );
  355. BOOL bLineColor = pThis->IsLineColor();
  356. Color aOldCol = pThis->GetLineColor();
  357. pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetShadowColor() );
  358. Size aFullSz( pThis->GetOutputSizePixel() );
  359. Size aLineSz( aFullSz );
  360. // use the linesize only when floating
  361. // full window height is used when docked (single line)
  362. if( pThis->ImplIsFloatingMode() )
  363. {
  364. long nLineSize;
  365. if( pThis->mbHorz )
  366. {
  367. nLineSize = pThis->mnMaxItemHeight;
  368. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  369. nLineSize = pThis->mnWinHeight;
  370. aLineSz.Height() = nLineSize;
  371. }
  372. else
  373. {
  374. nLineSize = pThis->mnMaxItemWidth;
  375. aLineSz.Width() = nLineSize;
  376. }
  377. }
  378. long nLeft, nTop, nRight, nBottom;
  379. ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
  380. Size aTopLineSz( aLineSz );
  381. Size aBottomLineSz( aLineSz );
  382. if ( pThis->mnWinStyle & WB_BORDER )
  383. {
  384. if( pThis->mbHorz )
  385. {
  386. aTopLineSz.Height() += TB_BORDER_OFFSET2 + nTop;
  387. aBottomLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
  388. if( pThis->mnCurLines == 1 )
  389. aTopLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
  390. }
  391. else
  392. {
  393. aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
  394. aBottomLineSz.Width() += TB_BORDER_OFFSET1 + nRight;
  395. if( pThis->mnCurLines == 1 )
  396. aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
  397. }
  398. }
  399. if( pThis->mbHorz )
  400. {
  401. aTopLineSz.Height() += pThis->mnBorderY;
  402. if( pThis->mnCurLines == 1 )
  403. aTopLineSz.Height() += pThis->mnBorderY;
  404. aBottomLineSz.Height() += pThis->mnBorderY;
  405. }
  406. else
  407. {
  408. aTopLineSz.Width() += pThis->mnBorderX;
  409. if( pThis->mnCurLines == 1 )
  410. aTopLineSz.Width() += pThis->mnBorderX;
  411. aBottomLineSz.Width() += pThis->mnBorderX;
  412. }
  413. if ( pThis->mnWinStyle & WB_LINESPACING )
  414. {
  415. if( pThis->mbHorz )
  416. {
  417. aLineSz.Height() += TB_LINESPACING;
  418. if( pThis->mnCurLines > 1 )
  419. aTopLineSz.Height() += TB_LINESPACING;
  420. }
  421. else
  422. {
  423. aLineSz.Width() += TB_LINESPACING;
  424. if( pThis->mnCurLines > 1 )
  425. aTopLineSz.Width() += TB_LINESPACING;
  426. }
  427. }
  428. if( pThis->mbHorz )
  429. {
  430. long y = 0;
  431. BOOL bDrawSep = FALSE; // pThis->ImplIsFloatingMode() && ( pThis->mnWinStyle & WB_LINESPACING );
  432. pThis->DrawGradient( Rectangle( 0, y, aTopLineSz.Width(), y+aTopLineSz.Height()), g );
  433. y += aTopLineSz.Height();
  434. if ( bDrawSep )
  435. pThis->DrawLine( Point(0, y-2), Point(aTopLineSz.Width(), y-2) );
  436. while( y < (pThis->mnDY - aBottomLineSz.Height()) )
  437. {
  438. pThis->DrawGradient( Rectangle( 0, y, aLineSz.Width(), y+aLineSz.Height()), g);
  439. y += aLineSz.Height();
  440. if ( bDrawSep )
  441. pThis->DrawLine( Point(0, y-2), Point(aLineSz.Width(), y-2) );
  442. }
  443. pThis->DrawGradient( Rectangle( 0, y, aBottomLineSz.Width(), y+aBottomLineSz.Height()), g );
  444. if ( bDrawSep )
  445. pThis->DrawLine( Point(0, y-2), Point(aBottomLineSz.Width(), y-2) );
  446. }
  447. else
  448. {
  449. long x = 0;
  450. pThis->DrawGradient( Rectangle( x, 0, x+aTopLineSz.Width(), aTopLineSz.Height()), g );
  451. x += aTopLineSz.Width();
  452. while( x < (pThis->mnDX - aBottomLineSz.Width()) )
  453. {
  454. pThis->DrawGradient( Rectangle( x, 0, x+aLineSz.Width(), aLineSz.Height()), g);
  455. x += aLineSz.Width();
  456. }
  457. pThis->DrawGradient( Rectangle( x, 0, x+aBottomLineSz.Width(), aBottomLineSz.Height()), g );
  458. }
  459. if( bLineColor )
  460. pThis->SetLineColor( aOldCol );
  461. }
  462. BOOL ToolBox::ImplDrawNativeBackground( ToolBox* pThis, const Region & )
  463. {
  464. // use NWF
  465. Point aPt;
  466. Region aCtrlRegion( Rectangle( aPt, pThis->GetOutputSizePixel() ) );
  467. ControlState nState = CTRL_STATE_ENABLED;
  468. return pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT,
  469. aCtrlRegion, nState, ImplControlValue(), rtl::OUString() );
  470. }
  471. void ToolBox::ImplDrawTransparentBackground( ToolBox* pThis, const Region &rRegion )
  472. {
  473. // just invalidate to trigger paint of the parent
  474. const bool bOldPaintLock = pThis->mpData->mbIsPaintLocked;
  475. pThis->mpData->mbIsPaintLocked = true;
  476. // send an invalidate to the first opaque parent and invalidate the whole hierarchy from there (noclipchildren)
  477. pThis->Invalidate( rRegion, INVALIDATE_UPDATE|INVALIDATE_NOCLIPCHILDREN );
  478. pThis->mpData->mbIsPaintLocked = bOldPaintLock;
  479. }
  480. void ToolBox::ImplDrawConstantBackground( ToolBox* pThis, const Region &rRegion, BOOL bIsInPopupMode )
  481. {
  482. // draw a constant color
  483. if( !bIsInPopupMode )
  484. // default background
  485. pThis->Erase( rRegion.GetBoundRect() );
  486. else
  487. {
  488. // use different color in popupmode
  489. pThis->DrawWallpaper( rRegion.GetBoundRect(),
  490. Wallpaper( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() ) );
  491. }
  492. }
  493. void ToolBox::ImplDrawBackground( ToolBox* pThis, const Rectangle &rRect )
  494. {
  495. // execute pending paint requests
  496. ImplCheckUpdate( pThis );
  497. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  498. BOOL bIsInPopupMode = pThis->ImplIsInPopupMode();
  499. Region aPaintRegion( rRect );
  500. // make sure we do not invalidate/erase too much
  501. if( pThis->IsInPaint() )
  502. aPaintRegion.Intersect( pThis->GetActiveClipRegion() );
  503. pThis->Push( PUSH_CLIPREGION );
  504. pThis->IntersectClipRegion( aPaintRegion );
  505. if( !pWrapper /*|| bIsInPopupMode*/ )
  506. {
  507. // no gradient for ordinary toolbars (not dockable)
  508. if( !pThis->IsBackground() && !pThis->IsInPaint() )
  509. ImplDrawTransparentBackground( pThis, aPaintRegion );
  510. else
  511. ImplDrawConstantBackground( pThis, aPaintRegion, bIsInPopupMode );
  512. }
  513. else
  514. {
  515. // toolbars known to the dockingmanager will be drawn using NWF or a gradient
  516. // docked toolbars are transparent and NWF is already used in the docking area which is their common background
  517. // so NWF is used here for floating toolbars only
  518. BOOL bNativeOk = FALSE;
  519. if( pThis->ImplIsFloatingMode() && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL) )
  520. bNativeOk = ImplDrawNativeBackground( pThis, aPaintRegion );
  521. if( !bNativeOk )
  522. {
  523. if( !pThis->IsBackground() )
  524. {
  525. if( !pThis->IsInPaint() )
  526. ImplDrawTransparentBackground( pThis, aPaintRegion );
  527. }
  528. else
  529. ImplDrawGradientBackground( pThis, pWrapper );
  530. }
  531. }
  532. // restore clip region
  533. pThis->Pop();
  534. }
  535. void ToolBox::ImplErase( ToolBox* pThis, const Rectangle &rRect, BOOL bHighlight, BOOL bHasOpenPopup )
  536. {
  537. // the background of non NWF buttons is painted in a constant color
  538. // to have the same highlight color (transparency in DrawSelectionBackground())
  539. // items with open popups will also painted using a constant color
  540. if( !pThis->mpData->mbNativeButtons &&
  541. (bHighlight || ! (((Window*) pThis)->GetStyle() & WB_3DLOOK ) ) )
  542. {
  543. if( (((Window*) pThis)->GetStyle() & WB_3DLOOK ) )
  544. {
  545. pThis->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
  546. pThis->SetLineColor();
  547. if( bHasOpenPopup )
  548. // choose the same color as the popup will use
  549. pThis->SetFillColor( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() );
  550. else
  551. pThis->SetFillColor( Color( COL_WHITE ) );
  552. pThis->DrawRect( rRect );
  553. pThis->Pop();
  554. }
  555. else
  556. ImplDrawBackground( pThis, rRect );
  557. }
  558. else
  559. ImplDrawBackground( pThis, rRect );
  560. }
  561. void ToolBox::ImplDrawBorder( ToolBox* pWin )
  562. {
  563. const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
  564. long nDX = pWin->mnDX;
  565. long nDY = pWin->mnDY;
  566. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pWin );
  567. // draw borders for ordinary toolbars only (not dockable)
  568. if( pWrapper )
  569. return;
  570. if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
  571. {
  572. // draw bottom border
  573. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  574. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
  575. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  576. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  577. }
  578. else
  579. {
  580. // draw top border
  581. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  582. pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
  583. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  584. pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
  585. if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
  586. {
  587. if ( pWin->meAlign == WINDOWALIGN_LEFT )
  588. {
  589. // draw left-bottom border
  590. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  591. pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
  592. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
  593. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  594. pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
  595. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  596. }
  597. else
  598. {
  599. // draw right-bottom border
  600. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  601. pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
  602. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
  603. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  604. pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
  605. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  606. }
  607. }
  608. }
  609. if ( pWin->meAlign == WINDOWALIGN_BOTTOM || pWin->meAlign == WINDOWALIGN_TOP )
  610. {
  611. // draw right border
  612. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  613. pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
  614. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  615. pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
  616. }
  617. }
  618. // -----------------------------------------------------------------------
  619. static bool ImplIsFixedControl( const ImplToolItem *pItem )
  620. {
  621. return ( pItem->mpWindow &&
  622. (pItem->mpWindow->GetType() == WINDOW_FIXEDTEXT ||
  623. pItem->mpWindow->GetType() == WINDOW_FIXEDLINE ||
  624. pItem->mpWindow->GetType() == WINDOW_GROUPBOX) );
  625. }
  626. // -----------------------------------------------------------------------
  627. const ImplToolItem *ToolBox::ImplGetFirstClippedItem( const ToolBox* pThis )
  628. {
  629. std::vector< ImplToolItem >::const_iterator it;
  630. it = pThis->mpData->m_aItems.begin();
  631. while ( it != pThis->mpData->m_aItems.end() )
  632. {
  633. if( it->IsClipped() )
  634. return &(*it);
  635. ++it;
  636. }
  637. return NULL;
  638. }
  639. // -----------------------------------------------------------------------
  640. Size ToolBox::ImplCalcSize( const ToolBox* pThis, USHORT nCalcLines, USHORT nCalcMode )
  641. {
  642. long nMax;
  643. long nLeft = 0;
  644. long nTop = 0;
  645. long nRight = 0;
  646. long nBottom = 0;
  647. Size aSize;
  648. WindowAlign eOldAlign = pThis->meAlign;
  649. BOOL bOldHorz = pThis->mbHorz;
  650. BOOL bOldAssumeDocked = pThis->mpData->mbAssumeDocked;
  651. BOOL bOldAssumeFloating = pThis->mpData->mbAssumeFloating;
  652. if ( nCalcMode )
  653. {
  654. BOOL bOldFloatingMode = pThis->ImplIsFloatingMode();
  655. pThis->mpData->mbAssumeDocked = FALSE;
  656. pThis->mpData->mbAssumeFloating = FALSE;
  657. if ( nCalcMode == TB_CALCMODE_HORZ )
  658. {
  659. pThis->mpData->mbAssumeDocked = TRUE; // force non-floating mode during calculation
  660. ImplCalcBorder( WINDOWALIGN_TOP, nLeft, nTop, nRight, nBottom, pThis );
  661. ((ToolBox*)pThis)->mbHorz = TRUE;
  662. if ( pThis->mbHorz != bOldHorz )
  663. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
  664. }
  665. else if ( nCalcMode == TB_CALCMODE_VERT )
  666. {
  667. pThis->mpData->mbAssumeDocked = TRUE; // force non-floating mode during calculation
  668. ImplCalcBorder( WINDOWALIGN_LEFT, nLeft, nTop, nRight, nBottom, pThis );
  669. ((ToolBox*)pThis)->mbHorz = FALSE;
  670. if ( pThis->mbHorz != bOldHorz )
  671. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_LEFT;
  672. }
  673. else if ( nCalcMode == TB_CALCMODE_FLOAT )
  674. {
  675. pThis->mpData->mbAssumeFloating = TRUE; // force non-floating mode during calculation
  676. nLeft = nTop = nRight = nBottom = 0;
  677. ((ToolBox*)pThis)->mbHorz = TRUE;
  678. if ( pThis->mbHorz != bOldHorz )
  679. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
  680. }
  681. if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) ||
  682. (pThis->ImplIsFloatingMode() != bOldFloatingMode ) )
  683. ((ToolBox*)pThis)->mbCalc = TRUE;
  684. }
  685. else
  686. ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
  687. ((ToolBox*)pThis)->ImplCalcItem();
  688. if( !nCalcMode && pThis->ImplIsFloatingMode() )
  689. {
  690. aSize = ImplCalcFloatSize( ((ToolBox*)pThis), nCalcLines );
  691. }
  692. else
  693. {
  694. if ( pThis->mbHorz )
  695. {
  696. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  697. aSize.Height() = nCalcLines * pThis->mnWinHeight;
  698. else
  699. aSize.Height() = nCalcLines * pThis->mnMaxItemHeight;
  700. if ( pThis->mnWinStyle & WB_LINESPACING )
  701. aSize.Height() += (nCalcLines-1)*TB_LINESPACING;
  702. if ( pThis->mnWinStyle & WB_BORDER )
  703. aSize.Height() += (TB_BORDER_OFFSET2*2) + nTop + nBottom;
  704. nMax = 0;
  705. ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
  706. if ( nMax )
  707. aSize.Width() += nMax;
  708. if ( pThis->mnWinStyle & WB_BORDER )
  709. aSize.Width() += (TB_BORDER_OFFSET1*2) + nLeft + nRight;
  710. }
  711. else
  712. {
  713. aSize.Width() = nCalcLines * pThis->mnMaxItemWidth;
  714. if ( pThis->mnWinStyle & WB_LINESPACING )
  715. aSize.Width() += (nCalcLines-1)*TB_LINESPACING;
  716. if ( pThis->mnWinStyle & WB_BORDER )
  717. aSize.Width() += (TB_BORDER_OFFSET2*2) + nLeft + nRight;
  718. nMax = 0;
  719. ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
  720. if ( nMax )
  721. aSize.Height() += nMax;
  722. if ( pThis->mnWinStyle & WB_BORDER )
  723. aSize.Height() += (TB_BORDER_OFFSET1*2) + nTop + nBottom;
  724. }
  725. }
  726. // restore previous values
  727. if ( nCalcMode )
  728. {
  729. pThis->mpData->mbAssumeDocked = bOldAssumeDocked;
  730. pThis->mpData->mbAssumeFloating = bOldAssumeFloating;
  731. if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) )
  732. {
  733. ((ToolBox*)pThis)->meAlign = eOldAlign;
  734. ((ToolBox*)pThis)->mbHorz = bOldHorz;
  735. ((ToolBox*)pThis)->mbCalc = TRUE;
  736. }
  737. }
  738. if ( aSize.Width() )
  739. aSize.Width() += pThis->mnBorderX*2;
  740. if ( aSize.Height() )
  741. aSize.Height() += pThis->mnBorderY*2;
  742. return aSize;
  743. }
  744. // -----------------------------------------------------------------------
  745. void ToolBox::ImplCalcFloatSizes( ToolBox* pThis )
  746. {
  747. if ( pThis->mpFloatSizeAry )
  748. return;
  749. // calculate the minimal size, i.e. where the biggest item just fits
  750. long nCalcSize = 0;
  751. std::vector< ImplToolItem >::const_iterator it;
  752. it = pThis->mpData->m_aItems.begin();
  753. while ( it != pThis->mpData->m_aItems.end() )
  754. {
  755. if ( it->mbVisible )
  756. {
  757. if ( it->mpWindow )
  758. {
  759. long nTempSize = it->mpWindow->GetSizePixel().Width();
  760. if ( nTempSize > nCalcSize )
  761. nCalcSize = nTempSize;
  762. }
  763. else
  764. {
  765. if( it->maItemSize.Width() > nCalcSize )
  766. nCalcSize = it->maItemSize.Width();
  767. }
  768. }
  769. ++it;
  770. }
  771. // calc an upper bound for ImplCalcBreaks below
  772. long upperBoundWidth = nCalcSize * pThis->mpData->m_aItems.size();
  773. USHORT i;
  774. USHORT nLines;
  775. USHORT nCalcLines;
  776. USHORT nTempLines;
  777. long nHeight;
  778. long nMaxLineWidth;
  779. nCalcLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, TRUE );
  780. pThis->mpFloatSizeAry = new ImplToolSizeArray;
  781. pThis->mpFloatSizeAry->mpSize = new ImplToolSize[nCalcLines];
  782. pThis->mpFloatSizeAry->mnLength = nCalcLines;
  783. memset( pThis->mpFloatSizeAry->mpSize, 0, sizeof( ImplToolSize )*nCalcLines );
  784. i = 0;
  785. nTempLines = nLines = nCalcLines;
  786. while ( nLines )
  787. {
  788. nHeight = ImplCalcSize( pThis, nTempLines, TB_CALCMODE_FLOAT ).Height();
  789. pThis->mpFloatSizeAry->mnLastEntry = i;
  790. pThis->mpFloatSizeAry->mpSize[i].mnHeight = nHeight;
  791. pThis->mpFloatSizeAry->mpSize[i].mnLines = nTempLines;
  792. pThis->mpFloatSizeAry->mpSize[i].mnWidth = nMaxLineWidth+(TB_BORDER_OFFSET1*2);
  793. nLines--;
  794. if ( nLines )
  795. {
  796. do
  797. {
  798. nCalcSize += pThis->mnMaxItemWidth;
  799. nTempLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, TRUE );
  800. }
  801. while ( (nCalcSize < upperBoundWidth) && (nLines < nTempLines) && (nTempLines != 1) );
  802. if ( nTempLines < nLines )
  803. nLines = nTempLines;
  804. }
  805. i++;
  806. }
  807. }
  808. // -----------------------------------------------------------------------
  809. Size ToolBox::ImplCalcFloatSize( ToolBox* pThis, USHORT& rLines )
  810. {
  811. ImplCalcFloatSizes( pThis );
  812. if ( !rLines )
  813. {
  814. rLines = pThis->mnFloatLines;
  815. if ( !rLines )
  816. rLines = pThis->mnLines;
  817. }
  818. USHORT i = 0;
  819. while ( i < pThis->mpFloatSizeAry->mnLastEntry &&
  820. rLines < pThis->mpFloatSizeAry->mpSize[i].mnLines )
  821. i++;
  822. Size aSize( pThis->mpFloatSizeAry->mpSize[i].mnWidth,
  823. pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  824. rLines = pThis->mpFloatSizeAry->mpSize[i].mnLines;
  825. if ( pThis->maNextToolBoxStr.Len() && pThis->mbScroll )
  826. aSize.Width() += TB_NEXT_SIZE-TB_NEXT_OFFSET;
  827. return aSize;
  828. }
  829. // -----------------------------------------------------------------------
  830. void ToolBox::ImplCalcMinMaxFloatSize( ToolBox* pThis, Size& rMinSize, Size& rMaxSize )
  831. {
  832. ImplCalcFloatSizes( pThis );
  833. USHORT i = 0;
  834. rMinSize = Size( pThis->mpFloatSizeAry->mpSize[i].mnWidth, pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  835. rMaxSize = Size( pThis->mpFloatSizeAry->mpSize[i].mnWidth, pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  836. while ( ++i <= pThis->mpFloatSizeAry->mnLastEntry )
  837. {
  838. if( pThis->mpFloatSizeAry->mpSize[i].mnWidth < rMinSize.Width() )
  839. rMinSize.Width() = pThis->mpFloatSizeAry->mpSize[i].mnWidth;
  840. if( pThis->mpFloatSizeAry->mpSize[i].mnHeight < rMinSize.Height() )
  841. rMinSize.Height() = pThis->mpFloatSizeAry->mpSize[i].mnHeight;
  842. if( pThis->mpFloatSizeAry->mpSize[i].mnWidth > rMaxSize.Width() )
  843. rMaxSize.Width() = pThis->mpFloatSizeAry->mpSize[i].mnWidth;
  844. if( pThis->mpFloatSizeAry->mpSize[i].mnHeight > rMaxSize.Height() )
  845. rMaxSize.Height() = pThis->mpFloatSizeAry->mpSize[i].mnHeight;
  846. }
  847. }
  848. void ToolBox::ImplSetMinMaxFloatSize( ToolBox *pThis )
  849. {
  850. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  851. Size aMinSize, aMaxSize;
  852. ImplCalcMinMaxFloatSize( pThis, aMinSize, aMaxSize );
  853. if( pWrapper )
  854. {
  855. pWrapper->SetMinOutputSizePixel( aMinSize );
  856. pWrapper->SetMaxOutputSizePixel( aMaxSize );
  857. pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( pThis->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE) ? TRUE : FALSE );
  858. }
  859. else
  860. {
  861. // TODO: change SetMinOutputSizePixel to be not inline
  862. pThis->SetMinOutputSizePixel( aMinSize );
  863. pThis->SetMaxOutputSizePixel( aMaxSize );
  864. }
  865. }
  866. // -----------------------------------------------------------------------
  867. USHORT ToolBox::ImplCalcLines( ToolBox* pThis, long nToolSize )
  868. {
  869. long nLineHeight;
  870. if ( pThis->mbHorz )
  871. {
  872. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  873. nLineHeight = pThis->mnWinHeight;
  874. else
  875. nLineHeight = pThis->mnMaxItemHeight;
  876. }
  877. else
  878. nLineHeight = pThis->mnMaxItemWidth;
  879. if ( pThis->mnWinStyle & WB_BORDER )
  880. nToolSize -= TB_BORDER_OFFSET2*2;
  881. if ( pThis->mnWinStyle & WB_LINESPACING )
  882. {
  883. nLineHeight += TB_LINESPACING;
  884. nToolSize += TB_LINESPACING;
  885. }
  886. // #i91917# always report at least one line
  887. long nLines = nToolSize/nLineHeight;
  888. if( nLines < 1 )
  889. nLines = 1;
  890. return static_cast<USHORT>(nLines);
  891. }
  892. // -----------------------------------------------------------------------
  893. USHORT ToolBox::ImplTestLineSize( ToolBox* pThis, const Point& rPos )
  894. {
  895. if ( !pThis->ImplIsFloatingMode() &&
  896. (!pThis->mbScroll || (pThis->mnLines > 1) || (pThis->mnCurLines > pThis->mnVisLines)) )
  897. {
  898. WindowAlign eAlign = pThis->GetAlign();
  899. if ( eAlign == WINDOWALIGN_LEFT )
  900. {
  901. if ( rPos.X() > pThis->mnDX-DOCK_LINEOFFSET )
  902. return DOCK_LINEHSIZE | DOCK_LINERIGHT;
  903. }
  904. else if ( eAlign == WINDOWALIGN_TOP )
  905. {
  906. if ( rPos.Y() > pThis->mnDY-DOCK_LINEOFFSET )
  907. return DOCK_LINEVSIZE | DOCK_LINEBOTTOM;
  908. }
  909. else if ( eAlign == WINDOWALIGN_RIGHT )
  910. {
  911. if ( rPos.X() < DOCK_LINEOFFSET )
  912. return DOCK_LINEHSIZE | DOCK_LINELEFT;
  913. }
  914. else if ( eAlign == WINDOWALIGN_BOTTOM )
  915. {
  916. if ( rPos.Y() < DOCK_LINEOFFSET )
  917. return DOCK_LINEVSIZE | DOCK_LINETOP;
  918. }
  919. }
  920. return 0;
  921. }
  922. // -----------------------------------------------------------------------
  923. void ToolBox::ImplLineSizing( ToolBox* pThis, const Point& rPos, Rectangle& rRect,
  924. USHORT nLineMode )
  925. {
  926. BOOL mbHorz;
  927. long nOneLineSize;
  928. long nCurSize;
  929. long nMaxSize;
  930. long nSize;
  931. Size aSize;
  932. if ( nLineMode & DOCK_LINERIGHT )
  933. {
  934. nCurSize = rPos.X() - rRect.Left();
  935. mbHorz = FALSE;
  936. }
  937. else if ( nLineMode & DOCK_LINEBOTTOM )
  938. {
  939. nCurSize = rPos.Y() - rRect.Top();
  940. mbHorz = TRUE;
  941. }
  942. else if ( nLineMode & DOCK_LINELEFT )
  943. {
  944. nCurSize = rRect.Right() - rPos.X();
  945. mbHorz = FALSE;
  946. }
  947. else if ( nLineMode & DOCK_LINETOP )
  948. {
  949. nCurSize = rRect.Bottom() - rPos.Y();
  950. mbHorz = TRUE;
  951. }
  952. else {
  953. DBG_ERROR( "ImplLineSizing: Trailing else" );
  954. nCurSize = 0;
  955. mbHorz = FALSE;
  956. }
  957. Size aWinSize = pThis->GetSizePixel();
  958. USHORT nMaxLines = (pThis->mnLines > pThis->mnCurLines) ? pThis->mnLines : pThis->mnCurLines;
  959. if ( nMaxLines > TB_MAXLINES )
  960. nMaxLines = TB_MAXLINES;
  961. if ( mbHorz )
  962. {
  963. nOneLineSize = ImplCalcSize( pThis, 1 ).Height();
  964. nMaxSize = pThis->maOutDockRect.GetHeight() - 20;
  965. if ( nMaxSize < aWinSize.Height() )
  966. nMaxSize = aWinSize.Height();
  967. }
  968. else
  969. {
  970. nOneLineSize = ImplCalcSize( pThis, 1 ).Width();
  971. nMaxSize = pThis->maOutDockRect.GetWidth() - 20;
  972. if ( nMaxSize < aWinSize.Width() )
  973. nMaxSize = aWinSize.Width();
  974. }
  975. USHORT i = 1;
  976. if ( nCurSize <= nOneLineSize )
  977. nSize = nOneLineSize;
  978. else
  979. {
  980. nSize = 0;
  981. while ( (nSize < nCurSize) && (i < nMaxLines) )
  982. {
  983. i++;
  984. aSize = ImplCalcSize( pThis, i );
  985. if ( mbHorz )
  986. nSize = aSize.Height();
  987. else
  988. nSize = aSize.Width();
  989. if ( nSize > nMaxSize )
  990. {
  991. i--;
  992. aSize = ImplCalcSize( pThis, i );
  993. if ( mbHorz )
  994. nSize = aSize.Height();
  995. else
  996. nSize = aSize.Width();
  997. break;
  998. }
  999. }
  1000. }
  1001. if ( nLineMode & DOCK_LINERIGHT )
  1002. rRect.Right() = rRect.Left()+nSize-1;
  1003. else if ( nLineMode & DOCK_LINEBOTTOM )
  1004. rRect.Bottom() = rRect.Top()+nSize-1;
  1005. else if ( nLineMode & DOCK_LINELEFT )
  1006. rRect.Left() = rRect.Right()-nSize;
  1007. else //if ( nLineMode & DOCK_LINETOP )
  1008. rRect.Top() = rRect.Bottom()-nSize;
  1009. pThis->mnDockLines = i;
  1010. }
  1011. // -----------------------------------------------------------------------
  1012. USHORT ToolBox::ImplFindItemPos( ToolBox* pBox, const Point& rPos )
  1013. {
  1014. USHORT nPos = 0;
  1015. long nLast = 0;
  1016. Point aPos = rPos;
  1017. Size aSize( pBox->mnDX, pBox->mnDY );
  1018. if ( aPos.X() > aSize.Width()-TB_BORDER_OFFSET1 )
  1019. aPos.X() = aSize.Width()-TB_BORDER_OFFSET1;
  1020. if ( aPos.Y() > aSize.Height()-TB_BORDER_OFFSET1 )
  1021. aPos.Y() = aSize.Height()-TB_BORDER_OFFSET1;
  1022. // Item suchen, das geklickt wurde
  1023. std::vector< ImplToolItem >::const_iterator it = pBox->mpData->m_aItems.begin();
  1024. while ( it != pBox->mpData->m_aItems.end() )
  1025. {
  1026. if ( it->mbVisible )
  1027. {
  1028. if ( nLast || !it->maRect.IsEmpty() )
  1029. {
  1030. if ( pBox->mbHorz )
  1031. {
  1032. if ( nLast &&
  1033. ((nLast < it->maRect.Top()) || it->maRect.IsEmpty()) )
  1034. return nPos;
  1035. if ( aPos.Y() <= it->maRect.Bottom() )
  1036. {
  1037. if ( aPos.X() < it->maRect.Left() )
  1038. return nPos;
  1039. else if ( aPos.X() < it->maRect.Right() )
  1040. return nPos+1;
  1041. else if ( !nLast )
  1042. nLast = it->maRect.Bottom();
  1043. }
  1044. }
  1045. else
  1046. {
  1047. if ( nLast &&
  1048. ((nLast < it->maRect.Left()) || it->maRect.IsEmpty()) )
  1049. return nPos;
  1050. if ( aPos.X() <= it->maRect.Right() )
  1051. {
  1052. if ( aPos.Y() < it->maRect.Top() )
  1053. return nPos;
  1054. else if ( aPos.Y() < it->maRect.Bottom() )
  1055. return nPos+1;
  1056. else if ( !nLast )
  1057. nLast = it->maRect.Right();
  1058. }
  1059. }
  1060. }
  1061. }
  1062. nPos++;
  1063. ++it;
  1064. }
  1065. return nPos;
  1066. }
  1067. // -----------------------------------------------------------------------
  1068. ImplTBDragMgr::ImplTBDragMgr()
  1069. {
  1070. mpBoxList = new ImplTBList( 4, 4 );
  1071. mnLineMode = 0;
  1072. mnStartLines = 0;
  1073. mbCustomizeMode = FALSE;
  1074. mbResizeMode = FALSE;
  1075. mbShowDragRect = FALSE;
  1076. mpDragBox = NULL;
  1077. maAccel.InsertItem( KEY_RETURN, KeyCode( KEY_RETURN ) );
  1078. maAccel.InsertItem( KEY_ESCAPE, KeyCode( KEY_ESCAPE ) );
  1079. maAccel.SetSelectHdl( LINK( this, ImplTBDragMgr, SelectHdl ) );
  1080. }
  1081. // -----------------------------------------------------------------------
  1082. ImplTBDragMgr::~ImplTBDragMgr()
  1083. {
  1084. delete mpBoxList;
  1085. }
  1086. // -----------------------------------------------------------------------
  1087. ToolBox* ImplTBDragMgr::FindToolBox( const Rectangle& rRect )
  1088. {
  1089. ToolBox* pBox = mpBoxList->First();
  1090. while ( pBox )
  1091. {
  1092. /*
  1093. * FIXME: since we can have multiple frames now we cannot
  1094. * find the drag target by its position alone.
  1095. * As long as the toolbar config dialogue is not a system window
  1096. * this works in one frame only anyway. If the dialogue
  1097. * changes to a system window, we need a new implementation here
  1098. */
  1099. if ( pBox->IsReallyVisible() && pBox->ImplGetWindowImpl()->mpFrame == mpDragBox->ImplGetWindowImpl()->mpFrame )
  1100. {
  1101. if ( !pBox->ImplIsFloatingMode() )
  1102. {
  1103. Point aPos = pBox->GetPosPixel();
  1104. aPos = pBox->GetParent()->OutputToScreenPixel( aPos );
  1105. Rectangle aTempRect( aPos, pBox->GetSizePixel() );
  1106. if ( aTempRect.IsOver( rRect ) )
  1107. return pBox;
  1108. }
  1109. }
  1110. pBox = mpBoxList->Next();
  1111. }
  1112. return pBox;
  1113. }
  1114. // -----------------------------------------------------------------------
  1115. void ImplTBDragMgr::StartDragging( ToolBox* pToolBox,
  1116. const Point& rPos, const Rectangle& rRect,
  1117. USHORT nDragLineMode, BOOL bResizeItem,
  1118. void* pData )
  1119. {
  1120. mpDragBox = pToolBox;
  1121. pToolBox->CaptureMouse();
  1122. pToolBox->mbDragging = TRUE;
  1123. Application::InsertAccel( &maAccel );
  1124. if ( nDragLineMode )
  1125. {
  1126. mnLineMode = nDragLineMode;
  1127. mnStartLines = pToolBox->mnDockLines;
  1128. }
  1129. else
  1130. {
  1131. mpCustomizeData = pData;
  1132. mbResizeMode = bResizeItem;
  1133. pToolBox->Activate();
  1134. pToolBox->mnCurItemId = pToolBox->mnConfigItem;
  1135. pToolBox->Highlight();
  1136. pToolBox->mnCurItemId = 0;
  1137. if ( mbResizeMode )
  1138. {
  1139. if ( rRect.GetWidth() < TB_MIN_WIN_WIDTH )
  1140. mnMinWidth = rRect.GetWidth();
  1141. else
  1142. mnMinWidth = TB_MIN_WIN_WIDTH;
  1143. mnMaxWidth = pToolBox->GetSizePixel().Width()-rRect.Left()-
  1144. TB_SPIN_SIZE-TB_BORDER_OFFSET1-(TB_SPIN_OFFSET*2);
  1145. }
  1146. }
  1147. // MouseOffset berechnen
  1148. maMouseOff.X() = rRect.Left() - rPos.X();
  1149. maMouseOff.Y() = rRect.Top() - rPos.Y();
  1150. maRect = rRect;
  1151. maStartRect = rRect;
  1152. mbShowDragRect = TRUE;
  1153. pToolBox->ShowTracking( maRect );
  1154. }
  1155. // -----------------------------------------------------------------------
  1156. void ImplTBDragMgr::Dragging( const Point& rPos )
  1157. {
  1158. if ( mnLineMode )
  1159. {
  1160. ToolBox::ImplLineSizing( mpDragBox, rPos, maRect, mnLineMode );
  1161. Point aOff = mpDragBox->OutputToScreenPixel( Point() );
  1162. maRect.Move( aOff.X(), aOff.Y() );
  1163. mpDragBox->Docking( rPos, maRect );
  1164. maRect.Move( -aOff.X(), -aOff.Y() );
  1165. mpDragBox->ShowTracking( maRect );
  1166. }
  1167. else
  1168. {
  1169. if ( mbResizeMode )
  1170. {
  1171. long nXOff = rPos.X()-maStartRect.Left();
  1172. nXOff += maMouseOff.X()+(maStartRect.Right()-maStartRect.Left());
  1173. if ( nXOff < mnMinWidth )
  1174. nXOff = mnMinWidth;
  1175. if ( nXOff > mnMaxWidth )
  1176. nXOff = mnMaxWidth;
  1177. maRect.Right() = maStartRect.Left()+nXOff;
  1178. }
  1179. else
  1180. {
  1181. maRect.SetPos( rPos );
  1182. maRect.Move( maMouseOff.X(), maMouseOff.Y() );
  1183. }
  1184. mpDragBox->ShowTracking( maRect );
  1185. }
  1186. }
  1187. // -----------------------------------------------------------------------
  1188. void ImplTBDragMgr::EndDragging( BOOL bOK )
  1189. {
  1190. mpDragBox->HideTracking();
  1191. mpDragBox->ReleaseMouse();
  1192. mpDragBox->mbDragging = FALSE;
  1193. mbShowDragRect = FALSE;
  1194. Application::RemoveAccel( &maAccel );
  1195. if ( mnLineMode )
  1196. {
  1197. if ( !bOK )
  1198. {
  1199. mpDragBox->mnDockLines = mnStartLines;
  1200. mpDragBox->EndDocking( maStartRect, FALSE );
  1201. }
  1202. else
  1203. mpDragBox->EndDocking( maRect, FALSE );
  1204. mnLineMode = 0;
  1205. mnStartLines = 0;
  1206. }
  1207. else
  1208. {
  1209. USHORT nTempItem = mpDragBox->mnConfigItem;
  1210. if ( nTempItem )
  1211. {
  1212. mpDragBox->mnConfigItem = 0;
  1213. if ( !mbResizeMode )
  1214. mpDragBox->Invalidate( mpDragBox->GetItemRect( nTempItem ) );
  1215. }
  1216. if ( bOK && (maRect != maStartRect) )
  1217. {
  1218. if ( mbResizeMode )
  1219. {
  1220. ImplToolItem* pItem = mpDragBox->ImplGetItem( nTempItem );
  1221. Size aSize = pItem->mpWindow->GetSizePixel();
  1222. aSize.Width() = maRect.GetWidth();
  1223. pItem->mpWindow->SetSizePixel( aSize );
  1224. // ToolBox neu brechnen und neu ausgeben
  1225. mpDragBox->ImplInvalidate( TRUE );
  1226. mpDragBox->Customize( ToolBoxCustomizeEvent( mpDragBox, nTempItem,
  1227. TOOLBOX_CUSTOMIZE_RESIZE,
  1228. mpCustomizeData ) );
  1229. }
  1230. else
  1231. {
  1232. Point aOff = mpDragBox->OutputToScreenPixel( Point() );
  1233. Rectangle aScreenRect( maRect );
  1234. aScreenRect.Move( aOff.X(), aOff.Y() );
  1235. ToolBox* pDropBox = FindToolBox( aScreenRect );
  1236. if ( pDropBox )
  1237. {
  1238. // Such-Position bestimmen
  1239. Point aPos;
  1240. if ( pDropBox->mbHorz )
  1241. {
  1242. aPos.X() = aScreenRect.Left()-TB_CUSTOMIZE_OFFSET;
  1243. aPos.Y() = aScreenRect.Center().Y();
  1244. }
  1245. else
  1246. {
  1247. aPos.X() = aScreenRect.Center().X();
  1248. aPos.Y() = aScreenRect.Top()-TB_CUSTOMIZE_OFFSET;
  1249. }
  1250. aPos = pDropBox->ScreenToOutputPixel( aPos );
  1251. USHORT nPos = ToolBox::ImplFindItemPos( pDropBox, aPos );
  1252. mpDragBox->Customize( ToolBoxCustomizeEvent( pDropBox, nTempItem,
  1253. nPos, mpCustomizeData ) );
  1254. }
  1255. else
  1256. {
  1257. mpDragBox->Customize( ToolBoxCustomizeEvent( NULL, nTempItem,
  1258. 0, mpCustomizeData ) );
  1259. }
  1260. }
  1261. }
  1262. mpCustomizeData = NULL;
  1263. mbResizeMode = FALSE;
  1264. mpDragBox->Deactivate();
  1265. }
  1266. mpDragBox = NULL;
  1267. }
  1268. // -----------------------------------------------------------------------
  1269. void ImplTBDragMgr::UpdateDragRect()
  1270. {
  1271. // Nur Updaten, wenn wir schon im Dragging sind
  1272. if ( !mbShowDragRect )
  1273. return;
  1274. mpDragBox->ShowTracking( maRect );
  1275. }
  1276. // -----------------------------------------------------------------------
  1277. IMPL_LINK( ImplTBDragMgr, SelectHdl, Accelerator*, pAccel )
  1278. {
  1279. if ( pAccel->GetCurItemId() == KEY_ESCAPE )
  1280. EndDragging( FALSE );
  1281. else
  1282. EndDragging( TRUE );
  1283. return TRUE;
  1284. }
  1285. // -----------------------------------------------------------------------
  1286. void ImplTBDragMgr::StartCustomizeMode()
  1287. {
  1288. mbCustomizeMode = TRUE;
  1289. ToolBox* pBox = mpBoxList->First();
  1290. while ( pBox )
  1291. {
  1292. pBox->ImplStartCustomizeMode();
  1293. pBox = mpBoxList->Next();
  1294. }
  1295. }
  1296. // -----------------------------------------------------------------------
  1297. void ImplTBDragMgr::EndCustomizeMode()
  1298. {
  1299. mbCustomizeMode = FALSE;
  1300. ToolBox* pBox = mpBoxList->First();
  1301. while ( pBox )
  1302. {
  1303. pBox->ImplEndCustomizeMode();
  1304. pBox = mpBoxList->Next();
  1305. }
  1306. }
  1307. // -----------------------------------------------------------------------
  1308. static void ImplDrawOutButton( OutputDevice* pOutDev, const Rectangle& rRect,
  1309. USHORT nStyle )
  1310. {
  1311. const StyleSettings& rStyleSettings = pOutDev->GetSettings().GetStyleSettings();
  1312. Color aShadowColor = rStyleSettings.GetShadowColor();
  1313. Point aPos( rRect.TopLeft() );
  1314. Size aSize( rRect.GetSize() );
  1315. long nOffset = 0;
  1316. if ( pOutDev->GetBackground().GetColor() == aShadowColor )
  1317. aShadowColor = rStyleSettings.GetDarkShadowColor();
  1318. if ( nStyle & BUTTON_DRAW_PRESSED )
  1319. {
  1320. aPos.X()++;
  1321. aPos.Y()++;
  1322. nOffset++;
  1323. }
  1324. // Hintergrund loeschen
  1325. pOutDev->Erase( rRect );
  1326. // Button zeichnen
  1327. pOutDev->SetLineColor( rStyleSettings.GetLightColor() );
  1328. pOutDev->DrawLine( aPos,
  1329. Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y() ) );
  1330. pOutDev->DrawLine( aPos,
  1331. Point( aPos.X(), aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
  1332. pOutDev->SetLineColor( aShadowColor );
  1333. pOutDev->DrawLine( Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y() ),
  1334. Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
  1335. pOutDev->DrawLine( Point( aPos.X(), aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ),
  1336. Point( aPos.X()+aSize.Width()-OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-OUTBUTTON_BORDER ) );
  1337. for ( long i = 0; i < OUTBUTTON_BORDER-1-nOffset; i++ )
  1338. {
  1339. pOutDev->DrawLine( Point( aPos.X()+aSize.Width()-(OUTBUTTON_BORDER-i-1), aPos.Y()+OUTBUTTON_BORDER ),
  1340. Point( aPos.X()+aSize.Width()-(OUTBUTTON_BORDER-i-1), aPos.Y()+aSize.Height()-1 ) );
  1341. pOutDev->DrawLine( Point( aPos.X()+OUTBUTTON_BORDER, aPos.Y()+aSize.Height()-(OUTBUTTON_BORDER-i-1) ),
  1342. Point( aPos.X()+aSize.Width()-1, aPos.Y()+aSize.Height()-(OUTBUTTON_BORDER-i-1) ) );
  1343. }
  1344. }
  1345. // -----------------------------------------------------------------------
  1346. void ToolBox::ImplInit( Window* pParent, WinBits nStyle )
  1347. {
  1348. // Variablen initialisieren
  1349. ImplGetWindowImpl()->mbToolBox = TRUE;
  1350. mpBtnDev = NULL;
  1351. mpFloatSizeAry = NULL;
  1352. mpData = new ImplToolBoxPrivateData;
  1353. mpFloatWin = NULL;
  1354. mnDX = 0;
  1355. mnDY = 0;
  1356. mnMaxItemWidth = 0;
  1357. mnMaxItemHeight = 0;
  1358. mnWinHeight = 0;
  1359. mnBorderX = 0;
  1360. mnBorderY = 0;
  1361. mnLeftBorder = 0;
  1362. mnTopBorder = 0;
  1363. mnRightBorder = 0;
  1364. mnBottomBorder = 0;
  1365. mnLastResizeDY = 0;
  1366. mnOutStyle = TOOLBOX_STYLE_FLAT; // force flat buttons since NWF
  1367. mnHighItemId = 0;
  1368. mnCurItemId = 0;
  1369. mnDownItemId = 0;
  1370. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  1371. mnFocusPos = TOOLBOX_ITEM_NOTFOUND; // current position during keyboard access
  1372. mnLines = 1;
  1373. mnCurLine = 1;
  1374. mnCurLines = 1;
  1375. mnVisLines = 1;
  1376. mnFloatLines = 0;
  1377. mnConfigItem = 0;
  1378. mnMouseClicks = 0;
  1379. mnMouseModifier = 0;
  1380. mbDrag = FALSE;
  1381. mbSelection = FALSE;
  1382. mbCommandDrag = FALSE;
  1383. mbUpper = FALSE;
  1384. mbLower = FALSE;
  1385. mbNextTool = FALSE;
  1386. mbIn = FALSE;
  1387. mbCalc = TRUE;
  1388. mbFormat = FALSE;
  1389. mbFullPaint = FALSE;
  1390. mbHorz = TRUE;
  1391. mbScroll = (nStyle & WB_SCROLL) != 0;
  1392. mbCustomize = FALSE;
  1393. mbCustomizeMode = FALSE;
  1394. mbDragging = FALSE;
  1395. mbHideStatusText = FALSE;
  1396. mbMenuStrings = FALSE;
  1397. mbIsShift = FALSE;
  1398. mbIsKeyEvent = FALSE;
  1399. mbChangingHighlight = FALSE;
  1400. meButtonType = BUTTON_SYMBOL;
  1401. meAlign = WINDOWALIGN_TOP;
  1402. meLastStyle = POINTER_ARROW;
  1403. mnWinStyle = nStyle;
  1404. mnLastFocusItemId = 0;
  1405. mnKeyModifier = 0;
  1406. mnActivateCount = 0;
  1407. maTimer.SetTimeout( 50 );
  1408. maTimer.SetTimeoutHdl( LINK( this, ToolBox, ImplUpdateHdl ) );
  1409. // set timeout and handler for dropdown items
  1410. mpData->maDropdownTimer.SetTimeout( 250 );
  1411. mpData->maDropdownTimer.SetTimeoutHdl( LINK( this, ToolBox, ImplDropdownLongClickHdl ) );
  1412. DockingWindow::ImplInit( pParent, nStyle & ~(WB_BORDER) );
  1413. // always set WB_TABSTOP for ToolBars !!! if( mnWinStyle & WB_TABSTOP )
  1414. {
  1415. // dockingwindow's ImplInit removes some bits, so restore them here
  1416. // to allow keyboard handling for toolbars
  1417. ImplGetWindowImpl()->mnStyle |= WB_TABSTOP|WB_NODIALOGCONTROL;
  1418. ImplGetWindowImpl()->mnStyle &= ~WB_DIALOGCONTROL;
  1419. }
  1420. ImplInitSettings( TRUE, TRUE, TRUE );
  1421. }
  1422. // -----------------------------------------------------------------------
  1423. void ToolBox::ImplInitSettings( BOOL bFont,
  1424. BOOL bForeground, BOOL bBackground )
  1425. {
  1426. mpData->mbNativeButtons = IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON );
  1427. const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
  1428. if ( bFont )
  1429. {
  1430. Font aFont = rStyleSettings.GetToolFont();
  1431. if ( IsControlFont() )
  1432. aFont.Merge( GetControlFont() );
  1433. SetZoomedPointFont( aFont );
  1434. }
  1435. if ( bForeground || bFont )
  1436. {
  1437. Color aColor;
  1438. if ( IsControlForeground() )
  1439. aColor = GetControlForeground();
  1440. else if ( Window::GetStyle() & WB_3DLOOK )
  1441. aColor = rStyleSettings.GetButtonTextColor();
  1442. else
  1443. aColor = rStyleSettings.GetWindowTextColor();
  1444. SetTextColor( aColor );
  1445. SetTextFillColor();
  1446. }
  1447. if ( bBackground )
  1448. {
  1449. Color aColor;
  1450. if ( IsControlBackground() )
  1451. {
  1452. aColor = GetControlBackground();
  1453. SetBackground( aColor );
  1454. SetPaintTransparent( FALSE );
  1455. SetParentClipMode( 0 );
  1456. }
  1457. else
  1458. {
  1459. if( IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) )
  1460. {
  1461. SetBackground();
  1462. SetPaintTransparent( TRUE );
  1463. SetParentClipMode( PARENTCLIPMODE_NOCLIP );
  1464. mpData->maDisplayBackground = Wallpaper( rStyleSettings.GetFaceColor() );
  1465. }
  1466. else
  1467. {
  1468. if ( Window::GetStyle() & WB_3DLOOK )
  1469. aColor = rStyleSettings.GetFaceColor();
  1470. else
  1471. aColor = rStyleSettings.GetWindowColor();
  1472. SetBackground( aColor );
  1473. SetPaintTransparent( FALSE );
  1474. SetParentClipMode( 0 );
  1475. ImplUpdateImageList();
  1476. }
  1477. }
  1478. }
  1479. }
  1480. // -----------------------------------------------------------------------
  1481. void ToolBox::ImplLoadRes( const ResId& rResId )
  1482. {
  1483. ResMgr* pMgr = rResId.GetResMgr();
  1484. if( ! pMgr )
  1485. return;
  1486. DockingWindow::ImplLoadRes( rResId );
  1487. ULONG nObjMask;
  1488. nObjMask = ReadLongRes();
  1489. if ( nObjMask & RSC_TOOLBOX_BUTTONTYPE )
  1490. SetButtonType( (ButtonType)ReadLongRes() );
  1491. if ( nObjMask & RSC_TOOLBOX_ALIGN )
  1492. SetAlign( (WindowAlign)ReadLongRes() );
  1493. if ( nObjMask & RSC_TOOLBOX_LINECOUNT )
  1494. SetLineCount( sal::static_int_cast<USHORT>(ReadLongRes()) );
  1495. if ( nObjMask & RSC_TOOLBOX_CUSTOMIZE )
  1496. {
  1497. BOOL bCust = (BOOL)ReadShortRes();
  1498. EnableCustomize( bCust );
  1499. }
  1500. if ( nObjMask & RSC_TOOLBOX_MENUSTRINGS )
  1501. {
  1502. BOOL bCust = (BOOL)ReadShortRes();
  1503. EnableMenuStrings( bCust );
  1504. }
  1505. if ( nObjMask & RSC_TOOLBOX_FLOATLINES )
  1506. SetFloatingLines( ReadShortRes() );
  1507. if ( nObjMask & RSC_TOOLBOX_ITEMIMAGELIST )
  1508. {
  1509. maImageList = ImageList( ResId( (RSHEADER_TYPE*)GetClassRes(), *pMgr ) );
  1510. IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
  1511. }
  1512. if ( nObjMask & RSC_TOOLBOX_ITEMLIST )
  1513. {
  1514. ULONG nEle = ReadLongRes();
  1515. // Item hinzufuegen
  1516. for ( ULONG i = 0; i < nEle; i++ )
  1517. {
  1518. InsertItem( ResId( (RSHEADER_TYPE *)GetClassRes(), *pMgr ) );
  1519. IncrementRes( GetObjSizeRes( (RSHEADER_TYPE *)GetClassRes() ) );
  1520. }
  1521. }
  1522. }
  1523. // -----------------------------------------------------------------------
  1524. ToolBox::ToolBox( Window* pParent, WinBits nStyle ) :
  1525. DockingWindow( WINDOW_TOOLBOX )
  1526. {
  1527. ImplInit( pParent, nStyle );
  1528. }
  1529. // -----------------------------------------------------------------------
  1530. ToolBox::ToolBox( Window* pParent, const ResId& rResId ) :
  1531. DockingWindow( WINDOW_TOOLBOX )
  1532. {
  1533. RTL_LOGFILE_CONTEXT( aLog, "vcl: ToolBox::ToolBox( Window* pParent, const ResId& rResId )" );
  1534. rResId.SetRT( RSC_TOOLBOX );
  1535. WinBits nStyle = ImplInitRes( rResId );
  1536. ImplInit( pParent, nStyle );
  1537. ImplLoadRes( rResId );
  1538. // Groesse des FloatingWindows berechnen und umschalten, wenn die
  1539. // ToolBox initial im FloatingModus ist
  1540. if ( ImplIsFloatingMode() )
  1541. mbHorz = TRUE;
  1542. else
  1543. Resize();
  1544. if ( !(nStyle & WB_HIDE) )
  1545. Show();
  1546. }
  1547. // -----------------------------------------------------------------------
  1548. ToolBox::~ToolBox()
  1549. {
  1550. // custom menu event still running?
  1551. if( mpData->mnEventId )
  1552. Application::RemoveUserEvent( mpData->mnEventId );
  1553. // #103005# make sure our activate/deactivate balance is right
  1554. while( mnActivateCount > 0 )
  1555. Deactivate();
  1556. // Falls noch ein Floating-Window connected ist, dann den
  1557. // PopupModus beenden
  1558. if ( mpFloatWin )
  1559. mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
  1560. // delete private data
  1561. delete mpData;
  1562. // FloatSizeAry gegebenenfalls loeschen
  1563. if ( mpFloatSizeAry )
  1564. delete mpFloatSizeAry;
  1565. // Wenn keine ToolBox-Referenzen mehr auf die Listen bestehen, dann
  1566. // Listen mit wegloeschen
  1567. ImplSVData* pSVData = ImplGetSVData();
  1568. if ( pSVData->maCtrlData.mpTBDragMgr )
  1569. {
  1570. // Wenn im TBDrag-Manager, dann wieder rausnehmen
  1571. if ( mbCustomize )
  1572. pSVData->maCtrlData.mpTBDragMgr->Remove( this );
  1573. if ( !pSVData->maCtrlData.mpTBDragMgr->Count() )
  1574. {
  1575. delete pSVData->maCtrlData.mpTBDragMgr;
  1576. pSVData->maCtrlData.mpTBDragMgr = NULL;
  1577. }
  1578. }
  1579. }
  1580. // -----------------------------------------------------------------------
  1581. ImplToolItem* ToolBox::ImplGetItem( USHORT nItemId ) const
  1582. {
  1583. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  1584. while ( it != mpData->m_aItems.end() )
  1585. {
  1586. if ( it->mnId == nItemId )
  1587. return &(*it);
  1588. ++it;
  1589. }
  1590. return NULL;
  1591. }
  1592. // -----------------------------------------------------------------------
  1593. static void ImplAddButtonBorder( long &rWidth, long& rHeight, USHORT aOutStyle, BOOL bNativeButtons )
  1594. {
  1595. if ( aOutStyle & TOOLBOX_STYLE_OUTBUTTON )
  1596. {
  1597. rWidth += OUTBUTTON_SIZE;
  1598. rHeight += OUTBUTTON_SIZE;
  1599. }
  1600. else
  1601. {
  1602. rWidth += SMALLBUTTON_HSIZE;
  1603. rHeight += SMALLBUTTON_VSIZE;
  1604. }
  1605. if( bNativeButtons )
  1606. {
  1607. // give more border space for rounded buttons
  1608. rWidth += 2;
  1609. rHeight += 4;
  1610. }
  1611. }
  1612. // -----------------------------------------------------------------------
  1613. BOOL ToolBox::ImplCalcItem()
  1614. {
  1615. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  1616. // recalc required ?
  1617. if ( !mbCalc )
  1618. return FALSE;
  1619. ImplDisableFlatButtons();
  1620. long nDefWidth;
  1621. long nDefHeight;
  1622. long nMaxWidth = 0;
  1623. long nMaxHeight = 0;
  1624. long nHeight;
  1625. long nMinWidth = 6;
  1626. long nMinHeight = 6;
  1627. long nDropDownArrowWidth = TB_DROPDOWNARROWWIDTH;
  1628. // set defaults if image or text is needed but empty
  1629. nDefWidth = GetDefaultImageSize().Width();
  1630. nDefHeight = GetDefaultImageSize().Height();
  1631. mnWinHeight = 0;
  1632. // determine minimum size necessary in NWF
  1633. {
  1634. Rectangle aRect( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
  1635. Region aReg = aRect;
  1636. ImplControlValue aVal;
  1637. Region aNativeBounds, aNativeContent;
  1638. if( IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
  1639. {
  1640. if( GetNativeControlRegion( CTRL_TOOLBAR, PART_BUTTON,
  1641. aReg,
  1642. CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
  1643. aVal, OUString(),
  1644. aNativeBounds, aNativeContent ) )
  1645. {
  1646. aRect = aNativeBounds.GetBoundRect();
  1647. if( aRect.GetWidth() > nMinWidth )
  1648. nMinWidth = aRect.GetWidth();
  1649. if( aRect.GetHeight() > nMinHeight )
  1650. nMinHeight = aRect.GetHeight();
  1651. if( nDropDownArrowWidth < nMinWidth )
  1652. nDropDownArrowWidth = nMinWidth;
  1653. if( nMinWidth > mpData->mnMenuButtonWidth )
  1654. mpData->mnMenuButtonWidth = nMinWidth;
  1655. else if( nMinWidth < TB_MENUBUTTON_SIZE )
  1656. mpData->mnMenuButtonWidth = TB_MENUBUTTON_SIZE;
  1657. }
  1658. }
  1659. // also calculate the area for comboboxes, drop down list boxes and spinfields
  1660. // as these are often inserted into toolboxes; set mnWinHeight to the
  1661. // greater of those values to prevent toolbar flickering (#i103385#)
  1662. aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
  1663. aReg = aRect;
  1664. if( GetNativeControlRegion( CTRL_COMBOBOX, PART_ENTIRE_CONTROL,
  1665. aReg,
  1666. CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
  1667. aVal, OUString(),
  1668. aNativeBounds, aNativeContent ) )
  1669. {
  1670. aRect = aNativeBounds.GetBoundRect();
  1671. if( aRect.GetHeight() > mnWinHeight )
  1672. mnWinHeight = aRect.GetHeight();
  1673. }
  1674. aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
  1675. aReg = aRect;
  1676. if( GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL,
  1677. aReg,
  1678. CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
  1679. aVal, OUString(),
  1680. aNativeBounds, aNativeContent ) )
  1681. {
  1682. aRect = aNativeBounds.GetBoundRect();
  1683. if( aRect.GetHeight() > mnWinHeight )
  1684. mnWinHeight = aRect.GetHeight();
  1685. }
  1686. aRect = Rectangle( Point( 0, 0 ), Size( nMinWidth, nMinHeight ) );
  1687. aReg = aRect;
  1688. if( GetNativeControlRegion( CTRL_SPINBOX, PART_ENTIRE_CONTROL,
  1689. aReg,
  1690. CTRL_STATE_ENABLED | CTRL_STATE_ROLLOVER,
  1691. aVal, OUString(),
  1692. aNativeBounds, aNativeContent ) )
  1693. {
  1694. aRect = aNativeBounds.GetBoundRect();
  1695. if( aRect.GetHeight() > mnWinHeight )
  1696. mnWinHeight = aRect.GetHeight();
  1697. }
  1698. }
  1699. if ( ! mpData->m_aItems.empty() )
  1700. {
  1701. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  1702. while ( it != mpData->m_aItems.end() )
  1703. {
  1704. BOOL bImage;
  1705. BOOL bText;
  1706. it->mbVisibleText = FALSE; // indicates if text will definitely be drawn, influences dropdown pos
  1707. if ( it->meType == TOOLBOXITEM_BUTTON )
  1708. {
  1709. // check if image and/or text exists
  1710. if ( !(it->maImage) )
  1711. bImage = FALSE;
  1712. else
  1713. bImage = TRUE;
  1714. if ( !it->maText.Len() )
  1715. bText = FALSE;
  1716. else
  1717. bText = TRUE;
  1718. ButtonType tmpButtonType = determineButtonType( &(*it), meButtonType ); // default to toolbox setting
  1719. if ( bImage || bText )
  1720. {
  1721. it->mbEmptyBtn = FALSE;
  1722. if ( tmpButtonType == BUTTON_SYMBOL )
  1723. {
  1724. // we're drawing images only
  1725. if ( bImage || !bText )
  1726. {
  1727. it->maItemSize = it->maImage.GetSizePixel();
  1728. }
  1729. else
  1730. {
  1731. it->maItemSize = Size( GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET,
  1732. GetTextHeight() );
  1733. it->mbVisibleText = TRUE;
  1734. }
  1735. }
  1736. else if ( tmpButtonType == BUTTON_TEXT )
  1737. {
  1738. // we're drawing text only
  1739. if ( bText || !bImage )
  1740. {
  1741. it->maItemSize = Size( GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET,
  1742. GetTextHeight() );
  1743. it->mbVisibleText = TRUE;
  1744. }
  1745. else
  1746. {
  1747. it->maItemSize = it->maImage.GetSizePixel();
  1748. }
  1749. }
  1750. else
  1751. {
  1752. // we're drawing images and text
  1753. it->maItemSize.Width() = bText ? GetCtrlTextWidth( it->maText )+TB_TEXTOFFSET : 0;
  1754. it->maItemSize.Height() = bText ? GetTextHeight() : 0;
  1755. // leave space between image and text
  1756. if( bText )
  1757. it->maItemSize.Width() += TB_IMAGETEXTOFFSET;
  1758. // image and text side by side
  1759. it->maItemSize.Width() += it->maImage.GetSizePixel().Width();
  1760. if ( it->maImage.GetSizePixel().Height() > it->maItemSize.Height() )
  1761. it->maItemSize.Height() = it->maImage.GetSizePixel().Height();
  1762. it->mbVisibleText = bText;
  1763. }
  1764. }
  1765. else
  1766. { // no image and no text
  1767. it->maItemSize = Size( nDefWidth, nDefHeight );
  1768. it->mbEmptyBtn = TRUE;
  1769. }
  1770. // Gegebenenfalls die Fensterhoehe mit beruecksichtigen
  1771. if ( it->mpWindow )
  1772. {
  1773. nHeight = it->mpWindow->GetSizePixel().Height();
  1774. if ( nHeight > mnWinHeight )
  1775. mnWinHeight = nHeight;
  1776. }
  1777. // add in drop down arrow
  1778. if( it->mnBits & TIB_DROPDOWN )
  1779. {
  1780. it->maItemSize.Width() += nDropDownArrowWidth;
  1781. it->mnDropDownArrowWidth = nDropDownArrowWidth;
  1782. }
  1783. // text items will be rotated in vertical mode
  1784. // -> swap width and height
  1785. if( it->mbVisibleText && !mbHorz )
  1786. {
  1787. long tmp = it->maItemSize.Width();
  1788. it->maItemSize.Width() = it->maItemSize.Height();
  1789. it->maItemSize.Height() = tmp;
  1790. }
  1791. }
  1792. else if ( it->meType == TOOLBOXITEM_SPACE )
  1793. {
  1794. it->maItemSize = Size( nDefWidth, nDefHeight );
  1795. }
  1796. if ( it->meType == TOOLBOXITEM_BUTTON || it->meType == TOOLBOXITEM_SPACE )
  1797. {
  1798. // add borders
  1799. ImplAddButtonBorder( it->maItemSize.Width(), it->maItemSize.Height(), mnOutStyle, mpData->mbNativeButtons );
  1800. if( it->meType == TOOLBOXITEM_BUTTON )
  1801. {
  1802. if( it->maItemSize.Width() < nMinWidth )
  1803. it->maItemSize.Width() = nMinWidth;
  1804. if( it->maItemSize.Height() < nMinHeight )
  1805. it->maItemSize.Height() = nMinHeight;
  1806. }
  1807. // keep track of max item size
  1808. if ( it->maItemSize.Width() > nMaxWidth )
  1809. nMaxWidth = it->maItemSize.Width();
  1810. if ( it->maItemSize.Height() > nMaxHeight )
  1811. nMaxHeight = it->maItemSize.Height();
  1812. }
  1813. ++it;
  1814. }
  1815. }
  1816. else
  1817. {
  1818. nMaxWidth = nDefWidth;
  1819. nMaxHeight = nDefHeight;
  1820. ImplAddButtonBorder( nMaxWidth, nMaxHeight, mnOutStyle, mpData->mbNativeButtons );
  1821. }
  1822. if( !ImplIsFloatingMode() && GetToolboxButtonSize() != TOOLBOX_BUTTONSIZE_DONTCARE )
  1823. {
  1824. // make sure all vertical toolbars have the same width and horizontal have the same height
  1825. // this depends on the used button sizes
  1826. // as this is used for alignement of multiple toolbars
  1827. // it is only required for docked toolbars
  1828. long nFixedWidth = nDefWidth+nDropDownArrowWidth;
  1829. long nFixedHeight = nDefHeight;
  1830. ImplAddButtonBorder( nFixedWidth, nFixedHeight, mnOutStyle, mpData->mbNativeButtons );
  1831. if( mbHorz )
  1832. nMaxHeight = nFixedHeight;
  1833. else
  1834. nMaxWidth = nFixedWidth;
  1835. }
  1836. mbCalc = FALSE;
  1837. mbFormat = TRUE;
  1838. // do we have to recalc the sizes ?
  1839. if ( (nMaxWidth != mnMaxItemWidth) || (nMaxHeight != mnMaxItemHeight) )
  1840. {
  1841. mnMaxItemWidth = nMaxWidth;
  1842. mnMaxItemHeight = nMaxHeight;
  1843. return TRUE;
  1844. }
  1845. else
  1846. return FALSE;
  1847. }
  1848. // -----------------------------------------------------------------------
  1849. USHORT ToolBox::ImplCalcBreaks( long nWidth, long* pMaxLineWidth, BOOL bCalcHorz )
  1850. {
  1851. ULONG nLineStart = 0;
  1852. ULONG nGroupStart = 0;
  1853. long nLineWidth = 0;
  1854. long nCurWidth;
  1855. long nLastGroupLineWidth = 0;
  1856. long nMaxLineWidth = 0;
  1857. USHORT nLines = 1;
  1858. BOOL bWindow;
  1859. BOOL bBreak = FALSE;
  1860. long nWidthTotal = nWidth;
  1861. // when docked the menubutton will be in the first line
  1862. // ->initialize first linewidth with button
  1863. if( IsMenuEnabled() && !ImplIsFloatingMode() )
  1864. nLineWidth = mpData->maMenubuttonItem.maItemSize.Width();
  1865. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  1866. while ( it != mpData->m_aItems.end() )
  1867. {
  1868. it->mbBreak = bBreak;
  1869. bBreak = FALSE;
  1870. if ( it->mbVisible )
  1871. {
  1872. bWindow = FALSE;
  1873. bBreak = FALSE;
  1874. nCurWidth = 0;
  1875. if ( it->meType == TOOLBOXITEM_BUTTON || it->meType == TOOLBOXITEM_SPACE )
  1876. {
  1877. if ( bCalcHorz )
  1878. nCurWidth = it->maItemSize.Width();
  1879. else
  1880. nCurWidth = it->maItemSize.Height();
  1881. if ( it->mpWindow && bCalcHorz )
  1882. {
  1883. long nWinItemWidth = it->mpWindow->GetSizePixel().Width();
  1884. if ( !mbScroll || (nWinItemWidth <= nWidthTotal) )
  1885. {
  1886. nCurWidth = nWinItemWidth;
  1887. bWindow = TRUE;
  1888. }
  1889. else
  1890. {
  1891. if ( it->mbEmptyBtn )
  1892. {
  1893. nCurWidth = 0;
  1894. }
  1895. }
  1896. }
  1897. // check for line break
  1898. if ( (nLineWidth+nCurWidth > nWidthTotal) && mbScroll )
  1899. bBreak = TRUE;
  1900. }
  1901. else if ( it->meType == TOOLBOXITEM_SEPARATOR )
  1902. nCurWidth = it->mnSepSize;
  1903. // treat breaks as separators, except when using old style toolbars (ie. no menu button)
  1904. else if ( (it->meType == TOOLBOXITEM_BREAK) && !IsMenuEnabled() )
  1905. bBreak = TRUE;
  1906. if ( bBreak )
  1907. {
  1908. nLines++;
  1909. // Gruppe auseinanderbrechen oder ganze Gruppe umbrechen?
  1910. if ( (it->meType == TOOLBOXITEM_BREAK) ||
  1911. (nLineStart == nGroupStart) )
  1912. {
  1913. if ( nLineWidth > nMaxLineWidth )
  1914. nMaxLineWidth = nLineWidth;
  1915. nLineWidth = 0;
  1916. nLineStart = it - mpData->m_aItems.begin();
  1917. nGroupStart = nLineStart;
  1918. it->mbBreak = TRUE;
  1919. bBreak = FALSE;
  1920. }
  1921. else
  1922. {
  1923. if ( nLastGroupLineWidth > nMaxLineWidth )
  1924. nMaxLineWidth = nLastGroupLineWidth;
  1925. // Wenn ganze Gruppe umgebrochen wird, diese auf
  1926. // Zeilenanfang setzen und wieder neu berechnen
  1927. nLineWidth = 0;
  1928. nLineStart = nGroupStart;
  1929. it = mpData->m_aItems.begin() + nGroupStart;
  1930. continue;
  1931. }
  1932. }
  1933. else
  1934. {
  1935. if( ImplIsFloatingMode() || !IsMenuEnabled() ) // no group breaking when being docked single-line
  1936. {
  1937. if ( (it->meType != TOOLBOXITEM_BUTTON) || bWindow )
  1938. {
  1939. // found separator or break
  1940. nLastGroupLineWidth = nLineWidth;
  1941. nGroupStart = it - mpData->m_aItems.begin();
  1942. if ( !bWindow )
  1943. nGroupStart++;
  1944. }
  1945. }
  1946. }
  1947. nLineWidth += nCurWidth;
  1948. }
  1949. ++it;
  1950. }
  1951. if ( pMaxLineWidth )
  1952. {
  1953. if ( nLineWidth > nMaxLineWidth )
  1954. nMaxLineWidth = nLineWidth;
  1955. if( ImplIsFloatingMode() && !ImplIsInPopupMode() )
  1956. {
  1957. // leave enough space to display buttons in the decoration
  1958. long aMinWidth = 2 * GetSettings().GetStyleSettings().GetFloatTitleHeight();
  1959. if( nMaxLineWidth < aMinWidth )
  1960. nMaxLineWidth = aMinWidth;
  1961. }
  1962. // Wegen Separatoren kann MaxLineWidth > Width werden, hat aber
  1963. // auf die Umbrueche keine Auswirkung
  1964. //if ( nMaxLineWidth > nWidth )
  1965. // nMaxLineWidth = nWidth;
  1966. *pMaxLineWidth = nMaxLineWidth;
  1967. }
  1968. return nLines;
  1969. }
  1970. // -----------------------------------------------------------------------
  1971. namespace
  1972. {
  1973. BOOL ImplFollowedByVisibleButton( std::vector< ImplToolItem >::iterator _aSeparator, std::vector< ImplToolItem >::iterator _aEnd )
  1974. {
  1975. std::vector< ImplToolItem >::iterator aLookup = _aSeparator;
  1976. while ( ++aLookup != _aEnd )
  1977. {
  1978. if ( aLookup->meType == TOOLBOXITEM_SEPARATOR )
  1979. return ImplFollowedByVisibleButton( aLookup, _aEnd );
  1980. if ( ( aLookup->meType == TOOLBOXITEM_BUTTON ) && aLookup->mbVisible )
  1981. return TRUE;
  1982. }
  1983. return FALSE;
  1984. }
  1985. }
  1986. // -----------------------------------------------------------------------
  1987. Size ToolBox::ImplGetOptimalFloatingSize( FloatingSizeMode eMode )
  1988. {
  1989. if( !ImplIsFloatingMode() )
  1990. return Size();
  1991. Size aCurrentSize( mnDX, mnDY );
  1992. Size aSize1( aCurrentSize );
  1993. Size aSize2( aCurrentSize );
  1994. // try to preserve current height
  1995. if( eMode == FSMODE_AUTO || eMode == FSMODE_FAVOURHEIGHT )
  1996. {
  1997. // calc number of floating lines for current window height
  1998. USHORT nFloatLinesHeight = ImplCalcLines( this, mnDY );
  1999. // calc window size according to this number
  2000. aSize1 = ImplCalcFloatSize( this, nFloatLinesHeight );
  2001. if( eMode == FSMODE_FAVOURHEIGHT || aCurrentSize == aSize1 )
  2002. return aSize1;
  2003. }
  2004. if( eMode == FSMODE_AUTO || eMode == FSMODE_FAVOURWIDTH )
  2005. {
  2006. // try to preserve current width
  2007. long nLineHeight = ( mnWinHeight > mnMaxItemHeight ) ? mnWinHeight : mnMaxItemHeight;
  2008. int nBorderX = 2*TB_BORDER_OFFSET1 + mnLeftBorder + mnRightBorder + 2*mnBorderX;
  2009. int nBorderY = 2*TB_BORDER_OFFSET2 + mnTopBorder + mnBottomBorder + 2*mnBorderY;
  2010. Size aSz( aCurrentSize );
  2011. long maxX;
  2012. USHORT nLines = ImplCalcBreaks( aSz.Width()-nBorderX, &maxX, mbHorz );
  2013. USHORT manyLines = 1000;
  2014. Size aMinimalFloatSize = ImplCalcFloatSize( this, manyLines );
  2015. aSz.Height() = nBorderY + nLineHeight * nLines;
  2016. // line space when more than one line
  2017. if ( mnWinStyle & WB_LINESPACING )
  2018. aSz.Height() += (nLines-1)*TB_LINESPACING;
  2019. aSz.Width() = nBorderX + maxX;
  2020. // avoid clipping of any items
  2021. if( aSz.Width() < aMinimalFloatSize.Width() )
  2022. aSize2 = ImplCalcFloatSize( this, nLines );
  2023. else
  2024. aSize2 = aSz;
  2025. if( eMode == FSMODE_FAVOURWIDTH || aCurrentSize == aSize2 )
  2026. return aSize2;
  2027. else
  2028. {
  2029. // set the size with the smallest delta as the current size
  2030. long dx1 = abs( mnDX - aSize1.Width() );
  2031. long dy1 = abs( mnDY - aSize1.Height() );
  2032. long dx2 = abs( mnDX - aSize2.Width() );
  2033. long dy2 = abs( mnDY - aSize2.Height() );
  2034. if( dx1*dy1 < dx2*dy2 )
  2035. aCurrentSize = aSize1;
  2036. else
  2037. aCurrentSize = aSize2;
  2038. }
  2039. }
  2040. return aCurrentSize;
  2041. }
  2042. void ToolBox::ImplFormat( BOOL bResize )
  2043. {
  2044. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  2045. // Muss ueberhaupt neu formatiert werden
  2046. if ( !mbFormat )
  2047. return;
  2048. mpData->ImplClearLayoutData();
  2049. // Positionen/Groessen berechnen
  2050. Rectangle aEmptyRect;
  2051. long nLineSize;
  2052. long nLeft;
  2053. long nRight;
  2054. long nTop;
  2055. long nBottom;
  2056. long nMax; // width of layoutarea in pixels
  2057. long nX;
  2058. long nY;
  2059. USHORT nFormatLine;
  2060. BOOL bMustFullPaint;
  2061. BOOL bLastSep;
  2062. std::vector< ImplToolItem >::iterator it;
  2063. std::vector< ImplToolItem >::iterator temp_it;
  2064. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
  2065. BOOL bIsInPopupMode = ImplIsInPopupMode();
  2066. // FloatSizeAry gegebenenfalls loeschen
  2067. if ( mpFloatSizeAry )
  2068. {
  2069. delete mpFloatSizeAry;
  2070. mpFloatSizeAry = NULL;
  2071. }
  2072. // compute border sizes
  2073. ImplCalcBorder( meAlign, mnLeftBorder, mnTopBorder, mnRightBorder, mnBottomBorder, this );
  2074. // update drag area (where the 'grip' will be placed)
  2075. Rectangle aOldDragRect;
  2076. if( pWrapper )
  2077. aOldDragRect = pWrapper->GetDragArea();
  2078. ImplUpdateDragArea( this );
  2079. if ( ImplCalcItem() )
  2080. bMustFullPaint = TRUE;
  2081. else
  2082. bMustFullPaint = FALSE;
  2083. // calculate new size during interactive resize or
  2084. // set computed size when formatting only
  2085. if ( ImplIsFloatingMode() )
  2086. {
  2087. if ( bResize )
  2088. mnFloatLines = ImplCalcLines( this, mnDY );
  2089. else
  2090. SetOutputSizePixel( ImplGetOptimalFloatingSize( FSMODE_AUTO ) );
  2091. }
  2092. // Horizontal
  2093. if ( mbHorz )
  2094. {
  2095. // nLineSize: height of a single line, will fit highest item
  2096. nLineSize = mnMaxItemHeight;
  2097. if ( mnWinHeight > mnMaxItemHeight )
  2098. nLineSize = mnWinHeight;
  2099. if ( mbScroll )
  2100. {
  2101. nMax = mnDX;
  2102. mnVisLines = ImplCalcLines( this, mnDY );
  2103. }
  2104. else
  2105. {
  2106. // layout over all lines
  2107. mnVisLines = mnLines;
  2108. nMax = TB_MAXNOSCROLL;
  2109. }
  2110. // add in all border offsets
  2111. // inner border as well as custom border (mnBorderX, mnBorderY)
  2112. if ( mnWinStyle & WB_BORDER )
  2113. {
  2114. nLeft = TB_BORDER_OFFSET1 + mnLeftBorder;
  2115. nTop = TB_BORDER_OFFSET2 + mnTopBorder;
  2116. nBottom = TB_BORDER_OFFSET1 + mnBottomBorder;
  2117. nMax -= nLeft + TB_BORDER_OFFSET1 + mnRightBorder;
  2118. }
  2119. else
  2120. {
  2121. nLeft = 0;
  2122. nTop = 0;
  2123. nBottom = 0;
  2124. }
  2125. nLeft += mnBorderX;
  2126. nTop += mnBorderY;
  2127. nBottom += mnBorderY;
  2128. nMax -= mnBorderX*2;
  2129. // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
  2130. // we have to center all items in the window height
  2131. if( IsMenuEnabled() && !ImplIsFloatingMode() )
  2132. {
  2133. long nWinHeight = mnDY - nTop - nBottom;
  2134. if( nWinHeight > nLineSize )
  2135. nLineSize = nWinHeight;
  2136. }
  2137. }
  2138. else
  2139. {
  2140. nLineSize = mnMaxItemWidth;
  2141. if ( mbScroll )
  2142. {
  2143. mnVisLines = ImplCalcLines( this, mnDX );
  2144. nMax = mnDY;
  2145. }
  2146. else
  2147. {
  2148. mnVisLines = mnLines;
  2149. nMax = TB_MAXNOSCROLL;
  2150. }
  2151. if ( mnWinStyle & WB_BORDER )
  2152. {
  2153. nTop = TB_BORDER_OFFSET1 + mnTopBorder;
  2154. nLeft = TB_BORDER_OFFSET2 + mnLeftBorder;
  2155. nRight = TB_BORDER_OFFSET2 + mnRightBorder;
  2156. nMax -= nTop + TB_BORDER_OFFSET1 + mnBottomBorder;
  2157. }
  2158. else
  2159. {
  2160. nLeft = 0;
  2161. nTop = 0;
  2162. nRight = 0;
  2163. }
  2164. nLeft += mnBorderX;
  2165. nRight+= mnBorderX;
  2166. nTop += mnBorderY;
  2167. nMax -= mnBorderY*2;
  2168. // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
  2169. // we have to center all items in the window height
  2170. if( !ImplIsFloatingMode() && IsMenuEnabled() )
  2171. {
  2172. long nWinWidth = mnDX - nLeft - nRight;
  2173. if( nWinWidth > nLineSize )
  2174. nLineSize = nWinWidth;
  2175. }
  2176. }
  2177. // no calculation if the window has no size (nMax=0)
  2178. // non scrolling toolboxes must be computed though
  2179. if ( (nMax <= 0) && mbScroll )
  2180. {
  2181. mnVisLines = 1;
  2182. mnCurLine = 1;
  2183. mnCurLines = 1;
  2184. it = mpData->m_aItems.begin();
  2185. while ( it != mpData->m_aItems.end() )
  2186. {
  2187. it->maRect = aEmptyRect;
  2188. // For items not visible, release resources only needed during
  2189. // painting the items (on Win98, for example, these are system-wide
  2190. // resources that are easily exhausted, so be nice):
  2191. /* !!!
  2192. it->maImage.ClearCaches();
  2193. it->maHighImage.ClearCaches();
  2194. */
  2195. ++it;
  2196. }
  2197. maLowerRect = aEmptyRect;
  2198. maUpperRect = aEmptyRect;
  2199. maNextToolRect = aEmptyRect;
  2200. }
  2201. else
  2202. {
  2203. // init start values
  2204. nX = nLeft; // top-left offset
  2205. nY = nTop;
  2206. nFormatLine = 1;
  2207. bLastSep = TRUE;
  2208. // save old scroll rectangles and reset them
  2209. Rectangle aOldLowerRect = maLowerRect;
  2210. Rectangle aOldUpperRect = maUpperRect;
  2211. Rectangle aOldNextToolRect = maNextToolRect;
  2212. Rectangle aOldMenubuttonRect = mpData->maMenubuttonItem.maRect;
  2213. maUpperRect = aEmptyRect;
  2214. maLowerRect = aEmptyRect;
  2215. maNextToolRect = aEmptyRect;
  2216. mpData->maMenubuttonItem.maRect = aEmptyRect;
  2217. // additional toolboxes require a toggle button (maNextToolRect)
  2218. if ( maNextToolBoxStr.Len() && mbScroll )
  2219. {
  2220. nMax -= TB_NEXT_SIZE-TB_NEXT_OFFSET;
  2221. if ( mbHorz )
  2222. {
  2223. maNextToolRect.Left() = nLeft+nMax;
  2224. maNextToolRect.Right() = maNextToolRect.Left()+TB_NEXT_SIZE-1;
  2225. maNextToolRect.Top() = nTop;
  2226. maNextToolRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
  2227. }
  2228. else
  2229. {
  2230. maNextToolRect.Top() = nTop+nMax;
  2231. maNextToolRect.Bottom() = maNextToolRect.Top()+TB_NEXT_SIZE-1;
  2232. maNextToolRect.Left() = nLeft;
  2233. maNextToolRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
  2234. }
  2235. }
  2236. // do we have any toolbox items at all ?
  2237. if ( !mpData->m_aItems.empty() || IsMenuEnabled() )
  2238. {
  2239. // compute line breaks and visible lines give the current window width (nMax)
  2240. // the break indicators will be stored within each item (it->mbBreak)
  2241. mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
  2242. // check for scrollbar buttons or dropdown menu
  2243. // (if a menu is enabled, this will be used to store clipped
  2244. // items and no scroll buttons will appear)
  2245. if ( (!ImplIsFloatingMode() && (mnCurLines > mnVisLines) && mbScroll ) ||
  2246. IsMenuEnabled() )
  2247. {
  2248. // compute linebreaks again, incorporating scrollbar buttons
  2249. if( !IsMenuEnabled() )
  2250. {
  2251. nMax -= TB_SPIN_SIZE+TB_SPIN_OFFSET;
  2252. mnCurLines = ImplCalcBreaks( nMax, NULL, mbHorz );
  2253. }
  2254. // compute scroll rectangles or menu button
  2255. if ( mbHorz )
  2256. {
  2257. if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
  2258. {
  2259. if( !ImplIsFloatingMode() )
  2260. {
  2261. mpData->maMenubuttonItem.maRect.Right() = mnDX - 2;
  2262. mpData->maMenubuttonItem.maRect.Top() = nTop;
  2263. mpData->maMenubuttonItem.maRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
  2264. }
  2265. else
  2266. {
  2267. mpData->maMenubuttonItem.maRect.Right() = mnDX - mnRightBorder-mnBorderX-TB_BORDER_OFFSET1-1;
  2268. mpData->maMenubuttonItem.maRect.Top() = nTop;
  2269. mpData->maMenubuttonItem.maRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
  2270. }
  2271. mpData->maMenubuttonItem.maRect.Left() = mpData->maMenubuttonItem.maRect.Right() - mpData->mnMenuButtonWidth;
  2272. }
  2273. else
  2274. {
  2275. maUpperRect.Left() = nLeft+nMax+TB_SPIN_OFFSET;
  2276. maUpperRect.Right() = maUpperRect.Left()+TB_SPIN_SIZE-1;
  2277. maUpperRect.Top() = nTop;
  2278. maLowerRect.Bottom() = mnDY-mnBottomBorder-mnBorderY-TB_BORDER_OFFSET2-1;
  2279. maLowerRect.Left() = maUpperRect.Left();
  2280. maLowerRect.Right() = maUpperRect.Right();
  2281. maUpperRect.Bottom() = maUpperRect.Top() +
  2282. (maLowerRect.Bottom()-maUpperRect.Top())/2;
  2283. maLowerRect.Top() = maUpperRect.Bottom();
  2284. }
  2285. }
  2286. else
  2287. {
  2288. if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
  2289. {
  2290. if( !ImplIsFloatingMode() )
  2291. {
  2292. mpData->maMenubuttonItem.maRect.Bottom() = mnDY - 2;
  2293. mpData->maMenubuttonItem.maRect.Left() = nLeft;
  2294. mpData->maMenubuttonItem.maRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
  2295. }
  2296. else
  2297. {
  2298. mpData->maMenubuttonItem.maRect.Bottom() = mnDY - mnBottomBorder-mnBorderY-TB_BORDER_OFFSET1-1;
  2299. mpData->maMenubuttonItem.maRect.Left() = nLeft;
  2300. mpData->maMenubuttonItem.maRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
  2301. }
  2302. mpData->maMenubuttonItem.maRect.Top() = mpData->maMenubuttonItem.maRect.Bottom() - mpData->mnMenuButtonWidth;
  2303. }
  2304. else
  2305. {
  2306. maUpperRect.Top() = nTop+nMax+TB_SPIN_OFFSET;;
  2307. maUpperRect.Bottom() = maUpperRect.Top()+TB_SPIN_SIZE-1;
  2308. maUpperRect.Left() = nLeft;
  2309. maLowerRect.Right() = mnDX-mnRightBorder-mnBorderX-TB_BORDER_OFFSET2-1;
  2310. maLowerRect.Top() = maUpperRect.Top();
  2311. maLowerRect.Bottom() = maUpperRect.Bottom();
  2312. maUpperRect.Right() = maUpperRect.Left() +
  2313. (maLowerRect.Right()-maUpperRect.Left())/2;
  2314. maLowerRect.Left() = maUpperRect.Right();
  2315. }
  2316. }
  2317. }
  2318. // no scrolling when there is a "more"-menu
  2319. // anything will "fit" in a single line then
  2320. if( IsMenuEnabled() )
  2321. mnCurLines = 1;
  2322. // determine the currently visible line
  2323. if ( mnVisLines >= mnCurLines )
  2324. mnCurLine = 1;
  2325. else if ( mnCurLine+mnVisLines-1 > mnCurLines )
  2326. mnCurLine = mnCurLines - (mnVisLines-1);
  2327. it = mpData->m_aItems.begin();
  2328. while ( it != mpData->m_aItems.end() )
  2329. {
  2330. // hide double separators
  2331. if ( it->meType == TOOLBOXITEM_SEPARATOR )
  2332. {
  2333. it->mbVisible = FALSE;
  2334. if ( !bLastSep )
  2335. {
  2336. // check if any visible items have to appear behind it
  2337. temp_it = it+1;
  2338. while ( temp_it != mpData->m_aItems.end() )
  2339. {
  2340. if ( (temp_it->meType == TOOLBOXITEM_SEPARATOR) ||
  2341. ((temp_it->meType == TOOLBOXITEM_BUTTON) &&
  2342. temp_it->mbVisible) )
  2343. {
  2344. it->mbVisible = TRUE;
  2345. break;
  2346. }
  2347. ++temp_it;
  2348. }
  2349. }
  2350. bLastSep = TRUE;
  2351. }
  2352. else if ( it->mbVisible )
  2353. bLastSep = FALSE;
  2354. it->mbShowWindow = FALSE;
  2355. // check for line break and advance nX/nY accordingly
  2356. if ( it->mbBreak )
  2357. {
  2358. nFormatLine++;
  2359. // increment starting with the second line
  2360. if ( nFormatLine > mnCurLine )
  2361. {
  2362. if ( mbHorz )
  2363. {
  2364. nX = nLeft;
  2365. if ( mnWinStyle & WB_LINESPACING )
  2366. nY += nLineSize+TB_LINESPACING;
  2367. else
  2368. nY += nLineSize;
  2369. }
  2370. else
  2371. {
  2372. nY = nTop;
  2373. if ( mnWinStyle & WB_LINESPACING )
  2374. nX += nLineSize+TB_LINESPACING;
  2375. else
  2376. nX += nLineSize;
  2377. }
  2378. }
  2379. }
  2380. if ( !it->mbVisible || (nFormatLine < mnCurLine) ||
  2381. (nFormatLine > mnCurLine+mnVisLines-1) )
  2382. // item is not visible
  2383. it->maCalcRect = aEmptyRect;
  2384. else
  2385. {
  2386. // 1. determine current item width/height
  2387. // take window size and orientation into account, because this affects the size of item windows
  2388. Size aCurrentItemSize( it->GetSize( mbHorz, mbScroll, nMax, Size(mnMaxItemWidth, mnMaxItemHeight) ) );
  2389. // 2. position item rect and use size from step 1
  2390. // items will be centered horizontally (if mbHorz) or vertically
  2391. // advance nX and nY accordingly
  2392. if ( mbHorz )
  2393. {
  2394. it->maCalcRect.Left() = nX;
  2395. it->maCalcRect.Top() = nY+(nLineSize-aCurrentItemSize.Height())/2;
  2396. it->maCalcRect.Right() = nX+aCurrentItemSize.Width()-1;
  2397. it->maCalcRect.Bottom() = it->maCalcRect.Top()+aCurrentItemSize.Height()-1;
  2398. nX += aCurrentItemSize.Width();
  2399. }
  2400. else
  2401. {
  2402. it->maCalcRect.Left() = nX+(nLineSize-aCurrentItemSize.Width())/2;
  2403. it->maCalcRect.Top() = nY;
  2404. it->maCalcRect.Right() = it->maCalcRect.Left()+aCurrentItemSize.Width()-1;
  2405. it->maCalcRect.Bottom() = nY+aCurrentItemSize.Height()-1;
  2406. nY += aCurrentItemSize.Height();
  2407. }
  2408. }
  2409. // position window items into calculated item rect
  2410. if ( it->mpWindow )
  2411. {
  2412. if ( it->mbShowWindow )
  2413. {
  2414. Point aPos( it->maCalcRect.Left(), it->maCalcRect.Top() );
  2415. it->mpWindow->SetPosPixel( aPos );
  2416. if ( !mbCustomizeMode )
  2417. it->mpWindow->Show();
  2418. }
  2419. else
  2420. it->mpWindow->Hide();
  2421. }
  2422. ++it;
  2423. } // end of loop over all items
  2424. }
  2425. else
  2426. // we have no toolbox items
  2427. mnCurLines = 1;
  2428. if( IsMenuEnabled() && ImplIsFloatingMode() && !ImplHasExternalMenubutton() && !bIsInPopupMode )
  2429. {
  2430. // custom menu will be the last button in floating mode
  2431. ImplToolItem &rIt = mpData->maMenubuttonItem;
  2432. if ( mbHorz )
  2433. {
  2434. rIt.maRect.Left() = nX+TB_MENUBUTTON_OFFSET;
  2435. rIt.maRect.Top() = nY;
  2436. rIt.maRect.Right() = rIt.maRect.Left() + mpData->mnMenuButtonWidth;
  2437. rIt.maRect.Bottom() = nY+nLineSize-1;
  2438. nX += rIt.maItemSize.Width();
  2439. }
  2440. else
  2441. {
  2442. rIt.maRect.Left() = nX;
  2443. rIt.maRect.Top() = nY+TB_MENUBUTTON_OFFSET;
  2444. rIt.maRect.Right() = nX+nLineSize-1;
  2445. rIt.maRect.Bottom() = rIt.maRect.Top() + mpData->mnMenuButtonWidth;
  2446. nY += rIt.maItemSize.Height();
  2447. }
  2448. }
  2449. // if toolbox visible trigger paint for changed regions
  2450. if ( IsVisible() && !mbFullPaint )
  2451. {
  2452. if ( bMustFullPaint )
  2453. {
  2454. maPaintRect = Rectangle( mnLeftBorder, mnTopBorder,
  2455. mnDX-mnRightBorder, mnDY-mnBottomBorder );
  2456. }
  2457. else
  2458. {
  2459. if ( aOldLowerRect != maLowerRect )
  2460. {
  2461. maPaintRect.Union( maLowerRect );
  2462. maPaintRect.Union( aOldLowerRect );
  2463. }
  2464. if ( aOldUpperRect != maUpperRect )
  2465. {
  2466. maPaintRect.Union( maUpperRect );
  2467. maPaintRect.Union( aOldUpperRect );
  2468. }
  2469. if ( aOldNextToolRect != maNextToolRect )
  2470. {
  2471. maPaintRect.Union( maNextToolRect );
  2472. maPaintRect.Union( aOldNextToolRect );
  2473. }
  2474. if ( aOldMenubuttonRect != mpData->maMenubuttonItem.maRect )
  2475. {
  2476. maPaintRect.Union( mpData->maMenubuttonItem.maRect );
  2477. maPaintRect.Union( aOldMenubuttonRect );
  2478. }
  2479. if ( pWrapper && aOldDragRect != pWrapper->GetDragArea() )
  2480. {
  2481. maPaintRect.Union( pWrapper->GetDragArea() );
  2482. maPaintRect.Union( aOldDragRect );
  2483. }
  2484. it = mpData->m_aItems.begin();
  2485. while ( it != mpData->m_aItems.end() )
  2486. {
  2487. if ( it->maRect != it->maCalcRect )
  2488. {
  2489. maPaintRect.Union( it->maRect );
  2490. maPaintRect.Union( it->maCalcRect );
  2491. }
  2492. ++it;
  2493. }
  2494. }
  2495. Invalidate( maPaintRect );
  2496. }
  2497. // store the new calculated item rects
  2498. maPaintRect = aEmptyRect;
  2499. Rectangle aVisibleRect(Point(0, 0), GetOutputSizePixel());
  2500. it = mpData->m_aItems.begin();
  2501. while ( it != mpData->m_aItems.end() )
  2502. {
  2503. it->maRect = it->maCalcRect;
  2504. if (!it->maRect.IsOver(aVisibleRect))
  2505. {
  2506. // For items not visible, release resources only needed during
  2507. // painting the items (on Win98, for example, these are system-
  2508. // wide resources that are easily exhausted, so be nice):
  2509. /* !!!
  2510. it->maImage.ClearCaches();
  2511. it->maHighImage.ClearCaches();
  2512. */
  2513. }
  2514. ++it;
  2515. }
  2516. }
  2517. // indicate formatting is done
  2518. mbFormat = FALSE;
  2519. }
  2520. // -----------------------------------------------------------------------
  2521. IMPL_LINK( ToolBox, ImplDropdownLongClickHdl, ToolBox*, EMPTYARG )
  2522. {
  2523. if( mnCurPos != TOOLBOX_ITEM_NOTFOUND &&
  2524. (mpData->m_aItems[ mnCurPos ].mnBits & TIB_DROPDOWN)
  2525. )
  2526. {
  2527. mpData->mbDropDownByKeyboard = FALSE;
  2528. GetDropdownClickHdl().Call( this );
  2529. // do not reset data if the dropdown handler opened a floating window
  2530. // see ImplFloatControl()
  2531. if( mpFloatWin == NULL )
  2532. {
  2533. // no floater was opened
  2534. Deactivate();
  2535. ImplDrawItem( mnCurPos, FALSE );
  2536. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  2537. mnCurItemId = 0;
  2538. mnDownItemId = 0;
  2539. mnMouseClicks = 0;
  2540. mnMouseModifier = 0;
  2541. mnHighItemId = 0;
  2542. }
  2543. }
  2544. return 0;
  2545. }
  2546. // -----------------------------------------------------------------------
  2547. IMPL_LINK( ToolBox, ImplUpdateHdl, void*, EMPTYARG )
  2548. {
  2549. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  2550. if( mbFormat )
  2551. ImplFormat();
  2552. return 0;
  2553. }
  2554. // -----------------------------------------------------------------------
  2555. static void ImplDrawMoreIndicator( ToolBox *pBox, const Rectangle& rRect, BOOL bSetColor, BOOL bRotate )
  2556. {
  2557. Color aOldFillColor = pBox->GetFillColor();
  2558. Color aOldLineColor = pBox->GetLineColor();
  2559. pBox->SetLineColor();
  2560. if ( bSetColor )
  2561. {
  2562. if ( pBox->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
  2563. pBox->SetFillColor( Color( COL_WHITE ) );
  2564. else
  2565. pBox->SetFillColor( Color( COL_BLACK ) );
  2566. }
  2567. if( !bRotate )
  2568. {
  2569. long width = 8;
  2570. long height = 5;
  2571. long x = rRect.Left() + (rRect.getWidth() - width)/2 + 1;
  2572. long y = rRect.Top() + (rRect.getHeight() - height)/2 + 1;
  2573. while( height >= 1)
  2574. {
  2575. pBox->DrawRect( Rectangle( x, y, x+1, y ) );
  2576. x+=4;
  2577. pBox->DrawRect( Rectangle( x, y, x+1, y ) );
  2578. x-=4;
  2579. y++;
  2580. if( height <= 3) x--;
  2581. else x++;
  2582. height--;
  2583. }
  2584. }
  2585. else
  2586. {
  2587. long width = 5;
  2588. long height = 8;
  2589. long x = rRect.Left() + (rRect.getWidth() - width)/2 + 1;
  2590. long y = rRect.Top() + (rRect.getHeight() - height)/2 + 1;
  2591. while( width >= 1)
  2592. {
  2593. pBox->DrawRect( Rectangle( x, y, x, y+1 ) );
  2594. y+=4;
  2595. pBox->DrawRect( Rectangle( x, y, x, y+1 ) );
  2596. y-=4;
  2597. x++;
  2598. if( width <= 3) y--;
  2599. else y++;
  2600. width--;
  2601. }
  2602. }
  2603. pBox->SetFillColor( aOldFillColor );
  2604. pBox->SetLineColor( aOldLineColor );
  2605. }
  2606. static void ImplDrawDropdownArrow( ToolBox *pBox, const Rectangle& rDropDownRect, BOOL bSetColor, BOOL bRotate )
  2607. {
  2608. BOOL bLineColor = pBox->IsLineColor();
  2609. BOOL bFillColor = pBox->IsFillColor();
  2610. Color aOldFillColor = pBox->GetFillColor();
  2611. Color aOldLineColor = pBox->GetLineColor();
  2612. pBox->SetLineColor();
  2613. if ( bSetColor )
  2614. {
  2615. if ( pBox->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
  2616. pBox->SetFillColor( Color( COL_WHITE ) );
  2617. else
  2618. pBox->SetFillColor( Color( COL_BLACK ) );
  2619. }
  2620. if( !bRotate )
  2621. {
  2622. long width = 5;
  2623. long height = 3;
  2624. long x = rDropDownRect.Left() + (rDropDownRect.getWidth() - width)/2;
  2625. long y = rDropDownRect.Top() + (rDropDownRect.getHeight() - height)/2;
  2626. while( width >= 1)
  2627. {
  2628. pBox->DrawRect( Rectangle( x, y, x+width-1, y ) );
  2629. y++; x++;
  2630. width -= 2;
  2631. }
  2632. }
  2633. else
  2634. {
  2635. long width = 3;
  2636. long height = 5;
  2637. long x = rDropDownRect.Left() + (rDropDownRect.getWidth() - width)/2;
  2638. long y = rDropDownRect.Top() + (rDropDownRect.getHeight() - height)/2;
  2639. while( height >= 1)
  2640. {
  2641. pBox->DrawRect( Rectangle( x, y, x, y+height-1 ) );
  2642. y++; x++;
  2643. height -= 2;
  2644. }
  2645. }
  2646. if( bFillColor )
  2647. pBox->SetFillColor( aOldFillColor );
  2648. else
  2649. pBox->SetFillColor();
  2650. if( bLineColor )
  2651. pBox->SetLineColor( aOldLineColor );
  2652. else
  2653. pBox->SetLineColor( );
  2654. }
  2655. void ToolBox::ImplDrawToolArrow( ToolBox* pBox, long nX, long nY, BOOL bBlack, BOOL bColTransform,
  2656. BOOL bLeft, BOOL bTop, long nSize )
  2657. {
  2658. Color aOldFillColor = pBox->GetFillColor();
  2659. WindowAlign eAlign = pBox->meAlign;
  2660. long n = 0;
  2661. long nHalfSize;
  2662. if ( bLeft )
  2663. eAlign = WINDOWALIGN_RIGHT;
  2664. else if ( bTop )
  2665. eAlign = WINDOWALIGN_BOTTOM;
  2666. nHalfSize = nSize/2;
  2667. switch ( eAlign )
  2668. {
  2669. case WINDOWALIGN_LEFT:
  2670. if ( bBlack )
  2671. pBox->SetFillColor( Color( bColTransform ? COL_WHITE : COL_BLACK ) );
  2672. while ( n <= nHalfSize )
  2673. {
  2674. pBox->DrawRect( Rectangle( nX+n, nY+n, nX+n, nY+nSize-n ) );
  2675. n++;
  2676. }
  2677. if ( bBlack )
  2678. {
  2679. pBox->SetFillColor( aOldFillColor );
  2680. n = 1;
  2681. while ( n < nHalfSize )
  2682. {
  2683. pBox->DrawRect( Rectangle( nX+n, nY+1+n, nX+n, nY+nSize-1-n ) );
  2684. n++;
  2685. }
  2686. }
  2687. break;
  2688. case WINDOWALIGN_TOP:
  2689. if ( bBlack )
  2690. pBox->SetFillColor( Color( bColTransform ? COL_WHITE : COL_BLACK ) );
  2691. while ( n <= nHalfSize )
  2692. {
  2693. pBox->DrawRect( Rectangle( nX+n, nY+n, nX+nSize-n, nY+n ) );
  2694. n++;
  2695. }
  2696. if ( bBlack )
  2697. {
  2698. pBox->SetFillColor( aOldFillColor );
  2699. n = 1;
  2700. while ( n < nHalfSize )
  2701. {
  2702. pBox->DrawRect( Rectangle( nX+1+n, nY+n, nX+nSize-1-n, nY+n ) );
  2703. n++;
  2704. }
  2705. }
  2706. break;
  2707. case WINDOWALIGN_RIGHT:
  2708. if ( bBlack )
  2709. pBox->SetFillColor( Color( bColTransform ? COL_WHITE : COL_BLACK ) );
  2710. while ( n <= nHalfSize )
  2711. {
  2712. pBox->DrawRect( Rectangle( nX+nHalfSize-n, nY+n, nX+nHalfSize-n, nY+nSize-n ) );
  2713. n++;
  2714. }
  2715. if ( bBlack )
  2716. {
  2717. pBox->SetFillColor( aOldFillColor );
  2718. n = 1;
  2719. while ( n < nHalfSize )
  2720. {
  2721. pBox->DrawRect( Rectangle( nX+nHalfSize-n, nY+1+n, nX+nHalfSize-n, nY+nSize-1-n ) );
  2722. n++;
  2723. }
  2724. }
  2725. break;
  2726. case WINDOWALIGN_BOTTOM:
  2727. if ( bBlack )
  2728. pBox->SetFillColor( Color( bColTransform ? COL_WHITE : COL_BLACK ) );
  2729. while ( n <= nHalfSize )
  2730. {
  2731. pBox->DrawRect( Rectangle( nX+n, nY+nHalfSize-n, nX+nSize-n, nY+nHalfSize-n ) );
  2732. n++;
  2733. }
  2734. if ( bBlack )
  2735. {
  2736. pBox->SetFillColor( aOldFillColor );
  2737. n = 1;
  2738. while ( n < nHalfSize )
  2739. {
  2740. pBox->DrawRect( Rectangle( nX+1+n, nY+nHalfSize-n, nX+nSize-1-n, nY+nHalfSize-n ) );
  2741. n++;
  2742. }
  2743. }
  2744. break;
  2745. }
  2746. }
  2747. void ToolBox::SetToolArrowClipregion( ToolBox* pBox, long nX, long nY,
  2748. BOOL bLeft, BOOL bTop, long nSize )
  2749. {
  2750. WindowAlign eAlign = pBox->meAlign;
  2751. long nHalfSize;
  2752. if ( bLeft )
  2753. eAlign = WINDOWALIGN_RIGHT;
  2754. else if ( bTop )
  2755. eAlign = WINDOWALIGN_BOTTOM;
  2756. nHalfSize = nSize/2;
  2757. Point p[6];
  2758. switch ( eAlign )
  2759. {
  2760. case WINDOWALIGN_LEFT:
  2761. p[0].X() = nX-1; p[0].Y() = nY-1;
  2762. p[1].X() = nX-1; p[1].Y() = nY+nSize+1;
  2763. p[2].X() = nX+1; p[2].Y() = nY+nSize+1;
  2764. p[3].X() = nX+nHalfSize+1; p[3].Y() = nY+nHalfSize+1;
  2765. p[4].X() = nX+nHalfSize+1; p[4].Y() = nY+nHalfSize-1;
  2766. p[5].X() = nX+1; p[5].Y() = nY-1;
  2767. break;
  2768. case WINDOWALIGN_TOP:
  2769. p[0].X() = nX-1; p[0].Y() = nY-1;
  2770. p[1].X() = nX-1; p[1].Y() = nY+1;
  2771. p[2].X() = nX+nHalfSize-1; p[2].Y() = nY+nHalfSize+1;
  2772. p[3].X() = nX+nHalfSize+1; p[3].Y() = nY+nHalfSize+1;
  2773. p[4].X() = nX+nSize+1; p[4].Y() = nY+1;
  2774. p[5].X() = nX+nSize+1; p[5].Y() = nY-1;
  2775. break;
  2776. case WINDOWALIGN_RIGHT:
  2777. p[0].X() = nX+nHalfSize-1; p[0].Y() = nY-1;
  2778. p[1].X() = nX-1; p[1].Y() = nY+nHalfSize-1;
  2779. p[2].X() = nX-1; p[2].Y() = nY+nHalfSize+1;
  2780. p[3].X() = nX+nHalfSize-1; p[3].Y() = nY+nSize+1;
  2781. p[4].X() = nX+nHalfSize+1; p[4].Y() = nY+nSize+1;
  2782. p[5].X() = nX+nHalfSize+1; p[5].Y() = nY-1;
  2783. break;
  2784. case WINDOWALIGN_BOTTOM:
  2785. p[0].X() = nX-1; p[0].Y() = nY+nHalfSize-1;
  2786. p[1].X() = nX-1; p[1].Y() = nY+nHalfSize+1;
  2787. p[2].X() = nX+nSize+1; p[2].Y() = nY+nHalfSize+1;
  2788. p[3].X() = nX+nSize+1; p[3].Y() = nY+nHalfSize-1;
  2789. p[4].X() = nX+nHalfSize+1; p[4].Y() = nY-1;
  2790. p[5].X() = nX+nHalfSize-1; p[5].Y() = nY-1;
  2791. break;
  2792. }
  2793. Polygon aPoly(6,p);
  2794. Region aRgn( aPoly );
  2795. pBox->SetClipRegion( aRgn );
  2796. }
  2797. // -----------------------------------------------------------------------
  2798. void ToolBox::ImplDrawMenubutton( ToolBox *pThis, BOOL bHighlight )
  2799. {
  2800. if( !pThis->mpData->maMenubuttonItem.maRect.IsEmpty() )
  2801. {
  2802. // #i53937# paint menu button only if necessary
  2803. if( !(pThis->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE) && !pThis->ImplHasClippedItems() )
  2804. return;
  2805. // execute pending paint requests
  2806. ImplCheckUpdate( pThis );
  2807. BOOL bFillColor = pThis->IsFillColor();
  2808. BOOL bLineColor = pThis->IsLineColor();
  2809. Color aOldFillCol = pThis->GetFillColor();
  2810. Color aOldLineCol = pThis->GetLineColor();
  2811. BOOL bNativeButtons = pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON );
  2812. Rectangle aInnerRect( pThis->mpData->maMenubuttonItem.maRect );
  2813. if( pThis->mpData->mnMenuButtonWidth > TB_MENUBUTTON_SIZE )
  2814. {
  2815. long nDiff = pThis->mpData->mnMenuButtonWidth - TB_MENUBUTTON_SIZE;
  2816. long nDiff1 = nDiff/2;
  2817. long nDiff2 = nDiff - nDiff1;
  2818. if( pThis->IsHorizontal() )
  2819. {
  2820. aInnerRect.Left() += nDiff1;
  2821. aInnerRect.Right() -= nDiff2;
  2822. }
  2823. else
  2824. {
  2825. aInnerRect.Top() += nDiff1;
  2826. aInnerRect.Bottom() -= nDiff2;
  2827. }
  2828. }
  2829. if( pThis->IsHorizontal() )
  2830. {
  2831. aInnerRect.nLeft+=2;
  2832. aInnerRect.nRight-=1;
  2833. aInnerRect.nTop+=1;
  2834. aInnerRect.nBottom-=1;
  2835. }
  2836. else
  2837. {
  2838. aInnerRect.nLeft+=1;
  2839. aInnerRect.nRight-=1;
  2840. aInnerRect.nTop+=2;
  2841. aInnerRect.nBottom-=1;
  2842. }
  2843. ImplErase( pThis, bNativeButtons ? pThis->mpData->maMenubuttonItem.maRect : aInnerRect, bHighlight );
  2844. if( bHighlight )
  2845. {
  2846. if( bNativeButtons )
  2847. ImplDrawButton( pThis, pThis->mpData->maMenubuttonItem.maRect, 2, FALSE, TRUE, FALSE );
  2848. else
  2849. pThis->DrawSelectionBackground( aInnerRect, 2, FALSE, FALSE, FALSE );
  2850. }
  2851. else
  2852. {
  2853. // improve visibility by using a dark gradient
  2854. Gradient g;
  2855. g.SetAngle( pThis->mbHorz ? 0 : 900 );
  2856. g.SetStyle( GRADIENT_LINEAR );
  2857. g.SetStartColor( pThis->GetSettings().GetStyleSettings().GetFaceColor() );
  2858. g.SetEndColor( pThis->GetSettings().GetStyleSettings().GetShadowColor() );
  2859. pThis->DrawGradient( aInnerRect, g );
  2860. }
  2861. Rectangle aRect( aInnerRect );
  2862. if( pThis->mbHorz )
  2863. aRect.Top() = aRect.Bottom() - aRect.getHeight()/3;
  2864. else
  2865. aRect.Left() = aRect.Right() - aRect.getWidth()/3;
  2866. if( pThis->mpData->maMenuType & TOOLBOX_MENUTYPE_CUSTOMIZE )
  2867. ImplDrawDropdownArrow( pThis, aRect, TRUE, !pThis->mbHorz );
  2868. if( pThis->ImplHasClippedItems() )
  2869. {
  2870. aRect = aInnerRect;
  2871. if( pThis->mbHorz )
  2872. aRect.Bottom() = aRect.Top() + aRect.getHeight()/3;
  2873. else
  2874. aRect.Right() = aRect.Left() + aRect.getWidth()/3;
  2875. ImplDrawMoreIndicator( pThis, aRect, TRUE, !pThis->mbHorz );
  2876. }
  2877. // store highlight state
  2878. pThis->mpData->mbMenubuttonSelected = bHighlight;
  2879. // restore colors
  2880. if( bFillColor )
  2881. pThis->SetFillColor( aOldFillCol );
  2882. else
  2883. pThis->SetFillColor();
  2884. if( bLineColor )
  2885. pThis->SetLineColor( aOldLineCol );
  2886. else
  2887. pThis->SetLineColor();
  2888. }
  2889. }
  2890. // -----------------------------------------------------------------------
  2891. void ToolBox::ImplDrawSpin( BOOL bUpperIn, BOOL bLowerIn )
  2892. {
  2893. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  2894. BOOL bTmpUpper;
  2895. BOOL bTmpLower;
  2896. if ( maUpperRect.IsEmpty() || maLowerRect.IsEmpty() )
  2897. return;
  2898. if ( mnCurLine > 1 )
  2899. bTmpUpper = TRUE;
  2900. else
  2901. bTmpUpper = FALSE;
  2902. if ( mnCurLine+mnVisLines-1 < mnCurLines )
  2903. bTmpLower = TRUE;
  2904. else
  2905. bTmpLower = FALSE;
  2906. if ( !IsEnabled() )
  2907. {
  2908. bTmpUpper = FALSE;
  2909. bTmpLower = FALSE;
  2910. }
  2911. ImplDrawSpinButton( this, maUpperRect, maLowerRect,
  2912. bUpperIn, bLowerIn, bTmpUpper, bTmpLower, !mbHorz );
  2913. }
  2914. // -----------------------------------------------------------------------
  2915. void ToolBox::ImplDrawNext( BOOL bIn )
  2916. {
  2917. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  2918. if ( maNextToolRect.IsEmpty() )
  2919. return;
  2920. DecorationView aDecoView( this );
  2921. // Button malen
  2922. long nX = SMALLBUTTON_OFF_NORMAL_X;
  2923. long nY = SMALLBUTTON_OFF_NORMAL_Y;
  2924. USHORT nStyle = 0;
  2925. if ( bIn == 1 )
  2926. {
  2927. nStyle |= BUTTON_DRAW_PRESSED;
  2928. nX = SMALLBUTTON_OFF_PRESSED_X;
  2929. nY = SMALLBUTTON_OFF_PRESSED_Y;
  2930. }
  2931. aDecoView.DrawButton( maNextToolRect, nStyle );
  2932. // Inhalt ausgeben
  2933. BOOL bLeft = FALSE;
  2934. BOOL bTop = FALSE;
  2935. if ( mbHorz )
  2936. {
  2937. bLeft = TRUE;
  2938. nX += (maNextToolRect.GetWidth()-6)/2-4;
  2939. nY += (maNextToolRect.GetHeight()-6)/2-6;
  2940. }
  2941. else
  2942. {
  2943. bTop = TRUE;
  2944. nY += (maNextToolRect.GetHeight()-6)/2-4;
  2945. nX += (maNextToolRect.GetWidth()-6)/2-6;
  2946. }
  2947. nX += maNextToolRect.Left();
  2948. nY += maNextToolRect.Top();
  2949. SetLineColor();
  2950. SetFillColor( COL_LIGHTBLUE );
  2951. ImplDrawToolArrow( this, nX, nY, TRUE, FALSE, bLeft, bTop, 10 );
  2952. }
  2953. // -----------------------------------------------------------------------
  2954. static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, USHORT highlight, BOOL bChecked, BOOL bEnabled, BOOL bIsWindow )
  2955. {
  2956. // draws toolbar button background either native or using a coloured selection
  2957. // if bIsWindow is TRUE, the corresponding item is a control and only a selection border will be drawn
  2958. BOOL bNativeOk = FALSE;
  2959. if( !bIsWindow && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
  2960. {
  2961. ImplControlValue aControlValue;
  2962. Region aCtrlRegion( rRect );
  2963. ControlState nState = 0;
  2964. if ( highlight == 1 ) nState |= CTRL_STATE_PRESSED;
  2965. if ( highlight == 2 ) nState |= CTRL_STATE_ROLLOVER;
  2966. if ( bEnabled ) nState |= CTRL_STATE_ENABLED;
  2967. aControlValue.setTristateVal( bChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
  2968. bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
  2969. aCtrlRegion, nState, aControlValue, rtl::OUString() );
  2970. }
  2971. if( !bNativeOk )
  2972. pThis->DrawSelectionBackground( rRect, bIsWindow ? 3 : highlight, bChecked, TRUE, bIsWindow, 2, NULL, NULL );
  2973. }
  2974. void ToolBox::ImplDrawItem( USHORT nPos, BOOL bHighlight, BOOL bPaint, BOOL bLayout )
  2975. {
  2976. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  2977. if( nPos >= mpData->m_aItems.size() )
  2978. return;
  2979. // execute pending paint requests
  2980. ImplCheckUpdate( this );
  2981. ImplDisableFlatButtons();
  2982. SetFillColor();
  2983. ImplToolItem* pItem = &mpData->m_aItems[nPos];
  2984. MetricVector* pVector = bLayout ? &mpData->m_pLayoutData->m_aUnicodeBoundRects : NULL;
  2985. String* pDisplayText = bLayout ? &mpData->m_pLayoutData->m_aDisplayText : NULL;
  2986. // Falls Rechteck ausserhalb des sichbaren Bereichs liegt
  2987. if ( pItem->maRect.IsEmpty() )
  2988. return;
  2989. const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
  2990. // no gradient background for items that have a popup open
  2991. BOOL bHasOpenPopup = (mpFloatWin != NULL) && (mnDownItemId==pItem->mnId);
  2992. BOOL bHighContrastWhite = FALSE;
  2993. // check the face color as highcontrast indicator
  2994. // because the toolbox itself might have a gradient
  2995. if( rStyleSettings.GetFaceColor() == Color( COL_WHITE ) )
  2996. bHighContrastWhite = TRUE;
  2997. // draw separators in flat style only
  2998. if ( !bLayout &&
  2999. (mnOutStyle & TOOLBOX_STYLE_FLAT) &&
  3000. (pItem->meType == TOOLBOXITEM_SEPARATOR) &&
  3001. nPos > 0
  3002. )
  3003. {
  3004. // no separator before or after windows or at breaks
  3005. ImplToolItem* pTempItem = &mpData->m_aItems[nPos-1];
  3006. if ( pTempItem && !pTempItem->mbShowWindow && nPos < mpData->m_aItems.size()-1 )
  3007. {
  3008. pTempItem = &mpData->m_aItems[nPos+1];
  3009. if ( !pTempItem->mbShowWindow && !pTempItem->mbBreak )
  3010. {
  3011. long nCenterPos, nSlim;
  3012. SetLineColor( rStyleSettings.GetSeparatorColor() );
  3013. if ( IsHorizontal() )
  3014. {
  3015. nSlim = (pItem->maRect.Bottom() - pItem->maRect.Top ()) / 4;
  3016. nCenterPos = pItem->maRect.Center().X();
  3017. DrawLine( Point( nCenterPos, pItem->maRect.Top() + nSlim ),
  3018. Point( nCenterPos, pItem->maRect.Bottom() - nSlim ) );
  3019. }
  3020. else
  3021. {
  3022. nSlim = (pItem->maRect.Right() - pItem->maRect.Left ()) / 4;
  3023. nCenterPos = pItem->maRect.Center().Y();
  3024. DrawLine( Point( pItem->maRect.Left() + nSlim, nCenterPos ),
  3025. Point( pItem->maRect.Right() - nSlim, nCenterPos ) );
  3026. }
  3027. }
  3028. }
  3029. }
  3030. // do nothing if item is no button or will be displayed as window
  3031. if ( (pItem->meType != TOOLBOXITEM_BUTTON) ||
  3032. (pItem->mbShowWindow && !mbCustomizeMode) )
  3033. return;
  3034. // we need a TBDragMananger to draw the configuration item
  3035. ImplTBDragMgr* pMgr;
  3036. if ( pItem->mnId == mnConfigItem )
  3037. {
  3038. pMgr = ImplGetTBDragMgr();
  3039. pMgr->HideDragRect();
  3040. }
  3041. else
  3042. pMgr = NULL;
  3043. // during configuration mode visible windows will be drawn in a special way
  3044. if ( mbCustomizeMode && pItem->mbShowWindow )
  3045. {
  3046. Font aOldFont = GetFont();
  3047. Color aOldTextColor = GetTextColor();
  3048. SetZoomedPointFont( rStyleSettings.GetAppFont() );
  3049. SetLineColor( Color( COL_BLACK ) );
  3050. SetFillColor( rStyleSettings.GetFieldColor() );
  3051. SetTextColor( rStyleSettings.GetFieldTextColor() );
  3052. if( !bLayout )
  3053. DrawRect( pItem->maRect );
  3054. Size aSize( GetCtrlTextWidth( pItem->maText ), GetTextHeight() );
  3055. Point aPos( pItem->maRect.Left()+2, pItem->maRect.Top() );
  3056. aPos.Y() += (pItem->maRect.GetHeight()-aSize.Height())/2;
  3057. BOOL bClip;
  3058. if ( (aSize.Width() > pItem->maRect.GetWidth()-2) ||
  3059. (aSize.Height() > pItem->maRect.GetHeight()-2) )
  3060. {
  3061. bClip = TRUE;
  3062. Rectangle aTempRect( pItem->maRect.Left()+1, pItem->maRect.Top()+1,
  3063. pItem->maRect.Right()-1, pItem->maRect.Bottom()-1 );
  3064. Region aTempRegion( aTempRect );
  3065. SetClipRegion( aTempRegion );
  3066. }
  3067. else
  3068. bClip = FALSE;
  3069. if( bLayout )
  3070. {
  3071. mpData->m_pLayoutData->m_aLineIndices.push_back( mpData->m_pLayoutData->m_aDisplayText.Len() );
  3072. mpData->m_pLayoutData->m_aLineItemIds.push_back( pItem->mnId );
  3073. mpData->m_pLayoutData->m_aLineItemPositions.push_back( nPos );
  3074. }
  3075. DrawCtrlText( aPos, pItem->maText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
  3076. if ( bClip )
  3077. SetClipRegion();
  3078. SetFont( aOldFont );
  3079. SetTextColor( aOldTextColor );
  3080. // Gegebenenfalls noch Config-Frame zeichnen
  3081. if ( pMgr && !bLayout)
  3082. pMgr->UpdateDragRect();
  3083. return;
  3084. }
  3085. // draw button
  3086. Size aBtnSize = pItem->maRect.GetSize();
  3087. if( ImplGetSVData()->maNWFData.mbToolboxDropDownSeparate )
  3088. {
  3089. // separate button not for dropdown only where the whole button is painted
  3090. if ( pItem->mnBits & TIB_DROPDOWN &&
  3091. ((pItem->mnBits & TIB_DROPDOWNONLY) != TIB_DROPDOWNONLY) )
  3092. {
  3093. Rectangle aArrowRect = pItem->GetDropDownRect( mbHorz );
  3094. if( aArrowRect.Top() == pItem->maRect.Top() ) // dropdown arrow on right side
  3095. aBtnSize.Width() -= aArrowRect.GetWidth();
  3096. else // dropdown arrow on bottom side
  3097. aBtnSize.Height() -= aArrowRect.GetHeight();
  3098. }
  3099. }
  3100. Rectangle aButtonRect( pItem->maRect.TopLeft(), aBtnSize );
  3101. long nOffX = SMALLBUTTON_OFF_NORMAL_X;
  3102. long nOffY = SMALLBUTTON_OFF_NORMAL_Y;
  3103. long nImageOffX=0;
  3104. long nImageOffY=0;
  3105. long nTextOffX=0;
  3106. long nTextOffY=0;
  3107. USHORT nStyle = 0;
  3108. if ( pItem->meState == STATE_CHECK )
  3109. {
  3110. nStyle |= BUTTON_DRAW_CHECKED;
  3111. }
  3112. else if ( pItem->meState == STATE_DONTKNOW )
  3113. {
  3114. nStyle |= BUTTON_DRAW_DONTKNOW;
  3115. }
  3116. if ( bHighlight == 1 )
  3117. {
  3118. nStyle |= BUTTON_DRAW_PRESSED;
  3119. }
  3120. if ( mnOutStyle & TOOLBOX_STYLE_OUTBUTTON )
  3121. {
  3122. nOffX = OUTBUTTON_OFF_NORMAL_X;
  3123. nOffY = OUTBUTTON_OFF_NORMAL_Y;
  3124. if ( bHighlight )
  3125. {
  3126. nOffX++;
  3127. nOffY++;
  3128. }
  3129. }
  3130. if( ! bLayout )
  3131. {
  3132. if ( mnOutStyle & TOOLBOX_STYLE_FLAT )
  3133. {
  3134. if ( (pItem->meState != STATE_NOCHECK) || !bPaint )
  3135. {
  3136. ImplErase( this, pItem->maRect, bHighlight, bHasOpenPopup );
  3137. }
  3138. }
  3139. else
  3140. {
  3141. if ( mnOutStyle & TOOLBOX_STYLE_OUTBUTTON )
  3142. ImplDrawOutButton( this, aButtonRect, nStyle );
  3143. else
  3144. {
  3145. DecorationView aDecoView( this );
  3146. aDecoView.DrawButton( aButtonRect, nStyle );
  3147. }
  3148. }
  3149. }
  3150. nOffX += pItem->maRect.Left();
  3151. nOffY += pItem->maRect.Top();
  3152. // determine what has to be drawn on the button: image, text or both
  3153. BOOL bImage;
  3154. BOOL bText;
  3155. ButtonType tmpButtonType = determineButtonType( pItem, meButtonType ); // default to toolbox setting
  3156. pItem->DetermineButtonDrawStyle( tmpButtonType, bImage, bText );
  3157. // compute output values
  3158. long nBtnWidth = aBtnSize.Width()-SMALLBUTTON_HSIZE;
  3159. long nBtnHeight = aBtnSize.Height()-SMALLBUTTON_VSIZE;
  3160. Size aImageSize;
  3161. Size aTxtSize;
  3162. if ( bText )
  3163. {
  3164. aTxtSize.Width() = GetCtrlTextWidth( pItem->maText );
  3165. aTxtSize.Height() = GetTextHeight();
  3166. }
  3167. if ( bImage && ! bLayout )
  3168. {
  3169. const Image* pImage;
  3170. if ( bHighlight && (!(pItem->maHighImage)) == FALSE )
  3171. pImage = &(pItem->maHighImage);
  3172. else
  3173. pImage = &(pItem->maImage);
  3174. aImageSize = pImage->GetSizePixel();
  3175. // determine drawing flags
  3176. USHORT nImageStyle = 0;
  3177. if ( !pItem->mbEnabled || !IsEnabled() )
  3178. nImageStyle |= IMAGE_DRAW_DISABLE;
  3179. // #i35563# the dontknow state indicates different states at the same time
  3180. // which should not be rendered disabled but normal
  3181. //if ( pItem->meState == STATE_DONTKNOW )
  3182. // nImageStyle |= IMAGE_DRAW_DISABLE;
  3183. // draw the image
  3184. nImageOffX = nOffX;
  3185. nImageOffY = nOffY;
  3186. if ( (pItem->mnBits & (TIB_LEFT|TIB_DROPDOWN)) || bText )
  3187. {
  3188. // left align also to leave space for drop down arrow
  3189. // and when drawing text+image
  3190. // just center in y, except for vertical (ie rotated text)
  3191. if( mbHorz || !bText )
  3192. nImageOffY += (nBtnHeight-aImageSize.Height())/2;
  3193. }
  3194. else
  3195. {
  3196. nImageOffX += (nBtnWidth-aImageSize.Width())/2;
  3197. nImageOffY += (nBtnHeight-aImageSize.Height())/2;
  3198. }
  3199. if ( bHighlight || (pItem->meState == STATE_CHECK) )
  3200. {
  3201. if( bHasOpenPopup )
  3202. ImplDrawFloatwinBorder( pItem );
  3203. else
  3204. ImplDrawButton( this, aButtonRect, bHighlight, pItem->meState == STATE_CHECK, pItem->mbEnabled && IsEnabled(), pItem->mbShowWindow ? TRUE : FALSE );
  3205. if( bHighlight )
  3206. {
  3207. if( bHighContrastWhite )
  3208. nImageStyle |= IMAGE_DRAW_COLORTRANSFORM;
  3209. }
  3210. }
  3211. DrawImage( Point( nImageOffX, nImageOffY ), *pImage, nImageStyle );
  3212. }
  3213. // draw the text
  3214. BOOL bRotate = FALSE;
  3215. if ( bText )
  3216. {
  3217. nTextOffX = nOffX;
  3218. nTextOffY = nOffY;
  3219. // rotate text when vertically docked
  3220. Font aOldFont = GetFont();
  3221. if( pItem->mbVisibleText && !ImplIsFloatingMode() &&
  3222. ((meAlign == WINDOWALIGN_LEFT) || (meAlign == WINDOWALIGN_RIGHT)) )
  3223. {
  3224. bRotate = TRUE;
  3225. Font aRotateFont = aOldFont;
  3226. /*
  3227. if ( meAlign == WINDOWALIGN_LEFT )
  3228. {
  3229. aRotateFont.SetOrientation( 900 );
  3230. nTextOffX += (nBtnWidth-aTxtSize.Height())/2;
  3231. nTextOffY += aTxtSize.Width();
  3232. nTextOffY += (nBtnHeight-aTxtSize.Width())/2;
  3233. }
  3234. else*/
  3235. {
  3236. aRotateFont.SetOrientation( 2700 );
  3237. // center horizontally
  3238. nTextOffX += aTxtSize.Height();
  3239. nTextOffX += (nBtnWidth-aTxtSize.Height())/2;
  3240. // add in image offset
  3241. if( bImage )
  3242. nTextOffY = nImageOffY + aImageSize.Height() + TB_IMAGETEXTOFFSET;
  3243. }
  3244. SetFont( aRotateFont );
  3245. }
  3246. else
  3247. {
  3248. // center vertically
  3249. nTextOffY += (nBtnHeight-aTxtSize.Height())/2;
  3250. // add in image offset
  3251. if( bImage )
  3252. nTextOffX = nImageOffX + aImageSize.Width() + TB_IMAGETEXTOFFSET;
  3253. //nTextOffX += TB_TEXTOFFSET/2;
  3254. }
  3255. // draw selection only if not already drawn during image output (see above)
  3256. if ( !bLayout && !bImage && (bHighlight || (pItem->meState == STATE_CHECK) ) )
  3257. {
  3258. if( bHasOpenPopup )
  3259. ImplDrawFloatwinBorder( pItem );
  3260. else
  3261. ImplDrawButton( this, pItem->maRect, bHighlight, pItem->meState == STATE_CHECK, pItem->mbEnabled && IsEnabled(), pItem->mbShowWindow ? TRUE : FALSE );
  3262. }
  3263. USHORT nTextStyle = 0;
  3264. if ( !pItem->mbEnabled )
  3265. nTextStyle |= TEXT_DRAW_DISABLE;
  3266. if( bLayout )
  3267. {
  3268. mpData->m_pLayoutData->m_aLineIndices.push_back( mpData->m_pLayoutData->m_aDisplayText.Len() );
  3269. mpData->m_pLayoutData->m_aLineItemIds.push_back( pItem->mnId );
  3270. mpData->m_pLayoutData->m_aLineItemPositions.push_back( nPos );
  3271. }
  3272. DrawCtrlText( Point( nTextOffX, nTextOffY ), pItem->maText,
  3273. 0, STRING_LEN, nTextStyle, pVector, pDisplayText );
  3274. if ( bRotate )
  3275. SetFont( aOldFont );
  3276. }
  3277. if( bLayout )
  3278. return;
  3279. // paint optional drop down arrow
  3280. if ( pItem->mnBits & TIB_DROPDOWN )
  3281. {
  3282. Rectangle aDropDownRect( pItem->GetDropDownRect( mbHorz ) );
  3283. BOOL bSetColor = TRUE;
  3284. if ( !pItem->mbEnabled || !IsEnabled() )
  3285. {
  3286. bSetColor = FALSE;
  3287. SetFillColor( rStyleSettings.GetShadowColor() );
  3288. }
  3289. // dropdown only will be painted without inner border
  3290. if( (pItem->mnBits & TIB_DROPDOWNONLY) != TIB_DROPDOWNONLY )
  3291. {
  3292. ImplErase( this, aDropDownRect, bHighlight, bHasOpenPopup );
  3293. if( bHighlight || (pItem->meState == STATE_CHECK) )
  3294. {
  3295. if( bHasOpenPopup )
  3296. ImplDrawFloatwinBorder( pItem );
  3297. else
  3298. ImplDrawButton( this, aDropDownRect, bHighlight, pItem->meState == STATE_CHECK, pItem->mbEnabled && IsEnabled(), FALSE );
  3299. }
  3300. }
  3301. ImplDrawDropdownArrow( this, aDropDownRect, bSetColor, bRotate );
  3302. }
  3303. // Gegebenenfalls noch Config-Frame zeichnen
  3304. if ( pMgr )
  3305. pMgr->UpdateDragRect();
  3306. }
  3307. // -----------------------------------------------------------------------
  3308. void ToolBox::ImplStartCustomizeMode()
  3309. {
  3310. mbCustomizeMode = TRUE;
  3311. mpData->ImplClearLayoutData();
  3312. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3313. while ( it != mpData->m_aItems.end() )
  3314. {
  3315. if ( it->mbShowWindow )
  3316. {
  3317. it->mpWindow->Hide();
  3318. if ( !(it->maRect.IsEmpty()) )
  3319. Invalidate( it->maRect );
  3320. }
  3321. ++it;
  3322. }
  3323. }
  3324. void ToolBox::SetCustomizeMode( BOOL bSet )
  3325. {
  3326. if ( bSet )
  3327. ImplStartCustomizeMode();
  3328. else
  3329. ImplEndCustomizeMode();
  3330. }
  3331. // -----------------------------------------------------------------------
  3332. void ToolBox::ImplEndCustomizeMode()
  3333. {
  3334. mbCustomizeMode = FALSE;
  3335. mpData->ImplClearLayoutData();
  3336. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3337. while ( it != mpData->m_aItems.end() )
  3338. {
  3339. if ( it->mbShowWindow )
  3340. {
  3341. if ( !(it->maRect.IsEmpty()) )
  3342. Invalidate( it->maRect );
  3343. it->mpWindow->Show();
  3344. }
  3345. ++it;
  3346. }
  3347. }
  3348. // -----------------------------------------------------------------------
  3349. void ToolBox::ImplDrawFloatwinBorder( ImplToolItem* pItem )
  3350. {
  3351. if ( !pItem->maRect.IsEmpty() )
  3352. {
  3353. Rectangle aRect( mpFloatWin->ImplGetItemEdgeClipRect() );
  3354. aRect.SetPos( AbsoluteScreenToOutputPixel( aRect.TopLeft() ) );
  3355. SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
  3356. Point p1, p2;
  3357. p1 = pItem->maRect.TopLeft();
  3358. p1.X()++;
  3359. p2 = pItem->maRect.TopRight();
  3360. p2.X()--;
  3361. DrawLine( p1, p2);
  3362. p1 = pItem->maRect.BottomLeft();
  3363. p1.X()++;
  3364. p2 = pItem->maRect.BottomRight();
  3365. p2.X()--;
  3366. DrawLine( p1, p2);
  3367. p1 = pItem->maRect.TopLeft();
  3368. p1.Y()++;
  3369. p2 = pItem->maRect.BottomLeft();
  3370. p2.Y()--;
  3371. DrawLine( p1, p2);
  3372. p1 = pItem->maRect.TopRight();
  3373. p1.Y()++;
  3374. p2 = pItem->maRect.BottomRight();
  3375. p2.Y()--;
  3376. DrawLine( p1, p2);
  3377. //DrawRect( pItem->maRect );
  3378. }
  3379. }
  3380. void ToolBox::ImplFloatControl( BOOL bStart, FloatingWindow* pFloatWindow )
  3381. {
  3382. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  3383. if ( bStart )
  3384. {
  3385. mpFloatWin = pFloatWindow;
  3386. // redraw item, to trigger drawing of a special border
  3387. ImplDrawItem( mnCurPos, TRUE );
  3388. mbDrag = FALSE;
  3389. EndTracking();
  3390. ReleaseMouse();
  3391. }
  3392. else
  3393. {
  3394. mpFloatWin = NULL;
  3395. // if focus is still in this toolbox, then the floater was opened by keyboard
  3396. // draw current item with highlight and keep old state
  3397. BOOL bWasKeyboardActivate = mpData->mbDropDownByKeyboard;
  3398. if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
  3399. ImplDrawItem( mnCurPos, bWasKeyboardActivate ? 2 : 0 );
  3400. Deactivate();
  3401. if( !bWasKeyboardActivate )
  3402. {
  3403. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  3404. mnCurItemId = 0;
  3405. mnHighItemId = 0;
  3406. }
  3407. mnDownItemId = 0;
  3408. }
  3409. }
  3410. // -----------------------------------------------------------------------
  3411. void ToolBox::ShowLine( BOOL bNext )
  3412. {
  3413. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  3414. mbFormat = TRUE;
  3415. if ( mpData->mbPageScroll )
  3416. {
  3417. USHORT delta = mnVisLines;
  3418. if ( bNext )
  3419. {
  3420. mnCurLine = mnCurLine + delta;
  3421. if ( mnCurLine+mnVisLines-1 > mnCurLines )
  3422. mnCurLine = mnCurLines - mnVisLines+1;
  3423. }
  3424. else
  3425. {
  3426. if( mnCurLine >= delta+1 )
  3427. mnCurLine = mnCurLine - delta;
  3428. else
  3429. mnCurLine = 1;
  3430. }
  3431. }
  3432. else
  3433. {
  3434. if ( bNext )
  3435. mnCurLine++;
  3436. else
  3437. mnCurLine--;
  3438. }
  3439. ImplFormat();
  3440. }
  3441. // -----------------------------------------------------------------------
  3442. BOOL ToolBox::ImplHandleMouseMove( const MouseEvent& rMEvt, BOOL bRepeat )
  3443. {
  3444. Point aMousePos = rMEvt.GetPosPixel();
  3445. // Ist ToolBox aktiv
  3446. if ( mbDrag && mnCurPos != TOOLBOX_ITEM_NOTFOUND )
  3447. {
  3448. // Befindet sich Maus ueber dem Item
  3449. ImplToolItem* pItem = &mpData->m_aItems[mnCurPos];
  3450. if ( pItem->maRect.IsInside( aMousePos ) )
  3451. {
  3452. if ( !mnCurItemId )
  3453. {
  3454. ImplDrawItem( mnCurPos, TRUE );
  3455. mnCurItemId = pItem->mnId;
  3456. Highlight();
  3457. }
  3458. if ( (pItem->mnBits & TIB_REPEAT) && bRepeat )
  3459. Select();
  3460. }
  3461. else
  3462. {
  3463. if ( mnCurItemId )
  3464. {
  3465. ImplDrawItem( mnCurPos );
  3466. mnCurItemId = 0;
  3467. ImplDrawItem( mnCurPos );
  3468. Highlight();
  3469. }
  3470. }
  3471. return TRUE;
  3472. }
  3473. if ( mbUpper )
  3474. {
  3475. BOOL bNewIn = maUpperRect.IsInside( aMousePos );
  3476. if ( bNewIn != mbIn )
  3477. {
  3478. mbIn = bNewIn;
  3479. ImplDrawSpin( mbIn, FALSE );
  3480. }
  3481. return TRUE;
  3482. }
  3483. if ( mbLower )
  3484. {
  3485. BOOL bNewIn = maLowerRect.IsInside( aMousePos );
  3486. if ( bNewIn != mbIn )
  3487. {
  3488. mbIn = bNewIn;
  3489. ImplDrawSpin( FALSE, mbIn );
  3490. }
  3491. return TRUE;
  3492. }
  3493. if ( mbNextTool )
  3494. {
  3495. BOOL bNewIn = maNextToolRect.IsInside( aMousePos );
  3496. if ( bNewIn != mbIn )
  3497. {
  3498. mbIn = bNewIn;
  3499. ImplDrawNext( mbIn );
  3500. }
  3501. return TRUE;
  3502. }
  3503. return FALSE;
  3504. }
  3505. // -----------------------------------------------------------------------
  3506. BOOL ToolBox::ImplHandleMouseButtonUp( const MouseEvent& rMEvt, BOOL bCancel )
  3507. {
  3508. ImplDisableFlatButtons();
  3509. // stop eventual running dropdown timer
  3510. if( mnCurPos < mpData->m_aItems.size() &&
  3511. (mpData->m_aItems[mnCurPos].mnBits & TIB_DROPDOWN ) )
  3512. {
  3513. mpData->maDropdownTimer.Stop();
  3514. }
  3515. if ( mbDrag || mbSelection )
  3516. {
  3517. // Hier die MouseDaten setzen, wenn Selection-Modus, da dann kein
  3518. // MouseButtonDown-Handler gerufen wird
  3519. if ( mbSelection )
  3520. {
  3521. mnMouseClicks = rMEvt.GetClicks();
  3522. mnMouseModifier = rMEvt.GetModifier();
  3523. }
  3524. Deactivate();
  3525. if ( mbDrag )
  3526. mbDrag = FALSE;
  3527. else
  3528. {
  3529. mbSelection = FALSE;
  3530. if ( mnCurPos == TOOLBOX_ITEM_NOTFOUND )
  3531. return TRUE;
  3532. }
  3533. // Wurde Maus ueber dem Item losgelassen
  3534. if( mnCurPos < mpData->m_aItems.size() )
  3535. {
  3536. ImplToolItem* pItem = &mpData->m_aItems[mnCurPos];
  3537. if ( pItem->maRect.IsInside( rMEvt.GetPosPixel() ) )
  3538. {
  3539. mnCurItemId = pItem->mnId;
  3540. if ( !bCancel )
  3541. {
  3542. // Gegebenenfalls ein AutoCheck durchfuehren
  3543. if ( pItem->mnBits & TIB_AUTOCHECK )
  3544. {
  3545. if ( pItem->mnBits & TIB_RADIOCHECK )
  3546. {
  3547. if ( pItem->meState != STATE_CHECK )
  3548. SetItemState( pItem->mnId, STATE_CHECK );
  3549. }
  3550. else
  3551. {
  3552. if ( pItem->meState != STATE_CHECK )
  3553. pItem->meState = STATE_CHECK;
  3554. else
  3555. pItem->meState = STATE_NOCHECK;
  3556. }
  3557. }
  3558. // Select nicht bei Repeat ausloesen, da dies schon im
  3559. // MouseButtonDown ausgeloest wurde
  3560. if ( !(pItem->mnBits & TIB_REPEAT) )
  3561. {
  3562. // Gegen zerstoeren im Select-Handler sichern
  3563. ImplDelData aDelData;
  3564. ImplAddDel( &aDelData );
  3565. Select();
  3566. if ( aDelData.IsDelete() )
  3567. return TRUE;
  3568. ImplRemoveDel( &aDelData );
  3569. }
  3570. }
  3571. {
  3572. DBG_CHKTHIS( Window, ImplDbgCheckWindow );
  3573. }
  3574. // Items nicht geloescht, im Select-Handler
  3575. if ( mnCurItemId )
  3576. {
  3577. BOOL bHighlight;
  3578. if ( (mnCurItemId == mnHighItemId) && (mnOutStyle & TOOLBOX_STYLE_FLAT) )
  3579. bHighlight = 2;
  3580. else
  3581. bHighlight = FALSE;
  3582. // Get current pos for the case that items are inserted/removed
  3583. // in the toolBox
  3584. mnCurPos = GetItemPos( mnCurItemId );
  3585. if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
  3586. {
  3587. ImplDrawItem( mnCurPos, bHighlight );
  3588. Flush();
  3589. }
  3590. }
  3591. }
  3592. }
  3593. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  3594. mnCurItemId = 0;
  3595. mnDownItemId = 0;
  3596. mnMouseClicks = 0;
  3597. mnMouseModifier = 0;
  3598. return TRUE;
  3599. }
  3600. else if ( mbUpper || mbLower )
  3601. {
  3602. if ( mbIn )
  3603. ShowLine( !mbUpper );
  3604. mbUpper = FALSE;
  3605. mbLower = FALSE;
  3606. mbIn = FALSE;
  3607. ImplDrawSpin( FALSE, FALSE );
  3608. return TRUE;
  3609. }
  3610. else if ( mbNextTool )
  3611. {
  3612. mbNextTool = FALSE;
  3613. mbIn = FALSE;
  3614. ImplDrawNext( FALSE );
  3615. NextToolBox();
  3616. return TRUE;
  3617. }
  3618. return FALSE;
  3619. }
  3620. // -----------------------------------------------------------------------
  3621. void ToolBox::MouseMove( const MouseEvent& rMEvt )
  3622. {
  3623. // pressing a modifier generates synthetic mouse moves
  3624. // ignore it if keyboard selection is acive
  3625. if( HasFocus() && ( rMEvt.GetMode() & MOUSE_MODIFIERCHANGED ) )
  3626. return;
  3627. if ( ImplHandleMouseMove( rMEvt ) )
  3628. return;
  3629. ImplDisableFlatButtons();
  3630. Point aMousePos = rMEvt.GetPosPixel();
  3631. // only highlight when the focus is not inside a child window of a toolbox
  3632. // eg, in a edit control
  3633. // and do not hilight when focus is in a different toolbox
  3634. BOOL bDrawHotSpot = TRUE;
  3635. Window *pWin = Application::GetFocusWindow();
  3636. if( pWin && pWin->ImplGetWindowImpl()->mbToolBox && pWin != this )
  3637. bDrawHotSpot = FALSE;
  3638. /*
  3639. else
  3640. if( pWin && !pWin->ImplGetWindowImpl()->mbToolBox )
  3641. while( pWin )
  3642. {
  3643. pWin = pWin->GetParent();
  3644. if( pWin && pWin->ImplGetWindowImpl()->mbToolBox )
  3645. {
  3646. bDrawHotSpot = FALSE;
  3647. break;
  3648. }
  3649. }
  3650. */
  3651. if ( mbSelection && bDrawHotSpot )
  3652. {
  3653. USHORT i = 0;
  3654. USHORT nNewPos = TOOLBOX_ITEM_NOTFOUND;
  3655. // Item suchen, das geklickt wurde
  3656. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3657. while ( it != mpData->m_aItems.end() )
  3658. {
  3659. // Wenn Mausposition in diesem Item vorhanden, kann die
  3660. // Suche abgebrochen werden
  3661. if ( it->maRect.IsInside( aMousePos ) )
  3662. {
  3663. // Wenn es ein Button ist, dann wird er selektiert
  3664. if ( it->meType == TOOLBOXITEM_BUTTON )
  3665. {
  3666. // Wenn er disablet ist, findet keine Aenderung
  3667. // statt
  3668. if ( !it->mbEnabled || it->mbShowWindow )
  3669. nNewPos = mnCurPos;
  3670. else
  3671. nNewPos = i;
  3672. }
  3673. break;
  3674. }
  3675. i++;
  3676. ++it;
  3677. }
  3678. // was a new entery selected ?
  3679. // don't change selection if keyboard selection is active and
  3680. // mouse leaves the toolbox
  3681. if ( nNewPos != mnCurPos && !( HasFocus() && nNewPos == TOOLBOX_ITEM_NOTFOUND ) )
  3682. {
  3683. if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
  3684. {
  3685. ImplDrawItem( mnCurPos );
  3686. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( mnCurPos ) );
  3687. }
  3688. mnCurPos = nNewPos;
  3689. if ( mnCurPos != TOOLBOX_ITEM_NOTFOUND )
  3690. {
  3691. mnCurItemId = mnHighItemId = it->mnId;
  3692. ImplDrawItem( mnCurPos, 2 /*TRUE*/ ); // always use shadow effect (2)
  3693. }
  3694. else
  3695. mnCurItemId = mnHighItemId = 0;
  3696. Highlight();
  3697. }
  3698. return;
  3699. }
  3700. if ( mbDragging )
  3701. {
  3702. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  3703. pMgr->Dragging( aMousePos );
  3704. return;
  3705. }
  3706. PointerStyle eStyle = POINTER_ARROW;
  3707. // change mouse cursor over drag area
  3708. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
  3709. if( pWrapper && pWrapper->GetDragArea().IsInside( rMEvt.GetPosPixel() ) )
  3710. eStyle = POINTER_MOVE;
  3711. if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
  3712. {
  3713. if ( rMEvt.GetMode() & MOUSE_SIMPLEMOVE )
  3714. {
  3715. USHORT nLinePtr = ImplTestLineSize( this, rMEvt.GetPosPixel() );
  3716. if ( nLinePtr & DOCK_LINEHSIZE )
  3717. {
  3718. if ( meAlign == WINDOWALIGN_LEFT )
  3719. eStyle = POINTER_WINDOW_ESIZE;
  3720. else
  3721. eStyle = POINTER_WINDOW_WSIZE;
  3722. }
  3723. else if ( nLinePtr & DOCK_LINEVSIZE )
  3724. {
  3725. if ( meAlign == WINDOWALIGN_TOP )
  3726. eStyle = POINTER_WINDOW_SSIZE;
  3727. else
  3728. eStyle = POINTER_WINDOW_NSIZE;
  3729. }
  3730. }
  3731. }
  3732. if ( (eStyle == POINTER_ARROW) && mbCustomizeMode )
  3733. {
  3734. // Item suchen, das geklickt wurde
  3735. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3736. while ( it != mpData->m_aItems.end() )
  3737. {
  3738. // Wenn es ein Customize-Window ist, gegebenenfalls den
  3739. // Resize-Pointer anzeigen
  3740. if ( it->mbShowWindow )
  3741. {
  3742. if ( it->maRect.IsInside( aMousePos ) )
  3743. {
  3744. if ( it->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X() )
  3745. eStyle = POINTER_HSIZEBAR;
  3746. break;
  3747. }
  3748. }
  3749. ++it;
  3750. }
  3751. }
  3752. if ( bDrawHotSpot && ( ((eStyle == POINTER_ARROW) && (mnOutStyle & TOOLBOX_STYLE_HANDPOINTER)) ||
  3753. (mnOutStyle & TOOLBOX_STYLE_FLAT) || !mnOutStyle ) )
  3754. {
  3755. BOOL bClearHigh = TRUE;
  3756. if ( !rMEvt.IsLeaveWindow() && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
  3757. {
  3758. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3759. while ( it != mpData->m_aItems.end() )
  3760. {
  3761. if ( it->maRect.IsInside( aMousePos ) )
  3762. {
  3763. if ( (it->meType == TOOLBOXITEM_BUTTON) && it->mbEnabled )
  3764. {
  3765. if ( !mnOutStyle || (mnOutStyle & TOOLBOX_STYLE_FLAT) )
  3766. {
  3767. bClearHigh = FALSE;
  3768. if ( mnHighItemId != it->mnId )
  3769. {
  3770. USHORT nTempPos = sal::static_int_cast<USHORT>(it - mpData->m_aItems.begin());
  3771. if ( mnHighItemId )
  3772. {
  3773. ImplHideFocus();
  3774. USHORT nPos = GetItemPos( mnHighItemId );
  3775. ImplDrawItem( nPos );
  3776. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nPos ) );
  3777. }
  3778. if ( mpData->mbMenubuttonSelected )
  3779. {
  3780. // remove highlight from menubutton
  3781. ImplDrawMenubutton( this, FALSE );
  3782. }
  3783. mnHighItemId = it->mnId;
  3784. ImplDrawItem( nTempPos, 2 );
  3785. ImplShowFocus();
  3786. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
  3787. }
  3788. }
  3789. if ( mnOutStyle & TOOLBOX_STYLE_HANDPOINTER )
  3790. eStyle = POINTER_REFHAND;
  3791. }
  3792. break;
  3793. }
  3794. ++it;
  3795. }
  3796. }
  3797. // only clear highlight when focus is not in toolbar
  3798. BOOL bMenuButtonHit = mpData->maMenubuttonItem.maRect.IsInside( aMousePos );
  3799. if ( bClearHigh || bMenuButtonHit )
  3800. {
  3801. if ( !bMenuButtonHit && mpData->mbMenubuttonSelected )
  3802. {
  3803. // remove highlight from menubutton
  3804. ImplDrawMenubutton( this, FALSE );
  3805. }
  3806. if( mnHighItemId )
  3807. {
  3808. USHORT nClearPos = GetItemPos( mnHighItemId );
  3809. if ( nClearPos != TOOLBOX_ITEM_NOTFOUND )
  3810. {
  3811. ImplDrawItem( nClearPos, (nClearPos == mnCurPos) ? TRUE : FALSE );
  3812. if( nClearPos != mnCurPos )
  3813. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nClearPos ) );
  3814. }
  3815. ImplHideFocus();
  3816. mnHighItemId = 0;
  3817. }
  3818. if( bMenuButtonHit )
  3819. {
  3820. ImplDrawMenubutton( this, TRUE );
  3821. }
  3822. }
  3823. }
  3824. if ( meLastStyle != eStyle )
  3825. {
  3826. meLastStyle = eStyle;
  3827. Pointer aPtr( eStyle );
  3828. SetPointer( aPtr );
  3829. }
  3830. DockingWindow::MouseMove( rMEvt );
  3831. }
  3832. // -----------------------------------------------------------------------
  3833. void ToolBox::MouseButtonDown( const MouseEvent& rMEvt )
  3834. {
  3835. // Nur bei linker Maustaste ToolBox ausloesen und wenn wir uns nicht
  3836. // noch in der normalen Bearbeitung befinden
  3837. if ( rMEvt.IsLeft() && !mbDrag && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
  3838. {
  3839. // Activate schon hier rufen, da gegebenenfalls noch Items
  3840. // ausgetauscht werden
  3841. Activate();
  3842. // ToolBox hier updaten, damit der Anwender weiss, was Sache ist
  3843. if ( mbFormat )
  3844. {
  3845. ImplFormat();
  3846. Update();
  3847. }
  3848. Point aMousePos = rMEvt.GetPosPixel();
  3849. USHORT i = 0;
  3850. USHORT nNewPos = TOOLBOX_ITEM_NOTFOUND;
  3851. // Item suchen, das geklickt wurde
  3852. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  3853. while ( it != mpData->m_aItems.end() )
  3854. {
  3855. // Ist es dieses Item
  3856. if ( it->maRect.IsInside( aMousePos ) )
  3857. {
  3858. // Ist es ein Separator oder ist das Item disabled,
  3859. // dann mache nichts
  3860. if ( (it->meType == TOOLBOXITEM_BUTTON) &&
  3861. (!it->mbShowWindow || mbCustomizeMode) )
  3862. nNewPos = i;
  3863. break;
  3864. }
  3865. i++;
  3866. ++it;
  3867. }
  3868. // Item gefunden
  3869. if ( nNewPos != TOOLBOX_ITEM_NOTFOUND )
  3870. {
  3871. if ( mbCustomize )
  3872. {
  3873. if ( rMEvt.IsMod2() || mbCustomizeMode )
  3874. {
  3875. Deactivate();
  3876. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  3877. Rectangle aItemRect = GetItemRect( it->mnId );
  3878. mnConfigItem = it->mnId;
  3879. BOOL bResizeItem;
  3880. if ( mbCustomizeMode && it->mbShowWindow &&
  3881. (it->maRect.Right()-TB_RESIZE_OFFSET <= aMousePos.X()) )
  3882. bResizeItem = TRUE;
  3883. else
  3884. bResizeItem = FALSE;
  3885. pMgr->StartDragging( this, aMousePos, aItemRect, 0, bResizeItem );
  3886. return;
  3887. }
  3888. }
  3889. if ( !it->mbEnabled )
  3890. {
  3891. Deactivate();
  3892. return;
  3893. }
  3894. // Aktuelle Daten setzen
  3895. USHORT nTrackFlags = 0;
  3896. mnCurPos = i;
  3897. mnCurItemId = it->mnId;
  3898. mnDownItemId = mnCurItemId;
  3899. mnMouseClicks = rMEvt.GetClicks();
  3900. mnMouseModifier = rMEvt.GetModifier();
  3901. if ( it->mnBits & TIB_REPEAT )
  3902. nTrackFlags |= STARTTRACK_BUTTONREPEAT;
  3903. if ( mbSelection )
  3904. {
  3905. ImplDrawItem( mnCurPos, TRUE );
  3906. Highlight();
  3907. }
  3908. else
  3909. {
  3910. // Hier schon bDrag setzen, da in EndSelection ausgewertet wird
  3911. mbDrag = TRUE;
  3912. // Bei Doppelklick nur den Handler rufen, aber bevor der
  3913. // Button gehiltet wird, da evt. in diesem Handler der
  3914. // Drag-Vorgang abgebrochen wird
  3915. if ( rMEvt.GetClicks() == 2 )
  3916. DoubleClick();
  3917. if ( mbDrag )
  3918. {
  3919. ImplDrawItem( mnCurPos, TRUE );
  3920. Highlight();
  3921. }
  3922. // was dropdown arrow pressed
  3923. if( (it->mnBits & TIB_DROPDOWN) )
  3924. {
  3925. if( ( (it->mnBits & TIB_DROPDOWNONLY) == TIB_DROPDOWNONLY) || it->GetDropDownRect( mbHorz ).IsInside( aMousePos ))
  3926. {
  3927. // dropdownonly always triggers the dropdown handler, over the whole button area
  3928. // the drop down arrow should not trigger the item action
  3929. mpData->mbDropDownByKeyboard = FALSE;
  3930. GetDropdownClickHdl().Call( this );
  3931. // do not reset data if the dropdown handler opened a floating window
  3932. // see ImplFloatControl()
  3933. if( mpFloatWin == NULL )
  3934. {
  3935. // no floater was opened
  3936. Deactivate();
  3937. ImplDrawItem( mnCurPos, FALSE );
  3938. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  3939. mnCurItemId = 0;
  3940. mnDownItemId = 0;
  3941. mnMouseClicks = 0;
  3942. mnMouseModifier = 0;
  3943. mnHighItemId = 0;
  3944. }
  3945. return;
  3946. }
  3947. else // activate long click timer
  3948. mpData->maDropdownTimer.Start();
  3949. }
  3950. // Click-Handler aufrufen
  3951. if ( rMEvt.GetClicks() != 2 )
  3952. Click();
  3953. // Bei Repeat auch den Select-Handler rufen
  3954. if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
  3955. Select();
  3956. // Wenn die Aktion nicht im Click-Handler abgebrochen wurde
  3957. if ( mbDrag )
  3958. StartTracking( nTrackFlags );
  3959. }
  3960. // Wenn Maus ueber einem Item gedrueckt wurde, koennen wir
  3961. // die Bearbeitung abbrechen
  3962. return;
  3963. }
  3964. Deactivate();
  3965. // menu button hit ?
  3966. if( mpData->maMenubuttonItem.maRect.IsInside( aMousePos ) )
  3967. {
  3968. ExecuteCustomMenu();
  3969. return;
  3970. }
  3971. // Gegebenenfalls noch Scroll- und Next-Buttons ueberpruefen
  3972. if ( maUpperRect.IsInside( aMousePos ) )
  3973. {
  3974. if ( mnCurLine > 1 )
  3975. {
  3976. StartTracking();
  3977. mbUpper = TRUE;
  3978. mbIn = TRUE;
  3979. ImplDrawSpin( TRUE, FALSE );
  3980. }
  3981. return;
  3982. }
  3983. if ( maLowerRect.IsInside( aMousePos ) )
  3984. {
  3985. if ( mnCurLine+mnVisLines-1 < mnCurLines )
  3986. {
  3987. StartTracking();
  3988. mbLower = TRUE;
  3989. mbIn = TRUE;
  3990. ImplDrawSpin( FALSE, TRUE );
  3991. }
  3992. return;
  3993. }
  3994. if ( maNextToolRect.IsInside( aMousePos ) )
  3995. {
  3996. StartTracking();
  3997. mbNextTool = TRUE;
  3998. mbIn = TRUE;
  3999. ImplDrawNext( TRUE );
  4000. return;
  4001. }
  4002. // Linesizing testen
  4003. if ( (mnWinStyle & TB_WBLINESIZING) == TB_WBLINESIZING )
  4004. {
  4005. USHORT nLineMode = ImplTestLineSize( this, aMousePos );
  4006. if ( nLineMode )
  4007. {
  4008. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4009. // Handler rufen, damit die Dock-Rectangles gesetzt werden
  4010. // koenen
  4011. StartDocking();
  4012. Point aPos = GetParent()->OutputToScreenPixel( GetPosPixel() );
  4013. Size aSize = GetSizePixel();
  4014. aPos = ScreenToOutputPixel( aPos );
  4015. // Dragging starten
  4016. pMgr->StartDragging( this, aMousePos, Rectangle( aPos, aSize ),
  4017. nLineMode, FALSE );
  4018. return;
  4019. }
  4020. }
  4021. // Kein Item, dann nur Click oder DoubleClick
  4022. if ( rMEvt.GetClicks() == 2 )
  4023. DoubleClick();
  4024. else
  4025. Click();
  4026. }
  4027. if ( !mbDrag && !mbSelection && (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
  4028. DockingWindow::MouseButtonDown( rMEvt );
  4029. }
  4030. // -----------------------------------------------------------------------
  4031. void ToolBox::MouseButtonUp( const MouseEvent& rMEvt )
  4032. {
  4033. if ( ImplHandleMouseButtonUp( rMEvt ) )
  4034. return;
  4035. if ( mbDragging && (rMEvt.IsLeft() || mbCommandDrag) )
  4036. {
  4037. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4038. pMgr->EndDragging();
  4039. return;
  4040. }
  4041. mbCommandDrag = FALSE;
  4042. DockingWindow::MouseButtonUp( rMEvt );
  4043. }
  4044. // -----------------------------------------------------------------------
  4045. void ToolBox::Tracking( const TrackingEvent& rTEvt )
  4046. {
  4047. ImplDelData aDelData;
  4048. ImplAddDel( &aDelData );
  4049. if ( rTEvt.IsTrackingEnded() )
  4050. ImplHandleMouseButtonUp( rTEvt.GetMouseEvent(), rTEvt.IsTrackingCanceled() );
  4051. else
  4052. ImplHandleMouseMove( rTEvt.GetMouseEvent(), rTEvt.IsTrackingRepeat() );
  4053. if ( aDelData.IsDelete() )
  4054. // toolbox was deleted
  4055. return;
  4056. ImplRemoveDel( &aDelData );
  4057. DockingWindow::Tracking( rTEvt );
  4058. }
  4059. // -----------------------------------------------------------------------
  4060. void ToolBox::Paint( const Rectangle& rPaintRect )
  4061. {
  4062. if( mpData->mbIsPaintLocked )
  4063. return;
  4064. if ( rPaintRect == Rectangle( 0, 0, mnDX-1, mnDY-1 ) )
  4065. mbFullPaint = TRUE;
  4066. ImplFormat();
  4067. mbFullPaint = FALSE;
  4068. ImplDrawBackground( this, rPaintRect );
  4069. if ( (mnWinStyle & WB_BORDER) && !ImplIsFloatingMode() )
  4070. ImplDrawBorder( this );
  4071. if( !ImplIsFloatingMode() )
  4072. ImplDrawGrip( this );
  4073. ImplDrawMenubutton( this, mpData->mbMenubuttonSelected );
  4074. // SpinButtons zeichnen
  4075. if ( mnWinStyle & WB_SCROLL )
  4076. {
  4077. if ( mnCurLines > mnLines )
  4078. ImplDrawSpin( FALSE, FALSE );
  4079. }
  4080. // NextButton zeichnen
  4081. ImplDrawNext( FALSE );
  4082. // Buttons zeichnen
  4083. USHORT nHighPos;
  4084. if ( mnHighItemId )
  4085. nHighPos = GetItemPos( mnHighItemId );
  4086. else
  4087. nHighPos = TOOLBOX_ITEM_NOTFOUND;
  4088. USHORT nCount = (USHORT)mpData->m_aItems.size();
  4089. for( USHORT i = 0; i < nCount; i++ )
  4090. {
  4091. ImplToolItem* pItem = &mpData->m_aItems[i];
  4092. // Nur malen, wenn Rechteck im PaintRectangle liegt
  4093. if ( !pItem->maRect.IsEmpty() && rPaintRect.IsOver( pItem->maRect ) )
  4094. {
  4095. BOOL bHighlight = FALSE;
  4096. if ( i == mnCurPos )
  4097. bHighlight = 1;
  4098. else if ( i == nHighPos )
  4099. bHighlight = 2;
  4100. ImplDrawItem( i, bHighlight );
  4101. }
  4102. }
  4103. ImplShowFocus();
  4104. }
  4105. // -----------------------------------------------------------------------
  4106. void ToolBox::Move()
  4107. {
  4108. DockingWindow::Move();
  4109. }
  4110. // -----------------------------------------------------------------------
  4111. void ToolBox::Resize()
  4112. {
  4113. Size aSize = GetOutputSizePixel();
  4114. // #i31422# some WindowManagers send (0,0) sizes when
  4115. // switching virtual desktops - ignore this and avoid reformatting
  4116. if( !aSize.Width() && !aSize.Height() )
  4117. return;
  4118. long nOldDX = mnDX;
  4119. long nOldDY = mnDY;
  4120. mnDX = aSize.Width();
  4121. mnDY = aSize.Height();
  4122. mnLastResizeDY = 0;
  4123. // invalidate everything to have gradient backgrounds properly drawn
  4124. Invalidate();
  4125. // Evt. neu formatieren oder neu painten
  4126. if ( mbScroll )
  4127. {
  4128. if ( !mbFormat )
  4129. {
  4130. mbFormat = TRUE;
  4131. if( IsReallyVisible() )
  4132. ImplFormat( TRUE );
  4133. }
  4134. }
  4135. // Border muss neu ausgegeben werden
  4136. if ( mnWinStyle & WB_BORDER )
  4137. {
  4138. // Da wir sonst beim Paint denken, das alles neu gepaintet wird
  4139. if ( mbFormat && IsReallyVisible() )
  4140. Invalidate();
  4141. else
  4142. {
  4143. if ( mnRightBorder )
  4144. {
  4145. if ( nOldDX > mnDX )
  4146. Invalidate( Rectangle( mnDX-mnRightBorder-1, 0, mnDX, mnDY ) );
  4147. else
  4148. Invalidate( Rectangle( nOldDX-mnRightBorder-1, 0, nOldDX, nOldDY ) );
  4149. }
  4150. if ( mnBottomBorder )
  4151. {
  4152. if ( nOldDY > mnDY )
  4153. Invalidate( Rectangle( 0, mnDY-mnBottomBorder-1, mnDX, mnDY ) );
  4154. else
  4155. Invalidate( Rectangle( 0, nOldDY-mnBottomBorder-1, nOldDX, nOldDY ) );
  4156. }
  4157. }
  4158. }
  4159. }
  4160. // -----------------------------------------------------------------------
  4161. const XubString& ToolBox::ImplGetHelpText( USHORT nItemId ) const
  4162. {
  4163. ImplToolItem* pItem = ImplGetItem( nItemId );
  4164. if ( pItem )
  4165. {
  4166. if ( !pItem->maHelpText.Len() && ( pItem->mnHelpId || pItem->maCommandStr.Len() ))
  4167. {
  4168. Help* pHelp = Application::GetHelp();
  4169. if ( pHelp )
  4170. {
  4171. if ( pItem->maCommandStr.Len() )
  4172. pItem->maHelpText = pHelp->GetHelpText( pItem->maCommandStr, this );
  4173. if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
  4174. pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId, this );
  4175. }
  4176. }
  4177. return pItem->maHelpText;
  4178. }
  4179. else
  4180. return ImplGetSVEmptyStr();
  4181. }
  4182. // -----------------------------------------------------------------------
  4183. void ToolBox::RequestHelp( const HelpEvent& rHEvt )
  4184. {
  4185. USHORT nItemId;
  4186. Point aHelpPos;
  4187. if( !rHEvt.KeyboardActivated() )
  4188. {
  4189. nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
  4190. aHelpPos = rHEvt.GetMousePosPixel();
  4191. }
  4192. else
  4193. {
  4194. if( !mnHighItemId )
  4195. return;
  4196. else
  4197. nItemId = mnHighItemId;
  4198. Rectangle aRect( GetItemRect( nItemId ) );
  4199. if( aRect.IsEmpty() )
  4200. return;
  4201. else
  4202. aHelpPos = OutputToScreenPixel( aRect.Center() );
  4203. }
  4204. if ( nItemId )
  4205. {
  4206. if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
  4207. {
  4208. // Rechteck ermitteln
  4209. Rectangle aTempRect = GetItemRect( nItemId );
  4210. Point aPt = OutputToScreenPixel( aTempRect.TopLeft() );
  4211. aTempRect.Left() = aPt.X();
  4212. aTempRect.Top() = aPt.Y();
  4213. aPt = OutputToScreenPixel( aTempRect.BottomRight() );
  4214. aTempRect.Right() = aPt.X();
  4215. aTempRect.Bottom() = aPt.Y();
  4216. // Text ermitteln und anzeigen
  4217. XubString aStr = GetQuickHelpText( nItemId );
  4218. const XubString& rHelpStr = GetHelpText( nItemId );
  4219. if ( !aStr.Len() )
  4220. aStr = MnemonicGenerator::EraseAllMnemonicChars( GetItemText( nItemId ) );
  4221. if ( rHEvt.GetMode() & HELPMODE_BALLOON )
  4222. {
  4223. if ( rHelpStr.Len() )
  4224. aStr = rHelpStr;
  4225. Help::ShowBalloon( this, aHelpPos, aTempRect, aStr );
  4226. }
  4227. else
  4228. Help::ShowQuickHelp( this, aTempRect, aStr, rHelpStr, QUICKHELP_CTRLTEXT );
  4229. return;
  4230. }
  4231. else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
  4232. {
  4233. String aCommand = GetItemCommand( nItemId );
  4234. ULONG nHelpId = GetHelpId( nItemId );
  4235. if ( aCommand.Len() || nHelpId )
  4236. {
  4237. // Wenn eine Hilfe existiert, dann ausloesen
  4238. Help* pHelp = Application::GetHelp();
  4239. if ( pHelp )
  4240. {
  4241. if ( aCommand.Len() )
  4242. pHelp->Start( aCommand, this );
  4243. else if ( nHelpId )
  4244. pHelp->Start( nHelpId, this );
  4245. }
  4246. return;
  4247. }
  4248. }
  4249. }
  4250. else if ( maNextToolRect.IsInside( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) ) )
  4251. {
  4252. if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
  4253. {
  4254. // Rechteck ermitteln
  4255. Rectangle aTempRect = maNextToolRect;
  4256. Point aPt = OutputToScreenPixel( aTempRect.TopLeft() );
  4257. aTempRect.Left() = aPt.X();
  4258. aTempRect.Top() = aPt.Y();
  4259. aPt = OutputToScreenPixel( aTempRect.BottomRight() );
  4260. aTempRect.Right() = aPt.X();
  4261. aTempRect.Bottom() = aPt.Y();
  4262. if ( rHEvt.GetMode() & HELPMODE_BALLOON )
  4263. Help::ShowBalloon( this, aTempRect.Center(), aTempRect, maNextToolBoxStr );
  4264. else
  4265. Help::ShowQuickHelp( this, aTempRect, maNextToolBoxStr );
  4266. return;
  4267. }
  4268. }
  4269. DockingWindow::RequestHelp( rHEvt );
  4270. }
  4271. // -----------------------------------------------------------------------
  4272. long ToolBox::Notify( NotifyEvent& rNEvt )
  4273. {
  4274. if ( rNEvt.GetType() == EVENT_KEYINPUT )
  4275. {
  4276. KeyEvent aKEvt = *rNEvt.GetKeyEvent();
  4277. KeyCode aKeyCode = aKEvt.GetKeyCode();
  4278. USHORT nKeyCode = aKeyCode.GetCode();
  4279. switch( nKeyCode )
  4280. {
  4281. case KEY_TAB:
  4282. {
  4283. // internal TAB cycling only if parent is not a dialog or if we are the ony child
  4284. // otherwise the dialog control will take over
  4285. BOOL bNoTabCycling = ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL) ) == WB_DIALOGCONTROL &&
  4286. ImplGetParent()->GetChildCount() != 1 );
  4287. if( bNoTabCycling && ! (GetStyle() & WB_FORCETABCYCLE) )
  4288. return DockingWindow::Notify( rNEvt );
  4289. else if( ImplChangeHighlightUpDn( aKeyCode.IsShift() ? TRUE : FALSE , bNoTabCycling ) )
  4290. return FALSE;
  4291. else
  4292. return DockingWindow::Notify( rNEvt );
  4293. }
  4294. default:
  4295. break;
  4296. };
  4297. }
  4298. else if( rNEvt.GetType() == EVENT_GETFOCUS )
  4299. {
  4300. if( rNEvt.GetWindow() == this )
  4301. {
  4302. // the toolbar itself got the focus
  4303. if( mnLastFocusItemId != 0 )
  4304. {
  4305. // restore last item
  4306. ImplChangeHighlight( ImplGetItem( mnLastFocusItemId ) );
  4307. mnLastFocusItemId = 0;
  4308. }
  4309. else if( (GetGetFocusFlags() & (GETFOCUS_BACKWARD|GETFOCUS_TAB) ) == (GETFOCUS_BACKWARD|GETFOCUS_TAB))
  4310. // Shift-TAB was pressed in the parent
  4311. ImplChangeHighlightUpDn( FALSE );
  4312. else
  4313. ImplChangeHighlightUpDn( TRUE );
  4314. mnLastFocusItemId = 0;
  4315. return true;
  4316. }
  4317. else
  4318. {
  4319. // a child window got the focus so update current item to
  4320. // allow for proper lose focus handling in keyboard navigation
  4321. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  4322. while( it != mpData->m_aItems.end() )
  4323. {
  4324. if ( it->mbVisible )
  4325. {
  4326. if ( it->mpWindow && it->mpWindow->ImplIsWindowOrChild( rNEvt.GetWindow() ) )
  4327. {
  4328. mnHighItemId = it->mnId;
  4329. break;
  4330. }
  4331. }
  4332. ++it;
  4333. }
  4334. return DockingWindow::Notify( rNEvt );
  4335. }
  4336. }
  4337. else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
  4338. {
  4339. // deselect
  4340. ImplHideFocus();
  4341. mnHighItemId = 0;
  4342. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  4343. }
  4344. return DockingWindow::Notify( rNEvt );
  4345. }
  4346. // -----------------------------------------------------------------------
  4347. void ToolBox::Command( const CommandEvent& rCEvt )
  4348. {
  4349. // StartDrag auf MouseButton/Left/Alt abbilden
  4350. if ( (rCEvt.GetCommand() == COMMAND_STARTDRAG) && rCEvt.IsMouseEvent() &&
  4351. mbCustomize && !mbDragging && !mbDrag && !mbSelection &&
  4352. (mnCurPos == TOOLBOX_ITEM_NOTFOUND) )
  4353. {
  4354. // Wir erlauben nur das Draggen von Items. Deshalb muessen wir
  4355. // testen, ob auch ein Item angeklickt wurde, ansonsten wuerden
  4356. // wir evt. das Fenster verschieben, was nicht gewollt waere.
  4357. // Wir machen dieses jedoch nur im Customize-Mode, da ansonsten
  4358. // Items zuhaeufig ausversehen verschoben werden.
  4359. if ( mbCustomizeMode )
  4360. {
  4361. Point aMousePos = rCEvt.GetMousePosPixel();
  4362. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  4363. while ( it != mpData->m_aItems.end() )
  4364. {
  4365. // Ist es dieses Item
  4366. if ( it->maRect.IsInside( aMousePos ) )
  4367. {
  4368. // Ist es ein Separator oder ist das Item disabled,
  4369. // dann mache nichts
  4370. if ( (it->meType == TOOLBOXITEM_BUTTON) &&
  4371. !it->mbShowWindow )
  4372. mbCommandDrag = TRUE;
  4373. break;
  4374. }
  4375. ++it;
  4376. }
  4377. if ( mbCommandDrag )
  4378. {
  4379. MouseEvent aMEvt( aMousePos, 1, MOUSE_SIMPLECLICK,
  4380. MOUSE_LEFT, KEY_MOD2 );
  4381. ToolBox::MouseButtonDown( aMEvt );
  4382. return;
  4383. }
  4384. }
  4385. }
  4386. else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
  4387. {
  4388. if ( (mnCurLine > 1) || (mnCurLine+mnVisLines-1 < mnCurLines) )
  4389. {
  4390. const CommandWheelData* pData = rCEvt.GetWheelData();
  4391. if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
  4392. {
  4393. if ( (mnCurLine > 1) && (pData->GetDelta() > 0) )
  4394. ShowLine( FALSE );
  4395. else if ( (mnCurLine+mnVisLines-1 < mnCurLines) && (pData->GetDelta() < 0) )
  4396. ShowLine( TRUE );
  4397. ImplDrawSpin( FALSE, FALSE );
  4398. return;
  4399. }
  4400. }
  4401. }
  4402. DockingWindow::Command( rCEvt );
  4403. }
  4404. // -----------------------------------------------------------------------
  4405. void ToolBox::StateChanged( StateChangedType nType )
  4406. {
  4407. DockingWindow::StateChanged( nType );
  4408. if ( nType == STATE_CHANGE_INITSHOW )
  4409. ImplFormat();
  4410. else if ( nType == STATE_CHANGE_ENABLE )
  4411. ImplUpdateItem();
  4412. else if ( nType == STATE_CHANGE_UPDATEMODE )
  4413. {
  4414. if ( IsUpdateMode() )
  4415. Invalidate();
  4416. }
  4417. else if ( (nType == STATE_CHANGE_ZOOM) ||
  4418. (nType == STATE_CHANGE_CONTROLFONT) )
  4419. {
  4420. mbCalc = TRUE;
  4421. mbFormat = TRUE;
  4422. ImplInitSettings( TRUE, FALSE, FALSE );
  4423. Invalidate();
  4424. }
  4425. else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
  4426. {
  4427. ImplInitSettings( FALSE, TRUE, FALSE );
  4428. Invalidate();
  4429. }
  4430. else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
  4431. {
  4432. ImplInitSettings( FALSE, FALSE, TRUE ); // font, foreground, background
  4433. Invalidate();
  4434. }
  4435. }
  4436. // -----------------------------------------------------------------------
  4437. void ToolBox::DataChanged( const DataChangedEvent& rDCEvt )
  4438. {
  4439. DockingWindow::DataChanged( rDCEvt );
  4440. if ( (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
  4441. (rDCEvt.GetType() == DATACHANGED_FONTS) ||
  4442. (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
  4443. ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
  4444. (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
  4445. {
  4446. mbCalc = TRUE;
  4447. mbFormat = TRUE;
  4448. ImplInitSettings( TRUE, TRUE, TRUE );
  4449. Invalidate();
  4450. }
  4451. }
  4452. // -----------------------------------------------------------------------
  4453. BOOL ToolBox::PrepareToggleFloatingMode()
  4454. {
  4455. return DockingWindow::PrepareToggleFloatingMode();
  4456. }
  4457. // -----------------------------------------------------------------------
  4458. void ToolBox::ToggleFloatingMode()
  4459. {
  4460. DockingWindow::ToggleFloatingMode();
  4461. BOOL mbOldHorz = mbHorz;
  4462. if ( ImplIsFloatingMode() )
  4463. {
  4464. mbHorz = TRUE;
  4465. meAlign = WINDOWALIGN_TOP;
  4466. mbScroll = TRUE;
  4467. if( mbOldHorz != mbHorz )
  4468. mbCalc = TRUE; // orientation was changed !
  4469. ImplSetMinMaxFloatSize( this );
  4470. SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines ) );
  4471. }
  4472. else
  4473. {
  4474. mbScroll = (mnWinStyle & WB_SCROLL) ? TRUE : FALSE;
  4475. if ( (meAlign == WINDOWALIGN_TOP) || (meAlign == WINDOWALIGN_BOTTOM) )
  4476. mbHorz = TRUE;
  4477. else
  4478. mbHorz = FALSE;
  4479. // set focus back to document
  4480. ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
  4481. }
  4482. if( mbOldHorz != mbHorz )
  4483. {
  4484. // if orientation changes, the toolbox has to be initialized again
  4485. // to update the direction of the gradient
  4486. mbCalc = TRUE;
  4487. ImplInitSettings( TRUE, TRUE, TRUE );
  4488. }
  4489. mbFormat = TRUE;
  4490. ImplFormat();
  4491. }
  4492. // -----------------------------------------------------------------------
  4493. void ToolBox::StartDocking()
  4494. {
  4495. meDockAlign = meAlign;
  4496. mnDockLines = mnLines;
  4497. mbLastFloatMode = ImplIsFloatingMode();
  4498. DockingWindow::StartDocking();
  4499. }
  4500. // -----------------------------------------------------------------------
  4501. BOOL ToolBox::Docking( const Point& rPos, Rectangle& rRect )
  4502. {
  4503. // Wenn Dragging, dann nicht machen, da vorher schon berechnet
  4504. if ( mbDragging )
  4505. return FALSE;
  4506. BOOL bFloatMode = FALSE;
  4507. DockingWindow::Docking( rPos, rRect );
  4508. // Befindet sich die Maus ausserhalb des Bereichs befindet, kann es nur ein
  4509. // FloatWindow werden
  4510. Rectangle aDockingRect( rRect );
  4511. if ( !ImplIsFloatingMode() )
  4512. {
  4513. // don't use tracking rectangle for alignment check, because it will be too large
  4514. // to get a floating mode as result - switch to floating size
  4515. // so the calculation only depends on the position of the rectangle, not the current
  4516. // docking state of the window
  4517. USHORT nTemp = 0;
  4518. aDockingRect.SetSize( ImplCalcFloatSize( this, nTemp ) );
  4519. // in this mode docking is never done by keyboard, so it's OK to use the mouse position
  4520. aDockingRect.SetPos( ImplGetFrameWindow()->GetPointerPosPixel() );
  4521. }
  4522. Rectangle aIntersection = maOutDockRect.GetIntersection( aDockingRect );
  4523. if ( !aIntersection.IsEmpty() && !IsDockingPrevented() )
  4524. {
  4525. Rectangle aInRect = maInDockRect;
  4526. Size aDockSize;
  4527. aDockSize.Width() = ImplCalcSize( this, mnLines, TB_CALCMODE_VERT ).Width();
  4528. aDockSize.Height() = ImplCalcSize( this, mnLines, TB_CALCMODE_HORZ ).Height();
  4529. aInRect.Left() += aDockSize.Width()/2;
  4530. aInRect.Top() += aDockSize.Height()/2;
  4531. aInRect.Right() -= aDockSize.Width()/2;
  4532. aInRect.Bottom() -= aDockSize.Height()/2;
  4533. // Wenn Fenster zu klein, wird das gesammte InDock-Rect genommen
  4534. if ( aInRect.Left() >= aInRect.Right() )
  4535. {
  4536. aInRect.Left() = maInDockRect.Left();
  4537. aInRect.Right() = maInDockRect.Right();
  4538. }
  4539. if ( aInRect.Top() >= aInRect.Bottom() )
  4540. {
  4541. aInRect.Top() = maInDockRect.Top();
  4542. aInRect.Bottom() = maInDockRect.Bottom();
  4543. }
  4544. // Wenn Maus nicht im Dock-Bereich, dann kann es nur zum
  4545. // FloatWindow werden
  4546. Rectangle aIntersect = aInRect.GetIntersection( aDockingRect );
  4547. if ( aIntersect == aDockingRect )
  4548. bFloatMode = TRUE;
  4549. else
  4550. {
  4551. // docking rectangle is in the "sensible area"
  4552. Point aPos = aDockingRect.TopLeft();
  4553. Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() );
  4554. Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() );
  4555. Size aInSize = aInRect.GetSize();
  4556. if ( aInPosTL.X() <= 0 )
  4557. meDockAlign = WINDOWALIGN_LEFT;
  4558. else if ( aInPosTL.Y() <= 0)
  4559. meDockAlign = WINDOWALIGN_TOP;
  4560. else if ( aInPosBR.X() >= aInSize.Width() )
  4561. meDockAlign = WINDOWALIGN_RIGHT;
  4562. else if ( aInPosBR.Y() >= aInSize.Height() )
  4563. meDockAlign = WINDOWALIGN_BOTTOM;
  4564. // Wenn sich Dock-Align geaendert hat, muessen wir die
  4565. // neue Dock-Groesse setzen
  4566. if ( (meDockAlign == WINDOWALIGN_TOP) || (meDockAlign == WINDOWALIGN_BOTTOM) )
  4567. aDockSize.Width() = maInDockRect.GetWidth();
  4568. else
  4569. aDockSize.Height() = maInDockRect.GetHeight();
  4570. aDockingRect.SetSize( aDockSize );
  4571. Point aPosTL( maInDockRect.TopLeft() );
  4572. switch ( meDockAlign )
  4573. {
  4574. case WINDOWALIGN_TOP :
  4575. aDockingRect.SetPos( aPosTL );
  4576. break;
  4577. case WINDOWALIGN_LEFT :
  4578. aDockingRect.SetPos( aPosTL );
  4579. break;
  4580. case WINDOWALIGN_BOTTOM :
  4581. {
  4582. Point aPosBL( maInDockRect.BottomLeft() );
  4583. aPosBL.Y() -= aDockingRect.GetHeight();
  4584. aDockingRect.SetPos( aPosBL );
  4585. break;
  4586. }
  4587. case WINDOWALIGN_RIGHT :
  4588. {
  4589. Point aPosTR( maInDockRect.TopRight() );
  4590. aPosTR.X() -= aDockingRect.GetWidth();
  4591. aDockingRect.SetPos( aPosTR );
  4592. break;
  4593. }
  4594. }
  4595. }
  4596. }
  4597. else
  4598. bFloatMode = TRUE;
  4599. if ( bFloatMode )
  4600. {
  4601. meDockAlign = meAlign;
  4602. if ( !mbLastFloatMode )
  4603. {
  4604. USHORT nTemp = 0;
  4605. aDockingRect.SetSize( ImplCalcFloatSize( this, nTemp ) );
  4606. }
  4607. }
  4608. rRect = aDockingRect;
  4609. mbLastFloatMode = bFloatMode;
  4610. return bFloatMode;
  4611. }
  4612. // -----------------------------------------------------------------------
  4613. void ToolBox::EndDocking( const Rectangle& rRect, BOOL bFloatMode )
  4614. {
  4615. if ( !IsDockingCanceled() )
  4616. {
  4617. if ( mnLines != mnDockLines )
  4618. SetLineCount( mnDockLines );
  4619. if ( meAlign != meDockAlign )
  4620. SetAlign( meDockAlign );
  4621. }
  4622. if ( bFloatMode || (bFloatMode != ImplIsFloatingMode()) )
  4623. DockingWindow::EndDocking( rRect, bFloatMode );
  4624. }
  4625. // -----------------------------------------------------------------------
  4626. void ToolBox::Resizing( Size& rSize )
  4627. {
  4628. USHORT nCalcLines;
  4629. USHORT nTemp;
  4630. // Alle Floatinggroessen berechnen
  4631. ImplCalcFloatSizes( this );
  4632. if ( !mnLastResizeDY )
  4633. mnLastResizeDY = mnDY;
  4634. // Ist vertikales Resizing angesagt
  4635. if ( (mnLastResizeDY != rSize.Height()) && (mnDY != rSize.Height()) )
  4636. {
  4637. nCalcLines = ImplCalcLines( this, rSize.Height() );
  4638. if ( nCalcLines < 1 )
  4639. nCalcLines = 1;
  4640. rSize = ImplCalcFloatSize( this, nCalcLines );
  4641. }
  4642. else
  4643. {
  4644. nCalcLines = 1;
  4645. nTemp = nCalcLines;
  4646. Size aTempSize = ImplCalcFloatSize( this, nTemp );
  4647. while ( (aTempSize.Width() > rSize.Width()) &&
  4648. (nCalcLines <= mpFloatSizeAry->mpSize[0].mnLines) )
  4649. {
  4650. nCalcLines++;
  4651. nTemp = nCalcLines;
  4652. aTempSize = ImplCalcFloatSize( this, nTemp );
  4653. }
  4654. rSize = aTempSize;
  4655. }
  4656. mnLastResizeDY = rSize.Height();
  4657. }
  4658. // -----------------------------------------------------------------------
  4659. Size ToolBox::CalcWindowSizePixel( USHORT nCalcLines ) const
  4660. {
  4661. return ImplCalcSize( this, nCalcLines );
  4662. }
  4663. Size ToolBox::CalcWindowSizePixel( USHORT nCalcLines, WindowAlign eAlign ) const
  4664. {
  4665. return ImplCalcSize( this, nCalcLines,
  4666. (eAlign == WINDOWALIGN_TOP || eAlign == WINDOWALIGN_BOTTOM) ? TB_CALCMODE_HORZ : TB_CALCMODE_VERT );
  4667. }
  4668. USHORT ToolBox::ImplCountLineBreaks( const ToolBox *pThis )
  4669. {
  4670. USHORT nLines = 0;
  4671. std::vector< ImplToolItem >::const_iterator it = ((ToolBox*)pThis)->mpData->m_aItems.begin();
  4672. while ( it != ((ToolBox*)pThis)->mpData->m_aItems.end() )
  4673. {
  4674. if( it->meType == TOOLBOXITEM_BREAK )
  4675. nLines++;
  4676. it++;
  4677. }
  4678. return nLines;
  4679. }
  4680. Size ToolBox::CalcPopupWindowSizePixel() const
  4681. {
  4682. // count number of breaks and calc corresponding floating window size
  4683. USHORT nLines = ImplCountLineBreaks( this );
  4684. if( nLines )
  4685. nLines++; // add the first line
  4686. else
  4687. {
  4688. // no breaks found: use quadratic layout
  4689. nLines = (USHORT) ceil( sqrt( (double) GetItemCount() ) );
  4690. }
  4691. BOOL bPopup = mpData->mbAssumePopupMode;
  4692. ToolBox *pThis = (ToolBox*) this;
  4693. pThis->mpData->mbAssumePopupMode = TRUE;
  4694. Size aSize = CalcFloatingWindowSizePixel( nLines );
  4695. pThis->mpData->mbAssumePopupMode = bPopup;
  4696. return aSize;
  4697. }
  4698. Size ToolBox::CalcFloatingWindowSizePixel() const
  4699. {
  4700. USHORT nLines = ImplCountLineBreaks( this );
  4701. nLines++; // add the first line
  4702. return CalcFloatingWindowSizePixel( nLines );
  4703. }
  4704. Size ToolBox::CalcFloatingWindowSizePixel( USHORT nCalcLines ) const
  4705. {
  4706. BOOL bFloat = mpData->mbAssumeFloating;
  4707. BOOL bDocking = mpData->mbAssumeDocked;
  4708. // simulate floating mode and force reformat before calculating
  4709. ToolBox *pThis = (ToolBox*) this;
  4710. pThis->mpData->mbAssumeFloating = TRUE;
  4711. pThis->mpData->mbAssumeDocked = FALSE;
  4712. Size aSize = ImplCalcFloatSize( (ToolBox*) this, nCalcLines );
  4713. pThis->mbFormat = TRUE;
  4714. pThis->mpData->mbAssumeFloating = bFloat;
  4715. pThis->mpData->mbAssumeDocked = bDocking;
  4716. return aSize;
  4717. }
  4718. // -----------------------------------------------------------------------
  4719. Size ToolBox::CalcMinimumWindowSizePixel() const
  4720. {
  4721. if( ImplIsFloatingMode() )
  4722. return ImplCalcSize( this, mnFloatLines );
  4723. else
  4724. {
  4725. // create dummy toolbox for measurements
  4726. ToolBox *pToolBox = new ToolBox( GetParent(), GetStyle() );
  4727. // copy until first useful item
  4728. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  4729. while( it != mpData->m_aItems.end() )
  4730. {
  4731. pToolBox->CopyItem( *this, it->mnId );
  4732. if( (it->meType != TOOLBOXITEM_BUTTON) ||
  4733. !it->mbVisible || ImplIsFixedControl( &(*it) ) )
  4734. it++;
  4735. else
  4736. break;
  4737. }
  4738. // add to docking manager if required to obtain a drag area
  4739. // (which is accounted for in calcwindowsizepixel)
  4740. if( ImplGetDockingManager()->GetDockingWindowWrapper( this ) )
  4741. ImplGetDockingManager()->AddWindow( pToolBox );
  4742. // account for menu
  4743. if( IsMenuEnabled() )
  4744. pToolBox->SetMenuType( GetMenuType() );
  4745. pToolBox->SetAlign( GetAlign() );
  4746. Size aSize = pToolBox->CalcWindowSizePixel( 1 );
  4747. ImplGetDockingManager()->RemoveWindow( pToolBox );
  4748. pToolBox->Clear();
  4749. delete pToolBox;
  4750. return aSize;
  4751. }
  4752. }
  4753. // -----------------------------------------------------------------------
  4754. void ToolBox::EnableCustomize( BOOL bEnable )
  4755. {
  4756. if ( bEnable != mbCustomize )
  4757. {
  4758. mbCustomize = bEnable;
  4759. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4760. if ( bEnable )
  4761. pMgr->Insert( this );
  4762. else
  4763. pMgr->Remove( this );
  4764. }
  4765. }
  4766. // -----------------------------------------------------------------------
  4767. void ToolBox::StartCustomize( const Rectangle& rRect, void* pData )
  4768. {
  4769. DBG_ASSERT( mbCustomize,
  4770. "ToolBox::StartCustomize(): ToolBox must be customized" );
  4771. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4772. Point aMousePos = GetPointerPosPixel();
  4773. Point aPos = ScreenToOutputPixel( rRect.TopLeft() );
  4774. Rectangle aRect( aPos.X(), aPos.Y(),
  4775. aPos.X()+rRect.GetWidth()+SMALLBUTTON_HSIZE,
  4776. aPos.Y()+rRect.GetHeight()+SMALLBUTTON_VSIZE );
  4777. aMousePos = ScreenToOutputPixel( aPos );
  4778. Pointer aPtr;
  4779. SetPointer( aPtr );
  4780. pMgr->StartDragging( this, aMousePos, aRect, 0, FALSE, pData );
  4781. }
  4782. // -----------------------------------------------------------------------
  4783. void ToolBox::StartCustomizeMode()
  4784. {
  4785. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4786. pMgr->StartCustomizeMode();
  4787. }
  4788. // -----------------------------------------------------------------------
  4789. void ToolBox::EndCustomizeMode()
  4790. {
  4791. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4792. pMgr->EndCustomizeMode();
  4793. }
  4794. // -----------------------------------------------------------------------
  4795. BOOL ToolBox::IsCustomizeMode()
  4796. {
  4797. ImplTBDragMgr* pMgr = ImplGetTBDragMgr();
  4798. return pMgr->IsCustomizeMode();
  4799. }
  4800. // -----------------------------------------------------------------------
  4801. void ToolBox::GetFocus()
  4802. {
  4803. DockingWindow::GetFocus();
  4804. }
  4805. // -----------------------------------------------------------------------
  4806. void ToolBox::LoseFocus()
  4807. {
  4808. ImplChangeHighlight( NULL, TRUE );
  4809. DockingWindow::LoseFocus();
  4810. }
  4811. // -----------------------------------------------------------------------
  4812. // performs the action associated with an item, ie simulates clicking the item
  4813. void ToolBox::TriggerItem( USHORT nItemId, BOOL bShift, BOOL bCtrl )
  4814. {
  4815. mnHighItemId = nItemId;
  4816. USHORT nModifier = 0;
  4817. if( bShift )
  4818. nModifier |= KEY_SHIFT;
  4819. if( bCtrl )
  4820. nModifier |= KEY_MOD1;
  4821. KeyCode aKeyCode( 0, nModifier );
  4822. ImplActivateItem( aKeyCode );
  4823. }
  4824. // -----------------------------------------------------------------------
  4825. // calls the button's action handler
  4826. // returns TRUE if action was called
  4827. BOOL ToolBox::ImplActivateItem( KeyCode aKeyCode )
  4828. {
  4829. BOOL bRet = TRUE;
  4830. if( mnHighItemId )
  4831. {
  4832. ImplToolItem *pToolItem = ImplGetItem( mnHighItemId );
  4833. // #107712#, activate can also be called for disabled entries
  4834. if( pToolItem && !pToolItem->mbEnabled )
  4835. return TRUE;
  4836. if( pToolItem && pToolItem->mpWindow && HasFocus() )
  4837. {
  4838. ImplHideFocus();
  4839. mbChangingHighlight = TRUE; // avoid focus change due to loose focus
  4840. pToolItem->mpWindow->ImplControlFocus( GETFOCUS_TAB );
  4841. mbChangingHighlight = FALSE;
  4842. }
  4843. else
  4844. {
  4845. mnDownItemId = mnCurItemId = mnHighItemId;
  4846. ImplToolItem* pItem = ImplGetItem( mnHighItemId );
  4847. if ( pItem->mnBits & TIB_AUTOCHECK )
  4848. {
  4849. if ( pItem->mnBits & TIB_RADIOCHECK )
  4850. {
  4851. if ( pItem->meState != STATE_CHECK )
  4852. SetItemState( pItem->mnId, STATE_CHECK );
  4853. }
  4854. else
  4855. {
  4856. if ( pItem->meState != STATE_CHECK )
  4857. pItem->meState = STATE_CHECK;
  4858. else
  4859. pItem->meState = STATE_NOCHECK;
  4860. }
  4861. }
  4862. mnMouseModifier = aKeyCode.GetModifier();
  4863. mbIsKeyEvent = TRUE;
  4864. Activate();
  4865. Click();
  4866. // #107776# we might be destroyed in the selecthandler
  4867. ImplDelData aDelData;
  4868. ImplAddDel( &aDelData );
  4869. Select();
  4870. if ( aDelData.IsDelete() )
  4871. return bRet;
  4872. ImplRemoveDel( &aDelData );
  4873. Deactivate();
  4874. mbIsKeyEvent = FALSE;
  4875. mnMouseModifier = 0;
  4876. }
  4877. }
  4878. else
  4879. bRet = FALSE;
  4880. return bRet;
  4881. }
  4882. // -----------------------------------------------------------------------
  4883. BOOL ImplCloseLastPopup( Window *pParent )
  4884. {
  4885. // close last popup toolbox (see also:
  4886. // ImplHandleMouseFloatMode(...) in winproc.cxx )
  4887. if( ImplGetSVData()->maWinData.mpFirstFloat )
  4888. {
  4889. FloatingWindow* pLastLevelFloat = ImplGetSVData()->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
  4890. // only close the floater if it is not our direct parent, which would kill ourself
  4891. if( pLastLevelFloat && pLastLevelFloat != pParent )
  4892. {
  4893. pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
  4894. return TRUE;
  4895. }
  4896. }
  4897. return FALSE;
  4898. }
  4899. // opens a drop down toolbox item
  4900. // returns TRUE if item was opened
  4901. BOOL ToolBox::ImplOpenItem( KeyCode aKeyCode )
  4902. {
  4903. USHORT nCode = aKeyCode.GetCode();
  4904. BOOL bRet = TRUE;
  4905. // arrow keys should work only in the opposite direction of alignment (to not break cursor travelling)
  4906. if ( ((nCode == KEY_LEFT || nCode == KEY_RIGHT) && IsHorizontal())
  4907. || ((nCode == KEY_UP || nCode == KEY_DOWN) && !IsHorizontal()) )
  4908. return FALSE;
  4909. if( IsMenuEnabled() && mpData->mbMenubuttonSelected )
  4910. {
  4911. if( ImplCloseLastPopup( GetParent() ) )
  4912. return bRet;
  4913. ImplUpdateCustomMenu();
  4914. Application::PostUserEvent( mpData->mnEventId, LINK( this, ToolBox, ImplCallExecuteCustomMenu ) );
  4915. }
  4916. else if( mnHighItemId && ImplGetItem( mnHighItemId ) &&
  4917. (ImplGetItem( mnHighItemId )->mnBits & TIB_DROPDOWN) )
  4918. {
  4919. if( ImplCloseLastPopup( GetParent() ) )
  4920. return bRet;
  4921. mnDownItemId = mnCurItemId = mnHighItemId;
  4922. mnCurPos = GetItemPos( mnCurItemId );
  4923. mnLastFocusItemId = mnCurItemId; // save item id for possible later focus restore
  4924. mnMouseModifier = aKeyCode.GetModifier();
  4925. mbIsShift = TRUE;
  4926. mbIsKeyEvent = TRUE;
  4927. Activate();
  4928. mpData->mbDropDownByKeyboard = TRUE;
  4929. GetDropdownClickHdl().Call( this );
  4930. mbIsKeyEvent = FALSE;
  4931. mbIsShift = FALSE;
  4932. mnMouseModifier = 0;
  4933. }
  4934. else
  4935. bRet = FALSE;
  4936. return bRet;
  4937. }
  4938. // -----------------------------------------------------------------------
  4939. void ToolBox::KeyInput( const KeyEvent& rKEvt )
  4940. {
  4941. KeyCode aKeyCode = rKEvt.GetKeyCode();
  4942. mnKeyModifier = aKeyCode.GetModifier();
  4943. USHORT nCode = aKeyCode.GetCode();
  4944. BOOL bParentIsDialog = ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL) ) == WB_DIALOGCONTROL );
  4945. BOOL bForwardKey = FALSE;
  4946. BOOL bGrabFocusToDocument = FALSE;
  4947. // #107776# we might be destroyed in the keyhandler
  4948. ImplDelData aDelData;
  4949. ImplAddDel( &aDelData );
  4950. switch ( nCode )
  4951. {
  4952. case KEY_UP:
  4953. {
  4954. // Ctrl-Cursor activates next toolbox, indicated by a blue arrow pointing to the left/up
  4955. if( aKeyCode.GetModifier() ) // allow only pure cursor keys
  4956. break;
  4957. if( !IsHorizontal() )
  4958. ImplChangeHighlightUpDn( TRUE );
  4959. else
  4960. ImplOpenItem( aKeyCode );
  4961. }
  4962. break;
  4963. case KEY_LEFT:
  4964. {
  4965. if( aKeyCode.GetModifier() ) // allow only pure cursor keys
  4966. break;
  4967. if( IsHorizontal() )
  4968. ImplChangeHighlightUpDn( TRUE );
  4969. else
  4970. ImplOpenItem( aKeyCode );
  4971. }
  4972. break;
  4973. case KEY_DOWN:
  4974. {
  4975. if( aKeyCode.GetModifier() ) // allow only pure cursor keys
  4976. break;
  4977. if( !IsHorizontal() )
  4978. ImplChangeHighlightUpDn( FALSE );
  4979. else
  4980. ImplOpenItem( aKeyCode );
  4981. }
  4982. break;
  4983. case KEY_RIGHT:
  4984. {
  4985. if( aKeyCode.GetModifier() ) // allow only pure cursor keys
  4986. break;
  4987. if( IsHorizontal() )
  4988. ImplChangeHighlightUpDn( FALSE );
  4989. else
  4990. ImplOpenItem( aKeyCode );
  4991. }
  4992. break;
  4993. case KEY_PAGEUP:
  4994. if ( mnCurLine > 1 )
  4995. {
  4996. if( mnCurLine > mnVisLines )
  4997. mnCurLine = mnCurLine - mnVisLines;
  4998. else
  4999. mnCurLine = 1;
  5000. mbFormat = TRUE;
  5001. ImplFormat();
  5002. ImplDrawSpin( FALSE, FALSE );
  5003. ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine ) );
  5004. }
  5005. break;
  5006. case KEY_PAGEDOWN:
  5007. if ( mnCurLine+mnVisLines-1 < mnCurLines )
  5008. {
  5009. if( mnCurLine + 2*mnVisLines-1 < mnCurLines )
  5010. mnCurLine = mnCurLine + mnVisLines;
  5011. else
  5012. mnCurLine = mnCurLines;
  5013. mbFormat = TRUE;
  5014. ImplFormat();
  5015. ImplDrawSpin( FALSE, FALSE );
  5016. ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine ) );
  5017. }
  5018. break;
  5019. case KEY_END:
  5020. {
  5021. ImplChangeHighlight( NULL );
  5022. ImplChangeHighlightUpDn( FALSE );
  5023. }
  5024. break;
  5025. case KEY_HOME:
  5026. {
  5027. ImplChangeHighlight( NULL );
  5028. ImplChangeHighlightUpDn( TRUE );
  5029. }
  5030. break;
  5031. case KEY_ESCAPE:
  5032. {
  5033. if( !ImplIsFloatingMode() && bParentIsDialog )
  5034. DockingWindow::KeyInput( rKEvt );
  5035. else
  5036. {
  5037. // send focus to document pane
  5038. Window *pWin = this;
  5039. while( pWin )
  5040. {
  5041. if( !pWin->GetParent() )
  5042. {
  5043. pWin->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT )->GrabFocus();
  5044. break;
  5045. }
  5046. pWin = pWin->GetParent();
  5047. }
  5048. }
  5049. }
  5050. break;
  5051. case KEY_RETURN:
  5052. {
  5053. // #107712#, disabled entries are selectable now
  5054. // leave toolbox and move focus to document
  5055. if( mnHighItemId )
  5056. {
  5057. ImplToolItem *pItem = ImplGetItem( mnHighItemId );
  5058. if( !pItem->mbEnabled )
  5059. {
  5060. Sound::Beep( SOUND_DISABLE, this );
  5061. bGrabFocusToDocument = TRUE;
  5062. }
  5063. }
  5064. if( !bGrabFocusToDocument )
  5065. bForwardKey = !ImplActivateItem( aKeyCode );
  5066. }
  5067. break;
  5068. default:
  5069. {
  5070. USHORT aKeyGroup = aKeyCode.GetGroup();
  5071. ImplToolItem *pItem = NULL;
  5072. if( mnHighItemId )
  5073. pItem = ImplGetItem( mnHighItemId );
  5074. // #i13931# forward alphanum keyinput into embedded control
  5075. if( (aKeyGroup == KEYGROUP_NUM || aKeyGroup == KEYGROUP_ALPHA ) && pItem && pItem->mpWindow && pItem->mbEnabled )
  5076. {
  5077. Window *pFocusWindow = Application::GetFocusWindow();
  5078. ImplHideFocus();
  5079. mbChangingHighlight = TRUE; // avoid focus change due to loose focus
  5080. pItem->mpWindow->ImplControlFocus( GETFOCUS_TAB );
  5081. mbChangingHighlight = FALSE;
  5082. if( pFocusWindow != Application::GetFocusWindow() )
  5083. Application::GetFocusWindow()->KeyInput( rKEvt );
  5084. }
  5085. else
  5086. {
  5087. // do nothing to avoid key presses going into the document
  5088. // while the toolbox has the focus
  5089. // just forward function and special keys and combinations with Alt-key
  5090. if( aKeyGroup == KEYGROUP_FKEYS || aKeyGroup == KEYGROUP_MISC || aKeyCode.IsMod2() )
  5091. bForwardKey = TRUE;
  5092. }
  5093. }
  5094. }
  5095. if ( aDelData.IsDelete() )
  5096. return;
  5097. ImplRemoveDel( &aDelData );
  5098. // #107251# move focus away if this toolbox was disabled during keyinput
  5099. if( HasFocus() && mpData->mbKeyInputDisabled && (ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL) ) == WB_DIALOGCONTROL)
  5100. {
  5101. USHORT n = 0;
  5102. Window *pFocusControl = ImplGetParent()->ImplGetDlgWindow( n, DLGWINDOW_FIRST );
  5103. if ( pFocusControl && pFocusControl != this )
  5104. pFocusControl->ImplControlFocus( GETFOCUS_INIT );
  5105. }
  5106. mnKeyModifier = 0;
  5107. // #107712#, leave toolbox
  5108. if( bGrabFocusToDocument )
  5109. {
  5110. GrabFocusToDocument();
  5111. return;
  5112. }
  5113. if( bForwardKey )
  5114. DockingWindow::KeyInput( rKEvt );
  5115. }
  5116. // -----------------------------------------------------------------------
  5117. // returns the current toolbox line of the item
  5118. USHORT ToolBox::ImplGetItemLine( ImplToolItem* pCurrentItem )
  5119. {
  5120. std::vector< ImplToolItem >::const_iterator it = mpData->m_aItems.begin();
  5121. USHORT nLine = 1;
  5122. while( it != mpData->m_aItems.end() )
  5123. {
  5124. if ( it->mbBreak )
  5125. nLine++;
  5126. if( &(*it) == pCurrentItem)
  5127. break;
  5128. ++it;
  5129. }
  5130. return nLine;
  5131. }
  5132. // returns the first displayable item in the given line
  5133. ImplToolItem* ToolBox::ImplGetFirstValidItem( USHORT nLine )
  5134. {
  5135. if( !nLine || nLine > mnCurLines )
  5136. return NULL;
  5137. nLine--;
  5138. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  5139. while( it != mpData->m_aItems.end() )
  5140. {
  5141. // find correct line
  5142. if ( it->mbBreak )
  5143. nLine--;
  5144. if( !nLine )
  5145. {
  5146. // find first useful item
  5147. while( it != mpData->m_aItems.end() && ((it->meType != TOOLBOXITEM_BUTTON) ||
  5148. /*!it->mbEnabled ||*/ !it->mbVisible || ImplIsFixedControl( &(*it) )) )
  5149. {
  5150. ++it;
  5151. if( it == mpData->m_aItems.end() || it->mbBreak )
  5152. return NULL; // no valid items in this line
  5153. }
  5154. return &(*it);
  5155. }
  5156. ++it;
  5157. }
  5158. return (it == mpData->m_aItems.end()) ? NULL : &(*it);
  5159. }
  5160. // returns the last displayable item in the given line
  5161. ImplToolItem* ToolBox::ImplGetLastValidItem( USHORT nLine )
  5162. {
  5163. if( !nLine || nLine > mnCurLines )
  5164. return NULL;
  5165. nLine--;
  5166. ImplToolItem *pFound = NULL;
  5167. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  5168. while( it != mpData->m_aItems.end() )
  5169. {
  5170. // find correct line
  5171. if ( it->mbBreak )
  5172. nLine--;
  5173. if( !nLine )
  5174. {
  5175. // find last useful item
  5176. while( it != mpData->m_aItems.end() && ((it->meType == TOOLBOXITEM_BUTTON) &&
  5177. /*it->mbEnabled &&*/ it->mbVisible && !ImplIsFixedControl( &(*it) )) )
  5178. {
  5179. pFound = &(*it);
  5180. ++it;
  5181. if( it == mpData->m_aItems.end() || it->mbBreak )
  5182. return pFound; // end of line: return last useful item
  5183. }
  5184. return pFound;
  5185. }
  5186. ++it;
  5187. }
  5188. return pFound;
  5189. }
  5190. // -----------------------------------------------------------------------
  5191. USHORT ToolBox::ImplFindItemPos( const ImplToolItem* pItem, const std::vector< ImplToolItem >& rList )
  5192. {
  5193. if( pItem )
  5194. {
  5195. USHORT nPos;
  5196. for( nPos = 0; nPos < rList.size(); nPos++ )
  5197. if( &rList[ nPos ] == pItem )
  5198. return nPos;
  5199. }
  5200. return TOOLBOX_ITEM_NOTFOUND;
  5201. }
  5202. void ToolBox::ChangeHighlight( USHORT nPos )
  5203. {
  5204. if ( nPos < GetItemCount() ) {
  5205. ImplGrabFocus( 0 );
  5206. ImplChangeHighlight ( ImplGetItem ( GetItemId ( (USHORT) nPos ) ), FALSE );
  5207. }
  5208. }
  5209. void ToolBox::ImplChangeHighlight( ImplToolItem* pItem, BOOL bNoGrabFocus )
  5210. {
  5211. // avoid recursion due to focus change
  5212. if( mbChangingHighlight )
  5213. return;
  5214. mbChangingHighlight = TRUE;
  5215. ImplToolItem* pOldItem = NULL;
  5216. if ( mnHighItemId )
  5217. {
  5218. ImplHideFocus();
  5219. USHORT nPos = GetItemPos( mnHighItemId );
  5220. pOldItem = ImplGetItem( mnHighItemId );
  5221. // #i89962# ImplDrawItem can cause Invalidate/Update
  5222. // which will in turn ImplShowFocus again
  5223. // set mnHighItemId to 0 already to prevent this hen/egg problem
  5224. mnHighItemId = 0;
  5225. ImplDrawItem( nPos, FALSE );
  5226. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF, reinterpret_cast< void* >( nPos ) );
  5227. }
  5228. if( !bNoGrabFocus && pItem != pOldItem && pOldItem && pOldItem->mpWindow )
  5229. {
  5230. // move focus into toolbox
  5231. GrabFocus();
  5232. }
  5233. if( pItem )
  5234. {
  5235. USHORT aPos = ToolBox::ImplFindItemPos( pItem, mpData->m_aItems );
  5236. if( aPos != TOOLBOX_ITEM_NOTFOUND)
  5237. {
  5238. // check for line breaks
  5239. USHORT nLine = ImplGetItemLine( pItem );
  5240. if( nLine >= mnCurLine + mnVisLines )
  5241. {
  5242. mnCurLine = nLine - mnVisLines + 1;
  5243. mbFormat = TRUE;
  5244. }
  5245. else if ( nLine < mnCurLine )
  5246. {
  5247. mnCurLine = nLine;
  5248. mbFormat = TRUE;
  5249. }
  5250. if( mbFormat )
  5251. {
  5252. ImplFormat();
  5253. }
  5254. mnHighItemId = pItem->mnId;
  5255. ImplDrawItem( aPos, 2 ); // always use shadow effect (2)
  5256. if( mbSelection )
  5257. mnCurPos = aPos;
  5258. ImplShowFocus();
  5259. ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT );
  5260. }
  5261. }
  5262. else
  5263. {
  5264. ImplHideFocus();
  5265. mnHighItemId = 0;
  5266. mnCurPos = TOOLBOX_ITEM_NOTFOUND;
  5267. }
  5268. mbChangingHighlight = FALSE;
  5269. }
  5270. // -----------------------------------------------------------------------
  5271. // check for keyboard accessible items
  5272. static BOOL ImplIsValidItem( const ImplToolItem* pItem, BOOL bNotClipped )
  5273. {
  5274. BOOL bValid = (pItem && pItem->meType == TOOLBOXITEM_BUTTON && pItem->mbVisible && !ImplIsFixedControl( pItem ));
  5275. if( bValid && bNotClipped && pItem->IsClipped() )
  5276. bValid = FALSE;
  5277. return bValid;
  5278. }
  5279. // -----------------------------------------------------------------------
  5280. BOOL ToolBox::ImplChangeHighlightUpDn( BOOL bUp, BOOL bNoCycle )
  5281. {
  5282. ImplToolItem* pToolItem = ImplGetItem( mnHighItemId );
  5283. if( !pToolItem || !mnHighItemId )
  5284. {
  5285. // menubutton highlighted ?
  5286. if( mpData->mbMenubuttonSelected )
  5287. {
  5288. if( bUp )
  5289. {
  5290. // select last valid non-clipped item
  5291. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.end();
  5292. ImplToolItem* pItem = NULL;
  5293. while( it != mpData->m_aItems.begin() )
  5294. {
  5295. --it;
  5296. if ( ImplIsValidItem( &(*it), TRUE ) )
  5297. {
  5298. pItem = &(*it);
  5299. break;
  5300. }
  5301. }
  5302. ImplDrawMenubutton( this, FALSE );
  5303. ImplChangeHighlight( pItem );
  5304. }
  5305. else
  5306. {
  5307. // select first valid non-clipped item
  5308. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  5309. while( it != mpData->m_aItems.end() )
  5310. {
  5311. if ( ImplIsValidItem( &(*it), TRUE ) )
  5312. break;
  5313. ++it;
  5314. }
  5315. if( it != mpData->m_aItems.end() )
  5316. {
  5317. ImplDrawMenubutton( this, FALSE );
  5318. ImplChangeHighlight( &(*it) );
  5319. }
  5320. }
  5321. return TRUE;
  5322. }
  5323. if( bUp )
  5324. {
  5325. // Select first valid item
  5326. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.begin();
  5327. while( it != mpData->m_aItems.end() )
  5328. {
  5329. if ( ImplIsValidItem( &(*it), FALSE ) )
  5330. break;
  5331. ++it;
  5332. }
  5333. // select the menu button if a clipped item would be selected
  5334. if( (it != mpData->m_aItems.end() && &(*it) == ImplGetFirstClippedItem( this )) && IsMenuEnabled() )
  5335. {
  5336. ImplChangeHighlight( NULL );
  5337. ImplDrawMenubutton( this, TRUE );
  5338. }
  5339. else
  5340. ImplChangeHighlight( (it != mpData->m_aItems.end()) ? &(*it) : NULL );
  5341. return TRUE;
  5342. }
  5343. else
  5344. {
  5345. // Select last valid item
  5346. // docked toolbars have the menubutton as last item - if this button is enabled
  5347. if( IsMenuEnabled() && !ImplIsFloatingMode() )
  5348. {
  5349. ImplChangeHighlight( NULL );
  5350. ImplDrawMenubutton( this, TRUE );
  5351. }
  5352. else
  5353. {
  5354. std::vector< ImplToolItem >::iterator it = mpData->m_aItems.end();
  5355. ImplToolItem* pItem = NULL;
  5356. while( it != mpData->m_aItems.begin() )
  5357. {
  5358. --it;
  5359. if ( ImplIsValidItem( &(*it), FALSE ) )
  5360. {
  5361. pItem = &(*it);
  5362. break;
  5363. }
  5364. }
  5365. ImplChangeHighlight( pItem );
  5366. }
  5367. return TRUE;
  5368. }
  5369. }
  5370. if( pToolItem )
  5371. {
  5372. ULONG pos = ToolBox::ImplFindItemPos( pToolItem, mpData->m_aItems );
  5373. ULONG nCount = mpData->m_aItems.size();
  5374. ULONG i=0;
  5375. do
  5376. {
  5377. if( bUp )
  5378. {
  5379. if( !pos-- )
  5380. {
  5381. if( bNoCycle )
  5382. return FALSE;
  5383. // highlight the menu button if it is the last item
  5384. if( IsMenuEnabled() && !ImplIsFloatingMode() )
  5385. {
  5386. ImplChangeHighlight( NULL );
  5387. ImplDrawMenubutton( this, TRUE );
  5388. return TRUE;
  5389. }
  5390. else
  5391. pos = nCount-1;
  5392. }
  5393. }
  5394. else
  5395. {
  5396. if( ++pos >= nCount )
  5397. {
  5398. if( bNoCycle )
  5399. return FALSE;
  5400. // highlight the menu button if it is the last item
  5401. if( IsMenuEnabled() && !ImplIsFloatingMode() )
  5402. {
  5403. ImplChangeHighlight( NULL );
  5404. ImplDrawMenubutton( this, TRUE );
  5405. return TRUE;
  5406. }
  5407. else
  5408. pos = 0;
  5409. }
  5410. }
  5411. pToolItem = &mpData->m_aItems[pos];
  5412. if ( ImplIsValidItem( pToolItem, FALSE ) )
  5413. break;
  5414. } while( ++i < nCount);
  5415. if( pToolItem->IsClipped() && IsMenuEnabled() )
  5416. {
  5417. // select the menu button if a clipped item would be selected
  5418. ImplChangeHighlight( NULL );
  5419. ImplDrawMenubutton( this, TRUE );
  5420. }
  5421. else if( i != nCount )
  5422. ImplChangeHighlight( pToolItem );
  5423. else
  5424. return FALSE;
  5425. }
  5426. return TRUE;
  5427. }
  5428. // -----------------------------------------------------------------------
  5429. void ToolBox::ImplShowFocus()
  5430. {
  5431. if( mnHighItemId && HasFocus() )
  5432. {
  5433. ImplToolItem* pItem = ImplGetItem( mnHighItemId );
  5434. if( pItem->mpWindow )
  5435. {
  5436. Window *pWin = pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow ? pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow : pItem->mpWindow;
  5437. pWin->ImplGetWindowImpl()->mbDrawSelectionBackground = TRUE;
  5438. pWin->Invalidate( 0 );
  5439. }
  5440. }
  5441. }
  5442. // -----------------------------------------------------------------------
  5443. void ToolBox::ImplHideFocus()
  5444. {
  5445. if( mnHighItemId )
  5446. {
  5447. ImplToolItem* pItem = ImplGetItem( mnHighItemId );
  5448. if( pItem->mpWindow )
  5449. {
  5450. Window *pWin = pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow ? pItem->mpWindow->ImplGetWindowImpl()->mpBorderWindow : pItem->mpWindow;
  5451. pWin->ImplGetWindowImpl()->mbDrawSelectionBackground = FALSE;
  5452. pWin->Invalidate( 0 );
  5453. }
  5454. }
  5455. if ( mpData->mbMenubuttonSelected )
  5456. {
  5457. // remove highlight from menubutton
  5458. ImplDrawMenubutton( this, FALSE );
  5459. }
  5460. }
  5461. // -----------------------------------------------------------------------
  5462. void ToolBox::ImplDisableFlatButtons()
  5463. {
  5464. #ifdef WNT // Check in the Windows registry if an AT tool wants no flat toolboxes
  5465. static bool bInit = false, bValue = false;
  5466. if( ! bInit )
  5467. {
  5468. bInit = true;
  5469. HKEY hkey;
  5470. if( ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER,
  5471. "Software\\OpenOffice.org\\Accessibility\\AtToolSupport",
  5472. &hkey) )
  5473. {
  5474. DWORD dwType = 0;
  5475. WIN_BYTE Data[6]; // possible values: "true", "false", "1", "0", DWORD
  5476. DWORD cbData = sizeof(Data);
  5477. if( ERROR_SUCCESS == RegQueryValueEx(hkey, "DisableFlatToolboxButtons",
  5478. NULL, &dwType, Data, &cbData) )
  5479. {
  5480. switch (dwType)
  5481. {
  5482. case REG_SZ:
  5483. bValue = ((0 == stricmp((const char *) Data, "1")) || (0 == stricmp((const char *) Data, "true")));
  5484. break;
  5485. case REG_DWORD:
  5486. bValue = (bool)(((DWORD *) Data)[0]);
  5487. break;
  5488. }
  5489. }
  5490. RegCloseKey(hkey);
  5491. }
  5492. }
  5493. if( bValue )
  5494. mnOutStyle &= ~TOOLBOX_STYLE_FLAT;
  5495. #endif
  5496. }