From: Christian Heller Date: Mon, 28 Oct 2024 12:34:45 +0000 (+0100) Subject: Browser: Minor refactoring. X-Git-Url: https://plomlompom.com/repos/%7B%7Bdb.prefix%7D%7D/static/%7B%7B%20web_path%20%7D%7D/day?a=commitdiff_plain;h=80ca49c5f93fe1e2d2a8643b77fd9bf3adb610f5;p=stable_plom Browser: Minor refactoring. --- diff --git a/browser.py b/browser.py index 6de2728..bc2167f 100755 --- a/browser.py +++ b/browser.py @@ -344,16 +344,15 @@ class GalleryConfig(): class GallerySlot(Gtk.Button): """Slot in Gallery representing a GalleryItem.""" - def __init__(self, item, on_click_file=None): + def __init__(self, item, slots_geometry, on_click_file=None): super().__init__() + self._geometry = slots_geometry self.add_css_class('slot') self.set_hexpand(True) self.item = item self.item.slot = self if on_click_file: self.connect('clicked', on_click_file) - self._slot_size = None - self._side_margin = None def mark(self, css_class, do_add=True): """Add or remove css_class from self.""" @@ -362,18 +361,18 @@ class GallerySlot(Gtk.Button): else: self.remove_css_class(css_class) - def ensure_slot_size(self, slot_size, margin): + def ensure_slot_size(self): """Call ._size_widget to size .props.child; if none, make empty one.""" - self._slot_size = slot_size - self._side_margin = margin // 2 if self.get_child() is None: self.set_child(Gtk.Label(label='+')) self._size_widget() def _size_widget(self): for s in ('bottom', 'top', 'start', 'end'): - setattr(self.get_child().props, f'margin_{s}', self._side_margin) - self.get_child().set_size_request(self._slot_size, self._slot_size) + setattr(self.get_child().props, f'margin_{s}', + self._geometry.side_margin) + self.get_child().set_size_request(self._geometry.size_sans_margins, + self._geometry.size_sans_margins) def update_widget(self, is_in_vp): """(Un-)load slot, for Imgs if (not) is_in_vp, update CSS class.""" @@ -400,6 +399,21 @@ class GallerySlot(Gtk.Button): self.mark('bookmarked', self.item.bookmarked) +class GallerySlotsGeometry: + """Collect variable sizes shared among all GallerySlots.""" + + def __init__(self): + self._margin = GALLERY_SLOT_MARGIN + assert 0 == self._margin % 2 # avoid ._margin != 2 * .side_margin + self.side_margin = self._margin // 2 + self.size, self.size_sans_margins = -1, -1 + + def set_size(self, size): + """Not only set .size but also update .size_sans_margins.""" + self.size = size + self.size_sans_margins = self.size - self._margin + + class GalleryItem(GObject.GObject): """Gallery representation of filesystem entry, base to DirItem, ImgItem.""" slot: GallerySlot @@ -476,10 +490,10 @@ class ImgItem(GalleryItem): class VerticalLabel(Gtk.DrawingArea): """Label of vertical text (rotated -90°).""" - def __init__(self, text, max_height_ref): + def __init__(self, text, slots_geometry): super().__init__() self._text = text - self._max_height_ref = max_height_ref + self._slots_geometry = slots_geometry test_layout = self.create_pango_layout() test_layout.set_markup(text) _, self._text_height = test_layout.get_pixel_size() @@ -489,7 +503,7 @@ class VerticalLabel(Gtk.DrawingArea): """Create layout, rotate by 90°, size widget to measurements.""" layout = self.create_pango_layout() layout.set_markup(self._text) - layout.set_width(self._max_height_ref[0] * Pango.SCALE) + layout.set_width(self._slots_geometry.size * Pango.SCALE) layout.set_ellipsize(Pango.EllipsizeMode.MIDDLE) text_width, _ = layout.get_pixel_size() cairo_ctx.translate(0, text_width + (height - text_width)) @@ -526,7 +540,7 @@ class Gallery: self._recurse_dirs = False self._by_1st = False self._per_row = GALLERY_PER_ROW_DEFAULT - self._slot_margin = GALLERY_SLOT_MARGIN + self._slots_geometry = GallerySlotsGeometry() self.dir_entries = [] self.items_attrs = {} @@ -538,7 +552,6 @@ class Gallery: scroller = Gtk.ScrolledWindow(propagate_natural_height=True) self._col_headers_frame = Gtk.Fixed() self._col_headers_grid = None - self._slot_size_ref = [0] self.frame = Gtk.Box(orientation=OR_V) self.frame.append(self._col_headers_frame) self.frame.append(scroller) @@ -810,7 +823,7 @@ class Gallery: if 1 == len(remaining): for i, attr in enumerate(ancestors): vlabel = VerticalLabel(f'{attr[0]}: {attr[1]}', - self._slot_size_ref) + self._slots_geometry) self._grid.attach(vlabel, i, i_row_ref[0], 1, 1) row = [None] * len(attr_values) for item in items_of_parent: @@ -821,10 +834,10 @@ class Gallery: row[idx_val_in_attr_values] = item for i_col, item in enumerate(row): if item: - slot = GallerySlot(item, - item_clicker(i_slot_ref[0])) + slot = GallerySlot(item, self._slots_geometry) else: - slot = GallerySlot(GalleryItem('', '')) # dummy + slot = GallerySlot(GalleryItem('', ''), # dummy + self._slots_geometry) self.slots += [slot] i_slot_ref[0] += 1 self._grid.attach(slot, i_col + len(ancestors), @@ -876,7 +889,8 @@ class Gallery: if self._per_row == i_col: i_col = 0 i_row += 1 - slot = GallerySlot(item, item_clicker(i)) + slot = GallerySlot(item, self._slots_geometry, + item_clicker(i)) self._grid.attach(slot, i_col, i_row, 1, 1) self.slots += [slot] i_col += 1 @@ -953,7 +967,7 @@ class Gallery: i_vlabels += 1 max_slot_width = (vp_width - side_offset) // self._per_row slot_size = min(vp_height, max_slot_width) - self._slot_size_ref[0] = slot_size + self._slots_geometry.set_size(slot_size) if self._by_1st: i_widgets = 0 while True: @@ -961,14 +975,14 @@ class Gallery: if 0 == i_widgets: widget.set_size_request(side_offset, -1) elif isinstance(widget, Gtk.Label): - widget.set_size_request(slot_size, -1) + widget.set_size_request(self._slots_geometry.size, -1) else: break i_widgets += 1 - slot_size_sans_margin = slot_size - self._slot_margin for idx, slot in enumerate(self.slots): - slot.ensure_slot_size(slot_size_sans_margin, self._slot_margin) - vp_scroll.set_upper(slot_size * ceil(len(self.slots) / self._per_row)) + slot.ensure_slot_size() + vp_scroll.set_upper(self._slots_geometry.size * ceil(len(self.slots) + / self._per_row)) if self._scroll_to_focus(vp_scroll, vp_top, vp_bottom): return for idx, slot in enumerate(self.slots): @@ -979,9 +993,8 @@ class Gallery: def _position_to_viewport( self, idx, vp_top, vp_bottom, in_vp_greedy=False): - slot_size = self._slot_size_ref[0] - slot_top = (idx // self._per_row) * slot_size - slot_bottom = slot_top + slot_size + slot_top = (idx // self._per_row) * self._slots_geometry.size + slot_bottom = slot_top + self._slots_geometry.size if in_vp_greedy: in_vp = (slot_bottom >= vp_top and slot_top <= vp_bottom) else: @@ -989,18 +1002,18 @@ class Gallery: return in_vp, slot_top, slot_bottom def _scroll_to_focus(self, vp_scroll, vp_top, vp_bottom): - slot_size = self._slot_size_ref[0] scroll_to_focus = self._shall_scroll_to_focus self._shall_redraw, self._shall_scroll_to_focus = False, False if scroll_to_focus: in_vp, slot_top, slot_bottom = self._position_to_viewport( - self.selected_idx, slot_size, vp_top, vp_bottom) + self.selected_idx, vp_top, vp_bottom) if not in_vp: self._shall_redraw, self._shall_scroll_to_focus = True, True if slot_top < vp_top: vp_scroll.set_value(slot_top) else: - vp_scroll.set_value(slot_bottom - slot_size) + vp_scroll.set_value(slot_bottom + - self._slots_geometry.size) return True return False