For some reason (use of OpenGL?) with Qt6 these modes fail for me.
Needless to say, I consider this API change a very unfriendly
behavior.
Replace these modes by DrawTriangleStrip and DrawLineStrip.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Scatter items of selected dives were shown in blue when
changing to scatter mode. They should be yellow from the
start, not only when hovering over them.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
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>
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>
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>
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>
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>
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>
Since there are no disk-segment QSG primitives (one could draw
a triangle fan, but that doesn't seem optimal), this draws
into a pixmap and blits that as a QSG node.
Since this is the only series without axis, it needs a function
that returns the size of the plot area. This didn't exist, so
add it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The original plan to reuse the ChartPixmapItem for the
scatteritems was dumped, because it is unclear if the
textures are shared if generated for each item.
Instead, a new ChartScatterItem was created, where all
items share the same textures (one for highlighted,
one for non-highlighted). This means that the rendering
of the scatter items is now done in the chartitem.cpp
file, which feels like a layering violation. Not good,
but the easiest for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is lazy: Derive from the bar chart item and add whiskers
in the subclassed render() function. The code is ugly, because
the base class function clears the dirty flags and therefore
the derived class has to remember them. Oh well.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To replace the QGraphicsScene, we need the possibility of
showing and hiding items.
Turns out, the QSG API is completely insane.
Whether an item should be shown is queried by the virtual
function isSubtreeBlocked(), which is supposed to be
overriden by the derived classes.
However, the common nodes for rectangles and pixmaps are
supposed to be created by QQuickWindow, for hardware
optimization. This gives nodes that cannot be derived
from and therefore whether the item is shown or not cannot
be controlled.
There are therefore two distinct cases to consider: The
node is allocated by the code directly or indirectly by
QQuickWindow.
In the latter case, we use a proxy node with the only
purpose of having a "visible" flag and add the obtained
node as a child.
This madness is performed with template trickery to get
unified code.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
To this end, two new ChartItems were added: A "bar" (a rectangle
with a border) and a "text" (multiple lines of text).
It turns out that the text on the bars now looks atrocious.
The reason appears to be that the antialiasing of the font-rendering
does not blend into the alpha channel, but into a supposed
background color? This will have to be investigated.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
So far the items to be recalculated in the drawing thread
had a "dirty" flag and were kept in one array par z-level.
Once the series are implemented in terms of QSGNodes, there
may lots of these items. To make this more efficient when
only one or two of these items change (e.g. highlighting due
to mouseover), keep the dirty items in a linked list.
Of course, this makes the draw first version of the chart
less efficient.
There are more fancy ways of implementing the double-linked
list, but the few ns gained in the render thread are hardly
worth it.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Slowly converting the QGraphicsScene items to QSGNodes to
avoid full replot of the scene.
This adds a new abstraction for line-nodes. Since the render()
function here is fundamentally different from the pixmap-nodes
we had so far, this has to be made virtual.
Also, move the quartile markers to their own source file,
since the StatsView source file is quite huge already.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The chart items were drawn in order of creation. To control this,
add a notion of Z-value. In contrast to QGraphicsScene, make
this a small integer value.
To controll order of drawing, a plain QSGNode is created for
every possible Z-Value and items are added to these nodes.
Thus, items are rendered by Z-value and if the Z-value is equal
by order of creation.
Likewise split the list of chart-items into Z-values, so that
items can be quickly unregistered: The items that will be
removed individually will usuall be part of Z-levels with only
few items (e.g. legend, infobox). Z-levels with many items
(notably the series) will always be fully rebuilt.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In order not to waste CPU by constantly rerendering the chart,
we must use these weird OpenGL QSGNode things. The interface
is appallingly low-level and unfriendly.
As a first test, try to convert the legend. Create a wrapper
class that represents a rectangular item with a texture
and that will certainly need some (lots of) optimization.
Make sure that all low-level QSG-objects are only accessed
in the rendering thread. This means that the wrapper has
to maintain a notion of "dirtiness" of the state. I.e.
which part of the QSG-objects have to be modified.
From the low-level wrapper derive a class that draws a rounded
rectangle for every resize. The child class of that must then
paint on the rectangle after every resize.
That looks all not very fortunate, but it displays a
legend and will make it possible to move the legend
without and drawing operations, only shifting around
an OpenGL surface.
The render thread goes through all chart-items and
rerenders them if dirty. Currently, on deletion
of these items, this list is not reset. I.e. currently
it is not supported to remove individual items.
Only the full scene can be cleared!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>