fix: cream background on every style, warm highlight on cursor row
Every Lip Gloss style now has Background(ScreenBg) so ANSI sequences carry the cream color inherently. Previously only PadLine added bg to padding spaces, but inner escape codes reset the background. All spacing between styled segments uses bg()/wbg() helpers. Cursor row elements use Background(Warm) for highlight.
This commit is contained in:
+47
-18
@@ -57,6 +57,11 @@ func CategoryColor(cat string) color.Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ─── Reusable styles ─────────────────────────────────────────
|
// ─── Reusable styles ─────────────────────────────────────────
|
||||||
|
//
|
||||||
|
// IMPORTANT: Every style MUST have Background(ScreenBg) so the cream
|
||||||
|
// background propagates through all ANSI sequences. Wrapping
|
||||||
|
// already-styled text with a background style does NOT work because
|
||||||
|
// inner escape sequences reset the background.
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Title bar
|
// Title bar
|
||||||
@@ -69,44 +74,53 @@ var (
|
|||||||
// Header / breadcrumb
|
// Header / breadcrumb
|
||||||
Breadcrumb = lipgloss.NewStyle().
|
Breadcrumb = lipgloss.NewStyle().
|
||||||
Foreground(Mid).
|
Foreground(Mid).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(false)
|
Bold(false)
|
||||||
|
|
||||||
BreadcrumbActive = lipgloss.NewStyle().
|
BreadcrumbActive = lipgloss.NewStyle().
|
||||||
Foreground(Dark).
|
Foreground(Dark).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
|
|
||||||
// File row
|
// File row
|
||||||
FileName = lipgloss.NewStyle().
|
FileName = lipgloss.NewStyle().
|
||||||
Foreground(Dark).
|
Foreground(Dark).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
|
|
||||||
FileSize = lipgloss.NewStyle().
|
FileSize = lipgloss.NewStyle().
|
||||||
Foreground(Light)
|
Foreground(Light).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
ExtBadge = func(c color.Color) lipgloss.Style {
|
ExtBadge = func(c color.Color) lipgloss.Style {
|
||||||
return lipgloss.NewStyle().
|
return lipgloss.NewStyle().
|
||||||
Foreground(c).
|
Foreground(c).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status indicators
|
// Status indicators
|
||||||
StatusIdle = lipgloss.NewStyle().
|
StatusIdle = lipgloss.NewStyle().
|
||||||
Foreground(Light).
|
Foreground(Light).
|
||||||
|
Background(ScreenBg).
|
||||||
Italic(true)
|
Italic(true)
|
||||||
|
|
||||||
StatusConverting = lipgloss.NewStyle().
|
StatusConverting = lipgloss.NewStyle().
|
||||||
Foreground(Pink).
|
Foreground(Pink).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
|
|
||||||
StatusDone = lipgloss.NewStyle().
|
StatusDone = lipgloss.NewStyle().
|
||||||
Foreground(Mint).
|
Foreground(Mint).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
|
|
||||||
StatusError = lipgloss.NewStyle().
|
StatusError = lipgloss.NewStyle().
|
||||||
Foreground(Red).
|
Foreground(Red).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
|
|
||||||
// Buttons / actions
|
// Buttons / actions (these keep their own bg colors)
|
||||||
ButtonPrimary = lipgloss.NewStyle().
|
ButtonPrimary = lipgloss.NewStyle().
|
||||||
Foreground(lipgloss.Color("#ffffff")).
|
Foreground(lipgloss.Color("#ffffff")).
|
||||||
Background(Pink).
|
Background(Pink).
|
||||||
@@ -121,50 +135,67 @@ var (
|
|||||||
|
|
||||||
// Progress bar
|
// Progress bar
|
||||||
ProgressFilled = lipgloss.NewStyle().
|
ProgressFilled = lipgloss.NewStyle().
|
||||||
Foreground(Pink)
|
Foreground(Pink).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
ProgressEmpty = lipgloss.NewStyle().
|
ProgressEmpty = lipgloss.NewStyle().
|
||||||
Foreground(BorderCl)
|
Foreground(BorderCl).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
// Help / footer
|
// Help / footer
|
||||||
Help = lipgloss.NewStyle().
|
Help = lipgloss.NewStyle().
|
||||||
Foreground(Light).
|
Foreground(Light).
|
||||||
|
Background(ScreenBg).
|
||||||
Italic(true)
|
Italic(true)
|
||||||
|
|
||||||
// Cursor / selection
|
// Cursor / selection
|
||||||
Selected = lipgloss.NewStyle().
|
Selected = lipgloss.NewStyle().
|
||||||
Bold(true).
|
Bold(true).
|
||||||
Foreground(Pink)
|
Foreground(Pink).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
Unselected = lipgloss.NewStyle().
|
Unselected = lipgloss.NewStyle().
|
||||||
Foreground(Dark)
|
Foreground(Dark).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
// Divider
|
// Divider
|
||||||
Divider = lipgloss.NewStyle().
|
Divider = lipgloss.NewStyle().
|
||||||
Foreground(BorderCl)
|
Foreground(BorderCl).
|
||||||
|
Background(ScreenBg)
|
||||||
|
|
||||||
// Logo / branding
|
// Logo / branding
|
||||||
Logo = lipgloss.NewStyle().
|
Logo = lipgloss.NewStyle().
|
||||||
Foreground(Pink).
|
Foreground(Pink).
|
||||||
|
Background(ScreenBg).
|
||||||
Bold(true)
|
Bold(true)
|
||||||
)
|
)
|
||||||
|
|
||||||
// PadLine pads a single rendered line to the full terminal width and applies
|
// BgStyle returns a plain style with just the cream background, useful
|
||||||
// the cream background behind ALL content (not just the padding). This is
|
// for spacing characters that need to carry the background color.
|
||||||
// achieved by placing the line inside a full-width style with Background set.
|
var BgStyle = lipgloss.NewStyle().Background(ScreenBg)
|
||||||
|
|
||||||
|
// WarmBgStyle returns a plain style with the warm highlight background.
|
||||||
|
var WarmBgStyle = lipgloss.NewStyle().Background(Warm)
|
||||||
|
|
||||||
|
// PadLine pads a single rendered line to the full terminal width with
|
||||||
|
// cream background spaces on the right edge.
|
||||||
func PadLine(line string, width int) string {
|
func PadLine(line string, width int) string {
|
||||||
return PadLineWithBg(line, width, ScreenBg)
|
w := lipgloss.Width(line)
|
||||||
|
if w >= width {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
pad := BgStyle.Render(strings.Repeat(" ", width-w))
|
||||||
|
return line + pad
|
||||||
}
|
}
|
||||||
|
|
||||||
// PadLineWithBg pads a line to full width with a specific background color.
|
// PadLineWithBg pads a line to full width with a specific background color.
|
||||||
func PadLineWithBg(line string, width int, bg color.Color) string {
|
func PadLineWithBg(line string, width int, bg color.Color) string {
|
||||||
w := lipgloss.Width(line)
|
w := lipgloss.Width(line)
|
||||||
if w >= width {
|
if w >= width {
|
||||||
// Even if the line is already wide enough, wrap with background
|
return line
|
||||||
return lipgloss.NewStyle().Background(bg).Render(line)
|
|
||||||
}
|
}
|
||||||
pad := strings.Repeat(" ", width-w)
|
pad := lipgloss.NewStyle().Background(bg).Render(strings.Repeat(" ", width-w))
|
||||||
return lipgloss.NewStyle().Background(bg).Render(line + pad)
|
return line + pad
|
||||||
}
|
}
|
||||||
|
|
||||||
// FillBlankLines returns n blank lines fully painted with the screen
|
// FillBlankLines returns n blank lines fully painted with the screen
|
||||||
@@ -173,9 +204,7 @@ func FillBlankLines(n, width int) string {
|
|||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
blankLine := lipgloss.NewStyle().
|
blankLine := BgStyle.Render(strings.Repeat(" ", width))
|
||||||
Background(ScreenBg).
|
|
||||||
Render(strings.Repeat(" ", width))
|
|
||||||
lines := make([]string, n)
|
lines := make([]string, n)
|
||||||
for i := range lines {
|
for i := range lines {
|
||||||
lines[i] = blankLine
|
lines[i] = blankLine
|
||||||
|
|||||||
+118
-43
@@ -21,6 +21,16 @@ const (
|
|||||||
colGap = 2 // gap between columns
|
colGap = 2 // gap between columns
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// bg renders spacing text with the cream background.
|
||||||
|
func bg(s string) string {
|
||||||
|
return theme.BgStyle.Render(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// wbg renders spacing text with the warm highlight background.
|
||||||
|
func wbg(s string) string {
|
||||||
|
return theme.WarmBgStyle.Render(s)
|
||||||
|
}
|
||||||
|
|
||||||
// nameWidth calculates the flexible Name column width.
|
// nameWidth calculates the flexible Name column width.
|
||||||
func nameWidth(termW int) int {
|
func nameWidth(termW int) int {
|
||||||
fixed := colCursor + colCheck + colSize + colFormat + colStatus + colGap*3
|
fixed := colCursor + colCheck + colSize + colFormat + colStatus + colGap*3
|
||||||
@@ -31,7 +41,7 @@ func nameWidth(termW int) int {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
// pad is a shortcut that pads a line to full width with cream background.
|
// pad pads a line to full width with cream background.
|
||||||
func (m Model) pad(line string) string {
|
func (m Model) pad(line string) string {
|
||||||
return theme.PadLine(line, m.width)
|
return theme.PadLine(line, m.width)
|
||||||
}
|
}
|
||||||
@@ -43,7 +53,7 @@ func (m Model) padWarm(line string) string {
|
|||||||
|
|
||||||
// blank returns a full-width blank line with cream background.
|
// blank returns a full-width blank line with cream background.
|
||||||
func (m Model) blank() string {
|
func (m Model) blank() string {
|
||||||
return theme.PadLine("", m.width)
|
return theme.BgStyle.Render(strings.Repeat(" ", m.width))
|
||||||
}
|
}
|
||||||
|
|
||||||
// View renders the entire TUI, filling the full terminal.
|
// View renders the entire TUI, filling the full terminal.
|
||||||
@@ -100,10 +110,8 @@ func (m Model) View() string {
|
|||||||
// Calculate how many blank lines we need between content and bottom bar
|
// Calculate how many blank lines we need between content and bottom bar
|
||||||
totalUsed := len(lines) + len(bottomLines)
|
totalUsed := len(lines) + len(bottomLines)
|
||||||
remaining := m.height - totalUsed
|
remaining := m.height - totalUsed
|
||||||
if remaining > 0 {
|
for i := 0; i < remaining; i++ {
|
||||||
for i := 0; i < remaining; i++ {
|
lines = append(lines, m.blank())
|
||||||
lines = append(lines, m.blank())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append bottom bar lines
|
// Append bottom bar lines
|
||||||
@@ -121,7 +129,6 @@ func (m Model) View() string {
|
|||||||
|
|
||||||
func (m Model) renderTitleBar() string {
|
func (m Model) renderTitleBar() string {
|
||||||
title := theme.Logo.Render("transmute")
|
title := theme.Logo.Render("transmute")
|
||||||
|
|
||||||
fileCount := fmt.Sprintf("%d files", len(m.files))
|
fileCount := fmt.Sprintf("%d files", len(m.files))
|
||||||
selected := 0
|
selected := 0
|
||||||
for _, f := range m.files {
|
for _, f := range m.files {
|
||||||
@@ -131,14 +138,14 @@ func (m Model) renderTitleBar() string {
|
|||||||
}
|
}
|
||||||
info := theme.Breadcrumb.Render(fmt.Sprintf(" %s \u00B7 %d selected", fileCount, selected))
|
info := theme.Breadcrumb.Render(fmt.Sprintf(" %s \u00B7 %d selected", fileCount, selected))
|
||||||
|
|
||||||
left := " " + title + info
|
left := bg(" ") + title + info
|
||||||
rightContent := theme.Help.Render("? help") + " "
|
rightContent := theme.Help.Render("? help") + bg(" ")
|
||||||
gap := m.width - lipgloss.Width(left) - lipgloss.Width(rightContent)
|
gap := m.width - lipgloss.Width(left) - lipgloss.Width(rightContent)
|
||||||
if gap < 1 {
|
if gap < 1 {
|
||||||
gap = 1
|
gap = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return left + strings.Repeat(" ", gap) + rightContent
|
return left + bg(strings.Repeat(" ", gap)) + rightContent
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Divider ─────────────────────────────────────────────────
|
// ─── Divider ─────────────────────────────────────────────────
|
||||||
@@ -148,7 +155,7 @@ func (m Model) renderDivider() string {
|
|||||||
if w < 10 {
|
if w < 10 {
|
||||||
w = 10
|
w = 10
|
||||||
}
|
}
|
||||||
return " " + theme.Divider.Render(strings.Repeat("\u2500", w)) + " "
|
return bg(" ") + theme.Divider.Render(strings.Repeat("\u2500", w)) + bg(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Column header ───────────────────────────────────────────
|
// ─── Column header ───────────────────────────────────────────
|
||||||
@@ -162,7 +169,7 @@ func (m Model) renderColumnHeader() string {
|
|||||||
fmtHdr := theme.Breadcrumb.Copy().Width(colFormat).Align(lipgloss.Center).Render("Convert to")
|
fmtHdr := theme.Breadcrumb.Copy().Width(colFormat).Align(lipgloss.Center).Render("Convert to")
|
||||||
statHdr := theme.Breadcrumb.Copy().Width(colStatus).Align(lipgloss.Center).Render("Status")
|
statHdr := theme.Breadcrumb.Copy().Width(colStatus).Align(lipgloss.Center).Render("Status")
|
||||||
|
|
||||||
return nameHdr + " " + sizeHdr + " " + fmtHdr + " " + statHdr
|
return nameHdr + bg(" ") + sizeHdr + bg(" ") + fmtHdr + bg(" ") + statHdr
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── File rows ───────────────────────────────────────────────
|
// ─── File rows ───────────────────────────────────────────────
|
||||||
@@ -172,6 +179,7 @@ func (m Model) renderFileRows() []string {
|
|||||||
if len(m.files) == 0 {
|
if len(m.files) == 0 {
|
||||||
empty := lipgloss.NewStyle().
|
empty := lipgloss.NewStyle().
|
||||||
Foreground(theme.Light).
|
Foreground(theme.Light).
|
||||||
|
Background(theme.ScreenBg).
|
||||||
Italic(true).
|
Italic(true).
|
||||||
Render(" No supported files found. Pass file paths or glob patterns as arguments.")
|
Render(" No supported files found. Pass file paths or glob patterns as arguments.")
|
||||||
return []string{m.blank(), m.pad(empty), m.blank()}
|
return []string{m.blank(), m.pad(empty), m.blank()}
|
||||||
@@ -185,8 +193,8 @@ func (m Model) renderFileRows() []string {
|
|||||||
|
|
||||||
var rows []string
|
var rows []string
|
||||||
for i := m.scroll; i < end; i++ {
|
for i := m.scroll; i < end; i++ {
|
||||||
row := m.renderFileRow(i)
|
|
||||||
isCursor := i == m.cursor
|
isCursor := i == m.cursor
|
||||||
|
row := m.renderFileRow(i)
|
||||||
if isCursor {
|
if isCursor {
|
||||||
rows = append(rows, m.padWarm(row))
|
rows = append(rows, m.padWarm(row))
|
||||||
} else {
|
} else {
|
||||||
@@ -209,22 +217,44 @@ func (m Model) renderFileRow(idx int) string {
|
|||||||
isCursor := idx == m.cursor
|
isCursor := idx == m.cursor
|
||||||
nw := nameWidth(m.width)
|
nw := nameWidth(m.width)
|
||||||
|
|
||||||
// ── Cursor indicator ──
|
// Choose background helper based on whether this is the cursor row
|
||||||
cursor := " "
|
sp := bg
|
||||||
if isCursor {
|
if isCursor {
|
||||||
cursor = " " + theme.Selected.Render(">") + " "
|
sp = wbg
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Cursor indicator ──
|
||||||
|
cursor := sp(" ")
|
||||||
|
if isCursor {
|
||||||
|
cursor = sp(" ") + theme.Selected.Copy().Background(theme.Warm).Render(">") + sp(" ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Selection dot ──
|
// ── Selection dot ──
|
||||||
check := theme.Breadcrumb.Render("\u25CB") + " " // ○
|
var check string
|
||||||
if f.selected {
|
if f.selected {
|
||||||
check = theme.StatusDone.Render("\u25CF") + " " // ● (mint)
|
if isCursor {
|
||||||
|
check = theme.StatusDone.Copy().Background(theme.Warm).Render("\u25CF") + sp(" ")
|
||||||
|
} else {
|
||||||
|
check = theme.StatusDone.Render("\u25CF") + sp(" ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if isCursor {
|
||||||
|
check = theme.Breadcrumb.Copy().Background(theme.Warm).Render("\u25CB") + sp(" ")
|
||||||
|
} else {
|
||||||
|
check = theme.Breadcrumb.Render("\u25CB") + sp(" ")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Icon + ext badge + filename ──
|
// ── Icon + ext badge + filename ──
|
||||||
icon := detect.CategoryIcon(f.category)
|
icon := detect.CategoryIcon(f.category)
|
||||||
catColor := theme.CategoryColor(string(f.category))
|
catColor := theme.CategoryColor(string(f.category))
|
||||||
extBadge := theme.ExtBadge(catColor).Render(strings.ToUpper(f.ext))
|
|
||||||
|
var extBadge string
|
||||||
|
if isCursor {
|
||||||
|
extBadge = theme.ExtBadge(catColor).Background(theme.Warm).Render(strings.ToUpper(f.ext))
|
||||||
|
} else {
|
||||||
|
extBadge = theme.ExtBadge(catColor).Render(strings.ToUpper(f.ext))
|
||||||
|
}
|
||||||
|
|
||||||
nameText := f.name
|
nameText := f.name
|
||||||
maxName := nw - 10
|
maxName := nw - 10
|
||||||
@@ -237,55 +267,100 @@ func (m Model) renderFileRow(idx int) string {
|
|||||||
|
|
||||||
var nameStyle lipgloss.Style
|
var nameStyle lipgloss.Style
|
||||||
if isCursor {
|
if isCursor {
|
||||||
nameStyle = theme.FileName.Copy().Bold(true)
|
nameStyle = theme.FileName.Copy().Background(theme.Warm).Bold(true)
|
||||||
} else {
|
} else {
|
||||||
nameStyle = theme.FileName
|
nameStyle = theme.FileName
|
||||||
}
|
}
|
||||||
|
|
||||||
nameContent := icon + " " + extBadge + " " + nameStyle.Render(nameText)
|
nameContent := sp(icon+" ") + extBadge + sp(" ") + nameStyle.Render(nameText)
|
||||||
nameCell := lipgloss.NewStyle().Width(nw).MaxWidth(nw).Render(nameContent)
|
var nameCellStyle lipgloss.Style
|
||||||
|
if isCursor {
|
||||||
|
nameCellStyle = lipgloss.NewStyle().Width(nw).MaxWidth(nw).Background(theme.Warm)
|
||||||
|
} else {
|
||||||
|
nameCellStyle = lipgloss.NewStyle().Width(nw).MaxWidth(nw).Background(theme.ScreenBg)
|
||||||
|
}
|
||||||
|
nameCell := nameCellStyle.Render(nameContent)
|
||||||
|
|
||||||
// ── Size ──
|
// ── Size ──
|
||||||
sizeCell := theme.FileSize.Copy().Width(colSize).Align(lipgloss.Right).Render(formatSize(f.size))
|
var sizeCell string
|
||||||
|
if isCursor {
|
||||||
|
sizeCell = theme.FileSize.Copy().Background(theme.Warm).Width(colSize).Align(lipgloss.Right).Render(formatSize(f.size))
|
||||||
|
} else {
|
||||||
|
sizeCell = theme.FileSize.Copy().Width(colSize).Align(lipgloss.Right).Render(formatSize(f.size))
|
||||||
|
}
|
||||||
|
|
||||||
// ── Format selector ──
|
// ── Format selector ──
|
||||||
fmtStr := renderFormatSelector(f, isCursor)
|
fmtStr := renderFormatSelector(f, isCursor)
|
||||||
fmtCell := lipgloss.NewStyle().Width(colFormat).Align(lipgloss.Center).Render(fmtStr)
|
var fmtCell string
|
||||||
|
if isCursor {
|
||||||
|
fmtCell = lipgloss.NewStyle().Width(colFormat).Align(lipgloss.Center).Background(theme.Warm).Render(fmtStr)
|
||||||
|
} else {
|
||||||
|
fmtCell = lipgloss.NewStyle().Width(colFormat).Align(lipgloss.Center).Background(theme.ScreenBg).Render(fmtStr)
|
||||||
|
}
|
||||||
|
|
||||||
// ── Status ──
|
// ── Status ──
|
||||||
var statusStr string
|
var statusStr string
|
||||||
switch f.status {
|
switch f.status {
|
||||||
case "idle":
|
case "idle":
|
||||||
statusStr = theme.StatusIdle.Render("idle")
|
if isCursor {
|
||||||
|
statusStr = theme.StatusIdle.Copy().Background(theme.Warm).Render("idle")
|
||||||
|
} else {
|
||||||
|
statusStr = theme.StatusIdle.Render("idle")
|
||||||
|
}
|
||||||
case "converting":
|
case "converting":
|
||||||
statusStr = theme.StatusConverting.Render("converting...")
|
if isCursor {
|
||||||
|
statusStr = theme.StatusConverting.Copy().Background(theme.Warm).Render("converting...")
|
||||||
|
} else {
|
||||||
|
statusStr = theme.StatusConverting.Render("converting...")
|
||||||
|
}
|
||||||
case "done":
|
case "done":
|
||||||
statusStr = theme.StatusDone.Render("done")
|
if isCursor {
|
||||||
|
statusStr = theme.StatusDone.Copy().Background(theme.Warm).Render("done")
|
||||||
|
} else {
|
||||||
|
statusStr = theme.StatusDone.Render("done")
|
||||||
|
}
|
||||||
case "error":
|
case "error":
|
||||||
statusStr = theme.StatusError.Render("error")
|
if isCursor {
|
||||||
|
statusStr = theme.StatusError.Copy().Background(theme.Warm).Render("error")
|
||||||
|
} else {
|
||||||
|
statusStr = theme.StatusError.Render("error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var statusCell string
|
||||||
|
if isCursor {
|
||||||
|
statusCell = lipgloss.NewStyle().Width(colStatus).Align(lipgloss.Center).Background(theme.Warm).Render(statusStr)
|
||||||
|
} else {
|
||||||
|
statusCell = lipgloss.NewStyle().Width(colStatus).Align(lipgloss.Center).Background(theme.ScreenBg).Render(statusStr)
|
||||||
}
|
}
|
||||||
statusCell := lipgloss.NewStyle().Width(colStatus).Align(lipgloss.Center).Render(statusStr)
|
|
||||||
|
|
||||||
return cursor + check + nameCell + " " + sizeCell + " " + fmtCell + " " + statusCell
|
return cursor + check + nameCell + sp(" ") + sizeCell + sp(" ") + fmtCell + sp(" ") + statusCell
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderFormatSelector(f fileEntry, active bool) string {
|
func renderFormatSelector(f fileEntry, active bool) string {
|
||||||
if len(f.formats) == 0 {
|
if len(f.formats) == 0 {
|
||||||
|
if active {
|
||||||
|
return theme.Help.Copy().Background(theme.Warm).Render("\u2014")
|
||||||
|
}
|
||||||
return theme.Help.Render("\u2014")
|
return theme.Help.Render("\u2014")
|
||||||
}
|
}
|
||||||
|
|
||||||
left := " "
|
sp := bg
|
||||||
right := " "
|
if active {
|
||||||
|
sp = wbg
|
||||||
|
}
|
||||||
|
|
||||||
|
left := sp(" ")
|
||||||
|
right := sp(" ")
|
||||||
if active && f.formatIdx > 0 {
|
if active && f.formatIdx > 0 {
|
||||||
left = theme.Help.Render("< ")
|
left = theme.Help.Copy().Background(theme.Warm).Render("< ")
|
||||||
}
|
}
|
||||||
if active && f.formatIdx < len(f.formats)-1 {
|
if active && f.formatIdx < len(f.formats)-1 {
|
||||||
right = theme.Help.Render(" >")
|
right = theme.Help.Copy().Background(theme.Warm).Render(" >")
|
||||||
}
|
}
|
||||||
|
|
||||||
var middle string
|
var middle string
|
||||||
if active {
|
if active {
|
||||||
middle = theme.Selected.Render(f.targetFormat)
|
middle = theme.Selected.Copy().Background(theme.Warm).Render(f.targetFormat)
|
||||||
} else {
|
} else {
|
||||||
middle = theme.Unselected.Render(f.targetFormat)
|
middle = theme.Unselected.Render(f.targetFormat)
|
||||||
}
|
}
|
||||||
@@ -305,19 +380,19 @@ func (m Model) renderBottomBar() string {
|
|||||||
|
|
||||||
var left string
|
var left string
|
||||||
if selected > 0 {
|
if selected > 0 {
|
||||||
left = " " + theme.ButtonPrimary.Render(fmt.Sprintf(" Convert %d files [c] ", selected))
|
left = bg(" ") + theme.ButtonPrimary.Render(fmt.Sprintf(" Convert %d files [c] ", selected))
|
||||||
} else {
|
} else {
|
||||||
left = " " + theme.Help.Render("Select files to convert")
|
left = bg(" ") + theme.Help.Render("Select files to convert")
|
||||||
}
|
}
|
||||||
|
|
||||||
right := theme.Help.Render("up/down navigate left/right format space select a all q quit") + " "
|
right := theme.Help.Render("up/down navigate left/right format space select a all q quit") + bg(" ")
|
||||||
|
|
||||||
gap := m.width - lipgloss.Width(left) - lipgloss.Width(right)
|
gap := m.width - lipgloss.Width(left) - lipgloss.Width(right)
|
||||||
if gap < 1 {
|
if gap < 1 {
|
||||||
gap = 1
|
gap = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return left + strings.Repeat(" ", gap) + right
|
return left + bg(strings.Repeat(" ", gap)) + right
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Converting view ─────────────────────────────────────────
|
// ─── Converting view ─────────────────────────────────────────
|
||||||
@@ -339,7 +414,7 @@ func (m Model) renderConverting() string {
|
|||||||
filled = barWidth
|
filled = barWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
bar := " " +
|
bar := bg(" ") +
|
||||||
theme.ProgressFilled.Render(strings.Repeat("\u2588", filled)) +
|
theme.ProgressFilled.Render(strings.Repeat("\u2588", filled)) +
|
||||||
theme.ProgressEmpty.Render(strings.Repeat("\u2591", barWidth-filled))
|
theme.ProgressEmpty.Render(strings.Repeat("\u2591", barWidth-filled))
|
||||||
|
|
||||||
@@ -440,9 +515,9 @@ func (m Model) renderHelp() string {
|
|||||||
lines = append(lines, "")
|
lines = append(lines, "")
|
||||||
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
lines = append(lines, fmt.Sprintf(" %s %s",
|
lines = append(lines, bg(" ")+
|
||||||
theme.Selected.Copy().Width(18).Render(k.key),
|
theme.Selected.Copy().Width(18).Render(k.key)+bg(" ")+
|
||||||
theme.Help.Render(k.desc)))
|
theme.Help.Render(k.desc))
|
||||||
}
|
}
|
||||||
lines = append(lines, "")
|
lines = append(lines, "")
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// CurrentVersion is the embedded build version. Updated at release time.
|
// CurrentVersion is the embedded build version. Updated at release time.
|
||||||
CurrentVersion = "0.1.1"
|
CurrentVersion = "0.1.2"
|
||||||
|
|
||||||
repoOwner = "noauf"
|
repoOwner = "noauf"
|
||||||
repoName = "Transmute"
|
repoName = "Transmute"
|
||||||
|
|||||||
Reference in New Issue
Block a user