Add basic urwid frame and divider theming support.
parent
aaf57cfd56
commit
33efb379ad
|
@ -220,6 +220,8 @@ default_prefs = {
|
||||||
"dramatic_exit": True,
|
"dramatic_exit": True,
|
||||||
"date": "%Y/%m/%d",
|
"date": "%Y/%m/%d",
|
||||||
"time": "%H:%M",
|
"time": "%H:%M",
|
||||||
|
"frame_theme": "tilde",
|
||||||
|
"custom_divider_char": False,
|
||||||
"frame_title": "BBJ",
|
"frame_title": "BBJ",
|
||||||
"use_custom_frame_title": False,
|
"use_custom_frame_title": False,
|
||||||
"max_text_width": 80,
|
"max_text_width": 80,
|
||||||
|
@ -274,6 +276,50 @@ escape_map = {
|
||||||
if len(key) > 1
|
if len(key) > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
themes = {
|
||||||
|
"tilde": {
|
||||||
|
"divider": "-",
|
||||||
|
"frame": {
|
||||||
|
"tlcorner": "@",
|
||||||
|
"trcorner": "@",
|
||||||
|
"blcorner": "@",
|
||||||
|
"brcorner": "@",
|
||||||
|
"tline": "=",
|
||||||
|
"bline": "=",
|
||||||
|
"lline": "|",
|
||||||
|
"rline": "|",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"urwid": {
|
||||||
|
"divider": "─",
|
||||||
|
"frame": {
|
||||||
|
"tlcorner": "┌",
|
||||||
|
"trcorner": "┐",
|
||||||
|
"blcorner": "└",
|
||||||
|
"brcorner": "┘",
|
||||||
|
"tline": "─",
|
||||||
|
"bline": "─",
|
||||||
|
"lline": "│",
|
||||||
|
"rline": "│",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"none": {
|
||||||
|
"divider": " ",
|
||||||
|
"frame": {
|
||||||
|
"tlcorner": "",
|
||||||
|
"trcorner": "",
|
||||||
|
"blcorner": "",
|
||||||
|
"brcorner": "",
|
||||||
|
"tline": "",
|
||||||
|
"bline": "",
|
||||||
|
"lline": "",
|
||||||
|
"rline": "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rcpath = os.path.join(os.getenv("HOME"), ".bbjrc")
|
rcpath = os.path.join(os.getenv("HOME"), ".bbjrc")
|
||||||
markpath = os.path.join(os.getenv("HOME"), ".bbjmarks")
|
markpath = os.path.join(os.getenv("HOME"), ".bbjmarks")
|
||||||
pinpath = os.path.join(os.getenv("HOME"), ".bbjpins")
|
pinpath = os.path.join(os.getenv("HOME"), ".bbjpins")
|
||||||
|
@ -289,21 +335,29 @@ class App(object):
|
||||||
"position": 0,
|
"position": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.theme = themes[self.prefs["frame_theme"]].copy()
|
||||||
|
if isinstance(self.prefs["custom_divider_char"], str):
|
||||||
|
self.theme["divider"] = self.prefs["custom_divider_char"]
|
||||||
|
except KeyError:
|
||||||
|
exit("Selected theme does not exist. Please check "
|
||||||
|
"the `frame_theme` value in ~/.bbjrc")
|
||||||
|
|
||||||
self.mode = None
|
self.mode = None
|
||||||
self.thread = None
|
self.thread = None
|
||||||
self.window_split = False
|
self.window_split = False
|
||||||
self.last_index_pos = None
|
self.last_index_pos = None
|
||||||
self.last_alarm = None
|
self.last_alarm = None
|
||||||
|
|
||||||
|
if self.prefs["use_custom_frame_title"]:
|
||||||
|
self.frame_title = self.prefs["frame_title"]
|
||||||
|
else:
|
||||||
|
self.frame_title = network.instance_info["instance_name"]
|
||||||
|
|
||||||
self.walker = urwid.SimpleFocusListWalker([])
|
self.walker = urwid.SimpleFocusListWalker([])
|
||||||
self.box = ActionBox(self.walker)
|
self.box = ActionBox(self.walker)
|
||||||
self.body = urwid.AttrMap(
|
self.body = urwid.AttrMap(
|
||||||
urwid.LineBox(
|
urwid.LineBox(self.box, **self.frame_theme(self.frame_title)),
|
||||||
self.box,
|
|
||||||
title=self.prefs["frame_title"]
|
|
||||||
if self.prefs["use_custom_frame_title"]
|
|
||||||
else network.instance_info["instance_name"],
|
|
||||||
**frame_theme()),
|
|
||||||
"default"
|
"default"
|
||||||
)
|
)
|
||||||
self.loop = urwid.MainLoop(
|
self.loop = urwid.MainLoop(
|
||||||
|
@ -312,6 +366,17 @@ class App(object):
|
||||||
handle_mouse=self.prefs["mouse_integration"])
|
handle_mouse=self.prefs["mouse_integration"])
|
||||||
|
|
||||||
|
|
||||||
|
def frame_theme(self, title=""):
|
||||||
|
"""
|
||||||
|
Return the kwargs for a frame theme.
|
||||||
|
"""
|
||||||
|
# TITLE
|
||||||
|
theme = self.theme["frame"].copy()
|
||||||
|
if theme["tline"] != "":
|
||||||
|
theme.update({"title": title})
|
||||||
|
return theme
|
||||||
|
|
||||||
|
|
||||||
def set_header(self, text, *format_specs):
|
def set_header(self, text, *format_specs):
|
||||||
"""
|
"""
|
||||||
Update the header line with the logged in user, a seperator,
|
Update the header line with the logged in user, a seperator,
|
||||||
|
@ -430,9 +495,9 @@ class App(object):
|
||||||
|
|
||||||
self.loop.widget.footer[0].set_text(
|
self.loop.widget.footer[0].set_text(
|
||||||
bars["edit_window"].format(
|
bars["edit_window"].format(
|
||||||
app.prefs["edit_escapes"]["abort"].upper(),
|
self.prefs["edit_escapes"]["abort"].upper(),
|
||||||
app.prefs["edit_escapes"]["focus"].upper(),
|
self.prefs["edit_escapes"]["focus"].upper(),
|
||||||
app.prefs["edit_escapes"]["fhelp"].upper(),
|
self.prefs["edit_escapes"]["fhelp"].upper(),
|
||||||
focus)
|
focus)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -469,8 +534,7 @@ class App(object):
|
||||||
"""
|
"""
|
||||||
widget = OptionsMenu(
|
widget = OptionsMenu(
|
||||||
ActionBox(urwid.SimpleFocusListWalker(self.make_message_body(message))),
|
ActionBox(urwid.SimpleFocusListWalker(self.make_message_body(message))),
|
||||||
title=">>%d" % message["post_id"],
|
**self.frame_theme(">>%d" % message["post_id"])
|
||||||
**frame_theme()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
|
@ -508,7 +572,7 @@ class App(object):
|
||||||
|
|
||||||
widget = OptionsMenu(
|
widget = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
||||||
title="View a Quote", **frame_theme()
|
**self.frame_theme("View a Quote")
|
||||||
)
|
)
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
|
@ -559,7 +623,7 @@ class App(object):
|
||||||
# TODO: create a central routine for creating popups. this is getting really ridiculous
|
# TODO: create a central routine for creating popups. this is getting really ridiculous
|
||||||
popup = OptionsMenu(
|
popup = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
||||||
**frame_theme())
|
**self.frame_theme())
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
popup, self.loop.widget,
|
popup, self.loop.widget,
|
||||||
|
@ -607,8 +671,7 @@ class App(object):
|
||||||
|
|
||||||
widget = OptionsMenu(
|
widget = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
||||||
title=str(">>%d (%s)" % (message["post_id"], author["user_name"])),
|
**self.frame_theme(">>%d (%s)" % (message["post_id"], author["user_name"]))
|
||||||
**frame_theme()
|
|
||||||
)
|
)
|
||||||
size = self.loop.screen_size
|
size = self.loop.screen_size
|
||||||
|
|
||||||
|
@ -668,7 +731,7 @@ class App(object):
|
||||||
("dim", "last post by "),
|
("dim", "last post by "),
|
||||||
(str(last_author["color"]), "~" + last_author["user_name"])
|
(str(last_author["color"]), "~" + last_author["user_name"])
|
||||||
]),
|
]),
|
||||||
urwid.AttrMap(urwid.Divider("-"), "dim")
|
urwid.AttrMap(urwid.Divider(self.theme["divider"]), "dim")
|
||||||
]
|
]
|
||||||
|
|
||||||
if self.prefs["index_spacing"]:
|
if self.prefs["index_spacing"]:
|
||||||
|
@ -715,7 +778,7 @@ class App(object):
|
||||||
MessageBody(message),
|
MessageBody(message),
|
||||||
width=self.prefs["max_text_width"]),
|
width=self.prefs["max_text_width"]),
|
||||||
urwid.Divider(),
|
urwid.Divider(),
|
||||||
urwid.AttrMap(urwid.Divider("-"), "dim")
|
urwid.AttrMap(urwid.Divider(self.theme["divider"]), "dim")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -904,7 +967,7 @@ class App(object):
|
||||||
urwid.AttrMap(StringPrompt(callback), "opt_prompt"),
|
urwid.AttrMap(StringPrompt(callback), "opt_prompt"),
|
||||||
urwid.Text("Use a blank query to reset the {}.".format(self.mode))
|
urwid.Text("Use a blank query to reset the {}.".format(self.mode))
|
||||||
])),
|
])),
|
||||||
**frame_theme())
|
**self.frame_theme())
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
popup, self.loop.widget,
|
popup, self.loop.widget,
|
||||||
|
@ -950,7 +1013,7 @@ class App(object):
|
||||||
# TODO: create a central routine for creating popups. this is getting really ridiculous
|
# TODO: create a central routine for creating popups. this is getting really ridiculous
|
||||||
popup = OptionsMenu(
|
popup = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(buttons)),
|
||||||
**frame_theme())
|
**self.frame_theme())
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
popup, self.loop.widget,
|
popup, self.loop.widget,
|
||||||
|
@ -1026,7 +1089,7 @@ class App(object):
|
||||||
|
|
||||||
popup = OptionsMenu(
|
popup = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(items)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(items)),
|
||||||
**frame_theme())
|
**self.frame_theme())
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
popup, self.loop.widget,
|
popup, self.loop.widget,
|
||||||
|
@ -1043,6 +1106,18 @@ class App(object):
|
||||||
display.set_text((str(author["color"]), ">>%s %s" % (value, author["user_name"])))
|
display.set_text((str(author["color"]), ">>%s %s" % (value, author["user_name"])))
|
||||||
|
|
||||||
|
|
||||||
|
def set_theme(self, button, new_state):
|
||||||
|
"""
|
||||||
|
Callback for the theme radio buttons in the options.
|
||||||
|
"""
|
||||||
|
if new_state == True:
|
||||||
|
self.theme = themes[button.label].copy()
|
||||||
|
if self.prefs["custom_divider_char"]:
|
||||||
|
self.theme["divider"] = self.prefs["custom_divider_char"]
|
||||||
|
self.prefs["frame_theme"] = button.label
|
||||||
|
bbjrc("update", **self.prefs)
|
||||||
|
|
||||||
|
|
||||||
def set_new_editor(self, button, value, arg):
|
def set_new_editor(self, button, value, arg):
|
||||||
"""
|
"""
|
||||||
Callback for the option radio buttons to set the the text editor.
|
Callback for the option radio buttons to set the the text editor.
|
||||||
|
@ -1117,13 +1192,12 @@ class App(object):
|
||||||
"This is BBJ, a client/server textboard made for tilde.town!",
|
"This is BBJ, a client/server textboard made for tilde.town!",
|
||||||
True),
|
True),
|
||||||
urwid.Text(("dim", "...by ~desvox")),
|
urwid.Text(("dim", "...by ~desvox")),
|
||||||
urwid.Divider("-"),
|
urwid.Divider(self.theme["divider"]),
|
||||||
urwid.Button("Post Formatting Help", self.formatting_help),
|
urwid.Button("Post Formatting Help", self.formatting_help),
|
||||||
urwid.Divider("-"),
|
urwid.Divider(self.theme["divider"]),
|
||||||
urwid.Text(general_help)
|
urwid.Text(general_help)
|
||||||
])),
|
])),
|
||||||
title="?????",
|
**self.frame_theme("?????")
|
||||||
**frame_theme()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
app.loop.widget = urwid.Overlay(
|
app.loop.widget = urwid.Overlay(
|
||||||
|
@ -1146,8 +1220,7 @@ class App(object):
|
||||||
|
|
||||||
widget = OptionsMenu(
|
widget = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(app.make_message_body(message, True))),
|
urwid.ListBox(urwid.SimpleFocusListWalker(app.make_message_body(message, True))),
|
||||||
title="Formatting Help",
|
**self.frame_theme("Formatting Help")
|
||||||
**frame_theme()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
va = 5 if self.window_split else 50
|
va = 5 if self.window_split else 50
|
||||||
|
@ -1156,7 +1229,7 @@ class App(object):
|
||||||
widget, app.loop.widget,
|
widget, app.loop.widget,
|
||||||
align=("relative", 50),
|
align=("relative", 50),
|
||||||
valign=("relative", va),
|
valign=("relative", va),
|
||||||
width=app.prefs["max_text_width"],
|
width=self.prefs["max_text_width"],
|
||||||
height=("relative", vh)
|
height=("relative", vh)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1260,8 +1333,7 @@ class App(object):
|
||||||
self.save_escape_key,
|
self.save_escape_key,
|
||||||
[mode]
|
[mode]
|
||||||
), "opt_prompt")])),
|
), "opt_prompt")])),
|
||||||
title="Set key for " + mode,
|
**self.frame_theme("Set key for " + mode)
|
||||||
**frame_theme()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
app.loop.widget = urwid.Overlay(
|
app.loop.widget = urwid.Overlay(
|
||||||
|
@ -1335,6 +1407,14 @@ class App(object):
|
||||||
account_message = "You're browsing anonymously, and cannot set account preferences."
|
account_message = "You're browsing anonymously, and cannot set account preferences."
|
||||||
account_stuff = [urwid.Button("Login/Register", on_press=self.relog)]
|
account_stuff = [urwid.Button("Login/Register", on_press=self.relog)]
|
||||||
|
|
||||||
|
theme_buttons = []
|
||||||
|
for name, theme in themes.items():
|
||||||
|
urwid.RadioButton(
|
||||||
|
theme_buttons, name,
|
||||||
|
state=theme["frame"] == self.theme["frame"],
|
||||||
|
on_state_change=self.set_theme
|
||||||
|
)
|
||||||
|
|
||||||
time_box = urwid.Text(self.timestring(time(), "time"))
|
time_box = urwid.Text(self.timestring(time(), "time"))
|
||||||
time_edit = Prompt(edit_text=self.prefs["time"])
|
time_edit = Prompt(edit_text=self.prefs["time"])
|
||||||
urwid.connect_signal(time_edit, "change", self.live_time_render, (time_box, "time"))
|
urwid.connect_signal(time_edit, "change", self.live_time_render, (time_box, "time"))
|
||||||
|
@ -1385,7 +1465,7 @@ class App(object):
|
||||||
for item in account_stuff:
|
for item in account_stuff:
|
||||||
content.append(item)
|
content.append(item)
|
||||||
|
|
||||||
for item in [urwid.Divider("-"),
|
for item in [urwid.Divider(self.theme["divider"]),
|
||||||
urwid.Text(("opt_header", "App"), 'center'),
|
urwid.Text(("opt_header", "App"), 'center'),
|
||||||
urwid.Divider(),
|
urwid.Divider(),
|
||||||
urwid.CheckBox(
|
urwid.CheckBox(
|
||||||
|
@ -1411,6 +1491,15 @@ class App(object):
|
||||||
urwid.Divider()]:
|
urwid.Divider()]:
|
||||||
content.append(item)
|
content.append(item)
|
||||||
|
|
||||||
|
for item in [urwid.Text(("button", "Border Theme")),
|
||||||
|
urwid.Text("Restart to fully apply.")]:
|
||||||
|
content.append(item)
|
||||||
|
|
||||||
|
for item in theme_buttons:
|
||||||
|
content.append(item)
|
||||||
|
|
||||||
|
content.append(urwid.Divider())
|
||||||
|
|
||||||
for item in time_stuff:
|
for item in time_stuff:
|
||||||
content.append(item)
|
content.append(item)
|
||||||
|
|
||||||
|
@ -1451,12 +1540,11 @@ class App(object):
|
||||||
for item in edit_mode:
|
for item in edit_mode:
|
||||||
content.append(item)
|
content.append(item)
|
||||||
|
|
||||||
content.append(urwid.Divider("-"))
|
content.append(urwid.Divider(self.theme["divider"]))
|
||||||
|
|
||||||
widget = OptionsMenu(
|
widget = OptionsMenu(
|
||||||
urwid.ListBox(urwid.SimpleFocusListWalker(content)),
|
urwid.ListBox(urwid.SimpleFocusListWalker(content)),
|
||||||
title="Options",
|
**self.frame_theme("Options"))
|
||||||
**frame_theme())
|
|
||||||
|
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
widget, self.loop.widget,
|
widget, self.loop.widget,
|
||||||
|
@ -1572,13 +1660,12 @@ class App(object):
|
||||||
if self.mode == "index":
|
if self.mode == "index":
|
||||||
self.set_header('Composing "{}"', title)
|
self.set_header('Composing "{}"', title)
|
||||||
self.set_footer("[{}]Abort [{}]Formatting Help [Save and quit to submit your thread]".format(
|
self.set_footer("[{}]Abort [{}]Formatting Help [Save and quit to submit your thread]".format(
|
||||||
app.prefs["edit_escapes"]["abort"].upper(), app.prefs["edit_escapes"]["fhelp"].upper()
|
self.prefs["edit_escapes"]["abort"].upper(), self.prefs["edit_escapes"]["fhelp"].upper()
|
||||||
))
|
))
|
||||||
self.loop.widget = urwid.Overlay(
|
self.loop.widget = urwid.Overlay(
|
||||||
urwid.LineBox(
|
urwid.LineBox(
|
||||||
ExternalEditor("thread_create", title=title),
|
ExternalEditor("thread_create", title=title),
|
||||||
title=self.prefs["editor"] or "",
|
**self.frame_theme(self.prefs["editor"] or "")),
|
||||||
**frame_theme()),
|
|
||||||
self.loop.widget,
|
self.loop.widget,
|
||||||
align="center",
|
align="center",
|
||||||
valign="middle",
|
valign="middle",
|
||||||
|
@ -1603,7 +1690,7 @@ class App(object):
|
||||||
urwid.AttrMap(
|
urwid.AttrMap(
|
||||||
urwid.LineBox(
|
urwid.LineBox(
|
||||||
ExternalEditor(endpoint, init_body=init_body, **params),
|
ExternalEditor(endpoint, init_body=init_body, **params),
|
||||||
**frame_theme()
|
**self.frame_theme()
|
||||||
), "bar"),
|
), "bar"),
|
||||||
self.loop.screen_size[1] // 2)])
|
self.loop.screen_size[1] // 2)])
|
||||||
|
|
||||||
|
@ -2371,18 +2458,6 @@ def log_in(relog=False):
|
||||||
sleep(0.5) # let that confirmation message shine
|
sleep(0.5) # let that confirmation message shine
|
||||||
|
|
||||||
|
|
||||||
def frame_theme(mode="default"):
|
|
||||||
"""
|
|
||||||
Return the kwargs for a frame theme.
|
|
||||||
"""
|
|
||||||
if mode == "default":
|
|
||||||
return dict(
|
|
||||||
tlcorner="@", trcorner="@", blcorner="@", brcorner="@",
|
|
||||||
tline="=", bline="=", lline="|", rline="|"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def bbjrc(mode, **params):
|
def bbjrc(mode, **params):
|
||||||
# TODO: Refactor this, the arguments and code do not properly match how this
|
# TODO: Refactor this, the arguments and code do not properly match how this
|
||||||
# function is used anymore
|
# function is used anymore
|
||||||
|
|
Loading…
Reference in New Issue