bump product version to 6.4.0.3
[LibreOffice.git] / vcl / source / window / brdwin.cxx
blob1b436b544700adca97bbd2554b25964b5e4b2a56
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <strings.hrc>
21 #include <svdata.hxx>
22 #include <brdwin.hxx>
23 #include <window.h>
25 #include <vcl/textrectinfo.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/decoview.hxx>
28 #include <vcl/syswin.hxx>
29 #include <vcl/dockwin.hxx>
30 #include <vcl/floatwin.hxx>
31 #include <vcl/help.hxx>
32 #include <vcl/edit.hxx>
33 #include <vcl/settings.hxx>
34 #include <vcl/toolbox.hxx>
35 #include <vcl/ptrstyle.hxx>
37 using namespace ::com::sun::star::uno;
39 // useful caption height for title bar buttons
40 #define MIN_CAPTION_HEIGHT 18
42 namespace vcl {
44 void Window::ImplCalcSymbolRect( tools::Rectangle& rRect )
46 // Add border, not shown in the non-default representation,
47 // as we want to use it for small buttons
48 rRect.AdjustLeft( -1 );
49 rRect.AdjustTop( -1 );
50 rRect.AdjustRight( 1 );
51 rRect.AdjustBottom( 1 );
53 // we leave 5% room between the symbol and the button border
54 long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
55 long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
56 rRect.AdjustLeft(nExtraWidth );
57 rRect.AdjustRight( -nExtraWidth );
58 rRect.AdjustTop(nExtraHeight );
59 rRect.AdjustBottom( -nExtraHeight );
62 } /* namespace vcl */
64 static void ImplDrawBrdWinSymbol( vcl::RenderContext* pDev,
65 const tools::Rectangle& rRect, SymbolType eSymbol )
67 // we leave 5% room between the symbol and the button border
68 DecorationView aDecoView( pDev );
69 tools::Rectangle aTempRect = rRect;
70 vcl::Window::ImplCalcSymbolRect( aTempRect );
71 aDecoView.DrawSymbol( aTempRect, eSymbol,
72 pDev->GetSettings().GetStyleSettings().GetButtonTextColor() );
75 static void ImplDrawBrdWinSymbolButton( vcl::RenderContext* pDev,
76 const tools::Rectangle& rRect,
77 SymbolType eSymbol, DrawButtonFlags nState )
79 bool bMouseOver(nState & DrawButtonFlags::Highlight);
80 nState &= ~DrawButtonFlags::Highlight;
82 tools::Rectangle aTempRect;
83 vcl::Window *pWin = dynamic_cast< vcl::Window* >(pDev);
84 if( pWin )
86 if( bMouseOver )
88 // provide a bright background for selection effect
89 pDev->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() );
90 pDev->SetLineColor();
91 pDev->DrawRect( rRect );
92 pWin->DrawSelectionBackground( rRect, 2, bool(nState & DrawButtonFlags::Pressed),
93 true );
95 aTempRect = rRect;
96 aTempRect.AdjustLeft(3 );
97 aTempRect.AdjustRight( -4 );
98 aTempRect.AdjustTop(3 );
99 aTempRect.AdjustBottom( -4 );
101 else
103 DecorationView aDecoView( pDev );
104 aTempRect = aDecoView.DrawButton( rRect, nState|DrawButtonFlags::Flat );
106 ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
110 ImplBorderWindowView::~ImplBorderWindowView()
114 bool ImplBorderWindowView::MouseMove( const MouseEvent& )
116 return false;
119 bool ImplBorderWindowView::MouseButtonDown( const MouseEvent& )
121 return false;
124 bool ImplBorderWindowView::Tracking( const TrackingEvent& )
126 return false;
129 OUString ImplBorderWindowView::RequestHelp( const Point&, tools::Rectangle& )
131 return OUString();
134 tools::Rectangle ImplBorderWindowView::GetMenuRect() const
136 return tools::Rectangle();
139 void ImplBorderWindowView::ImplInitTitle(ImplBorderFrameData* pData)
141 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
143 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) ||
144 (pData->mnTitleType == BorderWindowTitleType::NONE) )
146 pData->mnTitleType = BorderWindowTitleType::NONE;
147 pData->mnTitleHeight = 0;
149 else
151 const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
152 if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
153 pData->mnTitleHeight = ToolBox::ImplGetDragWidth(*pData->mpBorderWindow, false) + 2;
154 else
156 if (pData->mnTitleType == BorderWindowTitleType::Small)
158 pBorderWindow->SetPointFont(*pBorderWindow, rStyleSettings.GetFloatTitleFont() );
159 pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
161 else // pData->mnTitleType == BorderWindowTitleType::Normal
163 // FIXME RenderContext
164 pBorderWindow->SetPointFont(*pBorderWindow, rStyleSettings.GetTitleFont());
165 pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
167 long nTextHeight = pBorderWindow->GetTextHeight();
168 if (nTextHeight > pData->mnTitleHeight)
169 pData->mnTitleHeight = nTextHeight;
174 BorderWindowHitTest ImplBorderWindowView::ImplHitTest( ImplBorderFrameData const * pData, const Point& rPos )
176 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
178 if ( pData->maTitleRect.IsInside( rPos ) )
180 if ( pData->maCloseRect.IsInside( rPos ) )
181 return BorderWindowHitTest::Close;
182 else if ( pData->maRollRect.IsInside( rPos ) )
183 return BorderWindowHitTest::Roll;
184 else if ( pData->maMenuRect.IsInside( rPos ) )
185 return BorderWindowHitTest::Menu;
186 else if ( pData->maDockRect.IsInside( rPos ) )
187 return BorderWindowHitTest::Dock;
188 else if ( pData->maHideRect.IsInside( rPos ) )
189 return BorderWindowHitTest::Hide;
190 else if ( pData->maHelpRect.IsInside( rPos ) )
191 return BorderWindowHitTest::Help;
192 else
193 return BorderWindowHitTest::Title;
196 if ( (pBorderWindow->GetStyle() & WB_SIZEABLE) &&
197 !pBorderWindow->mbRollUp )
199 long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
200 if ( nSizeWidth < 16 )
201 nSizeWidth = 16;
203 // no corner resize for floating toolbars, which would lead to jumps while formatting
204 // setting nSizeWidth = 0 will only return pure left,top,right,bottom
205 if( pBorderWindow->GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP) )
206 nSizeWidth = 0;
208 if ( rPos.X() < pData->mnLeftBorder )
210 if ( rPos.Y() < nSizeWidth )
211 return BorderWindowHitTest::TopLeft;
212 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
213 return BorderWindowHitTest::BottomLeft;
214 else
215 return BorderWindowHitTest::Left;
217 else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
219 if ( rPos.Y() < nSizeWidth )
220 return BorderWindowHitTest::TopRight;
221 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
222 return BorderWindowHitTest::BottomRight;
223 else
224 return BorderWindowHitTest::Right;
226 else if ( rPos.Y() < pData->mnNoTitleTop )
228 if ( rPos.X() < nSizeWidth )
229 return BorderWindowHitTest::TopLeft;
230 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
231 return BorderWindowHitTest::TopRight;
232 else
233 return BorderWindowHitTest::Top;
235 else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
237 if ( rPos.X() < nSizeWidth )
238 return BorderWindowHitTest::BottomLeft;
239 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
240 return BorderWindowHitTest::BottomRight;
241 else
242 return BorderWindowHitTest::Bottom;
246 return BorderWindowHitTest::NONE;
249 void ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
251 DrawButtonFlags oldCloseState = pData->mnCloseState;
252 DrawButtonFlags oldMenuState = pData->mnMenuState;
253 pData->mnCloseState &= ~DrawButtonFlags::Highlight;
254 pData->mnMenuState &= ~DrawButtonFlags::Highlight;
256 Point aMousePos = rMEvt.GetPosPixel();
257 BorderWindowHitTest nHitTest = ImplHitTest( pData, aMousePos );
258 PointerStyle ePtrStyle = PointerStyle::Arrow;
259 if ( nHitTest & BorderWindowHitTest::Left )
260 ePtrStyle = PointerStyle::WindowWSize;
261 else if ( nHitTest & BorderWindowHitTest::Right )
262 ePtrStyle = PointerStyle::WindowESize;
263 else if ( nHitTest & BorderWindowHitTest::Top )
264 ePtrStyle = PointerStyle::WindowNSize;
265 else if ( nHitTest & BorderWindowHitTest::Bottom )
266 ePtrStyle = PointerStyle::WindowSSize;
267 else if ( nHitTest & BorderWindowHitTest::TopLeft )
268 ePtrStyle = PointerStyle::WindowNWSize;
269 else if ( nHitTest & BorderWindowHitTest::BottomRight )
270 ePtrStyle = PointerStyle::WindowSESize;
271 else if ( nHitTest & BorderWindowHitTest::TopRight )
272 ePtrStyle = PointerStyle::WindowNESize;
273 else if ( nHitTest & BorderWindowHitTest::BottomLeft )
274 ePtrStyle = PointerStyle::WindowSWSize;
275 else if ( nHitTest & BorderWindowHitTest::Close )
276 pData->mnCloseState |= DrawButtonFlags::Highlight;
277 else if ( nHitTest & BorderWindowHitTest::Menu )
278 pData->mnMenuState |= DrawButtonFlags::Highlight;
279 else if ( nHitTest & BorderWindowHitTest::Title &&
280 pData->mnTitleType == BorderWindowTitleType::Tearoff && !rMEvt.IsLeaveWindow() )
281 ePtrStyle = PointerStyle::Move;
282 pData->mpBorderWindow->SetPointer( ePtrStyle );
284 if( pData->mnCloseState != oldCloseState )
285 pData->mpBorderWindow->Invalidate( pData->maCloseRect );
286 if( pData->mnMenuState != oldMenuState )
287 pData->mpBorderWindow->Invalidate( pData->maMenuRect );
290 OUString ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData const * pData,
291 const Point& rPos,
292 tools::Rectangle& rHelpRect )
294 const char* pHelpId = nullptr;
295 OUString aHelpStr;
296 BorderWindowHitTest nHitTest = ImplHitTest( pData, rPos );
297 if ( nHitTest != BorderWindowHitTest::NONE )
299 if ( nHitTest & BorderWindowHitTest::Close )
301 pHelpId = SV_HELPTEXT_CLOSE;
302 rHelpRect = pData->maCloseRect;
304 else if ( nHitTest & BorderWindowHitTest::Roll )
306 if ( pData->mpBorderWindow->mbRollUp )
307 pHelpId = SV_HELPTEXT_ROLLDOWN;
308 else
309 pHelpId = SV_HELPTEXT_ROLLUP;
310 rHelpRect = pData->maRollRect;
312 else if ( nHitTest & BorderWindowHitTest::Dock )
314 pHelpId = SV_HELPTEXT_MAXIMIZE;
315 rHelpRect = pData->maDockRect;
317 else if ( nHitTest & BorderWindowHitTest::Hide )
319 pHelpId = SV_HELPTEXT_MINIMIZE;
320 rHelpRect = pData->maHideRect;
322 else if ( nHitTest & BorderWindowHitTest::Help )
324 pHelpId = SV_HELPTEXT_HELP;
325 rHelpRect = pData->maHelpRect;
327 else if ( nHitTest & BorderWindowHitTest::Title )
329 if( !pData->maTitleRect.IsEmpty() )
331 // tooltip only if title truncated
332 if( pData->mbTitleClipped )
334 rHelpRect = pData->maTitleRect;
335 // no help id, use window title as help string
336 aHelpStr = pData->mpBorderWindow->GetText();
342 if (pHelpId)
343 aHelpStr = VclResId(pHelpId);
345 return aHelpStr;
348 long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData )
350 // title is not visible therefore no width
351 if ( !pData->mnTitleHeight )
352 return 0;
354 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
355 long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
356 nTitleWidth += pData->maCloseRect.GetWidth();
357 nTitleWidth += pData->maRollRect.GetWidth();
358 nTitleWidth += pData->maDockRect.GetWidth();
359 nTitleWidth += pData->maMenuRect.GetWidth();
360 nTitleWidth += pData->maHideRect.GetWidth();
361 nTitleWidth += pData->maHelpRect.GetWidth();
362 nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
363 return nTitleWidth;
367 ImplNoBorderWindowView::ImplNoBorderWindowView()
371 void ImplNoBorderWindowView::Init( OutputDevice*, long, long )
375 void ImplNoBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
376 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
378 rLeftBorder = 0;
379 rTopBorder = 0;
380 rRightBorder = 0;
381 rBottomBorder = 0;
384 long ImplNoBorderWindowView::CalcTitleWidth() const
386 return 0;
389 void ImplNoBorderWindowView::DrawWindow(vcl::RenderContext&, const Point*)
393 ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
394 : mpBorderWindow(pBorderWindow)
395 , mpOutDev(nullptr)
396 , mnWidth(0)
397 , mnHeight(0)
398 , mnLeftBorder(0)
399 , mnTopBorder(0)
400 , mnRightBorder(0)
401 , mnBottomBorder(0)
402 , mbNWFBorder(false)
406 void ImplSmallBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
408 mpOutDev = pDev;
409 mnWidth = nWidth;
410 mnHeight = nHeight;
411 mbNWFBorder = false;
413 vcl::Window *pWin = nullptr, *pCtrl = nullptr;
414 if (mpOutDev->GetOutDevType() == OUTDEV_WINDOW)
415 pWin = static_cast<vcl::Window*>(mpOutDev.get());
417 if (pWin)
418 pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
420 long nOrigLeftBorder = mnLeftBorder;
421 long nOrigTopBorder = mnTopBorder;
422 long nOrigRightBorder = mnRightBorder;
423 long nOrigBottomBorder = mnBottomBorder;
425 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
426 if ( nBorderStyle & WindowBorderStyle::NOBORDER )
428 mnLeftBorder = 0;
429 mnTopBorder = 0;
430 mnRightBorder = 0;
431 mnBottomBorder = 0;
433 else
435 // FIXME: this is currently only on macOS, check with other
436 // platforms
437 if( ImplGetSVData()->maNWFData.mbNoFocusRects && !( nBorderStyle & WindowBorderStyle::NWF ) )
439 // for native widget drawing we must find out what
440 // control this border belongs to
441 ControlType aCtrlType = ControlType::Generic;
442 if (pCtrl)
444 switch( pCtrl->GetType() )
446 case WindowType::LISTBOX:
447 if( pCtrl->GetStyle() & WB_DROPDOWN )
449 aCtrlType = ControlType::Listbox;
450 mbNWFBorder = true;
452 break;
453 case WindowType::COMBOBOX:
454 if( pCtrl->GetStyle() & WB_DROPDOWN )
456 aCtrlType = ControlType::Combobox;
457 mbNWFBorder = true;
459 break;
460 case WindowType::MULTILINEEDIT:
461 aCtrlType = ControlType::MultilineEditbox;
462 mbNWFBorder = true;
463 break;
464 case WindowType::EDIT:
465 case WindowType::PATTERNFIELD:
466 case WindowType::METRICFIELD:
467 case WindowType::CURRENCYFIELD:
468 case WindowType::DATEFIELD:
469 case WindowType::TIMEFIELD:
470 case WindowType::LONGCURRENCYFIELD:
471 case WindowType::NUMERICFIELD:
472 case WindowType::SPINFIELD:
473 case WindowType::CALCINPUTLINE:
474 mbNWFBorder = true;
475 if (pCtrl->GetStyle() & WB_SPIN)
476 aCtrlType = ControlType::Spinbox;
477 else
478 aCtrlType = ControlType::Editbox;
479 break;
480 default:
481 break;
484 if( mbNWFBorder )
486 ImplControlValue aControlValue;
487 Size aMinSize( mnWidth - mnLeftBorder - mnRightBorder, mnHeight - mnTopBorder - mnBottomBorder );
488 if( aMinSize.Width() < 10 ) aMinSize.setWidth( 10 );
489 if( aMinSize.Height() < 10 ) aMinSize.setHeight( 10 );
490 tools::Rectangle aCtrlRegion( Point(mnLeftBorder, mnTopBorder), aMinSize );
491 tools::Rectangle aBounds, aContent;
492 if( pWin->GetNativeControlRegion( aCtrlType, ControlPart::Entire, aCtrlRegion,
493 ControlState::ENABLED, aControlValue,
494 aBounds, aContent ) )
496 mnLeftBorder = aContent.Left() - aBounds.Left();
497 mnRightBorder = aBounds.Right() - aContent.Right();
498 mnTopBorder = aContent.Top() - aBounds.Top();
499 mnBottomBorder = aBounds.Bottom() - aContent.Bottom();
500 if( mnWidth && mnHeight )
503 mpBorderWindow->SetPaintTransparent( true );
504 mpBorderWindow->SetBackground();
505 pCtrl->SetPaintTransparent( true );
507 vcl::Window* pCompoundParent = nullptr;
508 if( pWin->GetParent() && pWin->GetParent()->IsCompoundControl() )
509 pCompoundParent = pWin->GetParent();
511 if( pCompoundParent )
512 pCompoundParent->SetPaintTransparent( true );
514 if( mnWidth < aBounds.GetWidth() || mnHeight < aBounds.GetHeight() )
516 if( ! pCompoundParent ) // compound controls have to fix themselves
518 Point aPos( mpBorderWindow->GetPosPixel() );
519 if( mnWidth < aBounds.GetWidth() )
520 aPos.AdjustX( -((aBounds.GetWidth() - mnWidth) / 2) );
521 if( mnHeight < aBounds.GetHeight() )
522 aPos.AdjustY( -((aBounds.GetHeight() - mnHeight) / 2) );
523 mpBorderWindow->SetPosSizePixel( aPos, aBounds.GetSize() );
528 else
529 mbNWFBorder = false;
533 if( ! mbNWFBorder )
535 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
536 DrawFrameFlags nFlags = DrawFrameFlags::NoDraw;
537 // move border outside if border was converted or if the BorderWindow is a frame window,
538 if ( mpBorderWindow->mbSmallOutBorder )
539 nStyle = DrawFrameStyle::DoubleOut;
540 else if ( nBorderStyle & WindowBorderStyle::NWF )
541 nStyle = DrawFrameStyle::NWF;
542 else
543 nStyle = DrawFrameStyle::DoubleIn;
544 if ( nBorderStyle & WindowBorderStyle::MONO )
545 nFlags |= DrawFrameFlags::Mono;
547 DecorationView aDecoView( mpOutDev );
548 tools::Rectangle aRect( 0, 0, 10, 10 );
549 tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, nStyle, nFlags );
550 mnLeftBorder = aCalcRect.Left();
551 mnTopBorder = aCalcRect.Top();
552 mnRightBorder = aRect.Right()-aCalcRect.Right();
553 mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
557 if (pCtrl)
559 //fdo#57090 If the borders have changed, then trigger a queue_resize on
560 //the bordered window, which will resync its borders at that point
561 if (nOrigLeftBorder != mnLeftBorder ||
562 nOrigTopBorder != mnTopBorder ||
563 nOrigRightBorder != mnRightBorder ||
564 nOrigBottomBorder != mnBottomBorder)
566 pCtrl->queue_resize();
571 void ImplSmallBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
572 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
574 rLeftBorder = mnLeftBorder;
575 rTopBorder = mnTopBorder;
576 rRightBorder = mnRightBorder;
577 rBottomBorder = mnBottomBorder;
580 long ImplSmallBorderWindowView::CalcTitleWidth() const
582 return 0;
585 void ImplSmallBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point*)
587 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
588 if (nBorderStyle & WindowBorderStyle::NOBORDER)
589 return;
591 bool bNativeOK = false;
592 // for native widget drawing we must find out what
593 // control this border belongs to
594 vcl::Window* pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
596 ControlType aCtrlType = ControlType::Generic;
597 ControlPart aCtrlPart = ControlPart::Entire;
598 if (pCtrl)
600 switch (pCtrl->GetType())
602 case WindowType::MULTILINEEDIT:
603 aCtrlType = ControlType::MultilineEditbox;
604 break;
605 case WindowType::EDIT:
606 case WindowType::PATTERNFIELD:
607 case WindowType::METRICFIELD:
608 case WindowType::CURRENCYFIELD:
609 case WindowType::DATEFIELD:
610 case WindowType::TIMEFIELD:
611 case WindowType::LONGCURRENCYFIELD:
612 case WindowType::NUMERICFIELD:
613 case WindowType::SPINFIELD:
614 case WindowType::CALCINPUTLINE:
615 if (pCtrl->GetStyle() & WB_SPIN)
616 aCtrlType = ControlType::Spinbox;
617 else
618 aCtrlType = ControlType::Editbox;
619 break;
621 case WindowType::LISTBOX:
622 case WindowType::MULTILISTBOX:
623 case WindowType::TREELISTBOX:
624 aCtrlType = ControlType::Listbox;
625 if (pCtrl->GetStyle() & WB_DROPDOWN)
626 aCtrlPart = ControlPart::Entire;
627 else
628 aCtrlPart = ControlPart::ListboxWindow;
629 break;
631 case WindowType::LISTBOXWINDOW:
632 aCtrlType = ControlType::Listbox;
633 aCtrlPart = ControlPart::ListboxWindow;
634 break;
636 case WindowType::COMBOBOX:
637 case WindowType::PATTERNBOX:
638 case WindowType::NUMERICBOX:
639 case WindowType::METRICBOX:
640 case WindowType::CURRENCYBOX:
641 case WindowType::DATEBOX:
642 case WindowType::TIMEBOX:
643 case WindowType::LONGCURRENCYBOX:
644 if (pCtrl->GetStyle() & WB_DROPDOWN)
646 aCtrlType = ControlType::Combobox;
647 aCtrlPart = ControlPart::Entire;
649 else
651 aCtrlType = ControlType::Listbox;
652 aCtrlPart = ControlPart::ListboxWindow;
654 break;
656 default:
657 break;
661 if (aCtrlType != ControlType::Generic && pCtrl->IsNativeControlSupported(aCtrlType, aCtrlPart))
663 ImplControlValue aControlValue;
664 ControlState nState = ControlState::ENABLED;
666 if (!mpBorderWindow->IsEnabled())
667 nState &= ~ControlState::ENABLED;
668 if (mpBorderWindow->HasFocus())
669 nState |= ControlState::FOCUSED;
670 else if(mbNWFBorder)
672 // FIXME: this is currently only on macOS, see if other platforms can profit
674 // FIXME: for macOS focus rings all controls need to support GetNativeControlRegion
675 // for the dropdown style
676 if (pCtrl->HasFocus() || pCtrl->HasChildPathFocus())
677 nState |= ControlState::FOCUSED;
680 bool bMouseOver = false;
681 vcl::Window *pCtrlChild = pCtrl->GetWindow(GetWindowType::FirstChild);
682 while(pCtrlChild && !(bMouseOver = pCtrlChild->IsMouseOver()))
684 pCtrlChild = pCtrlChild->GetWindow(GetWindowType::Next);
687 if (bMouseOver)
688 nState |= ControlState::ROLLOVER;
690 Point aPoint;
691 tools::Rectangle aCtrlRegion(aPoint, Size(mnWidth, mnHeight));
693 tools::Rectangle aBoundingRgn(aPoint, Size(mnWidth, mnHeight));
694 tools::Rectangle aContentRgn(aCtrlRegion);
695 if (!ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize &&
696 rRenderContext.GetNativeControlRegion(aCtrlType, aCtrlPart, aCtrlRegion,
697 nState, aControlValue,
698 aBoundingRgn, aContentRgn))
700 aCtrlRegion=aContentRgn;
703 bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, aCtrlPart, aCtrlRegion, nState, aControlValue, OUString());
705 // if the native theme draws the spinbuttons in one call, make sure the proper settings
706 // are passed, this might force a redraw though... (TODO: improve)
707 if ((aCtrlType == ControlType::Spinbox) && !pCtrl->IsNativeControlSupported(ControlType::Spinbox, ControlPart::ButtonUp))
709 Edit* pEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
710 if (pEdit && !pEdit->SupportsDoubleBuffering())
711 pCtrl->Paint(*pCtrl, tools::Rectangle()); // make sure the buttons are also drawn as they might overwrite the border
715 if (bNativeOK)
716 return;
718 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
719 DrawFrameFlags nFlags = DrawFrameFlags::NONE;
720 // move border outside if border was converted or if the border window is a frame window,
721 if (mpBorderWindow->mbSmallOutBorder)
722 nStyle = DrawFrameStyle::DoubleOut;
723 else if (nBorderStyle & WindowBorderStyle::NWF)
724 nStyle = DrawFrameStyle::NWF;
725 else
726 nStyle = DrawFrameStyle::DoubleIn;
727 if (nBorderStyle & WindowBorderStyle::MONO)
728 nFlags |= DrawFrameFlags::Mono;
729 if (nBorderStyle & WindowBorderStyle::MENU)
730 nFlags |= DrawFrameFlags::Menu;
731 // tell DrawFrame that we're drawing a window border of a frame window to avoid round corners
732 if (mpBorderWindow == mpBorderWindow->ImplGetFrameWindow())
733 nFlags |= DrawFrameFlags::WindowBorder;
735 DecorationView aDecoView(&rRenderContext);
736 tools::Rectangle aInRect(Point(), Size(mnWidth, mnHeight));
737 aDecoView.DrawFrame(aInRect, nStyle, nFlags);
741 ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
743 maFrameData.mpBorderWindow = pBorderWindow;
744 maFrameData.mbDragFull = false;
745 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
746 maFrameData.mnCloseState = DrawButtonFlags::NONE;
747 maFrameData.mnRollState = DrawButtonFlags::NONE;
748 maFrameData.mnDockState = DrawButtonFlags::NONE;
749 maFrameData.mnMenuState = DrawButtonFlags::NONE;
750 maFrameData.mnHideState = DrawButtonFlags::NONE;
751 maFrameData.mnHelpState = DrawButtonFlags::NONE;
752 maFrameData.mbTitleClipped = false;
755 ImplStdBorderWindowView::~ImplStdBorderWindowView()
759 bool ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
761 ImplMouseMove( &maFrameData, rMEvt );
762 return true;
765 bool ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
767 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
769 if ( rMEvt.IsLeft() || rMEvt.IsRight() )
771 maFrameData.maMouseOff = rMEvt.GetPosPixel();
772 maFrameData.mnHitTest = ImplHitTest( &maFrameData, maFrameData.maMouseOff );
773 if ( maFrameData.mnHitTest != BorderWindowHitTest::NONE )
775 DragFullOptions nDragFullTest = DragFullOptions::NONE;
776 bool bTracking = true;
777 bool bHitTest = true;
779 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
781 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
782 pBorderWindow->InvalidateBorder();
784 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Roll )
786 maFrameData.mnRollState |= DrawButtonFlags::Pressed;
787 pBorderWindow->InvalidateBorder();
789 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
791 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
792 pBorderWindow->InvalidateBorder();
794 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
796 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
797 pBorderWindow->InvalidateBorder();
799 // call handler already on mouse down
800 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
802 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
803 pClientWindow->TitleButtonClick( TitleButton::Menu );
806 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
808 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
809 pBorderWindow->InvalidateBorder();
811 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
813 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
814 pBorderWindow->InvalidateBorder();
816 else
818 if ( rMEvt.GetClicks() == 1 )
820 Point aPos = pBorderWindow->GetPosPixel();
821 Size aSize = pBorderWindow->GetOutputSizePixel();
822 maFrameData.mnTrackX = aPos.X();
823 maFrameData.mnTrackY = aPos.Y();
824 maFrameData.mnTrackWidth = aSize.Width();
825 maFrameData.mnTrackHeight = aSize.Height();
827 if (maFrameData.mnHitTest & BorderWindowHitTest::Title)
828 nDragFullTest = DragFullOptions::WindowMove;
829 else
830 nDragFullTest = DragFullOptions::WindowSize;
832 else
834 bTracking = false;
836 if ( (maFrameData.mnHitTest & BorderWindowHitTest::Title) &&
837 ((rMEvt.GetClicks() % 2) == 0) )
839 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
840 bHitTest = false;
842 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
844 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
845 // always perform docking on double click, no button required
846 pClientWindow->TitleButtonClick( TitleButton::Docking );
852 if ( bTracking )
854 maFrameData.mbDragFull = false;
855 if ( nDragFullTest != DragFullOptions::NONE )
856 maFrameData.mbDragFull = true; // always fulldrag for proper docking, ignore system settings
857 pBorderWindow->StartTracking();
859 else if ( bHitTest )
860 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
864 return true;
867 bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
869 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
871 if ( rTEvt.IsTrackingEnded() )
873 BorderWindowHitTest nHitTest = maFrameData.mnHitTest;
874 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
876 if ( nHitTest & BorderWindowHitTest::Close )
878 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
880 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
881 pBorderWindow->InvalidateBorder();
883 // do not call a Click-Handler when aborting
884 if ( !rTEvt.IsTrackingCanceled() )
886 // dispatch to correct window type (why is Close() not virtual ??? )
887 // TODO: make Close() virtual
888 VclPtr<vcl::Window> pWin = pBorderWindow->ImplGetClientWindow()->ImplGetWindow();
889 SystemWindow *pSysWin = dynamic_cast<SystemWindow* >(pWin.get());
890 DockingWindow *pDockWin = dynamic_cast<DockingWindow*>(pWin.get());
891 if ( pSysWin )
892 pSysWin->Close();
893 else if ( pDockWin )
894 pDockWin->Close();
898 else if ( nHitTest & BorderWindowHitTest::Roll )
900 if ( maFrameData.mnRollState & DrawButtonFlags::Pressed )
902 maFrameData.mnRollState &= ~DrawButtonFlags::Pressed;
903 pBorderWindow->InvalidateBorder();
905 // do not call a Click-Handler when aborting
906 if ( !rTEvt.IsTrackingCanceled() )
908 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
910 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
911 if ( pClientWindow->IsRollUp() )
912 pClientWindow->RollDown();
913 else
914 pClientWindow->RollUp();
919 else if ( nHitTest & BorderWindowHitTest::Dock )
921 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
923 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
924 pBorderWindow->InvalidateBorder();
926 // do not call a Click-Handler when aborting
927 if ( !rTEvt.IsTrackingCanceled() )
929 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
931 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
932 pClientWindow->TitleButtonClick( TitleButton::Docking );
937 else if ( nHitTest & BorderWindowHitTest::Menu )
939 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
941 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
942 pBorderWindow->InvalidateBorder();
944 // handler already called on mouse down
947 else if ( nHitTest & BorderWindowHitTest::Hide )
949 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
951 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
952 pBorderWindow->InvalidateBorder();
954 // do not call a Click-Handler when aborting
955 if ( !rTEvt.IsTrackingCanceled() )
957 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
959 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
960 pClientWindow->TitleButtonClick( TitleButton::Hide );
965 else if ( nHitTest & BorderWindowHitTest::Help )
967 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
969 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
970 pBorderWindow->InvalidateBorder();
973 else
975 if ( maFrameData.mbDragFull )
977 // restore old state when aborting
978 if ( rTEvt.IsTrackingCanceled() )
979 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
981 else
983 pBorderWindow->HideTracking();
984 if ( !rTEvt.IsTrackingCanceled() )
985 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
988 if ( !rTEvt.IsTrackingCanceled() )
990 if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
992 if ( static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
993 static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->EndPopupMode( FloatWinPopupEndFlags::TearOff );
998 else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
1000 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1002 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
1004 if ( maFrameData.maCloseRect.IsInside( aMousePos ) )
1006 if ( !(maFrameData.mnCloseState & DrawButtonFlags::Pressed) )
1008 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
1009 pBorderWindow->InvalidateBorder();
1012 else
1014 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
1016 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
1017 pBorderWindow->InvalidateBorder();
1021 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Roll )
1023 if ( maFrameData.maRollRect.IsInside( aMousePos ) )
1025 if ( !(maFrameData.mnRollState & DrawButtonFlags::Pressed) )
1027 maFrameData.mnRollState |= DrawButtonFlags::Pressed;
1028 pBorderWindow->InvalidateBorder();
1031 else
1033 if ( maFrameData.mnRollState & DrawButtonFlags::Pressed )
1035 maFrameData.mnRollState &= ~DrawButtonFlags::Pressed;
1036 pBorderWindow->InvalidateBorder();
1040 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
1042 if ( maFrameData.maDockRect.IsInside( aMousePos ) )
1044 if ( !(maFrameData.mnDockState & DrawButtonFlags::Pressed) )
1046 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
1047 pBorderWindow->InvalidateBorder();
1050 else
1052 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
1054 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
1055 pBorderWindow->InvalidateBorder();
1059 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
1061 if ( maFrameData.maMenuRect.IsInside( aMousePos ) )
1063 if ( !(maFrameData.mnMenuState & DrawButtonFlags::Pressed) )
1065 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
1066 pBorderWindow->InvalidateBorder();
1069 else
1071 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
1073 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
1074 pBorderWindow->InvalidateBorder();
1078 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
1080 if ( maFrameData.maHideRect.IsInside( aMousePos ) )
1082 if ( !(maFrameData.mnHideState & DrawButtonFlags::Pressed) )
1084 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
1085 pBorderWindow->InvalidateBorder();
1088 else
1090 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
1092 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
1093 pBorderWindow->InvalidateBorder();
1097 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
1099 if ( maFrameData.maHelpRect.IsInside( aMousePos ) )
1101 if ( !(maFrameData.mnHelpState & DrawButtonFlags::Pressed) )
1103 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
1104 pBorderWindow->InvalidateBorder();
1107 else
1109 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
1111 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
1112 pBorderWindow->InvalidateBorder();
1116 else
1118 aMousePos.AdjustX( -(maFrameData.maMouseOff.X()) );
1119 aMousePos.AdjustY( -(maFrameData.maMouseOff.Y()) );
1121 if ( maFrameData.mnHitTest & BorderWindowHitTest::Title )
1123 maFrameData.mpBorderWindow->SetPointer( PointerStyle::Move );
1125 Point aPos = pBorderWindow->GetPosPixel();
1126 aPos.AdjustX(aMousePos.X() );
1127 aPos.AdjustY(aMousePos.Y() );
1128 if ( maFrameData.mbDragFull )
1130 pBorderWindow->SetPosPixel( aPos );
1131 pBorderWindow->ImplUpdateAll();
1132 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1134 else
1136 maFrameData.mnTrackX = aPos.X();
1137 maFrameData.mnTrackY = aPos.Y();
1138 pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), ShowTrackFlags::Big );
1141 else
1143 Point aOldPos = pBorderWindow->GetPosPixel();
1144 Size aSize = pBorderWindow->GetSizePixel();
1145 tools::Rectangle aNewRect( aOldPos, aSize );
1146 long nOldWidth = aSize.Width();
1147 long nOldHeight = aSize.Height();
1148 long nBorderWidth = maFrameData.mnLeftBorder+maFrameData.mnRightBorder;
1149 long nBorderHeight = maFrameData.mnTopBorder+maFrameData.mnBottomBorder;
1150 long nMinWidth = pBorderWindow->mnMinWidth+nBorderWidth;
1151 long nMinHeight = pBorderWindow->mnMinHeight+nBorderHeight;
1152 long nMinWidth2 = nBorderWidth;
1153 long nMaxWidth = pBorderWindow->mnMaxWidth+nBorderWidth;
1154 long nMaxHeight = pBorderWindow->mnMaxHeight+nBorderHeight;
1156 if ( maFrameData.mnTitleHeight )
1158 nMinWidth2 += 4;
1160 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1161 nMinWidth2 += maFrameData.maCloseRect.GetWidth();
1163 if ( nMinWidth2 > nMinWidth )
1164 nMinWidth = nMinWidth2;
1165 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1167 aNewRect.AdjustLeft(aMousePos.X() );
1168 if ( aNewRect.GetWidth() < nMinWidth )
1169 aNewRect.SetLeft( aNewRect.Right()-nMinWidth+1 );
1170 else if ( aNewRect.GetWidth() > nMaxWidth )
1171 aNewRect.SetLeft( aNewRect.Right()-nMaxWidth+1 );
1173 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1175 aNewRect.AdjustRight(aMousePos.X() );
1176 if ( aNewRect.GetWidth() < nMinWidth )
1177 aNewRect.SetRight( aNewRect.Left()+nMinWidth+1 );
1178 else if ( aNewRect.GetWidth() > nMaxWidth )
1179 aNewRect.SetRight( aNewRect.Left()+nMaxWidth+1 );
1181 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1183 aNewRect.AdjustTop(aMousePos.Y() );
1184 if ( aNewRect.GetHeight() < nMinHeight )
1185 aNewRect.SetTop( aNewRect.Bottom()-nMinHeight+1 );
1186 else if ( aNewRect.GetHeight() > nMaxHeight )
1187 aNewRect.SetTop( aNewRect.Bottom()-nMaxHeight+1 );
1189 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1191 aNewRect.AdjustBottom(aMousePos.Y() );
1192 if ( aNewRect.GetHeight() < nMinHeight )
1193 aNewRect.SetBottom( aNewRect.Top()+nMinHeight+1 );
1194 else if ( aNewRect.GetHeight() > nMaxHeight )
1195 aNewRect.SetBottom( aNewRect.Top()+nMaxHeight+1 );
1198 // call Resizing-Handler for SystemWindows
1199 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
1201 // adjust size for Resizing-call
1202 aSize = aNewRect.GetSize();
1203 aSize.AdjustWidth( -nBorderWidth );
1204 aSize.AdjustHeight( -nBorderHeight );
1205 static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
1206 aSize.AdjustWidth(nBorderWidth );
1207 aSize.AdjustHeight(nBorderHeight );
1208 if ( aSize.Width() < nMinWidth )
1209 aSize.setWidth( nMinWidth );
1210 if ( aSize.Height() < nMinHeight )
1211 aSize.setHeight( nMinHeight );
1212 if ( aSize.Width() > nMaxWidth )
1213 aSize.setWidth( nMaxWidth );
1214 if ( aSize.Height() > nMaxHeight )
1215 aSize.setHeight( nMaxHeight );
1216 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1217 aNewRect.SetLeft( aNewRect.Right()-aSize.Width()+1 );
1218 else
1219 aNewRect.SetRight( aNewRect.Left()+aSize.Width()-1 );
1220 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1221 aNewRect.SetTop( aNewRect.Bottom()-aSize.Height()+1 );
1222 else
1223 aNewRect.SetBottom( aNewRect.Top()+aSize.Height()-1 );
1226 if ( maFrameData.mbDragFull )
1228 // no move (only resize) if position did not change
1229 if( aOldPos != aNewRect.TopLeft() )
1230 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1231 aNewRect.GetWidth(), aNewRect.GetHeight() );
1232 else
1233 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1234 aNewRect.GetWidth(), aNewRect.GetHeight(), PosSizeFlags::Size );
1236 pBorderWindow->ImplUpdateAll();
1237 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1238 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1239 maFrameData.maMouseOff.AdjustX(aNewRect.GetWidth()-nOldWidth );
1240 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1241 maFrameData.maMouseOff.AdjustY(aNewRect.GetHeight()-nOldHeight );
1243 else
1245 maFrameData.mnTrackX = aNewRect.Left();
1246 maFrameData.mnTrackY = aNewRect.Top();
1247 maFrameData.mnTrackWidth = aNewRect.GetWidth();
1248 maFrameData.mnTrackHeight = aNewRect.GetHeight();
1249 pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), ShowTrackFlags::Big );
1255 return true;
1258 OUString ImplStdBorderWindowView::RequestHelp( const Point& rPos, tools::Rectangle& rHelpRect )
1260 return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
1263 tools::Rectangle ImplStdBorderWindowView::GetMenuRect() const
1265 return maFrameData.maMenuRect;
1268 void ImplStdBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
1270 ImplBorderFrameData* pData = &maFrameData;
1271 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
1272 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
1273 DecorationView aDecoView( pDev );
1274 tools::Rectangle aRect( 0, 0, 10, 10 );
1275 tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, DrawFrameStyle::DoubleOut, DrawFrameFlags::NoDraw );
1277 pData->mpOutDev = pDev;
1278 pData->mnWidth = nWidth;
1279 pData->mnHeight = nHeight;
1281 pData->mnTitleType = pBorderWindow->mnTitleType;
1283 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) || (pData->mnTitleType == BorderWindowTitleType::NONE) )
1284 pData->mnBorderSize = 0;
1285 else if ( pData->mnTitleType == BorderWindowTitleType::Tearoff )
1286 pData->mnBorderSize = 0;
1287 else
1288 pData->mnBorderSize = StyleSettings::GetBorderSize();
1289 pData->mnLeftBorder = aCalcRect.Left();
1290 pData->mnTopBorder = aCalcRect.Top();
1291 pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
1292 pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
1293 pData->mnLeftBorder += pData->mnBorderSize;
1294 pData->mnTopBorder += pData->mnBorderSize;
1295 pData->mnRightBorder += pData->mnBorderSize;
1296 pData->mnBottomBorder += pData->mnBorderSize;
1297 pData->mnNoTitleTop = pData->mnTopBorder;
1299 ImplInitTitle(&maFrameData);
1300 if (pData->mnTitleHeight)
1302 // to improve symbol display force a minimum title height
1303 if (pData->mnTitleType != BorderWindowTitleType::Tearoff &&
1304 pData->mnTitleHeight < MIN_CAPTION_HEIGHT)
1305 pData->mnTitleHeight = MIN_CAPTION_HEIGHT;
1307 // set a proper background for drawing
1308 // highlighted buttons in the title
1309 pBorderWindow->SetBackground( rStyleSettings.GetFaceColor() );
1311 pData->maTitleRect.SetLeft( pData->mnLeftBorder );
1312 pData->maTitleRect.SetRight( nWidth-pData->mnRightBorder-1 );
1313 pData->maTitleRect.SetTop( pData->mnTopBorder );
1314 pData->maTitleRect.SetBottom( pData->maTitleRect.Top()+pData->mnTitleHeight-1 );
1316 if ( pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small) )
1318 long nRight = pData->maTitleRect.Right() - 3;
1319 long const nItemTop = pData->maTitleRect.Top() + 2;
1320 long const nItemBottom = pData->maTitleRect.Bottom() - 2;
1322 auto addSquareOnRight = [&nRight, nItemTop, nItemBottom](
1323 tools::Rectangle & rect, long gap)
1325 rect.SetTop( nItemTop );
1326 rect.SetBottom( nItemBottom );
1327 rect.SetRight( nRight );
1328 rect.SetLeft( rect.Right() - rect.GetHeight() + 1 );
1329 nRight -= rect.GetWidth() + gap;
1332 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1334 addSquareOnRight(pData->maCloseRect, 3);
1337 if ( pBorderWindow->mbMenuBtn )
1339 addSquareOnRight(pData->maMenuRect, 0);
1342 if ( pBorderWindow->mbDockBtn )
1344 addSquareOnRight(pData->maDockRect, 0);
1347 if ( pBorderWindow->mbHideBtn )
1349 addSquareOnRight(pData->maHideRect, 0);
1352 if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
1354 addSquareOnRight(pData->maRollRect, 0);
1357 else
1359 pData->maCloseRect.SetEmpty();
1360 pData->maDockRect.SetEmpty();
1361 pData->maMenuRect.SetEmpty();
1362 pData->maHideRect.SetEmpty();
1363 pData->maRollRect.SetEmpty();
1364 pData->maHelpRect.SetEmpty();
1367 pData->mnTopBorder += pData->mnTitleHeight;
1369 else
1371 pData->maTitleRect.SetEmpty();
1372 pData->maCloseRect.SetEmpty();
1373 pData->maDockRect.SetEmpty();
1374 pData->maMenuRect.SetEmpty();
1375 pData->maHideRect.SetEmpty();
1376 pData->maRollRect.SetEmpty();
1377 pData->maHelpRect.SetEmpty();
1381 void ImplStdBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1382 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1384 rLeftBorder = maFrameData.mnLeftBorder;
1385 rTopBorder = maFrameData.mnTopBorder;
1386 rRightBorder = maFrameData.mnRightBorder;
1387 rBottomBorder = maFrameData.mnBottomBorder;
1390 long ImplStdBorderWindowView::CalcTitleWidth() const
1392 return ImplCalcTitleWidth( &maFrameData );
1395 void ImplStdBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point* pOffset)
1397 ImplBorderFrameData* pData = &maFrameData;
1398 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
1399 Point aTmpPoint = pOffset ? *pOffset : Point();
1400 tools::Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
1401 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1402 DecorationView aDecoView(&rRenderContext);
1403 Color aFaceColor(rStyleSettings.GetFaceColor());
1404 Color aFrameColor(aFaceColor);
1406 aFrameColor.DecreaseContrast(sal_uInt8(0.5 * 255));
1408 // Draw Frame
1409 vcl::Region oldClipRgn(rRenderContext.GetClipRegion());
1411 // for popups, don't draw part of the frame
1412 if (!(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small)))
1414 FloatingWindow* pWin = dynamic_cast<FloatingWindow*>(pData->mpBorderWindow->GetWindow(GetWindowType::Client));
1415 if (pWin)
1417 vcl::Region aClipRgn(aInRect);
1418 tools::Rectangle aItemClipRect(pWin->ImplGetItemEdgeClipRect());
1419 if (!aItemClipRect.IsEmpty())
1421 aItemClipRect.SetPos(pData->mpBorderWindow->AbsoluteScreenToOutputPixel(aItemClipRect.TopLeft()));
1422 aClipRgn.Exclude(aItemClipRect);
1423 rRenderContext.SetClipRegion(aClipRgn);
1428 // single line frame
1429 rRenderContext.SetLineColor(aFrameColor);
1430 rRenderContext.SetFillColor();
1431 rRenderContext.DrawRect(aInRect);
1432 aInRect.AdjustLeft( 1 );
1433 aInRect.AdjustRight( -1 );
1434 aInRect.AdjustTop( 1 );
1435 aInRect.AdjustBottom( -1 );
1437 // restore
1438 if (!(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small)))
1439 rRenderContext.SetClipRegion(oldClipRgn);
1441 // Draw Border
1442 rRenderContext.SetLineColor();
1443 long nBorderSize = pData->mnBorderSize;
1444 if (nBorderSize)
1446 rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
1447 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top()),
1448 Size(aInRect.GetWidth(), nBorderSize)));
1449 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top() + nBorderSize),
1450 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1451 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Bottom() - nBorderSize + 1),
1452 Size(aInRect.GetWidth(), nBorderSize)));
1453 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Right()-nBorderSize + 1, aInRect.Top() + nBorderSize),
1454 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1457 // Draw Title
1458 if (!pData->maTitleRect.IsEmpty())
1460 aInRect = pData->maTitleRect;
1462 // use no gradient anymore, just a static titlecolor
1463 if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
1464 rRenderContext.SetFillColor(rStyleSettings.GetFaceGradientColor());
1465 else if (pData->mnTitleType == BorderWindowTitleType::Popup)
1466 rRenderContext.SetFillColor(aFaceColor);
1467 else
1468 rRenderContext.SetFillColor(aFrameColor);
1470 rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
1471 tools::Rectangle aTitleRect(pData->maTitleRect);
1472 if(pOffset)
1473 aTitleRect.Move(pOffset->X(), pOffset->Y());
1474 rRenderContext.DrawRect(aTitleRect);
1476 if (pData->mnTitleType != BorderWindowTitleType::Tearoff)
1478 aInRect.AdjustLeft(2 );
1479 aInRect.AdjustRight( -2 );
1481 if (!pData->maHelpRect.IsEmpty())
1482 aInRect.SetRight( pData->maHelpRect.Left() - 2 );
1483 else if (!pData->maRollRect.IsEmpty())
1484 aInRect.SetRight( pData->maRollRect.Left() - 2 );
1485 else if (!pData->maHideRect.IsEmpty())
1486 aInRect.SetRight( pData->maHideRect.Left() - 2 );
1487 else if (!pData->maDockRect.IsEmpty())
1488 aInRect.SetRight( pData->maDockRect.Left() - 2 );
1489 else if (!pData->maMenuRect.IsEmpty())
1490 aInRect.SetRight( pData->maMenuRect.Left() - 2 );
1491 else if (!pData->maCloseRect.IsEmpty())
1492 aInRect.SetRight( pData->maCloseRect.Left() - 2 );
1494 if (pOffset)
1495 aInRect.Move(pOffset->X(), pOffset->Y());
1497 DrawTextFlags nTextStyle = DrawTextFlags::Left | DrawTextFlags::VCenter | DrawTextFlags::EndEllipsis | DrawTextFlags::Clip;
1499 // must show tooltip ?
1500 TextRectInfo aInfo;
1501 rRenderContext.GetTextRect(aInRect, pBorderWindow->GetText(), nTextStyle, &aInfo);
1502 pData->mbTitleClipped = aInfo.IsEllipses();
1504 rRenderContext.DrawText(aInRect, pBorderWindow->GetText(), nTextStyle);
1506 else
1508 ToolBox::ImplDrawGrip(rRenderContext, aTitleRect, ToolBox::ImplGetDragWidth(rRenderContext, false),
1509 WindowAlign::Left, false);
1513 if (!pData->maCloseRect.IsEmpty())
1515 tools::Rectangle aSymbolRect(pData->maCloseRect);
1516 if (pOffset)
1517 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1518 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::CLOSE, pData->mnCloseState);
1520 if (!pData->maDockRect.IsEmpty())
1522 tools::Rectangle aSymbolRect(pData->maDockRect);
1523 if (pOffset)
1524 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1525 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::DOCK, pData->mnDockState);
1527 if (!pData->maMenuRect.IsEmpty())
1529 tools::Rectangle aSymbolRect(pData->maMenuRect);
1530 if (pOffset)
1531 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1532 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::MENU, pData->mnMenuState);
1534 if (!pData->maHideRect.IsEmpty())
1536 tools::Rectangle aSymbolRect(pData->maHideRect);
1537 if (pOffset)
1538 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1539 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HIDE, pData->mnHideState);
1541 if (!pData->maRollRect.IsEmpty())
1543 SymbolType eType;
1544 if (pBorderWindow->mbRollUp)
1545 eType = SymbolType::ROLLDOWN;
1546 else
1547 eType = SymbolType::ROLLUP;
1548 tools::Rectangle aSymbolRect(pData->maRollRect);
1549 if (pOffset)
1550 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1551 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, eType, pData->mnRollState);
1554 if (!pData->maHelpRect.IsEmpty())
1556 tools::Rectangle aSymbolRect(pData->maHelpRect);
1557 if (pOffset)
1558 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1559 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HELP, pData->mnHelpState);
1563 void ImplBorderWindow::ImplInit( vcl::Window* pParent,
1564 WinBits nStyle, BorderWindowStyle nTypeStyle,
1565 SystemParentData* pSystemParentData
1568 // remove all unwanted WindowBits
1569 WinBits nOrgStyle = nStyle;
1570 WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_POPUP);
1571 if ( nTypeStyle & BorderWindowStyle::App )
1572 nTestStyle |= WB_APP;
1573 nStyle &= nTestStyle;
1575 mpWindowImpl->mbBorderWin = true;
1576 mbSmallOutBorder = false;
1577 if ( nTypeStyle & BorderWindowStyle::Frame )
1579 if( nStyle & WB_SYSTEMCHILDWINDOW )
1581 mpWindowImpl->mbOverlapWin = true;
1582 mpWindowImpl->mbFrame = true;
1583 mbFrameBorder = false;
1585 else if( nStyle & (WB_OWNERDRAWDECORATION | WB_POPUP) )
1587 mpWindowImpl->mbOverlapWin = true;
1588 mpWindowImpl->mbFrame = true;
1589 mbFrameBorder = (nOrgStyle & WB_NOBORDER) == 0;
1591 else
1593 mpWindowImpl->mbOverlapWin = true;
1594 mpWindowImpl->mbFrame = true;
1595 mbFrameBorder = false;
1596 // closeable windows may have a border as well, eg. system floating windows without caption
1597 if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE/* | WB_CLOSEABLE*/)) == WB_BORDER )
1598 mbSmallOutBorder = true;
1601 else if ( nTypeStyle & BorderWindowStyle::Overlap )
1603 mpWindowImpl->mbOverlapWin = true;
1604 mbFrameBorder = true;
1606 else
1607 mbFrameBorder = false;
1609 if ( nTypeStyle & BorderWindowStyle::Float )
1610 mbFloatWindow = true;
1611 else
1612 mbFloatWindow = false;
1614 Window::ImplInit( pParent, nStyle, pSystemParentData );
1615 SetBackground();
1616 SetTextFillColor();
1618 mpMenuBarWindow = nullptr;
1619 mnMinWidth = 0;
1620 mnMinHeight = 0;
1621 mnMaxWidth = SHRT_MAX;
1622 mnMaxHeight = SHRT_MAX;
1623 mnOrgMenuHeight = 0;
1624 mbRollUp = false;
1625 mbMenuHide = false;
1626 mbDockBtn = false;
1627 mbMenuBtn = false;
1628 mbHideBtn = false;
1629 mbDisplayActive = IsActive();
1631 if ( nTypeStyle & BorderWindowStyle::Float )
1632 mnTitleType = BorderWindowTitleType::Small;
1633 else
1634 mnTitleType = BorderWindowTitleType::Normal;
1635 mnBorderStyle = WindowBorderStyle::NORMAL;
1636 InitView();
1639 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent,
1640 SystemParentData* pSystemParentData,
1641 WinBits nStyle, BorderWindowStyle nTypeStyle
1642 ) : Window( WindowType::BORDERWINDOW )
1644 ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
1647 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent, WinBits nStyle ,
1648 BorderWindowStyle nTypeStyle ) :
1649 Window( WindowType::BORDERWINDOW )
1651 ImplInit( pParent, nStyle, nTypeStyle, nullptr );
1654 ImplBorderWindow::~ImplBorderWindow()
1656 disposeOnce();
1659 void ImplBorderWindow::dispose()
1661 mpBorderView.reset();
1662 mpMenuBarWindow.clear();
1663 mpNotebookBar.disposeAndClear();
1664 vcl::Window::dispose();
1667 void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
1669 if (mpBorderView)
1670 mpBorderView->MouseMove( rMEvt );
1673 void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
1675 if (mpBorderView)
1676 mpBorderView->MouseButtonDown( rMEvt );
1679 void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
1681 if (mpBorderView)
1682 mpBorderView->Tracking( rTEvt );
1685 void ImplBorderWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
1687 if (mpBorderView)
1688 mpBorderView->DrawWindow(rRenderContext);
1691 void ImplBorderWindow::Draw( OutputDevice* pOutDev, const Point& rPos )
1693 if (mpBorderView)
1694 mpBorderView->DrawWindow(*pOutDev, &rPos);
1697 void ImplBorderWindow::Activate()
1699 SetDisplayActive( true );
1700 Window::Activate();
1703 void ImplBorderWindow::Deactivate()
1705 // remove active windows from the ruler, also ignore the Deactivate
1706 // if a menu becomes active
1707 if ( GetActivateMode() != ActivateModeFlags::NONE && !ImplGetSVData()->maWinData.mbNoDeactivate )
1708 SetDisplayActive( false );
1709 Window::Deactivate();
1712 void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
1714 // no keyboard help for border window
1715 if ( rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK) && !rHEvt.KeyboardActivated() )
1717 Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
1718 tools::Rectangle aHelpRect;
1719 OUString aHelpStr( mpBorderView->RequestHelp( aMousePosPixel, aHelpRect ) );
1721 // retrieve rectangle
1722 if ( !aHelpStr.isEmpty() )
1724 aHelpRect.SetPos( OutputToScreenPixel( aHelpRect.TopLeft() ) );
1725 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1726 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aHelpStr );
1727 else
1728 Help::ShowQuickHelp( this, aHelpRect, aHelpStr );
1729 return;
1733 Window::RequestHelp( rHEvt );
1736 void ImplBorderWindow::Resize()
1738 Size aSize = GetOutputSizePixel();
1740 if ( !mbRollUp )
1742 vcl::Window* pClientWindow = ImplGetClientWindow();
1744 sal_Int32 nLeftBorder;
1745 sal_Int32 nTopBorder;
1746 sal_Int32 nRightBorder;
1747 sal_Int32 nBottomBorder;
1748 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1750 if (mpMenuBarWindow)
1752 long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
1753 if ( mbMenuHide )
1755 if ( nMenuHeight )
1756 mnOrgMenuHeight = nMenuHeight;
1757 nMenuHeight = 0;
1759 else
1761 if ( !nMenuHeight )
1762 nMenuHeight = mnOrgMenuHeight;
1764 mpMenuBarWindow->setPosSizePixel(
1765 nLeftBorder, nTopBorder,
1766 aSize.Width()-nLeftBorder-nRightBorder,
1767 nMenuHeight);
1769 // shift the notebookbar down accordingly
1770 nTopBorder += nMenuHeight;
1773 if (mpNotebookBar)
1775 long nNotebookBarHeight = mpNotebookBar->GetSizePixel().Height();
1777 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1778 const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader();
1779 // since size of notebookbar changes, to make common persona for menubar
1780 // and notebookbar persona should be set again with changed coordinates
1781 if (!aPersona.IsEmpty())
1783 Wallpaper aWallpaper(aPersona);
1784 aWallpaper.SetStyle(WallpaperStyle::TopRight);
1785 aWallpaper.SetRect(tools::Rectangle(Point(0, -nTopBorder),
1786 Size(aSize.Width() - nLeftBorder - nRightBorder,
1787 nNotebookBarHeight + nTopBorder)));
1788 mpNotebookBar->SetBackground(aWallpaper);
1791 mpNotebookBar->setPosSizePixel(
1792 nLeftBorder, nTopBorder,
1793 aSize.Width() - nLeftBorder - nRightBorder,
1794 nNotebookBarHeight);
1797 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
1798 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
1799 pClientWindow->ImplPosSizeWindow( pClientWindow->mpWindowImpl->mnLeftBorder,
1800 pClientWindow->mpWindowImpl->mnTopBorder,
1801 aSize.Width()-pClientWindow->mpWindowImpl->mnLeftBorder-pClientWindow->mpWindowImpl->mnRightBorder,
1802 aSize.Height()-pClientWindow->mpWindowImpl->mnTopBorder-pClientWindow->mpWindowImpl->mnBottomBorder,
1803 PosSizeFlags::X | PosSizeFlags::Y |
1804 PosSizeFlags::Width | PosSizeFlags::Height );
1807 // UpdateView
1808 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1809 InvalidateBorder();
1811 Window::Resize();
1814 void ImplBorderWindow::StateChanged( StateChangedType nType )
1816 if ( (nType == StateChangedType::Text) ||
1817 (nType == StateChangedType::Data) )
1819 if (IsReallyVisible() && mbFrameBorder)
1820 InvalidateBorder();
1823 Window::StateChanged( nType );
1826 void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
1828 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1829 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1830 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1831 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1833 if ( !mpWindowImpl->mbFrame || (GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP)) )
1834 UpdateView( true, ImplGetWindow()->GetOutputSizePixel() );
1837 Window::DataChanged( rDCEvt );
1840 void ImplBorderWindow::InitView()
1842 if ( mbSmallOutBorder )
1843 mpBorderView.reset(new ImplSmallBorderWindowView( this ));
1844 else if ( mpWindowImpl->mbFrame )
1846 if( mbFrameBorder )
1847 mpBorderView.reset(new ImplStdBorderWindowView( this ));
1848 else
1849 mpBorderView.reset(new ImplNoBorderWindowView);
1851 else if ( !mbFrameBorder )
1852 mpBorderView.reset(new ImplSmallBorderWindowView( this ));
1853 else
1854 mpBorderView.reset(new ImplStdBorderWindowView( this ));
1855 Size aSize = GetOutputSizePixel();
1856 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1859 void ImplBorderWindow::UpdateView( bool bNewView, const Size& rNewOutSize )
1861 sal_Int32 nLeftBorder;
1862 sal_Int32 nTopBorder;
1863 sal_Int32 nRightBorder;
1864 sal_Int32 nBottomBorder;
1865 Size aOldSize = GetSizePixel();
1866 Size aOutputSize = rNewOutSize;
1868 if ( bNewView )
1870 mpBorderView.reset();
1871 InitView();
1873 else
1875 Size aSize = aOutputSize;
1876 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1877 aSize.AdjustWidth(nLeftBorder+nRightBorder );
1878 aSize.AdjustHeight(nTopBorder+nBottomBorder );
1879 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1882 vcl::Window* pClientWindow = ImplGetClientWindow();
1883 if ( pClientWindow )
1885 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
1886 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
1888 GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1889 if ( aOldSize.Width() || aOldSize.Height() )
1891 aOutputSize.AdjustWidth(nLeftBorder+nRightBorder );
1892 aOutputSize.AdjustHeight(nTopBorder+nBottomBorder );
1893 if ( aOutputSize == GetSizePixel() )
1894 InvalidateBorder();
1895 else
1896 SetSizePixel( aOutputSize );
1900 void ImplBorderWindow::InvalidateBorder()
1902 if ( IsReallyVisible() )
1904 // invalidate only if we have a border
1905 sal_Int32 nLeftBorder;
1906 sal_Int32 nTopBorder;
1907 sal_Int32 nRightBorder;
1908 sal_Int32 nBottomBorder;
1909 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1910 if ( nLeftBorder || nTopBorder || nRightBorder || nBottomBorder )
1912 tools::Rectangle aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
1913 vcl::Region aRegion( aWinRect );
1914 aWinRect.AdjustLeft(nLeftBorder );
1915 aWinRect.AdjustTop(nTopBorder );
1916 aWinRect.AdjustRight( -nRightBorder );
1917 aWinRect.AdjustBottom( -nBottomBorder );
1918 // no output area anymore, now invalidate all
1919 if ( (aWinRect.Right() < aWinRect.Left()) ||
1920 (aWinRect.Bottom() < aWinRect.Top()) )
1921 Invalidate( InvalidateFlags::NoChildren );
1922 else
1924 aRegion.Exclude( aWinRect );
1925 Invalidate( aRegion, InvalidateFlags::NoChildren );
1931 void ImplBorderWindow::SetDisplayActive( bool bActive )
1933 if ( mbDisplayActive != bActive )
1935 mbDisplayActive = bActive;
1936 if ( mbFrameBorder )
1937 InvalidateBorder();
1941 void ImplBorderWindow::SetTitleType( BorderWindowTitleType nTitleType, const Size& rSize )
1943 mnTitleType = nTitleType;
1944 UpdateView( false, rSize );
1947 void ImplBorderWindow::SetBorderStyle( WindowBorderStyle nStyle )
1949 if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
1951 mnBorderStyle = nStyle;
1952 UpdateView( false, ImplGetWindow()->GetOutputSizePixel() );
1956 void ImplBorderWindow::SetRollUp( bool bRollUp, const Size& rSize )
1958 mbRollUp = bRollUp;
1959 UpdateView( false, rSize );
1962 void ImplBorderWindow::SetCloseButton()
1964 SetStyle( GetStyle() | WB_CLOSEABLE );
1965 Size aSize = GetOutputSizePixel();
1966 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1967 InvalidateBorder();
1970 void ImplBorderWindow::SetDockButton( bool bDockButton )
1972 mbDockBtn = bDockButton;
1973 Size aSize = GetOutputSizePixel();
1974 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1975 InvalidateBorder();
1978 void ImplBorderWindow::SetHideButton( bool bHideButton )
1980 mbHideBtn = bHideButton;
1981 Size aSize = GetOutputSizePixel();
1982 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1983 InvalidateBorder();
1986 void ImplBorderWindow::SetMenuButton( bool bMenuButton )
1988 mbMenuBtn = bMenuButton;
1989 Size aSize = GetOutputSizePixel();
1990 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1991 InvalidateBorder();
1994 void ImplBorderWindow::UpdateMenuHeight()
1996 Resize();
1999 void ImplBorderWindow::SetMenuBarWindow( vcl::Window* pWindow )
2001 mpMenuBarWindow = pWindow;
2002 UpdateMenuHeight();
2003 if ( pWindow )
2004 pWindow->Show();
2007 void ImplBorderWindow::SetMenuBarMode( bool bHide )
2009 mbMenuHide = bHide;
2010 UpdateMenuHeight();
2013 void ImplBorderWindow::SetNotebookBar(const OUString& rUIXMLDescription,
2014 const css::uno::Reference<css::frame::XFrame>& rFrame,
2015 const NotebookBarAddonsItem& aNotebookBarAddonsItem)
2017 if (mpNotebookBar)
2018 mpNotebookBar.disposeAndClear();
2019 mpNotebookBar = VclPtr<NotebookBar>::Create(this, "NotebookBar", rUIXMLDescription, rFrame,
2020 aNotebookBarAddonsItem);
2021 Resize();
2024 void ImplBorderWindow::CloseNotebookBar()
2026 if (mpNotebookBar)
2027 mpNotebookBar.disposeAndClear();
2028 mpNotebookBar = nullptr;
2029 Resize();
2032 void ImplBorderWindow::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2033 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2035 mpBorderView->GetBorder(rLeftBorder, rTopBorder, rRightBorder, rBottomBorder);
2037 if (mpMenuBarWindow && !mbMenuHide)
2038 rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
2040 if (mpNotebookBar && mpNotebookBar->IsVisible())
2041 rTopBorder += mpNotebookBar->GetSizePixel().Height();
2044 long ImplBorderWindow::CalcTitleWidth() const
2046 return mpBorderView->CalcTitleWidth();
2049 tools::Rectangle ImplBorderWindow::GetMenuRect() const
2051 return mpBorderView->GetMenuRect();
2054 Size ImplBorderWindow::GetOptimalSize() const
2056 const vcl::Window* pClientWindow = ImplGetClientWindow();
2057 if (pClientWindow)
2058 return pClientWindow->GetOptimalSize();
2059 return Size(mnMinWidth, mnMinHeight);
2062 void ImplBorderWindow::queue_resize(StateChangedType eReason)
2064 //if we are floating, then we don't want to inform our parent that it needs
2065 //to calculate a new layout allocation. Because while we are a child
2066 //of our parent we are not embedded into the parent so it doesn't care
2067 //about us.
2068 if (mbFloatWindow)
2069 return;
2070 vcl::Window::queue_resize(eReason);
2073 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */