commit
cde090bf24
|
@ -1204,6 +1204,11 @@ async def backfill_bars(
|
||||||
https://github.com/pikers/piker/issues/128
|
https://github.com/pikers/piker/issues/128
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if platform.system() == 'Windows':
|
||||||
|
log.warning(
|
||||||
|
'Decreasing history query count to 4 since, windows...')
|
||||||
|
count = 4
|
||||||
|
|
||||||
out, fails = await get_bars(sym)
|
out, fails = await get_bars(sym)
|
||||||
|
|
||||||
if out is None:
|
if out is None:
|
||||||
|
|
|
@ -1054,7 +1054,7 @@ async def _emsd_main(
|
||||||
|
|
||||||
# signal to client that we're started and deliver
|
# signal to client that we're started and deliver
|
||||||
# all known pps and accounts for this ``brokerd``.
|
# all known pps and accounts for this ``brokerd``.
|
||||||
await ems_ctx.started((pp_msgs, relay.accounts))
|
await ems_ctx.started((pp_msgs, list(relay.accounts)))
|
||||||
|
|
||||||
# establish 2-way stream with requesting order-client and
|
# establish 2-way stream with requesting order-client and
|
||||||
# begin handling inbound order requests and updates
|
# begin handling inbound order requests and updates
|
||||||
|
|
|
@ -60,7 +60,7 @@ def repodir():
|
||||||
"""
|
"""
|
||||||
dirpath = os.path.abspath(
|
dirpath = os.path.abspath(
|
||||||
# we're 3 levels down in **this** module file
|
# we're 3 levels down in **this** module file
|
||||||
dirname(dirname(dirname(os.path.realpath(__file__))))
|
dirname(dirname(os.path.realpath(__file__)))
|
||||||
)
|
)
|
||||||
return dirpath
|
return dirpath
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ def load(
|
||||||
path = path or get_broker_conf_path()
|
path = path or get_broker_conf_path()
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
shutil.copyfile(
|
shutil.copyfile(
|
||||||
os.path.join(repodir(), 'data/brokers.toml'),
|
os.path.join(repodir(), 'config', 'brokers.toml'),
|
||||||
path,
|
path,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,9 @@ class GodWidget(QWidget):
|
||||||
# assigned in the startup func `_async_main()`
|
# assigned in the startup func `_async_main()`
|
||||||
self._root_n: trio.Nursery = None
|
self._root_n: trio.Nursery = None
|
||||||
|
|
||||||
|
self._widgets: dict[str, QWidget] = {}
|
||||||
|
self._resizing: bool = False
|
||||||
|
|
||||||
# def init_timeframes_ui(self):
|
# def init_timeframes_ui(self):
|
||||||
# self.tf_layout = QHBoxLayout()
|
# self.tf_layout = QHBoxLayout()
|
||||||
# self.tf_layout.setSpacing(0)
|
# self.tf_layout.setSpacing(0)
|
||||||
|
@ -259,7 +262,16 @@ class GodWidget(QWidget):
|
||||||
Where we do UX magic to make things not suck B)
|
Where we do UX magic to make things not suck B)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
log.debug('god widget resize')
|
if self._resizing:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._resizing = True
|
||||||
|
|
||||||
|
log.info('God widget resize')
|
||||||
|
for name, widget in self._widgets.items():
|
||||||
|
widget.on_resize()
|
||||||
|
|
||||||
|
self._resizing = False
|
||||||
|
|
||||||
|
|
||||||
class ChartnPane(QFrame):
|
class ChartnPane(QFrame):
|
||||||
|
|
|
@ -61,7 +61,9 @@ _do_overrides()
|
||||||
# XXX: pretty sure none of this shit works on linux as per:
|
# XXX: pretty sure none of this shit works on linux as per:
|
||||||
# https://bugreports.qt.io/browse/QTBUG-53022
|
# https://bugreports.qt.io/browse/QTBUG-53022
|
||||||
# it seems to work on windows.. no idea wtf is up.
|
# it seems to work on windows.. no idea wtf is up.
|
||||||
|
is_windows = False
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
|
is_windows = True
|
||||||
|
|
||||||
# Proper high DPI scaling is available in Qt >= 5.6.0. This attibute
|
# Proper high DPI scaling is available in Qt >= 5.6.0. This attibute
|
||||||
# must be set before creating the application
|
# must be set before creating the application
|
||||||
|
@ -182,6 +184,8 @@ def run_qtractor(
|
||||||
|
|
||||||
window.main_widget = main_widget
|
window.main_widget = main_widget
|
||||||
window.setCentralWidget(instance)
|
window.setCentralWidget(instance)
|
||||||
|
if is_windows:
|
||||||
|
window.configure_to_desktop()
|
||||||
|
|
||||||
# actually render to screen
|
# actually render to screen
|
||||||
window.show()
|
window.show()
|
||||||
|
|
|
@ -49,7 +49,6 @@ from PyQt5 import QtCore
|
||||||
from PyQt5 import QtWidgets
|
from PyQt5 import QtWidgets
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt,
|
Qt,
|
||||||
# QSize,
|
|
||||||
QModelIndex,
|
QModelIndex,
|
||||||
QItemSelectionModel,
|
QItemSelectionModel,
|
||||||
)
|
)
|
||||||
|
@ -126,6 +125,10 @@ class CompleterView(QTreeView):
|
||||||
# self.setSizeAdjustPolicy(QAbstractScrollArea.AdjustIgnored)
|
# self.setSizeAdjustPolicy(QAbstractScrollArea.AdjustIgnored)
|
||||||
|
|
||||||
# ux settings
|
# ux settings
|
||||||
|
self.setSizePolicy(
|
||||||
|
QtWidgets.QSizePolicy.Expanding,
|
||||||
|
QtWidgets.QSizePolicy.Expanding,
|
||||||
|
)
|
||||||
self.setItemsExpandable(True)
|
self.setItemsExpandable(True)
|
||||||
self.setExpandsOnDoubleClick(False)
|
self.setExpandsOnDoubleClick(False)
|
||||||
self.setAnimated(False)
|
self.setAnimated(False)
|
||||||
|
@ -153,23 +156,58 @@ class CompleterView(QTreeView):
|
||||||
|
|
||||||
self.setStyleSheet(f"font: {size}px")
|
self.setStyleSheet(f"font: {size}px")
|
||||||
|
|
||||||
def resize(self):
|
# def resizeEvent(self, event: 'QEvent') -> None:
|
||||||
|
# event.accept()
|
||||||
|
# super().resizeEvent(event)
|
||||||
|
|
||||||
|
def on_resize(self) -> None:
|
||||||
|
'''
|
||||||
|
Resize relay event from god.
|
||||||
|
|
||||||
|
'''
|
||||||
|
self.resize_to_results()
|
||||||
|
|
||||||
|
def resize_to_results(self):
|
||||||
model = self.model()
|
model = self.model()
|
||||||
cols = model.columnCount()
|
cols = model.columnCount()
|
||||||
|
# rows = model.rowCount()
|
||||||
|
|
||||||
|
col_w_tot = 0
|
||||||
for i in range(cols):
|
for i in range(cols):
|
||||||
self.resizeColumnToContents(i)
|
self.resizeColumnToContents(i)
|
||||||
|
col_w_tot += self.columnWidth(i)
|
||||||
|
|
||||||
# inclusive of search bar and header "rows" in pixel terms
|
win = self.window()
|
||||||
rows = 100
|
win_h = win.height()
|
||||||
# max_rows = 8 # 6 + search and headers
|
edit_h = self.parent().bar.height()
|
||||||
row_px = self.rowHeight(self.currentIndex())
|
sb_h = win.statusBar().height()
|
||||||
# print(f'font_h: {font_h}\n px_height: {px_height}')
|
|
||||||
|
|
||||||
# TODO: probably make this more general / less hacky
|
# TODO: probably make this more general / less hacky
|
||||||
self.setMinimumSize(self.width(), rows * row_px)
|
# we should figure out the exact number of rows to allow
|
||||||
self.setMaximumSize(self.width() + 10, rows * row_px)
|
# inclusive of search bar and header "rows", in pixel terms.
|
||||||
self.setFixedWidth(333)
|
# Eventually when we have an "info" widget below the results we
|
||||||
|
# will want space for it and likely terminating the results-view
|
||||||
|
# space **exactly on a row** would be ideal.
|
||||||
|
# if row_px > 0:
|
||||||
|
# rows = ceil(window_h / row_px) - 4
|
||||||
|
# else:
|
||||||
|
# rows = 16
|
||||||
|
# self.setFixedHeight(rows * row_px)
|
||||||
|
# self.resize(self.width(), rows * row_px)
|
||||||
|
|
||||||
|
# NOTE: if the heigh set here is **too large** then the resize
|
||||||
|
# event will perpetually trigger as the window causes some kind
|
||||||
|
# of recompute of callbacks.. so we have to ensure it's limited.
|
||||||
|
h = win_h - (edit_h + 1.666*sb_h)
|
||||||
|
assert h > 0
|
||||||
|
self.setFixedHeight(round(h))
|
||||||
|
|
||||||
|
# size to width of longest result seen thus far
|
||||||
|
# TODO: should we always dynamically scale to longest result?
|
||||||
|
if self.width() < col_w_tot:
|
||||||
|
self.setFixedWidth(col_w_tot)
|
||||||
|
|
||||||
|
self.update()
|
||||||
|
|
||||||
def is_selecting_d1(self) -> bool:
|
def is_selecting_d1(self) -> bool:
|
||||||
cidx = self.selectionModel().currentIndex()
|
cidx = self.selectionModel().currentIndex()
|
||||||
|
@ -218,7 +256,8 @@ class CompleterView(QTreeView):
|
||||||
idx: QModelIndex,
|
idx: QModelIndex,
|
||||||
|
|
||||||
) -> QStandardItem:
|
) -> QStandardItem:
|
||||||
'''Select and return the item at index ``idx``.
|
'''
|
||||||
|
Select and return the item at index ``idx``.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
sel = self.selectionModel()
|
sel = self.selectionModel()
|
||||||
|
@ -233,7 +272,8 @@ class CompleterView(QTreeView):
|
||||||
return model.itemFromIndex(idx)
|
return model.itemFromIndex(idx)
|
||||||
|
|
||||||
def select_first(self) -> QStandardItem:
|
def select_first(self) -> QStandardItem:
|
||||||
'''Select the first depth >= 2 entry from the completer tree and
|
'''
|
||||||
|
Select the first depth >= 2 entry from the completer tree and
|
||||||
return it's item.
|
return it's item.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -296,7 +336,8 @@ class CompleterView(QTreeView):
|
||||||
section: str,
|
section: str,
|
||||||
|
|
||||||
) -> Optional[QModelIndex]:
|
) -> Optional[QModelIndex]:
|
||||||
'''Find the *first* depth = 1 section matching ``section`` in
|
'''
|
||||||
|
Find the *first* depth = 1 section matching ``section`` in
|
||||||
the tree and return its index.
|
the tree and return its index.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -334,7 +375,7 @@ class CompleterView(QTreeView):
|
||||||
else:
|
else:
|
||||||
model.setItem(idx.row(), 1, QStandardItem())
|
model.setItem(idx.row(), 1, QStandardItem())
|
||||||
|
|
||||||
self.resize()
|
self.resize_to_results()
|
||||||
|
|
||||||
return idx
|
return idx
|
||||||
else:
|
else:
|
||||||
|
@ -405,7 +446,7 @@ class CompleterView(QTreeView):
|
||||||
|
|
||||||
def show_matches(self) -> None:
|
def show_matches(self) -> None:
|
||||||
self.show()
|
self.show()
|
||||||
self.resize()
|
self.resize_to_results()
|
||||||
|
|
||||||
|
|
||||||
class SearchBar(Edit):
|
class SearchBar(Edit):
|
||||||
|
@ -425,6 +466,7 @@ class SearchBar(Edit):
|
||||||
self.godwidget = godwidget
|
self.godwidget = godwidget
|
||||||
super().__init__(parent, **kwargs)
|
super().__init__(parent, **kwargs)
|
||||||
self.view: CompleterView = view
|
self.view: CompleterView = view
|
||||||
|
godwidget._widgets[view.mode_name] = view
|
||||||
|
|
||||||
def show(self) -> None:
|
def show(self) -> None:
|
||||||
super().show()
|
super().show()
|
||||||
|
@ -459,7 +501,7 @@ class SearchWidget(QtWidgets.QWidget):
|
||||||
# size it as we specify
|
# size it as we specify
|
||||||
self.setSizePolicy(
|
self.setSizePolicy(
|
||||||
QtWidgets.QSizePolicy.Fixed,
|
QtWidgets.QSizePolicy.Fixed,
|
||||||
QtWidgets.QSizePolicy.Fixed,
|
QtWidgets.QSizePolicy.Expanding,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.godwidget = godwidget
|
self.godwidget = godwidget
|
||||||
|
|
|
@ -22,6 +22,7 @@ import math
|
||||||
|
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
|
from PyQt5.QtCore import Qt, QCoreApplication
|
||||||
from qdarkstyle import DarkPalette
|
from qdarkstyle import DarkPalette
|
||||||
|
|
||||||
from ..log import get_logger
|
from ..log import get_logger
|
||||||
|
@ -121,6 +122,9 @@ class DpiAwareFont:
|
||||||
dpi = mn_dpi
|
dpi = mn_dpi
|
||||||
|
|
||||||
mult = 1.0
|
mult = 1.0
|
||||||
|
|
||||||
|
# No implicit DPI scaling was done by the DE so let's engage
|
||||||
|
# some hackery ad-hoc scaling shiat.
|
||||||
# dpi is likely somewhat scaled down so use slightly larger font size
|
# dpi is likely somewhat scaled down so use slightly larger font size
|
||||||
if scale >= 1.1 and self._font_size:
|
if scale >= 1.1 and self._font_size:
|
||||||
|
|
||||||
|
@ -135,6 +139,16 @@ class DpiAwareFont:
|
||||||
# relative aspect ratios or something?
|
# relative aspect ratios or something?
|
||||||
inches *= mult
|
inches *= mult
|
||||||
|
|
||||||
|
# XXX: if additionally we detect a known DE scaling factor we
|
||||||
|
# also scale *up* our font size on top of the existing
|
||||||
|
# heuristical (aka no clue why it works) scaling from the block
|
||||||
|
# above XD
|
||||||
|
if (
|
||||||
|
hasattr(Qt, 'AA_EnableHighDpiScaling')
|
||||||
|
and QCoreApplication.testAttribute(Qt.AA_EnableHighDpiScaling)
|
||||||
|
):
|
||||||
|
inches *= round(scale)
|
||||||
|
|
||||||
# TODO: we might want to fiddle with incrementing font size by
|
# TODO: we might want to fiddle with incrementing font size by
|
||||||
# +1 for the edge cases above. it seems doing it via scaling is
|
# +1 for the edge cases above. it seems doing it via scaling is
|
||||||
# always going to hit that error in range mapping from inches:
|
# always going to hit that error in range mapping from inches:
|
||||||
|
|
|
@ -153,8 +153,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
# XXX: for tiling wms this should scale
|
# XXX: for tiling wms this should scale
|
||||||
# with the alloted window size.
|
# with the alloted window size.
|
||||||
# TODO: detect for tiling and if untrue set some size?
|
# TODO: detect for tiling and if untrue set some size?
|
||||||
# size = (300, 500)
|
size = (300, 500)
|
||||||
size = (0, 0)
|
|
||||||
|
|
||||||
title = 'piker chart (ur symbol is loading bby)'
|
title = 'piker chart (ur symbol is loading bby)'
|
||||||
|
|
||||||
|
@ -165,6 +164,7 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
|
|
||||||
self._status_bar: QStatusBar = None
|
self._status_bar: QStatusBar = None
|
||||||
self._status_label: QLabel = None
|
self._status_label: QLabel = None
|
||||||
|
self._size: Optional[tuple[int, int]] = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mode_label(self) -> QtGui.QLabel:
|
def mode_label(self) -> QtGui.QLabel:
|
||||||
|
@ -269,6 +269,30 @@ class MainWindow(QtGui.QMainWindow):
|
||||||
assert screen, "Wow Qt is dumb as shit and has no screen..."
|
assert screen, "Wow Qt is dumb as shit and has no screen..."
|
||||||
return screen
|
return screen
|
||||||
|
|
||||||
|
def configure_to_desktop(
|
||||||
|
self,
|
||||||
|
size: Optional[tuple[int, int]] = None,
|
||||||
|
|
||||||
|
) -> None:
|
||||||
|
'''
|
||||||
|
Explicitly size the window dimensions (for stacked window
|
||||||
|
managers).
|
||||||
|
|
||||||
|
For tina systems (like windoze) try to do a sane window size on
|
||||||
|
startup.
|
||||||
|
|
||||||
|
'''
|
||||||
|
# https://stackoverflow.com/a/18975846
|
||||||
|
if not size and not self._size:
|
||||||
|
app = QtGui.QApplication.instance()
|
||||||
|
geo = self.current_screen().geometry()
|
||||||
|
h, w = geo.height(), geo.width()
|
||||||
|
self.setMaximumSize(w, h)
|
||||||
|
# use approx 1/3 of the area of the screen by default
|
||||||
|
self._size = round(w * .666), round(h * .666)
|
||||||
|
|
||||||
|
self.resize(*size or self._size)
|
||||||
|
|
||||||
|
|
||||||
# singleton app per actor
|
# singleton app per actor
|
||||||
_qt_win: QtGui.QMainWindow = None
|
_qt_win: QtGui.QMainWindow = None
|
||||||
|
|
|
@ -22,6 +22,7 @@ from contextlib import asynccontextmanager
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
import platform
|
||||||
import time
|
import time
|
||||||
from typing import Optional, Dict, Callable, Any
|
from typing import Optional, Dict, Callable, Any
|
||||||
import uuid
|
import uuid
|
||||||
|
@ -429,6 +430,9 @@ class OrderMode:
|
||||||
|
|
||||||
# TODO: make this not trash.
|
# TODO: make this not trash.
|
||||||
# XXX: linux only for now
|
# XXX: linux only for now
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
return
|
||||||
|
|
||||||
result = await trio.run_process(
|
result = await trio.run_process(
|
||||||
[
|
[
|
||||||
'notify-send',
|
'notify-send',
|
||||||
|
|
Loading…
Reference in New Issue