diff options
Diffstat (limited to 'src/sugar/tutorius/actions.py')
-rw-r--r-- | src/sugar/tutorius/actions.py | 132 |
1 files changed, 85 insertions, 47 deletions
diff --git a/src/sugar/tutorius/actions.py b/src/sugar/tutorius/actions.py index 58a4216..12de298 100644 --- a/src/sugar/tutorius/actions.py +++ b/src/sugar/tutorius/actions.py @@ -16,8 +16,13 @@ """ This module defines Actions that can be done and undone on a state """ +from gettext import gettext as _ +from sugar.tutorius import gtkutils from dialog import TutoriusDialog +import overlayer +from sugar.tutorius.editor import WidgetIdentifier +from sugar.tutorius.services import ObjectStore class Action(object): @@ -25,7 +30,7 @@ class Action(object): def __init__(self): object.__init__(self) - def do(self): + def do(self, **kwargs): """ Perform the action """ @@ -38,49 +43,12 @@ class Action(object): pass #Should raise NotImplemented? -class DoOnceMixin(object): - """Mixin class used to have an action be called only on the first do(). - - To use this mixin, create a new class that derives from this and from - the action you want executed only once. - - class ConcreteOnceAction(DoOnceMixin, ConcreteAction): - pass +class OnceWrapper(object): + """ + Wraps a class to perform an action once only This ConcreteActions's do() method will only be called on the first do() and the undo() will be callable after do() has been called - - Maybe it would be better off just using a wrapper class instead of this. - - But it was fun to play with. - - Did I mention the wrapper is 25 lines "south" of here? Besides, this mixin - class fails at __init__ ..... mixins... right....narwhals! - """ - def __init__(self ): - super(DoOnceMixin, self).__init__() - self._called = False - self._need_undo = False - - def do(self): - """ - Do the action only on the first time - """ - if not self._called: - self._called = True - super(DoOnceMixin, self).do() - self._need_undo = True - - def undo(self): - """ - Undo the action if it's been done - """ - if self._need_undo: - super(DoOnceMixin, self).undo() - self._need_undo = False - -class OnceWrapper(object): - """Wraps a class to perform an action once only """ def __init__(self, action): self._action = action @@ -95,7 +63,7 @@ class OnceWrapper(object): self._called = True self._action.do() self._need_undo = True - + def undo(self): """ Undo the action if it's been done @@ -105,10 +73,16 @@ class OnceWrapper(object): self._need_undo = False class DialogMessage(Action): - """Show a dialog!""" - def __init__(self, message): + """ + 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] + """ + def __init__(self, message, pos=[0,0]): super(DialogMessage, self).__init__() self._message = message + self.position = pos self._dialog = None def do(self): @@ -118,6 +92,7 @@ class DialogMessage(Action): self._dialog = TutoriusDialog(self._message) self._dialog.set_button_clicked_cb(self._dialog.close_self) self._dialog.set_modal(False) + self._dialog.move(self.position[0], self.position[1]) self._dialog.show() def undo(self): @@ -127,9 +102,72 @@ class DialogMessage(Action): if self._dialog: self._dialog.destroy() self._dialog = None + + +class BubbleMessage(Action): + """ + 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 speaker treeish representation of the speaking widget + """ + def __init__(self, message, pos=[0,0], speaker=None, tailpos=None): + Action.__init__(self) + self._message = message + self.position = pos + + self.overlay = None + self._bubble = None + self._speaker = None + self._tailpos = tailpos + + + def do(self): + """ + Show the dialog + """ + # get or inject overlayer + self.overlay = ObjectStore().activity._overlayer + # FIXME: subwindows, are left to overlap this. This behaviour is + # undesirable. subwindows (i.e. child of top level windows) should be + # handled either by rendering over them, or by finding different way to + # draw the overlay. + + if not self._bubble: + x, y = self.position + # 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._tailpos) + self._bubble.show() + self.overlay.put(self._bubble, x, y) + self.overlay.queue_draw() + + def undo(self): + """ + Destroy the dialog + """ + if self._bubble: + self._bubble.destroy() + self._bubble = None +class WidgetIdentifyAction(Action): + def __init__(self): + self.activity = None + self._dialog = None + + def do(self): + os = ObjectStore() + if os.activity: + self.activity = os.activity + + self._dialog = WidgetIdentifier(self.activity) + self._dialog.show() + + + def undo(self): + if self._dialog: + self._dialog.destroy() -class OnceDialogMessage(DoOnceMixin, DialogMessage): - """Broken!""" - pass |