dc06f92d69c29caa62ae5e54d940827cb953818f
[platform/upstream/pygobject2.git] / gi / overrides / Gdk.py
1 # -*- Mode: Python; py-indent-offset: 4 -*-
2 # vim: tabstop=4 shiftwidth=4 expandtab
3 #
4 # Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
5 #               2010 Simon van der Linden <svdlinden@src.gnome.org>
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
20 # USA
21
22 from ..overrides import override
23 from ..module import get_introspection_module
24
25 import sys
26
27 Gdk = get_introspection_module('Gdk')
28
29 __all__ = []
30
31
32 class Color(Gdk.Color):
33     MAX_VALUE = 65535
34
35     def __init__(self, red, green, blue):
36         Gdk.Color.__init__(self)
37         self.red = red
38         self.green = green
39         self.blue = blue
40
41     def __new__(cls, *args, **kwargs):
42         return Gdk.Color.__new__(cls)
43
44     def __eq__(self, other):
45         return self.equal(other)
46
47     def __repr__(self):
48         return '<Gdk.Color(red=%d, green=%d, blue=%d)>' % (self.red, self.green, self.blue)
49
50     red_float = property(fget=lambda self: self.red / float(self.MAX_VALUE),
51                          fset=lambda self, v: setattr(self, 'red', int(v * self.MAX_VALUE)))
52
53     green_float = property(fget=lambda self: self.green / float(self.MAX_VALUE),
54                            fset=lambda self, v: setattr(self, 'green', int(v * self.MAX_VALUE)))
55
56     blue_float = property(fget=lambda self: self.blue / float(self.MAX_VALUE),
57                           fset=lambda self, v: setattr(self, 'blue', int(v * self.MAX_VALUE)))
58
59     def to_floats(self):
60         """Return (red_float, green_float, blue_float) triple."""
61
62         return (self.red_float, self.green_float, self.blue_float)
63
64     @staticmethod
65     def from_floats(red, green, blue):
66         """Return a new Color object from red/green/blue values from 0.0 to 1.0."""
67
68         return Color(int(red * Color.MAX_VALUE),
69                      int(green * Color.MAX_VALUE),
70                      int(blue * Color.MAX_VALUE))
71
72 Color = override(Color)
73 __all__.append('Color')
74
75 if Gdk._version == '3.0':
76     class RGBA(Gdk.RGBA):
77         def __init__(self, red=1.0, green=1.0, blue=1.0, alpha=1.0):
78             Gdk.RGBA.__init__(self)
79             self.red = red
80             self.green = green
81             self.blue = blue
82             self.alpha = alpha
83
84         def __new__(cls, *args, **kwargs):
85             return Gdk.RGBA.__new__(cls)
86
87         def __eq__(self, other):
88             return self.equal(other)
89
90         def __repr__(self):
91             return '<Gdk.Color(red=%f, green=%f, blue=%f, alpha=%f)>' % (self.red, self.green, self.blue, self.alpha)
92
93         def __iter__(self):
94             """Iterator which allows easy conversion to tuple and list types."""
95
96             yield self.red
97             yield self.green
98             yield self.blue
99             yield self.alpha
100
101         def to_color(self):
102             """Converts this RGBA into a Color instance which excludes alpha."""
103
104             return Color(int(self.red * Color.MAX_VALUE),
105                          int(self.green * Color.MAX_VALUE),
106                          int(self.blue * Color.MAX_VALUE))
107
108         @classmethod
109         def from_color(cls, color):
110             """Returns a new RGBA instance given a Color instance."""
111
112             return cls(color.red_float, color.green_float, color.blue_float)
113
114     RGBA = override(RGBA)
115     __all__.append('RGBA')
116
117 if Gdk._version == '2.0':
118     class Rectangle(Gdk.Rectangle):
119
120         def __init__(self, x, y, width, height):
121             Gdk.Rectangle.__init__(self)
122             self.x = x
123             self.y = y
124             self.width = width
125             self.height = height
126
127         def __new__(cls, *args, **kwargs):
128             return Gdk.Rectangle.__new__(cls)
129
130         def __repr__(self):
131             return '<Gdk.Rectangle(x=%d, y=%d, width=%d, height=%d)>' % (self.x, self.y, self.height, self.width)
132
133     Rectangle = override(Rectangle)
134     __all__.append('Rectangle')
135 else:
136     from gi.repository import cairo as _cairo
137     Rectangle = _cairo.RectangleInt
138
139     __all__.append('Rectangle')
140
141 if Gdk._version == '2.0':
142     class Drawable(Gdk.Drawable):
143         def cairo_create(self):
144             return Gdk.cairo_create(self)
145
146     Drawable = override(Drawable)
147     __all__.append('Drawable')
148 else:
149     class Window(Gdk.Window):
150         def __new__(cls, parent, attributes, attributes_mask):
151             # Gdk.Window had to be made abstract,
152             # this override allows using the standard constructor
153             return Gdk.Window.new(parent, attributes, attributes_mask)
154
155         def __init__(self, parent, attributes, attributes_mask):
156             pass
157
158         def cairo_create(self):
159             return Gdk.cairo_create(self)
160
161     Window = override(Window)
162     __all__.append('Window')
163
164 Gdk.EventType._2BUTTON_PRESS = getattr(Gdk.EventType, "2BUTTON_PRESS")
165 Gdk.EventType._3BUTTON_PRESS = getattr(Gdk.EventType, "3BUTTON_PRESS")
166
167
168 class Event(Gdk.Event):
169     _UNION_MEMBERS = {
170         Gdk.EventType.DELETE: 'any',
171         Gdk.EventType.DESTROY: 'any',
172         Gdk.EventType.EXPOSE: 'expose',
173         Gdk.EventType.MOTION_NOTIFY: 'motion',
174         Gdk.EventType.BUTTON_PRESS: 'button',
175         Gdk.EventType._2BUTTON_PRESS: 'button',
176         Gdk.EventType._3BUTTON_PRESS: 'button',
177         Gdk.EventType.BUTTON_RELEASE: 'button',
178         Gdk.EventType.KEY_PRESS: 'key',
179         Gdk.EventType.KEY_RELEASE: 'key',
180         Gdk.EventType.ENTER_NOTIFY: 'crossing',
181         Gdk.EventType.LEAVE_NOTIFY: 'crossing',
182         Gdk.EventType.FOCUS_CHANGE: 'focus_change',
183         Gdk.EventType.CONFIGURE: 'configure',
184         Gdk.EventType.MAP: 'any',
185         Gdk.EventType.UNMAP: 'any',
186         Gdk.EventType.PROPERTY_NOTIFY: 'property',
187         Gdk.EventType.SELECTION_CLEAR: 'selection',
188         Gdk.EventType.SELECTION_REQUEST: 'selection',
189         Gdk.EventType.SELECTION_NOTIFY: 'selection',
190         Gdk.EventType.PROXIMITY_IN: 'proximity',
191         Gdk.EventType.PROXIMITY_OUT: 'proximity',
192         Gdk.EventType.DRAG_ENTER: 'dnd',
193         Gdk.EventType.DRAG_LEAVE: 'dnd',
194         Gdk.EventType.DRAG_MOTION: 'dnd',
195         Gdk.EventType.DRAG_STATUS: 'dnd',
196         Gdk.EventType.DROP_START: 'dnd',
197         Gdk.EventType.DROP_FINISHED: 'dnd',
198         Gdk.EventType.CLIENT_EVENT: 'client',
199         Gdk.EventType.VISIBILITY_NOTIFY: 'visibility',
200     }
201
202     if Gdk._version == '2.0':
203         _UNION_MEMBERS[Gdk.EventType.NO_EXPOSE] = 'no_expose'
204
205     def __new__(cls, *args, **kwargs):
206         return Gdk.Event.__new__(cls)
207
208     def __getattr__(self, name):
209         real_event = getattr(self, '_UNION_MEMBERS').get(self.type)
210         if real_event:
211             return getattr(getattr(self, real_event), name)
212         else:
213             raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
214
215 Event = override(Event)
216 __all__.append('Event')
217
218 # manually bind GdkEvent members to GdkEvent
219
220 modname = globals()['__name__']
221 module = sys.modules[modname]
222
223 # right now we can't get the type_info from the
224 # field info so manually list the class names
225 event_member_classes = ['EventAny',
226                         'EventExpose',
227                         'EventVisibility',
228                         'EventMotion',
229                         'EventButton',
230                         'EventScroll',
231                         'EventKey',
232                         'EventCrossing',
233                         'EventFocus',
234                         'EventConfigure',
235                         'EventProperty',
236                         'EventSelection',
237                         'EventOwnerChange',
238                         'EventProximity',
239                         'EventDND',
240                         'EventWindowState',
241                         'EventSetting',
242                         'EventGrabBroken']
243
244 if Gdk._version == '2.0':
245     event_member_classes.append('EventNoExpose')
246
247 # whitelist all methods that have a success return we want to mask
248 gsuccess_mask_funcs = ['get_state',
249                        'get_axis',
250                        'get_coords',
251                        'get_root_coords']
252
253
254 def _gsuccess_mask(func):
255     def cull_success(*args):
256         result = func(*args)
257         success = result[0]
258         if not success:
259             return None
260         else:
261             if len(result) == 2:
262                 return result[1]
263             else:
264                 return result[1:]
265     return cull_success
266
267 for event_class in event_member_classes:
268     override_class = type(event_class, (getattr(Gdk, event_class),), {})
269     # add the event methods
270     for method_info in Gdk.Event.__info__.get_methods():
271         name = method_info.get_name()
272         event_method = getattr(Gdk.Event, name)
273         # python2 we need to use the __func__ attr to avoid internal
274         # instance checks
275         event_method = getattr(event_method, '__func__', event_method)
276
277         # use the _gsuccess_mask decorator if this method is whitelisted
278         if name in gsuccess_mask_funcs:
279             event_method = _gsuccess_mask(event_method)
280         setattr(override_class, name, event_method)
281
282     setattr(module, event_class, override_class)
283     __all__.append(event_class)
284
285 # end GdkEvent overrides
286
287
288 class DragContext(Gdk.DragContext):
289     def finish(self, success, del_, time):
290         Gtk = get_introspection_module('Gtk')
291         Gtk.drag_finish(self, success, del_, time)
292
293 DragContext = override(DragContext)
294 __all__.append('DragContext')
295
296
297 class Cursor(Gdk.Cursor):
298     def __new__(cls, *args, **kwds):
299         arg_len = len(args)
300         kwd_len = len(kwds)
301         total_len = arg_len + kwd_len
302
303         def _new(cursor_type):
304             return cls.new(cursor_type)
305
306         def _new_for_display(display, cursor_type):
307             return cls.new_for_display(display, cursor_type)
308
309         def _new_from_pixbuf(display, pixbuf, x, y):
310             return cls.new_from_pixbuf(display, pixbuf, x, y)
311
312         def _new_from_pixmap(source, mask, fg, bg, x, y):
313             return cls.new_from_pixmap(source, mask, fg, bg, x, y)
314
315         _constructor = None
316         if total_len == 1:
317             _constructor = _new
318         elif total_len == 2:
319             _constructor = _new_for_display
320         elif total_len == 4:
321             _constructor = _new_from_pixbuf
322         elif total_len == 6:
323             if Gdk._version != '2.0':
324                 # pixmaps don't exist in Gdk 3.0
325                 raise ValueError("Wrong number of parameters")
326             _constructor = _new_from_pixmap
327         else:
328             raise ValueError("Wrong number of parameters")
329
330         return _constructor(*args, **kwds)
331
332     def __init__(self, *args, **kwargs):
333         Gdk.Cursor.__init__(self)
334
335 Cursor = override(Cursor)
336 __all__.append('Cursor')
337
338 _Gdk_color_parse = Gdk.color_parse
339
340
341 @override(Gdk.color_parse)
342 def color_parse(color):
343     success, color = _Gdk_color_parse(color)
344     if not success:
345         return None
346     return color
347
348
349 # Note, we cannot override the entire class as Gdk.Atom has no gtype, so just
350 # hack some individual methods
351 def _gdk_atom_str(atom):
352     n = atom.name()
353     if n:
354         return n
355     # fall back to atom index
356     return 'Gdk.Atom<%i>' % hash(atom)
357
358
359 def _gdk_atom_repr(atom):
360     n = atom.name()
361     if n:
362         return 'Gdk.Atom<%s>' % n
363     # fall back to atom index
364     return 'Gdk.Atom<%i>' % hash(atom)
365
366
367 Gdk.Atom.__str__ = _gdk_atom_str
368 Gdk.Atom.__repr__ = _gdk_atom_repr
369
370
371 # constants
372 if Gdk._version >= '3.0':
373     SELECTION_PRIMARY = Gdk.atom_intern('PRIMARY', True)
374     __all__.append('SELECTION_PRIMARY')
375
376     SELECTION_SECONDARY = Gdk.atom_intern('SECONDARY', True)
377     __all__.append('SELECTION_SECONDARY')
378
379     SELECTION_CLIPBOARD = Gdk.atom_intern('CLIPBOARD', True)
380     __all__.append('SELECTION_CLIPBOARD')
381
382     TARGET_BITMAP = Gdk.atom_intern('BITMAP', True)
383     __all__.append('TARGET_BITMAP')
384
385     TARGET_COLORMAP = Gdk.atom_intern('COLORMAP', True)
386     __all__.append('TARGET_COLORMAP')
387
388     TARGET_DRAWABLE = Gdk.atom_intern('DRAWABLE', True)
389     __all__.append('TARGET_DRAWABLE')
390
391     TARGET_PIXMAP = Gdk.atom_intern('PIXMAP', True)
392     __all__.append('TARGET_PIXMAP')
393
394     TARGET_STRING = Gdk.atom_intern('STRING', True)
395     __all__.append('TARGET_STRING')
396
397     SELECTION_TYPE_ATOM = Gdk.atom_intern('ATOM', True)
398     __all__.append('SELECTION_TYPE_ATOM')
399
400     SELECTION_TYPE_BITMAP = Gdk.atom_intern('BITMAP', True)
401     __all__.append('SELECTION_TYPE_BITMAP')
402
403     SELECTION_TYPE_COLORMAP = Gdk.atom_intern('COLORMAP', True)
404     __all__.append('SELECTION_TYPE_COLORMAP')
405
406     SELECTION_TYPE_DRAWABLE = Gdk.atom_intern('DRAWABLE', True)
407     __all__.append('SELECTION_TYPE_DRAWABLE')
408
409     SELECTION_TYPE_INTEGER = Gdk.atom_intern('INTEGER', True)
410     __all__.append('SELECTION_TYPE_INTEGER')
411
412     SELECTION_TYPE_PIXMAP = Gdk.atom_intern('PIXMAP', True)
413     __all__.append('SELECTION_TYPE_PIXMAP')
414
415     SELECTION_TYPE_WINDOW = Gdk.atom_intern('WINDOW', True)
416     __all__.append('SELECTION_TYPE_WINDOW')
417
418     SELECTION_TYPE_STRING = Gdk.atom_intern('STRING', True)
419     __all__.append('SELECTION_TYPE_STRING')
420
421 import sys
422
423 initialized, argv = Gdk.init_check(sys.argv)
424 if not initialized:
425     raise RuntimeError("Gdk couldn't be initialized")