Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Commit

Permalink
switch view state
Browse files Browse the repository at this point in the history
  • Loading branch information
ingbyr committed Sep 6, 2022
1 parent e867b6a commit e11f846
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 60 deletions.
26 changes: 14 additions & 12 deletions tui/text_view.go → tui/editor_view.go
@@ -1,46 +1,48 @@
package tui

import (
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/textarea"
tea "github.com/charmbracelet/bubbletea"
)

type TextView struct {
type EditorView struct {
model *Model
HostTextarea textarea.Model
}

func NewTextView(model *Model) *TextView {
func NewTextView(model *Model) *EditorView {
t := textarea.New()
t.ShowLineNumbers = true
t.Placeholder = "Host items here"
t.Focus()
return &TextView{
return &EditorView{
model: model,
HostTextarea: textarea.New(),
}
}

func (v *TextView) Init() tea.Cmd {
func (v *EditorView) Init() tea.Cmd {
return nil
}

func (v *TextView) Update(msg tea.Msg) []tea.Cmd {
func (v *EditorView) Update(msg tea.Msg) []tea.Cmd {
var cmd tea.Cmd
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
v.HostTextarea.SetHeight(msg.Height - 10)
v.HostTextarea.SetHeight(msg.Height - v.model.helpView.MaxHeight())
v.HostTextarea.SetWidth(msg.Width - v.model.groupView.groupList.Width())
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
if v.model.state == editorViewState {
v.HostTextarea, cmd = v.HostTextarea.Update(msg)
}
}
v.HostTextarea, cmd = v.HostTextarea.Update(msg)
return append(cmds, cmd)
}

func (v *TextView) View() string {
func (v *EditorView) View() string {
return v.HostTextarea.View()
}

func (v *EditorView) Focus() {
v.HostTextarea.Focus()
}
55 changes: 34 additions & 21 deletions tui/group_view.go
Expand Up @@ -54,6 +54,8 @@ type GroupView struct {
groupList list.Model
selectedNode *gohost.Node[gohost.TreeNode]
selectedIndex int
selectedGroup gohost.Group
selectedHost gohost.Host

service *gohost.Service
}
Expand Down Expand Up @@ -83,61 +85,64 @@ func (v *GroupView) Init() tea.Cmd {
}

func (v *GroupView) Update(msg tea.Msg) []tea.Cmd {

var cmd tea.Cmd
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.WindowSizeMsg:
v.groupList.SetHeight(msg.Height - v.model.helpView.MaxHeight())
v.groupList.SetWidth(msg.Width)
// FIXME not work
v.groupList.SetWidth(msg.Width / 3)
v.model.helpView.debug = fmt.Sprintf("w %d h %d, w %d h %d", msg.Width, msg.Height, v.groupList.Width(), v.groupList.Height())
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Enter):
selectedItem := v.groupList.SelectedItem()
if selectedItem != nil {
v.selectedNode = selectedItem.(*gohost.Node[gohost.TreeNode])
v.selectedIndex = v.groupList.Index()
switch node := v.selectedNode.Data.(type) {
case gohost.Group:
cmds = v.onGroupNodeEnterClick(cmds)
v.selectedNode.IsFolded = !v.selectedNode.IsFolded
case gohost.Host:
v.groupList.Title = "select host " + node.GetName()
if v.model.state == groupViewState {
switch {
case key.Matches(msg, keys.Enter):
selectedItem := v.groupList.SelectedItem()
if selectedItem != nil {
v.selectedNode = selectedItem.(*gohost.Node[gohost.TreeNode])
v.selectedIndex = v.groupList.Index()
switch v.selectedNode.Data.(type) {
case gohost.Group:
v.onGroupNodeEnterClick(&cmds)
case gohost.Host:
v.onHostNodeSelected(&cmds)
}
}
}
v.groupList, cmd = v.groupList.Update(msg)
}
}

v.groupList, cmd = v.groupList.Update(msg)
return append(cmds, cmd)
}

func (v *GroupView) View() string {
return v.groupList.View()
}

func (v *GroupView) onGroupNodeEnterClick(cmds []tea.Cmd) []tea.Cmd {
func (v *GroupView) onGroupNodeEnterClick(cmds *[]tea.Cmd) {
v.selectedGroup = v.selectedNode.Data.(gohost.Group)
if v.selectedNode.IsFolded {
cmds = v.unfoldSelectedGroup(cmds)
v.unfoldSelectedGroup(cmds)
} else {
v.foldSelectedGroup()
}
return cmds
v.selectedNode.IsFolded = !v.selectedNode.IsFolded
}

func (v *GroupView) unfoldSelectedGroup(cmds []tea.Cmd) []tea.Cmd {
func (v *GroupView) unfoldSelectedGroup(cmds *[]tea.Cmd) {
subGroups := v.service.ChildNodes(v.selectedNode.GetID())
idx := v.selectedIndex
for i := range subGroups {
idx++
cmds = append(cmds, v.groupList.InsertItem(idx, subGroups[i]))
*cmds = append(*cmds, v.groupList.InsertItem(idx, subGroups[i]))
}
subHosts := v.service.LoadHostNodes(v.selectedNode.GetID())
for i := range subHosts {
idx++
cmds = append(cmds, v.groupList.InsertItem(idx, subHosts[i]))
*cmds = append(*cmds, v.groupList.InsertItem(idx, subHosts[i]))
}
return cmds
}

func (v *GroupView) foldSelectedGroup() {
Expand All @@ -156,3 +161,11 @@ func (v *GroupView) foldSelectedGroup() {
}
}
}

func (v *GroupView) onHostNodeSelected(cmds *[]tea.Cmd) {
// TODO display host content
v.selectedHost = v.selectedNode.Data.(gohost.Host)
v.model.Log("select host: " + v.selectedHost.GetName())
v.model.SwitchState(editorViewState)
v.model.editorView.HostTextarea.Placeholder = "abc"
}
2 changes: 1 addition & 1 deletion tui/help_view.go
Expand Up @@ -46,7 +46,7 @@ func (h *HelpView) View() string {
}

func (h *HelpView) MaxHeight() int {
return 5
return 6
}

func (h *HelpView) Width() int {
Expand Down
20 changes: 13 additions & 7 deletions tui/keymap.go
Expand Up @@ -3,13 +3,14 @@ package tui
import "github.com/charmbracelet/bubbles/key"

type keyMaps struct {
Up key.Binding
Down key.Binding
Left key.Binding
Right key.Binding
Help key.Binding
Quit key.Binding
Enter key.Binding
Up key.Binding
Down key.Binding
Left key.Binding
Right key.Binding
Help key.Binding
Quit key.Binding
Enter key.Binding
Switch key.Binding
}

func newKeys() keyMaps {
Expand Down Expand Up @@ -42,6 +43,10 @@ func newKeys() keyMaps {
key.WithKeys("enter"),
key.WithHelp("enter", "select or confirm"),
),
Switch: key.NewBinding(
key.WithKeys("tab"),
key.WithHelp("tab", "switch view"),
),
}
}

Expand All @@ -53,6 +58,7 @@ func (k keyMaps) FullHelp() [][]key.Binding {
return [][]key.Binding{
{k.Up, k.Down}, // column
{k.Left, k.Right},
{k.Switch},
{k.Help, k.Quit},
}
}
57 changes: 38 additions & 19 deletions tui/model.go
Expand Up @@ -5,38 +5,38 @@ import (
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"strconv"
"strings"
)

type sessionState uint
type sessionState int

const (
groupViewState = iota
editorViewState
sysHostViewState
lastState
)

var (
modelStyle = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.HiddenBorder())
//focusedModelStyle = lipgloss.NewStyle().Padding(1, 2).BorderStyle(lipgloss.NormalBorder()).BorderForeground(lipgloss.Color("69"))
keys = newKeys()
modelStyle = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.HiddenBorder())
focusedModelStyle = lipgloss.NewStyle().PaddingLeft(1).PaddingRight(1).BorderStyle(lipgloss.NormalBorder()).BorderForeground(lipgloss.Color("69"))
keys = newKeys()
)

type Model struct {
state sessionState
helpView *HelpView
groupView *GroupView
textView *TextView
quitting bool
state sessionState
helpView *HelpView
groupView *GroupView
editorView *EditorView
quitting bool
}

func NewModel() (*Model, error) {
model := &Model{
state: groupViewState,
state: 0,
}
model.helpView = NewHelpView(model)
model.groupView = NewGroupView(model)
model.textView = NewTextView(model)
model.editorView = NewTextView(model)
return model, nil
}

Expand All @@ -50,13 +50,15 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.WindowSizeMsg:
case tea.KeyMsg:
switch {
case key.Matches(msg, keys.Switch):
m.switchNextState()
case key.Matches(msg, keys.Quit):
m.quitting = true
cmds = append(cmds, tea.Quit)
}
}
cmds = append(cmds, m.groupView.Update(msg)...)
cmds = append(cmds, m.textView.Update(msg)...)
cmds = append(cmds, m.editorView.Update(msg)...)
cmds = append(cmds, m.helpView.Update(msg)...)
return m, tea.Batch(cmds...)
}
Expand All @@ -65,14 +67,31 @@ func (m *Model) View() string {
var str string
switch m.state {
case groupViewState:
str += lipgloss.JoinHorizontal(lipgloss.Top,
str = lipgloss.JoinHorizontal(lipgloss.Top,
focusedModelStyle.Render(m.groupView.View()),
modelStyle.Render(m.editorView.View()))
case editorViewState:
str = lipgloss.JoinHorizontal(lipgloss.Top,
modelStyle.Render(m.groupView.View()),
modelStyle.Render(m.textView.View()))
focusedModelStyle.Render(m.editorView.View()))
}
//str += "\n" + m.debug
helperStr := m.helpView.View()
helperHeight := strings.Count(helperStr, "\n")
m.helpView.debug = strconv.Itoa(helperHeight)
str = lipgloss.JoinVertical(lipgloss.Left, str, m.helpView.View())
return str
}

func (m *Model) Log(msg string) {
m.helpView.debug = msg
}

func (m *Model) switchNextState() sessionState {
m.SwitchState((m.state + 1) % lastState)
m.Log("state:" + strconv.Itoa(int(m.state)))
return m.state
}

func (m *Model) SwitchState(state sessionState) {
if state == editorViewState {
m.editorView.Focus()
}
m.state = state
}

0 comments on commit e11f846

Please sign in to comment.