Skip to content

Commit

Permalink
Merge pull request #43 from mycroftw/fix-clock-minutes-issues
Browse files Browse the repository at this point in the history
Fix clock flicker issue
  • Loading branch information
mycroftw authored Oct 15, 2024
2 parents 231a05a + c1a8f83 commit e1b47ec
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 73 deletions.
80 changes: 64 additions & 16 deletions bridgeClock.wxg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<!-- generated by wxGlade 1.0.5 on Sun Dec 31 23:37:43 2023 -->
<!-- generated by wxGlade 1.0.5 on Tue Oct 15 15:16:35 2024 -->

<application class="MyApp" encoding="UTF-8" for_version="3.0" header_extension=".h" indent_amount="4" indent_symbol="space" is_template="0" language="python" mark_blocks="1" name="app" option="0" overwrite="1" path="./wxglade_out.py" source_extension=".cpp" top_window="round_timer" use_gettext="0" use_new_namespace="1">
<object class="RoundTimer" name="round_timer" base="EditFrame">
Expand Down Expand Up @@ -83,29 +83,77 @@
<underlined>0</underlined>
<face>Copperplate Gothic Bold</face>
</font>
<style>wxALIGN_CENTER_HORIZONTAL</style>
<style>wxALIGN_CENTER_HORIZONTAL|wxST_NO_AUTORESIZE</style>
<label>Round 1</label>
<attribute>1</attribute>
</object>
</object>
<object class="sizeritem">
<option>8</option>
<option>6</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticText" name="label_clock" base="EditStaticText">
<background>#b00fff</background>
<foreground>#ffff00</foreground>
<font>
<size>256</size>
<family>roman</family>
<style>normal</style>
<weight>bold</weight>
<underlined>0</underlined>
<face />
</font>
<style>wxALIGN_CENTER_HORIZONTAL</style>
<label>20:00</label>
<object class="wxBoxSizer" name="sizer_clock" base="EditBoxSizer">
<orient>wxHORIZONTAL</orient>
<attribute>1</attribute>
<object class="sizeritem">
<option>3</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticText" name="label_clock_minutes" base="EditStaticText">
<background>#b00fff</background>
<foreground>#ffff00</foreground>
<font>
<size>256</size>
<family>roman</family>
<style>normal</style>
<weight>bold</weight>
<underlined>0</underlined>
<face />
</font>
<style>wxALIGN_RIGHT|wxST_NO_AUTORESIZE</style>
<label>15</label>
<attribute>1</attribute>
</object>
</object>
<object class="sizeritem">
<option>0</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticText" name="label_clock_colon" base="EditStaticText">
<background>#b00fff</background>
<foreground>#ffff00</foreground>
<font>
<size>256</size>
<family>roman</family>
<style>normal</style>
<weight>bold</weight>
<underlined>0</underlined>
<face />
</font>
<label>:</label>
<attribute>1</attribute>
</object>
</object>
<object class="sizeritem">
<option>3</option>
<border>0</border>
<flag>wxEXPAND</flag>
<object class="wxStaticText" name="label_clock_seconds" base="EditStaticText">
<background>#b00fff</background>
<foreground>#ffff00</foreground>
<font>
<size>256</size>
<family>roman</family>
<style>normal</style>
<weight>bold</weight>
<underlined>0</underlined>
<face />
</font>
<style>wxALIGN_LEFT|wxST_NO_AUTORESIZE</style>
<label>00</label>
<attribute>1</attribute>
</object>
</object>
</object>
</object>
<object class="sizeritem">
Expand Down
112 changes: 89 additions & 23 deletions bridge_clock_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,35 @@ def _pause_game(self) -> None:
self.button_start.SetLabelText("Start")
self.button_start.SetValue(False)

def _set_bg(self, colour: str) -> None:
"""Set the background colour of the clock and round text areas."""
bc_log("in _set_bg")
for widget in (
self.label_clock_colon,
self.label_clock_minutes,
self.label_clock_seconds,
self.label_round,
):
widget.SetBackgroundColour(colour)
self.panel_1.Refresh()

@staticmethod
def _display_label(widget: wx.TextCtrl, label: str) -> None:
"""Change and resize a clock label."""
widget.SetLabelText(label)

def _display_round_label(self, label: str) -> None:
"""For ease of reading: display round text."""
self._display_label(self.label_round, label)

def _display_clock_minutes_label(self, label: str) -> None:
"""For ease of reading: display minutes."""
self._display_label(self.label_clock_minutes, label)

def _display_clock_seconds_label(self, label: str) -> None:
"""For ease of reading: change clock_seconds text."""
self._display_label(self.label_clock_seconds, label)

def _round_1(self) -> None:
"""Return to round 1."""
self.round = 1
Expand All @@ -236,9 +265,8 @@ def _break_this_round(self) -> bool:

def _update_round(self) -> None:
"""Change the round label"""
self.label_round.SetLabelText(f"Round {self.round}")
self.label_clock.SetBackgroundColour(RUN_COLOUR)
self.label_round.SetBackgroundColour(RUN_COLOUR)
self._display_round_label(f"Round {self.round}")
self._set_bg(RUN_COLOUR)
self.panel_1.Layout()

def _reset_clock(self) -> None:
Expand All @@ -252,7 +280,13 @@ def _reset_clock(self) -> None:
def _update_clock(self) -> None:
"""Display the current countdown clock value"""
time_left = self.round_end - wx.DateTime.Now()
self.label_clock.SetLabelText(time_left.Format("%M:%S"))
(minutes, seconds) = time_left.Format("%M:%S").split(":")
for time, widget in (
(minutes, self.label_clock_minutes),
(seconds, self.label_clock_seconds),
):
if time != widget.GetLabelText():
self._display_label(widget, time)
self.panel_1.Layout()

def _update_statusbar(self) -> None:
Expand Down Expand Up @@ -311,9 +345,8 @@ def _next_round(self) -> None:
def _go_to_break(self) -> None:
"""Display a visible hospitality break, and count down."""
self._in_break = True
self.label_clock.SetBackgroundColour(BREAK_COLOUR)
self.label_round.SetBackgroundColour(BREAK_COLOUR)
self.label_round.SetLabelText("NEXT ROUND IN:")
self._set_bg(BREAK_COLOUR)
self._display_round_label("NEXT ROUND IN:")
self.round_end = wx.DateTime.Now() + wx.TimeSpan.Minutes(
self.settings.break_length
)
Expand All @@ -323,8 +356,8 @@ def _go_to_break(self) -> None:
def _game_over(self) -> None:
"""Game is over."""
self._pause_game()
self.label_clock.SetLabelText("Done! ")
self._handle_resize(self.label_clock, "Done! ")
self._display_label(self.label_clock_minutes, "Game")
self._display_label(self.label_clock_seconds, "Over")
self.panel_1.Layout()
self._game_finished = True
bc_log(f"End of Game, {wx.DateTime.UNow().Format('%H:%M:%S.%l')}")
Expand All @@ -334,7 +367,10 @@ def _present_file_dialog(
) -> None:
"""Popup a file dialog for loading or saving configuration."""
dlg = wx.FileDialog(
self, message=message, defaultDir=str(Path(__file__)), wildcard=wildcard
self,
message=message,
defaultDir=str(Path(__file__) / "settings"),
wildcard=wildcard,
)
if dlg.ShowModal() == wx.ID_OK:
pth = Path(dlg.GetPath())
Expand Down Expand Up @@ -435,23 +471,53 @@ def on_close(self, event) -> None:
event.Skip()

@staticmethod
def _handle_resize(obj: wx.Control, scale_text: str) -> None:
"""Scale text to fit window."""
w, h = obj.GetSize()
tw, th = obj.GetTextExtent(scale_text).Get()
scale = min(h / th, w / tw)
new_font = obj.GetFont().Scaled(scale)
obj.SetFont(new_font)
def _rescale_text(
boundary_object: wx.Sizer | wx.Window, widget_info: Tuple[wx.Window, str]
) -> None:
"""Work out the new font size for the scaled widgets and set it in them.
Note that this works only for widgets in horizontal format; height is constant.
"""
if not widget_info:
bc_log("_rescale_text given no widgets to scale, ignoring!")
return

current_width, current_height = boundary_object.GetSize()
total_width = 0
for widget, scale_text in widget_info:
text_width, text_height = widget.GetTextExtent(scale_text).Get()
total_width += text_width
scale = min(current_width / total_width, current_height / text_height)
new_font = widget_info[0][0].GetFont().Scaled(scale)
for widget, _ in widget_info:
widget.SetFont(new_font)

def _resize_round(self) -> None:
"""Scale Round text to fit window."""
if self._in_break:
scale_text = "TIME TO NEXT:"
else:
scale_text = "ROUND 8" if self.settings.rounds < 10 else "ROUND 88"
round_widget_info = ((self.label_round, scale_text),)
self._rescale_text(self.label_round, round_widget_info)

def _resize_clock(self) -> None:
"""Scale all clock widgets to fit window."""
minutes_text = "88" if self.settings.round_length < 100 else "888"
clock_widget_info = (
(self.label_clock_minutes, minutes_text),
(self.label_clock_colon, ":"),
(self.label_clock_seconds, "88"),
)
self._rescale_text(self.sizer_clock, clock_widget_info)

def on_resize(self, event) -> None:
"""Hack to resolve sizer not auto-sizing with panel on maximize/unmaximize."""
self.Layout()
bc_log("In on_resize!")
self.sizer_1.SetDimension(self.panel_1.GetPosition(), self.panel_1.GetSize())
self._handle_resize(self.label_round, "NEXT ROUND IN:")
self._handle_resize(
self.label_clock,
"88:88" if self.settings.round_length < 100 else "888:88",
)
self._resize_round()
self._resize_clock()
self.panel_1.Layout()
event.Skip()

Expand Down Expand Up @@ -528,7 +594,7 @@ def on_goto_break(self, event):
"Break already scheduled for this round.",
style=wx.PD_AUTO_HIDE,
)
dlg.SetPosition( # show above "go to break" button)
dlg.SetPosition( # show above "go to break" button
self.button_break.GetScreenPosition() - (0, dlg.GetSize().GetHeight())
)
wx.CallLater(500, dlg.Update, 100)
Expand Down
45 changes: 36 additions & 9 deletions clock_main_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@

# -*- coding: UTF-8 -*-
#
# generated by wxGlade 1.0.5 on Sat Sep 28 17:40:11 2024
# generated by wxGlade 1.0.5 on Tue Oct 15 15:16:29 2024
#
# automated code generation - disable some pylint checks from them.
# pylint: disable=line-too-long
# wxPython being what it is...
# pylint: disable=too-many-ancestors
# pylint: disable=too-many-instance-attributes
Expand Down Expand Up @@ -86,7 +85,10 @@ def __init__(self, *args, **kwds): # pylint: disable=too-many-statements
self.sizer_1 = wx.BoxSizer(wx.VERTICAL)

self.label_round = wx.StaticText(
self.panel_1, wx.ID_ANY, "Round 1", style=wx.ALIGN_CENTER_HORIZONTAL
self.panel_1,
wx.ID_ANY,
"Round 1",
style=wx.ALIGN_CENTER_HORIZONTAL | wx.ST_NO_AUTORESIZE,
)
self.label_round.SetBackgroundColour(wx.Colour(176, 0, 255))
self.label_round.SetForegroundColour(wx.Colour(255, 255, 255))
Expand All @@ -102,17 +104,42 @@ def __init__(self, *args, **kwds): # pylint: disable=too-many-statements
)
self.sizer_1.Add(self.label_round, 1, wx.EXPAND, 0)

self.label_clock = wx.StaticText(
self.panel_1, wx.ID_ANY, "20:00", style=wx.ALIGN_CENTER_HORIZONTAL
self.sizer_clock = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_1.Add(self.sizer_clock, 6, wx.EXPAND, 0)

self.label_clock_minutes = wx.StaticText(
self.panel_1, wx.ID_ANY, "15", style=wx.ALIGN_RIGHT | wx.ST_NO_AUTORESIZE
)
self.label_clock_minutes.SetBackgroundColour(wx.Colour(176, 15, 255))
self.label_clock_minutes.SetForegroundColour(wx.Colour(255, 255, 0))
self.label_clock_minutes.SetFont(
wx.Font(
256, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, ""
)
)
self.sizer_clock.Add(self.label_clock_minutes, 3, wx.EXPAND, 0)

self.label_clock_colon = wx.StaticText(self.panel_1, wx.ID_ANY, ":")
self.label_clock_colon.SetBackgroundColour(wx.Colour(176, 15, 255))
self.label_clock_colon.SetForegroundColour(wx.Colour(255, 255, 0))
self.label_clock_colon.SetFont(
wx.Font(
256, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, ""
)
)
self.sizer_clock.Add(self.label_clock_colon, 0, wx.EXPAND, 0)

self.label_clock_seconds = wx.StaticText(
self.panel_1, wx.ID_ANY, "00", style=wx.ALIGN_LEFT | wx.ST_NO_AUTORESIZE
)
self.label_clock.SetBackgroundColour(wx.Colour(176, 15, 255))
self.label_clock.SetForegroundColour(wx.Colour(255, 255, 0))
self.label_clock.SetFont(
self.label_clock_seconds.SetBackgroundColour(wx.Colour(176, 15, 255))
self.label_clock_seconds.SetForegroundColour(wx.Colour(255, 255, 0))
self.label_clock_seconds.SetFont(
wx.Font(
256, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, 0, ""
)
)
self.sizer_1.Add(self.label_clock, 8, wx.EXPAND, 0)
self.sizer_clock.Add(self.label_clock_seconds, 3, wx.EXPAND, 0)

self.sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
self.sizer_1.Add(self.sizer_2, 0, wx.EXPAND, 0)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wxPython
Loading

0 comments on commit e1b47ec

Please sign in to comment.