1 Commits

Author SHA1 Message Date
forbes
ef16ecbaa2 fix: viewport background gradient — Overlay0/Mantle 3-color gradient (#188)
Change viewport background from 2-color Base→Crust gradient to
3-color Overlay0→Mantle→Overlay0 gradient for better visual depth.
2026-02-14 13:03:37 -06:00
3 changed files with 341 additions and 126 deletions

View File

@@ -27,13 +27,13 @@
<FCUInt Name="colorError" Value="4086016255"/> <FCUInt Name="colorError" Value="4086016255"/>
</FCParamGroup> </FCParamGroup>
<FCParamGroup Name="View"> <FCParamGroup Name="View">
<FCUInt Name="BackgroundColor" Value="505294591"/> <FCUInt Name="BackgroundColor" Value="404235775"/>
<FCUInt Name="BackgroundColor2" Value="286333951"/> <FCUInt Name="BackgroundColor2" Value="1819313919"/>
<FCUInt Name="BackgroundColor3" Value="404235775"/> <FCUInt Name="BackgroundColor3" Value="1819313919"/>
<FCUInt Name="BackgroundColor4" Value="825378047"/> <FCUInt Name="BackgroundColor4" Value="404235775"/>
<FCBool Name="Simple" Value="0"/> <FCBool Name="Simple" Value="0"/>
<FCBool Name="Gradient" Value="1"/> <FCBool Name="Gradient" Value="1"/>
<FCBool Name="UseBackgroundColorMid" Value="0"/> <FCBool Name="UseBackgroundColorMid" Value="1"/>
<FCUInt Name="HighlightColor" Value="3416717311"/> <FCUInt Name="HighlightColor" Value="3416717311"/>
<FCUInt Name="SelectionColor" Value="3032415999"/> <FCUInt Name="SelectionColor" Value="3032415999"/>
<FCUInt Name="PreselectColor" Value="2497893887"/> <FCUInt Name="PreselectColor" Value="2497893887"/>

View File

@@ -3,7 +3,7 @@
<name>ZTools</name> <name>ZTools</name>
<description>Velocity-focused CAD tools injected into PartDesign, Assembly, and Spreadsheet contexts, plus Catppuccin Mocha theme.</description> <description>Extended PartDesign workbench with velocity-focused tools, advanced datum creation, and Catppuccin Mocha theme.</description>
<version>0.1.0</version> <version>0.1.0</version>

View File

@@ -1,109 +1,356 @@
# ztools Command Provider for Kindred Create # ztools Workbench for FreeCAD 1.0+
# Injects ZTools commands into context toolbars via EditingContextResolver. # Extended PartDesign replacement with velocity-focused tools
# No longer a standalone workbench — commands appear in the appropriate
# editing context (PartDesign body/feature, Assembly, Spreadsheet).
import FreeCAD as App import FreeCAD as App
import FreeCADGui as Gui import FreeCADGui as Gui
def _ensure_workbenches_loaded(): class ZToolsWorkbench(Gui.Workbench):
"""Activate dependent workbenches so their commands are registered.""" """Extended PartDesign workbench with velocity-focused tools."""
wb_list = Gui.listWorkbenches()
for wb_name in (
"PartDesignWorkbench",
"SketcherWorkbench",
"AssemblyWorkbench",
"SpreadsheetWorkbench",
):
if wb_name in wb_list:
try:
Gui.activateWorkbench(wb_name)
except Exception as e:
App.Console.PrintWarning(f"ztools: could not init {wb_name}: {e}\n")
MenuText = "ztools"
ToolTip = "Extended PartDesign replacement for faster CAD workflows"
def _register(): # Catppuccin Mocha themed icon
"""Import ZTools commands and inject them into context toolbars.""" Icon = """
_ensure_workbenches_loaded() /* XPM */
static char * ztools_xpm[] = {
"16 16 5 1",
" c None",
". c #313244",
"+ c #cba6f7",
"@ c #94e2d5",
"# c #45475a",
" ",
" ############ ",
" #..........# ",
" #.++++++++.# ",
" #.+......+.# ",
" #.....+++..# ",
" #....++....# ",
" #...++.....# ",
" #..++......# ",
" #.++.......# ",
" #.++++++++@# ",
" #..........# ",
" ############ ",
" ",
" ",
" "};
"""
# Import all ZTools command modules (registers Gui commands) def Initialize(self):
from ztools.commands import ( # noqa: F401 """Called on workbench first activation."""
assembly_pattern_commands, # Load PartDesign and Sketcher workbenches to register their commands
datum_commands, # We need to actually activate them briefly to ensure commands are registered
pattern_commands, # Activate dependent workbenches so their commands are registered.
pocket_commands, # Use activateWorkbench() instead of calling Initialize() directly,
spreadsheet_commands, # since direct calls skip the C++ __Workbench__ injection step.
) # Wrap each individually so one failure doesn't block the rest.
wb_list = Gui.listWorkbenches()
current_wb = Gui.activeWorkbench()
for wb_name in (
"PartDesignWorkbench",
"SketcherWorkbench",
"AssemblyWorkbench",
"SpreadsheetWorkbench",
):
if wb_name in wb_list:
try:
Gui.activateWorkbench(wb_name)
except Exception as e:
App.Console.PrintWarning(f"Could not initialize {wb_name}: {e}\n")
# Restore ztools as the active workbench
try:
Gui.activateWorkbench("ZToolsWorkbench")
except Exception:
pass
# Apply Catppuccin Mocha Spreadsheet colors # Command imports moved to module scope (after Gui.addWorkbench) so they
try: # are available before Initialize() runs. See end of file.
from ztools.resources.theme import apply_spreadsheet_colors
apply_spreadsheet_colors() # =====================================================================
except Exception as e: # PartDesign Structure Tools
App.Console.PrintWarning(f"ztools: could not apply spreadsheet colors: {e}\n") # =====================================================================
self.structure_tools = [
"PartDesign_Body",
"PartDesign_NewSketch",
]
# Register WorkbenchManipulator for injecting into native workbench toolbars # =====================================================================
Gui.addWorkbenchManipulator(_ZToolsManipulator()) # PartDesign Reference Geometry (Datums)
# =====================================================================
self.partdesign_datum_tools = [
"PartDesign_Plane",
"PartDesign_Line",
"PartDesign_Point",
"PartDesign_CoordinateSystem",
"PartDesign_ShapeBinder",
"PartDesign_SubShapeBinder",
"PartDesign_Clone",
]
# Inject ZTools commands into editing context toolbars. # =====================================================================
# These calls append commands to the named toolbar within the given context, # PartDesign Additive Features
# so when the EditingContextResolver activates a context the injected # =====================================================================
# commands appear alongside the native ones. self.additive_tools = [
try: "PartDesign_Pad",
Gui.injectEditingCommands( "PartDesign_Revolution",
"partdesign.body", "PartDesign_AdditiveLoft",
"Part Design Helper Features", "PartDesign_AdditivePipe",
["ZTools_DatumCreator", "ZTools_DatumManager"], "PartDesign_AdditiveHelix",
]
# =====================================================================
# PartDesign Additive Primitives (compound command with dropdown)
# =====================================================================
self.additive_primitives = [
"PartDesign_CompPrimitiveAdditive",
]
# =====================================================================
# PartDesign Subtractive Features
# =====================================================================
self.subtractive_tools = [
"PartDesign_Pocket",
"PartDesign_Hole",
"PartDesign_Groove",
"PartDesign_SubtractiveLoft",
"PartDesign_SubtractivePipe",
"PartDesign_SubtractiveHelix",
]
# =====================================================================
# PartDesign Subtractive Primitives (compound command with dropdown)
# =====================================================================
self.subtractive_primitives = [
"PartDesign_CompPrimitiveSubtractive",
]
# =====================================================================
# PartDesign Transformation Features (Patterns)
# =====================================================================
self.transformation_tools = [
"PartDesign_Mirrored",
"PartDesign_LinearPattern",
"PartDesign_PolarPattern",
"PartDesign_MultiTransform",
]
# =====================================================================
# PartDesign Dress-Up Features
# =====================================================================
self.dressup_tools = [
"PartDesign_Fillet",
"PartDesign_Chamfer",
"PartDesign_Draft",
"PartDesign_Thickness",
]
# =====================================================================
# PartDesign Boolean Operations
# =====================================================================
self.boolean_tools = [
"PartDesign_Boolean",
]
# =====================================================================
# Sketcher Tools (commonly used with PartDesign)
# =====================================================================
self.sketcher_tools = [
"Sketcher_NewSketch",
"Sketcher_EditSketch",
"Sketcher_MapSketch",
"Sketcher_ValidateSketch",
]
# =====================================================================
# ZTools Custom Tools
# =====================================================================
self.ztools_datum_tools = [
"ZTools_DatumCreator",
"ZTools_DatumManager",
]
self.ztools_pattern_tools = [
"ZTools_RotatedLinearPattern",
]
self.ztools_pocket_tools = [
"ZTools_EnhancedPocket",
]
# =====================================================================
# Assembly Workbench Tools (FreeCAD 1.0+)
# =====================================================================
self.assembly_structure_tools = [
"Assembly_CreateAssembly",
"Assembly_InsertLink",
"Assembly_InsertNewPart",
]
self.assembly_joint_tools = [
"Assembly_CreateJointFixed",
"Assembly_CreateJointRevolute",
"Assembly_CreateJointCylindrical",
"Assembly_CreateJointSlider",
"Assembly_CreateJointBall",
"Assembly_CreateJointDistance",
"Assembly_CreateJointParallel",
"Assembly_CreateJointPerpendicular",
"Assembly_CreateJointAngle",
"Assembly_CreateJointRackPinion",
"Assembly_CreateJointScrew",
"Assembly_CreateJointGears",
"Assembly_CreateJointBelt",
]
self.assembly_management_tools = [
"Assembly_ToggleGrounded",
"Assembly_SolveAssembly",
"Assembly_CreateView",
"Assembly_CreateBom",
"Assembly_ExportASMT",
]
# =====================================================================
# ZTools Assembly Pattern Tools
# =====================================================================
self.ztools_assembly_tools = [
"ZTools_AssemblyLinearPattern",
"ZTools_AssemblyPolarPattern",
]
# =====================================================================
# Spreadsheet Workbench Tools
# =====================================================================
self.spreadsheet_tools = [
"Spreadsheet_CreateSheet",
"Spreadsheet_Import",
"Spreadsheet_Export",
"Spreadsheet_SetAlias",
"Spreadsheet_MergeCells",
"Spreadsheet_SplitCell",
]
# =====================================================================
# ZTools Spreadsheet Formatting Tools
# =====================================================================
self.ztools_spreadsheet_tools = [
"ZTools_SpreadsheetStyleBold",
"ZTools_SpreadsheetStyleItalic",
"ZTools_SpreadsheetStyleUnderline",
"ZTools_SpreadsheetAlignLeft",
"ZTools_SpreadsheetAlignCenter",
"ZTools_SpreadsheetAlignRight",
"ZTools_SpreadsheetBgColor",
"ZTools_SpreadsheetTextColor",
"ZTools_SpreadsheetQuickAlias",
]
# =====================================================================
# Append Toolbars
# =====================================================================
self.appendToolbar("Structure", self.structure_tools)
self.appendToolbar("Sketcher", self.sketcher_tools)
self.appendToolbar("Datums", self.partdesign_datum_tools)
self.appendToolbar("Additive", self.additive_tools + self.additive_primitives)
self.appendToolbar(
"Subtractive", self.subtractive_tools + self.subtractive_primitives
) )
Gui.injectEditingCommands( self.appendToolbar("Transformations", self.transformation_tools)
"partdesign.feature", self.appendToolbar("Dress-Up", self.dressup_tools)
"Part Design Modeling Features", self.appendToolbar("Boolean", self.boolean_tools)
["ZTools_EnhancedPocket"], self.appendToolbar("Assembly", self.assembly_structure_tools)
) self.appendToolbar("Assembly Joints", self.assembly_joint_tools)
Gui.injectEditingCommands( self.appendToolbar("Assembly Management", self.assembly_management_tools)
"partdesign.feature", self.appendToolbar("ztools Datums", self.ztools_datum_tools)
"Part Design Transformation Features", self.appendToolbar("ztools Patterns", self.ztools_pattern_tools)
["ZTools_RotatedLinearPattern"], self.appendToolbar("ztools Features", self.ztools_pocket_tools)
) self.appendToolbar("ztools Assembly", self.ztools_assembly_tools)
Gui.injectEditingCommands( self.appendToolbar("Spreadsheet", self.spreadsheet_tools)
"assembly.edit", self.appendToolbar("ztools Spreadsheet", self.ztools_spreadsheet_tools)
"Assembly Management",
["ZTools_AssemblyLinearPattern", "ZTools_AssemblyPolarPattern"],
)
Gui.injectEditingCommands(
"spreadsheet",
"Spreadsheet",
[
"ZTools_SpreadsheetStyleBold",
"ZTools_SpreadsheetStyleItalic",
"ZTools_SpreadsheetStyleUnderline",
"ZTools_SpreadsheetAlignLeft",
"ZTools_SpreadsheetAlignCenter",
"ZTools_SpreadsheetAlignRight",
"ZTools_SpreadsheetBgColor",
"ZTools_SpreadsheetTextColor",
"ZTools_SpreadsheetQuickAlias",
],
)
except Exception as e:
App.Console.PrintWarning(f"ztools: could not inject context commands: {e}\n")
App.Console.PrintMessage("ztools commands registered\n") # =====================================================================
# Append Menus
# =====================================================================
self.appendMenu("Structure", self.structure_tools)
self.appendMenu("Sketch", self.sketcher_tools)
self.appendMenu(["PartDesign", "Datums"], self.partdesign_datum_tools)
self.appendMenu(
["PartDesign", "Additive"], self.additive_tools + self.additive_primitives
)
self.appendMenu(
["PartDesign", "Subtractive"],
self.subtractive_tools + self.subtractive_primitives,
)
self.appendMenu(["PartDesign", "Transformations"], self.transformation_tools)
self.appendMenu(["PartDesign", "Dress-Up"], self.dressup_tools)
self.appendMenu(["PartDesign", "Boolean"], self.boolean_tools)
self.appendMenu(["Assembly", "Structure"], self.assembly_structure_tools)
self.appendMenu(["Assembly", "Joints"], self.assembly_joint_tools)
self.appendMenu(["Assembly", "Management"], self.assembly_management_tools)
self.appendMenu(["Spreadsheet", "Edit"], self.spreadsheet_tools)
self.appendMenu(["Spreadsheet", "Format"], self.ztools_spreadsheet_tools)
self.appendMenu(
"ztools",
self.ztools_datum_tools
+ self.ztools_pattern_tools
+ self.ztools_pocket_tools
+ self.ztools_assembly_tools
+ self.ztools_spreadsheet_tools,
)
App.Console.PrintMessage("ztools workbench initialized\n")
def Activated(self):
"""Called when workbench is activated."""
# Apply Catppuccin Mocha colors to Spreadsheet preferences
try:
from ztools.resources.theme import apply_spreadsheet_colors
apply_spreadsheet_colors()
except Exception as e:
App.Console.PrintWarning(f"Could not apply spreadsheet colors: {e}\n")
App.Console.PrintMessage("ztools workbench activated\n")
def Deactivated(self):
"""Called when workbench is deactivated."""
pass
def GetClassName(self):
return "Gui::PythonWorkbench"
Gui.addWorkbench(ZToolsWorkbench())
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# WorkbenchManipulator: inject ZTools commands into native workbench toolbars # Eager command registration
# ---------------------------------------------------------------------------
# Import command modules at module scope so Gui.addCommand() calls run before
# any workbench activates. This ensures the PartDesign manipulator can
# reference them regardless of workbench activation order (#52).
from ztools.commands import (
assembly_pattern_commands,
datum_commands,
pattern_commands,
pocket_commands,
spreadsheet_commands,
)
# ---------------------------------------------------------------------------
# WorkbenchManipulator: inject ZTools commands into PartDesign workbench
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
class _ZToolsManipulator: class _ZToolsPartDesignManipulator:
"""Adds ZTools commands to PartDesign, Assembly, and Spreadsheet toolbars.""" """Adds ZTools commands to PartDesign toolbars and menus."""
def modifyToolBars(self): def modifyToolBars(self):
return [ return [
# PartDesign
{"append": "ZTools_DatumCreator", "toolBar": "Part Design Helper Features"}, {"append": "ZTools_DatumCreator", "toolBar": "Part Design Helper Features"},
{"append": "ZTools_DatumManager", "toolBar": "Part Design Helper Features"}, {"append": "ZTools_DatumManager", "toolBar": "Part Design Helper Features"},
{ {
@@ -114,47 +361,15 @@ class _ZToolsManipulator:
"append": "ZTools_RotatedLinearPattern", "append": "ZTools_RotatedLinearPattern",
"toolBar": "Part Design Transformation Features", "toolBar": "Part Design Transformation Features",
}, },
# Assembly
{"append": "ZTools_AssemblyLinearPattern", "toolBar": "Assembly"},
{"append": "ZTools_AssemblyPolarPattern", "toolBar": "Assembly"},
# Spreadsheet
{"append": "ZTools_SpreadsheetStyleBold", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetStyleItalic", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetStyleUnderline", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetAlignLeft", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetAlignCenter", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetAlignRight", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetBgColor", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetTextColor", "toolBar": "Spreadsheet"},
{"append": "ZTools_SpreadsheetQuickAlias", "toolBar": "Spreadsheet"},
] ]
def modifyMenuBar(self): def modifyMenuBar(self):
return [ return [
{ {"append": "ZTools_DatumCreator", "menuItem": "PartDesign_Body"},
"insert": "ZTools_DatumCreator", {"append": "ZTools_DatumManager", "menuItem": "PartDesign_Body"},
"menuItem": "PartDesign_Boolean", {"append": "ZTools_EnhancedPocket", "menuItem": "PartDesign_Body"},
"after": "", {"append": "ZTools_RotatedLinearPattern", "menuItem": "PartDesign_Body"},
},
{
"insert": "ZTools_DatumManager",
"menuItem": "ZTools_DatumCreator",
"after": "",
},
{
"insert": "ZTools_EnhancedPocket",
"menuItem": "ZTools_DatumManager",
"after": "",
},
{
"insert": "ZTools_RotatedLinearPattern",
"menuItem": "ZTools_EnhancedPocket",
"after": "",
},
] ]
# Deferred registration — wait for dependent workbenches to finish loading Gui.addWorkbenchManipulator(_ZToolsPartDesignManipulator())
from PySide.QtCore import QTimer # noqa: E402
QTimer.singleShot(2000, _register)