Qt Virtual Chart Table (QVCT)
CChartControl.cpp
Go to the documentation of this file.
1 // INDENTING (emacs/vi): -*- mode:c++; tab-width:2; c-basic-offset:2; intent-tabs-mode:nil; -*- ex: set tabstop=2 expandtab:
2 
3 /*
4  * Qt Virtual Chart Table (QVCT)
5  * Copyright (C) 2012 Cedric Dufour <http://cedric.dufour.name>
6  * Author: Cedric Dufour <http://cedric.dufour.name>
7  *
8  * The Qt Virtual Chart Table (QVCT) is free software:
9  * you can redistribute it and/or modify it under the terms of the GNU General
10  * Public License as published by the Free Software Foundation, Version 3.
11  *
12  * The Qt Virtual Chart Table (QVCT) is distributed in the hope
13  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * See the GNU General Public License for more details.
17  */
18 
19 //QT
20 #include <QFrame>
21 #include <QPushButton>
22 #include <QSlider>
23 #include <QWidget>
24 #include <QVBoxLayout>
25 
26 // QVCT
27 #include "QVCTRuntime.hpp"
28 #include "charts/CChartControl.hpp"
29 
30 
31 //------------------------------------------------------------------------------
32 // CONSTRUCTORS / DESTRUCTOR
33 //------------------------------------------------------------------------------
34 
35 CChartControl::CChartControl( QWidget* _pqParent )
36  : QWidget( _pqParent )
37  , bPointerEnable( true )
38 {
40 }
41 
43 {
44  // Retrieve the chart table
45  CChartTable* __poChartTable = QVCTRuntime::useChartTable();
46 
47  // Create layout
48  QVBoxLayout* __pqVBoxLayout = new QVBoxLayout();
49 
50  // Add controls
51  pqPushButtonPositionLock = new QPushButton( QIcon( ":icons/32x32/move_unlock.png" ), "" );
52  pqPushButtonPositionLock->setToolTip( tr("Keep chart position synchronized with other charts") );
53  pqPushButtonPositionLock->installEventFilter( __poChartTable );
54  pqPushButtonPositionLock->setMaximumSize( 36, 34 );
55  pqPushButtonPositionLock->setCheckable( true );
56  __pqVBoxLayout->addWidget( pqPushButtonPositionLock );
57  QWidget::connect( pqPushButtonPositionLock, SIGNAL( toggled(bool) ), this, SLOT( slotPositionLock(bool) ) );
58 
59  pqPushButtonScaleLock = new QPushButton( QIcon( ":icons/32x32/zoom_unlock.png" ), "" );
60  pqPushButtonScaleLock->setToolTip( tr("Keep chart scale synchronized with other charts") );
61  pqPushButtonScaleLock->installEventFilter( __poChartTable );
62  pqPushButtonScaleLock->setMaximumSize( 36, 34 );
63  pqPushButtonScaleLock->setCheckable( true );
64  __pqVBoxLayout->addWidget( pqPushButtonScaleLock );
65  QWidget::connect( pqPushButtonScaleLock, SIGNAL( toggled(bool) ), this, SLOT( slotScaleLock(bool) ) );
66 
67  QFrame* __pqFrameSeparator1 = new QFrame();
68  __pqFrameSeparator1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
69  __pqVBoxLayout->addWidget( __pqFrameSeparator1 );
70 
71  pqPushButtonScaleActual = new QPushButton( QIcon( ":icons/32x32/zoom_actual.png" ), "" );
72  pqPushButtonScaleActual->setToolTip( tr("Match chart scale to screen resolution") );
73  pqPushButtonScaleActual->installEventFilter( __poChartTable );
74  pqPushButtonScaleActual->setMaximumSize( 36, 34 );
75  __pqVBoxLayout->addWidget( pqPushButtonScaleActual );
76  QWidget::connect( pqPushButtonScaleActual, SIGNAL( clicked() ), __poChartTable, SLOT( slotScaleActual() ) );
77 
78  pqPushButtonScaleIn = new QPushButton( QIcon( ":icons/32x32/zoom_in.png" ), "" );
79  pqPushButtonScaleIn->setToolTip( tr("Zoom chart (decrease scale)") );
80  pqPushButtonScaleIn->installEventFilter( __poChartTable );
81  pqPushButtonScaleIn->setMaximumSize( 36, 34 );
82  __pqVBoxLayout->addWidget( pqPushButtonScaleIn );
83  QWidget::connect( pqPushButtonScaleIn, SIGNAL( clicked() ), this, SLOT( slotScaleIn() ) );
84 
85  pqSliderScale = new QSlider( Qt::Vertical );
86  pqSliderScale->installEventFilter( __poChartTable );
87  pqSliderScale->setRange( 0, 1000 );
88  pqSliderScale->setSingleStep( 1 );
89  pqSliderScale->setPageStep( 10 );
90  __pqVBoxLayout->addWidget( pqSliderScale, 1 );
91  __pqVBoxLayout->setAlignment( pqSliderScale, Qt::AlignHCenter );
92  QWidget::connect( pqSliderScale, SIGNAL( valueChanged(int) ), this, SLOT( slotScaleTo(int) ) );
93 
94  pqPushButtonScaleOut = new QPushButton( QIcon( ":icons/32x32/zoom_out.png" ), "" );
95  pqPushButtonScaleOut->setToolTip( tr("Unzoom chart (increase scale)") );
96  pqPushButtonScaleOut->installEventFilter( __poChartTable );
97  pqPushButtonScaleOut->setMaximumSize( 36, 34 );
98  __pqVBoxLayout->addWidget( pqPushButtonScaleOut );
99  QWidget::connect( pqPushButtonScaleOut, SIGNAL( clicked() ), this, SLOT( slotScaleOut() ) );
100 
101  pqPushButtonScaleFit = new QPushButton( QIcon( ":icons/32x32/zoom_fit.png" ), "" );
102  pqPushButtonScaleFit->setToolTip( tr("Adjust scale to display entire chart") );
103  pqPushButtonScaleFit->installEventFilter( __poChartTable );
104  pqPushButtonScaleFit->setMaximumSize( 36, 34 );
105  __pqVBoxLayout->addWidget( pqPushButtonScaleFit );
106  QWidget::connect( pqPushButtonScaleFit, SIGNAL( clicked() ), __poChartTable, SLOT( slotScaleFit() ) );
107 
108  QFrame* __pqFrameSeparator2 = new QFrame();
109  __pqFrameSeparator2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
110  __pqVBoxLayout->addWidget( __pqFrameSeparator2 );
111 
112  pqPushButtonTarget = new QPushButton( QIcon( ":icons/32x32/target.png" ), "" );
113  pqPushButtonTarget->setToolTip( tr("Enable target destination") );
114  pqPushButtonTarget->installEventFilter( __poChartTable );
115  pqPushButtonTarget->setMaximumSize( 36, 34 );
116  pqPushButtonTarget->setCheckable( true );
117  __pqVBoxLayout->addWidget( pqPushButtonTarget );
118  QWidget::connect( pqPushButtonTarget, SIGNAL( toggled(bool) ), __poChartTable, SLOT( slotPointerTarget(bool) ) );
119 
120  pqPushButtonMeasureSingle = new QPushButton( QIcon( ":icons/32x32/measure_single.png" ), "" );
121  pqPushButtonMeasureSingle->setToolTip( tr("Enable single segment measurement(s)") );
122  pqPushButtonMeasureSingle->installEventFilter( __poChartTable );
123  pqPushButtonMeasureSingle->setMaximumSize( 36, 34 );
124  pqPushButtonMeasureSingle->setCheckable( true );
125  __pqVBoxLayout->addWidget( pqPushButtonMeasureSingle );
126  QWidget::connect( pqPushButtonMeasureSingle, SIGNAL( toggled(bool) ), __poChartTable, SLOT( slotPointerPathSingle(bool) ) );
127 
128  pqPushButtonMeasure = new QPushButton( QIcon( ":icons/32x32/measure.png" ), "" );
129  pqPushButtonMeasure->setToolTip( tr("Enable ongoing measurements (pointer path)") );
130  pqPushButtonMeasure->installEventFilter( __poChartTable );
131  pqPushButtonMeasure->setMaximumSize( 36, 34 );
132  pqPushButtonMeasure->setCheckable( true );
133  __pqVBoxLayout->addWidget( pqPushButtonMeasure );
134  QWidget::connect( pqPushButtonMeasure, SIGNAL( toggled(bool) ), __poChartTable, SLOT( slotPointerPath(bool) ) );
135 
136  QFrame* __pqFrameSeparator3 = new QFrame();
137  __pqFrameSeparator3->setFrameStyle( QFrame::HLine | QFrame::Sunken );
138  __pqVBoxLayout->addWidget( __pqFrameSeparator3 );
139 
140  pqPushButtonElevation = new QPushButton( QIcon( ":icons/32x32/elevation_add.png" ), "" );
141  pqPushButtonElevation->setToolTip( tr("Add, view or hide elevation data") );
142  pqPushButtonElevation->installEventFilter( __poChartTable );
143  pqPushButtonElevation->setMaximumSize( 36, 34 );
144  pqPushButtonElevation->setCheckable( true );
145  __pqVBoxLayout->addWidget( pqPushButtonElevation );
146  QWidget::connect( pqPushButtonElevation, SIGNAL( toggled(bool) ), this, SLOT( slotElevation(bool) ) );
147 
148  QPushButton* __pqPushButtonLoad = new QPushButton( QIcon( ":icons/32x32/chart_load.png" ), "" );
149  __pqPushButtonLoad->setToolTip( tr("Load chart from disk") );
150  __pqPushButtonLoad->installEventFilter( __poChartTable );
151  __pqPushButtonLoad->setMaximumSize( 36, 34 );
152  __pqVBoxLayout->addWidget( __pqPushButtonLoad );
153  QWidget::connect( __pqPushButtonLoad, SIGNAL( clicked() ), __poChartTable, SLOT( slotLoadChart() ) );
154 
155  // Disable controls (since no chart is loaded yet)
156  enableControls( false );
157 
158  // Set the layout
159  QWidget::setLayout( __pqVBoxLayout );
160 }
161 
162 
163 //------------------------------------------------------------------------------
164 // METHODS
165 //------------------------------------------------------------------------------
166 
167 //
168 // SLOTS
169 //
170 
172 {
173  pqPushButtonPositionLock->setIcon( QIcon( _bLock ? ":icons/32x32/move_lock.png" : ":icons/32x32/move_unlock.png" ) );
175 }
176 
177 void CChartControl::slotScaleLock( bool _bLock )
178 {
179  pqPushButtonScaleLock->setIcon( QIcon( _bLock ? ":icons/32x32/zoom_lock.png" : ":icons/32x32/zoom_unlock.png" ) );
181 }
182 
183 void CChartControl::slotScaleTo( int _iValue )
184 {
185  // NOTE: Scale range must is inverted and normalized when used as CChartTable's scale reference
186  QVCTRuntime::useChartTable()->setScale( ( 1000 - _iValue ) / 1000.0, false, false );
187 }
188 
190 {
191  stepScale( true, true );
192 }
193 
195 {
196  stepScale( false, true );
197 }
198 
199 void CChartControl::slotElevation( bool _bAddOrShow )
200 {
201  // Retrieve the chart table
202  CChartTable* __poChartTable = QVCTRuntime::useChartTable();
203 
204  // Manage elevation data
205  if( _bAddOrShow )
206  {
207  if( !__poChartTable->hasElevation() ) __poChartTable->slotAddElevation();
208  if( __poChartTable->hasElevation() )
209  {
210  __poChartTable->showElevation( true );
211  pqPushButtonElevation->setIcon( QIcon( ":icons/32x32/elevation_visible.png" ) );
212  }
213  else
214  {
215  pqPushButtonElevation->setChecked( false );
216  }
217  }
218  else
219  {
220  if( __poChartTable->hasElevation() )
221  {
222  __poChartTable->showElevation( false );
223  pqPushButtonElevation->setIcon( QIcon( ":icons/32x32/elevation_hidden.png" ) );
224  }
225  }
226 }
227 
229 {
230  pqPushButtonElevation->setChecked( true );
231 }
232 
233 
234 //
235 // SETTERS
236 //
237 
238 void CChartControl::lockPosition( bool _bLock )
239 {
240  pqPushButtonPositionLock->setChecked( _bLock );
241 }
242 
243 void CChartControl::lockScale( bool _bLock )
244 {
245  pqPushButtonScaleLock->setChecked( _bLock );
246 }
247 
248 void CChartControl::setScale( double _fdScale )
249 {
250  // NOTE: Scale range must is inverted and normalized when used as the CChartTable's scale reference
251  pqSliderScale->setValue( 1000 * ( 1.0 - _fdScale ) );
252 }
253 
254 void CChartControl::stepScale( bool _bIncrease, bool _bBigStep )
255 {
256  pqSliderScale->setValue( pqSliderScale->value() + ( _bIncrease ? 1 : -1 ) * ( _bBigStep ? pqSliderScale->pageStep() : pqSliderScale->singleStep() ) );
257 }
258 
259 void CChartControl::enableTarget( bool _bEnable )
260 {
261  if( !pqPushButtonTarget->isEnabled() ) return;
262  pqPushButtonTarget->setChecked( _bEnable );
263 }
264 
266 {
267  if( !pqPushButtonMeasureSingle->isEnabled() ) return;
268  pqPushButtonMeasureSingle->setChecked( _bEnable );
269 }
270 
271 void CChartControl::enableMeasure( bool _bEnable )
272 {
273  if( !pqPushButtonMeasure->isEnabled() ) return;
274  pqPushButtonMeasure->setChecked( _bEnable );
275 }
276 
277 void CChartControl::setElevation( bool _bHasElevation, bool _bShowElevation )
278 {
279  if( !pqPushButtonElevation->isEnabled() ) return;
280  if( _bHasElevation )
281  {
282  pqPushButtonElevation->setChecked( _bShowElevation );
283  pqPushButtonElevation->setIcon( QIcon( _bShowElevation ? ":icons/32x32/elevation_visible.png" : ":icons/32x32/elevation_hidden.png" ) );
284  }
285  else
286  {
287  pqPushButtonElevation->setChecked( false );
288  pqPushButtonElevation->setIcon( QIcon( ":icons/32x32/elevation_add.png" ) );
289  }
290 }
291 
292 //
293 // OTHER
294 //
295 
296 void CChartControl::enableControls( bool _bEnable )
297 {
298  pqPushButtonPositionLock->setEnabled( _bEnable );
299  pqPushButtonScaleLock->setEnabled( _bEnable );
300  pqPushButtonScaleActual->setEnabled( _bEnable );
301  pqPushButtonScaleIn->setEnabled( _bEnable );
302  pqSliderScale->setEnabled( _bEnable );
303  pqPushButtonScaleOut->setEnabled( _bEnable );
304  pqPushButtonScaleFit->setEnabled( _bEnable );
305  pqPushButtonElevation->setEnabled( _bEnable );
306  if( !_bEnable )
307  {
308  pqPushButtonPositionLock->setChecked( false );
309  pqPushButtonScaleLock->setChecked( false );
310  pqPushButtonElevation->setChecked( false );
311  pqPushButtonElevation->setIcon( QIcon( ":icons/32x32/elevation_add.png" ) );
312  pqSliderScale->setValue( 0 );
313  }
314  if( !_bEnable || bPointerEnable )
315  {
316  if( !_bEnable ) QVCTRuntime::useChartTable()->enablePointerPath( false );
317  pqPushButtonTarget->setEnabled( _bEnable );
318  pqPushButtonMeasureSingle->setEnabled( _bEnable );
319  pqPushButtonMeasure->setEnabled( _bEnable );
320  }
321 }
322 
323 void CChartControl::enablePointer( bool _bEnable )
324 {
325  bPointerEnable = _bEnable;
327  pqPushButtonTarget->setEnabled( bPointerEnable );
329  pqPushButtonMeasure->setEnabled( bPointerEnable );
330 }
331 
void slotScaleTo(int _iValue)
[UI:Slot] Slot to trigger scaling to the given value
QPushButton * pqPushButtonElevation
[UI:Button] Elevation model
void enableControls(bool _bEnable)
Enables/disables all chart controls.
void slotScaleIn()
[UI:Slot] Slot to trigger scale in (zoom out)
QSlider * pqSliderScale
[UI:Button] Scale slider
void stepScale(bool _bIncrease, bool _bBigStep=true)
Increases/decreases the scale by discrete steps.
void enablePointer(bool _bEnable)
Enables/disables pointer actions.
void slotElevation(bool _bAddOrShow)
[UI:Slot] Slot to manage elevation model (add, view, hide)
void slotPositionLock(bool _bLock)
[UI:Slot] Slot to modify the position lock/unlock status
QPushButton * pqPushButtonMeasure
[UI:Button] Ongoing measurements
bool bPointerEnable
Pointer actions activation status.
QPushButton * pqPushButtonScaleIn
[UI:Button] Scale in (zoom out)
void slotScaleLock(bool _bLock)
[UI:Slot] Slot to modify the scale lock/unlock status
void constructLayout()
Constructs the layout of the user-interface.
void slotElevationAdd()
[UI:Slot] Slot to add elevation model
void setScale(double _fdScale)
Sets the scale at the given value.
QPushButton * pqPushButtonScaleFit
[UI:Button] Scale fit
void slotScaleOut()
[UI:Slot] Slot to trigger scale out (zoom in)
QPushButton * pqPushButtonScaleLock
[UI:Button] Lock/unlock scale
void enableMeasureSingle(bool _bEnable)
Enables/disables single measurement.
void setElevation(bool _bHasElevation, bool _bShowElevation)
Sets elevation status.
void lockScale(bool _bLock)
Sets the scale lock/unlock status.
QPushButton * pqPushButtonPositionLock
[UI:Button] Lock/unlock position
void enableTarget(bool _bEnable)
Enables/disables target.
CChartControl(QWidget *_pqParent=0)
QPushButton * pqPushButtonScaleActual
[UI:Button] Scale actual
void enableMeasure(bool _bEnable)
Enables/disables ongoing measurements.
QPushButton * pqPushButtonTarget
[UI:Button] Target
QPushButton * pqPushButtonMeasureSingle
[UI:Button] Single measurement
void lockPosition(bool _bLock)
Sets the position lock/unlock status.
QPushButton * pqPushButtonScaleOut
[UI:Button] Scale out (zoom in)
[UI] Virtual "chart table" (view)
Definition: CChartTable.hpp:55
void showElevation(bool _bShow)
Display elevation data (instead of raster data) of the currently selected chart (if any)
void lockScale(bool _bLock)
Sets the scale lock/unlock status.
void setScale(double _fdScale, bool _bSkipCurrent=false, bool _bUpdateControl=true)
Sets the reference scale factor.
void lockPosition(bool _bLock)
Sets the position lock/unlock status.
void slotAddElevation()
[UI:Slot] Slot to add elevation data to the currently displayed chart
bool hasElevation()
Returns whether the currently selected chart has been associated elevation data (if any)
void enablePointerPath(bool _bEnable)
Enables/disables ongoing measurements (pointer path)
static CChartTable * useChartTable()