Commit Graph

198 Commits

Author SHA1 Message Date
3fc28fd54b Document background drawing with clips — use push/pop, not op.Record macro 2026-05-09 19:17:56 -04:00
f433a992b7 Clean up debug output and fix clip push/pop pattern 2026-05-09 19:16:10 -04:00
4a9253616d Fix StatusBar background using push/pop instead of op.Record macro
The op.Record macro was leaving a clip on the stack that prevented
subsequent elements from drawing. Use clip.Rect{}.Push()/clip.Pop()
instead for immediate push/pop.
2026-05-09 19:13:33 -04:00
4893d69f4e Add light gray background to StatusBar and BottomBar
Rename shaper_usage.md to layout_rendering.md
2026-05-09 18:49:43 -04:00
b8c6878f46 Introduce distinct Dp/Px types to prevent coordinate mixing at compile time
- Add ui.Dp and ui.Px as distinct named types
- Logic layer works exclusively in Dp (positions, sizes, regions)
- Renderer converts Dp→Px at Gio interop boundaries
- Capture gtx.Constraints once at start of Draw() for consistent positioning
- main.go converts app.ConfigEvent pixels to Dp before passing to logic layer
- Update documentation with new coordinate system architecture
2026-05-09 18:40:47 -04:00
f563a515e6 Document BottomBar X positioning and widget constraint modification 2026-05-09 18:01:57 -04:00
4cf8641bbd Fix BottomBar X positioning to use visible window width 2026-05-09 18:01:24 -04:00
3a3a62a50c Document BottomBar visible window positioning and pixel/DP conversion 2026-05-09 17:22:31 -04:00
e096341533 Draw BottomBar at visible window bottom instead of region Y which may be outside viewport 2026-05-09 17:19:14 -04:00
9476f5448a Update BottomBar to use drawText instead of material.Label
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 15:53:14 -04:00
99b4db919b Always draw Cut, Copy, Paste, Search icons; only ConflictIcon is conditional
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 14:49:43 -04:00
9fd6239129 Clean up debug statements, restore proper icons, document multi-line text spacing
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 14:48:12 -04:00
f67cca1f4b Update shaper_usage.md with correct MinWidth/MaxWidth/MaxLines requirements and offset calculation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 14:07:47 -04:00
ca34a570a9 Fix text wrapping: add MinWidth/MaxWidth/MaxLines to all LayoutString calls
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 14:01:02 -04:00
ddd44baefd Fix offset to match Gio paintGlyph exactly: (x + first.X, y + first.Y) with no subtraction
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 13:15:29 -04:00
eb9754fde0 Fix text offset: use (x, y) for X and subtract baseline Y so text top aligns with y
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 13:11:03 -04:00
965d6074f3 Fix filename visibility by correcting coordinate offset in low-level drawing
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:52:22 -04:00
4798e8fe3d Fix offset calculation: derive from first glyph position like Gio's textView
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:32:28 -04:00
1ee75c1cd1 Add op.Record/Stop macro wrapping to drawLineText (matches Gio's textView)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:30:41 -04:00
1acad99450 Fix filename rendering: split drawText into layout + drawLineText to avoid triple LayoutString calls
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:26:35 -04:00
0f62ef32fa Update shaper_usage.md with correct glyph drawing approach
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:15:57 -04:00
fcd2fea870 Add drawTruncatedText for single-pass layout, measure, and render
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:14:46 -04:00
16719afb95 Use shaper.Shape() and shaper.Bitmaps() to draw glyphs directly (no double-shaping)
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:13:06 -04:00
0fdaea990f Revert to material.Label for rendering - shp.Draw() not available in Gio v0.9.0
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-09 11:02:42 -04:00
87992c3d99 Fix charWidths to match Gio's textView PxPerEm calculation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 23:37:10 -04:00
96b7c6dc97 Remove debug logging
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 20:48:23 -04:00
9c1e32c52a Fix filename truncation with proper scaling and ellipsis width measurement
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 20:47:08 -04:00
bbd16be9f2 Improve filename truncation to fit exact number of characters
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 20:21:35 -04:00
68d431408d Add 5px margin around StatusBar and BottomBar to avoid macOS corner clipping
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 18:53:05 -04:00
1ae02d57fd Fix BottomBar text positioning using op.Offset and remove debug logging
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 18:45:24 -04:00
4f4e50a13c Remove debug code from renderer
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 17:35:25 -04:00
aa422ab541 Fix element positioning in renderer
- Use gtx.Constraints.Min.X/Y instead of image.Point.ToSize()
- Properly position all elements at their region origins
- Fix StatusBar and BottomBar text positioning

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 17:26:49 -04:00
c452cbef6d Fix BottomBar element positioning in renderer
- drawBottomBar now uses element region to position text
- Clips to bottom bar region before drawing
- Positions cursor position, byte position, word wrap button correctly

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 17:12:21 -04:00
013416ee08 Move logic into separate internal/editor package
- Create internal/editor/state.go with State struct and EditorLayout
- Create internal/editor/logic.go with Logic struct and Run method
- Logic owns all state, provides channels for config, frames, input, results
- Main goroutine uses editor.NewLogic() and logic.Run()
- Proper separation for testing later

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 17:06:00 -04:00
556f72643f Implement full architecture scaffolding with logic and frame receiver goroutines
- Logic goroutine: receives config events, recomputes layout, sends frames
- Frame receiver goroutine: reads frames, stores under mutex, calls w.Invalidate()
- Main event loop: renders frames under mutex, sends config events to logic
- Proper channel topology: configChan, frameChan, inputChan
- Mutex around elems shared between goroutines
- Window resize triggers layout recomputation in logic goroutine

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 17:03:21 -04:00
869f0b13ac Implement initial editor mockup with StatusBar, BottomBar, window resize
Elements implemented:
- StatusBar (top bar with filename, action icons, conflict/search icons)
- BottomBar (bottom bar with cursor position, byte position, word wrap button)
- Button (interactive button element)
- AlphaIndex, SearchBar, Cursor, MergeHunk, Toast, Spacer (stubs)

Layout:
- EditorLayout function computes regions for StatusBar and BottomBar
- Filename truncation with ellipsis (mocked filename for testing)
- Mocked data: "very_long_filename...", "Ln 47, Col 12", "1024 / 50000"

Renderer:
- drawStatusBar: draws filename line + icon line
- drawBottomBar: draws cursor pos, byte pos, word wrap button
- drawButton: draws button text
- drawIconButton: draws icon buttons

Window resize:
- configChan setup in main.go
- ConfigEvent handling in event loop
- Layout recomputation on resize

Builds and runs successfully.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 16:22:46 -04:00
9f36806a4f Re-arrange top bar icons, move byte position to bottom bar
StatusBar (top bar):
- Icons re-arranged: [Cut] [Copy] [Paste] on left, [Conf] [Search] on right
- Removed Right/BytePosition field (moved to BottomBar)

BottomBar:
- Added BytePos field (e.g., "1024 / 50000 bytes")
- Word wrap is now a button (tap to toggle On/Off)
- Layout: CursorPos (left) | BytePos (center) | WordWrap button (right)

Element changes:
- StatusBar: removed Right field, added Search field
- BottomBar: added BytePos field, WordWrap is now a button

Interaction:
- Word wrap tap sends InputEvent{ElementID: "word_wrap"} to Logic
- Logic toggles word_wrap_enabled state field

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 15:22:12 -04:00
8b09697e6b Add search button to top bar, move cursor info to bottom bar
StatusBar (top bar):
- Added Search icon (always visible, toggles search bar)
- Removed cursor position from top bar (moved to bottom bar)
- Fixed icon slots: Cut, Copy, Search, Paste (left to right)
- File size between Paste and Conflict icons

BottomBar (new element):
- Always visible at bottom of editor page (24 DP fixed height)
- Left: cursor position (Ln X, Col Y)
- Right: word wrap status (On/Off)
- Cursor position updated on every cursor movement
- Word wrap status persisted to .pad/state.json

Search button:
- Tap toggles search bar visible/invisible
- When active: shows SearchBar element, focuses text field, shows keyboard
- When inactive: hides SearchBar, clears query, hides keyboard
- Primary search activation method on Android (Ctrl+F still works as secondary)

Layout:
- Top: StatusBar (filename + action icons)
- Middle: SearchBar (when active) + TextField (editor)
- Bottom: BottomBar (cursor position + word wrap status)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 15:13:16 -04:00
c210f9a2f1 Add cut/copy/paste with persistent clipboard and filename ellipsis toggle
Cut/Copy/Paste:
- Separate icons in StatusBar at fixed positions (no reflow)
- Clipboard persisted to .pad/clipboard.json (survives process death)
- Cut: copies to clipboard, deletes from buffer, appends to undo chain
- Copy: copies to clipboard, keeps text in buffer
- Paste: inserts clipboard text at cursor, appends to undo chain
- Visibility: Cut/Copy when selection exists, Paste when clipboard non-empty

Filename ellipsis toggle:
- Filename on separate line at top of StatusBar
- Truncated with ellipsis if too long
- Tap ellipsis toggles between truncated and full multi-line view
- filename_expanded state field (not persisted)

StatusBar layout:
- Line 1: filename (truncated or full)
- Line 2: [Cut] [Copy] Ln X, Col Y [Paste] size [Conflict]
- Fixed icon slots: Cut (left), Copy (36DP from Cut), Paste (right), Conflict (rightmost)
- Region.H computed dynamically based on filename expansion

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 15:02:00 -04:00
fdb51810f4 Add Android IME bridge via Fragment section to touch.md
- Fragment registration pattern from Passgo: app.ViewEvent → GioView → Context → Activity → FragmentManager
- IME Fragment architecture: hidden EditText in transparent Fragment overlay
- Two-way sync: Gio→EditText (cursor sync via setSelection), EditText→Gio (IME events via TextWatcher + JNI callback)
- Text window management: ±1KB around cursor, updated on cursor move and text changes
- IME feature support: autocorrect, swipe typing, voice, predictions, emoji, CJK composition
- Event merging: Main goroutine drains JNI callback channel alongside w.Event() calls
- Implementation notes: impl_android.go, jni_android.c, ime/ImeFragment.java

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 14:39:11 -04:00
e4c5804170 Add touch and input handling specification (doc/touch.md)
- Gioui primitives: pointer.InputOp, key.InputOp, key.FocusOp, SoftKeyboardOp
- Op/Event flow: Logic computes elements, Renderer submits ops, Main batches events
- Coordinate mapping: UI space → text space → byte space, with hit-region tags
- Gesture state machine: tap, double-tap, long-press, drag-select, scroll
- Gesture disambiguation: timing thresholds (500ms long-press, 300ms double-tap, 16DP drag)
- Selection logic: selection_start/selection_end byte offsets
- Input batching: Main accumulates events, sends batch to Logic per frame
- Keyboard interaction: focus acquisition/loss, key event table, IME composition
- Scroll momentum: fling logic with exponential decay, scroll clamping

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 12:01:06 -04:00
8bd9376fa9 Correct runtime architecture: batched input, config channel, frame receiver logic
- Update block diagram to show correct channel/mutex flow
- Frame receiver now calls w.Invalidate() inside the mutex lock
- Logic goroutine now waits on batched []InputEvent and configChan
- Main loop batches events and sends outside the lock
- Remove select-with-default batching from logic

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 10:56:34 -04:00
f8f81b1fec Update architecture: input batching, priority workers, memory monitoring
- Add input batching to Logic goroutine via non-blocking select loop
- Add two-tier priority queue (high/low) to Worker pool
- Add §10 Memory Monitoring and Management (heap stats, debug page, future governor)
- Update diagram and channel topology to reflect new channels

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 10:10:06 -04:00
4b048b679e Add runtime architecture specification
- New doc/architecture.md: concurrency model, goroutine responsibilities,
  channel topology, deadlock analysis, sync/async partitioning
- Update SPEC.md §3: split into code organization + runtime architecture,
  cross-reference to architecture.md

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-08 08:24:04 -04:00
485fc59e06 Spec: resolve open design decisions
- Line index: cached on disk in .pad/indices/, invalidated by mtime/size,
  incremental updates during editing sessions
- Atomic writes: temp files live in .pad/tmp/, excluded from Syncthing via .stignore
- State storage: multi-file JSON approach (state.json, cursors.json, undo/*.json)
  over SQLite — simpler, debuggable, sufficient for expected workload
- Undo limits: 1 MB inline cap on deleted field; larger deletions stored in
  separate backup files; 10 MB total disk budget for undo directory
- Added search and word wrap sections to the editor spec
- Updated performance guarantees with search/jump targets
2026-05-07 20:23:24 -04:00
dfc112f5d4 Update specs to match Element interface implementation
- Element is an interface with Region() and Visible() methods
- Concrete types have unexported region/visible/id fields
- Constructors (NewLabel, NewListView) replace embedded Element struct
- Theme simplified to FontSize only
- Removed OnSelect/OnPress callback IDs from element types
- Added internal/ui/ to architecture in spec.md

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-07 18:19:54 -04:00
6720359360 Add Gioui scaffolding with Label and ListView rendering
- Element interface with Region() and Visible() methods
- Label and ListView element types with constructors
- Renderer that clips and draws elements in slice order
- Main app loop with Gioui window and frame events

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-05-07 17:45:56 -04:00
97d869db6c Initial commit: project specification 2026-05-07 12:24:15 -04:00