fix: render more of launchers
This commit is contained in:
@@ -90,6 +90,7 @@ class FuzzyMenu(Window):
|
||||
self._items: list[Any] = []
|
||||
self._filtered: list[Any] = []
|
||||
self._selected_index: int = 0
|
||||
self._scroll_offset: int = 0
|
||||
|
||||
self.viewport = Box(name="viewport", spacing=4, orientation="v")
|
||||
|
||||
@@ -115,12 +116,14 @@ class FuzzyMenu(Window):
|
||||
self._items = self._provider.items()
|
||||
self.search_entry.set_text("")
|
||||
self._selected_index = 0
|
||||
self._scroll_offset = 0
|
||||
self._refresh_viewport("")
|
||||
super().show()
|
||||
self.search_entry.grab_focus()
|
||||
|
||||
def _on_text_changed(self, entry, *_):
|
||||
self._selected_index = 0
|
||||
self._scroll_offset = 0
|
||||
self._refresh_viewport(entry.get_text())
|
||||
|
||||
def _on_key_press(self, _widget, event):
|
||||
@@ -130,6 +133,9 @@ class FuzzyMenu(Window):
|
||||
if keyval == Gdk.KEY_Escape:
|
||||
self.hide()
|
||||
return True
|
||||
if ctrl and keyval in (Gdk.KEY_g, Gdk.KEY_G):
|
||||
self.hide()
|
||||
return True
|
||||
if keyval in (Gdk.KEY_Return, Gdk.KEY_KP_Enter):
|
||||
self._activate_selected()
|
||||
return True
|
||||
@@ -141,27 +147,51 @@ class FuzzyMenu(Window):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _window_size(self) -> int:
|
||||
return self._max_results if self._max_results is not None else len(self._filtered)
|
||||
|
||||
def _move_selection(self, delta: int):
|
||||
if not self._filtered:
|
||||
return
|
||||
self._selected_index = (self._selected_index + delta) % len(self._filtered)
|
||||
self._update_selection_highlight()
|
||||
new_index = self._selected_index + delta
|
||||
new_index = max(0, min(new_index, len(self._filtered) - 1))
|
||||
if new_index == self._selected_index:
|
||||
return
|
||||
self._selected_index = new_index
|
||||
window = self._window_size()
|
||||
if window <= 0:
|
||||
self._scroll_offset = 0
|
||||
elif self._selected_index < self._scroll_offset:
|
||||
self._scroll_offset = self._selected_index
|
||||
elif self._selected_index >= self._scroll_offset + window:
|
||||
self._scroll_offset = self._selected_index - window + 1
|
||||
self._render_visible()
|
||||
|
||||
def _refresh_viewport(self, query: str):
|
||||
self._filtered = self._provider.filter(self._items, query)
|
||||
if self._max_results is not None:
|
||||
self._filtered = self._filtered[: self._max_results]
|
||||
if self._selected_index >= len(self._filtered):
|
||||
self._selected_index = 0
|
||||
self._scroll_offset = 0
|
||||
self._render_visible()
|
||||
|
||||
def _render_visible(self):
|
||||
window = self._window_size()
|
||||
if window <= 0:
|
||||
visible: list[Any] = []
|
||||
else:
|
||||
max_offset = max(0, len(self._filtered) - window)
|
||||
self._scroll_offset = min(self._scroll_offset, max_offset)
|
||||
visible = self._filtered[self._scroll_offset : self._scroll_offset + window]
|
||||
self.viewport.children = []
|
||||
for item in self._filtered:
|
||||
for item in visible:
|
||||
self.viewport.add(self._provider.render(item))
|
||||
self._update_selection_highlight()
|
||||
|
||||
def _update_selection_highlight(self):
|
||||
visible_index = self._selected_index - self._scroll_offset
|
||||
for i, child in enumerate(self.viewport.get_children()):
|
||||
ctx = child.get_style_context()
|
||||
if i == self._selected_index:
|
||||
if i == visible_index:
|
||||
ctx.add_class("selected")
|
||||
else:
|
||||
ctx.remove_class("selected")
|
||||
|
||||
@@ -48,6 +48,7 @@ class ClipboardProvider:
|
||||
label=item.preview,
|
||||
h_align="start",
|
||||
ellipsization="end",
|
||||
max_chars_width=120,
|
||||
name="clip-preview",
|
||||
),
|
||||
],
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
min-width: 720px;
|
||||
}
|
||||
|
||||
#viewport {
|
||||
@@ -53,3 +54,4 @@
|
||||
font-size: 11px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user