win_default.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // package win_default -- окно по умолчанию
  2. package win_default
  3. import (
  4. "fmt"
  5. tea "github.com/charmbracelet/bubbletea"
  6. "wartank/desktop/win_base"
  7. "wartank/pkg/cons"
  8. "wartank/pkg/types"
  9. )
  10. // WinDefault -- окно по умолчанию
  11. type WinDefault struct {
  12. *win_base.WinBase
  13. cursor int // позиция курсора в списке
  14. choices []string // выбранный пункт в списке
  15. selected map[int]struct{} // что выбрано из списка
  16. model tea.Model // Модель для обработки
  17. }
  18. // NewWinDefault -- возвращает новое окно по умолчанию
  19. func NewWinDefault(desk types.IDesktop) (*WinDefault, error) {
  20. winBase, err := win_base.NewWinBase(desk, cons.WinDefault)
  21. if err != nil {
  22. return nil, fmt.Errorf("NewWinDefault(): in create IWinBase, err=\n\t%w", err)
  23. }
  24. sf := &WinDefault{
  25. WinBase: winBase,
  26. // Список дел
  27. choices: []string{"Купить картошку", "Оплатить мобилку", "Заплатить за кредит"},
  28. selected: make(map[int]struct{}),
  29. }
  30. return sf, nil
  31. }
  32. // Update -- обрабатывает команду цикла
  33. func (sf *WinDefault) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
  34. isMsg := false
  35. switch msg := msg.(type) {
  36. // Может клавиша нажата
  37. case tea.KeyMsg:
  38. switch msg.String() { // Да, нажато, а что именно?
  39. case "up", "k": // Если "up" или "k" перемещение курсора вверх
  40. if sf.cursor > 0 {
  41. sf.cursor--
  42. isMsg = true
  43. }
  44. case "down", "j": // Если "down" или "j" перемещение курсора вниз
  45. if sf.cursor < len(sf.choices)-1 {
  46. sf.cursor++
  47. isMsg = true
  48. }
  49. case "enter", " ": // Нажатие "enter" или "пробел" переключает выбранный элемент списка
  50. _, ok := sf.selected[sf.cursor]
  51. if ok {
  52. delete(sf.selected, sf.cursor)
  53. } else {
  54. sf.selected[sf.cursor] = struct{}{}
  55. }
  56. isMsg = true
  57. case "w": // Настройки графического клиента
  58. sf.Desk().SetWin(cons.WinConfig)
  59. }
  60. }
  61. if isMsg {
  62. sf.Desk().SetWin(sf.Name())
  63. return sf.model, nil
  64. }
  65. return nil, nil
  66. }
  67. // View -- перерисовывание окна по требованию
  68. func (sf *WinDefault) View() string {
  69. // Заголовок
  70. s := "Что нам нужно сделать?\n\n"
  71. // Перебор по списку выбора
  72. for i, choice := range sf.choices {
  73. // Курсор указывает на этот выбор?
  74. cursor := " " // нет курсора
  75. if sf.cursor == i {
  76. cursor = ">" // есть курсор
  77. }
  78. // Этот элемент выбран?
  79. checked := " " // не выбран
  80. if _, ok := sf.selected[i]; ok {
  81. checked = "+" // выбран!
  82. }
  83. // отрендерить заново
  84. s += fmt.Sprintf("%s [%s] %s\n", cursor, checked, choice)
  85. }
  86. // Подвал
  87. s += "\n\n[ctrl+q]-выход [w]-настройки\n"
  88. // Вернуть строку экрана для отрисовки
  89. return s
  90. }