From 3fd7107e08d55a8b856b1f12d564d8c1159520c5 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Mon, 12 Sep 2022 09:58:11 -0400 Subject: [PATCH] Scale view to measured results row count In other words instead of some static view size previously determined by the accompanying (slow) chart's height, (recursively) calculate the number of displayed rows and compute the minimal height needed. This still caps the view at the height of the chart such that the view will switch to scroll bar mode when too many results are shown and can't all be fit in the vertical space. Deats: - add a ``CompleterView.iter_df_rows()`` which recursively iterates all rows in depth-first order making it simple to compute the absolute number of result rows in view and thus the minimal number of pixels to show all results. - always pass the height in the `.on_resize()` handler to ensure triggering the height logic when new results are generated in the search loop. --- piker/ui/_search.py | 66 +++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/piker/ui/_search.py b/piker/ui/_search.py index db8b1729..a9557b7b 100644 --- a/piker/ui/_search.py +++ b/piker/ui/_search.py @@ -35,9 +35,13 @@ from collections import defaultdict from contextlib import asynccontextmanager from functools import partial from typing import ( - Optional, Callable, - Awaitable, Sequence, - Any, AsyncIterator + Optional, + Callable, + Awaitable, + Sequence, + Any, + AsyncIterator, + Iterator, ) import time # from pprint import pformat @@ -119,7 +123,7 @@ class CompleterView(QTreeView): # TODO: size this based on DPI font self.setIndentation(_font.px_size) - # self.setUniformRowHeights(True) + self.setUniformRowHeights(True) # self.setColumnWidth(0, 3) # self.setVerticalBarPolicy(Qt.ScrollBarAlwaysOff) # self.setSizeAdjustPolicy(QAbstractScrollArea.AdjustIgnored) @@ -166,11 +170,15 @@ class CompleterView(QTreeView): ) -> None: model = self.model() cols = model.columnCount() - - # rows = model.rowCount() cidx = self.selectionModel().currentIndex() - row_h = self.rowHeight(cidx) - # print(f'row_h: {row_h}') + rows = model.rowCount() + self.expandAll() + + row_h = rows_h = self.rowHeight(cidx) * rows + for idx, item in self.iter_df_rows(): + row_h = self.rowHeight(idx) + rows_h += row_h + # print(f'row_h: {row_h}\nrows_h: {rows_h}') col_w_tot = 0 for i in range(cols): @@ -195,16 +203,16 @@ class CompleterView(QTreeView): if h: h: int = round(h) - # mn = row_h * 2 - # self.setMinimumHeight(mn) - # abs_mx = h - row_h - # print(f'set min {abs_mx}') - # self.setFixedHeight(round(0.9 * h)) - self.setMinimumHeight(round(0.91 * h)) + abs_mx = round(0.91 * h) + self.setMaximumHeight(abs_mx) - # self.setMaximumHeight(0.9 * abs_mx) - # 6 result row slots and 3 rows for sections and headers - # mn = (6 + 3) * row_h + if rows_h <= abs_mx: + # self.setMinimumHeight(rows_h) + self.setMinimumHeight(rows_h) + # self.setFixedHeight(rows_h) + + else: + self.setMinimumHeight(abs_mx) # dyncamically size to width of longest result seen curr_w = self.width() @@ -335,6 +343,23 @@ class CompleterView(QTreeView): item = model.itemFromIndex(idx) yield idx, item + def iter_df_rows( + self, + iparent: QModelIndex = QModelIndex(), + + ) -> Iterator[tuple[QModelIndex, QStandardItem]]: + + model = self.model() + isections = model.rowCount(iparent) + for i in range(isections): + idx = model.index(i, 0, iparent) + item = model.itemFromIndex(idx) + yield idx, item + + if model.hasChildren(idx): + # recursively yield child items depth-first + yield from self.iter_df_rows(idx) + def find_section( self, section: str, @@ -358,7 +383,8 @@ class CompleterView(QTreeView): status_field: str = None, ) -> None: - '''Clear all result-rows from under the depth = 1 section. + ''' + Clear all result-rows from under the depth = 1 section. ''' idx = self.find_section(section) @@ -459,7 +485,7 @@ class CompleterView(QTreeView): # a resize of some higher level parent-container widget. search = self.parent() w, h = search.space_dims() - self.resize_to_results(w=w) + self.resize_to_results(w=w, h=h) self.show() @@ -942,8 +968,8 @@ async def handle_keyboard_input( if key in (Qt.Key_Enter, Qt.Key_Return): _search_enabled = False await search.chart_current_item(clear_to_cache=True) - view.show_matches() search.show_only_cache_entries() + view.show_matches() search.focus() elif not ctl and not bar.text():