#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango

class App(Gtk.Window):
    def __init__(self):
        super().__init__(title='Font Browser')
        self.set_default_size(700, 500)
        hpaned = Gtk.Paned(); self.add(hpaned)
        # left: font list
        left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=4)
        left.set_margin_top(6); left.set_margin_bottom(6)
        left.set_margin_start(6); left.set_margin_end(6)
        self.search = Gtk.SearchEntry()
        self.search.connect('search-changed', self.filter_fonts)
        left.pack_start(self.search, False, False, 0)
        sw = Gtk.ScrolledWindow(); sw.set_size_request(220, -1)
        self.store = Gtk.ListStore(str)
        self.filter_model = self.store.filter_new()
        self.filter_model.set_visible_func(self.font_visible)
        tv = Gtk.TreeView(model=self.filter_model)
        col = Gtk.TreeViewColumn('Font', Gtk.CellRendererText(), text=0)
        tv.append_column(col)
        tv.get_selection().connect('changed', self.on_select)
        sw.add(tv)
        left.pack_start(sw, True, True, 0)
        hpaned.add1(left)
        # right: preview
        right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8)
        right.set_margin_top(10); right.set_margin_bottom(10)
        right.set_margin_start(10); right.set_margin_end(10)
        self.font_name_lbl = Gtk.Label(label='Select a font', xalign=0)
        right.pack_start(self.font_name_lbl, False, False, 0)
        hb = Gtk.Box(spacing=8)
        hb.add(Gtk.Label(label='Preview text:'))
        self.preview_entry = Gtk.Entry()
        self.preview_entry.set_text('The quick brown fox jumps over the lazy dog 0123456789')
        self.preview_entry.connect('changed', self.update_preview)
        hb.pack_start(self.preview_entry, True, True, 0)
        right.pack_start(hb, False, False, 0)
        hb2 = Gtk.Box(spacing=8)
        hb2.add(Gtk.Label(label='Size:'))
        self.size_spin = Gtk.SpinButton.new_with_range(6, 96, 2)
        self.size_spin.set_value(16)
        self.size_spin.connect('value-changed', self.update_preview)
        hb2.pack_start(self.size_spin, False, False, 0)
        right.pack_start(hb2, False, False, 0)
        sw2 = Gtk.ScrolledWindow()
        self.preview = Gtk.Label(label='', xalign=0, wrap=True)
        sw2.add(self.preview)
        right.pack_start(sw2, True, True, 0)
        hpaned.add2(right)
        self.current_font = 'Sans'
        # load fonts
        ctx = self.get_pango_context()
        families = sorted([f.get_name() for f in ctx.list_families()])
        for f in families: self.store.append([f])
    def font_visible(self, model, it, _):
        q = self.search.get_text().lower()
        return q in model[it][0].lower() if q else True
    def filter_fonts(self, *_):
        self.filter_model.refilter()
    def on_select(self, sel):
        model, it = sel.get_selected()
        if it:
            self.current_font = model[it][0]
            self.font_name_lbl.set_text(self.current_font)
            self.update_preview()
    def update_preview(self, *_):
        txt = self.preview_entry.get_text()
        sz = int(self.size_spin.get_value())
        fd = Pango.FontDescription(f'{self.current_font} {sz}')
        self.preview.set_text(txt)
        self.preview.override_font(fd)

win = App()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()
