mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
Quick Favorites Manager - show operators suggestions
This commit is contained in:
@@ -25,7 +25,7 @@ classes = (
|
||||
operator.RemoveQuickFavoritesItem,
|
||||
operator.MoveQuickFavoritesItem,
|
||||
operator.AddQuickFavoritesItem,
|
||||
operator.EnableQuickFavoriteSearch,
|
||||
operator.ConfirmQuickFavoriteOperator,
|
||||
operator.DrawSystemArrows,
|
||||
operator.GetConnectedSystemElements,
|
||||
operator.IfcSverchokUseBonsaiFile,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# Bonsai - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of Bonsai.
|
||||
#
|
||||
# Bonsai 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.
|
||||
#
|
||||
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Any
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def refresh() -> None:
|
||||
QuickFavoritesData.is_loaded = False
|
||||
|
||||
|
||||
class QuickFavoritesData:
|
||||
data: dict[str, Any] = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls) -> None:
|
||||
cls.data = {
|
||||
"operators": cls.operators(),
|
||||
}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def operators(cls) -> list[str]:
|
||||
items: list[str] = []
|
||||
for module_name in dir(bpy.ops):
|
||||
module = getattr(bpy.ops, module_name)
|
||||
for op_name in dir(module):
|
||||
op = getattr(module, op_name)
|
||||
bl_label = op.get_rna_type().name
|
||||
items.append(f"{module_name}.{op_name} - {bl_label}")
|
||||
return items
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Literal, assert_never, cast, get_args
|
||||
from typing import TYPE_CHECKING, Literal, assert_never, get_args
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.geolocation
|
||||
@@ -355,9 +355,9 @@ class DrawSystemArrows(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return matrix
|
||||
|
||||
|
||||
class EnableQuickFavoriteSearch(bpy.types.Operator):
|
||||
bl_idname = "bim.enable_quick_favorite_search"
|
||||
bl_label = "Enable Search"
|
||||
class ConfirmQuickFavoriteOperator(bpy.types.Operator):
|
||||
bl_idname = "bim.confirm_quick_favorite_operator"
|
||||
bl_label = "Confirm Operator"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
index: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
||||
|
||||
@@ -367,18 +367,13 @@ class EnableQuickFavoriteSearch(bpy.types.Operator):
|
||||
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||
props = tool.Misc.get_misc_props()
|
||||
fav = props.quick_favorites[self.index]
|
||||
name = fav.search.strip()
|
||||
rna = fav.get_searched_operator()
|
||||
|
||||
# TODO: don't use try / except.
|
||||
try:
|
||||
module, func = name.split(".", 1)
|
||||
op = getattr(getattr(bpy.ops, module), func)
|
||||
rna = cast(bpy.types.Struct, op.get_rna_type())
|
||||
except (ValueError, AttributeError):
|
||||
self.report({"ERROR"}, f"Operator '{name}' not found.")
|
||||
if rna is None:
|
||||
self.report({"INFO"}, "No operator entered for search.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
fav.operator_id = name
|
||||
fav.operator_id = tool.Blender.operator_idname_to_py(rna.identifier)
|
||||
fav.label = rna.name
|
||||
fav.properties.clear()
|
||||
has_skipped = False
|
||||
@@ -429,7 +424,7 @@ class ImportQuickFavorites(bpy.types.Operator):
|
||||
fav = props.quick_favorites.add()
|
||||
fav.label = qf.ui_name
|
||||
fav.search = qf.op_idname_py
|
||||
bpy.ops.bim.enable_quick_favorite_search(index=i)
|
||||
bpy.ops.bim.confirm_quick_favorite_operator(index=i)
|
||||
fav.label = qf.ui_name or fav.label
|
||||
|
||||
for prop in fav.properties:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import TYPE_CHECKING, Literal, get_args
|
||||
from typing import TYPE_CHECKING, Literal, cast, get_args
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
@@ -30,6 +30,8 @@ from bpy.props import (
|
||||
)
|
||||
from bpy.types import PropertyGroup
|
||||
|
||||
from bonsai.bim.module.misc.data import QuickFavoritesData
|
||||
|
||||
QuickFavoriteValueType = Literal["float_value", "bool_value", "int_value", "string_value"]
|
||||
|
||||
|
||||
@@ -61,20 +63,46 @@ class QuickFavoriteProperty(PropertyGroup):
|
||||
is_active: bool
|
||||
|
||||
|
||||
def get_operator_suggestions(self: "QuickFavoritesItem", context: bpy.types.Context, edit_text: str) -> list[str]:
|
||||
if not QuickFavoritesData.is_loaded:
|
||||
QuickFavoritesData.load()
|
||||
return QuickFavoritesData.data["operators"]
|
||||
|
||||
|
||||
class QuickFavoritesItem(PropertyGroup):
|
||||
is_expanded: BoolProperty(name="Is Expanded", default=True) # pyright: ignore[reportRedeclaration]
|
||||
search: StringProperty(name="Search", default="") # pyright: ignore[reportRedeclaration]
|
||||
is_expanded: BoolProperty(name="Is Expanded", default=False) # pyright: ignore[reportRedeclaration]
|
||||
search: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Search",
|
||||
default="",
|
||||
search=get_operator_suggestions,
|
||||
# Resetting `search_options`, allowing users only to use suggestions.
|
||||
search_options=set(),
|
||||
)
|
||||
properties: CollectionProperty(type=QuickFavoriteProperty) # pyright: ignore[reportRedeclaration]
|
||||
operator_id: StringProperty(name="Operator ID", default="") # pyright: ignore[reportRedeclaration]
|
||||
operator_id: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Operator ID",
|
||||
default="",
|
||||
)
|
||||
label: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||
name="Label",
|
||||
description="Label that will be used in Quick Favorites for this operator",
|
||||
default="",
|
||||
)
|
||||
|
||||
def get_searched_operator(self) -> bpy.types.Struct | None:
|
||||
if not self.search:
|
||||
return None
|
||||
search_label = self.search
|
||||
name = search_label.split(" - ", 1)[0]
|
||||
module, func = name.split(".", 1)
|
||||
op = getattr(getattr(bpy.ops, module), func)
|
||||
rna = cast(bpy.types.Struct, op.get_rna_type())
|
||||
return rna
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_expanded: bool
|
||||
search: str
|
||||
"""Internal property set when confirming results of the search field"""
|
||||
properties: bpy.types.bpy_prop_collection_idprop[QuickFavoriteProperty]
|
||||
operator_id: str
|
||||
label: str
|
||||
|
||||
@@ -77,8 +77,8 @@ class BIM_PT_quick_favorites_manager(bpy.types.Panel):
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.label(text="Quick Favorites:")
|
||||
row.operator("bim.import_quick_favorites", text="", icon="BLENDER")
|
||||
row.operator("bim.add_quick_favorites_item", text="", icon="ADD")
|
||||
row.operator("bim.import_quick_favorites", text="", icon="BLENDER")
|
||||
op = row.operator("bim.show_description", text="", icon="INFO")
|
||||
op.attr_name = "Quick Favorites Manager"
|
||||
op.description = (
|
||||
@@ -115,13 +115,16 @@ class BIM_PT_quick_favorites_manager(bpy.types.Panel):
|
||||
continue
|
||||
row = box.row(align=True)
|
||||
row.prop(fav, "search", text="")
|
||||
row.operator("bim.enable_quick_favorite_search", text="", icon="VIEWZOOM").index = i
|
||||
row.operator("bim.confirm_quick_favorite_operator", text="", icon="VIEWZOOM").index = i
|
||||
if not fav.operator_id:
|
||||
continue
|
||||
layout.separator()
|
||||
box.label(text="Properties:")
|
||||
prop_box = box.box()
|
||||
for item in fav.properties:
|
||||
row = prop_box.row(align=True)
|
||||
row.prop(item, item.value_prop, text=item.display_name)
|
||||
row.prop(item, "is_active", text="", icon="RADIOBUT_ON" if item.is_active else "RADIOBUT_OFF")
|
||||
if fav.properties:
|
||||
box.label(text="Properties:")
|
||||
prop_box = box.box()
|
||||
for item in fav.properties:
|
||||
row = prop_box.row(align=True)
|
||||
row.prop(item, item.value_prop, text=item.display_name)
|
||||
row.prop(item, "is_active", text="", icon="RADIOBUT_ON" if item.is_active else "RADIOBUT_OFF")
|
||||
else:
|
||||
box.label(text="No Properties.")
|
||||
|
||||
Reference in New Issue
Block a user