1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: toolbox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
37 #include <rtl/logfile.hxx>
38 #include <tools/list.hxx>
39 #include <tools/debug.hxx>
44 #include <vcl/svdata.hxx>
45 #include <vcl/event.hxx>
46 #include <vcl/decoview.hxx>
47 #include <vcl/accel.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/help.hxx>
50 #include <vcl/sound.hxx>
51 #include <vcl/virdev.hxx>
53 #include <vcl/toolbox.hxx>
54 #include <vcl/toolbox.h>
55 #include <vcl/bitmap.hxx>
56 #include <tools/poly.hxx>
57 #include <vcl/salframe.hxx>
58 #include <vcl/mnemonic.hxx>
59 #include <vcl/gradient.hxx>
60 #include <vcl/menu.hxx>
61 #include <vcl/window.h>
67 // =======================================================================
71 // =======================================================================
73 #define SMALLBUTTON_HSIZE 7
74 #define SMALLBUTTON_VSIZE 7
76 #define SMALLBUTTON_OFF_NORMAL_X 3
77 #define SMALLBUTTON_OFF_NORMAL_Y 3
78 #define SMALLBUTTON_OFF_CHECKED_X 4
79 #define SMALLBUTTON_OFF_CHECKED_Y 4
80 #define SMALLBUTTON_OFF_PRESSED_X 5
81 #define SMALLBUTTON_OFF_PRESSED_Y 5
83 #define OUTBUTTON_SIZE 6
84 #define OUTBUTTON_BORDER 4
85 #define OUTBUTTON_OFF_NORMAL_X 1
86 #define OUTBUTTON_OFF_NORMAL_Y 1
88 // -----------------------------------------------------------------------
90 #define DEF_MIN_WIDTH 8
91 #define DEF_MIN_HEIGHT 8
92 #define DEF_TEXT_WIDTH 40
94 #define TB_TEXTOFFSET 2
95 #define TB_IMAGETEXTOFFSET 3
96 #define TB_LINESPACING 3
97 #define TB_SPIN_SIZE 14
98 #define TB_SPIN_OFFSET 2
99 #define TB_NEXT_SIZE 22
100 #define TB_NEXT_OFFSET 2
101 #define TB_BORDER_OFFSET1 4
102 #define TB_BORDER_OFFSET2 2
103 #define TB_CUSTOMIZE_OFFSET 2
104 #define TB_RESIZE_OFFSET 3
105 #define TB_MAXLINES 5
106 #define TB_MAXNOSCROLL 32765
108 #define TB_MIN_WIN_WIDTH 20
110 #define TB_CALCMODE_HORZ 1
111 #define TB_CALCMODE_VERT 2
112 #define TB_CALCMODE_FLOAT 3
114 #define TB_WBLINESIZING (WB_SIZEABLE | WB_DOCKABLE | WB_SCROLL)
116 #define TB_MAX_GROUPS 100
118 #define DOCK_LINEHSIZE ((USHORT)0x0001)
119 #define DOCK_LINEVSIZE ((USHORT)0x0002)
120 #define DOCK_LINERIGHT ((USHORT)0x1000)
121 #define DOCK_LINEBOTTOM ((USHORT)0x2000)
122 #define DOCK_LINELEFT ((USHORT)0x4000)
123 #define DOCK_LINETOP ((USHORT)0x8000)
124 #define DOCK_LINEOFFSET 3
127 // -----------------------------------------------------------------------
128 static void ImplDrawButton( ToolBox
* pThis
, const Rectangle
&rRect
, USHORT highlight
, BOOL bChecked
, BOOL bEnabled
, BOOL bIsWindow
);
129 // -----------------------------------------------------------------------
138 struct ImplToolSizeArray
142 ImplToolSize
* mpSize
;
144 ImplToolSizeArray() { mpSize
= NULL
; mnLength
= 0; mnLastEntry
= 0; }
145 ~ImplToolSizeArray() { if( mpSize
) delete [] mpSize
; mnLength
= 0; }
148 // -----------------------------------------------------------------------
150 DECLARE_LIST( ImplTBList
, ToolBox
* )
155 ImplTBList
* mpBoxList
;
159 Rectangle maStartRect
;
165 void* mpCustomizeData
;
166 BOOL mbCustomizeMode
;
174 void Insert( ToolBox
* pBox
)
175 { mpBoxList
->Insert( pBox
); }
176 void Remove( ToolBox
* pBox
)
177 { mpBoxList
->Remove( pBox
); }
179 { return mpBoxList
->Count(); }
181 ToolBox
* FindToolBox( const Rectangle
& rRect
);
183 void StartDragging( ToolBox
* pDragBox
,
184 const Point
& rPos
, const Rectangle
& rRect
,
185 USHORT nLineMode
, BOOL bResizeItem
,
186 void* pData
= NULL
);
187 void Dragging( const Point
& rPos
);
188 void EndDragging( BOOL bOK
= TRUE
);
189 void HideDragRect() { if ( mbShowDragRect
) mpDragBox
->HideTracking(); }
190 void UpdateDragRect();
191 DECL_LINK( SelectHdl
, Accelerator
* );
193 void StartCustomizeMode();
194 void EndCustomizeMode();
195 BOOL
IsCustomizeMode() { return mbCustomizeMode
; }
196 BOOL
IsResizeMode() { return mbResizeMode
; }
199 // -----------------------------------------------------------------------
201 static ImplTBDragMgr
* ImplGetTBDragMgr()
203 ImplSVData
* pSVData
= ImplGetSVData();
204 if ( !pSVData
->maCtrlData
.mpTBDragMgr
)
205 pSVData
->maCtrlData
.mpTBDragMgr
= new ImplTBDragMgr
;
206 return pSVData
->maCtrlData
.mpTBDragMgr
;
209 // -----------------------------------------------------------------------
211 int ToolBox::ImplGetDragWidth( ToolBox
* pThis
)
213 #define TB_DRAGWIDTH 8 // the default width of the grip
215 int width
= TB_DRAGWIDTH
;
216 if( pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) )
219 ImplControlValue aControlValue
;
221 Region aContent
, aBound
;
222 Region
aArea( Rectangle(aPoint
, pThis
->GetOutputSizePixel()) );
224 if ( pThis
->GetNativeControlRegion(CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_VERT
: PART_THUMB_HORZ
,
225 aArea
, 0, aControlValue
, rtl::OUString(), aBound
, aContent
) )
227 width
= pThis
->mbHorz
? aContent
.GetBoundRect().GetWidth() : aContent
.GetBoundRect().GetHeight();
233 ButtonType
determineButtonType( ImplToolItem
* pItem
, ButtonType defaultType
)
235 ButtonType tmpButtonType
= defaultType
;
236 ToolBoxItemBits
nBits( pItem
->mnBits
& 0x300 );
237 if ( nBits
& TIB_TEXTICON
) // item has custom setting
239 tmpButtonType
= BUTTON_SYMBOLTEXT
;
240 if ( nBits
== TIB_TEXT_ONLY
)
241 tmpButtonType
= BUTTON_TEXT
;
242 else if ( nBits
== TIB_ICON_ONLY
)
243 tmpButtonType
= BUTTON_SYMBOL
;
245 return tmpButtonType
;
248 // -----------------------------------------------------------------------
250 void ToolBox::ImplUpdateDragArea( ToolBox
*pThis
)
252 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
255 if ( pThis
->ImplIsFloatingMode() || pWrapper
->IsLocked() )
256 pWrapper
->SetDragArea( Rectangle() );
259 if( pThis
->meAlign
== WINDOWALIGN_TOP
|| pThis
->meAlign
== WINDOWALIGN_BOTTOM
)
260 pWrapper
->SetDragArea( Rectangle( 0, 0, ImplGetDragWidth( pThis
), pThis
->GetOutputSizePixel().Height() ) );
262 pWrapper
->SetDragArea( Rectangle( 0, 0, pThis
->GetOutputSizePixel().Width(), ImplGetDragWidth( pThis
) ) );
267 // -----------------------------------------------------------------------
269 void ToolBox::ImplCalcBorder( WindowAlign eAlign
, long& rLeft
, long& rTop
,
270 long& rRight
, long& rBottom
, const ToolBox
*pThis
)
272 if( pThis
->ImplIsFloatingMode() || !(pThis
->mnWinStyle
& WB_BORDER
) )
274 // no border in floating mode
275 rLeft
= rTop
= rRight
= rBottom
= 0;
279 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
281 // reserve dragarea only for dockable toolbars
282 int dragwidth
= ( pWrapper
&& !pWrapper
->IsLocked() ) ? ImplGetDragWidth( (ToolBox
*)pThis
) : 0;
284 // no shadow border for dockable toolbars
285 int borderwidth
= pWrapper
? 0: 2;
287 if ( eAlign
== WINDOWALIGN_TOP
)
289 rLeft
= borderwidth
+dragwidth
;
291 rRight
= borderwidth
;
294 else if ( eAlign
== WINDOWALIGN_LEFT
)
297 rTop
= borderwidth
+dragwidth
;
299 rBottom
= borderwidth
;
301 else if ( eAlign
== WINDOWALIGN_BOTTOM
)
303 rLeft
= borderwidth
+dragwidth
;
305 rRight
= borderwidth
;
306 rBottom
= borderwidth
;
311 rTop
= borderwidth
+dragwidth
;
312 rRight
= borderwidth
;
313 rBottom
= borderwidth
;
317 // -----------------------------------------------------------------------
319 static void ImplCheckUpdate( ToolBox
*pThis
)
321 // remove any pending invalidates to avoid
322 // have them triggered when paint is locked (see mpData->mbIsPaintLocked)
323 // which would result in erasing the background only and not painting any items
324 // this must not be done when we're already in Paint()
326 // this is only required for transparent toolbars (see ImplDrawTransparentBackground() )
327 if( !pThis
->IsBackground() && pThis
->HasPaintEvent() && !pThis
->IsInPaint() )
331 // -----------------------------------------------------------------------
333 void ToolBox::ImplDrawGrip( ToolBox
* pThis
)
335 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
336 if( pWrapper
&& !pWrapper
->GetDragArea().IsEmpty() )
338 // execute pending paint requests
339 ImplCheckUpdate( pThis
);
341 BOOL bNativeOk
= FALSE
;
342 if( pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_HORZ
: PART_THUMB_VERT
) )
344 ImplControlValue aControlValue
;
345 ToolbarValue aToolbarValue
;
346 aToolbarValue
.maGripRect
= pWrapper
->GetDragArea();
347 aControlValue
.setOptionalVal( (void *)(&aToolbarValue
) );
349 Region
aCtrlRegion( Rectangle( aPt
, pThis
->GetOutputSizePixel() ) );
350 ControlState nState
= CTRL_STATE_ENABLED
;
352 bNativeOk
= pThis
->DrawNativeControl( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_THUMB_VERT
: PART_THUMB_HORZ
,
353 aCtrlRegion
, nState
, aControlValue
, rtl::OUString() );
359 const StyleSettings
& rStyleSettings
= pThis
->GetSettings().GetStyleSettings();
360 pThis
->SetLineColor( rStyleSettings
.GetShadowColor() );
362 Size
aSz ( pThis
->GetOutputSizePixel() );
364 if ( pThis
->meAlign
== WINDOWALIGN_TOP
|| pThis
->meAlign
== WINDOWALIGN_BOTTOM
)
366 int height
= (int) (0.6 * aSz
.Height() + 0.5);
367 int i
= (aSz
.Height() - height
) / 2;
371 int x
= ImplGetDragWidth( pThis
) / 2;
373 pThis
->DrawPixel( Point(x
, i
), rStyleSettings
.GetDarkShadowColor() );
374 pThis
->DrawPixel( Point(x
+1, i
), rStyleSettings
.GetShadowColor() );
376 pThis
->DrawPixel( Point(x
, i
+1), rStyleSettings
.GetShadowColor() );
377 pThis
->DrawPixel( Point(x
+1, i
+1), rStyleSettings
.GetFaceColor() );
378 pThis
->DrawPixel( Point(x
+2, i
+1), Color(COL_WHITE
) );
380 pThis
->DrawPixel( Point(x
+1, i
+2), Color(COL_WHITE
) );
381 pThis
->DrawPixel( Point(x
+2, i
+2), Color(COL_WHITE
) );
387 int width
= (int) (0.6 * aSz
.Width() + 0.5);
388 int i
= (aSz
.Width() - width
) / 2;
392 int y
= ImplGetDragWidth(pThis
) / 2;
394 pThis
->DrawPixel( Point(i
, y
), rStyleSettings
.GetDarkShadowColor() );
395 pThis
->DrawPixel( Point(i
+1, y
), rStyleSettings
.GetShadowColor() );
397 pThis
->DrawPixel( Point(i
, y
+1), rStyleSettings
.GetShadowColor() );
398 pThis
->DrawPixel( Point(i
+1, y
+1), rStyleSettings
.GetFaceColor() );
399 pThis
->DrawPixel( Point(i
+2, y
+1), Color(COL_WHITE
) );
401 pThis
->DrawPixel( Point(i
+1, y
+2), Color(COL_WHITE
) );
402 pThis
->DrawPixel( Point(i
+2, y
+2), Color(COL_WHITE
) );
409 void ToolBox::ImplDrawGradientBackground( ToolBox
* pThis
, ImplDockingWindowWrapper
* )
411 // draw a nice gradient
413 Color startCol
, endCol
;
414 startCol
= pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor();
415 endCol
= pThis
->GetSettings().GetStyleSettings().GetFaceColor();
416 if( endCol
.IsDark() )
417 // no 'extreme' gradient when high contrast
421 g
.SetAngle( pThis
->mbHorz
? 0 : 900 );
422 g
.SetStyle( GRADIENT_LINEAR
);
424 g
.SetStartColor( startCol
);
425 g
.SetEndColor( endCol
);
427 BOOL bLineColor
= pThis
->IsLineColor();
428 Color aOldCol
= pThis
->GetLineColor();
429 pThis
->SetLineColor( pThis
->GetSettings().GetStyleSettings().GetShadowColor() );
431 Size
aFullSz( pThis
->GetOutputSizePixel() );
432 Size
aLineSz( aFullSz
);
434 // use the linesize only when floating
435 // full window height is used when docked (single line)
436 if( pThis
->ImplIsFloatingMode() )
441 nLineSize
= pThis
->mnMaxItemHeight
;
442 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
443 nLineSize
= pThis
->mnWinHeight
;
445 aLineSz
.Height() = nLineSize
;
449 nLineSize
= pThis
->mnMaxItemWidth
;
450 aLineSz
.Width() = nLineSize
;
454 long nLeft
, nTop
, nRight
, nBottom
;
455 ImplCalcBorder( pThis
->meAlign
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
457 Size
aTopLineSz( aLineSz
);
458 Size
aBottomLineSz( aLineSz
);
460 if ( pThis
->mnWinStyle
& WB_BORDER
)
464 aTopLineSz
.Height() += TB_BORDER_OFFSET2
+ nTop
;
465 aBottomLineSz
.Height() += TB_BORDER_OFFSET2
+ nBottom
;
467 if( pThis
->mnCurLines
== 1 )
468 aTopLineSz
.Height() += TB_BORDER_OFFSET2
+ nBottom
;
472 aTopLineSz
.Width() += TB_BORDER_OFFSET1
+ nLeft
;
473 aBottomLineSz
.Width() += TB_BORDER_OFFSET1
+ nRight
;
475 if( pThis
->mnCurLines
== 1 )
476 aTopLineSz
.Width() += TB_BORDER_OFFSET1
+ nLeft
;
482 aTopLineSz
.Height() += pThis
->mnBorderY
;
483 if( pThis
->mnCurLines
== 1 )
484 aTopLineSz
.Height() += pThis
->mnBorderY
;
486 aBottomLineSz
.Height() += pThis
->mnBorderY
;
490 aTopLineSz
.Width() += pThis
->mnBorderX
;
491 if( pThis
->mnCurLines
== 1 )
492 aTopLineSz
.Width() += pThis
->mnBorderX
;
494 aBottomLineSz
.Width() += pThis
->mnBorderX
;
498 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
502 aLineSz
.Height() += TB_LINESPACING
;
503 if( pThis
->mnCurLines
> 1 )
504 aTopLineSz
.Height() += TB_LINESPACING
;
508 aLineSz
.Width() += TB_LINESPACING
;
509 if( pThis
->mnCurLines
> 1 )
510 aTopLineSz
.Width() += TB_LINESPACING
;
517 BOOL bDrawSep
= FALSE
; // pThis->ImplIsFloatingMode() && ( pThis->mnWinStyle & WB_LINESPACING );
519 pThis
->DrawGradient( Rectangle( 0, y
, aTopLineSz
.Width(), y
+aTopLineSz
.Height()), g
);
520 y
+= aTopLineSz
.Height();
523 pThis
->DrawLine( Point(0, y
-2), Point(aTopLineSz
.Width(), y
-2) );
525 while( y
< (pThis
->mnDY
- aBottomLineSz
.Height()) )
527 pThis
->DrawGradient( Rectangle( 0, y
, aLineSz
.Width(), y
+aLineSz
.Height()), g
);
528 y
+= aLineSz
.Height();
531 pThis
->DrawLine( Point(0, y
-2), Point(aLineSz
.Width(), y
-2) );
534 pThis
->DrawGradient( Rectangle( 0, y
, aBottomLineSz
.Width(), y
+aBottomLineSz
.Height()), g
);
536 pThis
->DrawLine( Point(0, y
-2), Point(aBottomLineSz
.Width(), y
-2) );
542 pThis
->DrawGradient( Rectangle( x
, 0, x
+aTopLineSz
.Width(), aTopLineSz
.Height()), g
);
543 x
+= aTopLineSz
.Width();
545 while( x
< (pThis
->mnDX
- aBottomLineSz
.Width()) )
547 pThis
->DrawGradient( Rectangle( x
, 0, x
+aLineSz
.Width(), aLineSz
.Height()), g
);
548 x
+= aLineSz
.Width();
551 pThis
->DrawGradient( Rectangle( x
, 0, x
+aBottomLineSz
.Width(), aBottomLineSz
.Height()), g
);
555 pThis
->SetLineColor( aOldCol
);
559 BOOL
ToolBox::ImplDrawNativeBackground( ToolBox
* pThis
, const Region
& )
563 Region
aCtrlRegion( Rectangle( aPt
, pThis
->GetOutputSizePixel() ) );
564 ControlState nState
= CTRL_STATE_ENABLED
;
566 return pThis
->DrawNativeControl( CTRL_TOOLBAR
, pThis
->mbHorz
? PART_DRAW_BACKGROUND_HORZ
: PART_DRAW_BACKGROUND_VERT
,
567 aCtrlRegion
, nState
, ImplControlValue(), rtl::OUString() );
570 void ToolBox::ImplDrawTransparentBackground( ToolBox
* pThis
, const Region
&rRegion
)
572 // just invalidate to trigger paint of the parent
574 const bool bOldPaintLock
= pThis
->mpData
->mbIsPaintLocked
;
575 pThis
->mpData
->mbIsPaintLocked
= true;
577 // send an invalidate to the first opaque parent and invalidate the whole hierarchy from there (noclipchildren)
578 pThis
->Invalidate( rRegion
, INVALIDATE_UPDATE
|INVALIDATE_NOCLIPCHILDREN
);
580 pThis
->mpData
->mbIsPaintLocked
= bOldPaintLock
;
583 void ToolBox::ImplDrawConstantBackground( ToolBox
* pThis
, const Region
&rRegion
, BOOL bIsInPopupMode
)
585 // draw a constant color
586 if( !bIsInPopupMode
)
587 // default background
588 pThis
->Erase( rRegion
.GetBoundRect() );
591 // use different color in popupmode
592 pThis
->DrawWallpaper( rRegion
.GetBoundRect(),
593 Wallpaper( pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor() ) );
598 void ToolBox::ImplDrawBackground( ToolBox
* pThis
, const Rectangle
&rRect
)
600 // execute pending paint requests
601 ImplCheckUpdate( pThis
);
603 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
604 BOOL bIsInPopupMode
= pThis
->ImplIsInPopupMode();
606 Region
aPaintRegion( rRect
);
608 // make sure we do not invalidate/erase too much
609 if( pThis
->IsInPaint() )
610 aPaintRegion
.Intersect( pThis
->GetActiveClipRegion() );
612 pThis
->Push( PUSH_CLIPREGION
);
613 pThis
->IntersectClipRegion( aPaintRegion
);
616 if( !pWrapper
/*|| bIsInPopupMode*/ )
618 // no gradient for ordinary toolbars (not dockable)
619 if( !pThis
->IsBackground() && !pThis
->IsInPaint() )
620 ImplDrawTransparentBackground( pThis
, aPaintRegion
);
622 ImplDrawConstantBackground( pThis
, aPaintRegion
, bIsInPopupMode
);
626 // toolbars known to the dockingmanager will be drawn using NWF or a gradient
627 // docked toolbars are transparent and NWF is already used in the docking area which is their common background
628 // so NWF is used here for floating toolbars only
629 BOOL bNativeOk
= FALSE
;
630 if( pThis
->ImplIsFloatingMode() && pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) )
631 bNativeOk
= ImplDrawNativeBackground( pThis
, aPaintRegion
);
635 if( !pThis
->IsBackground() )
637 if( !pThis
->IsInPaint() )
638 ImplDrawTransparentBackground( pThis
, aPaintRegion
);
641 ImplDrawGradientBackground( pThis
, pWrapper
);
645 // restore clip region
649 void ToolBox::ImplErase( ToolBox
* pThis
, const Rectangle
&rRect
, BOOL bHighlight
, BOOL bHasOpenPopup
)
651 // the background of non NWF buttons is painted in a constant color
652 // to have the same highlight color (transparency in DrawSelectionBackground())
653 // items with open popups will also painted using a constant color
654 if( !pThis
->mpData
->mbNativeButtons
&&
655 (bHighlight
|| ! (((Window
*) pThis
)->GetStyle() & WB_3DLOOK
) ) )
657 if( (((Window
*) pThis
)->GetStyle() & WB_3DLOOK
) )
659 pThis
->Push( PUSH_LINECOLOR
| PUSH_FILLCOLOR
);
660 pThis
->SetLineColor();
662 // choose the same color as the popup will use
663 pThis
->SetFillColor( pThis
->GetSettings().GetStyleSettings().GetFaceGradientColor() );
665 pThis
->SetFillColor( Color( COL_WHITE
) );
667 pThis
->DrawRect( rRect
);
671 ImplDrawBackground( pThis
, rRect
);
674 ImplDrawBackground( pThis
, rRect
);
677 void ToolBox::ImplDrawBorder( ToolBox
* pWin
)
679 const StyleSettings
& rStyleSettings
= pWin
->GetSettings().GetStyleSettings();
680 long nDX
= pWin
->mnDX
;
681 long nDY
= pWin
->mnDY
;
683 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pWin
);
685 // draw borders for ordinary toolbars only (not dockable)
689 if ( pWin
->meAlign
== WINDOWALIGN_BOTTOM
)
691 // draw bottom border
692 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
693 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-1, nDY
-2 ) );
694 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
695 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
700 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
701 pWin
->DrawLine( Point( 0, 0 ), Point( nDX
-1, 0 ) );
702 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
703 pWin
->DrawLine( Point( 0, 1 ), Point( nDX
-1, 1 ) );
705 if ( (pWin
->meAlign
== WINDOWALIGN_LEFT
) || (pWin
->meAlign
== WINDOWALIGN_RIGHT
) )
707 if ( pWin
->meAlign
== WINDOWALIGN_LEFT
)
709 // draw left-bottom border
710 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
711 pWin
->DrawLine( Point( 0, 0 ), Point( 0, nDY
-1 ) );
712 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-1, nDY
-2 ) );
713 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
714 pWin
->DrawLine( Point( 1, 1 ), Point( 1, nDY
-3 ) );
715 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
719 // draw right-bottom border
720 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
721 pWin
->DrawLine( Point( nDX
-2, 0 ), Point( nDX
-2, nDY
-3 ) );
722 pWin
->DrawLine( Point( 0, nDY
-2 ), Point( nDX
-2, nDY
-2 ) );
723 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
724 pWin
->DrawLine( Point( nDX
-1, 0 ), Point( nDX
-1, nDY
-1 ) );
725 pWin
->DrawLine( Point( 0, nDY
-1 ), Point( nDX
-1, nDY
-1 ) );
731 if ( pWin
->meAlign
== WINDOWALIGN_BOTTOM
|| pWin
->meAlign
== WINDOWALIGN_TOP
)
734 pWin
->SetLineColor( rStyleSettings
.GetShadowColor() );
735 pWin
->DrawLine( Point( nDX
-2, 0 ), Point( nDX
-2, nDY
-1 ) );
736 pWin
->SetLineColor( rStyleSettings
.GetLightColor() );
737 pWin
->DrawLine( Point( nDX
-1, 0 ), Point( nDX
-1, nDY
-1 ) );
741 // -----------------------------------------------------------------------
743 static bool ImplIsFixedControl( const ImplToolItem
*pItem
)
745 return ( pItem
->mpWindow
&&
746 (pItem
->mpWindow
->GetType() == WINDOW_FIXEDTEXT
||
747 pItem
->mpWindow
->GetType() == WINDOW_FIXEDLINE
||
748 pItem
->mpWindow
->GetType() == WINDOW_GROUPBOX
) );
751 // -----------------------------------------------------------------------
753 const ImplToolItem
*ToolBox::ImplGetFirstClippedItem( const ToolBox
* pThis
)
755 std::vector
< ImplToolItem
>::const_iterator it
;
756 it
= pThis
->mpData
->m_aItems
.begin();
757 while ( it
!= pThis
->mpData
->m_aItems
.end() )
759 if( it
->IsClipped() )
766 // -----------------------------------------------------------------------
768 Size
ToolBox::ImplCalcSize( const ToolBox
* pThis
, USHORT nCalcLines
, USHORT nCalcMode
)
776 WindowAlign eOldAlign
= pThis
->meAlign
;
777 BOOL bOldHorz
= pThis
->mbHorz
;
778 BOOL bOldAssumeDocked
= pThis
->mpData
->mbAssumeDocked
;
779 BOOL bOldAssumeFloating
= pThis
->mpData
->mbAssumeFloating
;
783 BOOL bOldFloatingMode
= pThis
->ImplIsFloatingMode();
785 pThis
->mpData
->mbAssumeDocked
= FALSE
;
786 pThis
->mpData
->mbAssumeFloating
= FALSE
;
788 if ( nCalcMode
== TB_CALCMODE_HORZ
)
790 pThis
->mpData
->mbAssumeDocked
= TRUE
; // force non-floating mode during calculation
791 ImplCalcBorder( WINDOWALIGN_TOP
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
792 ((ToolBox
*)pThis
)->mbHorz
= TRUE
;
793 if ( pThis
->mbHorz
!= bOldHorz
)
794 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_TOP
;
796 else if ( nCalcMode
== TB_CALCMODE_VERT
)
798 pThis
->mpData
->mbAssumeDocked
= TRUE
; // force non-floating mode during calculation
799 ImplCalcBorder( WINDOWALIGN_LEFT
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
800 ((ToolBox
*)pThis
)->mbHorz
= FALSE
;
801 if ( pThis
->mbHorz
!= bOldHorz
)
802 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_LEFT
;
804 else if ( nCalcMode
== TB_CALCMODE_FLOAT
)
806 pThis
->mpData
->mbAssumeFloating
= TRUE
; // force non-floating mode during calculation
807 nLeft
= nTop
= nRight
= nBottom
= 0;
808 ((ToolBox
*)pThis
)->mbHorz
= TRUE
;
809 if ( pThis
->mbHorz
!= bOldHorz
)
810 ((ToolBox
*)pThis
)->meAlign
= WINDOWALIGN_TOP
;
813 if ( (pThis
->meAlign
!= eOldAlign
) || (pThis
->mbHorz
!= bOldHorz
) ||
814 (pThis
->ImplIsFloatingMode() != bOldFloatingMode
) )
815 ((ToolBox
*)pThis
)->mbCalc
= TRUE
;
818 ImplCalcBorder( pThis
->meAlign
, nLeft
, nTop
, nRight
, nBottom
, pThis
);
820 ((ToolBox
*)pThis
)->ImplCalcItem();
822 if( !nCalcMode
&& pThis
->ImplIsFloatingMode() )
824 aSize
= ImplCalcFloatSize( ((ToolBox
*)pThis
), nCalcLines
);
830 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
831 aSize
.Height() = nCalcLines
* pThis
->mnWinHeight
;
833 aSize
.Height() = nCalcLines
* pThis
->mnMaxItemHeight
;
835 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
836 aSize
.Height() += (nCalcLines
-1)*TB_LINESPACING
;
838 if ( pThis
->mnWinStyle
& WB_BORDER
)
839 aSize
.Height() += (TB_BORDER_OFFSET2
*2) + nTop
+ nBottom
;
842 ((ToolBox
*)pThis
)->ImplCalcBreaks( TB_MAXNOSCROLL
, &nMax
, pThis
->mbHorz
);
844 aSize
.Width() += nMax
;
846 if ( pThis
->mnWinStyle
& WB_BORDER
)
847 aSize
.Width() += (TB_BORDER_OFFSET1
*2) + nLeft
+ nRight
;
851 aSize
.Width() = nCalcLines
* pThis
->mnMaxItemWidth
;
853 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
854 aSize
.Width() += (nCalcLines
-1)*TB_LINESPACING
;
856 if ( pThis
->mnWinStyle
& WB_BORDER
)
857 aSize
.Width() += (TB_BORDER_OFFSET2
*2) + nLeft
+ nRight
;
860 ((ToolBox
*)pThis
)->ImplCalcBreaks( TB_MAXNOSCROLL
, &nMax
, pThis
->mbHorz
);
862 aSize
.Height() += nMax
;
864 if ( pThis
->mnWinStyle
& WB_BORDER
)
865 aSize
.Height() += (TB_BORDER_OFFSET1
*2) + nTop
+ nBottom
;
868 // restore previous values
871 pThis
->mpData
->mbAssumeDocked
= bOldAssumeDocked
;
872 pThis
->mpData
->mbAssumeFloating
= bOldAssumeFloating
;
873 if ( (pThis
->meAlign
!= eOldAlign
) || (pThis
->mbHorz
!= bOldHorz
) )
875 ((ToolBox
*)pThis
)->meAlign
= eOldAlign
;
876 ((ToolBox
*)pThis
)->mbHorz
= bOldHorz
;
877 ((ToolBox
*)pThis
)->mbCalc
= TRUE
;
882 aSize
.Width() += pThis
->mnBorderX
*2;
883 if ( aSize
.Height() )
884 aSize
.Height() += pThis
->mnBorderY
*2;
889 // -----------------------------------------------------------------------
891 void ToolBox::ImplCalcFloatSizes( ToolBox
* pThis
)
893 if ( pThis
->mpFloatSizeAry
)
896 // calculate the minimal size, i.e. where the biggest item just fits
899 std::vector
< ImplToolItem
>::const_iterator it
;
900 it
= pThis
->mpData
->m_aItems
.begin();
901 while ( it
!= pThis
->mpData
->m_aItems
.end() )
907 long nTempSize
= it
->mpWindow
->GetSizePixel().Width();
908 if ( nTempSize
> nCalcSize
)
909 nCalcSize
= nTempSize
;
913 if( it
->maItemSize
.Width() > nCalcSize
)
914 nCalcSize
= it
->maItemSize
.Width();
920 // calc an upper bound for ImplCalcBreaks below
921 long upperBoundWidth
= nCalcSize
* pThis
->mpData
->m_aItems
.size();
929 nCalcLines
= pThis
->ImplCalcBreaks( nCalcSize
, &nMaxLineWidth
, TRUE
);
931 pThis
->mpFloatSizeAry
= new ImplToolSizeArray
;
932 pThis
->mpFloatSizeAry
->mpSize
= new ImplToolSize
[nCalcLines
];
933 pThis
->mpFloatSizeAry
->mnLength
= nCalcLines
;
935 memset( pThis
->mpFloatSizeAry
->mpSize
, 0, sizeof( ImplToolSize
)*nCalcLines
);
937 nTempLines
= nLines
= nCalcLines
;
940 nHeight
= ImplCalcSize( pThis
, nTempLines
, TB_CALCMODE_FLOAT
).Height();
941 pThis
->mpFloatSizeAry
->mnLastEntry
= i
;
942 pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
= nHeight
;
943 pThis
->mpFloatSizeAry
->mpSize
[i
].mnLines
= nTempLines
;
944 pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
= nMaxLineWidth
+(TB_BORDER_OFFSET1
*2);
950 nCalcSize
+= pThis
->mnMaxItemWidth
;
951 nTempLines
= pThis
->ImplCalcBreaks( nCalcSize
, &nMaxLineWidth
, TRUE
);
953 while ( (nCalcSize
< upperBoundWidth
) && (nLines
< nTempLines
) && (nTempLines
!= 1) );
954 if ( nTempLines
< nLines
)
961 // -----------------------------------------------------------------------
963 Size
ToolBox::ImplCalcFloatSize( ToolBox
* pThis
, USHORT
& rLines
)
965 ImplCalcFloatSizes( pThis
);
969 rLines
= pThis
->mnFloatLines
;
971 rLines
= pThis
->mnLines
;
975 while ( i
< pThis
->mpFloatSizeAry
->mnLastEntry
&&
976 rLines
< pThis
->mpFloatSizeAry
->mpSize
[i
].mnLines
)
979 Size
aSize( pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
,
980 pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
);
981 rLines
= pThis
->mpFloatSizeAry
->mpSize
[i
].mnLines
;
982 if ( pThis
->maNextToolBoxStr
.Len() && pThis
->mbScroll
)
983 aSize
.Width() += TB_NEXT_SIZE
-TB_NEXT_OFFSET
;
987 // -----------------------------------------------------------------------
989 void ToolBox::ImplCalcMinMaxFloatSize( ToolBox
* pThis
, Size
& rMinSize
, Size
& rMaxSize
)
991 ImplCalcFloatSizes( pThis
);
994 rMinSize
= Size( pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
, pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
);
995 rMaxSize
= Size( pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
, pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
);
996 while ( ++i
<= pThis
->mpFloatSizeAry
->mnLastEntry
)
998 if( pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
< rMinSize
.Width() )
999 rMinSize
.Width() = pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
;
1000 if( pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
< rMinSize
.Height() )
1001 rMinSize
.Height() = pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
;
1003 if( pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
> rMaxSize
.Width() )
1004 rMaxSize
.Width() = pThis
->mpFloatSizeAry
->mpSize
[i
].mnWidth
;
1005 if( pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
> rMaxSize
.Height() )
1006 rMaxSize
.Height() = pThis
->mpFloatSizeAry
->mpSize
[i
].mnHeight
;
1010 void ToolBox::ImplSetMinMaxFloatSize( ToolBox
*pThis
)
1012 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( pThis
);
1013 Size aMinSize
, aMaxSize
;
1014 ImplCalcMinMaxFloatSize( pThis
, aMinSize
, aMaxSize
);
1017 pWrapper
->SetMinOutputSizePixel( aMinSize
);
1018 pWrapper
->SetMaxOutputSizePixel( aMaxSize
);
1019 pWrapper
->ShowTitleButton( TITLE_BUTTON_MENU
, ( pThis
->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE
) ? TRUE
: FALSE
);
1023 // TODO: change SetMinOutputSizePixel to be not inline
1024 pThis
->SetMinOutputSizePixel( aMinSize
);
1025 pThis
->SetMaxOutputSizePixel( aMaxSize
);
1029 // -----------------------------------------------------------------------
1032 USHORT
ToolBox::ImplCalcLines( ToolBox
* pThis
, long nToolSize
)
1036 if ( pThis
->mbHorz
)
1038 if ( pThis
->mnWinHeight
> pThis
->mnMaxItemHeight
)
1039 nLineHeight
= pThis
->mnWinHeight
;
1041 nLineHeight
= pThis
->mnMaxItemHeight
;
1044 nLineHeight
= pThis
->mnMaxItemWidth
;
1046 if ( pThis
->mnWinStyle
& WB_BORDER
)
1047 nToolSize
-= TB_BORDER_OFFSET2
*2;
1049 if ( pThis
->mnWinStyle
& WB_LINESPACING
)
1051 nLineHeight
+= TB_LINESPACING
;
1052 nToolSize
+= TB_LINESPACING
;
1055 // #i91917# always report at least one line
1056 long nLines
= nToolSize
/nLineHeight
;
1060 return static_cast<USHORT
>(nLines
);
1063 // -----------------------------------------------------------------------
1065 USHORT
ToolBox::ImplTestLineSize( ToolBox
* pThis
, const Point
& rPos
)
1067 if ( !pThis
->ImplIsFloatingMode() &&
1068 (!pThis
->mbScroll
|| (pThis
->mnLines
> 1) || (pThis
->mnCurLines
> pThis
->mnVisLines
)) )
1070 WindowAlign eAlign
= pThis
->GetAlign();
1072 if ( eAlign
== WINDOWALIGN_LEFT
)
1074 if ( rPos
.X() > pThis
->mnDX
-DOCK_LINEOFFSET
)
1075 return DOCK_LINEHSIZE
| DOCK_LINERIGHT
;
1077 else if ( eAlign
== WINDOWALIGN_TOP
)
1079 if ( rPos
.Y() > pThis
->mnDY
-DOCK_LINEOFFSET
)
1080 return DOCK_LINEVSIZE
| DOCK_LINEBOTTOM
;
1082 else if ( eAlign
== WINDOWALIGN_RIGHT
)
1084 if ( rPos
.X() < DOCK_LINEOFFSET
)
1085 return DOCK_LINEHSIZE
| DOCK_LINELEFT
;
1087 else if ( eAlign
== WINDOWALIGN_BOTTOM
)
1089 if ( rPos
.Y() < DOCK_LINEOFFSET
)
1090 return DOCK_LINEVSIZE
| DOCK_LINETOP
;
1097 // -----------------------------------------------------------------------
1099 void ToolBox::ImplLineSizing( ToolBox
* pThis
, const Point
& rPos
, Rectangle
& rRect
,
1109 if ( nLineMode
& DOCK_LINERIGHT
)
1111 nCurSize
= rPos
.X() - rRect
.Left();
1114 else if ( nLineMode
& DOCK_LINEBOTTOM
)
1116 nCurSize
= rPos
.Y() - rRect
.Top();
1119 else if ( nLineMode
& DOCK_LINELEFT
)
1121 nCurSize
= rRect
.Right() - rPos
.X();
1124 else if ( nLineMode
& DOCK_LINETOP
)
1126 nCurSize
= rRect
.Bottom() - rPos
.Y();
1130 DBG_ERROR( "ImplLineSizing: Trailing else" );
1135 Size aWinSize
= pThis
->GetSizePixel();
1136 USHORT nMaxLines
= (pThis
->mnLines
> pThis
->mnCurLines
) ? pThis
->mnLines
: pThis
->mnCurLines
;
1137 if ( nMaxLines
> TB_MAXLINES
)
1138 nMaxLines
= TB_MAXLINES
;
1141 nOneLineSize
= ImplCalcSize( pThis
, 1 ).Height();
1142 nMaxSize
= pThis
->maOutDockRect
.GetHeight() - 20;
1143 if ( nMaxSize
< aWinSize
.Height() )
1144 nMaxSize
= aWinSize
.Height();
1148 nOneLineSize
= ImplCalcSize( pThis
, 1 ).Width();
1149 nMaxSize
= pThis
->maOutDockRect
.GetWidth() - 20;
1150 if ( nMaxSize
< aWinSize
.Width() )
1151 nMaxSize
= aWinSize
.Width();
1155 if ( nCurSize
<= nOneLineSize
)
1156 nSize
= nOneLineSize
;
1160 while ( (nSize
< nCurSize
) && (i
< nMaxLines
) )
1163 aSize
= ImplCalcSize( pThis
, i
);
1165 nSize
= aSize
.Height();
1167 nSize
= aSize
.Width();
1168 if ( nSize
> nMaxSize
)
1171 aSize
= ImplCalcSize( pThis
, i
);
1173 nSize
= aSize
.Height();
1175 nSize
= aSize
.Width();
1181 if ( nLineMode
& DOCK_LINERIGHT
)
1182 rRect
.Right() = rRect
.Left()+nSize
-1;
1183 else if ( nLineMode
& DOCK_LINEBOTTOM
)
1184 rRect
.Bottom() = rRect
.Top()+nSize
-1;
1185 else if ( nLineMode
& DOCK_LINELEFT
)
1186 rRect
.Left() = rRect
.Right()-nSize
;
1187 else //if ( nLineMode & DOCK_LINETOP )
1188 rRect
.Top() = rRect
.Bottom()-nSize
;
1190 pThis
->mnDockLines
= i
;
1193 // -----------------------------------------------------------------------
1195 USHORT
ToolBox::ImplFindItemPos( ToolBox
* pBox
, const Point
& rPos
)
1200 Size
aSize( pBox
->mnDX
, pBox
->mnDY
);
1202 if ( aPos
.X() > aSize
.Width()-TB_BORDER_OFFSET1
)
1203 aPos
.X() = aSize
.Width()-TB_BORDER_OFFSET1
;
1204 if ( aPos
.Y() > aSize
.Height()-TB_BORDER_OFFSET1
)
1205 aPos
.Y() = aSize
.Height()-TB_BORDER_OFFSET1
;
1207 // Item suchen, das geklickt wurde
1208 std::vector
< ImplToolItem
>::const_iterator it
= pBox
->mpData
->m_aItems
.begin();
1209 while ( it
!= pBox
->mpData
->m_aItems
.end() )
1211 if ( it
->mbVisible
)
1213 if ( nLast
|| !it
->maRect
.IsEmpty() )
1218 ((nLast
< it
->maRect
.Top()) || it
->maRect
.IsEmpty()) )
1221 if ( aPos
.Y() <= it
->maRect
.Bottom() )
1223 if ( aPos
.X() < it
->maRect
.Left() )
1225 else if ( aPos
.X() < it
->maRect
.Right() )
1228 nLast
= it
->maRect
.Bottom();
1234 ((nLast
< it
->maRect
.Left()) || it
->maRect
.IsEmpty()) )
1237 if ( aPos
.X() <= it
->maRect
.Right() )
1239 if ( aPos
.Y() < it
->maRect
.Top() )
1241 else if ( aPos
.Y() < it
->maRect
.Bottom() )
1244 nLast
= it
->maRect
.Right();
1257 // -----------------------------------------------------------------------
1259 ImplTBDragMgr::ImplTBDragMgr()
1261 mpBoxList
= new ImplTBList( 4, 4 );
1264 mbCustomizeMode
= FALSE
;
1265 mbResizeMode
= FALSE
;
1266 mbShowDragRect
= FALSE
;
1269 maAccel
.InsertItem( KEY_RETURN
, KeyCode( KEY_RETURN
) );
1270 maAccel
.InsertItem( KEY_ESCAPE
, KeyCode( KEY_ESCAPE
) );
1271 maAccel
.SetSelectHdl( LINK( this, ImplTBDragMgr
, SelectHdl
) );
1274 // -----------------------------------------------------------------------
1276 ImplTBDragMgr::~ImplTBDragMgr()
1281 // -----------------------------------------------------------------------
1283 ToolBox
* ImplTBDragMgr::FindToolBox( const Rectangle
& rRect
)
1285 ToolBox
* pBox
= mpBoxList
->First();
1289 * FIXME: since we can have multiple frames now we cannot
1290 * find the drag target by its position alone.
1291 * As long as the toolbar config dialogue is not a system window
1292 * this works in one frame only anyway. If the dialogue
1293 * changes to a system window, we need a new implementation here
1295 if ( pBox
->IsReallyVisible() && pBox
->ImplGetWindowImpl()->mpFrame
== mpDragBox
->ImplGetWindowImpl()->mpFrame
)
1297 if ( !pBox
->ImplIsFloatingMode() )
1299 Point aPos
= pBox
->GetPosPixel();
1300 aPos
= pBox
->GetParent()->OutputToScreenPixel( aPos
);
1301 Rectangle
aTempRect( aPos
, pBox
->GetSizePixel() );
1302 if ( aTempRect
.IsOver( rRect
) )
1307 pBox
= mpBoxList
->Next();
1313 // -----------------------------------------------------------------------
1315 void ImplTBDragMgr::StartDragging( ToolBox
* pToolBox
,
1316 const Point
& rPos
, const Rectangle
& rRect
,
1317 USHORT nDragLineMode
, BOOL bResizeItem
,
1320 mpDragBox
= pToolBox
;
1321 pToolBox
->CaptureMouse();
1322 pToolBox
->mbDragging
= TRUE
;
1323 Application::InsertAccel( &maAccel
);
1325 if ( nDragLineMode
)
1327 mnLineMode
= nDragLineMode
;
1328 mnStartLines
= pToolBox
->mnDockLines
;
1332 mpCustomizeData
= pData
;
1333 mbResizeMode
= bResizeItem
;
1334 pToolBox
->Activate();
1335 pToolBox
->mnCurItemId
= pToolBox
->mnConfigItem
;
1336 pToolBox
->Highlight();
1337 pToolBox
->mnCurItemId
= 0;
1340 if ( rRect
.GetWidth() < TB_MIN_WIN_WIDTH
)
1341 mnMinWidth
= rRect
.GetWidth();
1343 mnMinWidth
= TB_MIN_WIN_WIDTH
;
1344 mnMaxWidth
= pToolBox
->GetSizePixel().Width()-rRect
.Left()-
1345 TB_SPIN_SIZE
-TB_BORDER_OFFSET1
-(TB_SPIN_OFFSET
*2);
1349 // MouseOffset berechnen
1350 maMouseOff
.X() = rRect
.Left() - rPos
.X();
1351 maMouseOff
.Y() = rRect
.Top() - rPos
.Y();
1353 maStartRect
= rRect
;
1354 mbShowDragRect
= TRUE
;
1355 pToolBox
->ShowTracking( maRect
);
1358 // -----------------------------------------------------------------------
1360 void ImplTBDragMgr::Dragging( const Point
& rPos
)
1364 ToolBox::ImplLineSizing( mpDragBox
, rPos
, maRect
, mnLineMode
);
1365 Point aOff
= mpDragBox
->OutputToScreenPixel( Point() );
1366 maRect
.Move( aOff
.X(), aOff
.Y() );
1367 mpDragBox
->Docking( rPos
, maRect
);
1368 maRect
.Move( -aOff
.X(), -aOff
.Y() );
1369 mpDragBox
->ShowTracking( maRect
);
1375 long nXOff
= rPos
.X()-maStartRect
.Left();
1376 nXOff
+= maMouseOff
.X()+(maStartRect
.Right()-maStartRect
.Left());
1377 if ( nXOff
< mnMinWidth
)
1379 if ( nXOff
> mnMaxWidth
)
1381 maRect
.Right() = maStartRect
.Left()+nXOff
;
1385 maRect
.SetPos( rPos
);
1386 maRect
.Move( maMouseOff
.X(), maMouseOff
.Y() );
1388 mpDragBox
->ShowTracking( maRect
);
1392 // -----------------------------------------------------------------------
1394 void ImplTBDragMgr::EndDragging( BOOL bOK
)
1396 mpDragBox
->HideTracking();
1397 mpDragBox
->ReleaseMouse();
1398 mpDragBox
->mbDragging
= FALSE
;
1399 mbShowDragRect
= FALSE
;
1400 Application::RemoveAccel( &maAccel
);
1406 mpDragBox
->mnDockLines
= mnStartLines
;
1407 mpDragBox
->EndDocking( maStartRect
, FALSE
);
1410 mpDragBox
->EndDocking( maRect
, FALSE
);
1416 USHORT nTempItem
= mpDragBox
->mnConfigItem
;
1419 mpDragBox
->mnConfigItem
= 0;
1420 if ( !mbResizeMode
)
1421 mpDragBox
->Invalidate( mpDragBox
->GetItemRect( nTempItem
) );
1424 if ( bOK
&& (maRect
!= maStartRect
) )
1428 ImplToolItem
* pItem
= mpDragBox
->ImplGetItem( nTempItem
);
1429 Size aSize
= pItem
->mpWindow
->GetSizePixel();
1430 aSize
.Width() = maRect
.GetWidth();
1431 pItem
->mpWindow
->SetSizePixel( aSize
);
1433 // ToolBox neu brechnen und neu ausgeben
1434 mpDragBox
->ImplInvalidate( TRUE
);
1435 mpDragBox
->Customize( ToolBoxCustomizeEvent( mpDragBox
, nTempItem
,
1436 TOOLBOX_CUSTOMIZE_RESIZE
,
1437 mpCustomizeData
) );
1441 Point aOff
= mpDragBox
->OutputToScreenPixel( Point() );
1442 Rectangle
aScreenRect( maRect
);
1443 aScreenRect
.Move( aOff
.X(), aOff
.Y() );
1444 ToolBox
* pDropBox
= FindToolBox( aScreenRect
);
1447 // Such-Position bestimmen
1449 if ( pDropBox
->mbHorz
)
1451 aPos
.X() = aScreenRect
.Left()-TB_CUSTOMIZE_OFFSET
;
1452 aPos
.Y() = aScreenRect
.Center().Y();
1456 aPos
.X() = aScreenRect
.Center().X();
1457 aPos
.Y() = aScreenRect
.Top()-TB_CUSTOMIZE_OFFSET
;
1460 aPos
= pDropBox
->ScreenToOutputPixel( aPos
);
1461 USHORT nPos
= ToolBox::ImplFindItemPos( pDropBox
, aPos
);
1462 mpDragBox
->Customize( ToolBoxCustomizeEvent( pDropBox
, nTempItem
,
1463 nPos
, mpCustomizeData
) );
1467 mpDragBox
->Customize( ToolBoxCustomizeEvent( NULL
, nTempItem
,
1468 0, mpCustomizeData
) );
1472 mpCustomizeData
= NULL
;
1473 mbResizeMode
= FALSE
;
1474 mpDragBox
->Deactivate();
1480 // -----------------------------------------------------------------------
1482 void ImplTBDragMgr::UpdateDragRect()
1484 // Nur Updaten, wenn wir schon im Dragging sind
1485 if ( !mbShowDragRect
)
1488 mpDragBox
->ShowTracking( maRect
);
1491 // -----------------------------------------------------------------------
1493 IMPL_LINK( ImplTBDragMgr
, SelectHdl
, Accelerator
*, pAccel
)
1495 if ( pAccel
->GetCurItemId() == KEY_ESCAPE
)
1496 EndDragging( FALSE
);
1498 EndDragging( TRUE
);
1503 // -----------------------------------------------------------------------
1505 void ImplTBDragMgr::StartCustomizeMode()
1507 mbCustomizeMode
= TRUE
;
1509 ToolBox
* pBox
= mpBoxList
->First();
1512 pBox
->ImplStartCustomizeMode();
1513 pBox
= mpBoxList
->Next();
1517 // -----------------------------------------------------------------------
1519 void ImplTBDragMgr::EndCustomizeMode()
1521 mbCustomizeMode
= FALSE
;
1523 ToolBox
* pBox
= mpBoxList
->First();
1526 pBox
->ImplEndCustomizeMode();
1527 pBox
= mpBoxList
->Next();
1531 // -----------------------------------------------------------------------
1534 static void ImplDrawOutButton( OutputDevice
* pOutDev
, const Rectangle
& rRect
,
1537 const StyleSettings
& rStyleSettings
= pOutDev
->GetSettings().GetStyleSettings();
1538 Color aShadowColor
= rStyleSettings
.GetShadowColor();
1539 Point
aPos( rRect
.TopLeft() );
1540 Size
aSize( rRect
.GetSize() );
1543 if ( pOutDev
->GetBackground().GetColor() == aShadowColor
)
1544 aShadowColor
= rStyleSettings
.GetDarkShadowColor();
1546 if ( nStyle
& BUTTON_DRAW_PRESSED
)
1553 // Hintergrund loeschen
1554 pOutDev
->Erase( rRect
);
1557 pOutDev
->SetLineColor( rStyleSettings
.GetLightColor() );
1558 pOutDev
->DrawLine( aPos
,
1559 Point( aPos
.X()+aSize
.Width()-OUTBUTTON_BORDER
, aPos
.Y() ) );
1560 pOutDev
->DrawLine( aPos
,
1561 Point( aPos
.X(), aPos
.Y()+aSize
.Height()-OUTBUTTON_BORDER
) );
1562 pOutDev
->SetLineColor( aShadowColor
);
1563 pOutDev
->DrawLine( Point( aPos
.X()+aSize
.Width()-OUTBUTTON_BORDER
, aPos
.Y() ),
1564 Point( aPos
.X()+aSize
.Width()-OUTBUTTON_BORDER
, aPos
.Y()+aSize
.Height()-OUTBUTTON_BORDER
) );
1565 pOutDev
->DrawLine( Point( aPos
.X(), aPos
.Y()+aSize
.Height()-OUTBUTTON_BORDER
),
1566 Point( aPos
.X()+aSize
.Width()-OUTBUTTON_BORDER
, aPos
.Y()+aSize
.Height()-OUTBUTTON_BORDER
) );
1567 for ( long i
= 0; i
< OUTBUTTON_BORDER
-1-nOffset
; i
++ )
1569 pOutDev
->DrawLine( Point( aPos
.X()+aSize
.Width()-(OUTBUTTON_BORDER
-i
-1), aPos
.Y()+OUTBUTTON_BORDER
),
1570 Point( aPos
.X()+aSize
.Width()-(OUTBUTTON_BORDER
-i
-1), aPos
.Y()+aSize
.Height()-1 ) );
1571 pOutDev
->DrawLine( Point( aPos
.X()+OUTBUTTON_BORDER
, aPos
.Y()+aSize
.Height()-(OUTBUTTON_BORDER
-i
-1) ),
1572 Point( aPos
.X()+aSize
.Width()-1, aPos
.Y()+aSize
.Height()-(OUTBUTTON_BORDER
-i
-1) ) );
1577 // -----------------------------------------------------------------------
1579 void ToolBox::ImplInit( Window
* pParent
, WinBits nStyle
)
1582 // Variablen initialisieren
1583 ImplGetWindowImpl()->mbToolBox
= TRUE
;
1585 mpFloatSizeAry
= NULL
;
1586 mpData
= new ImplToolBoxPrivateData
;
1591 mnMaxItemHeight
= 0;
1600 mnOutStyle
= TOOLBOX_STYLE_FLAT
; // force flat buttons since NWF
1604 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
1605 mnFocusPos
= TOOLBOX_ITEM_NOTFOUND
; // current position during keyboard access
1613 mnMouseModifier
= 0;
1615 mbSelection
= FALSE
;
1616 mbCommandDrag
= FALSE
;
1623 mbFullPaint
= FALSE
;
1625 mbScroll
= (nStyle
& WB_SCROLL
) != 0;
1626 mbCustomize
= FALSE
;
1627 mbCustomizeMode
= FALSE
;
1629 mbHideStatusText
= FALSE
;
1630 mbMenuStrings
= FALSE
;
1632 mbIsKeyEvent
= FALSE
;
1633 mbChangingHighlight
= FALSE
;
1634 meButtonType
= BUTTON_SYMBOL
;
1635 meAlign
= WINDOWALIGN_TOP
;
1636 meLastStyle
= POINTER_ARROW
;
1637 mnWinStyle
= nStyle
;
1638 mnLastFocusItemId
= 0;
1640 mnActivateCount
= 0;
1642 maTimer
.SetTimeout( 50 );
1643 maTimer
.SetTimeoutHdl( LINK( this, ToolBox
, ImplUpdateHdl
) );
1645 // set timeout and handler for dropdown items
1646 mpData
->maDropdownTimer
.SetTimeout( 250 );
1647 mpData
->maDropdownTimer
.SetTimeoutHdl( LINK( this, ToolBox
, ImplDropdownLongClickHdl
) );
1649 DockingWindow::ImplInit( pParent
, nStyle
& ~(WB_BORDER
) );
1652 // always set WB_TABSTOP for ToolBars !!! if( mnWinStyle & WB_TABSTOP )
1654 // dockingwindow's ImplInit removes some bits, so restore them here
1655 // to allow keyboard handling for toolbars
1656 ImplGetWindowImpl()->mnStyle
|= WB_TABSTOP
|WB_NODIALOGCONTROL
;
1657 ImplGetWindowImpl()->mnStyle
&= ~WB_DIALOGCONTROL
;
1660 ImplInitSettings( TRUE
, TRUE
, TRUE
);
1663 // -----------------------------------------------------------------------
1665 void ToolBox::ImplInitSettings( BOOL bFont
,
1666 BOOL bForeground
, BOOL bBackground
)
1668 mpData
->mbNativeButtons
= IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
);
1670 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
1674 Font aFont
= rStyleSettings
.GetToolFont();
1675 if ( IsControlFont() )
1676 aFont
.Merge( GetControlFont() );
1677 SetZoomedPointFont( aFont
);
1680 if ( bForeground
|| bFont
)
1683 if ( IsControlForeground() )
1684 aColor
= GetControlForeground();
1685 else if ( Window::GetStyle() & WB_3DLOOK
)
1686 aColor
= rStyleSettings
.GetButtonTextColor();
1688 aColor
= rStyleSettings
.GetWindowTextColor();
1689 SetTextColor( aColor
);
1696 if ( IsControlBackground() )
1698 aColor
= GetControlBackground();
1699 SetBackground( aColor
);
1700 SetPaintTransparent( FALSE
);
1701 SetParentClipMode( 0 );
1705 if( IsNativeControlSupported( CTRL_TOOLBAR
, PART_ENTIRE_CONTROL
) )
1708 SetPaintTransparent( TRUE
);
1709 SetParentClipMode( PARENTCLIPMODE_NOCLIP
);
1710 mpData
->maDisplayBackground
= Wallpaper( rStyleSettings
.GetFaceColor() );
1714 if ( Window::GetStyle() & WB_3DLOOK
)
1715 aColor
= rStyleSettings
.GetFaceColor();
1717 aColor
= rStyleSettings
.GetWindowColor();
1719 SetBackground( aColor
);
1720 SetPaintTransparent( FALSE
);
1721 SetParentClipMode( 0 );
1723 ImplUpdateImageList();
1729 // -----------------------------------------------------------------------
1731 void ToolBox::ImplLoadRes( const ResId
& rResId
)
1733 ResMgr
* pMgr
= rResId
.GetResMgr();
1737 DockingWindow::ImplLoadRes( rResId
);
1741 nObjMask
= ReadLongRes();
1743 if ( nObjMask
& RSC_TOOLBOX_BUTTONTYPE
)
1744 SetButtonType( (ButtonType
)ReadLongRes() );
1746 if ( nObjMask
& RSC_TOOLBOX_ALIGN
)
1747 SetAlign( (WindowAlign
)ReadLongRes() );
1749 if ( nObjMask
& RSC_TOOLBOX_LINECOUNT
)
1750 SetLineCount( sal::static_int_cast
<USHORT
>(ReadLongRes()) );
1752 if ( nObjMask
& RSC_TOOLBOX_CUSTOMIZE
)
1754 BOOL bCust
= (BOOL
)ReadShortRes();
1755 EnableCustomize( bCust
);
1758 if ( nObjMask
& RSC_TOOLBOX_MENUSTRINGS
)
1760 BOOL bCust
= (BOOL
)ReadShortRes();
1761 EnableMenuStrings( bCust
);
1764 if ( nObjMask
& RSC_TOOLBOX_FLOATLINES
)
1765 SetFloatingLines( ReadShortRes() );
1767 if ( nObjMask
& RSC_TOOLBOX_ITEMIMAGELIST
)
1769 maImageList
= ImageList( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
1770 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
1773 if ( nObjMask
& RSC_TOOLBOX_ITEMLIST
)
1775 ULONG nEle
= ReadLongRes();
1778 for ( ULONG i
= 0; i
< nEle
; i
++ )
1780 InsertItem( ResId( (RSHEADER_TYPE
*)GetClassRes(), *pMgr
) );
1781 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
1786 // -----------------------------------------------------------------------
1788 ToolBox::ToolBox( Window
* pParent
, WinBits nStyle
) :
1789 DockingWindow( WINDOW_TOOLBOX
)
1791 ImplInit( pParent
, nStyle
);
1794 // -----------------------------------------------------------------------
1796 ToolBox::ToolBox( Window
* pParent
, const ResId
& rResId
) :
1797 DockingWindow( WINDOW_TOOLBOX
)
1799 RTL_LOGFILE_CONTEXT( aLog
, "vcl: ToolBox::ToolBox( Window* pParent, const ResId& rResId )" );
1801 rResId
.SetRT( RSC_TOOLBOX
);
1802 WinBits nStyle
= ImplInitRes( rResId
);
1803 ImplInit( pParent
, nStyle
);
1804 ImplLoadRes( rResId
);
1806 // Groesse des FloatingWindows berechnen und umschalten, wenn die
1807 // ToolBox initial im FloatingModus ist
1808 if ( ImplIsFloatingMode() )
1813 if ( !(nStyle
& WB_HIDE
) )
1817 // -----------------------------------------------------------------------
1821 // custom menu event still running?
1822 if( mpData
->mnEventId
)
1823 Application::RemoveUserEvent( mpData
->mnEventId
);
1825 // #103005# make sure our activate/deactivate balance is right
1826 while( mnActivateCount
> 0 )
1829 // Falls noch ein Floating-Window connected ist, dann den
1830 // PopupModus beenden
1832 mpFloatWin
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
1834 // delete private data
1837 // FloatSizeAry gegebenenfalls loeschen
1838 if ( mpFloatSizeAry
)
1839 delete mpFloatSizeAry
;
1841 // Wenn keine ToolBox-Referenzen mehr auf die Listen bestehen, dann
1842 // Listen mit wegloeschen
1843 ImplSVData
* pSVData
= ImplGetSVData();
1844 if ( pSVData
->maCtrlData
.mpTBDragMgr
)
1846 // Wenn im TBDrag-Manager, dann wieder rausnehmen
1848 pSVData
->maCtrlData
.mpTBDragMgr
->Remove( this );
1850 if ( !pSVData
->maCtrlData
.mpTBDragMgr
->Count() )
1852 delete pSVData
->maCtrlData
.mpTBDragMgr
;
1853 pSVData
->maCtrlData
.mpTBDragMgr
= NULL
;
1858 // -----------------------------------------------------------------------
1860 ImplToolItem
* ToolBox::ImplGetItem( USHORT nItemId
) const
1862 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
1863 while ( it
!= mpData
->m_aItems
.end() )
1865 if ( it
->mnId
== nItemId
)
1872 // -----------------------------------------------------------------------
1874 static void ImplAddButtonBorder( long &rWidth
, long& rHeight
, USHORT aOutStyle
, BOOL bNativeButtons
)
1876 if ( aOutStyle
& TOOLBOX_STYLE_OUTBUTTON
)
1878 rWidth
+= OUTBUTTON_SIZE
;
1879 rHeight
+= OUTBUTTON_SIZE
;
1883 rWidth
+= SMALLBUTTON_HSIZE
;
1884 rHeight
+= SMALLBUTTON_VSIZE
;
1887 if( bNativeButtons
)
1889 // give more border space for rounded buttons
1895 // -----------------------------------------------------------------------
1897 BOOL
ToolBox::ImplCalcItem()
1899 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
1901 // recalc required ?
1905 ImplDisableFlatButtons();
1910 long nMaxHeight
= 0;
1913 long nMinHeight
= 6;
1914 long nDropDownArrowWidth
= TB_DROPDOWNARROWWIDTH
;
1916 // set defaults if image or text is needed but empty
1917 nDefWidth
= GetDefaultImageSize().Width();
1918 nDefHeight
= GetDefaultImageSize().Height();
1921 // determine minimum size necessary in NWF
1923 Rectangle
aRect( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1924 Region aReg
= aRect
;
1925 ImplControlValue aVal
;
1926 Region aNativeBounds
, aNativeContent
;
1927 if( IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
) )
1929 if( GetNativeControlRegion( CTRL_TOOLBAR
, PART_BUTTON
,
1931 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1933 aNativeBounds
, aNativeContent
) )
1935 aRect
= aNativeBounds
.GetBoundRect();
1936 if( aRect
.GetWidth() > nMinWidth
)
1937 nMinWidth
= aRect
.GetWidth();
1938 if( aRect
.GetHeight() > nMinHeight
)
1939 nMinHeight
= aRect
.GetHeight();
1940 if( nDropDownArrowWidth
< nMinWidth
)
1941 nDropDownArrowWidth
= nMinWidth
;
1942 if( nMinWidth
> mpData
->mnMenuButtonWidth
)
1943 mpData
->mnMenuButtonWidth
= nMinWidth
;
1944 else if( nMinWidth
< TB_MENUBUTTON_SIZE
)
1945 mpData
->mnMenuButtonWidth
= TB_MENUBUTTON_SIZE
;
1949 // also calculate the area for comboboxes, drop down list boxes and spinfields
1950 // as these are often inserted into toolboxes; set mnWinHeight to the
1951 // greater of those values to prevent toolbar flickering (#i103385#)
1952 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1954 if( GetNativeControlRegion( CTRL_COMBOBOX
, PART_ENTIRE_CONTROL
,
1956 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1958 aNativeBounds
, aNativeContent
) )
1960 aRect
= aNativeBounds
.GetBoundRect();
1961 if( aRect
.GetHeight() > mnWinHeight
)
1962 mnWinHeight
= aRect
.GetHeight();
1964 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1966 if( GetNativeControlRegion( CTRL_LISTBOX
, PART_ENTIRE_CONTROL
,
1968 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1970 aNativeBounds
, aNativeContent
) )
1972 aRect
= aNativeBounds
.GetBoundRect();
1973 if( aRect
.GetHeight() > mnWinHeight
)
1974 mnWinHeight
= aRect
.GetHeight();
1976 aRect
= Rectangle( Point( 0, 0 ), Size( nMinWidth
, nMinHeight
) );
1978 if( GetNativeControlRegion( CTRL_SPINBOX
, PART_ENTIRE_CONTROL
,
1980 CTRL_STATE_ENABLED
| CTRL_STATE_ROLLOVER
,
1982 aNativeBounds
, aNativeContent
) )
1984 aRect
= aNativeBounds
.GetBoundRect();
1985 if( aRect
.GetHeight() > mnWinHeight
)
1986 mnWinHeight
= aRect
.GetHeight();
1990 if ( ! mpData
->m_aItems
.empty() )
1992 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
1993 while ( it
!= mpData
->m_aItems
.end() )
1998 it
->mbVisibleText
= FALSE
; // indicates if text will definitely be drawn, influences dropdown pos
2000 if ( it
->meType
== TOOLBOXITEM_BUTTON
)
2002 // check if image and/or text exists
2003 if ( !(it
->maImage
) )
2007 if ( !it
->maText
.Len() )
2011 ButtonType tmpButtonType
= determineButtonType( &(*it
), meButtonType
); // default to toolbox setting
2012 if ( bImage
|| bText
)
2015 it
->mbEmptyBtn
= FALSE
;
2017 if ( tmpButtonType
== BUTTON_SYMBOL
)
2019 // we're drawing images only
2020 if ( bImage
|| !bText
)
2022 it
->maItemSize
= it
->maImage
.GetSizePixel();
2026 it
->maItemSize
= Size( GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
,
2028 it
->mbVisibleText
= TRUE
;
2031 else if ( tmpButtonType
== BUTTON_TEXT
)
2033 // we're drawing text only
2034 if ( bText
|| !bImage
)
2036 it
->maItemSize
= Size( GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
,
2038 it
->mbVisibleText
= TRUE
;
2042 it
->maItemSize
= it
->maImage
.GetSizePixel();
2047 // we're drawing images and text
2048 it
->maItemSize
.Width() = bText
? GetCtrlTextWidth( it
->maText
)+TB_TEXTOFFSET
: 0;
2049 it
->maItemSize
.Height() = bText
? GetTextHeight() : 0;
2051 // leave space between image and text
2053 it
->maItemSize
.Width() += TB_IMAGETEXTOFFSET
;
2055 // image and text side by side
2056 it
->maItemSize
.Width() += it
->maImage
.GetSizePixel().Width();
2057 if ( it
->maImage
.GetSizePixel().Height() > it
->maItemSize
.Height() )
2058 it
->maItemSize
.Height() = it
->maImage
.GetSizePixel().Height();
2060 it
->mbVisibleText
= bText
;
2064 { // no image and no text
2065 it
->maItemSize
= Size( nDefWidth
, nDefHeight
);
2066 it
->mbEmptyBtn
= TRUE
;
2069 // Gegebenenfalls die Fensterhoehe mit beruecksichtigen
2072 nHeight
= it
->mpWindow
->GetSizePixel().Height();
2073 if ( nHeight
> mnWinHeight
)
2074 mnWinHeight
= nHeight
;
2077 // add in drop down arrow
2078 if( it
->mnBits
& TIB_DROPDOWN
)
2080 it
->maItemSize
.Width() += nDropDownArrowWidth
;
2081 it
->mnDropDownArrowWidth
= nDropDownArrowWidth
;
2084 // text items will be rotated in vertical mode
2085 // -> swap width and height
2086 if( it
->mbVisibleText
&& !mbHorz
)
2088 long tmp
= it
->maItemSize
.Width();
2089 it
->maItemSize
.Width() = it
->maItemSize
.Height();
2090 it
->maItemSize
.Height() = tmp
;
2093 else if ( it
->meType
== TOOLBOXITEM_SPACE
)
2095 it
->maItemSize
= Size( nDefWidth
, nDefHeight
);
2098 if ( it
->meType
== TOOLBOXITEM_BUTTON
|| it
->meType
== TOOLBOXITEM_SPACE
)
2101 ImplAddButtonBorder( it
->maItemSize
.Width(), it
->maItemSize
.Height(), mnOutStyle
, mpData
->mbNativeButtons
);
2103 if( it
->meType
== TOOLBOXITEM_BUTTON
)
2105 if( it
->maItemSize
.Width() < nMinWidth
)
2106 it
->maItemSize
.Width() = nMinWidth
;
2107 if( it
->maItemSize
.Height() < nMinHeight
)
2108 it
->maItemSize
.Height() = nMinHeight
;
2111 // keep track of max item size
2112 if ( it
->maItemSize
.Width() > nMaxWidth
)
2113 nMaxWidth
= it
->maItemSize
.Width();
2114 if ( it
->maItemSize
.Height() > nMaxHeight
)
2115 nMaxHeight
= it
->maItemSize
.Height();
2123 nMaxWidth
= nDefWidth
;
2124 nMaxHeight
= nDefHeight
;
2126 ImplAddButtonBorder( nMaxWidth
, nMaxHeight
, mnOutStyle
, mpData
->mbNativeButtons
);
2129 if( !ImplIsFloatingMode() && GetToolboxButtonSize() != TOOLBOX_BUTTONSIZE_DONTCARE
)
2131 // make sure all vertical toolbars have the same width and horizontal have the same height
2132 // this depends on the used button sizes
2133 // as this is used for alignement of multiple toolbars
2134 // it is only required for docked toolbars
2136 long nFixedWidth
= nDefWidth
+nDropDownArrowWidth
;
2137 long nFixedHeight
= nDefHeight
;
2138 ImplAddButtonBorder( nFixedWidth
, nFixedHeight
, mnOutStyle
, mpData
->mbNativeButtons
);
2141 nMaxHeight
= nFixedHeight
;
2143 nMaxWidth
= nFixedWidth
;
2149 // do we have to recalc the sizes ?
2150 if ( (nMaxWidth
!= mnMaxItemWidth
) || (nMaxHeight
!= mnMaxItemHeight
) )
2152 mnMaxItemWidth
= nMaxWidth
;
2153 mnMaxItemHeight
= nMaxHeight
;
2161 // -----------------------------------------------------------------------
2163 USHORT
ToolBox::ImplCalcBreaks( long nWidth
, long* pMaxLineWidth
, BOOL bCalcHorz
)
2165 ULONG nLineStart
= 0;
2166 ULONG nGroupStart
= 0;
2167 long nLineWidth
= 0;
2169 long nLastGroupLineWidth
= 0;
2170 long nMaxLineWidth
= 0;
2173 BOOL bBreak
= FALSE
;
2174 long nWidthTotal
= nWidth
;
2176 // when docked the menubutton will be in the first line
2177 // ->initialize first linewidth with button
2178 if( IsMenuEnabled() && !ImplIsFloatingMode() )
2179 nLineWidth
= mpData
->maMenubuttonItem
.maItemSize
.Width();
2181 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
2182 while ( it
!= mpData
->m_aItems
.end() )
2184 it
->mbBreak
= bBreak
;
2187 if ( it
->mbVisible
)
2193 if ( it
->meType
== TOOLBOXITEM_BUTTON
|| it
->meType
== TOOLBOXITEM_SPACE
)
2196 nCurWidth
= it
->maItemSize
.Width();
2198 nCurWidth
= it
->maItemSize
.Height();
2200 if ( it
->mpWindow
&& bCalcHorz
)
2202 long nWinItemWidth
= it
->mpWindow
->GetSizePixel().Width();
2203 if ( !mbScroll
|| (nWinItemWidth
<= nWidthTotal
) )
2205 nCurWidth
= nWinItemWidth
;
2210 if ( it
->mbEmptyBtn
)
2217 // check for line break
2218 if ( (nLineWidth
+nCurWidth
> nWidthTotal
) && mbScroll
)
2221 else if ( it
->meType
== TOOLBOXITEM_SEPARATOR
)
2222 nCurWidth
= it
->mnSepSize
;
2223 // treat breaks as separators, except when using old style toolbars (ie. no menu button)
2224 else if ( (it
->meType
== TOOLBOXITEM_BREAK
) && !IsMenuEnabled() )
2231 // Gruppe auseinanderbrechen oder ganze Gruppe umbrechen?
2232 if ( (it
->meType
== TOOLBOXITEM_BREAK
) ||
2233 (nLineStart
== nGroupStart
) )
2235 if ( nLineWidth
> nMaxLineWidth
)
2236 nMaxLineWidth
= nLineWidth
;
2239 nLineStart
= it
- mpData
->m_aItems
.begin();
2240 nGroupStart
= nLineStart
;
2246 if ( nLastGroupLineWidth
> nMaxLineWidth
)
2247 nMaxLineWidth
= nLastGroupLineWidth
;
2249 // Wenn ganze Gruppe umgebrochen wird, diese auf
2250 // Zeilenanfang setzen und wieder neu berechnen
2252 nLineStart
= nGroupStart
;
2253 it
= mpData
->m_aItems
.begin() + nGroupStart
;
2259 if( ImplIsFloatingMode() || !IsMenuEnabled() ) // no group breaking when being docked single-line
2261 if ( (it
->meType
!= TOOLBOXITEM_BUTTON
) || bWindow
)
2263 // found separator or break
2264 nLastGroupLineWidth
= nLineWidth
;
2265 nGroupStart
= it
- mpData
->m_aItems
.begin();
2272 nLineWidth
+= nCurWidth
;
2279 if ( pMaxLineWidth
)
2281 if ( nLineWidth
> nMaxLineWidth
)
2282 nMaxLineWidth
= nLineWidth
;
2284 if( ImplIsFloatingMode() && !ImplIsInPopupMode() )
2286 // leave enough space to display buttons in the decoration
2287 long aMinWidth
= 2 * GetSettings().GetStyleSettings().GetFloatTitleHeight();
2288 if( nMaxLineWidth
< aMinWidth
)
2289 nMaxLineWidth
= aMinWidth
;
2292 // Wegen Separatoren kann MaxLineWidth > Width werden, hat aber
2293 // auf die Umbrueche keine Auswirkung
2294 //if ( nMaxLineWidth > nWidth )
2295 // nMaxLineWidth = nWidth;
2297 *pMaxLineWidth
= nMaxLineWidth
;
2303 // -----------------------------------------------------------------------
2306 BOOL
ImplFollowedByVisibleButton( std::vector
< ImplToolItem
>::iterator _aSeparator
, std::vector
< ImplToolItem
>::iterator _aEnd
)
2308 std::vector
< ImplToolItem
>::iterator aLookup
= _aSeparator
;
2309 while ( ++aLookup
!= _aEnd
)
2311 if ( aLookup
->meType
== TOOLBOXITEM_SEPARATOR
)
2312 return ImplFollowedByVisibleButton( aLookup
, _aEnd
);
2314 if ( ( aLookup
->meType
== TOOLBOXITEM_BUTTON
) && aLookup
->mbVisible
)
2322 // -----------------------------------------------------------------------
2324 Size
ToolBox::ImplGetOptimalFloatingSize( FloatingSizeMode eMode
)
2326 if( !ImplIsFloatingMode() )
2329 Size
aCurrentSize( mnDX
, mnDY
);
2330 Size
aSize1( aCurrentSize
);
2331 Size
aSize2( aCurrentSize
);
2333 // try to preserve current height
2334 if( eMode
== FSMODE_AUTO
|| eMode
== FSMODE_FAVOURHEIGHT
)
2336 // calc number of floating lines for current window height
2337 USHORT nFloatLinesHeight
= ImplCalcLines( this, mnDY
);
2338 // calc window size according to this number
2339 aSize1
= ImplCalcFloatSize( this, nFloatLinesHeight
);
2341 if( eMode
== FSMODE_FAVOURHEIGHT
|| aCurrentSize
== aSize1
)
2345 if( eMode
== FSMODE_AUTO
|| eMode
== FSMODE_FAVOURWIDTH
)
2347 // try to preserve current width
2348 long nLineHeight
= ( mnWinHeight
> mnMaxItemHeight
) ? mnWinHeight
: mnMaxItemHeight
;
2349 int nBorderX
= 2*TB_BORDER_OFFSET1
+ mnLeftBorder
+ mnRightBorder
+ 2*mnBorderX
;
2350 int nBorderY
= 2*TB_BORDER_OFFSET2
+ mnTopBorder
+ mnBottomBorder
+ 2*mnBorderY
;
2351 Size
aSz( aCurrentSize
);
2353 USHORT nLines
= ImplCalcBreaks( aSz
.Width()-nBorderX
, &maxX
, mbHorz
);
2355 USHORT manyLines
= 1000;
2356 Size aMinimalFloatSize
= ImplCalcFloatSize( this, manyLines
);
2358 aSz
.Height() = nBorderY
+ nLineHeight
* nLines
;
2359 // line space when more than one line
2360 if ( mnWinStyle
& WB_LINESPACING
)
2361 aSz
.Height() += (nLines
-1)*TB_LINESPACING
;
2363 aSz
.Width() = nBorderX
+ maxX
;
2365 // avoid clipping of any items
2366 if( aSz
.Width() < aMinimalFloatSize
.Width() )
2367 aSize2
= ImplCalcFloatSize( this, nLines
);
2371 if( eMode
== FSMODE_FAVOURWIDTH
|| aCurrentSize
== aSize2
)
2375 // set the size with the smallest delta as the current size
2376 long dx1
= abs( mnDX
- aSize1
.Width() );
2377 long dy1
= abs( mnDY
- aSize1
.Height() );
2379 long dx2
= abs( mnDX
- aSize2
.Width() );
2380 long dy2
= abs( mnDY
- aSize2
.Height() );
2382 if( dx1
*dy1
< dx2
*dy2
)
2383 aCurrentSize
= aSize1
;
2385 aCurrentSize
= aSize2
;
2388 return aCurrentSize
;
2392 void ToolBox::ImplFormat( BOOL bResize
)
2394 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
2396 // Muss ueberhaupt neu formatiert werden
2400 mpData
->ImplClearLayoutData();
2402 // Positionen/Groessen berechnen
2403 Rectangle aEmptyRect
;
2409 long nMax
; // width of layoutarea in pixels
2413 BOOL bMustFullPaint
;
2416 std::vector
< ImplToolItem
>::iterator it
;
2417 std::vector
< ImplToolItem
>::iterator temp_it
;
2419 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
2420 BOOL bIsInPopupMode
= ImplIsInPopupMode();
2422 // FloatSizeAry gegebenenfalls loeschen
2423 if ( mpFloatSizeAry
)
2425 delete mpFloatSizeAry
;
2426 mpFloatSizeAry
= NULL
;
2429 // compute border sizes
2430 ImplCalcBorder( meAlign
, mnLeftBorder
, mnTopBorder
, mnRightBorder
, mnBottomBorder
, this );
2432 // update drag area (where the 'grip' will be placed)
2433 Rectangle aOldDragRect
;
2435 aOldDragRect
= pWrapper
->GetDragArea();
2436 ImplUpdateDragArea( this );
2438 if ( ImplCalcItem() )
2439 bMustFullPaint
= TRUE
;
2441 bMustFullPaint
= FALSE
;
2444 // calculate new size during interactive resize or
2445 // set computed size when formatting only
2446 if ( ImplIsFloatingMode() )
2449 mnFloatLines
= ImplCalcLines( this, mnDY
);
2451 SetOutputSizePixel( ImplGetOptimalFloatingSize( FSMODE_AUTO
) );
2457 // nLineSize: height of a single line, will fit highest item
2458 nLineSize
= mnMaxItemHeight
;
2460 if ( mnWinHeight
> mnMaxItemHeight
)
2461 nLineSize
= mnWinHeight
;
2466 mnVisLines
= ImplCalcLines( this, mnDY
);
2470 // layout over all lines
2471 mnVisLines
= mnLines
;
2472 nMax
= TB_MAXNOSCROLL
;
2475 // add in all border offsets
2476 // inner border as well as custom border (mnBorderX, mnBorderY)
2477 if ( mnWinStyle
& WB_BORDER
)
2479 nLeft
= TB_BORDER_OFFSET1
+ mnLeftBorder
;
2480 nTop
= TB_BORDER_OFFSET2
+ mnTopBorder
;
2481 nBottom
= TB_BORDER_OFFSET1
+ mnBottomBorder
;
2482 nMax
-= nLeft
+ TB_BORDER_OFFSET1
+ mnRightBorder
;
2493 nBottom
+= mnBorderY
;
2494 nMax
-= mnBorderX
*2;
2496 // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
2497 // we have to center all items in the window height
2498 if( IsMenuEnabled() && !ImplIsFloatingMode() )
2500 long nWinHeight
= mnDY
- nTop
- nBottom
;
2501 if( nWinHeight
> nLineSize
)
2502 nLineSize
= nWinHeight
;
2507 nLineSize
= mnMaxItemWidth
;
2511 mnVisLines
= ImplCalcLines( this, mnDX
);
2516 mnVisLines
= mnLines
;
2517 nMax
= TB_MAXNOSCROLL
;
2520 if ( mnWinStyle
& WB_BORDER
)
2522 nTop
= TB_BORDER_OFFSET1
+ mnTopBorder
;
2523 nLeft
= TB_BORDER_OFFSET2
+ mnLeftBorder
;
2524 nRight
= TB_BORDER_OFFSET2
+ mnRightBorder
;
2525 nMax
-= nTop
+ TB_BORDER_OFFSET1
+ mnBottomBorder
;
2537 nMax
-= mnBorderY
*2;
2539 // adjust linesize if docked in single-line mode (i.e. when using a clipped item menu)
2540 // we have to center all items in the window height
2541 if( !ImplIsFloatingMode() && IsMenuEnabled() )
2543 long nWinWidth
= mnDX
- nLeft
- nRight
;
2544 if( nWinWidth
> nLineSize
)
2545 nLineSize
= nWinWidth
;
2549 // no calculation if the window has no size (nMax=0)
2550 // non scrolling toolboxes must be computed though
2551 if ( (nMax
<= 0) && mbScroll
)
2557 it
= mpData
->m_aItems
.begin();
2558 while ( it
!= mpData
->m_aItems
.end() )
2560 it
->maRect
= aEmptyRect
;
2562 // For items not visible, release resources only needed during
2563 // painting the items (on Win98, for example, these are system-wide
2564 // resources that are easily exhausted, so be nice):
2567 it->maImage.ClearCaches();
2568 it->maHighImage.ClearCaches();
2574 maLowerRect
= aEmptyRect
;
2575 maUpperRect
= aEmptyRect
;
2576 maNextToolRect
= aEmptyRect
;
2580 // init start values
2581 nX
= nLeft
; // top-left offset
2586 // save old scroll rectangles and reset them
2587 Rectangle aOldLowerRect
= maLowerRect
;
2588 Rectangle aOldUpperRect
= maUpperRect
;
2589 Rectangle aOldNextToolRect
= maNextToolRect
;
2590 Rectangle aOldMenubuttonRect
= mpData
->maMenubuttonItem
.maRect
;
2591 maUpperRect
= aEmptyRect
;
2592 maLowerRect
= aEmptyRect
;
2593 maNextToolRect
= aEmptyRect
;
2594 mpData
->maMenubuttonItem
.maRect
= aEmptyRect
;
2596 // additional toolboxes require a toggle button (maNextToolRect)
2597 if ( maNextToolBoxStr
.Len() && mbScroll
)
2599 nMax
-= TB_NEXT_SIZE
-TB_NEXT_OFFSET
;
2602 maNextToolRect
.Left() = nLeft
+nMax
;
2603 maNextToolRect
.Right() = maNextToolRect
.Left()+TB_NEXT_SIZE
-1;
2604 maNextToolRect
.Top() = nTop
;
2605 maNextToolRect
.Bottom() = mnDY
-mnBottomBorder
-mnBorderY
-TB_BORDER_OFFSET2
-1;
2609 maNextToolRect
.Top() = nTop
+nMax
;
2610 maNextToolRect
.Bottom() = maNextToolRect
.Top()+TB_NEXT_SIZE
-1;
2611 maNextToolRect
.Left() = nLeft
;
2612 maNextToolRect
.Right() = mnDX
-mnRightBorder
-mnBorderX
-TB_BORDER_OFFSET2
-1;
2616 // do we have any toolbox items at all ?
2617 if ( !mpData
->m_aItems
.empty() || IsMenuEnabled() )
2619 // compute line breaks and visible lines give the current window width (nMax)
2620 // the break indicators will be stored within each item (it->mbBreak)
2621 mnCurLines
= ImplCalcBreaks( nMax
, NULL
, mbHorz
);
2623 // check for scrollbar buttons or dropdown menu
2624 // (if a menu is enabled, this will be used to store clipped
2625 // items and no scroll buttons will appear)
2626 if ( (!ImplIsFloatingMode() && (mnCurLines
> mnVisLines
) && mbScroll
) ||
2629 // compute linebreaks again, incorporating scrollbar buttons
2630 if( !IsMenuEnabled() )
2632 nMax
-= TB_SPIN_SIZE
+TB_SPIN_OFFSET
;
2633 mnCurLines
= ImplCalcBreaks( nMax
, NULL
, mbHorz
);
2636 // compute scroll rectangles or menu button
2639 if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2641 if( !ImplIsFloatingMode() )
2643 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
- 2;
2644 mpData
->maMenubuttonItem
.maRect
.Top() = nTop
;
2645 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
-mnBottomBorder
-mnBorderY
-TB_BORDER_OFFSET2
-1;
2649 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
- mnRightBorder
-mnBorderX
-TB_BORDER_OFFSET1
-1;
2650 mpData
->maMenubuttonItem
.maRect
.Top() = nTop
;
2651 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
-mnBottomBorder
-mnBorderY
-TB_BORDER_OFFSET2
-1;
2653 mpData
->maMenubuttonItem
.maRect
.Left() = mpData
->maMenubuttonItem
.maRect
.Right() - mpData
->mnMenuButtonWidth
;
2657 maUpperRect
.Left() = nLeft
+nMax
+TB_SPIN_OFFSET
;
2658 maUpperRect
.Right() = maUpperRect
.Left()+TB_SPIN_SIZE
-1;
2659 maUpperRect
.Top() = nTop
;
2660 maLowerRect
.Bottom() = mnDY
-mnBottomBorder
-mnBorderY
-TB_BORDER_OFFSET2
-1;
2661 maLowerRect
.Left() = maUpperRect
.Left();
2662 maLowerRect
.Right() = maUpperRect
.Right();
2663 maUpperRect
.Bottom() = maUpperRect
.Top() +
2664 (maLowerRect
.Bottom()-maUpperRect
.Top())/2;
2665 maLowerRect
.Top() = maUpperRect
.Bottom();
2670 if( IsMenuEnabled() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2672 if( !ImplIsFloatingMode() )
2674 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
- 2;
2675 mpData
->maMenubuttonItem
.maRect
.Left() = nLeft
;
2676 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
-mnRightBorder
-mnBorderX
-TB_BORDER_OFFSET2
-1;
2680 mpData
->maMenubuttonItem
.maRect
.Bottom() = mnDY
- mnBottomBorder
-mnBorderY
-TB_BORDER_OFFSET1
-1;
2681 mpData
->maMenubuttonItem
.maRect
.Left() = nLeft
;
2682 mpData
->maMenubuttonItem
.maRect
.Right() = mnDX
-mnRightBorder
-mnBorderX
-TB_BORDER_OFFSET2
-1;
2684 mpData
->maMenubuttonItem
.maRect
.Top() = mpData
->maMenubuttonItem
.maRect
.Bottom() - mpData
->mnMenuButtonWidth
;
2688 maUpperRect
.Top() = nTop
+nMax
+TB_SPIN_OFFSET
;;
2689 maUpperRect
.Bottom() = maUpperRect
.Top()+TB_SPIN_SIZE
-1;
2690 maUpperRect
.Left() = nLeft
;
2691 maLowerRect
.Right() = mnDX
-mnRightBorder
-mnBorderX
-TB_BORDER_OFFSET2
-1;
2692 maLowerRect
.Top() = maUpperRect
.Top();
2693 maLowerRect
.Bottom() = maUpperRect
.Bottom();
2694 maUpperRect
.Right() = maUpperRect
.Left() +
2695 (maLowerRect
.Right()-maUpperRect
.Left())/2;
2696 maLowerRect
.Left() = maUpperRect
.Right();
2701 // no scrolling when there is a "more"-menu
2702 // anything will "fit" in a single line then
2703 if( IsMenuEnabled() )
2706 // determine the currently visible line
2707 if ( mnVisLines
>= mnCurLines
)
2709 else if ( mnCurLine
+mnVisLines
-1 > mnCurLines
)
2710 mnCurLine
= mnCurLines
- (mnVisLines
-1);
2712 it
= mpData
->m_aItems
.begin();
2713 while ( it
!= mpData
->m_aItems
.end() )
2715 // hide double separators
2716 if ( it
->meType
== TOOLBOXITEM_SEPARATOR
)
2718 it
->mbVisible
= FALSE
;
2721 // check if any visible items have to appear behind it
2723 while ( temp_it
!= mpData
->m_aItems
.end() )
2725 if ( (temp_it
->meType
== TOOLBOXITEM_SEPARATOR
) ||
2726 ((temp_it
->meType
== TOOLBOXITEM_BUTTON
) &&
2727 temp_it
->mbVisible
) )
2729 it
->mbVisible
= TRUE
;
2737 else if ( it
->mbVisible
)
2740 it
->mbShowWindow
= FALSE
;
2742 // check for line break and advance nX/nY accordingly
2747 // increment starting with the second line
2748 if ( nFormatLine
> mnCurLine
)
2753 if ( mnWinStyle
& WB_LINESPACING
)
2754 nY
+= nLineSize
+TB_LINESPACING
;
2761 if ( mnWinStyle
& WB_LINESPACING
)
2762 nX
+= nLineSize
+TB_LINESPACING
;
2769 if ( !it
->mbVisible
|| (nFormatLine
< mnCurLine
) ||
2770 (nFormatLine
> mnCurLine
+mnVisLines
-1) )
2771 // item is not visible
2772 it
->maCalcRect
= aEmptyRect
;
2775 // 1. determine current item width/height
2776 // take window size and orientation into account, because this affects the size of item windows
2778 Size
aCurrentItemSize( it
->GetSize( mbHorz
, mbScroll
, nMax
, Size(mnMaxItemWidth
, mnMaxItemHeight
) ) );
2780 // 2. position item rect and use size from step 1
2781 // items will be centered horizontally (if mbHorz) or vertically
2782 // advance nX and nY accordingly
2785 it
->maCalcRect
.Left() = nX
;
2786 it
->maCalcRect
.Top() = nY
+(nLineSize
-aCurrentItemSize
.Height())/2;
2787 it
->maCalcRect
.Right() = nX
+aCurrentItemSize
.Width()-1;
2788 it
->maCalcRect
.Bottom() = it
->maCalcRect
.Top()+aCurrentItemSize
.Height()-1;
2789 nX
+= aCurrentItemSize
.Width();
2793 it
->maCalcRect
.Left() = nX
+(nLineSize
-aCurrentItemSize
.Width())/2;
2794 it
->maCalcRect
.Top() = nY
;
2795 it
->maCalcRect
.Right() = it
->maCalcRect
.Left()+aCurrentItemSize
.Width()-1;
2796 it
->maCalcRect
.Bottom() = nY
+aCurrentItemSize
.Height()-1;
2797 nY
+= aCurrentItemSize
.Height();
2801 // position window items into calculated item rect
2804 if ( it
->mbShowWindow
)
2806 Point
aPos( it
->maCalcRect
.Left(), it
->maCalcRect
.Top() );
2807 it
->mpWindow
->SetPosPixel( aPos
);
2808 if ( !mbCustomizeMode
)
2809 it
->mpWindow
->Show();
2812 it
->mpWindow
->Hide();
2816 } // end of loop over all items
2819 // we have no toolbox items
2823 if( IsMenuEnabled() && ImplIsFloatingMode() && !ImplHasExternalMenubutton() && !bIsInPopupMode
)
2825 // custom menu will be the last button in floating mode
2826 ImplToolItem
&rIt
= mpData
->maMenubuttonItem
;
2830 rIt
.maRect
.Left() = nX
+TB_MENUBUTTON_OFFSET
;
2831 rIt
.maRect
.Top() = nY
;
2832 rIt
.maRect
.Right() = rIt
.maRect
.Left() + mpData
->mnMenuButtonWidth
;
2833 rIt
.maRect
.Bottom() = nY
+nLineSize
-1;
2834 nX
+= rIt
.maItemSize
.Width();
2838 rIt
.maRect
.Left() = nX
;
2839 rIt
.maRect
.Top() = nY
+TB_MENUBUTTON_OFFSET
;
2840 rIt
.maRect
.Right() = nX
+nLineSize
-1;
2841 rIt
.maRect
.Bottom() = rIt
.maRect
.Top() + mpData
->mnMenuButtonWidth
;
2842 nY
+= rIt
.maItemSize
.Height();
2847 // if toolbox visible trigger paint for changed regions
2848 if ( IsVisible() && !mbFullPaint
)
2850 if ( bMustFullPaint
)
2852 maPaintRect
= Rectangle( mnLeftBorder
, mnTopBorder
,
2853 mnDX
-mnRightBorder
, mnDY
-mnBottomBorder
);
2857 if ( aOldLowerRect
!= maLowerRect
)
2859 maPaintRect
.Union( maLowerRect
);
2860 maPaintRect
.Union( aOldLowerRect
);
2862 if ( aOldUpperRect
!= maUpperRect
)
2864 maPaintRect
.Union( maUpperRect
);
2865 maPaintRect
.Union( aOldUpperRect
);
2867 if ( aOldNextToolRect
!= maNextToolRect
)
2869 maPaintRect
.Union( maNextToolRect
);
2870 maPaintRect
.Union( aOldNextToolRect
);
2872 if ( aOldMenubuttonRect
!= mpData
->maMenubuttonItem
.maRect
)
2874 maPaintRect
.Union( mpData
->maMenubuttonItem
.maRect
);
2875 maPaintRect
.Union( aOldMenubuttonRect
);
2877 if ( pWrapper
&& aOldDragRect
!= pWrapper
->GetDragArea() )
2879 maPaintRect
.Union( pWrapper
->GetDragArea() );
2880 maPaintRect
.Union( aOldDragRect
);
2883 it
= mpData
->m_aItems
.begin();
2884 while ( it
!= mpData
->m_aItems
.end() )
2886 if ( it
->maRect
!= it
->maCalcRect
)
2888 maPaintRect
.Union( it
->maRect
);
2889 maPaintRect
.Union( it
->maCalcRect
);
2895 Invalidate( maPaintRect
);
2898 // store the new calculated item rects
2899 maPaintRect
= aEmptyRect
;
2900 Rectangle
aVisibleRect(Point(0, 0), GetOutputSizePixel());
2901 it
= mpData
->m_aItems
.begin();
2902 while ( it
!= mpData
->m_aItems
.end() )
2904 it
->maRect
= it
->maCalcRect
;
2905 if (!it
->maRect
.IsOver(aVisibleRect
))
2907 // For items not visible, release resources only needed during
2908 // painting the items (on Win98, for example, these are system-
2909 // wide resources that are easily exhausted, so be nice):
2912 it->maImage.ClearCaches();
2913 it->maHighImage.ClearCaches();
2920 // indicate formatting is done
2924 // -----------------------------------------------------------------------
2926 IMPL_LINK( ToolBox
, ImplDropdownLongClickHdl
, ToolBox
*, EMPTYARG
)
2928 if( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
&&
2929 (mpData
->m_aItems
[ mnCurPos
].mnBits
& TIB_DROPDOWN
)
2932 mpData
->mbDropDownByKeyboard
= FALSE
;
2933 GetDropdownClickHdl().Call( this );
2935 // do not reset data if the dropdown handler opened a floating window
2936 // see ImplFloatControl()
2937 if( mpFloatWin
== NULL
)
2939 // no floater was opened
2941 ImplDrawItem( mnCurPos
, FALSE
);
2943 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
2947 mnMouseModifier
= 0;
2955 // -----------------------------------------------------------------------
2957 IMPL_LINK( ToolBox
, ImplUpdateHdl
, void*, EMPTYARG
)
2959 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
2967 // -----------------------------------------------------------------------
2969 static void ImplDrawMoreIndicator( ToolBox
*pBox
, const Rectangle
& rRect
, BOOL bSetColor
, BOOL bRotate
)
2971 Color aOldFillColor
= pBox
->GetFillColor();
2972 Color aOldLineColor
= pBox
->GetLineColor();
2973 pBox
->SetLineColor();
2977 if ( pBox
->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
2978 pBox
->SetFillColor( Color( COL_WHITE
) );
2980 pBox
->SetFillColor( Color( COL_BLACK
) );
2987 long x
= rRect
.Left() + (rRect
.getWidth() - width
)/2 + 1;
2988 long y
= rRect
.Top() + (rRect
.getHeight() - height
)/2 + 1;
2991 pBox
->DrawRect( Rectangle( x
, y
, x
+1, y
) );
2993 pBox
->DrawRect( Rectangle( x
, y
, x
+1, y
) );
2996 if( height
<= 3) x
--;
3005 long x
= rRect
.Left() + (rRect
.getWidth() - width
)/2 + 1;
3006 long y
= rRect
.Top() + (rRect
.getHeight() - height
)/2 + 1;
3009 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+1 ) );
3011 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+1 ) );
3014 if( width
<= 3) y
--;
3020 pBox
->SetFillColor( aOldFillColor
);
3021 pBox
->SetLineColor( aOldLineColor
);
3024 static void ImplDrawDropdownArrow( ToolBox
*pBox
, const Rectangle
& rDropDownRect
, BOOL bSetColor
, BOOL bRotate
)
3026 BOOL bLineColor
= pBox
->IsLineColor();
3027 BOOL bFillColor
= pBox
->IsFillColor();
3028 Color aOldFillColor
= pBox
->GetFillColor();
3029 Color aOldLineColor
= pBox
->GetLineColor();
3030 pBox
->SetLineColor();
3034 if ( pBox
->GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
3035 pBox
->SetFillColor( Color( COL_WHITE
) );
3037 pBox
->SetFillColor( Color( COL_BLACK
) );
3044 long x
= rDropDownRect
.Left() + (rDropDownRect
.getWidth() - width
)/2;
3045 long y
= rDropDownRect
.Top() + (rDropDownRect
.getHeight() - height
)/2;
3048 pBox
->DrawRect( Rectangle( x
, y
, x
+width
-1, y
) );
3057 long x
= rDropDownRect
.Left() + (rDropDownRect
.getWidth() - width
)/2;
3058 long y
= rDropDownRect
.Top() + (rDropDownRect
.getHeight() - height
)/2;
3061 pBox
->DrawRect( Rectangle( x
, y
, x
, y
+height
-1 ) );
3068 pBox
->SetFillColor( aOldFillColor
);
3070 pBox
->SetFillColor();
3072 pBox
->SetLineColor( aOldLineColor
);
3074 pBox
->SetLineColor( );
3077 void ToolBox::ImplDrawToolArrow( ToolBox
* pBox
, long nX
, long nY
, BOOL bBlack
, BOOL bColTransform
,
3078 BOOL bLeft
, BOOL bTop
, long nSize
)
3080 Color aOldFillColor
= pBox
->GetFillColor();
3081 WindowAlign eAlign
= pBox
->meAlign
;
3085 eAlign
= WINDOWALIGN_RIGHT
;
3087 eAlign
= WINDOWALIGN_BOTTOM
;
3089 nHalfSize
= nSize
/2;
3093 case WINDOWALIGN_LEFT
:
3095 pBox
->SetFillColor( Color( bColTransform
? COL_WHITE
: COL_BLACK
) );
3096 while ( n
<= nHalfSize
)
3098 pBox
->DrawRect( Rectangle( nX
+n
, nY
+n
, nX
+n
, nY
+nSize
-n
) );
3103 pBox
->SetFillColor( aOldFillColor
);
3105 while ( n
< nHalfSize
)
3107 pBox
->DrawRect( Rectangle( nX
+n
, nY
+1+n
, nX
+n
, nY
+nSize
-1-n
) );
3112 case WINDOWALIGN_TOP
:
3114 pBox
->SetFillColor( Color( bColTransform
? COL_WHITE
: COL_BLACK
) );
3115 while ( n
<= nHalfSize
)
3117 pBox
->DrawRect( Rectangle( nX
+n
, nY
+n
, nX
+nSize
-n
, nY
+n
) );
3122 pBox
->SetFillColor( aOldFillColor
);
3124 while ( n
< nHalfSize
)
3126 pBox
->DrawRect( Rectangle( nX
+1+n
, nY
+n
, nX
+nSize
-1-n
, nY
+n
) );
3131 case WINDOWALIGN_RIGHT
:
3133 pBox
->SetFillColor( Color( bColTransform
? COL_WHITE
: COL_BLACK
) );
3134 while ( n
<= nHalfSize
)
3136 pBox
->DrawRect( Rectangle( nX
+nHalfSize
-n
, nY
+n
, nX
+nHalfSize
-n
, nY
+nSize
-n
) );
3141 pBox
->SetFillColor( aOldFillColor
);
3143 while ( n
< nHalfSize
)
3145 pBox
->DrawRect( Rectangle( nX
+nHalfSize
-n
, nY
+1+n
, nX
+nHalfSize
-n
, nY
+nSize
-1-n
) );
3150 case WINDOWALIGN_BOTTOM
:
3152 pBox
->SetFillColor( Color( bColTransform
? COL_WHITE
: COL_BLACK
) );
3153 while ( n
<= nHalfSize
)
3155 pBox
->DrawRect( Rectangle( nX
+n
, nY
+nHalfSize
-n
, nX
+nSize
-n
, nY
+nHalfSize
-n
) );
3160 pBox
->SetFillColor( aOldFillColor
);
3162 while ( n
< nHalfSize
)
3164 pBox
->DrawRect( Rectangle( nX
+1+n
, nY
+nHalfSize
-n
, nX
+nSize
-1-n
, nY
+nHalfSize
-n
) );
3172 void ToolBox::SetToolArrowClipregion( ToolBox
* pBox
, long nX
, long nY
,
3173 BOOL bLeft
, BOOL bTop
, long nSize
)
3175 WindowAlign eAlign
= pBox
->meAlign
;
3178 eAlign
= WINDOWALIGN_RIGHT
;
3180 eAlign
= WINDOWALIGN_BOTTOM
;
3182 nHalfSize
= nSize
/2;
3188 case WINDOWALIGN_LEFT
:
3189 p
[0].X() = nX
-1; p
[0].Y() = nY
-1;
3190 p
[1].X() = nX
-1; p
[1].Y() = nY
+nSize
+1;
3191 p
[2].X() = nX
+1; p
[2].Y() = nY
+nSize
+1;
3192 p
[3].X() = nX
+nHalfSize
+1; p
[3].Y() = nY
+nHalfSize
+1;
3193 p
[4].X() = nX
+nHalfSize
+1; p
[4].Y() = nY
+nHalfSize
-1;
3194 p
[5].X() = nX
+1; p
[5].Y() = nY
-1;
3196 case WINDOWALIGN_TOP
:
3197 p
[0].X() = nX
-1; p
[0].Y() = nY
-1;
3198 p
[1].X() = nX
-1; p
[1].Y() = nY
+1;
3199 p
[2].X() = nX
+nHalfSize
-1; p
[2].Y() = nY
+nHalfSize
+1;
3200 p
[3].X() = nX
+nHalfSize
+1; p
[3].Y() = nY
+nHalfSize
+1;
3201 p
[4].X() = nX
+nSize
+1; p
[4].Y() = nY
+1;
3202 p
[5].X() = nX
+nSize
+1; p
[5].Y() = nY
-1;
3204 case WINDOWALIGN_RIGHT
:
3205 p
[0].X() = nX
+nHalfSize
-1; p
[0].Y() = nY
-1;
3206 p
[1].X() = nX
-1; p
[1].Y() = nY
+nHalfSize
-1;
3207 p
[2].X() = nX
-1; p
[2].Y() = nY
+nHalfSize
+1;
3208 p
[3].X() = nX
+nHalfSize
-1; p
[3].Y() = nY
+nSize
+1;
3209 p
[4].X() = nX
+nHalfSize
+1; p
[4].Y() = nY
+nSize
+1;
3210 p
[5].X() = nX
+nHalfSize
+1; p
[5].Y() = nY
-1;
3212 case WINDOWALIGN_BOTTOM
:
3213 p
[0].X() = nX
-1; p
[0].Y() = nY
+nHalfSize
-1;
3214 p
[1].X() = nX
-1; p
[1].Y() = nY
+nHalfSize
+1;
3215 p
[2].X() = nX
+nSize
+1; p
[2].Y() = nY
+nHalfSize
+1;
3216 p
[3].X() = nX
+nSize
+1; p
[3].Y() = nY
+nHalfSize
-1;
3217 p
[4].X() = nX
+nHalfSize
+1; p
[4].Y() = nY
-1;
3218 p
[5].X() = nX
+nHalfSize
-1; p
[5].Y() = nY
-1;
3222 Region
aRgn( aPoly
);
3223 pBox
->SetClipRegion( aRgn
);
3226 // -----------------------------------------------------------------------
3228 void ToolBox::ImplDrawMenubutton( ToolBox
*pThis
, BOOL bHighlight
)
3230 if( !pThis
->mpData
->maMenubuttonItem
.maRect
.IsEmpty() )
3232 // #i53937# paint menu button only if necessary
3233 if( !(pThis
->GetMenuType() & TOOLBOX_MENUTYPE_CUSTOMIZE
) && !pThis
->ImplHasClippedItems() )
3236 // execute pending paint requests
3237 ImplCheckUpdate( pThis
);
3239 BOOL bFillColor
= pThis
->IsFillColor();
3240 BOOL bLineColor
= pThis
->IsLineColor();
3241 Color aOldFillCol
= pThis
->GetFillColor();
3242 Color aOldLineCol
= pThis
->GetLineColor();
3243 BOOL bNativeButtons
= pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
);
3245 Rectangle
aInnerRect( pThis
->mpData
->maMenubuttonItem
.maRect
);
3246 if( pThis
->mpData
->mnMenuButtonWidth
> TB_MENUBUTTON_SIZE
)
3248 long nDiff
= pThis
->mpData
->mnMenuButtonWidth
- TB_MENUBUTTON_SIZE
;
3249 long nDiff1
= nDiff
/2;
3250 long nDiff2
= nDiff
- nDiff1
;
3251 if( pThis
->IsHorizontal() )
3253 aInnerRect
.Left() += nDiff1
;
3254 aInnerRect
.Right() -= nDiff2
;
3258 aInnerRect
.Top() += nDiff1
;
3259 aInnerRect
.Bottom() -= nDiff2
;
3263 if( pThis
->IsHorizontal() )
3265 aInnerRect
.nLeft
+=2;
3266 aInnerRect
.nRight
-=1;
3268 aInnerRect
.nBottom
-=1;
3272 aInnerRect
.nLeft
+=1;
3273 aInnerRect
.nRight
-=1;
3275 aInnerRect
.nBottom
-=1;
3278 ImplErase( pThis
, bNativeButtons
? pThis
->mpData
->maMenubuttonItem
.maRect
: aInnerRect
, bHighlight
);
3282 if( bNativeButtons
)
3283 ImplDrawButton( pThis
, pThis
->mpData
->maMenubuttonItem
.maRect
, 2, FALSE
, TRUE
, FALSE
);
3285 pThis
->DrawSelectionBackground( aInnerRect
, 2, FALSE
, FALSE
, FALSE
);
3289 // improve visibility by using a dark gradient
3291 g
.SetAngle( pThis
->mbHorz
? 0 : 900 );
3292 g
.SetStyle( GRADIENT_LINEAR
);
3294 g
.SetStartColor( pThis
->GetSettings().GetStyleSettings().GetFaceColor() );
3295 g
.SetEndColor( pThis
->GetSettings().GetStyleSettings().GetShadowColor() );
3297 pThis
->DrawGradient( aInnerRect
, g
);
3300 Rectangle
aRect( aInnerRect
);
3302 aRect
.Top() = aRect
.Bottom() - aRect
.getHeight()/3;
3304 aRect
.Left() = aRect
.Right() - aRect
.getWidth()/3;
3306 if( pThis
->mpData
->maMenuType
& TOOLBOX_MENUTYPE_CUSTOMIZE
)
3307 ImplDrawDropdownArrow( pThis
, aRect
, TRUE
, !pThis
->mbHorz
);
3309 if( pThis
->ImplHasClippedItems() )
3313 aRect
.Bottom() = aRect
.Top() + aRect
.getHeight()/3;
3315 aRect
.Right() = aRect
.Left() + aRect
.getWidth()/3;
3317 ImplDrawMoreIndicator( pThis
, aRect
, TRUE
, !pThis
->mbHorz
);
3320 // store highlight state
3321 pThis
->mpData
->mbMenubuttonSelected
= bHighlight
;
3325 pThis
->SetFillColor( aOldFillCol
);
3327 pThis
->SetFillColor();
3329 pThis
->SetLineColor( aOldLineCol
);
3331 pThis
->SetLineColor();
3335 // -----------------------------------------------------------------------
3337 void ToolBox::ImplDrawSpin( BOOL bUpperIn
, BOOL bLowerIn
)
3339 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3344 if ( maUpperRect
.IsEmpty() || maLowerRect
.IsEmpty() )
3347 if ( mnCurLine
> 1 )
3352 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
3363 ImplDrawSpinButton( this, maUpperRect
, maLowerRect
,
3364 bUpperIn
, bLowerIn
, bTmpUpper
, bTmpLower
, !mbHorz
);
3367 // -----------------------------------------------------------------------
3369 void ToolBox::ImplDrawNext( BOOL bIn
)
3371 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3373 if ( maNextToolRect
.IsEmpty() )
3376 DecorationView
aDecoView( this );
3379 long nX
= SMALLBUTTON_OFF_NORMAL_X
;
3380 long nY
= SMALLBUTTON_OFF_NORMAL_Y
;
3384 nStyle
|= BUTTON_DRAW_PRESSED
;
3385 nX
= SMALLBUTTON_OFF_PRESSED_X
;
3386 nY
= SMALLBUTTON_OFF_PRESSED_Y
;
3388 aDecoView
.DrawButton( maNextToolRect
, nStyle
);
3396 nX
+= (maNextToolRect
.GetWidth()-6)/2-4;
3397 nY
+= (maNextToolRect
.GetHeight()-6)/2-6;
3402 nY
+= (maNextToolRect
.GetHeight()-6)/2-4;
3403 nX
+= (maNextToolRect
.GetWidth()-6)/2-6;
3406 nX
+= maNextToolRect
.Left();
3407 nY
+= maNextToolRect
.Top();
3409 SetFillColor( COL_LIGHTBLUE
);
3410 ImplDrawToolArrow( this, nX
, nY
, TRUE
, FALSE
, bLeft
, bTop
, 10 );
3413 // -----------------------------------------------------------------------
3415 static void ImplDrawButton( ToolBox
* pThis
, const Rectangle
&rRect
, USHORT highlight
, BOOL bChecked
, BOOL bEnabled
, BOOL bIsWindow
)
3417 // draws toolbar button background either native or using a coloured selection
3418 // if bIsWindow is TRUE, the corresponding item is a control and only a selection border will be drawn
3420 BOOL bNativeOk
= FALSE
;
3421 if( !bIsWindow
&& pThis
->IsNativeControlSupported( CTRL_TOOLBAR
, PART_BUTTON
) )
3423 ImplControlValue aControlValue
;
3424 Region
aCtrlRegion( rRect
);
3425 ControlState nState
= 0;
3427 if ( highlight
== 1 ) nState
|= CTRL_STATE_PRESSED
;
3428 if ( highlight
== 2 ) nState
|= CTRL_STATE_ROLLOVER
;
3429 if ( bEnabled
) nState
|= CTRL_STATE_ENABLED
;
3431 aControlValue
.setTristateVal( bChecked
? BUTTONVALUE_ON
: BUTTONVALUE_OFF
);
3434 bNativeOk
= pThis
->DrawNativeControl( CTRL_TOOLBAR
, PART_BUTTON
,
3435 aCtrlRegion
, nState
, aControlValue
, rtl::OUString() );
3439 pThis
->DrawSelectionBackground( rRect
, bIsWindow
? 3 : highlight
, bChecked
, TRUE
, bIsWindow
, 2, NULL
, NULL
);
3442 void ToolBox::ImplDrawItem( USHORT nPos
, BOOL bHighlight
, BOOL bPaint
, BOOL bLayout
)
3444 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3446 if( nPos
>= mpData
->m_aItems
.size() )
3449 // execute pending paint requests
3450 ImplCheckUpdate( this );
3452 ImplDisableFlatButtons();
3456 ImplToolItem
* pItem
= &mpData
->m_aItems
[nPos
];
3457 MetricVector
* pVector
= bLayout
? &mpData
->m_pLayoutData
->m_aUnicodeBoundRects
: NULL
;
3458 String
* pDisplayText
= bLayout
? &mpData
->m_pLayoutData
->m_aDisplayText
: NULL
;
3460 // Falls Rechteck ausserhalb des sichbaren Bereichs liegt
3461 if ( pItem
->maRect
.IsEmpty() )
3464 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3466 // no gradient background for items that have a popup open
3467 BOOL bHasOpenPopup
= (mpFloatWin
!= NULL
) && (mnDownItemId
==pItem
->mnId
);
3469 BOOL bHighContrastWhite
= FALSE
;
3470 // check the face color as highcontrast indicator
3471 // because the toolbox itself might have a gradient
3472 if( rStyleSettings
.GetFaceColor() == Color( COL_WHITE
) )
3473 bHighContrastWhite
= TRUE
;
3475 // draw separators in flat style only
3477 (mnOutStyle
& TOOLBOX_STYLE_FLAT
) &&
3478 (pItem
->meType
== TOOLBOXITEM_SEPARATOR
) &&
3482 // no separator before or after windows or at breaks
3483 ImplToolItem
* pTempItem
= &mpData
->m_aItems
[nPos
-1];
3484 if ( pTempItem
&& !pTempItem
->mbShowWindow
&& nPos
< mpData
->m_aItems
.size()-1 )
3486 pTempItem
= &mpData
->m_aItems
[nPos
+1];
3487 if ( !pTempItem
->mbShowWindow
&& !pTempItem
->mbBreak
)
3489 long nCenterPos
, nSlim
;
3490 SetLineColor( rStyleSettings
.GetSeparatorColor() );
3491 if ( IsHorizontal() )
3493 nSlim
= (pItem
->maRect
.Bottom() - pItem
->maRect
.Top ()) / 4;
3494 nCenterPos
= pItem
->maRect
.Center().X();
3495 DrawLine( Point( nCenterPos
, pItem
->maRect
.Top() + nSlim
),
3496 Point( nCenterPos
, pItem
->maRect
.Bottom() - nSlim
) );
3500 nSlim
= (pItem
->maRect
.Right() - pItem
->maRect
.Left ()) / 4;
3501 nCenterPos
= pItem
->maRect
.Center().Y();
3502 DrawLine( Point( pItem
->maRect
.Left() + nSlim
, nCenterPos
),
3503 Point( pItem
->maRect
.Right() - nSlim
, nCenterPos
) );
3509 // do nothing if item is no button or will be displayed as window
3510 if ( (pItem
->meType
!= TOOLBOXITEM_BUTTON
) ||
3511 (pItem
->mbShowWindow
&& !mbCustomizeMode
) )
3514 // we need a TBDragMananger to draw the configuration item
3515 ImplTBDragMgr
* pMgr
;
3516 if ( pItem
->mnId
== mnConfigItem
)
3518 pMgr
= ImplGetTBDragMgr();
3519 pMgr
->HideDragRect();
3524 // during configuration mode visible windows will be drawn in a special way
3525 if ( mbCustomizeMode
&& pItem
->mbShowWindow
)
3527 Font aOldFont
= GetFont();
3528 Color aOldTextColor
= GetTextColor();
3530 SetZoomedPointFont( rStyleSettings
.GetAppFont() );
3531 SetLineColor( Color( COL_BLACK
) );
3532 SetFillColor( rStyleSettings
.GetFieldColor() );
3533 SetTextColor( rStyleSettings
.GetFieldTextColor() );
3535 DrawRect( pItem
->maRect
);
3537 Size
aSize( GetCtrlTextWidth( pItem
->maText
), GetTextHeight() );
3538 Point
aPos( pItem
->maRect
.Left()+2, pItem
->maRect
.Top() );
3539 aPos
.Y() += (pItem
->maRect
.GetHeight()-aSize
.Height())/2;
3541 if ( (aSize
.Width() > pItem
->maRect
.GetWidth()-2) ||
3542 (aSize
.Height() > pItem
->maRect
.GetHeight()-2) )
3545 Rectangle
aTempRect( pItem
->maRect
.Left()+1, pItem
->maRect
.Top()+1,
3546 pItem
->maRect
.Right()-1, pItem
->maRect
.Bottom()-1 );
3547 Region
aTempRegion( aTempRect
);
3548 SetClipRegion( aTempRegion
);
3554 mpData
->m_pLayoutData
->m_aLineIndices
.push_back( mpData
->m_pLayoutData
->m_aDisplayText
.Len() );
3555 mpData
->m_pLayoutData
->m_aLineItemIds
.push_back( pItem
->mnId
);
3556 mpData
->m_pLayoutData
->m_aLineItemPositions
.push_back( nPos
);
3558 DrawCtrlText( aPos
, pItem
->maText
, 0, STRING_LEN
, TEXT_DRAW_MNEMONIC
, pVector
, pDisplayText
);
3561 SetFont( aOldFont
);
3562 SetTextColor( aOldTextColor
);
3564 // Gegebenenfalls noch Config-Frame zeichnen
3565 if ( pMgr
&& !bLayout
)
3566 pMgr
->UpdateDragRect();
3571 Size aBtnSize
= pItem
->maRect
.GetSize();
3572 if( ImplGetSVData()->maNWFData
.mbToolboxDropDownSeparate
)
3574 // separate button not for dropdown only where the whole button is painted
3575 if ( pItem
->mnBits
& TIB_DROPDOWN
&&
3576 ((pItem
->mnBits
& TIB_DROPDOWNONLY
) != TIB_DROPDOWNONLY
) )
3578 Rectangle aArrowRect
= pItem
->GetDropDownRect( mbHorz
);
3579 if( aArrowRect
.Top() == pItem
->maRect
.Top() ) // dropdown arrow on right side
3580 aBtnSize
.Width() -= aArrowRect
.GetWidth();
3581 else // dropdown arrow on bottom side
3582 aBtnSize
.Height() -= aArrowRect
.GetHeight();
3585 Rectangle
aButtonRect( pItem
->maRect
.TopLeft(), aBtnSize
);
3586 long nOffX
= SMALLBUTTON_OFF_NORMAL_X
;
3587 long nOffY
= SMALLBUTTON_OFF_NORMAL_Y
;
3594 if ( pItem
->meState
== STATE_CHECK
)
3596 nStyle
|= BUTTON_DRAW_CHECKED
;
3598 else if ( pItem
->meState
== STATE_DONTKNOW
)
3600 nStyle
|= BUTTON_DRAW_DONTKNOW
;
3602 if ( bHighlight
== 1 )
3604 nStyle
|= BUTTON_DRAW_PRESSED
;
3607 if ( mnOutStyle
& TOOLBOX_STYLE_OUTBUTTON
)
3609 nOffX
= OUTBUTTON_OFF_NORMAL_X
;
3610 nOffY
= OUTBUTTON_OFF_NORMAL_Y
;
3620 if ( mnOutStyle
& TOOLBOX_STYLE_FLAT
)
3622 if ( (pItem
->meState
!= STATE_NOCHECK
) || !bPaint
)
3624 ImplErase( this, pItem
->maRect
, bHighlight
, bHasOpenPopup
);
3629 if ( mnOutStyle
& TOOLBOX_STYLE_OUTBUTTON
)
3630 ImplDrawOutButton( this, aButtonRect
, nStyle
);
3633 DecorationView
aDecoView( this );
3634 aDecoView
.DrawButton( aButtonRect
, nStyle
);
3639 nOffX
+= pItem
->maRect
.Left();
3640 nOffY
+= pItem
->maRect
.Top();
3642 // determine what has to be drawn on the button: image, text or both
3645 ButtonType tmpButtonType
= determineButtonType( pItem
, meButtonType
); // default to toolbox setting
3646 pItem
->DetermineButtonDrawStyle( tmpButtonType
, bImage
, bText
);
3648 // compute output values
3649 long nBtnWidth
= aBtnSize
.Width()-SMALLBUTTON_HSIZE
;
3650 long nBtnHeight
= aBtnSize
.Height()-SMALLBUTTON_VSIZE
;
3656 aTxtSize
.Width() = GetCtrlTextWidth( pItem
->maText
);
3657 aTxtSize
.Height() = GetTextHeight();
3660 if ( bImage
&& ! bLayout
)
3662 const Image
* pImage
;
3663 if ( bHighlight
&& (!(pItem
->maHighImage
)) == FALSE
)
3664 pImage
= &(pItem
->maHighImage
);
3666 pImage
= &(pItem
->maImage
);
3668 aImageSize
= pImage
->GetSizePixel();
3670 // determine drawing flags
3671 USHORT nImageStyle
= 0;
3673 if ( !pItem
->mbEnabled
|| !IsEnabled() )
3674 nImageStyle
|= IMAGE_DRAW_DISABLE
;
3676 // #i35563# the dontknow state indicates different states at the same time
3677 // which should not be rendered disabled but normal
3678 //if ( pItem->meState == STATE_DONTKNOW )
3679 // nImageStyle |= IMAGE_DRAW_DISABLE;
3684 if ( (pItem
->mnBits
& (TIB_LEFT
|TIB_DROPDOWN
)) || bText
)
3686 // left align also to leave space for drop down arrow
3687 // and when drawing text+image
3688 // just center in y, except for vertical (ie rotated text)
3689 if( mbHorz
|| !bText
)
3690 nImageOffY
+= (nBtnHeight
-aImageSize
.Height())/2;
3694 nImageOffX
+= (nBtnWidth
-aImageSize
.Width())/2;
3695 nImageOffY
+= (nBtnHeight
-aImageSize
.Height())/2;
3697 if ( bHighlight
|| (pItem
->meState
== STATE_CHECK
) )
3700 ImplDrawFloatwinBorder( pItem
);
3702 ImplDrawButton( this, aButtonRect
, bHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), pItem
->mbShowWindow
? TRUE
: FALSE
);
3706 if( bHighContrastWhite
)
3707 nImageStyle
|= IMAGE_DRAW_COLORTRANSFORM
;
3710 DrawImage( Point( nImageOffX
, nImageOffY
), *pImage
, nImageStyle
);
3714 BOOL bRotate
= FALSE
;
3720 // rotate text when vertically docked
3721 Font aOldFont
= GetFont();
3722 if( pItem
->mbVisibleText
&& !ImplIsFloatingMode() &&
3723 ((meAlign
== WINDOWALIGN_LEFT
) || (meAlign
== WINDOWALIGN_RIGHT
)) )
3727 Font aRotateFont
= aOldFont
;
3729 if ( meAlign == WINDOWALIGN_LEFT )
3731 aRotateFont.SetOrientation( 900 );
3732 nTextOffX += (nBtnWidth-aTxtSize.Height())/2;
3733 nTextOffY += aTxtSize.Width();
3734 nTextOffY += (nBtnHeight-aTxtSize.Width())/2;
3738 aRotateFont
.SetOrientation( 2700 );
3740 // center horizontally
3741 nTextOffX
+= aTxtSize
.Height();
3742 nTextOffX
+= (nBtnWidth
-aTxtSize
.Height())/2;
3744 // add in image offset
3746 nTextOffY
= nImageOffY
+ aImageSize
.Height() + TB_IMAGETEXTOFFSET
;
3749 SetFont( aRotateFont
);
3753 // center vertically
3754 nTextOffY
+= (nBtnHeight
-aTxtSize
.Height())/2;
3756 // add in image offset
3758 nTextOffX
= nImageOffX
+ aImageSize
.Width() + TB_IMAGETEXTOFFSET
;
3759 //nTextOffX += TB_TEXTOFFSET/2;
3762 // draw selection only if not already drawn during image output (see above)
3763 if ( !bLayout
&& !bImage
&& (bHighlight
|| (pItem
->meState
== STATE_CHECK
) ) )
3766 ImplDrawFloatwinBorder( pItem
);
3768 ImplDrawButton( this, pItem
->maRect
, bHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), pItem
->mbShowWindow
? TRUE
: FALSE
);
3771 USHORT nTextStyle
= 0;
3772 if ( !pItem
->mbEnabled
)
3773 nTextStyle
|= TEXT_DRAW_DISABLE
;
3776 mpData
->m_pLayoutData
->m_aLineIndices
.push_back( mpData
->m_pLayoutData
->m_aDisplayText
.Len() );
3777 mpData
->m_pLayoutData
->m_aLineItemIds
.push_back( pItem
->mnId
);
3778 mpData
->m_pLayoutData
->m_aLineItemPositions
.push_back( nPos
);
3780 DrawCtrlText( Point( nTextOffX
, nTextOffY
), pItem
->maText
,
3781 0, STRING_LEN
, nTextStyle
, pVector
, pDisplayText
);
3783 SetFont( aOldFont
);
3789 // paint optional drop down arrow
3790 if ( pItem
->mnBits
& TIB_DROPDOWN
)
3792 Rectangle
aDropDownRect( pItem
->GetDropDownRect( mbHorz
) );
3793 BOOL bSetColor
= TRUE
;
3794 if ( !pItem
->mbEnabled
|| !IsEnabled() )
3797 SetFillColor( rStyleSettings
.GetShadowColor() );
3800 // dropdown only will be painted without inner border
3801 if( (pItem
->mnBits
& TIB_DROPDOWNONLY
) != TIB_DROPDOWNONLY
)
3803 ImplErase( this, aDropDownRect
, bHighlight
, bHasOpenPopup
);
3805 if( bHighlight
|| (pItem
->meState
== STATE_CHECK
) )
3808 ImplDrawFloatwinBorder( pItem
);
3810 ImplDrawButton( this, aDropDownRect
, bHighlight
, pItem
->meState
== STATE_CHECK
, pItem
->mbEnabled
&& IsEnabled(), FALSE
);
3813 ImplDrawDropdownArrow( this, aDropDownRect
, bSetColor
, bRotate
);
3816 // Gegebenenfalls noch Config-Frame zeichnen
3818 pMgr
->UpdateDragRect();
3821 // -----------------------------------------------------------------------
3823 void ToolBox::ImplStartCustomizeMode()
3825 mbCustomizeMode
= TRUE
;
3827 mpData
->ImplClearLayoutData();
3829 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3830 while ( it
!= mpData
->m_aItems
.end() )
3832 if ( it
->mbShowWindow
)
3834 it
->mpWindow
->Hide();
3836 if ( !(it
->maRect
.IsEmpty()) )
3837 Invalidate( it
->maRect
);
3844 void ToolBox::SetCustomizeMode( BOOL bSet
)
3847 ImplStartCustomizeMode();
3849 ImplEndCustomizeMode();
3852 // -----------------------------------------------------------------------
3854 void ToolBox::ImplEndCustomizeMode()
3856 mbCustomizeMode
= FALSE
;
3858 mpData
->ImplClearLayoutData();
3860 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
3861 while ( it
!= mpData
->m_aItems
.end() )
3863 if ( it
->mbShowWindow
)
3865 if ( !(it
->maRect
.IsEmpty()) )
3866 Invalidate( it
->maRect
);
3868 it
->mpWindow
->Show();
3875 // -----------------------------------------------------------------------
3877 void ToolBox::ImplDrawFloatwinBorder( ImplToolItem
* pItem
)
3879 if ( !pItem
->maRect
.IsEmpty() )
3881 Rectangle
aRect( mpFloatWin
->ImplGetItemEdgeClipRect() );
3882 aRect
.SetPos( AbsoluteScreenToOutputPixel( aRect
.TopLeft() ) );
3883 SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() );
3886 p1
= pItem
->maRect
.TopLeft();
3888 p2
= pItem
->maRect
.TopRight();
3891 p1
= pItem
->maRect
.BottomLeft();
3893 p2
= pItem
->maRect
.BottomRight();
3897 p1
= pItem
->maRect
.TopLeft();
3899 p2
= pItem
->maRect
.BottomLeft();
3902 p1
= pItem
->maRect
.TopRight();
3904 p2
= pItem
->maRect
.BottomRight();
3908 //DrawRect( pItem->maRect );
3912 void ToolBox::ImplFloatControl( BOOL bStart
, FloatingWindow
* pFloatWindow
)
3914 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3918 mpFloatWin
= pFloatWindow
;
3920 // redraw item, to trigger drawing of a special border
3921 ImplDrawItem( mnCurPos
, TRUE
);
3931 // if focus is still in this toolbox, then the floater was opened by keyboard
3932 // draw current item with highlight and keep old state
3933 BOOL bWasKeyboardActivate
= mpData
->mbDropDownByKeyboard
;
3936 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3937 ImplDrawItem( mnCurPos
, bWasKeyboardActivate
? 2 : 0 );
3940 if( !bWasKeyboardActivate
)
3942 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
3951 // -----------------------------------------------------------------------
3953 void ToolBox::ShowLine( BOOL bNext
)
3955 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
3959 if ( mpData
->mbPageScroll
)
3961 USHORT delta
= mnVisLines
;
3964 mnCurLine
= mnCurLine
+ delta
;
3965 if ( mnCurLine
+mnVisLines
-1 > mnCurLines
)
3966 mnCurLine
= mnCurLines
- mnVisLines
+1;
3970 if( mnCurLine
>= delta
+1 )
3971 mnCurLine
= mnCurLine
- delta
;
3987 // -----------------------------------------------------------------------
3989 BOOL
ToolBox::ImplHandleMouseMove( const MouseEvent
& rMEvt
, BOOL bRepeat
)
3991 Point aMousePos
= rMEvt
.GetPosPixel();
3993 // Ist ToolBox aktiv
3994 if ( mbDrag
&& mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
3996 // Befindet sich Maus ueber dem Item
3997 ImplToolItem
* pItem
= &mpData
->m_aItems
[mnCurPos
];
3998 if ( pItem
->maRect
.IsInside( aMousePos
) )
4002 ImplDrawItem( mnCurPos
, TRUE
);
4003 mnCurItemId
= pItem
->mnId
;
4007 if ( (pItem
->mnBits
& TIB_REPEAT
) && bRepeat
)
4014 ImplDrawItem( mnCurPos
);
4016 ImplDrawItem( mnCurPos
);
4026 BOOL bNewIn
= maUpperRect
.IsInside( aMousePos
);
4027 if ( bNewIn
!= mbIn
)
4030 ImplDrawSpin( mbIn
, FALSE
);
4037 BOOL bNewIn
= maLowerRect
.IsInside( aMousePos
);
4038 if ( bNewIn
!= mbIn
)
4041 ImplDrawSpin( FALSE
, mbIn
);
4048 BOOL bNewIn
= maNextToolRect
.IsInside( aMousePos
);
4049 if ( bNewIn
!= mbIn
)
4052 ImplDrawNext( mbIn
);
4060 // -----------------------------------------------------------------------
4062 BOOL
ToolBox::ImplHandleMouseButtonUp( const MouseEvent
& rMEvt
, BOOL bCancel
)
4064 ImplDisableFlatButtons();
4066 // stop eventual running dropdown timer
4067 if( mnCurPos
< mpData
->m_aItems
.size() &&
4068 (mpData
->m_aItems
[mnCurPos
].mnBits
& TIB_DROPDOWN
) )
4070 mpData
->maDropdownTimer
.Stop();
4073 if ( mbDrag
|| mbSelection
)
4075 // Hier die MouseDaten setzen, wenn Selection-Modus, da dann kein
4076 // MouseButtonDown-Handler gerufen wird
4079 mnMouseClicks
= rMEvt
.GetClicks();
4080 mnMouseModifier
= rMEvt
.GetModifier();
4089 mbSelection
= FALSE
;
4090 if ( mnCurPos
== TOOLBOX_ITEM_NOTFOUND
)
4094 // Wurde Maus ueber dem Item losgelassen
4095 if( mnCurPos
< mpData
->m_aItems
.size() )
4097 ImplToolItem
* pItem
= &mpData
->m_aItems
[mnCurPos
];
4098 if ( pItem
->maRect
.IsInside( rMEvt
.GetPosPixel() ) )
4100 mnCurItemId
= pItem
->mnId
;
4103 // Gegebenenfalls ein AutoCheck durchfuehren
4104 if ( pItem
->mnBits
& TIB_AUTOCHECK
)
4106 if ( pItem
->mnBits
& TIB_RADIOCHECK
)
4108 if ( pItem
->meState
!= STATE_CHECK
)
4109 SetItemState( pItem
->mnId
, STATE_CHECK
);
4113 if ( pItem
->meState
!= STATE_CHECK
)
4114 pItem
->meState
= STATE_CHECK
;
4116 pItem
->meState
= STATE_NOCHECK
;
4120 // Select nicht bei Repeat ausloesen, da dies schon im
4121 // MouseButtonDown ausgeloest wurde
4122 if ( !(pItem
->mnBits
& TIB_REPEAT
) )
4124 // Gegen zerstoeren im Select-Handler sichern
4125 ImplDelData aDelData
;
4126 ImplAddDel( &aDelData
);
4128 if ( aDelData
.IsDelete() )
4130 ImplRemoveDel( &aDelData
);
4135 DBG_CHKTHIS( Window
, ImplDbgCheckWindow
);
4138 // Items nicht geloescht, im Select-Handler
4142 if ( (mnCurItemId
== mnHighItemId
) && (mnOutStyle
& TOOLBOX_STYLE_FLAT
) )
4146 // Get current pos for the case that items are inserted/removed
4148 mnCurPos
= GetItemPos( mnCurItemId
);
4149 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
4151 ImplDrawItem( mnCurPos
, bHighlight
);
4158 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
4162 mnMouseModifier
= 0;
4165 else if ( mbUpper
|| mbLower
)
4168 ShowLine( !mbUpper
);
4172 ImplDrawSpin( FALSE
, FALSE
);
4175 else if ( mbNextTool
)
4179 ImplDrawNext( FALSE
);
4187 // -----------------------------------------------------------------------
4189 void ToolBox::MouseMove( const MouseEvent
& rMEvt
)
4191 // pressing a modifier generates synthetic mouse moves
4192 // ignore it if keyboard selection is acive
4193 if( HasFocus() && ( rMEvt
.GetMode() & MOUSE_MODIFIERCHANGED
) )
4196 if ( ImplHandleMouseMove( rMEvt
) )
4199 ImplDisableFlatButtons();
4201 Point aMousePos
= rMEvt
.GetPosPixel();
4203 // only highlight when the focus is not inside a child window of a toolbox
4204 // eg, in a edit control
4205 // and do not hilight when focus is in a different toolbox
4206 BOOL bDrawHotSpot
= TRUE
;
4207 Window
*pWin
= Application::GetFocusWindow();
4208 if( pWin
&& pWin
->ImplGetWindowImpl()->mbToolBox
&& pWin
!= this )
4209 bDrawHotSpot
= FALSE
;
4212 if( pWin && !pWin->ImplGetWindowImpl()->mbToolBox )
4215 pWin = pWin->GetParent();
4216 if( pWin && pWin->ImplGetWindowImpl()->mbToolBox )
4218 bDrawHotSpot = FALSE;
4224 if ( mbSelection
&& bDrawHotSpot
)
4227 USHORT nNewPos
= TOOLBOX_ITEM_NOTFOUND
;
4229 // Item suchen, das geklickt wurde
4230 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4231 while ( it
!= mpData
->m_aItems
.end() )
4233 // Wenn Mausposition in diesem Item vorhanden, kann die
4234 // Suche abgebrochen werden
4235 if ( it
->maRect
.IsInside( aMousePos
) )
4237 // Wenn es ein Button ist, dann wird er selektiert
4238 if ( it
->meType
== TOOLBOXITEM_BUTTON
)
4240 // Wenn er disablet ist, findet keine Aenderung
4242 if ( !it
->mbEnabled
|| it
->mbShowWindow
)
4255 // was a new entery selected ?
4256 // don't change selection if keyboard selection is active and
4257 // mouse leaves the toolbox
4258 if ( nNewPos
!= mnCurPos
&& !( HasFocus() && nNewPos
== TOOLBOX_ITEM_NOTFOUND
) )
4260 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
4262 ImplDrawItem( mnCurPos
);
4263 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( mnCurPos
) );
4267 if ( mnCurPos
!= TOOLBOX_ITEM_NOTFOUND
)
4269 mnCurItemId
= mnHighItemId
= it
->mnId
;
4270 ImplDrawItem( mnCurPos
, 2 /*TRUE*/ ); // always use shadow effect (2)
4273 mnCurItemId
= mnHighItemId
= 0;
4282 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4283 pMgr
->Dragging( aMousePos
);
4287 PointerStyle eStyle
= POINTER_ARROW
;
4289 // change mouse cursor over drag area
4290 ImplDockingWindowWrapper
*pWrapper
= ImplGetDockingManager()->GetDockingWindowWrapper( this );
4291 if( pWrapper
&& pWrapper
->GetDragArea().IsInside( rMEvt
.GetPosPixel() ) )
4292 eStyle
= POINTER_MOVE
;
4294 if ( (mnWinStyle
& TB_WBLINESIZING
) == TB_WBLINESIZING
)
4296 if ( rMEvt
.GetMode() & MOUSE_SIMPLEMOVE
)
4298 USHORT nLinePtr
= ImplTestLineSize( this, rMEvt
.GetPosPixel() );
4299 if ( nLinePtr
& DOCK_LINEHSIZE
)
4301 if ( meAlign
== WINDOWALIGN_LEFT
)
4302 eStyle
= POINTER_WINDOW_ESIZE
;
4304 eStyle
= POINTER_WINDOW_WSIZE
;
4306 else if ( nLinePtr
& DOCK_LINEVSIZE
)
4308 if ( meAlign
== WINDOWALIGN_TOP
)
4309 eStyle
= POINTER_WINDOW_SSIZE
;
4311 eStyle
= POINTER_WINDOW_NSIZE
;
4316 if ( (eStyle
== POINTER_ARROW
) && mbCustomizeMode
)
4318 // Item suchen, das geklickt wurde
4319 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4320 while ( it
!= mpData
->m_aItems
.end() )
4322 // Wenn es ein Customize-Window ist, gegebenenfalls den
4323 // Resize-Pointer anzeigen
4324 if ( it
->mbShowWindow
)
4326 if ( it
->maRect
.IsInside( aMousePos
) )
4328 if ( it
->maRect
.Right()-TB_RESIZE_OFFSET
<= aMousePos
.X() )
4329 eStyle
= POINTER_HSIZEBAR
;
4338 if ( bDrawHotSpot
&& ( ((eStyle
== POINTER_ARROW
) && (mnOutStyle
& TOOLBOX_STYLE_HANDPOINTER
)) ||
4339 (mnOutStyle
& TOOLBOX_STYLE_FLAT
) || !mnOutStyle
) )
4341 BOOL bClearHigh
= TRUE
;
4342 if ( !rMEvt
.IsLeaveWindow() && (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
4344 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4345 while ( it
!= mpData
->m_aItems
.end() )
4347 if ( it
->maRect
.IsInside( aMousePos
) )
4349 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) && it
->mbEnabled
)
4351 if ( !mnOutStyle
|| (mnOutStyle
& TOOLBOX_STYLE_FLAT
) )
4354 if ( mnHighItemId
!= it
->mnId
)
4356 USHORT nTempPos
= sal::static_int_cast
<USHORT
>(it
- mpData
->m_aItems
.begin());
4360 USHORT nPos
= GetItemPos( mnHighItemId
);
4361 ImplDrawItem( nPos
);
4362 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nPos
) );
4364 if ( mpData
->mbMenubuttonSelected
)
4366 // remove highlight from menubutton
4367 ImplDrawMenubutton( this, FALSE
);
4369 mnHighItemId
= it
->mnId
;
4370 ImplDrawItem( nTempPos
, 2 );
4372 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT
);
4375 if ( mnOutStyle
& TOOLBOX_STYLE_HANDPOINTER
)
4376 eStyle
= POINTER_REFHAND
;
4385 // only clear highlight when focus is not in toolbar
4386 BOOL bMenuButtonHit
= mpData
->maMenubuttonItem
.maRect
.IsInside( aMousePos
);
4387 if ( bClearHigh
|| bMenuButtonHit
)
4389 if ( !bMenuButtonHit
&& mpData
->mbMenubuttonSelected
)
4391 // remove highlight from menubutton
4392 ImplDrawMenubutton( this, FALSE
);
4397 USHORT nClearPos
= GetItemPos( mnHighItemId
);
4398 if ( nClearPos
!= TOOLBOX_ITEM_NOTFOUND
)
4400 ImplDrawItem( nClearPos
, (nClearPos
== mnCurPos
) ? TRUE
: FALSE
);
4401 if( nClearPos
!= mnCurPos
)
4402 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nClearPos
) );
4408 if( bMenuButtonHit
)
4410 ImplDrawMenubutton( this, TRUE
);
4415 if ( meLastStyle
!= eStyle
)
4417 meLastStyle
= eStyle
;
4418 Pointer
aPtr( eStyle
);
4422 DockingWindow::MouseMove( rMEvt
);
4425 // -----------------------------------------------------------------------
4427 void ToolBox::MouseButtonDown( const MouseEvent
& rMEvt
)
4429 // Nur bei linker Maustaste ToolBox ausloesen und wenn wir uns nicht
4430 // noch in der normalen Bearbeitung befinden
4431 if ( rMEvt
.IsLeft() && !mbDrag
&& (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
4433 // Activate schon hier rufen, da gegebenenfalls noch Items
4434 // ausgetauscht werden
4437 // ToolBox hier updaten, damit der Anwender weiss, was Sache ist
4444 Point aMousePos
= rMEvt
.GetPosPixel();
4446 USHORT nNewPos
= TOOLBOX_ITEM_NOTFOUND
;
4448 // Item suchen, das geklickt wurde
4449 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4450 while ( it
!= mpData
->m_aItems
.end() )
4452 // Ist es dieses Item
4453 if ( it
->maRect
.IsInside( aMousePos
) )
4455 // Ist es ein Separator oder ist das Item disabled,
4456 // dann mache nichts
4457 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) &&
4458 (!it
->mbShowWindow
|| mbCustomizeMode
) )
4469 if ( nNewPos
!= TOOLBOX_ITEM_NOTFOUND
)
4473 if ( rMEvt
.IsMod2() || mbCustomizeMode
)
4477 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4478 Rectangle aItemRect
= GetItemRect( it
->mnId
);
4479 mnConfigItem
= it
->mnId
;
4482 if ( mbCustomizeMode
&& it
->mbShowWindow
&&
4483 (it
->maRect
.Right()-TB_RESIZE_OFFSET
<= aMousePos
.X()) )
4486 bResizeItem
= FALSE
;
4487 pMgr
->StartDragging( this, aMousePos
, aItemRect
, 0, bResizeItem
);
4492 if ( !it
->mbEnabled
)
4499 // Aktuelle Daten setzen
4500 USHORT nTrackFlags
= 0;
4502 mnCurItemId
= it
->mnId
;
4503 mnDownItemId
= mnCurItemId
;
4504 mnMouseClicks
= rMEvt
.GetClicks();
4505 mnMouseModifier
= rMEvt
.GetModifier();
4506 if ( it
->mnBits
& TIB_REPEAT
)
4507 nTrackFlags
|= STARTTRACK_BUTTONREPEAT
;
4512 ImplDrawItem( mnCurPos
, TRUE
);
4517 // Hier schon bDrag setzen, da in EndSelection ausgewertet wird
4520 // Bei Doppelklick nur den Handler rufen, aber bevor der
4521 // Button gehiltet wird, da evt. in diesem Handler der
4522 // Drag-Vorgang abgebrochen wird
4523 if ( rMEvt
.GetClicks() == 2 )
4529 ImplDrawItem( mnCurPos
, TRUE
);
4533 // was dropdown arrow pressed
4534 if( (it
->mnBits
& TIB_DROPDOWN
) )
4536 if( ( (it
->mnBits
& TIB_DROPDOWNONLY
) == TIB_DROPDOWNONLY
) || it
->GetDropDownRect( mbHorz
).IsInside( aMousePos
))
4538 // dropdownonly always triggers the dropdown handler, over the whole button area
4540 // the drop down arrow should not trigger the item action
4541 mpData
->mbDropDownByKeyboard
= FALSE
;
4542 GetDropdownClickHdl().Call( this );
4544 // do not reset data if the dropdown handler opened a floating window
4545 // see ImplFloatControl()
4546 if( mpFloatWin
== NULL
)
4548 // no floater was opened
4550 ImplDrawItem( mnCurPos
, FALSE
);
4552 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
4556 mnMouseModifier
= 0;
4561 else // activate long click timer
4562 mpData
->maDropdownTimer
.Start();
4566 // Click-Handler aufrufen
4567 if ( rMEvt
.GetClicks() != 2 )
4570 // Bei Repeat auch den Select-Handler rufen
4571 if ( nTrackFlags
& STARTTRACK_BUTTONREPEAT
)
4574 // Wenn die Aktion nicht im Click-Handler abgebrochen wurde
4576 StartTracking( nTrackFlags
);
4579 // Wenn Maus ueber einem Item gedrueckt wurde, koennen wir
4580 // die Bearbeitung abbrechen
4586 // menu button hit ?
4587 if( mpData
->maMenubuttonItem
.maRect
.IsInside( aMousePos
) )
4589 ExecuteCustomMenu();
4594 // Gegebenenfalls noch Scroll- und Next-Buttons ueberpruefen
4595 if ( maUpperRect
.IsInside( aMousePos
) )
4597 if ( mnCurLine
> 1 )
4602 ImplDrawSpin( TRUE
, FALSE
);
4606 if ( maLowerRect
.IsInside( aMousePos
) )
4608 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
4613 ImplDrawSpin( FALSE
, TRUE
);
4617 if ( maNextToolRect
.IsInside( aMousePos
) )
4622 ImplDrawNext( TRUE
);
4626 // Linesizing testen
4627 if ( (mnWinStyle
& TB_WBLINESIZING
) == TB_WBLINESIZING
)
4629 USHORT nLineMode
= ImplTestLineSize( this, aMousePos
);
4632 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4634 // Handler rufen, damit die Dock-Rectangles gesetzt werden
4638 Point aPos
= GetParent()->OutputToScreenPixel( GetPosPixel() );
4639 Size aSize
= GetSizePixel();
4640 aPos
= ScreenToOutputPixel( aPos
);
4643 pMgr
->StartDragging( this, aMousePos
, Rectangle( aPos
, aSize
),
4649 // Kein Item, dann nur Click oder DoubleClick
4650 if ( rMEvt
.GetClicks() == 2 )
4656 if ( !mbDrag
&& !mbSelection
&& (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
4657 DockingWindow::MouseButtonDown( rMEvt
);
4660 // -----------------------------------------------------------------------
4662 void ToolBox::MouseButtonUp( const MouseEvent
& rMEvt
)
4664 if ( ImplHandleMouseButtonUp( rMEvt
) )
4667 if ( mbDragging
&& (rMEvt
.IsLeft() || mbCommandDrag
) )
4669 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
4670 pMgr
->EndDragging();
4673 mbCommandDrag
= FALSE
;
4675 DockingWindow::MouseButtonUp( rMEvt
);
4678 // -----------------------------------------------------------------------
4680 void ToolBox::Tracking( const TrackingEvent
& rTEvt
)
4682 ImplDelData aDelData
;
4683 ImplAddDel( &aDelData
);
4685 if ( rTEvt
.IsTrackingEnded() )
4686 ImplHandleMouseButtonUp( rTEvt
.GetMouseEvent(), rTEvt
.IsTrackingCanceled() );
4688 ImplHandleMouseMove( rTEvt
.GetMouseEvent(), rTEvt
.IsTrackingRepeat() );
4690 if ( aDelData
.IsDelete() )
4691 // toolbox was deleted
4693 ImplRemoveDel( &aDelData
);
4694 DockingWindow::Tracking( rTEvt
);
4697 // -----------------------------------------------------------------------
4699 void ToolBox::Paint( const Rectangle
& rPaintRect
)
4701 if( mpData
->mbIsPaintLocked
)
4703 if ( rPaintRect
== Rectangle( 0, 0, mnDX
-1, mnDY
-1 ) )
4706 mbFullPaint
= FALSE
;
4709 ImplDrawBackground( this, rPaintRect
);
4711 if ( (mnWinStyle
& WB_BORDER
) && !ImplIsFloatingMode() )
4712 ImplDrawBorder( this );
4714 if( !ImplIsFloatingMode() )
4715 ImplDrawGrip( this );
4717 ImplDrawMenubutton( this, mpData
->mbMenubuttonSelected
);
4719 // SpinButtons zeichnen
4720 if ( mnWinStyle
& WB_SCROLL
)
4722 if ( mnCurLines
> mnLines
)
4723 ImplDrawSpin( FALSE
, FALSE
);
4726 // NextButton zeichnen
4727 ImplDrawNext( FALSE
);
4732 nHighPos
= GetItemPos( mnHighItemId
);
4734 nHighPos
= TOOLBOX_ITEM_NOTFOUND
;
4736 USHORT nCount
= (USHORT
)mpData
->m_aItems
.size();
4737 for( USHORT i
= 0; i
< nCount
; i
++ )
4739 ImplToolItem
* pItem
= &mpData
->m_aItems
[i
];
4741 // Nur malen, wenn Rechteck im PaintRectangle liegt
4742 if ( !pItem
->maRect
.IsEmpty() && rPaintRect
.IsOver( pItem
->maRect
) )
4744 BOOL bHighlight
= FALSE
;
4745 if ( i
== mnCurPos
)
4747 else if ( i
== nHighPos
)
4749 ImplDrawItem( i
, bHighlight
);
4755 // -----------------------------------------------------------------------
4757 void ToolBox::Move()
4759 DockingWindow::Move();
4762 // -----------------------------------------------------------------------
4764 void ToolBox::Resize()
4766 Size aSize
= GetOutputSizePixel();
4767 // #i31422# some WindowManagers send (0,0) sizes when
4768 // switching virtual desktops - ignore this and avoid reformatting
4769 if( !aSize
.Width() && !aSize
.Height() )
4774 mnDX
= aSize
.Width();
4775 mnDY
= aSize
.Height();
4779 // invalidate everything to have gradient backgrounds properly drawn
4782 // Evt. neu formatieren oder neu painten
4788 if( IsReallyVisible() )
4793 // Border muss neu ausgegeben werden
4794 if ( mnWinStyle
& WB_BORDER
)
4796 // Da wir sonst beim Paint denken, das alles neu gepaintet wird
4797 if ( mbFormat
&& IsReallyVisible() )
4801 if ( mnRightBorder
)
4803 if ( nOldDX
> mnDX
)
4804 Invalidate( Rectangle( mnDX
-mnRightBorder
-1, 0, mnDX
, mnDY
) );
4806 Invalidate( Rectangle( nOldDX
-mnRightBorder
-1, 0, nOldDX
, nOldDY
) );
4809 if ( mnBottomBorder
)
4811 if ( nOldDY
> mnDY
)
4812 Invalidate( Rectangle( 0, mnDY
-mnBottomBorder
-1, mnDX
, mnDY
) );
4814 Invalidate( Rectangle( 0, nOldDY
-mnBottomBorder
-1, nOldDX
, nOldDY
) );
4820 // -----------------------------------------------------------------------
4821 const XubString
& ToolBox::ImplGetHelpText( USHORT nItemId
) const
4823 ImplToolItem
* pItem
= ImplGetItem( nItemId
);
4827 if ( !pItem
->maHelpText
.Len() && ( pItem
->mnHelpId
|| pItem
->maCommandStr
.Len() ))
4829 Help
* pHelp
= Application::GetHelp();
4832 if ( pItem
->maCommandStr
.Len() )
4833 pItem
->maHelpText
= pHelp
->GetHelpText( pItem
->maCommandStr
, this );
4834 if ( !pItem
->maHelpText
.Len() && pItem
->mnHelpId
)
4835 pItem
->maHelpText
= pHelp
->GetHelpText( pItem
->mnHelpId
, this );
4839 return pItem
->maHelpText
;
4842 return ImplGetSVEmptyStr();
4845 // -----------------------------------------------------------------------
4847 void ToolBox::RequestHelp( const HelpEvent
& rHEvt
)
4852 if( !rHEvt
.KeyboardActivated() )
4854 nItemId
= GetItemId( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) );
4855 aHelpPos
= rHEvt
.GetMousePosPixel();
4862 nItemId
= mnHighItemId
;
4863 Rectangle
aRect( GetItemRect( nItemId
) );
4864 if( aRect
.IsEmpty() )
4867 aHelpPos
= OutputToScreenPixel( aRect
.Center() );
4872 if ( rHEvt
.GetMode() & (HELPMODE_BALLOON
| HELPMODE_QUICK
) )
4874 // Rechteck ermitteln
4875 Rectangle aTempRect
= GetItemRect( nItemId
);
4876 Point aPt
= OutputToScreenPixel( aTempRect
.TopLeft() );
4877 aTempRect
.Left() = aPt
.X();
4878 aTempRect
.Top() = aPt
.Y();
4879 aPt
= OutputToScreenPixel( aTempRect
.BottomRight() );
4880 aTempRect
.Right() = aPt
.X();
4881 aTempRect
.Bottom() = aPt
.Y();
4883 // Text ermitteln und anzeigen
4884 XubString aStr
= GetQuickHelpText( nItemId
);
4885 const XubString
& rHelpStr
= GetHelpText( nItemId
);
4887 aStr
= MnemonicGenerator::EraseAllMnemonicChars( GetItemText( nItemId
) );
4888 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
4890 if ( rHelpStr
.Len() )
4892 Help::ShowBalloon( this, aHelpPos
, aTempRect
, aStr
);
4895 Help::ShowQuickHelp( this, aTempRect
, aStr
, rHelpStr
, QUICKHELP_CTRLTEXT
);
4898 else if ( rHEvt
.GetMode() & HELPMODE_EXTENDED
)
4900 String aCommand
= GetItemCommand( nItemId
);
4901 ULONG nHelpId
= GetHelpId( nItemId
);
4903 if ( aCommand
.Len() || nHelpId
)
4905 // Wenn eine Hilfe existiert, dann ausloesen
4906 Help
* pHelp
= Application::GetHelp();
4909 if ( aCommand
.Len() )
4910 pHelp
->Start( aCommand
, this );
4912 pHelp
->Start( nHelpId
, this );
4918 else if ( maNextToolRect
.IsInside( ScreenToOutputPixel( rHEvt
.GetMousePosPixel() ) ) )
4920 if ( rHEvt
.GetMode() & (HELPMODE_BALLOON
| HELPMODE_QUICK
) )
4922 // Rechteck ermitteln
4923 Rectangle aTempRect
= maNextToolRect
;
4924 Point aPt
= OutputToScreenPixel( aTempRect
.TopLeft() );
4925 aTempRect
.Left() = aPt
.X();
4926 aTempRect
.Top() = aPt
.Y();
4927 aPt
= OutputToScreenPixel( aTempRect
.BottomRight() );
4928 aTempRect
.Right() = aPt
.X();
4929 aTempRect
.Bottom() = aPt
.Y();
4931 if ( rHEvt
.GetMode() & HELPMODE_BALLOON
)
4932 Help::ShowBalloon( this, aTempRect
.Center(), aTempRect
, maNextToolBoxStr
);
4934 Help::ShowQuickHelp( this, aTempRect
, maNextToolBoxStr
);
4939 DockingWindow::RequestHelp( rHEvt
);
4942 // -----------------------------------------------------------------------
4944 long ToolBox::Notify( NotifyEvent
& rNEvt
)
4946 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
4948 KeyEvent aKEvt
= *rNEvt
.GetKeyEvent();
4949 KeyCode aKeyCode
= aKEvt
.GetKeyCode();
4950 USHORT nKeyCode
= aKeyCode
.GetCode();
4955 // internal TAB cycling only if parent is not a dialog or if we are the ony child
4956 // otherwise the dialog control will take over
4957 BOOL bNoTabCycling
= ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
&&
4958 ImplGetParent()->GetChildCount() != 1 );
4960 if( bNoTabCycling
&& ! (GetStyle() & WB_FORCETABCYCLE
) )
4961 return DockingWindow::Notify( rNEvt
);
4962 else if( ImplChangeHighlightUpDn( aKeyCode
.IsShift() ? TRUE
: FALSE
, bNoTabCycling
) )
4965 return DockingWindow::Notify( rNEvt
);
4971 else if( rNEvt
.GetType() == EVENT_GETFOCUS
)
4973 if( rNEvt
.GetWindow() == this )
4975 // the toolbar itself got the focus
4976 if( mnLastFocusItemId
!= 0 )
4978 // restore last item
4979 ImplChangeHighlight( ImplGetItem( mnLastFocusItemId
) );
4980 mnLastFocusItemId
= 0;
4982 else if( (GetGetFocusFlags() & (GETFOCUS_BACKWARD
|GETFOCUS_TAB
) ) == (GETFOCUS_BACKWARD
|GETFOCUS_TAB
))
4983 // Shift-TAB was pressed in the parent
4984 ImplChangeHighlightUpDn( FALSE
);
4986 ImplChangeHighlightUpDn( TRUE
);
4988 mnLastFocusItemId
= 0;
4994 // a child window got the focus so update current item to
4995 // allow for proper lose focus handling in keyboard navigation
4996 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
4997 while( it
!= mpData
->m_aItems
.end() )
4999 if ( it
->mbVisible
)
5001 if ( it
->mpWindow
&& it
->mpWindow
->ImplIsWindowOrChild( rNEvt
.GetWindow() ) )
5003 mnHighItemId
= it
->mnId
;
5010 return DockingWindow::Notify( rNEvt
);
5013 else if( rNEvt
.GetType() == EVENT_LOSEFOCUS
)
5018 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
5021 return DockingWindow::Notify( rNEvt
);
5024 // -----------------------------------------------------------------------
5026 void ToolBox::Command( const CommandEvent
& rCEvt
)
5028 // StartDrag auf MouseButton/Left/Alt abbilden
5029 if ( (rCEvt
.GetCommand() == COMMAND_STARTDRAG
) && rCEvt
.IsMouseEvent() &&
5030 mbCustomize
&& !mbDragging
&& !mbDrag
&& !mbSelection
&&
5031 (mnCurPos
== TOOLBOX_ITEM_NOTFOUND
) )
5033 // Wir erlauben nur das Draggen von Items. Deshalb muessen wir
5034 // testen, ob auch ein Item angeklickt wurde, ansonsten wuerden
5035 // wir evt. das Fenster verschieben, was nicht gewollt waere.
5036 // Wir machen dieses jedoch nur im Customize-Mode, da ansonsten
5037 // Items zuhaeufig ausversehen verschoben werden.
5038 if ( mbCustomizeMode
)
5040 Point aMousePos
= rCEvt
.GetMousePosPixel();
5041 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
5042 while ( it
!= mpData
->m_aItems
.end() )
5044 // Ist es dieses Item
5045 if ( it
->maRect
.IsInside( aMousePos
) )
5047 // Ist es ein Separator oder ist das Item disabled,
5048 // dann mache nichts
5049 if ( (it
->meType
== TOOLBOXITEM_BUTTON
) &&
5051 mbCommandDrag
= TRUE
;
5058 if ( mbCommandDrag
)
5060 MouseEvent
aMEvt( aMousePos
, 1, MOUSE_SIMPLECLICK
,
5061 MOUSE_LEFT
, KEY_MOD2
);
5062 ToolBox::MouseButtonDown( aMEvt
);
5067 else if ( rCEvt
.GetCommand() == COMMAND_WHEEL
)
5069 if ( (mnCurLine
> 1) || (mnCurLine
+mnVisLines
-1 < mnCurLines
) )
5071 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
5072 if ( pData
->GetMode() == COMMAND_WHEEL_SCROLL
)
5074 if ( (mnCurLine
> 1) && (pData
->GetDelta() > 0) )
5076 else if ( (mnCurLine
+mnVisLines
-1 < mnCurLines
) && (pData
->GetDelta() < 0) )
5078 ImplDrawSpin( FALSE
, FALSE
);
5084 DockingWindow::Command( rCEvt
);
5087 // -----------------------------------------------------------------------
5089 void ToolBox::StateChanged( StateChangedType nType
)
5091 DockingWindow::StateChanged( nType
);
5093 if ( nType
== STATE_CHANGE_INITSHOW
)
5095 else if ( nType
== STATE_CHANGE_ENABLE
)
5097 else if ( nType
== STATE_CHANGE_UPDATEMODE
)
5099 if ( IsUpdateMode() )
5102 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
5103 (nType
== STATE_CHANGE_CONTROLFONT
) )
5107 ImplInitSettings( TRUE
, FALSE
, FALSE
);
5110 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
5112 ImplInitSettings( FALSE
, TRUE
, FALSE
);
5115 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
5117 ImplInitSettings( FALSE
, FALSE
, TRUE
); // font, foreground, background
5122 // -----------------------------------------------------------------------
5124 void ToolBox::DataChanged( const DataChangedEvent
& rDCEvt
)
5126 DockingWindow::DataChanged( rDCEvt
);
5128 if ( (rDCEvt
.GetType() == DATACHANGED_DISPLAY
) ||
5129 (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
5130 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
5131 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
5132 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
5136 ImplInitSettings( TRUE
, TRUE
, TRUE
);
5141 // -----------------------------------------------------------------------
5143 BOOL
ToolBox::PrepareToggleFloatingMode()
5145 return DockingWindow::PrepareToggleFloatingMode();
5148 // -----------------------------------------------------------------------
5150 void ToolBox::ToggleFloatingMode()
5152 DockingWindow::ToggleFloatingMode();
5154 BOOL mbOldHorz
= mbHorz
;
5156 if ( ImplIsFloatingMode() )
5159 meAlign
= WINDOWALIGN_TOP
;
5162 if( mbOldHorz
!= mbHorz
)
5163 mbCalc
= TRUE
; // orientation was changed !
5165 ImplSetMinMaxFloatSize( this );
5166 SetOutputSizePixel( ImplCalcFloatSize( this, mnFloatLines
) );
5170 mbScroll
= (mnWinStyle
& WB_SCROLL
) ? TRUE
: FALSE
;
5171 if ( (meAlign
== WINDOWALIGN_TOP
) || (meAlign
== WINDOWALIGN_BOTTOM
) )
5176 // set focus back to document
5177 ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT
)->GrabFocus();
5180 if( mbOldHorz
!= mbHorz
)
5182 // if orientation changes, the toolbox has to be initialized again
5183 // to update the direction of the gradient
5185 ImplInitSettings( TRUE
, TRUE
, TRUE
);
5192 // -----------------------------------------------------------------------
5194 void ToolBox::StartDocking()
5196 meDockAlign
= meAlign
;
5197 mnDockLines
= mnLines
;
5198 mbLastFloatMode
= ImplIsFloatingMode();
5199 DockingWindow::StartDocking();
5202 // -----------------------------------------------------------------------
5204 BOOL
ToolBox::Docking( const Point
& rPos
, Rectangle
& rRect
)
5206 // Wenn Dragging, dann nicht machen, da vorher schon berechnet
5210 BOOL bFloatMode
= FALSE
;
5212 DockingWindow::Docking( rPos
, rRect
);
5214 // Befindet sich die Maus ausserhalb des Bereichs befindet, kann es nur ein
5215 // FloatWindow werden
5216 Rectangle
aDockingRect( rRect
);
5217 if ( !ImplIsFloatingMode() )
5219 // don't use tracking rectangle for alignment check, because it will be too large
5220 // to get a floating mode as result - switch to floating size
5221 // so the calculation only depends on the position of the rectangle, not the current
5222 // docking state of the window
5224 aDockingRect
.SetSize( ImplCalcFloatSize( this, nTemp
) );
5226 // in this mode docking is never done by keyboard, so it's OK to use the mouse position
5227 aDockingRect
.SetPos( ImplGetFrameWindow()->GetPointerPosPixel() );
5230 Rectangle aIntersection
= maOutDockRect
.GetIntersection( aDockingRect
);
5231 if ( !aIntersection
.IsEmpty() && !IsDockingPrevented() )
5233 Rectangle aInRect
= maInDockRect
;
5235 aDockSize
.Width() = ImplCalcSize( this, mnLines
, TB_CALCMODE_VERT
).Width();
5236 aDockSize
.Height() = ImplCalcSize( this, mnLines
, TB_CALCMODE_HORZ
).Height();
5237 aInRect
.Left() += aDockSize
.Width()/2;
5238 aInRect
.Top() += aDockSize
.Height()/2;
5239 aInRect
.Right() -= aDockSize
.Width()/2;
5240 aInRect
.Bottom() -= aDockSize
.Height()/2;
5242 // Wenn Fenster zu klein, wird das gesammte InDock-Rect genommen
5243 if ( aInRect
.Left() >= aInRect
.Right() )
5245 aInRect
.Left() = maInDockRect
.Left();
5246 aInRect
.Right() = maInDockRect
.Right();
5248 if ( aInRect
.Top() >= aInRect
.Bottom() )
5250 aInRect
.Top() = maInDockRect
.Top();
5251 aInRect
.Bottom() = maInDockRect
.Bottom();
5254 // Wenn Maus nicht im Dock-Bereich, dann kann es nur zum
5255 // FloatWindow werden
5256 Rectangle aIntersect
= aInRect
.GetIntersection( aDockingRect
);
5257 if ( aIntersect
== aDockingRect
)
5261 // docking rectangle is in the "sensible area"
5262 Point aPos
= aDockingRect
.TopLeft();
5263 Point
aInPosTL( aPos
.X()-aInRect
.Left(), aPos
.Y()-aInRect
.Top() );
5264 Point
aInPosBR( aPos
.X()-aInRect
.Left() + aDockingRect
.GetWidth(), aPos
.Y()-aInRect
.Top() + aDockingRect
.GetHeight() );
5265 Size aInSize
= aInRect
.GetSize();
5267 if ( aInPosTL
.X() <= 0 )
5268 meDockAlign
= WINDOWALIGN_LEFT
;
5269 else if ( aInPosTL
.Y() <= 0)
5270 meDockAlign
= WINDOWALIGN_TOP
;
5271 else if ( aInPosBR
.X() >= aInSize
.Width() )
5272 meDockAlign
= WINDOWALIGN_RIGHT
;
5273 else if ( aInPosBR
.Y() >= aInSize
.Height() )
5274 meDockAlign
= WINDOWALIGN_BOTTOM
;
5276 // Wenn sich Dock-Align geaendert hat, muessen wir die
5277 // neue Dock-Groesse setzen
5278 if ( (meDockAlign
== WINDOWALIGN_TOP
) || (meDockAlign
== WINDOWALIGN_BOTTOM
) )
5279 aDockSize
.Width() = maInDockRect
.GetWidth();
5281 aDockSize
.Height() = maInDockRect
.GetHeight();
5283 aDockingRect
.SetSize( aDockSize
);
5285 Point
aPosTL( maInDockRect
.TopLeft() );
5286 switch ( meDockAlign
)
5288 case WINDOWALIGN_TOP
:
5289 aDockingRect
.SetPos( aPosTL
);
5291 case WINDOWALIGN_LEFT
:
5292 aDockingRect
.SetPos( aPosTL
);
5294 case WINDOWALIGN_BOTTOM
:
5296 Point
aPosBL( maInDockRect
.BottomLeft() );
5297 aPosBL
.Y() -= aDockingRect
.GetHeight();
5298 aDockingRect
.SetPos( aPosBL
);
5301 case WINDOWALIGN_RIGHT
:
5303 Point
aPosTR( maInDockRect
.TopRight() );
5304 aPosTR
.X() -= aDockingRect
.GetWidth();
5305 aDockingRect
.SetPos( aPosTR
);
5316 meDockAlign
= meAlign
;
5317 if ( !mbLastFloatMode
)
5320 aDockingRect
.SetSize( ImplCalcFloatSize( this, nTemp
) );
5324 rRect
= aDockingRect
;
5325 mbLastFloatMode
= bFloatMode
;
5330 // -----------------------------------------------------------------------
5332 void ToolBox::EndDocking( const Rectangle
& rRect
, BOOL bFloatMode
)
5334 if ( !IsDockingCanceled() )
5336 if ( mnLines
!= mnDockLines
)
5337 SetLineCount( mnDockLines
);
5338 if ( meAlign
!= meDockAlign
)
5339 SetAlign( meDockAlign
);
5341 if ( bFloatMode
|| (bFloatMode
!= ImplIsFloatingMode()) )
5342 DockingWindow::EndDocking( rRect
, bFloatMode
);
5345 // -----------------------------------------------------------------------
5347 void ToolBox::Resizing( Size
& rSize
)
5352 // Alle Floatinggroessen berechnen
5353 ImplCalcFloatSizes( this );
5355 if ( !mnLastResizeDY
)
5356 mnLastResizeDY
= mnDY
;
5358 // Ist vertikales Resizing angesagt
5359 if ( (mnLastResizeDY
!= rSize
.Height()) && (mnDY
!= rSize
.Height()) )
5361 nCalcLines
= ImplCalcLines( this, rSize
.Height() );
5362 if ( nCalcLines
< 1 )
5364 rSize
= ImplCalcFloatSize( this, nCalcLines
);
5370 Size aTempSize
= ImplCalcFloatSize( this, nTemp
);
5371 while ( (aTempSize
.Width() > rSize
.Width()) &&
5372 (nCalcLines
<= mpFloatSizeAry
->mpSize
[0].mnLines
) )
5376 aTempSize
= ImplCalcFloatSize( this, nTemp
);
5381 mnLastResizeDY
= rSize
.Height();
5384 // -----------------------------------------------------------------------
5386 Size
ToolBox::CalcWindowSizePixel( USHORT nCalcLines
) const
5388 return ImplCalcSize( this, nCalcLines
);
5391 Size
ToolBox::CalcWindowSizePixel( USHORT nCalcLines
, WindowAlign eAlign
) const
5393 return ImplCalcSize( this, nCalcLines
,
5394 (eAlign
== WINDOWALIGN_TOP
|| eAlign
== WINDOWALIGN_BOTTOM
) ? TB_CALCMODE_HORZ
: TB_CALCMODE_VERT
);
5397 USHORT
ToolBox::ImplCountLineBreaks( const ToolBox
*pThis
)
5401 std::vector
< ImplToolItem
>::const_iterator it
= ((ToolBox
*)pThis
)->mpData
->m_aItems
.begin();
5402 while ( it
!= ((ToolBox
*)pThis
)->mpData
->m_aItems
.end() )
5404 if( it
->meType
== TOOLBOXITEM_BREAK
)
5411 Size
ToolBox::CalcPopupWindowSizePixel() const
5413 // count number of breaks and calc corresponding floating window size
5414 USHORT nLines
= ImplCountLineBreaks( this );
5417 nLines
++; // add the first line
5420 // no breaks found: use quadratic layout
5421 nLines
= (USHORT
) ceil( sqrt( (double) GetItemCount() ) );
5424 BOOL bPopup
= mpData
->mbAssumePopupMode
;
5425 ToolBox
*pThis
= (ToolBox
*) this;
5426 pThis
->mpData
->mbAssumePopupMode
= TRUE
;
5428 Size aSize
= CalcFloatingWindowSizePixel( nLines
);
5430 pThis
->mpData
->mbAssumePopupMode
= bPopup
;
5434 Size
ToolBox::CalcFloatingWindowSizePixel() const
5436 USHORT nLines
= ImplCountLineBreaks( this );
5437 nLines
++; // add the first line
5438 return CalcFloatingWindowSizePixel( nLines
);
5441 Size
ToolBox::CalcFloatingWindowSizePixel( USHORT nCalcLines
) const
5443 BOOL bFloat
= mpData
->mbAssumeFloating
;
5444 BOOL bDocking
= mpData
->mbAssumeDocked
;
5446 // simulate floating mode and force reformat before calculating
5447 ToolBox
*pThis
= (ToolBox
*) this;
5448 pThis
->mpData
->mbAssumeFloating
= TRUE
;
5449 pThis
->mpData
->mbAssumeDocked
= FALSE
;
5451 Size aSize
= ImplCalcFloatSize( (ToolBox
*) this, nCalcLines
);
5453 pThis
->mbFormat
= TRUE
;
5454 pThis
->mpData
->mbAssumeFloating
= bFloat
;
5455 pThis
->mpData
->mbAssumeDocked
= bDocking
;
5460 // -----------------------------------------------------------------------
5462 Size
ToolBox::CalcMinimumWindowSizePixel() const
5464 if( ImplIsFloatingMode() )
5465 return ImplCalcSize( this, mnFloatLines
);
5468 // create dummy toolbox for measurements
5469 ToolBox
*pToolBox
= new ToolBox( GetParent(), GetStyle() );
5471 // copy until first useful item
5472 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5473 while( it
!= mpData
->m_aItems
.end() )
5475 pToolBox
->CopyItem( *this, it
->mnId
);
5476 if( (it
->meType
!= TOOLBOXITEM_BUTTON
) ||
5477 !it
->mbVisible
|| ImplIsFixedControl( &(*it
) ) )
5483 // add to docking manager if required to obtain a drag area
5484 // (which is accounted for in calcwindowsizepixel)
5485 if( ImplGetDockingManager()->GetDockingWindowWrapper( this ) )
5486 ImplGetDockingManager()->AddWindow( pToolBox
);
5489 if( IsMenuEnabled() )
5490 pToolBox
->SetMenuType( GetMenuType() );
5492 pToolBox
->SetAlign( GetAlign() );
5493 Size aSize
= pToolBox
->CalcWindowSizePixel( 1 );
5495 ImplGetDockingManager()->RemoveWindow( pToolBox
);
5503 // -----------------------------------------------------------------------
5505 void ToolBox::EnableCustomize( BOOL bEnable
)
5507 if ( bEnable
!= mbCustomize
)
5509 mbCustomize
= bEnable
;
5511 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
5513 pMgr
->Insert( this );
5515 pMgr
->Remove( this );
5519 // -----------------------------------------------------------------------
5521 void ToolBox::StartCustomize( const Rectangle
& rRect
, void* pData
)
5523 DBG_ASSERT( mbCustomize
,
5524 "ToolBox::StartCustomize(): ToolBox must be customized" );
5526 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
5527 Point aMousePos
= GetPointerPosPixel();
5528 Point aPos
= ScreenToOutputPixel( rRect
.TopLeft() );
5529 Rectangle
aRect( aPos
.X(), aPos
.Y(),
5530 aPos
.X()+rRect
.GetWidth()+SMALLBUTTON_HSIZE
,
5531 aPos
.Y()+rRect
.GetHeight()+SMALLBUTTON_VSIZE
);
5532 aMousePos
= ScreenToOutputPixel( aPos
);
5535 pMgr
->StartDragging( this, aMousePos
, aRect
, 0, FALSE
, pData
);
5538 // -----------------------------------------------------------------------
5540 void ToolBox::StartCustomizeMode()
5542 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
5543 pMgr
->StartCustomizeMode();
5546 // -----------------------------------------------------------------------
5548 void ToolBox::EndCustomizeMode()
5550 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
5551 pMgr
->EndCustomizeMode();
5554 // -----------------------------------------------------------------------
5556 BOOL
ToolBox::IsCustomizeMode()
5558 ImplTBDragMgr
* pMgr
= ImplGetTBDragMgr();
5559 return pMgr
->IsCustomizeMode();
5562 // -----------------------------------------------------------------------
5564 void ToolBox::GetFocus()
5566 DockingWindow::GetFocus();
5569 // -----------------------------------------------------------------------
5571 void ToolBox::LoseFocus()
5573 ImplChangeHighlight( NULL
, TRUE
);
5575 DockingWindow::LoseFocus();
5578 // -----------------------------------------------------------------------
5580 // performs the action associated with an item, ie simulates clicking the item
5581 void ToolBox::TriggerItem( USHORT nItemId
, BOOL bShift
, BOOL bCtrl
)
5583 mnHighItemId
= nItemId
;
5584 USHORT nModifier
= 0;
5586 nModifier
|= KEY_SHIFT
;
5588 nModifier
|= KEY_MOD1
;
5589 KeyCode
aKeyCode( 0, nModifier
);
5590 ImplActivateItem( aKeyCode
);
5593 // -----------------------------------------------------------------------
5595 // calls the button's action handler
5596 // returns TRUE if action was called
5597 BOOL
ToolBox::ImplActivateItem( KeyCode aKeyCode
)
5602 ImplToolItem
*pToolItem
= ImplGetItem( mnHighItemId
);
5604 // #107712#, activate can also be called for disabled entries
5605 if( pToolItem
&& !pToolItem
->mbEnabled
)
5608 if( pToolItem
&& pToolItem
->mpWindow
&& HasFocus() )
5611 mbChangingHighlight
= TRUE
; // avoid focus change due to loose focus
5612 pToolItem
->mpWindow
->ImplControlFocus( GETFOCUS_TAB
);
5613 mbChangingHighlight
= FALSE
;
5617 mnDownItemId
= mnCurItemId
= mnHighItemId
;
5618 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
5619 if ( pItem
->mnBits
& TIB_AUTOCHECK
)
5621 if ( pItem
->mnBits
& TIB_RADIOCHECK
)
5623 if ( pItem
->meState
!= STATE_CHECK
)
5624 SetItemState( pItem
->mnId
, STATE_CHECK
);
5628 if ( pItem
->meState
!= STATE_CHECK
)
5629 pItem
->meState
= STATE_CHECK
;
5631 pItem
->meState
= STATE_NOCHECK
;
5634 mnMouseModifier
= aKeyCode
.GetModifier();
5635 mbIsKeyEvent
= TRUE
;
5639 // #107776# we might be destroyed in the selecthandler
5640 ImplDelData aDelData
;
5641 ImplAddDel( &aDelData
);
5643 if ( aDelData
.IsDelete() )
5645 ImplRemoveDel( &aDelData
);
5648 mbIsKeyEvent
= FALSE
;
5649 mnMouseModifier
= 0;
5657 // -----------------------------------------------------------------------
5659 BOOL
ImplCloseLastPopup( Window
*pParent
)
5661 // close last popup toolbox (see also:
5662 // ImplHandleMouseFloatMode(...) in winproc.cxx )
5664 if( ImplGetSVData()->maWinData
.mpFirstFloat
)
5666 FloatingWindow
* pLastLevelFloat
= ImplGetSVData()->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
5667 // only close the floater if it is not our direct parent, which would kill ourself
5668 if( pLastLevelFloat
&& pLastLevelFloat
!= pParent
)
5670 pLastLevelFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
5677 // opens a drop down toolbox item
5678 // returns TRUE if item was opened
5679 BOOL
ToolBox::ImplOpenItem( KeyCode aKeyCode
)
5681 USHORT nCode
= aKeyCode
.GetCode();
5684 // arrow keys should work only in the opposite direction of alignment (to not break cursor travelling)
5685 if ( ((nCode
== KEY_LEFT
|| nCode
== KEY_RIGHT
) && IsHorizontal())
5686 || ((nCode
== KEY_UP
|| nCode
== KEY_DOWN
) && !IsHorizontal()) )
5689 if( IsMenuEnabled() && mpData
->mbMenubuttonSelected
)
5691 if( ImplCloseLastPopup( GetParent() ) )
5694 ImplUpdateCustomMenu();
5695 Application::PostUserEvent( mpData
->mnEventId
, LINK( this, ToolBox
, ImplCallExecuteCustomMenu
) );
5697 else if( mnHighItemId
&& ImplGetItem( mnHighItemId
) &&
5698 (ImplGetItem( mnHighItemId
)->mnBits
& TIB_DROPDOWN
) )
5700 if( ImplCloseLastPopup( GetParent() ) )
5703 mnDownItemId
= mnCurItemId
= mnHighItemId
;
5704 mnCurPos
= GetItemPos( mnCurItemId
);
5705 mnLastFocusItemId
= mnCurItemId
; // save item id for possible later focus restore
5706 mnMouseModifier
= aKeyCode
.GetModifier();
5708 mbIsKeyEvent
= TRUE
;
5711 mpData
->mbDropDownByKeyboard
= TRUE
;
5712 GetDropdownClickHdl().Call( this );
5714 mbIsKeyEvent
= FALSE
;
5716 mnMouseModifier
= 0;
5724 // -----------------------------------------------------------------------
5726 void ToolBox::KeyInput( const KeyEvent
& rKEvt
)
5728 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
5729 mnKeyModifier
= aKeyCode
.GetModifier();
5730 USHORT nCode
= aKeyCode
.GetCode();
5731 BOOL bParentIsDialog
= ( ( ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
);
5732 BOOL bForwardKey
= FALSE
;
5733 BOOL bGrabFocusToDocument
= FALSE
;
5735 // #107776# we might be destroyed in the keyhandler
5736 ImplDelData aDelData
;
5737 ImplAddDel( &aDelData
);
5743 // Ctrl-Cursor activates next toolbox, indicated by a blue arrow pointing to the left/up
5744 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5746 if( !IsHorizontal() )
5747 ImplChangeHighlightUpDn( TRUE
);
5749 ImplOpenItem( aKeyCode
);
5754 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5756 if( IsHorizontal() )
5757 ImplChangeHighlightUpDn( TRUE
);
5759 ImplOpenItem( aKeyCode
);
5764 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5766 if( !IsHorizontal() )
5767 ImplChangeHighlightUpDn( FALSE
);
5769 ImplOpenItem( aKeyCode
);
5774 if( aKeyCode
.GetModifier() ) // allow only pure cursor keys
5776 if( IsHorizontal() )
5777 ImplChangeHighlightUpDn( FALSE
);
5779 ImplOpenItem( aKeyCode
);
5783 if ( mnCurLine
> 1 )
5785 if( mnCurLine
> mnVisLines
)
5786 mnCurLine
= mnCurLine
- mnVisLines
;
5791 ImplDrawSpin( FALSE
, FALSE
);
5792 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine
) );
5796 if ( mnCurLine
+mnVisLines
-1 < mnCurLines
)
5798 if( mnCurLine
+ 2*mnVisLines
-1 < mnCurLines
)
5799 mnCurLine
= mnCurLine
+ mnVisLines
;
5801 mnCurLine
= mnCurLines
;
5804 ImplDrawSpin( FALSE
, FALSE
);
5805 ImplChangeHighlight( ImplGetFirstValidItem( mnCurLine
) );
5810 ImplChangeHighlight( NULL
);
5811 ImplChangeHighlightUpDn( FALSE
);
5816 ImplChangeHighlight( NULL
);
5817 ImplChangeHighlightUpDn( TRUE
);
5822 if( !ImplIsFloatingMode() && bParentIsDialog
)
5823 DockingWindow::KeyInput( rKEvt
);
5826 // send focus to document pane
5827 Window
*pWin
= this;
5830 if( !pWin
->GetParent() )
5832 pWin
->ImplGetFrameWindow()->GetWindow( WINDOW_CLIENT
)->GrabFocus();
5835 pWin
= pWin
->GetParent();
5842 // #107712#, disabled entries are selectable now
5843 // leave toolbox and move focus to document
5846 ImplToolItem
*pItem
= ImplGetItem( mnHighItemId
);
5847 if( !pItem
->mbEnabled
)
5849 Sound::Beep( SOUND_DISABLE
, this );
5850 bGrabFocusToDocument
= TRUE
;
5853 if( !bGrabFocusToDocument
)
5854 bForwardKey
= !ImplActivateItem( aKeyCode
);
5859 USHORT aKeyGroup
= aKeyCode
.GetGroup();
5860 ImplToolItem
*pItem
= NULL
;
5862 pItem
= ImplGetItem( mnHighItemId
);
5863 // #i13931# forward alphanum keyinput into embedded control
5864 if( (aKeyGroup
== KEYGROUP_NUM
|| aKeyGroup
== KEYGROUP_ALPHA
) && pItem
&& pItem
->mpWindow
&& pItem
->mbEnabled
)
5866 Window
*pFocusWindow
= Application::GetFocusWindow();
5868 mbChangingHighlight
= TRUE
; // avoid focus change due to loose focus
5869 pItem
->mpWindow
->ImplControlFocus( GETFOCUS_TAB
);
5870 mbChangingHighlight
= FALSE
;
5871 if( pFocusWindow
!= Application::GetFocusWindow() )
5872 Application::GetFocusWindow()->KeyInput( rKEvt
);
5876 // do nothing to avoid key presses going into the document
5877 // while the toolbox has the focus
5878 // just forward function and special keys and combinations with Alt-key
5879 if( aKeyGroup
== KEYGROUP_FKEYS
|| aKeyGroup
== KEYGROUP_MISC
|| aKeyCode
.IsMod2() )
5885 if ( aDelData
.IsDelete() )
5887 ImplRemoveDel( &aDelData
);
5889 // #107251# move focus away if this toolbox was disabled during keyinput
5890 if( HasFocus() && mpData
->mbKeyInputDisabled
&& (ImplGetParent()->GetStyle() & (WB_DIALOGCONTROL
| WB_NODIALOGCONTROL
) ) == WB_DIALOGCONTROL
)
5893 Window
*pFocusControl
= ImplGetParent()->ImplGetDlgWindow( n
, DLGWINDOW_FIRST
);
5894 if ( pFocusControl
&& pFocusControl
!= this )
5895 pFocusControl
->ImplControlFocus( GETFOCUS_INIT
);
5900 // #107712#, leave toolbox
5901 if( bGrabFocusToDocument
)
5903 GrabFocusToDocument();
5908 DockingWindow::KeyInput( rKEvt
);
5911 // -----------------------------------------------------------------------
5913 // returns the current toolbox line of the item
5914 USHORT
ToolBox::ImplGetItemLine( ImplToolItem
* pCurrentItem
)
5916 std::vector
< ImplToolItem
>::const_iterator it
= mpData
->m_aItems
.begin();
5918 while( it
!= mpData
->m_aItems
.end() )
5922 if( &(*it
) == pCurrentItem
)
5929 // returns the first displayable item in the given line
5930 ImplToolItem
* ToolBox::ImplGetFirstValidItem( USHORT nLine
)
5932 if( !nLine
|| nLine
> mnCurLines
)
5937 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5938 while( it
!= mpData
->m_aItems
.end() )
5940 // find correct line
5945 // find first useful item
5946 while( it
!= mpData
->m_aItems
.end() && ((it
->meType
!= TOOLBOXITEM_BUTTON
) ||
5947 /*!it->mbEnabled ||*/ !it
->mbVisible
|| ImplIsFixedControl( &(*it
) )) )
5950 if( it
== mpData
->m_aItems
.end() || it
->mbBreak
)
5951 return NULL
; // no valid items in this line
5958 return (it
== mpData
->m_aItems
.end()) ? NULL
: &(*it
);
5961 // returns the last displayable item in the given line
5962 ImplToolItem
* ToolBox::ImplGetLastValidItem( USHORT nLine
)
5964 if( !nLine
|| nLine
> mnCurLines
)
5968 ImplToolItem
*pFound
= NULL
;
5969 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
5970 while( it
!= mpData
->m_aItems
.end() )
5972 // find correct line
5977 // find last useful item
5978 while( it
!= mpData
->m_aItems
.end() && ((it
->meType
== TOOLBOXITEM_BUTTON
) &&
5979 /*it->mbEnabled &&*/ it
->mbVisible
&& !ImplIsFixedControl( &(*it
) )) )
5983 if( it
== mpData
->m_aItems
.end() || it
->mbBreak
)
5984 return pFound
; // end of line: return last useful item
5994 // -----------------------------------------------------------------------
5996 USHORT
ToolBox::ImplFindItemPos( const ImplToolItem
* pItem
, const std::vector
< ImplToolItem
>& rList
)
6001 for( nPos
= 0; nPos
< rList
.size(); nPos
++ )
6002 if( &rList
[ nPos
] == pItem
)
6005 return TOOLBOX_ITEM_NOTFOUND
;
6008 void ToolBox::ChangeHighlight( USHORT nPos
)
6010 if ( nPos
< GetItemCount() ) {
6012 ImplChangeHighlight ( ImplGetItem ( GetItemId ( (USHORT
) nPos
) ), FALSE
);
6016 void ToolBox::ImplChangeHighlight( ImplToolItem
* pItem
, BOOL bNoGrabFocus
)
6018 // avoid recursion due to focus change
6019 if( mbChangingHighlight
)
6022 mbChangingHighlight
= TRUE
;
6024 ImplToolItem
* pOldItem
= NULL
;
6029 USHORT nPos
= GetItemPos( mnHighItemId
);
6030 pOldItem
= ImplGetItem( mnHighItemId
);
6031 // #i89962# ImplDrawItem can cause Invalidate/Update
6032 // which will in turn ImplShowFocus again
6033 // set mnHighItemId to 0 already to prevent this hen/egg problem
6035 ImplDrawItem( nPos
, FALSE
);
6036 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHTOFF
, reinterpret_cast< void* >( nPos
) );
6039 if( !bNoGrabFocus
&& pItem
!= pOldItem
&& pOldItem
&& pOldItem
->mpWindow
)
6041 // move focus into toolbox
6047 USHORT aPos
= ToolBox::ImplFindItemPos( pItem
, mpData
->m_aItems
);
6048 if( aPos
!= TOOLBOX_ITEM_NOTFOUND
)
6050 // check for line breaks
6051 USHORT nLine
= ImplGetItemLine( pItem
);
6053 if( nLine
>= mnCurLine
+ mnVisLines
)
6055 mnCurLine
= nLine
- mnVisLines
+ 1;
6058 else if ( nLine
< mnCurLine
)
6069 mnHighItemId
= pItem
->mnId
;
6070 ImplDrawItem( aPos
, 2 ); // always use shadow effect (2)
6076 ImplCallEventListeners( VCLEVENT_TOOLBOX_HIGHLIGHT
);
6083 mnCurPos
= TOOLBOX_ITEM_NOTFOUND
;
6086 mbChangingHighlight
= FALSE
;
6089 // -----------------------------------------------------------------------
6091 // check for keyboard accessible items
6092 static BOOL
ImplIsValidItem( const ImplToolItem
* pItem
, BOOL bNotClipped
)
6094 BOOL bValid
= (pItem
&& pItem
->meType
== TOOLBOXITEM_BUTTON
&& pItem
->mbVisible
&& !ImplIsFixedControl( pItem
));
6095 if( bValid
&& bNotClipped
&& pItem
->IsClipped() )
6100 // -----------------------------------------------------------------------
6102 BOOL
ToolBox::ImplChangeHighlightUpDn( BOOL bUp
, BOOL bNoCycle
)
6104 ImplToolItem
* pToolItem
= ImplGetItem( mnHighItemId
);
6106 if( !pToolItem
|| !mnHighItemId
)
6108 // menubutton highlighted ?
6109 if( mpData
->mbMenubuttonSelected
)
6113 // select last valid non-clipped item
6114 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.end();
6115 ImplToolItem
* pItem
= NULL
;
6116 while( it
!= mpData
->m_aItems
.begin() )
6119 if ( ImplIsValidItem( &(*it
), TRUE
) )
6125 ImplDrawMenubutton( this, FALSE
);
6126 ImplChangeHighlight( pItem
);
6130 // select first valid non-clipped item
6131 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
6132 while( it
!= mpData
->m_aItems
.end() )
6134 if ( ImplIsValidItem( &(*it
), TRUE
) )
6138 if( it
!= mpData
->m_aItems
.end() )
6140 ImplDrawMenubutton( this, FALSE
);
6141 ImplChangeHighlight( &(*it
) );
6149 // Select first valid item
6150 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.begin();
6151 while( it
!= mpData
->m_aItems
.end() )
6153 if ( ImplIsValidItem( &(*it
), FALSE
) )
6158 // select the menu button if a clipped item would be selected
6159 if( (it
!= mpData
->m_aItems
.end() && &(*it
) == ImplGetFirstClippedItem( this )) && IsMenuEnabled() )
6161 ImplChangeHighlight( NULL
);
6162 ImplDrawMenubutton( this, TRUE
);
6165 ImplChangeHighlight( (it
!= mpData
->m_aItems
.end()) ? &(*it
) : NULL
);
6170 // Select last valid item
6172 // docked toolbars have the menubutton as last item - if this button is enabled
6173 if( IsMenuEnabled() && !ImplIsFloatingMode() )
6175 ImplChangeHighlight( NULL
);
6176 ImplDrawMenubutton( this, TRUE
);
6180 std::vector
< ImplToolItem
>::iterator it
= mpData
->m_aItems
.end();
6181 ImplToolItem
* pItem
= NULL
;
6182 while( it
!= mpData
->m_aItems
.begin() )
6185 if ( ImplIsValidItem( &(*it
), FALSE
) )
6191 ImplChangeHighlight( pItem
);
6199 ULONG pos
= ToolBox::ImplFindItemPos( pToolItem
, mpData
->m_aItems
);
6200 ULONG nCount
= mpData
->m_aItems
.size();
6212 // highlight the menu button if it is the last item
6213 if( IsMenuEnabled() && !ImplIsFloatingMode() )
6215 ImplChangeHighlight( NULL
);
6216 ImplDrawMenubutton( this, TRUE
);
6225 if( ++pos
>= nCount
)
6230 // highlight the menu button if it is the last item
6231 if( IsMenuEnabled() && !ImplIsFloatingMode() )
6233 ImplChangeHighlight( NULL
);
6234 ImplDrawMenubutton( this, TRUE
);
6242 pToolItem
= &mpData
->m_aItems
[pos
];
6244 if ( ImplIsValidItem( pToolItem
, FALSE
) )
6247 } while( ++i
< nCount
);
6249 if( pToolItem
->IsClipped() && IsMenuEnabled() )
6251 // select the menu button if a clipped item would be selected
6252 ImplChangeHighlight( NULL
);
6253 ImplDrawMenubutton( this, TRUE
);
6255 else if( i
!= nCount
)
6256 ImplChangeHighlight( pToolItem
);
6263 // -----------------------------------------------------------------------
6265 void ToolBox::ImplShowFocus()
6267 if( mnHighItemId
&& HasFocus() )
6269 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
6270 if( pItem
->mpWindow
)
6272 Window
*pWin
= pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
? pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
: pItem
->mpWindow
;
6273 pWin
->ImplGetWindowImpl()->mbDrawSelectionBackground
= TRUE
;
6274 pWin
->Invalidate( 0 );
6279 // -----------------------------------------------------------------------
6281 void ToolBox::ImplHideFocus()
6285 ImplToolItem
* pItem
= ImplGetItem( mnHighItemId
);
6286 if( pItem
->mpWindow
)
6288 Window
*pWin
= pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
? pItem
->mpWindow
->ImplGetWindowImpl()->mpBorderWindow
: pItem
->mpWindow
;
6289 pWin
->ImplGetWindowImpl()->mbDrawSelectionBackground
= FALSE
;
6290 pWin
->Invalidate( 0 );
6294 if ( mpData
->mbMenubuttonSelected
)
6296 // remove highlight from menubutton
6297 ImplDrawMenubutton( this, FALSE
);
6301 // -----------------------------------------------------------------------
6303 void ToolBox::ImplDisableFlatButtons()
6305 #ifdef WNT // Check in the Windows registry if an AT tool wants no flat toolboxes
6306 static bool bInit
= false, bValue
= false;
6312 if( ERROR_SUCCESS
== RegOpenKey(HKEY_CURRENT_USER
,
6313 "Software\\OpenOffice.org\\Accessibility\\AtToolSupport",
6317 WIN_BYTE Data
[6]; // possible values: "true", "false", "1", "0", DWORD
6318 DWORD cbData
= sizeof(Data
);
6320 if( ERROR_SUCCESS
== RegQueryValueEx(hkey
, "DisableFlatToolboxButtons",
6321 NULL
, &dwType
, Data
, &cbData
) )
6326 bValue
= ((0 == stricmp((const char *) Data
, "1")) || (0 == stricmp((const char *) Data
, "true")));
6329 bValue
= (bool)(((DWORD
*) Data
)[0]);
6337 mnOutStyle
&= ~TOOLBOX_STYLE_FLAT
;