1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <vcl/dockingarea.hxx>
21 #include <vcl/syswin.hxx>
22 #include <vcl/menu.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/event.hxx>
30 class DockingAreaWindow::ImplData
38 DockingAreaWindow::ImplData::ImplData()
40 meAlign
= WindowAlign::Top
;
43 DockingAreaWindow::DockingAreaWindow( vcl::Window
* pParent
) :
44 Window( WindowType::DOCKINGAREA
)
46 ImplInit( pParent
, WB_CLIPCHILDREN
|WB_3DLOOK
, nullptr );
48 mpImplData
.reset(new ImplData
);
51 DockingAreaWindow::~DockingAreaWindow()
56 void DockingAreaWindow::dispose()
62 void DockingAreaWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
64 Window::DataChanged( rDCEvt
);
66 if ( (rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
72 static void ImplInvalidateMenubar( DockingAreaWindow
const * pThis
)
74 // due to a possible common gradient covering menubar and top dockingarea
75 // the menubar must be repainted if the top dockingarea changes size or visibility
76 if( ImplGetSVData()->maNWFData
.mbMenuBarDockingAreaCommonBG
&&
77 (pThis
->GetAlign() == WindowAlign::Top
)
78 && pThis
->IsNativeControlSupported( ControlType::Toolbar
, ControlPart::Entire
)
79 && pThis
->IsNativeControlSupported( ControlType::Menubar
, ControlPart::Entire
) )
81 SystemWindow
*pSysWin
= pThis
->GetSystemWindow();
82 if( pSysWin
&& pSysWin
->GetMenuBar() )
84 vcl::Window
*pMenubarWin
= pSysWin
->GetMenuBar()->GetWindow();
86 pMenubarWin
->Invalidate();
91 void DockingAreaWindow::StateChanged( StateChangedType nType
)
93 Window::StateChanged( nType
);
95 if ( nType
== StateChangedType::Visible
)
96 ImplInvalidateMenubar( this );
99 bool DockingAreaWindow::IsHorizontal() const
101 return ( mpImplData
->meAlign
== WindowAlign::Top
|| mpImplData
->meAlign
== WindowAlign::Bottom
);
104 void DockingAreaWindow::SetAlign( WindowAlign eNewAlign
)
106 if( eNewAlign
!= mpImplData
->meAlign
)
108 mpImplData
->meAlign
= eNewAlign
;
113 WindowAlign
DockingAreaWindow::GetAlign() const
115 return mpImplData
->meAlign
;
118 void DockingAreaWindow::ApplySettings(vcl::RenderContext
& rRenderContext
)
120 const StyleSettings rSetting
= rRenderContext
.GetSettings().GetStyleSettings();
121 const BitmapEx
& rPersonaBitmap
= (GetAlign() == WindowAlign::Top
) ? rSetting
.GetPersonaHeader() : rSetting
.GetPersonaFooter();
123 if (!rPersonaBitmap
.IsEmpty() && (GetAlign() == WindowAlign::Top
|| GetAlign()==WindowAlign::Bottom
))
125 Wallpaper
aWallpaper(rPersonaBitmap
);
126 if (GetAlign() == WindowAlign::Top
)
127 aWallpaper
.SetStyle(WallpaperStyle::TopRight
);
129 aWallpaper
.SetStyle(WallpaperStyle::BottomRight
);
130 aWallpaper
.SetColor(rSetting
.GetWorkspaceColor());
132 // we need to shift the bitmap vertically so that it spans over the
133 // menubar conveniently
134 SystemWindow
* pSysWin
= GetSystemWindow();
135 MenuBar
* pMenuBar
= pSysWin
? pSysWin
->GetMenuBar() : nullptr;
136 int nMenubarHeight
= pMenuBar
? pMenuBar
->GetMenuBarHeight() : 0;
137 aWallpaper
.SetRect(tools::Rectangle(Point(0, -nMenubarHeight
),
138 Size(rRenderContext
.GetOutputWidthPixel(),
139 rRenderContext
.GetOutputHeightPixel() + nMenubarHeight
)));
141 rRenderContext
.SetBackground(aWallpaper
);
143 else if (!rRenderContext
.IsNativeControlSupported(ControlType::Toolbar
, ControlPart::Entire
))
145 Wallpaper aWallpaper
;
146 aWallpaper
.SetStyle(WallpaperStyle::ApplicationGradient
);
147 rRenderContext
.SetBackground(aWallpaper
);
150 rRenderContext
.SetBackground(Wallpaper(rSetting
.GetFaceColor()));
154 void DockingAreaWindow::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
156 const StyleSettings rSetting
= rRenderContext
.GetSettings().GetStyleSettings();
158 EnableNativeWidget(); // only required because the toolkit currently switches this flag off
159 if (!rRenderContext
.IsNativeControlSupported(ControlType::Toolbar
, ControlPart::Entire
))
162 ToolbarValue aControlValue
;
164 if (GetAlign() == WindowAlign::Top
&& ImplGetSVData()->maNWFData
.mbMenuBarDockingAreaCommonBG
)
166 // give NWF a hint that this dockingarea is adjacent to the menubar
167 // useful for special gradient effects that should cover both windows
168 aControlValue
.mbIsTopDockingArea
= true;
171 ControlState nState
= ControlState::ENABLED
;
172 const bool isFooter
= GetAlign() == WindowAlign::Bottom
&& !rSetting
.GetPersonaFooter().IsEmpty();
174 if ((GetAlign() == WindowAlign::Top
&& !rSetting
.GetPersonaHeader().IsEmpty() ) || isFooter
)
175 Erase(rRenderContext
);
176 else if (!ImplGetSVData()->maNWFData
.mbDockingAreaSeparateTB
)
178 // draw a single toolbar background covering the whole docking area
179 tools::Rectangle
aCtrlRegion(Point(), GetOutputSizePixel());
181 rRenderContext
.DrawNativeControl(ControlType::Toolbar
, IsHorizontal() ? ControlPart::DrawBackgroundHorz
: ControlPart::DrawBackgroundVert
,
182 aCtrlRegion
, nState
, aControlValue
, OUString() );
184 if (!ImplGetSVData()->maNWFData
.mbDockingAreaAvoidTBFrames
)
186 // each toolbar gets a thin border to better recognize its borders on the homogeneous docking area
187 sal_uInt16 nChildren
= GetChildCount();
188 for (sal_uInt16 n
= 0; n
< nChildren
; n
++)
190 vcl::Window
* pChild
= GetChild(n
);
191 if (pChild
->IsVisible())
193 Point aPos
= pChild
->GetPosPixel();
194 Size aSize
= pChild
->GetSizePixel();
195 tools::Rectangle
aRect(aPos
, aSize
);
197 rRenderContext
.SetLineColor(rRenderContext
.GetSettings().GetStyleSettings().GetLightColor());
198 rRenderContext
.DrawLine(aRect
.TopLeft(), aRect
.TopRight());
199 rRenderContext
.DrawLine(aRect
.TopLeft(), aRect
.BottomLeft());
201 rRenderContext
.SetLineColor(rRenderContext
.GetSettings().GetStyleSettings().GetSeparatorColor());
202 rRenderContext
.DrawLine(aRect
.BottomLeft(), aRect
.BottomRight());
203 rRenderContext
.DrawLine(aRect
.TopRight(), aRect
.BottomRight());
210 // create map to find toolbar lines
211 Size
aOutSz(GetOutputSizePixel());
212 std::map
<int, int> ranges
;
213 sal_uInt16 nChildren
= GetChildCount();
214 for (sal_uInt16 n
= 0; n
< nChildren
; n
++)
216 vcl::Window
* pChild
= GetChild(n
);
217 Point aPos
= pChild
->GetPosPixel();
218 Size aSize
= pChild
->GetSizePixel();
220 ranges
[aPos
.Y()] = aSize
.Height();
222 ranges
[aPos
.X()] = aSize
.Width();
225 // draw multiple toolbar backgrounds, i.e., one for each toolbar line
226 for (auto const& range
: ranges
)
228 tools::Rectangle aTBRect
;
231 aTBRect
.SetLeft( 0 );
232 aTBRect
.SetRight( aOutSz
.Width() - 1 );
233 aTBRect
.SetTop( range
.first
);
234 aTBRect
.SetBottom( range
.first
+ range
.second
- 1 );
238 aTBRect
.SetLeft( range
.first
);
239 aTBRect
.SetRight( range
.first
+ range
.second
- 1 );
241 aTBRect
.SetBottom( aOutSz
.Height() - 1 );
243 rRenderContext
.DrawNativeControl(ControlType::Toolbar
, IsHorizontal() ? ControlPart::DrawBackgroundHorz
: ControlPart::DrawBackgroundVert
,
244 aTBRect
, nState
, aControlValue
, OUString());
249 void DockingAreaWindow::Resize()
251 ImplInvalidateMenubar( this );
252 if (IsNativeControlSupported(ControlType::Toolbar
, ControlPart::Entire
))
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */