Fix pp arrow/label placement bugs

- Every time a symbol is switched on chart we need to wait until the
  search bar sidepane has been added beside the slow chart before
  determining the offset for the pp line's arrow/labels; trigger this in
  `GodWidget.load_symbol()` -> required monkeypatching on a
  `.mode: OrderMode` to the `.rt_linked` for now..
- Drop the search pane widget removal from the current linked chart,
  seems faster?
- On the slow chart override the `LevelMarker.scene_x()` callback to
  adjust for the case where no L1 labels are shown beside the y-axis.
history_view
Tyler Goodlet 2022-09-13 17:46:50 -04:00
parent 44c6f6dfda
commit e492e9ca0c
3 changed files with 58 additions and 14 deletions

View File

@ -208,15 +208,15 @@ class GodWidget(QWidget):
if not self.vbox.isEmpty():
qframe = self.hist_linked.chart.qframe
if qframe.sidepane is self.search:
qframe.hbox.removeWidget(self.search)
# XXX: seems to make switching slower?
# qframe = self.hist_linked.chart.qframe
# if qframe.sidepane is self.search:
# qframe.hbox.removeWidget(self.search)
for linked in [self.rt_linked, self.hist_linked]:
# XXX: this is CRITICAL especially with pixel buffer caching
linked.hide()
linked.unfocus()
# self.hist_linked.unfocus()
# XXX: pretty sure we don't need this
# remove any existing plots?
@ -271,12 +271,8 @@ class GodWidget(QWidget):
linked.graphics_cycle()
await trio.sleep(0)
# XXX: since the pp config is a singleton widget we have to
# also switch it over to the new chart's interal-layout
# linked.chart.qframe.hbox.removeWidget(self.pp_pane)
chart = linked.chart
# resume feeds *after* rendering chart view asap
chart = linked.chart
if chart:
chart.resume_all_feeds()
@ -284,7 +280,7 @@ class GodWidget(QWidget):
# last had the xlast in view, if so then shift so it's
# still in view, if the user was viewing history then
# do nothing yah?
chart.default_view()
# chart.default_view()
# if a history chart instance is already up then
# set the search widget as its sidepane.
@ -292,6 +288,15 @@ class GodWidget(QWidget):
if hist_chart:
hist_chart.qframe.set_sidepane(self.search)
# NOTE: this is really stupid/hard to follow.
# we have to reposition the active position nav
# **AFTER** applying the search bar as a sidepane
# to the newly switched to symbol.
await trio.sleep(0)
pp_nav = self.rt_linked.mode.current_pp.nav
pp_nav.show()
pp_nav.hide_info()
# set window titlebar info
symbol = self.rt_linked.symbol
if symbol is not None:

View File

@ -55,7 +55,10 @@ from ._forms import (
FieldsForm,
mk_order_pane_layout,
)
from .order_mode import open_order_mode
from .order_mode import (
open_order_mode,
OrderMode,
)
from .._profile import (
pg_profile_enabled,
ms_slower_then,
@ -1031,18 +1034,21 @@ async def display_symbol_data(
godwidget.resize_all()
mode: OrderMode
async with (
open_order_mode(
feed,
godwidget,
fqsn,
order_mode_started
)
) as mode
):
if not vlm_chart:
# trigger another view reset if no sub-chart
chart.default_view()
rt_linked.mode = mode
# let Qt run to render all widgets and make sure the
# sidepanes line up vertically.
await trio.sleep(0)

View File

@ -405,7 +405,7 @@ class SettingsPane:
self.pnl_label.format(pnl=pnl_value)
def position_line(
def pp_line(
chart: ChartPlotWidget, # noqa
size: float,
@ -461,6 +461,9 @@ def position_line(
marker.update()
marker.show()
line._marker = marker
line.track_marker_pos = True
# show position marker on view "edge" when out of view
vb = line.getViewBox()
vb.sigRangeChanged.connect(marker.position_in_view)
@ -548,7 +551,7 @@ class Nav(Struct):
# create and show a pp line if none yet exists
if line is None:
arrow = self.level_markers[key]
line = position_line(
line = pp_line(
chart=chart,
level=price,
size=size,
@ -634,6 +637,18 @@ class Nav(Struct):
# labels
level_marker.show()
# NOTE: be sure to re-trigger arrow/label placement in case
# a new sidepane or other widget (like the search bar) was
# dynamically swapped into the chart-row-widget-space in
# which case we want to reposition in the view but including
# the new x-distance added by that sidepane. See details in
# ``LevelMarker.position_in_view()`` but more less ``.
# ``ChartPlotWidget.self.marker_right_points()`` gets called
# which itself eventually calls `.getAxis.pos().x()` and
# it's THIS that needs to be called **AFTER** the sidepane
# has been added..
level_marker.position_in_view()
pp_label.show()
size_label.show()
@ -767,6 +782,24 @@ class PositionTracker:
level=nav.level,
on_paint=nav.update_graphics,
)
# TODO: we really need some kinda "spacing" manager for all
# this stuff...
def offset_from_yaxis() -> float:
'''
If no L1 labels are present beside the x-axis place
the line label offset from the y-axis just enough to avoid
label overlap with any sticky labels.
'''
x = chart.marker_right_points()[1]
if chart._max_l1_line_len == 0:
mkw = pp_label.txt.boundingRect().width()
x -= 1.5 * mkw
return x
arrow.scene_x = offset_from_yaxis
arrow.hide() # never show on startup
view.scene().addItem(arrow)
nav.level_markers[key] = arrow