I'm looking for the best way to propagate model updates to the GUI, using a "classic" (as in: non reactive functional) GUI toolkit: Terminal.GUI. Currently I have this code (simplified):
type Tui(state: StateManager) =
let state = state
let window = Window(bla bla bla)
let lblPath = Label(bla bla bla)
let lstView =
{ new ListView(bla bla bla) with
member this.ProcessKey(k: KeyEvent) =
let updateViews() =
Application.MainLoop.Invoke(fun () ->
this.SetSource model.CurrentState.LstData
lblPath.Text <- ustr model.CurrentState.CurrPath)
match k.Key with
| Key.CursorRight ->
state.changeTheState()
updateViews()
true
| _ -> true }
do
Application.Init()
// add all GUI components: window.add(lblPath), etc
Application.Run()
// XXX repetition of updateViews() above!
Application.MainLoop.Invoke(fun () ->
lstView.SetSource model.CurrentState.LstData
lblPath.Text <- ustr model.CurrentState.CurrPath)
The issue here is that the code to update the view components is duplicated. I believe this is because:
- in that
ProcessKeymethod of theListViewobject expression I cannot access any external method of the Tui class (this is probably also because F# compiler is one-pass only (?)) - outside that method I cannot access the
updateViewfunction
Is there a better way of doing this that would avoid code repetition? Am I using the wrong pattern GUI update pattern?
(Complete code is here)