[chronojump] Encoder signal graph while capture now is managed by a Cairo scroll
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Encoder signal graph while capture now is managed by a Cairo scroll
- Date: Tue, 15 Mar 2022 09:58:07 +0000 (UTC)
commit 2055d5b9fb1afbe4695d825bc51b22b4258506e7
Author: Xavier de Blas <xaviblas gmail com>
Date: Tue Mar 15 10:57:08 2022 +0100
Encoder signal graph while capture now is managed by a Cairo scroll
glade/app1.glade | 55 +++++++++++----
src/Makefile.am | 1 +
src/encoderCapture.cs | 11 +++
src/gui/app1/encoder.cs | 38 ++++++++++-
src/gui/cairo/encoder.cs | 169 +++++++++++++++++++++++++++++++++++++++++++++++
src/gui/cairo/xy.cs | 9 +++
6 files changed, 268 insertions(+), 15 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index 5c5357b8a..508d00bae 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -26252,6 +26252,9 @@ Concentric</property>
<child>
<placeholder/>
</child>
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
@@ -32660,18 +32663,6 @@ Concentric</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <widget class="GtkLabel"
id="label_video_encoder_tests_will_be_filmed">
- <property name="can_focus">False</property>
- <property name="label" translatable="yes">Tests
will be filmed</property>
- </widget>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
<widget class="GtkHBox"
id="hbox_video_encoder_capturing">
<property name="can_focus">False</property>
<property name="spacing">4</property>
@@ -32708,6 +32699,18 @@ Concentric</property>
</packing>
</child>
<child>
+ <widget class="GtkLabel"
id="label_video_encoder_tests_will_be_filmed">
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes">Tests
will be filmed</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkHBox"
id="hbox_video_encoder_no_capturing">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -33777,6 +33780,10 @@ Concentric</property>
<property name="show_tabs">False</property>
<property name="show_border">False</property>
<child>
+ <widget class="GtkVBox" id="vbox260">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
<widget class="GtkDrawingArea"
id="encoder_capture_signal_drawingarea">
<property name="height_request">100</property>
<property name="visible">True</property>
@@ -33785,6 +33792,27 @@ Concentric</property>
<signal name="expose_event"
handler="on_encoder_capture_signal_drawingarea_expose_event" swapped="no"/>
<signal name="configure_event"
handler="on_encoder_capture_signal_drawingarea_configure_event" swapped="no"/>
</widget>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkDrawingArea"
id="encoder_capture_signal_drawingarea_cairo">
+ <property name="height_request">100</property>
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">False</property>
+ <signal name="expose_event"
handler="on_encoder_capture_signal_drawingarea_cairo_expose_event" swapped="no"/>
+ </widget>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
</child>
<child>
<widget class="GtkLabel"
id="label_encoder_capture">
@@ -42362,6 +42390,9 @@ then click this button.</property>
<child>
<placeholder/>
</child>
+ <child>
+ <placeholder/>
+ </child>
</widget>
<packing>
<property name="expand">False</property>
diff --git a/src/Makefile.am b/src/Makefile.am
index 345129917..f09a4adc4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,6 +36,7 @@ SOURCES = \
gui/app1/runEncoderAnalyze.cs\
gui/app1/shortcuts.cs\
gui/cairo/bars.cs\
+ gui/cairo/encoder.cs\
gui/cairo/generic.cs\
gui/cairo/jumpsDjOptimalFall.cs\
gui/cairo/jumpsRunsEvolution.cs\
diff --git a/src/encoderCapture.cs b/src/encoderCapture.cs
index ade10d134..d7fa6ece7 100644
--- a/src/encoderCapture.cs
+++ b/src/encoderCapture.cs
@@ -37,6 +37,8 @@ public abstract class EncoderCapture
//this is unused if showOnlyBars (configChronojump.EncoderCaptureShowOnlyBars)
public List<Gdk.Point> EncoderCapturePoints;
public List<Gdk.Point> EncoderCapturePointsInertialDisc;
+ public List<PointF> EncoderCapturePointsCairo;
+ public List<PointF> EncoderCapturePointsInertialDiscCairo;
public int EncoderCapturePointsCaptured;
public int EncoderCapturePointsPainted;
@@ -166,6 +168,8 @@ public abstract class EncoderCapture
{
EncoderCapturePoints = new List<Gdk.Point>();
EncoderCapturePointsInertialDisc = new List<Gdk.Point>();
+ EncoderCapturePointsCairo = new List<PointF>();
+ EncoderCapturePointsInertialDiscCairo = new List<PointF>();
EncoderCapturePointsCaptured = 0;
EncoderCapturePointsPainted = 0; //-1 means delete screen
}
@@ -676,6 +680,8 @@ public abstract class EncoderCapture
{
EncoderCapturePoints = new List<Gdk.Point>();
EncoderCapturePointsInertialDisc = new List<Gdk.Point>();
+ EncoderCapturePointsCairo = new List<PointF>();
+ EncoderCapturePointsInertialDiscCairo = new List<PointF>();
EncoderCapturePointsCaptured = 0;
EncoderCapturePointsPainted = -1; //-1 means delete screen
}
@@ -758,6 +764,8 @@ public abstract class EncoderCapture
Convert.ToInt32(widthG * i / xWidth),
Convert.ToInt32( (heightG/2) - ( sum * heightG / realHeightG) )
));
+
+ EncoderCapturePointsCairo.Add(new PointF(i, sum));
}
//on inertial also uses to EncoderCapturePointsInertialDisc
@@ -970,6 +978,9 @@ public class EncoderCaptureInertial : EncoderCapture
Convert.ToInt32(widthG * i / xWidth),
Convert.ToInt32( (heightG/2) - ( sumInertialDisc * heightG / realHeightG) )
));
+
+ EncoderCapturePointsCairo.Add(new PointF(i, sum));
+ EncoderCapturePointsInertialDiscCairo.Add(new PointF(i, sumInertialDisc));
}
protected override void encoderCapturePointsAdaptativeDisplay()
diff --git a/src/gui/app1/encoder.cs b/src/gui/app1/encoder.cs
index 2ecdb2b8d..02fea23a3 100644
--- a/src/gui/app1/encoder.cs
+++ b/src/gui/app1/encoder.cs
@@ -342,6 +342,7 @@ public partial class ChronoJumpWindow
[Widget] Gtk.TreeView treeview_encoder_analyze_curves;
[Widget] Gtk.DrawingArea encoder_capture_signal_drawingarea;
+ [Widget] Gtk.DrawingArea encoder_capture_signal_drawingarea_cairo;
[Widget] Gtk.DrawingArea encoder_capture_curves_bars_drawingarea;
Gdk.Pixmap encoder_capture_signal_pixmap = null;
Gdk.Pixmap encoder_capture_curves_bars_pixmap = null;
@@ -449,6 +450,10 @@ public partial class ChronoJumpWindow
*
*/
+ CairoGraphEncoderSignal cairoGraphEncoderSignal;
+ static List<PointF> cairoGraphEncoderSignalPoints_l;
+ static List<PointF> cairoGraphEncoderSignalInertialPoints_l;
+
enum encoderSensEnum {
NOSESSION, NOPERSON, YESPERSON, PROCESSINGCAPTURE, PROCESSINGR, DONENOSIGNAL, DONEYESSIGNAL }
encoderSensEnum encoderSensEnumStored; //tracks how was sensitive before PROCESSINGCAPTURE or
PROCESSINGR
@@ -1021,6 +1026,10 @@ public partial class ChronoJumpWindow
sensitiveGuiEventDoing(preferences.encoderCaptureInfinite);
+ cairoGraphEncoderSignal = null;
+ cairoGraphEncoderSignalPoints_l = new List<PointF>();
+ cairoGraphEncoderSignalInertialPoints_l = new List<PointF>();
+
LogB.Debug("Calling encoderThreadStart for capture");
//record this encoderConfiguration to SQL for next Chronojump open
@@ -5890,6 +5899,7 @@ public partial class ChronoJumpWindow
for(int j=0, i = eCapture.EncoderCapturePointsPainted +1 ; i <= last ; i ++, j++)
{
paintPoints[j] = eCapture.EncoderCapturePoints[i];
+ cairoGraphEncoderSignalPoints_l.Add(eCapture.EncoderCapturePointsCairo[i]);
if(refreshAreaOnly) {
if(eCapture.EncoderCapturePoints[i].Y > maxY)
@@ -5897,7 +5907,6 @@ public partial class ChronoJumpWindow
if(eCapture.EncoderCapturePoints[i].Y < minY)
minY = eCapture.EncoderCapturePoints[i].Y;
}
-
}
if(mode == UpdateEncoderPaintModes.INERTIAL) {
@@ -5916,6 +5925,9 @@ public partial class ChronoJumpWindow
minY = eCapture.EncoderCapturePointsInertialDisc[i].Y;
}
}
+ //only assign the points if they are different than paintPoints
+// if(eCapture.EncoderCapturePointsInertialDiscCairo[i] !=
eCapture.EncoderCapturePointsCairo[i]) //do not avoid this step on cairo
+
cairoGraphEncoderSignalInertialPoints_l.Add(eCapture.EncoderCapturePointsInertialDiscCairo[i]);
}
encoder_capture_signal_pixmap.DrawPoints(pen_gray_encoder_signal,
paintPointsInertial);
}
@@ -6147,6 +6159,21 @@ public partial class ChronoJumpWindow
encoder_capture_signal_allocationXOld = allocation.Width;
}
+ public void on_encoder_capture_signal_drawingarea_cairo_expose_event (object o, ExposeEventArgs args)
+ {
+ updateEncoderCaptureSignalCairo (current_mode == Constants.Modes.POWERINERTIAL, true);
+ }
+ private void updateEncoderCaptureSignalCairo (bool inertial, bool forceRedraw)
+ {
+ if(cairoGraphEncoderSignal == null)
+ cairoGraphEncoderSignal = new CairoGraphEncoderSignal (
+ encoder_capture_signal_drawingarea_cairo, "title");
+
+ cairoGraphEncoderSignal.DoSendingList (preferences.fontType.ToString(), inertial,
+ cairoGraphEncoderSignalPoints_l, cairoGraphEncoderSignalInertialPoints_l,
+ forceRedraw, CairoXY.PlotTypes.LINES);
+ }
+
private double sendMaxPowerSpeedForceIntersession(Constants.EncoderVariablesCapture evc)
{
if(evc == Constants.EncoderVariablesCapture.MeanPower)
@@ -6536,6 +6563,8 @@ public partial class ChronoJumpWindow
if(eraseSignal && encoder_capture_signal_pixmap != null)
UtilGtk.ErasePaint(encoder_capture_signal_drawingarea, encoder_capture_signal_pixmap);
+ //TODO maybe delete cairo signal here
+
layout_encoder_capture_signal = new Pango.Layout
(encoder_capture_signal_drawingarea.PangoContext);
layout_encoder_capture_signal.FontDescription = Pango.FontDescription.FromString
(preferences.GetFontTypeWithSize(10));
@@ -6850,10 +6879,13 @@ public partial class ChronoJumpWindow
//capturingSendCurveToR(); //unused, done while capturing
readingCurveFromR();
- if(encoderConfigurationCurrent.has_inertia)
+ if(encoderConfigurationCurrent.has_inertia) {
updateEncoderCaptureGraphPaint(UpdateEncoderPaintModes.INERTIAL);
- else
+ updateEncoderCaptureSignalCairo (true, false); //inertial, forceRedraw
+ } else {
updateEncoderCaptureGraphPaint(UpdateEncoderPaintModes.GRAVITATORY);
+ updateEncoderCaptureSignalCairo (false, false);
+ }
if(needToRefreshTreeviewCapture)
{
diff --git a/src/gui/cairo/encoder.cs b/src/gui/cairo/encoder.cs
new file mode 100644
index 000000000..93fb586ba
--- /dev/null
+++ b/src/gui/cairo/encoder.cs
@@ -0,0 +1,169 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * ChronoJump is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (C) 2022 Xavier de Blas <xaviblas gmail com>
+ */
+
+using System;
+using System.Collections.Generic; //List
+using Gtk;
+using Cairo;
+
+
+public class CairoGraphEncoderSignal : CairoXY
+{
+ //TODO: check if this two are doing anything
+ private int points_list_painted;
+ private int points_list_inertial_painted;
+ //private bool doing;
+
+ //regular constructor
+ public CairoGraphEncoderSignal (DrawingArea area, string title)
+ {
+ this.area = area;
+ this.title = title;
+ this.colorBackground = colorFromGdk(Config.ColorBackground); //but note if we are using
system colors, this will not match
+
+ //doing = false;
+ points_list_painted = 0;
+ points_list_inertial_painted = 0;
+ }
+
+ //TODO: remove most of the null comparisons, see if we can do at start and delete graph or whatever,
but not continue all the time making comparisons
+ public override void DoSendingList (string font, bool isInertial,
+ List<PointF> points_list, List<PointF> points_list_inertial,
+ bool forceRedraw, PlotTypes plotType)
+ {
+// if(doing)
+// return;
+
+ //doing = true;
+ bool initGraphDone = false;
+ bool maxValuesChanged = false;
+
+ if(points_list != null)
+ {
+ maxValuesChanged = findPointMaximums(false, points_list);
+ if(isInertial && points_list_inertial != null)
+ {
+ bool maxValuesChangedInertial = findPointMaximums(false,
points_list_inertial);
+ if(! maxValuesChanged && maxValuesChangedInertial)
+ maxValuesChanged = true;
+ }
+
+ //show a vertical window of 100 mm (on inertial -+100 mm)
+ //LogB.Information(string.Format("minY: {0}, maxY: {1}", minY, maxY));
+ if(maxY < 100)
+ maxY = 100; //to be able to graph at start when all the points are 0
+ if(isInertial && minY > -100)
+ minY = -100;
+ }
+
+ if( maxValuesChanged || forceRedraw ||
+ (points_list != null && points_list.Count != points_list_painted) ||
+ (points_list_inertial != null && points_list_inertial.Count !=
points_list_inertial_painted)
+ )
+ {
+ initGraph( font, 1, (maxValuesChanged || forceRedraw) );
+ initGraphDone = true;
+ points_list_painted = 0;
+ points_list_inertial_painted = 0;
+ }
+
+ //do not draw axis at the moment (and it is not in 0Y right now)
+ //if(maxValuesChanged || forceRedraw)
+ // paintAxis();
+
+ if( points_list == null || points_list.Count == 0 ||
+ (isInertial && (points_list_inertial == null || points_list_inertial.Count ==
0)) )
+ return;
+
+ g.LineWidth = 1;
+ pointsRadius = 1;
+
+ //display this milliseconds on screen, when is higher, scroll
+ int msWidth = 10000;
+ if(absoluteMaxX < msWidth)
+ absoluteMaxX = msWidth;
+
+ int startAt = 0;
+ if(points_list.Count - msWidth > 0)
+ {
+ startAt = points_list.Count - msWidth;
+ minX = points_list[startAt].X;
+ }
+
+ if(maxValuesChanged || forceRedraw || points_list.Count != points_list_painted)
+ {
+ //on inertial draw person on 3 px, disk on 1
+ if(isInertial)
+ g.LineWidth = 2;
+
+ plotRealPoints(plotType, points_list, startAt);
+ points_list_painted = points_list.Count;
+ }
+
+ if( isInertial &&
+ (maxValuesChanged || forceRedraw || points_list_inertial.Count !=
points_list_inertial_painted) )
+ {
+ g.LineWidth = 1;
+ plotRealPoints(plotType, points_list_inertial, startAt);
+ points_list_inertial_painted = points_list_inertial.Count;
+ }
+
+ if(initGraphDone)
+ endGraphDisposing(g, surface, area.GdkWindow);
+
+ //doing = false;
+ }
+
+ //based on XY findPointMaximums
+ private bool findPointMaximums (List<PointF> points_list)
+ {
+ bool changedY = false;
+ for(int i = 0; i < points_list.Count; i ++)
+ {
+ PointF p = points_list[i];
+
+ if(p.X < minX)
+ minX = p.X;
+ if(p.X > maxX)
+ maxX = p.X;
+ if(p.Y < minY)
+ {
+ minY = p.Y;
+ changedY = true;
+ }
+ if(p.Y > maxY)
+ {
+ maxY = p.Y;
+ changedY = true;
+ }
+ }
+
+ //if there is only one point, or by any reason mins == maxs, have mins and maxs separated
+ separateMinXMaxXIfNeeded();
+ separateMinYMaxYIfNeeded();
+
+ return changedY;
+ }
+
+ protected override void writeTitle()
+ {
+ }
+}
+
diff --git a/src/gui/cairo/xy.cs b/src/gui/cairo/xy.cs
index 441d4c00f..eb44bb301 100644
--- a/src/gui/cairo/xy.cs
+++ b/src/gui/cairo/xy.cs
@@ -110,6 +110,15 @@ public abstract class CairoXY : CairoGeneric
public virtual void Do(string font)
{
}
+
+ //encoderSignal (with inertial stuff & ! triggers at the moment)
+ public virtual void DoSendingList(string font, bool isInertial,
+ List<PointF> points_list, List<PointF> points_list_inertial,
+ bool forceRedraw, PlotTypes plotType)
+ {
+ }
+
+ //raceAnalyzer XY graphs (triggers)
public virtual void DoSendingList(string font, List<PointF> points_list, TriggerList triggerList,
bool forceRedraw, PlotTypes plotType)
{
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]