126 lines
3.3 KiB
Python
126 lines
3.3 KiB
Python
![]() |
#!/bin/env python3
|
||
|
|
||
|
import urwid as u
|
||
|
|
||
|
class ListItem(u.WidgetWrap):
|
||
|
|
||
|
def __init__ (self, country):
|
||
|
|
||
|
self.content = country
|
||
|
|
||
|
name = country["name"]
|
||
|
|
||
|
t = u.AttrWrap(u.Text(name), "country", "country_selected")
|
||
|
|
||
|
u.WidgetWrap.__init__(self, t)
|
||
|
|
||
|
def selectable (self):
|
||
|
return True
|
||
|
|
||
|
def keypress(self, size, key):
|
||
|
return key
|
||
|
|
||
|
class ListView(u.WidgetWrap):
|
||
|
|
||
|
def __init__(self):
|
||
|
|
||
|
u.register_signal(self.__class__, ['show_details'])
|
||
|
|
||
|
self.walker = u.SimpleFocusListWalker([])
|
||
|
|
||
|
lb = u.ListBox(self.walker)
|
||
|
|
||
|
u.WidgetWrap.__init__(self, lb)
|
||
|
|
||
|
def modified(self):
|
||
|
|
||
|
focus_w, _ = self.walker.get_focus()
|
||
|
|
||
|
u.emit_signal(self, 'show_details', focus_w.content)
|
||
|
|
||
|
def set_data(self, countries):
|
||
|
|
||
|
countries_widgets = [ListItem(c) for c in countries]
|
||
|
|
||
|
u.disconnect_signal(self.walker, 'modified', self.modified)
|
||
|
|
||
|
while len(self.walker) > 0:
|
||
|
self.walker.pop()
|
||
|
|
||
|
self.walker.extend(countries_widgets)
|
||
|
|
||
|
u.connect_signal(self.walker, "modified", self.modified)
|
||
|
|
||
|
self.walker.set_focus(0)
|
||
|
|
||
|
class DetailView(u.WidgetWrap):
|
||
|
|
||
|
def __init__ (self):
|
||
|
t = u.Text("")
|
||
|
u.WidgetWrap.__init__(self, t)
|
||
|
|
||
|
def set_country(self, c):
|
||
|
s = f'Name: {c["name"]}\nPop: {c["pop"]}\nGDP: {c["gdp"]}'
|
||
|
self._w.set_text(s)
|
||
|
|
||
|
class App(object):
|
||
|
|
||
|
def unhandled_input(self, key):
|
||
|
if key in ('q',):
|
||
|
raise u.ExitMainLoop()
|
||
|
|
||
|
def show_details(self, country):
|
||
|
self.detail_view.set_country(country)
|
||
|
|
||
|
def __init__(self):
|
||
|
|
||
|
self.palette = {
|
||
|
("bg", "black", "white"),
|
||
|
("country", "black", "white"),
|
||
|
("country_selected", "black", "yellow"),
|
||
|
("footer", "white, bold", "dark red")
|
||
|
}
|
||
|
|
||
|
self.list_view = ListView()
|
||
|
self.detail_view = DetailView()
|
||
|
|
||
|
u.connect_signal(self.list_view, 'show_details', self.show_details)
|
||
|
|
||
|
footer = u.AttrWrap(u.Text(" Q to exit"), "footer")
|
||
|
|
||
|
col_rows = u.raw_display.Screen().get_cols_rows()
|
||
|
h = col_rows[0] - 2
|
||
|
|
||
|
f1 = u.Filler(self.list_view, valign='top', height=h)
|
||
|
f2 = u.Filler(self.detail_view, valign='top')
|
||
|
|
||
|
c_list = u.LineBox(f1, title="Countries")
|
||
|
c_details = u.LineBox(f2, title="Country Details")
|
||
|
|
||
|
columns = u.Columns([('weight', 30, c_list), ('weight', 70, c_details)])
|
||
|
|
||
|
frame = u.AttrMap(u.Frame(body=columns, footer=footer), 'bg')
|
||
|
|
||
|
self.loop = u.MainLoop(frame, self.palette, unhandled_input=self.unhandled_input)
|
||
|
|
||
|
def update_data(self):
|
||
|
|
||
|
l = [] # https://databank.worldbank.org/embed/Population-and-GDP-by-Country/id/29c4df41
|
||
|
l.append({"name":"USA", "pop":"325,084,756", "gdp":"$ 19.485 trillion"})
|
||
|
l.append({"name":"China", "pop":"1,421,021,791", "gdp":"$ 12.238 trillion"})
|
||
|
l.append({"name":"Japan", "pop":"127,502,725", "gdp":"$ 4.872 trillion"})
|
||
|
l.append({"name":"Germany", "pop":"82,658,409", "gdp":"$ 3.693 trillion"})
|
||
|
l.append({"name":"India", "pop":"1,338,676,785", "gdp":"$ 2.651 trillion"})
|
||
|
|
||
|
self.list_view.set_data(l)
|
||
|
|
||
|
def start(self):
|
||
|
|
||
|
self.update_data()
|
||
|
self.loop.run()
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
|
||
|
app = App()
|
||
|
app.start()
|