b1b1d0a4d73f40e1b720adbba875fdd1e144661f
[blender.git] / release / scripts / startup / bl_ui / __init__.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20
21 # note, properties_animviz is a helper module only.
22
23 if "bpy" in locals():
24     from imp import reload as _reload
25     for val in _modules_loaded.values():
26         _reload(val)
27 _modules = [
28     "properties_animviz",
29     "properties_constraint",
30     "properties_data_armature",
31     "properties_data_bone",
32     "properties_data_camera",
33     "properties_data_curve",
34     "properties_data_empty",
35     "properties_data_lamp",
36     "properties_data_lattice",
37     "properties_data_mesh",
38     "properties_data_metaball",
39     "properties_data_modifier",
40     "properties_data_speaker",
41     "properties_game",
42     "properties_mask_common",
43     "properties_material",
44     "properties_object",
45     "properties_paint_common",
46     "properties_particle",
47     "properties_physics_cloth",
48     "properties_physics_common",
49     "properties_physics_dynamicpaint",
50     "properties_physics_field",
51     "properties_physics_fluid",
52     "properties_physics_rigidbody",
53     "properties_physics_rigidbody_constraint",
54     "properties_physics_smoke",
55     "properties_physics_softbody",
56     "properties_render",
57     "properties_render_layer",
58     "properties_scene",
59     "properties_texture",
60     "properties_world",
61     "space_clip",
62     "space_console",
63     "space_dopesheet",
64     "space_filebrowser",
65     "space_graph",
66     "space_image",
67     "space_info",
68     "space_logic",
69     "space_nla",
70     "space_node",
71     "space_outliner",
72     "space_properties",
73     "space_sequencer",
74     "space_text",
75     "space_time",
76     "space_userpref",
77     "space_view3d",
78     "space_view3d_toolbar",
79 ]
80
81 import bpy
82
83 if bpy.app.build_options.freestyle:
84     _modules.append("properties_freestyle")
85 __import__(name=__name__, fromlist=_modules)
86 _namespace = globals()
87 _modules_loaded = {name: _namespace[name] for name in _modules if name != 'bpy'}
88 del _namespace
89
90
91 def register():
92     bpy.utils.register_module(__name__)
93
94     # space_userprefs.py
95     from bpy.props import StringProperty, EnumProperty
96     from bpy.types import WindowManager
97
98     def addon_filter_items(self, context):
99         import addon_utils
100
101         items = [('All', "All", "All Addons"),
102                  ('User', "User", "All Addons Installed by User"),
103                  ('Enabled', "Enabled", "All Enabled Addons"),
104                  ('Disabled', "Disabled", "All Disabled Addons"),
105                  ]
106
107         items_unique = set()
108
109         for mod in addon_utils.modules(refresh=False):
110             info = addon_utils.module_bl_info(mod)
111             items_unique.add(info["category"])
112
113         items.extend([(cat, cat, "") for cat in sorted(items_unique)])
114         return items
115
116     WindowManager.addon_search = StringProperty(
117             name="Search",
118             description="Search within the selected filter",
119             )
120     WindowManager.addon_filter = EnumProperty(
121             items=addon_filter_items,
122             name="Category",
123             description="Filter addons by category",
124             )
125
126     WindowManager.addon_support = EnumProperty(
127             items=[('OFFICIAL', "Official", "Officially supported"),
128                    ('COMMUNITY', "Community", "Maintained by community developers"),
129                    ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")
130                    ],
131             name="Support",
132             description="Display support level",
133             default={'OFFICIAL', 'COMMUNITY'},
134             options={'ENUM_FLAG'},
135             )
136     # done...
137
138
139 def unregister():
140     bpy.utils.unregister_module(__name__)
141
142
143 # Define a default UIList, when a list does not need any custom drawing...
144 # Keep in sync with its #defined name in UI_interface.h
145 class UI_UL_list(bpy.types.UIList):
146     # These are common filtering or ordering operations (same as the default C ones!).
147     @staticmethod
148     def filter_items_by_name(pattern, bitflag, items, propname="name", flags=None, reverse=False):
149         """
150         Set FILTER_ITEM for items which name matches filter_name one (case-insensitive).
151         pattern is the filtering pattern.
152         propname is the name of the string property to use for filtering.
153         flags must be a list of integers the same length as items, or None!
154         return a list of flags (based on given flags if not None),
155         or an empty list if no flags were given and no filtering has been done.
156         """
157         import fnmatch
158
159         if not pattern or not items:  # Empty pattern or list = no filtering!
160             return flags or []
161
162         if flags is None:
163             flags = [0] * len(items)
164
165         # Implicitly add heading/trailing wildcards.
166         pattern = "*" + pattern + "*"
167
168         for i, item in enumerate(items):
169             name = getattr(item, propname, None)
170             # This is similar to a logical xor
171             if bool(name and fnmatch.fnmatchcase(name, pattern)) is not bool(reverse):
172                 flags[i] |= bitflag
173         return flags
174
175     @staticmethod
176     def sort_items_helper(sort_data, key, reverse=False):
177         """
178         Common sorting utility. Returns a neworder list mapping org_idx -> new_idx.
179         sort_data must be an (unordered) list of tuples [(org_idx, ...), (org_idx, ...), ...].
180         key must be the same kind of callable you would use for sorted() builtin function.
181         reverse will reverse the sorting!
182         """
183         sort_data.sort(key=key, reverse=reverse)
184         neworder = [None] * len(sort_data)
185         for newidx, (orgidx, *_) in enumerate(sort_data):
186             neworder[orgidx] = newidx
187         return neworder
188
189     @classmethod
190     def sort_items_by_name(cls, items, propname="name"):
191         """
192         Re-order items using their names (case-insensitive).
193         propname is the name of the string property to use for sorting.
194         return a list mapping org_idx -> new_idx,
195                or an empty list if no sorting has been done.
196         """
197         neworder = [None] * len(items)
198         _sort = [(idx, getattr(it, propname, "")) for idx, it in enumerate(items)]
199         return cls.sort_items_helper(_sort, lambda e: e[1].lower())
200
201
202 bpy.utils.register_class(UI_UL_list)