sampler-fork/widgets/layout.go

197 lines
4.6 KiB
Go

package widgets
import (
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/widgets/runchart"
ui "github.com/sqshq/termui"
)
type Layout struct {
ui.Block
components []Component
menu *Menu
mode Mode
selection int
}
type Mode rune
const (
ModeDefault Mode = 0
ModeComponentSelect Mode = 1
ModeMenuOptionSelect Mode = 2
ModeComponentMove Mode = 3
ModeComponentResize Mode = 4
ModeChartPinpoint Mode = 5
)
const (
columnsCount = 30
rowsCount = 30
)
func NewLayout(width, height int, menu *Menu) *Layout {
block := *ui.NewBlock()
block.SetRect(0, 0, width, height)
return &Layout{
Block: block,
components: make([]Component, 0),
menu: menu,
mode: ModeDefault,
selection: 0,
}
}
func (l *Layout) AddComponent(drawable ui.Drawable, title string, position Position, size Size, Type ComponentType) {
l.components = append(l.components, Component{drawable, title, position, size, Type})
}
func (l *Layout) GetComponents(Type ComponentType) []ui.Drawable {
var components []ui.Drawable
for _, component := range l.components {
if component.Type == Type {
components = append(components, component.Drawable)
}
}
return components
}
func (l *Layout) HandleConsoleEvent(e string) {
switch e {
case console.KeyEnter:
switch l.mode {
case ModeComponentSelect:
l.menu.choose()
l.mode = ModeMenuOptionSelect
case ModeMenuOptionSelect:
option := l.menu.getSelectedOption()
switch option {
case MenuOptionMove:
l.mode = ModeComponentMove
l.menu.moveOrResize()
case MenuOptionResize:
l.mode = ModeComponentResize
l.menu.moveOrResize()
case MenuOptionPinpoint:
l.mode = ModeChartPinpoint
l.menu.idle()
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
chart.MoveSelection(0)
case MenuOptionResume:
l.mode = ModeDefault
l.menu.idle()
}
case ModeComponentMove:
fallthrough
case ModeComponentResize:
l.menu.idle()
l.mode = ModeDefault
}
case console.KeyEsc:
switch l.mode {
case ModeChartPinpoint:
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
chart.DisableSelection()
fallthrough
case ModeComponentSelect:
fallthrough
case ModeMenuOptionSelect:
l.menu.idle()
l.mode = ModeDefault
}
case console.KeyLeft:
switch l.mode {
case ModeDefault:
l.mode = ModeComponentSelect
l.selection = 0
l.menu.highlight(l.getComponent(l.selection))
case ModeChartPinpoint:
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
chart.MoveSelection(-1)
case ModeComponentSelect:
if l.selection > 0 {
l.selection--
}
l.menu.highlight(l.getComponent(l.selection))
case ModeComponentMove:
l.getSelectedComponent().Move(-1, 0)
case ModeComponentResize:
l.getSelectedComponent().Resize(-1, 0)
}
case console.KeyRight:
switch l.mode {
case ModeDefault:
l.mode = ModeComponentSelect
l.selection = 0
l.menu.highlight(l.getComponent(l.selection))
case ModeChartPinpoint:
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
chart.MoveSelection(1)
case ModeComponentSelect:
if l.selection < len(l.components)-1 {
l.selection++
}
l.menu.highlight(l.getComponent(l.selection))
case ModeComponentMove:
l.getSelectedComponent().Move(1, 0)
case ModeComponentResize:
l.getSelectedComponent().Resize(1, 0)
}
case console.KeyUp:
switch l.mode {
case ModeMenuOptionSelect:
l.menu.up()
case ModeComponentMove:
l.getSelectedComponent().Move(0, -1)
case ModeComponentResize:
l.getSelectedComponent().Resize(0, -1)
}
case console.KeyDown:
switch l.mode {
case ModeMenuOptionSelect:
l.menu.down()
case ModeComponentMove:
l.getSelectedComponent().Move(0, 1)
case ModeComponentResize:
l.getSelectedComponent().Resize(0, 1)
}
}
}
func (l *Layout) ChangeDimensions(width, height int) {
l.SetRect(0, 0, width, height)
}
// TODO func to get prev/next component navigating left/right/top/bottom
func (l *Layout) getComponent(i int) Component {
return l.components[i]
}
func (l *Layout) getSelectedComponent() *Component {
return &l.components[l.selection]
}
func (l *Layout) Draw(buffer *ui.Buffer) {
columnWidth := float64(l.GetRect().Dx()) / columnsCount
rowHeight := float64(l.GetRect().Dy()) / rowsCount
for _, component := range l.components {
x1 := float64(component.Position.X) * columnWidth
y1 := float64(component.Position.Y) * rowHeight
x2 := x1 + float64(component.Size.X)*columnWidth
y2 := y1 + float64(component.Size.Y)*rowHeight
component.Drawable.SetRect(int(x1), int(y1), int(x2), int(y2))
component.Drawable.Draw(buffer)
}
l.menu.Draw(buffer)
}