195 lines
5.7 KiB
Racket
195 lines
5.7 KiB
Racket
#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].
|
|
} |