# Features.py
# By MW, Jul 2013
# GPLv3+
#
# Graphical primitives for Feature classes
import gtk, gobject
[docs]class Feature_gtk(gobject.GObject) :
def __init__(self, feature, state) :
self.__gobject_init__()
self.state = state
self.feature = feature
self.visible = True
self.bounds = None # (min_frame, max_frame)
[docs] def set_bounds(self, b) :
self.bounds = b
[docs] def draw(self, cr, params) :
pass
[docs] def get_panel(self) :
f = gtk.Frame(self.feature.get_name())
f.show()
return f
[docs] def set_visible(self, v) :
self.visible = v
# Register new signal
gobject.type_register(Feature_gtk)
gobject.signal_new("slider-changed", Feature_gtk, gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, ())
[docs]class Point_gtk(Feature_gtk) :
def __init__(self, feature, state) :
Feature_gtk.__init__(self, feature, state)
self.point = None
[docs] def draw(self, cr, params) :
point = self.feature.get_point()
if point != None and self.visible :
col = self.feature.get_color()
n = self.feature.get_name()
coord = params['to_px'](point)
cr.set_font_size(10)
cr.set_source_rgb(col[0], col[1], col[2])
cr.move_to(coord, params['top_r'])
cr.line_to(coord, params['bottom_r']+params['top_r'])
cr.stroke()
cr.move_to(coord-3, params['bottom_t'])
cr.text_path(self.feature.get_short_name())
cr.stroke()
cr.save()
cr.clip()
cr.paint()
cr.restore()
[docs] def get_panel(self) :
f = gtk.Frame(self.feature.get_name()+' ('+self.feature.get_short_name()+')')
box = gtk.HBox()
point_l = gtk.Label('Set frame')
b = self.bounds
p = self.feature.get_point()
if p == None :
p = -1
point_adj = gtk.Adjustment(p, -1, b[1], 1, 1, 0)
point_sb = gtk.SpinButton(point_adj)
current_b = gtk.Button('Current frame')
del_b_i = gtk.Image()
del_b_i.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_SMALL_TOOLBAR)
del_b = gtk.Button()
del_b.add(del_b_i)
del_b.set_tooltip_text('Delete feature')
current_b.connect('clicked',self.current_b_evt, self.feature, point_sb)
point_sb.connect('value-changed',self.sb_evt,self.feature)
del_b.connect('clicked', self.del_evt, self.feature, point_sb)
box.pack_start(point_l, fill=False, expand=False)
box.pack_start(point_sb, fill=False, expand=False)
box.pack_start(current_b, fill=False, expand=False)
box.pack_start(del_b, fill=False, expand=False)
b = gtk.VBox()
b.pack_start(box, fill=False, expand=False)
b.pack_start(gtk.Label(''), fill=False, expand=False)
f.add(b)
f.show_all()
return f
[docs] def sb_evt(self, b, feature) :
self.update(feature, b.get_value())
[docs] def current_b_evt(self, b, feature, sb) :
i = self.state.get_subclass('player').get_current_index()
sb.set_value(i)
self.update(feature, i)
[docs] def del_evt(self, b, feature, sb) :
sb.set_value(-1)
self.update(feature, None)
[docs] def update(self, feature, p) :
feature.set_point(p)
self.emit('slider-changed')
[docs]class Multipoint_gtk(Feature_gtk) :
"""Should multipoint inherit from Point rather than Feature? YES!"""
def __init__(self, f, s) :
Feature_gtk.__init__(self, f,s)
[docs]class Segment_gtk(Feature_gtk) :
def __init__(self, f, s) :
Feature_gtk.__init__(self, f,s)
[docs] def get_panel(self) :
f = gtk.Frame(self.feature.get_name()+' ('+self.feature.get_short_name()+')')
box = gtk.HBox()
table = gtk.Table(2,3)
segl_l = gtk.Label('Set begin')
segr_l = gtk.Label('Set end')
b = self.bounds
seg = list(self.feature.get_segment())
if seg[0] == None :
seg[0] = -1
if seg[1] == None :
seg[1] = -1
segl_adj = gtk.Adjustment(seg[0], -1, b[1], 1, 1, 0)
segl_sb = gtk.SpinButton(segl_adj)
segr_adj = gtk.Adjustment(seg[1], -1, b[1], 1, 1, 0)
segr_sb = gtk.SpinButton(segr_adj)
current_bl = gtk.Button('Set begin')
current_br = gtk.Button('Set end')
sbs = (segl_sb, segr_sb)
current_bl.connect('clicked',self.current_b_evt, self.feature,'left', sbs)
current_br.connect('clicked',self.current_b_evt,self.feature,'right', sbs)
segl_sb.connect('value-changed',self.sb_evt,self.feature,'left', sbs)
segr_sb.connect('value-changed',self.sb_evt, self.feature,'right',sbs)
del_b_i = gtk.Image()
del_b_i.set_from_stock(gtk.STOCK_DELETE, gtk.ICON_SIZE_SMALL_TOOLBAR)
del_b = gtk.Button()
del_b.add(del_b_i)
del_b.set_tooltip_text('Delete feature')
del_b.connect('clicked', self.del_evt, self.feature, sbs)
table.attach(segl_l, 0,1,0,1)
table.attach(segl_sb, 1,2,0,1)
table.attach(current_bl, 2,3,0,1)
table.attach(segr_l, 0,1,1,2)
table.attach(segr_sb, 1,2,1,2)
table.attach(current_br, 2,3,1,2)
box.pack_start(table, fill=False, expand=False)
box.pack_start(del_b, fill=False, expand=False)
b = gtk.VBox()
b.pack_start(box, fill=False, expand=False)
b.pack_start(gtk.Label(''), fill=True, expand=True)
f.add(b)
f.show_all()
return f
[docs] def draw(self, cr, params) :
segment = self.feature.get_segment()
if None not in segment and self.visible :
col = self.feature.get_color()
n1 = params['to_px'](segment[0])
n2 = params['to_px'](segment[1])
cr.set_font_size(10)
cr.set_source_rgb(col[0], col[1], col[2])
cr.rectangle(n1, params['top_r'], n2-n1, params['bottom_r'])
cr.move_to(n1 + (n2-n1)/2-3, params['bottom_t'])
cr.text_path(self.feature.get_short_name())
cr.save()
cr.clip()
cr.paint()
cr.restore()
[docs] def sb_evt(self, b, feature, direction, sbs) :
if b.get_value() != -1 :
new_bounds = self.update(b.get_value(), feature, direction)
sbs[0].set_value(new_bounds[0])
sbs[1].set_value(new_bounds[1])
[docs] def current_b_evt(self, b, feature, direction, sbs) :
i = self.state.get_subclass('player').get_current_index()
new_bounds = self.update(i, feature, direction)
# Update spinbuttons
sbs[0].set_value(new_bounds[0])
sbs[1].set_value(new_bounds[1])
[docs] def del_evt(self, b, feature, sbs) :
feature.set_segment((None, None))
sbs[0].set_value(-1)
sbs[1].set_value(-1)
self.emit('slider-changed')
[docs] def update(self,i, feature, direction) :
conv = {'left' : 0, 'right' : 1}
bounds = list(feature.get_segment())
if direction == 'left' and (bounds[1] == None or bounds[1] <= i) :
if i+1 < self.state.get_frame_nb() :
new_bounds = (i, i+1)
else :
new_bounds = (i-1, i)
elif direction == 'right' and (bounds[0] == None or bounds[0]>=i) :
if i-1 >= 0 :
new_bounds = (i-1, i)
else :
new_bounds = (0,1)
else :
bounds[conv[direction]] = i
new_bounds = bounds
feature.set_segment(new_bounds)
self.emit('slider-changed')
return new_bounds
[docs]class Cell_gtk(Segment_gtk) :
def __init__(self, f, s) :
Segment_gtk.__init__(self, f,s)
[docs] def get_panel(self) :
f = gtk.Frame('Cell')
l = gtk.Label()
l.set_max_width_chars(20)
l.set_text('You can edit the cell temporal\n'
'limits by editing the "Cell" inset')
f.add(l)
f.show_all()
return f
[docs]class Multisegment_gtk(Feature_gtk) :
def __init__(self, f,s) :
Feature_gtk.__init__(self, f,s)