single border by default

This commit is contained in:
booleanmaybe 2026-04-19 10:13:18 -04:00
parent 8cc1614724
commit f377bb54dd
4 changed files with 16 additions and 116 deletions

View file

@ -8,6 +8,12 @@ import (
// NewApp creates a tview application.
func NewApp() *tview.Application {
tview.Borders.HorizontalFocus = tview.Borders.Horizontal
tview.Borders.VerticalFocus = tview.Borders.Vertical
tview.Borders.TopLeftFocus = tview.Borders.TopLeft
tview.Borders.TopRightFocus = tview.Borders.TopRight
tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft
tview.Borders.BottomRightFocus = tview.Borders.BottomRight
return tview.NewApplication()
}

View file

@ -1,56 +0,0 @@
package view
import (
"github.com/boolean-maybe/tiki/config"
"github.com/gdamore/tcell/v2"
)
// Single-line box drawing characters
const (
BorderHorizontal = '─'
BorderVertical = '│'
BorderTopLeft = '┌'
BorderTopRight = '┐'
BorderBottomLeft = '└'
BorderBottomRight = '┘'
)
// DrawSingleLineBorder draws a single-line border around the given rectangle
// using the TaskBoxUnselectedBorder color from config.
// This is useful for primitives that should not use tview's double-line focus borders.
func DrawSingleLineBorder(screen tcell.Screen, x, y, width, height int) {
if width <= 0 || height <= 0 {
return
}
colors := config.GetColors()
style := tcell.StyleDefault.Foreground(colors.TaskBoxUnselectedBorder.TCell()).Background(colors.ContentBackgroundColor.TCell())
DrawSingleLineBorderWithStyle(screen, x, y, width, height, style)
}
// DrawSingleLineBorderWithStyle draws a single-line border with a custom style
func DrawSingleLineBorderWithStyle(screen tcell.Screen, x, y, width, height int, style tcell.Style) {
if width <= 0 || height <= 0 {
return
}
// Draw horizontal lines
for i := x + 1; i < x+width-1; i++ {
screen.SetContent(i, y, BorderHorizontal, nil, style)
screen.SetContent(i, y+height-1, BorderHorizontal, nil, style)
}
// Draw vertical lines
for i := y + 1; i < y+height-1; i++ {
screen.SetContent(x, i, BorderVertical, nil, style)
screen.SetContent(x+width-1, i, BorderVertical, nil, style)
}
// Draw corners
screen.SetContent(x, y, BorderTopLeft, nil, style)
screen.SetContent(x+width-1, y, BorderTopRight, nil, style)
screen.SetContent(x, y+height-1, BorderBottomLeft, nil, style)
screen.SetContent(x+width-1, y+height-1, BorderBottomRight, nil, style)
}

View file

@ -9,7 +9,6 @@ import (
"github.com/boolean-maybe/tiki/controller"
"github.com/boolean-maybe/tiki/model"
"github.com/boolean-maybe/tiki/util"
"github.com/boolean-maybe/tiki/view"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
@ -35,32 +34,9 @@ type paletteRow struct {
label string
}
// singleBorderFlex wraps a tview.Flex to draw single-line borders instead of
// tview's default double-line borders on focus.
type singleBorderFlex struct {
*tview.Flex
}
func (f *singleBorderFlex) Draw(screen tcell.Screen) {
x, y, width, height := f.GetRect()
colors := config.GetColors()
bgStyle := tcell.StyleDefault.Background(colors.ContentBackgroundColor.TCell())
for row := y; row < y+height; row++ {
for col := x; col < x+width; col++ {
screen.SetContent(col, row, ' ', nil, bgStyle)
}
}
view.DrawSingleLineBorder(screen, x, y, width, height)
f.Flex.SetRect(x+1, y+1, width-2, height-2)
f.Flex.Draw(screen)
}
// ActionPalette is a modal overlay listing all available actions, filterable by fuzzy typing.
type ActionPalette struct {
root *singleBorderFlex
root *tview.Flex
filterInput *tview.InputField
listView *tview.TextView
hintView *tview.TextView
@ -121,14 +97,13 @@ func NewActionPalette(
mutedHex := colors.TaskDetailPlaceholderColor.Hex()
ap.hintView.SetText(fmt.Sprintf(" [%s]↑↓ Select ⏎ Run Esc Close", mutedHex))
// root layout — single-line border wrapper avoids tview's double-line focus borders
inner := tview.NewFlex().SetDirection(tview.FlexRow)
inner.SetBackgroundColor(colors.ContentBackgroundColor.TCell())
inner.SetBorder(false)
inner.AddItem(ap.filterInput, 1, 0, true)
inner.AddItem(ap.listView, 0, 1, false)
inner.AddItem(ap.hintView, 1, 0, false)
ap.root = &singleBorderFlex{Flex: inner}
ap.root = tview.NewFlex().SetDirection(tview.FlexRow)
ap.root.SetBackgroundColor(colors.ContentBackgroundColor.TCell())
ap.root.SetBorder(true)
ap.root.SetBorderColor(colors.TaskBoxUnselectedBorder.TCell())
ap.root.AddItem(ap.filterInput, 1, 0, true)
ap.root.AddItem(ap.listView, 0, 1, false)
ap.root.AddItem(ap.hintView, 1, 0, false)
// wire filter input to intercept all palette keys
ap.filterInput.SetInputCapture(ap.handleFilterInput)

View file

@ -19,12 +19,12 @@ func NewSearchBox() *SearchBox {
colors := config.GetColors()
inputField := tview.NewInputField()
// Configure the input field (border drawn manually in Draw)
inputField.SetLabel("> ")
inputField.SetLabelColor(colors.SearchBoxLabelColor.TCell())
inputField.SetFieldBackgroundColor(colors.ContentBackgroundColor.TCell())
inputField.SetFieldTextColor(colors.ContentTextColor.TCell())
inputField.SetBorder(false)
inputField.SetBorder(true)
inputField.SetBorderColor(colors.TaskBoxUnselectedBorder.TCell())
sb := &SearchBox{
InputField: inputField,
@ -51,31 +51,6 @@ func (sb *SearchBox) Clear() *SearchBox {
return sb
}
// Draw renders the search box with single-line borders
// (overrides InputField.Draw to avoid double-line focus borders)
func (sb *SearchBox) Draw(screen tcell.Screen) {
x, y, width, height := sb.GetRect()
if width <= 0 || height <= 0 {
return
}
// Fill interior with theme-aware background color
bgColor := config.GetColors().ContentBackgroundColor.TCell()
bgStyle := tcell.StyleDefault.Background(bgColor)
for row := y; row < y+height; row++ {
for col := x; col < x+width; col++ {
screen.SetContent(col, row, ' ', nil, bgStyle)
}
}
// Draw single-line border using shared utility
DrawSingleLineBorder(screen, x, y, width, height)
// Draw InputField inside border (offset by 1 for border)
sb.SetRect(x+1, y+1, width-2, height-2)
sb.InputField.Draw(screen)
}
// InputHandler handles key input for the search box
func (sb *SearchBox) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return sb.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {