-
Notifications
You must be signed in to change notification settings - Fork 439
Expand file tree
/
Copy pathbitmap_loader.py
More file actions
149 lines (122 loc) · 4.95 KB
/
bitmap_loader.py
File metadata and controls
149 lines (122 loc) · 4.95 KB
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
# =============================================================================
# Copyright (C) 2010 Diego Duclos
#
# This file is part of pyfa.
#
# pyfa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyfa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pyfa. If not, see <http://www.gnu.org/licenses/>.
# =============================================================================
import io
import os.path
import zipfile
from collections import OrderedDict
# noinspection PyPackageRequirements
import wx
from logbook import Logger
import config
pyfalog = Logger(__name__)
class BitmapLoader:
# Can be None if we're running from tests
if config.imgsZIP is None:
pyfalog.info("Using local image files.")
archive = None
else:
try:
archive = zipfile.ZipFile(config.imgsZIP, 'r')
pyfalog.info("Using zipped image files.")
except (IOError, TypeError):
pyfalog.info("Using local image files.")
archive = None
cached_bitmaps = OrderedDict()
dont_use_cached_bitmaps = False
max_cached_bitmaps = 500
scaling_factor = None
@classmethod
def getStaticBitmap(cls, name, parent, location):
bitmap = cls.getBitmap(name or 0, location)
if bitmap is None:
return None
static = wx.StaticBitmap(parent)
static.SetBitmap(bitmap)
return static
@classmethod
def getBitmap(cls, name, location):
if cls.dont_use_cached_bitmaps:
return cls.loadBitmap(name, location)
path = "%s%s" % (name, location)
if len(cls.cached_bitmaps) == cls.max_cached_bitmaps:
cls.cached_bitmaps.popitem(False)
if path not in cls.cached_bitmaps:
bmp = cls.loadBitmap(name, location)
cls.cached_bitmaps[path] = bmp
else:
bmp = cls.cached_bitmaps[path]
return bmp
@classmethod
def getImage(cls, name, location):
bmp = cls.getBitmap(name, location)
if bmp is not None:
return bmp.ConvertToImage()
else:
return None
@classmethod
def loadBitmap(cls, name, location):
if cls.scaling_factor is None:
cls.scaling_factor = 1 if 'wxGTK' in wx.PlatformInfo else int(wx.GetApp().GetTopWindow().GetContentScaleFactor())
scale = cls.scaling_factor
filename, img = cls.loadScaledBitmap(name, location, scale)
while img is None and scale > 0:
# can't find the correctly scaled image, fallback to smaller scales
scale -= 1
filename, img = cls.loadScaledBitmap(name, location, scale)
if img is None:
pyfalog.warning("Missing icon file: {0}/{1}".format(location, filename))
return None
return BitmapLoader.getScaledBitmap(image=img, scale=scale)
@staticmethod
def getScaledBitmap(image: wx.Image, scale: int) -> wx.Bitmap:
if scale > 1:
image.Rescale(image.GetWidth() // scale, image.GetHeight() // scale)
return image.ConvertToBitmap()
@classmethod
def loadScaledBitmap(cls, name, location, scale=0):
"""Attempts to load a scaled bitmap.
Args:
name (str): TypeID or basename of the image being requested.
location (str): Path to a location that may contain the image.
scale (int): Scale factor of the image variant to load. If ``0``, attempts to load the unscaled variant.
Returns:
(str, wx.Image): Tuple of the filename that may have been loaded and the image at that location. The
filename will always be present, but the image may be ``None``.
"""
filename = "{0}@{1}x.png".format(name, scale) if scale > 0 else "{0}.png".format(name)
img = cls.loadImage(filename, location)
return filename, img
@classmethod
def loadImage(cls, filename, location):
if cls.archive:
path = os.path.join(location, filename)
if os.sep != "/" and os.sep in path:
path = path.replace(os.sep, "/")
try:
img_data = cls.archive.read(path)
bbuf = io.BytesIO(img_data)
return wx.Image(bbuf)
except KeyError:
pyfalog.warning("Missing icon file from zip: {0}".format(path))
else:
path = os.path.join(config.pyfaPath, 'imgs' + os.sep + location + os.sep + filename)
if os.path.exists(path):
return wx.Image(path)
else:
return None