emmental/sidebar/tagbox.py

127 lines
4.0 KiB
Python

# Copyright 2021 (c) Anna Schumaker.
from . import tagrow
from gi.repository import Gtk
import lib
import playlist
import tagdb
class TagBox(Gtk.ScrolledWindow):
def __init__(self, tagstore, icon, header=False):
Gtk.ScrolledWindow.__init__(self)
self.listbox = Gtk.ListBox()
self.tagstore = tagstore
self.icon = icon
self.bus = lib.bus.Bus(50)
self.set_child(self.listbox)
self.set_vexpand(True)
for tag in self.tagstore.tags():
self.on_tag_added(tag)
self.listbox.set_activate_on_single_click(False)
self.listbox.set_sort_func(self.sort_func)
if header == True:
self.listbox.set_header_func(self.header_func)
self.listbox.connect("row-activated", self.row_activated)
self.listbox.connect("row-selected", self.row_selected)
tagstore.Added.register(self.tag_added)
tagstore.Removed.register(self.tag_removed)
def __alloc_tagrow__(self, tag):
return tagrow.TagRow(tag, self.icon)
def __getitem__(self, i):
return self.listbox.get_row_at_index(i)
def clear(self):
while (row := self[0]) != None:
self.on_tag_removed(row.tag)
self.bus.clear()
def header_func(self, cur, prev):
c = cur.tag.get_header()
if prev == None or prev.tag.get_header() != c:
cur.set_header(tagrow.TagHeader(c))
else:
cur.set_header(None)
def row_activated(self, listbox, row):
tagdb.Stack.push(row.tag)
def row_selected(self, listbox, row):
playlist.Model.switch_tag(row.tag)
def sort_func(self, lhs, rhs):
if lhs.tag < rhs.tag:
return -1
if rhs.tag < lhs.tag:
return 1
return 0
def on_tag_added(self, tag):
tag.widgets = self.__alloc_tagrow__(tag)
tag.TrackAdded.register(self.tag_changed)
tag.TrackRemoved.register(self.tag_changed)
self.listbox.append(tag.widgets)
def tag_added(self, tag):
self.bus.board(self.on_tag_added, tag)
def on_tag_changed(self, tag):
tag.widgets.set_label()
def tag_changed(self, tag, track, pos):
self.bus.board(self.on_tag_changed, tag)
def on_tag_removed(self, tag):
self.listbox.remove(tag.widgets)
tag.TrackAdded.unregister(self.tag_changed)
tag.TrackRemoved.unregister(self.tag_changed)
tag.widgets = None
def tag_removed(self, tag):
self.bus.board(self.on_tag_removed, tag)
class ParentTagBox(TagBox):
def __init__(self, tagstore, icon, childstore, childicon, header=False):
TagBox.__init__(self, tagstore, icon, header)
self.childstore = childstore
self.childicon = childicon
for child in childstore.tags():
self.on_child_tag_added(child)
childstore.Added.register(self.child_tag_added)
childstore.Removed.register(self.child_tag_removed)
def __alloc_tagrow__(self, tag):
return tagrow.ParentTagRow(tag, self.icon)
def on_child_tag_added(self, tag):
tag.widgets = tagrow.TagRow(tag, self.childicon)
tag.widgets.set_margin_start(35)
tag.parent.widgets.add_child(tag.widgets)
tag.TrackAdded.register(self.tag_changed)
tag.TrackRemoved.register(self.tag_changed)
self.listbox.append(tag.widgets)
def child_tag_added(self, tag):
self.bus.board(self.on_child_tag_added, tag)
def on_child_tag_removed(self, tag):
self.listbox.remove(tag.widgets)
tag.TrackAdded.unregister(self.tag_changed)
tag.TrackRemoved.unregister(self.tag_changed)
tag.widgets = None
def child_tag_removed(self, tag):
self.bus.board(self.on_child_tag_removed, tag)
def header_func(self, cur, prev):
if isinstance(cur, tagrow.ParentTagRow):
if prev and not isinstance(prev, tagrow.ParentTagRow):
prev = prev.tag.parent.widgets
super().header_func(cur, prev)