tdf#161341 show/hide controls/shapes/pictures in view/print
[LibreOffice.git] / vcl / source / window / brdwin.cxx
blob4946df1ea5492152fb4b60dcfd610b597076b015
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 <salframe.hxx>
24 #include <window.h>
26 #include <vcl/textrectinfo.hxx>
27 #include <vcl/event.hxx>
28 #include <vcl/decoview.hxx>
29 #include <vcl/syswin.hxx>
30 #include <vcl/dockwin.hxx>
31 #include <vcl/toolkit/floatwin.hxx>
32 #include <vcl/help.hxx>
33 #include <vcl/toolkit/edit.hxx>
34 #include <vcl/settings.hxx>
35 #include <vcl/toolbox.hxx>
36 #include <vcl/ptrstyle.hxx>
38 using namespace ::com::sun::star::uno;
40 // useful caption height for title bar buttons
41 #define MIN_CAPTION_HEIGHT 18
43 namespace vcl {
45 void Window::ImplCalcSymbolRect( tools::Rectangle& rRect )
47 // Add border, not shown in the non-default representation,
48 // as we want to use it for small buttons
49 rRect.AdjustLeft( -1 );
50 rRect.AdjustTop( -1 );
51 rRect.AdjustRight( 1 );
52 rRect.AdjustBottom( 1 );
54 // we leave 5% room between the symbol and the button border
55 tools::Long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
56 tools::Long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
57 rRect.AdjustLeft(nExtraWidth );
58 rRect.AdjustRight( -nExtraWidth );
59 rRect.AdjustTop(nExtraHeight );
60 rRect.AdjustBottom( -nExtraHeight );
63 } /* namespace vcl */
65 static void ImplDrawBrdWinSymbol( vcl::RenderContext* pDev,
66 const tools::Rectangle& rRect, SymbolType eSymbol )
68 // we leave 5% room between the symbol and the button border
69 DecorationView aDecoView( pDev );
70 tools::Rectangle aTempRect = rRect;
71 vcl::Window::ImplCalcSymbolRect( aTempRect );
72 aDecoView.DrawSymbol( aTempRect, eSymbol,
73 pDev->GetSettings().GetStyleSettings().GetButtonTextColor() );
76 static void ImplDrawBrdWinSymbolButton( vcl::RenderContext* pDev,
77 const tools::Rectangle& rRect,
78 SymbolType eSymbol, DrawButtonFlags nState )
80 bool bMouseOver(nState & DrawButtonFlags::Highlight);
81 nState &= ~DrawButtonFlags::Highlight;
83 tools::Rectangle aTempRect;
84 vcl::Window *pWin = pDev->GetOwnerWindow();
85 if( pWin )
87 if( bMouseOver )
89 // provide a bright background for selection effect
90 pDev->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() );
91 pDev->SetLineColor();
92 pDev->DrawRect( rRect );
93 pWin->DrawSelectionBackground( rRect, 2, bool(nState & DrawButtonFlags::Pressed),
94 true );
96 aTempRect = rRect;
97 aTempRect.AdjustLeft(3 );
98 aTempRect.AdjustRight( -4 );
99 aTempRect.AdjustTop(3 );
100 aTempRect.AdjustBottom( -4 );
102 else
104 DecorationView aDecoView( pDev );
105 aTempRect = aDecoView.DrawButton( rRect, nState|DrawButtonFlags::Flat );
107 ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
111 ImplBorderWindowView::~ImplBorderWindowView()
115 bool ImplBorderWindowView::MouseMove( const MouseEvent& )
117 return false;
120 bool ImplBorderWindowView::MouseButtonDown( const MouseEvent& )
122 return false;
125 bool ImplBorderWindowView::Tracking( const TrackingEvent& )
127 return false;
130 OUString ImplBorderWindowView::RequestHelp( const Point&, tools::Rectangle& )
132 return OUString();
135 tools::Rectangle ImplBorderWindowView::GetMenuRect() const
137 return tools::Rectangle();
140 void ImplBorderWindowView::ImplInitTitle(ImplBorderFrameData* pData)
142 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
144 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) ||
145 (pData->mnTitleType == BorderWindowTitleType::NONE) )
147 pData->mnTitleType = BorderWindowTitleType::NONE;
148 pData->mnTitleHeight = 0;
150 else
152 const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
153 if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
154 pData->mnTitleHeight = ToolBox::ImplGetDragWidth(*pData->mpBorderWindow, false) + 2;
155 else
157 if (pData->mnTitleType == BorderWindowTitleType::Small)
159 pBorderWindow->SetPointFont(*pBorderWindow->GetOutDev(), rStyleSettings.GetFloatTitleFont() );
160 pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
162 else // pData->mnTitleType == BorderWindowTitleType::Normal
164 // FIXME RenderContext
165 pBorderWindow->SetPointFont(*pBorderWindow->GetOutDev(), rStyleSettings.GetTitleFont());
166 pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
168 tools::Long nTextHeight = pBorderWindow->GetTextHeight();
169 if (nTextHeight > pData->mnTitleHeight)
170 pData->mnTitleHeight = nTextHeight;
175 BorderWindowHitTest ImplBorderWindowView::ImplHitTest( ImplBorderFrameData const * pData, const Point& rPos )
177 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
179 if ( pData->maTitleRect.Contains( rPos ) )
181 if ( pData->maCloseRect.Contains( rPos ) )
182 return BorderWindowHitTest::Close;
183 else if ( pData->maMenuRect.Contains( rPos ) )
184 return BorderWindowHitTest::Menu;
185 else if ( pData->maDockRect.Contains( rPos ) )
186 return BorderWindowHitTest::Dock;
187 else if ( pData->maHideRect.Contains( rPos ) )
188 return BorderWindowHitTest::Hide;
189 else if ( pData->maHelpRect.Contains( rPos ) )
190 return BorderWindowHitTest::Help;
191 else
192 return BorderWindowHitTest::Title;
195 if (pBorderWindow->GetStyle() & WB_SIZEABLE)
197 tools::Long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
198 if ( nSizeWidth < 16 )
199 nSizeWidth = 16;
201 // no corner resize for floating toolbars, which would lead to jumps while formatting
202 // setting nSizeWidth = 0 will only return pure left,top,right,bottom
203 if( pBorderWindow->GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP) )
204 nSizeWidth = 0;
206 if ( rPos.X() < pData->mnLeftBorder )
208 if ( rPos.Y() < nSizeWidth )
209 return BorderWindowHitTest::TopLeft;
210 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
211 return BorderWindowHitTest::BottomLeft;
212 else
213 return BorderWindowHitTest::Left;
215 else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
217 if ( rPos.Y() < nSizeWidth )
218 return BorderWindowHitTest::TopRight;
219 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
220 return BorderWindowHitTest::BottomRight;
221 else
222 return BorderWindowHitTest::Right;
224 else if ( rPos.Y() < pData->mnNoTitleTop )
226 if ( rPos.X() < nSizeWidth )
227 return BorderWindowHitTest::TopLeft;
228 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
229 return BorderWindowHitTest::TopRight;
230 else
231 return BorderWindowHitTest::Top;
233 else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
235 if ( rPos.X() < nSizeWidth )
236 return BorderWindowHitTest::BottomLeft;
237 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
238 return BorderWindowHitTest::BottomRight;
239 else
240 return BorderWindowHitTest::Bottom;
244 return BorderWindowHitTest::NONE;
247 void ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
249 DrawButtonFlags oldCloseState = pData->mnCloseState;
250 DrawButtonFlags oldMenuState = pData->mnMenuState;
251 pData->mnCloseState &= ~DrawButtonFlags::Highlight;
252 pData->mnMenuState &= ~DrawButtonFlags::Highlight;
254 Point aMousePos = rMEvt.GetPosPixel();
255 BorderWindowHitTest nHitTest = ImplHitTest( pData, aMousePos );
256 PointerStyle ePtrStyle = PointerStyle::Arrow;
257 if ( nHitTest & BorderWindowHitTest::Left )
258 ePtrStyle = PointerStyle::WindowWSize;
259 else if ( nHitTest & BorderWindowHitTest::Right )
260 ePtrStyle = PointerStyle::WindowESize;
261 else if ( nHitTest & BorderWindowHitTest::Top )
262 ePtrStyle = PointerStyle::WindowNSize;
263 else if ( nHitTest & BorderWindowHitTest::Bottom )
264 ePtrStyle = PointerStyle::WindowSSize;
265 else if ( nHitTest & BorderWindowHitTest::TopLeft )
266 ePtrStyle = PointerStyle::WindowNWSize;
267 else if ( nHitTest & BorderWindowHitTest::BottomRight )
268 ePtrStyle = PointerStyle::WindowSESize;
269 else if ( nHitTest & BorderWindowHitTest::TopRight )
270 ePtrStyle = PointerStyle::WindowNESize;
271 else if ( nHitTest & BorderWindowHitTest::BottomLeft )
272 ePtrStyle = PointerStyle::WindowSWSize;
273 else if ( nHitTest & BorderWindowHitTest::Close )
274 pData->mnCloseState |= DrawButtonFlags::Highlight;
275 else if ( nHitTest & BorderWindowHitTest::Menu )
276 pData->mnMenuState |= DrawButtonFlags::Highlight;
277 else if ( nHitTest & BorderWindowHitTest::Title &&
278 pData->mnTitleType == BorderWindowTitleType::Tearoff && !rMEvt.IsLeaveWindow() )
279 ePtrStyle = PointerStyle::Move;
280 pData->mpBorderWindow->SetPointer( ePtrStyle );
282 if( pData->mnCloseState != oldCloseState )
283 pData->mpBorderWindow->Invalidate( pData->maCloseRect );
284 if( pData->mnMenuState != oldMenuState )
285 pData->mpBorderWindow->Invalidate( pData->maMenuRect );
288 OUString ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData const * pData,
289 const Point& rPos,
290 tools::Rectangle& rHelpRect )
292 TranslateId pHelpId;
293 OUString aHelpStr;
294 BorderWindowHitTest nHitTest = ImplHitTest( pData, rPos );
295 if ( nHitTest != BorderWindowHitTest::NONE )
297 if ( nHitTest & BorderWindowHitTest::Close )
299 pHelpId = SV_HELPTEXT_CLOSE;
300 rHelpRect = pData->maCloseRect;
302 else if ( nHitTest & BorderWindowHitTest::Dock )
304 pHelpId = SV_HELPTEXT_MAXIMIZE;
305 rHelpRect = pData->maDockRect;
307 else if ( nHitTest & BorderWindowHitTest::Hide )
309 pHelpId = SV_HELPTEXT_MINIMIZE;
310 rHelpRect = pData->maHideRect;
312 else if ( nHitTest & BorderWindowHitTest::Help )
314 pHelpId = SV_HELPTEXT_HELP;
315 rHelpRect = pData->maHelpRect;
317 else if ( nHitTest & BorderWindowHitTest::Title )
319 if( !pData->maTitleRect.IsEmpty() )
321 // tooltip only if title truncated
322 if( pData->mbTitleClipped )
324 rHelpRect = pData->maTitleRect;
325 // no help id, use window title as help string
326 aHelpStr = pData->mpBorderWindow->GetText();
332 if (pHelpId)
333 aHelpStr = VclResId(pHelpId);
335 return aHelpStr;
338 tools::Long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData )
340 // title is not visible therefore no width
341 if ( !pData->mnTitleHeight )
342 return 0;
344 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
345 tools::Long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
346 auto nCloseRectWidth = pData->maCloseRect.GetWidth();
347 assert(nCloseRectWidth >= 0 && "coverity 2023.12.2");
348 nTitleWidth += nCloseRectWidth;
349 auto nDockRectWidth = pData->maDockRect.GetWidth();
350 assert(nDockRectWidth >= 0 && "coverity 2023.12.2");
351 nTitleWidth += nDockRectWidth;
352 auto nMenuRectWidth = pData->maMenuRect.GetWidth();
353 assert(nMenuRectWidth >= 0 && "coverity 2023.12.2");
354 nTitleWidth += nMenuRectWidth;
355 auto nHideRectWidth = pData->maHideRect.GetWidth();
356 assert(nHideRectWidth >= 0 && "coverity 2023.12.2");
357 nTitleWidth += nHideRectWidth;
358 auto nHelpRectWidth = pData->maHelpRect.GetWidth();
359 assert(nHelpRectWidth >= 0 && "coverity 2023.12.2");
360 nTitleWidth += nHelpRectWidth;
361 nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
362 return nTitleWidth;
366 ImplNoBorderWindowView::ImplNoBorderWindowView()
370 void ImplNoBorderWindowView::Init( OutputDevice*, tools::Long, tools::Long )
374 void ImplNoBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
375 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
377 rLeftBorder = 0;
378 rTopBorder = 0;
379 rRightBorder = 0;
380 rBottomBorder = 0;
383 tools::Long ImplNoBorderWindowView::CalcTitleWidth() const
385 return 0;
388 void ImplNoBorderWindowView::DrawWindow(vcl::RenderContext&, const Point*)
392 ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
393 : mpBorderWindow(pBorderWindow)
394 , mpOutDev(nullptr)
395 , mnWidth(0)
396 , mnHeight(0)
397 , mnLeftBorder(0)
398 , mnTopBorder(0)
399 , mnRightBorder(0)
400 , mnBottomBorder(0)
401 , mbNWFBorder(false)
405 void ImplSmallBorderWindowView::Init( OutputDevice* pDev, tools::Long nWidth, tools::Long nHeight )
407 mpOutDev = pDev;
408 mnWidth = nWidth;
409 mnHeight = nHeight;
410 mbNWFBorder = false;
412 vcl::Window *pWin = mpOutDev->GetOwnerWindow();
413 vcl::Window *pCtrl = nullptr;
414 vcl::Window *pSubEdit = nullptr;
415 if (pWin)
416 pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
418 tools::Long nOrigLeftBorder = mnLeftBorder;
419 tools::Long nOrigTopBorder = mnTopBorder;
420 tools::Long nOrigRightBorder = mnRightBorder;
421 tools::Long nOrigBottomBorder = mnBottomBorder;
423 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
424 if ( nBorderStyle & WindowBorderStyle::NOBORDER )
426 mnLeftBorder = 0;
427 mnTopBorder = 0;
428 mnRightBorder = 0;
429 mnBottomBorder = 0;
431 else
433 // FIXME: this is currently only on macOS, check with other
434 // platforms
435 if( ImplGetSVData()->maNWFData.mbNoFocusRects && !( nBorderStyle & WindowBorderStyle::NWF ) )
437 // for native widget drawing we must find out what
438 // control this border belongs to
439 ControlType aCtrlType = ControlType::Generic;
440 ControlPart aCtrlPart = ControlPart::Entire;
441 if (pCtrl && !(pCtrl->GetBorderStyle() & WindowBorderStyle::NONATIVEBORDER))
443 switch( pCtrl->GetType() )
445 case WindowType::LISTBOX:
446 if( pCtrl->GetStyle() & WB_DROPDOWN )
448 aCtrlType = ControlType::Listbox;
449 mbNWFBorder = true;
450 pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
452 break;
453 case WindowType::LISTBOXWINDOW:
454 aCtrlType = ControlType::Listbox;
455 aCtrlPart = ControlPart::ListboxWindow;
456 mbNWFBorder = true;
457 break;
458 case WindowType::COMBOBOX:
459 if( pCtrl->GetStyle() & WB_DROPDOWN )
461 aCtrlType = ControlType::Combobox;
462 mbNWFBorder = true;
463 pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
465 break;
466 case WindowType::MULTILINEEDIT:
467 aCtrlType = ControlType::MultilineEditbox;
468 mbNWFBorder = true;
469 break;
470 case WindowType::EDIT:
471 case WindowType::PATTERNFIELD:
472 case WindowType::METRICFIELD:
473 case WindowType::CURRENCYFIELD:
474 case WindowType::DATEFIELD:
475 case WindowType::TIMEFIELD:
476 case WindowType::SPINFIELD:
477 case WindowType::FORMATTEDFIELD:
478 mbNWFBorder = true;
479 if (pCtrl->GetStyle() & WB_SPIN)
480 aCtrlType = ControlType::Spinbox;
481 else
482 aCtrlType = ControlType::Editbox;
483 pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
484 break;
485 default:
486 break;
489 if( mbNWFBorder )
491 ImplControlValue aControlValue;
492 Size aMinSize( mnWidth, mnHeight );
493 if( aMinSize.Width() < 10 ) aMinSize.setWidth( 10 );
494 if( aMinSize.Height() < 10 ) aMinSize.setHeight( 10 );
495 tools::Rectangle aCtrlRegion( Point(), aMinSize );
496 tools::Rectangle aBounds, aContent;
497 if( pWin->GetNativeControlRegion( aCtrlType, aCtrlPart, aCtrlRegion,
498 ControlState::ENABLED, aControlValue,
499 aBounds, aContent ) )
501 aBounds.AdjustLeft(mnLeftBorder);
502 aBounds.AdjustRight(-mnRightBorder);
503 aBounds.AdjustTop(mnTopBorder);
504 aBounds.AdjustBottom(-mnBottomBorder);
505 aContent.AdjustLeft(mnLeftBorder);
506 aContent.AdjustRight(-mnRightBorder);
507 aContent.AdjustTop(mnTopBorder);
508 aContent.AdjustBottom(-mnBottomBorder);
509 mnLeftBorder = aContent.Left() - aBounds.Left();
510 mnRightBorder = aBounds.Right() - aContent.Right();
511 mnTopBorder = aContent.Top() - aBounds.Top();
512 mnBottomBorder = aBounds.Bottom() - aContent.Bottom();
513 if( mnWidth && mnHeight )
516 mpBorderWindow->SetPaintTransparent( true );
517 mpBorderWindow->SetBackground();
518 if (!pCtrl->IsControlBackground())
520 pCtrl->SetPaintTransparent(true);
521 if (pSubEdit)
522 pSubEdit->SetPaintTransparent(true);
525 vcl::Window* pCompoundParent = nullptr;
526 if( pWin->GetParent() && pWin->GetParent()->IsCompoundControl() )
527 pCompoundParent = pWin->GetParent();
529 if( pCompoundParent )
530 pCompoundParent->SetPaintTransparent( true );
532 if( mnWidth < aBounds.GetWidth() || mnHeight < aBounds.GetHeight() )
534 if( ! pCompoundParent ) // compound controls have to fix themselves
536 Point aPos( mpBorderWindow->GetPosPixel() );
537 if( mnWidth < aBounds.GetWidth() )
538 aPos.AdjustX( -((aBounds.GetWidth() - mnWidth) / 2) );
539 if( mnHeight < aBounds.GetHeight() )
540 aPos.AdjustY( -((aBounds.GetHeight() - mnHeight) / 2) );
541 mpBorderWindow->SetPosSizePixel( aPos, aBounds.GetSize() );
546 else
547 mbNWFBorder = false;
551 if( ! mbNWFBorder )
553 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
554 DrawFrameFlags nFlags = DrawFrameFlags::NoDraw;
555 // move border outside if border was converted or if the BorderWindow is a frame window,
556 if ( mpBorderWindow->mbSmallOutBorder )
557 nStyle = DrawFrameStyle::DoubleOut;
558 else if ( nBorderStyle & WindowBorderStyle::NWF )
559 nStyle = DrawFrameStyle::NWF;
560 else
561 nStyle = DrawFrameStyle::DoubleIn;
562 if ( nBorderStyle & WindowBorderStyle::MONO )
563 nFlags |= DrawFrameFlags::Mono;
565 DecorationView aDecoView( mpOutDev );
566 tools::Rectangle aRect( 0, 0, 10, 10 );
567 tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, nStyle, nFlags );
568 mnLeftBorder = aCalcRect.Left();
569 mnTopBorder = aCalcRect.Top();
570 mnRightBorder = aRect.Right()-aCalcRect.Right();
571 mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
575 if (pCtrl)
577 //fdo#57090 If the borders have changed, then trigger a queue_resize on
578 //the bordered window, which will resync its borders at that point
579 if (nOrigLeftBorder != mnLeftBorder ||
580 nOrigTopBorder != mnTopBorder ||
581 nOrigRightBorder != mnRightBorder ||
582 nOrigBottomBorder != mnBottomBorder)
584 pCtrl->queue_resize();
589 void ImplSmallBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
590 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
592 rLeftBorder = mnLeftBorder;
593 rTopBorder = mnTopBorder;
594 rRightBorder = mnRightBorder;
595 rBottomBorder = mnBottomBorder;
598 tools::Long ImplSmallBorderWindowView::CalcTitleWidth() const
600 return 0;
603 void ImplSmallBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point*)
605 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
606 if (nBorderStyle & WindowBorderStyle::NOBORDER)
607 return;
609 bool bNativeOK = false;
610 // for native widget drawing we must find out what
611 // control this border belongs to
612 vcl::Window* pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
614 ControlType aCtrlType = ControlType::Generic;
615 ControlPart aCtrlPart = ControlPart::Entire;
616 if (pCtrl)
618 switch (pCtrl->GetType())
620 case WindowType::MULTILINEEDIT:
621 aCtrlType = ControlType::MultilineEditbox;
622 break;
623 case WindowType::EDIT:
624 case WindowType::PATTERNFIELD:
625 case WindowType::METRICFIELD:
626 case WindowType::CURRENCYFIELD:
627 case WindowType::DATEFIELD:
628 case WindowType::TIMEFIELD:
629 case WindowType::SPINFIELD:
630 case WindowType::FORMATTEDFIELD:
631 if (pCtrl->GetStyle() & WB_SPIN)
632 aCtrlType = ControlType::Spinbox;
633 else
634 aCtrlType = ControlType::Editbox;
635 break;
637 case WindowType::LISTBOX:
638 case WindowType::MULTILISTBOX:
639 case WindowType::TREELISTBOX:
640 aCtrlType = ControlType::Listbox;
641 if (pCtrl->GetStyle() & WB_DROPDOWN)
642 aCtrlPart = ControlPart::Entire;
643 else
644 aCtrlPart = ControlPart::ListboxWindow;
645 break;
647 case WindowType::LISTBOXWINDOW:
648 aCtrlType = ControlType::Listbox;
649 aCtrlPart = ControlPart::ListboxWindow;
650 break;
652 case WindowType::COMBOBOX:
653 case WindowType::PATTERNBOX:
654 case WindowType::NUMERICBOX:
655 case WindowType::METRICBOX:
656 case WindowType::CURRENCYBOX:
657 case WindowType::DATEBOX:
658 case WindowType::TIMEBOX:
659 case WindowType::LONGCURRENCYBOX:
660 if (pCtrl->GetStyle() & WB_DROPDOWN)
662 aCtrlType = ControlType::Combobox;
663 aCtrlPart = ControlPart::Entire;
665 else
667 aCtrlType = ControlType::Listbox;
668 aCtrlPart = ControlPart::ListboxWindow;
670 break;
672 default:
673 break;
677 if (aCtrlType != ControlType::Generic && pCtrl->IsNativeControlSupported(aCtrlType, aCtrlPart))
679 ImplControlValue aControlValue;
680 ControlState nState = ControlState::ENABLED;
682 if (!mpBorderWindow->IsEnabled())
683 nState &= ~ControlState::ENABLED;
684 if (mpBorderWindow->HasFocus() || pCtrl->HasFocus() || pCtrl->HasChildPathFocus())
685 nState |= ControlState::FOCUSED;
687 bool bMouseOver = pCtrl->IsMouseOver();
688 if (!bMouseOver)
690 vcl::Window *pCtrlChild = pCtrl->GetWindow(GetWindowType::FirstChild);
691 while(pCtrlChild)
693 bMouseOver = pCtrlChild->IsMouseOver();
694 if (bMouseOver)
695 break;
696 pCtrlChild = pCtrlChild->GetWindow(GetWindowType::Next);
700 if (bMouseOver)
701 nState |= ControlState::ROLLOVER;
703 Point aPoint;
704 tools::Rectangle aCtrlRegion(aPoint, Size(mnWidth, mnHeight));
706 tools::Rectangle aBoundingRgn(aPoint, Size(mnWidth, mnHeight));
707 tools::Rectangle aContentRgn(aCtrlRegion);
708 if (!ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize &&
709 rRenderContext.GetNativeControlRegion(aCtrlType, aCtrlPart, aCtrlRegion,
710 nState, aControlValue,
711 aBoundingRgn, aContentRgn))
713 aCtrlRegion=aContentRgn;
716 Color aBackgroundColor = COL_AUTO;
717 if (pCtrl->IsControlBackground())
718 aBackgroundColor = pCtrl->GetBackgroundColor();
719 bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, aCtrlPart, aCtrlRegion, nState, aControlValue, OUString(), aBackgroundColor);
721 // if the native theme draws the spinbuttons in one call, make sure the proper settings
722 // are passed, this might force a redraw though... (TODO: improve)
723 if ((aCtrlType == ControlType::Spinbox) && !pCtrl->IsNativeControlSupported(ControlType::Spinbox, ControlPart::ButtonUp))
725 Edit* pEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
726 if (pEdit && !pEdit->SupportsDoubleBuffering())
727 pCtrl->Paint(*pCtrl->GetOutDev(), tools::Rectangle()); // make sure the buttons are also drawn as they might overwrite the border
731 if (bNativeOK)
732 return;
734 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
735 DrawFrameFlags nFlags = DrawFrameFlags::NONE;
736 // move border outside if border was converted or if the border window is a frame window,
737 if (mpBorderWindow->mbSmallOutBorder)
738 nStyle = DrawFrameStyle::DoubleOut;
739 else if (nBorderStyle & WindowBorderStyle::NWF)
740 nStyle = DrawFrameStyle::NWF;
741 else
742 nStyle = DrawFrameStyle::DoubleIn;
743 if (nBorderStyle & WindowBorderStyle::MONO)
744 nFlags |= DrawFrameFlags::Mono;
745 if (nBorderStyle & WindowBorderStyle::MENU)
746 nFlags |= DrawFrameFlags::Menu;
747 // tell DrawFrame that we're drawing a window border of a frame window to avoid round corners
748 if (mpBorderWindow == mpBorderWindow->ImplGetFrameWindow())
749 nFlags |= DrawFrameFlags::WindowBorder;
751 DecorationView aDecoView(&rRenderContext);
752 tools::Rectangle aInRect(Point(), Size(mnWidth, mnHeight));
753 aDecoView.DrawFrame(aInRect, nStyle, nFlags);
757 ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
759 maFrameData.mpBorderWindow = pBorderWindow;
760 maFrameData.mbDragFull = false;
761 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
762 maFrameData.mnCloseState = DrawButtonFlags::NONE;
763 maFrameData.mnDockState = DrawButtonFlags::NONE;
764 maFrameData.mnMenuState = DrawButtonFlags::NONE;
765 maFrameData.mnHideState = DrawButtonFlags::NONE;
766 maFrameData.mnHelpState = DrawButtonFlags::NONE;
767 maFrameData.mbTitleClipped = false;
770 ImplStdBorderWindowView::~ImplStdBorderWindowView()
774 bool ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
776 ImplMouseMove( &maFrameData, rMEvt );
777 return true;
780 bool ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
782 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
784 if ( rMEvt.IsLeft() || rMEvt.IsRight() )
786 maFrameData.maMouseOff = rMEvt.GetPosPixel();
787 maFrameData.mnHitTest = ImplHitTest( &maFrameData, maFrameData.maMouseOff );
788 if ( maFrameData.mnHitTest != BorderWindowHitTest::NONE )
790 DragFullOptions nDragFullTest = DragFullOptions::NONE;
791 bool bTracking = true;
792 bool bHitTest = true;
794 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
796 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
797 pBorderWindow->InvalidateBorder();
799 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
801 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
802 pBorderWindow->InvalidateBorder();
804 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
806 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
807 pBorderWindow->InvalidateBorder();
809 // call handler already on mouse down
810 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
812 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
813 pClientWindow->TitleButtonClick( TitleButton::Menu );
816 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
817 pBorderWindow->InvalidateBorder();
819 bTracking = false;
821 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
823 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
824 pBorderWindow->InvalidateBorder();
826 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
828 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
829 pBorderWindow->InvalidateBorder();
831 else
833 if ( rMEvt.GetClicks() == 1 )
835 Point aPos = pBorderWindow->GetPosPixel();
836 Size aSize = pBorderWindow->GetOutputSizePixel();
837 maFrameData.mnTrackX = aPos.X();
838 maFrameData.mnTrackY = aPos.Y();
839 maFrameData.mnTrackWidth = aSize.Width();
840 maFrameData.mnTrackHeight = aSize.Height();
842 if (maFrameData.mnHitTest & BorderWindowHitTest::Title)
843 nDragFullTest = DragFullOptions::WindowMove;
844 else
845 nDragFullTest = DragFullOptions::WindowSize;
847 else
849 bTracking = false;
851 if ( (maFrameData.mnHitTest & BorderWindowHitTest::Title) &&
852 ((rMEvt.GetClicks() % 2) == 0) )
854 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
855 bHitTest = false;
857 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
859 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
860 // always perform docking on double click, no button required
861 pClientWindow->TitleButtonClick( TitleButton::Docking );
867 if ( bTracking )
869 maFrameData.mbDragFull = false;
870 if ( nDragFullTest != DragFullOptions::NONE )
871 maFrameData.mbDragFull = true; // always fulldrag for proper docking, ignore system settings
872 pBorderWindow->StartTracking();
874 else if ( bHitTest )
875 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
879 return true;
882 bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
884 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
886 if ( rTEvt.IsTrackingEnded() )
888 BorderWindowHitTest nHitTest = maFrameData.mnHitTest;
889 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
891 if ( nHitTest & BorderWindowHitTest::Close )
893 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
895 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
896 pBorderWindow->InvalidateBorder();
898 // do not call a Click-Handler when aborting
899 if ( !rTEvt.IsTrackingCanceled() )
901 // dispatch to correct window type (why is Close() not virtual ??? )
902 // TODO: make Close() virtual
903 VclPtr<vcl::Window> pWin = pBorderWindow->ImplGetClientWindow()->ImplGetWindow();
904 SystemWindow *pSysWin = dynamic_cast<SystemWindow* >(pWin.get());
905 DockingWindow *pDockWin = dynamic_cast<DockingWindow*>(pWin.get());
906 if ( pSysWin )
907 pSysWin->Close();
908 else if ( pDockWin )
909 pDockWin->Close();
913 else if ( nHitTest & BorderWindowHitTest::Dock )
915 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
917 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
918 pBorderWindow->InvalidateBorder();
920 // do not call a Click-Handler when aborting
921 if ( !rTEvt.IsTrackingCanceled() )
923 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
925 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
926 pClientWindow->TitleButtonClick( TitleButton::Docking );
931 else if ( nHitTest & BorderWindowHitTest::Menu )
933 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
935 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
936 pBorderWindow->InvalidateBorder();
938 // handler already called on mouse down
941 else if ( nHitTest & BorderWindowHitTest::Hide )
943 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
945 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
946 pBorderWindow->InvalidateBorder();
948 // do not call a Click-Handler when aborting
949 if ( !rTEvt.IsTrackingCanceled() )
951 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
953 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
954 pClientWindow->TitleButtonClick( TitleButton::Hide );
959 else if ( nHitTest & BorderWindowHitTest::Help )
961 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
963 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
964 pBorderWindow->InvalidateBorder();
967 else
969 if ( maFrameData.mbDragFull )
971 // restore old state when aborting
972 if ( rTEvt.IsTrackingCanceled() )
973 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
975 else
977 pBorderWindow->HideTracking();
978 if ( !rTEvt.IsTrackingCanceled() )
979 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
982 if ( !rTEvt.IsTrackingCanceled() )
984 if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
986 if ( static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
987 static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->EndPopupMode( FloatWinPopupEndFlags::TearOff );
992 else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
994 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
996 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
998 if ( maFrameData.maCloseRect.Contains( aMousePos ) )
1000 if ( !(maFrameData.mnCloseState & DrawButtonFlags::Pressed) )
1002 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
1003 pBorderWindow->InvalidateBorder();
1006 else
1008 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
1010 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
1011 pBorderWindow->InvalidateBorder();
1015 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
1017 if ( maFrameData.maDockRect.Contains( aMousePos ) )
1019 if ( !(maFrameData.mnDockState & DrawButtonFlags::Pressed) )
1021 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
1022 pBorderWindow->InvalidateBorder();
1025 else
1027 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
1029 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
1030 pBorderWindow->InvalidateBorder();
1034 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
1036 if ( maFrameData.maMenuRect.Contains( aMousePos ) )
1038 if ( !(maFrameData.mnMenuState & DrawButtonFlags::Pressed) )
1040 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
1041 pBorderWindow->InvalidateBorder();
1044 else
1046 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
1048 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
1049 pBorderWindow->InvalidateBorder();
1053 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
1055 if ( maFrameData.maHideRect.Contains( aMousePos ) )
1057 if ( !(maFrameData.mnHideState & DrawButtonFlags::Pressed) )
1059 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
1060 pBorderWindow->InvalidateBorder();
1063 else
1065 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
1067 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
1068 pBorderWindow->InvalidateBorder();
1072 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
1074 if ( maFrameData.maHelpRect.Contains( aMousePos ) )
1076 if ( !(maFrameData.mnHelpState & DrawButtonFlags::Pressed) )
1078 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
1079 pBorderWindow->InvalidateBorder();
1082 else
1084 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
1086 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
1087 pBorderWindow->InvalidateBorder();
1091 else
1093 aMousePos.AdjustX( -(maFrameData.maMouseOff.X()) );
1094 aMousePos.AdjustY( -(maFrameData.maMouseOff.Y()) );
1096 if ( maFrameData.mnHitTest & BorderWindowHitTest::Title )
1098 maFrameData.mpBorderWindow->SetPointer( PointerStyle::Move );
1100 Point aPos = pBorderWindow->GetPosPixel();
1101 aPos.AdjustX(aMousePos.X() );
1102 aPos.AdjustY(aMousePos.Y() );
1103 if ( maFrameData.mbDragFull )
1105 pBorderWindow->SetPosPixel( aPos );
1106 pBorderWindow->ImplUpdateAll();
1107 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1109 else
1111 maFrameData.mnTrackX = aPos.X();
1112 maFrameData.mnTrackY = aPos.Y();
1113 pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), ShowTrackFlags::Big );
1116 else
1118 Point aOldPos = pBorderWindow->GetPosPixel();
1119 Size aSize = pBorderWindow->GetSizePixel();
1120 tools::Rectangle aNewRect( aOldPos, aSize );
1121 tools::Long nOldWidth = aSize.Width();
1122 tools::Long nOldHeight = aSize.Height();
1123 tools::Long nBorderWidth = maFrameData.mnLeftBorder+maFrameData.mnRightBorder;
1124 tools::Long nBorderHeight = maFrameData.mnTopBorder+maFrameData.mnBottomBorder;
1125 tools::Long nMinWidth = pBorderWindow->mnMinWidth+nBorderWidth;
1126 tools::Long nMinHeight = pBorderWindow->mnMinHeight+nBorderHeight;
1127 tools::Long nMinWidth2 = nBorderWidth;
1128 tools::Long nMaxWidth = pBorderWindow->mnMaxWidth+nBorderWidth;
1129 tools::Long nMaxHeight = pBorderWindow->mnMaxHeight+nBorderHeight;
1131 if ( maFrameData.mnTitleHeight )
1133 nMinWidth2 += 4;
1135 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1136 nMinWidth2 += maFrameData.maCloseRect.GetWidth();
1138 if ( nMinWidth2 > nMinWidth )
1139 nMinWidth = nMinWidth2;
1140 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1142 aNewRect.AdjustLeft(aMousePos.X() );
1143 if ( aNewRect.GetWidth() < nMinWidth )
1144 aNewRect.SetLeft( aNewRect.Right()-nMinWidth+1 );
1145 else if ( aNewRect.GetWidth() > nMaxWidth )
1146 aNewRect.SetLeft( aNewRect.Right()-nMaxWidth+1 );
1148 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1150 aNewRect.AdjustRight(aMousePos.X() );
1151 if ( aNewRect.GetWidth() < nMinWidth )
1152 aNewRect.SetRight( aNewRect.Left()+nMinWidth+1 );
1153 else if ( aNewRect.GetWidth() > nMaxWidth )
1154 aNewRect.SetRight( aNewRect.Left()+nMaxWidth+1 );
1156 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1158 aNewRect.AdjustTop(aMousePos.Y() );
1159 if ( aNewRect.GetHeight() < nMinHeight )
1160 aNewRect.SetTop( aNewRect.Bottom()-nMinHeight+1 );
1161 else if ( aNewRect.GetHeight() > nMaxHeight )
1162 aNewRect.SetTop( aNewRect.Bottom()-nMaxHeight+1 );
1164 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1166 aNewRect.AdjustBottom(aMousePos.Y() );
1167 if ( aNewRect.GetHeight() < nMinHeight )
1168 aNewRect.SetBottom( aNewRect.Top()+nMinHeight+1 );
1169 else if ( aNewRect.GetHeight() > nMaxHeight )
1170 aNewRect.SetBottom( aNewRect.Top()+nMaxHeight+1 );
1173 // call Resizing-Handler for SystemWindows
1174 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
1176 // adjust size for Resizing-call
1177 aSize = aNewRect.GetSize();
1178 aSize.AdjustWidth( -nBorderWidth );
1179 aSize.AdjustHeight( -nBorderHeight );
1180 static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
1181 aSize.AdjustWidth(nBorderWidth );
1182 aSize.AdjustHeight(nBorderHeight );
1183 if ( aSize.Width() < nMinWidth )
1184 aSize.setWidth( nMinWidth );
1185 if ( aSize.Height() < nMinHeight )
1186 aSize.setHeight( nMinHeight );
1187 if ( aSize.Width() > nMaxWidth )
1188 aSize.setWidth( nMaxWidth );
1189 if ( aSize.Height() > nMaxHeight )
1190 aSize.setHeight( nMaxHeight );
1191 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1192 aNewRect.SetLeft( aNewRect.Right()-aSize.Width()+1 );
1193 else
1194 aNewRect.SetRight( aNewRect.Left()+aSize.Width()-1 );
1195 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1196 aNewRect.SetTop( aNewRect.Bottom()-aSize.Height()+1 );
1197 else
1198 aNewRect.SetBottom( aNewRect.Top()+aSize.Height()-1 );
1201 if ( maFrameData.mbDragFull )
1203 // no move (only resize) if position did not change
1204 if( aOldPos != aNewRect.TopLeft() )
1205 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1206 aNewRect.GetWidth(), aNewRect.GetHeight() );
1207 else
1208 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1209 aNewRect.GetWidth(), aNewRect.GetHeight(), PosSizeFlags::Size );
1211 pBorderWindow->ImplUpdateAll();
1212 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1213 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1214 maFrameData.maMouseOff.AdjustX(aNewRect.GetWidth()-nOldWidth );
1215 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1216 maFrameData.maMouseOff.AdjustY(aNewRect.GetHeight()-nOldHeight );
1218 else
1220 maFrameData.mnTrackX = aNewRect.Left();
1221 maFrameData.mnTrackY = aNewRect.Top();
1222 maFrameData.mnTrackWidth = aNewRect.GetWidth();
1223 maFrameData.mnTrackHeight = aNewRect.GetHeight();
1224 pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), ShowTrackFlags::Big );
1230 return true;
1233 OUString ImplStdBorderWindowView::RequestHelp( const Point& rPos, tools::Rectangle& rHelpRect )
1235 return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
1238 tools::Rectangle ImplStdBorderWindowView::GetMenuRect() const
1240 return maFrameData.maMenuRect;
1243 void ImplStdBorderWindowView::Init( OutputDevice* pDev, tools::Long nWidth, tools::Long nHeight )
1245 ImplBorderFrameData* pData = &maFrameData;
1246 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
1247 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
1248 DecorationView aDecoView( pDev );
1249 tools::Rectangle aRect( 0, 0, 10, 10 );
1250 tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, DrawFrameStyle::DoubleOut, DrawFrameFlags::NoDraw );
1252 pData->mpOutDev = pDev;
1253 pData->mnWidth = nWidth;
1254 pData->mnHeight = nHeight;
1256 pData->mnTitleType = pBorderWindow->mnTitleType;
1258 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) || (pData->mnTitleType == BorderWindowTitleType::NONE) )
1259 pData->mnBorderSize = 0;
1260 else if ( pData->mnTitleType == BorderWindowTitleType::Tearoff )
1261 pData->mnBorderSize = 0;
1262 else
1263 pData->mnBorderSize = StyleSettings::GetBorderSize();
1264 pData->mnLeftBorder = aCalcRect.Left();
1265 pData->mnTopBorder = aCalcRect.Top();
1266 pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
1267 pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
1268 pData->mnLeftBorder += pData->mnBorderSize;
1269 pData->mnTopBorder += pData->mnBorderSize;
1270 pData->mnRightBorder += pData->mnBorderSize;
1271 pData->mnBottomBorder += pData->mnBorderSize;
1272 pData->mnNoTitleTop = pData->mnTopBorder;
1274 ImplInitTitle(&maFrameData);
1275 if (pData->mnTitleHeight)
1277 // to improve symbol display force a minimum title height
1278 if (pData->mnTitleType != BorderWindowTitleType::Tearoff &&
1279 pData->mnTitleHeight < MIN_CAPTION_HEIGHT)
1280 pData->mnTitleHeight = MIN_CAPTION_HEIGHT;
1282 // set a proper background for drawing
1283 // highlighted buttons in the title
1284 pBorderWindow->SetBackground( rStyleSettings.GetFaceColor() );
1286 pData->maTitleRect.SetLeft( pData->mnLeftBorder );
1287 pData->maTitleRect.SetRight( nWidth-pData->mnRightBorder-1 );
1288 pData->maTitleRect.SetTop( pData->mnTopBorder );
1289 pData->maTitleRect.SetBottom( pData->maTitleRect.Top()+pData->mnTitleHeight-1 );
1291 if ( pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small) )
1293 tools::Long nRight = pData->maTitleRect.Right() - 3;
1294 tools::Long const nItemTop = pData->maTitleRect.Top() + 2;
1295 tools::Long const nItemBottom = pData->maTitleRect.Bottom() - 2;
1297 auto addSquareOnRight = [&nRight, nItemTop, nItemBottom](
1298 tools::Rectangle & rect, tools::Long gap)
1300 rect.SetTop( nItemTop );
1301 rect.SetBottom( nItemBottom );
1302 rect.SetRight( nRight );
1303 rect.SetLeft( rect.Right() - rect.GetHeight() + 1 );
1304 nRight -= rect.GetWidth() + gap;
1307 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1309 addSquareOnRight(pData->maCloseRect, 3);
1312 if ( pBorderWindow->mbMenuBtn )
1314 addSquareOnRight(pData->maMenuRect, 0);
1317 if ( pBorderWindow->mbDockBtn )
1319 addSquareOnRight(pData->maDockRect, 0);
1322 if ( pBorderWindow->mbHideBtn )
1324 addSquareOnRight(pData->maHideRect, 0);
1327 else
1329 pData->maCloseRect.SetEmpty();
1330 pData->maDockRect.SetEmpty();
1331 pData->maMenuRect.SetEmpty();
1332 pData->maHideRect.SetEmpty();
1333 pData->maHelpRect.SetEmpty();
1336 pData->mnTopBorder += pData->mnTitleHeight;
1338 else
1340 pData->maTitleRect.SetEmpty();
1341 pData->maCloseRect.SetEmpty();
1342 pData->maDockRect.SetEmpty();
1343 pData->maMenuRect.SetEmpty();
1344 pData->maHideRect.SetEmpty();
1345 pData->maHelpRect.SetEmpty();
1349 void ImplStdBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1350 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1352 rLeftBorder = maFrameData.mnLeftBorder;
1353 rTopBorder = maFrameData.mnTopBorder;
1354 rRightBorder = maFrameData.mnRightBorder;
1355 rBottomBorder = maFrameData.mnBottomBorder;
1358 tools::Long ImplStdBorderWindowView::CalcTitleWidth() const
1360 return ImplCalcTitleWidth( &maFrameData );
1363 void ImplStdBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point* pOffset)
1365 ImplBorderFrameData* pData = &maFrameData;
1366 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
1367 Point aTmpPoint = pOffset ? *pOffset : Point();
1368 tools::Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
1369 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1370 Color aFaceColor(rStyleSettings.GetFaceColor());
1371 Color aFrameColor(aFaceColor);
1373 aFrameColor.DecreaseContrast(sal_uInt8(0.5 * 255));
1375 // Draw Frame
1376 vcl::Region oldClipRgn(rRenderContext.GetClipRegion());
1378 // for popups, don't draw part of the frame
1379 const bool bShowJunctionToLauncher = !(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small));
1380 if (bShowJunctionToLauncher && !ImplGetSVData()->maNWFData.mbNoFrameJunctionForPopups)
1382 FloatingWindow* pWin = dynamic_cast<FloatingWindow*>(pData->mpBorderWindow->GetWindow(GetWindowType::Client));
1383 if (pWin)
1385 vcl::Region aClipRgn(aInRect);
1386 AbsoluteScreenPixelRectangle aItemClipRect(pWin->ImplGetItemEdgeClipRect());
1387 if (!aItemClipRect.IsEmpty())
1389 tools::Rectangle aTmp(pData->mpBorderWindow->AbsoluteScreenToOutputPixel(aItemClipRect.TopLeft()), aItemClipRect.GetSize());
1390 aClipRgn.Exclude(aTmp);
1391 rRenderContext.SetClipRegion(aClipRgn);
1396 // single line frame
1397 rRenderContext.SetLineColor(aFrameColor);
1398 rRenderContext.SetFillColor();
1399 rRenderContext.DrawRect(aInRect);
1400 aInRect.AdjustLeft( 1 );
1401 aInRect.AdjustRight( -1 );
1402 aInRect.AdjustTop( 1 );
1403 aInRect.AdjustBottom( -1 );
1405 // restore
1406 if (!(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small)))
1407 rRenderContext.SetClipRegion(oldClipRgn);
1409 // Draw Border
1410 rRenderContext.SetLineColor();
1411 tools::Long nBorderSize = pData->mnBorderSize;
1412 if (nBorderSize)
1414 rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
1415 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top()),
1416 Size(aInRect.GetWidth(), nBorderSize)));
1417 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top() + nBorderSize),
1418 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1419 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Bottom() - nBorderSize + 1),
1420 Size(aInRect.GetWidth(), nBorderSize)));
1421 rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Right()-nBorderSize + 1, aInRect.Top() + nBorderSize),
1422 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1425 // Draw Title
1426 if (!pData->maTitleRect.IsEmpty())
1428 aInRect = pData->maTitleRect;
1430 // use no gradient anymore, just a static titlecolor
1431 if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
1432 rRenderContext.SetFillColor(rStyleSettings.GetFaceGradientColor());
1433 else if (pData->mnTitleType == BorderWindowTitleType::Popup)
1434 rRenderContext.SetFillColor(aFaceColor);
1435 else
1436 rRenderContext.SetFillColor(aFrameColor);
1438 rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
1439 tools::Rectangle aTitleRect(pData->maTitleRect);
1440 if(pOffset)
1441 aTitleRect.Move(pOffset->X(), pOffset->Y());
1442 rRenderContext.DrawRect(aTitleRect);
1444 if (pData->mnTitleType != BorderWindowTitleType::Tearoff)
1446 aInRect.AdjustLeft(2 );
1447 aInRect.AdjustRight( -2 );
1449 if (!pData->maHelpRect.IsEmpty())
1450 aInRect.SetRight( pData->maHelpRect.Left() - 2 );
1451 else if (!pData->maHideRect.IsEmpty())
1452 aInRect.SetRight( pData->maHideRect.Left() - 2 );
1453 else if (!pData->maDockRect.IsEmpty())
1454 aInRect.SetRight( pData->maDockRect.Left() - 2 );
1455 else if (!pData->maMenuRect.IsEmpty())
1456 aInRect.SetRight( pData->maMenuRect.Left() - 2 );
1457 else if (!pData->maCloseRect.IsEmpty())
1458 aInRect.SetRight( pData->maCloseRect.Left() - 2 );
1460 if (pOffset)
1461 aInRect.Move(pOffset->X(), pOffset->Y());
1463 DrawTextFlags nTextStyle = DrawTextFlags::Left | DrawTextFlags::VCenter | DrawTextFlags::EndEllipsis | DrawTextFlags::Clip;
1465 // must show tooltip ?
1466 TextRectInfo aInfo;
1467 rRenderContext.GetTextRect(aInRect, pBorderWindow->GetText(), nTextStyle, &aInfo);
1468 pData->mbTitleClipped = aInfo.IsEllipses();
1470 rRenderContext.DrawText(aInRect, pBorderWindow->GetText(), nTextStyle);
1472 else
1474 ToolBox::ImplDrawGrip(rRenderContext, aTitleRect, ToolBox::ImplGetDragWidth(rRenderContext, false),
1475 WindowAlign::Left, false);
1479 if (!pData->maCloseRect.IsEmpty())
1481 tools::Rectangle aSymbolRect(pData->maCloseRect);
1482 if (pOffset)
1483 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1484 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::CLOSE, pData->mnCloseState);
1486 if (!pData->maDockRect.IsEmpty())
1488 tools::Rectangle aSymbolRect(pData->maDockRect);
1489 if (pOffset)
1490 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1491 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::DOCK, pData->mnDockState);
1493 if (!pData->maMenuRect.IsEmpty())
1495 tools::Rectangle aSymbolRect(pData->maMenuRect);
1496 if (pOffset)
1497 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1498 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::MENU, pData->mnMenuState);
1500 if (!pData->maHideRect.IsEmpty())
1502 tools::Rectangle aSymbolRect(pData->maHideRect);
1503 if (pOffset)
1504 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1505 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HIDE, pData->mnHideState);
1508 if (!pData->maHelpRect.IsEmpty())
1510 tools::Rectangle aSymbolRect(pData->maHelpRect);
1511 if (pOffset)
1512 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1513 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HELP, pData->mnHelpState);
1517 void ImplBorderWindow::ImplInit( vcl::Window* pParent,
1518 WinBits nStyle, BorderWindowStyle nTypeStyle,
1519 SystemParentData* pSystemParentData
1522 // remove all unwanted WindowBits
1523 WinBits nOrgStyle = nStyle;
1524 WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_POPUP);
1525 if ( nTypeStyle & BorderWindowStyle::App )
1526 nTestStyle |= WB_APP;
1527 nStyle &= nTestStyle;
1529 mpWindowImpl->mbBorderWin = true;
1530 mbSmallOutBorder = false;
1531 if ( nTypeStyle & BorderWindowStyle::Frame )
1533 mpWindowImpl->mbOverlapWin = true;
1534 mpWindowImpl->mbFrame = true;
1536 if( nStyle & WB_SYSTEMCHILDWINDOW )
1538 mbFrameBorder = false;
1540 else if( nStyle & (WB_OWNERDRAWDECORATION | WB_POPUP) )
1542 mbFrameBorder = (nOrgStyle & WB_NOBORDER) == 0;
1544 else
1546 mbFrameBorder = false;
1547 // closeable windows may have a border as well, eg. system floating windows without caption
1548 if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE/* | WB_CLOSEABLE*/)) == WB_BORDER )
1549 mbSmallOutBorder = true;
1552 else if ( nTypeStyle & BorderWindowStyle::Overlap )
1554 mpWindowImpl->mbOverlapWin = true;
1555 mbFrameBorder = true;
1557 else
1558 mbFrameBorder = false;
1560 if ( nTypeStyle & BorderWindowStyle::Float )
1561 mbFloatWindow = true;
1562 else
1563 mbFloatWindow = false;
1565 Window::ImplInit( pParent, nStyle, pSystemParentData );
1566 SetBackground();
1567 SetTextFillColor();
1569 mpMenuBarWindow = nullptr;
1570 mnMinWidth = 0;
1571 mnMinHeight = 0;
1572 mnMaxWidth = SHRT_MAX;
1573 mnMaxHeight = SHRT_MAX;
1574 mnOrgMenuHeight = 0;
1575 mbMenuHide = false;
1576 mbDockBtn = false;
1577 mbMenuBtn = false;
1578 mbHideBtn = false;
1579 mbDisplayActive = IsActive();
1581 if ( nTypeStyle & BorderWindowStyle::Float )
1582 mnTitleType = BorderWindowTitleType::Small;
1583 else
1584 mnTitleType = BorderWindowTitleType::Normal;
1585 mnBorderStyle = WindowBorderStyle::NORMAL;
1586 InitView();
1589 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent,
1590 SystemParentData* pSystemParentData,
1591 WinBits nStyle, BorderWindowStyle nTypeStyle
1592 ) : Window( WindowType::BORDERWINDOW )
1594 ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
1597 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent, WinBits nStyle ,
1598 BorderWindowStyle nTypeStyle ) :
1599 Window( WindowType::BORDERWINDOW )
1601 ImplInit( pParent, nStyle, nTypeStyle, nullptr );
1604 ImplBorderWindow::~ImplBorderWindow()
1606 disposeOnce();
1609 void ImplBorderWindow::dispose()
1611 mpBorderView.reset();
1612 mpMenuBarWindow.clear();
1613 mpNotebookBar.disposeAndClear();
1614 vcl::Window::dispose();
1617 void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
1619 if (mpBorderView)
1620 mpBorderView->MouseMove( rMEvt );
1623 void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
1625 if (mpBorderView)
1626 mpBorderView->MouseButtonDown( rMEvt );
1629 void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
1631 if (mpBorderView)
1632 mpBorderView->Tracking( rTEvt );
1635 void ImplBorderWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
1637 if (mpBorderView)
1638 mpBorderView->DrawWindow(rRenderContext);
1641 void ImplBorderWindow::Draw( OutputDevice* pOutDev, const Point& rPos )
1643 if (mpBorderView)
1644 mpBorderView->DrawWindow(*pOutDev, &rPos);
1647 void ImplBorderWindow::Activate()
1649 SetDisplayActive( true );
1650 Window::Activate();
1653 void ImplBorderWindow::Deactivate()
1655 // remove active windows from the ruler, also ignore the Deactivate
1656 // if a menu becomes active
1657 if (GetActivateMode() != ActivateModeFlags::NONE && !ImplGetSVData()->mpWinData->mbNoDeactivate)
1658 SetDisplayActive( false );
1659 Window::Deactivate();
1662 void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
1664 // no keyboard help for border window
1665 if ( rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK) && !rHEvt.KeyboardActivated() )
1667 Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
1668 tools::Rectangle aHelpRect;
1669 OUString aHelpStr( mpBorderView->RequestHelp( aMousePosPixel, aHelpRect ) );
1671 // retrieve rectangle
1672 if ( !aHelpStr.isEmpty() )
1674 aHelpRect.SetPos( OutputToScreenPixel( aHelpRect.TopLeft() ) );
1675 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1676 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aHelpStr );
1677 else
1678 Help::ShowQuickHelp( this, aHelpRect, aHelpStr );
1679 return;
1683 Window::RequestHelp( rHEvt );
1686 void ImplBorderWindow::Resize()
1688 Size aSize = GetOutputSizePixel();
1690 vcl::Window* pClientWindow = ImplGetClientWindow();
1692 sal_Int32 nLeftBorder;
1693 sal_Int32 nTopBorder;
1694 sal_Int32 nRightBorder;
1695 sal_Int32 nBottomBorder;
1696 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1698 if (mpMenuBarWindow)
1700 tools::Long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
1701 if ( mbMenuHide )
1703 if ( nMenuHeight )
1704 mnOrgMenuHeight = nMenuHeight;
1705 nMenuHeight = 0;
1707 else
1709 if ( !nMenuHeight )
1710 nMenuHeight = mnOrgMenuHeight;
1712 mpMenuBarWindow->setPosSizePixel(
1713 nLeftBorder, nTopBorder,
1714 aSize.Width()-nLeftBorder-nRightBorder,
1715 nMenuHeight);
1717 // shift the notebookbar down accordingly
1718 nTopBorder += nMenuHeight;
1721 if (mpNotebookBar)
1723 tools::Long nNotebookBarHeight = mpNotebookBar->GetSizePixel().Height();
1725 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1726 const BitmapEx& aPersona = rStyleSettings.GetPersonaHeader();
1727 // since size of notebookbar changes, to make common persona for menubar
1728 // and notebookbar persona should be set again with changed coordinates
1729 if (!aPersona.IsEmpty())
1731 Wallpaper aWallpaper(aPersona);
1732 aWallpaper.SetStyle(WallpaperStyle::TopRight);
1733 aWallpaper.SetRect(tools::Rectangle(Point(0, -nTopBorder),
1734 Size(aSize.Width() - nLeftBorder - nRightBorder,
1735 nNotebookBarHeight + nTopBorder)));
1736 mpNotebookBar->SetBackground(aWallpaper);
1739 mpNotebookBar->setPosSizePixel(
1740 nLeftBorder, nTopBorder,
1741 aSize.Width() - nLeftBorder - nRightBorder,
1742 nNotebookBarHeight);
1745 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
1746 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
1747 pClientWindow->ImplPosSizeWindow( pClientWindow->mpWindowImpl->mnLeftBorder,
1748 pClientWindow->mpWindowImpl->mnTopBorder,
1749 aSize.Width()-pClientWindow->mpWindowImpl->mnLeftBorder-pClientWindow->mpWindowImpl->mnRightBorder,
1750 aSize.Height()-pClientWindow->mpWindowImpl->mnTopBorder-pClientWindow->mpWindowImpl->mnBottomBorder,
1751 PosSizeFlags::X | PosSizeFlags::Y |
1752 PosSizeFlags::Width | PosSizeFlags::Height );
1754 // UpdateView
1755 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1756 InvalidateBorder();
1758 Window::Resize();
1761 void ImplBorderWindow::StateChanged( StateChangedType nType )
1763 if ( (nType == StateChangedType::Text) ||
1764 (nType == StateChangedType::Data) )
1766 if (IsReallyVisible() && mbFrameBorder)
1767 InvalidateBorder();
1770 Window::StateChanged( nType );
1773 void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
1775 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1776 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1777 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1778 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1780 if ( !mpWindowImpl->mbFrame || (GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP)) )
1781 UpdateView( true, ImplGetWindow()->GetOutputSizePixel() );
1784 Window::DataChanged( rDCEvt );
1787 void ImplBorderWindow::InitView()
1789 if ( mbSmallOutBorder )
1790 mpBorderView.reset(new ImplSmallBorderWindowView( this ));
1791 else if ( mpWindowImpl->mbFrame )
1793 if( mbFrameBorder )
1794 mpBorderView.reset(new ImplStdBorderWindowView( this ));
1795 else
1796 mpBorderView.reset(new ImplNoBorderWindowView);
1798 else if ( !mbFrameBorder )
1799 mpBorderView.reset(new ImplSmallBorderWindowView( this ));
1800 else
1801 mpBorderView.reset(new ImplStdBorderWindowView( this ));
1802 Size aSize = GetOutputSizePixel();
1803 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1806 void ImplBorderWindow::UpdateView( bool bNewView, const Size& rNewOutSize )
1808 sal_Int32 nLeftBorder;
1809 sal_Int32 nTopBorder;
1810 sal_Int32 nRightBorder;
1811 sal_Int32 nBottomBorder;
1812 Size aOldSize = GetSizePixel();
1813 Size aOutputSize = rNewOutSize;
1815 if ( bNewView )
1817 mpBorderView.reset();
1818 InitView();
1820 else
1822 Size aSize = aOutputSize;
1823 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1824 aSize.AdjustWidth(nLeftBorder+nRightBorder );
1825 aSize.AdjustHeight(nTopBorder+nBottomBorder );
1826 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1829 vcl::Window* pClientWindow = ImplGetClientWindow();
1830 if ( pClientWindow )
1832 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
1833 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
1835 GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1836 if ( aOldSize.Width() || aOldSize.Height() )
1838 aOutputSize.AdjustWidth(nLeftBorder+nRightBorder );
1839 aOutputSize.AdjustHeight(nTopBorder+nBottomBorder );
1840 if ( aOutputSize == GetSizePixel() )
1841 InvalidateBorder();
1842 else
1843 SetSizePixel( aOutputSize );
1847 void ImplBorderWindow::InvalidateBorder()
1849 if ( !IsReallyVisible() )
1850 return;
1852 // invalidate only if we have a border
1853 sal_Int32 nLeftBorder;
1854 sal_Int32 nTopBorder;
1855 sal_Int32 nRightBorder;
1856 sal_Int32 nBottomBorder;
1857 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1858 if ( !(nLeftBorder || nTopBorder || nRightBorder || nBottomBorder) )
1859 return;
1861 tools::Rectangle aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
1862 vcl::Region aRegion( aWinRect );
1863 aWinRect.AdjustLeft(nLeftBorder );
1864 aWinRect.AdjustTop(nTopBorder );
1865 aWinRect.AdjustRight( -nRightBorder );
1866 aWinRect.AdjustBottom( -nBottomBorder );
1867 // no output area anymore, now invalidate all
1868 if ( (aWinRect.Right() < aWinRect.Left()) ||
1869 (aWinRect.Bottom() < aWinRect.Top()) )
1870 Invalidate( InvalidateFlags::NoChildren );
1871 else
1873 aRegion.Exclude( aWinRect );
1874 Invalidate( aRegion, InvalidateFlags::NoChildren );
1878 void ImplBorderWindow::SetDisplayActive( bool bActive )
1880 if ( mbDisplayActive != bActive )
1882 mbDisplayActive = bActive;
1883 if ( mbFrameBorder )
1884 InvalidateBorder();
1888 void ImplBorderWindow::SetTitleType( BorderWindowTitleType nTitleType, const Size& rSize )
1890 mnTitleType = nTitleType;
1891 UpdateView( false, rSize );
1894 void ImplBorderWindow::SetBorderStyle( WindowBorderStyle nStyle )
1896 if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
1898 mnBorderStyle = nStyle;
1899 UpdateView( false, ImplGetWindow()->GetOutputSizePixel() );
1903 void ImplBorderWindow::SetCloseButton()
1905 SetStyle( GetStyle() | WB_CLOSEABLE );
1906 Size aSize = GetOutputSizePixel();
1907 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1908 InvalidateBorder();
1911 void ImplBorderWindow::SetDockButton( bool bDockButton )
1913 mbDockBtn = bDockButton;
1914 Size aSize = GetOutputSizePixel();
1915 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1916 InvalidateBorder();
1919 void ImplBorderWindow::SetHideButton( bool bHideButton )
1921 mbHideBtn = bHideButton;
1922 Size aSize = GetOutputSizePixel();
1923 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1924 InvalidateBorder();
1927 void ImplBorderWindow::SetMenuButton( bool bMenuButton )
1929 mbMenuBtn = bMenuButton;
1930 Size aSize = GetOutputSizePixel();
1931 mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
1932 InvalidateBorder();
1935 void ImplBorderWindow::UpdateMenuHeight()
1937 Resize();
1940 void ImplBorderWindow::SetMenuBarWindow( vcl::Window* pWindow )
1942 mpMenuBarWindow = pWindow;
1943 UpdateMenuHeight();
1944 if ( pWindow )
1945 pWindow->Show();
1948 void ImplBorderWindow::SetMenuBarMode( bool bHide )
1950 mbMenuHide = bHide;
1951 UpdateMenuHeight();
1954 void ImplBorderWindow::SetNotebookBar(const OUString& rUIXMLDescription,
1955 const css::uno::Reference<css::frame::XFrame>& rFrame,
1956 const NotebookBarAddonsItem& aNotebookBarAddonsItem)
1958 if (mpNotebookBar)
1959 mpNotebookBar.disposeAndClear();
1960 mpNotebookBar = VclPtr<NotebookBar>::Create(this, "NotebookBar", rUIXMLDescription, rFrame,
1961 aNotebookBarAddonsItem);
1962 Resize();
1965 void ImplBorderWindow::CloseNotebookBar()
1967 if (mpNotebookBar)
1968 mpNotebookBar.disposeAndClear();
1969 mpNotebookBar = nullptr;
1970 Resize();
1973 void ImplBorderWindow::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1974 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1976 mpBorderView->GetBorder(rLeftBorder, rTopBorder, rRightBorder, rBottomBorder);
1978 if (mpMenuBarWindow && !mbMenuHide)
1979 rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
1981 if (mpNotebookBar && mpNotebookBar->IsVisible())
1982 rTopBorder += mpNotebookBar->GetSizePixel().Height();
1985 tools::Long ImplBorderWindow::CalcTitleWidth() const
1987 return mpBorderView->CalcTitleWidth();
1990 tools::Rectangle ImplBorderWindow::GetMenuRect() const
1992 return mpBorderView->GetMenuRect();
1995 Size ImplBorderWindow::GetOptimalSize() const
1997 const vcl::Window* pClientWindow = ImplGetClientWindow();
1998 if (pClientWindow)
1999 return pClientWindow->GetOptimalSize();
2000 return Size(mnMinWidth, mnMinHeight);
2003 void ImplBorderWindow::queue_resize(StateChangedType eReason)
2005 //if we are floating, then we don't want to inform our parent that it needs
2006 //to calculate a new layout allocation. Because while we are a child
2007 //of our parent we are not embedded into the parent so it doesn't care
2008 //about us.
2009 if (mbFloatWindow)
2010 return;
2011 vcl::Window::queue_resize(eReason);
2014 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */