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/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>
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
)
52 ,meImageSet( i_imageSet
)
54 maWaitTimer
.SetTimeout( mnStepTime
);
55 maWaitTimer
.SetTimeoutHdl( LINK( this, Throbber
, TimeOutHdl
) );
57 SetScaleMode( ImageScaleMode::None
);
61 Throbber::Throbber( Window
* i_parentWindow
, const ResId
& i_resId
, const ImageSet i_imageSet
)
62 :ImageControl( i_parentWindow
, i_resId
)
67 ,meImageSet( i_imageSet
)
69 maWaitTimer
.SetTimeout( mnStepTime
);
70 maWaitTimer
.SetTimeoutHdl( LINK( this, Throbber
, TimeOutHdl
) );
72 SetScaleMode( ImageScaleMode::None
);
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();
100 Reference
< XGraphic
> xGraphic
;
101 aMediaProperties
.put( "URL", *imageURL
);
102 xGraphic
.set( xGraphicProvider
->queryGraphic( aMediaProperties
.getPropertyValues() ), UNO_QUERY
);
103 aImages
.push_back( Image( xGraphic
) );
110 void Throbber::Resize()
112 ImageControl::Resize();
114 if ( meImageSet
== IMAGES_AUTO
)
118 void Throbber::initImages()
120 if ( meImageSet
== IMAGES_NONE
)
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
) );
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();
148 if ( check
->empty() )
150 SAL_WARN( "vcl.control", "Throbber::initImages: illegal image!" );
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
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()
187 void Throbber::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() );
210 rImageList
.getConstArray(),
211 rImageList
.getConstArray() + rImageList
.getLength(),
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 };
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;
232 OSL_ENSURE( false, "Throbber::getDefaultImageURLs: illegal image set!" );
236 aImageURLs
.reserve( nImageCounts
[index
] );
237 for ( size_t i
=0; i
<nImageCounts
[index
]; ++i
)
240 aURL
.appendAscii( "private:graphicrepository/vcl/res/spinner-" );
241 aURL
.appendAscii( pResolutions
[index
] );
242 aURL
.appendAscii( "-" );
244 aURL
.appendAscii( "0" );
245 aURL
.append ( sal_Int32( i
+ 1 ) );
246 aURL
.appendAscii( ".png" );
248 aImageURLs
.push_back( aURL
.makeStringAndClear() );
254 IMPL_LINK_NOARG(Throbber
, TimeOutHdl
)
256 SolarMutexGuard aGuard
;
257 if ( maImageList
.empty() )
260 if ( mnCurStep
< mnStepCount
- 1 )
275 SetImage( maImageList
[ mnCurStep
] );
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */