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

Toolbar layout fixes #1273

Merged
merged 10 commits into from
May 6, 2015
17 changes: 11 additions & 6 deletions Packages/vcs/Lib/vtk_ui/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,20 @@ def add_state(self, label=None, image=None, bgcolor=None, fgcolor=None, opacity=
self.states.append(ButtonState(label=label, image=image, bgcolor=bgcolor, fgcolor=fgcolor, opacity=opacity))

def place(self):

width, height = self.get_dimensions()
x, y = self.get_position()
bounds = (x, x + width, y - height, y, 0, 0)

self.repr.SetPlaceFactor(1)
self.repr.PlaceWidget(bounds)
self.repr.Modified()
if self.showing():
# This One Weird Hack will make your Buttons Go In the Right Place - Developers hate it!
# Buttons weren't always getting properly placed (toolbars in toolbars being the canonical example)
# This makes them show up correctly. Weird, but it works.
h_state = self.repr.GetHighlightState()
self.repr.Highlight((h_state + 1) % 3)
self.repr.Highlight(h_state)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice comment :P

Strange. Looking at the C++, all this does is trigger a HighlightEvent (which, according to git grep doesn't seem to be handled anywhere internally by VTK, nor by uvcdat/vistrails), and calls Modified(), which you do above. Strange.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're telling me. I actually have a tendency to delve down into the C++ source when I find a weird hack like this, so I can ideally not have the weird hack anymore. This time I failed.


text_width, text_height = self.text_widget.get_dimensions()
swidth, sheight = self.interactor.GetRenderWindow().GetSize()
Expand Down Expand Up @@ -289,7 +297,7 @@ def in_bounds(self, x, y):
def __advance__(self, point):
state = self.repr.GetState()
self.set_state( (state + 1) % len(self.states) )
#self.clicked(self.widget, "StateChangedEvent") Do we need to call this? I bet we don't.
self.clicked(self.widget, "StateChangedEvent")

def clicked(self, obj, event):
state = self.get_state()
Expand Down Expand Up @@ -332,10 +340,7 @@ def __init__(self, interactor, label, on=None, off=None, corner_radius=5, width=
self.label = label

def get_text(self):
if self.get_state() == 0:
return self.label.get_text()[len(on_prefix):]
else:
return self.label.get_text()[len(off_prefix):]
return self.label

def toggle(self, state):
if state == 1:
Expand Down
29 changes: 20 additions & 9 deletions Packages/vcs/Lib/vtk_ui/toolbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Toolbar(object):

def __init__(self, interactor, label, vertical=True, left=10, top=10, open_label="Open", on_open=None, close_label="Close", button_margin=5, parent=None, save=None):
def __init__(self, interactor, label, vertical=True, left=10, top=10, open_label="Open", on_open=None, close_label="Close", on_close=None, button_margin=5, parent=None, save=None):

self.save = save
self.interactor = interactor
Expand All @@ -12,13 +12,13 @@ def __init__(self, interactor, label, vertical=True, left=10, top=10, open_label
self.top = top
self.label = ToggleButton(self.interactor, label, on=self.__on__, off=self.__off__, on_prefix=open_label, off_prefix=close_label, left=self.left - self.margin, top=self.top)
self.on_open = on_open
self.on_close = on_close
self.vertical = vertical

self.open = False

# Increment this as widgets are added
self.width, self.height = self.label.get_dimensions()
self.height += button_margin

self.widgets = []
self.bars = {}
Expand Down Expand Up @@ -47,13 +47,15 @@ def __delleft(self):

def __on__(self):
self.open = True
self.show_widgets()
if self.on_open is not None:
self.on_open()
self.show_widgets()

def __off__(self):
self.open = False
self.hide_widgets()
if self.on_close is not None:
self.on_close()

def copy(self, interactor):
t = Toolbar(interactor, self.label.label, vertical=self.vertical, left=self.left - self.margin, top=self.top, button_margin=self.margin)
Expand Down Expand Up @@ -87,9 +89,6 @@ def place(self):
self.width += self.margin

for widget in self.widgets:

widget_width, widget_height = widget.get_dimensions()

if self.vertical:
widget.left = self.left
widget.top = self.top + self.height
Expand All @@ -107,6 +106,7 @@ def place(self):
self.height += widget_height + self.margin
else:
self.width += widget_width + self.margin
self.label.manager.queue_render()

def get_dimensions(self):
"""
Expand Down Expand Up @@ -136,11 +136,10 @@ def hide(self):
self.hide_widgets()

def show_widgets(self):
self.place()
for widget in self.widgets:
widget.show()

self.place()

def hide_widgets(self):
"""
Hides all widgets in this toolbar
Expand Down Expand Up @@ -182,7 +181,6 @@ def add_button(self, labels, **kwargs):
kwargs["top"] = self.top

b = Button(self.interactor, **kwargs)

if self.open:
b.show()

Expand All @@ -192,6 +190,7 @@ def add_button(self, labels, **kwargs):
self.width = kwargs["left"] + b.get_dimensions()[0]

self.widgets.append(b)

return b


Expand All @@ -211,6 +210,18 @@ def add_toolbar(self, label, **kwargs):

if "vertical" not in kwargs:
kwargs["vertical"] = self.vertical
_open = kwargs.get("on_open", None)
def hook_open():
self.place()
if _open:
_open()
_close = kwargs.get("on_close", None)
def hook_close():
self.place()
if _close:
_close()
kwargs["on_open"] = hook_open
kwargs["on_close"] = hook_close

toolbar = Toolbar(self.interactor, label, **kwargs)

Expand Down
40 changes: 40 additions & 0 deletions testing/vcs/vtk_ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,43 @@ cdat_add_test(test_vtk_ui_textbox_blank_text
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_textbox_blank_text.py
)

cdat_add_test(test_vtk_ui_toolbar_label
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toolbar_label.py
${BASELINE_DIR}/test_vtk_ui_toolbar_label.png
)

cdat_add_test(test_vtk_ui_toolbar_open
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toolbar_open.py
${BASELINE_DIR}/test_vtk_ui_toolbar_open.png
)

cdat_add_test(test_vtk_ui_toolbar_close
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toolbar_close.py
${BASELINE_DIR}/test_vtk_ui_toolbar_close.png
)

cdat_add_test(test_vtk_ui_toggle_button_get_text
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toggle_button_get_text.py
)

cdat_add_test(test_vtk_ui_toolbar_in_toolbar_open
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toolbar_in_toolbar_open.py
${BASELINE_DIR}/test_vtk_ui_toolbar_in_toolbar_open.png
)

cdat_add_test(test_vtk_ui_toolbar_in_toolbar_closed
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_toolbar_in_toolbar_closed.py
${BASELINE_DIR}/test_vtk_ui_toolbar_in_toolbar_closed.png
)

cdat_add_test(test_vtk_ui_button_state_advance
"${PYTHON_EXECUTABLE}"
${TEST_DIR}/test_vtk_ui_button_state_advance.py
)
32 changes: 32 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_button_state_advance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
Test button state change
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_button_state_advance(vtk_ui_test):
def do_test(self):
self.win.SetSize(100, 100)
states = [vcs.vtk_ui.ButtonState(label="State %d" % i, fgcolor=(.1 * i + .5, .1 * i + .5, .1 * i + .5), bgcolor=(.5 - .1 * i,.5 - .1 * i,.5 - .1 * i)) for i in range(5)]

b = vcs.vtk_ui.Button(self.inter, states=states, action=self.pass_me, left=0, top=0)
b.show()

b.set_state(1)
b.repr.NextState()
b.widget.InvokeEvent("StateChangedEvent")


def pass_me(self, state):
if state == 2:
print "Button action executed"
self.passed = 0
else:
print state, "Action passed inaccurate state"
from sys import exit
sys.exit(1)

if __name__ == "__main__":
test_vtk_ui_button_state_advance().test()
16 changes: 16 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toggle_button_get_text.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Test toggle_button get text
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toggle_button_get_text(vtk_ui_test):
def do_test(self):
b = vcs.vtk_ui.ToggleButton(self.inter, "Simple label")
b.set_state(1)
assert b.get_text() == "Simple label"
b.set_state(0)
assert b.get_text() == "Simple label"
self.passed = 0
24 changes: 24 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toolbar_close.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Test toolbar placement and basic appearance
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toolbar_close(vtk_ui_test):
def do_test(self):
self.win.SetSize(200, 100)

toolbar = vcs.vtk_ui.Toolbar(self.inter, "Test Bar")
toolbar.add_button(["Test Button"])
toolbar.add_button(["Other Test"])
toolbar.label.__advance__(1)
toolbar.label.__advance__(0)
assert toolbar.open == False
toolbar.show()

self.test_file = "test_vtk_ui_toolbar_close.png"

if __name__ == "__main__":
test_vtk_ui_toolbar_close().test()
29 changes: 29 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toolbar_in_toolbar_closed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Test toolbar placement inside toolbar
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toolbar_in_toolbar_closed(vtk_ui_test):
def do_test(self):
self.win.SetSize(200, 250)

toolbar = vcs.vtk_ui.Toolbar(self.inter, "Test Bar")
tb = toolbar.add_toolbar("Sub-bar")
tb.add_button(["first"])
tb.add_button(["second"])
toolbar.add_button(["Test Button"])
toolbar.add_button(["Other Test"])
toolbar.show()

# Open both toolbars
toolbar.label.__advance__(1)
tb.label.__advance__(1)
tb.label.__advance__(0)

self.test_file = "test_vtk_ui_toolbar_in_toolbar_closed.png"

if __name__ == "__main__":
test_vtk_ui_toolbar_in_toolbar_closed().test()
28 changes: 28 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toolbar_in_toolbar_open.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
Test toolbar placement inside toolbar
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toolbar_in_toolbar_open(vtk_ui_test):
def do_test(self):
self.win.SetSize(200, 250)

toolbar = vcs.vtk_ui.Toolbar(self.inter, "Test Bar")
tb = toolbar.add_toolbar("Sub-bar")
tb.add_button(["first"])
tb.add_button(["second"])
toolbar.add_button(["Test Button"])
toolbar.add_button(["Other Test"])
toolbar.show()

# Open both toolbars
toolbar.label.__advance__(1)
tb.label.__advance__(1)

self.test_file = "test_vtk_ui_toolbar_in_toolbar_open.png"

if __name__ == "__main__":
test_vtk_ui_toolbar_in_toolbar_open().test()
23 changes: 23 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toolbar_label.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
Test toolbar placement and basic appearance
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toolbar_label(vtk_ui_test):
def do_test(self):
self.win.SetSize(200, 100)

toolbar = vcs.vtk_ui.Toolbar(self.inter, "Test Bar")
# Should default to closed; these will help make sure
toolbar.add_button(["Test Button"])
toolbar.add_button(["Other Test"])
assert toolbar.open == False
toolbar.show()

self.test_file = "test_vtk_ui_toolbar_label.png"

if __name__ == "__main__":
test_vtk_ui_toolbar_label().test()
24 changes: 24 additions & 0 deletions testing/vcs/vtk_ui/test_vtk_ui_toolbar_open.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Test toolbar placement and basic appearance
"""
import vcs.vtk_ui


from vtk_ui_test import vtk_ui_test

class test_vtk_ui_toolbar_open(vtk_ui_test):
def do_test(self):
self.win.SetSize(200, 100)

toolbar = vcs.vtk_ui.Toolbar(self.inter, "Test Bar")
toolbar.add_button(["Test Button"])
toolbar.add_button(["Other Test"])
toolbar.label.__advance__(1)
assert toolbar.open == True
toolbar.show()


self.test_file = "test_vtk_ui_toolbar_open.png"

if __name__ == "__main__":
test_vtk_ui_toolbar_open().test()