2023-08-16 00:20:26 +10:00
|
|
|
# SPDX-FileCopyrightText: 2011-2023 Blender Authors
|
2023-06-15 13:09:04 +10:00
|
|
|
#
|
2022-02-11 09:07:11 +11:00
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
2011-03-21 12:35:49 +00:00
|
|
|
|
|
|
|
|
# note, properties_animviz is a helper module only.
|
|
|
|
|
|
2016-03-04 06:14:02 +11:00
|
|
|
# support reloading sub-modules
|
2011-03-21 12:35:49 +00:00
|
|
|
if "bpy" in locals():
|
2015-01-23 12:37:58 +11:00
|
|
|
from importlib import reload
|
2017-03-29 12:35:00 +11:00
|
|
|
_modules_loaded[:] = [reload(val) for val in _modules_loaded]
|
2015-01-23 12:37:58 +11:00
|
|
|
del reload
|
2016-03-03 06:31:11 +11:00
|
|
|
|
2013-03-21 23:25:18 +00:00
|
|
|
_modules = [
|
2024-01-25 14:46:04 +01:00
|
|
|
"anim",
|
2023-08-03 16:54:39 +02:00
|
|
|
"asset_shelf",
|
2022-09-26 12:36:13 -05:00
|
|
|
"node_add_menu",
|
2023-08-24 13:46:11 +02:00
|
|
|
"node_add_menu_compositor",
|
2022-09-26 12:36:13 -05:00
|
|
|
"node_add_menu_geometry",
|
2023-09-01 23:36:34 +02:00
|
|
|
"node_add_menu_shader",
|
2023-09-05 21:52:31 +02:00
|
|
|
"node_add_menu_texture",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_animviz",
|
2013-03-11 01:59:48 +00:00
|
|
|
"properties_constraint",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_data_armature",
|
|
|
|
|
"properties_data_bone",
|
|
|
|
|
"properties_data_camera",
|
|
|
|
|
"properties_data_curve",
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
"properties_data_curves",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_data_empty",
|
2023-06-22 10:51:43 +02:00
|
|
|
"properties_data_grease_pencil",
|
2018-06-27 14:41:53 +02:00
|
|
|
"properties_data_light",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_data_lattice",
|
|
|
|
|
"properties_data_mesh",
|
|
|
|
|
"properties_data_metaball",
|
|
|
|
|
"properties_data_modifier",
|
2020-03-17 14:41:48 +01:00
|
|
|
"properties_data_pointcloud",
|
2018-07-31 10:22:19 +02:00
|
|
|
"properties_data_shaderfx",
|
2017-06-12 20:59:54 +10:00
|
|
|
"properties_data_lightprobe",
|
2011-08-01 11:44:20 +00:00
|
|
|
"properties_data_speaker",
|
2020-03-17 14:41:48 +01:00
|
|
|
"properties_data_volume",
|
2012-07-25 13:09:12 +00:00
|
|
|
"properties_mask_common",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_material",
|
2018-07-31 10:22:19 +02:00
|
|
|
"properties_material_gpencil",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_object",
|
2013-08-30 11:46:19 +00:00
|
|
|
"properties_paint_common",
|
2014-02-13 19:49:26 +02:00
|
|
|
"properties_grease_pencil_common",
|
2016-12-28 17:30:58 +01:00
|
|
|
"properties_particle",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_physics_cloth",
|
|
|
|
|
"properties_physics_common",
|
2011-05-24 07:08:58 +00:00
|
|
|
"properties_physics_dynamicpaint",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_physics_field",
|
Geometry Nodes: add simulation support
This adds support for building simulations with geometry nodes. A new
`Simulation Input` and `Simulation Output` node allow maintaining a
simulation state across multiple frames. Together these two nodes form
a `simulation zone` which contains all the nodes that update the simulation
state from one frame to the next.
A new simulation zone can be added via the menu
(`Simulation > Simulation Zone`) or with the node add search.
The simulation state contains a geometry by default. However, it is possible
to add multiple geometry sockets as well as other socket types. Currently,
field inputs are evaluated and stored for the preceding geometry socket in
the order that the sockets are shown. Simulation state items can be added
by linking one of the empty sockets to something else. In the sidebar, there
is a new panel that allows adding, removing and reordering these sockets.
The simulation nodes behave as follows:
* On the first frame, the inputs of the `Simulation Input` node are evaluated
to initialize the simulation state. In later frames these sockets are not
evaluated anymore. The `Delta Time` at the first frame is zero, but the
simulation zone is still evaluated.
* On every next frame, the `Simulation Input` node outputs the simulation
state of the previous frame. Nodes in the simulation zone can edit that
data in arbitrary ways, also taking into account the `Delta Time`. The new
simulation state has to be passed to the `Simulation Output` node where it
is cached and forwarded.
* On a frame that is already cached or baked, the nodes in the simulation
zone are not evaluated, because the `Simulation Output` node can return
the previously cached data directly.
It is not allowed to connect sockets from inside the simulation zone to the
outside without going through the `Simulation Output` node. This is a necessary
restriction to make caching and sub-frame interpolation work. Links can go into
the simulation zone without problems though.
Anonymous attributes are not propagated by the simulation nodes unless they
are explicitly stored in the simulation state. This is unfortunate, but
currently there is no practical and reliable alternative. The core problem
is detecting which anonymous attributes will be required for the simulation
and afterwards. While we can detect this for the current evaluation, we can't
look into the future in time to see what data will be necessary. We intend to
make it easier to explicitly pass data through a simulation in the future,
even if the simulation is in a nested node group.
There is a new `Simulation Nodes` panel in the physics tab in the properties
editor. It allows baking all simulation zones on the selected objects. The
baking options are intentially kept at a minimum for this MVP. More features
for simulation baking as well as baking in general can be expected to be added
separately.
All baked data is stored on disk in a folder next to the .blend file. #106937
describes how baking is implemented in more detail. Volumes can not be baked
yet and materials are lost during baking for now. Packing the baked data into
the .blend file is not yet supported.
The timeline indicates which frames are currently cached, baked or cached but
invalidated by user-changes.
Simulation input and output nodes are internally linked together by their
`bNode.identifier` which stays the same even if the node name changes. They
are generally added and removed together. However, there are still cases where
"dangling" simulation nodes can be created currently. Those generally don't
cause harm, but would be nice to avoid this in more cases in the future.
Co-authored-by: Hans Goudey <h.goudey@me.com>
Co-authored-by: Lukas Tönne <lukas@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/104924
2023-05-03 13:18:51 +02:00
|
|
|
"properties_physics_geometry_nodes",
|
2013-01-23 05:56:44 +00:00
|
|
|
"properties_physics_rigidbody",
|
2013-01-23 05:56:56 +00:00
|
|
|
"properties_physics_rigidbody_constraint",
|
2019-12-16 15:42:07 +01:00
|
|
|
"properties_physics_fluid",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_physics_softbody",
|
|
|
|
|
"properties_render",
|
2018-11-02 11:56:41 +11:00
|
|
|
"properties_output",
|
2017-11-22 10:52:39 -02:00
|
|
|
"properties_view_layer",
|
2011-03-21 12:35:49 +00:00
|
|
|
"properties_scene",
|
|
|
|
|
"properties_texture",
|
|
|
|
|
"properties_world",
|
2021-03-16 19:35:53 +01:00
|
|
|
"properties_collection",
|
2023-01-27 14:44:06 +01:00
|
|
|
"generic_ui_list",
|
2017-10-21 16:19:48 +11:00
|
|
|
|
|
|
|
|
# Generic Space Modules
|
|
|
|
|
#
|
|
|
|
|
# Depends on DNA_WORKSPACE_TOOL (C define).
|
2017-11-02 23:05:13 +11:00
|
|
|
"space_toolsystem_common",
|
2017-10-21 16:19:48 +11:00
|
|
|
"space_toolsystem_toolbar",
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
"space_clip",
|
2011-03-21 12:35:49 +00:00
|
|
|
"space_console",
|
|
|
|
|
"space_dopesheet",
|
|
|
|
|
"space_filebrowser",
|
|
|
|
|
"space_graph",
|
|
|
|
|
"space_image",
|
|
|
|
|
"space_info",
|
|
|
|
|
"space_nla",
|
|
|
|
|
"space_node",
|
|
|
|
|
"space_outliner",
|
2013-06-19 19:37:17 +00:00
|
|
|
"space_properties",
|
2011-03-21 12:35:49 +00:00
|
|
|
"space_sequencer",
|
2021-03-08 16:23:21 +01:00
|
|
|
"space_spreadsheet",
|
2018-05-23 22:38:25 +02:00
|
|
|
"space_statusbar",
|
2011-03-21 12:35:49 +00:00
|
|
|
"space_text",
|
|
|
|
|
"space_time",
|
UI: New Global Top-Bar (WIP)
== Main Features/Changes for Users
* Add horizontal bar at top of all non-temp windows, consisting out of two horizontal sub-bars.
* Upper sub-bar contains global menus (File, Render, etc.), tabs for workspaces and scene selector.
* Lower sub-bar contains object mode selector, screen-layout and render-layer selector. Later operator and/or tool settings will be placed here.
* Individual sections of the topbar are individually scrollable.
* Workspace tabs can be double- or ctrl-clicked for renaming and contain 'x' icon for deleting.
* Top-bar should scale nicely with DPI.
* The lower half of the top-bar can be hided by dragging the lower top-bar edge up. Better hiding options are planned (e.g. hide in fullscreen modes).
* Info editors at the top of the window and using the full window width with be replaced by the top-bar.
* In fullscreen modes, no more info editor is added on top, the top-bar replaces it.
== Technical Features/Changes
* Adds initial support for global areas
A global area is part of the window, not part of the regular screen-layout.
I've added a macro iterator to iterate over both, global and screen-layout level areas. When iterating over areas, from now on developers should always consider if they have to include global areas.
* Adds a TOPBAR editor type
The editor type is hidden in the UI editor type menu.
* Adds a variation of the ID template to display IDs as tab buttons (template_ID_tabs in BPY)
* Does various changes to RNA button creation code to improve their appearance in the horizontal top-bar.
* Adds support for dynamically sized regions. That is, regions that scale automatically to the layout bounds.
The code for this is currently a big hack (it's based on drawing the UI multiple times). This should definitely be improved.
* Adds a template for displaying operator properties optimized for the top-bar. This will probably change a lot still and is in fact disabled in code.
Since the final top-bar design depends a lot on other 2.8 designs (mainly tool-system and workspaces), we decided to not show the operator or tool settings in the top-bar for now. That means most of the lower sub-bar is empty for the time being.
NOTE: Top-bar or global area data is not written to files or SDNA. They are simply added to the window when opening Blender or reading a file. This allows us doing changes to the top-bar without having to care for compatibility.
== ToDo's
It's a bit hard to predict all the ToDo's here are the known main ones:
* Add options for the new active-tool system and for operator redo to the topbar.
* Automatically hide the top-bar in fullscreen modes.
* General visual polish.
* Top-bar drag & drop support (WIP in temp-tab_drag_drop).
* Improve dynamic regions (should also fix some layout glitches).
* Make internal terminology consistent.
* Enable topbar file writing once design is more advanced.
* Address TODO's and XXX's in code :)
Thanks @brecht for the review! And @sergey for the complaining ;)
Differential Revision: D2758
2018-04-20 17:14:03 +02:00
|
|
|
"space_topbar",
|
2011-03-21 12:35:49 +00:00
|
|
|
"space_userpref",
|
|
|
|
|
"space_view3d",
|
|
|
|
|
"space_view3d_toolbar",
|
2018-08-30 13:30:16 +10:00
|
|
|
|
|
|
|
|
# XXX, keep last so panels show after all other tool options.
|
2018-08-21 15:27:29 +02:00
|
|
|
"properties_workspace",
|
2018-06-05 16:32:11 +02:00
|
|
|
]
|
2013-03-21 23:25:18 +00:00
|
|
|
|
|
|
|
|
import bpy
|
|
|
|
|
|
|
|
|
|
if bpy.app.build_options.freestyle:
|
|
|
|
|
_modules.append("properties_freestyle")
|
2016-03-03 06:31:11 +11:00
|
|
|
|
2011-03-21 12:35:49 +00:00
|
|
|
__import__(name=__name__, fromlist=_modules)
|
|
|
|
|
_namespace = globals()
|
2016-03-03 06:31:11 +11:00
|
|
|
_modules_loaded = [_namespace[name] for name in _modules]
|
2011-03-21 12:35:49 +00:00
|
|
|
del _namespace
|
|
|
|
|
|
2022-12-15 09:34:22 +11:00
|
|
|
|
2024-01-18 11:25:48 +11:00
|
|
|
# Bypass the caching mechanism in the "Format" panel to make sure it is properly translated on language update.
|
|
|
|
|
@bpy.app.handlers.persistent
|
|
|
|
|
def translation_update(_):
|
|
|
|
|
from .properties_output import RENDER_PT_format
|
|
|
|
|
RENDER_PT_format._frame_rate_args_prev = None
|
|
|
|
|
|
|
|
|
|
|
2011-03-21 12:35:49 +00:00
|
|
|
def register():
|
2017-03-18 20:03:24 +11:00
|
|
|
from bpy.utils import register_class
|
2024-01-23 14:17:02 +11:00
|
|
|
for cls in classes:
|
|
|
|
|
register_class(cls)
|
2017-03-18 20:03:24 +11:00
|
|
|
for mod in _modules_loaded:
|
|
|
|
|
for cls in mod.classes:
|
|
|
|
|
register_class(cls)
|
2011-03-21 12:35:49 +00:00
|
|
|
|
2021-10-20 11:54:09 +02:00
|
|
|
space_filebrowser.register_props()
|
|
|
|
|
|
2018-02-01 13:58:44 +11:00
|
|
|
from bpy.props import (
|
|
|
|
|
EnumProperty,
|
|
|
|
|
StringProperty,
|
|
|
|
|
)
|
UI: Support UI list tooltips, defined via Python scripts
Makes it possible to create tooltips for UI list rows, which can be
filled in .py scripts, similar to how they can extend other menus. This
is used by the (to be committed) Pose Library add-on to display pose
operations (selecting bones of a pose, blending a pose, etc).
It's important that the Python scripts check if the UI list is the
correct one by checking the list ID.
For this to work, a new `bpy.context.ui_list` can be checked. For
example, the Pose Library add-on does the following check:
```
def is_pose_asset_view() -> bool:
# Important: Must check context first, or the menu is added for every kind of list.
list = getattr(context, "ui_list", None)
if not list or list.bl_idname != "UI_UL_asset_view" or list.list_id != "pose_assets":
return False
if not context.asset_handle:
return False
return True
```
2021-07-13 15:01:00 +02:00
|
|
|
from bpy.types import (
|
|
|
|
|
WindowManager,
|
|
|
|
|
)
|
2011-03-21 12:35:49 +00:00
|
|
|
|
UI: Support UI list tooltips, defined via Python scripts
Makes it possible to create tooltips for UI list rows, which can be
filled in .py scripts, similar to how they can extend other menus. This
is used by the (to be committed) Pose Library add-on to display pose
operations (selecting bones of a pose, blending a pose, etc).
It's important that the Python scripts check if the UI list is the
correct one by checking the list ID.
For this to work, a new `bpy.context.ui_list` can be checked. For
example, the Pose Library add-on does the following check:
```
def is_pose_asset_view() -> bool:
# Important: Must check context first, or the menu is added for every kind of list.
list = getattr(context, "ui_list", None)
if not list or list.bl_idname != "UI_UL_asset_view" or list.list_id != "pose_assets":
return False
if not context.asset_handle:
return False
return True
```
2021-07-13 15:01:00 +02:00
|
|
|
# space_userprefs.py
|
2019-04-19 07:32:24 +02:00
|
|
|
def addon_filter_items(_self, _context):
|
2011-05-26 18:11:59 +00:00
|
|
|
import addon_utils
|
|
|
|
|
|
2018-02-01 13:58:44 +11:00
|
|
|
items = [
|
|
|
|
|
('All', "All", "All Add-ons"),
|
|
|
|
|
('User', "User", "All Add-ons Installed by User"),
|
|
|
|
|
]
|
2011-05-26 18:11:59 +00:00
|
|
|
|
|
|
|
|
items_unique = set()
|
|
|
|
|
|
2013-08-28 06:36:54 +00:00
|
|
|
for mod in addon_utils.modules(refresh=False):
|
2024-02-01 17:03:40 +11:00
|
|
|
bl_info = addon_utils.module_bl_info(mod)
|
|
|
|
|
items_unique.add(bl_info["category"])
|
2011-05-26 18:11:59 +00:00
|
|
|
|
|
|
|
|
items.extend([(cat, cat, "") for cat in sorted(items_unique)])
|
|
|
|
|
return items
|
|
|
|
|
|
2011-08-19 19:25:20 +00:00
|
|
|
WindowManager.addon_search = StringProperty(
|
2022-07-10 10:35:05 +02:00
|
|
|
name="Filter",
|
|
|
|
|
description="Filter by add-on name, author & category",
|
2018-02-01 13:58:44 +11:00
|
|
|
options={'TEXTEDIT_UPDATE'},
|
|
|
|
|
)
|
2011-03-21 12:35:49 +00:00
|
|
|
WindowManager.addon_filter = EnumProperty(
|
2018-02-01 13:58:44 +11:00
|
|
|
items=addon_filter_items,
|
|
|
|
|
name="Category",
|
|
|
|
|
description="Filter add-ons by category",
|
|
|
|
|
)
|
2011-03-21 12:35:49 +00:00
|
|
|
|
2022-12-15 09:39:23 +11:00
|
|
|
# These items are static but depend on the version cycle.
|
|
|
|
|
items = [
|
|
|
|
|
('OFFICIAL', "Official", "Officially supported"),
|
|
|
|
|
('COMMUNITY', "Community", "Maintained by community developers"),
|
|
|
|
|
]
|
|
|
|
|
if bpy.app.version_cycle == "alpha":
|
|
|
|
|
items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"))
|
|
|
|
|
|
2011-03-21 12:35:49 +00:00
|
|
|
WindowManager.addon_support = EnumProperty(
|
2022-12-15 09:39:23 +11:00
|
|
|
items=items,
|
2018-02-01 13:58:44 +11:00
|
|
|
name="Support",
|
|
|
|
|
description="Display support level",
|
|
|
|
|
default={'OFFICIAL', 'COMMUNITY'},
|
|
|
|
|
options={'ENUM_FLAG'},
|
|
|
|
|
)
|
2022-12-15 09:39:23 +11:00
|
|
|
del items
|
|
|
|
|
|
2024-01-18 11:25:48 +11:00
|
|
|
bpy.app.handlers.translation_update_post.append(translation_update)
|
|
|
|
|
|
2011-03-21 12:35:49 +00:00
|
|
|
# done...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def unregister():
|
2017-03-18 20:03:24 +11:00
|
|
|
from bpy.utils import unregister_class
|
|
|
|
|
for mod in reversed(_modules_loaded):
|
|
|
|
|
for cls in reversed(mod.classes):
|
2017-03-29 12:35:00 +11:00
|
|
|
if cls.is_registered:
|
|
|
|
|
unregister_class(cls)
|
2024-01-23 14:17:02 +11:00
|
|
|
for cls in reversed(classes):
|
|
|
|
|
if cls.is_registered:
|
|
|
|
|
unregister_class(cls)
|
2013-01-15 23:15:32 +00:00
|
|
|
|
2024-01-18 11:25:48 +11:00
|
|
|
try:
|
|
|
|
|
bpy.app.handlers.translation_update_post.remove(translation_update)
|
|
|
|
|
except ValueError:
|
|
|
|
|
pass
|
|
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
# Define a default UIList, when a list does not need any custom drawing...
|
2023-08-05 02:57:52 +02:00
|
|
|
# Keep in sync with its #defined name in UI_interface.hh
|
2018-06-05 16:32:11 +02:00
|
|
|
|
|
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
class UI_UL_list(bpy.types.UIList):
|
2013-08-29 12:55:31 +00:00
|
|
|
# These are common filtering or ordering operations (same as the default C ones!).
|
|
|
|
|
@staticmethod
|
|
|
|
|
def filter_items_by_name(pattern, bitflag, items, propname="name", flags=None, reverse=False):
|
|
|
|
|
"""
|
|
|
|
|
Set FILTER_ITEM for items which name matches filter_name one (case-insensitive).
|
|
|
|
|
pattern is the filtering pattern.
|
|
|
|
|
propname is the name of the string property to use for filtering.
|
|
|
|
|
flags must be a list of integers the same length as items, or None!
|
|
|
|
|
return a list of flags (based on given flags if not None),
|
2013-09-18 05:20:43 +00:00
|
|
|
or an empty list if no flags were given and no filtering has been done.
|
2013-08-29 12:55:31 +00:00
|
|
|
"""
|
|
|
|
|
import fnmatch
|
2023-11-04 16:53:49 +11:00
|
|
|
import re
|
2013-08-29 12:55:31 +00:00
|
|
|
|
2013-08-29 14:37:46 +00:00
|
|
|
if not pattern or not items: # Empty pattern or list = no filtering!
|
2013-08-29 12:55:31 +00:00
|
|
|
return flags or []
|
|
|
|
|
|
|
|
|
|
if flags is None:
|
|
|
|
|
flags = [0] * len(items)
|
2013-08-29 14:37:46 +00:00
|
|
|
|
|
|
|
|
# Implicitly add heading/trailing wildcards.
|
2024-04-17 14:47:13 +10:00
|
|
|
pattern_regex = re.compile(fnmatch.translate("*" + pattern + "*"), re.IGNORECASE)
|
2013-08-29 14:37:46 +00:00
|
|
|
|
|
|
|
|
for i, item in enumerate(items):
|
|
|
|
|
name = getattr(item, propname, None)
|
2023-11-04 16:53:49 +11:00
|
|
|
# This is similar to a logical XOR.
|
|
|
|
|
if bool(name and pattern_regex.match(name)) is not reverse:
|
2013-08-29 14:37:46 +00:00
|
|
|
flags[i] |= bitflag
|
2013-08-29 12:55:31 +00:00
|
|
|
return flags
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def sort_items_helper(sort_data, key, reverse=False):
|
|
|
|
|
"""
|
|
|
|
|
Common sorting utility. Returns a neworder list mapping org_idx -> new_idx.
|
|
|
|
|
sort_data must be an (unordered) list of tuples [(org_idx, ...), (org_idx, ...), ...].
|
|
|
|
|
key must be the same kind of callable you would use for sorted() builtin function.
|
|
|
|
|
reverse will reverse the sorting!
|
|
|
|
|
"""
|
|
|
|
|
sort_data.sort(key=key, reverse=reverse)
|
|
|
|
|
neworder = [None] * len(sort_data)
|
|
|
|
|
for newidx, (orgidx, *_) in enumerate(sort_data):
|
|
|
|
|
neworder[orgidx] = newidx
|
|
|
|
|
return neworder
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def sort_items_by_name(cls, items, propname="name"):
|
|
|
|
|
"""
|
|
|
|
|
Re-order items using their names (case-insensitive).
|
|
|
|
|
propname is the name of the string property to use for sorting.
|
|
|
|
|
return a list mapping org_idx -> new_idx,
|
2024-06-01 16:17:01 +10:00
|
|
|
or an empty list if no sorting has been done.
|
2013-08-29 12:55:31 +00:00
|
|
|
"""
|
|
|
|
|
_sort = [(idx, getattr(it, propname, "")) for idx, it in enumerate(items)]
|
|
|
|
|
return cls.sort_items_helper(_sort, lambda e: e[1].lower())
|
|
|
|
|
|
This commit frees list ui items from their dependencies to Panel, and hence from all the limitations this implied (mostly, the "only one list per panel" one).
It introduces a new (py-extendable and registrable) RNA type, UIList (roughly similar to Panel one), which currently contains only "standard" list's scroll pos and size (but may be expended to include e.g. some filtering data, etc.). This now makes lists completely independent from Panels!
This UIList has a draw_item callback which allows to customize items' drawing from python, that all addons can now use. Incidentally, this also greatly simplifies the C code of this widget, as we do not code any "special case" here anymore!
To make all this work, other changes were also necessary:
* Now all buttons (uiBut struct) have a 'custom_data' void pointer, used currently to store the uiList struct associated with a given uiLayoutListBox.
* DynamicPaintSurface now exposes a new bool, use_color_preview (readonly), saying whether that surface has some 3D view preview data or not.
* UILayout class has now four new (static) functions, to get the actual icon of any RNA object (important e.g. with materials or textures), and to get an enum item's UI name, description and icon.
* UILayout's label() func now takes an optional 'icon_value' integer parameter, which if not zero will override the 'icon' one (mandatory to use "custom" icons as generated for material/texture/... previews).
Note: not sure whether we should add that one to all UILayout's prop funcs?
Note: will update addons using template list asap.
2012-12-28 09:20:16 +00:00
|
|
|
|
UI: Support UI list tooltips, defined via Python scripts
Makes it possible to create tooltips for UI list rows, which can be
filled in .py scripts, similar to how they can extend other menus. This
is used by the (to be committed) Pose Library add-on to display pose
operations (selecting bones of a pose, blending a pose, etc).
It's important that the Python scripts check if the UI list is the
correct one by checking the list ID.
For this to work, a new `bpy.context.ui_list` can be checked. For
example, the Pose Library add-on does the following check:
```
def is_pose_asset_view() -> bool:
# Important: Must check context first, or the menu is added for every kind of list.
list = getattr(context, "ui_list", None)
if not list or list.bl_idname != "UI_UL_asset_view" or list.list_id != "pose_assets":
return False
if not context.asset_handle:
return False
return True
```
2021-07-13 15:01:00 +02:00
|
|
|
class UI_MT_list_item_context_menu(bpy.types.Menu):
|
|
|
|
|
"""
|
|
|
|
|
UI List item context menu definition. Scripts can append/prepend this to
|
|
|
|
|
add own operators to the context menu. They must check context though, so
|
|
|
|
|
their items only draw in a valid context and for the correct UI list.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
bl_label = "List Item"
|
|
|
|
|
bl_idname = "UI_MT_list_item_context_menu"
|
|
|
|
|
|
2024-12-11 11:26:24 +11:00
|
|
|
def draw(self, _context):
|
UI: Support UI list tooltips, defined via Python scripts
Makes it possible to create tooltips for UI list rows, which can be
filled in .py scripts, similar to how they can extend other menus. This
is used by the (to be committed) Pose Library add-on to display pose
operations (selecting bones of a pose, blending a pose, etc).
It's important that the Python scripts check if the UI list is the
correct one by checking the list ID.
For this to work, a new `bpy.context.ui_list` can be checked. For
example, the Pose Library add-on does the following check:
```
def is_pose_asset_view() -> bool:
# Important: Must check context first, or the menu is added for every kind of list.
list = getattr(context, "ui_list", None)
if not list or list.bl_idname != "UI_UL_asset_view" or list.list_id != "pose_assets":
return False
if not context.asset_handle:
return False
return True
```
2021-07-13 15:01:00 +02:00
|
|
|
# Dummy function. This type is just for scripts to append their own
|
|
|
|
|
# context menu items.
|
|
|
|
|
pass
|
|
|
|
|
|
2022-04-19 15:05:55 +10:00
|
|
|
|
2022-08-18 14:42:48 +02:00
|
|
|
class UI_MT_button_context_menu(bpy.types.Menu):
|
|
|
|
|
"""
|
|
|
|
|
UI button context menu definition. Scripts can append/prepend this to
|
|
|
|
|
add own operators to the context menu. They must check context though, so
|
|
|
|
|
their items only draw in a valid context and for the correct buttons.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
bl_label = "List Item"
|
|
|
|
|
bl_idname = "UI_MT_button_context_menu"
|
|
|
|
|
|
2024-12-11 11:26:24 +11:00
|
|
|
def draw(self, _context):
|
2022-08-18 14:42:48 +02:00
|
|
|
# Draw menu entries created with the legacy `WM_MT_button_context` class.
|
|
|
|
|
# This is deprecated, and support will be removed in a future release.
|
|
|
|
|
if hasattr(bpy.types, "WM_MT_button_context"):
|
|
|
|
|
self.layout.menu_contents("WM_MT_button_context")
|
|
|
|
|
|
|
|
|
|
|
2024-01-23 14:17:02 +11:00
|
|
|
classes = (
|
|
|
|
|
UI_UL_list,
|
|
|
|
|
UI_MT_list_item_context_menu,
|
|
|
|
|
UI_MT_button_context_menu,
|
|
|
|
|
)
|