Commit Graph

101 Commits

Author SHA1 Message Date
50e9ca5b34 Updates to rendering pipeline and documentation. 2026-05-25 17:40:35 -04:00
22c1d5bed1 fix: correct text layout and rendering pipeline
- Fix render.go: replace broken material.Label with shaper-based text
  rendering (LayoutString + Shape + glyph iteration) per Gio's paintGlyph
- Fix render.go: only apply clip rects at container boundaries; leaf
  elements have zero-size regions that were clipping all text out
- Fix render.go: call r.drawElement recursively for container children
  so nested containers work and clips are applied correctly
- Fix render.go: add drawLineText/drawLine helpers matching Gio's
  paintGlyph offset calculation (x + first.X, y + first.Y)
- Fix element.go: Button.Draw now uses r.drawText instead of duplicate
  broken material.Label code; Label defaults to black when color is unset
- Fix state.go: container children use relative coordinates instead of
  mixed screen-space/container-relative positions
- Fix main.go: ConfigEvent carries raw pixel dimensions only; ScaleEvent
  carries scale only; layout is computed once per frame using both,
  eliminating the infinite Invalidate() loop
2026-05-18 21:03:22 -04:00
8739bae517 refactor: unified Element interface with Draw method and Container type
- Add Draw(gtx, r *Renderer) to Element interface
- Add Container type that implements Element and holds []Element children
- Leaf types (Label, Icon, Button) implement Draw themselves
- Single recursive drawElement function in Renderer — no switch/case
- Remove StatusBar/BottomBar — replaced by Container
- Remove shaper.go — no longer needed with Gio material labels
- Simplify main.go — scale via ScaleProvider interface
- 5 files changed, shaper.go deleted
2026-05-18 11:25:43 -04:00
93a7a0a0b2 fix: remove duplicate scale storage, read from State via ScaleProvider interface
- Remove Renderer.scale field and SetScale method
- Add ScaleProvider interface to avoid editor/ui import cycle
- Add Scale() method to State, rename Scale field to scale
- Renderer reads scale through r.scale.Scale()
- Fix icons.go blank import preventing embed.FS usage
- Update main.go to pass State as ScaleProvider to Renderer
2026-05-17 10:59:29 -04:00
fa43bf2402 Add ShapeText/DrawShapedText: single shaper call, zero-call drawing
- New shaper.go: ShapeText() returns ShapedText with measured width +
  stored PathSpec + BitmapsCall, DrawShapedText() draws with zero shaper calls
- drawStatusBar: ShapeText for filename + right icons, positions from widths
- drawBottomBar: ShapeText for cursor/bytepos/wrap, positions by alignment
- No separate measureText helper: ShapeText.Width provides measurements
- StatusBar uses IconLeft/IconRow string slices for icon configuration
- BottomBar uses BarAlignment enum for item positioning
2026-05-12 12:06:28 -04:00
5da60ac9b3 Fix Y positioning. Expand status bar height. 2026-05-10 20:12:35 -04:00
dc4962a6c4 Fix icon Y positioning: offset by icon height to align bottom with baseline
- drawPng uses top-left corner, drawText uses baseline
- Icon bottom (Y=42) now aligns with baseline at Y=42
- Icon top is at Y=26 (42-16), occupies Y=26 to Y=42
2026-05-10 07:32:15 -04:00
1416e2db26 Move icon Y position from +20 to +32 DP below filename
- Icon was overlapping the first row of status bar
- Increased vertical spacing to avoid overlap
2026-05-10 07:14:20 -04:00
fdd1e841ae Use original iconY position (30 DP) without offset
- User confirmed icon showed up at this position
- Icon renders in second row of status bar as intended
2026-05-10 07:12:49 -04:00
28c7253622 Fix icon path and Y positioning
- Read icons/cut.png (not cut.png) to match embed directive
- Offset icon Y by iconSize so bottom aligns with text baseline
- drawText uses baseline positioning, drawPng uses top-left corner
2026-05-10 07:10:02 -04:00
f259145084 Fix icon Y positioning: offset by icon height to align bottom with baseline
- drawText positions glyphs by baseline, drawPng uses top-left corner
- Subtract iconSize from iconY so icon bottom aligns with text baseline
- Icon now renders within status bar instead of overlapping top
2026-05-10 07:03:43 -04:00
0ac2941802 Replace unicode cut icon with PNG icon in StatusBar
- Load cut.png from embedded filesystem
- drawStatusBar uses drawPng() for cut icon (16dp)
- No other files modified
2026-05-10 06:52:54 -04:00
106e91832a Add drawPng function to Renderer for PNG icon rendering
- Takes image.Image, position (x,y) in Dp, size (width,height) in Dp
- Tint color with alpha < 255 applies color overlay using clip.Rect
- Converts Dp to pixels using Renderer.toPx()
- Uses paint.NewImageOp for image rendering
2026-05-10 06:50:03 -04:00
fe3e7c3d75 Revert to last working state (68437c3) before PNG icon changes 2026-05-10 06:45:47 -04:00
1b1cf51528 Remove search/conflict icon references — only cut/copy/paste exist
- StatusBar now only draws cut, copy, paste PNG icons
- Removed code that tried to draw non-existent search.png and conflict.png
2026-05-10 06:39:22 -04:00
d2509123b0 Replace Unicode icons with PNG icons in StatusBar
- Move icons/ to internal/ui/icons/ for go:embed
- Renderer.loadIcons() loads PNGs from embedded filesystem
- drawStatusBar() uses drawPng() for cut/copy/paste/search/conflict icons
- Icons are 16dp, rendered from 48x48 PNGs (2x density)
2026-05-10 06:29:19 -04:00
14284afa73 Add drawPng function to Renderer for PNG icon rendering
- Takes image.Image, position (x,y) in Dp, size (width,height) in Dp
- Tint color with alpha < 255 applies color overlay using clip.Rect
- Converts Dp to pixels using Renderer.toPx()
- Uses paint.NewImageOp for image rendering
2026-05-10 06:26:29 -04:00
620d534454 Break import cycle: use StateReader interface instead of direct State reference
- StateReader interface in ui package (Scale(), ScreenWidth(), ScreenHeight())
- State implements StateReader
- Renderer reads scale/window size via interface, never imports editor
- State fields are private (screenWidth, screenHeight, scale) with accessor methods
- No SetScale/SetWindowSize calls from main.go — Renderer reads from State directly
2026-05-09 20:33:00 -04:00
21b4df59a3 Fix event flow: ConfigEvent sets size, FrameEvent sets scale only
- ConfigEvent: ONLY from app.ConfigEvent, sets width/height in State
- FrameEvent: gets scale from gtx.Metric.PxPerDp, sends ScaleEvent only if changed
- ScaleEvent: updates State.Scale
- Renderer reads windowW/windowH from State (SetWindowSize), not gtx.Constraints
- Renderer reads scale from State (SetScale), not gtx.Metric.PxPerDp
- main.go: ConfigEvent calls SetWindowSize, FrameEvent calls SetScale
2026-05-09 20:26:10 -04:00
68437c32a7 Store scale in State, use it everywhere instead of gtx.Metric.PxPerDp
- State.Scale stores the scale factor (default 1.0)
- ScaleEvent applies SetScale() which updates State.Scale
- Logic.Scale() accessor returns current scale
- Renderer.SetScale() updates renderer's scale from State
- main.go: uses logic.Scale() to get scale, calls renderer.SetScale()
- No more references to gtx.Metric.PxPerDp in render.go or main.go
2026-05-09 20:23:02 -04:00
ef31701d87 Unify ConfigEvent and ScaleEvent on single channel with type switch
- ConfigUpdate interface with apply(*State) method
- ConfigEvent and ScaleEvent both implement ConfigUpdate
- Logic.ConfigChan() accepts both types
- Type switch in Run() differentiates ConfigEvent vs ScaleEvent
- main.go sends both on same ConfigChan()
2026-05-09 20:10:06 -04:00
b581abb691 Redesign ConfigEvent/Scale handling: ConfigEvent sets size, FrameEvent updates scale
- Logic layer has separate ConfigChan and ScaleChan
- ConfigEvent: width/height in Dp, set on ConfigEvent
- ScaleEvent: scale factor, set on FrameEvent when scale changes
- Logic has ScreenSize() accessor for layout/rendering pipeline
- Logic has SetScale() to update scale and recompute layout
- main.go: ConfigEvent stores pixels, converts to DP using current scale
- main.go: FrameEvent gets actual scale, sends ScaleEvent if changed
2026-05-09 19:59:27 -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
4cf8641bbd Fix BottomBar X positioning to use visible window width 2026-05-09 18:01:24 -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
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
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
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
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
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
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