Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/util/gtkcompat.py
blob: 9ee9f4a3d96cc96fdf3fbc22682ed4cb42a09d09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Import Gtk and GObject, put include crazy thunks so that old
# code using pygtk and Gtk 2.0 code continues to run.
FORCE_GTK2 = False

try:
  if FORCE_GTK2: raise ValueError("forcing gtk2")
  import gi
  gi.require_version('Gtk', '3.0')
  from gi.repository import Gtk, Gdk, GObject, GdkPixbuf
  from gi.repository import Pango, PangoCairo
  def Rectangle(x, y, w, h):
    r = Gdk.Rectangle()
    r.x, r.y = x, y
    r.width, r.height = w, h
    return r
  GObject.TYPE_NONE = None # compatibility hack
  class GConf:
    pass # XXX no more GConf, sigh

  # No CairoContext wrapper needed for gir/gtk3
  Gdk.CairoContext = lambda x: x # GTK2 compatibility

except ValueError, ImportError:
  # fall back to old pygtk, with various evil hacks
  import pygtk
  pygtk.require('2.0')
  import gtk as Gtk
  import gobject as GObject
  import gconf
  import pango as Pango
  import pangocairo as PangoCairo
  import cairo
  Gdk = Gtk.gdk
  Rectangle = Gdk.Rectangle

  class GConf:
    class Client:
      get_default = gconf.client_get_default

  class GObjectSignalFlags:
    RUN_FIRST = GObject.SIGNAL_RUN_FIRST
  GObject.SignalFlags = GObjectSignalFlags

  Gdk.cairo_set_source_pixbuf = \
    lambda cr, img, x, y: cr.set_source_pixbuf(img, x, y)
  def gdk_pixbuf_get_from_surface(surface, x, y, w, h):
    pixmap = Gdk.Pixmap(None, w, h, 24)
    cr = pixmap.cairo_create()
    cr.set_source_surface(surface, -x, -y)
    cr.rectangle(0,0,w,h);
    cr.set_operator(cairo.OPERATOR_SOURCE)
    cr.fill()
    cmap = Gdk.colormap_get_system()
    return Gdk.pixbuf_get_from_drawable(None, pixmap, cmap, 0, 0, 0, 0, w, h)
  Gdk.pixbuf_get_from_surface = gdk_pixbuf_get_from_surface

  class GdkEventMask:
    EXPOSURE_MASK = Gdk.EXPOSURE_MASK
    BUTTON_PRESS_MASK = Gdk.BUTTON_PRESS_MASK
    BUTTON_RELEASE_MASK = Gdk.BUTTON_RELEASE_MASK
    POINTER_MOTION_MASK = Gdk.POINTER_MOTION_MASK
    KEY_PRESS_MASK = Gdk.KEY_PRESS_MASK
    VISIBILITY_NOTIFY_MASK = Gdk.VISIBILITY_NOTIFY_MASK
  Gdk.EventMask = GdkEventMask

  class GdkModifierType:
    MOD1_MASK = Gdk.MOD1_MASK
    CONTROL_MASK = Gdk.CONTROL_MASK
  Gdk.ModifierType = GdkModifierType

  class GdkPixbuf:
    class InterpType:
      NEAREST = Gdk.INTERP_NEAREST
    class Colorspace:
      RGB = Gdk.COLORSPACE_RGB
    class Pixbuf:
      # XXX not the same as Gdk.Pixbuf, sadly.  don't do instanceof!
      new_from_file_at_size = Gdk.pixbuf_new_from_file_at_size
      new_from_file = Gdk.pixbuf_new_from_file
      loader_new_with_mime_type = Gdk.pixbuf_loader_new_with_mime_type
    class PixbufLoader:
      @staticmethod
      def new_with_type(type):
        return Gdk.PixbufLoader(type)

  class GdkScreen:
    width = Gdk.screen_width
    height = Gdk.screen_height
  Gdk.Screen = GdkScreen

  class GdkVisibilityState:
    FULLY_OBSCURED = Gdk.VISIBILITY_FULLY_OBSCURED
  Gdk.VisibilityState = GdkVisibilityState

  class GdkWindowTypeHint:
    NORMAL = Gdk.WINDOW_TYPE_HINT_NORMAL
  Gdk.WindowTypeHint = GdkWindowTypeHint

  class GtkFileChooserAction:
    OPEN = Gtk.FILE_CHOOSER_ACTION_OPEN
    SAVE = Gtk.FILE_CHOOSER_ACTION_SAVE
  Gtk.FileChooserAction = GtkFileChooserAction

  class GtkResponseType:
    OK = Gtk.RESPONSE_OK
    CANCEL = Gtk.RESPONSE_CANCEL
    ACCEPT = Gtk.RESPONSE_ACCEPT
  Gtk.ResponseType = GtkResponseType

  class GtkButtonsType:
    OK_CANCEL = Gtk.BUTTONS_OK_CANCEL
  Gtk.ButtonsType = GtkButtonsType

  class GtkMessageType:
    INFO = Gtk.MESSAGE_INFO
  Gtk.MessageType = GtkMessageType

  class GtkDialogFlags:
    MODAL = Gtk.DIALOG_MODAL
    DESTROY_WITH_PARENT = Gtk.DIALOG_DESTROY_WITH_PARENT
  Gtk.DialogFlags = GtkDialogFlags

  class GtkIconTheme:
    get_default = Gtk.icon_theme_get_default
  Gtk.IconTheme = GtkIconTheme

  class GtkPolicyType:
    AUTOMATIC = Gtk.POLICY_AUTOMATIC
  Gtk.PolicyType = GtkPolicyType

  class GtkWrapMode:
    WORD = Gtk.WRAP_WORD
  Gtk.WrapMode = GtkWrapMode

  class GtkWindowType:
    TOPLEVEL = Gtk.WINDOW_TOPLEVEL
  Gtk.WindowType = GtkWindowType

  # hack around named parameter for Gtk.Label
  GtkLabel = Gtk.Label
  def GtkLabel2(label=''):
    return GtkLabel(label)
  Gtk.Label = GtkLabel2

  # hack around named parameters
  GtkVBox1 = Gtk.VBox
  class GtkVBox2:
    @staticmethod
    def new(homogenous, spacing):
      return GtkVBox1(homogenous, spacing)
  Gtk.VBox = GtkVBox2

  GtkMenuItem1 = Gtk.MenuItem
  class GtkMenuItem2:
    @staticmethod
    def new_with_label(label):
      return GtkMenuItem1(label)
  Gtk.MenuItem = GtkMenuItem2

  class PangoLayout2(Pango.Layout):
    @staticmethod
    def new(cr):
      # call cr.create_layout(), but wrap the result so we can override
      # set_text() below
      return PangoLayout2(cr.create_layout().get_context())
    def set_text(self, text, val):
      if val != -1: text = text[:val]
      super(PangoLayout2, self).set_text(text)

  Pango.Layout = PangoLayout2

  PangoCairo.create_context = lambda x: PangoCairo.CairoContext(x)
  PangoCairo.update_layout = lambda cr, pl: cr.update_layout(pl)
  PangoCairo.show_layout = lambda cr, pl: cr.show_layout(pl)