Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the watcher class to UI #448

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions fury/ui/core.py
Expand Up @@ -3,6 +3,7 @@
__all__ = ["Rectangle2D", "Disk2D", "TextBlock2D"]

import abc
from fury.ui.helpers import Watcher
from warnings import warn

import numpy as np
Expand Down Expand Up @@ -83,6 +84,7 @@ def __init__(self, position=(0, 0)):
self._callbacks = []

self._setup() # Setup needed actors and sub UI components.
self.watcher = Watcher(self)
self.position = position

self.left_button_state = "released"
Expand Down
90 changes: 90 additions & 0 deletions fury/ui/helpers.py
Expand Up @@ -55,3 +55,93 @@ def clip_overflow(textblock, width, side='right'):
if side == 'left':
textblock.message = textblock.message[::-1]
return textblock.message


class Watcher:
"""Class to monitor a UI element in runtime

Attributes
----------
instance: :class: `UI`
UI element instance
show_m: :class: `ShowManager`
Show Manager
is_running: bool
Current running state of the watcher
i_ren: :class: `CustomInteractorStyle`
CustomInteractorStyle
"""

def __init__(self, object):
"""Initialize the watcher class

Parameters
----------
object: :class: `UI`
Instance of the UI element
"""
self.instance = object
self.show_m = None
self.i_ren = None
self.attr = None
self.original_attr = None
self.updated_attr = None
self.is_running = False
self.callback = None

def start(self, delay, show_m, attr):
"""Start the watcher

Parameters
----------
delay: int
delay between each update call
show_m: :class: `window.ShowManager`
show manager
attr: str
attribute to watch
"""
self.show_m = show_m
self.attr = attr
self.i_ren = self.show_m.scene.GetRenderWindow()\
.GetInteractor().GetInteractorStyle()

if hasattr(self.instance, self.attr):
self.original_attr = getattr(self.instance, attr)

if type(self.original_attr) == np.array:
self.original_attr = self.original_attr.tolist()
else:
raise(AttributeError(
f'{self.instance} has no attribute {self.attr}')
)

if delay > 0:
self.id_timer = self.show_m\
.add_timer_callback(True, delay, self.update)
else:
self.id_observer = self.i_ren.AddObserver('RenderEvent',
self.update)

self.is_running = True

def stop(self):
"""Stop the watcher
"""
if self.id_timer:
self.show_m.destroy_timer(self.id_timer)

if self.id_observer:
self.i_ren.RemoveObserver(self.id_observer)

self.is_running = False

def update(self, _obj, _evt):
""" Update the instance of UI element.
"""
self.updated_attr = getattr(self.instance, self.attr)

if self.original_attr != self.updated_attr:
self.callback(self.i_ren, _obj, self.instance)
self.original_attr = self.updated_attr
self.i_ren.force_render()