This removes the limitation of having a hard-coded maximum number of
entries. There is no cost to code size. Iteration speed across Qnav
blocks may be slightly slower, because the elements are allocated in
arbitrary heap locations, which may prevent the next item from being
prefetched across links. But, there are rarely more than 3 entries, and
most of the time there are 0 entries. Iteration occurs only when
redrawing the Qnav blocks and when quitting.
We use a doubly linked list instead of singly linked because we need
quick access to the top entry while also needing to iterate from the
bottom to top when drawing the entries.
An equivalent implementation with a stretchy/dynamic array of pointers
was made, but the code size was larger and required more error checks
and an extra heap allocation.
A theoretical implementation that wants to reduce heap fragmentation
could use a contiguous or slab allocation of multiple Qnav blocks/items.
This would probably require more code, but may be worth it if this
menuing/widget system is extended for reuse across projects in the
future.
For now, we separately heap allocate each Qnav item and link them
together. Not great, but we don't have to worry about picking an
arbitrary count for an array of pointers, and we aren't increasing the
code size or complexity. Those are important things for this project.
This commit implements the Qnav/Qmenu system directly in ncurses,
replacing the old implementation which relied on the 'menu' library.
The new code is shorter, easier to read, and doesn't need the 'menu'
library to be linked.
For users, the behavior of the menus should be the same.
We still rely on the 'form' library for text field input in the menus.
`sdd` was the first attempt at making one of these
individually-allocated string management/utility things. I didn't end up
liking the design, so I tried again from scratch, and called the new one
`oso`. Let's see how that one turns out. The name might change again in
the future, though I feel better about the design of this one.
Used regular curses newwin WINDOWs before. Now uses newpad/subpad. The
buffers will be clipped correctly to the visible terminal area, and will
not be erased when the window is made too small and then resized to be
big again.
This needs work. It seems pretty annoying to me right now.
This commit also adds a way for Qmsg to differentiate between
dismiss-easily and dismiss-deliberately types of msg dialogs.