2025-12-26 17:45:37 +05:00
|
|
|
|
package fields
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2026-01-21 17:56:21 +05:00
|
|
|
|
"bubble/types"
|
2026-01-19 17:44:49 +05:00
|
|
|
|
"fmt"
|
2026-01-26 17:46:17 +05:00
|
|
|
|
"github.com/charmbracelet/bubbles/key"
|
2025-12-26 17:45:37 +05:00
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2026-01-20 17:40:21 +05:00
|
|
|
|
// CheckboxModel структура описывающая модель выбора из двух состояний да и нет
|
2025-12-26 17:45:37 +05:00
|
|
|
|
type CheckboxModel struct {
|
2026-01-20 17:40:21 +05:00
|
|
|
|
label string //Имя поля
|
|
|
|
|
|
description string //Описание поля
|
|
|
|
|
|
checked bool //Выбранное состояние
|
2026-01-21 17:56:21 +05:00
|
|
|
|
validate types.BoolValidateFunc //Функция валидации
|
2026-01-20 17:40:21 +05:00
|
|
|
|
err error //Поле ошибки валидации
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-20 17:40:21 +05:00
|
|
|
|
// NewCheckboxModel создаем новую модель выбора
|
2026-01-21 17:56:21 +05:00
|
|
|
|
func NewCheckboxModel(label, description string, checked bool, validator types.BoolValidateFunc) *CheckboxModel {
|
2026-01-20 17:40:21 +05:00
|
|
|
|
checkbox := &CheckboxModel{
|
|
|
|
|
|
label: label,
|
2026-01-19 17:44:49 +05:00
|
|
|
|
description: description,
|
2026-01-20 17:40:21 +05:00
|
|
|
|
validate: validator,
|
|
|
|
|
|
checked: checked,
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
2026-01-21 17:56:21 +05:00
|
|
|
|
checkbox.CheckboxValidate()
|
2026-01-20 17:40:21 +05:00
|
|
|
|
return checkbox
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) Init() tea.Cmd {
|
|
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-20 17:40:21 +05:00
|
|
|
|
// Update отслеживает действия с полем
|
2025-12-26 17:45:37 +05:00
|
|
|
|
func (m *CheckboxModel) Update(msg tea.Msg) (FieldModel, tea.Cmd) {
|
|
|
|
|
|
switch msg := msg.(type) {
|
|
|
|
|
|
case tea.KeyMsg:
|
2026-01-20 17:40:21 +05:00
|
|
|
|
//Отслеживает нажатия клавиш.
|
2026-01-26 17:46:17 +05:00
|
|
|
|
switch {
|
|
|
|
|
|
case key.Matches(msg, types.MainKeys.Confirm):
|
|
|
|
|
|
//Если была нажата клавиша подтверждения, то меняем текущее значение на противоположное
|
2026-01-20 17:40:21 +05:00
|
|
|
|
m.checked = !m.checked
|
2026-01-21 17:56:21 +05:00
|
|
|
|
m.CheckboxValidate()
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return m, nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) View() string {
|
2026-01-20 17:40:21 +05:00
|
|
|
|
res := fmt.Sprintf("%s: ", m.label)
|
|
|
|
|
|
if m.checked {
|
2025-12-26 17:45:37 +05:00
|
|
|
|
res += "[x]"
|
|
|
|
|
|
} else {
|
|
|
|
|
|
res += "[ ]"
|
|
|
|
|
|
}
|
2026-01-20 17:40:21 +05:00
|
|
|
|
if m.err != nil {
|
|
|
|
|
|
res += fmt.Sprintf("\nОшибка валидации: %s", m.err)
|
|
|
|
|
|
} else if m.description != "" {
|
2026-01-19 17:44:49 +05:00
|
|
|
|
res += fmt.Sprintf("\n%s", m.description)
|
|
|
|
|
|
}
|
2025-12-26 17:45:37 +05:00
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) Focus() {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) Blur() {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) CaptureKeys() bool {
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) GetLabel() string {
|
2026-01-20 17:40:21 +05:00
|
|
|
|
return m.label
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) GetValue() interface{} {
|
2026-01-20 17:40:21 +05:00
|
|
|
|
return m.checked
|
2025-12-26 17:45:37 +05:00
|
|
|
|
}
|
2026-01-21 17:56:21 +05:00
|
|
|
|
|
|
|
|
|
|
func (m *CheckboxModel) CheckboxValidate() {
|
|
|
|
|
|
if m.validate != nil {
|
|
|
|
|
|
m.err = m.validate(m.checked)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|