Skip to content

Commit

Permalink
fix: fix displaying overlays
Browse files Browse the repository at this point in the history
  • Loading branch information
jackMort committed Nov 8, 2024
1 parent 1ad8657 commit be162a8
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 12 deletions.
2 changes: 1 addition & 1 deletion components/collections/collections.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var (
minified = lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(config.COLOR_SUBTLE).
Foreground(config.COLOR_FOREGROUND).
Foreground(config.COLOR_GRAY).
PaddingLeft(1)

focused = lipgloss.NewStyle().
Expand Down
9 changes: 8 additions & 1 deletion components/collections/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package collections
import (
"restman/app"
"restman/components/config"
"restman/components/overlay"
"restman/components/popup"
"restman/utils"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
Expand Down Expand Up @@ -38,6 +40,7 @@ type Create struct {
inputs []textinput.Model
focused int
err error
bgRaw string
}

func NewCreate(bgRaw string, width int) Create {
Expand All @@ -52,6 +55,7 @@ func NewCreate(bgRaw string, width int) Create {
inputs[BASE_URL_IDX].Prompt = ""

return Create{
bgRaw: bgRaw,
overlay: popup.NewOverlay(bgRaw, width, 13),
inputs: inputs,
focused: 0,
Expand Down Expand Up @@ -156,7 +160,10 @@ func (c Create) View() string {
ui := lipgloss.JoinVertical(lipgloss.Left, header, " ", inputs)
dialog := lipgloss.Place(c.overlay.Width()-2, c.overlay.Height()-2, lipgloss.Left, lipgloss.Top, ui)

return c.overlay.WrapView(general.Render(dialog))
content := general.Render(dialog)

startCol, startRow := utils.GetStartColRow(content, c.bgRaw)
return overlay.PlaceOverlay(startCol, startRow, content, c.bgRaw)
}

func (c Create) makeChoice() tea.Cmd {
Expand Down
1 change: 1 addition & 0 deletions components/collections/delegate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func newItemDelegate(keys *delegateKeyMap) list.DefaultDelegate {
if len(m.Items()) == 0 {
keys.remove.SetEnabled(false)
}
// TODO: ask for confirmation
return app.GetInstance().RemoveCollection(i)
}
}
Expand Down
132 changes: 132 additions & 0 deletions components/overlay/overlay.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package overlay

import (
"bytes"
"strings"

"github.com/mattn/go-runewidth"
"github.com/muesli/ansi"
"github.com/muesli/reflow/truncate"
)

// Code borrowed and cut down from @mrusme and https://github.com/charmbracelet/lipgloss/pull/102

// Split a string into lines, additionally returning the size of the widest line.
func getLines(s string) (lines []string, widest int) {
lines = strings.Split(s, "\n")

for _, l := range lines {
w := ansi.PrintableRuneWidth(l)
if widest < w {
widest = w
}
}

return lines, widest
}

// PlaceOverlay places overlay on top of background.
func PlaceOverlay(x, y int, overlay, background string) string {
overlayLines, overlayWidth := getLines(overlay)
backgroundLines, backgroundWidth := getLines(background)
backgroundHeight := len(backgroundLines)
overlayHeight := len(overlayLines)

if overlayWidth >= backgroundWidth && overlayHeight >= backgroundHeight {
return overlay
}

x = clamp(x, 0, backgroundWidth-overlayWidth)
y = clamp(y, 0, backgroundHeight-overlayHeight)

var b strings.Builder
for i, backgroundLine := range backgroundLines {
if i > 0 {
b.WriteByte('\n')
}
if i < y || i >= y+overlayHeight {
b.WriteString(backgroundLine)
continue
}

pos := 0
if x > 0 {
left := truncate.String(backgroundLine, uint(x))
pos = ansi.PrintableRuneWidth(left)
b.WriteString(left)
if pos < x {
pos = x
}
}

overlayLine := overlayLines[i-y]
b.WriteString(overlayLine)
pos += ansi.PrintableRuneWidth(overlayLine)

right := cutLeft(backgroundLine, pos)
b.WriteString(right)
}

return b.String()
}

// cutLeft cuts printable characters from the left.
// This function is heavily based on muesli's ansi and truncate packages.
func cutLeft(s string, cutWidth int) string {
var (
pos int
isAnsi bool
ab bytes.Buffer
b bytes.Buffer
)

for _, c := range s {
var w int
if c == ansi.Marker || isAnsi {
isAnsi = true
ab.WriteRune(c)
if ansi.IsTerminator(c) {
isAnsi = false
if bytes.HasSuffix(ab.Bytes(), []byte("[0m")) {
ab.Reset()
}
}
} else {
w = runewidth.RuneWidth(c)
}

if pos >= cutWidth {
if b.Len() == 0 {
if ab.Len() > 0 {
b.Write(ab.Bytes())
}
if pos-cutWidth > 1 {
b.WriteByte(' ')
continue
}
}
b.WriteRune(c)
}
pos += w
}

return b.String()
}

func clamp(v, lower, upper int) int {
return min(max(v, lower), upper)
}

func max(a, b int) int {
if a > b {
return a
}
return b
}

func min(a, b int) int {
if a < b {
return a
}
return b
}
9 changes: 8 additions & 1 deletion help.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package main

import (
"restman/components/config"
"restman/components/overlay"
"restman/components/popup"
"restman/utils"

"github.com/charmbracelet/bubbles/help"
tea "github.com/charmbracelet/bubbletea"
Expand All @@ -20,6 +22,7 @@ type Help struct {
overlay popup.Overlay
help help.Model
keys config.KeyMap
bgRaw string
}

func NewHelp(bgRaw string, width int) Help {
Expand All @@ -29,6 +32,7 @@ func NewHelp(bgRaw string, width int) Help {
help: help,
keys: config.Keys,
overlay: popup.NewOverlay(bgRaw, width, 20),
bgRaw: bgRaw,
}
}

Expand Down Expand Up @@ -72,5 +76,8 @@ func (c Help) View() string {
)
dialog := lipgloss.Place(c.overlay.Width(), c.overlay.Height(), lipgloss.Left, lipgloss.Top, ui)

return c.overlay.WrapView(dialog)
startCol, startRow := utils.GetStartColRow(dialog, c.bgRaw)
return overlay.PlaceOverlay(startCol, startRow, dialog, c.bgRaw)

// return c.overlay.WrapView(dialog)
}
18 changes: 10 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,15 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
}

case collections.CreateResultMsg, collections.AddToCollectionResultMsg:
cmd := m.AddToCollection()
// TODO: refactor to use in the same way as AddToCollection
case collections.CreateResultMsg:
m.popup = nil
return m, cmd

case collections.AddToCollectionResultMsg:
if msg.Result {
cmd = m.AddToCollection()
}
m.popup = nil
return m, cmd
}
Expand Down Expand Up @@ -297,12 +304,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, m.popup.Init()

case "ctrl+a":

bg := config.FullscreenStyle.
Width(m.width - 2).
Height(m.height - 2).
Render()
m.popup = NewHelp(bg, 70)
m.popup = NewHelp(m.View(), 70)
return m, m.popup.Init()

case "ctrl+s":
Expand Down
29 changes: 28 additions & 1 deletion utils/strings.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package utils

import "strings"
import (
"strings"

"github.com/muesli/ansi"
)

func Truncate(s string, n int) string {
if len(s) <= n {
Expand All @@ -12,3 +16,26 @@ func Truncate(s string, n int) string {
func SplitLines(s string) []string {
return strings.Split(s, "\n")
}

func GetStartColRow(content string, bgRaw string) (int, int) {

bg := strings.Split(bgRaw, "\n")
bgWidth := ansi.PrintableRuneWidth(bg[0])
bgHeight := len(bg)

cnt := strings.Split(content, "\n")
width := ansi.PrintableRuneWidth(cnt[0])
height := len(cnt)

if height > bgHeight {
height = bgHeight
}
if width > bgWidth {
width = bgWidth
}

startRow := (bgHeight - height) / 2
startCol := (bgWidth - width) / 2

return startCol, startRow
}

0 comments on commit be162a8

Please sign in to comment.