diff --git a/mpfmc/uix/display.py b/mpfmc/uix/display.py index 74cd30b2..5266bb60 100644 --- a/mpfmc/uix/display.py +++ b/mpfmc/uix/display.py @@ -2,6 +2,7 @@ from typing import List, Union, Optional from kivy.uix.floatlayout import FloatLayout +from kivy.graphics.instructions import Callback from kivy.clock import Clock from kivy.uix.screenmanager import (ScreenManager, NoTransition, @@ -18,7 +19,6 @@ from mpfmc.uix.widget import WidgetContainer, Widget from mpfmc.uix.slide import Slide - MYPY = False if MYPY: # pragma: no cover from mpfmc.core.mc import MpfMc @@ -588,7 +588,6 @@ def _post_active_slide_event(self, dt) -> None: class DisplayOutput(Scatter): - """Show a display as a widget.""" def __init__(self, parent: "KivyWidget", display: "Display", **kwargs): @@ -627,7 +626,7 @@ def add_display_source(self, widget): """ if not isinstance(widget, Display): raise KivyWidgetException( - 'add_widget_multi_parent() can be used only with instances' + 'add_display_source() can be used only with instances' ' of the Display class.') widget = widget.__self__ @@ -635,6 +634,16 @@ def add_display_source(self, widget): raise KivyWidgetException( 'Widget instances cannot be added to themselves.') + # This DisplayOutput instance will become the actual parent of the display. Other + # DisplayOutput instances connected to the same display will be stored in a list + # of parents and will be redrawn whenever this instance is redrawn. + + if widget.parents: + previous_parent = widget.parents[-1] + previous_parent.canvas.after.clear() + with self.canvas.after: # pylint: disable=not-context-manager + Callback(self.on_draw_display_source) + widget.parent = self widget.parents.append(self) @@ -648,15 +657,33 @@ def remove_display_source(self, widget): 'remove_display_source() can be used only with instances' ' of the Display class.') widget.parents.remove(self) - widget.parent = None + self.canvas.after.clear() + + if widget.parents: + widget.parent = widget.parents[-1] + + if len(widget.parents) > 1: + with widget.parent.canvas.after: + Callback(widget.parent.on_draw_display_source) + else: + widget.parent = None + self.canvas.remove(widget.container.canvas) def __repr__(self) -> str: # pragma: no cover try: - return ''.format( - self.size, self.pos, self.display.name) + return ''.format( + self.size, self.pos, self.display.name, id(self)) except AttributeError: - return ''.format(self.size) + return ''.format(self.size, id(self)) + + def on_draw_display_source(self, instr): + """Callback function when primary display source is redrawn.""" + del instr + + for display_source in self.display.parents: + if display_source != self: + display_source.canvas.ask_update() def on_parent_resize(self, *args): """Fit to parent on resize."""