Updated core
[LibreOffice.git] / UnoControls / source / controls / progressbar.cxx
blobce7c5eb2c1e874437d81904ce45a382b42229d09
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 "progressbar.hxx"
22 #include <com/sun/star/awt/GradientStyle.hpp>
23 #include <com/sun/star/awt/RasterOperation.hpp>
24 #include <com/sun/star/awt/Gradient.hpp>
25 #include <com/sun/star/awt/XGraphics.hpp>
26 #include <tools/debug.hxx>
27 #include <cppuhelper/typeprovider.hxx>
29 #include <math.h>
30 #include <limits.h>
32 using namespace ::cppu ;
33 using namespace ::osl ;
34 using namespace ::rtl ;
35 using namespace ::com::sun::star::uno ;
36 using namespace ::com::sun::star::lang ;
37 using namespace ::com::sun::star::awt ;
39 namespace unocontrols{
41 //____________________________________________________________________________________________________________
42 // construct/destruct
43 //____________________________________________________________________________________________________________
45 ProgressBar::ProgressBar( const Reference< XComponentContext >& rxContext )
46 : BaseControl ( rxContext )
47 , m_bHorizontal ( PROGRESSBAR_DEFAULT_HORIZONTAL )
48 , m_aBlockSize ( PROGRESSBAR_DEFAULT_BLOCKDIMENSION )
49 , m_nForegroundColor ( PROGRESSBAR_DEFAULT_FOREGROUNDCOLOR )
50 , m_nBackgroundColor ( PROGRESSBAR_DEFAULT_BACKGROUNDCOLOR )
51 , m_nMinRange ( PROGRESSBAR_DEFAULT_MINRANGE )
52 , m_nMaxRange ( PROGRESSBAR_DEFAULT_MAXRANGE )
53 , m_nBlockValue ( PROGRESSBAR_DEFAULT_BLOCKVALUE )
54 , m_nValue ( PROGRESSBAR_DEFAULT_VALUE )
58 ProgressBar::~ProgressBar()
62 //____________________________________________________________________________________________________________
63 // XInterface
64 //____________________________________________________________________________________________________________
66 Any SAL_CALL ProgressBar::queryInterface( const Type& rType ) throw( RuntimeException )
68 // Attention:
69 // Don't use mutex or guard in this method!!! Is a method of XInterface.
70 Any aReturn ;
71 Reference< XInterface > xDel = BaseControl::impl_getDelegator();
72 if ( xDel.is() )
74 // If an delegator exist, forward question to his queryInterface.
75 // Delegator will ask his own queryAggregation!
76 aReturn = xDel->queryInterface( rType );
78 else
80 // If an delegator unknown, forward question to own queryAggregation.
81 aReturn = queryAggregation( rType );
84 return aReturn ;
87 //____________________________________________________________________________________________________________
88 // XInterface
89 //____________________________________________________________________________________________________________
91 void SAL_CALL ProgressBar::acquire() throw()
93 // Attention:
94 // Don't use mutex or guard in this method!!! Is a method of XInterface.
96 // Forward to baseclass
97 BaseControl::acquire();
100 //____________________________________________________________________________________________________________
101 // XInterface
102 //____________________________________________________________________________________________________________
104 void SAL_CALL ProgressBar::release() throw()
106 // Attention:
107 // Don't use mutex or guard in this method!!! Is a method of XInterface.
109 // Forward to baseclass
110 BaseControl::release();
113 //____________________________________________________________________________________________________________
114 // XTypeProvider
115 //____________________________________________________________________________________________________________
117 Sequence< Type > SAL_CALL ProgressBar::getTypes() throw( RuntimeException )
119 // Optimize this method !
120 // We initialize a static variable only one time. And we don't must use a mutex at every call!
121 // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
122 static OTypeCollection* pTypeCollection = NULL ;
124 if ( pTypeCollection == NULL )
126 // Ready for multithreading; get global mutex for first call of this method only! see before
127 MutexGuard aGuard( Mutex::getGlobalMutex() );
129 // Control these pointer again ... it can be, that another instance will be faster then these!
130 if ( pTypeCollection == NULL )
132 // Create a static typecollection ...
133 static OTypeCollection aTypeCollection ( ::getCppuType(( const Reference< XControlModel >*) NULL ) ,
134 ::getCppuType(( const Reference< XProgressBar >*) NULL ) ,
135 BaseControl::getTypes()
137 // ... and set his address to static pointer!
138 pTypeCollection = &aTypeCollection ;
142 return pTypeCollection->getTypes();
145 //____________________________________________________________________________________________________________
146 // XAggregation
147 //____________________________________________________________________________________________________________
149 Any SAL_CALL ProgressBar::queryAggregation( const Type& aType ) throw( RuntimeException )
151 // Ask for my own supported interfaces ...
152 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
153 Any aReturn ( ::cppu::queryInterface( aType ,
154 static_cast< XControlModel* > ( this ) ,
155 static_cast< XProgressBar* > ( this )
159 // If searched interface not supported by this class ...
160 if ( aReturn.hasValue() == sal_False )
162 // ... ask baseclasses.
163 aReturn = BaseControl::queryAggregation( aType );
166 return aReturn ;
169 //____________________________________________________________________________________________________________
170 // XProgressBar
171 //____________________________________________________________________________________________________________
173 void SAL_CALL ProgressBar::setForegroundColor( sal_Int32 nColor ) throw( RuntimeException )
175 // Ready for multithreading
176 MutexGuard aGuard (m_aMutex) ;
178 // Safe color for later use.
179 m_nForegroundColor = nColor ;
181 // Repaint control
182 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
185 //____________________________________________________________________________________________________________
186 // XProgressBar
187 //____________________________________________________________________________________________________________
189 void SAL_CALL ProgressBar::setBackgroundColor ( sal_Int32 nColor ) throw( RuntimeException )
191 // Ready for multithreading
192 MutexGuard aGuard (m_aMutex) ;
194 // Safe color for later use.
195 m_nBackgroundColor = nColor ;
197 // Repaint control
198 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
201 //____________________________________________________________________________________________________________
202 // XProgressBar
203 //____________________________________________________________________________________________________________
205 void SAL_CALL ProgressBar::setValue ( sal_Int32 nValue ) throw( RuntimeException )
207 // This method is defined for follow things:
208 // 1) Values >= _nMinRange
209 // 2) Values <= _nMaxRange
211 // Ready for multithreading
212 MutexGuard aGuard (m_aMutex) ;
214 // save impossible cases
215 // This method is only defined for valid values
216 DBG_ASSERT ( (( nValue >= m_nMinRange ) && ( nValue <= m_nMaxRange )), "ProgressBar::setValue()\nNot valid value.\n" ) ;
218 // If new value not valid ... do nothing in release version!
219 if (
220 ( nValue >= m_nMinRange ) &&
221 ( nValue <= m_nMaxRange )
224 // New value is ok => save this
225 m_nValue = nValue ;
227 // Repaint to display changes
228 impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
232 //____________________________________________________________________________________________________________
233 // XProgressBar
234 //____________________________________________________________________________________________________________
236 void SAL_CALL ProgressBar::setRange ( sal_Int32 nMin, sal_Int32 nMax ) throw( RuntimeException )
238 // This method is defined for follow things:
239 // 1) All values of sal_Int32
240 // 2) Min < Max
241 // 3) Min > Max
243 // save impossible cases
244 // This method is only defined for valid values
245 // If you ignore this, the release version wil produce an error "division by zero" in "ProgressBar::setValue()"!
246 DBG_ASSERT ( ( nMin != nMax ) , "ProgressBar::setRange()\nValues for MIN and MAX are the same. This is not allowed!\n" ) ;
248 // Ready for multithreading
249 MutexGuard aGuard (m_aMutex) ;
251 // control the values for min and max
252 if ( nMin < nMax )
254 // Take correct Min and Max
255 m_nMinRange = nMin ;
256 m_nMaxRange = nMax ;
258 else
260 // Change Min and Max automaticly
261 m_nMinRange = nMax ;
262 m_nMaxRange = nMin ;
265 // assure that m_nValue is within the range
266 if (!(m_nMinRange < m_nValue && m_nValue < m_nMaxRange))
267 m_nValue = m_nMinRange;
269 impl_recalcRange () ;
271 // Do not repaint the control at this place!!!
272 // An old "m_nValue" is set and can not be correct for this new range.
273 // Next call of "ProgressBar::setValue()" do this.
276 //____________________________________________________________________________________________________________
277 // XProgressBar
278 //____________________________________________________________________________________________________________
280 sal_Int32 SAL_CALL ProgressBar::getValue () throw( RuntimeException )
282 // Ready for multithreading
283 MutexGuard aGuard (m_aMutex) ;
285 return ( m_nValue ) ;
288 //____________________________________________________________________________________________________________
289 // XWindow
290 //____________________________________________________________________________________________________________
292 void SAL_CALL ProgressBar::setPosSize (
293 sal_Int32 nX,
294 sal_Int32 nY,
295 sal_Int32 nWidth,
296 sal_Int32 nHeight,
297 sal_Int16 nFlags
298 ) throw( RuntimeException )
300 // Take old size BEFORE you set the new values at baseclass!
301 // You will control changes. At the other way, the values are the same!
302 Rectangle aBasePosSize = getPosSize () ;
303 BaseControl::setPosSize (nX, nY, nWidth, nHeight, nFlags) ;
305 // Do only, if size has changed.
306 if (
307 ( nWidth != aBasePosSize.Width ) ||
308 ( nHeight != aBasePosSize.Height )
311 impl_recalcRange ( ) ;
312 impl_paint ( 0, 0, impl_getGraphicsPeer () ) ;
316 //____________________________________________________________________________________________________________
317 // XControl
318 //____________________________________________________________________________________________________________
320 sal_Bool SAL_CALL ProgressBar::setModel( const Reference< XControlModel >& /*xModel*/ ) throw( RuntimeException )
322 // A model is not possible for this control.
323 return sal_False ;
326 //____________________________________________________________________________________________________________
327 // XControl
328 //____________________________________________________________________________________________________________
330 Reference< XControlModel > SAL_CALL ProgressBar::getModel() throw( RuntimeException )
332 // A model is not possible for this control.
333 return Reference< XControlModel >();
336 //____________________________________________________________________________________________________________
337 // impl but public method to register service
338 //____________________________________________________________________________________________________________
340 const Sequence< OUString > ProgressBar::impl_getStaticSupportedServiceNames()
342 MutexGuard aGuard( Mutex::getGlobalMutex() );
343 Sequence< OUString > seqServiceNames( 1 );
344 seqServiceNames.getArray() [0] = SERVICENAME_PROGRESSBAR;
345 return seqServiceNames ;
348 //____________________________________________________________________________________________________________
349 // impl but public method to register service
350 //____________________________________________________________________________________________________________
352 const OUString ProgressBar::impl_getStaticImplementationName()
354 return OUString(IMPLEMENTATIONNAME_PROGRESSBAR );
357 //____________________________________________________________________________________________________________
358 // protected method
359 //____________________________________________________________________________________________________________
361 void ProgressBar::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
363 // save impossible cases
364 DBG_ASSERT ( rGraphics.is(), "ProgressBar::paint()\nCalled with invalid Reference< XGraphics > ." ) ;
366 // This paint method ist not buffered !!
367 // Every request paint the completely control. ( but only, if peer exist )
368 if ( rGraphics.is () )
370 MutexGuard aGuard (m_aMutex) ;
372 // Clear background
373 // (same color for line and fill)
374 rGraphics->setFillColor ( m_nBackgroundColor ) ;
375 rGraphics->setLineColor ( m_nBackgroundColor ) ;
376 rGraphics->drawRect ( nX, nY, impl_getWidth(), impl_getHeight() ) ;
378 // same color for line and fill for blocks
379 rGraphics->setFillColor ( m_nForegroundColor ) ;
380 rGraphics->setLineColor ( m_nForegroundColor ) ;
382 sal_Int32 nBlockStart = 0 ; // = left site of new block
383 sal_Int32 nBlockCount = m_nBlockValue!=0.00 ? (sal_Int32)((m_nValue-m_nMinRange)/m_nBlockValue) : 0 ; // = number of next block
385 // Draw horizontal progressbar
386 // decision in "recalcRange()"
387 if (m_bHorizontal)
389 // Step to left side of window
390 nBlockStart = nX ;
392 for ( sal_Int16 i=1; i<=nBlockCount; ++i )
394 // step free field
395 nBlockStart += PROGRESSBAR_FREESPACE ;
396 // paint block
397 rGraphics->drawRect (nBlockStart, nY+PROGRESSBAR_FREESPACE, m_aBlockSize.Width, m_aBlockSize.Height) ;
398 // step next free field
399 nBlockStart += m_aBlockSize.Width ;
402 // draw vertikal progressbar
403 // decision in "recalcRange()"
404 else
406 // step to bottom side of window
407 nBlockStart = nY+impl_getHeight() ;
408 nBlockStart -= m_aBlockSize.Height ;
410 for ( sal_Int16 i=1; i<=nBlockCount; ++i )
412 // step free field
413 nBlockStart -= PROGRESSBAR_FREESPACE ;
414 // paint block
415 rGraphics->drawRect (nX+PROGRESSBAR_FREESPACE, nBlockStart, m_aBlockSize.Width, m_aBlockSize.Height) ;
416 // step next free field
417 nBlockStart -= m_aBlockSize.Height;
421 // Paint shadow border around the progressbar
422 rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_SHADOW ) ;
423 rGraphics->drawLine ( nX, nY, impl_getWidth(), nY ) ;
424 rGraphics->drawLine ( nX, nY, nX , impl_getHeight() ) ;
426 rGraphics->setLineColor ( PROGRESSBAR_LINECOLOR_BRIGHT ) ;
427 rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY ) ;
428 rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 ) ;
432 //____________________________________________________________________________________________________________
433 // protected method
434 //____________________________________________________________________________________________________________
436 void ProgressBar::impl_recalcRange ()
438 MutexGuard aGuard (m_aMutex) ;
440 sal_Int32 nWindowWidth = impl_getWidth() ;
441 sal_Int32 nWindowHeight = impl_getHeight() ;
442 double fBlockHeight ;
443 double fBlockWidth ;
444 double fMaxBlocks ;
446 if( nWindowWidth > nWindowHeight )
448 m_bHorizontal = sal_True ;
449 fBlockHeight = (nWindowHeight-(2*PROGRESSBAR_FREESPACE)) ;
450 fBlockWidth = fBlockHeight ;
451 fMaxBlocks = nWindowWidth/(fBlockWidth+PROGRESSBAR_FREESPACE);
453 else
455 m_bHorizontal = sal_False ;
456 fBlockWidth = (nWindowWidth-(2*PROGRESSBAR_FREESPACE)) ;
457 fBlockHeight = fBlockWidth ;
458 fMaxBlocks = nWindowHeight/(fBlockHeight+PROGRESSBAR_FREESPACE);
461 double fRange = m_nMaxRange-m_nMinRange ;
462 double fBlockValue = fRange/fMaxBlocks ;
464 m_nBlockValue = fBlockValue ;
465 m_aBlockSize.Height = (sal_Int32)fBlockHeight;
466 m_aBlockSize.Width = (sal_Int32)fBlockWidth ;
469 } // namespace unocontrols
471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */