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 : vcl::Window* mpParent;
44 : Size maMaxOutSize;
45 : };
46 :
47 107421 : DockingWindow::ImplData::ImplData()
48 : {
49 107421 : mpParent = NULL;
50 107421 : maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
51 107421 : }
52 :
53 107391 : DockingWindow::ImplData::~ImplData()
54 : {
55 107391 : }
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 : ImplSVEvent * mnLastUserEvent;
67 :
68 : DECL_LINK(DockingHdl, void *);
69 : DECL_LINK(DockTimerHdl, void *);
70 : public:
71 : ImplDockFloatWin( vcl::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( vcl::Window* pParent, WinBits nWinBits,
86 : DockingWindow* pDockingWin ) :
87 : FloatingWindow( pParent, nWinBits ),
88 : mpDockWin( pDockingWin ),
89 0 : mnLastTicks( tools::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 : (tools::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 107421 : void DockingWindow::ImplInitDockingWindowData()
300 : {
301 107421 : mpWindowImpl->mbDockWin = true;
302 107421 : mpFloatWin = NULL;
303 107421 : mpOldBorderWin = NULL;
304 107421 : mpImplData = new ImplData;
305 107421 : mnTrackX = 0;
306 107421 : mnTrackY = 0;
307 107421 : mnTrackWidth = 0;
308 107421 : mnTrackHeight = 0;
309 107421 : mnDockLeft = 0;
310 107421 : mnDockTop = 0;
311 107421 : mnDockRight = 0;
312 107421 : mnDockBottom = 0;
313 107421 : mnFloatBits = 0;
314 107421 : mbDockCanceled = false;
315 107421 : mbDockPrevented = false;
316 107421 : mbFloatPrevented = false;
317 107421 : mbDockable = false;
318 107421 : mbDocking = false;
319 107421 : mbDragFull = false;
320 107421 : mbLastFloatMode = false;
321 107421 : mbStartFloat = false;
322 107421 : mbTrackDock = false;
323 107421 : mbPinned = false;
324 107421 : mbRollUp = false;
325 107421 : mbDockBtn = false;
326 107421 : mbHideBtn = false;
327 107421 : }
328 :
329 107421 : void DockingWindow::ImplInit( vcl::Window* pParent, WinBits nStyle )
330 : {
331 107421 : if ( !(nStyle & WB_NODIALOGCONTROL) )
332 107421 : nStyle |= WB_DIALOGCONTROL;
333 :
334 107421 : mpImplData->mpParent = pParent;
335 107421 : mbDockable = (nStyle & WB_DOCKABLE) != 0;
336 107421 : mnFloatBits = WB_BORDER | (nStyle & DOCKWIN_FLOATSTYLES);
337 107421 : nStyle &= ~(DOCKWIN_FLOATSTYLES | WB_BORDER);
338 107421 : if ( nStyle & WB_DOCKBORDER )
339 0 : nStyle |= WB_BORDER;
340 :
341 107421 : Window::ImplInit( pParent, nStyle, NULL );
342 :
343 107421 : ImplInitSettings();
344 107421 : }
345 :
346 107593 : void DockingWindow::ImplInitSettings()
347 : {
348 : // Hack: to be able to build DockingWindows w/o background before switching
349 : // TODO: Hack
350 107593 : if ( IsBackground() )
351 : {
352 107593 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
353 :
354 107593 : Color aColor;
355 107593 : if ( IsControlBackground() )
356 0 : aColor = GetControlBackground();
357 107593 : else if ( Window::GetStyle() & WB_3DLOOK )
358 96621 : aColor = rStyleSettings.GetFaceColor();
359 : else
360 10972 : aColor = rStyleSettings.GetWindowColor();
361 107593 : SetBackground( aColor );
362 : }
363 107593 : }
364 :
365 750 : void DockingWindow::ImplLoadRes( const ResId& rResId )
366 : {
367 750 : Window::ImplLoadRes( rResId );
368 :
369 750 : sal_uLong nMask = ReadLongRes();
370 :
371 750 : if ( (RSC_DOCKINGWINDOW_XYMAPMODE | RSC_DOCKINGWINDOW_X |
372 750 : RSC_DOCKINGWINDOW_Y) & nMask )
373 : {
374 : // use Sizes of the Resource
375 0 : Point aPos;
376 0 : MapUnit ePosMap = MAP_PIXEL;
377 :
378 0 : if ( RSC_DOCKINGWINDOW_XYMAPMODE & nMask )
379 0 : ePosMap = (MapUnit)ReadLongRes();
380 :
381 0 : if ( RSC_DOCKINGWINDOW_X & nMask )
382 : {
383 0 : aPos.X() = ReadShortRes();
384 0 : aPos.X() = ImplLogicUnitToPixelX( aPos.X(), ePosMap );
385 : }
386 :
387 0 : if ( RSC_DOCKINGWINDOW_Y & nMask )
388 : {
389 0 : aPos.Y() = ReadShortRes();
390 0 : aPos.Y() = ImplLogicUnitToPixelY( aPos.Y(), ePosMap );
391 : }
392 :
393 0 : SetFloatingPos( aPos );
394 : }
395 :
396 750 : if ( nMask & RSC_DOCKINGWINDOW_FLOATING )
397 : {
398 0 : if ( ReadShortRes() != 0 )
399 0 : SetFloatingMode( true );
400 : }
401 750 : }
402 :
403 102395 : DockingWindow::DockingWindow( WindowType nType ) :
404 102395 : Window(nType)
405 : {
406 102395 : ImplInitDockingWindowData();
407 102395 : }
408 :
409 4824 : DockingWindow::DockingWindow( vcl::Window* pParent, WinBits nStyle ) :
410 4824 : Window( WINDOW_DOCKINGWINDOW )
411 : {
412 4824 : ImplInitDockingWindowData();
413 4824 : ImplInit( pParent, nStyle );
414 4824 : }
415 :
416 202 : DockingWindow::DockingWindow( vcl::Window* pParent, const ResId& rResId ) :
417 202 : Window( WINDOW_DOCKINGWINDOW )
418 : {
419 202 : ImplInitDockingWindowData();
420 202 : rResId.SetRT( RSC_DOCKINGWINDOW );
421 202 : WinBits nStyle = ImplInitRes( rResId );
422 202 : ImplInit( pParent, nStyle );
423 202 : ImplLoadRes( rResId );
424 :
425 202 : if ( !(nStyle & WB_HIDE) )
426 76 : Show();
427 202 : }
428 :
429 214784 : DockingWindow::~DockingWindow()
430 : {
431 107391 : if ( IsFloatingMode() )
432 : {
433 0 : Show( false, SHOW_NOFOCUSCHANGE );
434 0 : SetFloatingMode( false );
435 : }
436 107391 : delete mpImplData;
437 107393 : }
438 :
439 0 : void DockingWindow::Tracking( const TrackingEvent& rTEvt )
440 : {
441 0 : if( GetDockingManager()->IsDockable( this ) ) // new docking interface
442 0 : return Window::Tracking( rTEvt );
443 :
444 0 : if ( mbDocking )
445 : {
446 0 : if ( rTEvt.IsTrackingEnded() )
447 : {
448 0 : mbDocking = false;
449 0 : if ( mbDragFull )
450 : {
451 : // reset old state on Cancel
452 0 : if ( rTEvt.IsTrackingCanceled() )
453 : {
454 0 : StartDocking();
455 0 : Rectangle aRect( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) );
456 0 : EndDocking( aRect, mbStartFloat );
457 : }
458 : }
459 : else
460 : {
461 0 : HideTracking();
462 0 : if ( rTEvt.IsTrackingCanceled() )
463 : {
464 0 : mbDockCanceled = true;
465 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
466 0 : mbDockCanceled = false;
467 : }
468 : else
469 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
470 : }
471 : }
472 : // dock only for non-synthetic MouseEvents
473 0 : else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
474 : {
475 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
476 0 : Point aFrameMousePos = ImplOutputToFrame( aMousePos );
477 0 : Size aFrameSize = mpWindowImpl->mpFrameWindow->GetOutputSizePixel();
478 0 : if ( aFrameMousePos.X() < 0 )
479 0 : aFrameMousePos.X() = 0;
480 0 : if ( aFrameMousePos.Y() < 0 )
481 0 : aFrameMousePos.Y() = 0;
482 0 : if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
483 0 : aFrameMousePos.X() = aFrameSize.Width()-1;
484 0 : if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
485 0 : aFrameMousePos.Y() = aFrameSize.Height()-1;
486 0 : aMousePos = ImplFrameToOutput( aFrameMousePos );
487 0 : aMousePos.X() -= maMouseOff.X();
488 0 : aMousePos.Y() -= maMouseOff.Y();
489 0 : Point aFramePos = ImplOutputToFrame( aMousePos );
490 0 : Rectangle aTrackRect( aFramePos, Size( mnTrackWidth, mnTrackHeight ) );
491 0 : Rectangle aCompRect = aTrackRect;
492 0 : aFramePos.X() += maMouseOff.X();
493 0 : aFramePos.Y() += maMouseOff.Y();
494 0 : if ( mbDragFull )
495 0 : StartDocking();
496 0 : bool bFloatMode = Docking( aFramePos, aTrackRect );
497 0 : mbDockPrevented = false;
498 0 : mbFloatPrevented = false;
499 0 : if ( mbLastFloatMode != bFloatMode )
500 : {
501 0 : if ( bFloatMode )
502 : {
503 0 : aTrackRect.Left() -= mnDockLeft;
504 0 : aTrackRect.Top() -= mnDockTop;
505 0 : aTrackRect.Right() += mnDockRight;
506 0 : aTrackRect.Bottom() += mnDockBottom;
507 : }
508 : else
509 : {
510 0 : if ( aCompRect == aTrackRect )
511 : {
512 0 : aTrackRect.Left() += mnDockLeft;
513 0 : aTrackRect.Top() += mnDockTop;
514 0 : aTrackRect.Right() -= mnDockRight;
515 0 : aTrackRect.Bottom() -= mnDockBottom;
516 : }
517 : }
518 0 : mbLastFloatMode = bFloatMode;
519 : }
520 0 : if ( mbDragFull )
521 : {
522 0 : Point aPos;
523 0 : Point aOldPos = OutputToScreenPixel( aPos );
524 0 : EndDocking( aTrackRect, mbLastFloatMode );
525 : // repaint if state or position has changed
526 0 : if ( aOldPos != OutputToScreenPixel( aPos ) )
527 : {
528 0 : ImplUpdateAll();
529 0 : ImplGetFrameWindow()->ImplUpdateAll();
530 : }
531 : // EndDocking( aTrackRect, mbLastFloatMode );
532 : }
533 : else
534 : {
535 : sal_uInt16 nTrackStyle;
536 0 : if ( bFloatMode )
537 0 : nTrackStyle = SHOWTRACK_BIG;
538 : else
539 0 : nTrackStyle = SHOWTRACK_OBJECT;
540 0 : Rectangle aShowTrackRect = aTrackRect;
541 0 : aShowTrackRect.SetPos( ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
542 0 : ShowTracking( aShowTrackRect, nTrackStyle );
543 :
544 : // recalculate mouse offset, as the rectangle was changed
545 0 : maMouseOff.X() = aFramePos.X() - aTrackRect.Left();
546 0 : maMouseOff.Y() = aFramePos.Y() - aTrackRect.Top();
547 : }
548 :
549 0 : mnTrackX = aTrackRect.Left();
550 0 : mnTrackY = aTrackRect.Top();
551 0 : mnTrackWidth = aTrackRect.GetWidth();
552 0 : mnTrackHeight = aTrackRect.GetHeight();
553 : }
554 : }
555 : }
556 :
557 287970 : bool DockingWindow::Notify( NotifyEvent& rNEvt )
558 : {
559 287970 : if( GetDockingManager()->IsDockable( this ) ) // new docking interface
560 26256 : return Window::Notify( rNEvt );
561 :
562 261714 : if ( mbDockable )
563 : {
564 125918 : if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
565 : {
566 0 : const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
567 0 : if ( pMEvt->IsLeft() )
568 : {
569 0 : if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
570 : {
571 0 : SetFloatingMode( !IsFloatingMode() );
572 0 : return true;
573 : }
574 0 : else if ( pMEvt->GetClicks() == 1 )
575 : {
576 : // check if window is floating standalone (IsFloating())
577 : // or only partially floating and still docked with one border
578 : // ( !mpWindowImpl->mbFrame)
579 0 : if( ! IsFloatingMode() || ! mpFloatWin->mpWindowImpl->mbFrame )
580 : {
581 0 : Point aPos = pMEvt->GetPosPixel();
582 0 : vcl::Window* pWindow = rNEvt.GetWindow();
583 0 : if ( pWindow != this )
584 : {
585 0 : aPos = pWindow->OutputToScreenPixel( aPos );
586 0 : aPos = ScreenToOutputPixel( aPos );
587 : }
588 0 : ImplStartDocking( aPos );
589 : }
590 0 : return true;
591 : }
592 : }
593 : }
594 125918 : else if( rNEvt.GetType() == EVENT_KEYINPUT )
595 : {
596 0 : const vcl::KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
597 0 : if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
598 0 : rKey.IsShift() && rKey.IsMod1() )
599 : {
600 0 : SetFloatingMode( !IsFloatingMode() );
601 0 : return true;
602 : }
603 : }
604 : }
605 :
606 261714 : return Window::Notify( rNEvt );
607 : }
608 :
609 0 : void DockingWindow::StartDocking()
610 : {
611 0 : mbDocking = true;
612 0 : }
613 :
614 0 : bool DockingWindow::Docking( const Point&, Rectangle& )
615 : {
616 0 : return IsFloatingMode();
617 : }
618 :
619 0 : void DockingWindow::EndDocking( const Rectangle& rRect, bool bFloatMode )
620 : {
621 0 : if ( !IsDockingCanceled() )
622 : {
623 0 : bool bShow = false;
624 0 : if ( bool(bFloatMode) != IsFloatingMode() )
625 : {
626 0 : Show( false, SHOW_NOFOCUSCHANGE );
627 0 : SetFloatingMode( bFloatMode );
628 0 : bShow = true;
629 0 : if ( bFloatMode && mpFloatWin )
630 0 : mpFloatWin->SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
631 : }
632 0 : if ( !bFloatMode )
633 : {
634 0 : Point aPos = rRect.TopLeft();
635 0 : aPos = GetParent()->ScreenToOutputPixel( aPos );
636 0 : Window::SetPosSizePixel( aPos, rRect.GetSize() );
637 : }
638 :
639 0 : if ( bShow )
640 0 : Show();
641 : }
642 0 : mbDocking = false;
643 0 : }
644 :
645 0 : bool DockingWindow::PrepareToggleFloatingMode()
646 : {
647 0 : return true;
648 : }
649 :
650 0 : bool DockingWindow::Close()
651 : {
652 0 : ImplDelData aDelData;
653 0 : ImplAddDel( &aDelData );
654 0 : ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
655 0 : if ( aDelData.IsDead() )
656 0 : return false;
657 0 : ImplRemoveDel( &aDelData );
658 :
659 0 : if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() )
660 0 : return false;
661 :
662 0 : Show( false, SHOW_NOFOCUSCHANGE );
663 0 : return true;
664 : }
665 :
666 0 : void DockingWindow::ToggleFloatingMode()
667 : {
668 0 : }
669 :
670 0 : void DockingWindow::TitleButtonClick( sal_uInt16 )
671 : {
672 0 : }
673 :
674 0 : void DockingWindow::Pin()
675 : {
676 0 : }
677 :
678 0 : void DockingWindow::Roll()
679 : {
680 0 : }
681 :
682 0 : void DockingWindow::PopupModeEnd()
683 : {
684 0 : }
685 :
686 0 : void DockingWindow::Resizing( Size& )
687 : {
688 0 : }
689 :
690 247460 : void DockingWindow::StateChanged( StateChangedType nType )
691 : {
692 247460 : switch(nType)
693 : {
694 : case StateChangedType::CONTROLBACKGROUND:
695 0 : ImplInitSettings();
696 0 : Invalidate();
697 0 : break;
698 :
699 : case StateChangedType::STYLE:
700 0 : mbDockable = (GetStyle() & WB_DOCKABLE) != 0;
701 0 : break;
702 :
703 : default:
704 247460 : break;
705 : }
706 :
707 247460 : Window::StateChanged( nType );
708 247460 : }
709 :
710 316 : void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt )
711 : {
712 632 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
713 316 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
714 : {
715 172 : ImplInitSettings();
716 172 : Invalidate();
717 : }
718 : else
719 144 : Window::DataChanged( rDCEvt );
720 316 : }
721 :
722 0 : void DockingWindow::SetFloatingMode( bool bFloatMode )
723 : {
724 0 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
725 0 : if( pWrapper )
726 : {
727 0 : pWrapper->SetFloatingMode( bFloatMode );
728 0 : return;
729 : }
730 0 : if ( IsFloatingMode() != bFloatMode )
731 : {
732 0 : if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed
733 : {
734 0 : bool bVisible = IsVisible();
735 :
736 0 : if ( bFloatMode )
737 : {
738 0 : Show( false, SHOW_NOFOCUSCHANGE );
739 :
740 0 : maDockPos = Window::GetPosPixel();
741 :
742 0 : vcl::Window* pRealParent = mpWindowImpl->mpRealParent;
743 0 : mpOldBorderWin = mpWindowImpl->mpBorderWindow;
744 :
745 : ImplDockFloatWin* pWin =
746 : new ImplDockFloatWin(
747 : mpImplData->mpParent,
748 0 : mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits,
749 0 : this );
750 0 : mpFloatWin = pWin;
751 0 : mpWindowImpl->mpBorderWindow = NULL;
752 0 : mpWindowImpl->mnLeftBorder = 0;
753 0 : mpWindowImpl->mnTopBorder = 0;
754 0 : mpWindowImpl->mnRightBorder = 0;
755 0 : mpWindowImpl->mnBottomBorder = 0;
756 : // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
757 0 : if ( mpOldBorderWin )
758 0 : mpOldBorderWin->SetParent( pWin );
759 :
760 : // #i123765# reset the buffered DropTargets when undocking, else it may not
761 : // be correctly initialized
762 0 : mpWindowImpl->mxDNDListenerContainer.clear();
763 :
764 0 : SetParent( pWin );
765 0 : SetPosPixel( Point() );
766 0 : mpWindowImpl->mpBorderWindow = pWin;
767 0 : pWin->mpWindowImpl->mpClientWindow = this;
768 0 : mpWindowImpl->mpRealParent = pRealParent;
769 0 : pWin->SetText( Window::GetText() );
770 0 : pWin->SetOutputSizePixel( Window::GetSizePixel() );
771 0 : pWin->SetPosPixel( maFloatPos );
772 : // pass on DockingData to FloatingWindow
773 0 : pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
774 0 : pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
775 0 : pWin->SetPin( mbPinned );
776 0 : if ( mbRollUp )
777 0 : pWin->RollUp();
778 : else
779 0 : pWin->RollDown();
780 0 : pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
781 0 : pWin->SetMinOutputSizePixel( maMinOutSize );
782 0 : pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize );
783 :
784 0 : ToggleFloatingMode();
785 :
786 0 : if ( bVisible )
787 0 : Show();
788 : }
789 : else
790 : {
791 0 : Show( false, SHOW_NOFOCUSCHANGE );
792 :
793 : // store FloatingData in FloatingWindow
794 0 : maFloatPos = mpFloatWin->GetPosPixel();
795 0 : mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
796 0 : mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
797 0 : mbPinned = mpFloatWin->IsPinned();
798 0 : mbRollUp = mpFloatWin->IsRollUp();
799 0 : maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
800 0 : maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
801 0 : mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
802 :
803 0 : vcl::Window* pRealParent = mpWindowImpl->mpRealParent;
804 0 : mpWindowImpl->mpBorderWindow = NULL;
805 0 : if ( mpOldBorderWin )
806 : {
807 0 : SetParent( mpOldBorderWin );
808 0 : static_cast<ImplBorderWindow*>(mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
809 0 : mpOldBorderWin->Resize();
810 : }
811 0 : mpWindowImpl->mpBorderWindow = mpOldBorderWin;
812 0 : SetParent( pRealParent );
813 0 : mpWindowImpl->mpRealParent = pRealParent;
814 0 : delete static_cast<ImplDockFloatWin*>(mpFloatWin);
815 0 : mpFloatWin = NULL;
816 0 : SetPosPixel( maDockPos );
817 :
818 0 : ToggleFloatingMode();
819 :
820 0 : if ( bVisible )
821 0 : Show();
822 : }
823 : }
824 : }
825 : }
826 :
827 18 : void DockingWindow::SetFloatStyle( WinBits nStyle )
828 : {
829 18 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
830 18 : if( pWrapper )
831 : {
832 18 : pWrapper->SetFloatStyle( nStyle );
833 36 : return;
834 : }
835 :
836 0 : mnFloatBits = nStyle;
837 : }
838 :
839 23941 : WinBits DockingWindow::GetFloatStyle() const
840 : {
841 23941 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
842 23941 : if( pWrapper )
843 : {
844 18 : return pWrapper->GetFloatStyle();
845 : }
846 :
847 23923 : return mnFloatBits;
848 : }
849 :
850 218944 : void DockingWindow::setPosSizePixel( long nX, long nY,
851 : long nWidth, long nHeight,
852 : sal_uInt16 nFlags )
853 : {
854 218944 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
855 218944 : if( pWrapper )
856 : {
857 51804 : if ( pWrapper->mpFloatWin )
858 0 : pWrapper->mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
859 : else
860 51804 : Window::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
861 270748 : return;
862 : }
863 :
864 167140 : if ( mpFloatWin )
865 0 : mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
866 : else
867 167140 : Window::setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
868 : }
869 :
870 125289 : Point DockingWindow::GetPosPixel() const
871 : {
872 125289 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
873 125289 : if( pWrapper )
874 : {
875 87551 : if ( pWrapper->mpFloatWin )
876 0 : return pWrapper->mpFloatWin->GetPosPixel();
877 : else
878 87551 : return Window::GetPosPixel();
879 : }
880 :
881 37738 : if ( mpFloatWin )
882 0 : return mpFloatWin->GetPosPixel();
883 : else
884 37738 : return Window::GetPosPixel();
885 : }
886 :
887 280138 : Size DockingWindow::GetSizePixel() const
888 : {
889 280138 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
890 280138 : if( pWrapper )
891 : {
892 87551 : if ( pWrapper->mpFloatWin )
893 0 : return pWrapper->mpFloatWin->GetSizePixel();
894 : else
895 87551 : return Window::GetSizePixel();
896 : }
897 :
898 192587 : if ( mpFloatWin )
899 0 : return mpFloatWin->GetSizePixel();
900 : else
901 192587 : return Window::GetSizePixel();
902 : }
903 :
904 32861 : void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
905 : {
906 32861 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
907 32861 : if( pWrapper )
908 : {
909 16276 : if ( pWrapper->mpFloatWin )
910 0 : pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize );
911 : else
912 16276 : Window::SetOutputSizePixel( rNewSize );
913 49137 : return;
914 : }
915 :
916 16585 : if ( mpFloatWin )
917 0 : mpFloatWin->SetOutputSizePixel( rNewSize );
918 : else
919 16585 : Window::SetOutputSizePixel( rNewSize );
920 : }
921 :
922 249866 : Size DockingWindow::GetOutputSizePixel() const
923 : {
924 249866 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
925 249866 : if( pWrapper )
926 : {
927 174672 : if ( pWrapper->mpFloatWin )
928 0 : return pWrapper->mpFloatWin->GetOutputSizePixel();
929 : else
930 174672 : return Window::GetOutputSizePixel();
931 : }
932 :
933 75194 : if ( mpFloatWin )
934 0 : return mpFloatWin->GetOutputSizePixel();
935 : else
936 75194 : return Window::GetOutputSizePixel();
937 : }
938 :
939 5012 : Point DockingWindow::GetFloatingPos() const
940 : {
941 5012 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
942 5012 : if( pWrapper )
943 : {
944 0 : if ( pWrapper->mpFloatWin )
945 : {
946 0 : WindowStateData aData;
947 0 : aData.SetMask( WINDOWSTATE_MASK_POS );
948 0 : pWrapper->mpFloatWin->GetWindowStateData( aData );
949 0 : Point aPos( aData.GetX(), aData.GetY() );
950 0 : aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
951 0 : return aPos;
952 : }
953 : else
954 0 : return maFloatPos;
955 : }
956 :
957 5012 : if ( mpFloatWin )
958 : {
959 0 : WindowStateData aData;
960 0 : aData.SetMask( WINDOWSTATE_MASK_POS );
961 0 : mpFloatWin->GetWindowStateData( aData );
962 0 : Point aPos( aData.GetX(), aData.GetY() );
963 0 : aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
964 0 : return aPos;
965 : }
966 : else
967 5012 : return maFloatPos;
968 : }
969 :
970 2096589 : bool DockingWindow::IsFloatingMode() const
971 : {
972 2096589 : ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
973 2096589 : if( pWrapper )
974 1286168 : return pWrapper->IsFloatingMode();
975 : else
976 810421 : return (mpFloatWin != NULL);
977 : }
978 :
979 0 : void DockingWindow::SetMaxOutputSizePixel( const Size& rSize )
980 : {
981 0 : if ( mpFloatWin )
982 0 : mpFloatWin->SetMaxOutputSizePixel( rSize );
983 0 : mpImplData->maMaxOutSize = rSize;
984 1233 : }
985 :
986 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|