Reusable text vertical centering

This commit is contained in:
kdmukai
2021-10-01 14:26:36 -05:00
parent 66389017cf
commit b8886532f1
6 changed files with 51 additions and 29 deletions
+2 -2
View File
@@ -11,10 +11,10 @@ The `Controller` then ends up being quite stripped down. For example, there's no
* `Model`s: Store the persistent settings, the in-memory seeds, current wallet information, etc.
* `Controller`: Manages the state of the world and controls access to global resources.
* `View`s: Implementation of each screen. Prepares relevant data for display. Must also instantiate the display objects that will actually render the UI.
* `gui.templates`: Re-usable formatted UI renderers.
* `gui.screens`: Re-usable formatted UI renderers.
* `gui.components`: Basic individual UI elements that are used by the `templates` such as the top nav, buttons, button lists, text displays.
In an typical webserver context the `View` would send data to an html template (e.g. Jinja) which would then dynamically populate the page with html elements like `<input>`, `<button>`, `<img>`, etc. This is analgous to our `gui.templates` constructing a UI renderer by piecing together various `gui.components` as needed.
In an typical webserver context the `View` would send data to an html template (e.g. Jinja) which would then dynamically populate the page with html elements like `<input>`, `<button>`, `<img>`, etc. This is analgous to our `gui.screens` constructing a UI renderer by piecing together various `gui.components` as needed.
+4 -2
View File
@@ -90,7 +90,7 @@ class Controller(ConfigurableSingleton):
def start(self) -> None:
from .views import OpeningSplashView, MainMenuView
from .views import View, OpeningSplashView, MainMenuView
opening_splash = OpeningSplashView()
# opening_splash.start()
@@ -140,9 +140,11 @@ class Controller(ConfigurableSingleton):
if type(result) is tuple:
View_cls = result[0]
run_args = result[1]
else:
elif type(result) is View:
View_cls = result
run_args = {}
else:
raise Exception("Invalid View.run() return type; must be tuple(View, args_dict) or View.")
print(f"View_cls: {View_cls.__name__ if View_cls else 'None'}")
+40 -21
View File
@@ -14,6 +14,28 @@ COMPONENT_PADDING = 8
def calc_text_centering(font, text, is_text_centered, box_width, box_height, start_x, start_y):
# see: https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html#text-anchors
offset_x, offset_y = font.getoffset(text)
(box_left, box_top, box_right, box_bottom) = font.getbbox(text, anchor='lt')
ascent, descent = font.getmetrics()
# print(f"----- {text} -----")
# print(f"offset_x, offset_y: ({offset_x}, {offset_y})")
# print(f"(box_left, box_top, box_right, box_bottom): ({box_left}, {box_top}, {box_right}, {box_bottom})")
# print(f"ascent, descent: ({ascent}, {descent})")
if is_text_centered:
text_x = int((box_width - (box_right - offset_x)) / 2) - offset_x
else:
text_x = COMPONENT_PADDING
text_y = int((box_height - (ascent - offset_y)) / 2) - offset_y
return (start_x + text_x, start_y + text_y)
class Fonts(Singleton):
font_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "..", "resources", "fonts")
fonts = {}
@@ -184,21 +206,15 @@ class Button(BaseComponent):
if not self.font:
self.font = Fonts.get_font("OpenSans-SemiBold", 18)
# see: https://pillow.readthedocs.io/en/stable/handbook/text-anchors.html#text-anchors
offset_x, offset_y = self.font.getoffset(self.text)
(box_left, box_top, box_right, box_bottom) = self.font.getbbox(self.text, anchor='lt')
ascent, descent = self.font.getmetrics()
# print(f"----- {self.text} -----")
# print(f"offset_x, offset_y: ({offset_x}, {offset_y})")
# print(f"(box_left, box_top, box_right, box_bottom): ({box_left}, {box_top}, {box_right}, {box_bottom})")
# print(f"ascent, descent: ({ascent}, {descent})")
if self.is_text_centered:
self.text_x = self.screen_x + int((self.width - (box_right - offset_x)) / 2) - offset_x
else:
self.text_x = self.screen_x + COMPONENT_PADDING
self.text_y = self.screen_y + int((self.height - (ascent - offset_y)) / 2) - offset_y
(self.text_x, self.text_y) = calc_text_centering(
font=self.font,
text=self.text,
is_text_centered=self.is_text_centered,
box_width=self.width,
box_height=self.height,
start_x=self.screen_x,
start_y=self.screen_y
)
def render(self):
@@ -255,12 +271,15 @@ class TopNav(BaseComponent):
# break
# else:
# TESTING
self.text_width, self.text_height = self.font.getsize(self.text)
self.text_x = int((self.width - self.text_width) / 2)
self.text_y = int((self.height - self.text_height) / 2)
# End TESTING
(self.text_x, self.text_y) = calc_text_centering(
font=self.font,
text=self.text,
is_text_centered=True,
box_width=self.width,
box_height=self.height,
start_x=0,
start_y=0
)
def update_from_input(self, input, enter_from=None):
View File
+1 -2
View File
@@ -35,8 +35,7 @@ class SeedToolsMenuView(View):
).display()
if selected_menu_num == 0:
print("returning MainMenuView")
return (MainMenuView, {})
return MainMenuView
elif selected_menu_num == 1:
return Path.SAVE_SEED
elif selected_menu_num == 2:
+4 -2
View File
@@ -93,9 +93,11 @@ class MainMenuView(View):
if selected_menu_num == 0:
return SeedToolsMenuView
elif selected_menu_num == 1:
ret_val = Path.SIGN_TRANSACTION
return None
# ret_val = Path.SIGN_TRANSACTION
elif selected_menu_num == 2:
return self.display_settings_menu
return None
# return self.display_settings_menu
elif selected_menu_num == 3:
return PowerOffView