build fix: no comphelper/profilezone.hxx in this branch
[LibreOffice.git] / vcl / source / window / brdwin.cxx
blobb62eb6a94d5cfb09f7aa157fc26c469ae7410302
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 <svids.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/bitmap.hxx>
32 #include <vcl/gradient.hxx>
33 #include <vcl/image.hxx>
34 #include <vcl/virdev.hxx>
35 #include <vcl/help.hxx>
36 #include <vcl/edit.hxx>
37 #include <vcl/metric.hxx>
38 #include <vcl/settings.hxx>
40 using namespace ::com::sun::star::uno;
42 // useful caption height for title bar buttons
43 #define MIN_CAPTION_HEIGHT 18
45 static void ImplGetPinImage( DrawButtonFlags nStyle, bool bPinIn, Image& rImage )
47 // load ImageList if not available yet
48 ImplSVData* pSVData = ImplGetSVData();
49 if ( !pSVData->maCtrlData.mpPinImgList )
51 ResMgr* pResMgr = ImplGetResMgr();
52 pSVData->maCtrlData.mpPinImgList = new ImageList();
53 if( pResMgr )
55 Color aMaskColor( 0x00, 0x00, 0xFF );
56 pSVData->maCtrlData.mpPinImgList->InsertFromHorizontalBitmap
57 ( ResId( SV_RESID_BITMAP_PIN, *pResMgr ), 4,
58 &aMaskColor );
62 // get and return Image
63 sal_uInt16 nId;
64 if ( nStyle & DrawButtonFlags::Pressed )
66 if ( bPinIn )
67 nId = 4;
68 else
69 nId = 3;
71 else
73 if ( bPinIn )
74 nId = 2;
75 else
76 nId = 1;
78 rImage = pSVData->maCtrlData.mpPinImgList->GetImage( nId );
81 namespace vcl {
83 void Window::ImplCalcSymbolRect( Rectangle& rRect )
85 // Add border, not shown in the non-default representation,
86 // as we want to use it for small buttons
87 rRect.Left()--;
88 rRect.Top()--;
89 rRect.Right()++;
90 rRect.Bottom()++;
92 // we leave 5% room between the symbol and the button border
93 long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
94 long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
95 rRect.Left() += nExtraWidth;
96 rRect.Right() -= nExtraWidth;
97 rRect.Top() += nExtraHeight;
98 rRect.Bottom() -= nExtraHeight;
101 } /* namespace vcl */
103 static void ImplDrawBrdWinSymbol( vcl::RenderContext* pDev,
104 const Rectangle& rRect, SymbolType eSymbol )
106 // we leave 5% room between the symbol and the button border
107 DecorationView aDecoView( pDev );
108 Rectangle aTempRect = rRect;
109 vcl::Window::ImplCalcSymbolRect( aTempRect );
110 aDecoView.DrawSymbol( aTempRect, eSymbol,
111 pDev->GetSettings().GetStyleSettings().GetButtonTextColor() );
114 static void ImplDrawBrdWinSymbolButton( vcl::RenderContext* pDev,
115 const Rectangle& rRect,
116 SymbolType eSymbol, DrawButtonFlags nState )
118 bool bMouseOver(nState & DrawButtonFlags::Highlight);
119 nState &= ~DrawButtonFlags::Highlight;
121 Rectangle aTempRect;
122 vcl::Window *pWin = dynamic_cast< vcl::Window* >(pDev);
123 if( pWin )
125 if( bMouseOver )
127 // provide a bright background for selection effect
128 pDev->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() );
129 pDev->SetLineColor();
130 pDev->DrawRect( rRect );
131 pWin->DrawSelectionBackground( rRect, 2, bool(nState & DrawButtonFlags::Pressed),
132 true );
134 aTempRect = rRect;
135 aTempRect.Left()+=3;
136 aTempRect.Right()-=4;
137 aTempRect.Top()+=3;
138 aTempRect.Bottom()-=4;
140 else
142 DecorationView aDecoView( pDev );
143 aTempRect = aDecoView.DrawButton( rRect, nState|DrawButtonFlags::Flat );
145 ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
149 ImplBorderWindowView::~ImplBorderWindowView()
153 bool ImplBorderWindowView::MouseMove( const MouseEvent& )
155 return false;
158 bool ImplBorderWindowView::MouseButtonDown( const MouseEvent& )
160 return false;
163 bool ImplBorderWindowView::Tracking( const TrackingEvent& )
165 return false;
168 OUString ImplBorderWindowView::RequestHelp( const Point&, Rectangle& )
170 return OUString();
173 Rectangle ImplBorderWindowView::GetMenuRect() const
175 return Rectangle();
178 void ImplBorderWindowView::ImplInitTitle(ImplBorderFrameData* pData)
180 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
182 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) ||
183 (pData->mnTitleType == BorderWindowTitleType::NONE) )
185 pData->mnTitleType = BorderWindowTitleType::NONE;
186 pData->mnTitleHeight = 0;
188 else
190 const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
191 if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
192 pData->mnTitleHeight = rStyleSettings.GetTearOffTitleHeight();
193 else
195 if (pData->mnTitleType == BorderWindowTitleType::Small)
197 pBorderWindow->SetPointFont(*pBorderWindow, rStyleSettings.GetFloatTitleFont() );
198 pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
200 else // pData->mnTitleType == BorderWindowTitleType::Normal
202 // FIXME RenderContext
203 pBorderWindow->SetPointFont(*pBorderWindow, rStyleSettings.GetTitleFont());
204 pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
206 long nTextHeight = pBorderWindow->GetTextHeight();
207 if (nTextHeight > pData->mnTitleHeight)
208 pData->mnTitleHeight = nTextHeight;
213 BorderWindowHitTest ImplBorderWindowView::ImplHitTest( ImplBorderFrameData* pData, const Point& rPos )
215 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
217 if ( pData->maTitleRect.IsInside( rPos ) )
219 if ( pData->maCloseRect.IsInside( rPos ) )
220 return BorderWindowHitTest::Close;
221 else if ( pData->maRollRect.IsInside( rPos ) )
222 return BorderWindowHitTest::Roll;
223 else if ( pData->maMenuRect.IsInside( rPos ) )
224 return BorderWindowHitTest::Menu;
225 else if ( pData->maDockRect.IsInside( rPos ) )
226 return BorderWindowHitTest::Dock;
227 else if ( pData->maHideRect.IsInside( rPos ) )
228 return BorderWindowHitTest::Hide;
229 else if ( pData->maHelpRect.IsInside( rPos ) )
230 return BorderWindowHitTest::Help;
231 else if ( pData->maPinRect.IsInside( rPos ) )
232 return BorderWindowHitTest::Pin;
233 else
234 return BorderWindowHitTest::Title;
237 if ( (pBorderWindow->GetStyle() & WB_SIZEABLE) &&
238 !pBorderWindow->mbRollUp )
240 long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
241 if ( nSizeWidth < 16 )
242 nSizeWidth = 16;
244 // no corner resize for floating toolbars, which would lead to jumps while formatting
245 // setting nSizeWidth = 0 will only return pure left,top,right,bottom
246 if( pBorderWindow->GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP) )
247 nSizeWidth = 0;
249 if ( rPos.X() < pData->mnLeftBorder )
251 if ( rPos.Y() < nSizeWidth )
252 return BorderWindowHitTest::TopLeft;
253 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
254 return BorderWindowHitTest::BottomLeft;
255 else
256 return BorderWindowHitTest::Left;
258 else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
260 if ( rPos.Y() < nSizeWidth )
261 return BorderWindowHitTest::TopRight;
262 else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
263 return BorderWindowHitTest::BottomRight;
264 else
265 return BorderWindowHitTest::Right;
267 else if ( rPos.Y() < pData->mnNoTitleTop )
269 if ( rPos.X() < nSizeWidth )
270 return BorderWindowHitTest::TopLeft;
271 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
272 return BorderWindowHitTest::TopRight;
273 else
274 return BorderWindowHitTest::Top;
276 else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
278 if ( rPos.X() < nSizeWidth )
279 return BorderWindowHitTest::BottomLeft;
280 else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
281 return BorderWindowHitTest::BottomRight;
282 else
283 return BorderWindowHitTest::Bottom;
287 return BorderWindowHitTest::NONE;
290 bool ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
292 DrawButtonFlags oldCloseState = pData->mnCloseState;
293 DrawButtonFlags oldMenuState = pData->mnMenuState;
294 pData->mnCloseState &= ~DrawButtonFlags::Highlight;
295 pData->mnMenuState &= ~DrawButtonFlags::Highlight;
297 Point aMousePos = rMEvt.GetPosPixel();
298 BorderWindowHitTest nHitTest = ImplHitTest( pData, aMousePos );
299 PointerStyle ePtrStyle = PointerStyle::Arrow;
300 if ( nHitTest & BorderWindowHitTest::Left )
301 ePtrStyle = PointerStyle::WindowWSize;
302 else if ( nHitTest & BorderWindowHitTest::Right )
303 ePtrStyle = PointerStyle::WindowESize;
304 else if ( nHitTest & BorderWindowHitTest::Top )
305 ePtrStyle = PointerStyle::WindowNSize;
306 else if ( nHitTest & BorderWindowHitTest::Bottom )
307 ePtrStyle = PointerStyle::WindowSSize;
308 else if ( nHitTest & BorderWindowHitTest::TopLeft )
309 ePtrStyle = PointerStyle::WindowNWSize;
310 else if ( nHitTest & BorderWindowHitTest::BottomRight )
311 ePtrStyle = PointerStyle::WindowSESize;
312 else if ( nHitTest & BorderWindowHitTest::TopRight )
313 ePtrStyle = PointerStyle::WindowNESize;
314 else if ( nHitTest & BorderWindowHitTest::BottomLeft )
315 ePtrStyle = PointerStyle::WindowSWSize;
316 else if ( nHitTest & BorderWindowHitTest::Close )
317 pData->mnCloseState |= DrawButtonFlags::Highlight;
318 else if ( nHitTest & BorderWindowHitTest::Menu )
319 pData->mnMenuState |= DrawButtonFlags::Highlight;
320 pData->mpBorderWindow->SetPointer( Pointer( ePtrStyle ) );
322 if( pData->mnCloseState != oldCloseState )
323 pData->mpBorderWindow->Invalidate( pData->maCloseRect );
324 if( pData->mnMenuState != oldMenuState )
325 pData->mpBorderWindow->Invalidate( pData->maMenuRect );
327 return true;
330 OUString ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData* pData,
331 const Point& rPos,
332 Rectangle& rHelpRect )
334 sal_uInt16 nHelpId = 0;
335 OUString aHelpStr;
336 BorderWindowHitTest nHitTest = ImplHitTest( pData, rPos );
337 if ( nHitTest != BorderWindowHitTest::NONE )
339 if ( nHitTest & BorderWindowHitTest::Close )
341 nHelpId = SV_HELPTEXT_CLOSE;
342 rHelpRect = pData->maCloseRect;
344 else if ( nHitTest & BorderWindowHitTest::Roll )
346 if ( pData->mpBorderWindow->mbRollUp )
347 nHelpId = SV_HELPTEXT_ROLLDOWN;
348 else
349 nHelpId = SV_HELPTEXT_ROLLUP;
350 rHelpRect = pData->maRollRect;
352 else if ( nHitTest & BorderWindowHitTest::Dock )
354 nHelpId = SV_HELPTEXT_MAXIMIZE;
355 rHelpRect = pData->maDockRect;
357 else if ( nHitTest & BorderWindowHitTest::Hide )
359 nHelpId = SV_HELPTEXT_MINIMIZE;
360 rHelpRect = pData->maHideRect;
362 else if ( nHitTest & BorderWindowHitTest::Help )
364 nHelpId = SV_HELPTEXT_HELP;
365 rHelpRect = pData->maHelpRect;
367 else if ( nHitTest & BorderWindowHitTest::Pin )
369 nHelpId = SV_HELPTEXT_ALWAYSVISIBLE;
370 rHelpRect = pData->maPinRect;
372 else if ( nHitTest & BorderWindowHitTest::Title )
374 if( !pData->maTitleRect.IsEmpty() )
376 // tooltip only if title truncated
377 if( pData->mbTitleClipped )
379 rHelpRect = pData->maTitleRect;
380 // no help id, use window title as help string
381 aHelpStr = pData->mpBorderWindow->GetText();
387 if( nHelpId && ImplGetResMgr() )
388 aHelpStr = ResId(nHelpId, *ImplGetResMgr()).toString();
390 return aHelpStr;
393 long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData )
395 // title is not visible therefore no width
396 if ( !pData->mnTitleHeight )
397 return 0;
399 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
400 long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
401 nTitleWidth += pData->maPinRect.GetWidth();
402 nTitleWidth += pData->maCloseRect.GetWidth();
403 nTitleWidth += pData->maRollRect.GetWidth();
404 nTitleWidth += pData->maDockRect.GetWidth();
405 nTitleWidth += pData->maMenuRect.GetWidth();
406 nTitleWidth += pData->maHideRect.GetWidth();
407 nTitleWidth += pData->maHelpRect.GetWidth();
408 nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
409 return nTitleWidth;
413 ImplNoBorderWindowView::ImplNoBorderWindowView( ImplBorderWindow* )
417 void ImplNoBorderWindowView::Init( OutputDevice*, long, long )
421 void ImplNoBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
422 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
424 rLeftBorder = 0;
425 rTopBorder = 0;
426 rRightBorder = 0;
427 rBottomBorder = 0;
430 long ImplNoBorderWindowView::CalcTitleWidth() const
432 return 0;
435 void ImplNoBorderWindowView::DrawWindow(vcl::RenderContext&, const Point*)
439 ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
440 : mpBorderWindow(pBorderWindow)
441 , mpOutDev(nullptr)
442 , mnWidth(0)
443 , mnHeight(0)
444 , mnLeftBorder(0)
445 , mnTopBorder(0)
446 , mnRightBorder(0)
447 , mnBottomBorder(0)
448 , mbNWFBorder(false)
452 void ImplSmallBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
454 mpOutDev = pDev;
455 mnWidth = nWidth;
456 mnHeight = nHeight;
457 mbNWFBorder = false;
459 vcl::Window *pWin = nullptr, *pCtrl = nullptr;
460 if (mpOutDev->GetOutDevType() == OUTDEV_WINDOW)
461 pWin = static_cast<vcl::Window*>(mpOutDev.get());
463 if (pWin)
464 pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
466 long nOrigLeftBorder = mnLeftBorder;
467 long nOrigTopBorder = mnTopBorder;
468 long nOrigRightBorder = mnRightBorder;
469 long nOrigBottomBorder = mnBottomBorder;
471 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
472 if ( nBorderStyle & WindowBorderStyle::NOBORDER )
474 mnLeftBorder = 0;
475 mnTopBorder = 0;
476 mnRightBorder = 0;
477 mnBottomBorder = 0;
479 else
481 // FIXME: this is currently only on OS X, check with other
482 // platforms
483 if( ImplGetSVData()->maNWFData.mbNoFocusRects && !( nBorderStyle & WindowBorderStyle::NWF ) )
485 // for native widget drawing we must find out what
486 // control this border belongs to
487 ControlType aCtrlType = ControlType::Generic;
488 if (pCtrl)
490 switch( pCtrl->GetType() )
492 case WINDOW_LISTBOX:
493 if( pCtrl->GetStyle() & WB_DROPDOWN )
495 aCtrlType = ControlType::Listbox;
496 mbNWFBorder = true;
498 break;
499 case WINDOW_COMBOBOX:
500 if( pCtrl->GetStyle() & WB_DROPDOWN )
502 aCtrlType = ControlType::Combobox;
503 mbNWFBorder = true;
505 break;
506 case WINDOW_MULTILINEEDIT:
507 aCtrlType = ControlType::MultilineEditbox;
508 mbNWFBorder = true;
509 break;
510 case WINDOW_EDIT:
511 case WINDOW_PATTERNFIELD:
512 case WINDOW_METRICFIELD:
513 case WINDOW_CURRENCYFIELD:
514 case WINDOW_DATEFIELD:
515 case WINDOW_TIMEFIELD:
516 case WINDOW_LONGCURRENCYFIELD:
517 case WINDOW_NUMERICFIELD:
518 case WINDOW_SPINFIELD:
519 case WINDOW_CALCINPUTLINE:
520 mbNWFBorder = true;
521 if (pCtrl->GetStyle() & WB_SPIN)
522 aCtrlType = ControlType::Spinbox;
523 else
524 aCtrlType = ControlType::Editbox;
525 break;
526 default:
527 break;
530 if( mbNWFBorder )
532 ImplControlValue aControlValue;
533 Rectangle aCtrlRegion( (const Point&)Point(), Size( mnWidth < 10 ? 10 : mnWidth, mnHeight < 10 ? 10 : mnHeight ) );
534 Rectangle aBounds( aCtrlRegion );
535 Rectangle aContent( aCtrlRegion );
536 if( pWin->GetNativeControlRegion( aCtrlType, ControlPart::Entire, aCtrlRegion,
537 ControlState::ENABLED, aControlValue, OUString(),
538 aBounds, aContent ) )
540 mnLeftBorder = aContent.Left() - aBounds.Left();
541 mnRightBorder = aBounds.Right() - aContent.Right();
542 mnTopBorder = aContent.Top() - aBounds.Top();
543 mnBottomBorder = aBounds.Bottom() - aContent.Bottom();
544 if( mnWidth && mnHeight )
547 mpBorderWindow->SetPaintTransparent( true );
548 mpBorderWindow->SetBackground();
549 pCtrl->SetPaintTransparent( true );
551 vcl::Window* pCompoundParent = nullptr;
552 if( pWin->GetParent() && pWin->GetParent()->IsCompoundControl() )
553 pCompoundParent = pWin->GetParent();
555 if( pCompoundParent )
556 pCompoundParent->SetPaintTransparent( true );
558 if( mnWidth < aBounds.GetWidth() || mnHeight < aBounds.GetHeight() )
560 if( ! pCompoundParent ) // compound controls have to fix themselves
562 Point aPos( mpBorderWindow->GetPosPixel() );
563 if( mnWidth < aBounds.GetWidth() )
564 aPos.X() -= (aBounds.GetWidth() - mnWidth) / 2;
565 if( mnHeight < aBounds.GetHeight() )
566 aPos.Y() -= (aBounds.GetHeight() - mnHeight) / 2;
567 mpBorderWindow->SetPosSizePixel( aPos, aBounds.GetSize() );
572 else
573 mbNWFBorder = false;
577 if( ! mbNWFBorder )
579 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
580 DrawFrameFlags nFlags = DrawFrameFlags::NoDraw;
581 // move border outside if border was converted or if the BorderWindow is a frame window,
582 if ( mpBorderWindow->mbSmallOutBorder )
583 nStyle = DrawFrameStyle::DoubleOut;
584 else if ( nBorderStyle & WindowBorderStyle::NWF )
585 nStyle = DrawFrameStyle::NWF;
586 else
587 nStyle = DrawFrameStyle::DoubleIn;
588 if ( nBorderStyle & WindowBorderStyle::MONO )
589 nFlags |= DrawFrameFlags::Mono;
591 DecorationView aDecoView( mpOutDev );
592 Rectangle aRect( 0, 0, 10, 10 );
593 Rectangle aCalcRect = aDecoView.DrawFrame( aRect, nStyle, nFlags );
594 mnLeftBorder = aCalcRect.Left();
595 mnTopBorder = aCalcRect.Top();
596 mnRightBorder = aRect.Right()-aCalcRect.Right();
597 mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
601 if (pCtrl)
603 //fdo#57090 If the borders have changed, then trigger a queue_resize on
604 //the bordered window, which will resync its borders at that point
605 if (nOrigLeftBorder != mnLeftBorder ||
606 nOrigTopBorder != mnTopBorder ||
607 nOrigRightBorder != mnRightBorder ||
608 nOrigBottomBorder != mnBottomBorder)
610 pCtrl->queue_resize();
615 void ImplSmallBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
616 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
618 rLeftBorder = mnLeftBorder;
619 rTopBorder = mnTopBorder;
620 rRightBorder = mnRightBorder;
621 rBottomBorder = mnBottomBorder;
624 long ImplSmallBorderWindowView::CalcTitleWidth() const
626 return 0;
629 void ImplSmallBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point*)
631 WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
632 if (nBorderStyle & WindowBorderStyle::NOBORDER)
633 return;
635 bool bNativeOK = false;
636 // for native widget drawing we must find out what
637 // control this border belongs to
638 vcl::Window* pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
640 ControlType aCtrlType = ControlType::Generic;
641 ControlPart aCtrlPart = ControlPart::Entire;
642 if (pCtrl)
644 switch (pCtrl->GetType())
646 case WINDOW_MULTILINEEDIT:
647 aCtrlType = ControlType::MultilineEditbox;
648 break;
649 case WINDOW_EDIT:
650 case WINDOW_PATTERNFIELD:
651 case WINDOW_METRICFIELD:
652 case WINDOW_CURRENCYFIELD:
653 case WINDOW_DATEFIELD:
654 case WINDOW_TIMEFIELD:
655 case WINDOW_LONGCURRENCYFIELD:
656 case WINDOW_NUMERICFIELD:
657 case WINDOW_SPINFIELD:
658 case WINDOW_CALCINPUTLINE:
659 if (pCtrl->GetStyle() & WB_SPIN)
660 aCtrlType = ControlType::Spinbox;
661 else
662 aCtrlType = ControlType::Editbox;
663 break;
665 case WINDOW_LISTBOX:
666 case WINDOW_MULTILISTBOX:
667 case WINDOW_TREELISTBOX:
668 aCtrlType = ControlType::Listbox;
669 if (pCtrl->GetStyle() & WB_DROPDOWN)
670 aCtrlPart = ControlPart::Entire;
671 else
672 aCtrlPart = ControlPart::ListboxWindow;
673 break;
675 case WINDOW_LISTBOXWINDOW:
676 aCtrlType = ControlType::Listbox;
677 aCtrlPart = ControlPart::ListboxWindow;
678 break;
680 case WINDOW_COMBOBOX:
681 case WINDOW_PATTERNBOX:
682 case WINDOW_NUMERICBOX:
683 case WINDOW_METRICBOX:
684 case WINDOW_CURRENCYBOX:
685 case WINDOW_DATEBOX:
686 case WINDOW_TIMEBOX:
687 case WINDOW_LONGCURRENCYBOX:
688 if (pCtrl->GetStyle() & WB_DROPDOWN)
690 aCtrlType = ControlType::Combobox;
691 aCtrlPart = ControlPart::Entire;
693 else
695 aCtrlType = ControlType::Listbox;
696 aCtrlPart = ControlPart::ListboxWindow;
698 break;
700 default:
701 break;
705 if (aCtrlType != ControlType::Generic && pCtrl->IsNativeControlSupported(aCtrlType, aCtrlPart))
707 ImplControlValue aControlValue;
708 ControlState nState = ControlState::ENABLED;
710 if (!mpBorderWindow->IsEnabled())
711 nState &= ~ControlState::ENABLED;
712 if (mpBorderWindow->HasFocus())
713 nState |= ControlState::FOCUSED;
714 else if(mbNWFBorder)
716 // FIXME: this is currently only on OS X, see if other platforms can profit
718 // FIXME: for OS X focus rings all controls need to support GetNativeControlRegion
719 // for the dropdown style
720 if (pCtrl->HasFocus() || pCtrl->HasChildPathFocus())
721 nState |= ControlState::FOCUSED;
724 bool bMouseOver = false;
725 vcl::Window *pCtrlChild = pCtrl->GetWindow(GetWindowType::FirstChild);
726 while(pCtrlChild && !(bMouseOver = pCtrlChild->IsMouseOver()))
728 pCtrlChild = pCtrlChild->GetWindow(GetWindowType::Next);
731 if (bMouseOver)
732 nState |= ControlState::ROLLOVER;
734 Point aPoint;
735 Rectangle aCtrlRegion(aPoint, Size(mnWidth, mnHeight));
737 Rectangle aBoundingRgn(aPoint, Size(mnWidth, mnHeight));
738 Rectangle aContentRgn(aCtrlRegion);
739 if (!ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize &&
740 rRenderContext.GetNativeControlRegion(aCtrlType, aCtrlPart, aCtrlRegion,
741 nState, aControlValue, OUString(),
742 aBoundingRgn, aContentRgn))
744 aCtrlRegion=aContentRgn;
747 bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, aCtrlPart, aCtrlRegion, nState, aControlValue, OUString());
749 // if the native theme draws the spinbuttons in one call, make sure the proper settings
750 // are passed, this might force a redraw though.... (TODO: improve)
751 if ((aCtrlType == ControlType::Spinbox) && !pCtrl->IsNativeControlSupported(ControlType::Spinbox, ControlPart::ButtonUp))
753 Edit* pEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
754 if (pEdit && !pEdit->SupportsDoubleBuffering())
755 pCtrl->Paint(*pCtrl, Rectangle()); // make sure the buttons are also drawn as they might overwrite the border
759 if (bNativeOK)
760 return;
762 DrawFrameStyle nStyle = DrawFrameStyle::NONE;
763 DrawFrameFlags nFlags = DrawFrameFlags::NONE;
764 // move border outside if border was converted or if the border window is a frame window,
765 if (mpBorderWindow->mbSmallOutBorder)
766 nStyle = DrawFrameStyle::DoubleOut;
767 else if (nBorderStyle & WindowBorderStyle::NWF)
768 nStyle = DrawFrameStyle::NWF;
769 else
770 nStyle = DrawFrameStyle::DoubleIn;
771 if (nBorderStyle & WindowBorderStyle::MONO)
772 nFlags |= DrawFrameFlags::Mono;
773 if (nBorderStyle & WindowBorderStyle::MENU)
774 nFlags |= DrawFrameFlags::Menu;
775 // tell DrawFrame that we're drawing a window border of a frame window to avoid round corners
776 if (mpBorderWindow == mpBorderWindow->ImplGetFrameWindow())
777 nFlags |= DrawFrameFlags::WindowBorder;
779 DecorationView aDecoView(&rRenderContext);
780 Point aTmpPoint;
781 Rectangle aInRect(aTmpPoint, Size(mnWidth, mnHeight));
782 aDecoView.DrawFrame(aInRect, nStyle, nFlags);
786 ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
788 maFrameData.mpBorderWindow = pBorderWindow;
789 maFrameData.mbDragFull = false;
790 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
791 maFrameData.mnPinState = DrawButtonFlags::NONE;
792 maFrameData.mnCloseState = DrawButtonFlags::NONE;
793 maFrameData.mnRollState = DrawButtonFlags::NONE;
794 maFrameData.mnDockState = DrawButtonFlags::NONE;
795 maFrameData.mnMenuState = DrawButtonFlags::NONE;
796 maFrameData.mnHideState = DrawButtonFlags::NONE;
797 maFrameData.mnHelpState = DrawButtonFlags::NONE;
798 maFrameData.mbTitleClipped = false;
800 mpATitleVirDev = nullptr;
801 mpDTitleVirDev = nullptr;
804 ImplStdBorderWindowView::~ImplStdBorderWindowView()
806 mpATitleVirDev.disposeAndClear();
807 mpDTitleVirDev.disposeAndClear();
810 bool ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
812 return ImplMouseMove( &maFrameData, rMEvt );
815 bool ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
817 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
819 if ( rMEvt.IsLeft() || rMEvt.IsRight() )
821 maFrameData.maMouseOff = rMEvt.GetPosPixel();
822 maFrameData.mnHitTest = ImplHitTest( &maFrameData, maFrameData.maMouseOff );
823 if ( maFrameData.mnHitTest != BorderWindowHitTest::NONE )
825 DragFullOptions nDragFullTest = DragFullOptions::NONE;
826 bool bTracking = true;
827 bool bHitTest = true;
829 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
831 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
832 pBorderWindow->InvalidateBorder();
834 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Roll )
836 maFrameData.mnRollState |= DrawButtonFlags::Pressed;
837 pBorderWindow->InvalidateBorder();
839 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
841 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
842 pBorderWindow->InvalidateBorder();
844 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
846 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
847 pBorderWindow->InvalidateBorder();
849 // call handler already on mouse down
850 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
852 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
853 pClientWindow->TitleButtonClick( TitleButton::Menu );
856 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
858 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
859 pBorderWindow->InvalidateBorder();
861 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
863 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
864 pBorderWindow->InvalidateBorder();
866 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Pin )
868 maFrameData.mnPinState |= DrawButtonFlags::Pressed;
869 pBorderWindow->InvalidateBorder();
871 else
873 if ( rMEvt.GetClicks() == 1 )
875 if ( bTracking )
877 Point aPos = pBorderWindow->GetPosPixel();
878 Size aSize = pBorderWindow->GetOutputSizePixel();
879 maFrameData.mnTrackX = aPos.X();
880 maFrameData.mnTrackY = aPos.Y();
881 maFrameData.mnTrackWidth = aSize.Width();
882 maFrameData.mnTrackHeight = aSize.Height();
884 if ( maFrameData.mnHitTest & BorderWindowHitTest::Title )
885 nDragFullTest = DragFullOptions::WindowMove;
886 else
887 nDragFullTest = DragFullOptions::WindowSize;
890 else
892 bTracking = false;
894 if ( (maFrameData.mnHitTest & BorderWindowHitTest::Title) &&
895 ((rMEvt.GetClicks() % 2) == 0) )
897 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
898 bHitTest = false;
900 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
902 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
903 if ( true /*pBorderWindow->mbDockBtn*/ ) // always perform docking on double click, no button required
904 pClientWindow->TitleButtonClick( TitleButton::Docking );
905 else if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
907 if ( pClientWindow->IsRollUp() )
908 pClientWindow->RollDown();
909 else
910 pClientWindow->RollUp();
917 if ( bTracking )
919 maFrameData.mbDragFull = false;
920 if ( nDragFullTest != DragFullOptions::NONE )
921 maFrameData.mbDragFull = true; // always fulldrag for proper docking, ignore system settings
922 pBorderWindow->StartTracking();
924 else if ( bHitTest )
925 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
929 return true;
932 bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
934 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
936 if ( rTEvt.IsTrackingEnded() )
938 BorderWindowHitTest nHitTest = maFrameData.mnHitTest;
939 maFrameData.mnHitTest = BorderWindowHitTest::NONE;
941 if ( nHitTest & BorderWindowHitTest::Close )
943 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
945 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
946 pBorderWindow->InvalidateBorder();
948 // do not call a Click-Handler when aborting
949 if ( !rTEvt.IsTrackingCanceled() )
951 // dispatch to correct window type (why is Close() not virtual ??? )
952 // TODO: make Close() virtual
953 VclPtr<vcl::Window> pWin = pBorderWindow->ImplGetClientWindow()->ImplGetWindow();
954 SystemWindow *pSysWin = dynamic_cast<SystemWindow* >(pWin.get());
955 DockingWindow *pDockWin = dynamic_cast<DockingWindow*>(pWin.get());
956 if ( pSysWin )
957 pSysWin->Close();
958 else if ( pDockWin )
959 pDockWin->Close();
963 else if ( nHitTest & BorderWindowHitTest::Roll )
965 if ( maFrameData.mnRollState & DrawButtonFlags::Pressed )
967 maFrameData.mnRollState &= ~DrawButtonFlags::Pressed;
968 pBorderWindow->InvalidateBorder();
970 // do not call a Click-Handler when aborting
971 if ( !rTEvt.IsTrackingCanceled() )
973 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
975 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
976 if ( pClientWindow->IsRollUp() )
977 pClientWindow->RollDown();
978 else
979 pClientWindow->RollUp();
984 else if ( nHitTest & BorderWindowHitTest::Dock )
986 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
988 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
989 pBorderWindow->InvalidateBorder();
991 // do not call a Click-Handler when aborting
992 if ( !rTEvt.IsTrackingCanceled() )
994 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
996 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
997 pClientWindow->TitleButtonClick( TitleButton::Docking );
1002 else if ( nHitTest & BorderWindowHitTest::Menu )
1004 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
1006 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
1007 pBorderWindow->InvalidateBorder();
1009 // handler already called on mouse down
1012 else if ( nHitTest & BorderWindowHitTest::Hide )
1014 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
1016 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
1017 pBorderWindow->InvalidateBorder();
1019 // do not call a Click-Handler when aborting
1020 if ( !rTEvt.IsTrackingCanceled() )
1022 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
1024 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
1025 pClientWindow->TitleButtonClick( TitleButton::Hide );
1030 else if ( nHitTest & BorderWindowHitTest::Help )
1032 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
1034 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
1035 pBorderWindow->InvalidateBorder();
1037 // do not call a Click-Handler when aborting
1038 if ( !rTEvt.IsTrackingCanceled() )
1043 else if ( nHitTest & BorderWindowHitTest::Pin )
1045 if ( maFrameData.mnPinState & DrawButtonFlags::Pressed )
1047 maFrameData.mnPinState &= ~DrawButtonFlags::Pressed;
1048 pBorderWindow->InvalidateBorder();
1050 // do not call a Click-Handler when aborting
1051 if ( !rTEvt.IsTrackingCanceled() )
1053 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
1055 SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
1056 pClientWindow->SetPin( !pClientWindow->IsPinned() );
1061 else
1063 if ( maFrameData.mbDragFull )
1065 // restore old state when aborting
1066 if ( rTEvt.IsTrackingCanceled() )
1067 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
1069 else
1071 pBorderWindow->HideTracking();
1072 if ( !rTEvt.IsTrackingCanceled() )
1073 pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
1076 if ( !rTEvt.IsTrackingCanceled() )
1078 if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
1080 if ( static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
1081 static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->EndPopupMode( FloatWinPopupEndFlags::TearOff );
1086 else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
1088 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
1090 if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
1092 if ( maFrameData.maCloseRect.IsInside( aMousePos ) )
1094 if ( !(maFrameData.mnCloseState & DrawButtonFlags::Pressed) )
1096 maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
1097 pBorderWindow->InvalidateBorder();
1100 else
1102 if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
1104 maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
1105 pBorderWindow->InvalidateBorder();
1109 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Roll )
1111 if ( maFrameData.maRollRect.IsInside( aMousePos ) )
1113 if ( !(maFrameData.mnRollState & DrawButtonFlags::Pressed) )
1115 maFrameData.mnRollState |= DrawButtonFlags::Pressed;
1116 pBorderWindow->InvalidateBorder();
1119 else
1121 if ( maFrameData.mnRollState & DrawButtonFlags::Pressed )
1123 maFrameData.mnRollState &= ~DrawButtonFlags::Pressed;
1124 pBorderWindow->InvalidateBorder();
1128 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
1130 if ( maFrameData.maDockRect.IsInside( aMousePos ) )
1132 if ( !(maFrameData.mnDockState & DrawButtonFlags::Pressed) )
1134 maFrameData.mnDockState |= DrawButtonFlags::Pressed;
1135 pBorderWindow->InvalidateBorder();
1138 else
1140 if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
1142 maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
1143 pBorderWindow->InvalidateBorder();
1147 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
1149 if ( maFrameData.maMenuRect.IsInside( aMousePos ) )
1151 if ( !(maFrameData.mnMenuState & DrawButtonFlags::Pressed) )
1153 maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
1154 pBorderWindow->InvalidateBorder();
1157 else
1159 if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
1161 maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
1162 pBorderWindow->InvalidateBorder();
1166 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
1168 if ( maFrameData.maHideRect.IsInside( aMousePos ) )
1170 if ( !(maFrameData.mnHideState & DrawButtonFlags::Pressed) )
1172 maFrameData.mnHideState |= DrawButtonFlags::Pressed;
1173 pBorderWindow->InvalidateBorder();
1176 else
1178 if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
1180 maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
1181 pBorderWindow->InvalidateBorder();
1185 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
1187 if ( maFrameData.maHelpRect.IsInside( aMousePos ) )
1189 if ( !(maFrameData.mnHelpState & DrawButtonFlags::Pressed) )
1191 maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
1192 pBorderWindow->InvalidateBorder();
1195 else
1197 if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
1199 maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
1200 pBorderWindow->InvalidateBorder();
1204 else if ( maFrameData.mnHitTest & BorderWindowHitTest::Pin )
1206 if ( maFrameData.maPinRect.IsInside( aMousePos ) )
1208 if ( !(maFrameData.mnPinState & DrawButtonFlags::Pressed) )
1210 maFrameData.mnPinState |= DrawButtonFlags::Pressed;
1211 pBorderWindow->InvalidateBorder();
1214 else
1216 if ( maFrameData.mnPinState & DrawButtonFlags::Pressed )
1218 maFrameData.mnPinState &= ~DrawButtonFlags::Pressed;
1219 pBorderWindow->InvalidateBorder();
1223 else
1225 aMousePos.X() -= maFrameData.maMouseOff.X();
1226 aMousePos.Y() -= maFrameData.maMouseOff.Y();
1228 if ( maFrameData.mnHitTest & BorderWindowHitTest::Title )
1230 maFrameData.mpBorderWindow->SetPointer( Pointer( PointerStyle::Move ) );
1232 Point aPos = pBorderWindow->GetPosPixel();
1233 aPos.X() += aMousePos.X();
1234 aPos.Y() += aMousePos.Y();
1235 if ( maFrameData.mbDragFull )
1237 pBorderWindow->SetPosPixel( aPos );
1238 pBorderWindow->ImplUpdateAll();
1239 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1241 else
1243 maFrameData.mnTrackX = aPos.X();
1244 maFrameData.mnTrackY = aPos.Y();
1245 pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), ShowTrackFlags::Big );
1248 else
1250 Point aOldPos = pBorderWindow->GetPosPixel();
1251 Size aSize = pBorderWindow->GetSizePixel();
1252 Rectangle aNewRect( aOldPos, aSize );
1253 long nOldWidth = aSize.Width();
1254 long nOldHeight = aSize.Height();
1255 long nBorderWidth = maFrameData.mnLeftBorder+maFrameData.mnRightBorder;
1256 long nBorderHeight = maFrameData.mnTopBorder+maFrameData.mnBottomBorder;
1257 long nMinWidth = pBorderWindow->mnMinWidth+nBorderWidth;
1258 long nMinHeight = pBorderWindow->mnMinHeight+nBorderHeight;
1259 long nMinWidth2 = nBorderWidth;
1260 long nMaxWidth = pBorderWindow->mnMaxWidth+nBorderWidth;
1261 long nMaxHeight = pBorderWindow->mnMaxHeight+nBorderHeight;
1263 if ( maFrameData.mnTitleHeight )
1265 nMinWidth2 += 4;
1267 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1268 nMinWidth2 += maFrameData.maCloseRect.GetWidth();
1270 if ( nMinWidth2 > nMinWidth )
1271 nMinWidth = nMinWidth2;
1272 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1274 aNewRect.Left() += aMousePos.X();
1275 if ( aNewRect.GetWidth() < nMinWidth )
1276 aNewRect.Left() = aNewRect.Right()-nMinWidth+1;
1277 else if ( aNewRect.GetWidth() > nMaxWidth )
1278 aNewRect.Left() = aNewRect.Right()-nMaxWidth+1;
1280 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1282 aNewRect.Right() += aMousePos.X();
1283 if ( aNewRect.GetWidth() < nMinWidth )
1284 aNewRect.Right() = aNewRect.Left()+nMinWidth+1;
1285 else if ( aNewRect.GetWidth() > nMaxWidth )
1286 aNewRect.Right() = aNewRect.Left()+nMaxWidth+1;
1288 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1290 aNewRect.Top() += aMousePos.Y();
1291 if ( aNewRect.GetHeight() < nMinHeight )
1292 aNewRect.Top() = aNewRect.Bottom()-nMinHeight+1;
1293 else if ( aNewRect.GetHeight() > nMaxHeight )
1294 aNewRect.Top() = aNewRect.Bottom()-nMaxHeight+1;
1296 else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1298 aNewRect.Bottom() += aMousePos.Y();
1299 if ( aNewRect.GetHeight() < nMinHeight )
1300 aNewRect.Bottom() = aNewRect.Top()+nMinHeight+1;
1301 else if ( aNewRect.GetHeight() > nMaxHeight )
1302 aNewRect.Bottom() = aNewRect.Top()+nMaxHeight+1;
1305 // call Resizing-Handler for SystemWindows
1306 if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
1308 // adjust size for Resizing-call
1309 aSize = aNewRect.GetSize();
1310 aSize.Width() -= nBorderWidth;
1311 aSize.Height() -= nBorderHeight;
1312 static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
1313 aSize.Width() += nBorderWidth;
1314 aSize.Height() += nBorderHeight;
1315 if ( aSize.Width() < nMinWidth )
1316 aSize.Width() = nMinWidth;
1317 if ( aSize.Height() < nMinHeight )
1318 aSize.Height() = nMinHeight;
1319 if ( aSize.Width() > nMaxWidth )
1320 aSize.Width() = nMaxWidth;
1321 if ( aSize.Height() > nMaxHeight )
1322 aSize.Height() = nMaxHeight;
1323 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
1324 aNewRect.Left() = aNewRect.Right()-aSize.Width()+1;
1325 else
1326 aNewRect.Right() = aNewRect.Left()+aSize.Width()-1;
1327 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
1328 aNewRect.Top() = aNewRect.Bottom()-aSize.Height()+1;
1329 else
1330 aNewRect.Bottom() = aNewRect.Top()+aSize.Height()-1;
1333 if ( maFrameData.mbDragFull )
1335 // no move (only resize) if position did not change
1336 if( aOldPos != aNewRect.TopLeft() )
1337 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1338 aNewRect.GetWidth(), aNewRect.GetHeight() );
1339 else
1340 pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
1341 aNewRect.GetWidth(), aNewRect.GetHeight(), PosSizeFlags::Size );
1343 pBorderWindow->ImplUpdateAll();
1344 pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
1345 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
1346 maFrameData.maMouseOff.X() += aNewRect.GetWidth()-nOldWidth;
1347 if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
1348 maFrameData.maMouseOff.Y() += aNewRect.GetHeight()-nOldHeight;
1350 else
1352 maFrameData.mnTrackX = aNewRect.Left();
1353 maFrameData.mnTrackY = aNewRect.Top();
1354 maFrameData.mnTrackWidth = aNewRect.GetWidth();
1355 maFrameData.mnTrackHeight = aNewRect.GetHeight();
1356 pBorderWindow->ShowTracking( Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), ShowTrackFlags::Big );
1362 return true;
1365 OUString ImplStdBorderWindowView::RequestHelp( const Point& rPos, Rectangle& rHelpRect )
1367 return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
1370 Rectangle ImplStdBorderWindowView::GetMenuRect() const
1372 return maFrameData.maMenuRect;
1375 void ImplStdBorderWindowView::Init( OutputDevice* pDev, long nWidth, long nHeight )
1377 ImplBorderFrameData* pData = &maFrameData;
1378 ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
1379 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
1380 DecorationView aDecoView( pDev );
1381 Rectangle aRect( 0, 0, 10, 10 );
1382 Rectangle aCalcRect = aDecoView.DrawFrame( aRect, DrawFrameStyle::DoubleOut, DrawFrameFlags::NoDraw );
1384 pData->mpOutDev = pDev;
1385 pData->mnWidth = nWidth;
1386 pData->mnHeight = nHeight;
1388 pData->mnTitleType = pBorderWindow->mnTitleType;
1389 pData->mbFloatWindow = pBorderWindow->mbFloatWindow;
1391 if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) || (pData->mnTitleType == BorderWindowTitleType::NONE) )
1392 pData->mnBorderSize = 0;
1393 else if ( pData->mnTitleType == BorderWindowTitleType::Tearoff )
1394 pData->mnBorderSize = 0;
1395 else
1396 pData->mnBorderSize = rStyleSettings.GetBorderSize();
1397 pData->mnLeftBorder = aCalcRect.Left();
1398 pData->mnTopBorder = aCalcRect.Top();
1399 pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
1400 pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
1401 pData->mnLeftBorder += pData->mnBorderSize;
1402 pData->mnTopBorder += pData->mnBorderSize;
1403 pData->mnRightBorder += pData->mnBorderSize;
1404 pData->mnBottomBorder += pData->mnBorderSize;
1405 pData->mnNoTitleTop = pData->mnTopBorder;
1407 ImplInitTitle(&maFrameData);
1408 if (pData->mnTitleHeight)
1410 // to improve symbol display force a minimum title height
1411 if( pData->mnTitleHeight < MIN_CAPTION_HEIGHT )
1412 pData->mnTitleHeight = MIN_CAPTION_HEIGHT;
1414 // set a proper background for drawing
1415 // highlighted buttons in the title
1416 pBorderWindow->SetBackground( rStyleSettings.GetFaceColor() );
1418 pData->maTitleRect.Left() = pData->mnLeftBorder;
1419 pData->maTitleRect.Right() = nWidth-pData->mnRightBorder-1;
1420 pData->maTitleRect.Top() = pData->mnTopBorder;
1421 pData->maTitleRect.Bottom() = pData->maTitleRect.Top()+pData->mnTitleHeight-1;
1423 if ( pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small) )
1425 long nLeft = pData->maTitleRect.Left() + 1;
1426 long nRight = pData->maTitleRect.Right() - 3;
1427 long const nItemTop = pData->maTitleRect.Top() + 2;
1428 long const nItemBottom = pData->maTitleRect.Bottom() - 2;
1430 auto addOnLeft = [&nLeft, nItemTop, nItemBottom](
1431 Rectangle & rect, long width, long gap)
1433 rect.Top() = nItemTop;
1434 rect.Bottom() = nItemBottom;
1435 rect.Left() = nLeft;
1436 rect.Right() = rect.Left() + width;
1437 nLeft += rect.GetWidth() + gap;
1439 auto addSquareOnRight = [&nRight, nItemTop, nItemBottom](
1440 Rectangle & rect, long gap)
1442 rect.Top() = nItemTop;
1443 rect.Bottom() = nItemBottom;
1444 rect.Right() = nRight;
1445 rect.Left() = rect.Right() - rect.GetHeight() + 1;
1446 nRight -= rect.GetWidth() + gap;
1449 if ( pBorderWindow->GetStyle() & WB_PINABLE )
1451 Image aImage;
1452 ImplGetPinImage( DrawButtonFlags::NONE, false, aImage );
1453 addOnLeft(pData->maPinRect, aImage.GetSizePixel().Width(), 3);
1456 if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
1458 addSquareOnRight(pData->maCloseRect, 3);
1461 if ( pBorderWindow->mbMenuBtn )
1463 addSquareOnRight(pData->maMenuRect, 0);
1466 if ( pBorderWindow->mbDockBtn )
1468 addSquareOnRight(pData->maDockRect, 0);
1471 if ( pBorderWindow->mbHideBtn )
1473 addSquareOnRight(pData->maHideRect, 0);
1476 if ( pBorderWindow->GetStyle() & WB_ROLLABLE )
1478 addSquareOnRight(pData->maRollRect, 0);
1481 else
1483 pData->maPinRect.SetEmpty();
1484 pData->maCloseRect.SetEmpty();
1485 pData->maDockRect.SetEmpty();
1486 pData->maMenuRect.SetEmpty();
1487 pData->maHideRect.SetEmpty();
1488 pData->maRollRect.SetEmpty();
1489 pData->maHelpRect.SetEmpty();
1492 pData->mnTopBorder += pData->mnTitleHeight;
1494 else
1496 pData->maTitleRect.SetEmpty();
1497 pData->maPinRect.SetEmpty();
1498 pData->maCloseRect.SetEmpty();
1499 pData->maDockRect.SetEmpty();
1500 pData->maMenuRect.SetEmpty();
1501 pData->maHideRect.SetEmpty();
1502 pData->maRollRect.SetEmpty();
1503 pData->maHelpRect.SetEmpty();
1507 void ImplStdBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
1508 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
1510 rLeftBorder = maFrameData.mnLeftBorder;
1511 rTopBorder = maFrameData.mnTopBorder;
1512 rRightBorder = maFrameData.mnRightBorder;
1513 rBottomBorder = maFrameData.mnBottomBorder;
1516 long ImplStdBorderWindowView::CalcTitleWidth() const
1518 return ImplCalcTitleWidth( &maFrameData );
1521 void ImplStdBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point* pOffset)
1523 ImplBorderFrameData* pData = &maFrameData;
1524 ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
1525 Point aTmpPoint = pOffset ? Point(*pOffset) : Point();
1526 Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
1527 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1528 DecorationView aDecoView(&rRenderContext);
1529 Color aFaceColor(rStyleSettings.GetFaceColor());
1530 Color aFrameColor(aFaceColor);
1532 aFrameColor.DecreaseContrast(sal_uInt8(0.5 * 255));
1534 // Draw Frame
1535 vcl::Region oldClipRgn(rRenderContext.GetClipRegion());
1537 // for popups, don't draw part of the frame
1538 if (pData->mnTitleType == BorderWindowTitleType::Popup)
1540 FloatingWindow* pWin = dynamic_cast<FloatingWindow*>(pData->mpBorderWindow->GetWindow(GetWindowType::Client));
1541 if (pWin)
1543 vcl::Region aClipRgn(aInRect);
1544 Rectangle aItemClipRect(pWin->ImplGetItemEdgeClipRect());
1545 if (!aItemClipRect.IsEmpty())
1547 aItemClipRect.SetPos(pData->mpBorderWindow->AbsoluteScreenToOutputPixel(aItemClipRect.TopLeft()));
1548 aClipRgn.Exclude(aItemClipRect);
1549 rRenderContext.SetClipRegion(aClipRgn);
1554 // single line frame
1555 rRenderContext.SetLineColor(aFrameColor);
1556 rRenderContext.SetFillColor();
1557 rRenderContext.DrawRect(aInRect);
1558 ++aInRect.Left();
1559 --aInRect.Right();
1560 ++aInRect.Top();
1561 --aInRect.Bottom();
1563 // restore
1564 if (pData->mnTitleType == BorderWindowTitleType::Popup)
1565 rRenderContext.SetClipRegion(oldClipRgn);
1567 // Draw Border
1568 rRenderContext.SetLineColor();
1569 long nBorderSize = pData->mnBorderSize;
1570 if (nBorderSize)
1572 rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
1573 rRenderContext.DrawRect(Rectangle(Point(aInRect.Left(), aInRect.Top()),
1574 Size(aInRect.GetWidth(), nBorderSize)));
1575 rRenderContext.DrawRect(Rectangle(Point(aInRect.Left(), aInRect.Top() + nBorderSize),
1576 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1577 rRenderContext.DrawRect(Rectangle(Point(aInRect.Left(), aInRect.Bottom() - nBorderSize + 1),
1578 Size(aInRect.GetWidth(), nBorderSize)));
1579 rRenderContext.DrawRect(Rectangle(Point(aInRect.Right()-nBorderSize + 1, aInRect.Top() + nBorderSize),
1580 Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
1583 // Draw Title
1584 if (!pData->maTitleRect.IsEmpty())
1586 aInRect = pData->maTitleRect;
1588 // use no gradient anymore, just a static titlecolor
1589 if (pData->mnTitleType != BorderWindowTitleType::Popup)
1590 rRenderContext.SetFillColor(aFrameColor);
1591 else
1592 rRenderContext.SetFillColor(aFaceColor);
1594 rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
1595 Rectangle aTitleRect(pData->maTitleRect);
1596 if(pOffset)
1597 aTitleRect.Move(pOffset->X(), pOffset->Y());
1598 rRenderContext.DrawRect(aTitleRect);
1600 if (pData->mnTitleType != BorderWindowTitleType::Tearoff)
1602 aInRect.Left() += 2;
1603 aInRect.Right() -= 2;
1605 if (!pData->maPinRect.IsEmpty())
1606 aInRect.Left() = pData->maPinRect.Right() + 2;
1608 if (!pData->maHelpRect.IsEmpty())
1609 aInRect.Right() = pData->maHelpRect.Left() - 2;
1610 else if (!pData->maRollRect.IsEmpty())
1611 aInRect.Right() = pData->maRollRect.Left() - 2;
1612 else if (!pData->maHideRect.IsEmpty())
1613 aInRect.Right() = pData->maHideRect.Left() - 2;
1614 else if (!pData->maDockRect.IsEmpty())
1615 aInRect.Right() = pData->maDockRect.Left() - 2;
1616 else if (!pData->maMenuRect.IsEmpty())
1617 aInRect.Right() = pData->maMenuRect.Left() - 2;
1618 else if (!pData->maCloseRect.IsEmpty())
1619 aInRect.Right() = pData->maCloseRect.Left() - 2;
1621 if (pOffset)
1622 aInRect.Move(pOffset->X(), pOffset->Y());
1624 DrawTextFlags nTextStyle = DrawTextFlags::Left | DrawTextFlags::VCenter | DrawTextFlags::EndEllipsis | DrawTextFlags::Clip;
1626 // must show tooltip ?
1627 TextRectInfo aInfo;
1628 rRenderContext.GetTextRect(aInRect, pBorderWindow->GetText(), nTextStyle, &aInfo);
1629 pData->mbTitleClipped = aInfo.IsEllipses();
1631 rRenderContext.DrawText(aInRect, pBorderWindow->GetText(), nTextStyle);
1635 if (!pData->maCloseRect.IsEmpty())
1637 Rectangle aSymbolRect(pData->maCloseRect);
1638 if (pOffset)
1639 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1640 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::CLOSE, pData->mnCloseState);
1642 if (!pData->maDockRect.IsEmpty())
1644 Rectangle aSymbolRect(pData->maDockRect);
1645 if (pOffset)
1646 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1647 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::DOCK, pData->mnDockState);
1649 if (!pData->maMenuRect.IsEmpty())
1651 Rectangle aSymbolRect(pData->maMenuRect);
1652 if (pOffset)
1653 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1654 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::MENU, pData->mnMenuState);
1656 if (!pData->maHideRect.IsEmpty())
1658 Rectangle aSymbolRect(pData->maHideRect);
1659 if (pOffset)
1660 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1661 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HIDE, pData->mnHideState);
1663 if (!pData->maRollRect.IsEmpty())
1665 SymbolType eType;
1666 if (pBorderWindow->mbRollUp)
1667 eType = SymbolType::ROLLDOWN;
1668 else
1669 eType = SymbolType::ROLLUP;
1670 Rectangle aSymbolRect(pData->maRollRect);
1671 if (pOffset)
1672 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1673 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, eType, pData->mnRollState);
1676 if (!pData->maHelpRect.IsEmpty())
1678 Rectangle aSymbolRect(pData->maHelpRect);
1679 if (pOffset)
1680 aSymbolRect.Move(pOffset->X(), pOffset->Y());
1681 ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HELP, pData->mnHelpState);
1683 if (!pData->maPinRect.IsEmpty())
1685 Image aImage;
1686 ImplGetPinImage(pData->mnPinState, pBorderWindow->mbPinned, aImage);
1687 Size aImageSize = aImage.GetSizePixel();
1688 long nRectHeight = pData->maPinRect.GetHeight();
1689 Point aPos(pData->maPinRect.TopLeft());
1690 if (pOffset)
1691 aPos.Move(pOffset->X(), pOffset->Y());
1692 if (nRectHeight < aImageSize.Height())
1694 rRenderContext.DrawImage(aPos, Size( aImageSize.Width(), nRectHeight ), aImage);
1696 else
1698 aPos.Y() += (nRectHeight-aImageSize.Height()) / 2;
1699 rRenderContext.DrawImage(aPos, aImage);
1704 void ImplBorderWindow::ImplInit( vcl::Window* pParent,
1705 WinBits nStyle, BorderWindowStyle nTypeStyle,
1706 SystemParentData* pSystemParentData
1709 // remove all unwanted WindowBits
1710 WinBits nOrgStyle = nStyle;
1711 WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_PINABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_POPUP);
1712 if ( nTypeStyle & BorderWindowStyle::App )
1713 nTestStyle |= WB_APP;
1714 nStyle &= nTestStyle;
1716 mpWindowImpl->mbBorderWin = true;
1717 mbSmallOutBorder = false;
1718 if ( nTypeStyle & BorderWindowStyle::Frame )
1720 if( (nStyle & WB_SYSTEMCHILDWINDOW) )
1722 mpWindowImpl->mbOverlapWin = true;
1723 mpWindowImpl->mbFrame = true;
1724 mbFrameBorder = false;
1726 else if( (nStyle & (WB_OWNERDRAWDECORATION | WB_POPUP)) )
1728 mpWindowImpl->mbOverlapWin = true;
1729 mpWindowImpl->mbFrame = true;
1730 mbFrameBorder = (nOrgStyle & WB_NOBORDER) == 0;
1732 else
1734 mpWindowImpl->mbOverlapWin = true;
1735 mpWindowImpl->mbFrame = true;
1736 mbFrameBorder = false;
1737 // closeable windows may have a border as well, eg. system floating windows without caption
1738 if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE/* | WB_CLOSEABLE*/)) == WB_BORDER )
1739 mbSmallOutBorder = true;
1742 else if ( nTypeStyle & BorderWindowStyle::Overlap )
1744 mpWindowImpl->mbOverlapWin = true;
1745 mbFrameBorder = true;
1747 else
1748 mbFrameBorder = false;
1750 if ( nTypeStyle & BorderWindowStyle::Float )
1751 mbFloatWindow = true;
1752 else
1753 mbFloatWindow = false;
1755 Window::ImplInit( pParent, nStyle, pSystemParentData );
1756 SetBackground();
1757 SetTextFillColor();
1759 mpMenuBarWindow = nullptr;
1760 mnMinWidth = 0;
1761 mnMinHeight = 0;
1762 mnMaxWidth = SHRT_MAX;
1763 mnMaxHeight = SHRT_MAX;
1764 mnRollHeight = 0;
1765 mnOrgMenuHeight = 0;
1766 mbPinned = false;
1767 mbRollUp = false;
1768 mbMenuHide = false;
1769 mbDockBtn = false;
1770 mbMenuBtn = false;
1771 mbHideBtn = false;
1772 mbDisplayActive = IsActive();
1774 if ( nTypeStyle & BorderWindowStyle::Float )
1775 mnTitleType = BorderWindowTitleType::Small;
1776 else
1777 mnTitleType = BorderWindowTitleType::Normal;
1778 mnBorderStyle = WindowBorderStyle::NORMAL;
1779 InitView();
1782 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent,
1783 SystemParentData* pSystemParentData,
1784 WinBits nStyle, BorderWindowStyle nTypeStyle
1785 ) : Window( WINDOW_BORDERWINDOW )
1787 ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
1790 ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent, WinBits nStyle ,
1791 BorderWindowStyle nTypeStyle ) :
1792 Window( WINDOW_BORDERWINDOW )
1794 ImplInit( pParent, nStyle, nTypeStyle, nullptr );
1797 ImplBorderWindow::~ImplBorderWindow()
1799 disposeOnce();
1802 void ImplBorderWindow::dispose()
1804 delete mpBorderView;
1805 mpBorderView = nullptr;
1806 mpMenuBarWindow.clear();
1807 mpNotebookBar.disposeAndClear();
1808 vcl::Window::dispose();
1811 void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
1813 if (mpBorderView)
1814 mpBorderView->MouseMove( rMEvt );
1817 void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
1819 if (mpBorderView)
1820 mpBorderView->MouseButtonDown( rMEvt );
1823 void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
1825 if (mpBorderView)
1826 mpBorderView->Tracking( rTEvt );
1829 void ImplBorderWindow::Paint( vcl::RenderContext& rRenderContext, const Rectangle& )
1831 if (mpBorderView)
1832 mpBorderView->DrawWindow(rRenderContext);
1835 void ImplBorderWindow::Draw( const Rectangle&, OutputDevice* pOutDev, const Point& rPos )
1837 if (mpBorderView)
1838 mpBorderView->DrawWindow(*pOutDev, &rPos);
1841 void ImplBorderWindow::Activate()
1843 SetDisplayActive( true );
1844 Window::Activate();
1847 void ImplBorderWindow::Deactivate()
1849 // remove active windows from the ruler, also ignore the Deactivate
1850 // if a menu becomes active
1851 if ( GetActivateMode() != ActivateModeFlags::NONE && !ImplGetSVData()->maWinData.mbNoDeactivate )
1852 SetDisplayActive( false );
1853 Window::Deactivate();
1856 void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
1858 // no keyboard help for border window
1859 if ( rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK) && !rHEvt.KeyboardActivated() )
1861 Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
1862 Rectangle aHelpRect;
1863 OUString aHelpStr( mpBorderView->RequestHelp( aMousePosPixel, aHelpRect ) );
1865 // retrieve rectangle
1866 if ( !aHelpStr.isEmpty() )
1868 aHelpRect.SetPos( OutputToScreenPixel( aHelpRect.TopLeft() ) );
1869 if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
1870 Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aHelpStr );
1871 else
1872 Help::ShowQuickHelp( this, aHelpRect, aHelpStr );
1873 return;
1877 Window::RequestHelp( rHEvt );
1880 void ImplBorderWindow::Resize()
1882 Size aSize = GetOutputSizePixel();
1884 if ( !mbRollUp )
1886 vcl::Window* pClientWindow = ImplGetClientWindow();
1888 sal_Int32 nLeftBorder;
1889 sal_Int32 nTopBorder;
1890 sal_Int32 nRightBorder;
1891 sal_Int32 nBottomBorder;
1892 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
1894 if (mpMenuBarWindow)
1896 long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
1897 if ( mbMenuHide )
1899 if ( nMenuHeight )
1900 mnOrgMenuHeight = nMenuHeight;
1901 nMenuHeight = 0;
1903 else
1905 if ( !nMenuHeight )
1906 nMenuHeight = mnOrgMenuHeight;
1908 mpMenuBarWindow->setPosSizePixel(
1909 nLeftBorder, nTopBorder,
1910 aSize.Width()-nLeftBorder-nRightBorder,
1911 nMenuHeight);
1913 // shift the notebookbar down accordingly
1914 nTopBorder += nMenuHeight;
1917 if (mpNotebookBar)
1919 long nNotebookBarHeight = mpNotebookBar->GetSizePixel().Height();
1920 mpNotebookBar->setPosSizePixel(
1921 nLeftBorder, nTopBorder,
1922 aSize.Width() - nLeftBorder - nRightBorder,
1923 nNotebookBarHeight);
1926 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
1927 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
1928 pClientWindow->ImplPosSizeWindow( pClientWindow->mpWindowImpl->mnLeftBorder,
1929 pClientWindow->mpWindowImpl->mnTopBorder,
1930 aSize.Width()-pClientWindow->mpWindowImpl->mnLeftBorder-pClientWindow->mpWindowImpl->mnRightBorder,
1931 aSize.Height()-pClientWindow->mpWindowImpl->mnTopBorder-pClientWindow->mpWindowImpl->mnBottomBorder,
1932 PosSizeFlags::X | PosSizeFlags::Y |
1933 PosSizeFlags::Width | PosSizeFlags::Height );
1936 // UpdateView
1937 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1938 InvalidateBorder();
1940 Window::Resize();
1943 void ImplBorderWindow::StateChanged( StateChangedType nType )
1945 if ( (nType == StateChangedType::Text) ||
1946 (nType == StateChangedType::Image) ||
1947 (nType == StateChangedType::Data) )
1949 if (IsReallyVisible() && mbFrameBorder)
1950 InvalidateBorder();
1953 Window::StateChanged( nType );
1956 void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
1958 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1959 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1960 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1961 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1963 if ( !mpWindowImpl->mbFrame || (GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP)) )
1964 UpdateView( true, ImplGetWindow()->GetOutputSizePixel() );
1967 Window::DataChanged( rDCEvt );
1970 void ImplBorderWindow::InitView()
1972 if ( mbSmallOutBorder )
1973 mpBorderView = new ImplSmallBorderWindowView( this );
1974 else if ( mpWindowImpl->mbFrame )
1976 if( mbFrameBorder )
1977 mpBorderView = new ImplStdBorderWindowView( this );
1978 else
1979 mpBorderView = new ImplNoBorderWindowView( this );
1981 else if ( !mbFrameBorder )
1982 mpBorderView = new ImplSmallBorderWindowView( this );
1983 else
1984 mpBorderView = new ImplStdBorderWindowView( this );
1985 Size aSize = GetOutputSizePixel();
1986 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
1989 void ImplBorderWindow::UpdateView( bool bNewView, const Size& rNewOutSize )
1991 sal_Int32 nLeftBorder;
1992 sal_Int32 nTopBorder;
1993 sal_Int32 nRightBorder;
1994 sal_Int32 nBottomBorder;
1995 Size aOldSize = GetSizePixel();
1996 Size aOutputSize = rNewOutSize;
1998 if ( bNewView )
2000 delete mpBorderView;
2001 InitView();
2003 else
2005 Size aSize = aOutputSize;
2006 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2007 aSize.Width() += nLeftBorder+nRightBorder;
2008 aSize.Height() += nTopBorder+nBottomBorder;
2009 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2012 vcl::Window* pClientWindow = ImplGetClientWindow();
2013 if ( pClientWindow )
2015 GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
2016 pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
2018 GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2019 if ( aOldSize.Width() || aOldSize.Height() )
2021 aOutputSize.Width() += nLeftBorder+nRightBorder;
2022 aOutputSize.Height() += nTopBorder+nBottomBorder;
2023 if ( aOutputSize == GetSizePixel() )
2024 InvalidateBorder();
2025 else
2026 SetSizePixel( aOutputSize );
2030 void ImplBorderWindow::InvalidateBorder()
2032 if ( IsReallyVisible() )
2034 // invalidate only if we have a border
2035 sal_Int32 nLeftBorder;
2036 sal_Int32 nTopBorder;
2037 sal_Int32 nRightBorder;
2038 sal_Int32 nBottomBorder;
2039 mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
2040 if ( nLeftBorder || nTopBorder || nRightBorder || nBottomBorder )
2042 Rectangle aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
2043 vcl::Region aRegion( aWinRect );
2044 aWinRect.Left() += nLeftBorder;
2045 aWinRect.Top() += nTopBorder;
2046 aWinRect.Right() -= nRightBorder;
2047 aWinRect.Bottom() -= nBottomBorder;
2048 // no output area anymore, now invalidate all
2049 if ( (aWinRect.Right() < aWinRect.Left()) ||
2050 (aWinRect.Bottom() < aWinRect.Top()) )
2051 Invalidate( InvalidateFlags::NoChildren );
2052 else
2054 aRegion.Exclude( aWinRect );
2055 Invalidate( aRegion, InvalidateFlags::NoChildren );
2061 void ImplBorderWindow::SetDisplayActive( bool bActive )
2063 if ( mbDisplayActive != bActive )
2065 mbDisplayActive = bActive;
2066 if ( mbFrameBorder )
2067 InvalidateBorder();
2071 void ImplBorderWindow::SetTitleType( BorderWindowTitleType nTitleType, const Size& rSize )
2073 mnTitleType = nTitleType;
2074 UpdateView( false, rSize );
2077 void ImplBorderWindow::SetBorderStyle( WindowBorderStyle nStyle )
2079 if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
2081 mnBorderStyle = nStyle;
2082 UpdateView( false, ImplGetWindow()->GetOutputSizePixel() );
2086 void ImplBorderWindow::SetPin( bool bPin )
2088 mbPinned = bPin;
2089 InvalidateBorder();
2092 void ImplBorderWindow::SetRollUp( bool bRollUp, const Size& rSize )
2094 mbRollUp = bRollUp;
2095 mnRollHeight = rSize.Height();
2096 UpdateView( false, rSize );
2099 void ImplBorderWindow::SetCloseButton()
2101 SetStyle( GetStyle() | WB_CLOSEABLE );
2102 Size aSize = GetOutputSizePixel();
2103 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2104 InvalidateBorder();
2107 void ImplBorderWindow::SetDockButton( bool bDockButton )
2109 mbDockBtn = bDockButton;
2110 Size aSize = GetOutputSizePixel();
2111 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2112 InvalidateBorder();
2115 void ImplBorderWindow::SetHideButton( bool bHideButton )
2117 mbHideBtn = bHideButton;
2118 Size aSize = GetOutputSizePixel();
2119 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2120 InvalidateBorder();
2123 void ImplBorderWindow::SetMenuButton( bool bMenuButton )
2125 mbMenuBtn = bMenuButton;
2126 Size aSize = GetOutputSizePixel();
2127 mpBorderView->Init( this, aSize.Width(), aSize.Height() );
2128 InvalidateBorder();
2131 void ImplBorderWindow::UpdateMenuHeight()
2133 Resize();
2136 void ImplBorderWindow::SetMenuBarWindow( vcl::Window* pWindow )
2138 mpMenuBarWindow = pWindow;
2139 UpdateMenuHeight();
2140 if ( pWindow )
2141 pWindow->Show();
2144 void ImplBorderWindow::SetMenuBarMode( bool bHide )
2146 mbMenuHide = bHide;
2147 UpdateMenuHeight();
2150 void ImplBorderWindow::SetNotebookBar(const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame>& rFrame)
2152 if (mpNotebookBar)
2153 mpNotebookBar.disposeAndClear();
2154 mpNotebookBar = VclPtr<NotebookBar>::Create(this, "NotebookBar", rUIXMLDescription, rFrame);
2155 Resize();
2158 void ImplBorderWindow::CloseNotebookBar()
2160 if (mpNotebookBar)
2161 mpNotebookBar.disposeAndClear();
2162 mpNotebookBar = nullptr;
2163 Resize();
2166 void ImplBorderWindow::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
2167 sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
2169 mpBorderView->GetBorder(rLeftBorder, rTopBorder, rRightBorder, rBottomBorder);
2171 if (mpMenuBarWindow && !mbMenuHide)
2172 rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
2174 if (mpNotebookBar && mpNotebookBar->IsVisible())
2175 rTopBorder += mpNotebookBar->GetSizePixel().Height();
2178 long ImplBorderWindow::CalcTitleWidth() const
2180 return mpBorderView->CalcTitleWidth();
2183 Rectangle ImplBorderWindow::GetMenuRect() const
2185 return mpBorderView->GetMenuRect();
2188 Size ImplBorderWindow::GetOptimalSize() const
2190 const vcl::Window* pClientWindow = ImplGetClientWindow();
2191 if (pClientWindow)
2192 return pClientWindow->GetOptimalSize();
2193 return Size(mnMinWidth, mnMinHeight);
2196 void ImplBorderWindow::queue_resize(StateChangedType eReason)
2198 //if we are floating, then we don't want to inform our parent that it needs
2199 //to calculate a new layout allocation. Because while we are a child
2200 //of our parent we are not embedded into the parent so it doesn't care
2201 //about us.
2202 if (mbFloatWindow)
2203 return;
2204 vcl::Window::queue_resize(eReason);
2207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */