1 /* SPDX-FileCopyrightText: 2023 Blender Authors
3 * SPDX-License-Identifier: GPL-2.0-or-later */
6 * \ingroup pythonintern
8 * This file defines a singleton py object accessed via 'bpy.utils.previews',
9 * which exposes low-level API for custom previews/icons.
10 * It is replaced in final API by an higher-level python wrapper, that handles previews by addon,
11 * and automatically release them on deletion.
15 #include <structmember.h>
17 #include "RNA_access.hh"
18 #include "RNA_prototypes.hh"
21 #include "bpy_utils_previews.hh"
23 #include "../generic/py_capi_utils.hh"
25 #include "IMB_thumbs.hh"
27 #include "BKE_preview_image.hh"
29 #define STR_SOURCE_TYPES "'IMAGE', 'MOVIE', 'BLEND', 'FONT'"
33 bpy_utils_previews_new_doc
,
34 ".. method:: new(name)\n"
36 " Generate a new empty preview.\n"
38 " :arg name: The name (unique id) identifying the preview.\n"
40 " :return: The Preview matching given name, or a new empty one.\n"
41 " :rtype: :class:`bpy.types.ImagePreview`\n"
42 /* This is only true when accessed via 'bpy.utils.previews.ImagePreviewCollection.load',
43 * however this is the public API, allow this minor difference to the internal version here. */
44 " :raises KeyError: if ``name`` already exists.");
45 static PyObject
*bpy_utils_previews_new(PyObject
* /*self*/, PyObject
*args
)
50 if (!PyArg_ParseTuple(args
, "s:new", &name
)) {
54 prv
= BKE_previewimg_cached_ensure(name
);
55 PointerRNA ptr
= RNA_pointer_create_discrete(nullptr, &RNA_ImagePreview
, prv
);
57 return pyrna_struct_CreatePyObject(&ptr
);
62 bpy_utils_previews_load_doc
,
63 ".. method:: load(name, filepath, filetype, force_reload=False)\n"
65 " Generate a new preview from given file path.\n"
67 " :arg name: The name (unique id) identifying the preview.\n"
69 " :arg filepath: The file path to generate the preview from.\n"
70 " :type filepath: str | bytes\n"
71 " :arg filetype: The type of file, needed to generate the preview in [" STR_SOURCE_TYPES
73 " :type filetype: str\n"
74 " :arg force_reload: If True, force running thumbnail manager even if preview already "
76 " :type force_reload: bool\n"
77 " :return: The Preview matching given name, or a new empty one.\n"
78 " :rtype: :class:`bpy.types.ImagePreview`\n"
79 /* This is only true when accessed via 'bpy.utils.previews.ImagePreviewCollection.load',
80 * however this is the public API, allow this minor difference to the internal version here. */
81 " :raises KeyError: if ``name`` already exists.");
82 static PyObject
*bpy_utils_previews_load(PyObject
* /*self*/, PyObject
*args
)
85 PyC_UnicodeAsBytesAndSize_Data filepath_data
= {nullptr};
86 const PyC_StringEnumItems path_type_items
[] = {
87 {THB_SOURCE_IMAGE
, "IMAGE"},
88 {THB_SOURCE_MOVIE
, "MOVIE"},
89 {THB_SOURCE_BLEND
, "BLEND"},
90 {THB_SOURCE_FONT
, "FONT"},
91 {THB_SOURCE_OBJECT_IO
, "OBJECT_IO"},
94 PyC_StringEnum path_type
= {
96 /* The default isn't used. */
99 int force_reload
= false;
101 if (!PyArg_ParseTuple(args
,
103 "O&" /* `filepath` */
104 "O&" /* `filetype` */
105 "|" /* Optional arguments. */
106 "p" /* `force_reload` */
109 PyC_ParseUnicodeAsBytesAndSize
,
118 PreviewImage
*prv
= BKE_previewimg_cached_thumbnail_read(
119 name
, filepath_data
.value
, path_type
.value_found
, force_reload
);
121 Py_XDECREF(filepath_data
.value_coerce
);
123 PointerRNA ptr
= RNA_pointer_create_discrete(nullptr, &RNA_ImagePreview
, prv
);
124 return pyrna_struct_CreatePyObject(&ptr
);
129 bpy_utils_previews_release_doc
,
130 ".. method:: release(name)\n"
132 " Release (free) a previously created preview.\n"
135 " :arg name: The name (unique id) identifying the preview.\n"
136 " :type name: str\n");
137 static PyObject
*bpy_utils_previews_release(PyObject
* /*self*/, PyObject
*args
)
141 if (!PyArg_ParseTuple(args
, "s:release", &name
)) {
145 BKE_previewimg_cached_release(name
);
150 static PyMethodDef bpy_utils_previews_methods
[] = {
151 /* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */
152 {"new", (PyCFunction
)bpy_utils_previews_new
, METH_VARARGS
, bpy_utils_previews_new_doc
},
153 {"load", (PyCFunction
)bpy_utils_previews_load
, METH_VARARGS
, bpy_utils_previews_load_doc
},
155 (PyCFunction
)bpy_utils_previews_release
,
157 bpy_utils_previews_release_doc
},
158 {nullptr, nullptr, 0, nullptr},
163 bpy_utils_previews_doc
,
164 "This object contains basic static methods to handle cached (non-ID) previews in Blender\n"
165 "(low-level API, not exposed to final users).");
166 static PyModuleDef bpy_utils_previews_module
= {
167 /*m_base*/ PyModuleDef_HEAD_INIT
,
168 /*m_name*/ "bpy._utils_previews",
169 /*m_doc*/ bpy_utils_previews_doc
,
171 /*m_methods*/ bpy_utils_previews_methods
,
173 /*m_traverse*/ nullptr,
178 PyObject
*BPY_utils_previews_module()
182 submodule
= PyModule_Create(&bpy_utils_previews_module
);