Skip to content

Commit

Permalink
Merge pull request #1298 from dmreagan/textactor2d
Browse files Browse the repository at this point in the history
Make TextActor2D extend UI instead of object
  • Loading branch information
Garyfallidis committed Aug 6, 2017
2 parents a0df597 + f92f06b commit 5595842
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 69 deletions.
63 changes: 34 additions & 29 deletions dipy/viz/tests/test_ui.py
Expand Up @@ -150,11 +150,17 @@ def modify_button_callback(i_ren, obj, button):
button_test.color = button_color
# /Button

# TextBlock
text_block_test = ui.TextBlock2D()
text_block_test.message = 'TextBlock'
text_block_test.color = (0, 0, 0)

# Panel
panel = ui.Panel2D(center=(440, 90), size=(300, 150),
color=(1, 1, 1), align="right")
panel.add_element(rectangle_test, 'absolute', (580, 150))
panel.add_element(button_test, 'relative', (0.2, 0.2))
panel.add_element(text_block_test, 'relative', (0.7, 0.7))
npt.assert_raises(ValueError, panel.add_element, another_rectangle_test,
'error_string', (1, 2))
# /Panel
Expand Down Expand Up @@ -217,37 +223,36 @@ def test_ui_textbox(recording=False):

@npt.dec.skipif(not have_vtk or skip_it)
@xvfb_it
def test_text_actor_2d():
# TextActor2D
text_actor = ui.TextActor2D()
text_actor.message = "Hello World!"
npt.assert_equal("Hello World!", text_actor.message)
text_actor.font_size = 18
npt.assert_equal("18", str(text_actor.font_size))
text_actor.font_family = "Arial"
npt.assert_equal("Arial", text_actor.font_family)
def test_text_block_2d():
# TextBlock2D
text_block = ui.TextBlock2D()
text_block.message = "Hello World!"
npt.assert_equal("Hello World!", text_block.message)
text_block.font_size = 18
npt.assert_equal("18", str(text_block.font_size))
text_block.font_family = "Arial"
npt.assert_equal("Arial", text_block.font_family)
with npt.assert_raises(ValueError):
text_actor.font_family = "Verdana"
text_actor.justification = "left"
text_actor.justification = "right"
text_actor.justification = "center"
npt.assert_equal("Centered", text_actor.justification)
text_block.font_family = "Verdana"
text_block.justification = "left"
text_block.justification = "right"
text_block.justification = "center"
npt.assert_equal("Centered", text_block.justification)
with npt.assert_raises(ValueError):
text_actor.justification = "bottom"
text_actor.bold = True
text_actor.bold = False
npt.assert_equal(False, text_actor.bold)
text_actor.italic = True
text_actor.italic = False
npt.assert_equal(False, text_actor.italic)
text_actor.shadow = True
text_actor.shadow = False
npt.assert_equal(False, text_actor.shadow)
text_actor.color = (1, 0, 0)
npt.assert_equal((1, 0, 0), text_actor.color)
text_actor.position = (2, 3)
npt.assert_equal((2, 3), text_actor.position)
# /TextActor2D
text_block.justification = "bottom"
text_block.bold = True
text_block.bold = False
npt.assert_equal(False, text_block.bold)
text_block.italic = True
text_block.italic = False
npt.assert_equal(False, text_block.italic)
text_block.shadow = True
text_block.shadow = False
npt.assert_equal(False, text_block.shadow)
text_block.color = (1, 0, 0)
npt.assert_equal((1, 0, 0), text_block.color)
text_block.position = (2, 3)
npt.assert_equal((2, 3), text_block.position)


@npt.dec.skipif(not have_vtk or skip_it)
Expand Down
68 changes: 44 additions & 24 deletions dipy/viz/ui.py
Expand Up @@ -19,6 +19,7 @@

TWO_PI = 2 * np.pi


class UI(object):
""" An umbrella class for all UI elements.
Expand All @@ -28,11 +29,12 @@ class UI(object):
Attributes
----------
ui_param : object
This is an attribute that can be passed to the UI object by the interactor.
This is an attribute that can be passed to the UI object by the
interactor.
ui_list : list of :class:`UI`
This is used when there are more than one UI elements inside
a UI element. They're all automatically added to the renderer at the same time
as this one.
a UI element. They're all automatically added to the renderer at the
same time as this one.
parent_ui: UI
Reference to the parent UI element. This is useful of there is a parent
UI element and its reference needs to be passed down to the child.
Expand Down Expand Up @@ -212,7 +214,8 @@ def __init__(self, icon_fnames, size=(30, 30)):
def __build_icons(self, icon_fnames):
""" Converts file names to vtkImageDataGeometryFilters.
A pre-processing step to prevent re-read of file names during every state change.
A pre-processing step to prevent re-read of file names during every
state change.
Parameters
----------
Expand Down Expand Up @@ -670,7 +673,7 @@ def re_align(self, window_size_change):
raise ValueError("You can only left-align or right-align objects in a panel.")


class TextActor2D(object):
class TextBlock2D(UI):
""" Wraps over the default vtkTextActor and helps setting the text.
Contains member functions for text formatting.
Expand All @@ -682,6 +685,7 @@ class TextActor2D(object):
"""

def __init__(self):
super(TextBlock2D, self).__init__()
self.actor = vtkTextActor()

def get_actor(self):
Expand All @@ -694,6 +698,12 @@ def get_actor(self):
"""
return self.actor

def get_actors(self):
""" Returns the actors that compose this UI component.
"""
return [self.actor]

@property
def message(self):
""" Gets message from the text.
Expand Down Expand Up @@ -924,6 +934,16 @@ def position(self, position):
"""
self.actor.SetPosition(*position)

def set_center(self, position):
""" Sets the text center to position.
Parameters
----------
position : (float, float)
"""
self.position = position


class TextBox2D(UI):
""" An editable 2D text box that behaves as a UI component.
Expand Down Expand Up @@ -1029,26 +1049,26 @@ def build_actor(self, text, position, color, font_size,
Returns
-------
:class:`vtkActor2d`
"""
text_actor = TextActor2D()
text_actor.position = position
text_actor.message = text
text_actor.font_size = font_size
text_actor.font_family = font_family
text_actor.justification = justification
text_actor.bold = bold
text_actor.italic = italic
text_actor.shadow = shadow
:class:`TextBlock2D`
"""
text_block = TextBlock2D()
text_block.position = position
text_block.message = text
text_block.font_size = font_size
text_block.font_family = font_family
text_block.justification = justification
text_block.bold = bold
text_block.italic = italic
text_block.shadow = shadow
if vtk.vtkVersion.GetVTKSourceVersion().split(' ')[-1] <= "6.2.0":
pass
else:
text_actor.actor.GetTextProperty().SetBackgroundColor(1, 1, 1)
text_actor.actor.GetTextProperty().SetBackgroundOpacity(1.0)
text_actor.color = color
text_block.actor.GetTextProperty().SetBackgroundColor(1, 1, 1)
text_block.actor.GetTextProperty().SetBackgroundOpacity(1.0)
text_block.color = color

return text_actor
return text_block

def set_message(self, message):
""" Set custom text to textbox.
Expand Down Expand Up @@ -1331,7 +1351,7 @@ class LineSlider2D(UI):
The line on which the slider disk moves.
slider_disk : :class:`vtkActor`
The moving slider disk.
text : :class:`TextActor2D`
text : :class:`TextBlock2D`
The text that shows percentage.
"""
Expand Down Expand Up @@ -1433,7 +1453,7 @@ def build_actors(self, inner_radius, outer_radius, text_size):
# /Slider Disk

# Slider Text
self.text = TextActor2D()
self.text = TextBlock2D()
self.text.position = (self.left_x_position - 50, self.center[1] - 10)
self.text.font_size = text_size
# /Slider Text
Expand Down Expand Up @@ -1707,7 +1727,7 @@ def build_actors(self):
self.handle = vtk.vtkActor2D()
self.handle.SetMapper(handle_mapper)

self.text = TextActor2D()
self.text = TextBlock2D()
offset = np.array((16., 8.))
self.text.position = self.center - offset
self.text.font_size = self.text_size
Expand Down
53 changes: 37 additions & 16 deletions doc/examples/viz_advanced.py
Expand Up @@ -148,21 +148,25 @@
line_slider_z = ui.LineSlider2D(min_value=0,
max_value=shape[2] - 1,
initial_value=shape[2] / 2,
text_template="{value:.0f}")
text_template="{value:.0f}",
length=140)

line_slider_x = ui.LineSlider2D(min_value=0,
max_value=shape[0] - 1,
initial_value=shape[0] / 2,
text_template="{value:.0f}")
text_template="{value:.0f}",
length=140)

line_slider_y = ui.LineSlider2D(min_value=0,
max_value=shape[1] - 1,
initial_value=shape[1] / 2,
text_template="{value:.0f}")
text_template="{value:.0f}",
length=140)

opacity_slider = ui.LineSlider2D(min_value=0.0,
max_value=1.0,
initial_value=slicer_opacity)
initial_value=slicer_opacity,
length=140)

"""
Now we will write callbacks for the sliders and register them.
Expand Down Expand Up @@ -207,10 +211,27 @@ def change_opacity(i_ren, obj, slider):
We'll also create text labels to identify the sliders.
"""

line_slider_label_z = ui.TextBox2D(text="Z Slice", width=50, height=20)
line_slider_label_x = ui.TextBox2D(text="X Slice", width=50, height=20)
line_slider_label_y = ui.TextBox2D(text="Y Slice", width=50, height=20)
opacity_slider_label = ui.TextBox2D(text="Opacity", width=50, height=20)

def build_label(text):
label = ui.TextBlock2D()
label.message = text
label.font_size = 18
label.font_family = 'Arial'
label.justification = 'left'
label.bold = False
label.italic = False
label.shadow = False
label.actor.GetTextProperty().SetBackgroundColor(0, 0, 0)
label.actor.GetTextProperty().SetBackgroundOpacity(0.0)
label.color = (1, 1, 1)

return label


line_slider_label_z = build_label(text="Z Slice")
line_slider_label_x = build_label(text="X Slice")
line_slider_label_y = build_label(text="Y Slice")
opacity_slider_label = build_label(text="Opacity")

"""
Now we will create a ``panel`` to contain the sliders and labels.
Expand All @@ -223,14 +244,14 @@ def change_opacity(i_ren, obj, slider):
opacity=0.1,
align="right")

panel.add_element(line_slider_label_x, 'relative', (0.1, 0.8))
panel.add_element(line_slider_x, 'relative', (0.5, 0.8))
panel.add_element(line_slider_label_y, 'relative', (0.1, 0.6))
panel.add_element(line_slider_y, 'relative', (0.5, 0.6))
panel.add_element(line_slider_label_z, 'relative', (0.1, 0.4))
panel.add_element(line_slider_z, 'relative', (0.5, 0.4))
panel.add_element(opacity_slider_label, 'relative', (0.1, 0.2))
panel.add_element(opacity_slider, 'relative', (0.5, 0.2))
panel.add_element(line_slider_label_x, 'relative', (0.1, 0.75))
panel.add_element(line_slider_x, 'relative', (0.65, 0.8))
panel.add_element(line_slider_label_y, 'relative', (0.1, 0.55))
panel.add_element(line_slider_y, 'relative', (0.65, 0.6))
panel.add_element(line_slider_label_z, 'relative', (0.1, 0.35))
panel.add_element(line_slider_z, 'relative', (0.65, 0.4))
panel.add_element(opacity_slider_label, 'relative', (0.1, 0.15))
panel.add_element(opacity_slider, 'relative', (0.65, 0.2))

show_m.ren.add(panel)

Expand Down

0 comments on commit 5595842

Please sign in to comment.