forked from bartvdbraak/blender
154 lines
4.0 KiB
Python
154 lines
4.0 KiB
Python
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
#
|
|
# This program 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 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program 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 this program; if not, write to the Free Software Foundation,
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
# <pep8 compliant>
|
|
|
|
"""
|
|
This module contains utility functions to handle custom previews.
|
|
|
|
It behaves as a high-level 'cached' previews manager.
|
|
|
|
This allows scripts to generate their own previews, and use them as icons in UI widgets
|
|
('icon_value' for UILayout functions).
|
|
|
|
|
|
Custom Icon Example
|
|
-------------------
|
|
|
|
.. literalinclude:: ../../../release/scripts/templates_py/ui_previews_custom_icon.py
|
|
"""
|
|
|
|
__all__ = (
|
|
"new",
|
|
"remove",
|
|
"ImagePreviewCollection",
|
|
)
|
|
|
|
import _bpy
|
|
_utils_previews = _bpy._utils_previews
|
|
del _bpy
|
|
|
|
|
|
_uuid_open = set()
|
|
|
|
|
|
# High-level previews manager.
|
|
# not accessed directly
|
|
class ImagePreviewCollection(dict):
|
|
"""
|
|
Dictionary-like class of previews.
|
|
|
|
This is a subclass of Python's built-in dict type,
|
|
used to store multiple image previews.
|
|
|
|
.. note::
|
|
|
|
- instance with :mod:`bpy.utils.previews.new`
|
|
- keys must be ``str`` type.
|
|
- values will be :class:`bpy.types.ImagePreview`
|
|
"""
|
|
|
|
# Internal notes:
|
|
# - Blender's internal 'PreviewImage' struct uses 'self._uuid' prefix.
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._uuid = hex(id(self))
|
|
_uuid_open.add(self._uuid)
|
|
|
|
def __del__(self):
|
|
if self._uuid not in _uuid_open:
|
|
return
|
|
|
|
raise ResourceWarning(
|
|
"<%s id=%s[%d]>: left open, remove with "
|
|
"'bpy.utils.previews.remove()'" %
|
|
(self.__class__.__name__, self._uuid, len(self)))
|
|
self.close()
|
|
|
|
def _gen_key(self, name):
|
|
return ":".join((self._uuid, name))
|
|
|
|
def new(self, name):
|
|
if name in self:
|
|
raise KeyException("key %r already exists")
|
|
p = self[name] = _utils_previews.new(
|
|
self._gen_key(name))
|
|
return p
|
|
new.__doc__ = _utils_previews.new.__doc__
|
|
|
|
def load(self, name, path, path_type, force_reload=False):
|
|
if name in self:
|
|
raise KeyException("key %r already exists")
|
|
p = self[name] = _utils_previews.load(
|
|
self._gen_key(name), path, path_type, force_reload)
|
|
return p
|
|
load.__doc__ = _utils_previews.load.__doc__
|
|
|
|
def clear(self):
|
|
"""Clear all previews."""
|
|
for name in self.keys():
|
|
_utils_previews.release(self._gen_key(name))
|
|
super().clear()
|
|
|
|
def close(self):
|
|
"""Close the collection and clear all previews."""
|
|
self.clear()
|
|
_uuid_open.remove(self._uuid)
|
|
|
|
def __delitem__(self, key):
|
|
_utils_previews.release(self._gen_key(key))
|
|
super().__delitem__(key)
|
|
|
|
def __repr__(self):
|
|
return "<%s id=%s[%d], %s>" % (
|
|
self.__class__.__name__,
|
|
self._uuid,
|
|
len(self),
|
|
super().__repr__())
|
|
|
|
|
|
def new():
|
|
"""
|
|
:return: a new preview collection.
|
|
:rtype: :class:`ImagePreviewCollection`
|
|
"""
|
|
|
|
return ImagePreviewCollection()
|
|
|
|
|
|
def remove(pcoll):
|
|
"""
|
|
Remove the specified previews collection.
|
|
|
|
:arg pcoll: Preview collection to close.
|
|
:type pcoll: :class:`ImagePreviewCollection`
|
|
"""
|
|
pcoll.close()
|
|
|
|
|
|
# don't complain about resources on exit (only unregister)
|
|
import atexit
|
|
|
|
|
|
def exit_clear_warning():
|
|
del ImagePreviewCollection.__del__
|
|
|
|
atexit.register(exit_clear_warning)
|
|
del atexit, exit_clear_warning
|