Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/time.hxx>
21 : #include <tools/rc.h>
22 :
23 : #include <brdwin.hxx>
24 : #include <svdata.hxx>
25 : #include <salframe.hxx>
26 : #include <window.h>
27 :
28 : #include <vcl/event.hxx>
29 : #include <vcl/floatwin.hxx>
30 : #include <vcl/dockwin.hxx>
31 : #include <vcl/toolbox.hxx>
32 : #include <vcl/svapp.hxx>
33 : #include <vcl/timer.hxx>
34 : #include <vcl/idle.hxx>
35 : #include <vcl/lineinfo.hxx>
36 : #include <vcl/unowrap.hxx>
37 : #include <vcl/settings.hxx>
38 :
39 : #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE )
40 :
41 : class ImplDockFloatWin2 : public FloatingWindow
42 : {
43 : private:
44 : ImplDockingWindowWrapper* mpDockWin;
45 : sal_uInt64 mnLastTicks;
46 : Idle maDockIdle;
47 : Idle maEndDockIdle;
48 : Point maDockPos;
49 : Rectangle maDockRect;
50 : bool mbInMove;
51 : ImplSVEvent * mnLastUserEvent;
52 :
53 : DECL_LINK(DockingHdl, void *);
54 : DECL_LINK_TYPED(DockTimerHdl, Idle *, void);
55 : DECL_LINK_TYPED(EndDockTimerHdl, Idle *, void);
56 : public:
57 : ImplDockFloatWin2( vcl::Window* pParent, WinBits nWinBits,
58 : ImplDockingWindowWrapper* pDockingWin );
59 : virtual ~ImplDockFloatWin2();
60 : virtual void dispose() SAL_OVERRIDE;
61 :
62 : virtual void Move() SAL_OVERRIDE;
63 : virtual void Resize() SAL_OVERRIDE;
64 : virtual void TitleButtonClick( TitleButton nButton ) SAL_OVERRIDE;
65 : virtual void Pin() SAL_OVERRIDE;
66 : virtual void Roll() SAL_OVERRIDE;
67 : virtual void PopupModeEnd() SAL_OVERRIDE;
68 : virtual void Resizing( Size& rSize ) SAL_OVERRIDE;
69 : virtual bool Close() SAL_OVERRIDE;
70 : };
71 :
72 0 : ImplDockFloatWin2::ImplDockFloatWin2( vcl::Window* pParent, WinBits nWinBits,
73 : ImplDockingWindowWrapper* pDockingWin ) :
74 : FloatingWindow( pParent, nWinBits ),
75 : mpDockWin( pDockingWin ),
76 0 : mnLastTicks( tools::Time::GetSystemTicks() ),
77 : mbInMove( false ),
78 0 : mnLastUserEvent( 0 )
79 : {
80 : // copy state of DockingWindow
81 0 : if ( pDockingWin )
82 : {
83 0 : SetSettings( pDockingWin->GetWindow()->GetSettings() );
84 0 : Enable( pDockingWin->GetWindow()->IsEnabled(), false );
85 0 : EnableInput( pDockingWin->GetWindow()->IsInputEnabled(), false );
86 0 : AlwaysEnableInput( pDockingWin->GetWindow()->IsAlwaysEnableInput(), false );
87 0 : EnableAlwaysOnTop( pDockingWin->GetWindow()->IsAlwaysOnTopEnabled() );
88 0 : SetActivateMode( pDockingWin->GetWindow()->GetActivateMode() );
89 : }
90 :
91 0 : SetBackground( GetSettings().GetStyleSettings().GetFaceColor() );
92 :
93 0 : maDockIdle.SetIdleHdl( LINK( this, ImplDockFloatWin2, DockTimerHdl ) );
94 0 : maDockIdle.SetPriority( SchedulerPriority::MEDIUM );
95 0 : maEndDockIdle.SetIdleHdl( LINK( this, ImplDockFloatWin2, EndDockTimerHdl ) );
96 0 : maEndDockIdle.SetPriority( SchedulerPriority::MEDIUM );
97 0 : }
98 :
99 0 : ImplDockFloatWin2::~ImplDockFloatWin2()
100 : {
101 0 : disposeOnce();
102 0 : }
103 :
104 0 : void ImplDockFloatWin2::dispose()
105 : {
106 0 : if( mnLastUserEvent )
107 0 : Application::RemoveUserEvent( mnLastUserEvent );
108 0 : FloatingWindow::dispose();
109 0 : }
110 :
111 0 : IMPL_LINK_NOARG_TYPED(ImplDockFloatWin2, DockTimerHdl, Idle *, void)
112 : {
113 : DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" );
114 :
115 0 : maDockIdle.Stop();
116 0 : PointerState aState = GetPointerState();
117 :
118 0 : if( aState.mnState & KEY_MOD1 )
119 : {
120 : // i43499 CTRL disables docking now
121 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
122 0 : if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) )
123 0 : maDockIdle.Start();
124 : }
125 0 : else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
126 : {
127 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
128 0 : mpDockWin->EndDocking( maDockRect, false );
129 : }
130 : else
131 : {
132 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
133 0 : maDockIdle.Start();
134 : }
135 0 : }
136 :
137 0 : IMPL_LINK_NOARG_TYPED(ImplDockFloatWin2, EndDockTimerHdl, Idle *, void)
138 : {
139 : DBG_ASSERT( mpDockWin->IsFloatingMode(), "enddocktimer called but not floating" );
140 :
141 0 : maEndDockIdle.Stop();
142 0 : PointerState aState = GetPointerState();
143 0 : if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
144 : {
145 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
146 0 : mpDockWin->EndDocking( maDockRect, true );
147 : }
148 : else
149 : {
150 0 : maEndDockIdle.Start();
151 : }
152 0 : }
153 :
154 0 : IMPL_LINK_NOARG(ImplDockFloatWin2, DockingHdl)
155 : {
156 : // called during move of a floating window
157 0 : mnLastUserEvent = 0;
158 :
159 0 : vcl::Window *pDockingArea = mpDockWin->GetWindow()->GetParent();
160 0 : PointerState aState = pDockingArea->GetPointerState();
161 :
162 0 : bool bRealMove = true;
163 0 : if( GetStyle() & WB_OWNERDRAWDECORATION )
164 : {
165 : // for windows with ownerdraw decoration
166 : // we allow docking only when the window was moved
167 : // by dragging its caption
168 : // and ignore move request due to resizing
169 0 : vcl::Window *pBorder = GetWindow( GetWindowType::Border );
170 0 : if( pBorder != this )
171 : {
172 0 : Point aPt;
173 0 : Rectangle aBorderRect( aPt, pBorder->GetSizePixel() );
174 : sal_Int32 nLeft, nTop, nRight, nBottom;
175 0 : GetBorder( nLeft, nTop, nRight, nBottom );
176 : // limit borderrect to the caption part only and without the resizing borders
177 0 : aBorderRect.Bottom() = aBorderRect.Top() + nTop;
178 0 : aBorderRect.Left() += nLeft;
179 0 : aBorderRect.Right() -= nRight;
180 :
181 0 : PointerState aBorderState = pBorder->GetPointerState();
182 0 : if( aBorderRect.IsInside( aBorderState.maPos ) )
183 0 : bRealMove = true;
184 : else
185 0 : bRealMove = false;
186 : }
187 : }
188 :
189 0 : if( mpDockWin->IsDockable() &&
190 0 : mpDockWin->GetWindow()->IsVisible() &&
191 0 : (tools::Time::GetSystemTicks() - mnLastTicks > 500) &&
192 0 : ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) &&
193 0 : !(aState.mnState & KEY_MOD1) && // i43499 CTRL disables docking now
194 : bRealMove )
195 : {
196 0 : maDockPos = Point( pDockingArea->OutputToScreenPixel( pDockingArea->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) ) );
197 0 : maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() );
198 :
199 : // mouse pos in screen pixels
200 0 : Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos );
201 :
202 0 : if( ! mpDockWin->IsDocking() )
203 0 : mpDockWin->StartDocking( aMousePos, maDockRect );
204 :
205 0 : bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect );
206 :
207 0 : if( ! bFloatMode )
208 : {
209 : // indicates that the window could be docked at maDockRect
210 : maDockRect.SetPos( mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ScreenToOutputPixel(
211 0 : maDockRect.TopLeft() ) );
212 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
213 0 : maEndDockIdle.Stop();
214 0 : DockTimerHdl( nullptr );
215 : }
216 : else
217 : {
218 0 : mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking();
219 0 : maDockIdle.Stop();
220 0 : EndDockTimerHdl( nullptr );
221 : }
222 : }
223 0 : mbInMove = false;
224 0 : return 0;
225 : }
226 :
227 0 : void ImplDockFloatWin2::Move()
228 : {
229 0 : if( mbInMove )
230 0 : return;
231 :
232 0 : mbInMove = true;
233 0 : FloatingWindow::Move();
234 0 : mpDockWin->GetWindow()->Move();
235 :
236 : /*
237 : * note: the window should only dock if KEY_MOD1 is pressed
238 : * and the user releases all mouse buttons. The real problem here
239 : * is that we don't get mouse events (at least not on X)
240 : * if the mouse is on the decoration. So we have to start an
241 : * awkward timer based process that polls the modifier/buttons
242 : * to see whether they are in the right condition shortly after the
243 : * last Move message.
244 : */
245 0 : if( ! mnLastUserEvent )
246 0 : mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin2, DockingHdl ), NULL, true );
247 : }
248 :
249 0 : void ImplDockFloatWin2::Resize()
250 : {
251 : // forwarding of resize only required if we have no borderwindow ( GetWindow() then returns 'this' )
252 0 : if( GetWindow( GetWindowType::Border ) == this )
253 : {
254 0 : FloatingWindow::Resize();
255 0 : Size aSize( GetSizePixel() );
256 0 : mpDockWin->GetWindow()->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), PosSizeFlags::PosSize ); // TODO: is this needed ???
257 : }
258 0 : }
259 :
260 0 : void ImplDockFloatWin2::TitleButtonClick( TitleButton nButton )
261 : {
262 0 : FloatingWindow::TitleButtonClick( nButton );
263 0 : mpDockWin->TitleButtonClick( nButton );
264 0 : }
265 :
266 0 : void ImplDockFloatWin2::Pin()
267 : {
268 0 : FloatingWindow::Pin();
269 0 : }
270 :
271 0 : void ImplDockFloatWin2::Roll()
272 : {
273 0 : FloatingWindow::Roll();
274 0 : }
275 :
276 0 : void ImplDockFloatWin2::PopupModeEnd()
277 : {
278 0 : FloatingWindow::PopupModeEnd();
279 0 : }
280 :
281 0 : void ImplDockFloatWin2::Resizing( Size& rSize )
282 : {
283 0 : FloatingWindow::Resizing( rSize );
284 0 : mpDockWin->Resizing( rSize );
285 0 : }
286 :
287 0 : bool ImplDockFloatWin2::Close()
288 : {
289 0 : return true;
290 : }
291 :
292 212 : DockingManager::DockingManager()
293 : {
294 212 : }
295 :
296 420 : DockingManager::~DockingManager()
297 : {
298 210 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
299 210 : p = mDockingWindows.begin();
300 222 : for(; p != mDockingWindows.end(); ++p )
301 : {
302 12 : delete (*p);
303 : }
304 210 : mDockingWindows.clear();
305 210 : }
306 :
307 3799598 : ImplDockingWindowWrapper* DockingManager::GetDockingWindowWrapper( const vcl::Window *pWindow )
308 : {
309 3799598 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
310 3799598 : p = mDockingWindows.begin();
311 15673796 : while( p != mDockingWindows.end() )
312 : {
313 9416542 : if( (*p)->mpDockingWindow == pWindow )
314 1341942 : return (*p);
315 : else
316 8074600 : ++p;
317 : }
318 2457656 : return NULL;
319 : }
320 :
321 489912 : bool DockingManager::IsDockable( const vcl::Window *pWindow )
322 : {
323 489912 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
324 :
325 : /*
326 : if( pWindow->HasDockingHandler() )
327 : return true;
328 : */
329 489912 : return (pWrapper != NULL);
330 : }
331 :
332 17721 : bool DockingManager::IsFloating( const vcl::Window *pWindow )
333 : {
334 17721 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
335 17721 : if( pWrapper )
336 17721 : return pWrapper->IsFloatingMode();
337 : else
338 0 : return false;
339 : }
340 :
341 0 : bool DockingManager::IsLocked( const vcl::Window *pWindow )
342 : {
343 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
344 0 : if( pWrapper && pWrapper->IsLocked() )
345 0 : return true;
346 : else
347 0 : return false;
348 : }
349 :
350 0 : void DockingManager::Lock( const vcl::Window *pWindow )
351 : {
352 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
353 0 : if( pWrapper )
354 0 : pWrapper->Lock();
355 0 : }
356 :
357 0 : void DockingManager::Unlock( const vcl::Window *pWindow )
358 : {
359 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
360 0 : if( pWrapper )
361 0 : pWrapper->Unlock();
362 0 : }
363 :
364 9522 : void DockingManager::SetFloatingMode( const vcl::Window *pWindow, bool bFloating )
365 : {
366 9522 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
367 9522 : if( pWrapper )
368 9522 : pWrapper->SetFloatingMode( bFloating );
369 9522 : }
370 :
371 0 : void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWindow, FloatWinPopupFlags nFlags )
372 : {
373 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
374 0 : if( pWrapper )
375 0 : pWrapper->StartPopupMode( pParentToolBox, nFlags );
376 0 : }
377 :
378 0 : void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWindow )
379 : {
380 : StartPopupMode( pParentToolBox, pWindow, FloatWinPopupFlags::AllowTearOff |
381 : FloatWinPopupFlags::NoFocusClose |
382 0 : FloatWinPopupFlags::AllMouseButtonClose |
383 0 : FloatWinPopupFlags::NoMouseUpClose );
384 0 : }
385 :
386 0 : bool DockingManager::IsInPopupMode( const vcl::Window *pWindow )
387 : {
388 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
389 0 : if( pWrapper && pWrapper->IsInPopupMode() )
390 0 : return true;
391 : else
392 0 : return false;
393 : }
394 :
395 0 : void DockingManager::EndPopupMode( const vcl::Window *pWin )
396 : {
397 0 : ImplDockingWindowWrapper *pWrapper = GetDockingWindowWrapper( pWin );
398 0 : if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() )
399 0 : pWrapper->GetFloatingWindow()->EndPopupMode();
400 0 : }
401 :
402 12262 : void DockingManager::AddWindow( const vcl::Window *pWindow )
403 : {
404 12262 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
405 12262 : if( pWrapper )
406 12262 : return;
407 : else
408 12262 : pWrapper = new ImplDockingWindowWrapper( pWindow );
409 :
410 12262 : mDockingWindows.push_back( pWrapper );
411 : }
412 :
413 270153 : void DockingManager::RemoveWindow( const vcl::Window *pWindow )
414 : {
415 270153 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
416 270153 : p = mDockingWindows.begin();
417 1342995 : while( p != mDockingWindows.end() )
418 : {
419 814938 : if( (*p)->mpDockingWindow == pWindow )
420 : {
421 12249 : delete (*p);
422 12249 : mDockingWindows.erase( p );
423 12249 : break;
424 : }
425 : else
426 802689 : ++p;
427 : }
428 270153 : }
429 :
430 9522 : void DockingManager::SetPosSizePixel( vcl::Window *pWindow, long nX, long nY,
431 : long nWidth, long nHeight,
432 : PosSizeFlags nFlags )
433 : {
434 9522 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
435 9522 : if( pWrapper )
436 9522 : pWrapper->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
437 9522 : }
438 :
439 22041 : Rectangle DockingManager::GetPosSizePixel( const vcl::Window *pWindow )
440 : {
441 22041 : Rectangle aRect;
442 22041 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
443 22041 : if( pWrapper )
444 22041 : aRect = Rectangle( pWrapper->GetPosPixel(), pWrapper->GetSizePixel() );
445 :
446 22041 : return aRect;
447 : }
448 :
449 : // special floating window for popup mode
450 : // main purpose: provides tear-off area for undocking
451 :
452 : // if TEAROFF_DASHED defined a single dashed line is used
453 : // otherwise multiple smaller lines will be painted
454 : //#define TEAROFF_DASHED
455 :
456 : // size of the drag area
457 : #ifdef TEAROFF_DASHED
458 : #define POPUP_DRAGBORDER 2
459 : #define POPUP_DRAGGRIP 5
460 : #else
461 : #define POPUP_DRAGBORDER 3
462 : #define POPUP_DRAGGRIP 5
463 : #endif
464 : #define POPUP_DRAGHEIGHT (POPUP_DRAGGRIP+POPUP_DRAGBORDER+POPUP_DRAGBORDER)
465 : #define POPUP_DRAGWIDTH 20
466 :
467 : class ImplPopupFloatWin : public FloatingWindow
468 : {
469 : private:
470 : ImplDockingWindowWrapper* mpDockingWin;
471 : bool mbHighlight;
472 : bool mbMoving;
473 : bool mbTrackingEnabled;
474 : Point maDelta;
475 : Point maTearOffPosition;
476 : bool mbGripAtBottom;
477 : bool mbHasGrip;
478 : void ImplSetBorder();
479 :
480 : public:
481 : ImplPopupFloatWin( vcl::Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip );
482 : virtual ~ImplPopupFloatWin();
483 : virtual void dispose() SAL_OVERRIDE;
484 :
485 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible() SAL_OVERRIDE;
486 : virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
487 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
488 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
489 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
490 : virtual void Tracking( const TrackingEvent& rTEvt ) SAL_OVERRIDE;
491 : virtual void Resize() SAL_OVERRIDE;
492 : virtual vcl::Window* GetPreferredKeyInputWindow() SAL_OVERRIDE;
493 :
494 : Rectangle GetDragRect() const;
495 : Point GetToolboxPosition() const;
496 : Point GetTearOffPosition() const;
497 : void DrawGrip(vcl::RenderContext& rRenderContext);
498 : void DrawBorder(vcl::RenderContext& rRenderContext);
499 :
500 0 : bool hasGrip() const { return mbHasGrip; }
501 : };
502 :
503 0 : ImplPopupFloatWin::ImplPopupFloatWin( vcl::Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ) :
504 0 : FloatingWindow( pParent, WB_NOBORDER | WB_SYSTEMWINDOW | WB_NOSHADOW)
505 : {
506 0 : mpWindowImpl->mbToolbarFloatingWindow = true; // indicate window type, required for accessibility
507 : // which should not see this window as a toplevel window
508 0 : mpDockingWin = pDockingWin;
509 0 : mbHighlight = false;
510 0 : mbMoving = false;
511 0 : mbTrackingEnabled = false;
512 0 : mbGripAtBottom = true;
513 0 : mbHasGrip = bHasGrip;
514 :
515 0 : ImplSetBorder();
516 0 : }
517 :
518 0 : ImplPopupFloatWin::~ImplPopupFloatWin()
519 : {
520 0 : disposeOnce();
521 0 : }
522 :
523 0 : void ImplPopupFloatWin::dispose()
524 : {
525 0 : mpDockingWin = NULL;
526 0 : FloatingWindow::dispose();
527 0 : }
528 :
529 0 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ImplPopupFloatWin::CreateAccessible()
530 : {
531 : // switch off direct accessibilty support for this window
532 :
533 : // this is to avoid appearance of this window as standalone window in the accessibility hierarchy
534 : // as this window is only used as a helper for subtoolbars that are not teared-off, the parent toolbar
535 : // has to provide accessibility support (as implemented in the toolkit)
536 : // so the contained toolbar should appear as child of the correponsing toolbar item of the parent toolbar
537 0 : return ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >();
538 : }
539 :
540 0 : vcl::Window* ImplPopupFloatWin::GetPreferredKeyInputWindow()
541 : {
542 0 : if( mpWindowImpl->mpClientWindow )
543 0 : return mpWindowImpl->mpClientWindow;
544 : else
545 0 : return FloatingWindow::GetPreferredKeyInputWindow();
546 : }
547 :
548 0 : void ImplPopupFloatWin::ImplSetBorder()
549 : {
550 : // although we have no border in the sense of a borderwindow
551 : // we're using a special border for the grip
552 : // by setting those members the method SetOutputSizePixel() can
553 : // be used to set the proper window size
554 0 : mpWindowImpl->mnTopBorder = 1;
555 0 : if( hasGrip() )
556 0 : mpWindowImpl->mnTopBorder += POPUP_DRAGHEIGHT+2;
557 0 : mpWindowImpl->mnBottomBorder = 1;
558 0 : mpWindowImpl->mnLeftBorder = 1;
559 0 : mpWindowImpl->mnRightBorder = 1;
560 0 : }
561 :
562 0 : void ImplPopupFloatWin::Resize()
563 : {
564 : // the borderview overwrites the border during resize so restore it
565 0 : ImplSetBorder();
566 0 : }
567 :
568 0 : Rectangle ImplPopupFloatWin::GetDragRect() const
569 : {
570 0 : Rectangle aRect;
571 0 : if( hasGrip() )
572 : {
573 0 : aRect = Rectangle( 1,1, GetOutputSizePixel().Width()-1, 2+POPUP_DRAGHEIGHT );
574 0 : if( mbGripAtBottom )
575 : {
576 0 : int height = GetOutputSizePixel().Height();
577 0 : aRect.Top() = height - 3 - POPUP_DRAGHEIGHT;
578 0 : aRect.Bottom() = aRect.Top() + 1 + POPUP_DRAGHEIGHT;
579 : }
580 : }
581 0 : return aRect;
582 : }
583 :
584 0 : Point ImplPopupFloatWin::GetToolboxPosition() const
585 : {
586 : // return inner position where a toolbox could be placed
587 0 : Point aPt( 1, 1 + ((mbGripAtBottom || !hasGrip()) ? 0 : GetDragRect().getHeight()) ); // grip + border
588 :
589 0 : return aPt;
590 : }
591 :
592 0 : Point ImplPopupFloatWin::GetTearOffPosition() const
593 : {
594 0 : Point aPt( maTearOffPosition );
595 : //aPt += GetToolboxPosition(); // remove 'decoration'
596 0 : return aPt;
597 : }
598 :
599 0 : void ImplPopupFloatWin::DrawBorder(vcl::RenderContext& rRenderContext)
600 : {
601 0 : rRenderContext.SetFillColor();
602 0 : Point aPt;
603 0 : Rectangle aRect( aPt, GetOutputSizePixel() );
604 :
605 0 : vcl::Region oldClipRgn( GetClipRegion( ) );
606 0 : vcl::Region aClipRgn( aRect );
607 0 : Rectangle aItemClipRect( ImplGetItemEdgeClipRect() );
608 0 : if( !aItemClipRect.IsEmpty() )
609 : {
610 0 : aItemClipRect.SetPos( AbsoluteScreenToOutputPixel( aItemClipRect.TopLeft() ) );
611 :
612 : // draw the excluded border part with the background color of a toolbox
613 0 : rRenderContext.SetClipRegion( vcl::Region( aItemClipRect ) );
614 0 : rRenderContext.SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
615 0 : rRenderContext.DrawRect( aRect );
616 :
617 0 : aClipRgn.Exclude( aItemClipRect );
618 0 : SetClipRegion( aClipRgn );
619 : }
620 0 : rRenderContext.SetLineColor( rRenderContext.GetSettings().GetStyleSettings().GetShadowColor() );
621 0 : rRenderContext.DrawRect( aRect );
622 0 : rRenderContext.SetClipRegion( oldClipRgn );
623 0 : }
624 :
625 0 : void ImplPopupFloatWin::DrawGrip(vcl::RenderContext& rRenderContext)
626 : {
627 0 : bool bLinecolor = rRenderContext.IsLineColor();
628 0 : Color aLinecolor = rRenderContext.GetLineColor();
629 0 : bool bFillcolor = rRenderContext.IsFillColor();
630 0 : Color aFillcolor = rRenderContext.GetFillColor();
631 :
632 : // draw background
633 0 : Rectangle aRect(GetDragRect());
634 0 : aRect.Top() += POPUP_DRAGBORDER;
635 0 : aRect.Bottom() -= POPUP_DRAGBORDER;
636 0 : aRect.Left() += 3;
637 0 : aRect.Right() -= 3;
638 :
639 0 : if (mbHighlight)
640 : {
641 0 : rRenderContext.Erase(aRect);
642 0 : vcl::RenderTools::DrawSelectionBackground(rRenderContext, *this, aRect, 2, false, true, false);
643 : }
644 : else
645 : {
646 0 : rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetFaceColor());
647 0 : rRenderContext.SetLineColor();
648 0 : rRenderContext.DrawRect(aRect);
649 : }
650 :
651 0 : if (!ToolBox::AlwaysLocked()) // no grip if toolboxes are locked
652 : {
653 : #ifdef TEAROFF_DASHED
654 : // draw single dashed line
655 : LineInfo aLineInfo(LINE_DASH);
656 : aLineInfo.SetDistance(4);
657 : aLineInfo.SetDashLen(12);
658 : aLineInfo.SetDashCount(1);
659 :
660 : aRect.Left() += 2;
661 : aRect.Right()-= 2;
662 :
663 : aRect.Top() += 2;
664 : aRect.Bottom() = aRect.Top();
665 : rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetDarkShadowColor());
666 : rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight(), aLineInfo);
667 :
668 : if (!mbHighlight)
669 : {
670 : ++aRect.Top();
671 : ++aRect.Bottom();
672 : rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetLightColor());
673 : rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight(), aLineInfo);
674 : }
675 :
676 : #else
677 : // draw several grip lines
678 0 : rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetShadowColor());
679 0 : aRect.Top()++;
680 0 : aRect.Bottom() = aRect.Top();
681 :
682 0 : int width = POPUP_DRAGWIDTH;
683 0 : while(width >= aRect.getWidth())
684 : {
685 0 : width -= 4;
686 : }
687 0 : if (width <= 0)
688 0 : width = aRect.getWidth();
689 : //aRect.nLeft = aRect.nLeft + (aRect.getWidth() - width) / 2;
690 0 : aRect.Left() = (aRect.Left() + aRect.Right() - width) / 2;
691 0 : aRect.Right() = aRect.Left() + width;
692 :
693 0 : int i = 0;
694 0 : while (i < POPUP_DRAGGRIP)
695 : {
696 0 : rRenderContext.DrawRect(aRect);
697 0 : aRect.Top() += 2;
698 0 : aRect.Bottom() += 2;
699 0 : i += 2;
700 : }
701 : #endif
702 : }
703 :
704 0 : if (bLinecolor)
705 0 : rRenderContext.SetLineColor(aLinecolor);
706 : else
707 0 : rRenderContext.SetLineColor();
708 0 : if (bFillcolor)
709 0 : rRenderContext.SetFillColor(aFillcolor);
710 : else
711 0 : rRenderContext.SetFillColor();
712 0 : }
713 :
714 0 : void ImplPopupFloatWin::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
715 : {
716 0 : Rectangle aRect(Point(), rRenderContext.GetOutputSizePixel());
717 0 : rRenderContext.DrawWallpaper(aRect, Wallpaper(rRenderContext.GetSettings().GetStyleSettings().GetFaceGradientColor()));
718 0 : DrawBorder(rRenderContext);
719 0 : if (hasGrip())
720 0 : DrawGrip(rRenderContext);
721 0 : }
722 :
723 0 : void ImplPopupFloatWin::MouseMove( const MouseEvent& rMEvt )
724 : {
725 0 : Point aMousePos = rMEvt.GetPosPixel();
726 :
727 0 : if( !ToolBox::AlwaysLocked() ) // no tear off if locking is enabled
728 : {
729 0 : if( mbTrackingEnabled && rMEvt.IsLeft() && GetDragRect().IsInside( aMousePos ) )
730 : {
731 : // start window move
732 0 : mbMoving = true;
733 0 : StartTracking( StartTrackingFlags::NoKeyCancel );
734 0 : return;
735 : }
736 0 : if( !mbHighlight && GetDragRect().IsInside( aMousePos ) )
737 : {
738 0 : mbHighlight = true;
739 0 : Invalidate();
740 : }
741 0 : if (mbHighlight && ( rMEvt.IsLeaveWindow() || !GetDragRect().IsInside( aMousePos ) ) )
742 : {
743 0 : mbHighlight = false;
744 0 : Invalidate();
745 : }
746 : }
747 : }
748 :
749 0 : void ImplPopupFloatWin::MouseButtonUp( const MouseEvent& rMEvt )
750 : {
751 0 : mbTrackingEnabled = false;
752 0 : FloatingWindow::MouseButtonUp( rMEvt );
753 0 : }
754 :
755 0 : void ImplPopupFloatWin::MouseButtonDown( const MouseEvent& rMEvt )
756 : {
757 0 : Point aMousePos = rMEvt.GetPosPixel();
758 0 : if( GetDragRect().IsInside( aMousePos ) )
759 : {
760 : // get mouse pos at a static window to have a fixed reference point
761 0 : PointerState aState = GetParent()->GetPointerState();
762 0 : if (HasMirroredGraphics() && IsRTLEnabled())
763 0 : ImplMirrorFramePos(aState.maPos);
764 0 : maTearOffPosition = GetWindow( GetWindowType::Border )->GetPosPixel();
765 0 : maDelta = aState.maPos - maTearOffPosition;
766 0 : mbTrackingEnabled = true;
767 : }
768 : else
769 : {
770 0 : mbTrackingEnabled = false;
771 : }
772 0 : }
773 :
774 0 : void ImplPopupFloatWin::Tracking( const TrackingEvent& rTEvt )
775 : {
776 0 : if( mbMoving )
777 : {
778 0 : if ( rTEvt.IsTrackingEnded() )
779 : {
780 0 : mbMoving = false;
781 0 : EndPopupMode( FloatWinPopupEndFlags::TearOff );
782 : }
783 0 : else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
784 : {
785 : // move the window according to mouse pos
786 0 : PointerState aState = GetParent()->GetPointerState();
787 0 : const OutputDevice *pOutDev = GetOutDev();
788 0 : if (pOutDev->HasMirroredGraphics() && IsRTLEnabled())
789 0 : ImplMirrorFramePos(aState.maPos);
790 0 : maTearOffPosition = aState.maPos - maDelta;
791 0 : GetWindow( GetWindowType::Border )->SetPosPixel( maTearOffPosition );
792 : }
793 : }
794 0 : }
795 :
796 12262 : ImplDockingWindowWrapper::ImplDockingWindowWrapper( const vcl::Window *pWindow )
797 : : mpDockingWindow(const_cast<vcl::Window*>(pWindow))
798 : , mpFloatWin(NULL)
799 : , mpOldBorderWin(NULL)
800 : , mpParent(pWindow->GetParent())
801 : , maMaxOutSize( SHRT_MAX, SHRT_MAX )
802 : , mnTrackX(0)
803 : , mnTrackY(0)
804 : , mnTrackWidth(0)
805 : , mnTrackHeight(0)
806 : , mnDockLeft(0)
807 : , mnDockTop(0)
808 : , mnDockRight(0)
809 : , mnDockBottom(0)
810 12262 : , mnFloatBits(WB_BORDER | WB_CLOSEABLE | WB_SIZEABLE | (pWindow->GetStyle() & DOCKWIN_FLOATSTYLES))
811 : , mbDockCanceled(false)
812 : , mbFloatPrevented(false)
813 : , mbDockable(true)
814 : , mbDocking(false)
815 : , mbDragFull(false)
816 : , mbLastFloatMode(false)
817 : , mbStartFloat(false)
818 : , mbTrackDock(false)
819 : , mbPinned(false)
820 : , mbRollUp(false)
821 : , mbDockBtn(false)
822 : , mbHideBtn(false)
823 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
824 : , mbStartDockingEnabled(false)
825 24524 : , mbLocked(false)
826 : {
827 12262 : DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow.get() );
828 12262 : if( pDockWin )
829 12262 : mnFloatBits = pDockWin->GetFloatStyle();
830 12262 : }
831 :
832 36783 : ImplDockingWindowWrapper::~ImplDockingWindowWrapper()
833 : {
834 12261 : if ( IsFloatingMode() )
835 : {
836 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
837 0 : SetFloatingMode( false );
838 : }
839 24522 : }
840 :
841 0 : bool ImplDockingWindowWrapper::ImplStartDocking( const Point& rPos )
842 : {
843 0 : if ( !mbDockable )
844 0 : return false;
845 :
846 0 : if( !mbStartDockingEnabled )
847 0 : return false;
848 :
849 0 : maMouseOff = rPos;
850 0 : maMouseStart = maMouseOff;
851 0 : mbDocking = true;
852 0 : mbLastFloatMode = IsFloatingMode();
853 0 : mbStartFloat = mbLastFloatMode;
854 :
855 : // calculate FloatingBorder
856 0 : VclPtr<FloatingWindow> pWin;
857 0 : if ( mpFloatWin )
858 0 : pWin = mpFloatWin;
859 : else
860 0 : pWin = VclPtr<ImplDockFloatWin2>::Create( mpParent, mnFloatBits, nullptr );
861 0 : pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
862 0 : if ( !mpFloatWin )
863 0 : pWin.disposeAndClear();
864 :
865 0 : Point aPos = GetWindow()->ImplOutputToFrame( Point() );
866 0 : Size aSize = GetWindow()->GetOutputSizePixel();
867 0 : mnTrackX = aPos.X();
868 0 : mnTrackY = aPos.Y();
869 0 : mnTrackWidth = aSize.Width();
870 0 : mnTrackHeight = aSize.Height();
871 :
872 0 : if ( mbLastFloatMode )
873 : {
874 0 : maMouseOff.X() += mnDockLeft;
875 0 : maMouseOff.Y() += mnDockTop;
876 0 : mnTrackX -= mnDockLeft;
877 0 : mnTrackY -= mnDockTop;
878 0 : mnTrackWidth += mnDockLeft+mnDockRight;
879 0 : mnTrackHeight += mnDockTop+mnDockBottom;
880 : }
881 :
882 0 : vcl::Window *pDockingArea = GetWindow()->GetParent();
883 0 : vcl::Window::PointerState aState = pDockingArea->GetPointerState();
884 :
885 : // mouse pos in screen pixels
886 0 : Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos );
887 0 : Point aDockPos = Point( pDockingArea->AbsoluteScreenToOutputPixel( GetWindow()->OutputToAbsoluteScreenPixel( GetWindow()->GetPosPixel() ) ) );
888 0 : Rectangle aDockRect( aDockPos, GetWindow()->GetSizePixel() );
889 0 : StartDocking( aMousePos, aDockRect );
890 :
891 0 : GetWindow()->ImplUpdateAll();
892 0 : GetWindow()->ImplGetFrameWindow()->ImplUpdateAll();
893 :
894 0 : GetWindow()->StartTracking( StartTrackingFlags::KeyMod );
895 0 : return true;
896 : }
897 :
898 0 : void ImplDockingWindowWrapper::Tracking( const TrackingEvent& rTEvt )
899 : {
900 : // used during docking of a currently docked window
901 0 : if ( mbDocking )
902 : {
903 0 : if ( rTEvt.IsTrackingEnded() )
904 : {
905 0 : mbDocking = false;
906 0 : GetWindow()->HideTracking();
907 0 : if ( rTEvt.IsTrackingCanceled() )
908 : {
909 0 : mbDockCanceled = true;
910 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
911 0 : mbDockCanceled = false;
912 : }
913 : else
914 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
915 : }
916 : // Docking only upon non-synthetic MouseEvents
917 0 : else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
918 : {
919 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
920 0 : Point aFrameMousePos = GetWindow()->ImplOutputToFrame( aMousePos );
921 0 : Size aFrameSize = GetWindow()->ImplGetFrameWindow()->GetOutputSizePixel();
922 0 : if ( aFrameMousePos.X() < 0 )
923 0 : aFrameMousePos.X() = 0;
924 0 : if ( aFrameMousePos.Y() < 0 )
925 0 : aFrameMousePos.Y() = 0;
926 0 : if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
927 0 : aFrameMousePos.X() = aFrameSize.Width()-1;
928 0 : if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
929 0 : aFrameMousePos.Y() = aFrameSize.Height()-1;
930 0 : aMousePos = GetWindow()->ImplFrameToOutput( aFrameMousePos );
931 0 : aMousePos.X() -= maMouseOff.X();
932 0 : aMousePos.Y() -= maMouseOff.Y();
933 0 : Point aPos = GetWindow()->ImplOutputToFrame( aMousePos );
934 0 : Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) );
935 0 : Rectangle aCompRect = aTrackRect;
936 0 : aPos.X() += maMouseOff.X();
937 0 : aPos.Y() += maMouseOff.Y();
938 :
939 0 : bool bFloatMode = Docking( aPos, aTrackRect );
940 :
941 0 : mbFloatPrevented = false;
942 0 : if ( mbLastFloatMode != bFloatMode )
943 : {
944 0 : if ( bFloatMode )
945 : {
946 0 : aTrackRect.Left() -= mnDockLeft;
947 0 : aTrackRect.Top() -= mnDockTop;
948 0 : aTrackRect.Right() += mnDockRight;
949 0 : aTrackRect.Bottom() += mnDockBottom;
950 : }
951 : else
952 : {
953 0 : if ( aCompRect == aTrackRect )
954 : {
955 0 : aTrackRect.Left() += mnDockLeft;
956 0 : aTrackRect.Top() += mnDockTop;
957 0 : aTrackRect.Right() -= mnDockRight;
958 0 : aTrackRect.Bottom() -= mnDockBottom;
959 : }
960 : }
961 0 : mbLastFloatMode = bFloatMode;
962 : }
963 :
964 : sal_uInt16 nTrackStyle;
965 0 : if ( bFloatMode )
966 0 : nTrackStyle = SHOWTRACK_OBJECT;
967 : else
968 0 : nTrackStyle = SHOWTRACK_BIG;
969 0 : Rectangle aShowTrackRect = aTrackRect;
970 0 : aShowTrackRect.SetPos( GetWindow()->ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
971 :
972 0 : GetWindow()->ShowTracking( aShowTrackRect, nTrackStyle );
973 :
974 : // calculate mouse offset again, as the rectangle was changed
975 0 : maMouseOff.X() = aPos.X() - aTrackRect.Left();
976 0 : maMouseOff.Y() = aPos.Y() - aTrackRect.Top();
977 :
978 0 : mnTrackX = aTrackRect.Left();
979 0 : mnTrackY = aTrackRect.Top();
980 0 : mnTrackWidth = aTrackRect.GetWidth();
981 0 : mnTrackHeight = aTrackRect.GetHeight();
982 : }
983 : }
984 0 : }
985 :
986 0 : void ImplDockingWindowWrapper::StartDocking( const Point& rPoint, Rectangle& rRect )
987 : {
988 0 : DockingData data( rPoint, rRect, IsFloatingMode() );
989 :
990 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_STARTDOCKING, &data );
991 0 : mbDocking = true;
992 0 : }
993 :
994 0 : bool ImplDockingWindowWrapper::Docking( const Point& rPoint, Rectangle& rRect )
995 : {
996 0 : DockingData data( rPoint, rRect, IsFloatingMode() );
997 :
998 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_DOCKING, &data );
999 0 : rRect = data.maTrackRect;
1000 0 : return data.mbFloating;
1001 : }
1002 :
1003 0 : void ImplDockingWindowWrapper::EndDocking( const Rectangle& rRect, bool bFloatMode )
1004 : {
1005 0 : Rectangle aRect( rRect );
1006 :
1007 0 : if ( !IsDockingCanceled() )
1008 : {
1009 0 : bool bShow = false;
1010 0 : if ( bFloatMode != IsFloatingMode() )
1011 : {
1012 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
1013 0 : SetFloatingMode( bFloatMode );
1014 0 : bShow = true;
1015 0 : if ( bFloatMode )
1016 : {
1017 : // #i44800# always use outputsize - as in all other places
1018 0 : mpFloatWin->SetOutputSizePixel( aRect.GetSize() );
1019 0 : mpFloatWin->SetPosPixel( aRect.TopLeft() );
1020 : }
1021 : }
1022 0 : if ( !bFloatMode )
1023 : {
1024 0 : Point aPos = aRect.TopLeft();
1025 0 : aPos = GetWindow()->GetParent()->ScreenToOutputPixel( aPos );
1026 0 : GetWindow()->SetPosSizePixel( aPos, aRect.GetSize() );
1027 : }
1028 :
1029 0 : if ( bShow )
1030 0 : GetWindow()->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1031 : }
1032 :
1033 0 : EndDockingData data( aRect, IsFloatingMode(), IsDockingCanceled() );
1034 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_ENDDOCKING, &data );
1035 :
1036 0 : mbDocking = false;
1037 :
1038 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
1039 0 : mbStartDockingEnabled = false;
1040 0 : }
1041 :
1042 0 : bool ImplDockingWindowWrapper::PrepareToggleFloatingMode()
1043 : {
1044 0 : bool bFloating = true;
1045 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_PREPARETOGGLEFLOATING, &bFloating );
1046 0 : return bFloating;
1047 : }
1048 :
1049 0 : void ImplDockingWindowWrapper::ToggleFloatingMode()
1050 : {
1051 : // notify dockingwindow/toolbox
1052 : // note: this must be done *before* notifying the
1053 : // listeners to have the toolbox in the proper state
1054 0 : if( GetWindow()->IsDockingWindow() )
1055 0 : static_cast<DockingWindow*>(GetWindow())->ToggleFloatingMode();
1056 :
1057 : // now notify listeners
1058 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_TOGGLEFLOATING );
1059 :
1060 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
1061 0 : mbStartDockingEnabled = false;
1062 0 : }
1063 :
1064 0 : void ImplDockingWindowWrapper::TitleButtonClick( TitleButton nType )
1065 : {
1066 0 : if( nType == TitleButton::Menu )
1067 : {
1068 0 : ToolBox *pToolBox = dynamic_cast< ToolBox* >( GetWindow() );
1069 0 : if( pToolBox )
1070 : {
1071 0 : pToolBox->ExecuteCustomMenu();
1072 : }
1073 : }
1074 0 : if( nType == TitleButton::Docking )
1075 : {
1076 0 : SetFloatingMode( !IsFloatingMode() );
1077 : }
1078 0 : }
1079 :
1080 0 : void ImplDockingWindowWrapper::Resizing( Size& rSize )
1081 : {
1082 : // TODO: add virtual Resizing() to class Window, so we can get rid of class DockingWindow
1083 0 : DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >( GetWindow() );
1084 0 : if( pDockingWindow )
1085 0 : pDockingWindow->Resizing( rSize );
1086 0 : }
1087 :
1088 0 : void ImplDockingWindowWrapper::ShowTitleButton( TitleButton nButton, bool bVisible )
1089 : {
1090 0 : if ( mpFloatWin )
1091 0 : mpFloatWin->ShowTitleButton( nButton, bVisible );
1092 : else
1093 : {
1094 0 : if ( nButton == TitleButton::Docking )
1095 0 : mbDockBtn = bVisible;
1096 : else // if ( nButton == TitleButton::Hide )
1097 0 : mbHideBtn = bVisible;
1098 : }
1099 0 : }
1100 :
1101 0 : void ImplDockingWindowWrapper::StartPopupMode( ToolBox *pParentToolBox, FloatWinPopupFlags nFlags )
1102 : {
1103 : // do nothing if window is floating
1104 0 : if( IsFloatingMode() )
1105 0 : return;
1106 :
1107 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
1108 :
1109 : // prepare reparenting
1110 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
1111 0 : mpOldBorderWin = GetWindow()->GetWindow( GetWindowType::Border );
1112 0 : if( mpOldBorderWin.get() == GetWindow() )
1113 0 : mpOldBorderWin = NULL; // no border window found
1114 :
1115 : // the new parent for popup mode
1116 0 : VclPtrInstance<ImplPopupFloatWin> pWin( mpParent, this, bool(nFlags & FloatWinPopupFlags::AllowTearOff) );
1117 :
1118 0 : pWin->SetPopupModeEndHdl( LINK( this, ImplDockingWindowWrapper, PopupModeEnd ) );
1119 0 : pWin->SetText( GetWindow()->GetText() );
1120 :
1121 0 : pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
1122 :
1123 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1124 0 : GetWindow()->mpWindowImpl->mnLeftBorder = 0;
1125 0 : GetWindow()->mpWindowImpl->mnTopBorder = 0;
1126 0 : GetWindow()->mpWindowImpl->mnRightBorder = 0;
1127 0 : GetWindow()->mpWindowImpl->mnBottomBorder = 0;
1128 :
1129 : // position toolbox below dragrect
1130 0 : GetWindow()->SetPosPixel( pWin->GetToolboxPosition() );
1131 :
1132 : // reparent borderwindow and window
1133 0 : if ( mpOldBorderWin )
1134 0 : mpOldBorderWin->SetParent( pWin );
1135 0 : GetWindow()->SetParent( pWin );
1136 :
1137 : // correct border window pointers
1138 0 : GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
1139 0 : pWin->mpWindowImpl->mpClientWindow = GetWindow();
1140 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1141 :
1142 : // set mpFloatWin not until all window positioning is done !!!
1143 : // (SetPosPixel etc. check for valid mpFloatWin pointer)
1144 0 : mpFloatWin = pWin;
1145 :
1146 : // if the subtoolbar was opened via keyboard make sure that key events
1147 : // will go into subtoolbar
1148 0 : if( pParentToolBox->IsKeyEvent() )
1149 0 : nFlags |= FloatWinPopupFlags::GrabFocus;
1150 :
1151 0 : mpFloatWin->StartPopupMode( pParentToolBox, nFlags );
1152 0 : GetWindow()->Show();
1153 :
1154 0 : if( pParentToolBox->IsKeyEvent() )
1155 : {
1156 : // send HOME key to subtoolbar in order to select first item
1157 0 : KeyEvent aEvent( 0, vcl::KeyCode( KEY_HOME ) );
1158 0 : mpFloatWin->GetPreferredKeyInputWindow()->KeyInput( aEvent );
1159 0 : }
1160 : }
1161 :
1162 0 : IMPL_LINK_NOARG(ImplDockingWindowWrapper, PopupModeEnd)
1163 : {
1164 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
1165 :
1166 : // set parameter for handler before destroying floating window
1167 0 : ImplPopupFloatWin *pPopupFloatWin = static_cast<ImplPopupFloatWin*>(mpFloatWin.get());
1168 0 : EndPopupModeData aData( pPopupFloatWin->GetTearOffPosition(), mpFloatWin->IsPopupModeTearOff() );
1169 :
1170 : // before deleting change parent back, so we can delete the floating window alone
1171 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
1172 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1173 0 : if ( mpOldBorderWin )
1174 : {
1175 0 : GetWindow()->SetParent( mpOldBorderWin );
1176 0 : static_cast<ImplBorderWindow*>(mpOldBorderWin.get())->GetBorder(
1177 0 : GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
1178 0 : GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
1179 0 : mpOldBorderWin->Resize();
1180 : }
1181 0 : GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
1182 0 : GetWindow()->SetParent( pRealParent );
1183 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1184 :
1185 0 : mpFloatWin.disposeAndClear();
1186 :
1187 : // call handler - which will destroy the window and thus the wrapper as well !
1188 0 : GetWindow()->CallEventListeners( VCLEVENT_WINDOW_ENDPOPUPMODE, &aData );
1189 :
1190 0 : return 0;
1191 : }
1192 :
1193 0 : bool ImplDockingWindowWrapper::IsInPopupMode() const
1194 : {
1195 0 : if( GetFloatingWindow() )
1196 0 : return GetFloatingWindow()->IsInPopupMode();
1197 : else
1198 0 : return false;
1199 : }
1200 :
1201 9522 : void ImplDockingWindowWrapper::SetFloatingMode( bool bFloatMode )
1202 : {
1203 : // do nothing if window is docked and locked
1204 9522 : if( !IsFloatingMode() && IsLocked() )
1205 9522 : return;
1206 :
1207 9522 : if ( IsFloatingMode() != bFloatMode )
1208 : {
1209 0 : if ( PrepareToggleFloatingMode() )
1210 : {
1211 0 : bool bVisible = GetWindow()->IsVisible();
1212 :
1213 0 : if ( bFloatMode )
1214 : {
1215 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
1216 :
1217 0 : maDockPos = GetWindow()->GetPosPixel();
1218 :
1219 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent );
1220 0 : mpOldBorderWin = GetWindow()->GetWindow( GetWindowType::Border );
1221 0 : if( mpOldBorderWin == mpDockingWindow )
1222 0 : mpOldBorderWin = NULL; // no border window found
1223 :
1224 : ImplDockFloatWin2* pWin =
1225 : VclPtr<ImplDockFloatWin2>::Create(
1226 :
1227 : mpParent,
1228 0 : mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ?
1229 : mnFloatBits | WB_SYSTEMWINDOW
1230 0 : | WB_OWNERDRAWDECORATION
1231 : : mnFloatBits,
1232 0 : this );
1233 :
1234 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1235 0 : GetWindow()->mpWindowImpl->mnLeftBorder = 0;
1236 0 : GetWindow()->mpWindowImpl->mnTopBorder = 0;
1237 0 : GetWindow()->mpWindowImpl->mnRightBorder = 0;
1238 0 : GetWindow()->mpWindowImpl->mnBottomBorder = 0;
1239 :
1240 : // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
1241 0 : if ( mpOldBorderWin )
1242 0 : mpOldBorderWin->SetParent( pWin );
1243 0 : GetWindow()->SetParent( pWin );
1244 0 : pWin->SetPosPixel( Point() );
1245 :
1246 0 : GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
1247 0 : pWin->mpWindowImpl->mpClientWindow = mpDockingWindow;
1248 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1249 :
1250 0 : pWin->SetText( GetWindow()->GetText() );
1251 0 : pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
1252 0 : pWin->SetPosPixel( maFloatPos );
1253 : // pass on DockingData to FloatingWindow
1254 0 : pWin->ShowTitleButton( TitleButton::Docking, mbDockBtn );
1255 0 : pWin->ShowTitleButton( TitleButton::Hide, mbHideBtn );
1256 0 : pWin->SetPin( mbPinned );
1257 0 : if ( mbRollUp )
1258 0 : pWin->RollUp();
1259 : else
1260 0 : pWin->RollDown();
1261 0 : pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
1262 0 : pWin->SetMinOutputSizePixel( maMinOutSize );
1263 0 : pWin->SetMaxOutputSizePixel( maMaxOutSize );
1264 :
1265 0 : mpFloatWin = pWin;
1266 :
1267 0 : if ( bVisible )
1268 0 : GetWindow()->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1269 :
1270 0 : ToggleFloatingMode();
1271 : }
1272 : else
1273 : {
1274 0 : GetWindow()->Show( false, ShowFlags::NoFocusChange );
1275 :
1276 : // store FloatingData in FloatingWindow
1277 0 : maFloatPos = mpFloatWin->GetPosPixel();
1278 0 : mbDockBtn = mpFloatWin->IsTitleButtonVisible( TitleButton::Docking );
1279 0 : mbHideBtn = mpFloatWin->IsTitleButtonVisible( TitleButton::Hide );
1280 0 : mbPinned = mpFloatWin->IsPinned();
1281 0 : mbRollUp = mpFloatWin->IsRollUp();
1282 0 : maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
1283 0 : maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
1284 0 : maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
1285 :
1286 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( GetWindowType::Parent ); //mpWindowImpl->mpRealParent;
1287 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1288 0 : if ( mpOldBorderWin )
1289 : {
1290 0 : GetWindow()->SetParent( mpOldBorderWin );
1291 0 : static_cast<ImplBorderWindow*>(mpOldBorderWin.get())->GetBorder(
1292 0 : GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
1293 0 : GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
1294 0 : mpOldBorderWin->Resize();
1295 : }
1296 0 : GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
1297 0 : GetWindow()->SetParent( pRealParent );
1298 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1299 :
1300 0 : mpFloatWin.disposeAndClear();
1301 0 : GetWindow()->SetPosPixel( maDockPos );
1302 :
1303 0 : if ( bVisible )
1304 0 : GetWindow()->Show();
1305 :
1306 0 : ToggleFloatingMode();
1307 :
1308 : }
1309 : }
1310 : }
1311 : }
1312 :
1313 9 : void ImplDockingWindowWrapper::SetFloatStyle( WinBits nStyle )
1314 : {
1315 9 : mnFloatBits = nStyle;
1316 9 : }
1317 :
1318 :
1319 9522 : void ImplDockingWindowWrapper::setPosSizePixel( long nX, long nY,
1320 : long nWidth, long nHeight,
1321 : PosSizeFlags nFlags )
1322 : {
1323 9522 : if ( mpFloatWin )
1324 0 : mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
1325 : else
1326 9522 : GetWindow()->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
1327 9522 : }
1328 :
1329 22041 : Point ImplDockingWindowWrapper::GetPosPixel() const
1330 : {
1331 22041 : if ( mpFloatWin )
1332 0 : return mpFloatWin->GetPosPixel();
1333 : else
1334 22041 : return mpDockingWindow->GetPosPixel();
1335 : }
1336 :
1337 22041 : Size ImplDockingWindowWrapper::GetSizePixel() const
1338 : {
1339 22041 : if ( mpFloatWin )
1340 0 : return mpFloatWin->GetSizePixel();
1341 : else
1342 22041 : return mpDockingWindow->GetSizePixel();
1343 : }
1344 :
1345 : // old inlines from DockingWindow
1346 :
1347 0 : void ImplDockingWindowWrapper::SetMinOutputSizePixel( const Size& rSize )
1348 : {
1349 0 : if ( mpFloatWin )
1350 0 : mpFloatWin->SetMinOutputSizePixel( rSize );
1351 0 : maMinOutSize = rSize;
1352 0 : }
1353 :
1354 0 : void ImplDockingWindowWrapper::SetMaxOutputSizePixel( const Size& rSize )
1355 : {
1356 0 : if ( mpFloatWin )
1357 0 : mpFloatWin->SetMaxOutputSizePixel( rSize );
1358 0 : maMaxOutSize = rSize;
1359 0 : }
1360 :
1361 809491 : bool ImplDockingWindowWrapper::IsFloatingMode() const
1362 : {
1363 809491 : return (mpFloatWin != nullptr);
1364 : }
1365 :
1366 6803 : void ImplDockingWindowWrapper::SetDragArea( const Rectangle& rRect )
1367 : {
1368 6803 : maDragArea = rRect;
1369 6803 : }
1370 :
1371 :
1372 0 : void ImplDockingWindowWrapper::Lock()
1373 : {
1374 0 : mbLocked = true;
1375 : // only toolbars support locking
1376 0 : ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
1377 0 : if( pToolBox )
1378 0 : pToolBox->Lock( mbLocked );
1379 0 : }
1380 :
1381 0 : void ImplDockingWindowWrapper::Unlock()
1382 : {
1383 0 : mbLocked = false;
1384 : // only toolbars support locking
1385 0 : ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
1386 0 : if( pToolBox )
1387 0 : pToolBox->Lock( mbLocked );
1388 0 : }
1389 :
1390 :
1391 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|