Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addons/bubblemessage.py16
-rw-r--r--tests/actiontests.py4
-rw-r--r--tests/serializertests.py4
-rw-r--r--tutorius/constraints.py68
-rw-r--r--tutorius/creator.py27
-rw-r--r--tutorius/overlayer.py4
-rw-r--r--tutorius/properties.py77
7 files changed, 146 insertions, 54 deletions
diff --git a/addons/bubblemessage.py b/addons/bubblemessage.py
index 7a8bc72..0ed5f7e 100644
--- a/addons/bubblemessage.py
+++ b/addons/bubblemessage.py
@@ -19,15 +19,17 @@ class BubbleMessage(Action):
message = TStringProperty("Message")
# Create the position as an array of fixed-size 2
position = TArrayProperty([0,0], 2, 2)
+ #position = TPositionProperty((0,0))
#Create a list of tail positions as an array of N element : N to be defined...
- tail_pos = TArrayOneTypeProperty([[0,0],[0,0],[0,0]], 3, 3)
-
+ tail_pos = TArrayOneTypeProperty([position, position, position],type(position))
+ #Bug quand je declare un TIntProperty. creator.py, index out of range
+
def __init__(self, message=None, pos=None, speaker=None, tailpos=None):
"""
Shows a dialog with a given text, at the given position on the screen.
@param message A string to display to the user
- @param pos A list of the form [x, y]
+ @param pos A list of the form [x, y]
@param speaker treeish representation of the speaking widget
@param tailpos The position of each tail of the bubble; useful to point to
specific elements of the interface
@@ -38,8 +40,6 @@ class BubbleMessage(Action):
self.position = pos
if tailpos:
self.tail_pos = tailpos
- if tailpos2:
- self.tail_pos2 = tailpos2
if message:
self.message = message
@@ -65,7 +65,7 @@ class BubbleMessage(Action):
# TODO: tails are relative to tailpos. They should be relative to
# the speaking widget. Same of the bubble position.
self._bubble = overlayer.TextBubble(text=self.message,
- tailpos=self.tail_pos, tailpos2=self.tail_pos2)
+ tailpos=self.tail_pos)
self._bubble.show()
self.overlay.put(self._bubble, x, y)
self.overlay.queue_draw()
@@ -88,7 +88,7 @@ class BubbleMessage(Action):
assert not self._drag, "bubble action set to editmode twice"
x, y = self.position
self._bubble = overlayer.TextBubble(text=self.message,
- tailpos=self.tail_pos, tailpos2=self.tail_pos2)
+ tailpos=self.tail_pos)
self.overlay.put(self._bubble, x, y)
self._bubble.show()
@@ -96,7 +96,7 @@ class BubbleMessage(Action):
def exit_editmode(self, *args):
x,y = self._drag.position
- self.position = [int(x), int(y)]
+ self.position = [int(x), int(y)]#on perd la validation non ?
if self._drag:
self._drag.draggable = False
self._drag = None
diff --git a/tests/actiontests.py b/tests/actiontests.py
index 265ffa1..50116be 100644
--- a/tests/actiontests.py
+++ b/tests/actiontests.py
@@ -65,7 +65,7 @@ class DialogMessageTest(unittest.TestCase):
class BubbleMessageTest(unittest.TestCase):
def setUp(self):
- self.bubble = addon.create('BubbleMessage', message="Message text", pos=[200, 300], tailpos=[-15, -25], tailpos2=[-15, -25])
+ self.bubble = addon.create('BubbleMessage', message="Message text", pos=[200, 300])
def test_properties(self):
props = self.bubble.get_properties()
@@ -76,8 +76,6 @@ class BubbleMessageTest(unittest.TestCase):
assert "tail_pos" in props, 'No tail position property in BubbleMessage'
- assert "tail_pos2" in props, 'No tail position property in BubbleMessage'
-
class CountAction(Action):
"""
diff --git a/tests/serializertests.py b/tests/serializertests.py
index 320feaf..6c25bae 100644
--- a/tests/serializertests.py
+++ b/tests/serializertests.py
@@ -76,7 +76,7 @@ class XMLSerializerTest(unittest.TestCase):
# Add a few states
act1 = addon.create('BubbleMessage', message="Hi", pos=[300, 450])
ev1 = addon.create('GtkWidgetEventFilter', "0.12.31.2.2", "clicked", "Second")
- act2 = addon.create('BubbleMessage', message="Second message", pos=[250, 150], tailpos=[1,2], tailpos2=[1,2])
+ act2 = addon.create('BubbleMessage', message="Second message", pos=[250, 150], tailpos=[1,2])
st1 = State("INIT")
st1.add_action(act1)
@@ -143,7 +143,7 @@ class XMLSerializerTest(unittest.TestCase):
"""
st = State("INIT")
- act1 = addon.create('BubbleMessage', "Hi!", pos=[10,120], tailpos=[-12,30], tailpos2=[-12,30])
+ act1 = addon.create('BubbleMessage', "Hi!", pos=[10,120], tailpos=[-12,30])
act2 = addon.create('DialogMessage', "Hello again.", pos=[120,10])
act3 = WidgetIdentifyAction()
act4 = DisableWidgetAction("0.0.0.1.0.0.0")
diff --git a/tutorius/constraints.py b/tutorius/constraints.py
index 455ede3..e6c942f 100644
--- a/tutorius/constraints.py
+++ b/tutorius/constraints.py
@@ -205,21 +205,73 @@ class FileConstraint(Constraint):
raise FileConstraintError("Non-existing file : %s"%value)
return
+class IntCheckConstraintError(Exception):#######################################################
+ pass
+
+class IntCheckConstraint(Constraint):###########################################################
+ """
+ Ensures that the value can be converted into an Int
+ """
+ def validate(self, value):
+ try:
+ int(value)#la fonction int() ne peut convertir que des nombres ou des string sinon error
+ except:
+ raise IntCheckConstraintError("The value can't be converted into an Int")
+ return
+
+class FloatCheckConstraintError(Exception):#######################################################
+ pass
+
+class FloatCheckConstraint(Constraint):###########################################################
+ """
+ Ensures that the value can be converted into a float
+ """
+ def validate(self, value):
+ try:
+ float(value)#la fonction float() ne peut convertir que des nombres ou des string sinon error (ex pas de int([0,0]))
+ except:
+ raise FloatCheckConstraintError("The value can't be converted into a float")
+ return
+
+class ListIntCheckConstraintError(Exception):#####################################################
+ pass
+
+class ListIntCheckConstraint(Constraint):#########################################################
+ """
+ Ensures that the value is a tuple of int or can be converted into this
+ """
+ def validate(self, value):
+ try:
+ if len(value)==0:
+ raise IntCheckConstraint("Tuple is empty")
+ for i in range(len(value)):
+ int(value[i])#la fonction int() ne peut convertir que des nombres ou des string sinon error (ex pas de int([0,0]))
+ except:
+ raise IntCheckConstraintError("The value can't be converted into an int")
+ return
+
+class TypeConstraint(Constraint):################################################################
+ """
+ A Type constraint contains a OneType member that can be used in a children
+ class as a basic string. ex : SameTypeConstraint
+ """
+ def __init__(self, one_type):
+ self.one_type = one_type
-class SameTypeConstraintError(Exception):
+class SameTypeConstraintError(Exception):########################################################
pass
-class SameTypeConstraint(Constraint):
+class SameTypeConstraint(TypeConstraint):########################################################
"""
Ensures that the list is not empty and that properties of the list have the same type.
"""
-
def validate(self, value):
- if len(value)==0:
- raise SameTypeConstraintError("The list is empty")
- for i in value:
- if i.type != value[0].type:
- raise SameTypeConstraintError("Properties have diffferent type")
+ if self.one_type is not None:
+ if len(value)==0:
+ raise SameTypeConstraintError("The list is empty")
+ for i in value:
+ if type(i) != self.one_type:
+ raise SameTypeConstraintError("Properties have diffferent type")
return
diff --git a/tutorius/creator.py b/tutorius/creator.py
index 82d0628..a0ef714 100644
--- a/tutorius/creator.py
+++ b/tutorius/creator.py
@@ -297,7 +297,7 @@ class EditToolBox(gtk.Window):
self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_UTILITY)
self.set_destroy_with_parent(True)
self.set_deletable(False)
- self.set_size_request(200, 400)
+ self.set_size_request(400, 400)
self._vbox = gtk.VBox()
self.add(self._vbox)
@@ -337,6 +337,16 @@ class EditToolBox(gtk.Window):
for i in xrange(len(propval)):
entry = propwdg.get_children()[i]
entry.set_text(str(propval[i]))
+ elif isinstance(prop, properties.TArrayOneTypeProperty):################################
+ propwdg = row.get_children()[1]
+ for i in xrange(len(propval)):
+ entry = propwdg.get_children()[i]
+ elif isinstance(prop, properties.TPositionProperty):################################
+ propwdg = row.get_children()[1]
+ for i in xrange(len(propval)):
+ entry = propwdg.get_children()[i]
+ entry.set_text(str(propval[i]))
+ entry.set_text(str(propval[i]))
else:
propwdg = row.get_children()[1]
propwdg.set_text(str(propval))
@@ -379,6 +389,21 @@ class EditToolBox(gtk.Window):
propwdg.pack_start(entry)
entry.connect_after("focus-out-event", \
self._list_prop_changed, action, propname, i)
+ elif isinstance(prop, properties.TArrayOneTypeProperty):####################################
+ propwdg = gtk.HBox()
+ for i in xrange(len(propval)):
+ entry = gtk.Entry()
+ propwdg.pack_start(entry)
+ entry.connect_after("focus-out-event", \
+ self._list_prop_changed, action, propname, i)
+ elif isinstance(prop, properties.TPositionProperty):####################################
+ propwdg = gtk.HBox()
+ for i in xrange(len(propval)):
+ entry = gtk.Entry()
+ propwdg.pack_start(entry)
+ entry.connect_after("focus-out-event", \
+ self._list_prop_changed, action, propname, i)
+
else:
propwdg = gtk.Entry()
propwdg.set_text(str(propval))
diff --git a/tutorius/overlayer.py b/tutorius/overlayer.py
index 4ee5241..8e5be71 100644
--- a/tutorius/overlayer.py
+++ b/tutorius/overlayer.py
@@ -157,7 +157,7 @@ class TextBubble(gtk.Widget):
A CanvasDrawableWidget drawing a round textbox and a tail pointing
to a specified widget.
"""
- def __init__(self, text, speaker=None, tailpos=[[0,0],[0,0],[0,0]]):#list with N éléments (cf bublemessage.py)
+ def __init__(self, text, speaker=None, tailpos=None):
"""
Creates a new cairo rendered text bubble.
@@ -175,7 +175,7 @@ class TextBubble(gtk.Widget):
self.label = text
self.speaker = speaker
- self.tailpos = tailpos
+ self.tailpos = tailpos or []
self.line_width = 5
self.padding = 20
diff --git a/tutorius/properties.py b/tutorius/properties.py
index 65059b2..28f0ed4 100644
--- a/tutorius/properties.py
+++ b/tutorius/properties.py
@@ -133,6 +133,13 @@ class TutoriusProperty(object):
constraint = getattr(self, constraint_name)
constraint.validate(value)
return value
+
+ def type(self,value):################################################
+ """
+ Allow to use type() in the same way for TutoriusProperty or Python elements
+ """
+ if value != None :
+ return self.type
class TAddonListProperty(TutoriusProperty):
"""
@@ -166,9 +173,9 @@ class TIntProperty(TutoriusProperty):
self.type = "int"
self.upper_limit = UpperLimitConstraint(upper_limit)
self.lower_limit = LowerLimitConstraint(lower_limit)
-
+ self.type_check = IntCheckConstraint()##########################################################
self.default = self.validate(value)
-
+ #faut_il convertir value en int quelque part ?
class TFloatProperty(TutoriusProperty):
"""
Represents a floating point number. Can have an upper value limit and/or
@@ -177,12 +184,12 @@ class TFloatProperty(TutoriusProperty):
def __init__(self, value, lower_limit=None, upper_limit=None):
TutoriusProperty.__init__(self)
self.type = "float"
-
+ self.type_check = FloatCheckConstraint()##########################################################
self.upper_limit = UpperLimitConstraint(upper_limit)
self.lower_limit = LowerLimitConstraint(lower_limit)
self.default = self.validate(value)
-
+ #faut_il convertir value en float quelque part ?
class TStringProperty(TutoriusProperty):
"""
Represents a string. Can have a maximum size limit.
@@ -194,7 +201,7 @@ class TStringProperty(TutoriusProperty):
self.default = self.validate(value)
-class TArrayProperty(TutoriusProperty):
+class TArrayProperty(TutoriusProperty):#############################################################
"""
Represents an array of values. Can have a maximum number of element
limit, but there are no constraints on the content of the array.
@@ -202,14 +209,17 @@ class TArrayProperty(TutoriusProperty):
def __init__(self, value, min_size_limit=None, max_size_limit=None):
TutoriusProperty.__init__(self)
self.type = "array"
+ self.indexeur = value #stock la value, pour l'indexation
self.max_size_limit = MaxSizeConstraint(max_size_limit)
self.min_size_limit = MinSizeConstraint(min_size_limit)
- self.indexeur = value #stock la value, pour l'indexation
- self.default = self.validate(value)
+ self.default = self.validate(value)
- #def __getitem__(self, key): # obligation de redéfinir l'indexation
- # return self.indexeur[key] #
+ def __getitem__(self, key): # obligation de redéfinir l'indexation pour le dessin dans overlayer
+ return self.indexeur[key] #
+ #def append(self, value) ?: #invalide
+ #et enlever un élément ?
+
class TColorProperty(TutoriusProperty):
"""
Represents a RGB color with 3 8-bit integer values.
@@ -227,7 +237,7 @@ class TColorProperty(TutoriusProperty):
self._blue = blue or 0
self.default = self.validate([self._red, self._green, self._blue])
-
+
class TFileProperty(TutoriusProperty):
"""
Represents a path to a file on the disk.
@@ -311,36 +321,43 @@ class TAddonProperty(TutoriusProperty):
if isinstance(value, TPropContainer):
return super(TAddonProperty, self).validate(value)
raise ValueError("Expected TPropContainer instance as TaddonProperty value")
-
-
-
-class TPositionProperty(TutoriusProperty):
+
+class TPositionProperty(TutoriusProperty):#########################################################
"""
Represents a tuple of two int. The first value is the x position and the second the y position
"""
def __init__(self, (x, y)):
TutoriusProperty.__init__(self)
self.type = "position"
- self._x=x or 0
+ self._x=x or 0 #peut etre superflu ?
self._y=y or 0
+ self.typeCheck = ListIntCheckConstraint()
+ self.indexeur = [self._x, self._y]
self.default = self.validate((self._x,self._y))
- #voir les contraintes ou créer x en TintProperty
- #convertir en int ou raise error idem sur Tintproperty
-
- #contrainte générique du style is 'type' qui essai de convertir les éléments d'une séquence
-
- #contraintes deux élements
-
-
-class TArrayOneTypeProperty(TArrayProperty):
+
+ def __getitem__(self, key): # obligation de redéfinir l'indexation pour le dessin dans overlayer
+ return self.indexeur[key]
+ #fonctionnement obscur pour la modification des valeur a l'interieur du tuple position (par le clavier)
+
+class TArrayOneTypeProperty(TutoriusProperty):######################################################
"""
- Represents an array list of properties. Can have a maximum (and/or minimum) number of element
- limit. All the elements in the list must have the same type. The list must not be empty
+ Represents an array list of Tutorius_properties. All the elements in the list must have the same type. The list must not be empty
"""
- def __init__(self, value, min_size_limit=None, max_size_limit=None):
- TArrayProperty.__init__(self, value, min_size_limit, max_size_limit)
- self.type = "typedlist"
- self.required_type = SameTypeConstraint()
+ def __init__(self, value, OneType):
+ TutoriusProperty.__init__(self)
+ self.type = OneType
+ self.indexeur = value #stock la value, pour l'indexation
+ self.required_type = SameTypeConstraint(self.type)
self.default = self.validate(value)
+
+ # Tester
+
+ #Ne comprends pas bien les traitements a faire et comment ils sont fait actuellement dans le creator
+ #append
+ #et enlever un élément
+
+ #def __getitem__(self, key): # obligation de redéfinir l'indexation pour le dessin dans overlayer ou pas
+ # return self.indexeur[key]
+