"""UI container module."""
__all__ = ["Panel2D", "TabPanel2D", "TabUI", "ImageContainer2D",
"GridUI"]
import numpy as np
import vtk
from fury.io import load_image
from fury.ui.core import UI, Rectangle2D, TextBlock2D
from fury.utils import set_input, rotate
from fury.actor import grid
[docs]class Panel2D(UI):
"""A 2D UI Panel.
Can contain one or more UI elements.
Attributes
----------
alignment : [left, right]
Alignment of the panel with respect to the overall screen.
"""
[docs] def __init__(self, size, position=(0, 0), color=(0.1, 0.1, 0.1),
opacity=0.7, align="left", border_color=(1, 1, 1),
border_width=0, has_border=False):
"""Init class instance.
Parameters
----------
size : (int, int)
Size (width, height) in pixels of the panel.
position : (float, float)
Absolute coordinates (x, y) of the lower-left corner of the panel.
color : (float, float, float)
Must take values in [0, 1].
opacity : float
Must take values in [0, 1].
align : [left, right]
Alignment of the panel with respect to the overall screen.
border_color: (float, float, float), optional
Must take values in [0, 1].
border_width: float, optional
width of the border
has_border: bool, optional
If the panel should have borders.
"""
self.has_border = has_border
self._border_color = border_color
self._border_width = border_width
super(Panel2D, self).__init__(position)
self.resize(size)
self.alignment = align
self.color = color
self.opacity = opacity
self.position = position
self._drag_offset = None
def _setup(self):
"""Setup this UI component.
Create the background (Rectangle2D) of the panel.
Create the borders (Rectangle2D) of the panel.
"""
self._elements = []
self.element_offsets = []
self.background = Rectangle2D()
if self.has_border:
self.borders = {'left': Rectangle2D(),
'right': Rectangle2D(),
'top': Rectangle2D(),
'bottom': Rectangle2D()}
self.border_coords = {'left': (0., 0.),
'right': (1., 0.),
'top': (0., 1.),
'bottom': (0., 0.)}
for key in self.borders.keys():
self.borders[key].color = self._border_color
self.add_element(self.borders[key], self.border_coords[key])
for key in self.borders.keys():
self.borders[key].on_left_mouse_button_pressed = \
self.left_button_pressed
self.borders[key].on_left_mouse_button_dragged = \
self.left_button_dragged
self.add_element(self.background, (0, 0))
# Add default events listener for this UI component.
self.background.on_left_mouse_button_pressed = self.left_button_pressed
self.background.on_left_mouse_button_dragged = self.left_button_dragged
def _get_actors(self):
"""Get the actors composing this UI component."""
actors = []
for element in self._elements:
actors += element.actors
return actors
def _add_to_scene(self, scene):
"""Add all subcomponents or VTK props that compose this UI component.
Parameters
----------
scene : scene
"""
for element in self._elements:
element.add_to_scene(scene)
def _get_size(self):
return self.background.size
[docs] def resize(self, size):
"""Set the panel size.
Parameters
----------
size : (float, float)
Panel size (width, height) in pixels.
"""
self.background.resize(size)
if self.has_border:
self.borders['left'].resize((self._border_width,
size[1]+self._border_width))
self.borders['right'].resize((self._border_width,
size[1]+self._border_width))
self.borders['top'].resize((self.size[0]+self._border_width,
self._border_width))
self.borders['bottom'].resize((self.size[0]+self._border_width,
self._border_width))
self.update_border_coords()
def _set_position(self, coords):
"""Set the lower-left corner position of this UI component.
Parameters
----------
coords: (float, float)
Absolute pixel coordinates (x, y).
"""
coords = np.array(coords)
for element, offset in self.element_offsets:
element.position = coords + offset
@property
def color(self):
return self.background.color
@color.setter
def color(self, color):
self.background.color = color
@property
def opacity(self):
return self.background.opacity
@opacity.setter
def opacity(self, opacity):
self.background.opacity = opacity
[docs] def add_element(self, element, coords, anchor="position"):
"""Add a UI component to the panel.
The coordinates represent an offset from the lower left corner of the
panel.
Parameters
----------
element : UI
The UI item to be added.
coords : (float, float) or (int, int)
If float, normalized coordinates are assumed and they must be
between [0,1].
If int, pixels coordinates are assumed and it must fit within the
panel's size.
"""
coords = np.array(coords)
if np.issubdtype(coords.dtype, np.floating):
if np.any(coords < 0) or np.any(coords > 1):
raise ValueError("Normalized coordinates must be in [0,1].")
coords = coords * self.size
if anchor == "center":
element.center = self.position + coords
elif anchor == "position":
element.position = self.position + coords
else:
msg = ("Unknown anchor {}. Supported anchors are 'position'"
" and 'center'.")
raise ValueError(msg)
self._elements.append(element)
offset = element.position - self.position
self.element_offsets.append((element, offset))
[docs] def remove_element(self, element):
"""Remove a UI component from the panel.
Parameters
----------
element : UI
The UI item to be removed.
"""
idx = self._elements.index(element)
del self._elements[idx]
del self.element_offsets[idx]
[docs] def update_element(self, element, coords, anchor="position"):
"""Update the position of a UI component in the panel.
Parameters
----------
element : UI
The UI item to be updated.
coords : (float, float) or (int, int)
New coordinates.
If float, normalized coordinates are assumed and they must be
between [0,1].
If int, pixels coordinates are assumed and it must fit within the
panel's size.
"""
self.remove_element(element)
self.add_element(element, coords, anchor)
[docs] def re_align(self, window_size_change):
"""Re-organise the elements in case the window size is changed.
Parameters
----------
window_size_change : (int, int)
New window size (width, height) in pixels.
"""
if self.alignment == "left":
pass
elif self.alignment == "right":
self.position += np.array(window_size_change)
else:
msg = "You can only left-align or right-align objects in a panel."
raise ValueError(msg)
[docs] def update_border_coords(self):
"""Update the coordinates of the borders
"""
self.border_coords = {'left': (0., 0.),
'right': (1., 0.),
'top': (0., 1.),
'bottom': (0., 0.)}
for key in self.borders.keys():
self.update_element(self.borders[key], self.border_coords[key])
@property
def border_color(self):
sides = ['left', 'right', 'top', 'bottom']
return [self.borders[side].color for side in sides]
@border_color.setter
def border_color(self, side_color):
"""Set the color of a specific border
Parameters
----------
side_color: Iterable
Iterable to pack side, color values
"""
side, color = side_color
if side.lower() not in ['left', 'right', 'top', 'bottom']:
raise ValueError(
f'{side} not a valid border side')
self.borders[side].color = color
@property
def border_width(self):
sides = ['left', 'right', 'top', 'bottom']
widths = []
for side in sides:
if side in ['left', 'right']:
widths.append(self.borders[side].width)
elif side in ['top', 'bottom']:
widths.append(self.borders[side].height)
else:
raise ValueError(
f'{side} not a valid border side')
return widths
@border_width.setter
def border_width(self, side_width):
"""Set the border width of a specific border
Parameters
----------
side_width: Iterable
Iterable to pack side, width values
"""
side, border_width = side_width
if side.lower() in ['left', 'right']:
self.borders[side].width = border_width
elif side.lower() in ['top', 'bottom']:
self.borders[side].height = border_width
else:
raise ValueError(
f'{side} not a valid border side')
[docs]class TabPanel2D(UI):
"""Render content within a Tab.
Attributes
----------
content_panel: :class: 'Panel2D'
Hold all the content UI components.
text_block: :class: 'TextBlock2D'
Renders the title of the tab.
"""
[docs] def __init__(self, position=(0, 0), size=(100, 100),
title="New Tab", color=(0.5, 0.5, 0.5), content_panel=None):
"""Init class instance.
Parameters
----------
position : (float, float)
Absolute coordinates (x, y) of the lower-left corner of the
UI component
size : (int, int)
Width and height of the pixels of this UI component.
title : str
Renders the title for Tab panel.
color : list of 3 floats
Background color of tab panel.
content_panel : Panel2D
Panel consisting of the content UI elements.
"""
self.content_panel = content_panel
self.panel_size = size
self._text_size = (int(1.0 * size[0]), size[1])
super(TabPanel2D, self).__init__()
self.title = title
self.panel.position = position
self.color = color
def _setup(self):
"""Setup this UI component.
Create parent panel.
Create Text to hold tab information.
Create Button to close tab.
"""
self.panel = Panel2D(size=self.panel_size)
self.text_block = TextBlock2D(size=self._text_size,
color=(0, 0, 0))
self.panel.add_element(self.text_block, (0, 0))
def _get_actors(self):
"""Get the actors composing this UI component."""
return self.panel.actors + self.content_panel.actors
def _add_to_scene(self, _scene):
"""Add all subcomponents or VTK props that compose this UI component.
Parameters
----------
scene : scene
"""
self.panel.add_to_scene(_scene)
self.content_panel.add_to_scene(_scene)
def _set_position(self, _coords):
"""Set the lower-left corner position of this UI component.
Parameters
----------
coords: (float, float)
Absolute pixel coordinates (x, y).
"""
self.panel.position = _coords
def _get_size(self):
self.panel.size
[docs] def resize(self, size):
"""Resize Tab panel.
Parameters
----------
size : (int, int)
New width and height in pixels.
"""
self._text_size = (int(0.7 * size[0]), size[1])
self._button_size = (int(0.3 * size[0]), size[1])
self.panel.resize(size)
self.text_block.resize(self._text_size)
@property
def color(self):
"""Return the background color of tab panel."""
return self.panel.color
@color.setter
def color(self, color):
"""Set background color of tab panel.
Parameters
----------
color : list of 3 floats.
"""
self.panel.color = color
@property
def title(self):
"""Return the title of tab panel."""
return self.text_block.message
@title.setter
def title(self, text):
"""Set the title of tab panel.
Parameters
----------
text : str
New title for tab panel.
"""
self.text_block.message = text
[docs] def add_element(self, element, coords, anchor="position"):
"""Add a UI component to the content panel.
The coordinates represent an offset from the lower left corner of the
panel.
Parameters
----------
element : UI
The UI item to be added.
coords : (float, float) or (int, int)
If float, normalized coordinates are assumed and they must be
between [0,1].
If int, pixels coordinates are assumed and it must fit within the
panel's size.
"""
element.set_visibility(False)
self.content_panel.add_element(element, coords, anchor)
[docs] def remove_element(self, element):
"""Remove a UI component from the content panel.
Parameters
----------
element : UI
The UI item to be removed.
"""
self.content_panel.remove_element(element)
[docs] def update_element(self, element, coords, anchor="position"):
"""Update the position of a UI component in the content panel.
Parameters
----------
element : UI
The UI item to be updated.
coords : (float, float) or (int, int)
New coordinates.
If float, normalized coordinates are assumed and they must be
between [0,1].
If int, pixels coordinates are assumed and it must fit within the
panel's size.
"""
self.content_panel.update_element(element, coords, anchor="position")
[docs]class TabUI(UI):
"""UI element to add multiple panels within a single window.
Attributes
----------
tabs: :class: List of 'TabPanel2D'
Stores all the instances of 'TabPanel2D' that renderes the contents.
"""
[docs] def __init__(self, position=(0, 0), size=(100, 100), nb_tabs=1,
active_color=(1, 1, 1), inactive_color=(0.5, 0.5, 0.5),
draggable=False):
"""Init class instance.
Parameters
----------
position : (float, float)
Absolute coordinates (x, y) of the lower-left corner of this
UI component.
size : (int, int)
Width and height in pixels of this UI component.
nb_tabs : int
Number of tabs to be renders.
active_color : tuple of 3 floats.
Background color of active tab panel.
inactive_color : tuple of 3 floats.
Background color of inactive tab panels.
draggable : bool
Whether the UI element is draggable or not.
"""
self.tabs = []
self.nb_tabs = nb_tabs
self.parent_size = size
self.content_size = (size[0], int(0.9 * size[1]))
self.draggable = draggable
self.active_color = active_color
self.inactive_color = inactive_color
self.active_tab_idx = None
self.collapsed = True
super(TabUI, self).__init__()
self.position = position
def _setup(self):
"""Setup this UI component.
Create parent panel.
Create tab panels.
"""
self.parent_panel = Panel2D(self.parent_size, opacity=0.0)
# Offer some standard hooks to the user.
self.on_change = lambda ui: None
self.on_collapse = lambda ui: None
for _ in range(self.nb_tabs):
content_panel = Panel2D(size=self.content_size)
content_panel.set_visibility(False)
tab_panel = TabPanel2D(content_panel=content_panel)
self.tabs.append(tab_panel)
self.update_tabs()
def _get_actors(self):
"""Get the actors composing this UI component."""
actors = []
actors += self.parent_panel.actors
for tab_panel in self.tabs:
actors += tab_panel.actors
return actors
def _add_to_scene(self, _scene):
"""Add all subcomponents or VTK props that compose this UI component.
Parameters
----------
scene : scene
"""
self.parent_panel.add_to_scene(_scene)
for tab_panel in self.tabs:
tab_panel.add_to_scene(_scene)
def _set_position(self, _coords):
"""Set the lower-left corner position of this UI component.
Parameters
----------
coords: (float, float)
Absolute pixel coordinates (x, y).
"""
self.parent_panel.position = _coords
def _get_size(self):
return self.parent_panel.size
[docs] def update_tabs(self):
"""Update position, size and callbacks for tab panels."""
self.tab_panel_size =\
(self.size[0] // self.nb_tabs, int(0.1*self.size[1]))
tab_panel_pos = [0.0, 0.9]
for tab_panel in self.tabs:
tab_panel.resize(self.tab_panel_size)
tab_panel.content_panel.position = self.position
content_panel = tab_panel.content_panel
if self.draggable:
tab_panel.panel.background.on_left_mouse_button_pressed =\
self.left_button_pressed
content_panel.background.on_left_mouse_button_pressed =\
self.left_button_pressed
tab_panel.text_block.on_left_mouse_button_pressed =\
self.left_button_pressed
tab_panel.panel.background.on_left_mouse_button_dragged =\
self.left_button_dragged
content_panel.background.on_left_mouse_button_dragged =\
self.left_button_dragged
tab_panel.text_block.on_left_mouse_button_dragged =\
self.left_button_dragged
else:
tab_panel.panel.background.on_left_mouse_button_dragged =\
lambda i_ren, _obj, _comp: i_ren.force_render
content_panel.background.on_left_mouse_button_dragged =\
lambda i_ren, _obj, _comp: i_ren.force_render
tab_panel.text_block.on_left_mouse_button_clicked =\
self.select_tab_callback
tab_panel.panel.background.on_left_mouse_button_clicked =\
self.select_tab_callback
tab_panel.text_block.on_right_mouse_button_clicked =\
self.collapse_tab_ui
tab_panel.panel.background.on_right_mouse_button_clicked =\
self.collapse_tab_ui
tab_panel.content_panel.resize(self.content_size)
self.parent_panel.add_element(tab_panel, tab_panel_pos)
self.parent_panel.add_element(tab_panel.content_panel, (0.0, 0.0))
tab_panel_pos[0] += 1/self.nb_tabs
[docs] def select_tab_callback(self, iren, _obj, _tab_comp):
"""Handle events when a tab is selected."""
for idx, tab_panel in enumerate(self.tabs):
if tab_panel.text_block is not _tab_comp and\
tab_panel.panel.background is not _tab_comp:
tab_panel.color = self.inactive_color
tab_panel.content_panel.set_visibility(False)
else:
tab_panel.color = self.active_color
tab_panel.content_panel.set_visibility(True)
self.active_tab_idx = idx
self.collapsed = False
self.on_change(self)
iren.force_render()
iren.event.abort()
[docs] def collapse_tab_ui(self, iren, _obj, _tab_comp):
"""Handle events when Tab UI is collapsed."""
if self.active_tab_idx is not None:
active_tab_panel = self.tabs[self.active_tab_idx]
active_tab_panel.color = self.inactive_color
active_tab_panel.content_panel.set_visibility(False)
self.active_tab_idx = None
self.collapsed = True
self.on_collapse(self)
iren.force_render()
iren.event.abort()
[docs] def add_element(self, tab_idx, element, coords, anchor="position"):
"""Add element to content panel after checking its existence."""
if tab_idx < self.nb_tabs and tab_idx >= 0:
self.tabs[tab_idx].add_element(element, coords, anchor)
else:
raise IndexError("Tab with index "
"{} does not exist".format(tab_idx))
[docs] def remove_element(self, tab_idx, element):
"""Remove element from content panel after checking its existence."""
if tab_idx < self.nb_tabs and tab_idx >= 0:
self.tabs[tab_idx].remove_element(element)
else:
raise IndexError("Tab with index "
"{} does not exist".format(tab_idx))
[docs] def update_element(self, tab_idx, element, coords, anchor="position"):
"""Update element on content panel after checking its existence."""
if tab_idx < self.nb_tabs and tab_idx >= 0:
self.tabs[tab_idx].update_element(element, coords, anchor)
else:
raise IndexError("Tab with index "
"{} does not exist".format(tab_idx))
[docs]class ImageContainer2D(UI):
"""A 2D container to hold an image.
Currently Supports:
- png and jpg/jpeg images
Attributes
----------
size: (float, float)
Image size (width, height) in pixels.
img : vtkImageDataGeometryFilters
The image loaded from the specified path.
"""
[docs] def __init__(self, img_path, position=(0, 0), size=(100, 100)):
"""Init class instance.
Parameters
----------
img_path : string
URL or local path of the image
position : (float, float), optional
Absolute coordinates (x, y) of the lower-left corner of the image.
size : (int, int), optional
Width and height in pixels of the image.
"""
super(ImageContainer2D, self).__init__(position)
self.img = load_image(img_path, as_vtktype=True)
self.set_img(self.img)
self.resize(size)
def _get_size(self):
lower_left_corner = self.texture_points.GetPoint(0)
upper_right_corner = self.texture_points.GetPoint(2)
size = np.array(upper_right_corner) - np.array(lower_left_corner)
return abs(size[:2])
def _setup(self):
"""Setup this UI Component.
Return an image as a 2D actor with a specific position.
Returns
-------
:class:`vtkTexturedActor2D`
"""
self.texture_polydata = vtk.vtkPolyData()
self.texture_points = vtk.vtkPoints()
self.texture_points.SetNumberOfPoints(4)
polys = vtk.vtkCellArray()
polys.InsertNextCell(4)
polys.InsertCellPoint(0)
polys.InsertCellPoint(1)
polys.InsertCellPoint(2)
polys.InsertCellPoint(3)
self.texture_polydata.SetPolys(polys)
tc = vtk.vtkFloatArray()
tc.SetNumberOfComponents(2)
tc.SetNumberOfTuples(4)
tc.InsertComponent(0, 0, 0.0)
tc.InsertComponent(0, 1, 0.0)
tc.InsertComponent(1, 0, 1.0)
tc.InsertComponent(1, 1, 0.0)
tc.InsertComponent(2, 0, 1.0)
tc.InsertComponent(2, 1, 1.0)
tc.InsertComponent(3, 0, 0.0)
tc.InsertComponent(3, 1, 1.0)
self.texture_polydata.GetPointData().SetTCoords(tc)
texture_mapper = vtk.vtkPolyDataMapper2D()
texture_mapper = set_input(texture_mapper, self.texture_polydata)
image = vtk.vtkTexturedActor2D()
image.SetMapper(texture_mapper)
self.texture = vtk.vtkTexture()
image.SetTexture(self.texture)
image_property = vtk.vtkProperty2D()
image_property.SetOpacity(1.0)
image.SetProperty(image_property)
self.actor = image
# Add default events listener to the VTK actor.
self.handle_events(self.actor)
def _get_actors(self):
"""Return the actors that compose this UI component."""
return [self.actor]
def _add_to_scene(self, scene):
"""Add all subcomponents or VTK props that compose this UI component.
Parameters
----------
scene : scene
"""
scene.add(self.actor)
[docs] def resize(self, size):
"""Resize the image.
Parameters
----------
size : (float, float)
image size (width, height) in pixels.
"""
# Update actor.
self.texture_points.SetPoint(0, 0, 0, 0.0)
self.texture_points.SetPoint(1, size[0], 0, 0.0)
self.texture_points.SetPoint(2, size[0], size[1], 0.0)
self.texture_points.SetPoint(3, 0, size[1], 0.0)
self.texture_polydata.SetPoints(self.texture_points)
def _set_position(self, coords):
"""Set the lower-left corner position of this UI component.
Parameters
----------
coords: (float, float)
Absolute pixel coordinates (x, y).
"""
self.actor.SetPosition(*coords)
[docs] def scale(self, factor):
"""Scale the image.
Parameters
----------
factor : (float, float)
Scaling factor (width, height) in pixels.
"""
self.resize(self.size * factor)
[docs] def set_img(self, img):
"""Modify the image used by the vtkTexturedActor2D.
Parameters
----------
img : imageDataGeometryFilter
"""
self.texture = set_input(self.texture, img)
[docs]class GridUI(UI):
"""Add actors in a grid and interact with them individually."""
[docs] def __init__(self,
actors, captions=None, caption_offset=(0, -100, 0),
cell_padding=0,
cell_shape="rect", aspect_ratio=16/9., dim=None,
rotation_speed=1, rotation_axis=(0, 1, 0)):
# TODO: add rotation axis None by default
self.container = grid(actors, captions=captions,
caption_offset=caption_offset,
cell_padding=cell_padding,
cell_shape=cell_shape,
aspect_ratio=aspect_ratio, dim=dim)
self._actors = []
self._actors_dict = {}
self.rotation_speed = rotation_speed
self.rotation_axis = rotation_axis
for item in self.container._items:
self._actors.append(item._items[0])
self._actors_dict[item._items[0]] = {'x': -np.inf, 'y': -np.inf}
super(GridUI, self).__init__(position=(0, 0, 0))
def _get_size(self):
return
[docs] @staticmethod
def left_click_callback(istyle, _obj, _what):
istyle.trackball_actor.OnLeftButtonDown()
istyle.force_render()
istyle.event.abort()
[docs] @staticmethod
def left_release_callback(istyle, _obj, _what):
istyle.trackball_actor.OnLeftButtonUp()
istyle.force_render()
istyle.event.abort()
[docs] @staticmethod
def mouse_move_callback(istyle, _obj, _what):
istyle.trackball_actor.OnMouseMove()
istyle.force_render()
istyle.event.abort()
[docs] @staticmethod
def left_click_callback2(istyle, obj, self):
rx, ry, rz = self.rotation_axis
clockwise_rotation = np.array([self.rotation_speed,
rx, ry, rz])
rotate(obj, clockwise_rotation)
istyle.force_render()
istyle.event.abort()
[docs] @staticmethod
def left_release_callback2(istyle, _obj, _what):
istyle.force_render()
istyle.event.abort()
[docs] @staticmethod
def mouse_move_callback2(istyle, obj, self):
if self._actors_dict[obj]['y'] == - np.inf:
iren = istyle.GetInteractor()
event_pos = iren.GetEventPosition()
self._actors_dict[obj]['y'] = event_pos[1]
else:
iren = istyle.GetInteractor()
event_pos = iren.GetEventPosition()
rx, ry, rz = self.rotation_axis
if event_pos[1] >= self._actors_dict[obj]['y']:
clockwise_rotation = np.array([-self.rotation_speed,
rx, ry, rz])
rotate(obj, clockwise_rotation)
else:
anti_clockwise_rotation = np.array(
[self.rotation_speed, rx, ry, rz])
rotate(obj, anti_clockwise_rotation)
self._actors_dict[obj]['y'] = event_pos[1]
istyle.force_render()
istyle.event.abort()
ANTICLOCKWISE_ROTATION_Y = np.array([-10, 0, 1, 0])
CLOCKWISE_ROTATION_Y = np.array([10, 0, 1, 0])
ANTICLOCKWISE_ROTATION_X = np.array([-10, 1, 0, 0])
CLOCKWISE_ROTATION_X = np.array([10, 1, 0, 0])
[docs] def key_press_callback(self, istyle, obj, _what):
has_changed = False
if istyle.event.key == "Left":
has_changed = True
for a in self._actors:
rotate(a, self.ANTICLOCKWISE_ROTATION_Y)
elif istyle.event.key == "Right":
has_changed = True
for a in self._actors:
rotate(a, self.CLOCKWISE_ROTATION_Y)
elif istyle.event.key == "Up":
has_changed = True
for a in self._actors:
rotate(a, self.ANTICLOCKWISE_ROTATION_X)
elif istyle.event.key == "Down":
has_changed = True
for a in self._actors:
rotate(a, self.CLOCKWISE_ROTATION_X)
if has_changed:
istyle.force_render()
def _setup(self):
"""Set up this UI component and the events of its actor."""
# Add default events listener to the VTK actor.
for actor in self._actors:
# self.handle_events(actor)
if self.rotation_axis is None:
self.add_callback(actor, "LeftButtonPressEvent",
self.left_click_callback)
self.add_callback(actor, "LeftButtonReleaseEvent",
self.left_release_callback)
self.add_callback(actor, "MouseMoveEvent",
self.mouse_move_callback)
else:
self.add_callback(actor, "LeftButtonPressEvent",
self.left_click_callback2)
# TODO: possibly add this too
self.add_callback(actor, "LeftButtonReleaseEvent",
self.left_release_callback2)
self.add_callback(actor, "MouseMoveEvent",
self.mouse_move_callback2)
# TODO: this is currently not running
self.add_callback(actor, "KeyPressEvent",
self.key_press_callback)
# self.on_key_press = self.key_press_callback2
def _get_actors(self):
"""Get the actors composing this UI component."""
return self._actors
def _add_to_scene(self, scene):
"""Add all subcomponents or VTK props that compose this UI component.
Parameters
----------
scene : scene
"""
self.container.add_to_scene(scene)
[docs] def resize(self, size):
"""Resize the button.
Parameters
----------
size : (float, float)
Button size (width, height) in pixels.
"""
# Update actor.
pass
def _set_position(self, coords):
"""Set the lower-left corner position of this UI component.
Parameters
----------
coords: (float, float)
Absolute pixel coordinates (x, y).
"""
# coords = (0, 0, 0)
pass
# self.actor.SetPosition(*coords)
# self.container.SetPosition(*coords)