~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/wx/tools/Editra/src/ed_theme.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
###############################################################################
 
2
# Name: ed_theme.py                                                           #
 
3
# Purpose: Icon theme management for Editra                                   #
 
4
# Author: Cody Precord <cprecord@editra.org>                                  #
 
5
# Copyright: (c) 2007 Cody Precord <staff@editra.org>                         #
 
6
# License: wxWindows License                                                  #
 
7
###############################################################################
 
8
 
 
9
"""
 
10
Provide an interface for creating icon themes for Editra. This will allow for
 
11
themes to be created, installed, and managed as plugins, which means that they
 
12
can be installed as single file instead of dozens of individual image files.
 
13
 
 
14
@summary: Editra's theme interface and implementation
 
15
 
 
16
"""
 
17
 
 
18
__author__ = "Cody Precord <cprecord@editra.org>"
 
19
__svnid__ = "$Id: ed_theme.py 69346 2011-10-09 17:22:09Z CJP $"
 
20
__revision__ = "$Revision: 69346 $"
 
21
 
 
22
#--------------------------------------------------------------------------#
 
23
# Imports
 
24
import os
 
25
import wx
 
26
 
 
27
# Local Imports
 
28
import ed_glob
 
29
import util
 
30
import plugin
 
31
from profiler import Profile_Get, Profile_Set
 
32
import syntax.synglob as synglob
 
33
from syntax.syntax import SYNTAX_IDS
 
34
 
 
35
#--------------------------------------------------------------------------#
 
36
 
 
37
class ThemeI(plugin.Interface):
 
38
    """Interface for defining an icon theme in Editra
 
39
    When a icon theme is active Editra's ArtProvider will ask the active
 
40
    theme that implements this interface to give it a bitmap. The requests
 
41
    for bitmaps will be numerical ID values that come from ed_glob. These
 
42
    ID's are associated with different objects in the interface. The names
 
43
    are descriptive of the object they represent, for reference however
 
44
    see the implementation of the two main themes (Tango and Nuovo).
 
45
 
 
46
    @see: L{ed_glob}
 
47
    @see: L{syntax.synglob}
 
48
 
 
49
    """
 
50
    def GetName(self):
 
51
        """Return the name of this theme. This is used to identify the
 
52
        theme when the provider looks for resources based on user preferences
 
53
 
 
54
        @return: name string
 
55
 
 
56
        """
 
57
 
 
58
    def GetMenuBitmap(self, bmp_id):
 
59
        """Get the menu bitmap associated with the object id
 
60
        If this theme does not have a resource to provide for this
 
61
        object return a wx.NullBitmap.
 
62
 
 
63
        @return: 16x16 pixel bitmap
 
64
 
 
65
        """
 
66
        return wx.NullBitmap
 
67
 
 
68
    def GetFileBitmap(self, bmp_id):
 
69
        """Get the filetype bitmap associated with the object id, the
 
70
        valid object ids are defined in the module syntax.synglob and
 
71
        are used to request images for menu's and page tabs. The theme
 
72
        implimenting this interface should at least be able to
 
73
        provide an image for plain text files and return that for any
 
74
        unmapped types.
 
75
 
 
76
        If this theme does not have a resource to provide for this
 
77
        object return a wx.NullBitmap.
 
78
 
 
79
        @return: 16x16 pixel bitmap
 
80
 
 
81
        """
 
82
        return wx.NullBitmap
 
83
 
 
84
    def GetOtherBitmap(self, bmp_id):
 
85
        """Get the bitmap from the 'other' icon resources. Valid id's are
 
86
        identified by a mapping in the ART dictionary.
 
87
        
 
88
        If this theme does not have a resource to provide for this
 
89
        object return a wx.NullBitmap.
 
90
 
 
91
        @return: wx.Bitmap
 
92
 
 
93
        """
 
94
        return wx.NullBitmap
 
95
 
 
96
    def GetToolbarBitmap(self, bmp_id):
 
97
        """Get the toolbar bitmap associated with the object id. The
 
98
        toolbar icons must be returned as a 32x32 pixel bitmap any
 
99
        scaling that is needed will be handled by the art provider that
 
100
        requests the resource.
 
101
 
 
102
        If this theme does not have a resource to provide for this
 
103
        object return a wx.NullBitmap.
 
104
 
 
105
        @return: 32x32 pixel bitmap
 
106
 
 
107
        """
 
108
        return wx.NullBitmap
 
109
 
 
110
#-----------------------------------------------------------------------------#
 
111
 
 
112
class BitmapProvider(plugin.Plugin):
 
113
    """Plugin that fetches requested icons from the current active theme.
 
114
 
 
115
    """
 
116
    observers = plugin.ExtensionPoint(ThemeI)
 
117
 
 
118
    def __GetCurrentProvider(self):
 
119
        """Gets the provider of the current theme resources
 
120
        @return: ThemeI object
 
121
 
 
122
        """
 
123
        theme = Profile_Get('ICONS', 'str', u'')
 
124
        for prov in self.observers:
 
125
            if theme == prov.GetName():
 
126
                return prov
 
127
 
 
128
        # Case if a theme was deleted while it was the active theme
 
129
        if theme.lower() != u'default':
 
130
            Profile_Set('ICONS', u'Default')
 
131
 
 
132
        return None
 
133
 
 
134
    def _GetTango(self, bmp_id, client):
 
135
        """Try to get the icon from the default tango theme"""
 
136
        theme = None
 
137
        bmp = wx.NullBitmap
 
138
        for prov in self.observers:
 
139
            if prov.GetName() == TangoTheme.name:
 
140
                theme = prov
 
141
                break
 
142
        else:
 
143
            return bmp
 
144
 
 
145
        if client == wx.ART_TOOLBAR:
 
146
            bmp = theme.GetToolbarBitmap(bmp_id)
 
147
        elif client == wx.ART_MENU:
 
148
            bmp = theme.GetMenuBitmap(bmp_id)
 
149
        elif client == wx.ART_OTHER:
 
150
            bmp = theme.GetOtherBitmap(bmp_id)
 
151
        else:
 
152
            pass
 
153
 
 
154
        return bmp
 
155
 
 
156
    def GetThemes(self):
 
157
        """Gets a list of the installed and activated themes
 
158
        @return: list of strings
 
159
 
 
160
        """
 
161
        return [ name.GetName() for name in self.observers ]
 
162
 
 
163
    def GetBitmap(self, bmp_id, client):
 
164
        """Gets a 16x16 or 32x32 pixel bitmap depending on client value.
 
165
        May return a NullBitmap if no suitable bitmap can be
 
166
        found.
 
167
 
 
168
        @param bmp_id: id of bitmap to lookup
 
169
        @param client: wxART_MENU, wxART_TOOLBAR
 
170
        @see: L{ed_glob}
 
171
 
 
172
        """
 
173
        prov = self.__GetCurrentProvider()
 
174
        if prov is not None:
 
175
            if client == wx.ART_MENU:
 
176
                bmp = prov.GetMenuBitmap(bmp_id)
 
177
            elif client == wx.ART_OTHER:
 
178
                # Backwards compatibility for older interface
 
179
                if hasattr(prov, 'GetOtherBitmap'):
 
180
                    bmp = prov.GetOtherBitmap(bmp_id)
 
181
                else:
 
182
                    bmp = wx.NullBitmap
 
183
            else:
 
184
                bmp = prov.GetToolbarBitmap(bmp_id)
 
185
 
 
186
            if bmp.IsOk():
 
187
                return bmp
 
188
 
 
189
        # Try to fallback to tango theme when icon lookup fails
 
190
        bmp = self._GetTango(bmp_id, client)
 
191
        if bmp.IsOk():
 
192
            return bmp
 
193
 
 
194
        return wx.NullBitmap
 
195
 
 
196
#-----------------------------------------------------------------------------#
 
197
# Default theme data maps
 
198
ART = { ed_glob.ID_ABOUT  : u'about.png',
 
199
        ed_glob.ID_ADD    : u'add.png',
 
200
        ed_glob.ID_ADD_BM : u'bmark_add.png',
 
201
        ed_glob.ID_ADVANCED : u'advanced.png',
 
202
        ed_glob.ID_BACKWARD : u'backward.png',
 
203
        ed_glob.ID_BIN_FILE : u'bin_file.png',
 
204
        ed_glob.ID_CDROM  : u'cdrom.png',
 
205
        ed_glob.ID_CONTACT : u'mail.png',
 
206
        ed_glob.ID_COPY   : u'copy.png',
 
207
        ed_glob.ID_COMPUTER : u'computer.png',
 
208
        ed_glob.ID_CUT    : u'cut.png',
 
209
        ed_glob.ID_DELETE : u'delete.png',
 
210
        ed_glob.ID_DELETE_ALL : u'delete_all.png',
 
211
        ed_glob.ID_DOCPROP : u'doc_props.png',
 
212
        ed_glob.ID_DOCUMENTATION : u'docs.png',
 
213
        ed_glob.ID_DOWN   : u'down.png',
 
214
        ed_glob.ID_EXIT   : u'quit.png',
 
215
        ed_glob.ID_FILE   : u'file.png',
 
216
        ed_glob.ID_FIND   : u'find.png',
 
217
        ed_glob.ID_FIND_REPLACE : u'findr.png',
 
218
        ed_glob.ID_FIND_RESULTS : u'find.png',
 
219
        ed_glob.ID_FLOPPY : u'floppy.png',
 
220
        ed_glob.ID_FOLDER : u'folder.png',
 
221
        ed_glob.ID_FONT   : u'font.png',
 
222
        ed_glob.ID_FORWARD : u'forward.png',
 
223
        ed_glob.ID_HARDDISK : u'harddisk.png',
 
224
        ed_glob.ID_HOMEPAGE : u'web.png',
 
225
        ed_glob.ID_HTML_GEN : u'html_gen.png',
 
226
        ed_glob.ID_INDENT : u'indent.png',
 
227
        ed_glob.ID_LOGGER : u'log.png',
 
228
        ed_glob.ID_NEW    : u'new.png',
 
229
        ed_glob.ID_NEW_FOLDER : u'newfolder.png',
 
230
        ed_glob.ID_NEW_WINDOW: u'newwin.png',
 
231
        ed_glob.ID_NEXT_MARK : u'bmark_next.png',
 
232
        ed_glob.ID_NEXT_POS : u'forward.png',
 
233
        ed_glob.ID_OPEN    : u'open.png',
 
234
        ed_glob.ID_PACKAGE : u'package.png',
 
235
        ed_glob.ID_PASTE   : u'paste.png',
 
236
        ed_glob.ID_PLUGMGR : u'plugin.png',
 
237
        ed_glob.ID_PRE_MARK : u'bmark_pre.png',
 
238
        ed_glob.ID_PRE_POS : u'backward.png',
 
239
        ed_glob.ID_PREF    : u'pref.png',
 
240
        ed_glob.ID_PRINT   : u'print.png',
 
241
        ed_glob.ID_PRINT_PRE : u'printpre.png',
 
242
        ed_glob.ID_PYSHELL : u'pyshell.png',
 
243
        ed_glob.ID_REDO    : u'redo.png',
 
244
        ed_glob.ID_REFRESH : u'refresh.png',
 
245
        ed_glob.ID_REMOVE  : u'remove.png',
 
246
        ed_glob.ID_RTF_GEN : u'rtf_gen.png',
 
247
        ed_glob.ID_SAVE    : u'save.png',
 
248
        ed_glob.ID_SAVEALL : u'saveall.png',
 
249
        ed_glob.ID_SAVEAS  : u'saveas.png',
 
250
        ed_glob.ID_SELECTALL : u'selectall.png',
 
251
        ed_glob.ID_STOP    : u'stop.png',
 
252
        ed_glob.ID_STYLE_EDIT : u'style_edit.png',
 
253
        ed_glob.ID_TEX_GEN : u'tex_gen.png',
 
254
        ed_glob.ID_THEME  : u'theme.png',
 
255
        ed_glob.ID_UNDO   : u'undo.png',
 
256
        ed_glob.ID_UNINDENT : u'outdent.png',
 
257
        ed_glob.ID_UP     : u'up.png',
 
258
        ed_glob.ID_USB    : u'usb.png',
 
259
        ed_glob.ID_WEB    : u'web.png',
 
260
        ed_glob.ID_ZOOM_IN : u'zoomi.png',
 
261
        ed_glob.ID_ZOOM_OUT : u'zoomo.png',
 
262
        ed_glob.ID_ZOOM_NORMAL : u'zoomd.png',
 
263
        ed_glob.ID_READONLY : u'readonly.png',
 
264
 
 
265
        # code elements
 
266
        ed_glob.ID_CLASS_TYPE : u'class.png',
 
267
        ed_glob.ID_FUNCT_TYPE : u'function.png',
 
268
        ed_glob.ID_ELEM_TYPE : u'element.png',
 
269
        ed_glob.ID_VARIABLE_TYPE : u'variable.png',
 
270
        ed_glob.ID_ATTR_TYPE : u'attribute.png',
 
271
        ed_glob.ID_PROPERTY_TYPE : u'property.png',
 
272
        ed_glob.ID_METHOD_TYPE : u'method.png'
 
273
}
 
274
 
 
275
# File Type Art
 
276
MIME_ART = { synglob.ID_LANG_ADA : u'ada.png',
 
277
             synglob.ID_LANG_BASH : u'shell.png',
 
278
             synglob.ID_LANG_BOO : u'boo.png',
 
279
             synglob.ID_LANG_BOURNE : u'shell.png',
 
280
             synglob.ID_LANG_C : u'c.png',
 
281
             synglob.ID_LANG_CPP : u'cpp.png',
 
282
             synglob.ID_LANG_CSH : u'shell.png',
 
283
             synglob.ID_LANG_CSS : u'css.png',
 
284
             synglob.ID_LANG_DIFF : u'diff.png',
 
285
             synglob.ID_LANG_HTML : u'html.png',
 
286
             synglob.ID_LANG_JAVA : u'java.png',
 
287
             synglob.ID_LANG_KSH : u'shell.png',
 
288
             synglob.ID_LANG_LATEX : u'tex.png',
 
289
             synglob.ID_LANG_MAKE : u'makefile.png',
 
290
             synglob.ID_LANG_PASCAL : u'pascal.png',
 
291
             synglob.ID_LANG_PERL : u'perl.png',
 
292
             synglob.ID_LANG_PHP : u'php.png',
 
293
             synglob.ID_LANG_PS : u'postscript.png',
 
294
             synglob.ID_LANG_PYTHON : u'python.png',
 
295
             synglob.ID_LANG_RUBY : u'ruby.png',
 
296
             synglob.ID_LANG_TCL : u'tcl.png',
 
297
             synglob.ID_LANG_TEX : u'tex.png',
 
298
             synglob.ID_LANG_TXT : u'text.png',
 
299
             synglob.ID_LANG_XML : u'xml.png'
 
300
 }
 
301
 
 
302
#-----------------------------------------------------------------------------#
 
303
 
 
304
class TangoTheme(plugin.Plugin):
 
305
    """Represents the Tango Icon theme for Editra"""
 
306
    plugin.Implements(ThemeI)
 
307
 
 
308
    name = u'Tango'
 
309
 
 
310
    def __GetArtPath(self, client, mime=False):
 
311
        """Gets the path of the resource directory to get
 
312
        the bitmaps from.
 
313
        @param client: wx.ART_MENU/wx.ART_TOOLBAR
 
314
        @keyword mime: is this a filetype icon lookup
 
315
        @return: path of art resource
 
316
        @rtype: string
 
317
 
 
318
        """
 
319
        clients = { wx.ART_MENU : u"menu",
 
320
                    wx.ART_TOOLBAR : u"toolbar",
 
321
                    wx.ART_OTHER : u"other" }
 
322
 
 
323
        # Get the path
 
324
        if ed_glob.CONFIG['THEME_DIR'] == u'':
 
325
            theme = util.ResolvConfigDir(os.path.join(u"pixmaps", u"theme"))
 
326
            ed_glob.CONFIG['THEME_DIR'] = theme
 
327
 
 
328
        if mime:
 
329
            path = os.path.join(ed_glob.CONFIG['THEME_DIR'],
 
330
                                Profile_Get('ICONS'), u'mime')
 
331
        else:
 
332
            path = os.path.join(ed_glob.CONFIG['THEME_DIR'],
 
333
                                self.GetName(),
 
334
                                clients.get(client, u"menu"))
 
335
 
 
336
        path += os.sep
 
337
        if os.path.exists(path):
 
338
            return path
 
339
        else:
 
340
            return None
 
341
 
 
342
    def GetName(self):
 
343
        """Get the name of this theme
 
344
        @return: string
 
345
 
 
346
        """
 
347
        return TangoTheme.name
 
348
 
 
349
    def GetMenuBitmap(self, bmp_id):
 
350
        """Get a menu bitmap
 
351
        @param bmp_id: Id of bitmap to look for
 
352
 
 
353
        """
 
354
        if bmp_id in ART:
 
355
            path = self.__GetArtPath(wx.ART_MENU, mime=False)
 
356
            if path is not None:
 
357
                path = path + ART[bmp_id]
 
358
                if os.path.exists(path):
 
359
                    return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
 
360
        else:
 
361
            return self.GetFileBitmap(bmp_id)
 
362
 
 
363
        return wx.NullBitmap
 
364
 
 
365
    def GetFileBitmap(self, bmp_id):
 
366
        """Get a mime type bitmap from the theme
 
367
        @param bmp_id: Id of filetype bitmap to look up
 
368
        @see: L{syntax.synglob}
 
369
 
 
370
        """
 
371
        path = self.__GetArtPath(wx.ART_MENU, mime=True)
 
372
        if path is not None and bmp_id in SYNTAX_IDS:
 
373
            if bmp_id in MIME_ART:
 
374
                req = path + MIME_ART[bmp_id]
 
375
                if os.path.exists(req):
 
376
                    return wx.Bitmap(req, wx.BITMAP_TYPE_PNG)
 
377
 
 
378
            # Try to fall back to bmp for plain text when above is not found
 
379
            bkup = path + MIME_ART[synglob.ID_LANG_TXT]
 
380
            if os.path.exists(bkup):
 
381
                return wx.Bitmap(bkup, wx.BITMAP_TYPE_PNG)
 
382
 
 
383
        return wx.NullBitmap
 
384
 
 
385
    def GetOtherBitmap(self, bmp_id):
 
386
        """Get a other catagory bitmap.
 
387
        @param bmp_id: Id of art resource
 
388
 
 
389
        """
 
390
        if bmp_id in ART:
 
391
            path = self.__GetArtPath(wx.ART_OTHER, mime=False)
 
392
            if path is not None:
 
393
                path = path + ART[bmp_id]
 
394
                if os.path.exists(path):
 
395
                    return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
 
396
 
 
397
        return wx.NullBitmap
 
398
 
 
399
    def GetToolbarBitmap(self, bmp_id):
 
400
        """Get a toolbar bitmap
 
401
        @param bmp_id: Id of bitmap to look for
 
402
        @return: wx.NullBitmap or a 32x32 bitmap
 
403
 
 
404
        """
 
405
        if bmp_id in ART:
 
406
#            size = Profile_Get('ICON_SZ', default=(24, 24))
 
407
            path = self.__GetArtPath(wx.ART_TOOLBAR, mime=False)
 
408
            if path is not None:
 
409
#                tpath = os.path.join(path, '24', ART[bmp_id])
 
410
#                if size[0] == 24 and os.path.exists(tpath):
 
411
#                    path = tpath
 
412
#                else:
 
413
                path = path + ART[bmp_id]
 
414
 
 
415
                if os.path.exists(path):
 
416
                    return wx.Bitmap(path, wx.BITMAP_TYPE_PNG)
 
417
 
 
418
        return wx.NullBitmap