aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2016-02-12 18:01:27 -0200
committerSamuel Fadel <samuelfadel@gmail.com>2016-02-12 18:04:03 -0200
commit95a77b04a6855b26d340aaca5e3030a7d1a7cb3c (patch)
tree7f636d927f7d31f0972496387325332a098e529d
parent7a07231716f04ee98091a946e122056e1fa69686 (diff)
Many bugfixes related to ProjectionObserver.
* Correct handling of relative metrics in UI * undo(), reset() methods added * Main class responsible for undoing and resetting both history and the observer (MUST BE AT THE SAME TIME! -- this might indicate a design issue to be addressed in the future)
-rw-r--r--main.cpp8
-rw-r--r--main.h25
-rw-r--r--main_view.qml24
-rw-r--r--projectionobserver.cpp54
-rw-r--r--projectionobserver.h14
5 files changed, 88 insertions, 37 deletions
diff --git a/main.cpp b/main.cpp
index 6eed197..a5aaf68 100644
--- a/main.cpp
+++ b/main.cpp
@@ -247,14 +247,10 @@ int main(int argc, char **argv)
m->rpBarChart, &BarChart::brushItem);
// Recompute values whenever projection changes
- ProjectionObserver projectionObserver(X, cpIndices, m->projectionHistory);
+ ProjectionObserver projectionObserver(X, cpIndices);
m->projectionObserver = &projectionObserver;
QObject::connect(m->projectionHistory, &ProjectionHistory::mapAdded,
- m->projectionObserver, &ProjectionObserver::setMap);
- QObject::connect(m->projectionHistory, &ProjectionHistory::undoPerformed,
- m->projectionObserver, &ProjectionObserver::setMap);
- QObject::connect(m->projectionHistory, &ProjectionHistory::resetPerformed,
- m->projectionObserver, &ProjectionObserver::setMap);
+ m->projectionObserver, &ProjectionObserver::addMap);
QObject::connect(m->projectionObserver, &ProjectionObserver::cpValuesChanged,
m->cpPlot, &Scatterplot::setColorData);
QObject::connect(m->projectionObserver, &ProjectionObserver::rpValuesChanged,
diff --git a/main.h b/main.h
index c4699c4..e1964e7 100644
--- a/main.h
+++ b/main.h
@@ -83,7 +83,16 @@ public:
};
Q_INVOKABLE bool setObserverType(ObserverType observerType) {
- return projectionObserver->setType((int) observerType);
+ switch (observerType) {
+ case ObserverCurrent:
+ return projectionObserver->setType(ProjectionObserver::ObserverCurrent);
+ case ObserverDiffPrevious:
+ return projectionObserver->setType(ProjectionObserver::ObserverDiffPrevious);
+ case ObserverDiffFirst:
+ return projectionObserver->setType(ProjectionObserver::ObserverDiffFirst);
+ }
+
+ return false;
}
enum ColorScaleType {
@@ -130,12 +139,18 @@ public:
Scatterplot *cpPlot, *rpPlot;
VoronoiSplat *splat;
- ProjectionObserver *projectionObserver;
-
// Shared object that controls manipulation history
ProjectionHistory *projectionHistory;
- Q_INVOKABLE void undoManipulation() { projectionHistory->undo(); }
- Q_INVOKABLE void resetManipulation() { projectionHistory->reset(); }
+ ProjectionObserver *projectionObserver;
+
+ Q_INVOKABLE void undoManipulation() {
+ projectionHistory->undo();
+ projectionObserver->undo();
+ }
+ Q_INVOKABLE void resetManipulation() {
+ projectionHistory->reset();
+ projectionObserver->reset();
+ }
public slots:
void setCPIndices(const arma::uvec &indices) {
diff --git a/main_view.qml b/main_view.qml
index 65e1095..fd4bd4a 100644
--- a/main_view.qml
+++ b/main_view.qml
@@ -217,6 +217,7 @@ ApplicationWindow {
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
GroupBox {
+ Layout.fillWidth: true
title: "Control points"
checkable: true
__checkbox.onClicked: {
@@ -285,6 +286,7 @@ ApplicationWindow {
}
GroupBox {
+ Layout.fillWidth: true
title: "Regular points"
checked: true
checkable: true
@@ -392,7 +394,9 @@ ApplicationWindow {
GroupBox {
Layout.fillWidth: true
+ id: metricsGroupBox
title: "Projection metrics"
+ property RadioButton current: currentMetricRadioButton
Column {
ExclusiveGroup { id: wrtMetricsGroup }
@@ -402,7 +406,13 @@ ApplicationWindow {
text: "Current"
exclusiveGroup: wrtMetricsGroup
checked: true
- onClicked: Main.setObserverType(Main.ObserverCurrent)
+ onClicked: {
+ if (!Main.setObserverType(Main.ObserverCurrent)) {
+ metricsGroupBox.current.checked = true;
+ } else {
+ metricsGroupBox.current = this;
+ }
+ }
}
RadioButton {
id: diffPreviousMetricRadioButton
@@ -410,19 +420,21 @@ ApplicationWindow {
exclusiveGroup: wrtMetricsGroup
onClicked: {
if (!Main.setObserverType(Main.ObserverDiffPrevious)) {
- this.checked = false;
- currentMetricRadioButton.checked = true;
+ metricsGroupBox.current.checked = true;
+ } else {
+ metricsGroupBox.current = this;
}
}
}
RadioButton {
- id: diffOriginalMetricRadioButton
+ id: diffFirstMetricRadioButton
text: "Diff. to first"
exclusiveGroup: wrtMetricsGroup
onClicked: {
if (!Main.setObserverType(Main.ObserverDiffFirst)) {
- this.checked = false;
- currentMetricRadioButton.checked = true;
+ metricsGroupBox.current.checked = true;
+ } else {
+ metricsGroupBox.current = this;
}
}
}
diff --git a/projectionobserver.cpp b/projectionobserver.cpp
index a6b280f..94f266a 100644
--- a/projectionobserver.cpp
+++ b/projectionobserver.cpp
@@ -7,7 +7,7 @@
#include "numericrange.h"
ProjectionObserver::ProjectionObserver(const arma::mat &X,
- const arma::uvec &cpIndices, ProjectionHistory *history)
+ const arma::uvec &cpIndices)
: m_type(ObserverCurrent)
, m_X(X)
, m_cpIndices(cpIndices)
@@ -17,10 +17,9 @@ ProjectionObserver::ProjectionObserver(const arma::mat &X,
, m_values(X.n_rows)
, m_prevValues(X.n_rows)
, m_firstValues(X.n_rows)
- , m_history(history)
+ , m_hasFirst(false)
+ , m_hasPrev(false)
{
- Q_ASSERT(history);
-
m_distX = mp::dist(m_X);
NumericRange<arma::uword> allIndices(0, m_X.n_rows);
@@ -50,10 +49,36 @@ void ProjectionObserver::computeAlphas()
}
}
-void ProjectionObserver::setMap(const arma::mat &Y)
+void ProjectionObserver::undo()
+{
+ if (m_hasPrev) {
+ m_hasPrev = false;
+ m_distY = m_prevDistY;
+ m_values = m_prevValues;
+
+ if (m_cpSelectionEmpty && m_rpSelectionEmpty) {
+ emitValuesChanged();
+ }
+ }
+}
+
+void ProjectionObserver::reset()
+{
+ if (m_hasFirst) {
+ m_hasPrev = false;
+ m_distY = m_firstDistY;
+ m_values = m_firstValues;
+
+ if (m_cpSelectionEmpty && m_rpSelectionEmpty) {
+ emitValuesChanged();
+ }
+ }
+}
+
+void ProjectionObserver::addMap(const arma::mat &Y)
{
- // update data of previous map
- if (m_history->hasFirst()) {
+ if (m_hasFirst) {
+ m_hasPrev = true;
m_prevDistY = m_distY;
m_prevValues = m_values;
}
@@ -62,8 +87,8 @@ void ProjectionObserver::setMap(const arma::mat &Y)
mp::aggregatedError(m_distX, m_distY, m_values);
- // update data of first map
- if (!m_history->hasFirst()) {
+ if (!m_hasFirst) {
+ m_hasFirst = true;
m_firstDistY = m_distY;
m_firstValues = m_values;
}
@@ -73,13 +98,14 @@ void ProjectionObserver::setMap(const arma::mat &Y)
}
}
-bool ProjectionObserver::setType(int type)
+bool ProjectionObserver::setType(ObserverType type)
{
if (m_type == type) {
return true;
}
- if (type == ObserverDiffPrevious && !m_history->hasPrev()) {
+ if ((type == ObserverDiffPrevious && !m_hasPrev)
+ || (type == ObserverDiffFirst && !m_hasFirst)) {
return false;
}
@@ -151,7 +177,7 @@ bool ProjectionObserver::emitValuesChanged() const
emit valuesChanged(m_values);
return true;
case ObserverDiffPrevious:
- if (m_history->hasPrev()) {
+ if (m_hasPrev) {
arma::vec diff = m_values - m_prevValues;
emit rpValuesChanged(diff(m_rpIndices));
emit valuesChanged(diff);
@@ -159,7 +185,7 @@ bool ProjectionObserver::emitValuesChanged() const
}
return false;
case ObserverDiffFirst:
- if (m_history->hasFirst()) {
+ if (m_hasFirst) {
arma::vec diff = m_values - m_firstValues;
emit rpValuesChanged(diff(m_rpIndices));
emit valuesChanged(diff);
@@ -173,7 +199,7 @@ bool ProjectionObserver::emitValuesChanged() const
void ProjectionObserver::setRewind(double t)
{
- if (!m_history->hasPrev() || !m_cpSelectionEmpty || !m_rpSelectionEmpty) {
+ if (!m_hasPrev || !m_cpSelectionEmpty || !m_rpSelectionEmpty) {
return;
}
diff --git a/projectionobserver.h b/projectionobserver.h
index 7e9239d..c021482 100644
--- a/projectionobserver.h
+++ b/projectionobserver.h
@@ -18,8 +18,10 @@ public:
};
ProjectionObserver(const arma::mat &X,
- const arma::uvec &cpIndices,
- ProjectionHistory *history);
+ const arma::uvec &cpIndices);
+
+ void undo();
+ void reset();
signals:
void valuesChanged(const arma::vec &values) const;
@@ -30,8 +32,8 @@ signals:
void rpValuesRewound(const arma::vec &values) const;
public slots:
- void setMap(const arma::mat &Y);
- bool setType(int type);
+ void addMap(const arma::mat &Y);
+ bool setType(ObserverType type);
void setCPSelection(const std::vector<bool> &cpSelection);
void setRPSelection(const std::vector<bool> &rpSelection);
void setRewind(double t);
@@ -39,7 +41,7 @@ public slots:
private:
bool emitValuesChanged() const;
- int m_type;
+ ObserverType m_type;
arma::mat m_X;
arma::mat m_distX, m_distY, m_firstDistY, m_prevDistY;
arma::uvec m_cpIndices, m_rpIndices;
@@ -53,7 +55,7 @@ private:
// TODO: one per implemented measure
arma::vec m_values, m_firstValues, m_prevValues;
- ProjectionHistory *m_history;
+ bool m_hasFirst, m_hasPrev;
};
#endif // PROJECTIONOBSERVER_H