From 6b0c186d5b20061a4e9c58d701b7f2c0055027bc Mon Sep 17 00:00:00 2001 From: moon2 <moon2protonmail@protonmail.com> Date: Thu, 23 May 2024 14:23:05 +0200 Subject: [PATCH] tiny bugfixes, partial redraw for mixer + help --- python_payload/st3m/ui/elements/overlays.py | 34 +++-- python_payload/st3m/ui/help.py | 65 ++++---- python_payload/st3m/ui/mixer.py | 159 +++++++++++--------- 3 files changed, 151 insertions(+), 107 deletions(-) diff --git a/python_payload/st3m/ui/elements/overlays.py b/python_payload/st3m/ui/elements/overlays.py index b8efd73ae0..f277c4ee78 100644 --- a/python_payload/st3m/ui/elements/overlays.py +++ b/python_payload/st3m/ui/elements/overlays.py @@ -92,7 +92,7 @@ class Region: ) def copy(self, rect): - self.set(rect.x0, rect.x1, rect.y0, rect.y1) + self.set(rect.x0, rect.y0, rect.x1, rect.y1) def __eq__(self, rect): return ( @@ -160,6 +160,8 @@ class Compositor(Responder): if kind == OverlayKind.SystemMenu: if not self._system_menu.active: continue + elif self._system_menu.sub and kind < OverlayKind.SystemMenu: + continue elif not self.enabled.get(kind, False): continue if kind == OverlayKind.Indicators and not self.main.wants_icons(): @@ -266,6 +268,11 @@ class Compositor(Responder): or redraw or self._enabled[i] not in self._last_enabled ) + # catching partial redraws here + if self._system_menu.sub: + if not self._clip_rect.is_empty(): + self._system_menu.sub.full_redraw = True + self._clip_rect.add(-120, -120, 120, 120) for i in range(len(self._last_enabled)): redraw = redraw or self._last_enabled[i] not in self._enabled self._last_enabled = self._enabled @@ -276,12 +283,13 @@ class Compositor(Responder): redraw = True if not redraw: return - octx = sys_display.ctx(sys_display.osd) - octx.save() - octx.compositing_mode = octx.CLEAR self._last_clip.add_region(self._clip_rect) - self._last_clip.fill(octx) - octx.restore() + octx = sys_display.ctx(sys_display.osd) + if not self._system_menu.sub: + octx.save() + octx.compositing_mode = octx.CLEAR + self._last_clip.fill(octx) + octx.restore() for i in range(len(self._enabled)): self._enabled[i].draw(octx) sys_display.update(octx) @@ -471,7 +479,9 @@ class OverlaySystemMenu(Overlay): def needs_redraw(self, rect: Region) -> bool: if self.sub is not None: - rect.add(-120, -120, 120, 120) + pass + # adding it later in the pipeline for partial redraw reasons + # rect.add(-120, -120, 120, 120) else: rect.add(-44, -49, 44, 49) return True @@ -551,8 +561,6 @@ class OverlayVolume(Overlay): return if self._showing is not None: self._showing -= delta_ms - if self._showing < 0: - self._showing = None if not self.override_os_button_volume: prs = ( @@ -594,7 +602,7 @@ class OverlayVolume(Overlay): # Foreground opacity = self._showing / 200 - opacity = min(opacity, 1) + opacity = max(min(opacity, 1), 0) muted = self._muted if muted: @@ -632,9 +640,11 @@ class OverlayVolume(Overlay): ctx.fill() def needs_redraw(self, rect: Region) -> bool: - if self._showing: + if self._showing is not None: rect.add(-40, -40, 40, 40) - return self._showing + if self._showing < 0: + self._showing = None + return self._showing is not None class Icon(Responder): diff --git a/python_payload/st3m/ui/help.py b/python_payload/st3m/ui/help.py index 777d88adeb..625c54e1bd 100644 --- a/python_payload/st3m/ui/help.py +++ b/python_payload/st3m/ui/help.py @@ -15,6 +15,7 @@ class Help(Responder): self.x = -self.line_width / 2 self.y = -80 self.lines = None + self.full_redraw = True def think(self, ins, delta_ms): if self.lines is None: @@ -23,6 +24,8 @@ class Help(Responder): ud_dir -= self.input.buttons.app.left.pressed ud_dir += self.input.buttons.app.right.repeated ud_dir -= self.input.buttons.app.left.repeated + if ud_dir: + self.full_redraw = True self.y += -ud_dir * self.line_height * self.line_height_steps if self.y > -80: self.y = -80 @@ -31,32 +34,42 @@ class Help(Responder): self.y = min_y def draw(self, ctx): - ctx.rgb(0, 0, 0) - ctx.rectangle(-120, -120, 240, 240).fill() - ctx.rgb(0x81 / 255, 0xCD / 255, 0xC6 / 255) - ctx.move_to(0, self.y) - ctx.text_align = ctx.CENTER - if not (self.y < -120): - ctx.font_size = 24 - ctx.text("~ help ~") - ctx.font_size = 16 - offset = self.line_height - if not isinstance(self.help_text, str): - offset += self.line_height - ctx.move_to(0, self.y + offset) - ctx.text("no help found :/") - return - ctx.text_align = ctx.LEFT - if self.lines is None: - self.lines = wrap_text(self.help_text, self.line_width, ctx) - for line in self.lines: - offset += self.line_height - if (self.y + offset) < (-120): - continue - elif (self.y + offset) > (120 + self.line_height): - break - ctx.move_to(self.x, self.y + offset) - ctx.text(line) + if self.full_redraw: + ctx.rgb(0, 0, 0) + ctx.rectangle(-120, -120, 240, 240).fill() + ctx.rgb(0x81 / 255, 0xCD / 255, 0xC6 / 255) + ctx.move_to(0, self.y) + ctx.text_align = ctx.CENTER + if not (self.y < -120): + ctx.font_size = 24 + ctx.text("~ help ~") + ctx.font_size = 16 + offset = self.line_height + if not isinstance(self.help_text, str): + offset += self.line_height + ctx.move_to(0, self.y + offset) + ctx.text("no help found :/") + return + ctx.text_align = ctx.LEFT + if self.lines is None: + self.lines = wrap_text(self.help_text, self.line_width, ctx) + num_lines = len(self.lines) + x = 0 + while x < num_lines: + line = self.lines[x] + offset += self.line_height + diff = -120 - self.y - offset + if diff > 0: + jump = max(1, diff // self.line_height) + offset += self.line_height * (jump - 1) + x += jump + continue + elif (self.y + offset) > (120 + self.line_height): + break + if line: + ctx.move_to(self.x, self.y + offset) + ctx.text(line) + x += 1 def on_exit(self): pass diff --git a/python_payload/st3m/ui/mixer.py b/python_payload/st3m/ui/mixer.py index aa32a7ac88..fdae6eb58f 100644 --- a/python_payload/st3m/ui/mixer.py +++ b/python_payload/st3m/ui/mixer.py @@ -5,10 +5,13 @@ import media def recall_blm_channel_stats(blm_chan): + print(blm_chan) if blm_chan.free: + print("wha-!") return if blm_chan.name in session_channel_vol_mute: - chan = bl00mboxChannel(SysChannel(blm_chan)) + print("whee") + chan = bl00mboxChannel(bl00mbox.SysChannel(blm_chan)) vol, mute = session_channel_vol_mute[chan.get_name()] if mute: vol = -math.inf @@ -141,6 +144,7 @@ class HighlightColors: class AudioMixer(Responder): def __init__(self, inputcontroller): + self.full_redraw = True self.input = inputcontroller self._pos = 0 self.chan_width = 46 # scaling factor between _pos and draw_pos @@ -203,6 +207,7 @@ class AudioMixer(Responder): lr_dir -= self.input.buttons.app.left.pressed num_chans = len(self._chans) if self.input.buttons.app.middle.pressed: + self.full_redraw = True self._editing_channel += 1 self._editing_channel %= 3 if self._editing_channel == 1: @@ -233,6 +238,8 @@ class AudioMixer(Responder): lr_dir -= self.input.buttons.app.left.repeated self._pos += lr_dir self._pos %= num_chans + if lr_dir: + self.full_redraw = True self.acc_ms += delta_ms if num_chans > 2: target = min(num_chans - 2, max(self._pos, 1)) @@ -243,21 +250,26 @@ class AudioMixer(Responder): target *= self.chan_width self.acc_ms += delta_ms + pos_prev = self._draw_pos[0] while self.acc_ms > 0: self.acc_ms -= 20 self._draw_pos[2] = (target - self._draw_pos[0]) / 2 self._draw_pos[2] -= self._draw_pos[1] self._draw_pos[1] += self._draw_pos[2] / 10 self._draw_pos[0] += self._draw_pos[1] / 10 + self._draw_pos[0] = round(self._draw_pos[0], 1) + if not self.full_redraw: + self.full_redraw = self._draw_pos[0] != pos_prev def draw(self, ctx): - ctx.rgb(0, 0, 0) - ctx.rectangle(-120, -120, 240, 240).fill() ctx.text_align = ctx.CENTER ctx.rgb(0x81 / 255, 0xCD / 255, 0xC6 / 255) - ctx.font_size = 24 - ctx.move_to(0, -90) - ctx.text("~ mixer ~") + if self.full_redraw: + ctx.rgb(0, 0, 0) + ctx.rectangle(-120, -120, 240, 240).fill() + ctx.move_to(0, -90) + ctx.font_size = 24 + ctx.text("~ mixer ~") for x, chan in enumerate(self._chans): xpos = x * self.chan_width - self._draw_pos[0] if abs(xpos) > 120 + self.chan_width / 2: @@ -271,6 +283,8 @@ class AudioMixer(Responder): ctx.translate(xpos, (1 - highlight) * 2) self.draw_channel(colors, ctx, chan, highlight) ctx.restore() + if self.full_redraw: + self.full_redraw = False def draw_channel(self, colors, ctx, chan, highlight): ctx.text_align = ctx.RIGHT @@ -278,61 +292,81 @@ class AudioMixer(Responder): chan_len = 160 chan_upper = -80 chan_width = self.chan_width - 4 - ctx.round_rectangle(-chan_width / 2, chan_upper, chan_width, chan_len, 2).fill() - - ctx.font_size = 16 - # draw name - ctx.save() - ctx.rgb(*colors.name) - ctx.translate(0, 0) - ctx.rotate(-math.tau / 4) - ctx.move_to(-chan_upper - 4, -chan_width / 2 + 14) - name = chan.get_name() - while ctx.text_width(name) > 110: - name = name[:-1] - ctx.text(name) - ctx.restore() - - # draw number of plugins (bl00mbox only) - num_plugins = chan.get_num_plugins() - if num_plugins is not None: - ctx.font_size = 12 - ctx.rgb(*[0.7 * x for x in colors.bg]) - ctx.move_to(chan_width / 2 - 3, chan_upper + 12) - ctx.text(str(num_plugins)) - - # volume - ctx.rgb(0, 0, 0) - vol = chan.get_vol_dB() - ctx.move_to(chan_width / 2 - 3, 75) - ctx.font_size = 14 - ctx.text(f"{vol:.1f}") - - ctx.rgb(0, 0, 0) len_bar = chan_len - 38 bar_bottom = chan_upper + chan_len - 21 - ctx.rectangle(chan_width / 2 - 13, bar_bottom - len_bar, 9, len_bar).fill() - ctx.move_to(chan_width / 2 - 13, bar_bottom - len_bar * 5 / 7) - ctx.rel_line_to(-5, 0).stroke() - # vol bar - ctx.rgb(*colors.vol_bar) - vol_bar_len = (vol + 50) / 70 - vol_bar_len = min(1, max(0, vol_bar_len)) - vol_bar_len *= len_bar - ctx.rectangle( - chan_width / 2 - 12, bar_bottom - vol_bar_len, 3, vol_bar_len - ).fill() - if self._editing_channel == 1 and highlight: - ctx.rgb(0, 1, 0) - ctx.move_to(6, bar_bottom - vol_bar_len) - ctx.rel_line_to(-5, -3) - ctx.rel_line_to(0, 6) - ctx.rel_line_to(5, -3) - ctx.fill() + if self.full_redraw: + ctx.round_rectangle( + -chan_width / 2, chan_upper, chan_width, chan_len, 2 + ).fill() + # draw name + ctx.font_size = 16 + ctx.save() + ctx.rgb(*colors.name) + ctx.translate(0, 0) + ctx.rotate(-math.tau / 4) + ctx.move_to(-chan_upper - 4, -chan_width / 2 + 14) + name = chan.get_name() + while ctx.text_width(name) > 110: + name = name[:-1] + ctx.text(name) + ctx.restore() + + # draw number of plugins (bl00mbox only) + num_plugins = chan.get_num_plugins() + if num_plugins is not None: + ctx.font_size = 12 + ctx.rgb(*[0.7 * x for x in colors.bg]) + ctx.move_to(chan_width / 2 - 3, chan_upper + 12) + ctx.text(str(num_plugins)) + + # volume + vol = chan.get_vol_dB() + ctx.rgb(0, 0, 0) + ctx.move_to(chan_width / 2 - 3, 75) + ctx.font_size = 14 + ctx.text(f"{vol:.1f}") + + # mute + mute = int(chan.get_mute()) + ctx.rgb(*(colors.mute_bg[mute])) + ctx.rectangle(-chan_width / 2 + 3, 41, 18, 18).fill() + ctx.text_align = ctx.CENTER + ctx.font_size = 16 + ctx.move_to(-chan_width / 2 + 12, 55) + ctx.rgb(*(colors.mute_fg[mute])) + ctx.text("M") + if self._editing_channel == 2 and highlight: + ctx.rgb(0, 1, 0) + ctx.round_rectangle(-chan_width / 2 + 3, 41, 18, 18, 2).stroke() + + ctx.rgb(0, 0, 0) + ctx.rectangle(chan_width / 2 - 13, bar_bottom - len_bar, 9, len_bar).fill() + ctx.move_to(chan_width / 2 - 13, bar_bottom - len_bar * 5 / 7) + ctx.rel_line_to(-5, 0).stroke() + + # vol bar + ctx.rgb(*colors.vol_bar) + vol_bar_len = (vol + 50) / 70 + vol_bar_len = min(1, max(0, vol_bar_len)) + vol_bar_len *= len_bar + ctx.rectangle( + chan_width / 2 - 12, bar_bottom - vol_bar_len, 3, vol_bar_len + ).fill() + + if self._editing_channel == 1 and highlight: + ctx.rgb(0, 1, 0) + ctx.move_to(6, bar_bottom - vol_bar_len) + ctx.rel_line_to(-5, -3) + ctx.rel_line_to(0, 6) + ctx.rel_line_to(5, -3) + ctx.fill() + + ctx.rgb(0, 0, 0) + ctx.rectangle(chan_width / 2 - 9, bar_bottom - len_bar, 5, len_bar).fill() # rms bar # hmmmh do we reuse the 0dB notch for normalization...? - rms = chan.get_rms_dB() + 11 + rms = chan.get_rms_dB() + 12 ctx.rgb(*colors.rms_bar) rms_bar_len = (rms + 50) / 70 rms_bar_len = min(1, max(0, rms_bar_len)) @@ -341,19 +375,6 @@ class AudioMixer(Responder): chan_width / 2 - 8, bar_bottom - rms_bar_len, 3, rms_bar_len ).fill() - # mute - mute = int(chan.get_mute()) - ctx.rgb(*(colors.mute_bg[mute])) - ctx.rectangle(-chan_width / 2 + 3, 41, 18, 18).fill() - ctx.text_align = ctx.CENTER - ctx.font_size = 16 - ctx.move_to(-chan_width / 2 + 12, 55) - ctx.rgb(*(colors.mute_fg[mute])) - ctx.text("M") - if self._editing_channel == 2 and highlight: - ctx.rgb(0, 1, 0) - ctx.round_rectangle(-chan_width / 2 + 3, 41, 18, 18, 2).stroke() - def on_exit(self): for chan in self._chans: if isinstance(chan, bl00mboxChannel): -- GitLab