PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 1ms

/libreoffice-3.6.0.2/vcl/source/window/toolbox.cxx

#
C++ | 6042 lines | 4738 code | 796 blank | 508 comment | 1275 complexity | 8dc7e982bf22d4305b194966b59a74b2 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /*************************************************************************
  3. *
  4. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5. *
  6. * Copyright 2000, 2010 Oracle and/or its affiliates.
  7. *
  8. * OpenOffice.org - a multi-platform office productivity suite
  9. *
  10. * This file is part of OpenOffice.org.
  11. *
  12. * OpenOffice.org is free software: you can redistribute it and/or modify
  13. * it under the terms of the GNU Lesser General Public License version 3
  14. * only, as published by the Free Software Foundation.
  15. *
  16. * OpenOffice.org is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU Lesser General Public License version 3 for more details
  20. * (a copy is included in the LICENSE file that accompanied this code).
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * version 3 along with OpenOffice.org. If not, see
  24. * <http://www.openoffice.org/license.html>
  25. * for a copy of the LGPLv3 License.
  26. *
  27. ************************************************************************/
  28. #include <rtl/logfile.hxx>
  29. #include <tools/debug.hxx>
  30. #include <tools/rc.h>
  31. #include <tools/poly.hxx>
  32. #include <vcl/event.hxx>
  33. #include <vcl/decoview.hxx>
  34. #include <vcl/accel.hxx>
  35. #include <vcl/svapp.hxx>
  36. #include <vcl/help.hxx>
  37. #include <vcl/sound.hxx>
  38. #include <vcl/virdev.hxx>
  39. #include <vcl/spin.h>
  40. #include <vcl/toolbox.hxx>
  41. #include <vcl/bitmap.hxx>
  42. #include <vcl/mnemonic.hxx>
  43. #include <vcl/gradient.hxx>
  44. #include <vcl/menu.hxx>
  45. #include <svdata.hxx>
  46. #include <window.h>
  47. #include <toolbox.h>
  48. #include <salframe.hxx>
  49. #if defined WNT
  50. #include <svsys.h>
  51. #endif
  52. #include <string.h>
  53. #include <vector>
  54. #include <math.h>
  55. // =======================================================================
  56. DBG_NAMEEX( Window )
  57. // =======================================================================
  58. #define SMALLBUTTON_HSIZE 7
  59. #define SMALLBUTTON_VSIZE 7
  60. #define SMALLBUTTON_OFF_NORMAL_X 3
  61. #define SMALLBUTTON_OFF_NORMAL_Y 3
  62. #define SMALLBUTTON_OFF_PRESSED_X 5
  63. #define SMALLBUTTON_OFF_PRESSED_Y 5
  64. #define OUTBUTTON_SIZE 6
  65. #define OUTBUTTON_BORDER 4
  66. #define OUTBUTTON_OFF_NORMAL_X 1
  67. #define OUTBUTTON_OFF_NORMAL_Y 1
  68. // -----------------------------------------------------------------------
  69. #define TB_TEXTOFFSET 2
  70. #define TB_IMAGETEXTOFFSET 3
  71. #define TB_LINESPACING 3
  72. #define TB_SPIN_SIZE 14
  73. #define TB_SPIN_OFFSET 2
  74. #define TB_NEXT_SIZE 22
  75. #define TB_NEXT_OFFSET 2
  76. #define TB_BORDER_OFFSET1 4
  77. #define TB_BORDER_OFFSET2 2
  78. #define TB_CUSTOMIZE_OFFSET 2
  79. #define TB_RESIZE_OFFSET 3
  80. #define TB_MAXLINES 5
  81. #define TB_MAXNOSCROLL 32765
  82. #define TB_MIN_WIN_WIDTH 20
  83. #define TB_CALCMODE_HORZ 1
  84. #define TB_CALCMODE_VERT 2
  85. #define TB_CALCMODE_FLOAT 3
  86. #define TB_WBLINESIZING (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
  87. #define DOCK_LINEHSIZE ((sal_uInt16)0x0001)
  88. #define DOCK_LINEVSIZE ((sal_uInt16)0x0002)
  89. #define DOCK_LINERIGHT ((sal_uInt16)0x1000)
  90. #define DOCK_LINEBOTTOM ((sal_uInt16)0x2000)
  91. #define DOCK_LINELEFT ((sal_uInt16)0x4000)
  92. #define DOCK_LINETOP ((sal_uInt16)0x8000)
  93. #define DOCK_LINEOFFSET 3
  94. // -----------------------------------------------------------------------
  95. static void ImplDrawButton( ToolBox* pThis, const Rectangle &rRect, sal_uInt16 highlight, sal_Bool bChecked, sal_Bool bEnabled, sal_Bool bIsWindow );
  96. // -----------------------------------------------------------------------
  97. struct ImplToolSize
  98. {
  99. long mnWidth;
  100. long mnHeight;
  101. sal_uInt16 mnLines;
  102. };
  103. struct ImplToolSizeArray
  104. {
  105. long mnLength;
  106. long mnLastEntry;
  107. ImplToolSize* mpSize;
  108. ImplToolSizeArray() { mpSize = NULL; mnLength = 0; mnLastEntry = 0; }
  109. ~ImplToolSizeArray() { if( mpSize ) delete [] mpSize; mnLength = 0; }
  110. };
  111. // -----------------------------------------------------------------------
  112. typedef ::std::vector< ToolBox* > ImplTBList;
  113. class ImplTBDragMgr
  114. {
  115. private:
  116. ImplTBList* mpBoxList;
  117. ToolBox* mpDragBox;
  118. Point maMouseOff;
  119. Rectangle maRect;
  120. Rectangle maStartRect;
  121. Accelerator maAccel;
  122. long mnMinWidth;
  123. long mnMaxWidth;
  124. sal_uInt16 mnLineMode;
  125. sal_uInt16 mnStartLines;
  126. void* mpCustomizeData;
  127. sal_Bool mbCustomizeMode;
  128. sal_Bool mbResizeMode;
  129. sal_Bool mbShowDragRect;
  130. public:
  131. ImplTBDragMgr();
  132. ~ImplTBDragMgr();
  133. void push_back( ToolBox* pBox )
  134. { mpBoxList->push_back( pBox ); }
  135. void erase( ToolBox* pBox )
  136. {
  137. for ( ImplTBList::iterator it = mpBoxList->begin(); it != mpBoxList->end(); ++it ) {
  138. if ( *it == pBox ) {
  139. mpBoxList->erase( it );
  140. break;
  141. }
  142. }
  143. }
  144. size_t size() const
  145. { return mpBoxList->size(); }
  146. ToolBox* FindToolBox( const Rectangle& rRect );
  147. void StartDragging( ToolBox* pDragBox,
  148. const Point& rPos, const Rectangle& rRect,
  149. sal_uInt16 nLineMode, sal_Bool bResizeItem,
  150. void* pData = NULL );
  151. void Dragging( const Point& rPos );
  152. void EndDragging( sal_Bool bOK = sal_True );
  153. void HideDragRect() { if ( mbShowDragRect ) mpDragBox->HideTracking(); }
  154. void UpdateDragRect();
  155. DECL_LINK( SelectHdl, Accelerator* );
  156. sal_Bool IsCustomizeMode() { return mbCustomizeMode; }
  157. sal_Bool IsResizeMode() { return mbResizeMode; }
  158. };
  159. // -----------------------------------------------------------------------
  160. static ImplTBDragMgr* ImplGetTBDragMgr()
  161. {
  162. ImplSVData* pSVData = ImplGetSVData();
  163. if ( !pSVData->maCtrlData.mpTBDragMgr )
  164. pSVData->maCtrlData.mpTBDragMgr = new ImplTBDragMgr;
  165. return pSVData->maCtrlData.mpTBDragMgr;
  166. }
  167. // -----------------------------------------------------------------------
  168. int ToolBox::ImplGetDragWidth( ToolBox* pThis )
  169. {
  170. #define TB_DRAGWIDTH 8 // the default width of the grip
  171. int width = TB_DRAGWIDTH;
  172. if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL ) )
  173. {
  174. ImplControlValue aControlValue;
  175. Point aPoint;
  176. Rectangle aContent, aBound;
  177. Rectangle aArea( aPoint, pThis->GetOutputSizePixel() );
  178. if ( pThis->GetNativeControlRegion(CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
  179. aArea, 0, aControlValue, rtl::OUString(), aBound, aContent) )
  180. {
  181. width = pThis->mbHorz ? aContent.GetWidth() : aContent.GetHeight();
  182. }
  183. }
  184. return width;
  185. }
  186. ButtonType determineButtonType( ImplToolItem* pItem, ButtonType defaultType )
  187. {
  188. ButtonType tmpButtonType = defaultType;
  189. ToolBoxItemBits nBits( pItem->mnBits & 0x300 );
  190. if ( nBits & TIB_TEXTICON ) // item has custom setting
  191. {
  192. tmpButtonType = BUTTON_SYMBOLTEXT;
  193. if ( nBits == TIB_TEXT_ONLY )
  194. tmpButtonType = BUTTON_TEXT;
  195. else if ( nBits == TIB_ICON_ONLY )
  196. tmpButtonType = BUTTON_SYMBOL;
  197. }
  198. return tmpButtonType;
  199. }
  200. // -----------------------------------------------------------------------
  201. void ToolBox::ImplUpdateDragArea( ToolBox *pThis )
  202. {
  203. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  204. if( pWrapper )
  205. {
  206. if ( pThis->ImplIsFloatingMode() || pWrapper->IsLocked() )
  207. pWrapper->SetDragArea( Rectangle() );
  208. else
  209. {
  210. if( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
  211. pWrapper->SetDragArea( Rectangle( 0, 0, ImplGetDragWidth( pThis ), pThis->GetOutputSizePixel().Height() ) );
  212. else
  213. pWrapper->SetDragArea( Rectangle( 0, 0, pThis->GetOutputSizePixel().Width(), ImplGetDragWidth( pThis ) ) );
  214. }
  215. }
  216. }
  217. // -----------------------------------------------------------------------
  218. void ToolBox::ImplCalcBorder( WindowAlign eAlign, long& rLeft, long& rTop,
  219. long& rRight, long& rBottom, const ToolBox *pThis )
  220. {
  221. if( pThis->ImplIsFloatingMode() || !(pThis->mnWinStyle & WB_BORDER) )
  222. {
  223. // no border in floating mode
  224. rLeft = rTop = rRight = rBottom = 0;
  225. return;
  226. }
  227. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  228. // reserve dragarea only for dockable toolbars
  229. int dragwidth = ( pWrapper && !pWrapper->IsLocked() ) ? ImplGetDragWidth( (ToolBox*)pThis ) : 0;
  230. // no shadow border for dockable toolbars
  231. int borderwidth = pWrapper ? 0: 2;
  232. if ( eAlign == WINDOWALIGN_TOP )
  233. {
  234. rLeft = borderwidth+dragwidth;
  235. rTop = borderwidth;
  236. rRight = borderwidth;
  237. rBottom = 0;
  238. }
  239. else if ( eAlign == WINDOWALIGN_LEFT )
  240. {
  241. rLeft = borderwidth;
  242. rTop = borderwidth+dragwidth;
  243. rRight = 0;
  244. rBottom = borderwidth;
  245. }
  246. else if ( eAlign == WINDOWALIGN_BOTTOM )
  247. {
  248. rLeft = borderwidth+dragwidth;
  249. rTop = 0;
  250. rRight = borderwidth;
  251. rBottom = borderwidth;
  252. }
  253. else
  254. {
  255. rLeft = 0;
  256. rTop = borderwidth+dragwidth;
  257. rRight = borderwidth;
  258. rBottom = borderwidth;
  259. }
  260. }
  261. // -----------------------------------------------------------------------
  262. static void ImplCheckUpdate( ToolBox *pThis )
  263. {
  264. // remove any pending invalidates to avoid
  265. // have them triggered when paint is locked (see mpData->mbIsPaintLocked)
  266. // which would result in erasing the background only and not painting any items
  267. // this must not be done when we're already in Paint()
  268. // this is only required for transparent toolbars (see ImplDrawTransparentBackground() )
  269. if( !pThis->IsBackground() && pThis->HasPaintEvent() && !pThis->IsInPaint() )
  270. pThis->Update();
  271. }
  272. // -----------------------------------------------------------------------
  273. void ToolBox::ImplDrawGrip( ToolBox* pThis )
  274. {
  275. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  276. if( pWrapper && !pWrapper->GetDragArea().IsEmpty() )
  277. {
  278. // execute pending paint requests
  279. ImplCheckUpdate( pThis );
  280. sal_Bool bNativeOk = sal_False;
  281. if( pThis->IsNativeControlSupported( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_HORZ : PART_THUMB_VERT ) )
  282. {
  283. ToolbarValue aToolbarValue;
  284. aToolbarValue.maGripRect = pWrapper->GetDragArea();
  285. Point aPt;
  286. Rectangle aCtrlRegion( aPt, pThis->GetOutputSizePixel() );
  287. ControlState nState = CTRL_STATE_ENABLED;
  288. bNativeOk = pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_THUMB_VERT : PART_THUMB_HORZ,
  289. aCtrlRegion, nState, aToolbarValue, rtl::OUString() );
  290. }
  291. if( bNativeOk )
  292. return;
  293. const StyleSettings& rStyleSettings = pThis->GetSettings().GetStyleSettings();
  294. pThis->SetLineColor( rStyleSettings.GetShadowColor() );
  295. Size aSz ( pThis->GetOutputSizePixel() );
  296. if ( pThis->meAlign == WINDOWALIGN_TOP || pThis->meAlign == WINDOWALIGN_BOTTOM )
  297. {
  298. int height = (int) (0.6 * aSz.Height() + 0.5);
  299. int i = (aSz.Height() - height) / 2;
  300. height += i;
  301. while( i <= height )
  302. {
  303. int x = ImplGetDragWidth( pThis ) / 2;
  304. pThis->DrawPixel( Point(x, i), rStyleSettings.GetDarkShadowColor() );
  305. pThis->DrawPixel( Point(x+1, i), rStyleSettings.GetShadowColor() );
  306. pThis->DrawPixel( Point(x, i+1), rStyleSettings.GetShadowColor() );
  307. pThis->DrawPixel( Point(x+1, i+1), rStyleSettings.GetFaceColor() );
  308. pThis->DrawPixel( Point(x+2, i+1), Color(COL_WHITE) );
  309. pThis->DrawPixel( Point(x+1, i+2), Color(COL_WHITE) );
  310. pThis->DrawPixel( Point(x+2, i+2), Color(COL_WHITE) );
  311. i+=4;
  312. }
  313. }
  314. else
  315. {
  316. int width = (int) (0.6 * aSz.Width() + 0.5);
  317. int i = (aSz.Width() - width) / 2;
  318. width += i;
  319. while( i <= width )
  320. {
  321. int y = ImplGetDragWidth(pThis) / 2;
  322. pThis->DrawPixel( Point(i, y), rStyleSettings.GetDarkShadowColor() );
  323. pThis->DrawPixel( Point(i+1, y), rStyleSettings.GetShadowColor() );
  324. pThis->DrawPixel( Point(i, y+1), rStyleSettings.GetShadowColor() );
  325. pThis->DrawPixel( Point(i+1, y+1), rStyleSettings.GetFaceColor() );
  326. pThis->DrawPixel( Point(i+2, y+1), Color(COL_WHITE) );
  327. pThis->DrawPixel( Point(i+1, y+2), Color(COL_WHITE) );
  328. pThis->DrawPixel( Point(i+2, y+2), Color(COL_WHITE) );
  329. i+=4;
  330. }
  331. }
  332. }
  333. }
  334. void ToolBox::ImplDrawGradientBackground( ToolBox* pThis, ImplDockingWindowWrapper * )
  335. {
  336. // draw a nice gradient
  337. Color startCol, endCol;
  338. startCol = pThis->GetSettings().GetStyleSettings().GetFaceGradientColor();
  339. endCol = pThis->GetSettings().GetStyleSettings().GetFaceColor();
  340. if( pThis->GetSettings().GetStyleSettings().GetHighContrastMode() )
  341. // no 'extreme' gradient when high contrast
  342. startCol = endCol;
  343. Gradient g;
  344. g.SetAngle( pThis->mbHorz ? 0 : 900 );
  345. g.SetStyle( GradientStyle_LINEAR );
  346. g.SetStartColor( startCol );
  347. g.SetEndColor( endCol );
  348. sal_Bool bLineColor = pThis->IsLineColor();
  349. Color aOldCol = pThis->GetLineColor();
  350. pThis->SetLineColor( pThis->GetSettings().GetStyleSettings().GetShadowColor() );
  351. Size aFullSz( pThis->GetOutputSizePixel() );
  352. Size aLineSz( aFullSz );
  353. // use the linesize only when floating
  354. // full window height is used when docked (single line)
  355. if( pThis->ImplIsFloatingMode() )
  356. {
  357. long nLineSize;
  358. if( pThis->mbHorz )
  359. {
  360. nLineSize = pThis->mnMaxItemHeight;
  361. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  362. nLineSize = pThis->mnWinHeight;
  363. aLineSz.Height() = nLineSize;
  364. }
  365. else
  366. {
  367. nLineSize = pThis->mnMaxItemWidth;
  368. aLineSz.Width() = nLineSize;
  369. }
  370. }
  371. long nLeft, nTop, nRight, nBottom;
  372. ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
  373. Size aTopLineSz( aLineSz );
  374. Size aBottomLineSz( aLineSz );
  375. if ( pThis->mnWinStyle & WB_BORDER )
  376. {
  377. if( pThis->mbHorz )
  378. {
  379. aTopLineSz.Height() += TB_BORDER_OFFSET2 + nTop;
  380. aBottomLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
  381. if( pThis->mnCurLines == 1 )
  382. aTopLineSz.Height() += TB_BORDER_OFFSET2 + nBottom;
  383. }
  384. else
  385. {
  386. aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
  387. aBottomLineSz.Width() += TB_BORDER_OFFSET1 + nRight;
  388. if( pThis->mnCurLines == 1 )
  389. aTopLineSz.Width() += TB_BORDER_OFFSET1 + nLeft;
  390. }
  391. }
  392. if( pThis->mbHorz )
  393. {
  394. aTopLineSz.Height() += pThis->mnBorderY;
  395. if( pThis->mnCurLines == 1 )
  396. aTopLineSz.Height() += pThis->mnBorderY;
  397. aBottomLineSz.Height() += pThis->mnBorderY;
  398. }
  399. else
  400. {
  401. aTopLineSz.Width() += pThis->mnBorderX;
  402. if( pThis->mnCurLines == 1 )
  403. aTopLineSz.Width() += pThis->mnBorderX;
  404. aBottomLineSz.Width() += pThis->mnBorderX;
  405. }
  406. if ( pThis->mnWinStyle & WB_LINESPACING )
  407. {
  408. if( pThis->mbHorz )
  409. {
  410. aLineSz.Height() += TB_LINESPACING;
  411. if( pThis->mnCurLines > 1 )
  412. aTopLineSz.Height() += TB_LINESPACING;
  413. }
  414. else
  415. {
  416. aLineSz.Width() += TB_LINESPACING;
  417. if( pThis->mnCurLines > 1 )
  418. aTopLineSz.Width() += TB_LINESPACING;
  419. }
  420. }
  421. if( pThis->mbHorz )
  422. {
  423. long y = 0;
  424. sal_Bool bDrawSep = sal_False; // pThis->ImplIsFloatingMode() && ( pThis->mnWinStyle & WB_LINESPACING );
  425. pThis->DrawGradient( Rectangle( 0, y, aTopLineSz.Width(), y+aTopLineSz.Height()), g );
  426. y += aTopLineSz.Height();
  427. if ( bDrawSep )
  428. pThis->DrawLine( Point(0, y-2), Point(aTopLineSz.Width(), y-2) );
  429. while( y < (pThis->mnDY - aBottomLineSz.Height()) )
  430. {
  431. pThis->DrawGradient( Rectangle( 0, y, aLineSz.Width(), y+aLineSz.Height()), g);
  432. y += aLineSz.Height();
  433. if ( bDrawSep )
  434. pThis->DrawLine( Point(0, y-2), Point(aLineSz.Width(), y-2) );
  435. }
  436. pThis->DrawGradient( Rectangle( 0, y, aBottomLineSz.Width(), y+aBottomLineSz.Height()), g );
  437. if ( bDrawSep )
  438. pThis->DrawLine( Point(0, y-2), Point(aBottomLineSz.Width(), y-2) );
  439. }
  440. else
  441. {
  442. long x = 0;
  443. pThis->DrawGradient( Rectangle( x, 0, x+aTopLineSz.Width(), aTopLineSz.Height()), g );
  444. x += aTopLineSz.Width();
  445. while( x < (pThis->mnDX - aBottomLineSz.Width()) )
  446. {
  447. pThis->DrawGradient( Rectangle( x, 0, x+aLineSz.Width(), aLineSz.Height()), g);
  448. x += aLineSz.Width();
  449. }
  450. pThis->DrawGradient( Rectangle( x, 0, x+aBottomLineSz.Width(), aBottomLineSz.Height()), g );
  451. }
  452. if( bLineColor )
  453. pThis->SetLineColor( aOldCol );
  454. }
  455. sal_Bool ToolBox::ImplDrawNativeBackground( ToolBox* pThis, const Region & )
  456. {
  457. // use NWF
  458. Point aPt;
  459. Rectangle aCtrlRegion( aPt, pThis->GetOutputSizePixel() );
  460. ControlState nState = CTRL_STATE_ENABLED;
  461. return pThis->DrawNativeControl( CTRL_TOOLBAR, pThis->mbHorz ? PART_DRAW_BACKGROUND_HORZ : PART_DRAW_BACKGROUND_VERT,
  462. aCtrlRegion, nState, ImplControlValue(), rtl::OUString() );
  463. }
  464. void ToolBox::ImplDrawTransparentBackground( ToolBox* pThis, const Region &rRegion )
  465. {
  466. // just invalidate to trigger paint of the parent
  467. const bool bOldPaintLock = pThis->mpData->mbIsPaintLocked;
  468. pThis->mpData->mbIsPaintLocked = true;
  469. // send an invalidate to the first opaque parent and invalidate the whole hierarchy from there (noclipchildren)
  470. pThis->Invalidate( rRegion, INVALIDATE_UPDATE|INVALIDATE_NOCLIPCHILDREN );
  471. pThis->mpData->mbIsPaintLocked = bOldPaintLock;
  472. }
  473. void ToolBox::ImplDrawConstantBackground( ToolBox* pThis, const Region &rRegion, sal_Bool bIsInPopupMode )
  474. {
  475. // draw a constant color
  476. if( !bIsInPopupMode )
  477. // default background
  478. pThis->Erase( rRegion.GetBoundRect() );
  479. else
  480. {
  481. // use different color in popupmode
  482. pThis->DrawWallpaper( rRegion.GetBoundRect(),
  483. Wallpaper( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() ) );
  484. }
  485. }
  486. void ToolBox::ImplDrawBackground( ToolBox* pThis, const Rectangle &rRect )
  487. {
  488. // execute pending paint requests
  489. ImplCheckUpdate( pThis );
  490. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  491. sal_Bool bIsInPopupMode = pThis->ImplIsInPopupMode();
  492. Region aPaintRegion( rRect );
  493. // make sure we do not invalidate/erase too much
  494. if( pThis->IsInPaint() )
  495. aPaintRegion.Intersect( pThis->GetActiveClipRegion() );
  496. pThis->Push( PUSH_CLIPREGION );
  497. pThis->IntersectClipRegion( aPaintRegion );
  498. if( !pWrapper /*|| bIsInPopupMode*/ )
  499. {
  500. // no gradient for ordinary toolbars (not dockable)
  501. if( !pThis->IsBackground() && !pThis->IsInPaint() )
  502. ImplDrawTransparentBackground( pThis, aPaintRegion );
  503. else
  504. ImplDrawConstantBackground( pThis, aPaintRegion, bIsInPopupMode );
  505. }
  506. else
  507. {
  508. // toolbars known to the dockingmanager will be drawn using NWF or a gradient
  509. // docked toolbars are transparent and NWF is already used in the docking area which is their common background
  510. // so NWF is used here for floating toolbars only
  511. sal_Bool bNativeOk = sal_False;
  512. if( pThis->ImplIsFloatingMode() && pThis->IsNativeControlSupported( CTRL_TOOLBAR, PART_ENTIRE_CONTROL) )
  513. bNativeOk = ImplDrawNativeBackground( pThis, aPaintRegion );
  514. if( !bNativeOk )
  515. {
  516. if( !pThis->IsBackground() )
  517. {
  518. if( !pThis->IsInPaint() )
  519. ImplDrawTransparentBackground( pThis, aPaintRegion );
  520. }
  521. else
  522. ImplDrawGradientBackground( pThis, pWrapper );
  523. }
  524. }
  525. // restore clip region
  526. pThis->Pop();
  527. }
  528. void ToolBox::ImplErase( ToolBox* pThis, const Rectangle &rRect, sal_Bool bHighlight, sal_Bool bHasOpenPopup )
  529. {
  530. // the background of non NWF buttons is painted in a constant color
  531. // to have the same highlight color (transparency in DrawSelectionBackground())
  532. // items with open popups will also painted using a constant color
  533. if( !pThis->mpData->mbNativeButtons &&
  534. (bHighlight || ! (((Window*) pThis)->GetStyle() & WB_3DLOOK ) ) )
  535. {
  536. if( (((Window*) pThis)->GetStyle() & WB_3DLOOK ) )
  537. {
  538. pThis->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
  539. pThis->SetLineColor();
  540. if( bHasOpenPopup )
  541. // choose the same color as the popup will use
  542. pThis->SetFillColor( pThis->GetSettings().GetStyleSettings().GetFaceGradientColor() );
  543. else
  544. pThis->SetFillColor( Color( COL_WHITE ) );
  545. pThis->DrawRect( rRect );
  546. pThis->Pop();
  547. }
  548. else
  549. ImplDrawBackground( pThis, rRect );
  550. }
  551. else
  552. ImplDrawBackground( pThis, rRect );
  553. }
  554. void ToolBox::ImplDrawBorder( ToolBox* pWin )
  555. {
  556. const StyleSettings& rStyleSettings = pWin->GetSettings().GetStyleSettings();
  557. long nDX = pWin->mnDX;
  558. long nDY = pWin->mnDY;
  559. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pWin );
  560. // draw borders for ordinary toolbars only (not dockable)
  561. if( pWrapper )
  562. return;
  563. if ( pWin->meAlign == WINDOWALIGN_BOTTOM )
  564. {
  565. // draw bottom border
  566. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  567. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
  568. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  569. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  570. }
  571. else
  572. {
  573. // draw top border
  574. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  575. pWin->DrawLine( Point( 0, 0 ), Point( nDX-1, 0 ) );
  576. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  577. pWin->DrawLine( Point( 0, 1 ), Point( nDX-1, 1 ) );
  578. if ( (pWin->meAlign == WINDOWALIGN_LEFT) || (pWin->meAlign == WINDOWALIGN_RIGHT) )
  579. {
  580. if ( pWin->meAlign == WINDOWALIGN_LEFT )
  581. {
  582. // draw left-bottom border
  583. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  584. pWin->DrawLine( Point( 0, 0 ), Point( 0, nDY-1 ) );
  585. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-1, nDY-2 ) );
  586. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  587. pWin->DrawLine( Point( 1, 1 ), Point( 1, nDY-3 ) );
  588. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  589. }
  590. else
  591. {
  592. // draw right-bottom border
  593. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  594. pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-3 ) );
  595. pWin->DrawLine( Point( 0, nDY-2 ), Point( nDX-2, nDY-2 ) );
  596. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  597. pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
  598. pWin->DrawLine( Point( 0, nDY-1 ), Point( nDX-1, nDY-1 ) );
  599. }
  600. }
  601. }
  602. if ( pWin->meAlign == WINDOWALIGN_BOTTOM || pWin->meAlign == WINDOWALIGN_TOP )
  603. {
  604. // draw right border
  605. pWin->SetLineColor( rStyleSettings.GetShadowColor() );
  606. pWin->DrawLine( Point( nDX-2, 0 ), Point( nDX-2, nDY-1 ) );
  607. pWin->SetLineColor( rStyleSettings.GetLightColor() );
  608. pWin->DrawLine( Point( nDX-1, 0 ), Point( nDX-1, nDY-1 ) );
  609. }
  610. }
  611. // -----------------------------------------------------------------------
  612. static bool ImplIsFixedControl( const ImplToolItem *pItem )
  613. {
  614. return ( pItem->mpWindow &&
  615. (pItem->mpWindow->GetType() == WINDOW_FIXEDTEXT ||
  616. pItem->mpWindow->GetType() == WINDOW_FIXEDLINE ||
  617. pItem->mpWindow->GetType() == WINDOW_GROUPBOX) );
  618. }
  619. // -----------------------------------------------------------------------
  620. const ImplToolItem *ToolBox::ImplGetFirstClippedItem( const ToolBox* pThis )
  621. {
  622. std::vector< ImplToolItem >::const_iterator it;
  623. it = pThis->mpData->m_aItems.begin();
  624. while ( it != pThis->mpData->m_aItems.end() )
  625. {
  626. if( it->IsClipped() )
  627. return &(*it);
  628. ++it;
  629. }
  630. return NULL;
  631. }
  632. // -----------------------------------------------------------------------
  633. Size ToolBox::ImplCalcSize( const ToolBox* pThis, sal_uInt16 nCalcLines, sal_uInt16 nCalcMode )
  634. {
  635. long nMax;
  636. long nLeft = 0;
  637. long nTop = 0;
  638. long nRight = 0;
  639. long nBottom = 0;
  640. Size aSize;
  641. WindowAlign eOldAlign = pThis->meAlign;
  642. sal_Bool bOldHorz = pThis->mbHorz;
  643. sal_Bool bOldAssumeDocked = pThis->mpData->mbAssumeDocked;
  644. sal_Bool bOldAssumeFloating = pThis->mpData->mbAssumeFloating;
  645. if ( nCalcMode )
  646. {
  647. sal_Bool bOldFloatingMode = pThis->ImplIsFloatingMode();
  648. pThis->mpData->mbAssumeDocked = sal_False;
  649. pThis->mpData->mbAssumeFloating = sal_False;
  650. if ( nCalcMode == TB_CALCMODE_HORZ )
  651. {
  652. pThis->mpData->mbAssumeDocked = sal_True; // force non-floating mode during calculation
  653. ImplCalcBorder( WINDOWALIGN_TOP, nLeft, nTop, nRight, nBottom, pThis );
  654. ((ToolBox*)pThis)->mbHorz = sal_True;
  655. if ( pThis->mbHorz != bOldHorz )
  656. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
  657. }
  658. else if ( nCalcMode == TB_CALCMODE_VERT )
  659. {
  660. pThis->mpData->mbAssumeDocked = sal_True; // force non-floating mode during calculation
  661. ImplCalcBorder( WINDOWALIGN_LEFT, nLeft, nTop, nRight, nBottom, pThis );
  662. ((ToolBox*)pThis)->mbHorz = sal_False;
  663. if ( pThis->mbHorz != bOldHorz )
  664. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_LEFT;
  665. }
  666. else if ( nCalcMode == TB_CALCMODE_FLOAT )
  667. {
  668. pThis->mpData->mbAssumeFloating = sal_True; // force non-floating mode during calculation
  669. nLeft = nTop = nRight = nBottom = 0;
  670. ((ToolBox*)pThis)->mbHorz = sal_True;
  671. if ( pThis->mbHorz != bOldHorz )
  672. ((ToolBox*)pThis)->meAlign = WINDOWALIGN_TOP;
  673. }
  674. if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) ||
  675. (pThis->ImplIsFloatingMode() != bOldFloatingMode ) )
  676. ((ToolBox*)pThis)->mbCalc = sal_True;
  677. }
  678. else
  679. ImplCalcBorder( pThis->meAlign, nLeft, nTop, nRight, nBottom, pThis );
  680. ((ToolBox*)pThis)->ImplCalcItem();
  681. if( !nCalcMode && pThis->ImplIsFloatingMode() )
  682. {
  683. aSize = ImplCalcFloatSize( ((ToolBox*)pThis), nCalcLines );
  684. }
  685. else
  686. {
  687. if ( pThis->mbHorz )
  688. {
  689. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  690. aSize.Height() = nCalcLines * pThis->mnWinHeight;
  691. else
  692. aSize.Height() = nCalcLines * pThis->mnMaxItemHeight;
  693. if ( pThis->mnWinStyle & WB_LINESPACING )
  694. aSize.Height() += (nCalcLines-1)*TB_LINESPACING;
  695. if ( pThis->mnWinStyle & WB_BORDER )
  696. aSize.Height() += (TB_BORDER_OFFSET2*2) + nTop + nBottom;
  697. nMax = 0;
  698. ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
  699. if ( nMax )
  700. aSize.Width() += nMax;
  701. if ( pThis->mnWinStyle & WB_BORDER )
  702. aSize.Width() += (TB_BORDER_OFFSET1*2) + nLeft + nRight;
  703. }
  704. else
  705. {
  706. aSize.Width() = nCalcLines * pThis->mnMaxItemWidth;
  707. if ( pThis->mnWinStyle & WB_LINESPACING )
  708. aSize.Width() += (nCalcLines-1)*TB_LINESPACING;
  709. if ( pThis->mnWinStyle & WB_BORDER )
  710. aSize.Width() += (TB_BORDER_OFFSET2*2) + nLeft + nRight;
  711. nMax = 0;
  712. ((ToolBox*)pThis)->ImplCalcBreaks( TB_MAXNOSCROLL, &nMax, pThis->mbHorz );
  713. if ( nMax )
  714. aSize.Height() += nMax;
  715. if ( pThis->mnWinStyle & WB_BORDER )
  716. aSize.Height() += (TB_BORDER_OFFSET1*2) + nTop + nBottom;
  717. }
  718. }
  719. // restore previous values
  720. if ( nCalcMode )
  721. {
  722. pThis->mpData->mbAssumeDocked = bOldAssumeDocked;
  723. pThis->mpData->mbAssumeFloating = bOldAssumeFloating;
  724. if ( (pThis->meAlign != eOldAlign) || (pThis->mbHorz != bOldHorz) )
  725. {
  726. ((ToolBox*)pThis)->meAlign = eOldAlign;
  727. ((ToolBox*)pThis)->mbHorz = bOldHorz;
  728. ((ToolBox*)pThis)->mbCalc = sal_True;
  729. }
  730. }
  731. if ( aSize.Width() )
  732. aSize.Width() += pThis->mnBorderX*2;
  733. if ( aSize.Height() )
  734. aSize.Height() += pThis->mnBorderY*2;
  735. return aSize;
  736. }
  737. // -----------------------------------------------------------------------
  738. void ToolBox::ImplCalcFloatSizes( ToolBox* pThis )
  739. {
  740. if ( pThis->mpFloatSizeAry )
  741. return;
  742. // calculate the minimal size, i.e. where the biggest item just fits
  743. long nCalcSize = 0;
  744. std::vector< ImplToolItem >::const_iterator it;
  745. it = pThis->mpData->m_aItems.begin();
  746. while ( it != pThis->mpData->m_aItems.end() )
  747. {
  748. if ( it->mbVisible )
  749. {
  750. if ( it->mpWindow )
  751. {
  752. long nTempSize = it->mpWindow->GetSizePixel().Width();
  753. if ( nTempSize > nCalcSize )
  754. nCalcSize = nTempSize;
  755. }
  756. else
  757. {
  758. if( it->maItemSize.Width() > nCalcSize )
  759. nCalcSize = it->maItemSize.Width();
  760. }
  761. }
  762. ++it;
  763. }
  764. // calc an upper bound for ImplCalcBreaks below
  765. long upperBoundWidth = nCalcSize * pThis->mpData->m_aItems.size();
  766. sal_uInt16 i;
  767. sal_uInt16 nLines;
  768. sal_uInt16 nCalcLines;
  769. sal_uInt16 nTempLines;
  770. long nHeight;
  771. long nMaxLineWidth;
  772. nCalcLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, sal_True );
  773. pThis->mpFloatSizeAry = new ImplToolSizeArray;
  774. pThis->mpFloatSizeAry->mpSize = new ImplToolSize[nCalcLines];
  775. pThis->mpFloatSizeAry->mnLength = nCalcLines;
  776. memset( pThis->mpFloatSizeAry->mpSize, 0, sizeof( ImplToolSize )*nCalcLines );
  777. i = 0;
  778. nTempLines = nLines = nCalcLines;
  779. while ( nLines )
  780. {
  781. nHeight = ImplCalcSize( pThis, nTempLines, TB_CALCMODE_FLOAT ).Height();
  782. pThis->mpFloatSizeAry->mnLastEntry = i;
  783. pThis->mpFloatSizeAry->mpSize[i].mnHeight = nHeight;
  784. pThis->mpFloatSizeAry->mpSize[i].mnLines = nTempLines;
  785. pThis->mpFloatSizeAry->mpSize[i].mnWidth = nMaxLineWidth+(TB_BORDER_OFFSET1*2);
  786. nLines--;
  787. if ( nLines )
  788. {
  789. do
  790. {
  791. nCalcSize += pThis->mnMaxItemWidth;
  792. nTempLines = pThis->ImplCalcBreaks( nCalcSize, &nMaxLineWidth, sal_True );
  793. }
  794. while ( (nCalcSize < upperBoundWidth) && (nLines < nTempLines) && (nTempLines != 1) );
  795. if ( nTempLines < nLines )
  796. nLines = nTempLines;
  797. }
  798. i++;
  799. }
  800. }
  801. // -----------------------------------------------------------------------
  802. Size ToolBox::ImplCalcFloatSize( ToolBox* pThis, sal_uInt16& rLines )
  803. {
  804. ImplCalcFloatSizes( pThis );
  805. if ( !rLines )
  806. {
  807. rLines = pThis->mnFloatLines;
  808. if ( !rLines )
  809. rLines = pThis->mnLines;
  810. }
  811. sal_uInt16 i = 0;
  812. while ( i < pThis->mpFloatSizeAry->mnLastEntry &&
  813. rLines < pThis->mpFloatSizeAry->mpSize[i].mnLines )
  814. i++;
  815. Size aSize( pThis->mpFloatSizeAry->mpSize[i].mnWidth,
  816. pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  817. rLines = pThis->mpFloatSizeAry->mpSize[i].mnLines;
  818. if ( pThis->maNextToolBoxStr.Len() && pThis->mbScroll )
  819. aSize.Width() += TB_NEXT_SIZE-TB_NEXT_OFFSET;
  820. return aSize;
  821. }
  822. // -----------------------------------------------------------------------
  823. void ToolBox::ImplCalcMinMaxFloatSize( ToolBox* pThis, Size& rMinSize, Size& rMaxSize )
  824. {
  825. ImplCalcFloatSizes( pThis );
  826. sal_uInt16 i = 0;
  827. rMinSize = Size( pThis->mpFloatSizeAry->mpSize[i].mnWidth, pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  828. rMaxSize = Size( pThis->mpFloatSizeAry->mpSize[i].mnWidth, pThis->mpFloatSizeAry->mpSize[i].mnHeight );
  829. while ( ++i <= pThis->mpFloatSizeAry->mnLastEntry )
  830. {
  831. if( pThis->mpFloatSizeAry->mpSize[i].mnWidth < rMinSize.Width() )
  832. rMinSize.Width() = pThis->mpFloatSizeAry->mpSize[i].mnWidth;
  833. if( pThis->mpFloatSizeAry->mpSize[i].mnHeight < rMinSize.Height() )
  834. rMinSize.Height() = pThis->mpFloatSizeAry->mpSize[i].mnHeight;
  835. if( pThis->mpFloatSizeAry->mpSize[i].mnWidth > rMaxSize.Width() )
  836. rMaxSize.Width() = pThis->mpFloatSizeAry->mpSize[i].mnWidth;
  837. if( pThis->mpFloatSizeAry->mpSize[i].mnHeight > rMaxSize.Height() )
  838. rMaxSize.Height() = pThis->mpFloatSizeAry->mpSize[i].mnHeight;
  839. }
  840. }
  841. void ToolBox::ImplSetMinMaxFloatSize( ToolBox *pThis )
  842. {
  843. ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( pThis );
  844. Size aMinSize, aMaxSize;
  845. ImplCalcMinMaxFloatSize( pThis, aMinSize, aMaxSize );
  846. if( pWrapper )
  847. {
  848. pWrapper->SetMinOutputSizePixel( aMinSize );
  849. pWrapper->SetMaxOutputSizePixel( aMaxSize );
  850. pWrapper->ShowTitleButton( TITLE_BUTTON_MENU, ( pThis->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE) ? sal_True : sal_False );
  851. }
  852. else
  853. {
  854. // TODO: change SetMinOutputSizePixel to be not inline
  855. pThis->SetMinOutputSizePixel( aMinSize );
  856. pThis->SetMaxOutputSizePixel( aMaxSize );
  857. }
  858. }
  859. // -----------------------------------------------------------------------
  860. sal_uInt16 ToolBox::ImplCalcLines( ToolBox* pThis, long nToolSize )
  861. {
  862. long nLineHeight;
  863. if ( pThis->mbHorz )
  864. {
  865. if ( pThis->mnWinHeight > pThis->mnMaxItemHeight )
  866. nLineHeight = pThis->mnWinHeight;
  867. else
  868. nLineHeight = pThis->mnMaxItemHeight;
  869. }
  870. else
  871. nLineHeight = pThis->mnMaxItemWidth;
  872. if ( pThis->mnWinStyle & WB_BORDER )
  873. nToolSize -= TB_BORDER_OFFSET2*2;
  874. if ( pThis->mnWinStyle & WB_LINESPACING )
  875. {
  876. nLineHeight += TB_LINESPACING;
  877. nToolSize += TB_LINESPACING;
  878. }
  879. // #i91917# always report at least one line
  880. long nLines = nToolSize/nLineHeight;
  881. if( nLines < 1 )
  882. nLines = 1;
  883. return static_cast<sal_uInt16>(nLines);
  884. }
  885. // -----------------------------------------------------------------------
  886. sal_uInt16 ToolBox::ImplTestLineSize( ToolBox* pThis, const Point& rPos )
  887. {
  888. if ( !pThis->ImplIsFloatingMode() &&
  889. (!pThis->mbScroll || (pThis->mnLines > 1) || (pThis->mnCurLines > pThis->mnVisLines)) )
  890. {
  891. WindowAlign eAlign = pThis->GetAlign();
  892. if ( eAlign == WINDOWALIGN_LEFT )
  893. {
  894. if ( rPos.X() > pThis->mnDX-DOCK_LINEOFFSET )
  895. return DOCK_LINEHSIZE | DOCK_LINERIGHT;
  896. }
  897. else if ( eAlign == WINDOWALIGN_TOP )
  898. {
  899. if ( rPos.Y() > pThis->mnDY-DOCK_LINEOFFSET )
  900. return DOCK_LINEVSIZE | DOCK_LINEBOTTOM;
  901. }
  902. else if ( eAlign == WINDOWALIGN_RIGHT )
  903. {
  904. if ( rPos.X() < DOCK_LINEOFFSET )
  905. return DOCK_LINEHSIZE | DOCK_LINELEFT;
  906. }
  907. else if ( eAlign == WINDOWALIGN_BOTTOM )
  908. {
  909. if ( rPos.Y() < DOCK_LINEOFFSET )
  910. return DOCK_LINEVSIZE | DOCK_LINETOP;
  911. }
  912. }
  913. return 0;
  914. }
  915. // -----------------------------------------------------------------------
  916. void ToolBox::ImplLineSizing( ToolBox* pThis, const Point& rPos, Rectangle& rRect,
  917. sal_uInt16 nLineMode )
  918. {
  919. sal_Bool mbHorz;
  920. long nOneLineSize;
  921. long nCurSize;
  922. long nMaxSize;
  923. long nSize;
  924. Size aSize;
  925. if ( nLineMode & DOCK_LINERIGHT )
  926. {
  927. nCurSize = rPos.X() - rRect.Left();
  928. mbHorz = sal_False;
  929. }
  930. else if ( nLineMode & DOCK_LINEBOTTOM )
  931. {
  932. nCurSize = rPos.Y() - rRect.Top();
  933. mbHorz = sal_True;
  934. }
  935. else if ( nLineMode & DOCK_LINELEFT )
  936. {
  937. nCurSize = rRect.Right() - rPos.X();
  938. mbHorz = sal_False;
  939. }
  940. else if ( nLineMode & DOCK_LINETOP )
  941. {
  942. nCurSize = rRect.Bottom() - rPos.Y();
  943. mbHorz = sal_True;
  944. }
  945. else {
  946. OSL_FAIL( "ImplLineSizing: Trailing else" );
  947. nCurSize = 0;
  948. mbHorz = sal_False;
  949. }
  950. Size aWinSize = pThis->GetSizePixel();
  951. sal_uInt16 nMaxLines = (pThis->mnLines > pThis->mnCurLines) ? pThis->mnLines : pThis->mnCurLines;
  952. if ( nMaxLines > TB_MAXLINES )
  953. nMaxLines = TB_MAXLINES;
  954. if ( mbHorz )
  955. {
  956. nOneLineSize = ImplCalcSize( pThis, 1 ).Height();
  957. nMaxSize = pThis->maOutDockRect.GetHeight() - 20;
  958. if ( nMaxSize < aWinSize.Height() )
  959. nMaxSize = aWinSize.Height();
  960. }
  961. else
  962. {
  963. nOneLineSize = ImplCalcSize( pThis, 1 ).Width();
  964. nMaxSize = pThis->maOutDockRect.GetWidth() - 20;
  965. if ( nMaxSize < aWinSize.Width() )
  966. nMaxSize = aWinSize.Width();
  967. }
  968. sal_uInt16 i = 1;
  969. if ( nCurSize <= nOneLineSize )
  970. nSize = nOneLineSize;
  971. else
  972. {
  973. nSize = 0;
  974. while ( (nSize < nCurSize) && (i < nMaxLines) )
  975. {
  976. i++;
  977. aSize = ImplCalcSize( pThis, i );
  978. if ( mbHorz )
  979. nSize = aSize.Height();
  980. else
  981. nSize = aSize.Width();
  982. if ( nSize > nMaxSize )
  983. {
  984. i--;
  985. aSize = ImplCalcSize( pThis, i );
  986. if ( mbHorz )
  987. nSize = aSize.Height();
  988. else
  989. nSize = aSize.Width();
  990. break;
  991. }
  992. }
  993. }
  994. if ( nLineMode & DOCK_LINERIGHT )
  995. rRect.Right() = rRect.Left()+nSize-1;
  996. else if ( nLineMode & DOCK_LINEBOTTOM )
  997. rRect.Bottom() = rRect.Top()+nSize-1;
  998. else if ( nLineMode & DOCK_LINELEFT )
  999. rRect.Left() = rRect.Right()-nSize;
  1000. else
  1001. rRect.Top() = rRect.Bottom()-nSize;
  1002. pThis->mnDockLines = i;
  1003. }
  1004. // -----------------------------------------------------------------------
  1005. sal_uInt16 ToolBox::ImplFindItemPos( ToolBox* pBox, const Point& rPos )
  1006. {
  1007. sal_uInt16 nPos = 0;
  1008. long nLast = 0;
  1009. Point aPos = rPos;
  1010. Size aSize( pBox->mnDX, pBox->mnDY );
  1011. if ( aPos.X() > aSize.Width()-TB_BORDER_OFFSET1 )
  1012. aPos.X() = aSize.Width()-TB_BORDER_OFFSET1;
  1013. if ( aPos.Y() > aSize.Height()-TB_BORDER_OFFSET1 )
  1014. aPos.Y() = aSize.Height()-TB_BORDER_OFFSET1;
  1015. // Item suchen, das geklickt wurde
  1016. std::vector< ImplToolItem >::const_iterator it = pBox->mpData->m_aItems.begin();
  1017. while ( it != pBox->mpData->m_aItems.end() )
  1018. {
  1019. if ( it->mbVisible )
  1020. {
  1021. if ( nLast || !it->maRect.IsEmpty() )
  1022. {
  1023. if ( pBox->mbHorz )
  1024. {
  1025. if ( nLast &&
  1026. ((nLast < it->maRect.Top()) || it->maRect.IsEmpty()) )
  1027. return nPos;
  1028. if ( aPos.Y() <= it->maRect.Bottom() )
  1029. {
  1030. if ( aPos.X() < it->maRect.Left() )
  1031. return nPos;
  1032. else if ( aPos.X() < it->maRect.Right() )
  1033. return nPos+1;
  1034. else if ( !nLast )
  1035. nLast = it->maRect.Bottom();
  1036. }
  1037. }
  1038. else
  1039. {
  1040. if ( nLast &&
  1041. ((nLast < it->maRect.Left()) || it->maRect.IsEmpty()) )
  1042. return nPos;
  1043. if ( aPos.X() <= it->maRect.Right() )
  1044. {
  1045. if ( aPos.Y() < it->maRect.Top() )
  1046. return nPos;
  1047. else if ( aPos.Y() < it->maRect.Bottom() )
  1048. return nPos+1;
  1049. else if ( !nLast )
  1050. nLast = it->maRect.Right();
  1051. }
  1052. }
  1053. }
  1054. }
  1055. nPos++;
  1056. ++it;
  1057. }
  1058. return nPos;
  1059. }
  1060. // -----------------------------------------------------------------------
  1061. ImplTBDragMgr::ImplTBDragMgr()
  1062. {
  1063. mpBoxList = new ImplTBList();
  1064. mnLineMode = 0;
  1065. mnStartLines = 0;
  1066. mbCustomizeMode = sal_False;
  1067. mbResizeMode = sal_False;
  1068. mbShowDragRect = sal_False;
  1069. mpDragBox = NULL;
  1070. maAccel.InsertItem( KEY_RETURN, KeyCode( KEY_RETURN ) );
  1071. maAccel.InsertItem( KEY_ESCAPE, KeyCode( KEY_ESCAPE ) );
  1072. maAccel.SetSelectHdl( LINK( this, ImplTBDragMgr, SelectHdl ) );
  1073. }
  1074. // -----------------------------------------------------------------------
  1075. ImplTBDragMgr::~ImplTBDragMgr()
  1076. {
  1077. delete mpBoxList;
  1078. }
  1079. // -----------------------------------------------------------------------
  1080. ToolBox* ImplTBDragMgr::FindToolBox( const Rectangle& rRect )
  1081. {
  1082. for ( size_t i = 0, n = mpBoxList->size(); i < n; ++i )
  1083. {
  1084. ToolBox* pBox = (*mpBoxList)[ i ];
  1085. /*
  1086. * FIXME: since we can have multiple frames now we cannot
  1087. * find the drag target by its position alone.
  1088. * As long as the toolbar config dialogue is not a system window
  1089. * this works in one frame only anyway. If the dialogue
  1090. * changes to a system window, we need a new implementation here
  1091. */
  1092. if ( pBox->IsReallyVisible()
  1093. && pBox->ImplGetWindowImpl()->mpFrame == mpDragBox->ImplGetWindowImpl()->mpFrame
  1094. ) {
  1095. if ( !pBox->ImplIsFloatingMode() )
  1096. {
  1097. Point aPos = pBox->GetPosPixel();
  1098. aPos = pBox->GetParent()->OutputToScreenPixel( aPos );
  1099. Rectangle aTempRect( aPos, pBox->GetSizePixel() );
  1100. if ( aTempRect.IsOver( rRect ) )
  1101. return pBox;
  1102. }
  1103. }
  1104. }
  1105. return NULL;
  1106. }
  1107. // -----------------------------------------------------------------------
  1108. void ImplTBDragMgr::StartDragging( ToolBox* pToolBox,
  1109. const Point& rPos, const Rectangle& rRect,
  1110. sal_uInt16 nDragLineMode, sal_Bool bResizeItem,
  1111. void* pData )
  1112. {
  1113. mpDragBox = pToolBox;
  1114. pToolBox->CaptureMouse();
  1115. pToolBox->mbDragging = sal_True;
  1116. Application::InsertAccel( &maAccel );
  1117. if ( nDragLineMode )
  1118. {
  1119. mnLineMode = nDragLineMode;
  1120. mnStartLines = pToolBox->mnDockLines;
  1121. }
  1122. else
  1123. {
  1124. mpCustomizeData = pData;
  1125. mbResizeMode = bResizeItem;
  1126. pToolBox->Activate();
  1127. pToolBox->mnCurItemId = pToolBox->mnConfigItem;
  1128. pToolBox->Highlight();
  1129. pToolBox->mnCurItemId = 0;
  1130. if ( mbResizeMode )
  1131. {
  1132. if ( rRect.GetWidth() < TB_MIN_WIN_WIDTH )
  1133. mnMinWidth = rRect.GetWidth();
  1134. else
  1135. mnMinWidth = TB_MIN_WIN_WIDTH;
  1136. mnMaxWidth = pToolBox->GetSizePixel().Width()-rRect.Left()-
  1137. TB_SPIN_SIZE-TB_BORDER_OFFSET1-(TB_SPIN_OFFSET*2);
  1138. }
  1139. }
  1140. // MouseOffset berechnen
  1141. maMouseOff.X() = rRect.Left() - rPos.X();
  1142. maMouseOff.Y() = rRect.Top() - rPos.Y();
  1143. maRect = rRect;
  1144. maStartRect = rRect;
  1145. mbShowDragRect = sal_True;
  1146. pToolBox->ShowTracking( maRect );
  1147. }
  1148. // -----------------------------------------------------------------------
  1149. void ImplTBDragMgr::Dragging( const Point& rPos )
  1150. {
  1151. if ( mnLineMode )
  1152. {
  1153. ToolBox::ImplLineSizing( mpDragBox, rPos, maRect, mnLineMode );
  1154. Point aOff = mpDragBox->OutputToScreenPixel( Point() );
  1155. maRect.Move( aOff.X(), aOff.Y() );
  1156. mpDragBox->Docking( rPos, maRect );
  1157. maRect.Move( -aOff.X(), -aOff.Y() );
  1158. mpDragBox->ShowTracking( maRect );
  1159. }
  1160. else
  1161. {
  1162. if ( mbResizeMode )
  1163. {
  1164. long nXOff = rPos.X()-maStartRect.Left();
  1165. nXOff += maMouseOff.X()+(maStartRect.Right()-maStartRect.Left());
  1166. if ( nXOff < mnMinWidth )
  1167. nXOff = mnMinWidth;
  1168. if ( nXOff > mnMaxWidth )
  1169. nXOff = mnMaxWidth;
  1170. maRect.Right() = maStartRect.Left()+nXOff;
  1171. }
  1172. else
  1173. {
  1174. maRect.SetPos( rPos );
  1175. maRect.Move( maMouseOff.X(), maMouseOff.Y() );
  1176. }
  1177. mpDragBox->ShowTracking( maRect );
  1178. }
  1179. }
  1180. // -----------------------------------------------------------------------
  1181. void ImplTBDragMgr::EndDragging( sal_Bool bOK )
  1182. {
  1183. mpDragBox->HideTracking();
  1184. mpDragBox->ReleaseMouse();
  1185. mpDragBox->mbDragging = sal_False;
  1186. mbShowDragRect = sal_False;
  1187. Application::RemoveAccel( &maAccel );
  1188. if ( mnLineMode )
  1189. {
  1190. if ( !bOK )
  1191. {
  1192. mpDragBox->mnDockLines = mnStartLines;
  1193. mpDragBox->EndDocking( maStartRect, sal_False );
  1194. }
  1195. else
  1196. mpDragBox->EndDocking( maRect, sal_False );
  1197. mnLineMode = 0;
  1198. mnStartLines = 0;
  1199. }
  1200. else
  1201. {
  1202. sal_uInt16 nTempItem = mpDragBox->mnConfigItem;
  1203. if ( nTempItem )
  1204. {
  1205. mpDragBox->mnConfigItem = 0;
  1206. if ( !mbResizeMode )
  1207. mpDragBox->Invalidate( mpDragBox->GetItemRect( nTempItem ) );
  1208. }
  1209. if ( bOK && (maRect != maStartRect) )
  1210. {
  1211. if ( mbResizeMode )
  1212. {
  1213. ImplToolItem* pItem = mpDragBox->ImplGetItem( nTempItem );
  1214. Size aSize = pItem->mpWindow->GetSizePixel();
  1215. aSize.Width() = maRect.GetWidth();
  1216. pItem->mpWindow->SetSizePixel( aSize );
  1217. // re-calculate and show ToolBox
  1218. mpDragBox->ImplInvalidate( sal_True );
  1219. mpDragBox->Customize( ToolBoxCustomizeEvent( mpDragBox, nTempItem,
  1220. TOOLBOX_CUSTOMIZE_RESIZE,
  1221. mpCustomizeData ) );
  1222. }
  1223. else
  1224. {
  1225. Point aOff = mpDragBox->OutputToScreenPixel( Point() );
  1226. Rectangle aScreenRect( maRect );
  1227. aScreenRect.Move( aOff.X(), aOff.Y() );
  1228. ToolBox* pDropBox = FindToolBox( aScreenRect );
  1229. if ( pDropBox )
  1230. {
  1231. // Determine search position
  1232. Point aPos;
  1233. if ( pDropBox->mbHorz )
  1234. {
  1235. aPos.X() = aScreenRect.Left()-TB_CUSTOMIZE_OFFSET;
  1236. aPos.Y() = aScreenRect.Center().Y();
  1237. }
  1238. else
  1239. {
  1240. aPos.X() = aScreenRect.Center().X();
  1241. aPos.Y() = aScreenRect.Top()-TB_CUSTOMIZE_OFFSET;
  1242. }
  1243. aPos = pDropBox->ScreenToOutputPixel( aPos );
  1244. sal_uInt16 nPos = ToolBox::ImplFindItemPos( pDropBox, aPos );
  1245. mpDragBox->Customize( ToolBoxCustomizeEvent( pDropBox, nTempItem,
  1246. nPos, mpCustomizeData ) );
  1247. }
  1248. else
  1249. {
  1250. mpDragBox->Customize( ToolBoxCustomizeEvent( NULL, nTempItem,
  1251. 0, mpCustomizeData ) );
  1252. }
  1253. }
  1254. }
  1255. mpCustomizeData = NULL;
  1256. mbResizeMode = sal_False;
  1257. mpDragBox->Deactivate();
  1258. }
  1259. mpDragBox = NULL;
  1260. }
  1261. // -----------------------------------------------------------------------
  1262. void ImplTBDragMgr::UpdateDragRect()
  1263. {
  1264. // Only update if we're already dragging
  1265. if ( !mbShowDragRect )
  1266. return;
  1267. mpDragBox->ShowTracking( maRect );
  1268. }
  1269. // -----------------------------------------------------------------------
  1270. IMPL_LINK( ImplTBDragMgr, SelectHdl, Accelerator*, pAccel )
  1271. {
  1272. if ( pAccel->GetCurItemId() == KEY_ESCAPE )
  1273. EndDragging( sal_False );
  1274. else
  1275. EndDragging( sal_True );

Large files files are truncated, but you can click here to view the full file