LibreOffice Module vcl (master)  1
dockingarea.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <vcl/dockingarea.hxx>
21 #include <vcl/syswin.hxx>
22 #include <vcl/menu.hxx>
23 #include <vcl/settings.hxx>
24 #include <vcl/event.hxx>
25 
26 #include <svdata.hxx>
27 
28 #include <map>
29 
31 {
32 public:
33  ImplData();
34 
36 };
37 
39 {
40  meAlign = WindowAlign::Top;
41 }
42 
43 DockingAreaWindow::DockingAreaWindow( vcl::Window* pParent ) :
45 {
46  ImplInit( pParent, WB_CLIPCHILDREN|WB_3DLOOK, nullptr );
47 
48  mpImplData.reset(new ImplData);
49 }
50 
51 DockingAreaWindow::~DockingAreaWindow()
52 {
53  disposeOnce();
54 }
55 
56 void DockingAreaWindow::dispose()
57 {
58  mpImplData.reset();
59  Window::dispose();
60 }
61 
62 void DockingAreaWindow::DataChanged( const DataChangedEvent& rDCEvt )
63 {
64  Window::DataChanged( rDCEvt );
65 
66  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
67  {
68  Invalidate();
69  }
70 }
71 
72 static void ImplInvalidateMenubar( DockingAreaWindow const * pThis )
73 {
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 ) )
80  {
81  SystemWindow *pSysWin = pThis->GetSystemWindow();
82  if( pSysWin && pSysWin->GetMenuBar() )
83  {
84  vcl::Window *pMenubarWin = pSysWin->GetMenuBar()->GetWindow();
85  if( pMenubarWin )
86  pMenubarWin->Invalidate();
87  }
88  }
89 }
90 
91 void DockingAreaWindow::StateChanged( StateChangedType nType )
92 {
93  Window::StateChanged( nType );
94 
95  if ( nType == StateChangedType::Visible )
96  ImplInvalidateMenubar( this );
97 }
98 
99 bool DockingAreaWindow::IsHorizontal() const
100 {
101  return ( mpImplData->meAlign == WindowAlign::Top || mpImplData->meAlign == WindowAlign::Bottom );
102 }
103 
104 void DockingAreaWindow::SetAlign( WindowAlign eNewAlign )
105 {
106  if( eNewAlign != mpImplData->meAlign )
107  {
108  mpImplData->meAlign = eNewAlign;
109  Invalidate();
110  }
111 }
112 
113 WindowAlign DockingAreaWindow::GetAlign() const
114 {
115  return mpImplData->meAlign;
116 }
117 
118 void DockingAreaWindow::ApplySettings(vcl::RenderContext& rRenderContext)
119 {
120  const StyleSettings rSetting = rRenderContext.GetSettings().GetStyleSettings();
121  const BitmapEx& rPersonaBitmap = (GetAlign() == WindowAlign::Top) ? rSetting.GetPersonaHeader() : rSetting.GetPersonaFooter();
122 
123  if (!rPersonaBitmap.IsEmpty() && (GetAlign() == WindowAlign::Top || GetAlign()==WindowAlign::Bottom))
124  {
125  Wallpaper aWallpaper(rPersonaBitmap);
126  if (GetAlign() == WindowAlign::Top)
127  aWallpaper.SetStyle(WallpaperStyle::TopRight);
128  else
129  aWallpaper.SetStyle(WallpaperStyle::BottomRight);
130  aWallpaper.SetColor(rSetting.GetWorkspaceColor());
131 
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)));
140 
141  rRenderContext.SetBackground(aWallpaper);
142  }
144  {
145  Wallpaper aWallpaper;
147  rRenderContext.SetBackground(aWallpaper);
148  }
149  else
150  rRenderContext.SetBackground(Wallpaper(rSetting.GetFaceColor()));
151 
152 }
153 
154 void DockingAreaWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
155 {
156  const StyleSettings rSetting = rRenderContext.GetSettings().GetStyleSettings();
157 
158  EnableNativeWidget(); // only required because the toolkit currently switches this flag off
160  return;
161 
162  ToolbarValue aControlValue;
163 
164  if (GetAlign() == WindowAlign::Top && ImplGetSVData()->maNWFData.mbMenuBarDockingAreaCommonBG)
165  {
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;
169  }
170 
172  const bool isFooter = GetAlign() == WindowAlign::Bottom && !rSetting.GetPersonaFooter().IsEmpty();
173 
174  if ((GetAlign() == WindowAlign::Top && !rSetting.GetPersonaHeader().IsEmpty() ) || isFooter)
175  Erase(rRenderContext);
176  else if (!ImplGetSVData()->maNWFData.mbDockingAreaSeparateTB)
177  {
178  // draw a single toolbar background covering the whole docking area
179  tools::Rectangle aCtrlRegion(Point(), GetOutputSizePixel());
180 
182  aCtrlRegion, nState, aControlValue, OUString() );
183 
184  if (!ImplGetSVData()->maNWFData.mbDockingAreaAvoidTBFrames)
185  {
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++)
189  {
190  vcl::Window* pChild = GetChild(n);
191  if (pChild->IsVisible())
192  {
193  Point aPos = pChild->GetPosPixel();
194  Size aSize = pChild->GetSizePixel();
195  tools::Rectangle aRect(aPos, aSize);
196 
197  rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetLightColor());
198  rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
199  rRenderContext.DrawLine(aRect.TopLeft(), aRect.BottomLeft());
200 
201  rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetSeparatorColor());
202  rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
203  rRenderContext.DrawLine(aRect.TopRight(), aRect.BottomRight());
204  }
205  }
206  }
207  }
208  else
209  {
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++)
215  {
216  vcl::Window* pChild = GetChild(n);
217  Point aPos = pChild->GetPosPixel();
218  Size aSize = pChild->GetSizePixel();
219  if (IsHorizontal())
220  ranges[aPos.Y()] = aSize.Height();
221  else
222  ranges[aPos.X()] = aSize.Width();
223  }
224 
225  // draw multiple toolbar backgrounds, i.e., one for each toolbar line
226  for (auto const& range : ranges)
227  {
228  tools::Rectangle aTBRect;
229  if (IsHorizontal())
230  {
231  aTBRect.SetLeft( 0 );
232  aTBRect.SetRight( aOutSz.Width() - 1 );
233  aTBRect.SetTop( range.first );
234  aTBRect.SetBottom( range.first + range.second - 1 );
235  }
236  else
237  {
238  aTBRect.SetLeft( range.first );
239  aTBRect.SetRight( range.first + range.second - 1 );
240  aTBRect.SetTop( 0 );
241  aTBRect.SetBottom( aOutSz.Height() - 1 );
242  }
243  rRenderContext.DrawNativeControl(ControlType::Toolbar, IsHorizontal() ? ControlPart::DrawBackgroundHorz : ControlPart::DrawBackgroundVert,
244  aTBRect, nState, aControlValue, OUString());
245  }
246  }
247 }
248 
249 void DockingAreaWindow::Resize()
250 {
251  ImplInvalidateMenubar( this );
252  if (IsNativeControlSupported(ControlType::Toolbar, ControlPart::Entire))
253  Invalidate();
254 }
255 
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2838
long Width() const
WindowAlign
static void ImplInvalidateMenubar(DockingAreaWindow const *pThis)
Definition: dockingarea.cxx:72
SystemWindow * GetSystemWindow() const
Definition: stacking.cxx:810
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption)
Request rendering of a particular control and/or part.
long Height() const
const StyleSettings & GetStyleSettings() const
const Color & GetFaceColor() const
BitmapEx const & GetPersonaHeader() const
ImplSVNWFData maNWFData
Definition: svdata.hxx:398
sal_Int64 n
bool mbMenuBarDockingAreaCommonBG
Definition: svdata.hxx:315
virtual Size GetSizePixel() const
Definition: window.cxx:2396
const Color & GetWorkspaceColor() const
Color GetSeparatorColor() const
DataChangedEventType GetType() const
Definition: event.hxx:357
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
StateChangedType
Definition: window.hxx:310
void SetBackground()
AllSettingsFlags GetFlags() const
Definition: event.hxx:358
const Color & GetLightColor() const
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:88
BitmapEx const & GetPersonaFooter() const
bool IsEmpty() const
Definition: bitmapex.cxx:199
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
void SetLineColor()
int GetMenuBarHeight() const
Definition: menu.cxx:2662
void SetTop(long v)
void SetStyle(WallpaperStyle eStyle)
Definition: wall.cxx:209
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1162
void SetRight(long v)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:302
const AllSettings & GetSettings() const
Definition: outdev.hxx:418
long GetOutputWidthPixel() const
Definition: outdev.hxx:443
static bool EnableNativeWidget(const OutputDevice &i_rDevice)
long GetOutputHeightPixel() const
Definition: outdev.hxx:444
WindowType
MenuBar * GetMenuBar() const
Definition: syswin.hxx:160
vcl::Window * GetWindow() const
Definition: menu.hxx:373
bool IsVisible() const
Definition: window2.cxx:1102
void SetBottom(long v)
void SetLeft(long v)
sal_Int32 nState