LibreOffice Module vcl (master)  1
prgsbar.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/event.hxx>
21 #include <vcl/status.hxx>
22 #include <vcl/toolkit/prgsbar.hxx>
23 #include <vcl/settings.hxx>
24 #include <sal/log.hxx>
25 #include <vcl/svapp.hxx>
26 #include <vcl/idle.hxx>
27 
28 #define PROGRESSBAR_OFFSET 3
29 #define PROGRESSBAR_WIN_OFFSET 2
30 
31 void ProgressBar::ImplInit()
32 {
33  mnPercent = 0;
34  mbCalcNew = true;
35 
36  ImplInitSettings( true, true, true );
37 }
38 
39 static WinBits clearProgressBarBorder( vcl::Window const * pParent, WinBits nOrgStyle )
40 {
41  WinBits nOutStyle = nOrgStyle;
42  if( pParent && (nOrgStyle & WB_BORDER) != 0 )
43  {
45  nOutStyle &= WB_BORDER;
46  }
47  return nOutStyle;
48 }
49 
50 Size ProgressBar::GetOptimalSize() const
51 {
52  return Size(150, 20);
53 }
54 
55 ProgressBar::ProgressBar( vcl::Window* pParent, WinBits nWinStyle ) :
56  Window( pParent, clearProgressBarBorder( pParent, nWinStyle ) )
57 {
58  SetOutputSizePixel( GetOptimalSize() );
59  ImplInit();
60 }
61 
62 void ProgressBar::ImplInitSettings( bool bFont,
63  bool bForeground, bool bBackground )
64 {
65  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
66 
67 /* FIXME: !!! We do not support text output at the moment
68  if ( bFont )
69  ApplyControlFont(*this, rStyleSettings.GetAppFont());
70 */
71 
72  if ( bBackground )
73  {
74  if( !IsControlBackground() &&
75  IsNativeControlSupported( ControlType::Progress, ControlPart::Entire ) )
76  {
77  if( GetStyle() & WB_BORDER )
78  SetBorderStyle( WindowBorderStyle::REMOVEBORDER );
79  EnableChildTransparentMode();
80  SetPaintTransparent( true );
81  SetBackground();
82  SetParentClipMode( ParentClipMode::NoClip );
83  }
84  else
85  {
86  Color aColor;
87  if ( IsControlBackground() )
88  aColor = GetControlBackground();
89  else
90  aColor = rStyleSettings.GetFaceColor();
91  SetBackground( aColor );
92  }
93  }
94 
95  if ( bForeground || bFont )
96  {
97  Color aColor = rStyleSettings.GetHighlightColor();
98  if ( IsControlForeground() )
99  aColor = GetControlForeground();
100  if ( aColor.IsRGBEqual( GetBackground().GetColor() ) )
101  {
102  if ( aColor.GetLuminance() > 100 )
103  aColor.DecreaseLuminance( 64 );
104  else
105  aColor.IncreaseLuminance( 64 );
106  }
107  SetLineColor();
108  SetFillColor( aColor );
109 /* FIXME: !!! We do not support text output at the moment
110  SetTextColor( aColor );
111  SetTextFillColor();
112 */
113  }
114 }
115 
116 void ProgressBar::ImplDrawProgress(vcl::RenderContext& rRenderContext, sal_uInt16 nNewPerc)
117 {
118  if (mbCalcNew)
119  {
120  mbCalcNew = false;
121 
122  Size aSize(GetOutputSizePixel());
123  mnPrgsHeight = aSize.Height() - (PROGRESSBAR_WIN_OFFSET * 2);
124  mnPrgsWidth = (mnPrgsHeight * 2) / 3;
125  maPos.setY( PROGRESSBAR_WIN_OFFSET );
126  long nMaxWidth = aSize.Width() - (PROGRESSBAR_WIN_OFFSET * 2) + PROGRESSBAR_OFFSET;
127  sal_uInt16 nMaxCount = static_cast<sal_uInt16>(nMaxWidth / (mnPrgsWidth+PROGRESSBAR_OFFSET));
128  if (nMaxCount <= 1)
129  {
130  nMaxCount = 1;
131  }
132  else
133  {
134  while (((10000 / (10000 / nMaxCount)) * (mnPrgsWidth + PROGRESSBAR_OFFSET)) > nMaxWidth)
135  {
136  nMaxCount--;
137  }
138  }
139  mnPercentCount = 10000 / nMaxCount;
140  nMaxWidth = ((10000 / (10000 / nMaxCount)) * (mnPrgsWidth + PROGRESSBAR_OFFSET)) - PROGRESSBAR_OFFSET;
141  maPos.setX( (aSize.Width() - nMaxWidth) / 2 );
142  }
143 
144  ::DrawProgress(this, rRenderContext, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, mnPrgsHeight,
145  /*nPercent1=*/0, nNewPerc * 100, mnPercentCount,
146  tools::Rectangle(Point(), GetSizePixel()));
147 }
148 
149 void ProgressBar::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
150 {
151  ImplDrawProgress(rRenderContext, mnPercent);
152 }
153 
154 void ProgressBar::Resize()
155 {
156  mbCalcNew = true;
157  if ( IsReallyVisible() )
158  Invalidate();
159 }
160 
161 void ProgressBar::SetValue( sal_uInt16 nNewPercent )
162 {
163  SAL_WARN_IF( nNewPercent > 100, "vcl", "StatusBar::SetProgressValue(): nPercent > 100" );
164 
165  if ( nNewPercent < mnPercent )
166  {
167  mbCalcNew = true;
168  mnPercent = nNewPercent;
169  if ( IsReallyVisible() )
170  {
171  Invalidate();
172  }
173  }
174  else if ( mnPercent != nNewPercent )
175  {
176  mnPercent = nNewPercent;
177  Invalidate();
178 
179  // Make sure the progressbar is actually painted even if the caller is busy with its task,
180  // so the main loop would not be invoked.
181  Idle aIdle("ProgressBar::SetValue aIdle");
182  aIdle.SetPriority(TaskPriority::POST_PAINT);
183  aIdle.Start();
184  while (aIdle.IsActive())
185  {
187  }
188  }
189 }
190 
191 void ProgressBar::StateChanged( StateChangedType nType )
192 {
193 /* FIXME: !!! We do not support text output at the moment
194  if ( (nType == StateChangedType::Zoom) ||
195  (nType == StateChangedType::ControlFont) )
196  {
197  ImplInitSettings( true, false, false );
198  Invalidate();
199  }
200  else
201 */
203  {
204  ImplInitSettings( false, true, false );
205  Invalidate();
206  }
207  else if ( nType == StateChangedType::ControlBackground )
208  {
209  ImplInitSettings( false, false, true );
210  Invalidate();
211  }
212 
213  Window::StateChanged( nType );
214 }
215 
216 void ProgressBar::DataChanged( const DataChangedEvent& rDCEvt )
217 {
218  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
219  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
220  {
221  ImplInitSettings( true, true, true );
222  Invalidate();
223  }
224 
225  Window::DataChanged( rDCEvt );
226 }
227 
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
static WinBits clearProgressBarBorder(vcl::Window const *pParent, WinBits nOrgStyle)
Definition: prgsbar.cxx:39
DataChangedEventType GetType() const
Definition: event.hxx:357
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
const Color & GetHighlightColor() const
Everything running directly after painting.
StateChangedType
Definition: window.hxx:311
sal_Int64 WinBits
#define PROGRESSBAR_WIN_OFFSET
Definition: prgsbar.cxx:29
static void Yield()
Process the next event.
Definition: svapp.cxx:517
AllSettingsFlags GetFlags() const
Definition: event.hxx:358
void DrawProgress(vcl::Window *pWindow, vcl::RenderContext &rRenderContext, const Point &rPos, long nOffset, long nPrgsWidth, long nPrgsHeight, sal_uInt16 nPercent1, sal_uInt16 nPercent2, sal_uInt16 nPercentCount, const tools::Rectangle &rFramePosSize)
Definition: status.cxx:470
void IncreaseLuminance(sal_uInt8 cLumInc)
#define PROGRESSBAR_OFFSET
Definition: prgsbar.cxx:28
void DecreaseLuminance(sal_uInt8 cLumDec)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
bool IsRGBEqual(const Color &rColor) const
#define SAL_WARN_IF(condition, area, stream)
WinBits const WB_BORDER
void SetLineColor(const css::uno::Reference< css::beans::XPropertySet > &xGridProperties, sal_Int32 nColor)
An idle is a timer to be scheduled immediately.
Definition: idle.hxx:30