feat: add NixOS flake.nix support#270
Closed
eugenioenko wants to merge 84 commits into
Closed
Conversation
Implement a reusable tree widget in internal/widgets/ with JSON-serializable config, multi-action icons, context menus, scrollbar, and expand/collapse. Register it as a "Widget" sidebar panel with demo Docker data for visual testing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Card widget draws a border and insets its child content. Adds DrawBorder to the widgets.Surface interface and a CardWidgetAdapter bridge. Demo wraps the tree widget in a card in the Widget sidebar panel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Box widget provides configurable padding (top/bottom/left/right) without borders. Demo updated to use box with padding 1 on all sides. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Title widget renders a single-line header with optional dropdown icon when menu entries are provided. Dropdown widget is a standalone clickable icon that triggers a menu callback. Demo shows title widget in sidebar. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add VStack and HStack layout widgets with grow/fixed sizing based on each child's Height()/Width() methods. Remainder pixels distributed across first grow children. Define Widget interface in widgets package. Add generic WidgetAdapter to replace per-type adapters. Demo shows Docker view with title + 3 cards in a vstack. TODO: card border should use theme border style Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Box now handles borders (individual sides), padding, and margin — replacing Card entirely. Border style defaults to theme StyleBorder. Corner characters only draw when both adjacent sides are enabled. Added helper constructors for common cases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add BaseWidget with embedded BoxModel (border/padding/margin per side) and RenderBox() — all widgets inherit layout via struct embedding - Remove CardWidget; BoxWidget now delegates to BaseWidget for rendering - Add JSON widget builder (BuildFromJSON) for hot-reloadable widget panels - Add "Reload Widgets" command for edit-reload iteration without recompile - Title and Tree menu icons now use DropdownWidget internally with configurable icon and padding via JSON (icon, padded, menuIcon, menuIconPadded) - Remove per-type adapters; only generic WidgetAdapter remains - Add widget.json demo file with Docker container/image/volume layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HStack supports left/center/right, VStack supports top/center/bottom. Alignment applies when all children have fixed sizes. Grow children fill available space, making alignment irrelevant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add ButtonWidget with accelerator key support (underline, not background highlight), themed styles (StyleButton/StyleButtonFocused with inverted fg/bg default for focus), and JSON builder wiring. Replace hardcoded StyleCount with iota sentinel. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add FocusManager with flat focusable list, tab/shift+tab cycling, click-to-focus, and key routing to focused widget only. BoxWidget shows StyleBorderActive when its child has focus. Button padding now fills correctly with background color via BorderedInterior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Widget panel was built before ApplyBorderStyle, so it always used the theme default borders instead of the user's settings override. Rebuild after border style is applied at startup and at runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Label displays plain text (single line, no interactivity). Divider draws a horizontal rule using the theme border character. Both wired into the JSON builder. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Supports bordered (default, uses theme borders with active highlight) and borderless (chevron prefix with border color styling) modes. Includes cursor positioning, double-click word selection, clipboard, and paste. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TabsWidget (standalone tab bar with overflow indicator) and TabbedWidget (tab container that pairs tabs with child content panels, switchable from JSON). Fix click-focus bug where mouse forwarding in FocusManager consumed events before the tab bar could handle them. Also adds inner padding to bordered inputs and wires tabbed callbacks on widget panel reload. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TabsWidget is now focusable with left/right to move a selected cursor and Space/Enter to activate the tab. Underline indicator shows on the selected tab label text only (not padding spaces). SetFocused resets the selection to the active tab. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add StyleSelectedTab theme style with fallback to SidebarSelected for backwards compatibility. Reorder focus collection so content widgets are focused before the tab bar. Highlight overflow chevron when keyboard-navigating to hidden tabs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…idget Close the gaps needed for the tree widget to replace the explorer: - ActiveID highlights a node independently of selection (open file) - Muted flag renders node labels in muted style (gitignored/dotfiles) - OnExpand callback fires on expand for lazy child loading - Reload preserves expanded state while refreshing via OnExpand - SelectByID programmatically navigates to a node - Mouse handler now checks rect bounds before consuming events Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allows each node to specify its own badge style (e.g. StyleWarning for modified, StyleDanger for deleted) instead of always using StyleMuted. Falls back to StyleMuted when unset. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ListItem struct provides a clean flat definition (no children/nesting). Parsed as "list" type in JSON, maps to TreeWidget internally. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a Navigation sidebar panel that reimplements the explorer using the widget system's TreeWidget. Extracts shared code (LoadDirEntries, FileOp* helpers) so both explorer and navigation use the same filesystem loading and file operation logic, keeping them in sync on mutations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generic modal dialog that accepts any widget tree as content and renders a configurable button row. Supports Tab cycling between content focusables and buttons, Esc to dismiss, cursor forwarding for input widgets, and mouse click on buttons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Display widget that takes a string and wraps it at the available width. Reports Height() from the wrapped line count so layout containers (VStack, Dialog) can auto-size around it. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace custom button rendering, hit regions, and focus tracking with real ButtonWidget instances in a right-aligned HStack. Adapter's FocusManager handles Tab cycling. Add OnClick to ButtonConfig, default button padding 1 left/right, HeightForWidth interface for paragraph sizing, and demo confirm dialog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ersed colors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gap property spaces children in layout stacks. Bold field on Cell enables per-cell bold for styled cells. Dialog and title widgets now render text in bold. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… 25 items Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete old ui.InputDialogWidget and demo dialog. ShowInputDialog now composes a DialogWidget with an InputWidget as content. Add ShowInputDialogEx for custom confirm labels (Open, Review, etc). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete old ui.ConfirmDialogWidget. ShowConfirmDialog now composes a DialogWidget with a ParagraphWidget as content. Add ShowConfirmDialogEx for titled confirm dialogs. Fix dialog layout gaps between title, content, and footer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add OnSubmit callback to InputWidget triggered on Enter (not Shift+Enter). Wire it in ShowInputDialogEx so all input dialogs submit on Enter. Add "Unsaved Changes" title to quit dialog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Folds can be nil when editor receives mouse events before fold state is initialized. Found by chaos monkey testing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFG67qTw48fmHxyL7GvBGP
Fix SelectedGroup() not matching PR file nodes to their parent PR group, causing context menu diff commands to fail. Fix OpenPRDiff extended mode never triggering by deferring SetExtended until after OnFetchExtended is wired. Add ActivateSelected() to handle PR vs local file opening. Add 's' as stage/unstage shortcut. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFG67qTw48fmHxyL7GvBGP
VStack now queries HeightForWidth on children that return Height()==0, allowing ParagraphWidget to auto-size without manual pre-wrapping. Remove bottom divider from changes panel. Add commit description paragraph to changes help dialog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFG67qTw48fmHxyL7GvBGP
Add a commit history list to the Changes panel showing the last 10 commits with branch context. Updates dynamically when navigating between repo groups. - git.Log() returns recent commits as LogEntry (hash + message) - NewListWidget() sugar for flat TreeWidget from ListItem slice - BoxWidget.FixedHeight/FixedWidth for constrained layouts - TreeWidget.OnSelect callback fires on selection change - Input placeholder shows target repo and branch Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HFG67qTw48fmHxyL7GvBGP
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
restoreExpanded now checks isExpandable() instead of len(Children) > 0 and calls OnExpand to load children before recursing. Also skips OnExpand for collapsed roots to avoid unnecessary directory reads. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Action icon clicks on "Changes" and "Staged" section headers now only stage/unstage files within that group, not across all workspace roots. Keyboard shortcuts (a/u) still affect all groups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SetRoots to NavigationPanel that snapshots expanded state before rebuilding and restores it after. Expose CollectExpanded/RestoreExpanded on TreeWidget and refactor Reload to use them. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move ensureVisible out of Render into keyboard handlers so it doesn't fight scroll changes from mousewheel or scrollbar drag. Forward all mouse events through FocusManager to focused widget, not just Button1. Pad chevron 1 space from right edge. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Narrow the input surface by 2 columns so text doesn't render under the chevron indicator. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Only scroll the list when the mouse is within the widget rect, preventing wheel events from elsewhere on screen from scrolling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Early-return EventIgnored when collapsible and not focused, preventing clicks from falling through to the non-collapsible handler and selecting invisible items. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a selection exists and Left/Right is pressed without shift, cursor jumps to the selection boundary instead of moving by one. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap dispatch order so focused widgets get first shot at key events. If the widget consumes the event (e.g. Ctrl+A in an input), global keybindings like editor.selectAll don't fire. Fixes Ctrl+A/V/C/X not working in panel inputs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded 3-column width with computed menuIconWidth() that accounts for actual icon label and padding config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both padded/non-padded branches computed the same value. Now delegates to menuIconWidth() which handles both cases correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Iterate runes right-to-left to match the right-to-left layout, preventing reversed text for multi-character icons. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Offset rightX by menuIconWidth() so action click detection matches the rendered position when both actions and menu icon are present. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PopupRect() returns absolute screen coords; surface.Sub() treats args as offsets from origin. Subtract surface origin to prevent double-offset rendering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
buildTree uses index-based IDs (pr:0) but handleMenu compared against name-based IDs (pr:PR #42) which never matched. Use label match only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove 23 step-by-step slog calls that were left from debugging the diff opening flow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove Expanded, StagedExpanded, ChangesExpanded, and Input fields that were never read. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove type assertions to *RenderSurface for Origin() calls. All Surface implementations now provide Origin() directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Warn users that building from source uses the latest development code which may be less stable than official releases. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent blank rows at bottom when tree shrinks (collapse, delete, reload) by clamping scrollTop to max valid position in Render. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TestRootGlobalKeysFire now uses passThroughWidget (returns EventIgnored) so global keys still fire. Added TestRootFocusedWidgetBlocksGlobalKey to verify that a consuming widget prevents global key dispatch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Widget System 1.0
Closes #266 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
flake.nixfor NixOS users to build and install tttRe-opening after main branch restructuring (was PR #267).
🤖 Generated with Claude Code
https://claude.ai/code/session_018GG9dYw2AG18ro5c2dkPtm