diff --git a/commandmap.go b/commandmap.go index ab9481f..2ceeec4 100644 --- a/commandmap.go +++ b/commandmap.go @@ -90,7 +90,7 @@ func (cm *CommandMapping) RegisterViewCommands() { _, cellY := grid.CellPosition() dimX, _ := grid.Model().Dimensions() grid.MoveTo(dimX - 1, cellY) - })) + })) } // Registers the standard view key bindings. These commands require the frame @@ -112,6 +112,8 @@ func (cm *CommandMapping) RegisterViewKeyBindings() { cm.MapKey(ui.KeyArrowDown, cm.Command("move-down")) cm.MapKey(ui.KeyArrowLeft, cm.Command("move-left")) cm.MapKey(ui.KeyArrowRight, cm.Command("move-right")) + + cm.MapKey(':', cm.Command("enter-command")) } diff --git a/frame.go b/frame.go index a4b0f9f..ba24516 100644 --- a/frame.go +++ b/frame.go @@ -30,7 +30,7 @@ func NewFrame(uiManager *ui.Ui) *Frame { uiManager: uiManager, } - frame.grid = ui.NewGrid(&ui.TestModel{}) + frame.grid = ui.NewGrid(nil) frame.messageView = &ui.TextView{"Hello"} frame.statusBar = &ui.StatusBar{"Test", "Status"} frame.textEntrySwitch = &ui.ProxyLayout{frame.messageView} @@ -50,6 +50,11 @@ func (frame *Frame) RootComponent() ui.UiComponent { return frame.clientArea } +// Sets the current model of the frame +func (frame *Frame) SetModel(model ui.GridModel) { + frame.grid.SetModel(model) +} + // Returns the grid component func (frame *Frame) Grid() *ui.Grid { return frame.grid diff --git a/main.go b/main.go index 5cbfad7..df39621 100644 --- a/main.go +++ b/main.go @@ -11,39 +11,13 @@ func main() { } defer uiManager.Close() + model := &StdModel{} + frame := NewFrame(uiManager) - NewSession(frame) + NewSession(frame, model) uiManager.SetRootComponent(frame.RootComponent()) frame.EnterMode(GridMode) uiManager.Loop() -/* - cmdText := &ui.TextEntry{Prompt: "Enter: "} - - statusLayout := &ui.VertLinearLayout{} - statusLayout.Append(&ui.StatusBar{"Test", "Component"}) - statusLayout.Append(cmdText) - //statusLayout.Append(&ui.StatusBar{"Another", "Component"}) - //statusLayout.Append(&ui.StatusBar{"Third", "Test"}) - - grid := ui.NewGrid(&ui.TestModel{}) - - clientArea := &ui.RelativeLayout{ Client: grid, South: statusLayout } - - uiManager.SetRootComponent(clientArea) - uiManager.SetFocusedComponent(grid) - //uiManager.SetFocusedComponent(cmdText) - - uiManager.Loop() -*/ - /* - uiCtx, _ := NewUI() - - uiCtx.Redraw() - uiCtx.NextEvent() - - uiCtx.Close() - fmt.Printf("OK!") - */ } diff --git a/model.go b/model.go index 5e2f0ab..9a9d48e 100644 --- a/model.go +++ b/model.go @@ -5,12 +5,28 @@ package main /** - * An abstract model interface. + * An abstract model interface. At a minimum, models must be read only. */ type Model interface { /** - * The dimensions of the model (width, height). + * The dimensions of the model (height, width). */ - GetDimensions() (int, int) + Dimensions() (int, int) + + /** + * Returns the value of a cell. + */ + CellValue(r, c int) string +} + +// A read/write model. +type RWModel interface { + Model + + // Resize the model. + Resize(newRow, newCol int) + + // Sets the cell value + SetCellValue(r, c int, value string) } diff --git a/session.go b/session.go index 2028966..fc374ba 100644 --- a/session.go +++ b/session.go @@ -5,16 +5,20 @@ import "./ui" // The session is responsible for managing the UI and the model and handling // the interaction between the two and the user. type Session struct { + Model Model Frame *Frame Commands *CommandMapping } -func NewSession(frame *Frame) *Session { +func NewSession(frame *Frame, model Model) *Session { session := &Session{ + Model: model, Frame: frame, Commands: NewCommandMapping(), } + frame.SetModel(&SessionGridModel{session}) + session.Commands.RegisterViewCommands() session.Commands.RegisterViewKeyBindings() @@ -48,4 +52,32 @@ type SessionCommandContext struct { func (scc SessionCommandContext) Frame() *Frame { return scc.Session.Frame -} \ No newline at end of file +} + + + +// Session grid model +type SessionGridModel struct { + Session *Session +} + +// Returns the size of the grid model (width x height) +func (sgm *SessionGridModel) Dimensions() (int, int) { + rs, cs := sgm.Session.Model.Dimensions() + return cs, rs +} + +// Returns the size of the particular column. If the size is 0, this indicates that the column is hidden. +func (sgm *SessionGridModel) ColWidth(int) int { + return 24 +} + +// Returns the size of the particular row. If the size is 0, this indicates that the row is hidden. +func (sgm *SessionGridModel) RowHeight(int) int { + return 1 +} + +// Returns the value of the cell a position X, Y +func (sgm *SessionGridModel) CellValue(x int, y int) string { + return sgm.Session.Model.CellValue(y, x) +} diff --git a/stdmodel.go b/stdmodel.go new file mode 100644 index 0000000..3faacda --- /dev/null +++ b/stdmodel.go @@ -0,0 +1,58 @@ +package main + +// Cell +type Cell struct { + Value string +} + +// Standard model +type StdModel struct { + Cells [][]Cell +} + +/** + * The dimensions of the model (height, width). + */ +func (sm *StdModel) Dimensions() (int, int) { + if len(sm.Cells) == 0 { + return 0, 0 + } else { + return len(sm.Cells), len(sm.Cells[0]) + } +} + +/** + * Returns the value of a cell. + */ +func (sm *StdModel) CellValue(r, c int) string { + rs, cs := sm.Dimensions() + if (r >= 0) && (c >= 0) && (r < rs) && (c < cs) { + return sm.Cells[r][c].Value + } else { + return "" + } +} + +// Resize the model. +func (sm *StdModel) Resize(rs, cs int) { + oldRowCount := len(sm.Cells) + + newRows := make([][]Cell, rs) + for r := range newRows { + newCols := make([]Cell, cs) + if r < oldRowCount { + copy(newCols, sm.Cells[r]) + } + newRows[r] = newCols + } + + sm.Cells = newRows +} + +// Sets the cell value +func (sm *StdModel) SetCellValue(r, c int, value string) { + rs, cs := sm.Dimensions() + if (r >= 0) && (c >= 0) && (r < rs) && (c < cs) { + sm.Cells[r][c].Value = value + } +} \ No newline at end of file diff --git a/ui/grid.go b/ui/grid.go index cb09a55..92ead9a 100644 --- a/ui/grid.go +++ b/ui/grid.go @@ -78,6 +78,11 @@ func (grid *Grid) Model() GridModel { return grid.model } +// Sets the model +func (grid *Grid) SetModel(model GridModel) { + grid.model = model +} + /** * Shifts the viewport of the grid. */