|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (developer.feedback@nokia.com) |
|
6 ** |
|
7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile. |
|
8 ** |
|
9 ** GNU Lesser General Public License Usage |
|
10 ** This file may be used under the terms of the GNU Lesser General Public |
|
11 ** License version 2.1 as published by the Free Software Foundation and |
|
12 ** appearing in the file LICENSE.LGPL included in the packaging of this file. |
|
13 ** Please review the following information to ensure the GNU Lesser General |
|
14 ** Public License version 2.1 requirements will be met: |
|
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
16 ** |
|
17 ** In addition, as a special exception, Nokia gives you certain additional |
|
18 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
20 ** |
|
21 ** If you have questions regarding the use of this file, please contact |
|
22 ** Nokia at developer.feedback@nokia.com. |
|
23 ** |
|
24 ****************************************************************************/ |
|
25 |
|
26 #include "hbvolumeslider_p.h" |
|
27 #include "hbslider_p.h" |
|
28 #include "hbnamespace_p.h" |
|
29 #include "hbslidercontrol_p_p.h" |
|
30 #include "hbinstance.h" |
|
31 #include "hbabstractbutton.h" |
|
32 #include "hbslidercontrol_p.h" |
|
33 #include "hbstyleoptionslider.h" |
|
34 #include <QGraphicsSceneEvent> |
|
35 #include <QGraphicsScene> |
|
36 #include <hbwidgetfeedback.h> |
|
37 |
|
38 /*! |
|
39 \depricated |
|
40 This class will be depricated |
|
41 Use HbSlider instead |
|
42 Example usage: |
|
43 \code |
|
44 HbSlider *slider = new HbSlider(Qt::Horizontal); |
|
45 QList<HbSlider::SliderElement> sliderElements; |
|
46 sliderElements.append(HbSlider::DecreaseElement); |
|
47 sliderElements.append(HbSlider::TrackElement); |
|
48 sliderElements.append(HbSlider::IncreaseElement); |
|
49 sliderElements.append(HbSlider::IconElement); |
|
50 sliderElements.append(HbSlider::TextElement); |
|
51 slider->setElements(sliderElements); |
|
52 slider->setRange(0, 100); |
|
53 slider->setMajorTickInterval(50); |
|
54 slider->setTickPosition(Hb::SliderTicksLeft); |
|
55 // decreaseIcon is valid HbIcon |
|
56 slider->setIcon(HbSlider::DecreaseElement, decreaseIcon); |
|
57 // increaseIcon is valid HbIcon |
|
58 slider->setIcon(HbSlider:: IncreaseElement, increaseIcon); |
|
59 // icon is valid HbIcon |
|
60 slider->setIcon(HbSlider:: IncreaseElement,icon); |
|
61 slider->setText( "1%"); |
|
62 \endcode |
|
63 @hbwidgets |
|
64 \class HbVolumeSlider |
|
65 \brief HbVolumeSlider widget provides a vertical volume slider. |
|
66 |
|
67 HbVolumeSlider is provided for convenience. HbVolumeSlider sets appropriate |
|
68 icons and provides volume slider specific functionality like a |
|
69 checkable mute button and appropriate elements out of the box. HbVolumeSlider |
|
70 consists of following slider elements by default: |
|
71 \li HbSlider::IncreaseElement |
|
72 \li HbSlider::TrackElement |
|
73 \li HbSlider::DecreaseElement |
|
74 \li HbSlider::IconElement |
|
75 |
|
76 \image html hbvolumeslider.png A volume slider. |
|
77 |
|
78 The elements can be changed by calling HbSlider::setElements( ) later at any time. |
|
79 |
|
80 \note order of element can not be changed |
|
81 |
|
82 By default HbVolumeSlider will have ticks on right side ( Hb::SliderTicksRight) . |
|
83 |
|
84 Orientation of HbVolumeSlider can not be changed. If orientation change is needed, |
|
85 then first create HbSlider and set needed elements. |
|
86 |
|
87 Example usage: |
|
88 \code |
|
89 HbVolumeSlider *slider = new HbVolumeSlider( this ); |
|
90 connect( slider, SIGNAL( valueChanged( int ) ), receiver, SLOT( volumeSliderChanged( int ) ) ); |
|
91 connect( slider, SIGNAL( iconToggled( bool ) ), receiver, SLOT( volumeMuted( bool ) ) ); |
|
92 \endcode |
|
93 |
|
94 Note:: if setElement is called on this slider , application is reponsible for |
|
95 inconsitent UI. |
|
96 */ |
|
97 |
|
98 |
|
99 class HbVolumeSliderPrivate : public HbSliderPrivate |
|
100 { |
|
101 Q_DECLARE_PUBLIC( HbVolumeSlider ) |
|
102 |
|
103 public: |
|
104 HbVolumeSliderPrivate( ); |
|
105 virtual ~HbVolumeSliderPrivate( ); |
|
106 void init( ); |
|
107 void _q_valueChanged( int value ); |
|
108 void _q_muteToggled( bool state ); |
|
109 bool currentValueVisible; |
|
110 // store previous value for un mute |
|
111 int previousValue; |
|
112 }; |
|
113 |
|
114 |
|
115 HbVolumeSliderPrivate::HbVolumeSliderPrivate( ) |
|
116 { |
|
117 |
|
118 } |
|
119 |
|
120 |
|
121 HbVolumeSliderPrivate::~HbVolumeSliderPrivate( ) |
|
122 { |
|
123 } |
|
124 |
|
125 |
|
126 void HbVolumeSliderPrivate::init( ) |
|
127 { |
|
128 Q_Q( HbVolumeSlider ); |
|
129 q->connect( q, SIGNAL( valueChanged( int ) ), q, SLOT( _q_valueChanged( int ) ) ); |
|
130 q->connect( q, SIGNAL( iconToggled( bool ) ), q, SLOT( _q_muteToggled( bool ) ) ); |
|
131 QList<HbSlider::SliderElement> elements; |
|
132 elements << HbSlider::IncreaseElement |
|
133 << HbSlider::TrackElement |
|
134 << HbSlider::DecreaseElement |
|
135 << HbSlider::IconElement; |
|
136 if( currentValueVisible ) |
|
137 elements<<HbSlider::TextElement; |
|
138 setElements( elements ); |
|
139 // create element because HbSlider will not create element for NULL Icon |
|
140 // and volume slider Icon is set in style |
|
141 if ( !elementItemMap.contains(HbSlider::IncreaseElement) ) { |
|
142 elementItemMap [HbSlider::IncreaseElement].item = |
|
143 q->style( )->createPrimitive( HbStyle::P_SliderElement_increase, q); |
|
144 HbStyle::setItemName( elementItemMap [HbSlider::IncreaseElement].item, "increment-icon" ); |
|
145 elementItemMap[HbSlider::IncreaseElement].type = HbStyle::P_SliderElement_increase; |
|
146 elementItemMap [HbSlider::IncreaseElement].touchItem = q->style( )->createPrimitive( HbStyle::P_SliderElement_touchincrease, q ); |
|
147 // create touch area for increment |
|
148 HbStyle::setItemName( elementItemMap [HbSlider::IncreaseElement].touchItem, "increment-icon-toucharea" ); |
|
149 } |
|
150 |
|
151 if ( !elementItemMap.contains(HbSlider::DecreaseElement) ) { |
|
152 elementItemMap[HbSlider::DecreaseElement].item = |
|
153 q->style( )->createPrimitive( HbStyle::P_SliderElement_decrease, q ); |
|
154 elementItemMap[HbSlider::DecreaseElement].type = HbStyle::P_SliderElement_decrease; |
|
155 HbStyle::setItemName( elementItemMap[HbSlider::DecreaseElement].item, "decrement-icon" ); |
|
156 |
|
157 // create touch area for decrement |
|
158 elementItemMap[HbSlider::DecreaseElement].touchItem = q->style( )->createPrimitive( HbStyle::P_SliderElement_touchdecrease, q ) ; |
|
159 HbStyle::setItemName( elementItemMap[HbSlider::DecreaseElement].touchItem, "decrement-icon-toucharea" ); |
|
160 } |
|
161 if( !elementItemMap.contains(HbSlider::IconElement) ) { |
|
162 elementItemMap[HbSlider::IconElement].item = q->style( )->createPrimitive( HbStyle::P_SliderElement_icon,q ); |
|
163 elementItemMap[HbSlider::IconElement].type = HbStyle::P_SliderElement_icon; |
|
164 HbStyle::setItemName( elementItemMap[HbSlider::IconElement].item, "icon-icon" ); |
|
165 // creating a dummy button , because slider icon |
|
166 // need to emit all signal which is emitted by button |
|
167 // there is no need for touch item for slider icon because |
|
168 // button can act as touch area |
|
169 HbAbstractButton *sliderIcon = new HbAbstractButton( q ); |
|
170 elementItemMap [HbSlider::IconElement].touchItem=sliderIcon; |
|
171 HbStyle::setItemName( sliderIcon, "icon" ); |
|
172 q->connect( sliderIcon, SIGNAL( pressed( ) ), q, SIGNAL( iconPressed( ) ) ); |
|
173 q->connect( sliderIcon, SIGNAL( released( ) ), q, SIGNAL( iconReleased( ) ) ); |
|
174 q->connect( sliderIcon, SIGNAL( clicked( ) ), q, SIGNAL( iconClicked( ) ) ); |
|
175 q->connect( sliderIcon, SIGNAL( toggled( bool ) ), q, SIGNAL( iconToggled( bool ) ) ); |
|
176 |
|
177 #ifdef HB_EFFECTS |
|
178 q->connect( sliderIcon, SIGNAL( pressed( ) ), q, SLOT( _q_startIconPressedEffect( ) ) ); |
|
179 q->connect( sliderIcon, SIGNAL( released( ) ), q,SLOT( _q_startIconReleasedEffect( ) ) ); |
|
180 #endif |
|
181 } |
|
182 |
|
183 HbStyleOptionSlider option; |
|
184 q->initStyleOption( &option ); |
|
185 option.sliderElementIcon = icons.value( HbSlider::IncreaseElement ); |
|
186 q->style( )->updatePrimitive( elementItemMap [HbSlider::IncreaseElement].item,HbStyle::P_SliderElement_increase,&option ); |
|
187 option.sliderElementIcon = icons.value( HbSlider::DecreaseElement ); |
|
188 q->style( )->updatePrimitive( elementItemMap[HbSlider::DecreaseElement].item,HbStyle::P_SliderElement_decrease,&option ); |
|
189 option.sliderElementIcon = icons.value( HbSlider::IconElement ); |
|
190 q->style( )->updatePrimitive( elementItemMap[HbSlider::IconElement].item,elementItemMap[HbSlider::IconElement].type,&option ); |
|
191 q->setIconCheckable( true ); |
|
192 q->setFlags( QGraphicsItem::ItemIsFocusable ); |
|
193 q->setProperty("changeincrementState" ,false); |
|
194 q->setProperty("changedecrementState" ,false); |
|
195 q->setProperty("state", "normal"); |
|
196 } |
|
197 |
|
198 /*! |
|
199 this slot will be called when ever slider value changes |
|
200 This wil change icon of mute /unmute button based on slider value |
|
201 */ |
|
202 void HbVolumeSliderPrivate::_q_valueChanged( int value ) |
|
203 { |
|
204 Q_Q( HbVolumeSlider ); |
|
205 if( q->minimum( )==value ) { |
|
206 // volume is mute |
|
207 q->setIconChecked( true ); |
|
208 } else { |
|
209 // unmute volume |
|
210 q->setIconEnabled( true ); |
|
211 q->setIconChecked( false ); |
|
212 } |
|
213 } |
|
214 |
|
215 /*! |
|
216 This slot will be called when slider value reaches to non zero to zero |
|
217 or vice versa |
|
218 */ |
|
219 void HbVolumeSliderPrivate::_q_muteToggled( bool state ) |
|
220 { |
|
221 Q_Q( HbVolumeSlider ); |
|
222 HbStyleOptionSlider option; |
|
223 q->initStyleOption( &option ); |
|
224 sliderControl->setPreviousValue( false , 0 ); |
|
225 if( state ) { |
|
226 previousValue=q->value( ); |
|
227 if ( previousValue == q->minimum( ) ) { |
|
228 // mute via drag |
|
229 sliderControl->setPreviousValue( true , previousValue + q->singleStep( ) ); |
|
230 } |
|
231 else { |
|
232 //mute by clicking on mute icon |
|
233 sliderControl->setPreviousValue( true , previousValue ); |
|
234 } |
|
235 q->setValue( q->minimum( ) ); |
|
236 option.state |= QStyle::State_Sunken; |
|
237 if( previousValue==q->minimum( ) ){ |
|
238 q->setIconEnabled( false ); |
|
239 } |
|
240 } else { |
|
241 // If Icon is toggled by pressing on it |
|
242 sliderControl->setPreviousValue( false , 0 ); |
|
243 if( q->value( )==q->minimum( ) ) { |
|
244 q->setValue( previousValue ); |
|
245 } |
|
246 option.state&= ~( QStyle::State_Sunken ); |
|
247 } |
|
248 option.sliderElementIcon = icons.value( HbSlider::IconElement ); |
|
249 q->style( )->updatePrimitive( elementItemMap[HbSlider::IconElement].item,HbStyle::P_SliderElement_icon,&option ); |
|
250 |
|
251 } |
|
252 |
|
253 |
|
254 /*! |
|
255 \deprecated HbVolumeSlider::HbVolumeSlider( bool currentValueVisible,QGraphicsItem *parent ) |
|
256 is deprecated. Please use HbSlider instead |
|
257 |
|
258 The orientation is \b Qt::Vertical and the slider contains increase, track, |
|
259 |
|
260 decrease and icon elements by default. |
|
261 |
|
262 \sa setOrientation( ), setElements( ) |
|
263 |
|
264 show current value if \a currentValueVisible is true |
|
265 */ |
|
266 HbVolumeSlider::HbVolumeSlider( bool currentValueVisible,QGraphicsItem *parent ) |
|
267 : HbSlider( *new HbVolumeSliderPrivate, parent ) |
|
268 { |
|
269 Q_D( HbVolumeSlider ); |
|
270 d->q_ptr = this; |
|
271 d->currentValueVisible = currentValueVisible; |
|
272 d->init( ); |
|
273 // The default values for volume slider are specified by UX |
|
274 setRange( 0,100 ); |
|
275 setSingleStep( 10 ); |
|
276 setMajorTickInterval( 10 ); |
|
277 setSliderPosition( 80 ); |
|
278 setTickPosition( Hb::SliderTicksRight ); |
|
279 updatePrimitives( ); |
|
280 } |
|
281 |
|
282 /*! |
|
283 Destroys the volume slider. |
|
284 */ |
|
285 HbVolumeSlider::~HbVolumeSlider( ) |
|
286 { |
|
287 } |
|
288 |
|
289 |
|
290 /*! |
|
291 \deprecated HbVolumeSlider::setCurrentValueVisible( bool visible ) |
|
292 is deprecated. Please use HbSlider instead |
|
293 Sets whether the text element is visible. |
|
294 |
|
295 \sa isCurrentValueVisible( ) |
|
296 */ |
|
297 void HbVolumeSlider::setCurrentValueVisible( bool visible ) |
|
298 { |
|
299 Q_D( HbVolumeSlider ); |
|
300 if( visible != d->currentValueVisible ) { |
|
301 // add/delete text element |
|
302 d->currentValueVisible = visible; |
|
303 QList<HbSlider::SliderElement> elements; |
|
304 elements << HbSlider::IncreaseElement |
|
305 << HbSlider::TrackElement |
|
306 << HbSlider::DecreaseElement |
|
307 << HbSlider::IconElement; |
|
308 if( visible ) { |
|
309 elements<<HbSlider::TextElement; |
|
310 } |
|
311 //reset all value specified by UX |
|
312 d->setElements( elements ); |
|
313 setRange( 0,100 ); |
|
314 setSingleStep( 10 ); |
|
315 setMajorTickInterval( 10 ); |
|
316 setSliderPosition( 80 ); |
|
317 setTickPosition( Hb::SliderTicksRight ); |
|
318 updatePrimitives( ); |
|
319 } |
|
320 } |
|
321 |
|
322 |
|
323 /*! |
|
324 \deprecated HbVolumeSlider::isCurrentValueVisible( ) const |
|
325 is deprecated. Please use HbSlider instead |
|
326 Returns \c true whether the text element is visible. |
|
327 |
|
328 The default value is \c false. |
|
329 |
|
330 \sa setCurrentValueVisible( ) |
|
331 */ |
|
332 bool HbVolumeSlider::isCurrentValueVisible( ) const |
|
333 { |
|
334 Q_D( const HbVolumeSlider ); |
|
335 return d->currentValueVisible ; |
|
336 } |
|
337 |
|
338 /*! |
|
339 \deprecated HbVolumeSlider::setToolTipVisible( bool b ) |
|
340 is deprecated. Please use HbSlider instead |
|
341 \reimp |
|
342 |
|
343 This is not supported in HbVolumeSlider |
|
344 */ |
|
345 void HbVolumeSlider::setToolTipVisible( bool /*b*/ ) |
|
346 { |
|
347 Q_ASSERT_X( false, "HbZoomSlider::setToolTipVisible( )", |
|
348 "Current value display as tooltip is not supported in volume slider" ); |
|
349 } |
|
350 |
|
351 /*! |
|
352 \reimp |
|
353 unmute the volume to previous store value in case unmute happens |
|
354 by clicking increment/decrement icon |
|
355 */ |
|
356 void HbVolumeSlider::mousePressEvent( QGraphicsSceneMouseEvent *event ) |
|
357 { |
|
358 Q_D( HbVolumeSlider ); |
|
359 if( d->elementItemMap.contains(HbSlider::IncreaseElement) ) { |
|
360 if ( d->elementItemMap[HbSlider::IncreaseElement].touchItem->isUnderMouse( ) ) { |
|
361 d->pressOnIncrement = true; |
|
362 HbWidgetFeedback::triggered( d->sliderControl, Hb::InstantPressed, Hb::ModifierSliderElement ); |
|
363 event->accept( ); |
|
364 // if volume was mute |
|
365 if( isIconChecked( ) ){ |
|
366 // take to previous value and increase one step |
|
367 setValue( d->previousValue+singleStep( ) ); |
|
368 // start timer for repeat action |
|
369 d->sliderControl->setRepeatAction( |
|
370 HbAbstractSliderControl::SliderSingleStepAdd, d->sliderControl->maximum( ) ); |
|
371 } else {// simply increase by one step |
|
372 d->startIncrementing( ); |
|
373 } |
|
374 setProperty("changeincrementState" ,true); |
|
375 setProperty("changedecrementState" ,false); |
|
376 setProperty("state", "pressed"); |
|
377 return; |
|
378 } |
|
379 } |
|
380 if( d->elementItemMap.contains(HbSlider::DecreaseElement) ) { |
|
381 if ( d->elementItemMap[HbSlider::DecreaseElement].touchItem->isUnderMouse( ) ) { |
|
382 d->pressOnIncrement = false; |
|
383 HbWidgetFeedback::triggered( d->sliderControl, Hb::InstantPressed, Hb::ModifierSliderElement ); |
|
384 event->accept( ); |
|
385 if( isIconChecked( ) ){ |
|
386 //set value to previous value and decrement by one step |
|
387 setValue( d->previousValue-singleStep( ) ); |
|
388 if( value( )==minimum( ) ){ |
|
389 d->previousValue = value( ); |
|
390 setIconEnabled( false ); |
|
391 } |
|
392 //start timer for repeat action |
|
393 d->sliderControl->setRepeatAction( |
|
394 HbAbstractSliderControl::SliderSingleStepSub, d->sliderControl->minimum( ) ); |
|
395 } else { |
|
396 d->startDecrementing( ); |
|
397 } |
|
398 setProperty("changeincrementState" ,false); |
|
399 setProperty("changedecrementState" ,true); |
|
400 setProperty("state", "pressed"); |
|
401 return; |
|
402 } |
|
403 } |
|
404 HbSlider::mousePressEvent( event ); |
|
405 } |
|
406 |
|
407 /*! |
|
408 \reimp |
|
409 stop the timer and change image for increment element /decrement element |
|
410 */ |
|
411 void HbVolumeSlider::mouseReleaseEvent( QGraphicsSceneMouseEvent *event ) |
|
412 { |
|
413 Q_D( HbVolumeSlider ); |
|
414 HbSlider::mouseReleaseEvent( event ); |
|
415 d->stopRepeatAction( ); |
|
416 setProperty("state", "normal"); |
|
417 } |
|
418 |
|
419 /*! |
|
420 \reimp |
|
421 */ |
|
422 QVariant HbVolumeSlider::itemChange( GraphicsItemChange change, const QVariant &value ) |
|
423 { |
|
424 Q_D( HbVolumeSlider ); |
|
425 switch ( static_cast<HbPrivate::HbItemChangeValues>( change ) ) { |
|
426 case ItemVisibleHasChanged: |
|
427 if( !value.toBool( ) ){ |
|
428 d->stopRepeatAction( ); |
|
429 if( d->sliderControl ){ |
|
430 d->sliderControl->setSliderDown( false ); |
|
431 } |
|
432 setProperty("changeincrementState" ,false); |
|
433 setProperty("changedecrementState" ,false); |
|
434 setProperty("state", "normal"); |
|
435 } |
|
436 break; |
|
437 default: |
|
438 break; |
|
439 } |
|
440 return HbSlider::itemChange( change, value ); |
|
441 } |
|
442 |
|
443 /*! |
|
444 \reimp |
|
445 */ |
|
446 void HbVolumeSlider::initStyleOption( HbStyleOptionSlider *option ) const |
|
447 { |
|
448 option->sliderType=HbStyleOptionSlider::VolumeType; |
|
449 HbSlider::initStyleOption( option ); |
|
450 |
|
451 } |
|
452 |
|
453 /*! |
|
454 \reimp |
|
455 */ |
|
456 void HbVolumeSlider::focusInEvent( QFocusEvent* /*event*/ ) |
|
457 { |
|
458 Q_D( HbVolumeSlider ); |
|
459 d->sliderControl->setFocus( ); |
|
460 } |
|
461 |
|
462 #include "moc_hbvolumeslider_p.cpp" |
|
463 |
|
464 |
|
465 |