Files
sloth/annotationscene.py
T
2010-12-03 17:59:42 +01:00

200 lines
6.1 KiB
Python

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from sceneitems import *
import math
class ItemInserter:
def __init__(self, scene, model=None):
self.scene_ = scene
self.model_ = model
self.mode_ = None
def setModel(self, model):
self.model_ = model
def model(self):
return self.model_
def setScene(self, scene):
self.scene_ = scene
def scene(self):
return self.scene_
def setMode(self, mode):
self.mode_ = mode
def mode(self):
return self.mode
def mousePressEvent(self, event, index):
event.accept()
def mouseReleaseEvent(self, event, index):
event.accept()
def mouseMoveEvent(self, event, index):
event.accept()
class PointItemInserter(ItemInserter):
def mousePressEvent(self, event, index):
pos = event.scenePos()
# TODO create it in the model instead
item = QGraphicsEllipseItem(QRectF(pos.x()-1, pos.y()-1, 2, 2))
self.scene().addItem(item)
event.accept()
class RectItemInserter(ItemInserter):
def __init__(self, scene, model=None):
ItemInserter.__init__(self, scene, model)
self.current_item_ = None
self.init_pos_ = None
def mousePressEvent(self, event, index):
pos = event.scenePos()
# TODO create it in the model instead
item = QGraphicsRectItem(QRectF(pos.x(), pos.y(), 0, 0))
self.current_item_ = item
self.init_pos_ = pos
self.scene().addItem(item)
event.accept()
def mouseMoveEvent(self, event, index):
if self.current_item_ is not None:
assert self.init_pos_ is not None
pos = event.scenePos()
rect = QRectF(self.init_pos_.x(), self.init_pos_.y(),
pos.x() - self.init_pos_.x(), pos.y() - self.init_pos_.y())
self.current_item_.setRect(rect.normalized())
event.accept()
def mouseReleaseEvent(self, event, index):
if self.current_item_ is not None:
if self.current_item_.rect().width() > 1 and \
self.current_item_.rect().height() > 1:
# TODO commit to the model
print "added rect:", self.current_item_
self.current_item_ = None
self.init_pos_ = None
event.accept()
class PolygonItemInserter(ItemInserter):
def __init__(self, scene, model=None):
ItemInserter.__init__(self, scene, model)
self.current_item_ = None
def mousePressEvent(self, event, index):
pos = event.scenePos()
if self.current_item_ is None:
item = QGraphicsPolygonItem(QPolygonF([pos]))
self.current_item_ = item
self.scene().addItem(item)
else:
polygon = self.current_item_.polygon()
polygon.append(pos)
self.current_item_.setPolygon(polygon)
event.accept()
def mouseMoveEvent(self, event, index):
if self.current_item_ is not None:
pos = event.scenePos()
polygon = self.current_item_.polygon()
assert polygon.size() > 0
polygon[-1] = pos
self.current_item_.setPolygon(polygon)
event.accept()
class AnnotationScene(QGraphicsScene):
# TODO signal itemadded
def __init__(self, parent=None):
super(AnnotationScene, self).__init__(parent)
self.setBackgroundBrush(Qt.darkGray)
self.reset()
self.setSceneRect(0,0, 640, 480)
self.addRect(QRectF(0, 0, 640, 480), brush=Qt.white)
self.mode_ = None
self.inserters_ = {}
self.inserter_ = None
self.debug_ = True
self.addItemInserter('point', PointItemInserter(self))
self.addItemInserter('rect', RectItemInserter(self))
self.addItemInserter('poly', PolygonItemInserter(self))
self.addItemInserter('polygon', PolygonItemInserter(self))
#self.setMode({'type': 'point'})
#self.setMode({'type': 'rect'})
self.setMode({'type': 'poly'})
def reset(self):
self.clear()
def setMode(self, mode):
print "setMode :", mode
self.mode_ = mode
if self.mode_ == None:
self.inserter_ = None
return
if not self.mode_['type'] in self.inserters_:
raise InvalidArgumentException("Invalid mode")
self.inserter_ = self.inserters_[self.mode_['type']]
self.inserter_.setMode(self.mode_)
def addItemInserter(self, type, inserter):
if type in self.inserters_:
raise Exception("Type %s already has an inserter" % type)
self.inserters_[type] = inserter
def removeItemInserter(self, type):
if type in self.inserters_:
del self.inserters_[type]
def mousePressEvent(self, event):
if self.debug_:
print "mousePressEvent", self.sceneRect().contains(event.scenePos()), event.scenePos()
if not self.sceneRect().contains(event.scenePos()):
# ignore events outside the scene rect
return
elif self.inserter_ is not None:
# insert mode
self.inserter_.mousePressEvent(event, None)
else:
# selection mode
QGraphicsScene.mousePressEvent(self, event)
def mouseReleaseEvent(self, event):
if self.debug_:
print "mouseReleaseEvent", self.sceneRect().contains(event.scenePos()), event.scenePos()
if self.inserter_ is not None:
# insert mode
self.inserter_.mouseReleaseEvent(event, None)
else:
# selection mode
QGraphicsScene.mouseReleaseEvent(self, event)
def mouseMoveEvent(self, event):
if self.debug_:
print "mouseMoveEvent", self.sceneRect().contains(event.scenePos()), event.scenePos()
if self.inserter_ is not None:
# insert mode
self.inserter_.mouseMoveEvent(event, None)
else:
# selection mode
QGraphicsScene.mouseMoveEvent(self, event)
def addItem(self, item):
QGraphicsScene.addItem(self, item)
# TODO emit signal itemAdded