Files
ilovetui/examples/layout/fullapp/main.go
T

89 lines
2.9 KiB
Go

// Command fullapp demonstrates a more realistic app shell: the sidebar
// leaf isn't a plain placeholder pane, it's a full layout.Model of its own
// (sidebar.New(), a themed list, see sidebar/sidebar.go) embedded exactly
// like the "router" one below - layout.Model implements Pane, so any
// package can hand back one to be wrapped in a Leaf, no adapter needed.
//
// It also owns the app's single notification.Model (see second/second.go,
// which triggers toasts via notification.Show without ever holding a
// reference to it) and composites its toasts over the whole rendered
// layout, top-right - notification has no dependency on layout, so this is
// the same Render(background string) pattern as examples/notification, just
// with layout.Model.View() as the background instead of a plain string.
//
// Same story for the app's single modal.Model (see third/third.go), except
// modal is composited last, on top of notif's own output: a modal is meant
// to command the whole screen's attention, so it should flatten any toast
// already showing to the same dim gray as everything else, not leave it
// floating on top in full color.
package main
import (
"fmt"
"os"
tea "charm.land/bubbletea/v2"
"github.com/anotherhadi/ilovetui/examples/layout/fullapp/router"
"github.com/anotherhadi/ilovetui/examples/layout/fullapp/sidebar"
"github.com/anotherhadi/ilovetui/layout"
"github.com/anotherhadi/ilovetui/modal"
"github.com/anotherhadi/ilovetui/notification"
)
// model is the actual top-level tea.Model: layout itself reserves no quit
// key (that's an app policy, not layout's to make), so the host wraps it
// and handles ctrl+c/q itself, same as any other custom component in this
// repo (see examples/tabs).
type model struct {
layout layout.Model
notif notification.Model
modal modal.Model
}
func (m model) Init() tea.Cmd {
return tea.Batch(m.layout.Init(), m.notif.Init(), m.modal.Init())
}
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if key, ok := msg.(tea.KeyPressMsg); ok {
switch key.String() {
case "ctrl+c", "q":
return m, tea.Quit
}
}
updated, layoutCmd := m.layout.Update(msg)
m.layout = updated.(layout.Model)
var notifCmd, modalCmd tea.Cmd
m.notif, notifCmd = m.notif.Update(msg)
m.modal, modalCmd = m.modal.Update(msg)
return m, tea.Batch(layoutCmd, notifCmd, modalCmd)
}
func (m model) View() tea.View {
view := tea.NewView(m.modal.Render(m.notif.Render(m.layout.View())))
view.AltScreen = true
return view
}
func main() {
root := layout.HSplit(0.25,
layout.Leaf("sidebar", sidebar.New()),
layout.Leaf("router", router.New()),
).WithMaximum(20)
m := model{
layout: layout.New(root, layout.AsRoot()),
notif: notification.New(notification.WithPosition(notification.TopRight)),
modal: modal.New(),
}
if _, err := tea.NewProgram(m).Run(); err != nil {
fmt.Println("Error running program:", err)
os.Exit(1)
}
}