# Copyright (C) 2009, Tutorius.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from ..actions import Action, DragWrapper from ..properties import TStringProperty, TArrayProperty from .. import overlayer from ..services import ObjectStore class BubbleMessage(Action): message = TStringProperty("Message") # Create the position as an array of fixed-size 2 position = TArrayProperty((0,0), 2, 2) # Do the same for the tail position tail_pos = TArrayProperty((0,0), 2, 2) def __init__(self, message=None, position=None, speaker=None, tail_pos=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 position A list of the form [x, y] @param speaker treeish representation of the speaking widget @param tail_pos The position of the tail of the bubble; useful to point to specific elements of the interface """ Action.__init__(self) if position: self.position = position if tail_pos: self.tail_pos = tail_pos if message: self.message = message self.overlay = None self._bubble = None self._speaker = None def do(self, **kwargs): """ 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.overlay: self.overlay = ObjectStore().activity._overlayer 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.tail_pos) 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 def enter_editmode(self, *args): """ Enters edit mode. The action should display itself in some way, without affecting the currently running application. """ if not self.overlay: self.overlay = ObjectStore().activity._overlayer 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) self.overlay.put(self._bubble, x, y) self._bubble.show() self._drag = DragWrapper(self._bubble, self.position, True) def exit_editmode(self, *args): x,y = self._drag.position self.position = (int(x), int(y)) if self._drag: self._drag.draggable = False self._drag = None if self._bubble: self.overlay.remove(self._bubble) self._bubble = None self.overlay = None __action__ = { "name" : "BubbleMessage", "display_name" : "Message Bubble", "icon" : "message-bubble", "class" : BubbleMessage, "mandatory_props" : ["message"] }