Skip to content

Commit

Permalink
Merge pull request #1235 from chaosphere2112/text_fixup
Browse files Browse the repository at this point in the history
Text fixup
  • Loading branch information
David Lonie committed Apr 28, 2015
2 parents 29a1e60 + 7285ffa commit 405ecbb
Show file tree
Hide file tree
Showing 40 changed files with 2,106 additions and 657 deletions.
552 changes: 195 additions & 357 deletions Packages/vcs/Lib/configurator.py

Large diffs are not rendered by default.

48 changes: 30 additions & 18 deletions Packages/vcs/Lib/editors/label.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import point
import vcs
import text
#import vtk
import vtk
import vcs.vcs2vtk
from font import FontEditor
from vcs.vtk_ui.text import contrasting_color

__valign_map__ = {
0: 0,
Expand All @@ -19,6 +19,7 @@
"max": "vtk_backend_Max_text_actor",
}


def get_actor(member, dp):
if member.member in __backend_actor_names__:
actor = dp.backend[__backend_actor_names__[member.member]]
Expand All @@ -28,6 +29,7 @@ def get_actor(member, dp):
actor = None
return actor


class LabelEditor(point.PointEditor):
"""
An editor for text items that have data-provided text (template.min, template.max, etc.)
Expand All @@ -44,6 +46,12 @@ def __init__(self, interactor, label, dp, configurator):

self.actor = get_actor(self.label, self.display)

tprop = self.actor.GetTextProperty()
self.real_bg = tprop.GetBackgroundColor()
self.real_bg_opacity = tprop.GetBackgroundOpacity()

tprop.SetBackgroundColor(contrasting_color(*tprop.GetColor()))
tprop.SetBackgroundOpacity(.85)

text_types_name = template.name + "_" + label.member

Expand Down Expand Up @@ -83,7 +91,7 @@ def sync_actor(self):
if self.actor:
p = self.actor.GetTextProperty()
winSize = self.interactor.GetRenderWindow().GetSize()
vcs.vcs2vtk.prepTextProperty(p,winSize,to=self.to,tt=self.tt,cmap=None)
vcs.vcs2vtk.prepTextProperty(p, winSize, to=self.to, tt=self.tt, cmap=None)

def set_font(self, font):
self.tt.font = font
Expand Down Expand Up @@ -123,13 +131,15 @@ def set_color(self, cmap, color):
self.tt.color = color
self.picker = None
self.save()
tprop = self.actor.GetTextProperty()
tprop.SetBackgroundColor(contrasting_color(*tprop.GetColor()))
tprop.SetBackgroundOpacity(.85)
#text colormap is currently not in place, will be later.
#self.text.colormap = cmap

def cancel_color(self):
self.picker = None


def get_text(self):
return get_label_text(self.label, self.display)

Expand All @@ -140,9 +150,19 @@ def is_object(self, label):
return self.label == label

def in_bounds(self, x, y):
t = self.get_text()
swidth, sheight = self.interactor.GetRenderWindow().GetSize()
return inside_label(self.label, t, x, y, swidth, sheight)
w, h = self.interactor.GetRenderWindow().GetSize()
x, y = x * w, y * h
picker = vtk.vtkPropPicker()
for ren in vcs.vcs2vtk.vtkIterate(self.interactor.GetRenderWindow().GetRenderers()):
if ren.HasViewProp(self.actor):
break
else:
return False

if picker.PickProp(x, y, ren) and picker.GetViewProp() == self.actor:
return True
else:
return False

def delete(self):
super(LabelEditor, self).delete()
Expand All @@ -152,6 +172,9 @@ def delete(self):
def detach(self):
super(LabelEditor, self).detach()
self.toolbar.detach()
tprop = self.actor.GetTextProperty()
tprop.SetBackgroundColor(*self.real_bg)
tprop.SetBackgroundOpacity(self.real_bg_opacity)

def update_priority(self):
maxLayers = self.interactor.GetRenderWindow().GetNumberOfLayers()
Expand Down Expand Up @@ -184,14 +207,3 @@ def get_label_text(label, display):
except AttributeError:
t = ''
return t

def inside_label(label, t, x, y, screen_width, screen_height):
tt = label.texttable
to = label.textorientation

tc = vcs.createtextcombined(Tt_source=tt, To_source=to)
tc.string = [t]
tc.x = [label.x]
tc.y = [label.y]

return text.inside_text(tc, x, y, screen_width, screen_height) is not None
12 changes: 8 additions & 4 deletions Packages/vcs/Lib/editors/point.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from vcs.vtk_ui import behaviors, Handle
from vcs.vtk_ui import behaviors
import priority


class PointEditor(behaviors.ClickableMixin, behaviors.DraggableMixin, priority.PriorityEditor):
"""
Base editor for anything with a single "x" and "y" coordinate (so mostly labels)
Expand Down Expand Up @@ -30,10 +31,13 @@ def is_object(self, point):

def handle_click(self, point):
x, y = point
w, h = self.interactor.GetRenderWindow().GetSize()

adjusted_x, adjusted_y = float(x) / w, float(y) / h
try:
return self.in_bounds(x, y) or self.toolbar.in_toolbar(x, y)
return self.in_bounds(adjusted_x, adjusted_y) or self.toolbar.in_toolbar(x, y)
except AttributeError:
return self.in_bounds(x, y)
return self.in_bounds(adjusted_x, adjusted_y)

def render(self):
from vcs.vtk_ui.manager import get_manager
Expand All @@ -47,7 +51,6 @@ def drag_move(self, d_x, d_y):
w, h = self.interactor.GetRenderWindow().GetSize()
x, y = self.actor.GetPosition()
self.actor.SetPosition(x + w * d_x, y + h * d_y)
self.actor.GetMapper().Update()
self.render()
except AttributeError:
self.configurator.changed = True
Expand All @@ -64,6 +67,7 @@ def detach(self):
def deactivate(self):
self.configurator.deactivate(self)


def in_point(point, x, y):
if x < point.x + .001 and x > point.x - .001 and y > point.y - .001 and y < point.y + .001:
return True
Expand Down
2 changes: 1 addition & 1 deletion Packages/vcs/Lib/editors/priority.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def key_pressed(self, key, shift=False, alt=False, control=False):
self.raise_priority()
elif key == "Down":
self.lower_priority()
elif (len(key) == 1 and ord(key) == 127) or key == "Delete":
elif (len(key) == 1 and ord(key) == 127) or key in ("Delete", "Backspace"):
self.delete()

def get_object(self):
Expand Down
118 changes: 43 additions & 75 deletions Packages/vcs/Lib/editors/text.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from vcs.vtk_ui import Textbox, Toolbar, Label
import vcs.vtk_ui.text
from vcs.colorpicker import ColorPicker
from vtk import vtkTextProperty
from vtk import vtkTextProperty, vtkPropPicker, vtkPropCollection
from vcs.vtk_ui.behaviors import ClickableMixin
import priority
import vcs
from vcs.vcs2vtk import genTextActor
from vcs.vcs2vtk import genTextActor, vtkIterate
from font import FontEditor
import sys

Expand All @@ -17,6 +17,7 @@
4: 2,
}


class TextEditor(ClickableMixin, priority.PriorityEditor):
"""
Editor for `textcombined` objects
Expand Down Expand Up @@ -59,6 +60,7 @@ def __init__(self, interactor, text, index, dp, configurator):
prop.SetBackgroundColor(.87, .79, .55)
prop.SetBackgroundOpacity(1)
prop.SetColor(0, 0, 0)
prop.SetVerticalJustificationToTop()
self.tooltip = Label(self.interactor, "%s + Click to place new text." % ("Cmd" if sys.platform == "darwin" else "Ctrl"), textproperty=prop)
self.tooltip.left = 0
self.tooltip.top = self.interactor.GetRenderWindow().GetSize()[1] - self.tooltip.get_dimensions()[1]
Expand Down Expand Up @@ -105,25 +107,21 @@ def update(self):
string = self.text.string[ind]

text_width, text_height = text_dimensions(self.text, ind, (w, h))
x = x * w
y = h - y * h # mirror the y axis for widgets

if self.text.halign in ("right", 2):
x -= text_width
elif self.text.halign in ("center", 1):
x -= text_width / 2.0

if self.text.valign in ("half", 2):
y -= text_height / 2.0
elif self.text.valign in ("top", 0):
y -= text_height
x = x * w
y = y * h

box_prop = vtkTextProperty()
vcs.vcs2vtk.prepTextProperty(box_prop, (w, h), to=self.text, tt=self.text, cmap=cmap)
box_prop.SetOrientation(-1 * self.text.angle)
text_color = box_prop.GetColor()
highlight_color = vcs.vtk_ui.text.contrasting_color(*text_color)

textbox = Textbox(self.interactor, string, left=x, top=y, movable=True, on_editing_end=self.finished_editing, on_drag=self.moved_textbox, textproperty=box_prop, on_click=self.textbox_clicked)
textbox = Textbox(self.interactor, string, highlight_color=highlight_color, highlight_opacity=.8, movable=True, on_editing_end=self.finished_editing, on_drag=self.moved_textbox, textproperty=box_prop, on_click=self.textbox_clicked)
textbox.x = x
textbox.y = y
textbox.show()
textbox.show_highlight()

if ind == self.index:
textbox.start_editing()
Expand All @@ -132,15 +130,35 @@ def update(self):

def finished_editing(self, textbox):
index = self.textboxes.index(textbox)
self.text.string[index] = textbox.text
self.actors[index].SetInput(textbox.text)
if textbox.text == "":
del self.text.string[index]
del self.text.x[index]
del self.text.y[index]
del self.actors[index]
textbox.detach()
del self.textboxes[index]
if len(self.text.string) == 0:
self.deactivate()
return
else:
self.text.string[index] = textbox.text
self.actors[index].SetInput(textbox.text)

def get_box_at_point(self, x, y):
for box in self.textboxes:
if box.in_bounds(x, y):
return box
return None

def in_bounds(self, x, y):
return inside_text(self.text, x, y, *self.interactor.GetRenderWindow().GetSize(), index=self.index) is not None
return self.get_box_at_point(x, y) is not None

def click_release(self):
x, y = self.event_position()
text_index = inside_text(self.text, x, y, *self.interactor.GetRenderWindow().GetSize())
w, h = self.interactor.GetRenderWindow().GetSize()
box = self.get_box_at_point(x * w, y * h)

text_index = None if box is None else self.textboxes.index(box)

self.process_click(text_index, x, y)

Expand All @@ -162,7 +180,6 @@ def process_click(self, text_index, x, y):
return
else:
self.textboxes[self.index].stop_editing()

if text_index is not None:
# Change which one we're editing
self.index = text_index
Expand All @@ -177,22 +194,21 @@ def process_click(self, text_index, x, y):

self.text.x.append(x)
self.text.y.append(y)
self.text.string.append("New Text")
self.text.string.append("Click to Edit")

new_actor = genTextActor(self.actors[0].GetConsumer(0), string=["New Text"], x=[x], y=[y],to=self.text,tt=self.text,cmap=vcs.getcolormap())[0]
new_actor = genTextActor(self.actors[0].GetConsumer(0), string=["Click to Edit"], x=[x], y=[y],to=self.text,tt=self.text,cmap=vcs.getcolormap())[0]
new_actor.SetVisibility(0)
self.actors.append(new_actor)
self.index = new_index

self.update()

def textbox_clicked(self, point):
x, y = point

winsize = self.interactor.GetRenderWindow().GetSize()
for ind, box in enumerate(self.textboxes):
if box.in_bounds(*point):
clicked_on = ind

clicked_on = inside_text(self.text, x, y, *winsize)
self.process_click(clicked_on, x, y)
self.process_click(clicked_on, *point)

def deactivate(self):
self.configurator.deactivate(self)
Expand Down Expand Up @@ -241,7 +257,7 @@ def valign(self, state):
elif state == 1:
self.text.valign = 2
elif state == 2:
self.text.valign = 3
self.text.valign = 4
self.update()

def update_angle(self, value):
Expand Down Expand Up @@ -279,51 +295,3 @@ def text_dimensions(text, index, winsize):
prop = vtkTextProperty()
vcs.vcs2vtk.prepTextProperty(prop, winsize, text, text, vcs.getcolormap())
return vcs.vtk_ui.text.text_dimensions(text.string[index], prop)

def inside_text(text, x, y, screen_width, screen_height, index=None):
import math

winsize = (screen_width, screen_height)

if x > 1:
x = x / float(screen_width)
if y > 1:
y = y / float(screen_height)

for ind, xcoord in enumerate(text.x):
if index is not None:
if ind != index:
continue

ycoord = text.y[ind]
text_width, text_height = text_dimensions(text, ind, winsize)
text_width = text_width / float(screen_width)
text_height = text_height / float(screen_height)

local_x, local_y = x, y
# Adjust X, Y for angle
if text.angle != 0:
# Translate to the origin
translated_x, translated_y = x - xcoord, y - ycoord
# Rotate about the origin
theta = math.radians(text.angle)
txrot = translated_x * math.cos(theta) - translated_y * math.sin(theta)
tyrot = translated_x * math.sin(theta) + translated_y * math.cos(theta)
# Translate back to the point
local_x, local_y = txrot + xcoord, tyrot + ycoord

# Adjust for alignments
if text.valign in ("half", 2):
ycoord -= text_height / 2.0
elif text.valign in ("top", 0):
ycoord -= text_height

if text.halign in ("right", 2):
xcoord -= text_width
elif text.halign in ("center", 1):
xcoord -= text_width / 2.0

if local_x > xcoord and local_x < xcoord + text_width and local_y < ycoord + text_height and local_y > ycoord:
return ind

return None
7 changes: 7 additions & 0 deletions Packages/vcs/Lib/vcs2vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,3 +1450,10 @@ def stripGrid(vtk_grid):
thresh.Update()
vtk_grid = thresh.GetOutput()
return vtk_grid

def vtkIterate(iterator):
iterator.InitTraversal()
obj = iterator.GetNextItem()
while obj is not None:
yield obj
obj = iterator.GetNextItem()
Loading

0 comments on commit 405ecbb

Please sign in to comment.