-
Notifications
You must be signed in to change notification settings - Fork 6
Changing GUI code in the renderer
- Run Visual2 via
yarn launch
- Open developer tools window:
View->Toggle Dev Tools
. - This will be remembered on hot reload.
- View the *console window` tab - this is normally open by default.
- That will alert you to fatal code errors from
failwithf
or an unsafe F# constructlst.Tail
etc. It will also allow you to view printout viaprintf
etc.
When code is running under the renderer in the electron GUI failwithf
in code does not (usually) terminate the GUI. It terminates the specific action being executed and typically what you observe is nothing happening.
Debugging code in the Renderer it is therefore a good idea to have browser developer tools (dev tools) open.
If the app hangs on startup for any reason you cannot open dev tools normally.
- Kills the
yarn launch
process with Ctrl-C followed byY
in the console window - restart with yarn launch -D
The crash will be reported in the dev tools console window.
Especially to debug a crash you may need to trace execution. Add printfn
to anywhere in the code to get dev tools console printout.
See the Wiki page on the F# / FABLE / electron framework for writing desktop apps using HTML and CSS.
- Start Visual2 via
yarn launch
- View -> Toggle Dev Tools
- Make dev tools pane large
- Select Elements tab in dev tools pane
- open nodes as needed to explore DOM tree
- click on a node to select and view all its classes and styles
- click top leftmost button in dev tools pane (Elements tab) to select DOM node by using mouse over and/or click on element in Visual2 window.
The Visual2 GUI is defined by:
-
CSS with most of the custom Visual2 CSS in
vistally.css
-
Fable.import.Browser.document
top-level DOM node of the main window: accessible from F# as F# type HTMLElement. - HTML with the initial skeleton defined statically in the index.html file.
- DOM elements defined dynamically for the memory and symbols parts of the View pane by functions in views.fs using DOM create and mutate convenience functions defined in Refs.fs
- References to useful DOM elements in the skeleton (Buttons etc) are defined in Refs.fs using
getHTML
which locates a - listeners attached to html elements (to implement button clicks) are defined in Renderer.fs
In addition the editor window is implemented by the Monaco Editor JS component.
- The Monaco Playground shows how to interact with editor windows.
- The tab headings above each editor buffer are defined dynamically in tabs.fs.
- The editors themselves (needed to interact with characters) are kept in an F# global
Refs.editors
which maps numeric tab ids to editors. There is one editor (and one file) for each tab, but only the current tab is actually visible.
The DOM nodes with text content can have text overwritten, new child DOM nodes can be added to any node, etc. Generally it is good practice, where possible, to create new DOM functionally, without mutating nodes, and insert it into the visible document just once.
To prevent performance issues (for example the Views memory tab display). It is possible to cache inputs that change the DOM and where they have not changed, even when a new screen write is required, simply leave the existing DOM unchanged. This is done to great effect in the memory generation code.
It is good practice to have a small number of mutable variable that represent the entire app state and write out the entire DOM from them with pure functions. Visual2 almost keeps to this, with mutable values all shown in Refs.fs
. However some elements, like tab names, are written whenever they are changed (typically by file load/save), rather than whenever the screen is refreshed. This is probably not the cleanest solution but because tab changes are fairly isolated it works OK.
Visual2 is not consistent when it comes to tabs, where some of the app state (the file names of each loaded file) is actually stored in the DOM itself rather than in an F# variable. Convenience functions in Refs.fs
access this state, but it is bad practice and that whole section of code should be rewritten, a painful exercise.
A module GuiExamples containing sample GUI code has been added to branch hlp2019-test
.