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: floatwin.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 <vcl/svdata.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include <vcl/brdwin.hxx>
41 #include <vcl/event.hxx>
42 #include <vcl/toolbox.hxx>
43 #include <vcl/floatwin.hxx>
44 #include <vcl/window.h>
48 #include <vcl/salframe.hxx>
49 #include <tools/debug.hxx>
52 // =======================================================================
54 class FloatingWindow::ImplData
61 Rectangle maItemEdgeClipRect
; // used to clip the common edge between a toolbar item and the border of this window
64 FloatingWindow::ImplData::ImplData()
69 FloatingWindow::ImplData::~ImplData()
73 Rectangle
& FloatingWindow::ImplGetItemEdgeClipRect()
75 return mpImplData
->maItemEdgeClipRect
;
78 // =======================================================================
80 void FloatingWindow::ImplInit( Window
* pParent
, WinBits nStyle
)
82 mpImplData
= new ImplData
;
84 mpWindowImpl
->mbFloatWin
= TRUE
;
88 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL!" );
91 pParent
= ImplGetSVData()->maWinData
.mpAppWin
;
93 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
95 // no Border, then we dont need a border window
98 mpWindowImpl
->mbOverlapWin
= TRUE
;
99 nStyle
|= WB_DIALOGCONTROL
;
100 SystemWindow::ImplInit( pParent
, nStyle
, NULL
);
104 if ( !(nStyle
& WB_NODIALOGCONTROL
) )
105 nStyle
|= WB_DIALOGCONTROL
;
107 if( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_ROLLABLE
| WB_CLOSEABLE
| WB_STANDALONE
)
108 && !(nStyle
& WB_OWNERDRAWDECORATION
) )
110 WinBits nFloatWinStyle
= nStyle
;
111 // #99154# floaters are not closeable by default anymore, eg fullscreen floater
112 // nFloatWinStyle |= WB_CLOSEABLE;
113 mpWindowImpl
->mbFrame
= TRUE
;
114 mpWindowImpl
->mbOverlapWin
= TRUE
;
115 SystemWindow::ImplInit( pParent
, nFloatWinStyle
& ~WB_BORDER
, NULL
);
119 ImplBorderWindow
* pBorderWin
;
120 USHORT nBorderStyle
= BORDERWINDOW_STYLE_BORDER
| BORDERWINDOW_STYLE_FLOAT
;
122 if( nStyle
& WB_OWNERDRAWDECORATION
) nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
123 else nBorderStyle
|= BORDERWINDOW_STYLE_OVERLAP
;
125 if ( (nStyle
& WB_SYSTEMWINDOW
) && !(nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
)) )
127 nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
128 nStyle
|= WB_CLOSEABLE
; // make undecorated floaters closeable
130 pBorderWin
= new ImplBorderWindow( pParent
, nStyle
, nBorderStyle
);
131 SystemWindow::ImplInit( pBorderWin
, nStyle
& ~WB_BORDER
, NULL
);
132 pBorderWin
->mpWindowImpl
->mpClientWindow
= this;
133 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
134 pBorderWin
->SetDisplayActive( TRUE
);
135 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
136 mpWindowImpl
->mpRealParent
= pParent
;
139 SetActivateMode( 0 );
142 mpFirstPopupModeWin
= NULL
;
144 mnTitle
= (nStyle
& WB_MOVEABLE
) ? FLOATWIN_TITLE_NORMAL
: FLOATWIN_TITLE_NONE
;
145 mnOldTitle
= mnTitle
;
146 mnPopupModeFlags
= 0;
147 mbInPopupMode
= FALSE
;
149 mbPopupModeCanceled
= FALSE
;
150 mbPopupModeTearOff
= FALSE
;
156 // -----------------------------------------------------------------------
158 void FloatingWindow::ImplInitSettings()
160 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
163 if ( IsControlBackground() )
164 aColor
= GetControlBackground();
165 else if ( Window::GetStyle() & WB_3DLOOK
)
166 aColor
= rStyleSettings
.GetFaceColor();
168 aColor
= rStyleSettings
.GetWindowColor();
169 SetBackground( aColor
);
172 // =======================================================================
174 FloatingWindow::FloatingWindow( Window
* pParent
, WinBits nStyle
) :
175 SystemWindow( WINDOW_FLOATINGWINDOW
)
177 ImplInit( pParent
, nStyle
);
180 // -----------------------------------------------------------------------
182 FloatingWindow::FloatingWindow( Window
* pParent
, const ResId
& rResId
) :
183 SystemWindow( WINDOW_FLOATINGWINDOW
)
185 rResId
.SetRT( RSC_FLOATINGWINDOW
);
186 WinBits nStyle
= ImplInitRes( rResId
);
187 ImplInit( pParent
, nStyle
);
188 ImplLoadRes( rResId
);
190 if ( !(nStyle
& WB_HIDE
) )
194 // -----------------------------------------------------------------------
196 void FloatingWindow::ImplLoadRes( const ResId
& rResId
)
198 SystemWindow::ImplLoadRes( rResId
);
200 ULONG nObjMask
= ReadLongRes();
202 if ( (RSC_FLOATINGWINDOW_WHMAPMODE
| RSC_FLOATINGWINDOW_WIDTH
|
203 RSC_FLOATINGWINDOW_HEIGHT
) & nObjMask
)
205 // Groessenangabe aus der Resource verwenden
207 MapUnit eSizeMap
= MAP_PIXEL
;
209 if ( RSC_FLOATINGWINDOW_WHMAPMODE
& nObjMask
)
210 eSizeMap
= (MapUnit
) ReadShortRes();
211 if ( RSC_FLOATINGWINDOW_WIDTH
& nObjMask
)
212 aSize
.Width() = ReadShortRes();
213 if ( RSC_FLOATINGWINDOW_HEIGHT
& nObjMask
)
214 aSize
.Height() = ReadShortRes();
216 SetRollUpOutputSizePixel( LogicToPixel( aSize
, eSizeMap
) );
219 if (nObjMask
& RSC_FLOATINGWINDOW_ZOOMIN
)
221 if ( ReadShortRes() )
226 // -----------------------------------------------------------------------
228 FloatingWindow::~FloatingWindow()
230 if( mbPopupModeCanceled
)
231 // indicates that ESC key was pressed
232 // will be handled in Window::ImplGrabFocus()
233 SetDialogControlFlags( GetDialogControlFlags() | WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL
);
235 if ( IsInPopupMode() )
236 EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
| FLOATWIN_POPUPMODEEND_DONTCALLHDL
);
239 Application::RemoveUserEvent( mnPostId
);
244 // -----------------------------------------------------------------------
246 Point
FloatingWindow::CalcFloatingPosition( Window
* pWindow
, const Rectangle
& rRect
, ULONG nFlags
, USHORT
& rArrangeIndex
)
248 return ImplCalcPos( pWindow
, rRect
, nFlags
, rArrangeIndex
);
251 // -----------------------------------------------------------------------
253 Point
FloatingWindow::ImplCalcPos( Window
* pWindow
,
254 const Rectangle
& rRect
, ULONG nFlags
,
255 USHORT
& rArrangeIndex
)
257 // Fenster-Position ermitteln
259 Size aSize
= pWindow
->GetSizePixel();
260 Rectangle aScreenRect
= pWindow
->ImplGetFrameWindow()->GetDesktopRectPixel();
261 FloatingWindow
*pFloatingWindow
= dynamic_cast<FloatingWindow
*>( pWindow
);
264 Window
* pW
= pWindow
;
265 if ( pW
->mpWindowImpl
->mpRealParent
)
266 pW
= pW
->mpWindowImpl
->mpRealParent
;
268 Rectangle
normRect( rRect
); // rRect is already relative to top-level window
269 normRect
.SetPos( pW
->ScreenToOutputPixel( normRect
.TopLeft() ) );
271 BOOL bRTL
= Application::GetSettings().GetLayoutRTL();
273 Rectangle
devRect( pW
->OutputToAbsoluteScreenPixel( normRect
.TopLeft() ),
274 pW
->OutputToAbsoluteScreenPixel( normRect
.BottomRight() ) );
276 Rectangle
devRectRTL( devRect
);
278 // create a rect that can be compared to desktop coordinates
279 devRectRTL
= pW
->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect
);
280 if( Application::GetScreenCount() > 1 && ! Application::IsMultiDisplay() )
281 aScreenRect
= Application::GetScreenPosSizePixel(
282 Application::GetBestScreen( bRTL
? devRectRTL
: devRect
) );
285 USHORT nArrangeAry
[5];
286 USHORT nArrangeIndex
;
288 Point e1
,e2
; // the common edge between the item rect and the floating window
290 if ( nFlags
& FLOATWIN_POPUPMODE_LEFT
)
292 nArrangeAry
[0] = FLOATWIN_POPUPMODE_LEFT
;
293 nArrangeAry
[1] = FLOATWIN_POPUPMODE_RIGHT
;
294 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
295 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
296 nArrangeAry
[4] = FLOATWIN_POPUPMODE_LEFT
;
298 else if ( nFlags
& FLOATWIN_POPUPMODE_RIGHT
)
300 nArrangeAry
[0] = FLOATWIN_POPUPMODE_RIGHT
;
301 nArrangeAry
[1] = FLOATWIN_POPUPMODE_LEFT
;
302 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
303 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
304 nArrangeAry
[4] = FLOATWIN_POPUPMODE_RIGHT
;
306 else if ( nFlags
& FLOATWIN_POPUPMODE_UP
)
308 nArrangeAry
[0] = FLOATWIN_POPUPMODE_UP
;
309 nArrangeAry
[1] = FLOATWIN_POPUPMODE_DOWN
;
310 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
311 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
312 nArrangeAry
[4] = FLOATWIN_POPUPMODE_UP
;
316 nArrangeAry
[0] = FLOATWIN_POPUPMODE_DOWN
;
317 nArrangeAry
[1] = FLOATWIN_POPUPMODE_UP
;
318 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
319 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
320 nArrangeAry
[4] = FLOATWIN_POPUPMODE_DOWN
;
322 if ( nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
)
327 for ( ; nArrangeIndex
< 5; nArrangeIndex
++ )
330 switch ( nArrangeAry
[nArrangeIndex
] )
333 case FLOATWIN_POPUPMODE_LEFT
:
334 aPos
.X() = devRect
.Left()-aSize
.Width()+1;
335 aPos
.Y() = devRect
.Top();
336 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
337 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
339 if( (devRectRTL
.Right()+aSize
.Width()) > aScreenRect
.Right() )
344 if ( aPos
.X() < aScreenRect
.Left() )
349 e1
= devRect
.TopLeft();
350 e2
= devRect
.BottomLeft();
351 // set non-zero width
353 // don't clip corners
358 case FLOATWIN_POPUPMODE_RIGHT
:
359 aPos
= devRect
.TopRight();
360 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
361 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
363 if( (devRectRTL
.Left() - aSize
.Width()) < aScreenRect
.Left() )
368 if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
373 e1
= devRect
.TopRight();
374 e2
= devRect
.BottomRight();
375 // set non-zero width
377 // don't clip corners
382 case FLOATWIN_POPUPMODE_UP
:
383 aPos
.X() = devRect
.Left();
384 aPos
.Y() = devRect
.Top()-aSize
.Height()+1;
385 if ( aPos
.Y() < aScreenRect
.Top() )
389 e1
= devRect
.TopLeft();
390 e2
= devRect
.TopRight();
391 // set non-zero height
393 // don't clip corners
398 case FLOATWIN_POPUPMODE_DOWN
:
399 aPos
= devRect
.BottomLeft();
400 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
404 e1
= devRect
.BottomLeft();
405 e2
= devRect
.BottomRight();
406 // set non-zero height
408 // don't clip corners
415 // Evt. noch anpassen
416 if ( bBreak
&& !(nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
) )
418 if ( (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_LEFT
) ||
419 (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_RIGHT
) )
421 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
423 aPos
.Y() = devRect
.Bottom()-aSize
.Height()+1;
424 if ( aPos
.Y() < aScreenRect
.Top() )
425 aPos
.Y() = aScreenRect
.Top();
430 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
432 if( devRectRTL
.Right()-aSize
.Width()+1 < aScreenRect
.Left() )
433 aPos
.X() -= aScreenRect
.Left() - devRectRTL
.Right() + aSize
.Width() - 1;
434 else if( aPos
.X() + aSize
.Width() > aScreenRect
.Right() )
436 aPos
.X() -= aSize
.Width()-2; // popup to left instead
440 else if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
442 aPos
.X() = devRect
.Right()-aSize
.Width()+1;
443 if ( aPos
.X() < aScreenRect
.Left() )
444 aPos
.X() = aScreenRect
.Left();
452 if ( nArrangeIndex
> 4 )
455 rArrangeIndex
= nArrangeIndex
;
457 aPos
= pW
->AbsoluteScreenToOutputPixel( aPos
);
459 // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
460 if( pFloatingWindow
)
462 pFloatingWindow
->mpImplData
->maItemEdgeClipRect
=
466 // caller expects cordinates relative to top-level win
467 return pW
->OutputToScreenPixel( aPos
);
470 // -----------------------------------------------------------------------
472 FloatingWindow
* FloatingWindow::ImplFloatHitTest( Window
* pReference
, const Point
& rPos
, USHORT
& rHitTest
)
474 FloatingWindow
* pWin
= this;
476 Point
aAbsolute( rPos
);
478 // compare coordinates in absolute screen coordinates
479 if( pReference
->ImplHasMirroredGraphics() )
481 if(!pReference
->IsRTLEnabled() )
482 // --- RTL --- re-mirror back to get device coordiantes
483 pReference
->ImplReMirror( aAbsolute
);
485 Rectangle
aRect( pReference
->ScreenToOutputPixel(aAbsolute
), Size(1,1) ) ;
486 aRect
= pReference
->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect
);
487 aAbsolute
= aRect
.TopLeft();
490 aAbsolute
= Point( pReference
->OutputToAbsoluteScreenPixel(
491 pReference
->ScreenToOutputPixel(rPos
) ) );
495 // compute the floating window's size in absolute screen coordinates
497 // use the border window to have the exact position
498 Window
*pBorderWin
= pWin
->GetWindow( WINDOW_BORDER
);
500 Point aPt
; // the top-left corner in output coordinates ie (0,0)
501 Rectangle
devRect( pBorderWin
->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt
, pBorderWin
->GetSizePixel()) ) ) ;
502 if ( devRect
.IsInside( aAbsolute
) )
504 rHitTest
= IMPL_FLOATWIN_HITTEST_WINDOW
;
508 // test, if mouse is in rectangle, (this is typically the rect of the active
509 // toolbox item or similar)
510 // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
511 // is already in absolute device coordinates
512 if ( pWin
->maFloatRect
.IsInside( aAbsolute
) )
514 rHitTest
= IMPL_FLOATWIN_HITTEST_RECT
;
518 pWin
= pWin
->mpNextFloat
;
522 rHitTest
= IMPL_FLOATWIN_HITTEST_OUTSIDE
;
526 // -----------------------------------------------------------------------
528 FloatingWindow
* FloatingWindow::ImplFindLastLevelFloat()
530 FloatingWindow
* pWin
= this;
531 FloatingWindow
* pLastFoundWin
= pWin
;
535 if ( pWin
->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL
)
536 pLastFoundWin
= pWin
;
538 pWin
= pWin
->mpNextFloat
;
542 return pLastFoundWin
;
545 // -----------------------------------------------------------------------
547 BOOL
FloatingWindow::ImplIsFloatPopupModeWindow( const Window
* pWindow
)
549 FloatingWindow
* pWin
= this;
553 if ( pWin
->mpFirstPopupModeWin
== pWindow
)
556 pWin
= pWin
->mpNextFloat
;
563 // -----------------------------------------------------------------------
565 IMPL_LINK( FloatingWindow
, ImplEndPopupModeHdl
, void*, EMPTYARG
)
568 mnPopupModeFlags
= 0;
574 // -----------------------------------------------------------------------
576 long FloatingWindow::Notify( NotifyEvent
& rNEvt
)
578 // Zuerst Basisklasse rufen wegen TabSteuerung
579 long nRet
= SystemWindow::Notify( rNEvt
);
582 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
584 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
585 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
586 USHORT nKeyCode
= aKeyCode
.GetCode();
588 if ( (nKeyCode
== KEY_ESCAPE
) && (GetStyle() & WB_CLOSEABLE
) )
599 // -----------------------------------------------------------------------
601 void FloatingWindow::StateChanged( StateChangedType nType
)
603 SystemWindow::StateChanged( nType
);
605 if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
612 // -----------------------------------------------------------------------
614 void FloatingWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
616 SystemWindow::DataChanged( rDCEvt
);
618 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
619 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
626 // -----------------------------------------------------------------------
628 void FloatingWindow::ImplCallPopupModeEnd()
630 // PopupMode wurde beendet
631 mbInPopupMode
= FALSE
;
633 // Handler asyncron rufen
635 Application::PostUserEvent( mnPostId
, LINK( this, FloatingWindow
, ImplEndPopupModeHdl
) );
638 // -----------------------------------------------------------------------
640 void FloatingWindow::PopupModeEnd()
642 maPopupModeEndHdl
.Call( this );
645 // -----------------------------------------------------------------------
647 void FloatingWindow::SetTitleType( USHORT nTitle
)
649 if ( (mnTitle
!= nTitle
) && mpWindowImpl
->mpBorderWindow
)
652 Size aOutSize
= GetOutputSizePixel();
654 if ( nTitle
== FLOATWIN_TITLE_NORMAL
)
655 nTitleStyle
= BORDERWINDOW_TITLE_SMALL
;
656 else if ( nTitle
== FLOATWIN_TITLE_TEAROFF
)
657 nTitleStyle
= BORDERWINDOW_TITLE_TEAROFF
;
658 else // nTitle == FLOATWIN_TITLE_NONE
659 nTitleStyle
= BORDERWINDOW_TITLE_NONE
;
660 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->SetTitleType( nTitleStyle
, aOutSize
);
661 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
665 // -----------------------------------------------------------------------
667 void FloatingWindow::StartPopupMode( const Rectangle
& rRect
, ULONG nFlags
)
671 Show( FALSE
, SHOW_NOFOCUSCHANGE
);
677 mnOldTitle
= mnTitle
;
678 if ( nFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
)
679 SetTitleType( FLOATWIN_TITLE_TEAROFF
);
681 SetTitleType( FLOATWIN_TITLE_NONE
);
683 // avoid close on focus change for decorated floating windows only
684 if( mpWindowImpl
->mbFrame
&& (GetStyle() & WB_MOVEABLE
) )
685 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
687 // #102010# For debugging Accessibility
688 static const char* pEnv
= getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
690 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
692 // compute window position according to flags and arrangement
693 USHORT nArrangeIndex
;
694 SetPosPixel( ImplCalcPos( this, rRect
, nFlags
, nArrangeIndex
) );
696 // set data and display window
697 // convert maFloatRect to absolute device coordinates
698 // so they can be compared across different frames
699 // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
701 if( GetParent()->ImplHasMirroredGraphics() )
703 maFloatRect
.SetPos( GetParent()->ScreenToOutputPixel( rRect
.TopLeft() ) );
704 maFloatRect
= GetParent()->ImplOutputToUnmirroredAbsoluteScreenPixel( maFloatRect
);
707 maFloatRect
.SetPos( GetParent()->OutputToAbsoluteScreenPixel( GetParent()->ScreenToOutputPixel( rRect
.TopLeft() ) ) );
709 maFloatRect
.Left() -= 2;
710 maFloatRect
.Top() -= 2;
711 maFloatRect
.Right() += 2;
712 maFloatRect
.Bottom() += 2;
713 mnPopupModeFlags
= nFlags
;
714 mbInPopupMode
= TRUE
;
716 mbPopupModeCanceled
= FALSE
;
717 mbPopupModeTearOff
= FALSE
;
720 mbOldSaveBackMode
= IsSaveBackgroundEnabled();
721 EnableSaveBackground();
723 // add FloatingWindow to list of windows that are in popup mode
724 ImplSVData
* pSVData
= ImplGetSVData();
725 mpNextFloat
= pSVData
->maWinData
.mpFirstFloat
;
726 pSVData
->maWinData
.mpFirstFloat
= this;
727 if( nFlags
& FLOATWIN_POPUPMODE_GRABFOCUS
)
729 // force key input even without focus (useful for menues)
732 Show( TRUE
, SHOW_NOACTIVATE
);
735 // -----------------------------------------------------------------------
737 void FloatingWindow::StartPopupMode( ToolBox
* pBox
, ULONG nFlags
)
739 // get selected button
740 USHORT nItemId
= pBox
->GetDownItemId();
744 mpImplData
->mpBox
= pBox
;
745 pBox
->ImplFloatControl( TRUE
, this );
747 // retrieve some data from the ToolBox
748 Rectangle aRect
= pBox
->GetItemRect( nItemId
);
750 // convert to parent's screen coordinates
751 aPos
= GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox
->OutputToAbsoluteScreenPixel( aRect
.TopLeft() ) ) );
752 aRect
.SetPos( aPos
);
755 FLOATWIN_POPUPMODE_NOFOCUSCLOSE
|
756 // FLOATWIN_POPUPMODE_NOMOUSECLOSE |
757 FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE
|
758 // FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE | // #105968# floating toolboxes should close when clicked in (parent's) float rect
759 FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE
;
760 // | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
763 * FLOATWIN_POPUPMODE_NOKEYCLOSE |
764 * don't set since it disables closing floaters with escape
767 // Flags fuer Positionierung bestimmen
768 if ( !(nFlags
& (FLOATWIN_POPUPMODE_DOWN
| FLOATWIN_POPUPMODE_UP
|
769 FLOATWIN_POPUPMODE_LEFT
| FLOATWIN_POPUPMODE_RIGHT
|
770 FLOATWIN_POPUPMODE_NOAUTOARRANGE
)) )
772 if ( pBox
->IsHorizontal() )
773 nFlags
|= FLOATWIN_POPUPMODE_DOWN
;
775 nFlags
|= FLOATWIN_POPUPMODE_RIGHT
;
778 // FloatingModus starten
779 StartPopupMode( aRect
, nFlags
);
782 // -----------------------------------------------------------------------
784 void FloatingWindow::ImplEndPopupMode( USHORT nFlags
, ULONG nFocusId
)
786 if ( !mbInPopupMode
)
789 ImplSVData
* pSVData
= ImplGetSVData();
791 mbInCleanUp
= TRUE
; // prevent killing this window due to focus change while working with it
793 // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
794 while ( pSVData
->maWinData
.mpFirstFloat
&& pSVData
->maWinData
.mpFirstFloat
!= this )
795 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
798 // Fenster aus der Liste austragen
799 pSVData
->maWinData
.mpFirstFloat
= mpNextFloat
;
802 ULONG nPopupModeFlags
= mnPopupModeFlags
;
804 // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
805 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_TEAROFF
) ||
806 !(nPopupModeFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
) )
808 Show( FALSE
, SHOW_NOFOCUSCHANGE
);
810 // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
812 Window::EndSaveFocus( nFocusId
);
813 else if ( pSVData
->maWinData
.mpFocusWin
&& pSVData
->maWinData
.mpFirstFloat
&&
814 ImplIsWindowOrChild( pSVData
->maWinData
.mpFocusWin
) )
815 pSVData
->maWinData
.mpFirstFloat
->GrabFocus();
816 mbPopupModeTearOff
= FALSE
;
820 mbPopupModeTearOff
= TRUE
;
822 Window::EndSaveFocus( nFocusId
, FALSE
);
824 EnableSaveBackground( mbOldSaveBackMode
);
826 mbPopupModeCanceled
= (nFlags
& FLOATWIN_POPUPMODEEND_CANCEL
) != 0;
828 // Gegebenenfalls den Title wieder herstellen
829 SetTitleType( mnOldTitle
);
831 // ToolBox wieder auf normal schalten
832 if ( mpImplData
->mpBox
)
834 mpImplData
->mpBox
->ImplFloatControl( FALSE
, this );
835 mpImplData
->mpBox
= NULL
;
838 // Je nach Parameter den PopupModeEnd-Handler rufen
839 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_DONTCALLHDL
) )
840 ImplCallPopupModeEnd();
842 // Je nach Parameter die restlichen Fenster auch noch schliessen
843 if ( nFlags
& FLOATWIN_POPUPMODEEND_CLOSEALL
)
845 if ( !(nPopupModeFlags
& FLOATWIN_POPUPMODE_NEWLEVEL
) )
847 if ( pSVData
->maWinData
.mpFirstFloat
)
849 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
850 pLastLevelFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
858 // -----------------------------------------------------------------------
860 void FloatingWindow::EndPopupMode( USHORT nFlags
)
862 ImplEndPopupMode( nFlags
);
865 // -----------------------------------------------------------------------
867 void FloatingWindow::AddPopupModeWindow( Window
* pWindow
)
869 // !!! bisher erst 1 Fenster und noch keine Liste
870 mpFirstPopupModeWin
= pWindow
;
873 // -----------------------------------------------------------------------
875 void FloatingWindow::RemovePopupModeWindow( Window
* pWindow
)
877 // !!! bisher erst 1 Fenster und noch keine Liste
878 if ( mpFirstPopupModeWin
== pWindow
)
879 mpFirstPopupModeWin
= NULL
;