From a7add69f1840a7737618ba76c1989dd45c44b671 Mon Sep 17 00:00:00 2001 From: lash Date: Sat, 8 Apr 2023 11:31:05 +0100 Subject: [PATCH] Add menu browse display conditional on state --- go/resource/resource.go | 44 +++++++++++++++++++++++++---- go/resource/state.go | 23 ++++++++++++--- go/resource/state_test.go | 59 +++++++++++++++++++++++++++++++++++++++ go/state/state.go | 9 ++++-- 4 files changed, 123 insertions(+), 12 deletions(-) diff --git a/go/resource/resource.go b/go/resource/resource.go index d10ef95..1842b6d 100644 --- a/go/resource/resource.go +++ b/go/resource/resource.go @@ -18,7 +18,6 @@ type Resource interface { GetTemplate(sym string, sizer *Sizer) (string, error) // Get the template for a given symbol. GetCode(sym string) ([]byte, error) // Get the bytecode for the given symbol. PutMenu(string, string) error // Add a menu item. - ShiftMenu() (string, string, error) // Remove and return the first menu item in list. SetMenuBrowse(string, string, bool) error // Set menu browser display details. RenderTemplate(sym string, values map[string]string, idx uint16, sizer *Sizer) (string, error) // Render the given data map using the template of the symbol. RenderMenu() (string, error) // Render the current state of menu @@ -30,6 +29,8 @@ type MenuResource struct { menu [][2]string next [2]string prev [2]string + canNext bool + canPrev bool sinkValues []string codeFunc CodeFunc templateFunc TemplateFunc @@ -68,12 +69,22 @@ func(m *MenuResource) SetMenuBrowse(selector string, title string, back bool) er entry := [2]string{selector, title} if back { m.prev = entry + m.canPrev = true } else { m.next = entry + m.canNext = true } return nil } +//func(m *MenuResource) putNext() error { +// return m.PutMenu(m.next[0], m.next[1]) +//} +// +//func(m *MenuResource) putPrevious() error { +// return m.PutMenu(m.prev[0], m.prev[1]) +//} + // PutMenu adds a menu option to the menu rendering. func(m *MenuResource) PutMenu(selector string, title string) error { m.menu = append(m.menu, [2]string{selector, title}) @@ -81,10 +92,9 @@ func(m *MenuResource) PutMenu(selector string, title string) error { return nil } -// PutMenu removes and returns the first of remaining menu options. -// -// Fails if menu is empty. -func(m *MenuResource) ShiftMenu() (string, string, error) { +// removes and returns the first of remaining menu options. +// fails if menu is empty. +func(m *MenuResource) shiftMenu() (string, string, error) { if len(m.menu) == 0 { return "", "", fmt.Errorf("menu is empty") } @@ -93,14 +103,36 @@ func(m *MenuResource) ShiftMenu() (string, string, error) { return r[0], r[1], nil } +// add available browse options. +func(m *MenuResource) applyPage() error { + if m.canNext { + err := m.PutMenu(m.next[0], m.next[1]) + if err != nil { + return err + } + } + if m.canPrev { + err := m.PutMenu(m.prev[0], m.prev[1]) + if err != nil { + return err + } + } + return nil +} + // RenderMenu returns the full current state of the menu as a string. // // After this has been executed, the state of the menu will be empty. func(m *MenuResource) RenderMenu() (string, error) { + err := m.applyPage() + if err != nil { + return "", err + } + r := "" for true { l := len(r) - choice, title, err := m.ShiftMenu() + choice, title, err := m.shiftMenu() if err != nil { break } diff --git a/go/resource/state.go b/go/resource/state.go index 5b0b8de..c535ff3 100644 --- a/go/resource/state.go +++ b/go/resource/state.go @@ -20,10 +20,25 @@ func NewStateResource(st *state.State) *StateResource { } } -func(s *StateResource) WithState(st *state.State) *StateResource { - if s.st != nil { +func(sr *StateResource) WithState(st *state.State) *StateResource { + if sr.st != nil { panic("state already set") } - s.st = st - return s + sr.st = st + return sr +} + +func(sr *StateResource) SetMenuBrowse(selector string, title string, back bool) error { + var err error + next, prev := sr.st.Sides() + + if back { + if prev { + err = sr.Resource.SetMenuBrowse(selector, title, true) + } + } else if next { + err = sr.Resource.SetMenuBrowse(selector, title, false) + + } + return err } diff --git a/go/resource/state_test.go b/go/resource/state_test.go index b743958..6fe5e97 100644 --- a/go/resource/state_test.go +++ b/go/resource/state_test.go @@ -12,3 +12,62 @@ func TestStateResourceInit(t *testing.T) { _ = ToStateResource(rs).WithState(&st) _ = NewStateResource(&st) } + +func TestStateBrowse(t *testing.T) { + st := state.NewState(0) + st.Down("root") + + rs := NewStateResource(&st) + rs.PutMenu("1", "foo") + rs.PutMenu("2", "bar") + err := rs.SetMenuBrowse("11", "next", false) + if err != nil { + t.Fatal(err) + } + err = rs.SetMenuBrowse("22", "prev", true) + if err != nil { + t.Fatal(err) + } + s, err := rs.RenderMenu() + if err != nil { + t.Fatal(err) + } + + expect := `1:foo +2:bar +11:next` + if s != expect { + t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, s) + } + + idx, err := st.Next() + if err != nil { + t.Fatal(err) + } + if idx != 1 { + t.Fatalf("expected idx 1, got %v", idx) + } + rs = NewStateResource(&st) + rs.PutMenu("1", "foo") + rs.PutMenu("2", "bar") + err = rs.SetMenuBrowse("11", "next", false) + if err != nil { + t.Fatal(err) + } + err = rs.SetMenuBrowse("22", "prev", true) + if err != nil { + t.Fatal(err) + } + s, err = rs.RenderMenu() + if err != nil { + t.Fatal(err) + } + + expect = `1:foo +2:bar +11:next +22:prev` + if s != expect { + t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", expect, s) + } +} diff --git a/go/state/state.go b/go/state/state.go index 1f73f44..ae1ca64 100644 --- a/go/state/state.go +++ b/go/state/state.go @@ -204,7 +204,7 @@ func(st State) WithOutputSize(outputSize uint32) State { } // Where returns the current active rendering symbol. -func(st State) Where() (string, uint16) { +func(st *State) Where() (string, uint16) { if len(st.execPath) == 0 { return "", 0 } @@ -213,11 +213,13 @@ func(st State) Where() (string, uint16) { } // Next moves to the next sink page index. -func(st State) Next() (uint16, error) { +func(st *State) Next() (uint16, error) { if len(st.execPath) == 0 { return 0, fmt.Errorf("state root node not yet defined") } st.sizeIdx += 1 + s, idx := st.Where() + log.Printf("next page for %s: %v", s, idx) return st.sizeIdx, nil } @@ -232,6 +234,8 @@ func(st *State) Previous() (uint16, error) { return 0, fmt.Errorf("already at first index") } st.sizeIdx -= 1 + s, idx := st.Where() + log.Printf("previous page for %s: %v", s, idx) return st.sizeIdx, nil } @@ -243,6 +247,7 @@ func(st *State) Sides() (bool, bool) { return false, false } next := true + log.Printf("sides %v", st.sizeIdx) if st.sizeIdx == 0 { return next, false }