Added sanity check baseline made by claude.
Also changed the location to a panel in VIEW_3D instead of menu.
This commit is contained in:
1 parent
71b1a61b5c
commit
4617c47ad0
33 files changed
+2771
-52
No files matched your search
+217
@@ -0,0 +1,217 @@
|
||||
import textwrap
|
||||
|
||||
import bpy
|
||||
|
||||
from .. import config, tools_ops
|
||||
from ..core import CheckContext, Severity, checks_for_context, contexts, runner
|
||||
from ..core.runner import Status
|
||||
from .operators import EXPANDED
|
||||
|
||||
STATUS_ICONS = {
|
||||
Status.NOT_RUN: "DOT",
|
||||
Status.PASSED: "CHECKMARK",
|
||||
Status.INFO: "INFO",
|
||||
Status.WARNING: "ERROR",
|
||||
Status.ERROR: "CANCEL",
|
||||
Status.SKIPPED: "REMOVE",
|
||||
Status.CRASHED: "GHOST_ENABLED",
|
||||
}
|
||||
SEVERITY_ICONS = {
|
||||
Severity.INFO: "INFO",
|
||||
Severity.WARNING: "ERROR",
|
||||
Severity.ERROR: "CANCEL",
|
||||
}
|
||||
|
||||
|
||||
def _wrapped_label(layout, context, text, icon="NONE", margin=0):
|
||||
"""Label wrapped to the region width. ``margin`` is the room (in characters) taken by buttons."""
|
||||
char_width = 6.5 * context.preferences.system.ui_scale
|
||||
width = max(16, int(context.region.width / char_width) - 6 - margin)
|
||||
col = layout.column(align=True)
|
||||
for index, line in enumerate(textwrap.wrap(text, width) or [""]):
|
||||
col.label(text=line, icon=icon if index == 0 else "BLANK1")
|
||||
|
||||
|
||||
def draw_panel(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
settings = scene.wtd_sanity
|
||||
report = runner.LAST_REPORT
|
||||
if report is not None and report.context_id != settings.context:
|
||||
report = None
|
||||
|
||||
layout.prop(settings, "context", text="")
|
||||
if settings.context in contexts.ASSET:
|
||||
row = layout.row(align=True)
|
||||
row.prop(settings, "asset_name", text="Asset")
|
||||
if not settings.asset_name:
|
||||
guessed = CheckContext(scene, settings.context).asset_name
|
||||
row.label(text=guessed or "(from file name)")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.scale_y = 1.4
|
||||
row.operator("wtd_sanity.run_checks", text="Run Checks", icon="PLAY")
|
||||
row.operator("wtd_sanity.fix_all", text="Fix All", icon="TOOL_SETTINGS")
|
||||
row.operator("wtd_sanity.write_report", text="", icon="TEXT")
|
||||
|
||||
if settings.context == contexts.CHAR_MOD:
|
||||
layout.operator("wtd_sanity.export_char_reference", icon="EXPORT")
|
||||
|
||||
if report is not None:
|
||||
counts = report.counts()
|
||||
row = layout.row()
|
||||
for status in (
|
||||
Status.PASSED,
|
||||
Status.WARNING,
|
||||
Status.ERROR,
|
||||
Status.SKIPPED,
|
||||
Status.CRASHED,
|
||||
):
|
||||
if counts[status]:
|
||||
row.label(text=str(counts[status]), icon=STATUS_ICONS[status])
|
||||
|
||||
disabled = runner.disabled_check_ids(scene)
|
||||
box = None
|
||||
category = None
|
||||
for check in checks_for_context(settings.context):
|
||||
if check.category != category:
|
||||
category = check.category
|
||||
box = layout.box()
|
||||
box.label(text=category)
|
||||
_draw_check(box, context, check, report, check.id in disabled)
|
||||
|
||||
|
||||
def _draw_check(layout, context, check, report, disabled):
|
||||
result = report.results.get(check.id) if report else None
|
||||
status = result.status if result else Status.NOT_RUN
|
||||
expanded = check.id in EXPANDED
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator(
|
||||
"wtd_sanity.toggle_check",
|
||||
text="",
|
||||
emboss=False,
|
||||
icon="CHECKBOX_DEHLT" if disabled else "CHECKBOX_HLT",
|
||||
).check_id = check.id
|
||||
row.operator(
|
||||
"wtd_sanity.toggle_expand",
|
||||
text="",
|
||||
emboss=False,
|
||||
icon="DOWNARROW_HLT" if expanded else "RIGHTARROW",
|
||||
).check_id = check.id
|
||||
|
||||
label_row = row.row(align=True)
|
||||
label_row.enabled = not disabled
|
||||
label_row.alert = status in {Status.ERROR, Status.CRASHED}
|
||||
count = f" ({len(result.issues)})" if result and result.issues else ""
|
||||
label_row.label(text=check.label + count, icon=STATUS_ICONS[status])
|
||||
|
||||
buttons = row.row(align=True)
|
||||
if result and any(issue.id_name or issue.elements for issue in result.issues):
|
||||
buttons.operator(
|
||||
"wtd_sanity.select_issues", text="", icon="RESTRICT_SELECT_OFF"
|
||||
).check_id = check.id
|
||||
if result and result.failed and check.can_fix():
|
||||
buttons.operator(
|
||||
"wtd_sanity.fix_check", text="", icon="TOOL_SETTINGS"
|
||||
).check_id = check.id
|
||||
buttons.operator(
|
||||
"wtd_sanity.run_checks", text="", icon="FILE_REFRESH"
|
||||
).check_id = check.id
|
||||
|
||||
if not expanded:
|
||||
return
|
||||
col = layout.column()
|
||||
col.separator(factor=0.3)
|
||||
_wrapped_label(col, context, check.description, icon="QUESTION")
|
||||
if result is None:
|
||||
return
|
||||
if result.message:
|
||||
_wrapped_label(
|
||||
col,
|
||||
context,
|
||||
result.message.strip().splitlines()[-1],
|
||||
icon=STATUS_ICONS[status],
|
||||
)
|
||||
for index, issue in enumerate(result.issues[: config.MAX_ISSUES_DRAWN]):
|
||||
severity = issue.severity or check.severity
|
||||
issue_row = col.row(align=True)
|
||||
selectable = bool(issue.id_name or issue.elements)
|
||||
_wrapped_label(
|
||||
issue_row,
|
||||
context,
|
||||
issue.message,
|
||||
icon=SEVERITY_ICONS[severity],
|
||||
margin=7 if selectable else 0,
|
||||
)
|
||||
if selectable:
|
||||
op = issue_row.operator(
|
||||
"wtd_sanity.select_issues",
|
||||
text="",
|
||||
icon="RESTRICT_SELECT_OFF",
|
||||
emboss=False,
|
||||
)
|
||||
op.check_id = check.id
|
||||
op.issue_index = index
|
||||
if check.editable_names:
|
||||
id_block = issue.get_id()
|
||||
if id_block is not None and id_block.library is None:
|
||||
col.prop(id_block, "name", text="", icon="BLANK1")
|
||||
hidden = len(result.issues) - config.MAX_ISSUES_DRAWN
|
||||
if hidden > 0:
|
||||
col.label(text=f"... {hidden} more (see Write Report)", icon="BLANK1")
|
||||
col.separator(factor=0.5)
|
||||
|
||||
|
||||
class _SanityPanel:
|
||||
bl_region_type = "UI"
|
||||
bl_category = "WTD"
|
||||
bl_label = "Sanity Check"
|
||||
bl_options = {"DEFAULT_CLOSED"} # panel starts collapsed
|
||||
|
||||
def draw(self, context):
|
||||
draw_panel(self, context)
|
||||
|
||||
|
||||
class _ToolsPanel:
|
||||
bl_region_type = "UI"
|
||||
bl_category = "WTD"
|
||||
bl_label = "Tools"
|
||||
|
||||
def draw(self, context) -> None:
|
||||
layout = self.layout
|
||||
layout.operator(
|
||||
tools_ops.WTDGetOidForPath.bl_idname,
|
||||
text=tools_ops.WTDGetOidForPath.bl_label,
|
||||
)
|
||||
|
||||
# Adds a separator line
|
||||
layout.separator()
|
||||
|
||||
|
||||
class WTD_PT_sanity_view3d(_SanityPanel, bpy.types.Panel):
|
||||
bl_idname = "WTD_PT_sanity_view3d"
|
||||
bl_space_type = "VIEW_3D"
|
||||
|
||||
|
||||
class WTD_PT_tools_view3d(_ToolsPanel, bpy.types.Panel):
|
||||
bl_idname = "WTD_PT_tools_view3d"
|
||||
bl_space_type = "VIEW_3D"
|
||||
|
||||
|
||||
class WTD_PT_sanity_sequencer(_SanityPanel, bpy.types.Panel):
|
||||
bl_idname = "WTD_PT_sanity_sequencer"
|
||||
bl_space_type = "SEQUENCE_EDITOR"
|
||||
|
||||
|
||||
classes = (WTD_PT_sanity_view3d, WTD_PT_tools_view3d, WTD_PT_sanity_sequencer)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
Reference in new issue
Block a user