source: ntrip/trunk/BNC/qwt/qwt_slider.cpp@ 8938

Last change on this file since 8938 was 8127, checked in by stoecker, 8 years ago

update qwt and qwtpolar, many QT5 fixes (unfinished)

File size: 23.3 KB
RevLine 
[8127]1/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_slider.h"
11#include "qwt_painter.h"
12#include "qwt_scale_draw.h"
13#include "qwt_scale_map.h"
14#include <qevent.h>
15#include <qdrawutil.h>
16#include <qpainter.h>
17#include <qalgorithms.h>
18#include <qmath.h>
19#include <qstyle.h>
20#include <qstyleoption.h>
21#include <qapplication.h>
22
23static QSize qwtHandleSize( const QSize &size,
24 Qt::Orientation orientation, bool hasTrough )
25{
26 QSize handleSize = size;
27
28 if ( handleSize.isEmpty() )
29 {
30 const int handleThickness = 16;
31 handleSize.setWidth( 2 * handleThickness );
32 handleSize.setHeight( handleThickness );
33
34 if ( !hasTrough )
35 handleSize.transpose();
36
37 if ( orientation == Qt::Vertical )
38 handleSize.transpose();
39 }
40
41 return handleSize;
42}
43
44static QwtScaleDraw::Alignment qwtScaleDrawAlignment(
45 Qt::Orientation orientation, QwtSlider::ScalePosition scalePos )
46{
47 QwtScaleDraw::Alignment align;
48
49 if ( orientation == Qt::Vertical )
50 {
51 // NoScale lays out like Left
52 if ( scalePos == QwtSlider::LeadingScale )
53 align = QwtScaleDraw::RightScale;
54 else
55 align = QwtScaleDraw::LeftScale;
56 }
57 else
58 {
59 // NoScale lays out like Bottom
60 if ( scalePos == QwtSlider::TrailingScale )
61 align = QwtScaleDraw::TopScale;
62 else
63 align = QwtScaleDraw::BottomScale;
64 }
65
66 return align;
67}
68
69class QwtSlider::PrivateData
70{
71public:
72 PrivateData():
73 repeatTimerId( 0 ),
74 updateInterval( 150 ),
75 stepsIncrement( 0 ),
76 pendingValueChange( false ),
77 borderWidth( 2 ),
78 spacing( 4 ),
79 scalePosition( QwtSlider::TrailingScale ),
80 hasTrough( true ),
81 hasGroove( false ),
82 mouseOffset( 0 )
83 {
84 }
85
86 int repeatTimerId;
87 bool timerTick;
88 int updateInterval;
89 int stepsIncrement;
90 bool pendingValueChange;
91
92 QRect sliderRect;
93
94 QSize handleSize;
95 int borderWidth;
96 int spacing;
97
98 Qt::Orientation orientation;
99 QwtSlider::ScalePosition scalePosition;
100
101 bool hasTrough;
102 bool hasGroove;
103
104 int mouseOffset;
105
106 mutable QSize sizeHintCache;
107};
108/*!
109 Construct vertical slider in QwtSlider::Trough style
110 with a scale to the left.
111
112 The scale is initialized to [0.0, 100.0] and the value set to 0.0.
113
114 \param parent Parent widget
115
116 \sa setOrientation(), setScalePosition(), setBackgroundStyle()
117*/
118QwtSlider::QwtSlider( QWidget *parent ):
119 QwtAbstractSlider( parent )
120{
121 initSlider( Qt::Vertical );
122}
123
124/*!
125 Construct a slider in QwtSlider::Trough style
126
127 When orientation is Qt::Vertical the scale will be aligned to
128 the left - otherwise at the the top of the slider.
129
130 The scale is initialized to [0.0, 100.0] and the value set to 0.0.
131
132 \param parent Parent widget
133 \param orientation Orientation of the slider.
134*/
135QwtSlider::QwtSlider( Qt::Orientation orientation, QWidget *parent ):
136 QwtAbstractSlider( parent )
137{
138 initSlider( orientation );
139}
140
141//! Destructor
142QwtSlider::~QwtSlider()
143{
144 delete d_data;
145}
146
147void QwtSlider::initSlider( Qt::Orientation orientation )
148{
149 if ( orientation == Qt::Vertical )
150 setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );
151 else
152 setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
153
154 setAttribute( Qt::WA_WState_OwnSizePolicy, false );
155
156 d_data = new QwtSlider::PrivateData;
157
158 d_data->orientation = orientation;
159
160 scaleDraw()->setAlignment(
161 qwtScaleDrawAlignment( orientation, d_data->scalePosition ) );
162 scaleDraw()->setLength( 100 );
163
164 setScale( 0.0, 100.0 );
165 setValue( 0.0 );
166}
167
168/*!
169 \brief Set the orientation.
170 \param orientation Allowed values are Qt::Horizontal and Qt::Vertical.
171
172 \sa orientation(), scalePosition()
173*/
174void QwtSlider::setOrientation( Qt::Orientation orientation )
175{
176 if ( orientation == d_data->orientation )
177 return;
178
179 d_data->orientation = orientation;
180
181 scaleDraw()->setAlignment(
182 qwtScaleDrawAlignment( orientation, d_data->scalePosition ) );
183
184 if ( !testAttribute( Qt::WA_WState_OwnSizePolicy ) )
185 {
186 QSizePolicy sp = sizePolicy();
187 sp.transpose();
188 setSizePolicy( sp );
189
190 setAttribute( Qt::WA_WState_OwnSizePolicy, false );
191 }
192
193 if ( testAttribute( Qt::WA_WState_Polished ) )
194 layoutSlider( true );
195}
196
197/*!
198 \return Orientation
199 \sa setOrientation()
200*/
201Qt::Orientation QwtSlider::orientation() const
202{
203 return d_data->orientation;
204}
205
206/*!
207 \brief Change the position of the scale
208 \param scalePosition Position of the scale.
209
210 \sa ScalePosition, scalePosition()
211*/
212void QwtSlider::setScalePosition( ScalePosition scalePosition )
213{
214 if ( d_data->scalePosition == scalePosition )
215 return;
216
217 d_data->scalePosition = scalePosition;
218 scaleDraw()->setAlignment(
219 qwtScaleDrawAlignment( d_data->orientation, scalePosition ) );
220
221 if ( testAttribute( Qt::WA_WState_Polished ) )
222 layoutSlider( true );
223}
224
225/*!
226 \return Position of the scale
227 \sa setScalePosition()
228 */
229QwtSlider::ScalePosition QwtSlider::scalePosition() const
230{
231 return d_data->scalePosition;
232}
233
234/*!
235 \brief Change the slider's border width
236
237 The border width is used for drawing the slider handle and the
238 trough.
239
240 \param width Border width
241 \sa borderWidth()
242*/
243void QwtSlider::setBorderWidth( int width )
244{
245 if ( width < 0 )
246 width = 0;
247
248 if ( width != d_data->borderWidth )
249 {
250 d_data->borderWidth = width;
251
252 if ( testAttribute( Qt::WA_WState_Polished ) )
253 layoutSlider( true );
254 }
255}
256
257/*!
258 \return the border width.
259 \sa setBorderWidth()
260*/
261int QwtSlider::borderWidth() const
262{
263 return d_data->borderWidth;
264}
265
266/*!
267 \brief Change the spacing between trough and scale
268
269 A spacing of 0 means, that the backbone of the scale is covered
270 by the trough.
271
272 The default setting is 4 pixels.
273
274 \param spacing Number of pixels
275 \sa spacing();
276*/
277void QwtSlider::setSpacing( int spacing )
278{
279 if ( spacing <= 0 )
280 spacing = 0;
281
282 if ( spacing != d_data->spacing )
283 {
284 d_data->spacing = spacing;
285
286 if ( testAttribute( Qt::WA_WState_Polished ) )
287 layoutSlider( true );
288 }
289}
290
291/*!
292 \return Number of pixels between slider and scale
293 \sa setSpacing()
294*/
295int QwtSlider::spacing() const
296{
297 return d_data->spacing;
298}
299
300/*!
301 \brief Set the slider's handle size
302
303 When the size is empty the slider handle will be painted with a
304 default size depending on its orientation() and backgroundStyle().
305
306 \param size New size
307
308 \sa handleSize()
309*/
310void QwtSlider::setHandleSize( const QSize &size )
311{
312 if ( size != d_data->handleSize )
313 {
314 d_data->handleSize = size;
315
316 if ( testAttribute( Qt::WA_WState_Polished ) )
317 layoutSlider( true );
318 }
319}
320
321/*!
322 \return Size of the handle.
323 \sa setHandleSize()
324*/
325QSize QwtSlider::handleSize() const
326{
327 return d_data->handleSize;
328}
329
330/*!
331 \brief Set a scale draw
332
333 For changing the labels of the scales, it
334 is necessary to derive from QwtScaleDraw and
335 overload QwtScaleDraw::label().
336
337 \param scaleDraw ScaleDraw object, that has to be created with
338 new and will be deleted in ~QwtSlider() or the next
339 call of setScaleDraw().
340
341 \sa scaleDraw()
342*/
343void QwtSlider::setScaleDraw( QwtScaleDraw *scaleDraw )
344{
345 const QwtScaleDraw *previousScaleDraw = this->scaleDraw();
346 if ( scaleDraw == NULL || scaleDraw == previousScaleDraw )
347 return;
348
349 if ( previousScaleDraw )
350 scaleDraw->setAlignment( previousScaleDraw->alignment() );
351
352 setAbstractScaleDraw( scaleDraw );
353
354 if ( testAttribute( Qt::WA_WState_Polished ) )
355 layoutSlider( true );
356}
357
358/*!
359 \return the scale draw of the slider
360 \sa setScaleDraw()
361*/
362const QwtScaleDraw *QwtSlider::scaleDraw() const
363{
364 return static_cast<const QwtScaleDraw *>( abstractScaleDraw() );
365}
366
367/*!
368 \return the scale draw of the slider
369 \sa setScaleDraw()
370*/
371QwtScaleDraw *QwtSlider::scaleDraw()
372{
373 return static_cast<QwtScaleDraw *>( abstractScaleDraw() );
374}
375
376//! Notify changed scale
377void QwtSlider::scaleChange()
378{
379 QwtAbstractSlider::scaleChange();
380
381 if ( testAttribute( Qt::WA_WState_Polished ) )
382 layoutSlider( true );
383}
384
385/*!
386 \brief Specify the update interval for automatic scrolling
387
388 The minimal accepted value is 50 ms.
389
390 \param interval Update interval in milliseconds
391
392 \sa setUpdateInterval()
393*/
394void QwtSlider::setUpdateInterval( int interval )
395{
396 d_data->updateInterval = qMax( interval, 50 );
397}
398
399/*!
400 \return Update interval in milliseconds for automatic scrolling
401 \sa setUpdateInterval()
402 */
403int QwtSlider::updateInterval() const
404{
405 return d_data->updateInterval;
406}
407
408/*!
409 Draw the slider into the specified rectangle.
410
411 \param painter Painter
412 \param sliderRect Bounding rectangle of the slider
413*/
414void QwtSlider::drawSlider(
415 QPainter *painter, const QRect &sliderRect ) const
416{
417 QRect innerRect( sliderRect );
418
419 if ( d_data->hasTrough )
420 {
421 const int bw = d_data->borderWidth;
422 innerRect = sliderRect.adjusted( bw, bw, -bw, -bw );
423
424 painter->fillRect( innerRect, palette().brush( QPalette::Mid ) );
425 qDrawShadePanel( painter, sliderRect, palette(), true, bw, NULL );
426 }
427
428 const QSize handleSize = qwtHandleSize( d_data->handleSize,
429 d_data->orientation, d_data->hasTrough );
430
431 if ( d_data->hasGroove )
432 {
433 const int slotExtent = 4;
434 const int slotMargin = 4;
435
436 QRect slotRect;
437 if ( orientation() == Qt::Horizontal )
438 {
439 int slotOffset = qMax( 1, handleSize.width() / 2 - slotMargin );
440 int slotHeight = slotExtent + ( innerRect.height() % 2 );
441
442 slotRect.setWidth( innerRect.width() - 2 * slotOffset );
443 slotRect.setHeight( slotHeight );
444 }
445 else
446 {
447 int slotOffset = qMax( 1, handleSize.height() / 2 - slotMargin );
448 int slotWidth = slotExtent + ( innerRect.width() % 2 );
449
450 slotRect.setWidth( slotWidth );
451 slotRect.setHeight( innerRect.height() - 2 * slotOffset );
452
453 }
454
455 slotRect.moveCenter( innerRect.center() );
456
457 QBrush brush = palette().brush( QPalette::Dark );
458 qDrawShadePanel( painter, slotRect, palette(), true, 1 , &brush );
459 }
460
461 if ( isValid() )
462 drawHandle( painter, handleRect(), transform( value() ) );
463}
464
465/*!
466 Draw the thumb at a position
467
468 \param painter Painter
469 \param handleRect Bounding rectangle of the handle
470 \param pos Position of the handle marker in widget coordinates
471*/
472void QwtSlider::drawHandle( QPainter *painter,
473 const QRect &handleRect, int pos ) const
474{
475 const int bw = d_data->borderWidth;
476
477 qDrawShadePanel( painter,
478 handleRect, palette(), false, bw,
479 &palette().brush( QPalette::Button ) );
480
481 pos++; // shade line points one pixel below
482 if ( orientation() == Qt::Horizontal )
483 {
484 qDrawShadeLine( painter, pos, handleRect.top() + bw,
485 pos, handleRect.bottom() - bw, palette(), true, 1 );
486 }
487 else // Vertical
488 {
489 qDrawShadeLine( painter, handleRect.left() + bw, pos,
490 handleRect.right() - bw, pos, palette(), true, 1 );
491 }
492}
493
494/*!
495 \brief Determine what to do when the user presses a mouse button.
496
497 \param pos Mouse position
498
499 \retval True, when handleRect() contains pos
500 \sa scrolledTo()
501*/
502bool QwtSlider::isScrollPosition( const QPoint &pos ) const
503{
504 if ( handleRect().contains( pos ) )
505 {
506 const double v = ( orientation() == Qt::Horizontal )
507 ? pos.x() : pos.y();
508
509 d_data->mouseOffset = v - transform( value() );
510 return true;
511 }
512
513 return false;
514}
515
516/*!
517 \brief Determine the value for a new position of the
518 slider handle.
519
520 \param pos Mouse position
521
522 \return Value for the mouse position
523 \sa isScrollPosition()
524*/
525double QwtSlider::scrolledTo( const QPoint &pos ) const
526{
527 int p = ( orientation() == Qt::Horizontal )
528 ? pos.x() : pos.y();
529
530 p -= d_data->mouseOffset;
531
532 int min = transform( lowerBound() );
533 int max = transform( upperBound() );
534 if ( min > max )
535 qSwap( min, max );
536
537 p = qBound( min, p, max );
538
539 return scaleMap().invTransform( p );
540}
541
542/*!
543 Mouse press event handler
544 \param event Mouse event
545*/
546void QwtSlider::mousePressEvent( QMouseEvent *event )
547{
548 if ( isReadOnly() )
549 {
550 event->ignore();
551 return;
552 }
553
554 const QPoint pos = event->pos();
555
556 if ( isValid() && d_data->sliderRect.contains( pos ) )
557 {
558 if ( !handleRect().contains( pos ) )
559 {
560 const int markerPos = transform( value() );
561
562 d_data->stepsIncrement = pageSteps();
563
564 if ( d_data->orientation == Qt::Horizontal )
565 {
566 if ( pos.x() < markerPos )
567 d_data->stepsIncrement = -d_data->stepsIncrement;
568 }
569 else
570 {
571 if ( pos.y() < markerPos )
572 d_data->stepsIncrement = -d_data->stepsIncrement;
573 }
574
575 if ( isInverted() )
576 d_data->stepsIncrement = -d_data->stepsIncrement;
577
578 const double v = value();
579 incrementValue( d_data->stepsIncrement );
580
581 if ( v != value() )
582 {
583 if ( isTracking() )
584 Q_EMIT valueChanged( value() );
585 else
586 d_data->pendingValueChange = true;
587
588 Q_EMIT sliderMoved( value() );
589 }
590
591 d_data->timerTick = false;
592 d_data->repeatTimerId = startTimer( qMax( 250, 2 * updateInterval() ) );
593
594 return;
595 }
596 }
597
598 QwtAbstractSlider::mousePressEvent( event );
599}
600
601/*!
602 Mouse release event handler
603 \param event Mouse event
604*/
605void QwtSlider::mouseReleaseEvent( QMouseEvent *event )
606{
607 if ( d_data->repeatTimerId > 0 )
608 {
609 killTimer( d_data->repeatTimerId );
610 d_data->repeatTimerId = 0;
611 d_data->timerTick = false;
612 d_data->stepsIncrement = 0;
613 }
614
615 if ( d_data->pendingValueChange )
616 {
617 d_data->pendingValueChange = false;
618 Q_EMIT valueChanged( value() );
619 }
620
621 QwtAbstractSlider::mouseReleaseEvent( event );
622}
623
624/*!
625 Timer event handler
626
627 Handles the timer, when the mouse stays pressed
628 inside the sliderRect().
629
630 \param event Mouse event
631*/
632void QwtSlider::timerEvent( QTimerEvent *event )
633{
634 if ( event->timerId() != d_data->repeatTimerId )
635 {
636 QwtAbstractSlider::timerEvent( event );
637 return;
638 }
639
640 if ( !isValid() )
641 {
642 killTimer( d_data->repeatTimerId );
643 d_data->repeatTimerId = 0;
644 return;
645 }
646
647 const double v = value();
648 incrementValue( d_data->stepsIncrement );
649
650 if ( v != value() )
651 {
652 if ( isTracking() )
653 Q_EMIT valueChanged( value() );
654 else
655 d_data->pendingValueChange = true;
656
657 Q_EMIT sliderMoved( value() );
658 }
659
660 if ( !d_data->timerTick )
661 {
662 // restart the timer with a shorter interval
663 killTimer( d_data->repeatTimerId );
664 d_data->repeatTimerId = startTimer( updateInterval() );
665
666 d_data->timerTick = true;
667 }
668}
669
670/*!
671 Qt paint event handler
672 \param event Paint event
673*/
674void QwtSlider::paintEvent( QPaintEvent *event )
675{
676 QPainter painter( this );
677 painter.setClipRegion( event->region() );
678
679 QStyleOption opt;
680 opt.init(this);
681 style()->drawPrimitive(QStyle::PE_Widget, &opt, &painter, this);
682
683 if ( d_data->scalePosition != QwtSlider::NoScale )
684 {
685 if ( !d_data->sliderRect.contains( event->rect() ) )
686 scaleDraw()->draw( &painter, palette() );
687 }
688
689 drawSlider( &painter, d_data->sliderRect );
690
691 if ( hasFocus() )
692 QwtPainter::drawFocusRect( &painter, this, d_data->sliderRect );
693}
694
695/*!
696 Qt resize event handler
697 \param event Resize event
698*/
699void QwtSlider::resizeEvent( QResizeEvent *event )
700{
701 Q_UNUSED( event );
702
703 layoutSlider( false );
704}
705
706/*!
707 Handles QEvent::StyleChange and QEvent::FontChange events
708 \param event Change event
709*/
710void QwtSlider::changeEvent( QEvent *event )
711{
712 if ( event->type() == QEvent::StyleChange ||
713 event->type() == QEvent::FontChange )
714 {
715 if ( testAttribute( Qt::WA_WState_Polished ) )
716 layoutSlider( true );
717 }
718
719 QwtAbstractSlider::changeEvent( event );
720}
721
722/*!
723 Recalculate the slider's geometry and layout based on
724 the current geometry and fonts.
725
726 \param update_geometry notify the layout system and call update
727 to redraw the scale
728*/
729void QwtSlider::layoutSlider( bool update_geometry )
730{
731 int bw = 0;
732 if ( d_data->hasTrough )
733 bw = d_data->borderWidth;
734
735 const QSize handleSize = qwtHandleSize( d_data->handleSize,
736 d_data->orientation, d_data->hasTrough );
737
738 QRect sliderRect = contentsRect();
739
740 /*
741 The marker line of the handle needs to be aligned to
742 the scale. But the marker is in the center
743 and we need space enough to display the rest of the handle.
744
745 But the scale itself usually needs margins for displaying
746 the tick labels, that also might needs space beyond the
747 backbone.
748
749 Now it depends on what needs more margins. If it is the
750 slider the scale gets shrunk, otherwise the slider.
751 */
752
753 int scaleMargin = 0;
754 if ( d_data->scalePosition != QwtSlider::NoScale )
755 {
756 int d1, d2;
757 scaleDraw()->getBorderDistHint( font(), d1, d2 );
758
759 scaleMargin = qMax( d1, d2 ) - bw;
760 }
761
762 int scaleX, scaleY, scaleLength;
763
764 if ( d_data->orientation == Qt::Horizontal )
765 {
766 const int handleMargin = handleSize.width() / 2 - 1;
767 if ( scaleMargin > handleMargin )
768 {
769 int off = scaleMargin - handleMargin;
770 sliderRect.adjust( off, 0, -off, 0 );
771 }
772
773 scaleX = sliderRect.left() + bw + handleSize.width() / 2 - 1;
774 scaleLength = sliderRect.width() - handleSize.width();
775 }
776 else
777 {
778 int handleMargin = handleSize.height() / 2 - 1;
779 if ( scaleMargin > handleMargin )
780 {
781 int off = scaleMargin - handleMargin;
782 sliderRect.adjust( 0, off, 0, -off );
783 }
784
785 scaleY = sliderRect.top() + bw + handleSize.height() / 2 - 1;
786 scaleLength = sliderRect.height() - handleSize.height();
787 }
788
789 scaleLength -= 2 * bw;
790
791 // now align slider and scale according to the ScalePosition
792
793 if ( d_data->orientation == Qt::Horizontal )
794 {
795 const int h = handleSize.height() + 2 * bw;
796
797 if ( d_data->scalePosition == QwtSlider::TrailingScale )
798 {
799 sliderRect.setTop( sliderRect.bottom() + 1 - h );
800 scaleY = sliderRect.top() - d_data->spacing;
801 }
802 else
803 {
804 sliderRect.setHeight( h );
805 scaleY = sliderRect.bottom() + 1 + d_data->spacing;
806 }
807 }
808 else // Qt::Vertical
809 {
810 const int w = handleSize.width() + 2 * bw;
811
812 if ( d_data->scalePosition == QwtSlider::LeadingScale )
813 {
814 sliderRect.setWidth( w );
815 scaleX = sliderRect.right() + 1 + d_data->spacing;
816 }
817 else
818 {
819 sliderRect.setLeft( sliderRect.right() + 1 - w );
820 scaleX = sliderRect.left() - d_data->spacing;
821 }
822 }
823
824 d_data->sliderRect = sliderRect;
825
826 scaleDraw()->move( scaleX, scaleY );
827 scaleDraw()->setLength( scaleLength );
828
829 if ( update_geometry )
830 {
831 d_data->sizeHintCache = QSize(); // invalidate
832 updateGeometry();
833 update();
834 }
835}
836
837/*!
838 En/Disable the trough
839
840 The slider can be cutomized by showing a trough for the
841 handle.
842
843 \param on When true, the groove is visible
844 \sa hasTrough(), setGroove()
845 */
846void QwtSlider::setTrough( bool on )
847{
848 if ( d_data->hasTrough != on )
849 {
850 d_data->hasTrough = on;
851
852 if ( testAttribute( Qt::WA_WState_Polished ) )
853 layoutSlider( true );
854 }
855}
856
857/*!
858 \return True, when the trough is visisble
859 \sa setTrough(), hasGroove()
860 */
861bool QwtSlider::hasTrough() const
862{
863 return d_data->hasTrough;
864}
865
866/*!
867 En/Disable the groove
868
869 The slider can be cutomized by showing a groove for the
870 handle.
871
872 \param on When true, the groove is visible
873 \sa hasGroove(), setThrough()
874 */
875void QwtSlider::setGroove( bool on )
876{
877 if ( d_data->hasGroove != on )
878 {
879 d_data->hasGroove = on;
880
881 if ( testAttribute( Qt::WA_WState_Polished ) )
882 layoutSlider( true );
883 }
884}
885
886/*!
887 \return True, when the groove is visisble
888 \sa setGroove(), hasTrough()
889 */
890bool QwtSlider::hasGroove() const
891{
892 return d_data->hasGroove;
893}
894
895/*!
896 \return minimumSizeHint()
897*/
898QSize QwtSlider::sizeHint() const
899{
900 const QSize hint = minimumSizeHint();
901 return hint.expandedTo( QApplication::globalStrut() );
902}
903
904/*!
905 \return Minimum size hint
906 \sa sizeHint()
907*/
908QSize QwtSlider::minimumSizeHint() const
909{
910 if ( !d_data->sizeHintCache.isEmpty() )
911 return d_data->sizeHintCache;
912
913 const QSize handleSize = qwtHandleSize( d_data->handleSize,
914 d_data->orientation, d_data->hasTrough );
915
916 int bw = 0;
917 if ( d_data->hasTrough )
918 bw = d_data->borderWidth;
919
920 int sliderLength = 0;
921 int scaleExtent = 0;
922
923 if ( d_data->scalePosition != QwtSlider::NoScale )
924 {
925 int d1, d2;
926 scaleDraw()->getBorderDistHint( font(), d1, d2 );
927
928 const int scaleBorderDist = 2 * ( qMax( d1, d2 ) - bw );
929
930 int handleBorderDist;
931 if ( d_data->orientation == Qt::Horizontal )
932 handleBorderDist = handleSize.width();
933 else
934 handleBorderDist = handleSize.height();
935
936 sliderLength = scaleDraw()->minLength( font() );
937 if ( handleBorderDist > scaleBorderDist )
938 {
939 // We need additional space for the overlapping handle
940 sliderLength += handleBorderDist - scaleBorderDist;
941 }
942
943 scaleExtent += d_data->spacing;
944 scaleExtent += qCeil( scaleDraw()->extent( font() ) );
945 }
946
947 sliderLength = qMax( sliderLength, 84 ); // from QSlider
948
949 int w = 0;
950 int h = 0;
951
952 if ( d_data->orientation == Qt::Horizontal )
953 {
954 w = sliderLength;
955 h = handleSize.height() + 2 * bw + scaleExtent;
956 }
957 else
958 {
959 w = handleSize.width() + 2 * bw + scaleExtent;
960 h = sliderLength;
961 }
962
963 // finally add margins
964 int left, right, top, bottom;
965 getContentsMargins( &left, &top, &right, &bottom );
966
967 w += left + right;
968 h += top + bottom;
969
970 d_data->sizeHintCache = QSize( w, h );
971 return d_data->sizeHintCache;
972}
973
974/*!
975 \return Bounding rectangle of the slider handle
976 */
977QRect QwtSlider::handleRect() const
978{
979 if ( !isValid() )
980 return QRect();
981
982 const int markerPos = transform( value() );
983
984 QPoint center = d_data->sliderRect.center();
985 if ( d_data->orientation == Qt::Horizontal )
986 center.setX( markerPos );
987 else
988 center.setY( markerPos );
989
990 QRect rect;
991 rect.setSize( qwtHandleSize( d_data->handleSize,
992 d_data->orientation, d_data->hasTrough ) );
993 rect.moveCenter( center );
994
995 return rect;
996}
997
998/*!
999 \return Bounding rectangle of the slider - without the scale
1000 */
1001QRect QwtSlider::sliderRect() const
1002{
1003 return d_data->sliderRect;
1004}
Note: See TracBrowser for help on using the repository browser.