documentation

This commit is contained in:
2026-04-01 16:23:56 +02:00
parent 5ee62d0064
commit ab666368b1
27 changed files with 1080 additions and 164 deletions

195
scrbl/menu.scrbl Normal file
View File

@@ -0,0 +1,195 @@
#lang scribble/manual
@(require racket/base
scribble/core
(for-label racket/base
racket/string
net/url
json
"../private/menu.rkt"))
@title{menu}
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
@defmodule[menu]
Menu data structures used by the webview library.
This module provides constructors, predicates, traversal helpers, mutation
operations, and JSON conversion for menu trees.
@section{Overview}
A menu is represented as a tree. A menu consists of menu items, and a menu item
may optionally contain a submenu.
Menu identifiers are symbols. Menu item titles are strings. Icons are stored as
strings and may be supplied either as @racket[#f], strings, or URL values.
The module does not display menus itself. It provides the menu data structure
used by higher layers.
@section{Internal Representation}
Internally, menus are represented by transparent structure values. These
structure constructors and predicates are not exported directly. The public API
uses constructor procedures and helper functions operating on those internal
values.
@section{Predicates}
@defproc[(is-wv-menu? [mnu any/c]) boolean?]{
Returns @racket[#t] if @racket[mnu] is a valid menu tree and @racket[#f]
otherwise.
A value is recognized as a menu if it is an internal menu structure whose item
list is a list of internal menu items, and every submenu recursively also
satisfies @racket[is-wv-menu?].
}
@section{Constructors}
@defproc[(wv-menu [item-or-id any/c] ...)
any/c]{
Creates a menu.
If the first argument is a symbol, it is used as the menu identifier and removed
from the remaining arguments. Otherwise the menu identifier is @racket[#f].
If the first remaining argument is itself a list, that list is used as the item
list. Otherwise all remaining arguments are treated as menu items.
This means the following forms are accepted:
@racketblock[
(wv-menu item ...)
(wv-menu 'some-id item ...)
(wv-menu (list item ...))
(wv-menu 'some-id (list item ...))
]
The result is a value satisfying @racket[is-wv-menu?].
}
@defproc[(wv-menu-item [id symbol?]
[title string?]
[#:icon-url icon-url (or/c boolean? string? url?) #f]
[#:callback callback procedure? (λ args #t)]
[#:submenu submenu (or/c boolean? any/c) #f]
[#:separator separator boolean? #f])
any/c]{
Creates a menu item.
@racket[id] must be a symbol and @racket[title] must be a string.
@racket[icon-url] must be @racket[#f], a string, or a URL value. If it is a URL
value, it is converted to a string using @racket[url->string] before being
stored.
@racket[submenu] must be @racket[#f] or a value satisfying
@racket[is-wv-menu?].
@racket[separator] must be a boolean.
If any argument does not satisfy these conditions, an exception is raised.
}
@section{Traversal and Lookup}
@defproc[(wv-menu-for-each [menu any/c] [cb procedure?]) boolean?]{
Traverses @racket[menu] depth-first and calls @racket[cb] for each menu item.
If a menu item contains a submenu, that submenu is traversed recursively.
The callback is invoked only for menu items that are reached by the traversal.
The function returns @racket[#t].
}
@defproc[(with-wv-menu-item [menu any/c] [id symbol?] [cb procedure?]) any/c]{
Finds the menu item identified by @racket[id] and applies @racket[cb] to it.
If @racket[menu] does not satisfy @racket[is-wv-menu?], an exception is raised.
If @racket[id] is not a symbol, an exception is raised.
If no item with the given id can be found, an exception is raised.
After the callback has been applied, the original @racket[menu] value is
returned.
}
@section{Mutation}
@defproc[(wv-menu-set-title! [menu any/c] [id symbol?] [title string?])
any/c]{
Sets the title of the menu item identified by @racket[id].
@racket[title] must be a string. The function returns the original
@racket[menu] value.
}
@defproc[(wv-menu-set-icon! [menu any/c] [id symbol?]
[icon-url (or/c boolean? string? url?)])
any/c]{
Sets the icon URL of the menu item identified by @racket[id].
@racket[icon-url] must be @racket[#f], a string, or a URL value. If it is a URL
value, it is converted to a string using @racket[url->string] before being
stored.
The function returns the original @racket[menu] value.
}
@defproc[(wv-menu-set-callback! [menu any/c] [id symbol?] [cb procedure?])
any/c]{
Sets the callback of the menu item identified by @racket[id].
@racket[cb] must be a procedure. The function returns the original
@racket[menu] value.
}
@section{Conversion}
@defproc[(wv-menu->json [menu any/c]) string?]{
Converts @racket[menu] to a JSON string.
The conversion first builds a hash-based representation of the menu and then
writes that representation with @racket[write-json].
In the JSON representation:
@itemlist[#:style 'compact
@item{the top-level object contains the keys @racket['menu] and @racket['id]}
@item{menu item identifiers are converted to strings}
@item{menu item titles are written under the key @racket['name]}
@item{an icon is written only if it is not @racket[#f]}
@item{a submenu is written recursively only if it is not @racket[#f]}
@item{a separator flag is written only if it is not @racket[#f]}]
The @racket['id] field of the top-level menu is also converted to a string in
the JSON output.
}
@section{Accessors}
@defproc[(wv-menu-id [m any/c]) any/c]{
Returns the identifier of @racket[m].
}
@defproc[(wv-menu-item-id [mi any/c]) symbol?]{
Returns the identifier of the menu item @racket[mi].
}
@defproc[(wv-menu-item-callback [mi any/c]) procedure?]{
Returns the callback associated with the menu item @racket[mi].
}