Работа над отображением объектов, работа со стилями, работа с позиционированиме, изменение таблицы переменных
This commit is contained in:
parent
ada7db46cf
commit
2e8eee135e
7 changed files with 477 additions and 431 deletions
219
setup/final.go
219
setup/final.go
|
|
@ -36,67 +36,19 @@ func (m *FinalModel) Init() tea.Cmd {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *FinalModel) initViewport(width, height int) {
|
||||
m.viewport = viewport.New(width, height-8)
|
||||
m.viewport.Width = width
|
||||
m.viewport.Height = height - 10
|
||||
m.ready = true
|
||||
m.rebuildTable(m.viewport.Width)
|
||||
m.viewport.SetContent(m.table.Render())
|
||||
}
|
||||
|
||||
func (m *FinalModel) rebuildTable(width int) {
|
||||
if len(m.variables) == 0 {
|
||||
m.table = table.New().Headers("Нет переменных")
|
||||
return
|
||||
}
|
||||
availableWidth := width - 12 // примерно: 2 (отступы) + 4 (бордер) + запас
|
||||
if availableWidth < 70 {
|
||||
availableWidth = 70
|
||||
}
|
||||
t := table.New().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderStyle(ui.TableBorder).
|
||||
StyleFunc(func(row, col int) lipgloss.Style {
|
||||
var style lipgloss.Style
|
||||
switch {
|
||||
case row == table.HeaderRow:
|
||||
return ui.TableHeader
|
||||
case row%2 == 0:
|
||||
style = ui.TableRowEven.Padding(0, 2)
|
||||
default:
|
||||
style = ui.TableRowOdd.Padding(0, 2)
|
||||
}
|
||||
switch col {
|
||||
case 0, 1:
|
||||
style = style.Width(25)
|
||||
case 2:
|
||||
style = style.Width(availableWidth - 50 - 10)
|
||||
}
|
||||
return style
|
||||
}).
|
||||
Headers("Variable name", "Default value", "Used value")
|
||||
for _, v := range m.variables {
|
||||
used := fmt.Sprintf("%v", v.Value)
|
||||
if used == "" {
|
||||
used = "<пусто>"
|
||||
}
|
||||
t.Row(v.Name, v.Default, used)
|
||||
}
|
||||
m.table = t
|
||||
}
|
||||
|
||||
func (m *FinalModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
var cmd tea.Cmd
|
||||
switch msg := msg.(type) {
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
return m, tea.Quit
|
||||
case "up":
|
||||
m.viewport.ScrollUp(1)
|
||||
case "down":
|
||||
m.viewport.ScrollDown(1)
|
||||
case "left":
|
||||
m.viewport.ScrollLeft(1)
|
||||
case "right":
|
||||
m.viewport.ScrollRight(1)
|
||||
case "pageup":
|
||||
m.viewport.HalfPageUp()
|
||||
case "pagedown":
|
||||
|
|
@ -107,15 +59,9 @@ func (m *FinalModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.viewport.GotoBottom()
|
||||
}
|
||||
case tea.WindowSizeMsg:
|
||||
if !m.ready {
|
||||
m.height = msg.Height
|
||||
m.width = msg.Width
|
||||
m.initViewport(msg.Width, msg.Height)
|
||||
} else {
|
||||
m.viewport.Width = msg.Width - 4
|
||||
m.viewport.Height = msg.Height - 6
|
||||
}
|
||||
m.rebuildTable(m.viewport.Width)
|
||||
rendered := m.table.Render()
|
||||
m.viewport.SetContent(rendered)
|
||||
}
|
||||
m.viewport, cmd = m.viewport.Update(msg)
|
||||
return m, cmd
|
||||
|
|
@ -125,76 +71,103 @@ func (m *FinalModel) View() string {
|
|||
if !m.ready {
|
||||
return "Загрузка таблицы"
|
||||
}
|
||||
containerWidth, containerHeight, contentWidth, _ := ui.ContentSizes(m.width, m.height)
|
||||
|
||||
contentWidth := ui.ContentWidth(m.width)
|
||||
m.rebuildTable(contentWidth)
|
||||
|
||||
header := ui.HeaderStyle.Width(contentWidth).Render("Итоговые значения переменных")
|
||||
footer := ui.FooterStyle.Width(contentWidth).Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables)))
|
||||
|
||||
m.viewport.Width = contentWidth - 8
|
||||
m.viewport.Height = m.height - 12
|
||||
m.viewport.SetContent(m.table.Render())
|
||||
header := ui.FinalHeader.
|
||||
Width(contentWidth).
|
||||
Render("Итоговые значения переменных")
|
||||
footer := ui.FinalFooter.
|
||||
Width(contentWidth).
|
||||
Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables)))
|
||||
|
||||
renderedTable := m.table.Render()
|
||||
content := lipgloss.NewStyle().
|
||||
Align(lipgloss.Center).
|
||||
Render(renderedTable)
|
||||
m.viewport.SetContent(content)
|
||||
body := m.viewport.View()
|
||||
fullContent := lipgloss.JoinVertical(lipgloss.Top, header, body, footer)
|
||||
|
||||
content := lipgloss.JoinVertical(lipgloss.Left, header, body, footer)
|
||||
container := ui.AppContainer.Width(contentWidth).Render(content)
|
||||
|
||||
return lipgloss.Place(m.width, m.height,
|
||||
container := ui.AppContainer.
|
||||
Width(containerWidth).
|
||||
Height(containerHeight).
|
||||
Render(fullContent)
|
||||
return lipgloss.Place(
|
||||
m.width, m.height,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
container,
|
||||
lipgloss.WithWhitespaceChars("░"),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorGrey),
|
||||
lipgloss.WithWhitespaceChars("+"),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorError),
|
||||
)
|
||||
|
||||
//contentWidth := ui.AppContentWidth(m.width)
|
||||
//m.viewport.Width = contentWidth - 6
|
||||
//m.viewport.Height = m.height - 12
|
||||
//m.rebuildTable(contentWidth)
|
||||
//
|
||||
//header := ui.AppHeaderStyle.
|
||||
// Width(contentWidth).
|
||||
// Render("Итоговые значения переменных")
|
||||
//
|
||||
//footer := ui.AppFooterStyle.
|
||||
// Width(contentWidth).
|
||||
// Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables)))
|
||||
//
|
||||
//body := m.viewport.View()
|
||||
//content := lipgloss.JoinVertical(lipgloss.Left, header, body, footer)
|
||||
//
|
||||
//container := ui.AppContainerStyle.
|
||||
// Width(contentWidth).
|
||||
// Render(content)
|
||||
//
|
||||
//return lipgloss.Place(m.width, m.height,
|
||||
// lipgloss.Center, lipgloss.Center,
|
||||
// container,
|
||||
// lipgloss.WithWhitespaceChars("░"),
|
||||
// lipgloss.WithWhitespaceForeground(ui.ColorGrey),
|
||||
//)
|
||||
|
||||
//header := lipgloss.NewStyle().
|
||||
// Width(m.viewport.Width).
|
||||
// Align(lipgloss.Center).
|
||||
// Bold(true).
|
||||
// Background(ui.ColorPurple).
|
||||
// Foreground(ui.ColorWhite).
|
||||
// Padding(1).
|
||||
// Render("Итоговые значения переменных")
|
||||
//
|
||||
//footer := lipgloss.NewStyle().
|
||||
// Width(m.viewport.Width).
|
||||
// Align(lipgloss.Center).
|
||||
// Foreground(ui.ColorGrey).
|
||||
// Padding(0, 1).
|
||||
// Render(fmt.Sprintf("Строк: %d • q — выход • ↑↓ / jk — скролл", len(m.variables)))
|
||||
//
|
||||
//body := m.viewport.View()
|
||||
//return lipgloss.JoinVertical(lipgloss.Center,
|
||||
// header,
|
||||
// body,
|
||||
// footer,
|
||||
//)
|
||||
}
|
||||
|
||||
func (m *FinalModel) initViewport(width, height int) {
|
||||
|
||||
_, _, contentWidth, contentHeight := ui.ContentSizes(width, height)
|
||||
|
||||
tableWidth := contentWidth - 2*1
|
||||
tableHeight := int(float64(contentHeight)*ui.TableWithRatio) - 2*1
|
||||
|
||||
m.viewport = viewport.New(contentWidth, tableHeight)
|
||||
//размеры для viewport в нем будет находиться таблица и перемещаться в зависимости от команд
|
||||
|
||||
m.ready = true
|
||||
m.rebuildTable(tableWidth)
|
||||
m.viewport.SetContent(m.table.Render())
|
||||
}
|
||||
|
||||
func (m *FinalModel) rebuildTable(width int) {
|
||||
if len(m.variables) == 0 {
|
||||
m.table = table.New().
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderStyle(ui.FinalTableBorder).
|
||||
StyleFunc(func(row, col int) lipgloss.Style {
|
||||
return ui.FinalTableHeader
|
||||
}).Headers("Нет переменных")
|
||||
return
|
||||
}
|
||||
variableNameColWidth := 15
|
||||
defaultValueColWidth := 25
|
||||
usedValueColWidth := width - variableNameColWidth - defaultValueColWidth - 4*1
|
||||
//ширина таблицы - ширина первой колонки - ширина второй колонки - 4 границы (2 крайние, 2 между колонками)
|
||||
if usedValueColWidth < 30 { //если значение сильно меньше
|
||||
usedValueColWidth = 30
|
||||
}
|
||||
|
||||
t := table.New().
|
||||
Width(variableNameColWidth+defaultValueColWidth+usedValueColWidth+4).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderStyle(ui.FinalTableBorder).
|
||||
StyleFunc(func(row, col int) lipgloss.Style {
|
||||
var style lipgloss.Style
|
||||
if row == table.HeaderRow {
|
||||
return ui.FinalTableHeader
|
||||
}
|
||||
if row%2 == 0 {
|
||||
style = ui.FinalTableEvenRow
|
||||
} else {
|
||||
style = ui.FinalTableOddRow
|
||||
}
|
||||
switch col {
|
||||
case 0:
|
||||
return style.Width(variableNameColWidth).Align(lipgloss.Left)
|
||||
case 1:
|
||||
return style.Width(defaultValueColWidth).Align(lipgloss.Left)
|
||||
case 2:
|
||||
return style.Width(usedValueColWidth).Align(lipgloss.Left)
|
||||
}
|
||||
return style
|
||||
}).
|
||||
Headers("Variable name", "Default value", "Used value")
|
||||
|
||||
for _, v := range m.variables {
|
||||
used := fmt.Sprintf("%v", v.Value)
|
||||
if used == "" {
|
||||
used = "<Пусто>"
|
||||
}
|
||||
t.Row(v.Name, v.Default, used)
|
||||
}
|
||||
m.table = t
|
||||
}
|
||||
|
|
|
|||
118
setup/form.go
118
setup/form.go
|
|
@ -6,11 +6,11 @@ import (
|
|||
"bubble/types"
|
||||
"fmt"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/glamour"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/muesli/reflow/wordwrap"
|
||||
"github.com/sirupsen/logrus"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type FormModel struct {
|
||||
|
|
@ -77,12 +77,7 @@ func NewFormModel(application *types.PackageApplication, sectionIdx, focus, widt
|
|||
height: height,
|
||||
}
|
||||
if currentSection.Type == types.SectionAbout {
|
||||
md := strings.Join(currentSection.Paragraphs, "\n\n")
|
||||
renderer, _ := glamour.NewTermRenderer(
|
||||
glamour.WithAutoStyle(),
|
||||
glamour.WithWordWrap(width-10))
|
||||
rendered, _ := renderer.Render(md)
|
||||
m.renderedContent = rendered
|
||||
m.renderedContent = simpleAboutRender(currentSection.Paragraphs, width)
|
||||
m.focus = 0
|
||||
}
|
||||
return m
|
||||
|
|
@ -93,24 +88,17 @@ func (m *FormModel) Init() tea.Cmd {
|
|||
}
|
||||
|
||||
func (m *FormModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
||||
switch msg := msg.(type) {
|
||||
case tea.WindowSizeMsg:
|
||||
m.width = msg.Width
|
||||
m.height = msg.Height
|
||||
if m.CurrentSection.Type == types.SectionAbout {
|
||||
md := strings.Join(m.CurrentSection.Paragraphs, "\n\n")
|
||||
renderer, _ := glamour.NewTermRenderer(
|
||||
glamour.WithAutoStyle(),
|
||||
glamour.WithWordWrap(m.width-10),
|
||||
)
|
||||
rendered, _ := renderer.Render(md)
|
||||
m.renderedContent = rendered
|
||||
m.renderedContent = simpleAboutRender(m.CurrentSection.Paragraphs, m.width)
|
||||
}
|
||||
return m, nil
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
return m, tea.Quit
|
||||
case "esc":
|
||||
for _, field := range m.FieldModels {
|
||||
if field.CaptureKeys() {
|
||||
|
|
@ -134,7 +122,6 @@ func (m *FormModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
},
|
||||
}
|
||||
}
|
||||
//вернуться к списку приложений, чтобы выбрать другое приложение.
|
||||
case "enter":
|
||||
logrus.Infof("sections %s, focus %d, fields len %d", m.CurrentSection.Name, m.focus, len(m.FieldModels))
|
||||
if len(m.FieldModels) == m.focus {
|
||||
|
|
@ -176,71 +163,45 @@ func (m *FormModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
case types.SelectedOptionMsg:
|
||||
logrus.Infof("chose %+v", msg)
|
||||
}
|
||||
cmd := m.updateFields(msg)
|
||||
return m, cmd
|
||||
return m, m.updateFields(msg)
|
||||
}
|
||||
|
||||
func (m *FormModel) View() string {
|
||||
contentWidth := ui.ContentWidth(m.width)
|
||||
|
||||
var res strings.Builder
|
||||
containerWidth, containerHeight, contentWidth, _ := ui.ContentSizes(m.width, m.height)
|
||||
|
||||
formWidth := contentWidth - 2*1
|
||||
var strokes []string
|
||||
for i, field := range m.FieldModels {
|
||||
fieldStr := wordwrap.String(field.View(), contentWidth-10)
|
||||
fieldStroke := wordwrap.String(field.View(), formWidth)
|
||||
if i == m.focus {
|
||||
res.WriteString(ui.FormFieldFocused.Render(fieldStr))
|
||||
strokes = append(strokes, ui.FormFieldFocused.Render(fieldStroke))
|
||||
} else {
|
||||
res.WriteString(ui.FormFieldUnfocused.Render(fieldStr))
|
||||
strokes = append(strokes, ui.FormFieldUnfocused.Render(fieldStroke))
|
||||
}
|
||||
res.WriteString("\n\n")
|
||||
}
|
||||
|
||||
if m.CurrentSection.Type == types.SectionAbout {
|
||||
res.WriteString(m.renderedContent)
|
||||
strokes = append([]string{}, m.renderedContent)
|
||||
}
|
||||
|
||||
nextBtn := "[ next section ]"
|
||||
if m.focus == len(m.FieldModels) {
|
||||
res.WriteString(ui.FormNextButton.Render(nextBtn))
|
||||
strokes = append(strokes, ui.FormNextButton.Render(nextBtn))
|
||||
} else {
|
||||
res.WriteString(ui.FormFieldUnfocused.Render(nextBtn))
|
||||
strokes = append(strokes, ui.FormFieldUnfocused.Render(nextBtn))
|
||||
}
|
||||
|
||||
container := ui.FormContainer.Width(contentWidth).Render(res.String())
|
||||
return lipgloss.Place(m.width, m.height,
|
||||
container := ui.AppContainer.
|
||||
Width(containerWidth).
|
||||
Height(containerHeight).
|
||||
Render(strings.Join(strokes, "\n\n"))
|
||||
return lipgloss.Place(
|
||||
m.width, m.height,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
container,
|
||||
lipgloss.WithWhitespaceChars(" "),
|
||||
)
|
||||
|
||||
//for i, field := range m.FieldModels {
|
||||
// fieldStr := wordwrap.String(field.View(), contentWidth-8)
|
||||
// if i == m.focus {
|
||||
// res.WriteString(ui.FormFocusedStyle.Render(fieldStr))
|
||||
// } else {
|
||||
// res.WriteString(ui.FormUnfocusedStyle.Render(fieldStr))
|
||||
// }
|
||||
// res.WriteString("\n\n")
|
||||
//}
|
||||
//
|
||||
//if m.CurrentSection.Type == types.SectionAbout {
|
||||
// res.WriteString("\n\n" + m.renderedContent)
|
||||
//}
|
||||
//
|
||||
//button := "[ next section ]"
|
||||
//if m.focus == len(m.FieldModels) {
|
||||
// res.WriteString(ui.FormFocusedStyle.Render(button))
|
||||
//} else {
|
||||
// res.WriteString(ui.FormUnfocusedStyle.Render(button))
|
||||
//}
|
||||
//
|
||||
//container := ui.FormStyle.Width(contentWidth).Render(res.String())
|
||||
//
|
||||
//return lipgloss.Place(m.width, m.height,
|
||||
// lipgloss.Center, lipgloss.Top,
|
||||
// container,
|
||||
// lipgloss.WithWhitespaceChars(" "),
|
||||
//)
|
||||
}
|
||||
|
||||
func (m *FormModel) updateFields(msg tea.Msg) tea.Cmd {
|
||||
|
|
@ -283,3 +244,42 @@ func (m *FormModel) updateFields(msg tea.Msg) tea.Cmd {
|
|||
}
|
||||
return tea.Batch(cmds...)
|
||||
}
|
||||
|
||||
func simpleAboutRender(paragraphs []string, width int) string {
|
||||
var sb strings.Builder
|
||||
for _, p := range paragraphs {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
sb.WriteString("\n")
|
||||
continue
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(p, "# "):
|
||||
// Заголовок 1 уровня
|
||||
h1Len := utf8.RuneCountInString(p[2:])
|
||||
h1Offset := strings.Repeat(" ", (width-h1Len)/2)
|
||||
sb.WriteString(ui.AboutTitle.Render(h1Offset+p[2:]) + "\n\n")
|
||||
case strings.HasPrefix(p, "## "):
|
||||
// Заголовок 2 уровня
|
||||
sb.WriteString(ui.AboutH2.Render(p[3:]) + "\n\n")
|
||||
case strings.HasPrefix(p, "### "):
|
||||
// Заголовок 3 уровня
|
||||
sb.WriteString(" " + ui.AboutH3.Render(p[4:]) + "\n\n")
|
||||
case strings.HasPrefix(p, "- "), strings.HasPrefix(p, "* "):
|
||||
// Список простой
|
||||
text := strings.TrimLeft(p[2:], " ")
|
||||
wrapped := wordwrap.String(text, width-10)
|
||||
sb.WriteString(" " + ui.AboutBullet.Render("• ") + ui.AboutNormal.Render(wrapped) + "\n")
|
||||
case strings.HasPrefix(p, "> "):
|
||||
// Цитаты
|
||||
text := strings.TrimPrefix(p, "> ")
|
||||
wrapped := wordwrap.String(text, width-12)
|
||||
sb.WriteString(" " + ui.AboutNormal.Foreground(ui.ColorGrey).Render("│ "+wrapped) + "\n")
|
||||
default:
|
||||
// Обычный текст
|
||||
wrapped := wordwrap.String(p, width-8)
|
||||
sb.WriteString(" " + ui.AboutNormal.Render(wrapped) + "\n\n")
|
||||
}
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/charmbracelet/bubbles/list"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type ListApplicationItem struct {
|
||||
|
|
@ -42,9 +43,9 @@ func NewListApplicationsModel(applications []types.PackageApplication, width, he
|
|||
delegate.Styles.SelectedDesc = ui.ListSelectedStyle
|
||||
delegate.ShowDescription = false
|
||||
l := list.New(items, delegate, width, height)
|
||||
l.Title = "Выберите приложение для настройки"
|
||||
l.Title = "Приложения"
|
||||
l.Styles.Title = ui.ListTitleStyle
|
||||
|
||||
l.SetShowHelp(false)
|
||||
return &ListApplicationsModel{
|
||||
List: l,
|
||||
width: width,
|
||||
|
|
@ -65,15 +66,13 @@ func (m *ListApplicationsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, nil
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
return m, tea.Quit
|
||||
case "enter":
|
||||
selected := m.List.SelectedItem().(ListApplicationItem)
|
||||
return m, func() tea.Msg {
|
||||
return types.ShowModalMsg{
|
||||
Type: types.ModalConfirm,
|
||||
Title: "Начать установку",
|
||||
Message: fmt.Sprintf("Вы хотит настроить приложение:\n\n%s\n\nПродолжить?", selected.Title()),
|
||||
Message: fmt.Sprintf("Вы хотите настроить приложение:\n\n%s\n\nПродолжить?", selected.Title()),
|
||||
ModalButtons: []types.ModalButton{
|
||||
{Text: "Да", Value: true},
|
||||
{Text: "Нет", Value: false},
|
||||
|
|
@ -95,46 +94,63 @@ func (m *ListApplicationsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
}
|
||||
|
||||
func (m *ListApplicationsModel) View() string {
|
||||
contentWidth := ui.ContentWidth(m.width)
|
||||
listWidth := int(float64(contentWidth) * ui.ListWithRatio)
|
||||
m.List.SetSize(listWidth-6, m.height-10)
|
||||
gapStroke := " "
|
||||
containerWidth, containerHeight, contentWidth, contentHeight := ui.ContentSizes(m.width, m.height)
|
||||
|
||||
listView := m.List.View()
|
||||
listWidth := int(float64(contentWidth)*ui.ListWithRatio) - 2*1
|
||||
//ширина листа = пропорция от ширины контента - границы для контейнера листа
|
||||
listHeight := contentHeight - 2*1
|
||||
//высота листа = высота контента - границы для контейнера листа
|
||||
descWidth := int(float64(contentWidth)*(1-ui.ListWithRatio)) - 2*1 - len(gapStroke)
|
||||
//ширина описания = обратная пропорция листа от ширины контента - границы для контейнера описания - отступ от контейнера листа
|
||||
descHeight := contentHeight - 2*1
|
||||
//высота листа = высота контента - границы для контейнера описания
|
||||
|
||||
m.List.SetSize(listWidth, listHeight)
|
||||
|
||||
//logs.go logrus.DebugLevel set
|
||||
logrus.Debugf(
|
||||
"window: width %d, height %d\ncontainer: width %d, height %d\ncontent: width %d, height %d\nlist: width %d, height %d\ndesc: width %d, height %d\n\n",
|
||||
m.width, m.height,
|
||||
containerWidth, containerHeight,
|
||||
contentWidth, contentHeight,
|
||||
listWidth, listHeight,
|
||||
descWidth, descHeight,
|
||||
)
|
||||
|
||||
listView := lipgloss.NewStyle().
|
||||
Width(listWidth).
|
||||
Height(listHeight).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(ui.ColorPurple).
|
||||
AlignVertical(lipgloss.Top).
|
||||
Render(m.List.View())
|
||||
|
||||
var desc string
|
||||
if sel := m.List.SelectedItem(); sel != nil {
|
||||
desc = sel.(ListApplicationItem).Description()
|
||||
}
|
||||
descView := ui.ListDescriptionStyle.Width(contentWidth - listWidth - 10).Render(desc)
|
||||
body := lipgloss.JoinHorizontal(lipgloss.Top, listView, " ", descView)
|
||||
container := ui.ListContainer.Width(contentWidth).Render(body)
|
||||
|
||||
return lipgloss.Place(m.width, m.height,
|
||||
descView := ui.ListDescriptionStyle.
|
||||
Width(descWidth).
|
||||
Height(descHeight).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(ui.ColorError).
|
||||
AlignVertical(lipgloss.Top).
|
||||
Render(
|
||||
desc,
|
||||
)
|
||||
|
||||
body := lipgloss.JoinHorizontal(lipgloss.Center, listView, gapStroke, descView)
|
||||
container := ui.AppContainer.
|
||||
Width(containerWidth).
|
||||
Height(containerHeight).
|
||||
Render(body)
|
||||
return lipgloss.Place(
|
||||
m.width, m.height,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
container,
|
||||
lipgloss.WithWhitespaceChars("░"),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorGrey),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorWarning),
|
||||
)
|
||||
|
||||
//var desc string
|
||||
//if selected := m.List.SelectedItem(); selected != nil {
|
||||
// desc = selected.(ListApplicationItem).Description()
|
||||
//}
|
||||
//descView := ui.ListDescriptionStyle.
|
||||
// Width(contentWidth/2 - 4).
|
||||
// Render(desc)
|
||||
//
|
||||
//body := lipgloss.JoinHorizontal(lipgloss.Top, listView, " ", descView)
|
||||
//
|
||||
//container := ui.ListStyle.
|
||||
// Width(contentWidth).
|
||||
// Render(body)
|
||||
//
|
||||
//return lipgloss.Place(m.width, m.height,
|
||||
// lipgloss.Center, lipgloss.Center,
|
||||
// container,
|
||||
// lipgloss.WithWhitespaceChars("░"),
|
||||
// lipgloss.WithWhitespaceForeground(ui.ColorGrey),
|
||||
//)
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,24 @@ func (m *Main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
}
|
||||
case tea.KeyMsg:
|
||||
switch msg.String() {
|
||||
case "ctrl+c", "q":
|
||||
return m, tea.Quit
|
||||
case "ctrl+c":
|
||||
return m, func() tea.Msg {
|
||||
return types.ShowModalMsg{
|
||||
Type: types.ModalWarning,
|
||||
Title: "Закрытие приложения",
|
||||
Message: "Вы нажали ctrl+c, вы желаете закрыть приложение?",
|
||||
ModalButtons: []types.ModalButton{
|
||||
{Text: "Закрыть приложение", Value: true},
|
||||
{Text: "Не закрывать", Value: false},
|
||||
},
|
||||
OnResult: func(result any) tea.Cmd {
|
||||
if result == true {
|
||||
return tea.Quit
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
case types.NextSectionMsg:
|
||||
m.CurrentSectionIdx++
|
||||
|
|
@ -103,14 +119,12 @@ func (m *Main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.current = NewFinalModel(m.CurrentApplication.Variables, m.Width, m.Height)
|
||||
} else {
|
||||
m.current = NewFormModel(m.CurrentApplication, m.CurrentSectionIdx, 0, m.Width, m.Height)
|
||||
|
||||
}
|
||||
case types.SugarMsg:
|
||||
m.Sugar(msg)
|
||||
case types.SelectedAppMsg:
|
||||
//получаем сообщение о выборе приложения
|
||||
m.CurrentApplication = &msg.App
|
||||
|
||||
//ищем доступную секцию
|
||||
for sectionIdx := 0; sectionIdx < len(m.CurrentApplication.Sections); sectionIdx++ {
|
||||
section := m.CurrentApplication.Sections[sectionIdx]
|
||||
|
|
@ -136,7 +150,6 @@ func (m *Main) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
m.overlay = NewModalModel(msg, m.Width, m.Height)
|
||||
return m, nil
|
||||
case types.CloseModalMsg:
|
||||
logrus.Infof("modal close msg get")
|
||||
m.overlay = nil
|
||||
return m, tea.Batch(cmds...)
|
||||
}
|
||||
|
|
|
|||
144
setup/modal.go
144
setup/modal.go
|
|
@ -73,113 +73,89 @@ func (m *ModalModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
}
|
||||
|
||||
func (m *ModalModel) View() string {
|
||||
contentWidth := ui.ContentWidth(m.width)
|
||||
modalWidth := min(contentWidth-10, ui.ModalMaxHeight)
|
||||
if modalWidth < 60 {
|
||||
modalWidth = 60
|
||||
}
|
||||
|
||||
content := lipgloss.NewStyle().
|
||||
Width(modalWidth-8).
|
||||
Padding(1, 3).
|
||||
Render(m.message)
|
||||
containerWidth, containerHeight, _, _ := ui.ContentSizes(m.width, m.height)
|
||||
|
||||
modalWidth := min(containerWidth, ui.ModalMaxWidth)
|
||||
modalHeight := min(containerHeight, ui.ModalMaxHeight)
|
||||
|
||||
message := lipgloss.NewStyle().Render(m.message)
|
||||
var buttons []string
|
||||
|
||||
for i, btn := range m.buttons {
|
||||
for i, button := range m.buttons {
|
||||
style := ui.ModalButtonNormal
|
||||
if i == m.focus {
|
||||
style = ui.ModalButtonFocused
|
||||
}
|
||||
buttons = append(buttons, style.Render(btn.Text))
|
||||
buttons = append(buttons, style.Render(button.Text))
|
||||
}
|
||||
buttonRow := lipgloss.JoinHorizontal(lipgloss.Center, buttons...)
|
||||
modalBody := lipgloss.JoinVertical(lipgloss.Center, message, "", buttonRow)
|
||||
|
||||
body := lipgloss.JoinVertical(lipgloss.Center, content, "\n\n", buttonRow)
|
||||
var borderColor lipgloss.Color
|
||||
var modalTitleStyle lipgloss.Style
|
||||
|
||||
// Бордер и цвет в зависимости от типа
|
||||
var modalStyle lipgloss.Style
|
||||
var titleStyle lipgloss.Style
|
||||
switch m.modalType {
|
||||
case types.ModalError:
|
||||
modalStyle = ui.ModalBorderError
|
||||
titleStyle = ui.ModalTitleError
|
||||
borderColor = ui.ColorError
|
||||
modalTitleStyle = ui.ModalTitleError
|
||||
case types.ModalWarning, types.ModalConfirm:
|
||||
modalStyle = ui.ModalBorderWarning
|
||||
titleStyle = ui.ModalTitleWarning
|
||||
borderColor = ui.ColorWarning
|
||||
modalTitleStyle = ui.ModalTitleWarning
|
||||
default:
|
||||
modalStyle = ui.ModalBorderInfo
|
||||
titleStyle = ui.ModalTitleDefault
|
||||
borderColor = ui.ColorAccent
|
||||
modalTitleStyle = ui.ModalTitleDefault
|
||||
}
|
||||
|
||||
modal := lipgloss.NewStyle().
|
||||
Width(modalWidth).
|
||||
Padding(2, 4).
|
||||
Border(lipgloss.DoubleBorder()).
|
||||
BorderForeground(modalStyle.GetBorderBottomForeground()).
|
||||
Render(body)
|
||||
|
||||
if m.title != "" {
|
||||
title := titleStyle.Width(modalWidth).Align(lipgloss.Center).Render(m.title)
|
||||
modal = lipgloss.JoinVertical(lipgloss.Center, title, modal)
|
||||
}
|
||||
return lipgloss.Place(m.width, m.height,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
modal,
|
||||
lipgloss.WithWhitespaceChars("."),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorGrey))
|
||||
|
||||
//modalWidth := min(m.width-20, ui.ModalMaxHeight)
|
||||
//if modalWidth < 60 {
|
||||
// modalWidth = 60
|
||||
//}
|
||||
//var borderColor lipgloss.Color
|
||||
//var titleStyle lipgloss.Style
|
||||
//
|
||||
//switch m.modalType {
|
||||
//case types.ModalError:
|
||||
// borderColor = ui.ColorRed
|
||||
// titleStyle = lipgloss.NewStyle().Foreground(ui.ColorRed).Bold(true)
|
||||
// modalStyle = ui.ModalBorderError
|
||||
// modalTitleStyle = ui.ModalTitleError
|
||||
//case types.ModalWarning, types.ModalConfirm:
|
||||
// borderColor = ui.ColorPurple
|
||||
// titleStyle = lipgloss.NewStyle().Foreground(ui.ColorPurple).Bold(true)
|
||||
// modalStyle = ui.ModalBorderWarning
|
||||
// modalTitleStyle = ui.ModalTitleWarning
|
||||
//default:
|
||||
// borderColor = ui.ColorBlue
|
||||
// titleStyle = lipgloss.NewStyle().Foreground(ui.ColorBlue).Bold(true)
|
||||
// modalStyle = ui.ModalBorderInfo
|
||||
// modalTitleStyle = ui.ModalTitleDefault
|
||||
//}
|
||||
//content := lipgloss.NewStyle().Width(m.width-10).Padding(1, 2).Render(m.message)
|
||||
//var buttons []string
|
||||
//for i, btn := range m.buttons {
|
||||
// style := lipgloss.NewStyle().
|
||||
// Padding(0, 2).
|
||||
// Border(lipgloss.RoundedBorder()).
|
||||
// BorderForeground(ui.ColorGrey)
|
||||
// if i == m.focus {
|
||||
// style = style.Foreground(ui.ColorRed).BorderForeground(ui.ColorRed).Bold(true)
|
||||
// } else {
|
||||
// style = style.Foreground(ui.ColorGreenCyan)
|
||||
// }
|
||||
// buttons = append(buttons, style.Render(btn.Text))
|
||||
//}
|
||||
//buttonShow := lipgloss.JoinHorizontal(lipgloss.Center, buttons...)
|
||||
//body := lipgloss.JoinVertical(lipgloss.Center, content, "\n", buttonShow)
|
||||
//
|
||||
//modal := lipgloss.NewStyle().
|
||||
var modalView string
|
||||
symbolToRepeat := "*"
|
||||
if m.title != "" {
|
||||
modalView = ui.ModalContainer.
|
||||
Width(modalWidth).
|
||||
Height(modalHeight).
|
||||
Align(lipgloss.Center, lipgloss.Center).
|
||||
Border(lipgloss.DoubleBorder()).
|
||||
BorderForeground(borderColor).
|
||||
Render(modalBody)
|
||||
//modalView = ui.ModalContainer.
|
||||
// Width(modalWidth).
|
||||
// Height(modalHeight).
|
||||
// BorderForeground(borderColor).
|
||||
// Render(modalBody)
|
||||
//repeatCount := modalWidth - utf8.RuneCountInString(m.title)
|
||||
//if repeatCount < 0 {
|
||||
// repeatCount = 0
|
||||
//}
|
||||
//symbolFill := strings.Repeat(symbolToRepeat, repeatCount/2)
|
||||
//modalView = lipgloss.JoinVertical(lipgloss.Center, modalTitleStyle.Render(symbolFill+m.title+symbolFill), modalView)
|
||||
modalView = lipgloss.JoinVertical(lipgloss.Center, modalTitleStyle.Render(m.title), modalView)
|
||||
} else {
|
||||
modalView = ui.ModalContainer.
|
||||
Width(modalWidth).
|
||||
Height(modalHeight).
|
||||
BorderStyle(lipgloss.ASCIIBorder()).
|
||||
BorderForeground(borderColor).
|
||||
Render(modalBody)
|
||||
//modalView = modalStyle.
|
||||
// Width(modalWidth).
|
||||
// Height(modalHeight).
|
||||
// Padding(1, 3).
|
||||
// Border(lipgloss.DoubleBorder()).
|
||||
// BorderForeground(borderColor).
|
||||
// Render(body)
|
||||
//
|
||||
//if m.title != "" {
|
||||
// title := titleStyle.Width(modalWidth - 6).Render(m.title)
|
||||
// modal = lipgloss.JoinVertical(lipgloss.Center, title, modal)
|
||||
//}
|
||||
//
|
||||
//return lipgloss.Place(m.width, m.height,
|
||||
// lipgloss.Center, lipgloss.Center,
|
||||
// modal,
|
||||
// lipgloss.WithWhitespaceChars("."),
|
||||
// lipgloss.WithWhitespaceForeground(ui.ColorPurple),
|
||||
//)
|
||||
// Render(modalBody)
|
||||
}
|
||||
return lipgloss.Place(m.width, m.height,
|
||||
lipgloss.Center, lipgloss.Center,
|
||||
modalView,
|
||||
lipgloss.WithWhitespaceChars(symbolToRepeat),
|
||||
lipgloss.WithWhitespaceForeground(ui.ColorGrey))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,63 @@
|
|||
package ui
|
||||
|
||||
import "github.com/charmbracelet/lipgloss"
|
||||
|
||||
const (
|
||||
AppMaxWidth = 110
|
||||
AppMinWidth = 80
|
||||
AppSidePadding = 4
|
||||
ModalMaxWidth = 80
|
||||
ModalMaxHeight = 30
|
||||
ListWithRatio = 0.4
|
||||
import (
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
||||
func AppContentWidth(screenWidth int) int {
|
||||
w := screenWidth - 2*AppSidePadding
|
||||
if w > AppMaxWidth {
|
||||
return AppMaxWidth
|
||||
const (
|
||||
ApplicationMinWidth = 60
|
||||
ApplicationMaxHeight = 40
|
||||
ApplicationMinHeight = 20
|
||||
ApplicationHorizontalOffset = 3
|
||||
ApplicationVerticalOffset = 1
|
||||
ApplicationContainerPadding = 4
|
||||
|
||||
ModalMaxWidth = 50
|
||||
ModalMaxHeight = 15
|
||||
ListWithRatio = 0.4
|
||||
TableWithRatio = 0.8
|
||||
)
|
||||
|
||||
// ContentSizes вычисляет размеры для контейнера внутри окна и контента внутри контейнера.
|
||||
//
|
||||
// Принимает 2 параметра типа int, screenWidth и screenHeight ширина и высота окна.
|
||||
//
|
||||
// Возвращает 4 значения типа int.
|
||||
//
|
||||
// containerWidth это ширина контейнера внутри окна с отступами от левого и правого краёв, и с учетом границ
|
||||
//
|
||||
// containerHeight это высота контейнера внутри окна с отступами от верхнего и нижнего краёв, и с учетом границ
|
||||
//
|
||||
// contentWidth это ширина контента внутри контейнера с отступами от левого и правого краёв контейнера
|
||||
//
|
||||
// contentHeight это высота контента внутри контейнера с отступами от верхнего и нижнего краёв контейнера
|
||||
func ContentSizes(screenWidth, screenHeight int) (containerWidth, containerHeight, contentWidth, contentHeight int) {
|
||||
containerWidth = screenWidth - 2*ApplicationHorizontalOffset
|
||||
if containerWidth < ApplicationMinWidth {
|
||||
//если ширина слишком маленькая ставим минимальную поддерживаемую
|
||||
containerWidth = ApplicationMinWidth
|
||||
}
|
||||
if w < AppMinWidth {
|
||||
return AppMinWidth
|
||||
containerWidth = containerWidth - 2*1
|
||||
//Вычитаем из ширины контейнера 2 условных единицы для границ
|
||||
//Пример, окно 70, контейнер будет 64, места для контента тогда 62
|
||||
|
||||
containerHeight = screenHeight - 2*ApplicationVerticalOffset
|
||||
if containerHeight < ApplicationMinHeight {
|
||||
//если высота слишком маленькая ставим минимально поддерживаемую
|
||||
containerHeight = ApplicationMinHeight
|
||||
}
|
||||
return w
|
||||
containerHeight = containerHeight - 2*1
|
||||
//Вычитаем из высоты контейнера 2 условных единицы для границ
|
||||
//Пример, окно 30, контейнер будет 28, места для контента тогда 26
|
||||
|
||||
contentWidth = containerWidth - 2*ApplicationHorizontalOffset
|
||||
//Вычитаем из ширины контейнера отступы для контента внутри
|
||||
contentHeight = containerHeight - 2*ApplicationVerticalOffset
|
||||
//Вычитаем из высоты контейнера отступы для контента внутри
|
||||
return
|
||||
}
|
||||
|
||||
// Используемые цвета
|
||||
var (
|
||||
ColorFg = lipgloss.Color("#eeeeee")
|
||||
ColorBg = lipgloss.Color("#0d1117")
|
||||
|
|
@ -32,34 +68,93 @@ var (
|
|||
ColorPurple = lipgloss.Color("#cba6f7")
|
||||
ColorGrey = lipgloss.Color("#585b70")
|
||||
ColorDarkGrey = lipgloss.Color("#313244")
|
||||
)
|
||||
|
||||
AppContainer = lipgloss.NewStyle().
|
||||
Padding(2, 4).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(ColorPurple)
|
||||
|
||||
HeaderStyle = lipgloss.NewStyle().
|
||||
Bold(true).
|
||||
Foreground(ColorPurple).
|
||||
Background(ColorDarkGrey).
|
||||
Padding(1, 2).
|
||||
MarginBottom(1).
|
||||
Align(lipgloss.Center)
|
||||
|
||||
FooterStyle = lipgloss.NewStyle().
|
||||
Foreground(ColorGrey).
|
||||
Padding(0, 2).
|
||||
MarginTop(1).
|
||||
Align(lipgloss.Center)
|
||||
|
||||
ListContainer = lipgloss.NewStyle().
|
||||
Padding(1, 3).
|
||||
var AppContainer = lipgloss.NewStyle().
|
||||
Padding(ApplicationVerticalOffset, ApplicationHorizontalOffset).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(ColorAccent)
|
||||
|
||||
// Стили для списка приложений
|
||||
var (
|
||||
ListTitleStyle = lipgloss.NewStyle().Foreground(ColorPurple).Italic(true).Bold(true)
|
||||
ListSelectedStyle = lipgloss.NewStyle().Foreground(ColorError).Bold(true)
|
||||
ListDescriptionStyle = lipgloss.NewStyle().Foreground(ColorAccent2).MarginTop(1)
|
||||
ListDescriptionStyle = lipgloss.NewStyle().Foreground(ColorAccent2)
|
||||
)
|
||||
|
||||
// Стили для about
|
||||
var (
|
||||
AboutTitle = lipgloss.NewStyle().
|
||||
Foreground(ColorAccent).
|
||||
Bold(true).
|
||||
AlignHorizontal(lipgloss.Center)
|
||||
|
||||
AboutH2 = lipgloss.NewStyle().
|
||||
Foreground(ColorAccent).
|
||||
Bold(true)
|
||||
|
||||
AboutH3 = lipgloss.NewStyle().
|
||||
Foreground(ColorAccent).
|
||||
Bold(true)
|
||||
|
||||
AboutBullet = lipgloss.NewStyle().
|
||||
Foreground(ColorGrey)
|
||||
|
||||
AboutNormal = lipgloss.NewStyle().
|
||||
Foreground(ColorFg)
|
||||
)
|
||||
|
||||
// Стили для форм и полей ввода
|
||||
var (
|
||||
FormFieldFocused = lipgloss.NewStyle().Foreground(ColorError).Bold(true)
|
||||
FormFieldUnfocused = lipgloss.NewStyle().Foreground(ColorAccent2)
|
||||
FormNextButton = lipgloss.NewStyle().Foreground(ColorPurple).Bold(true)
|
||||
|
||||
SelectFileDirDeniedStyle = lipgloss.NewStyle().Foreground(ColorGrey)
|
||||
SelectFileDirParentStyle = lipgloss.NewStyle().Foreground(ColorPurple)
|
||||
SelectFileStyle = lipgloss.NewStyle().Foreground(ColorAccent)
|
||||
SelectDirStyle = lipgloss.NewStyle().Foreground(ColorAccent2)
|
||||
)
|
||||
|
||||
// Стили для таблицы переменных Final
|
||||
var (
|
||||
FinalHeader = lipgloss.NewStyle().
|
||||
Background(ColorDarkGrey).
|
||||
Foreground(ColorPurple).
|
||||
Bold(true).
|
||||
Align(lipgloss.Center).
|
||||
MarginBottom(1).
|
||||
Padding(1, 2)
|
||||
|
||||
FinalFooter = lipgloss.NewStyle().
|
||||
Foreground(ColorGrey).
|
||||
MarginTop(1).
|
||||
Padding(1, 0).
|
||||
Align(lipgloss.Center)
|
||||
|
||||
FinalTableBorder = lipgloss.NewStyle().
|
||||
Foreground(ColorPurple)
|
||||
|
||||
FinalTableHeader = lipgloss.NewStyle().
|
||||
Foreground(ColorPurple).
|
||||
Bold(true).
|
||||
Align(lipgloss.Center).
|
||||
Padding(0, 1)
|
||||
|
||||
FinalTableEvenRow = lipgloss.NewStyle().
|
||||
Background(ColorDarkGrey).
|
||||
Padding(0, 2)
|
||||
|
||||
FinalTableOddRow = lipgloss.NewStyle().
|
||||
Padding(0, 2)
|
||||
)
|
||||
|
||||
// Стили для модальных окон
|
||||
var (
|
||||
ModalContainer = lipgloss.NewStyle().
|
||||
Border(lipgloss.DoubleBorder()).
|
||||
Align(lipgloss.Center, lipgloss.Center)
|
||||
//Padding(ApplicationVerticalOffset, ApplicationHorizontalOffset)
|
||||
|
||||
ModalBorderError = lipgloss.NewStyle().BorderForeground(ColorError)
|
||||
ModalBorderWarning = lipgloss.NewStyle().BorderForeground(ColorWarning)
|
||||
|
|
@ -82,22 +177,10 @@ var (
|
|||
BorderForeground(ColorError).
|
||||
Foreground(ColorError).
|
||||
Bold(true)
|
||||
)
|
||||
|
||||
FormContainer = lipgloss.NewStyle().
|
||||
Padding(2, 4).
|
||||
Border(lipgloss.RoundedBorder()).
|
||||
BorderForeground(ColorAccent)
|
||||
|
||||
FormFieldFocused = lipgloss.NewStyle().Foreground(ColorError).Bold(true)
|
||||
FormFieldUnfocused = lipgloss.NewStyle().Foreground(ColorAccent2)
|
||||
FormNextButton = lipgloss.NewStyle().Foreground(ColorPurple).Bold(true)
|
||||
|
||||
TableBorder = lipgloss.NewStyle().Foreground(ColorPurple)
|
||||
TableHeader = lipgloss.NewStyle().Foreground(ColorPurple).Bold(true).Align(lipgloss.Center)
|
||||
TableRowEven = lipgloss.NewStyle().Foreground(ColorFg).Background(ColorDarkGrey)
|
||||
TableRowOdd = lipgloss.NewStyle().Foreground(ColorFg)
|
||||
TableCell = lipgloss.NewStyle().Padding(0, 2)
|
||||
|
||||
//Старые стили
|
||||
//var (
|
||||
//ColorWhite = lipgloss.Color("#ffffff")
|
||||
//ColorGrey = lipgloss.Color("#626262")
|
||||
//ColorBlack = lipgloss.Color("#000000")
|
||||
|
|
@ -131,10 +214,6 @@ var (
|
|||
//TableEvenRowStyle = TableCellStyle.Foreground(ColorWhite)
|
||||
//TableBorderStyle = lipgloss.NewStyle().Foreground(ColorPurple)
|
||||
//
|
||||
SelectFileDirDeniedStyle = lipgloss.NewStyle().Foreground(ColorGrey)
|
||||
SelectFileDirParentStyle = lipgloss.NewStyle().Foreground(ColorPurple)
|
||||
SelectFileStyle = lipgloss.NewStyle().Foreground(ColorAccent)
|
||||
SelectDirStyle = lipgloss.NewStyle().Foreground(ColorAccent2)
|
||||
//
|
||||
//SelectStyle = lipgloss.NewStyle().Foreground(ColorGreenCyan)
|
||||
//InputStyle = lipgloss.NewStyle().Foreground(ColorGreenCyan)
|
||||
|
|
@ -151,15 +230,4 @@ var (
|
|||
//ListSelectedItemStyle = lipgloss.NewStyle().Foreground(ColorRed).Bold(true)
|
||||
//ListTitleStyle = lipgloss.NewStyle().Foreground(ColorPurple).Italic(true)
|
||||
//ListDescriptionStyle = lipgloss.NewStyle().Foreground(ColorGreenCyan).MarginTop(1)
|
||||
)
|
||||
|
||||
func ContentWidth(screenWidth int) int {
|
||||
w := screenWidth - 2*AppSidePadding
|
||||
if w > AppMaxWidth {
|
||||
return AppMaxWidth
|
||||
}
|
||||
if w < AppMinWidth {
|
||||
return AppMinWidth
|
||||
}
|
||||
return w
|
||||
}
|
||||
//)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
|
||||
const SectionAbout = "abouta"
|
||||
const SectionAbout = "about"
|
||||
const SectionFinal = "final"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue