diff options
-rw-r--r-- | tutorius/overlayer.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/tutorius/overlayer.py b/tutorius/overlayer.py index 5eb0f49..f20ba83 100644 --- a/tutorius/overlayer.py +++ b/tutorius/overlayer.py @@ -769,4 +769,78 @@ class Mask(gtk.EventBox): gobject.type_register(Mask) +class Encircle(gtk.EventBox): + """ + A CanvasDrawableWidget drawing a rectangle over a specified widget. + """ + def __init__(self, widget, catch_events=False, pass_thru=()): + """ + Creates a new Rectangle + + @param catch_events whether the Mask should catch events + @param pass_thru the widgets that "punch holes" through this Mask. + Events will pass through to those widgets. + """ + gtk.EventBox.__init__(self) + self.wid = widget + self.no_expose = True # ignored + self._catch_events = False + self.catch_events = catch_events + self.pass_thru = list(pass_thru) + + def __del__(self): + for widget in self.pass_thru: + widget.drag_unhighlight() + + + def set_catch_events(self, do_catch): + """Sets whether the mask catches events of widgets under it""" + if bool(self._catch_events) ^ bool(do_catch): + if do_catch: + self._catch_events = True + self.grab_add() + else: + self.grab_remove() + self._catch_events = False + + def get_catch_events(self): + """Gets whether the mask catches events of widgets under it""" + return bool(self._catch_handle) + + catch_events = property(fset=set_catch_events, fget=get_catch_events) + + def draw_with_context(self, context): + """ + Draw using the passed cairo context instead of creating a new cairo + context. This eases blending between multiple cairo-rendered + widgets. + """ + # Fill container + mask_alloc = self.wid.get_allocation() + oldrule = context.get_fill_rule() + context.set_fill_rule(cairo.FILL_RULE_EVEN_ODD) + x, y = self.wid.translate_coordinates(self, 0, 0) + + context.rectangle(x-8, y-8, mask_alloc.width+16, mask_alloc.height+16) + # Draw the "hole" in the rectangle to give a rectangle outline to the widget + context.rectangle(x-2, y-2, mask_alloc.width+4, mask_alloc.height+4) + context.set_source_rgb(*xo_fill_color) + context.fill() + context.set_fill_rule(oldrule) + + def do_size_request(self, requisition): + """Fill requisition with size occupied by the masked widget.""" + # This is required for the event box to span across the widget + alloc = self.wid.get_allocation() + # Add 5 pixels more than the height and width of the widget to make a rectangle outline around it + requisition.width = alloc.width + 16 + requisition.height = alloc.height +16 + + def do_size_allocate(self, allocation): + """Save zone allocated to the widget.""" + self.allocation = allocation + +gobject.type_register(Encircle) + + # vim:set ts=4 sts=4 sw=4 et: |