# CellTracking.py
# By MW, Jun 2013
# GPLv3+
#
# Class managing the viewer of a player.
#+ It interacts with a State instance to update the displayed position. It does not launch a timer by itself.
import gtk, logging, cv2
[docs]class Viewer :
def __init__(self, player) :
self.player = player
self.size = (400, 300)
pplayer = self.player.state.get_subclass("player")
pplayer.set_window(self.size)
self.button_down = False # True when the user is moving a cell
self.test = 0
[docs] def get_viewer(self) :
""" Returns the panel displaying the movies
.. WARNING::
This function contains an horrible hack when trying to synchronize
click detection and image coordinates. Everything should be made
much more cleaner by replacing nested Box() by a nice Table() that
already exist bu is nested in the two Box()es
"""
# Create viewport
self.viewport = gtk.Viewport()
self.set_size(self.size)
# Get scrollbars
vadjustment = self.viewport.get_vadjustment()
hadjustment = self.viewport.get_hadjustment()
self.vscroll = gtk.VScrollbar(vadjustment)
self.hscroll = gtk.HScrollbar(hadjustment)
self.vscroll.connect("value-changed", self.scroll_changed)
self.hscroll.connect("value-changed", self.scroll_changed)
# Creating the widget
self.table = gtk.Table(2, 2, False) # The main table
self.table.attach(self.viewport, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
self.table.attach(self.vscroll, 1, 2, 0, 1, gtk.FILL | gtk.SHRINK, gtk.FILL | gtk.SHRINK)
self.table.attach(self.hscroll, 0, 1, 1, 2, gtk.FILL | gtk.SHRINK, gtk.FILL | gtk.SHRINK)
# Content of the viewport
self.image = gtk.Image()
#self.image.show()
self.update_viewer()
# Create Event box
out_box = gtk.VBox()
out_box.pack_start(gtk.Label(''))
in_box = gtk.HBox()
self.eventbox = gtk.EventBox()
self.eventbox.add(self.image)
in_box.pack_start(gtk.Label('')) # Horrible hack to get the image centered
in_box.pack_start(self.eventbox, fill=False, expand=False)
in_box.pack_start(gtk.Label(''))
in_box.show_all()
out_box.pack_start(in_box, fill=True, expand=True)
out_box.pack_start(gtk.Label(''))
# Set event (detect click)
self.eventbox.connect("button-press-event", self.clicked_image_evt)
self.eventbox.connect("button-release-event", self.buttonrelease_image_evt)
self.eventbox.connect("motion-notify-event", self.mouseover_image_evt)
self.viewport.add(out_box)
# Updating dimensions
#self.update_coord() # Gives wrong dimensions
return self.table
[docs] def update_viewer(self) :
"""Function that updates the viewer when necessary
This does not replace the 'scroll_changed' function"""
if 1 : # If the image has to be updated
state = self.player.state.get_subclass('player')
m = state.get_current_frame(state.current_zoom)
pixbuf = gtk.gdk.pixbuf_new_from_array(m*2, gtk.gdk.COLORSPACE_RGB, 8)
self.image.clear()
self.image.set_from_pixbuf(pixbuf)
[docs] def update_coord(self) :
player = self.player.state.get_subclass("player")
player.set_pos((self.hscroll.get_value(), self.vscroll.get_value()))
player.set_window((self.viewport.get_allocation()[2], self.viewport.get_allocation()[3]))
[docs] def set_size(self, size) :
"""Change the size of the viewer. Size should be given as a tuple"""
self.viewport.set_size_request(size[0], size[1]) # Set a minimum size (on the widget)
self.player.window.resize(1, 1) # Set to the minimum size
[docs] def set_scale(self, scale) :
s = self.player.state.movie.get_size()
self.set_size((int(scale*s[0]), int(scale*s[1])))
logging.debug("Window scale set to %s", str(scale*100)+"%")
[docs] def clicked_image_evt(self, w, event) :
"""Function called when the image is clicked"""
# Converting image coordinates
click = tuple(self.player.state.get_subclass('zoom').disp2im((event.x, event.y)))
self.player.state.get_subclass('player').set_image_click(click)
self.player.state.get_subclass('player').set_lock(True)
self.button_down = True
#print "click"
[docs] def mouseover_image_evt(self, w, event) :
if self.button_down :
click = tuple(self.player.state.get_subclass('zoom').disp2im( (event.x, event.y)))
self.player.cells.set_image_move(click)
#print "moving cell"