mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 07:46:54 +00:00
Quick Favorites Manager - show operators suggestions
This commit is contained in:
@@ -25,7 +25,7 @@ classes = (
|
|||||||
operator.RemoveQuickFavoritesItem,
|
operator.RemoveQuickFavoritesItem,
|
||||||
operator.MoveQuickFavoritesItem,
|
operator.MoveQuickFavoritesItem,
|
||||||
operator.AddQuickFavoritesItem,
|
operator.AddQuickFavoritesItem,
|
||||||
operator.EnableQuickFavoriteSearch,
|
operator.ConfirmQuickFavoriteOperator,
|
||||||
operator.DrawSystemArrows,
|
operator.DrawSystemArrows,
|
||||||
operator.GetConnectedSystemElements,
|
operator.GetConnectedSystemElements,
|
||||||
operator.IfcSverchokUseBonsaiFile,
|
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
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# 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 bpy
|
||||||
import ifcopenshell.util.geolocation
|
import ifcopenshell.util.geolocation
|
||||||
@@ -355,9 +355,9 @@ class DrawSystemArrows(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
return matrix
|
return matrix
|
||||||
|
|
||||||
|
|
||||||
class EnableQuickFavoriteSearch(bpy.types.Operator):
|
class ConfirmQuickFavoriteOperator(bpy.types.Operator):
|
||||||
bl_idname = "bim.enable_quick_favorite_search"
|
bl_idname = "bim.confirm_quick_favorite_operator"
|
||||||
bl_label = "Enable Search"
|
bl_label = "Confirm Operator"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
index: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
index: bpy.props.IntProperty() # pyright: ignore[reportRedeclaration]
|
||||||
|
|
||||||
@@ -367,18 +367,13 @@ class EnableQuickFavoriteSearch(bpy.types.Operator):
|
|||||||
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
def execute(self, context) -> set["rna_enums.OperatorReturnItems"]:
|
||||||
props = tool.Misc.get_misc_props()
|
props = tool.Misc.get_misc_props()
|
||||||
fav = props.quick_favorites[self.index]
|
fav = props.quick_favorites[self.index]
|
||||||
name = fav.search.strip()
|
rna = fav.get_searched_operator()
|
||||||
|
|
||||||
# TODO: don't use try / except.
|
if rna is None:
|
||||||
try:
|
self.report({"INFO"}, "No operator entered for search.")
|
||||||
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.")
|
|
||||||
return {"CANCELLED"}
|
return {"CANCELLED"}
|
||||||
|
|
||||||
fav.operator_id = name
|
fav.operator_id = tool.Blender.operator_idname_to_py(rna.identifier)
|
||||||
fav.label = rna.name
|
fav.label = rna.name
|
||||||
fav.properties.clear()
|
fav.properties.clear()
|
||||||
has_skipped = False
|
has_skipped = False
|
||||||
@@ -429,7 +424,7 @@ class ImportQuickFavorites(bpy.types.Operator):
|
|||||||
fav = props.quick_favorites.add()
|
fav = props.quick_favorites.add()
|
||||||
fav.label = qf.ui_name
|
fav.label = qf.ui_name
|
||||||
fav.search = qf.op_idname_py
|
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
|
fav.label = qf.ui_name or fav.label
|
||||||
|
|
||||||
for prop in fav.properties:
|
for prop in fav.properties:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
# 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
|
import bpy
|
||||||
from bpy.props import (
|
from bpy.props import (
|
||||||
@@ -30,6 +30,8 @@ from bpy.props import (
|
|||||||
)
|
)
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
|
|
||||||
|
from bonsai.bim.module.misc.data import QuickFavoritesData
|
||||||
|
|
||||||
QuickFavoriteValueType = Literal["float_value", "bool_value", "int_value", "string_value"]
|
QuickFavoriteValueType = Literal["float_value", "bool_value", "int_value", "string_value"]
|
||||||
|
|
||||||
|
|
||||||
@@ -61,20 +63,46 @@ class QuickFavoriteProperty(PropertyGroup):
|
|||||||
is_active: bool
|
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):
|
class QuickFavoritesItem(PropertyGroup):
|
||||||
is_expanded: BoolProperty(name="Is Expanded", default=True) # pyright: ignore[reportRedeclaration]
|
is_expanded: BoolProperty(name="Is Expanded", default=False) # pyright: ignore[reportRedeclaration]
|
||||||
search: StringProperty(name="Search", default="") # 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]
|
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]
|
label: StringProperty( # pyright: ignore[reportRedeclaration]
|
||||||
name="Label",
|
name="Label",
|
||||||
description="Label that will be used in Quick Favorites for this operator",
|
description="Label that will be used in Quick Favorites for this operator",
|
||||||
default="",
|
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:
|
if TYPE_CHECKING:
|
||||||
is_expanded: bool
|
is_expanded: bool
|
||||||
search: str
|
search: str
|
||||||
|
"""Internal property set when confirming results of the search field"""
|
||||||
properties: bpy.types.bpy_prop_collection_idprop[QuickFavoriteProperty]
|
properties: bpy.types.bpy_prop_collection_idprop[QuickFavoriteProperty]
|
||||||
operator_id: str
|
operator_id: str
|
||||||
label: str
|
label: str
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ class BIM_PT_quick_favorites_manager(bpy.types.Panel):
|
|||||||
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text="Quick Favorites:")
|
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.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 = row.operator("bim.show_description", text="", icon="INFO")
|
||||||
op.attr_name = "Quick Favorites Manager"
|
op.attr_name = "Quick Favorites Manager"
|
||||||
op.description = (
|
op.description = (
|
||||||
@@ -115,13 +115,16 @@ class BIM_PT_quick_favorites_manager(bpy.types.Panel):
|
|||||||
continue
|
continue
|
||||||
row = box.row(align=True)
|
row = box.row(align=True)
|
||||||
row.prop(fav, "search", text="")
|
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:
|
if not fav.operator_id:
|
||||||
continue
|
continue
|
||||||
layout.separator()
|
layout.separator()
|
||||||
box.label(text="Properties:")
|
if fav.properties:
|
||||||
prop_box = box.box()
|
box.label(text="Properties:")
|
||||||
for item in fav.properties:
|
prop_box = box.box()
|
||||||
row = prop_box.row(align=True)
|
for item in fav.properties:
|
||||||
row.prop(item, item.value_prop, text=item.display_name)
|
row = prop_box.row(align=True)
|
||||||
row.prop(item, "is_active", text="", icon="RADIOBUT_ON" if item.is_active else "RADIOBUT_OFF")
|
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