Move the various font objects the the StatsTheme structure to enable
different font weights for different themes.
For the dark theme, switch to a bold font, because the thin white
font was barely visible.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Create the themes only when needed (singleton pattern). If
the themes should do more than colors, such as for example
fonts, it is not clear whether that can be done before main()
runs. By creating the themes on demand, the Qt UI should
be initialized in the constructors of the themes.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Some of the colors (like the bin colors or the highlight yellow) stay
the same, others are adjusted to fit better with a dark background.
This is far from perfect, but it's ok-ish.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
To enable rudimentary theming, collect all colors in a new
theme class. The class has to be passed down to the various
items.
In general the items save a reference to the them in the
constructor. Alternatively, they might also just query
the StatsView everytime they need to access a color.
For now, it's hard the say what is preferred: a reference
per item or a function call per invokation?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These were leaking. Instead register them as global objects,
so they will be deleted on exit.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
With Qt the forward declaration fails as the export to QML for the statistics requires
the MOC code to be able to determine the sizeof(struct dive).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
A member function had a minute name change.
The SceneGraphBackend is now set via a string argument, not a magic constant.
Thankfully that appears to be backwards compatible.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We do want the -Wfloat-conversion warnings where they point out
potential bugs. But they are very distracting when they are triggered by
floating point literals (which the standard defines as double) passed to
a function expecting float arguments.
The fact that Qt6 changes the arguments to all these functions from
double to float is... hard to explain, but it is what it is. With these
changes, for the majority of cases we create inlined helpers that
conditionally compile to do the right thing. And in a handful of other
cases we simply cast to float (and accept that on Qt5 this then gets
cast back to double... for none of these cases the potential loss in
precision makes any difference, anyway - which likely is why the Qt
community made the decision to change the type of the arguments in the
first place).
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In general, replace "dive master" by "dive guide".
However, do not change written dive logs for now. On reading,
accept both versions.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This was a user request: Sort bar charts by height of the bars.
Obviously, this can only work for categorical charts, not for
histograms.
The UI is a break from the old concept: the sorting is chosen
based on the chart, whereas for the rest of the features, the
viable charts are presented based on the binning, etc.
I found it confusing to have the possible charts be selected
based on sorting. I.e. if a non-bin sort mode is selected,
the histogram charts disappear. On the flip side, this would
be more consistent. We can change it later.
For value-based bar charts, there are three sort modes: by
bin, by count (i.e. number of dives in that bar) and by
value (i.e. length of the bar). This hopefully satisfies all
needs.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We have a dive-site variable, therefore we probably should also
have a dive-trip variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
'constexpr' implies 'const' since it is a stronger guarantee,
so let's remove the redundant 'const'.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
And while doing that, have all the cases where we already include
qthelper.h simply use a define in that header file - but keep the two
other instances of the define where the C++ source don't need qthelper.h
otherwise.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Air is a special gas that does not contain oxygen according
to gasmix.o2.fraction. If you want to use the fo2, you
need to use get_o2() to treat this special case correctly.
This fixes a bug when setting the MND of a gas containing
21% oxygen when o2 is considered not narcotic.
Reported-by: Christoph Gruen <gruen.christoph@gmail.com>
Signed-off-by: Robert C. Helling <helling@atdotde.de>
This silences a Coverity warning. In principle, this should
never happen, since there are no slices if totalCount is 0.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This silences a Coverity warning. That what harmless, but
it's probably good practice to initialize all members.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Allow the user to restrict the analyzed dives based on the
current selection. One button restricts to the current selection
and one button resets the restriction.
Thus, the user can for example select bars in the bar chart
or a range in the scatter plot and perform statistics on
these sets.
The restriction works on top of the filter.
The UI can certainly be improved, but it is a start.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
For all the series but the scatter series (which supports
lasso selection), implement a range-selection using shift.
The code is fairly similar for all series and one might
think about factoring it out. But why bother?
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Multiple selection using ctrl was only supported for
scatter series. Factor out the corresponding code and
use it in all series.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Up to now, we passed a "shiftPressed" flag to the individual
selection functions. To be more general replace by a struct
with "shift" and "ctrl" flags.
While doing this:
1) Move the struct into a new statsselection file for better
encapsulation.
2) Change shift to control in the scatter series, since individual
selection of items is usually done with control, not shift.
Shift usually means "select range".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In analogy to the other charts, highlight selected pie slices.
Overlay them with a checkerboard pattern, like in the bar charts.
Since all charts now support highlighting, the divesSelected()
virtual function now doesn't need a default implementation
anymore.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This flag existed for historical reasons: The base of bar items
had no line and therefore the lines had to be draw differently
for horizontal (base to the left) and vertical (base on the bottom)
item.
This did not work properly and therefore has been removed. Thus,
the flag became pointless.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When all items of a bar in a bar chart are selected, highlight them
by overlaying with a checkerboard pattern. A gray checkerboard seems to
work reasonably well, regardless of base color.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Allow the user to select regions of the scatter plot using
a rectangular selection. When shift is pressed, do an
incremental selection.
Unfortunately, the list-selection code is so slow that this
becomes unusable for a large number of selected dives.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Somewhat improve selection mechanics in the scatter-plot by
allowing additional selections with shift-clicking. When the
dives under the mouse are already selected, then deselect them.
This appears to be a rather common UI idiom in desktop
applications.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
As a visual feedback, show the selected dives in the scatter
plot. React to application-wide selection changes. Currently,
the dive list is deactivated while in statistics mode, but
that may change.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When clicking on items in a plot, select the corresponding
dives. This can be useful for data validation.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It is crucial to replot the statistics when dives are
added / removed, to avoid stale pointers.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To make box-and-whiskers charts selectable (select corresponding
dives when clicking on box), save the dive list with the quartile
data.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
If we want to make bar charts selectable (when clicking on a
bar select the dives the bar represents), then we must store
the dives behind bars. Therefore, use dive-based bins instead
of count based bins in bar charts and pie charts. This gave
some churn because every structure where a count is stored
has to be changed to store a vector of dives. Try to use
move semantics where possible to avoid duplication of dive
lists.
On a positive note, the count_dives() function of the
binners can now be removed, since it is unused.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The subtraction of half the label width, needed for centered
labels, must have been lost somewhere.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Placing labels at half-integer values gives horrible
rendering artifacts. Therefore, always round to integer
values. The easiest way to do this is right before setting
the position. Introduce a helper function to round QPointF
in such scenarios.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
When reparenting the statistics widget, QtQuick deletes
the rootNode and all the child nodes. It is unclear whether
this is a bug or intended behavior. In any case, it means
that the pointers to QSG nodes in the chart items become
stale.
To avoid this, delete all chart items in the root node's
destructor, before QtQuick can do anything. It is unclear
from which context this is called (render or UI) and whether
this is even valid. In some tests, it seemed to work.
The difficulty is that all the stale pointers to chart items
have to be deleted as well. All in all, the QSG memory
management is a big nuisance and very brittle.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The updatePaintNode() function, which is run on the render
thread detected a geometry change and initiated recalculation
of the chart layout.
This means that plotAreaChanged() was called in two different
thread contexts, which is questionable. Instead, hook into
the geometryChanged() function and recalculate the chart items
there.
This fixes a rendering bug, because the old code would first
delete unneeded items and then rerender the chart. Thus, old
grid and tick items were still visible.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
While this didn't appear to be needed when dragging the legend with a
mouse, on a touch screen for some reason the drag ended after 30 pixels
either way horizontally (but no apparent limit vertically). By setting
this flag to true, drags on a tablet appear to work as expected.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The labels in bar an pie charts are realized as individual
QSG pixmap nodes with an alpha channel. Sadly, rendering
bright labels onto a transparent background gives very
ugly artifacts.
As a stop gap measure, until the problem is understood,
render on a background with the color of the pie slice
or bar.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Most colors were already collected there, but a few were dispersed
throughout the source files.
For future themeability, move the remaining colors to this common
place.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is not perfect - the polygon of the confidence area is
calculated even if it is not shown. Oh well.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Up to now, when the user changed the visibility of chart features
(legend, quartiles, labels, etc.) the whole chart was replot.
Instead, only change the visibility status of these items.
After all, this modularity is one of the things the conversion
to QSG was all about.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The scatter plot items shared their textures. These were
std::unique_ptrs and cleaned up on exit. Owing to QSG's
broken memory model, freeing the textures after QApplication
terminated its threads led to crashes. Therefore, leak the
textures. Not satisfying, but ultimately harmless and better
than a crash.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Fix a bug that was fixed in b5c8d0dbb4 and reintroduced in
e7907c494f. Here is the original commit message:
The range for a one-bin chart is [-0.5,0.5], thus the range
in an n-bin chart is [-0.5,n-0.5], not [-0.5,n+0.5].
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The code was wrong, because it deleted the ChartItems in the
main UI thread, not the render thread. This would delete the
QSG nodes in the UI thread and then crash on mobile.
Therefore refactor this part of the code by adding the
items to be deleted to a list that will be deleted by the
render thread.
As a drop in replacement of std::unique_ptr, implement
a silly ChartItemPtr class, which auto-initializes to null.
This turns the deterministic and easily controlled memory
management into a steaming pile of insanity. Obviously,
this can be made much more elegant, but this has to do for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>