[chronojump] New feature: ForceSensorExercises can show repetitions: con, con+ecc together/separeted



commit 19a9f9700c7c50a4967536f598b096cde0e15896
Author: Xavier de Blas <xaviblas gmail com>
Date:   Tue May 4 16:23:59 2021 +0200

    New feature: ForceSensorExercises can show repetitions: con, con+ecc together/separeted

 glade/force_sensor_exercise.glade  | 167 ++++++++++++++++++++++++++++++++-----
 src/exportFiles/fs.cs              |   5 +-
 src/forceSensor.cs                 |  54 +++++++++---
 src/forceSensorDynamics.cs         |  76 ++++++++++++-----
 src/gui/app1/forceSensorAnalyze.cs |   4 +-
 src/gui/forceSensorExercise.cs     | 103 ++++++++++++++++++-----
 src/sqlite/forceSensor.cs          |   6 +-
 7 files changed, 335 insertions(+), 80 deletions(-)
---
diff --git a/glade/force_sensor_exercise.glade b/glade/force_sensor_exercise.glade
index a51b2327..8d79fc86 100644
--- a/glade/force_sensor_exercise.glade
+++ b/glade/force_sensor_exercise.glade
@@ -456,7 +456,7 @@
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkVBox" id="vbox8">
+                  <widget class="GtkVBox" id="vbox_reps_detect">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="border_width">8</property>
@@ -478,23 +478,6 @@
                             <property name="position">0</property>
                           </packing>
                         </child>
-                        <child>
-                          <widget class="GtkCheckButton" id="check_show_ecc">
-                            <property name="label" translatable="yes">Show eccentric phase</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="active">True</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="on_check_show_ecc_toggled" swapped="no"/>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="pack_type">end</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
                       </widget>
                       <packing>
                         <property name="expand">False</property>
@@ -1036,7 +1019,7 @@
                   <widget class="GtkLabel" id="label1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label">repetitions</property>
+                    <property name="label">repetitionsDetect</property>
                   </widget>
                   <packing>
                     <property name="position">3</property>
@@ -1045,7 +1028,147 @@
                   </packing>
                 </child>
                 <child>
-                  <widget class="GtkVBox" id="vbox7">
+                  <widget class="GtkVBox" id="vbox_reps_detect1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="border_width">8</property>
+                    <property name="spacing">25</property>
+                    <child>
+                      <widget class="GtkHBox" id="hbox12">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <widget class="GtkLabel" id="label_show_repetitions">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Show repetitions</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkVBox" id="vbox7">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="spacing">16</property>
+                        <child>
+                          <widget class="GtkRadioButton" id="radio_reps_show_concentric">
+                            <property name="label" translatable="yes">Show only concentric phase</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="active">True</property>
+                            <property name="draw_indicator">True</property>
+                            <signal name="toggled" handler="on_radio_reps_show_concentric_toggled" 
swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkRadioButton" id="radio_reps_show_both">
+                            <property name="label" translatable="yes">Show both phases</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">False</property>
+                            <property name="draw_indicator">True</property>
+                            <property name="group">radio_reps_show_concentric</property>
+                            <signal name="toggled" handler="on_radio_reps_show_both_toggled" swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkAlignment" id="alignment_reps_show_both">
+                            <property name="can_focus">False</property>
+                            <property name="left_padding">30</property>
+                            <child>
+                              <widget class="GtkVBox" id="vbox8">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="spacing">12</property>
+                                <child>
+                                  <widget class="GtkRadioButton" id="radio_reps_show_both_together">
+                                    <property name="label" translatable="yes">Together</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">True</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <widget class="GtkRadioButton" id="radio_reps_show_both_separated">
+                                    <property name="label" translatable="yes">Separated</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">False</property>
+                                    <property name="active">True</property>
+                                    <property name="draw_indicator">True</property>
+                                    <property name="group">radio_reps_show_both_together</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="expand">True</property>
+                                    <property name="fill">True</property>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label">repetitionsShow</property>
+                  </widget>
+                  <packing>
+                    <property name="position">4</property>
+                    <property name="tab_fill">False</property>
+                    <property name="type">tab</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox_other">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="border_width">8</property>
@@ -1188,7 +1311,7 @@
                     </child>
                   </widget>
                   <packing>
-                    <property name="position">4</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
                 <child>
@@ -1198,7 +1321,7 @@
                     <property name="label">other</property>
                   </widget>
                   <packing>
-                    <property name="position">4</property>
+                    <property name="position">5</property>
                     <property name="tab_fill">False</property>
                     <property name="type">tab</property>
                   </packing>
diff --git a/src/exportFiles/fs.cs b/src/exportFiles/fs.cs
index a5c98d41..0ed3caf0 100644
--- a/src/exportFiles/fs.cs
+++ b/src/exportFiles/fs.cs
@@ -169,9 +169,10 @@ public class ForceSensorExport : ExportFiles
                        if(! fsesm.Exists(p.UniqueID, fsEx.UniqueID, fs.Laterality))
                                fsesm.AddForceSensorExportSet(p.UniqueID, fsEx.UniqueID, fs.Laterality);
 
-                       //make the exercise have EccReps = true in order to have an AB wiht the concentric 
and eccentric part
+                       //make the exercise have EccReps = true in order to have an AB with the concentric 
and eccentric part
                        //and send both to R to be able to have the force window in that AB
-                       fsEx.EccReps = true;
+                       //fsEx.EccReps = true;
+                       fsEx.RepetitionsShow = ForceSensorExercise.RepetitionsShowTypes.BOTHSEPARATED;
 
                        double eccMinDispl = fsEx.GetEccOrConMinMaybePreferences(true,
                                        forceSensorElasticEccMinDispl,
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index 5de1c637..b86c8928 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -384,7 +384,9 @@ public class ForceSensorExercise
        private bool tareBeforeCapture;
        private bool forceResultant;
        private bool elastic;
-       private bool eccReps;
+       //private bool eccReps;
+       public enum RepetitionsShowTypes { CONCENTRIC, BOTHTOGETHER, BOTHSEPARATED };
+       private RepetitionsShowTypes repetitionsShow;
        private double eccMin;
        private double conMin;
 
@@ -413,7 +415,7 @@ public class ForceSensorExercise
 
        public ForceSensorExercise(int uniqueID, string name, int percentBodyWeight, string resistance, int 
angleDefault,
                        string description, bool tareBeforeCapture, bool forceResultant, bool elastic,
-                       bool eccReps, double eccMin, double conMin)
+                       RepetitionsShowTypes repetitionsShow, double eccMin, double conMin)
        {
                this.uniqueID = uniqueID;
                this.name = name;
@@ -424,7 +426,7 @@ public class ForceSensorExercise
                this.tareBeforeCapture = tareBeforeCapture;
                this.forceResultant = forceResultant;
                this.elastic = elastic;
-               this.eccReps = eccReps;
+               this.repetitionsShow = repetitionsShow;
                this.eccMin = eccMin;
                this.conMin = conMin;
        }
@@ -449,7 +451,39 @@ public class ForceSensorExercise
                return uniqueID.ToString() + ":" + name + ":" + percentBodyWeight.ToString() + ":" +
                        resistance + ":" + angleDefault.ToString() + ":" + description + ":" +
                        tareBeforeCapture.ToString() + ":" + forceResultant.ToString() + ":" + 
elastic.ToString() + ":" +
-                       eccReps.ToString() + ":" + eccMin.ToString() + ":" + conMin.ToString();
+                       repetitionsShow.ToString() + ":" + eccMin.ToString() + ":" + conMin.ToString();
+       }
+
+       public int RepetitionsShowToCode()
+       {
+               /*
+                 DB 2.21 and before    DB ~2.22        SQL code
+                 eccReps 0             CONCENTRIC              0
+                 eccReps 1             BOTHTOGETHER            1
+                                       BOTHSEPARATED           2
+
+                 ~2.22 because is not really a change on DB
+               */
+
+               if(repetitionsShow == RepetitionsShowTypes.CONCENTRIC)
+                       return 0;
+               else if(repetitionsShow == RepetitionsShowTypes.BOTHTOGETHER)
+                       return 1;
+               else if(repetitionsShow == RepetitionsShowTypes.BOTHSEPARATED)
+                       return 2;
+
+               return 0;
+       }
+       public static RepetitionsShowTypes RepetitionsShowFromCode(int code)
+       {
+               if(code == 0)
+                       return RepetitionsShowTypes.CONCENTRIC;
+               else if(code == 1)
+                       return RepetitionsShowTypes.BOTHTOGETHER;
+               else if(code == 2)
+                       return RepetitionsShowTypes.BOTHSEPARATED;
+
+               return RepetitionsShowTypes.CONCENTRIC;
        }
 
        public string ToSQLInsertString()
@@ -464,7 +498,7 @@ public class ForceSensorExercise
                        Util.BoolToInt(tareBeforeCapture).ToString() + ", " +
                        Util.BoolToInt(forceResultant).ToString() + ", " +
                        Util.BoolToInt(elastic).ToString() + ", " +
-                       Util.BoolToInt(eccReps).ToString() + ", " +
+                       RepetitionsShowToCode().ToString() + ", " +
                        Util.ConvertToPoint(eccMin) + ", " + Util.ConvertToPoint(conMin);
        }
 
@@ -492,7 +526,7 @@ public class ForceSensorExercise
                                tareBeforeCapture == newEx.TareBeforeCapture &&
                                forceResultant == newEx.ForceResultant &&
                                elastic == newEx.Elastic &&
-                               eccReps == newEx.EccReps &&
+                               repetitionsShow == newEx.RepetitionsShow &&
                                eccMin == newEx.EccMin &&
                                conMin == newEx.ConMin)
                        return false;
@@ -542,10 +576,10 @@ public class ForceSensorExercise
        {
                get { return forceResultant && elastic; }
        }
-       public bool EccReps
+       public RepetitionsShowTypes RepetitionsShow
        {
-               get { return eccReps; }
-               set { eccReps = value; }
+               get { return repetitionsShow; }
+               set { repetitionsShow = value; }
        }
        public double EccMin
        {
@@ -2471,7 +2505,7 @@ public class ForceSensorAnalyzeInstant
                string str = (i+1).ToString() + sep; //sample
 
                //str += ForceSensorRepetition.GetRepetitionNumFromList(ForceSensorRepetition_l, 
i).ToString() + sep +  //repetition
-               str += ForceSensorRepetition.GetRepetitionCodeFromList(ForceSensorRepetition_l, i, 
fse.EccReps) + sep +         //repetition
+               str += ForceSensorRepetition.GetRepetitionCodeFromList(ForceSensorRepetition_l, i, 
fse.RepetitionsShow) + sep +         //repetition
                        Util.DoubleToCSV(timeAtCount, sepString) + sep +
                        Util.DoubleToCSV(fscAIPoints.GetForceAtCount(i), sepString) + sep +
                        Util.DoubleToCSV(CalculateRFD(i-1, i+1), 3, sepString);
diff --git a/src/forceSensorDynamics.cs b/src/forceSensorDynamics.cs
index 2694932c..ff94627d 100644
--- a/src/forceSensorDynamics.cs
+++ b/src/forceSensorDynamics.cs
@@ -205,7 +205,7 @@ public abstract class ForceSensorDynamics
                                concentricFlag, yList.Count, sampleStart, sampleEnd));
 
                //should accept eccentric reps?
-               if(! fse.EccReps && concentricFlag == -1)
+               if(fse.RepetitionsShow == ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC && 
concentricFlag == -1)
                        return;
 
                // 1) remove low force at beginning ot end of the repetition
@@ -298,6 +298,20 @@ public abstract class ForceSensorDynamics
                return false;
        }
 
+       protected ForceSensorRepetition.Types getForceSensorRepetitionType (double ySampleStart, double 
ySampleEnd)
+       {
+               ForceSensorRepetition.Types fsrType = ForceSensorRepetition.Types.DONOTSHOW;
+               if(fse.RepetitionsShow != ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC)
+               {
+                       if(ySampleEnd < ySampleStart)
+                               fsrType = ForceSensorRepetition.Types.ECC;
+                       else
+                               fsrType = ForceSensorRepetition.Types.CON;
+               }
+
+               return fsrType;
+       }
+
        protected abstract void addRepetition(List <double> yList, int sampleStart, int sampleEnd);
 
        public void CutSamplesForZoom(int startAtSample, int endAtSample)
@@ -394,15 +408,17 @@ public class ForceSensorDynamicsNotElastic : ForceSensorDynamics
        {
                //TODO: need to cut reps with low force prolonged at start or end
 
-               ForceSensorRepetition.Types fsrType = ForceSensorRepetition.Types.DONOTSHOW;
-               if(fse.EccReps)
+               ForceSensorRepetition.Types fsrType = getForceSensorRepetitionType (yList[sampleStart], 
yList[sampleEnd]);
+
+               //  modify previous repetition if this repetition is ECC and fse.RepetitionsShow == 
ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER
+               if(fsrType == ForceSensorRepetition.Types.ECC &&
+                               fse.RepetitionsShow == ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER 
&&
+                               forceSensorRepetition_l.Count > 0)
                {
-                       if(yList[sampleEnd] < yList[sampleStart])
-                               fsrType = ForceSensorRepetition.Types.ECC;
-                       else
-                               fsrType = ForceSensorRepetition.Types.CON;
-               }
-               forceSensorRepetition_l.Add(new ForceSensorRepetition(sampleStart, sampleEnd, fsrType));
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].sampleEnd = sampleEnd;
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].type = 
ForceSensorRepetition.Types.DONOTSHOW;
+               } else
+                       forceSensorRepetition_l.Add(new ForceSensorRepetition(sampleStart, sampleEnd, 
fsrType));
        }
 
        protected override void cutSamplesForZoomDo(int startAtSample, int endAtSample)
@@ -586,20 +602,31 @@ public class ForceSensorDynamicsElastic : ForceSensorDynamics
        {
                //TODO: need to cut reps with low force prolonged at start or end
 
-               ForceSensorRepetition.Types fsrType = ForceSensorRepetition.Types.DONOTSHOW;
-               if(fse.EccReps)
+               ForceSensorRepetition.Types fsrType = getForceSensorRepetitionType (yList[sampleStart], 
yList[sampleEnd]);
+
+               //  modify previous repetition if this repetition is ECC and fse.RepetitionsShow == 
ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER
+               if(fsrType == ForceSensorRepetition.Types.ECC &&
+                               fse.RepetitionsShow == ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER 
&&
+                               forceSensorRepetition_l.Count > 0)
                {
-                       if(yList[sampleEnd] < yList[sampleStart])
-                               fsrType = ForceSensorRepetition.Types.ECC;
-                       else
-                               fsrType = ForceSensorRepetition.Types.CON;
-               }
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].sampleEnd = sampleEnd;
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].type = 
ForceSensorRepetition.Types.DONOTSHOW;
+
+                       int sampleStartPreviousRep = forceSensorRepetition_l[forceSensorRepetition_l.Count 
-1].sampleStart;
 
-               //Calculate mean RFD and mean speed of the phase
-               double lastRFD = (force_l[sampleEnd] - force_l[sampleStart]) / (time_l[sampleEnd] - 
time_l[sampleStart]);
-               double lastMeanSpeed = (yList[sampleEnd] - yList[sampleStart]) / (time_l[sampleEnd] - 
time_l[sampleStart]);
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].RFD =
+                               (force_l[sampleEnd] - force_l[sampleStartPreviousRep]) / (time_l[sampleEnd] - 
time_l[sampleStartPreviousRep]);
 
-               forceSensorRepetition_l.Add(new ForceSensorRepetition(sampleStart, sampleEnd, fsrType, 
lastMeanSpeed, lastRFD));
+                       forceSensorRepetition_l[forceSensorRepetition_l.Count -1].meanSpeed =
+                               (yList[sampleEnd] - yList[sampleStartPreviousRep]) /  (time_l[sampleEnd] - 
time_l[sampleStartPreviousRep]);
+               } else
+               {
+                       //Calculate mean RFD and mean speed of the phase
+                       double lastRFD = (force_l[sampleEnd] - force_l[sampleStart]) / (time_l[sampleEnd] - 
time_l[sampleStart]);
+                       double lastMeanSpeed = (yList[sampleEnd] - yList[sampleStart]) / (time_l[sampleEnd] - 
time_l[sampleStart]);
+
+                       forceSensorRepetition_l.Add(new ForceSensorRepetition(sampleStart, sampleEnd, 
fsrType, lastMeanSpeed, lastRFD));
+               }
        }
 
        protected override void cutSamplesForZoomDo(int startAtSample, int endAtSample)
@@ -658,7 +685,8 @@ public class ForceSensorRepetition
        public int sampleStart; // this is sample, not graph in pixels.
        public int sampleEnd; // this is sample, not graph in pixels.
 
-       //if !fse.EccReps, then DONOTSHOW
+       //if(!fse.EccReps), then DONOTSHOW
+       //if(fse.RepetitionsShow == ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC), then DONOTSHOW
        public enum Types { DONOTSHOW, CON, ECC }
        public Types type;
 
@@ -709,7 +737,7 @@ public class ForceSensorRepetition
        }
        */
 
-       public static string GetRepetitionCodeFromList(List<ForceSensorRepetition> l, int sampleEnd, bool 
eccReps)
+       public static string GetRepetitionCodeFromList(List<ForceSensorRepetition> l, int sampleEnd, 
ForceSensorExercise.RepetitionsShowTypes repetitionsShow)
        {
                int rep = 1;
                foreach(ForceSensorRepetition fsr in l)
@@ -717,7 +745,9 @@ public class ForceSensorRepetition
                        if(sampleEnd >= fsr.sampleStart && sampleEnd <= fsr.sampleEnd)
                        {
                                LogB.Information(string.Format("fsr.sampleStart: {0}; fsr.sampleEnd: {1}; 
sampleEnd: {2}; rep: {3}", fsr.sampleStart, fsr.sampleEnd, sampleEnd, rep));
-                               if(! eccReps || rep == 0)
+                               if(repetitionsShow == ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC ||
+                                               repetitionsShow == 
ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER ||
+                                               rep == 0)
                                        return rep.ToString();
                                else
                                        return string.Format("{0}{1}", Math.Ceiling(rep/2.0), 
typeShort(fsr.type));
diff --git a/src/gui/app1/forceSensorAnalyze.cs b/src/gui/app1/forceSensorAnalyze.cs
index d30b80fd..f07a4447 100644
--- a/src/gui/app1/forceSensorAnalyze.cs
+++ b/src/gui/app1/forceSensorAnalyze.cs
@@ -1658,7 +1658,9 @@ public partial class ChronoJumpWindow
 //             LogB.Information(string.Format("at forceSensorWriteRepetitionNumber with (rep+1): {0}, 
endsAtLeft: {1}, endsAtRight: {2}", rep +1, endsAtLeft, endsAtRight));
 //             layout_force_ai_text.SetMarkup((rep+1).ToString());
 
-               if(! currentForceSensorExercise.EccReps)
+               //if(! currentForceSensorExercise.EccReps)
+               if(currentForceSensorExercise.RepetitionsShow == 
ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC ||
+                               currentForceSensorExercise.RepetitionsShow == 
ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER)
                        layout_force_ai_text.SetMarkup((number+1).ToString());
                else
                        layout_force_ai_text.SetMarkup(string.Format("{0}{1}", Math.Ceiling((number +1)/2.0), 
type));
diff --git a/src/gui/forceSensorExercise.cs b/src/gui/forceSensorExercise.cs
index 8545569e..cf444a4a 100644
--- a/src/gui/forceSensorExercise.cs
+++ b/src/gui/forceSensorExercise.cs
@@ -73,9 +73,8 @@ public class ForceSensorExerciseWindow
        [Widget] Gtk.HBox hbox_body_mass_add;
        [Widget] Gtk.SpinButton spin_body_mass_add;
 
-       //repetitions tab
+       //repetitions detect tab
        [Widget] Gtk.Label label_detect_repetitions;
-       [Widget] Gtk.CheckButton check_show_ecc;
        [Widget] Gtk.RadioButton radio_detect_repetitions_from_prefs;
        [Widget] Gtk.RadioButton radio_detect_repetitions_custom;
        [Widget] Gtk.HBox hbox_detect_repetitions_preferences;
@@ -90,6 +89,14 @@ public class ForceSensorExerciseWindow
        [Widget] Gtk.SpinButton spin_force_sensor_not_elastic_ecc_min_force;
        [Widget] Gtk.SpinButton spin_force_sensor_not_elastic_con_min_force;
 
+       //repetitions show tab
+       //[Widget] Gtk.CheckButton check_show_ecc;
+       [Widget] Gtk.RadioButton radio_reps_show_concentric;
+       [Widget] Gtk.RadioButton radio_reps_show_both;
+       [Widget] Gtk.Alignment alignment_reps_show_both;
+       [Widget] Gtk.RadioButton radio_reps_show_both_together;
+       [Widget] Gtk.RadioButton radio_reps_show_both_separated;
+
        //other tab
        [Widget] Gtk.Label label_other;
        [Widget] Gtk.TextView textview_other_explanation;
@@ -111,9 +118,10 @@ public class ForceSensorExerciseWindow
 
        private enum modesEnum { EDIT, ADD }
        private modesEnum modeEnum;
-       private enum Pages { FORCE, FIXATION, MASS, REPETITIONS, OTHER }
+       private enum Pages { FORCE, FIXATION, MASS, REPSDETECT, REPSSHOW, OTHER }
        private enum Options { FORCE_SENSOR, FORCE_RESULTANT, FIXATION_ELASTIC, FIXATION_NOT_ELASTIC,
-               MASS_ADD, MASS_SUBTRACT, MASS_NOTHING, REPETITIONS_PREFS, REPETITIONS_NO_PREFS, OTHER }
+               MASS_ADD, MASS_SUBTRACT, MASS_NOTHING,
+               REPETITIONS_PREFS, REPETITIONS_NO_PREFS, REPETITIONS_SHOW, OTHER }
 
        static ForceSensorExerciseWindow ForceSensorExerciseWindowBox;
 
@@ -191,7 +199,7 @@ public class ForceSensorExerciseWindow
                        }
 
                        ForceSensorExerciseWindowBox.repetitionsToGUI(
-                                       exercise.EccReps, repsFromPrefs,
+                                       exercise.RepetitionsShow, repsFromPrefs,
                                        em, cm,
                                        prefsForceSensorNotElasticEccMinForce, 
prefsForceSensorNotElasticConMinForce);
                } else {
@@ -209,7 +217,7 @@ public class ForceSensorExerciseWindow
                        }
 
                        ForceSensorExerciseWindowBox.repetitionsToGUI(
-                                       exercise.EccReps, repsFromPrefs,
+                                       exercise.RepetitionsShow, repsFromPrefs,
                                        prefsForceSensorElasticEccMinDispl, 
prefsForceSensorElasticConMinDispl,
                                        Convert.ToInt32(em), Convert.ToInt32(cm));
                }
@@ -241,7 +249,7 @@ public class ForceSensorExerciseWindow
                ForceSensorExerciseWindowBox.prefsForceSensorNotElasticConMinForce = 
prefsForceSensorNotElasticConMinForce;
 
                ForceSensorExerciseWindowBox.repetitionsToGUI(
-                               false, true, //show ecc, repsFromPrefs
+                               ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER, true, //repsFromPrefs
                                prefsForceSensorElasticEccMinDispl, prefsForceSensorElasticConMinDispl,
                                prefsForceSensorNotElasticEccMinForce, prefsForceSensorNotElasticConMinForce);
 
@@ -319,12 +327,11 @@ public class ForceSensorExerciseWindow
        }
 
        private void repetitionsToGUI(
-                       bool showEcc, bool repsFromPrefs,
+                       ForceSensorExercise.RepetitionsShowTypes repetitionsShow, bool repsFromPrefs,
                        double forceSensorElasticEccMinDispl, double forceSensorElasticConMinDispl,
                        int forceSensorNotElasticEccMinForce, int forceSensorNotElasticConMinForce)
        {
-               check_show_ecc.Active = showEcc;
-
+               //reps detect tab
                if(repsFromPrefs)
                        radio_detect_repetitions_from_prefs.Active = true;
                else
@@ -334,6 +341,23 @@ public class ForceSensorExerciseWindow
                spin_force_sensor_elastic_con_min_displ.Value = forceSensorElasticConMinDispl;
                spin_force_sensor_not_elastic_ecc_min_force.Value = forceSensorNotElasticEccMinForce;
                spin_force_sensor_not_elastic_con_min_force.Value = forceSensorNotElasticConMinForce;
+
+
+               //reps show tab
+               if(repetitionsShow == ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC)
+               {
+                       radio_reps_show_concentric.Active = true;
+                       alignment_reps_show_both.Visible = false;
+               } else
+               {
+                       radio_reps_show_both.Active = true;
+                       alignment_reps_show_both.Visible = true;
+
+                       if(repetitionsShow == ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER)
+                               radio_reps_show_both_together.Active = true;
+                       else
+                               radio_reps_show_both_separated.Active = true;
+               }
        }
 
        private string getTopExplanations (Pages p)
@@ -345,7 +369,9 @@ public class ForceSensorExerciseWindow
                        str = Catalog.GetString("How the force is transmitted to the sensor");
                else if(p == Pages.MASS)
                        str = Catalog.GetString("Depending on the exercise and configuration of the test, the 
total mass (mass of the person and the extra load) can affect the sensor measuring. Select how to manage this 
effect.");
-               else if(p == Pages.REPETITIONS)
+               else if(p == Pages.REPSDETECT)
+                       str = ""; //not shown
+               else if(p == Pages.REPSSHOW)
                        str = ""; //not shown
                else { //if(p == Pages.OTHER)
                        if(radio_force_resultant.Active && radio_mass_add.Active)
@@ -378,6 +404,8 @@ public class ForceSensorExerciseWindow
                        str = Catalog.GetString("If user changes values on preferences, these values will 
automatically change.");
                else if(o == Options.REPETITIONS_NO_PREFS)
                        str = Catalog.GetString("These values will be used to detect repetitions.");
+               else if(o == Options.REPETITIONS_SHOW)
+                       str = Catalog.GetString("Detected repetitions will show only concentric phase or 
both.");
                else //if(o == Options.OTHER)
                        str = Catalog.GetString("0 means horizontally") + "\n" +
                                Catalog.GetString("90 means vertically with the person above the sensor") + 
"\n" +
@@ -409,7 +437,9 @@ public class ForceSensorExerciseWindow
                else if(o == Options.MASS_NOTHING)
                        str = "1.- " + Catalog.GetString("Nordic hamstring. In a Nordic hamstring with the 
sensor attached to the ankle, the weight affects the values of the sensor but this weight is supported by the 
hamstrings we are measuring.") +
                                "\n2.- " + Catalog.GetString("Pulling on a TRX. Pulling from a TRX implies 
overcome the body weight. This body weight is also measured by the sensor.");
-               //else if(o == Options.REPETITIONS)
+               //else if(o == Options.REPSDETECT)
+               //      str = ""; //not shown
+               //else if(o == Options.REPSSHOW)
                //      str = ""; //not shown
                else //if(o == Options.OTHER)
                        str = "";
@@ -439,6 +469,8 @@ public class ForceSensorExerciseWindow
                        str = Catalog.GetString("Repetitions according to preferences");
                else if(o == Options.REPETITIONS_NO_PREFS)
                        str = Catalog.GetString("Repetitions using custom values");
+               else if(o == Options.REPETITIONS_SHOW)
+                       str = Catalog.GetString("Show repetitions");
                else //if(o == Options.OTHER)
                        str = Catalog.GetString("Angle explanation");
 
@@ -508,7 +540,7 @@ public class ForceSensorExerciseWindow
                        }
                        hbox_body_mass_add.Sensitive = radio_mass_add.Active;
                }
-               else if(p == Pages.REPETITIONS)
+               else if(p == Pages.REPSDETECT)
                {
                        if(radio_force_sensor_raw.Active || ! radio_fixation_elastic.Active)
                        {
@@ -559,6 +591,21 @@ public class ForceSensorExerciseWindow
                        //notebook_desc_examples.CurrentPage = 0;
                        notebook_desc_examples.GetNthPage(1).Hide();
                }
+               else if(p == Pages.REPSSHOW)
+               {
+                       if(radio_reps_show_concentric.Active)
+                               alignment_reps_show_both.Visible = false;
+                       else if(radio_reps_show_both.Active)
+                               alignment_reps_show_both.Visible = true;
+
+                       desc = getDescription(Options.REPETITIONS_SHOW);
+                       ex = getExample(Options.REPETITIONS_SHOW);
+                       set_notebook_desc_example_labels(Options.REPETITIONS_SHOW);
+
+                       radio_desc_examples_desc.Active = true;
+                       radio_desc_examples_examples.Hide();
+                       notebook_desc_examples.GetNthPage(1).Hide();
+               }
                else // if(p == Pages.OTHER)
                {
                        button_next.Visible = false;
@@ -591,7 +638,7 @@ public class ForceSensorExerciseWindow
        private void on_button_next_clicked (object o, EventArgs args)
        {
                if(notebook_main.CurrentPage == Convert.ToInt32(Pages.FORCE) && radio_force_sensor_raw.Active)
-                       notebook_main.CurrentPage = Convert.ToInt32(Pages.REPETITIONS);
+                       notebook_main.CurrentPage = Convert.ToInt32(Pages.REPSDETECT);
                else if(notebook_main.CurrentPage < Convert.ToInt32(Pages.OTHER))
                        notebook_main.CurrentPage ++;
                else
@@ -601,7 +648,7 @@ public class ForceSensorExerciseWindow
        }
        private void on_button_back_clicked (object o, EventArgs args)
        {
-               if(notebook_main.CurrentPage == Convert.ToInt32(Pages.REPETITIONS) && 
radio_force_sensor_raw.Active)
+               if(notebook_main.CurrentPage == Convert.ToInt32(Pages.REPSDETECT) && 
radio_force_sensor_raw.Active)
                        notebook_main.CurrentPage = Convert.ToInt32(Pages.FORCE);
                else if(notebook_main.CurrentPage > Convert.ToInt32(Pages.FORCE))
                        notebook_main.CurrentPage --;
@@ -624,15 +671,25 @@ public class ForceSensorExerciseWindow
                managePage(Pages.MASS);
        }
 
-       private void on_check_show_ecc_toggled (object o, EventArgs args)
+       private void on_radio_detect_repetitions_toggled (object o, EventArgs args)
        {
-               managePage(Pages.REPETITIONS);
+               managePage(Pages.REPSDETECT);
        }
 
-       private void on_radio_detect_repetitions_toggled (object o, EventArgs args)
+       /*
+       private void on_check_show_ecc_toggled (object o, EventArgs args)
        {
                managePage(Pages.REPETITIONS);
        }
+       */
+       private void on_radio_reps_show_concentric_toggled (object o, EventArgs args)
+       {
+               managePage(Pages.REPSSHOW);
+       }
+       private void on_radio_reps_show_both_toggled (object o, EventArgs args)
+       {
+               managePage(Pages.REPSSHOW);
+       }
 
        private void on_entry_name_changed (object o, EventArgs args)
        {
@@ -704,6 +761,14 @@ public class ForceSensorExerciseWindow
                if(modeEnum == modesEnum.EDIT)
                        myID = exercise.UniqueID;
 
+               ForceSensorExercise.RepetitionsShowTypes repetitionsShow;
+               if(radio_reps_show_concentric.Active)
+                       repetitionsShow = ForceSensorExercise.RepetitionsShowTypes.CONCENTRIC;
+               else if(radio_reps_show_both.Active && radio_reps_show_both_together.Active)
+                       repetitionsShow = ForceSensorExercise.RepetitionsShowTypes.BOTHTOGETHER;
+               else //if(radio_reps_show_both.Active && radio_reps_show_both_separated.Active)
+                       repetitionsShow = ForceSensorExercise.RepetitionsShowTypes.BOTHSEPARATED;
+
                ForceSensorExercise exerciseTemp = new ForceSensorExercise(
                                myID, entry_name.Text,
                                percentBodyWeight,
@@ -713,7 +778,7 @@ public class ForceSensorExerciseWindow
                                radio_mass_subtract.Active,     //tareBeforeCapture
                                radio_force_resultant.Active,
                                radio_fixation_elastic.Active,
-                               check_show_ecc.Active, eccMin, conMin);
+                               repetitionsShow, eccMin, conMin);
 
                if(modeEnum == modesEnum.ADD)
                {
diff --git a/src/sqlite/forceSensor.cs b/src/sqlite/forceSensor.cs
index c6a35c04..ac6f3132 100644
--- a/src/sqlite/forceSensor.cs
+++ b/src/sqlite/forceSensor.cs
@@ -451,7 +451,7 @@ class SqliteForceSensorExercise : Sqlite
                        "tareBeforeCapture INT, " +
                        "forceResultant INT NOT NULL, " +
                        "elastic INT NOT NULL, " +
-                       "eccReps INT DEFAULT 0, " +
+                       "eccReps INT DEFAULT 0, " +     //since ~2.22 (not really a change on DB) is 
repetitionsShow
                        "eccMin FLOAT DEFAULT -1, " +   //can be displacement or N
                        "conMin FLOAT DEFAULT -1)";     //can be displacement or N
                LogB.SQL(dbcmd.CommandText.ToString());
@@ -497,7 +497,7 @@ class SqliteForceSensorExercise : Sqlite
                        "\", tareBeforeCapture = " + Util.BoolToInt(ex.TareBeforeCapture).ToString() +
                        ", forceResultant = " + Util.BoolToInt(ex.ForceResultant).ToString() +
                        ", elastic = " + Util.BoolToInt(ex.Elastic).ToString() +
-                       ", eccReps = " + Util.BoolToInt(ex.EccReps).ToString() +
+                       ", eccReps = " + ex.RepetitionsShowToCode().ToString() +
                        ", eccMin = " + Util.ConvertToPoint(ex.EccMin) +
                        ", conMin = " + Util.ConvertToPoint(ex.ConMin) +
                        " WHERE uniqueID = " + ex.UniqueID;
@@ -576,7 +576,7 @@ class SqliteForceSensorExercise : Sqlite
                                                        
Util.IntToBool(Convert.ToInt32(reader[6].ToString())),  //tareBeforeCapture
                                                        
Util.IntToBool(Convert.ToInt32(reader[7].ToString())),  //forceResultant
                                                        
Util.IntToBool(Convert.ToInt32(reader[8].ToString())),  //elastic
-                                                       
Util.IntToBool(Convert.ToInt32(reader[9].ToString())),  //eccReps
+                                                       
ForceSensorExercise.RepetitionsShowFromCode(Convert.ToInt32(reader[9].ToString())),     //eccReps
                                                        
Convert.ToDouble(Util.ChangeDecimalSeparator(reader[10].ToString())),   //eccMin
                                                        
Convert.ToDouble(Util.ChangeDecimalSeparator(reader[11].ToString()))    //conMin
                                                        );


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]