mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
Reusable text vertical centering
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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'}")
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user