Several incompatible changes to the experimental proxy API to make it simpler
[rox-lib.git] / python / rox / icon_theme.py
blob6e24eec11fd68a8e7836b6406b0de9e7b8aa256f
1 """This is an internal module. Do not use it. GTK 2.4 will contain functions
2 that replace those defined here."""
4 import os
5 import basedir
6 import rox
8 theme_dirs = [os.path.join(os.environ.get('HOME', '/'), '.icons')] + \
9 list(basedir.load_data_paths('icons'))
11 class Index:
12 """A theme's index.theme file."""
13 def __init__(self, dir):
14 self.dir = dir
15 sections = file(os.path.join(dir, "index.theme")).read().split('\n[')
16 self.sections = {}
17 for s in sections:
18 lines = s.split('\n')
19 sname = lines[0].strip()
21 # Python < 2.2.2 doesn't support an argument to strip...
22 assert sname[-1] == ']'
23 if sname.startswith('['):
24 sname = sname[1:-1]
25 else:
26 sname = sname[:-1]
28 section = self.sections[sname] = {}
29 for line in lines[1:]:
30 if not line.strip(): continue
31 if line.startswith('#'): continue
32 key, value = map(str.strip, line.split('=', 1))
33 section[key] = value
35 self.subdirs = [SubDir(self, d) for
36 d in self.get('Icon Theme', 'Directories').split(';')]
38 def get(self, section, key):
39 "None if not found"
40 return self.sections.get(section, {}).get(key, None)
42 class SubDir:
43 """A subdirectory within a theme."""
44 def __init__(self, index, subdir):
45 icontype = index.get(subdir, 'Type')
46 self.name = subdir
47 self.size = int(index.get(subdir, 'Size'))
48 if icontype == "Fixed":
49 self.min_size = self.max_size = self.size
50 elif icontype == "Threshold":
51 threshold = int(index.get(subdir, 'Threshold'))
52 self.min_size = self.size - threshold
53 self.max_size = self.size + threshold
54 elif icontype == "Scaled":
55 self.min_size = int(index.get(subdir, 'MinSize'))
56 self.max_size = int(index.get(subdir, 'MaxSize'))
57 else:
58 self.min_size = self.max_size = 100000
60 class IconTheme:
61 """Icon themes are located by searching through various directories. You can use an IconTheme
62 to convert an icon name into a suitable image."""
64 def __init__(self, name):
65 self.name = name
67 self.indexes = []
68 for leaf in theme_dirs:
69 theme_dir = os.path.join(leaf, name)
70 index_file = os.path.join(theme_dir, 'index.theme')
71 if os.path.exists(os.path.join(index_file)):
72 try:
73 self.indexes.append(Index(theme_dir))
74 except:
75 rox.report_exception()
77 def lookup_icon(self, iconname, size):
78 icon = self._lookup_this_theme(iconname, size)
79 if icon: return icon
80 # XXX: inherits
82 def _lookup_this_theme(self, iconname, size):
83 dirs = []
84 for i in self.indexes:
85 for d in i.subdirs:
86 if size < d.min_size:
87 diff = d.min_size - size
88 elif size > d.max_size:
89 diff = size - d.max_size
90 else:
91 diff = 0
92 dirs.append((diff, os.path.join(i.dir, d.name)))
94 # Sort by closeness of size
95 dirs.sort()
97 for _, subdir in dirs:
98 for extension in ("png", "svg"):
99 filename = os.path.join(subdir,
100 iconname + '.' + extension)
101 if os.path.exists(filename):
102 return filename
103 return None
105 rox_theme = IconTheme('ROX')