COPASI API  4.16.103
CopasiSlider.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010 - 2013 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 // Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
7 // Properties, Inc., EML Research, gGmbH, University of Heidelberg,
8 // and The University of Manchester.
9 // All rights reserved.
10 
11 // Copyright (C) 2004 - 2007 by Pedro Mendes, Virginia Tech Intellectual
12 // Properties, Inc. and EML Research, gGmbH.
13 // All rights reserved.
14 
15 #include <cmath>
16 
17 #include <QtGui/QLabel>
18 #include <QtCore/QString>
19 #include <QtGui/QSlider>
20 #include <QtGui/QPixmap>
21 #include <QtGui/QToolButton>
22 #include <QtGui/QVBoxLayout>
23 #include <QtGui/QHBoxLayout>
24 #include <QtGui/QToolTip>
25 
26 #include "copasi.h"
27 
28 #include "CopasiSlider.h"
29 #include "listviews.h"
30 #include "qtUtilities.h"
31 #include "DataModelGUI.h"
33 
34 CopasiSlider::CopasiSlider(CSlider* pSlider, DataModelGUI * pDM, QWidget* parent):
35  QFrame(parent),
36  mpCSlider(pSlider),
37  mpQSlider(NULL),
38  mpLabel(NULL),
39  mpCloseButton(NULL),
40  mpEditButton(NULL),
41  mValueOutOfRange(false),
42  mpDM(pDM)
43 {
44  this->setLayout(new QHBoxLayout);
45  this->setFrameShape(QFrame::Box);
46  this->layout()->setContentsMargins(2, 2, 2, 2);
47  //this->layout()->setSpacing(0);
48  //this->layout()->setMargin(0);
49  QFrame* pFrame = new QFrame(NULL);
50  pFrame->setLayout(new QVBoxLayout);
51  pFrame->layout()->setContentsMargins(2, 2, 2, 2);
52  this->mpLabel = new QLabel(NULL);
53  this->mpLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
54  pFrame->layout()->addWidget(this->mpLabel);
55  this->mpQSlider = new QSlider(Qt::Horizontal);
56  mpQSlider->setFocusPolicy(Qt::WheelFocus);
57  this->mpQSlider->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
58 #ifdef WIN32
59  this->mpQSlider->setMinimumHeight(10);
60 #endif
61  pFrame->layout()->addWidget(this->mpQSlider);
62  this->layout()->addWidget(pFrame);
63 
64  pFrame = new QFrame(NULL);
65  pFrame->setLayout(new QVBoxLayout);
66  pFrame->layout()->setContentsMargins(2, 2, 2, 2);
67 
68  this->mpCloseButton = new QToolButton(NULL);
70  pFrame->layout()->addWidget(this->mpCloseButton);
71 
72  this->mpEditButton = new QToolButton(NULL);
74  pFrame->layout()->addWidget(this->mpEditButton);
75 
76  this->layout()->addWidget(pFrame);
77 
78  if (!this->mpCSlider->compile())
79  {
80  this->mpQSlider->setEnabled(false);
81  }
82 
83  this->updateSliderData();
84  this->mpCloseButton->setToolTip(tr("Remove Slider"));
85  this->mpEditButton->setToolTip(tr("Edit Slider"));
86 
87  connect(this->mpQSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
88  connect(this->mpQSlider, SIGNAL(sliderReleased()), this, SLOT(qSliderReleased()));
89  connect(this->mpQSlider, SIGNAL(sliderPressed()), this, SLOT(qSliderPressed()));
90  connect(this->mpCloseButton, SIGNAL(clicked()), this, SLOT(closeButtonClicked()));
91  connect(this->mpEditButton, SIGNAL(clicked()), this, SLOT(editButtonClicked()));
92 
93  setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
94 
95  // We need to assure that the slider is compiled
96  if (mpCSlider) mpCSlider->compile();
97 }
98 
100 {}
101 
103 {
104  if (mpQSlider == NULL) return;
105 
106  mpQSlider->setFocus(Qt::OtherFocusReason);
107 }
108 
110 {
111  if (this->mpCSlider)
112  {
113  //mpCSlider->compile();
114  this->mpQSlider->setMinimum(0);
115  this->mpQSlider->setMaximum(this->mpCSlider->getTickNumber());
116  this->mpQSlider->setTickInterval(1);
117  this->mpQSlider->setSingleStep(1);
118  this->mpQSlider->setPageStep(this->mpCSlider->getTickFactor());
119  disconnect(this->mpQSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
120  this->mpQSlider->setValue(this->calculatePositionFromValue(this->mpCSlider->getSliderValue()));
121  connect(this->mpQSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderValueChanged(int)));
122  this->updateLabel();
123 
124  if (this->mpQSlider->isEnabled() == false)
125  {
126  if (this->mpCSlider->getSliderObject() != NULL)
127  {
128  this->mpQSlider->setEnabled(true);
129  }
130  }
131 
132  this->update();
133  }
134 }
135 
137 {
138  return this->mpCSlider->getSliderValue();
139 }
140 
142 {
143 
144  // we set the value ourselves so that listviews can do the
145  // update of the dependent values as well as taking the framework into
146  // consideration
147 
148  // first we set the slider value without actually writing to the underlying object
149  this->mpCSlider->setSliderValue(value, false);
150  /* reget value in case it was outside range and got set to minValue or
151  * maxValue */
152  value = this->mpCSlider->getSliderValue();
153 
154  // now we handle writing to the object ourselves
155  CCopasiObject* pObject = this->object();
156 
157  if (pObject == NULL) return;
158 
159  if (pObject->isValueDbl())
160  pObject->setObjectValue(value);
161  else if (pObject->isValueInt())
162  pObject->setObjectValue((C_INT32) floor(value + 0.5));
163  else if (pObject->isValueBool())
164  pObject->setObjectValue(value != 0.0);
165 
166  // recalculate all other dependent values
168 
169  this->mpQSlider->setValue(this->calculatePositionFromValue(value));
170 
171  this->updateLabel();
172 }
173 
175 {
176  return this->mpCSlider->getTickFactor();
177 }
178 
180 {
181  this->mpCSlider->setTickFactor(factor);
182  this->mpQSlider->setPageStep(this->mpQSlider->singleStep()*factor);
183 }
184 
186 {
187  return (C_FLOAT64)(this->mpCSlider->getMaxValue() - this->mpCSlider->getMinValue()) / ((C_FLOAT64)this->mpCSlider->getTickNumber());
188 }
189 
190 void CopasiSlider::setNumMinorTicks(unsigned C_INT32 numMinorTicks)
191 {
192  this->mpCSlider->setTickNumber(numMinorTicks);
193  // set maxValue and value of slider
194  this->mpQSlider->setMaximum(numMinorTicks);
195  this->mpQSlider->setValue(this->calculatePositionFromValue(this->mpCSlider->getSliderValue()));
196 }
197 
199 {
200  return this->mpCSlider->getTickNumber();
201 }
202 
204 {
205  return this->mpCSlider->getMinValue();
206 }
207 
209 {
210  return this->mpCSlider->getMaxValue();
211 }
212 
214 {
215  return this->mpCSlider->getSliderObject();
216 }
217 
219 {
220  this->mpCSlider->setSliderObject(object);
221  this->updateSliderData();
222 }
223 
225 {
226  this->mpCSlider->setMaxValue(value);
227 
228  this->mpQSlider->setValue(this->calculatePositionFromValue(this->mpCSlider->getSliderValue()));
229 
230  this->updateLabel();
231 }
232 
234 {
235  this->mpCSlider->setMinValue(value);
236 
237  this->mpQSlider->setValue(this->calculatePositionFromValue(this->mpCSlider->getSliderValue()));
238 
239  this->updateLabel();
240 }
241 
243 {
244  double minValue, maxValue, currValue;
245  minValue = this->mpCSlider->getMinValue();
246  maxValue = this->mpCSlider->getMaxValue();
247  currValue = this->mpCSlider->getSliderValue();
248  CCopasiObject* object = this->mpCSlider->getSliderObject();
249  QString labelString = "";
250 
251  if (object)
252  {
253  labelString += FROM_UTF8(object->getObjectDisplayName(true, true));
254  labelString += " : [";
255  labelString += QString::number(minValue);
256  labelString += "-";
257  labelString += QString::number(maxValue);
258  labelString += "] {";
259  labelString += QString::number(currValue);
260  labelString += "}";
261 
262  if (this->mValueOutOfRange)
263  {
264  labelString += " (Value out of range!)";
265  }
266  }
267  else
268  {
269  labelString += "Object not available!";
270  }
271 
272  this->mpLabel->setText(labelString);
273 }
274 
276 {
277  this->mpCSlider->setSliderValue(this->calculateValueFromPosition(value), false);
278 
279  this->updateLabel();
280 
281  emit valueChanged(this->mpCSlider->getSliderValue());
282 }
283 
285 {
286  emit sliderReleased();
287 }
288 
290 {
291  emit sliderPressed();
292 }
293 
295 {
296  return this->mpCSlider->getSliderType();
297 }
298 
300 {
301  this->mpCSlider->setSliderType(type);
302 }
303 
304 void CopasiSlider::updateValue(bool modifyRange, bool updateDependencies)
305 {
306  double value = this->mpCSlider->getSliderValue();
307  double maxValue = this->mpCSlider->getMaxValue();
308  double minValue = this->mpCSlider->getMinValue();
309 
310  if ((value > maxValue) || (value < minValue))
311  {
312  if (!modifyRange)
313  {
314  this->mValueOutOfRange = true;
315  }
316  else
317  {
318  this->mValueOutOfRange = false;
319  this->mpCSlider->resetRange();
320  }
321  }
322 
323  // now we handle writing to the object ourselves
324  CCopasiObject* pObject = this->object();
325 
326  if (pObject == NULL) return;
327 
328  if (pObject->isValueDbl())
329  pObject->setObjectValue(value);
330  else if (pObject->isValueInt())
331  pObject->setObjectValue((C_INT32) floor(value + 0.5));
332  else if (pObject->isValueBool())
333  pObject->setObjectValue(value != 0.0);
334 
335  // recalculate all other dependent values
336  if (updateDependencies)
337  {
339  }
340 }
341 
343 {
344  emit closeClicked(this);
345 }
346 
348 {
349  emit editClicked(this);
350 }
351 
353 {
354  return this->mpCSlider;
355 }
356 
358 {
359  double value;
360  double exponent;
361 
362  switch (this->mpCSlider->getScaling())
363  {
364  case CSlider::linear:
365  value = this->mpCSlider->getMinValue() + position * this->minorTickInterval();
366  break;
367 
369  exponent = (((double)position) * log10(this->mpCSlider->getMaxValue() / this->mpCSlider->getMinValue())) / this->mpCSlider->getTickNumber();
370  value = this->mpCSlider->getMinValue() * pow(10.0, exponent);
371  break;
372 
373  default:
374  value = 0.0;
375  break;
376  }
377 
378  return value;
379 }
380 
382 {
383  int position;
384 
385  switch (this->mpCSlider->getScaling())
386  {
387  case CSlider::linear:
388  position = (int)floor(((value - this->mpCSlider->getMinValue()) / this->minorTickInterval()) + 0.5);
389  break;
390 
392  position = (int)floor((this->mpCSlider->getTickNumber() * (log10(value / this->mpCSlider->getMinValue()) / log10(this->mpCSlider->getMaxValue() / this->mpCSlider->getMinValue()))) + 0.5);
393  break;
394 
395  default:
396  position = 0;
397  }
398 
399  return position;
400 }
401 
403 {
404  this->setValue(this->originalValue());
405 }
406 
408 {
409  return this->mpCSlider->getOriginalValue();
410 }
411 
413 {
414  this->mpCSlider->setOriginalValue(value);
415 }
416 /**
417  * Checks whether the slider is actually valid.
418  * This is mainly done by calling isValid on the underlying CSlider object.
419  */
421 {
422  return (this->mpCSlider != NULL && this->mpCSlider->isValid());
423 }
bool compile(const std::vector< CCopasiContainer * > &listOfContainer=CCopasiContainer::EmptyList)
Definition: CSlider.cpp:69
CSlider * getCSlider() const
bool isValueInt() const
virtual std::string getObjectDisplayName(bool regular=true, bool richtext=false) const
void updateLabel()
#define FROM_UTF8(__x)
Definition: qtUtilities.h:73
void setObjectValue(const C_FLOAT64 &value)
void qSliderPressed()
void sliderPressed()
void setNumMinorTicks(unsigned C_INT32 numMinorTicks)
bool setSliderObject(CCopasiObject *pObject)
Definition: CSlider.cpp:104
virtual ~CopasiSlider()
bool setOriginalValue(const C_FLOAT64 value)
Definition: CSlider.cpp:191
void valueChanged(double)
CCopasiObject * object() const
void updateSliderData()
bool setMaxValue(const C_FLOAT64 maxValue)
Definition: CSlider.cpp:323
C_FLOAT64 minorTickInterval() const
CSlider::Type type() const
CSlider::Type getSliderType() const
Definition: CSlider.cpp:188
void setType(CSlider::Type type)
#define C_INT32
Definition: copasi.h:90
bool mValueOutOfRange
Definition: CopasiSlider.h:92
bool setTickFactor(const unsigned C_INT32 tickFactor)
Definition: CSlider.cpp:360
void editClicked(CopasiSlider *slider)
void updateValue(bool modifyRange, bool updateDependencies)
QLabel * mpLabel
Definition: CopasiSlider.h:89
int calculatePositionFromValue(C_FLOAT64 value)
void setOriginalValue(C_FLOAT64 value)
bool isValid() const
Definition: CSlider.cpp:408
bool setSliderType(const CSlider::Type type)
Definition: CSlider.cpp:182
void closeClicked(CopasiSlider *slider)
unsigned C_INT32 minorMajorFactor() const
void sliderReleased()
void setMinorMajorFactor(unsigned C_INT32 factor)
static const QIcon & icon(const IconID &id)
C_FLOAT64 value() const
const C_FLOAT64 & getSliderValue() const
Definition: CSlider.cpp:290
void editButtonClicked()
void refreshInitialValues()
DataModelGUI * mpDM
Definition: CopasiSlider.h:93
const C_FLOAT64 & getOriginalValue() const
Definition: CSlider.cpp:285
C_FLOAT64 calculateValueFromPosition(int position)
void closeButtonClicked()
const C_FLOAT64 & getMaxValue() const
Definition: CSlider.cpp:348
bool setTickNumber(const unsigned C_INT32 tickNumber)
Definition: CSlider.cpp:351
void setMinValue(C_FLOAT64 value)
C_FLOAT64 minValue() const
CSlider * mpCSlider
Definition: CopasiSlider.h:87
void qSliderReleased()
#define C_FLOAT64
Definition: copasi.h:92
bool isValid() const
bool isValueBool() const
unsigned C_INT32 numMinorTicks() const
void setObject(CCopasiObject *object)
C_FLOAT64 maxValue() const
bool setMinValue(const C_FLOAT64 minValue)
Definition: CSlider.cpp:295
bool isValueDbl() const
void setValue(C_FLOAT64 value)
unsigned C_INT32 getTickNumber() const
Definition: CSlider.cpp:357
void focusSlider()
C_FLOAT64 originalValue() const
QToolButton * mpCloseButton
Definition: CopasiSlider.h:90
QToolButton * mpEditButton
Definition: CopasiSlider.h:91
const C_FLOAT64 & getMinValue() const
Definition: CSlider.cpp:320
bool setSliderValue(const C_FLOAT64 value, const bool &writeToObject=true)
Definition: CSlider.cpp:215
void resetRange()
Definition: CSlider.cpp:159
void setMaxValue(C_FLOAT64 value)
unsigned C_INT32 getTickFactor() const
Definition: CSlider.cpp:366
void sliderValueChanged(int value)
Scale getScaling() const
Definition: CSlider.cpp:369
CCopasiObject * getSliderObject()
Definition: CSlider.cpp:176
QSlider * mpQSlider
Definition: CopasiSlider.h:88
CopasiSlider(CSlider *pSlider, DataModelGUI *pDM, QWidget *parent=0)