update credits
[LibreOffice.git] / vcl / source / control / throbber.cxx
blobde04560f1d2b5231024c25b4333ea06ce30c35cc
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 "vcl/throbber.hxx"
21 #include "vcl/svapp.hxx"
23 #include <com/sun/star/uno/XComponentContext.hpp>
24 #include <com/sun/star/graphic/GraphicProvider.hpp>
25 #include <com/sun/star/graphic/XGraphicProvider.hpp>
26 #include <com/sun/star/awt/ImageScaleMode.hpp>
28 #include <comphelper/componentcontext.hxx>
29 #include <comphelper/namedvaluecollection.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <rtl/ustrbuf.hxx>
32 #include <tools/diagnose_ex.h>
33 #include <tools/urlobj.hxx>
35 #include <limits>
37 using ::com::sun::star::uno::Sequence;
38 using ::com::sun::star::uno::Reference;
39 using ::com::sun::star::graphic::XGraphic;
40 using ::com::sun::star::graphic::XGraphicProvider;
41 using ::com::sun::star::uno::UNO_QUERY_THROW;
42 using ::com::sun::star::uno::UNO_QUERY;
43 using ::com::sun::star::uno::Exception;
44 namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
46 Throbber::Throbber( Window* i_parentWindow, WinBits i_style, const ImageSet i_imageSet )
47 :ImageControl( i_parentWindow, i_style )
48 ,mbRepeat( sal_True )
49 ,mnStepTime( 100 )
50 ,mnCurStep( 0 )
51 ,mnStepCount( 0 )
52 ,meImageSet( i_imageSet )
54 maWaitTimer.SetTimeout( mnStepTime );
55 maWaitTimer.SetTimeoutHdl( LINK( this, Throbber, TimeOutHdl ) );
57 SetScaleMode( ImageScaleMode::None );
58 initImages();
61 Throbber::Throbber( Window* i_parentWindow, const ResId& i_resId, const ImageSet i_imageSet )
62 :ImageControl( i_parentWindow, i_resId )
63 ,mbRepeat( sal_True )
64 ,mnStepTime( 100 )
65 ,mnCurStep( 0 )
66 ,mnStepCount( 0 )
67 ,meImageSet( i_imageSet )
69 maWaitTimer.SetTimeout( mnStepTime );
70 maWaitTimer.SetTimeoutHdl( LINK( this, Throbber, TimeOutHdl ) );
72 SetScaleMode( ImageScaleMode::None );
73 initImages();
76 Throbber::~Throbber()
78 maWaitTimer.Stop();
81 namespace
83 ::std::vector< Image > lcl_loadImageSet( const Throbber::ImageSet i_imageSet )
85 ::std::vector< Image > aImages;
86 ENSURE_OR_RETURN( i_imageSet != Throbber::IMAGES_NONE, "lcl_loadImageSet: illegal image set", aImages );
88 const Reference< com::sun::star::uno::XComponentContext > aContext( ::comphelper::getProcessComponentContext() );
89 const Reference< XGraphicProvider > xGraphicProvider( com::sun::star::graphic::GraphicProvider::create(aContext) );
91 ::std::vector< OUString > aImageURLs( Throbber::getDefaultImageURLs( i_imageSet ) );
92 aImages.reserve( aImageURLs.size() );
94 ::comphelper::NamedValueCollection aMediaProperties;
95 for ( ::std::vector< OUString >::const_iterator imageURL = aImageURLs.begin();
96 imageURL != aImageURLs.end();
97 ++imageURL
100 Reference< XGraphic > xGraphic;
101 aMediaProperties.put( "URL", *imageURL );
102 xGraphic.set( xGraphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
103 aImages.push_back( Image( xGraphic ) );
106 return aImages;
110 void Throbber::Resize()
112 ImageControl::Resize();
114 if ( meImageSet == IMAGES_AUTO )
115 initImages();
118 void Throbber::initImages()
120 if ( meImageSet == IMAGES_NONE )
121 return;
125 ::std::vector< ::std::vector< Image > > aImageSets;
126 if ( meImageSet == IMAGES_AUTO )
128 aImageSets.push_back( lcl_loadImageSet( IMAGES_16_PX ) );
129 aImageSets.push_back( lcl_loadImageSet( IMAGES_32_PX ) );
130 aImageSets.push_back( lcl_loadImageSet( IMAGES_64_PX ) );
132 else
134 aImageSets.push_back( lcl_loadImageSet( meImageSet ) );
137 // find the best matching image set (size-wise)
138 const ::Size aWindowSizePixel = GetSizePixel();
139 size_t nPreferredSet = 0;
140 if ( aImageSets.size() > 1 )
142 long nMinimalDistance = ::std::numeric_limits< long >::max();
143 for ( ::std::vector< ::std::vector< Image > >::const_iterator check = aImageSets.begin();
144 check != aImageSets.end();
145 ++check
148 if ( check->empty() )
150 SAL_WARN( "vcl.control", "Throbber::initImages: illegal image!" );
151 continue;
154 const Size aImageSize = (*check)[0].GetSizePixel();
156 if ( ( aImageSize.Width() > aWindowSizePixel.Width() )
157 || ( aImageSize.Height() > aWindowSizePixel.Height() )
159 // do not use an image set which doesn't fit into the window
160 continue;
162 const sal_Int64 distance =
163 ( aWindowSizePixel.Width() - aImageSize.Width() ) * ( aWindowSizePixel.Width() - aImageSize.Width() )
164 + ( aWindowSizePixel.Height() - aImageSize.Height() ) * ( aWindowSizePixel.Height() - aImageSize.Height() );
165 if ( distance < nMinimalDistance )
167 nMinimalDistance = distance;
168 nPreferredSet = check - aImageSets.begin();
173 if ( nPreferredSet < aImageSets.size() )
174 setImageList( aImageSets[nPreferredSet] );
176 catch( const Exception& )
178 DBG_UNHANDLED_EXCEPTION();
182 void Throbber::start()
184 maWaitTimer.Start();
187 void Throbber::stop()
189 maWaitTimer.Stop();
192 bool Throbber::isRunning() const
194 return maWaitTimer.IsActive();
197 void Throbber::setImageList( ::std::vector< Image > const& i_images )
199 maImageList = i_images;
201 mnStepCount = maImageList.size();
202 const Image aInitialImage( mnStepCount ? maImageList[ 0 ] : Image() );
203 SetImage( aInitialImage );
206 void Throbber::setImageList( const Sequence< Reference< XGraphic > >& rImageList )
208 ::std::vector< Image > aImages( rImageList.getLength() );
209 ::std::copy(
210 rImageList.getConstArray(),
211 rImageList.getConstArray() + rImageList.getLength(),
212 aImages.begin()
214 setImageList( aImages );
217 ::std::vector< OUString > Throbber::getDefaultImageURLs( const ImageSet i_imageSet )
219 ::std::vector< OUString > aImageURLs;
221 sal_Char const* const pResolutions[] = { "16", "32", "64" };
222 size_t const nImageCounts[] = { 6, 12, 12 };
224 size_t index = 0;
225 switch ( i_imageSet )
227 case IMAGES_16_PX: index = 0; break;
228 case IMAGES_32_PX: index = 1; break;
229 case IMAGES_64_PX: index = 2; break;
230 case IMAGES_NONE:
231 case IMAGES_AUTO:
232 OSL_ENSURE( false, "Throbber::getDefaultImageURLs: illegal image set!" );
233 return aImageURLs;
236 aImageURLs.reserve( nImageCounts[index] );
237 for ( size_t i=0; i<nImageCounts[index]; ++i )
239 OUStringBuffer aURL;
240 aURL.appendAscii( "private:graphicrepository/vcl/res/spinner-" );
241 aURL.appendAscii( pResolutions[index] );
242 aURL.appendAscii( "-" );
243 if ( i < 9 )
244 aURL.appendAscii( "0" );
245 aURL.append ( sal_Int32( i + 1 ) );
246 aURL.appendAscii( ".png" );
248 aImageURLs.push_back( aURL.makeStringAndClear() );
251 return aImageURLs;
254 IMPL_LINK_NOARG(Throbber, TimeOutHdl)
256 SolarMutexGuard aGuard;
257 if ( maImageList.empty() )
258 return 0;
260 if ( mnCurStep < mnStepCount - 1 )
261 mnCurStep += 1;
262 else
264 if ( mbRepeat )
266 // start over
267 mnCurStep = 0;
269 else
271 stop();
275 SetImage( maImageList[ mnCurStep ] );
277 return 0;
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */