Commit Graph
46 Commits
Author SHA1 Message Date
ArdaandClaude Opus 5.5 7ca029e3ea Tint Page Editor canvas while the document has unsaved changes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 10:06:22 +03:00
ArdaandClaude Opus 4.6 b0eb859f32 Add zoom support to OxPage editor with 50% default
Toolbar zoom buttons (in/out/reset/fit) and Ctrl+MouseWheel now
control the page editor canvas when it is active. Frame image is
scaled via PIL for smooth rendering at any zoom level.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-22 23:19:13 +03:00
ArdaandClaude Opus 4.6 16edd144e9 Add OxPage WYSIWYG editor panel for ontrolOx HMI pages
New ox_page_view.py with OxPageViewPanel: canvas rendering at device
resolution (800x480 Orion, 320x240 Rion), RGB565 color conversion,
widget tree, selection handles, drag-move, device frame image support.
Wired into main.py with context menu, history, panel lifecycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-22 21:06:56 +03:00
ArdaandClaude Opus 4.6 d5ef8eea6f Improve User Manager: Workbench-style permissions dialog, live mode support, double-click to open
- Permissions dialog now uses two-level UI: compact Edit User with >> buttons
  opening a separate grid dialog (Groups x Operator/Admin columns) with
  Clear All / Set All and auto-cascade (write implies read, admin implies operator)
- Provisioning has its own >> popup dialog
- Removed live mode restrictions for add/edit/delete user operations
- Broadened type detection and added safe int conversion for live mode values
- Double-click on tree node or canvas box opens special view (User Manager for
  UserService, Properties for other components)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-22 20:57:49 +03:00
ArdaandClaude Opus 4.6 43549046e5 Add User Manager panel for sys::UserService components
New user_service_view.py with table of sys::User children, add/edit/delete
dialogs, SHA-1 credential hashing, 32-bit permission bitmask (4 groups x 7
flags), 8-bit provisioning byte, and undo support. Wired into main.py with
context menu entry, panel management, history navigation, and live-mode DOM
resolution for correct display on connected devices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-22 20:10:03 +03:00
ArdaandClaude Opus 4.6 abdafef7cb Use manifest defaults when adding components and refresh properties from device
- Populate prop elements with manifest default values when adding
  components in both offline and live mode
- Send config values from manifest in SOX add command for live devices
- Refresh button in properties panel now fetches fresh values from
  the connected device before re-reading the DOM
- Properties panel fetches device values on open in live mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-20 00:14:52 +03:00
ArdaandClaude Opus 4.6 2530bbd92c Implement live device add/delete component and app actions
Fix add component from palette in live mode: resolve <app> element
as comp_id 0, fix type_id lookup to use type_name_map, set type_name
on newly added SoxComponent, sync device values into DOM after add,
write meta position back to device, and subscribe new component to COV.

Fix delete component in live mode: clean up subscriptions for deleted
component and all its descendants.

Add tree root context menu with device app actions (save, hibernate,
quit, restart, reboot) in live mode. Device save clears dirty state.

Clean up connection lost handling to do a full disconnect.
Fix slot registry to copy base slots and renumber IDs correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-19 16:30:42 +03:00
ArdaandClaude Opus 4.6 55f76d60df Add Device > Discover menu with standalone discovery dialog
Discover dialog shows a device list with Port, Wait Time fields and a
Discover button. Selecting a device and clicking Connect (or double-
clicking) opens a credentials prompt for username/password, then
connects. The Connect dialog is reverted to its original simple form.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-19 13:42:18 +03:00
ArdaandClaude Opus 4.6 60c022828d Fix live-mode link navigation not selecting the target link
In live mode the DOM is rebuilt from the device when switching sheets,
creating new element objects. The pending link from the old tree could
not be found by identity in canvas_link_map. Re-resolve it by from/to
attributes after the rebuild so the selection matches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 22:15:48 +03:00
ArdaandClaude Opus 4.6 c59cd22153 Fix live-device slot ID resolution, add print and tighten wire routing
_slot_name_by_id() now resolves SOX link slot IDs against the
inheritance-flattened final_components_registry instead of the
per-type slot_registry whose local IDs were wrong for types with
intermediate parents (e.g. RegFloat→Register→Component). This
produced incorrect link endpoints, inflated linked-slot visibility,
and different box sizes between file and live modes.

Also: tighten routing constants for denser wiring, add wiresheet
PNG print/export (Ctrl+P), sort link routing jobs by gap distance,
remove debug route logging, and fix live tree-expand re-selection.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 21:51:22 +03:00
ArdaandClaude Opus 4.6 e33a6bc5d8 Guard file open and device connect against conflicting state
Opening a file while connected to a device prompts to disconnect first.
Connecting to a device while a file is open prompts to save unsaved
changes, then closes the file before showing the connect dialog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 13:58:55 +03:00
ArdaandClaude Opus 4.6 4e38847f91 Fix live wiresheet: resolve type names and load schema gracefully
- Add type_name_map on SoxClient so components loaded after connect
  resolve proper names (e.g. control::And2) instead of kit::typeN.
  This lets the slot registry and final_components_registry match,
  so component boxes show their slots and property values.

- Load live schema gracefully: skip missing kit manifests instead of
  aborting, compile the kits we have, and warn about missing ones in
  the status bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 13:43:44 +03:00
ArdaandClaude Opus 4.6 599370f60c Put Device menu first in menu bar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 13:05:23 +03:00
ArdaandClaude Opus 4.6 a0e5ec1a31 Move Device menu after File in the menu bar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 13:04:15 +03:00
ArdaandClaude Opus 4.6 d32285abe8 Fix tree expand in live mode: use focused item and run IO in background
_on_tree_open used tree.selection() which may differ from the opened
node; switched to tree.focus(). Network calls in _live_tree_expand now
run in a daemon thread so the UI stays responsive during lazy loading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 09:11:14 +03:00
ArdaandClaude Opus 4.6 67c403339c Fix live tree selection lost after wiresheet DOM rebuild
After open_wiresheet rebuilds the DOM and tree, re-find the target
element by its comp id (not the old tree item ID which no longer
exists) and re-select it with the restoring flag to prevent recursion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-12 00:24:10 +03:00
ArdaandClaude Opus 4.6 1fd6e72b8c Fix DASP close deadlock and kit checksum sign display
Use RLock instead of Lock for _close_lock so close() can call
_shutdown() without deadlocking — previously the session never
marked itself closed, causing infinite keepalive sends.

Mask kit checksums to unsigned 32-bit for hex display so negative
i4 values render as proper 8-digit hex (e.g. d3984c51 not -2c67b3af).

Tested against live device at 192.168.1.251 — full handshake,
schema read, and component tree load confirmed working.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-11 23:57:19 +03:00
ArdaandClaude Opus 4.6 643bcdc952 Add Trace DASP preference to print protocol transactions to terminal
New checkbox in Preferences (default off). When enabled, every DASP
send (>>>) and receive (<<<) prints message type, seq/ack numbers,
payload size, and remote address to stdout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-11 23:48:10 +03:00
ArdaandClaude Opus 4.6 4431f11d83 Fix crash on tree select when item no longer exists after DOM rebuild
Guard tree.get_children() with tree.exists() so a stale item ID from
a COV or lazy-load rebuild does not raise TclError.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-11 23:43:22 +03:00
ArdaandClaude Opus 4.6 dafebcebda Live Editor: add DASP/Sox device connection with full CRUD and COV
Port the DASP transport and Sox protocol stack from sedonaOntrol Java
to Python, enabling live device editing alongside the existing offline
SAX editor. Lazy-loads components on navigation, caches them, and
subscribes to COV events for the active wiresheet.

New files: dasp.py, sox.py, device_session.py, connect_dialog.py,
live_hooks.py. Modified: app_state.py (live-mode state), main.py
(Device menu, COV polling, lazy tree expand), properties.py (Sox
write-through), sax_file.py (structural mutations route through
live_hooks), schema.py (find_manifest helper).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-11 23:31:36 +03:00
ArdaandClaude Opus 4.6 78678e1e0c Auto-open Kit Manager when file has kits without checksums
When a SAX file is opened and any declared kit is missing a checksum,
the Kit Manager panel opens automatically and the palette stays empty
until the checksums are resolved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 22:57:47 +03:00
ArdaandClaude Opus 4.6 5045cfbe35 Palette: refresh kit list after opening a file
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 22:11:35 +03:00
ArdaandClaude Opus 4.6 13b637a8b9 Palette: no misleading message when no file is open
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 22:03:03 +03:00
ArdaandClaude Opus 4.6 9944d93f74 Palette: show no kits until a file is open
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 21:59:28 +03:00
ArdaandClaude Opus 4.6 4e89d4c83f Palette: show only kits declared in the app's schema
The sidebar palette combo now lists kits from the open file's schema
rather than every kit installed in Sedona home, with their resolved
version labels. Falls back to all installed kits when no file is open.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 21:57:52 +03:00
ArdaandClaude Opus 4.6 a77edead25 Manage Kits as embedded panel, fix checksum zero-padding mismatch
Manage Kits now opens inside the editor pane (like Properties and Link
View) instead of a separate Toplevel window. Also normalize hex
checksums by stripping leading zeros so .kit and manifest filenames
that disagree on padding (e.g. 462d43e vs 0462d43e) still resolve to
a version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 21:08:59 +03:00
ArdaandClaude Opus 4.6 da0e18a9c3 Toolbar: pane toggle + tidy buttons, tooltips on every icon
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 18:25:44 +03:00
ArdaandClaude Opus 5 1546c1c8e0 Back and Forward walk the panels too, not just the sheets
Opening a Properties or Link view was invisible to the history, so Back
from one did two things at once: it took the panel down and stepped to the
sheet before the one it was opened over. There was no way back to a
picture you had just been reading.

A history entry is now a (kind, element) pair naming what the editor pane
held -- a sheet, a Properties view, or a Link View -- and restoring one
puts that back: a sheet entry selects its tree node, a panel entry
re-opens the panel. So opening a panel is a move like opening a sheet.
Back from a Properties view lands on whatever came before it and Forward
brings the panel back, and following a link out of the Link View now has a
way home: Back returns to the picture the link was followed from, and a
second Back to the sheet that was open before that.

The panel's own Close is deliberately not recorded. It means "leave this
view", and recording it would put a sheet entry after the panel's, so Back
would re-open the panel that had just been closed. Leaving the position
alone means Back steps to what came before the panel and Forward re-opens
it, which is what the arrows are for.

Both arrows still go through close_editor_panel first, so unsaved
Properties edits are asked about exactly as before and a refusal leaves
the view and the position where they were. Pruning now has two kinds of
entry to check -- a sheet needs a tree node, a panel needs its component
still in the document -- and collapses any pair it leaves naming the same
view, since a Back that visibly does nothing is worse than a shorter
trail.

sheet_history and its functions are renamed for what they now hold.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 19:39:45 +03:00
ArdaandClaude Opus 5 56749872b4 Link View: every link of a component, drawn around it
Right-clicking a component now offers Link View alongside Properties, from
the wiresheet and from the navigation tree alike. It takes over the editor
pane the same way and answers one question -- what is wired to this
component, and where does it go.

The chosen component sits in the middle wearing the stroke a selected box
wears on the sheet, with what links into it on the left and what it links
out to on the right, so every arrow points the way the signal travels.
Pale yellow ground and no grid: nothing here can be positioned, because
the layout is derived from the links every time it is drawn and no part of
it is stored in the file. Read-only throughout -- no drag, no add, no
delete -- so a component's wiring can be read without the risk of
rearranging it.

Every line is grey, since this is not a wiresheet and a wire-blue line
would invite the reader to treat it as one. A link on the same sheet is
solid; one that crosses is dashed, keeps the grey knob that sheet paints
on the slot, and has the far component drawn in with its sheet named
beneath it. A reference the document cannot resolve gets a placeholder
naming the path, because a link the view silently dropped would be the one
thing a reader could not find out from here.

Clicking a wire or a component follows the link: it opens the sheet of the
end that is not the component the view is about, with the link selected in
red. A link that stays on one sheet therefore goes back to that sheet
where both ends are drawn, and one that crosses opens the other sheet --
the end the view could only show as a knob.

Supporting changes:

- draw_component_box is factored out of render_components, so the sheet
  and this view paint a component with the same code and a box cannot read
  differently between them. draw_knob takes its canvas for the same
  reason.
- The editor pane's hand-over is now shared: _take_editor_pane,
  _give_editor_pane_back and close_editor_panel replace the
  Properties-only versions, so "you have not saved that" is still asked
  once, in one place, whichever panel has the pane.
- Fixes the jump to a link's other sheet, which arrived with the link not
  selected. An after_idle callback is not late enough -- ttk dispatches
  its own selection event later than one of those, so the repaint wiped
  the selection. The link is left in _pending_link_selection for
  on_tree_select to honour once it has painted.
- Each gap is sized to hold a lane per wire crossing it, and lanes are
  handed out nearest-target-first, so a fan of a dozen links nests instead
  of crowding a dozen verticals into a 30px band.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 18:54:44 +03:00
ArdaandClaude Opus 5 2db230dec1 Properties view: every slot of a component, edited in the editor pane
Right-click a component on the wiresheet or in the tree and Properties takes
over the editor pane, listing every slot the manifest declares rather than the
handful a box paints. Config slots that are not @readonly are white and
editable; everything else is grey.

Rows are built from the slot's facets, read against SedonaDoc/niagara.html:
@trueText/@falseText, @range, @precision, @unit, and @min/@max, which bound
what Save accepts. Three facets it had wrong:

  - null is a value, not an absence. control::WriteFloat pairs 'in' with a
    setNull action and the sample app stores val="null" on four of them, so
    null now shows, parses back, and reads as @nullText where declared.
  - @min/@max on a Buf count characters. TcpDevice.ipAddr is a Buf(17) with
    @max 16; a longer string is refused rather than overrunning the device.
  - an int's implicit range is noise. [-2147483648 - 2147483647] said no more
    than "a whole number", so only byte and short print a range they did not
    declare.

meta gets a row of its own: the '>>' opens its user groups as checkboxes and
its position as x and y, since typing 822411269 into a field sets neither.

Save writes only the rows that moved, as one undoable SlotValueCommand, and
refuses the lot if any row fails its range check. An edited field paints the
view in the canvas's own dirty tint, and every way of leaving asks before
discarding.

The file name on the tree's root row goes red while anything is unwritten,
counting both a dirty document and unsaved fields. Two things this needed:
the nav tree runs on its own style, because a themed Treeview's selected
foreground beats a row tag's; and the tag is added to or removed from the row
rather than recoloured, because reconfiguring a tag does not repaint rows that
are already drawn.

Also fixes a latent hazard the panel exposed: Del and Backspace are bound
application-wide, so they now stand down while a text field has focus rather
than deleting the component behind it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 23:38:03 +03:00
ArdaandClaude Opus 5 ed79e9af72 Tree rows get the same right-click actions as canvas boxes
Right-clicking a component in the navigation tree offered Delete Component
alone, while the same component on the wiresheet also offered Link Mark and
Link From / Link To. Which list a component was picked from should not change
what can be done with it, so both popups are now built by
fill_component_popup.

Its entries close over the component instead of reading a selection back,
which is what lets each popup act on the row or box that was actually clicked
-- the canvas commands went through app_state.selected_canvas_tag, which a
tree row never sets. do_link_mark, do_link_from_mark, do_link_to_mark and
delete_tree_selected_component fall out with it, and Link Mark now says in the
status bar what it marked, since nothing else on screen shows that.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:41:30 +03:00
ArdaandClaude Opus 5 a1f8059c49 Link popup: go to the sheet the other end of the link is on
Right-clicking a wire or a knob now offers Go to Link Wire Sheet "<name>",
naming the sheet the far end is on -- the end a grey knob stands in for. A link
with both ends on the open sheet has nowhere to go, so the entry is left off
rather than greyed out.

find_component_by_path turns a link's from/to reference back into the component
it points at, the inverse of get_component_path, and the sheet is that
component's parent; a parent of <app> is the file's root node, which the popup
names after the file.

Arriving selects the same link and scrolls it to the middle of the view. It is
found by its element rather than by the tag it was picked on, since a repaint
hands out fresh wire tags, and it waits for that repaint from an after_idle
callback: ttk queues its selection event rather than dispatching it, so the
sheet is not painted when the tree node is selected -- and painting a sheet
clears the selected link, which was wiping the selection this feature had just
made. The jump is an ordinary sheet opening, so Back returns to where the link
was picked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:26:46 +03:00
ArdaandClaude Opus 5 ad8396ef7b Zoom to Fit, with a toolbar icon beside the zoom controls
Fits the whole painted sheet in the visible canvas and scrolls it into view,
from the View menu, Ctrl/Cmd+9, or the four-corners button after the zoom
percentage. The ladder gains 25% and 33% at the bottom, so a wide sheet has
somewhere to fit into.

Fit is the one scale that is not on the ladder -- a sheet fits at whatever
scale it fits at -- so zoom_step now takes the first level above or below the
scale in force rather than the neighbour of the nearest rung.

The sheet is measured from item coordinates rather than canvas.bbox(), which
is inflated by the outline stroke: a stroke is the same two pixels at every
zoom, so a bbox divided back to 1:1 reports a slightly smaller sheet the
further in it is zoomed, and fitting an already fitted sheet crept from 288%
to 291% instead of standing still. Anything painted left of or above the
canvas origin is measured from the origin, since no amount of scrolling brings
it into view.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:14:46 +03:00
ArdaandClaude Opus 5 781138e3dc Wiresheet zoom, from the View menu, the toolbar and Ctrl+wheel
A ladder of scales from 50% to 300%, stepped by Zoom In / Zoom Out / Zoom 100%,
by the two buttons beside the navigation arrows, and by Ctrl and the wheel,
which holds the point under the pointer still. A menu or keyboard zoom holds
the middle of the view instead, so it closes in on what is already being
looked at.

Painting and routing stay at 1:1, because that is where every metric is tuned:
box header and row heights, wire stubs, lane gaps, standoffs, knob radii. Zoom
scales the finished picture, so a zoomed sheet keeps the proportions of a 1:1
one and the router reaches the same decisions at every scale. Text comes along
because the three box fonts are resized once the boxes have been measured with
them.

redraw_links replaces the direct draw_links calls a drag or a drop makes: the
router reads box positions off the canvas, so the boxes go back to 1:1 for the
routing pass and the result is scaled again. Canvas coordinates carry the zoom,
which is why the drag, release and drop handlers now snap against
meta_scale * zoom -- a box dragged the same distance across the screen lands on
the same meta step at 50%, 100% and 200%.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 23:03:35 +03:00
ArdaandClaude Opus 5 0166be3454 Tidy Layout on Control+W only
Cmd+W closes the window on macOS, so the Command half of the pair is left
alone; this is the one shortcut that is not bound on both modifiers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:41:03 +03:00
ArdaandClaude Opus 5 5f66ecef7b Tidy Layout on Ctrl/Cmd+W
Joins the Command/Control shortcut pairs, so the chord works the same on
either platform, and the View menu entry now shows it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:28:34 +03:00
ArdaandClaude Opus 5 4988483c64 Tidy Layout moves from the Edit menu to View
It re-flows what is on screen rather than editing the document, which is where
the rest of the sheet's presentation controls now live.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:26:52 +03:00
ArdaandClaude Opus 5 23a8bfbaa8 View menu: tree/palette toggle, and Back/Forward through opened sheets
Tree / Palette hides the left column so the wiresheet has the whole window.
ttk has no hide flag for a pane, so the column is dropped from the paned
window and re-inserted at the front, which is why the configured width is
re-applied afterwards.

Back and Forward walk the sheets opened this session, with two arrow buttons
in a new toolbar on the same commands. History entries hold the element whose
children are painted rather than a tree item id: rebuilding the tree hands out
fresh ids, while the elements themselves survive. Recording runs from the tree
selection handler, the one route every sheet opening takes, and is suppressed
while a walk drives that selection so it cannot rewrite its own trail. Opening
a different file retires the history; a delete or an undo drops only the
entries whose element has left the document, keeping the position on screen.

open_file builds the tree inline instead of going through
refresh_treeview_from_dom, so it never raised the tree-filled callback and the
history had no way to see a new file. It and reset_to_startup_state now fire
it, which also gets the tree column fitted on load rather than on the first
resize.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:25:03 +03:00
ArdaandClaude Opus 5 5424d84156 Left column: fixed width preference, auto scrollbars, pane floors
The tree and palette column took a share of every extra pixel the window
gained. It is now pinned to a width set in Preferences, defaulting to
230 px, so widening the window only ever feeds the wiresheet.

That fixed width brought two existing weaknesses into view:

- Long paths and type names had nowhere to go. Both lists now size their
  tree column to the widest visible row - ttk derives the horizontal
  scroll range from the column width, so a column left stretching can
  never scroll - and carry vertical and horizontal scrollbars that leave
  the grid when they have nothing to scroll.

- A short window squeezed the navigation tree away entirely. Both lists
  asked for ten rows, so the palette requested the most while the tree,
  carrying the larger weight, gave up its height first. The requested
  rows are now 6 and 5, a 300 px minimum window height keeps the
  shortfall shallow, and clamp_left_pane_split holds a dragged sash
  between the two floors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:06:21 +03:00
ArdaandClaude Opus 5 e2cd13b9a0 Wiresheet: grid-snapped layout, visible wire routing, knob legend
Layout rules for tidy and for dragging:
- Boxes snap to whole meta steps live while dragged, not only on release.
- The left-most column and top row clear the canvas edge by at least 30px,
  and neighbours by at least 30px, each rounded up to the next step.
- Box widths round up to the grid so a right edge lands on a grid line.
- Column gaps widen only where wires need lanes, so most stay at exactly 30px.
- A sheet too wide for meta's 0..255 range is laid out at 2, then 3, then 4
  grid squares per step. The multiplier is derived from the sheet's contents,
  so painting and tidying agree on it without recording anything in the file.
  The grid size in Preferences is untouched.

Wire routing:
- No wire may pass under a component. A link with no clear route is shown as
  knobs on both slots instead of a line hidden behind a box.
- Vertical runs hug a box within 15px, never closer than 10px, and two runs
  sharing a gap stand 10px apart.
- Horizontal runs of different links stay 5px apart. Runs from one output pin
  may share, since a fan-out is one signal.
- Straight routes claim their rows first, as their segments are pinned to
  their slots and cannot move later.

Knobs:
- Wire colour with a small white centre when the far end is on this sheet,
  grey when it is on another, half and half when a slot carries both.
- Selectable and deletable like a wire, and raised above the boxes so a click
  reaches them.
- Selecting a same-sheet pair draws a red dashed line between the two knobs.

Also:
- get_box_bounds returns the rectangle actually drawn rather than canvas.bbox,
  which was inflated by the outline stroke and by selection.
- Preferences offers to round the box width to a multiple of the grid.
- The tidy coordinate-limit warning said to lower the grid size; raising it is
  what helps, since the reach is 255 * grid size.
- Tidy Layout moves from its own menu into Edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 19:05:58 +03:00
ArdaandClaude Opus 5 01dadea610 Manage kits: reconcile the schema on save, and a dialog to repin builds
Placing a palette component no longer edits <schema> straight away. The kit is
noted as pending, its manifest is compiled so the box can be painted, and the
status bar says the kit will be declared on save. The <schema> block is then
reconciled when the file is written, in the one place that can report the whole
kit list the file will carry, with each kit's version and checksum.

What a kit's manifest depends on counts as used too, transitively, so placing a
component can bring in more than one entry: hvac pulls in types, ontrolPion
pulls in ontrolPlatform.

New Kits > Manage Kits... dialog lists every kit in three groups -- needed by
the app, declared but unused, and merely installed -- with the pinned build, the
newest installed build, and an Action dropdown of every build a kit ships.
The tick means the schema declares the kit: grey and fixed for kits the app
needs, unticked to remove, ticked to add at the newest build. "Upgrade all kits
to latest version" moves every declared kit; "Update kits" applies the ticks and
the Action column, additions and removals included.

Every schema change is applied as a batch, then verified: a missing manifest or
a component type that stops resolving reverts the whole block and reports why,
and a kit the app needs cannot be removed. Changes are one undo step, which
recompiles the slot registry in both directions since a repin can change a
component's slots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 12:06:25 +03:00
Arda b286b208da Kit manager menu oncesi 2026-08-21 09:12:46 +03:00
ArdaandClaude Opus 4.6 47bfaf04e0 Grey out incompatible slots in the link dialog
Parse the readonly facet from kit manifests and use it to disable
slots that cannot participate in a link: read-only slots are greyed
on the target side only (they remain selectable as sources), action
and void slots are greyed on both sides, and type mismatches are
greyed when the other side has a selection. A status label previews
the link path at the bottom of the dialog.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-20 21:58:17 +03:00
ArdaandClaude Opus 4.6 424caf777c Add link management: create, select, delete with undo/redo
Implement full link workflow between component slots on the wiresheet:
- Link Mark / Link From / Link To context menu items for creating links
- Link dialog with slot type validation and source/target swap button
- Selectable link wires (click to highlight in red) with right-click delete
- Undo/redo support for both add and delete link operations
- Component deletion already cascades to remove related links

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-08-20 16:34:17 +03:00
ArdaandClaude Opus 5 c8026f00db Warn and reset instead of exiting when a kit manifest is missing
A kit with no manifest under the Sedona home folder called sys.exit(1),
tearing down the whole app over one unopenable file.

schema now raises MissingManifestError instead, collecting every
unresolved kit first so one dialog names them all rather than the user
fixing them one reopen at a time. describe_missing_manifests builds the
body, pointing at the configured Sedona home and at Preferences.

open_file catches it, reports it, and calls the new
reset_to_startup_state to return to the just-launched state: no file,
empty tree, empty sheet, cleared registries and undo stack. The generic
except now resets too, since a half-parsed file previously left
current_file_path and a stale root behind.

Placing a palette component hits the same loader, where a full reset
would be too destructive: it rolls back the <kit> entry it just added,
rebuilds the previous registry, and abandons only that placement.

schema no longer imports sys or tkinter, so it reports nothing itself
and stays testable without a display. base_window_title moves to
app_state so the reset can restore the title without duplicating it.

README: document the new behaviour, drop the fixed gap, and correct the
stale "no undo, no keyboard shortcuts for save" claim.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 23:25:01 +03:00
arda.aydin@ontrol.com.tr 9c283c7eea First Commit
Sedona sax editor AI yardimi ile yaziliyor
2026-08-13 17:59:08 +03:00