"""Widgets are different than actors in that they can interact with events.
To do so they need as input a vtkRenderWindowInteractor also known as iren.
"""
import numpy as np
import vtk
[docs]def slider(iren, ren, callback, min_value=0, max_value=255, value=125,
label="Slider",
right_normalized_pos=(0.9, 0.5),
size=(50, 0),
label_format="%0.0lf",
color=(0.5, 0.5, 0.5),
selected_color=(0.9, 0.2, 0.1)):
""" A 2D slider widget
Parameters
----------
iren : vtkRenderWindowInteractor
Used to process events and handle them to the slider. Can also be given
by the attribute ``ShowManager.iren``.
ren : vtkRenderer or Renderer
Used to update the slider's position when the window changes. Can also
be given by the ``ShowManager.ren`` attribute.
callback : function
Function that has at least ``obj`` and ``event`` as parameters. It will
be called when the slider's bar has changed.
min_value : float
Minimum value of slider.
max_value : float
Maximum value of slider.
value :
Default value of slider.
label : str
Slider's caption.
right_normalized_pos : tuple
2d tuple holding the normalized right (X, Y) position of the slider.
size: tuple
2d tuple holding the size of the slider in pixels.
label_format: str
Formating in which the slider's value will appear for example "%0.2lf"
allows for 2 decimal values.
Returns
-------
slider : SliderObject
This object inherits from vtkSliderWidget and has additional method
called ``place`` which allows to update the position of the slider
when for example the window is resized.
"""
slider_rep = vtk.vtkSliderRepresentation2D()
slider_rep.SetMinimumValue(min_value)
slider_rep.SetMaximumValue(max_value)
slider_rep.SetValue(value)
slider_rep.SetTitleText(label)
slider_rep.GetPoint2Coordinate().SetCoordinateSystemToNormalizedDisplay()
slider_rep.GetPoint2Coordinate().SetValue(*right_normalized_pos)
coord2 = slider_rep.GetPoint2Coordinate().GetComputedDisplayValue(ren)
slider_rep.GetPoint1Coordinate().SetCoordinateSystemToDisplay()
slider_rep.GetPoint1Coordinate().SetValue(coord2[0] - size[0],
coord2[1] - size[1])
initial_window_size = ren.GetSize()
length = 0.04
width = 0.04
cap_length = 0.01
cap_width = 0.01
tube_width = 0.005
slider_rep.SetSliderLength(length)
slider_rep.SetSliderWidth(width)
slider_rep.SetEndCapLength(cap_length)
slider_rep.SetEndCapWidth(cap_width)
slider_rep.SetTubeWidth(tube_width)
slider_rep.SetLabelFormat(label_format)
slider_rep.GetLabelProperty().SetColor(*color)
slider_rep.GetTubeProperty().SetColor(*color)
slider_rep.GetCapProperty().SetColor(*color)
slider_rep.GetTitleProperty().SetColor(*color)
slider_rep.GetSelectedProperty().SetColor(*selected_color)
slider_rep.GetSliderProperty().SetColor(*color)
slider_rep.GetLabelProperty().SetShadow(0)
slider_rep.GetTitleProperty().SetShadow(0)
class SliderWidget(vtk.vtkSliderWidget):
def place(self, ren):
slider_rep = self.GetRepresentation()
coord2_norm = slider_rep.GetPoint2Coordinate()
coord2_norm.SetCoordinateSystemToNormalizedDisplay()
coord2_norm.SetValue(*right_normalized_pos)
coord2 = coord2_norm.GetComputedDisplayValue(ren)
slider_rep.GetPoint1Coordinate().SetCoordinateSystemToDisplay()
slider_rep.GetPoint1Coordinate().SetValue(coord2[0] - size[0],
coord2[1] - size[1])
window_size = ren.GetSize()
length = initial_window_size[0] * 0.04 / window_size[0]
width = initial_window_size[1] * 0.04 / window_size[1]
slider_rep.SetSliderLength(length)
slider_rep.SetSliderWidth(width)
def set_value(self, value):
return self.GetSliderRepresentation().SetValue(value)
def get_value(self):
return self.GetSliderRepresentation().GetValue()
slider = SliderWidget()
slider.SetInteractor(iren)
slider.SetRepresentation(slider_rep)
slider.SetAnimationModeToAnimate()
slider.KeyPressActivationOff()
slider.AddObserver("InteractionEvent", callback)
slider.SetEnabled(True)
# Place widget after window resizing.
def _place_widget(obj, event):
slider.place(ren)
iren.GetRenderWindow().AddObserver(
vtk.vtkCommand.StartEvent, _place_widget)
iren.GetRenderWindow().AddObserver(
vtk.vtkCommand.ModifiedEvent, _place_widget)
return slider
[docs]def text(iren, ren, callback, message="FURY",
left_down_pos=(0.8, 0.5), right_top_pos=(0.9, 0.5),
color=(1., .5, .0), opacity=1., border=False):
""" 2D text that can be clicked and process events
Parameters
----------
iren : vtkRenderWindowInteractor
Used to process events and handle them to the button. Can also be given
by the attribute ``ShowManager.iren``.
ren : vtkRenderer or Renderer
Used to update the slider's position when the window changes. Can also
be given by the ``ShowManager.ren`` attribute.
callback : function
Function that has at least ``obj`` and ``event`` as parameters. It will
be called when the button is pressed.
message : str
Message to be shown in the text widget
left_down_pos : tuple
Coordinates for left down corner of text. If float are provided,
the normalized coordinate system is used, otherwise the coordinates
represent pixel positions. Default is (0.8, 0.5).
right_top_pos : tuple
Coordinates for right top corner of text. If float are provided,
the normalized coordinate system is used, otherwise the coordinates
represent pixel positions. Default is (0.9, 0.5).
color : tuple
Foreground RGB color of text. Default is (1., .5, .0).
opacity : float
Takes values from 0 to 1. Default is 1.
border : bool
Show text border. Default is False.
Returns
-------
text : TextWidget
This object inherits from ``vtkTextWidget`` has an additional method
called ``place`` which allows to update the position of the text if
necessary.
"""
# Create the TextActor
text_actor = vtk.vtkTextActor()
text_actor.SetInput(message)
text_actor.GetTextProperty().SetColor(color)
text_actor.GetTextProperty().SetOpacity(opacity)
# Create the text representation. Used for positioning the text_actor
text_rep = vtk.vtkTextRepresentation()
text_rep.SetTextActor(text_actor)
if border:
text_rep.SetShowBorderToOn()
else:
text_rep.SetShowBorderToOff()
class TextWidget(vtk.vtkTextWidget):
def place(self, renderer):
text_rep = self.GetRepresentation()
position = text_rep.GetPositionCoordinate()
position2 = text_rep.GetPosition2Coordinate()
# The dtype of `left_down_pos` determines coordinate system type.
if np.issubdtype(np.asarray(left_down_pos).dtype, np.integer):
position.SetCoordinateSystemToDisplay()
else:
position.SetCoordinateSystemToNormalizedDisplay()
# The dtype of `right_top_pos` determines coordinate system type.
if np.issubdtype(np.asarray(right_top_pos).dtype, np.integer):
position2.SetCoordinateSystemToDisplay()
else:
position2.SetCoordinateSystemToNormalizedDisplay()
position.SetValue(*left_down_pos)
position2.SetValue(*right_top_pos)
text_widget = TextWidget()
text_widget.SetRepresentation(text_rep)
text_widget.SetInteractor(iren)
text_widget.SelectableOn()
text_widget.ResizableOff()
text_widget.AddObserver(vtk.vtkCommand.WidgetActivateEvent, callback)
# Place widget after window resizing.
def _place_widget(obj, event):
text_widget.place(ren)
iren.GetRenderWindow().AddObserver(
vtk.vtkCommand.StartEvent, _place_widget)
iren.GetRenderWindow().AddObserver(
vtk.vtkCommand.ModifiedEvent, _place_widget)
text_widget.On()
return text_widget