Commit Graph

15 Commits

Author SHA1 Message Date
forbes
3298d1c6dc feat: appearance mode toggle UI and observer enhancements
- Grouped toolbar dropdown (ZTools_AppearanceMode) replaces two separate buttons
- Set Category command (ZTools_SetCategory) with popup menu for batch tagging
- Category changes wrapped in undo transactions
- Status bar indicator showing current mode, clickable to toggle
- Debounced recompute handling (Shape property changes batched at 100ms)
- Observer re-applies colors after recompute to prevent reset

Closes #21
2026-02-07 13:32:23 -06:00
forbes
7b1e76c791 feat: appearance mode system with engineering color presets
Add configurable appearance mode system with two modes:
- Realistic: material passthrough (restores original ShapeColor)
- Engineering: colors parts by KindredCategory using Catppuccin Mocha palette

KindredCategory enum property (custom_body, fastener, structural, electrical,
seal_gasket, bearing_bushing, spring_compliant, moving_part) is added lazily
to Part::Feature objects when Engineering mode is activated.

Includes:
- AppearanceMode base class with apply/reset/apply_to_object interface
- AppearanceManager singleton with document observer for auto-coloring
- Palette loaded from JSON config (theme-overridable)
- View > Appearance Mode menu and toolbar integration
- Preference persistence at Kindred/AppearanceMode

Closes #20
2026-02-07 11:01:28 -06:00
forbes
d2f94c3d78 fix: defer PartDesign manipulator registration until commands are imported
The _ZToolsPartDesignManipulator was registered at module load time via
Gui.addWorkbenchManipulator(), but the commands it references
(ZTools_DatumCreator, ZTools_DatumManager, ZTools_EnhancedPocket,
ZTools_RotatedLinearPattern) are not registered until Initialize()
imports the command modules.

Move the addWorkbenchManipulator() call into Initialize() with a guard
to prevent duplicate registration. This eliminates the 'Unknown command'
warnings on startup.
2026-02-01 19:51:56 -06:00
Zoe Forbes
9dde3ad67b feat(theme): add spanning tree branch lines to CatppuccinMocha
Replace simple open/closed arrow indicators with full spanning tree
branch lines (vline, T-junction, L-junction) using the _dark SVG
variants. This renders the model tree with ASCII pipe-style connectors
instead of bare disclosure arrows.
2026-01-31 20:49:39 -06:00
Zoe Forbes
6507dff1a1 fix(datum): fix selection table column alignment
Use fixed-width columns (28px) for the type icon and remove button
instead of ResizeToContents, which was sizing them to the header text
width rather than the content. The 'Type' header label is removed
since the narrow icon column is self-explanatory. The remove button
uses setFixedSize(24,24) to sit cleanly within its fixed column.
2026-01-31 20:41:27 -06:00
Zoe Forbes
6f4ac5ffb1 fix(datum): prevent RuntimeError from deleted Qt widgets in params UI
QFormLayout.removeRow() destroys the widgets it owns, transferring
ownership to Qt which immediately deletes the underlying C++ objects.
The update_params_ui() method was calling removeRow(0) in a loop to
clear the parameter fields before re-populating them for the new mode.
This destroyed the long-lived QDoubleSpinBox instances (offset_spin,
angle_spin, param_spin, x/y/z_spin) stored as instance attributes.

On the next call to update_params_ui() — triggered by selection
changes, row removal, or mode override — the method attempted to
addRow() with these same Python references, but the C++ objects behind
them had already been freed by Qt. This produced:

  RuntimeError: Internal C++ object (PySide6.QtWidgets.QDoubleSpinBox)
  already deleted.

The fix replaces the removeRow() loop with a new _clear_params_layout()
method that uses QLayout.takeAt() to detach items from the layout
without destroying them. Each widget is hidden and reparented to None
(releasing Qt's ownership) so it survives the layout clearing and can
be safely re-added with addRow() and show() on the next mode switch.
2026-01-31 20:39:20 -06:00
Zoe Forbes
8d1f195e56 Add PartDesign WorkbenchManipulator and sync Catppuccin theme
- _ZToolsPartDesignManipulator: injects ZTools commands into PartDesign
  workbench toolbars (Helper, Modeling, Transformation) and menus via
  Gui.addWorkbenchManipulator() - no workbench switch needed
- Sync CatppuccinMocha.qss with canonical KindredCreate.qss: tree branch
  indicators, header min-height, dock/actiongroup padding, spreadsheet
  cell editor styling, CSS border-triangle arrows
2026-01-31 09:21:38 -06:00
Zoe Forbes
005348b8a9 Leverage FreeCAD AttachExtension for parametric datum updates
ZTools datum planes now use FreeCAD's built-in attachment engine instead
of setting MapMode='Deactivated' with manual placement. This means
datums automatically update when source geometry changes on recompute.

Each datum type maps to a vanilla MapMode:
  offset_from_face  -> FlatFace + AttachmentOffset.Base.z = distance
  offset_from_plane -> FlatFace + AttachmentOffset.Base.z = distance
  midplane          -> FlatFace on face1 + offset = half gap distance
  3_points          -> ThreePointsPlane (3 vertex refs)
  normal_to_edge    -> NormalToEdge + MapPathParameter for position
  angled            -> FlatFace + AttachmentOffset.Rotation for angle
  tangent_cylinder  -> manual fallback (TangentPlane needs vertex ref)

The C++ AttachExtension handles: automatic recompute via
extensionExecute(), dependency tracking via PropertyLinkSubList,
topology change handling, and live preview via extensionOnChanged().

Non-Body datums (Part::Plane) lack AttachExtension and continue to
use manual placement as before.

Other changes:
- New _configure_attachment() helper sets MapMode, AttachmentSupport,
  AttachmentOffset, and MapPathParameter on datum objects
- _setup_ztools_datum() accepts optional attachment parameters and
  falls back to manual placement when not provided
- DatumEditTaskPanel.on_param_changed() writes to AttachmentOffset
  and MapPathParameter for live editing instead of TODO stubs
- AttachmentSupport added to hidden properties list
- Spreadsheet links target AttachmentOffset.Base.z instead of
  Placement.Base.z for attached datums
- ZTools metadata (ZTools_Type, ZTools_Params, ZTools_SourceRefs)
  preserved for edit UI and styling
2026-01-31 08:09:53 -06:00
Zoe Forbes
0e95d1cc76 Fix Qt6 StandardButton TypeError and C++ ViewProvider Proxy errors
Three fixes:

1. Remove int() wrapper from getStandardButtons() return values.
   In Qt6/PySide6, the | operator on QDialogButtonBox.StandardButton
   returns a StandardButton enum that is not convertible to int via
   int(). FreeCAD's task panel system accepts the enum directly.
   Affected files: datum_commands.py, datum_viewprovider.py,
   assembly_pattern_commands.py

2. Guard _setup_ztools_viewprovider() against C++ ViewProviders.
   PartDesign datum objects (Plane, Line, Point) use pure C++
   ViewProviders (e.g. ViewProviderDatumPlane) that don't expose a
   Proxy attribute. The previous code crashed with:
   'Gui.ViewProviderGeometryObject' object has no attribute 'Proxy'
   Now checks hasattr(vo, 'Proxy') before attempting assignment and
   wraps the assignment in try/except as a secondary guard.

3. Use persistent setPropertyStatus('Hidden') instead of transient
   setEditorMode(2) for hiding attachment properties (MapMode,
   Support, etc.). setEditorMode is session-only and resets on
   document reload, leaving 'MapMode: Deactivated' visible in the
   property panel. setPropertyStatus persists in the document file.
2026-01-31 04:26:06 -06:00
Zoe Forbes
98bd444221 Fix workbench init and spreadsheet syntax errors
- Use Gui.activateWorkbench() instead of calling Initialize() directly
  on dependent workbenches. Direct calls skip the C++ __Workbench__
  injection step, causing 'AssemblyWorkbench has no attribute
  __Workbench__' errors.
- Fix duplicated generator expression in spreadsheet_commands.py
- Fix missing else clause in spreadsheet_commands.py
2026-01-29 22:42:29 -06:00
Zoe Forbes
4627fea225 Fix workbench not loading 2026-01-28 17:07:31 -06:00
Zoe Forbes
e6f1de4ef8 add kindred integration docs 2026-01-26 23:06:14 -06:00
Zoe Forbes
2f03558a33 add spreadsheet commands 2026-01-26 06:34:59 -06:00
Zoe Forbes
a66dac7afc Improve datum behaviour 2026-01-24 23:24:39 -06:00
Zoe Forbes
981b15804e first commit 2026-01-24 15:16:09 -06:00