-
Notifications
You must be signed in to change notification settings - Fork 285
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
Button and Slider Widgets #844
Open
amalss18
wants to merge
9
commits into
enthought:master
Choose a base branch
from
amalss18:widgets
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
96b3376
added basic functions for the slider widget
amalss18 8d07738
major changes
amalss18 e2a261a
major refactoring
amalss18 30cfac2
added button widget
amalss18 eb5dcbc
minor chane
amalss18 6295c7a
added new widget_source
amalss18 b8273f3
added traits objects
amalss18 aeb67c2
minor fix
amalss18 0361f5b
removed error with color and other small mods
amalss18 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from mayavi.core.source import Source | ||
|
||
|
||
class WidgetSource(Source): | ||
############################################## | ||
# 'Pipeline Interface'# | ||
############################################## | ||
def add_actors(self): | ||
"""Adds `self.widgets` to the scene. | ||
""" | ||
if not self._actors_added: | ||
self._update() | ||
self._actors_added = True | ||
if not self.visible: | ||
self._visible_changed(self.visible) | ||
self.scene.render() | ||
|
||
def remove_actors(self): | ||
"""Removes `self.widgets` from the scene. | ||
""" | ||
if self._actors_added: | ||
self.scene.remove_widgets(self.widgets) | ||
self._actors_added = False | ||
self.scene.render() | ||
|
||
###################################################################### | ||
# Non-public interface | ||
###################################################################### | ||
|
||
def _update(self): | ||
if self.scene is None: | ||
return | ||
|
||
def _scene_changed(self, old, new): | ||
if self._actors_added: | ||
old.remove_wdigets(self.widgets) | ||
self._update() | ||
|
||
def _actors_changed(self, old, new): | ||
if self._actors_added: | ||
self.scene.remove_widgets(old) | ||
# The widgets are added automatically when the importer | ||
# does a read. | ||
self.scene.render() | ||
|
||
def _actors_items_changed(self, list_event): | ||
if self._actors_added: | ||
self.scene.remove_widgets(list_event.removed) | ||
# The widgets are added automatically when the importer | ||
# does a read. | ||
self.scene.render() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,273 @@ | ||
from tvtk.api import tvtk | ||
from .tools import gcf | ||
from mayavi.sources.widget_source import WidgetSource | ||
from traits.api import RGBColor, Str, on_trait_change, Array, Float, Int, File, Bool | ||
from traitsui.api import ArrayEditor | ||
from traitsui.api import Group, View, Item | ||
|
||
|
||
class SliderWidget(WidgetSource): | ||
|
||
title_color = RGBColor | ||
title_text = Str | ||
minimum_value = Float | ||
maximum_value = Float | ||
position_1 = Array(dtype="float64", shape=(3, ), editor=ArrayEditor(), | ||
desc="x, y, z coordinates of the bottom left point") | ||
position_2 = Array(dtype="float64", shape=(3, ), editor=ArrayEditor(), | ||
desc="x, y, z coordinates of the top right point") | ||
|
||
slider_color = RGBColor | ||
slider_color_2 = RGBColor(desc="color of the slider when it's picked") | ||
|
||
cap_color = RGBColor | ||
cap_opacity = Float | ||
|
||
tube_color = RGBColor | ||
tube_opacity = Float | ||
|
||
label_color = RGBColor | ||
|
||
slider_rep = tvtk.SliderRepresentation2D() | ||
slider_widget = tvtk.SliderWidget() | ||
title = slider_rep._get_title_property() | ||
label = slider_rep._get_label_property() | ||
slider = slider_rep._get_slider_property() | ||
cap = slider_rep._get_cap_property() | ||
tube = slider_rep._get_tube_property() | ||
point1 = slider_rep._get_point1_coordinate() | ||
point2 = slider_rep._get_point2_coordinate() | ||
|
||
traits_view = View(Group(Item(name="title_color"), | ||
Item(name="title_text"), | ||
Item(name="position_1"), | ||
Item(name="position_2"), | ||
Item(name="minimum_value"), | ||
Item(name="maximum_value"), | ||
Item(name="slider_color"), | ||
Item(name="slider_color_2"), | ||
Item(name="cap_color"), | ||
Item(name="cap_opacity"), | ||
Item(name="tube_color"), | ||
Item(name="tube_opacity"), | ||
Item(name="label_color"), | ||
label="Properties") | ||
) | ||
|
||
def get_value(self): | ||
return self.slider_widget._get_representation().value | ||
|
||
@on_trait_change('position+') | ||
def _position_config(self): | ||
self.point1.value = self.position_1 | ||
self.point2.value = self.position_2 | ||
|
||
@on_trait_change("minimum_value, maximum_value") | ||
def _value_config(self): | ||
self.slider_rep.minimum_value = self.minimum_value | ||
self.slider_rep.maximum_value = self.maximum_value | ||
|
||
@on_trait_change('title+') | ||
def _title_config(self): | ||
color = self.title_color | ||
self.title.color = (color if color is not "white" else (1, 1, 1)) | ||
self.slider_rep.title_text = self.title_text | ||
self.title.shadow = 0 | ||
|
||
@on_trait_change('slider+') | ||
def _slider_config(self): | ||
color = self.slider_color_2 | ||
self.slider.color = self.slider_color | ||
self.slider_rep._get_selected_property().color = \ | ||
(color if color is not "white" else (1, 1, 1)) | ||
|
||
@on_trait_change("cap+") | ||
def cap_setup(self): | ||
self.cap.color = self.cap_color | ||
self.cap.opacity = self.cap_opacity | ||
|
||
@on_trait_change("tube+") | ||
def tube_setup(self): | ||
self.tube.color = self.tube_color | ||
self.tube.opacity = self.tube_opacity | ||
|
||
@on_trait_change("label+") | ||
def label_setup(self): | ||
self.label.color = self.label_color | ||
|
||
def _widget_setup(self, figure): | ||
self.slider_widget.set(interactor=figure().scene.interactor) | ||
self.slider_widget.set(representation=self.slider_rep) | ||
self.slider_widget.animation_mode = "animate" | ||
self.slider_widget.enabled = 1 | ||
self.default_slider() | ||
|
||
def default_slider(self): | ||
self.title_text = "Slider" | ||
self.title_color = (0, 0, 0) | ||
self.point1.coordinate_system = "normalized_display" | ||
self.point2.coordinate_system = "normalized_display" | ||
self.position_1 = (0.8, 0.9, 0) | ||
self.position_2 = (1, 0.9, 0) | ||
self.minimum_value = 0 | ||
self.maximum_value = 1 | ||
self.slider_rep.value = self.minimum_value | ||
self.slider_color = (0.3, 0.2, 0.9) | ||
self.slider_color_2 = (1, 0, 0) | ||
self.cap_color = (0, 0, 0) | ||
self.cap_opacity = 0 | ||
self.tube_color = (0, 0, 0) | ||
self.tube_opacity = 1 | ||
self.label_color = (1, 1, 1) | ||
self.label.shadow = 0 | ||
|
||
def add_callback(self, callback): | ||
self.slider_widget.add_observer("InteractionEvent", callback) | ||
|
||
def _update(self): | ||
if self.scene is None: | ||
return | ||
self.widgets = [self.slider_widget] | ||
|
||
def _visible_changed(self, value): | ||
if value: | ||
if not self._actors_added: | ||
self.scene.add_widgets(self.widgets) | ||
self._actors_added = True | ||
super(SliderWidget, self)._visible_changed(value) | ||
|
||
|
||
class ButtonWidget(WidgetSource): | ||
|
||
button_rep = tvtk.TexturedButtonRepresentation2D() | ||
button_widget = tvtk.ButtonWidget() | ||
text_image = tvtk.ImageData() | ||
|
||
file_location = File(exists=True) | ||
position = Array(dtype="float64", shape=(6,), editor=ArrayEditor(), | ||
desc="position as xmin, xmax, ymin, ymax, zmin, zmax") | ||
|
||
add_image = Bool | ||
text_color = RGBColor | ||
text = Str | ||
text_font_size = Int | ||
|
||
box_group = Group( | ||
Item(name="add_image"), | ||
Item(name="position") | ||
) | ||
|
||
text_group = Group( | ||
Item(name="text"), | ||
Item(name="text_color"), | ||
Item(name="text_font_size"), | ||
enabled_when="add_image is False" | ||
) | ||
|
||
image_group = Group( | ||
Item(name="file_location"), | ||
enabled_when="add_image is True" | ||
) | ||
|
||
default_view = View( | ||
Group( | ||
box_group, | ||
text_group, | ||
image_group | ||
) | ||
) | ||
|
||
@on_trait_change("add_image") | ||
def image_conifg(self): | ||
if self.add_image == 1 and self.file_location is not "": | ||
self.image() | ||
if self.add_image == 0: | ||
self.add_text() | ||
|
||
@on_trait_change("file_location") | ||
def image(self): | ||
d = {'bmp': tvtk.BMPReader(), | ||
'jpg': tvtk.JPEGReader(), | ||
'png': tvtk.PNGReader(), | ||
'pnm': tvtk.PNMReader(), | ||
'dcm': tvtk.DICOMImageReader(), | ||
'tiff': tvtk.TIFFReader(), | ||
'ximg': tvtk.GESignaReader(), | ||
'dem': tvtk.DEMReader(), | ||
'mha': tvtk.MetaImageReader(), | ||
'mhd': tvtk.MetaImageReader(), | ||
} | ||
reader = d[self.file_location[-3:]] | ||
reader.set(file_name=self.file_location) | ||
reader.update() | ||
image = tvtk.ImageData() | ||
image = reader._get_output() | ||
self.button_rep.set_button_texture(0, image) | ||
|
||
@on_trait_change("text+") | ||
def add_text(self): | ||
free_type = tvtk.FreeTypeStringToImage() | ||
text_property = tvtk.TextProperty() | ||
color = self.text_color | ||
text_property.color = (color if color is not "white" else (1, 1, 1)) | ||
text_property.font_size = self.text_font_size | ||
text_image = tvtk.ImageData() | ||
free_type.render_string(text_property, self.text, 0, text_image) | ||
self.button_rep.set_button_texture(0, text_image) | ||
|
||
@on_trait_change("position") | ||
def place_widget(self): | ||
self.button_rep.place_widget(self.position) | ||
|
||
def _widget_setup(self, figure): | ||
self.button_widget.set(interactor=figure().scene.interactor) | ||
self.button_widget.set(representation=self.button_rep) | ||
self.button_widget.enabled = 1 | ||
self.default_button() | ||
|
||
def default_button(self): | ||
self.button_rep.set_number_of_states(1) | ||
self.text = "Button" | ||
self.text_color = (1, 1, 0) | ||
self.text_font_size = 25 | ||
self.position = (-70, 70, -70, 70, 0, 0) | ||
|
||
def add_callback(self, callback): | ||
self.button_widget.add_observer("StateChangedEvent", callback) | ||
|
||
def _update(self): | ||
if self.scene is None: | ||
return | ||
self.widgets = [self.button_widget] | ||
|
||
def _visible_changed(self, value): | ||
if value: | ||
if not self._actors_added: | ||
self.scene.add_widgets(self.widgets) | ||
self._actors_added = True | ||
super(ButtonWidget, self)._visible_changed(value) | ||
|
||
def remove_actors(self): | ||
"""Removes `self.widgets` from the scene. | ||
""" | ||
if self._actors_added: | ||
self.scene.remove_widgets(self.widgets) | ||
self._actors_added = False | ||
self.button_rep.set_button_texture(0, self.text_image) | ||
self.scene.render() | ||
|
||
|
||
def slider_widget(figure=None): | ||
if figure is None: | ||
figure = gcf | ||
slider = SliderWidget() | ||
slider._widget_setup(figure) | ||
return slider | ||
|
||
|
||
def button_widget(figure=None): | ||
if figure is None: | ||
figure = gcf | ||
button = ButtonWidget() | ||
button._widget_setup(figure) | ||
return button |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, and the fact that this wasn't caught suggests no tests, can you please add a simple test so this is exercised?