Split into category packages; module github.com/ZacharyZhang-NY/MujicaUI

This commit is contained in:
ZacharyZhang-NY committed 2026-10-05 16:18:48 -04:00
1 parent 5a7e921c7e
commit 22b53e9e9e
1822 files changed
+24568 -21314

No files matched your search

+128
View File
@@ -0,0 +1,128 @@
package agent
import (
"fmt"
"github.com/egoist/mygo/ui"
"github.com/ZacharyZhang-NY/MujicaUI/core"
"github.com/ZacharyZhang-NY/MujicaUI/icons"
"github.com/ZacharyZhang-NY/MujicaUI/internal"
"github.com/ZacharyZhang-NY/MujicaUI/theme"
)
// FileChange is a proposed edit; empty Old adds a file.
type FileChange struct {
Path string
Old, New string
}
// FileDecision is a review state; zero is FilePending.
type FileDecision int
const (
FilePending FileDecision = iota
FileAccepted
FileRejected
)
// agentDiffCache holds a change's line diff until its text changes.
type agentDiffCache struct {
old, new string
lines []internal.DiffLine
add, del int
firstEdit int
done bool
}
func (dc *agentDiffCache) update(ch FileChange) {
if dc.done && dc.old == ch.Old && dc.new == ch.New {
return
}
dc.old, dc.new, dc.done = ch.Old, ch.New, true
dc.lines = internal.LineDiff(internal.SplitLines(ch.Old), internal.SplitLines(ch.New))
dc.add, dc.del = internal.DiffStats(dc.lines)
dc.firstEdit = 0
for i, l := range dc.lines {
if l.Op != internal.DiffEqual {
dc.firstEdit = i
break
}
}
}
// agentDiffOf returns the cached diff of ch kept on holder.
func agentDiffOf(holder *ui.Element, ch FileChange) *agentDiffCache {
dc := ui.Local(holder, "mujica.agent.diff", func() *agentDiffCache { return &agentDiffCache{} })
(*dc).update(ch)
return *dc
}
// agentDiffStats shows signed added and removed counts.
func agentDiffStats(c *ui.Context, add, del int) {
k := core.Tokens(c)
size := core.FontSize(c, theme.CaptionSize+1)
ui.Row(c).Gap(core.Density(c).Unit() * 1.5).Shrink(0).Label(fmt.Sprintf(core.Msg(c, "file_change_card.stats"), add, del)).Children(func() {
ui.Text(c, fmt.Sprintf("+%d", add)).TextColor(k.Success).FontSize(size).Font(theme.MonoFont)
ui.Text(c, fmt.Sprintf("−%d", del)).TextColor(k.Danger).FontSize(size).Font(theme.MonoFont)
})
}
// agentDiffRow draws one numbered, signed, tinted diff line.
func agentDiffRow(c *ui.Context, l internal.DiffLine) {
k := core.Tokens(c)
u := core.Density(c).Unit()
sign, bg, fg := " ", ui.Transparent, k.TextMuted
switch l.Op {
case internal.DiffInsert:
sign, bg, fg = "+", k.Success.Alpha(0.14), k.Success
case internal.DiffDelete:
sign, bg, fg = "−", k.Danger.Alpha(0.14), k.Danger
}
num := func(n int) string {
if n == 0 {
return ""
}
return fmt.Sprint(n)
}
ui.Row(c).Gap(u*2).Background(bg).Padding(0, u).Children(func() {
ui.Text(c, num(l.Old)).Width(36).TextAlign(ui.End).TextColor(k.TextMuted).Shrink(0)
ui.Text(c, num(l.New)).Width(36).TextAlign(ui.End).TextColor(k.TextMuted).Shrink(0)
ui.Text(c, sign).TextColor(fg).Width(10).Shrink(0)
text := l.Text
if text == "" {
text = " "
}
ui.Text(c, text).Grow(1).Shrink(1)
})
}
// agentDiffView shows lines[from:to] in a capped well, virtualized when long.
func agentDiffView(c *ui.Context, lines []internal.DiffLine, maxHeight float32) *ui.Element {
w := AgentWellRows(c, len(lines), func(i int) { agentDiffRow(c, lines[i]) }, maxHeight)
return w.Padding(core.Density(c).Unit(), 0)
}
// agentDecisionMark shows a decision by icon and word.
func agentDecisionMark(c *ui.Context, d FileDecision) {
ui.Row(c).Gap(core.Density(c).Unit()).AlignItems(ui.Center).Shrink(0).Children(func() {
AgentCaption(c, agentDecisionIcon(c, d))
})
}
// agentDecisionIcon draws a named decision icon, returning its word.
func agentDecisionIcon(c *ui.Context, d FileDecision) string {
k := core.Tokens(c)
tone, icon, word := k.TextMuted, "circle", core.Msg(c, "file_change_card.pending")
switch d {
case FileAccepted:
tone, icon, word = k.Success, "circle-check", core.Msg(c, "file_change_card.accepted")
case FileRejected:
tone, icon, word = k.Danger, "circle-x", core.Msg(c, "file_change_card.rejected")
case FilePending:
default:
panic(fmt.Sprintf("mujica: unknown FileDecision %d", int(d)))
}
ui.Icon(c, icons.Must(icon)).Size(14, 14).TextColor(tone).Shrink(0).Label(word)
return word
}