Commit graph

60 commits

Author SHA1 Message Date
Berthold Stoeger
9bca38afcf profile: recalculate profile info when switching from empty state
When the profile was to small, it would switch into empty state
and clear the plot info.

On resize events, the plot info is not recalculated.

This means that when making the profile extremely small and
then bigger, nothing is shown.

This may also happen on startup. The profile is rendered into
a 0x0 widget and then gets a resize event.

Therefore, remember when the profile is empty and force a
recalculation of the plot info.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-10-30 15:02:36 -07:00
Berthold Stoeger
7c8dc016b5 mobile: flip through dive computers on mobile
UI fixed by Dirk.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-10-01 18:47:16 +02:00
Berthold Stoeger
edf2a2f4f4 profile: implement panning of profile
When zoomed in, the profile position was moved by hovering with
the mouse. What a horrible user experience. This is especially
useless if we want to implement an interactive profile on mobile.

Instead, let the user start the panning with a mouse click. The
code is somewhat nasty, because the position is given as a
real in the [0,1] range, which represents all possible positions
from completely to the left to completely to the right.

This commit also removes the restriction that the planner handles
can only be moved when fully zoomed out. It is not completely
clear what the implications are. Let's see.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-09-03 13:51:00 -07:00
Vlad A
30a964c508 Added option to choose between different depth grid quantization schema.
This allows having 3m depth grid for metric users.

* All original properties ( named diferently ) were renamed to three_m_based_grid everywhere to be consistent.
* Plus other small changes requested during review.

Signed-off-by: Vlad A. <elf128@gmail.com>
Signed-off-by: Vlad A <elf128@gmail.com>
2022-05-21 17:29:40 -07:00
Berthold Stoeger
ada4632ff1 profile: remove last dc_number access from profile code
dc_number is a global variable indicating the currently displayed
dive on desktop. It makes no sense on mobile, since multiple
profiles can be active at the same time. Therefore, the profile
code should not access this global, but use the dc number that
is passed in.

This removes the last access.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-04-03 08:29:05 -07:00
Berthold Stoeger
b1384b286f cleanup: remove redundant get_dive_dc() calls
In ProfileScene::draw(), the divecomputer was calculated
thrice. Remove the two redundant calls.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-03-12 18:33:34 +01:00
Dirk Hohndel
cbad9607e8 cleanup: remove unused argument and private member
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2022-03-12 08:28:32 -08:00
Berthold Stoeger
e8698d615b profile: call plotProfile() with correct parameters in draw()
The signature of draw() was changed to include "keepPlotData"
as an optimization.

The caller in draw() was not changed and now the plot data
is not recalculated, which means no plot data at all in
prints and exports.

The various boolean parameters should be replaced by flags.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2022-01-20 15:45:51 +01:00
Berthold Stoeger
cf1ad3d831 profile: add space at bottom of temperature graph
The temperature graph connected directly to whatever was below.
Thus, the lowest temperature often was not clearly seen.

Add a general "bottom border" space to the main chart features
and set it to two pixels for the temperature and zero pixels
for the rest. Might need some fine-tuning.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
2645fa1495 profile: remove fast argument of create_plot_info_new()
This prevented calculation of the pressure data when dragging
planner handles. However, this lead to weird artifacts.

As an alternative, if this turns out to be too slow, we might
disable the plotting of the pressure curves instead.

That said, even on my super-slow fanless laptop, this performs
reasonably.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
352cdcc863 profile: fix crosshairs
In planner and edit mode, the cursor position is indicated using
crosshairs. They broke when changing to absolute scaling.

To fix them, remember the plot-area in the profile scene and
draw the crosshairs only inside this area (not on top of axes).
However, limit the position of the horizontal line to the
actual profile (dont paint inside the partial pressure, etc
graphs). The vertical line is painted above those graphs, so
that a timestamp can be related to partial pressure, tissue
loading, etc.

Also, set the z-value of the crosshairs. It was painted
inconsistently above some and below other chart features.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
de71435c11 profile: clear the chart when there is nothing to display
This is a shouldn't happen situation, because we always
fake a profile. Let's handle it gracefully anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
ecd3334a1c profile: when clearing the profile, also reset the profile data
When hovering over the chart after the chart was cleared,
there were artifacts owing to the stale profile data.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
7aacde3169 profile: remove ProfileScene::dataModel
All data access is now directly via the plot_info structure
owned by the ProfileScene itself.

Also removes DivePercentageItem::hColumn, which was an
artifact from the DivePlotDataModel.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
bdbcb1b7e3 profile: access the ProfileScene's plot_info
There were two plot_infos of the same dive: one owned by
ProfileScene and one owned by DivePlotDataModel. The latter
was (or at least should have been) a copy of the former.

Simply always access the plot-info which is owned by
ProfileScene anyway. That seems much less brittle. Why
risk some desyncing?

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
6f2965c5af profile: access profile data directly
The profile was using a Qt-model to access its data. This means
routing everything through Qt's QVariants and lead to verbose
code such as

double prev_y = dataModel.index(i-1, vDataColumn).data().toReal();

Instead of storing a data-column and do access via a template,
simply store accessor functions. The code from above now reads as

double prev_y = accessor(data[i-1]);

This should also be distinctly faster for the ns-optimizers among
us.

Only one case was somewhat nasty to convert: The accessors for
the 16 tissues are now generated via a recursive template. Thanks
to C++17's constexpr if, such a template is pleasantly easy
to follow, though.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
6fa5e59994 profile: remove AbstractProfilePolygonItem::hDataColumn
This indicated the data of the horizontal axis. It was (obviously)
always the time axis. Remove.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
e0f44237cc profile: move max_gas() from DivePlotDataModel to ProfileScene
There is only one user of this - let's remove complex
interdependencies.

Note: there seem to be two independent plot_infos: in the
ProfileScene and in the DivePlotDataModel. To avoid behavioral
change, this keeps using the DivePlotDataModel's version.
In any case, this has to be unified.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
5c5c0c4880 profile: redo animation of labels and grid lines
The old animation was weird: it would reuse the labels
based on the index, not on the value. Thus, with the
new scaling code, sometimes there was no animation at all,
if the value, but not the position changed.

Consider the values instead and let labels appear/disappear.
This makes things slightly more complex.

While changing this code, create our own animation-class.
Thus, we can avoid having the dive axes being QObjects.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
176a62f752 profile: improve calculation of the right border
The time axis might need some space and the average depth item
puts a formatted depth at to right of the profile. Consider
these when calculating the right border.

Since I found no way to turn of the average depth, this creates
a permanent border, which might or might not be a good thing.

Contains some refactoring of the label-size functions provided
by DiveTextItem.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
210660d057 profile: rewrite ProfileScene::pointOnProfile()
This function was used to check wether a screen-point
is located on the profile. Bizzarely, this was done by
transforming into local coordinates and checking
min/max value. Simply check the screen coordinates
directly. Moreover, make the function return whether
the point is inside the region, not outside the region,
to make logic more straight forward.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
71629521b7 profile: don't recalculate plot-info when zooming / scrolling
This is a potentially expensive operation (e.g. interpolation of
pressure values), so don't recalculate the plot data for every
redraw.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
5c83fcd647 profile: attempt to port mobile-visibility code
There was a bunch of conditionally compiled code on mobile
that had special hiding/unhiding rules.

Try to unify that with the desktop code by introducing a
"simplified" flag. This certainly breaks and will have to
be finetuned. In particular, I can't test CCR dives, which
are treated specially on mobile.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
1a429d9b17 profile: don't plot event-icons outside of range
Do this by extending the isInteresting() function for
dive event items.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
85d1e1d199 profile: only plot visible range of tank info
This was a rather trivial change: simply pass in the first
and the last second to the plot function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
118700fd18 profile: pass [from,to] range to polygon plotting functions
Only plot the zoomed range. Currently this passes the sample
before and after the range, so it generally "overshoots" by
one sample in each direction. The plan is to do clipping
on the first and last polygon segment later on.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
c09382036f profile: don't use scene for zooming
We were using the QGraphicsScene machinery to zoom into the
plot. This not only zoomed into the dive, but into the whole
thing. In general, one couldn't see the axes anymore.

Instead, adjust the range of the time-axis according to the
zoom-level and position.

Of course, the code isn't adapted to that and the result
is comical. The chart features will have to be fixed
one-by-one. Oh joy.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
2f9c0c04b5 profile: replace orientation by inverted flag
There were two somewhat redundant flags for the axes: the position
(left, right, bottom) and the orientation (up-down, left-right, etc).

Replace the latter by an inverted flag: if true, the axis is
up-down or right-left, i.e. the opposite of what one would expect
for a normal graph.

Set the flag in the constructor and remove the setOrientation()
function.

Sadly, the code is a bit complex, because screen coordinates are
top-to-bottom. Who thought that would be a good idea?

Note: this also fixes the placement of the ticks of the time
axis.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
3a79f3e78a profile: set textColor in constructor of DiveCartesianAxis
There were virtual functions to calculate the label colors
based on the value of the label. However, these functions
only returned constant values. Therefore, just set these
in the constructors.

Thuse, a few virtual functions and derived classes can be
removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
7bc90b6dfe profile: set visibility of text and lines in constructor
The visibility of axis text / lines is never changed, so set
in axis constructor.

Moreover, instead of rendering the lines/text and then setting
them invisible, do not render them if invisible.

The whole thing appears superfluous, since the proper way to
not show lines/text is to just not call updateTicks on the
axis. But in the future we might want to have axes with text
but no lines, so keep for now.

Since this means breaking out the text / line rendering
into their own function, we might rename some variables to
make them (at least somewhat) more clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
99c4741508 profile: avoid double recalculation of tick positions
The ticks were recalculated twice per plotDive() call:
1) When updating the position of the axes in updateChangeLine()
2) After setting the bounds in plotDive() via setBounds()

Remove the first instance. updateChangeLine() is called in
only one place [from plotDive()] and therefore, the recalculation
is always redundant. Moreover, rename the function to setPosition(),
since it doesn't do any animation at all.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
2c4e4b1e86 profile: move setting of gasYAxis bounds to plotDive()
The partial-pressure-axis was the only DiveCartesianAxis
child that had its own code to set the bounds. The bounds
of all other axes were set in plotDive().

For consistency, do this here as well. Thus, the whole
class can be removed.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
0de40a85b7 profile: generalize tick generation
The number of ticks was generated for each axis with custom
code. This code was not aware of the size of the profile and
could result in overly dense or sparse ticks.

Generalize the generation of the ticks. For now, round tick
values to integers. In the future, try to use more "nice"
looking values as we do for the statistics tab.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
177df72d33 profile: unify formating of axis labels
Instead of a host of virtual functions, let the base class
(DiveCartesianAxis) do the formatting of the axis labels.
To do so, it needs to know how to convert the internal
representation (e.g. mm) into the displayed value (e.g. feet).
Moreover, this transformation has to be adapted when changing
the locale-setting, therefore do it for every plot() call.

The transformation itself cannot be a simple linear translation,
because we have non-absolute display units, namely °C and °F.
Thankfully affine transformations are enough though.

Only one custom formatter remains: the time axis. It might
be a good idea to remove the virtual function and do this
via a flag.

This is all done not so much for code simplification, but
because for a general layout of the axis labels, the
axis has to understand the values of the labels and not
only handle them as opaque texts.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
322e2baa8d profile: calculate maximum label sizes on construction
Instead of calculating the label sizes of the axes when
relayouting the chart, calculate them at construction time.

To do so, pass the digits before and after the decimal comma
to the constructor.

This is not so much an optimization thing, but rather an
first stab at more general label rendering. Time, of course,
will always be an exception. But hopefully the remaining
values can be done more generally.

Note that currently this code is a total mess. For example,
the labels for the temperature axes are not converted to
F if needed. And therefore also not shown. This will need
some major rethinking.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
f19ab2e4fd profile: set DiveCartesianAxis::fontLabelScale in constructor
This never changes, no need for the complexities of a setter
function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
89d9105209 profile: set minimum/maximum of axes with a single call
This is bike-shedding: Instead of two setMinimum()/setMaximum()
calls, use a single setBounds() call. A few axes (notably depth
and time) always have a 0 as lower bound. However, this will
change once there is a proper zooming functionality.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
0bef8167d2 profile: always update axis-positions when plotting dive
The placement of the axes was done independently of the
plotting, e.g. when settings changed. Presumably,
for performance reasons. However, since the axes may
depend on whether a dive has heart-rate data or not,
this simply is not viable. To make this work, one
would have to remember whether the previous dive
showed the heart-rate, etc. Not worth it - always
reposition the axes. It should not matte performance-
wise.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
a031f3444c profile: make DiveCartesian axis grayscale aware
I doubt that this is necessary, but since most of the rest
of the profile code passes "isGrayscale" to "getColor()",
do the same here for consistency.

To avoid storing the isGrayscale flag, just create the pens
at construction time and store those.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
ae1758d4cd profile: don't render mobile profile in printmode
There is no more reason to render the profile in printMode.
DPR is also supported in normal mode.

Moreover, don't scale the DPR down by fontScale. If we
have to scale down the fonts, we'll have to do this
differently without squeezing the rest of the profile
features.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
9740651e01 profile: save depth of event
The DivePlotDataModel was saved with every event to access the
depth. However, since the depth never changes, we can simply
save the depth instead.

Also, since we only need the model to access the plot_info,
pass the plot_info directly. As noted in a previous commit
message, I believe that Qt models are a very bad choice
for intra-application data transfer. They should only ever
be used to interface with Qt.

And since touching this code, pass duration_t instead of int
to depthAtTime() to make the callers less cluttered.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
8a9ca5fcda profile: don't create "uninteresting" event icons
There is code to dynamically show/hide event icons of a certain
type. The same code is used to hide generally non-interesting/
redundant items.

Instead, don't even create these items. Yes, this is idle
premature optimization.

A loop over all created event icons to hide them can be
removed, because the icon is hidden anyway on construction
time.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
f82ae2be7f profile: cache pixmaps for dive event items
For better scalability, we might replace the dive event icons
by SVGs. Since rendering SVGs is potentially very slow, cache
the pixmaps when the scene is generated.

Note: this does not yet do any SVG rendering, only the caching
of pixmaps.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
505e4e47eb profile: reimplement DivePercentageItem
The tissue percentages were realized as 16 independent polygons.
That didn't work at all with the new absolute scaling.

Reimplement the item and blast it onto a pixmap. Not only is
this artifact-free, it also should (hopefully) be quite a bit
more efficient than painting numerous lines.

In contrast to the old code, this does access the plot_info
structure directly instead of using the model. Not so much
for performance reason, but rather to make things more robust:
We have a strongly typed language. Why would we shoehorn data
through the weakly typed QVariant and mess with wierd
index-arithmetics. Makes no sense to me. Qt-model have to
be used for interfacing with Qt. They are terrible for
intra-application data transfer.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
179df1bf80 profile: remove DiveCartesianAxis::tick_size
No user of that. Also remove the setter function.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
8046a05e95 profile: merge plotDive() into draw() call
Rendering resets the size, which now recalculates the axes.
Therefore, plotDive() must be called. The callers were doing
the opposite: call plotDive() first, then draw().

To make it easier for the callers, present a single interface
that handles these subtleties.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
d0beae59f9 profile: start with "absolutizing" the profile layout
The chart items were laid out in relative terms with respect
to a fixed scene size (100.0, 100.0). This simply does not
cut it when resizing the chart. Why should the axes always
occupy the same fraction of the chart independent of the size.

Moreover, this led to basically unmaintainable code.

Resize the scene according to the viewport and do
absolute placement of the items. This breaks the layout,
but at least now we have a chance to fix things
somewhat reasonably.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
41c23dcb22 profile: remove color parameter of DiveCartesianAxis::updateTicks()
The grid color is saved on construction, no need to pass a parameter.
Note that this fixes a bug where the color was passed as animation
speed. Ooops. That's what you get from weak typing.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
277b9234ab profile: pass position and gridColor on construction of axes
This is less hassle, than passing these around as parameters.
Note: The values are stored but not yet used ("position" has
not use yet and gridColor is still passed as parameter).

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00
Berthold Stoeger
04e0d96bae profile: set text and brush of DiveTextItem concurrently
The text and the brush are the two properties of text items
that change dynamically. To avoid complexities concerning
redrawing, set them concurrently instead of in two separate
calls.

Since setting one of the properties requires a full redraw,
there is no performance advantage in setting them individually.

This fixes a theoretical bug: the colors of axis labels were not
updated appropriately. However, it seems like value-dependent
labels weren't used anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2021-12-17 11:54:23 -08:00