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 : #include <vcl/event.hxx>
23 : #include <vcl/floatwin.hxx>
24 : #include <vcl/dockwin.hxx>
25 : #include <vcl/svapp.hxx>
26 : #include <vcl/timer.hxx>
27 : #include <vcl/unowrap.hxx>
28 : #include <vcl/settings.hxx>
29 :
30 : #include <svdata.hxx>
31 : #include <window.h>
32 : #include <brdwin.hxx>
33 : #include <salframe.hxx>
34 :
35 : #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE )
36 :
37 : class DockingWindow::ImplData
38 : {
39 : public:
40 : ImplData();
41 : ~ImplData();
42 :
43 : Window* mpParent;
44 : Size maMaxOutSize;
45 : };
46 :
47 0 : DockingWindow::ImplData::ImplData()
48 : {
49 0 : mpParent = NULL;
50 0 : maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
51 0 : }
52 :
53 0 : DockingWindow::ImplData::~ImplData()
54 : {
55 0 : }
56 :
57 : class ImplDockFloatWin : public FloatingWindow
58 : {
59 : private:
60 : DockingWindow* mpDockWin;
61 : sal_uLong mnLastTicks;
62 : Timer maDockTimer;
63 : Point maDockPos;
64 : Rectangle maDockRect;
65 : bool mbInMove;
66 : sal_uLong mnLastUserEvent;
67 :
68 : DECL_LINK(DockingHdl, void *);
69 : DECL_LINK(DockTimerHdl, void *);
70 : public:
71 : ImplDockFloatWin( Window* pParent, WinBits nWinBits,
72 : DockingWindow* pDockingWin );
73 : virtual ~ImplDockFloatWin();
74 :
75 : virtual void Move() SAL_OVERRIDE;
76 : virtual void Resize() SAL_OVERRIDE;
77 : virtual void TitleButtonClick( sal_uInt16 nButton ) SAL_OVERRIDE;
78 : virtual void Pin() SAL_OVERRIDE;
79 : virtual void Roll() SAL_OVERRIDE;
80 : virtual void PopupModeEnd() SAL_OVERRIDE;
81 : virtual void Resizing( Size& rSize ) SAL_OVERRIDE;
82 : virtual bool Close() SAL_OVERRIDE;
83 : };
84 :
85 0 : ImplDockFloatWin::ImplDockFloatWin( Window* pParent, WinBits nWinBits,
86 : DockingWindow* pDockingWin ) :
87 : FloatingWindow( pParent, nWinBits ),
88 : mpDockWin( pDockingWin ),
89 0 : mnLastTicks( Time::GetSystemTicks() ),
90 : mbInMove( false ),
91 0 : mnLastUserEvent( 0 )
92 : {
93 : // copy settings of DockingWindow
94 0 : if ( pDockingWin )
95 : {
96 0 : SetSettings( pDockingWin->GetSettings() );
97 0 : Enable( pDockingWin->IsEnabled(), false );
98 0 : EnableInput( pDockingWin->IsInputEnabled(), false );
99 0 : AlwaysEnableInput( pDockingWin->IsAlwaysEnableInput(), false );
100 0 : EnableAlwaysOnTop( pDockingWin->IsAlwaysOnTopEnabled() );
101 0 : SetActivateMode( pDockingWin->GetActivateMode() );
102 : }
103 :
104 0 : SetBackground();
105 :
106 0 : maDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin, DockTimerHdl ) );
107 0 : maDockTimer.SetTimeout( 50 );
108 0 : }
109 :
110 0 : ImplDockFloatWin::~ImplDockFloatWin()
111 : {
112 0 : if( mnLastUserEvent )
113 0 : Application::RemoveUserEvent( mnLastUserEvent );
114 0 : }
115 :
116 0 : IMPL_LINK_NOARG(ImplDockFloatWin, DockTimerHdl)
117 : {
118 : DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" );
119 :
120 0 : maDockTimer.Stop();
121 0 : PointerState aState = GetPointerState();
122 :
123 0 : if( aState.mnState & KEY_MOD1 )
124 : {
125 : // i43499 CTRL disables docking now
126 0 : mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
127 0 : mpDockWin->EndDocking( maDockRect, true );
128 0 : if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) )
129 0 : maDockTimer.Start();
130 : }
131 0 : else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
132 : {
133 0 : mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
134 0 : mpDockWin->EndDocking( maDockRect, false );
135 : }
136 : else
137 : {
138 0 : mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
139 0 : maDockTimer.Start();
140 : }
141 :
142 0 : return 0;
143 : }
144 :
145 0 : IMPL_LINK_NOARG(ImplDockFloatWin, DockingHdl)
146 : {
147 0 : PointerState aState = mpDockWin->GetParent()->GetPointerState();
148 :
149 0 : mnLastUserEvent = 0;
150 0 : if( mpDockWin->IsDockable() &&
151 0 : (Time::GetSystemTicks() - mnLastTicks > 500) &&
152 0 : ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) &&
153 0 : !(aState.mnState & KEY_MOD1) ) // i43499 CTRL disables docking now
154 : {
155 0 : maDockPos = Point( mpDockWin->GetParent()->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) );
156 0 : maDockPos = mpDockWin->GetParent()->OutputToScreenPixel( maDockPos ); // sfx expects screen coordinates
157 :
158 0 : if( ! mpDockWin->IsDocking() )
159 0 : mpDockWin->StartDocking();
160 0 : maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() );
161 :
162 : // mouse pos also in screen pixels
163 0 : Point aMousePos = mpDockWin->GetParent()->OutputToScreenPixel( aState.maPos );
164 :
165 0 : bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect );
166 0 : if( ! bFloatMode )
167 : {
168 0 : mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_OBJECT | SHOWTRACK_WINDOW );
169 0 : DockTimerHdl( this );
170 : }
171 : else
172 : {
173 0 : mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
174 0 : maDockTimer.Stop();
175 0 : mpDockWin->EndDocking( maDockRect, true );
176 : }
177 : }
178 0 : mbInMove = false;
179 0 : return 0;
180 : }
181 :
182 0 : void ImplDockFloatWin::Move()
183 : {
184 0 : if( mbInMove )
185 0 : return;
186 :
187 0 : mbInMove = true;
188 0 : FloatingWindow::Move();
189 0 : mpDockWin->Move();
190 :
191 : /*
192 : * note: the window should only dock if
193 : * the user releases all mouse buttons. The real problem here
194 : * is that we don't get mouse events (at least not on X)
195 : * if the mouse is on the decoration. So we have to start an
196 : * awkward timer based process that polls the modifier/buttons
197 : * to see whether they are in the right condition shortly after the
198 : * last Move message.
199 : */
200 0 : if( ! mnLastUserEvent )
201 0 : mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin, DockingHdl ) );
202 : }
203 :
204 0 : void ImplDockFloatWin::Resize()
205 : {
206 0 : FloatingWindow::Resize();
207 0 : Size aSize( GetSizePixel() );
208 0 : mpDockWin->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_POSSIZE );
209 0 : }
210 :
211 0 : void ImplDockFloatWin::TitleButtonClick( sal_uInt16 nButton )
212 : {
213 0 : FloatingWindow::TitleButtonClick( nButton );
214 0 : mpDockWin->TitleButtonClick( nButton );
215 0 : }
216 :
217 0 : void ImplDockFloatWin::Pin()
218 : {
219 0 : FloatingWindow::Pin();
220 0 : mpDockWin->Pin();
221 0 : }
222 :
223 0 : void ImplDockFloatWin::Roll()
224 : {
225 0 : FloatingWindow::Roll();
226 0 : mpDockWin->Roll();
227 0 : }
228 :
229 0 : void ImplDockFloatWin::PopupModeEnd()
230 : {
231 0 : FloatingWindow::PopupModeEnd();
232 0 : mpDockWin->PopupModeEnd();
233 0 : }
234 :
235 0 : void ImplDockFloatWin::Resizing( Size& rSize )
236 : {
237 0 : FloatingWindow::Resizing( rSize );
238 0 : mpDockWin->Resizing( rSize );
239 0 : }
240 :
241 0 : bool ImplDockFloatWin::Close()
242 : {
243 0 : return mpDockWin->Close();
244 : }
245 :
246 0 : bool DockingWindow::ImplStartDocking( const Point& rPos )
247 : {
248 0 : if ( !mbDockable )
249 0 : return false;
250 :
251 0 : maMouseOff = rPos;
252 0 : maMouseStart = maMouseOff;
253 0 : mbDocking = true;
254 0 : mbLastFloatMode = IsFloatingMode();
255 0 : mbStartFloat = mbLastFloatMode;
256 :
257 : // calculate FloatingBorder
258 : FloatingWindow* pWin;
259 0 : if ( mpFloatWin )
260 0 : pWin = mpFloatWin;
261 : else
262 0 : pWin = new ImplDockFloatWin( mpImplData->mpParent, mnFloatBits, NULL );
263 0 : pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
264 0 : if ( !mpFloatWin )
265 0 : delete pWin;
266 :
267 0 : Point aPos = ImplOutputToFrame( Point() );
268 0 : Size aSize = Window::GetOutputSizePixel();
269 0 : mnTrackX = aPos.X();
270 0 : mnTrackY = aPos.Y();
271 0 : mnTrackWidth = aSize.Width();
272 0 : mnTrackHeight = aSize.Height();
273 :
274 0 : if ( mbLastFloatMode )
275 : {
276 0 : maMouseOff.X() += mnDockLeft;
277 0 : maMouseOff.Y() += mnDockTop;
278 0 : mnTrackX -= mnDockLeft;
279 0 : mnTrackY -= mnDockTop;
280 0 : mnTrackWidth += mnDockLeft+mnDockRight;
281 0 : mnTrackHeight += mnDockTop+mnDockBottom;
282 : }
283 :
284 0 : if ( GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_DOCKING &&
285 0 : !( mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ) ) // no full drag when migrating to system window
286 0 : mbDragFull = true;
287 : else
288 : {
289 0 : StartDocking();
290 0 : mbDragFull = false;
291 0 : ImplUpdateAll();
292 0 : ImplGetFrameWindow()->ImplUpdateAll();
293 : }
294 :
295 0 : StartTracking( STARTTRACK_KEYMOD );
296 0 : return true;
297 : }
298 :
299 0 : void DockingWindow::ImplInitDockingWindowData()
300 : {
301 0 : mpImplData = new ImplData;
302 0 : mpWindowImpl->mbDockWin = true;
303 :
304 0 : mpFloatWin = NULL;
305 0 : mbDockCanceled = false;
306 0 : mbDockPrevented = false;
307 0 : mbFloatPrevented = false;
308 0 : mbDocking = false;
309 0 : mbPinned = false;
310 0 : mbRollUp = false;
311 0 : mbDockBtn = false;
312 0 : mbHideBtn = false;
313 0 : }
314 :
315 0 : void DockingWindow::ImplInit( Window* pParent, WinBits nStyle )
316 : {
317 0 : if ( !(nStyle & WB_NODIALOGCONTROL) )
318 0 : nStyle |= WB_DIALOGCONTROL;
319 :
320 0 : mpImplData->mpParent = pParent;
321 0 : mbDockable = (nStyle & WB_DOCKABLE) != 0;
322 0 : mnFloatBits = WB_BORDER | (nStyle & DOCKWIN_FLOATSTYLES);
323 0 : nStyle &= ~(DOCKWIN_FLOATSTYLES | WB_BORDER);
324 0 : if ( nStyle & WB_DOCKBORDER )
325 0 : nStyle |= WB_BORDER;
326 :
327 0 : Window::ImplInit( pParent, nStyle, NULL );
328 :
329 0 : ImplInitSettings();
330 0 : }
331 :
332 0 : void DockingWindow::ImplInitSettings()
333 : {
334 : // Hack: to be able to build DockingWindows w/o background before switching
335 : // TODO: Hack
336 0 : if ( IsBackground() )
337 : {
338 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
339 :
340 0 : Color aColor;
341 0 : if ( IsControlBackground() )
342 0 : aColor = GetControlBackground();
343 0 : else if ( Window::GetStyle() & WB_3DLOOK )
344 0 : aColor = rStyleSettings.GetFaceColor();
345 : else
346 0 : aColor = rStyleSettings.GetWindowColor();
347 0 : SetBackground( aColor );
348 : }
349 0 : }
350 :
351 0 : void DockingWindow::ImplLoadRes( const ResId& rResId )
352 : {
353 0 : Window::ImplLoadRes( rResId );
354 :
355 0 : sal_uLong nMask = ReadLongRes();
356 :
357 0 : if ( (RSC_DOCKINGWINDOW_XYMAPMODE | RSC_DOCKINGWINDOW_X |
358 0 : RSC_DOCKINGWINDOW_Y) & nMask )
359 : {
360 : // use Sizes of the Resource
361 0 : Point aPos;
362 0 : MapUnit ePosMap = MAP_PIXEL;
363 :
364 0 : if ( RSC_DOCKINGWINDOW_XYMAPMODE & nMask )
365 0 : ePosMap = (MapUnit)ReadLongRes();
366 :
367 0 : if ( RSC_DOCKINGWINDOW_X & nMask )
368 : {
369 0 : aPos.X() = ReadShortRes();
370 0 : aPos.X() = ImplLogicUnitToPixelX( aPos.X(), ePosMap );
371 : }
372 :
373 0 : if ( RSC_DOCKINGWINDOW_Y & nMask )
374 : {
375 0 : aPos.Y() = ReadShortRes();
376 0 : aPos.Y() = ImplLogicUnitToPixelY( aPos.Y(), ePosMap );
377 : }
378 :
379 0 : SetFloatingPos( aPos );
380 : }
381 :
382 0 : if ( nMask & RSC_DOCKINGWINDOW_FLOATING )
383 : {
384 0 : if ( ReadShortRes() != 0 )
385 0 : SetFloatingMode( true );
386 : }
387 0 : }
388 :
389 0 : DockingWindow::DockingWindow( WindowType nType ) :
390 0 : Window( nType )
391 : {
392 0 : ImplInitDockingWindowData();
393 0 : }
394 :
395 0 : DockingWindow::DockingWindow( Window* pParent, WinBits nStyle ) :
396 0 : Window( WINDOW_DOCKINGWINDOW )
397 : {
398 0 : ImplInitDockingWindowData();
399 0 : ImplInit( pParent, nStyle );
400 0 : }
401 :
402 0 : DockingWindow::DockingWindow( Window* pParent, const ResId& rResId ) :
403 0 : Window( WINDOW_DOCKINGWINDOW )
404 : {
405 0 : ImplInitDockingWindowData();
406 0 : rResId.SetRT( RSC_DOCKINGWINDOW );
407 0 : WinBits nStyle = ImplInitRes( rResId );
408 0 : ImplInit( pParent, nStyle );
409 0 : ImplLoadRes( rResId );
410 :
411 0 : if ( !(nStyle & WB_HIDE) )
412 0 : Show();
413 0 : }
414 :
415 0 : DockingWindow::~DockingWindow()
416 : {
417 0 : if ( IsFloatingMode() )
418 : {
419 0 : Show( false, SHOW_NOFOCUSCHANGE );
420 0 : SetFloatingMode( false );
421 : }
422 0 : delete mpImplData;
423 0 : }
424 :
425 0 : void DockingWindow::Tracking( const TrackingEvent& rTEvt )
426 : {
427 0 : if( GetDockingManager()->IsDockable( this ) ) // new docking interface
428 0 : return Window::Tracking( rTEvt );
429 :
430 0 : if ( mbDocking )
431 : {
432 0 : if ( rTEvt.IsTrackingEnded() )
433 : {
434 0 : mbDocking = false;
435 0 : if ( mbDragFull )
436 : {
437 : // reset old state on Cancel
438 0 : if ( rTEvt.IsTrackingCanceled() )
439 : {
440 0 : StartDocking();
441 0 : Rectangle aRect( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) );
442 0 : EndDocking( aRect, mbStartFloat );
443 : }
444 : }
445 : else
446 : {
447 0 : HideTracking();
448 0 : if ( rTEvt.IsTrackingCanceled() )
449 : {
450 0 : mbDockCanceled = true;
451 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
452 0 : mbDockCanceled = false;
453 : }
454 : else
455 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
456 : }
457 : }
458 : // dock only for non-synthetic MouseEvents
459 0 : else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
460 : {
461 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
462 0 : Point aFrameMousePos = ImplOutputToFrame( aMousePos );
463 0 : Size aFrameSize = mpWindowImpl->mpFrameWindow->GetOutputSizePixel();
464 0 : if ( aFrameMousePos.X() < 0 )
465 0 : aFrameMousePos.X() = 0;
466 0 : if ( aFrameMousePos.Y() < 0 )
467 0 : aFrameMousePos.Y() = 0;
468 0 : if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
469 0 : aFrameMousePos.X() = aFrameSize.Width()-1;
470 0 : if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
471 0 : aFrameMousePos.Y() = aFrameSize.Height()-1;
472 0 : aMousePos = ImplFrameToOutput( aFrameMousePos );
473 0 : aMousePos.X() -= maMouseOff.X();
474 0 : aMousePos.Y() -= maMouseOff.Y();
475 0 : Point aFramePos = ImplOutputToFrame( aMousePos );
476 0 : Rectangle aTrackRect( aFramePos, Size( mnTrackWidth, mnTrackHeight ) );
477 0 : Rectangle aCompRect = aTrackRect;
478 0 : aFramePos.X() += maMouseOff.X();
479 0 : aFramePos.Y() += maMouseOff.Y();
480 0 : if ( mbDragFull )
481 0 : StartDocking();
482 0 : bool bFloatMode = Docking( aFramePos, aTrackRect );
483 0 : mbDockPrevented = false;
484 0 : mbFloatPrevented = false;
485 0 : if ( mbLastFloatMode != bFloatMode )
486 : {
487 0 : if ( bFloatMode )
488 : {
489 0 : aTrackRect.Left() -= mnDockLeft;
490 0 : aTrackRect.Top() -= mnDockTop;
491 0 : aTrackRect.Right() += mnDockRight;
492 0 : aTrackRect.Bottom() += mnDockBottom;
493 : }
494 : else
495 : {
496 0 : if ( aCompRect == aTrackRect )
497 : {
498 0 : aTrackRect.Left() += mnDockLeft;
499 0 : aTrackRect.Top() += mnDockTop;
500 0 : aTrackRect.Right() -= mnDockRight;
501 0 : aTrackRect.Bottom() -= mnDockBottom;
502 : }
503 : }
504 0 : mbLastFloatMode = bFloatMode;
505 : }
506 0 : if ( mbDragFull )
507 : {
508 0 : Point aPos;
509 0 : Point aOldPos = OutputToScreenPixel( aPos );
510 0 : EndDocking( aTrackRect, mbLastFloatMode );
511 : // repaint if state or position has changed
512 0 : if ( aOldPos != OutputToScreenPixel( aPos ) )
513 : {
514 0 : ImplUpdateAll();
515 0 : ImplGetFrameWindow()->ImplUpdateAll();
516 : }
517 : // EndDocking( aTrackRect, mbLastFloatMode );
518 : }
519 : else
520 : {
521 : sal_uInt16 nTrackStyle;
522 0 : if ( bFloatMode )
523 0 : nTrackStyle = SHOWTRACK_BIG;
524 : else
525 0 : nTrackStyle = SHOWTRACK_OBJECT;
526 0 : Rectangle aShowTrackRect = aTrackRect;
527 0 : aShowTrackRect.SetPos( ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
528 0 : ShowTracking( aShowTrackRect, nTrackStyle );
529 :
530 : // recalculate mouse offset, as the rectangle was changed
531 0 : maMouseOff.X() = aFramePos.X() - aTrackRect.Left();
532 0 : maMouseOff.Y() = aFramePos.Y() - aTrackRect.Top();
533 : }
534 :
535 0 : mnTrackX = aTrackRect.Left();
536 0 : mnTrackY = aTrackRect.Top();
537 0 : mnTrackWidth = aTrackRect.GetWidth();
538 0 : mnTrackHeight = aTrackRect.GetHeight();
539 : }
540 : }
541 : }
542 :
543 0 : bool DockingWindow::Notify( NotifyEvent& rNEvt )
544 : {
545 0 : if( GetDockingManager()->IsDockable( this ) ) // new docking interface
546 0 : return Window::Notify( rNEvt );
547 :
548 0 : if ( mbDockable )
549 : {
550 0 : if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
551 : {
552 0 : const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
553 0 : if ( pMEvt->IsLeft() )
554 : {
555 0 : if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
556 : {
557 0 : SetFloatingMode( !IsFloatingMode() );
558 0 : return true;
559 : }
560 0 : else if ( pMEvt->GetClicks() == 1 )
561 : {
562 : // check if window is floating standalone (IsFloating())
563 : // or only partially floating and still docked with one border
564 : // ( !mpWindowImpl->mbFrame)
565 0 : if( ! IsFloatingMode() || ! mpFloatWin->mpWindowImpl->mbFrame )
566 : {
567 0 : Point aPos = pMEvt->GetPosPixel();
568 0 : Window* pWindow = rNEvt.GetWindow();
569 0 : if ( pWindow != this )
570 : {
571 0 : aPos = pWindow->OutputToScreenPixel( aPos );
572 0 : aPos = ScreenToOutputPixel( aPos );
573 : }
574 0 : ImplStartDocking( aPos );
575 : }
576 0 : return true;
577 : }
578 : }
579 : }
580 0 : else if( rNEvt.GetType() == EVENT_KEYINPUT )
581 : {
582 0 : const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
583 0 : if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
584 0 : rKey.IsShift() && rKey.IsMod1() )
585 : {
586 0 : SetFloatingMode( !IsFloatingMode() );
587 0 : return true;
588 : }
589 : }
590 : }
591 :
592 0 : return Window::Notify( rNEvt );
593 : }
594 :
595 0 : void DockingWindow::StartDocking()
596 : {
597 0 : mbDocking = true;
598 0 : }
599 :
600 0 : bool DockingWindow::Docking( const Point&, Rectangle& )
601 : {
602 0 : return IsFloatingMode();
603 : }
604 :
605 0 : void DockingWindow::EndDocking( const Rectangle& rRect, bool bFloatMode )
606 : {
607 0 : if ( !IsDockingCanceled() )
608 : {
609 0 : bool bShow = false;
610 0 : if ( bool(bFloatMode) != IsFloatingMode() )
611 : {
612 0 : Show( false, SHOW_NOFOCUSCHANGE );
613 0 : SetFloatingMode( bFloatMode );
614 0 : bShow = true;
615 0 : if ( bFloatMode && mpFloatWin )
616 0 : mpFloatWin->SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
617 : }
618 0 : if ( !bFloatMode )
619 : {
620 0 : Point aPos = rRect.TopLeft();
621 0 : aPos = GetParent()->ScreenToOutputPixel( aPos );
622 0 : Window::SetPosSizePixel( aPos, rRect.GetSize() );
623 : }
624 :
625 0 : if ( bShow )
626 0 : Show();
627 : }
628 0 : mbDocking = false;
629 0 : }
630 :
631 0 : bool DockingWindow::PrepareToggleFloatingMode()
632 : {
633 0 : return true;
634 : }
635 :
636 0 : bool DockingWindow::Close()
637 : {
638 0 : ImplDelData aDelData;
639 0 : ImplAddDel( &aDelData );
640 0 : ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
641 0 : if ( aDelData.IsDead() )
642 0 : return false;
643 0 : ImplRemoveDel( &aDelData );
644 :
645 0 : if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() )
646 0 : return false;
647 :
648 0 : Show( false, SHOW_NOFOCUSCHANGE );
649 0 : return true;
650 : }
651 :
652 0 : void DockingWindow::ToggleFloatingMode()
653 : {
654 0 : }
655 :
656 0 : void DockingWindow::TitleButtonClick( sal_uInt16 )
657 : {
658 0 : }
659 :
660 0 : void DockingWindow::Pin()
661 : {
662 0 : }
663 :
664 0 : void DockingWindow::Roll()
665 : {
666 0 : }
667 :
668 0 : void DockingWindow::PopupModeEnd()
669 : {
670 0 : }
671 :
672 0 : void DockingWindow::Resizing( Size& )
673 : {
674 0 : }
675 :
676 0 : void DockingWindow::StateChanged( StateChangedType nType )
677 : {
678 0 : switch(nType)
679 : {
680 : case STATE_CHANGE_CONTROLBACKGROUND:
681 0 : ImplInitSettings();
682 0 : Invalidate();
683 0 : break;
684 :
685 : case STATE_CHANGE_STYLE:
686 0 : mbDockable = (GetStyle() & WB_DOCKABLE) != 0;
687 0 : break;
688 :
689 : default:
690 0 : break;
691 : }
692 :
693 0 : Window::StateChanged( nType );
694 0 : }
695 :
696 0 : void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt )
697 : {
698 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
699 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
700 : {
701 0 : ImplInitSettings();
702 0 : Invalidate();
703 : }
704 : else
705 0 : Window::DataChanged( rDCEvt );
706 0 : }
707 :
708 0 : void DockingWindow::SetFloatingMode( bool bFloatMode )
709 : {
710 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
711 0 : if( pWrapper )
712 : {
713 0 : pWrapper->SetFloatingMode( bFloatMode );
714 0 : return;
715 : }
716 0 : if ( IsFloatingMode() != bFloatMode )
717 : {
718 0 : if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed
719 : {
720 0 : bool bVisible = IsVisible();
721 :
722 0 : if ( bFloatMode )
723 : {
724 0 : Show( false, SHOW_NOFOCUSCHANGE );
725 :
726 0 : maDockPos = Window::GetPosPixel();
727 :
728 0 : Window* pRealParent = mpWindowImpl->mpRealParent;
729 0 : mpOldBorderWin = mpWindowImpl->mpBorderWindow;
730 :
731 : ImplDockFloatWin* pWin =
732 : new ImplDockFloatWin(
733 : mpImplData->mpParent,
734 0 : mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits,
735 0 : this );
736 0 : mpFloatWin = pWin;
737 0 : mpWindowImpl->mpBorderWindow = NULL;
738 0 : mpWindowImpl->mnLeftBorder = 0;
739 0 : mpWindowImpl->mnTopBorder = 0;
740 0 : mpWindowImpl->mnRightBorder = 0;
741 0 : mpWindowImpl->mnBottomBorder = 0;
742 : // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
743 0 : if ( mpOldBorderWin )
744 0 : mpOldBorderWin->SetParent( pWin );
745 :
746 : // #i123765# reset the buffered DropTargets when undocking, else it may not
747 : // be correctly initialized
748 0 : mpWindowImpl->mxDNDListenerContainer.clear();
749 :
750 0 : SetParent( pWin );
751 0 : SetPosPixel( Point() );
752 0 : mpWindowImpl->mpBorderWindow = pWin;
753 0 : pWin->mpWindowImpl->mpClientWindow = this;
754 0 : mpWindowImpl->mpRealParent = pRealParent;
755 0 : pWin->SetText( Window::GetText() );
756 0 : pWin->SetOutputSizePixel( Window::GetSizePixel() );
757 0 : pWin->SetPosPixel( maFloatPos );
758 : // pass on DockingData to FloatingWindow
759 0 : pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
760 0 : pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
761 0 : pWin->SetPin( mbPinned );
762 0 : if ( mbRollUp )
763 0 : pWin->RollUp();
764 : else
765 0 : pWin->RollDown();
766 0 : pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
767 0 : pWin->SetMinOutputSizePixel( maMinOutSize );
768 0 : pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize );
769 :
770 0 : ToggleFloatingMode();
771 :
772 0 : if ( bVisible )
773 0 : Show();
774 : }
775 : else
776 : {
777 0 : Show( false, SHOW_NOFOCUSCHANGE );
778 :
779 : // store FloatingData in FloatingWindow
780 0 : maFloatPos = mpFloatWin->GetPosPixel();
781 0 : mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
782 0 : mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
783 0 : mbPinned = mpFloatWin->IsPinned();
784 0 : mbRollUp = mpFloatWin->IsRollUp();
785 0 : maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
786 0 : maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
787 0 : mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
788 :
789 0 : Window* pRealParent = mpWindowImpl->mpRealParent;
790 0 : mpWindowImpl->mpBorderWindow = NULL;
791 0 : if ( mpOldBorderWin )
792 : {
793 0 : SetParent( mpOldBorderWin );
794 0 : ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
795 0 : mpOldBorderWin->Resize();
796 : }
797 0 : mpWindowImpl->mpBorderWindow = mpOldBorderWin;
798 0 : SetParent( pRealParent );
799 0 : mpWindowImpl->mpRealParent = pRealParent;
800 0 : delete static_cast<ImplDockFloatWin*>(mpFloatWin);
801 0 : mpFloatWin = NULL;
802 0 : SetPosPixel( maDockPos );
803 :
804 0 : ToggleFloatingMode();
805 :
806 0 : if ( bVisible )
807 0 : Show();
808 : }
809 : }
810 : }
811 : }
812 :
813 0 : void DockingWindow::SetFloatStyle( WinBits nStyle )
814 : {
815 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
816 0 : if( pWrapper )
817 : {
818 0 : pWrapper->SetFloatStyle( nStyle );
819 0 : return;
820 : }
821 :
822 0 : mnFloatBits = nStyle;
823 : }
824 :
825 0 : WinBits DockingWindow::GetFloatStyle() const
826 : {
827 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
828 0 : if( pWrapper )
829 : {
830 0 : return pWrapper->GetFloatStyle();
831 : }
832 :
833 0 : return mnFloatBits;
834 : }
835 :
836 0 : void DockingWindow::setPosSizePixel( long nX, long nY,
837 : long nWidth, long nHeight,
838 : sal_uInt16 nFlags )
839 : {
840 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
841 0 : if( pWrapper )
842 : {
843 0 : if ( pWrapper->mpFloatWin )
844 0 : pWrapper->mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
845 : else
846 0 : Window::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
847 0 : return;
848 : }
849 :
850 0 : if ( mpFloatWin )
851 0 : mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
852 : else
853 0 : Window::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
854 : }
855 :
856 0 : Point DockingWindow::GetPosPixel() const
857 : {
858 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
859 0 : if( pWrapper )
860 : {
861 0 : if ( pWrapper->mpFloatWin )
862 0 : return pWrapper->mpFloatWin->GetPosPixel();
863 : else
864 0 : return Window::GetPosPixel();
865 : }
866 :
867 0 : if ( mpFloatWin )
868 0 : return mpFloatWin->GetPosPixel();
869 : else
870 0 : return Window::GetPosPixel();
871 : }
872 :
873 0 : Size DockingWindow::GetSizePixel() const
874 : {
875 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
876 0 : if( pWrapper )
877 : {
878 0 : if ( pWrapper->mpFloatWin )
879 0 : return pWrapper->mpFloatWin->GetSizePixel();
880 : else
881 0 : return Window::GetSizePixel();
882 : }
883 :
884 0 : if ( mpFloatWin )
885 0 : return mpFloatWin->GetSizePixel();
886 : else
887 0 : return Window::GetSizePixel();
888 : }
889 :
890 0 : void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
891 : {
892 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
893 0 : if( pWrapper )
894 : {
895 0 : if ( pWrapper->mpFloatWin )
896 0 : pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize );
897 : else
898 0 : Window::SetOutputSizePixel( rNewSize );
899 0 : return;
900 : }
901 :
902 0 : if ( mpFloatWin )
903 0 : mpFloatWin->SetOutputSizePixel( rNewSize );
904 : else
905 0 : Window::SetOutputSizePixel( rNewSize );
906 : }
907 :
908 0 : Size DockingWindow::GetOutputSizePixel() const
909 : {
910 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
911 0 : if( pWrapper )
912 : {
913 0 : if ( pWrapper->mpFloatWin )
914 0 : return pWrapper->mpFloatWin->GetOutputSizePixel();
915 : else
916 0 : return Window::GetOutputSizePixel();
917 : }
918 :
919 0 : if ( mpFloatWin )
920 0 : return mpFloatWin->GetOutputSizePixel();
921 : else
922 0 : return Window::GetOutputSizePixel();
923 : }
924 :
925 0 : Point DockingWindow::GetFloatingPos() const
926 : {
927 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
928 0 : if( pWrapper )
929 : {
930 0 : if ( pWrapper->mpFloatWin )
931 : {
932 0 : WindowStateData aData;
933 0 : aData.SetMask( WINDOWSTATE_MASK_POS );
934 0 : pWrapper->mpFloatWin->GetWindowStateData( aData );
935 0 : Point aPos( aData.GetX(), aData.GetY() );
936 0 : aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
937 0 : return aPos;
938 : }
939 : else
940 0 : return maFloatPos;
941 : }
942 :
943 0 : if ( mpFloatWin )
944 : {
945 0 : WindowStateData aData;
946 0 : aData.SetMask( WINDOWSTATE_MASK_POS );
947 0 : mpFloatWin->GetWindowStateData( aData );
948 0 : Point aPos( aData.GetX(), aData.GetY() );
949 0 : aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
950 0 : return aPos;
951 : }
952 : else
953 0 : return maFloatPos;
954 : }
955 :
956 0 : bool DockingWindow::IsFloatingMode() const
957 : {
958 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
959 0 : if( pWrapper )
960 0 : return pWrapper->IsFloatingMode();
961 : else
962 0 : return (mpFloatWin != NULL);
963 : }
964 :
965 0 : void DockingWindow::SetMaxOutputSizePixel( const Size& rSize )
966 : {
967 0 : if ( mpFloatWin )
968 0 : mpFloatWin->SetMaxOutputSizePixel( rSize );
969 0 : mpImplData->maMaxOutSize = rSize;
970 0 : }
971 :
972 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|