checkpoint new GUI toolbox docs
svn: r7109 original commit: c7c3d60b1666fcd4b1dba547bb7c64e7d61447ac
This commit is contained in:
parent
9efd90c2d0
commit
9f6f51f064
78
collects/scribblings/gui/add-color-intf.scrbl
Normal file
78
collects/scribblings/gui/add-color-intf.scrbl
Normal file
|
@ -0,0 +1,78 @@
|
|||
#reader(lib "defreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@definterface[add-color<%> ()]{
|
||||
|
||||
An @scheme[add-color<%>] object is used to additively change the RGB
|
||||
values of a @scheme[color%] object. An @scheme[add-color<%>] object
|
||||
only exists within a @scheme[style-delta%] object.
|
||||
|
||||
See also @method[style-delta% get-foreground-add] and
|
||||
@method[style-delta% get-background-add].
|
||||
|
||||
|
||||
|
||||
@defmethod[(get [r (box/c (integer-in -1000 1000))]
|
||||
[g (box/c (integer-in -1000 1000))]
|
||||
[b (box/c (integer-in -1000 1000))])
|
||||
void?]{
|
||||
|
||||
Gets all of the additive values.
|
||||
|
||||
@boxisfill[(scheme r) @elem{the additive value for the red component of the color}]
|
||||
@boxisfill[(scheme g) @elem{the additive value for the green component of the color}]
|
||||
@boxisfill[(scheme b) @elem{the additive value for the blue component of the color}]
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(get-b)
|
||||
(integer-in -1000 1000)]{
|
||||
|
||||
Gets the additive value for the blue component of the color.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(get-g)
|
||||
(integer-in -1000 1000)]{
|
||||
|
||||
Gets the additive value for the green component of the color.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(get-r)
|
||||
(integer-in -1000 1000)]{
|
||||
|
||||
Gets the additive value for the red component of the color.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(set [r (integer-in -1000 1000)]
|
||||
[g (integer-in -1000 1000)]
|
||||
[b (integer-in -1000 1000)])
|
||||
void?]{
|
||||
|
||||
Sets all of the additive values.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(set-b [v (integer-in -1000 1000)])
|
||||
void?]{
|
||||
|
||||
Sets the additive value for the blue component of the color.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(set-g [v (integer-in -1000 1000)])
|
||||
void?]{
|
||||
|
||||
Sets the additive value for the green component of the color.
|
||||
|
||||
}
|
||||
|
||||
@defmethod[(set-r [v (integer-in -1000 1000)])
|
||||
void?]{
|
||||
|
||||
Sets the additive value for the red component of the color.
|
||||
|
||||
}}
|
||||
|
|
@ -52,12 +52,6 @@
|
|||
@elem{The bitmap label is installed only
|
||||
if the control was originally created with a bitmap label.})
|
||||
|
||||
(define (NotDCRelated)
|
||||
@elem{A path is not connected to any particular @scheme[dc<%>] object, so
|
||||
setting a @scheme[dc<%>] origin or scale does not affect path
|
||||
operations. Instead, a @scheme[dc<%>]'s origin and scale apply at the
|
||||
time that the path is drawn or used to set a region.})
|
||||
|
||||
(define (popupmenuinfo what other more)
|
||||
(make-splice
|
||||
(list*
|
||||
|
@ -250,7 +244,7 @@ information@|details|, even if the editor currently has delayed refreshing (see
|
|||
@elem{snip @techlink{position}}))
|
||||
|
||||
(define (colorName name name2 r g b)
|
||||
name)
|
||||
(make-element `(show-color ,r ,g ,b) (list (to-element (bytes->string/latin-1 name)))))
|
||||
|
||||
(define (Resource s)
|
||||
@elem{@to-element[`(quote ,(string->symbol (string-append "MrEd:" s)))]
|
||||
|
@ -271,5 +265,10 @@ information@|details|, even if the editor currently has delayed refreshing (see
|
|||
"smaller"
|
||||
@elem{the editor is @|b|-aligned in the snip}))
|
||||
|
||||
(define (boxisfill which what)
|
||||
@elem{The @|which| box is filled with @|what|.})
|
||||
(define (boxisfillnull which what)
|
||||
@elem{The @|which| box is filled with @|what|, unless @|which| is @scheme[#f].})
|
||||
|
||||
)
|
||||
|
||||
|
|
44
collects/scribblings/gui/editor-classes.scrbl
Normal file
44
collects/scribblings/gui/editor-classes.scrbl
Normal file
|
@ -0,0 +1,44 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
@require["diagrams.ss"]
|
||||
|
||||
@title[#:style '(toc quiet)]{Editor Class Reference}
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@require["add-color-intf.scrbl"]
|
||||
@require["editor-intf.scrbl"]
|
||||
@;{
|
||||
@require["editor-admin-class.scrbl"]
|
||||
@require["editor-canvas-class.scrbl"]
|
||||
@require["editor-data-class.scrbl"]
|
||||
@require["editor-data-class-class.scrbl"]
|
||||
@require["editor-data-class-list-intf.scrbl"]
|
||||
@require["editor-snip-editor-admin-intf.scrbl"]
|
||||
@require["editor-snip-class.scrbl"]
|
||||
@require["editor-stream-in-class.scrbl"]
|
||||
@require["editor-stream-in-base-class.scrbl"]
|
||||
@require["editor-stream-in-bytes-base-class.scrbl"]
|
||||
@require["editor-stream-out-class.scrbl"]
|
||||
@require["editor-stream-out-base-class.scrbl"]
|
||||
@require["editor-stream-out-bytes-base-class.scrbl"]
|
||||
@require["editor-wordbreak-map-class.scrbl"]
|
||||
@require["image-snip-class.scrbl"]
|
||||
@require["keymap-class.scrbl"]
|
||||
@require["mult-color-intf.scrbl"]
|
||||
@require["pasteboard-class.scrbl"]
|
||||
@require["readable-snip-intf.scrbl"]
|
||||
@require["snip-class.scrbl"]
|
||||
@require["snip-admin-class.scrbl"]
|
||||
@require["snip-class-class.scrbl"]
|
||||
@require["snip-class-list-intf.scrbl"]
|
||||
@require["string-snip-class.scrbl"]
|
||||
@require["style-intf.scrbl"]
|
||||
@require["style-delta-class.scrbl"]
|
||||
@require["style-list-class.scrbl"]
|
||||
@require["tab-snip-class.scrbl"]
|
||||
@require["text-class.scrbl"]
|
||||
}
|
||||
|
||||
@include-class[add-color<%>]
|
||||
@include-class[editor<%>]
|
2361
collects/scribblings/gui/editor-intf.scrbl
Normal file
2361
collects/scribblings/gui/editor-intf.scrbl
Normal file
File diff suppressed because it is too large
Load Diff
752
collects/scribblings/gui/editor-overview.scrbl
Normal file
752
collects/scribblings/gui/editor-overview.scrbl
Normal file
|
@ -0,0 +1,752 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require[(lib "bnf.ss" "scribble")]
|
||||
@require["common.ss"]
|
||||
|
||||
@title[#:tag "mr:editor-overview"]{Editor Guide}
|
||||
|
||||
The editor toolbox provides a foundation for two common kinds of
|
||||
applications:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@italic{Programs that need a sophisticated text editor} ---
|
||||
The simple text field control is inadequate for text-intensive
|
||||
applications. Many programs need editors that can handle multiple
|
||||
fonts and non-text items.}
|
||||
|
||||
@item{@italic{Programs that need a canvas with dragable objects} ---
|
||||
The drawing toolbox provides a generic drawing surface for plotting
|
||||
lines and boxes, but many applications need an interactive canvas,
|
||||
where the user can drag and resize individual objects.}
|
||||
|
||||
}
|
||||
|
||||
Both kinds of applications need an extensible editor that can handle
|
||||
text, images, programmer-defined items, and even embedded
|
||||
editors. The difference between them is the layout of items. MrEd
|
||||
therefore provides two kinds of editors via two classes:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@scheme[text%] --- in a @deftech{text editor}, items are
|
||||
automatically positioned in a paragraph flow.}
|
||||
|
||||
@item{@scheme[pasteboard%] --- in a @deftech{pasteboard editor},
|
||||
items are explicitly positioned and dragable.}
|
||||
|
||||
}
|
||||
|
||||
MrEd's editor architecture addresses the full range of real-world
|
||||
issues for an editor---including cut-and-paste, extensible file
|
||||
formats, and layered text styles---while supporting a high level of
|
||||
extensibility. Unfortunately, the system is fairly complex as a
|
||||
result, and using the editor classes effectively requires a solid
|
||||
understanding of the structure and terminology of the editor
|
||||
toolbox. Nevertheless, enough applications fit one (or both) of the
|
||||
descriptions above to justify the depth and complexity of the toolbox
|
||||
and the learning investment required to use it.
|
||||
|
||||
A brief example illustrates how MrEd editors work. To start, an editor
|
||||
needs an @scheme[editor-canvas%] to display its contents. Then, we
|
||||
can create a text editor and install it into the canvas:
|
||||
|
||||
@schemeblock[
|
||||
(define f (new frame% [label "Simple Edit"]
|
||||
[width 200]
|
||||
[height 200]))
|
||||
(define c (new editor-canvas% [parent f]))
|
||||
(define t (new text%))
|
||||
(send c #,(:: editor-canvas% set-editor) t)
|
||||
(send f #,(:: top-level-window<%> show) #t)
|
||||
]
|
||||
|
||||
At this point, the editor is fully functional: the user can type text
|
||||
into the editor, but no cut-and-paste operations are available. We
|
||||
can support all of the standard operations on an editor via the
|
||||
menu bar:
|
||||
|
||||
@schemeblock[
|
||||
(define mb (new menu-bar% [parent f]))
|
||||
(define m-edit (new menu% [label "Edit"] [parent mb]))
|
||||
(define m-font (new menu% [label "Font"] [parent mb]))
|
||||
(append-editor-operation-menu-items m-edit #f)
|
||||
(append-editor-font-menu-items m-font)
|
||||
]
|
||||
|
||||
Now, the standard cut and paste operations work, and the user can even
|
||||
set font styles. The user can also insert an embedded editor by
|
||||
selecting @onscreen{Insert Text} from the @onscreen{Edit} menu; after
|
||||
selecting the menu item, a box appears in the editor with the caret
|
||||
inside. Typing with the caret in the box stretches the box as text is
|
||||
added, and font operations apply wherever the caret is active. Text
|
||||
on the outside of the box is rearranged as the box changes
|
||||
sizes. Note that the box itself can be copied and pasted.
|
||||
|
||||
The content of an editor is made up of @deftech{snips}. An embedded
|
||||
editor is a single snip from the embedding editor's point-of-view. To
|
||||
encode immediate text, a snip can be a single character, but more
|
||||
often a snip is a sequence of adjacent characters on the same
|
||||
line. The @method[text% find-snip] method extracts a snip
|
||||
from a text editor:
|
||||
|
||||
@schemeblock[
|
||||
(send t #,(:: text% find-snip) 0 'after)
|
||||
]
|
||||
|
||||
The above expression returns the first snip in the editor, which may
|
||||
be a string snip (for immediate text) or an editor snip (for an
|
||||
embedded editor).
|
||||
|
||||
An editor is not permanently attached to any display. We can take the
|
||||
text editor out of our canvas and put a pasteboard editor in the
|
||||
canvas, instead:
|
||||
|
||||
@schemeblock[
|
||||
(define pb (new pasteboard%))
|
||||
(send c #,(:: editor-canvas% set-editor) pb)
|
||||
]
|
||||
|
||||
With the pasteboard editor installed, the user can no longer type
|
||||
characters directly into the editor (because a pasteboard does not
|
||||
support directly entered text). However, the user can cut text from
|
||||
elsewhere and paste it into pasteboard, or select one of the
|
||||
@onscreen{Insert} menu items in the @onscreen{Edit} menu. Snips are
|
||||
clearly identifiable in a pasteboard editor (unlike a text editor)
|
||||
because each snip is separately dragable.
|
||||
|
||||
We can insert the old text editor (which we recently removed from the
|
||||
canvas) as an embedded editor in the pasteboard by explicitly
|
||||
creating an editor snip:
|
||||
|
||||
@schemeblock[
|
||||
(define s (make-object editor-snip% t)) (code:comment #, @t{@scheme[t] is the old text editor})
|
||||
(send pb #,(:: editor:<%> insert) s)
|
||||
]
|
||||
|
||||
An individual snip cannot be inserted into different editors at the
|
||||
same time, or inserted multiple times in the same editor:
|
||||
|
||||
@schemeblock[
|
||||
(send pb #,(:: editor<%> insert) s) (code:comment #, @t{no effect})
|
||||
]
|
||||
|
||||
However, we can make a deep copy of the snip and insert the copy into
|
||||
the pasteboard:
|
||||
|
||||
@schemeblock[
|
||||
(send pb #,(:: editor<%> insert) (send s #,(:: snip% copy)))
|
||||
]
|
||||
|
||||
Applications that use the editor classes typically derive new versions
|
||||
of the @scheme[text%] and @scheme[pasteboard%] classes. For
|
||||
example, to implement an append-only editor (which allows insertions
|
||||
only at the end and never allows deletions), derive a new class from
|
||||
@scheme[text%] and override the
|
||||
@method[text% can-insert?] and
|
||||
@method[text% can-delete?] methods:
|
||||
|
||||
@schemeblock[
|
||||
(define append-only-text%
|
||||
(class text%
|
||||
(inherit #,(:: text% last-position))
|
||||
(define/override (#,(:: text% can-insert?) s l) (= s #,(:: text% last-position)))
|
||||
(define/override (#,(:: text% can-delete?) s l) #f)
|
||||
(super-new)))
|
||||
]
|
||||
|
||||
@section[#:tag "mr:tb:miaoverview"]{Editor Structure and Terminology}
|
||||
|
||||
MrEd supports extensible and nestable editors by decomposing an editor
|
||||
assembly into three functional parts:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{The @deftech{editor} itself stores the state of the text or
|
||||
pasteboard and handles most events and editing operations. The
|
||||
@scheme[editor<%>] interface defines the core editor functionality,
|
||||
but editors are created as instances of @scheme[text%] or
|
||||
@scheme[pasteboard%].}
|
||||
|
||||
@item{A @deftech{snip} is a segment of information within the
|
||||
editor. Each snip can contain a sequence of characters, a picture,
|
||||
or an interactive object (such as an embedded editor). In a text
|
||||
editor, snips are constrained to fit on a single line and generally
|
||||
contain data of a single type. The @scheme[snip%] class implements a
|
||||
basic snip. Other snip classes include @scheme[string-snip%] for
|
||||
managing text, @scheme[image-snip%] for managing pictures, and
|
||||
@scheme[editor-snip%] for managing embedded editors.}
|
||||
|
||||
@item{A @deftech{display} presents the editor on the screen. The
|
||||
display lets the user scroll around an editor or change editors. Most
|
||||
displays are instances of the @scheme[editor-canvas%] class, but the
|
||||
@scheme[editor-snip%] class also acts as a display for embedded
|
||||
editors.}
|
||||
|
||||
}
|
||||
|
||||
These three parts are illustrated by a simple word processor. The
|
||||
editor corresponds to the text document. The editor object receives
|
||||
keyboard and mouse commands for editing the text. The text itself is
|
||||
distributed among snips. Each character could be a separate snip, or
|
||||
multiple characters on a single line could be grouped together into a
|
||||
snip. The display roughly corresponds to the window in which the
|
||||
text is displayed. While the editor manages the arrangement of the
|
||||
text as it is displayed into a window, the display determines which
|
||||
window to draw into and which part of the editor to display.
|
||||
|
||||
Each selectable entity in an editor is an @deftech{item}. In a
|
||||
pasteboard, all selection and dragging operations work on snips, so
|
||||
there is a one-to-one correspondence between snips and items. In an
|
||||
editor, one snip contains one or more consecutive items, and every
|
||||
item belongs to some snip. For example, in a simple text editor, each
|
||||
character is an item, but multiple adjacent characters may be grouped
|
||||
into a single snip. The number of items in a snip is the snip's
|
||||
@deftech{count}.
|
||||
|
||||
Each place where the insertion point can appear in a text editor is a
|
||||
@deftech{position}. A text editor with $n$ items contains $n+1$
|
||||
positions: one position before each item, and one position after the
|
||||
last item.
|
||||
|
||||
The order of snips within a pasteboard determines each snip's drawing
|
||||
plane. When two snips overlap within the pasteboard, the snip that is
|
||||
earlier in the order is in front of the other snip (i.e., the former
|
||||
is drawn after the latter, such that the former snip may cover part
|
||||
of the latter snip).
|
||||
|
||||
When an editor is drawn into a display, each snip and position has a
|
||||
@deftech{location}. The location of a position or snip is specified
|
||||
in coordinates relative to the top-left corner of the
|
||||
editor. Locations in an editor are only meaningful when the editor is
|
||||
displayed.
|
||||
|
||||
|
||||
@subsection[#:tag "mr:editoradministrators"]{Administrators}
|
||||
|
||||
Two extra layers of administration manage the @techlink{display}-editor and
|
||||
editor-snip connections. An editor never communicates directly with
|
||||
a @techlink{display}; instead, it always communicates with an @deftech{editor
|
||||
administrator}, an instance of the @scheme[editor-admin%] class,
|
||||
which relays information to the @techlink{display}. Similarly, a snip
|
||||
communicates with a @deftech{snip administrator}, an instance of the
|
||||
@scheme[snip-admin%] class.
|
||||
|
||||
The administrative layers make the editor hierarchy flexible without
|
||||
forcing every part of an editor assembly to contain the functionality
|
||||
of several parts. For example, a text editor can be a single
|
||||
@techlink{item} within another editor; without administrators, the
|
||||
@scheme[text%] class would also have to contain all the functionality
|
||||
of a @techlink{display} (for the containing editor) and a snip (for
|
||||
the embedded editor). Using administrators, an editor class can serve
|
||||
as both a containing and an embedded editor without directly
|
||||
implementing the @techlink{display} and snip functionality.
|
||||
|
||||
A snip belongs to at most one editor via a single administrator. An
|
||||
editor also has only one administrator at a time. However, the
|
||||
administrator that connects the an editor to the standard
|
||||
@techlink{display} (i.e., an editor canvas) can work with other such
|
||||
administrators. In particular, the administrator of an
|
||||
@scheme[editor-canvas%] (each one has its own administrator) can work
|
||||
with other @scheme[editor-canvas%] administrators, allowing an editor
|
||||
to be displayed in multiple @scheme[editor-canvas%] windows at the
|
||||
same time.
|
||||
|
||||
When an editor is displayed by multiple canvases, one of the canvases'
|
||||
administrators is used as the editor's primary administrator. To
|
||||
handle user and update events for other canvases, the editor's
|
||||
administrator is temporarily changed and then restored through the
|
||||
editor's @method[editor<%> set-admin] method. The return value of the
|
||||
editor's @method[editor<%> get-admin] method thus depends on the
|
||||
context of the call.
|
||||
|
||||
@subsection[#:tag "mr:editorstyles"]{Styles}
|
||||
|
||||
A @deftech{style}, an instance of the @scheme[style<%>] interface,
|
||||
parameterizes high-level display information that is common to all
|
||||
snip classes. This includes the font, color, and alignment for
|
||||
drawing the item. A single style is attached to each snip.
|
||||
|
||||
Styles are hierarchical: each style is defined in terms of another
|
||||
style. @index*['("Basic style") (list @elem{@scheme["Basic"]
|
||||
style})]{There} is a single @deftech{root style}, named
|
||||
@scheme["Basic"], from which all other styles in an editor are
|
||||
derived. The difference between a base style and each of its derived
|
||||
style is encoded in a @deftech{style delta} (or simply
|
||||
@deftech{delta}). A delta encodes changes such as
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{change the font family to @italic{X};}
|
||||
|
||||
@item{enlarge the font by adding @italic{Y} to the point size;}
|
||||
|
||||
@item{toggle the boldness of the font; or}
|
||||
|
||||
@item{change everything to match the style description @italic{Z}.}
|
||||
|
||||
}
|
||||
|
||||
Style objects are never created separately; rather, they are always
|
||||
created through a @deftech{style list}, an instance of the
|
||||
@scheme[style-list%] class. A style list manages the styles,
|
||||
servicing external requests to find a particular style, and it
|
||||
manages the hierarchical relationship between styles. A global style
|
||||
list is available, @indexed-scheme[the-style-list], but new style
|
||||
lists can be created for managing separate style hierarchies. For
|
||||
example, each editor will typically have its own style list.
|
||||
|
||||
Each new style is defined in one of two ways:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{A @deftech{derived style} is defined in terms of a base style
|
||||
and a delta. Every style (except for the root style) has a base
|
||||
style, even if it does not depend on the base style in any way (i.e.,
|
||||
the delta describes a fixed style rather than extensions to an
|
||||
existing style). (This is the usual kind of style inheritance, as
|
||||
found in word processors such as Microsoft Word.)}
|
||||
|
||||
@item{A @deftech{join style} is defined in terms of two other styles:
|
||||
a base style and a @deftech{shift style}. The meaning of a join style
|
||||
is determined by reinterpreting the shift style; in the
|
||||
reinterpretation, the base style is used as the {\em root\/} style
|
||||
for the shift style. (This is analogous to multi-level
|
||||
styles, like the paragraph and character styles in FrameMaker. In
|
||||
this analogy, the paragraph style is the base style, and the
|
||||
character style is the shift style. However, FrameMaker allows only
|
||||
those two levels; with join styles support any number of levels.)}
|
||||
|
||||
}
|
||||
|
||||
@index*['("Standard style") (list @elem{@scheme["Standard"]
|
||||
style})]{Usually}, when text is inserted into a text editor, it
|
||||
inherits the style of the preceding snip. If text is inserted into an
|
||||
empty editor, the text is usually assigned a style called
|
||||
@scheme["Standard"]. By default, the @scheme["Standard"] style is
|
||||
unmodified from the root style. The default style name can be changed
|
||||
by overriding @method[editor<%> default-style-name].
|
||||
|
||||
The exception to the above is when @xmethod[text% change-style] is
|
||||
called with the current selection @techlink{position} (when the
|
||||
selection is a @techlink{position} and not a range). In that case,
|
||||
the style is remembered, and if the next editor-modifying action is a
|
||||
text insertion, the inserted text gets the remembered style.
|
||||
|
||||
See @xmethod[text% get-styles-sticky] for more information about the
|
||||
style of inserted text.
|
||||
|
||||
|
||||
@section[#:tag "mr:editorfileformat"]{File Format}
|
||||
|
||||
To allow editor content to be saved to a file, the editor classes
|
||||
implement a special file format. (The format is used when cutting and
|
||||
pasting between applications or eventspaces, too). The file format is
|
||||
not documented, except that it begins
|
||||
@litchar{WXME01}@nonterm{digit}@nonterm{digit} ## }. Otherwise, the
|
||||
@method[editor<%> load-file] and @method[editor<%> save-file] methods
|
||||
define the format internally. The file format is the same for text
|
||||
and pasteboard editors. When a pasteboard saves its content to a
|
||||
file, it saves the snips from front to back, and also includes extra
|
||||
location information.
|
||||
|
||||
Editor data is read and written using @scheme[editor-stream-in%] and
|
||||
@scheme[editor-stream-out%] objects. Editor information can only be
|
||||
read from or written to one stream at a time. To write one or more
|
||||
editors to a stream, first call the function
|
||||
@scheme[write-editor-global-header] to write initialization data into
|
||||
an output stream. When all editors are written to the stream, call
|
||||
@scheme[write-editor-global-footer]. Similarly, reading editors from
|
||||
a stream is initialized with @scheme[read-editor-global-header] and
|
||||
finalized with @scheme[read-editor-global-footer]. Optionally, to
|
||||
support streams that span versions of MrEd, use
|
||||
@scheme[write-editor-version] and @scheme[read-editor-version] before
|
||||
the header operations.
|
||||
|
||||
The editor file data format can be embedded within another file, and
|
||||
it can be extended with new kinds of data. The editor file format can
|
||||
be extended in two ways: with snip- or content-specific data, and
|
||||
with editor-specific global data. These are described in the
|
||||
remainder of this section.
|
||||
|
||||
@subsection{Encoding Snips}
|
||||
|
||||
@index['("snips" "saving")]{@index['("snips" "cut and paste")]{The}}
|
||||
generalized notion of a snip allows new snip types to be defined and
|
||||
immediately used in any editor class. Also, when two applications
|
||||
support the same kinds of snips, snip data can easily be cut and
|
||||
pasted between them, and the same data files will be readable by each
|
||||
program. This interoperability is due to a consistent encoding
|
||||
mechanism that is built into the snip system.
|
||||
|
||||
Graceful and extensible encoding of snips requires that
|
||||
two issues are addressed:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{The encoding function for a snip can be associated with the snip
|
||||
itself. To convert a snip from an encoded representation (e.g., as
|
||||
bytes in a file) to a memory object, a decoding function must be
|
||||
provided for each type of snip. Furthermore, a list of such decoders
|
||||
must be available to the high-level decoding process. This decoding
|
||||
mapping is defined by associating a @deftech{snip class} object to
|
||||
every snip. A snip class is an instance of the @scheme[snip-class%]
|
||||
class.}
|
||||
|
||||
@item{Some editors may require additional information to be stored
|
||||
about a snip; this information is orthogonal to the type-specific
|
||||
information stored by the snip itself. For example, a pasteboard
|
||||
needs to remember a snip's @techlink{location}, while a text editor does not
|
||||
need this information. If data is being cut and pasted from one
|
||||
pasteboard to another, then information about relative @techlink{location}s
|
||||
needs to be maintained, but this information should not inhibit
|
||||
pasting into an editor. Extra data is associated with a snip through
|
||||
@deftech{editor data} objects, instances of the
|
||||
@scheme[editor-data%] class; decoding requires that each editor data
|
||||
object has an @deftech{editor data class}, an instance of the
|
||||
@scheme[editor-data-class%] class.}
|
||||
|
||||
}
|
||||
|
||||
Snip classes, snip data, and snip data classes solve problems related
|
||||
to encoding and decoding snips. In an application that has no need
|
||||
for saving files or cut-and-paste, these issues can be safely
|
||||
ignored.
|
||||
|
||||
@subsubsection[#:tag "mr:editorsnipclasses"]{Snip Classes}
|
||||
|
||||
Each snip can be associated to a @deftech{snip class}. This ``class''
|
||||
is not a class description in the programmer's language; it is an
|
||||
object which provides a way to create new snips of the appropriate
|
||||
type from an encoded snip specification.
|
||||
|
||||
Snip class objects can be added to the eventspace-specific
|
||||
@deftech{snip class list}, which is returned by
|
||||
@scheme[get-the-snip-class-list]. When a snip is encoded, the snip's
|
||||
class name is associated with the encoding; when the snip needs to be
|
||||
decoded, then the snip class list is searched by name to find the
|
||||
snip's class. The snip class will then provide a decoding function
|
||||
that can create a new snip from the encoding.
|
||||
|
||||
If a snip class's name is of the form @scheme["(lib ...)"], then the
|
||||
snip class implementation can be loaded on demand. The name is parsed
|
||||
using @scheme[read]; if the result has the form @scheme[(libKW string
|
||||
...)], then it is supplied to @scheme[dynamic-require] along with
|
||||
@scheme['snip-class]. If the result is a @scheme[snip-class%] object,
|
||||
it is inserted into the current eventspace's snip class list, and
|
||||
loading or saving continues using the new class.
|
||||
|
||||
@subsubsection[#:tag "mr:editordata"]{Editor Data}
|
||||
|
||||
While a snip belongs to an editor, the editor may store extra
|
||||
information about a snip in some specialized way. When the snip is to
|
||||
be encoded, this extra information needs to be put into an
|
||||
@deftech{editor data} object so that the extra information can be
|
||||
encoded as well. In a text editor, extra information can be
|
||||
associated with ranges of @techlink{item}s, as well as snips.
|
||||
|
||||
Just as a snip must be associated with a snip class to be decoded (see
|
||||
@|snipclassdiscuss|), an editor data object needs an @deftech{editor
|
||||
data class} for decoding. Every editor data class object can be added
|
||||
to the eventspace-specific @deftech{editor data class list}, returned
|
||||
by @scheme[get-the-editor-data-class-list]. Alternatively, like snip
|
||||
classes, editor data class names can use the form @scheme["(lib ...)"]
|
||||
to enable on-demand loading. The corresponding module should export an
|
||||
@scheme[editor-data-class%] object named
|
||||
@scheme['editor-data-class].
|
||||
|
||||
To store and load information about a snip or region in an editor:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{derive new classes from @scheme[editor-data%] and
|
||||
@scheme[editor-data-class%].}
|
||||
|
||||
@item{derive a new class from the @scheme[text%] or
|
||||
@scheme[pasteboard%] class, and override the @method[editor<%>
|
||||
get-snip-data] and @method[editor<%> set-snip-data] methods and/or the
|
||||
@method[text% get-region-data] and @method[text% set-region-data]
|
||||
methods.
|
||||
|
||||
Note: the @method[text% get-region-data] and @method[text%
|
||||
set-region-data] methods are called for cut-and-paste encoding, but
|
||||
not for file-saving encoding; see @|globaleditordatadiscuss| for
|
||||
information on extending the file format.}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@subsection[#:tag "mr:globaleditordata"]{Global Data: Headers and Footers}
|
||||
|
||||
The editor file format provides for adding extra global data in
|
||||
special header and footer sections. To save and load special header
|
||||
and/or footer records:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{Pick a name for each header/footer record. This name should not
|
||||
conflict with any other header/footer record name in use, and no one
|
||||
else should use these names. All names beginning with ``wx'' are
|
||||
reserved for internal use. By tagging extra header and footer records
|
||||
with a unique name, the file can be safely loaded under a system that
|
||||
does not support the records.}
|
||||
|
||||
@item{Derive a new class from the @scheme[text%] or
|
||||
@scheme[pasteboard%] class, and override the @method[editor<%>
|
||||
write-headers-to-file], @method[editor<%> write-footers-to-file],
|
||||
@method[editor<%> read-header-from-file] and/or @method[editor<%>
|
||||
read-footer-from-file] methods.}
|
||||
|
||||
}
|
||||
|
||||
When an editor is saved, the methods @method[editor<%>
|
||||
write-headers-to-file] and @method[editor<%> write-footers-to-file]
|
||||
are invoked; at this time, the derived @scheme[text%] or
|
||||
@scheme[pasteboard%] object has a chance to save records. To write a
|
||||
header/footer record, first invoke the @method[editor<%>
|
||||
begin-write-header-footer-to-file] method, at which point the record
|
||||
name is provided. Once the record is written, call @method[editor<%>
|
||||
end-write-header-footer-to-file].
|
||||
|
||||
When an editor is loaded and a header/footer record is encountered,
|
||||
the @method[editor<%> read-header-from-file] or @method[editor<%>
|
||||
read-footer-from-file] method is invoked, with the record name as the
|
||||
argument. If the name matches a known record type, then the data can
|
||||
be loaded.
|
||||
|
||||
See also @method[editor<%> write-headers-to-file] and
|
||||
@method[editor<%> write-headers-to-file].
|
||||
|
||||
|
||||
@section[#:tag "mr:editoreol"]{End of Line Ambiguity}
|
||||
|
||||
Because an editor can force a line break even when there is no
|
||||
carriage return item, a @techlink{position} alone does not always
|
||||
specify a @techlink{location} for the caret. Consider the last
|
||||
@techlink{position} of a line that is soft-broken (i.e., no carriage
|
||||
return is present): there is no @techlink{item} between the last
|
||||
@techlink{item} of the line and the first @techlink{item} of the next
|
||||
line, so two @techlink{location}s (one end-of-line and one
|
||||
start-of-line) map to the same @techlink{position}.
|
||||
|
||||
For this reason, @techlink{position}-setting and
|
||||
@techlink{position}-getting methods often have an extra argument. In
|
||||
the case of a @techlink{position}-setting method, the argument
|
||||
specifies whether the caret should be drawn at the left or right side
|
||||
of the page (in the event that the @techlink{location} is doubly
|
||||
defined); @scheme[#t] means that the caret should be drawn on the
|
||||
right side. Similarly, methods which calculate a @techlink{position}
|
||||
from a @techlink{location} will take an extra boxed boolean; the box
|
||||
is filled with @scheme[#t] if the position is ambiguous and it came
|
||||
from a right-side location, or @scheme[#f] otherwise.
|
||||
|
||||
@section[#:tag "mr:editorflattened"]{Flattened Text}
|
||||
|
||||
In plain text editors, there is a simple correlation between
|
||||
@techlink{position}s and characters. In an @scheme[editor<%>] object,
|
||||
this is not true much of the time, but it is still sometimes useful
|
||||
to just ``get the text'' of an editor.
|
||||
|
||||
Text can be extracted from an editor in either of two forms:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@deftech{Simple text}, where there is one character per
|
||||
@techlink{item}. @techlink{Item}s that are characters are mapped to
|
||||
themselves, and all other @techlink{item}s are mapped to a
|
||||
period. Line breaks are represented by carriage-return characters
|
||||
(ASCII 13).}
|
||||
|
||||
@item{@deftech{Flattened text}, where each @techlink{item} can map to
|
||||
an arbitrary string. @techlink{Item}s that are characters are still
|
||||
mapped to themselves, but more complicated @techlink{item}s can be
|
||||
represented with a useful string determined by the @techlink{item}'s
|
||||
snip. Newlines are mapped to platform-specific character sequences
|
||||
(linefeed under X, carriage return under Mac OS X, and
|
||||
linefeed-carriage return under Windows). This form is called
|
||||
``flattened'' because the editor's @techlink{item}s have been reduced
|
||||
to a linear sequence of characters.}
|
||||
|
||||
}
|
||||
|
||||
@section[#:tag "mr:drawcaretinfo"]{Caret Ownership}
|
||||
|
||||
Within a frame, only one object can contain the keyboard focus. This
|
||||
property must be maintained when a frame contains multiple editors in
|
||||
multiple @techlink{display}s, and when a single editor contains other
|
||||
editors as @techlink{item}s.
|
||||
|
||||
When an editor has the keyboard focus, it will usually display the
|
||||
current selection or a line indicating the insertion point; the line
|
||||
is called the @deftech{caret}.
|
||||
|
||||
When an editor contains other editors, it keeps track of caret
|
||||
ownership among the contained sub-editors. When the caret is taken
|
||||
away from the main editor, it will revoke caret ownership from the
|
||||
appropriate sub-editor.
|
||||
|
||||
When an editor or snip is drawn, an argument to the drawing method
|
||||
specifies whether the caret should be drawn with the data. This
|
||||
argument can be any of (in increasing order):
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{@indexed-scheme['no-caret] --- The caret should not be drawn at
|
||||
all.}
|
||||
|
||||
@item{@indexed-scheme['show-inactive-caret] --- The caret should be drawn
|
||||
as inactive; items may be identified as the local current selection,
|
||||
but the keyboard focus is elsewhere.}
|
||||
|
||||
@item{@indexed-scheme['show-caret] --- The caret should be drawn to show
|
||||
keyboard focus ownership.}
|
||||
|
||||
}
|
||||
|
||||
The @scheme['show-inactive-caret] display mode is useful for showing
|
||||
selection ranges in text editors that do not have the focus. This
|
||||
@scheme['show-inactive-caret] mode is distinct from @scheme['no-caret]
|
||||
mode; when editors are embedded, only the locally-active editor shows
|
||||
its selection.
|
||||
|
||||
|
||||
@section[#:tag "mr:editorcutandpastetime"]{Cut and Paste Time Stamps}
|
||||
|
||||
Methods of @scheme[editor<%>] that use the clipboard --- including
|
||||
@method[editor<%> copy], @method[editor<%> cut], @method[editor<%>
|
||||
paste], and @method[editor<%> do-edit-operation] --- consume a time
|
||||
stamp argument. This time stamp is generally extracted from the
|
||||
@scheme[mouse-event%] or @scheme[key-event%] object that triggered
|
||||
the clipboard action. X uses the time stamp to synchronize clipboard
|
||||
operations among the clipboard clients.
|
||||
|
||||
All instances of @scheme[event%] include a time stamp, which can be
|
||||
obtained using @method[event% get-time-stamp].
|
||||
|
||||
If the time stamp is 0, it defaults to the current time. Using 0 as the
|
||||
time stamp almost always works fine, but it is considered bad manners
|
||||
under X.
|
||||
|
||||
|
||||
@section[#:tag "mr:editorclickback"]{Clickbacks}
|
||||
|
||||
@deftech{Clickbacks} in a @scheme[text%] editor facilitate the
|
||||
creation of simple interactive objects, such as hypertext. A
|
||||
clickback is defined by associating a callback function with a range
|
||||
of @techlink{item}s in the editor. When a user clicks on the
|
||||
@techlink{item}s in that range, the callback function is invoked. For
|
||||
example, a hypertext clickback would associate a range to a callback
|
||||
function that changes the selection range in the editor.
|
||||
|
||||
By default, the callback function is invoked when the user releases
|
||||
the mouse button. The @method[text% set-clickback] method accepts
|
||||
an optional argument that causes the callback function to be invoked
|
||||
on the button press, instead. This behavior is useful, for example,
|
||||
for a clickback that creates a popup menu.
|
||||
|
||||
Note that there is no attempt to save clickback information when a
|
||||
file is saved, since a clickback will have an arbitrary procedure
|
||||
associated with it.
|
||||
|
||||
@section[#:tag "mr:lockinfo"]{Internal Editor Locks}
|
||||
|
||||
Instances of @scheme[editor<%>] have three levels of internal
|
||||
locking:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{write locking --- When an editor is internally locked for
|
||||
writing, the abstract content of the editor cannot be changed (e.g.,
|
||||
insertion attempts fail silently). However, snips in a text editor
|
||||
can still be split and merged, and the text editor can be changed in
|
||||
ways that affect the flow of lines. The
|
||||
@method[editor<%> locked-for-write?] method reports whether an
|
||||
editor is currently locked for writing.}
|
||||
|
||||
@item{flow locking --- When a text editor is internally locked for
|
||||
reflowing, it is locked for writing, the snip content of the editor
|
||||
cannot change, the @techlink{location} of a snip cannot be computed if it
|
||||
is not already known (see
|
||||
@xmethod[editor% locations-computed?]), and the editor cannot
|
||||
be drawn to a @techlink{display}. A request for uncomputed location
|
||||
information during a flow lock produces undefined results. The
|
||||
@method[editor<%> locked-for-flow?] method reports whether an
|
||||
editor is currently locked for flowing.}
|
||||
|
||||
@item{read locking --- When an editor is internally locked for
|
||||
reading, no operations can be performed on the editor (e.g., a
|
||||
request for the current selection position returns an undefined
|
||||
value). This extreme state is used only during callbacks to its snips
|
||||
for setting the snip's administrator, splitting the snip, or merging
|
||||
snips. The @method[editor<%> locked-for-read?] method reports
|
||||
whether an editor is currently locked for reading.}
|
||||
|
||||
}
|
||||
|
||||
The internal lock for an editor is {\em not\/} affected by calls to
|
||||
@method[editor<%> lock].
|
||||
|
||||
Methods that report @techlink{location}-independent information about an
|
||||
editor never trigger a lock. A method that reports @techlink{location}
|
||||
information may trigger a flow lock or write lock if the relevant
|
||||
information has not been computed since the last modification to the
|
||||
editor (see @xmethod[editor% locations-computed?]). A method
|
||||
that modifies the editor in any way, even setting the selection
|
||||
position, can trigger a read lock, flow lock, or write lock.
|
||||
|
||||
@section[#:tag "mr:editorthreads"]{Editors and Threads}
|
||||
|
||||
An editor is not tied to any particular thread or eventspace, except
|
||||
to the degree that it is displayed in a canvas (which has an
|
||||
eventspace). Concurrent access of an editor is always safe, in the
|
||||
sense that the editor will not become corrupted. However, because
|
||||
editor access can trigger locks, and because lock-rejected operations
|
||||
tend to fail silently, concurrent access can produce unexpected
|
||||
results.
|
||||
|
||||
Nevertheless, the editor supports certain concurrent patterns
|
||||
reliably. One relevant pattern is updating an editor in one thread
|
||||
while the editor is displayed in a canvas that is managed by a
|
||||
different (handler) thread. To ensure that canvas refreshes are not
|
||||
performed while the editor is locked for flowing, and to ensure that
|
||||
refreshes do not prevent editor modifications, the following are
|
||||
guaranteed:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{When an editor's @method[editor<%> refresh] method is
|
||||
called during an edit sequence (which is started by
|
||||
@method[editor<%> begin-edit-sequence] and ended with
|
||||
@method[editor<%> end-edit-sequence]), the requested refresh
|
||||
region is recorded, but the refresh is not performed. Instead, the
|
||||
refresh is delayed until the end of the edit sequence.}
|
||||
|
||||
@item{Attempting to start an edit sequence while a refresh is in
|
||||
progress blocks until the refresh is complete.}
|
||||
|
||||
@item{The @method[editor<%> on-display-size-when-ready] method
|
||||
calls @method[editor<%> on-display-size] only when the editor
|
||||
is not being refreshed and only when an edit sequence is not in
|
||||
progress. In the first case, the
|
||||
@method[editor<%> on-display-size] call is delegated to the
|
||||
refreshing thread to be called after the refresh completes. In the
|
||||
second case, the @method[editor<%> on-display-size] call is
|
||||
delegated to the edit-sequence thread, to be called when the edit
|
||||
sequence is complete.}
|
||||
|
||||
}
|
||||
|
||||
Thus, disabling an @scheme[editor-canvas%] object (using
|
||||
@method[window<%> enable]) is sufficient to ensure that a
|
||||
background thread can modify an editor displayed by the canvas, as
|
||||
long as all modifications are in edit sequences. The background
|
||||
modifications will impair canvas refreshes minimally and temporarily,
|
||||
and refreshes will not impair modifications in the background thread.
|
||||
|
||||
A second supported pattern is reading an editor in a background thread
|
||||
while the editor may be manipulated in other threads. Since no
|
||||
@techlink{location}-independent reads introduce locks, the such reads in
|
||||
the background thread will not impair other threads. However, other
|
||||
threads may interfere with the background thread, causing it to
|
||||
receive erroneous or out-of-date content information. This one-sided
|
||||
guarantee is useful if the background thread's work can be discarded
|
||||
when the editor is modified.
|
77
collects/scribblings/gui/font-funcs.scrbl
Normal file
77
collects/scribblings/gui/font-funcs.scrbl
Normal file
|
@ -0,0 +1,77 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@title{Fonts}
|
||||
|
||||
|
||||
@defproc[(get-face-list [family (one-of/c 'mono 'all) 'all])
|
||||
(listof string?)]{
|
||||
|
||||
Returns a list of font face names available on the current system. If
|
||||
@scheme['mono] is provided as the argument, then only faces that are
|
||||
known to correspond to monospace fonts are included in the list.
|
||||
|
||||
}
|
||||
|
||||
@defproc[(get-family-builtin-face [family (one-of/c 'default 'decorative 'roman 'script
|
||||
'swiss 'modern 'symbol 'system)])
|
||||
string?]{
|
||||
|
||||
Returns the built-in default face mapping for a particular font
|
||||
family. The built-in default can be overridden via preferences, as
|
||||
described in @secref["mr:fontresources"].
|
||||
|
||||
See @scheme[font%] for information about @scheme[family].
|
||||
|
||||
}
|
||||
|
||||
@defthing[menu-control-font (is-a?/c font%)]{
|
||||
|
||||
This font is the default for @scheme[popup-menu%] objects.
|
||||
|
||||
Under Mac OS X, this font is slightly larger than
|
||||
@scheme[normal-control-font]. Under Windows and X, it is the same
|
||||
size as @scheme[normal-control-font].
|
||||
|
||||
}
|
||||
|
||||
@defthing[normal-control-font (is-a?/c font%)]{
|
||||
|
||||
This font is the default for most controls, except
|
||||
@scheme[list-box%] and @scheme[group-box-panel%] objects.
|
||||
|
||||
|
||||
}
|
||||
|
||||
@defthing[small-control-font (is-a?/c font%)]{
|
||||
|
||||
This font is the default for @scheme[group-box-panel%] objects, and it is
|
||||
a suitable for controls in a floating window and other contexts that
|
||||
need smaller controls.
|
||||
|
||||
Under Windows, this font is the same size as
|
||||
@scheme[normal-control-font], since the Windows control font is
|
||||
already relatively small. Under X and Mac OS X, this font is slightly
|
||||
smaller than @scheme[normal-control-font].
|
||||
|
||||
|
||||
}
|
||||
|
||||
@defthing[tiny-control-font (is-a?/c font%)]{
|
||||
|
||||
This font is for tiny controls, and it is smaller than
|
||||
@scheme[small-control-font] on all platforms.
|
||||
|
||||
}
|
||||
|
||||
@defthing[view-control-font (is-a?/c font%)]{
|
||||
|
||||
This font is the default for @scheme[list-box%] objects (but not
|
||||
list box labels, which use @scheme[normal-control-font]).
|
||||
|
||||
Under Mac OS X, this font is slightly smaller than
|
||||
@scheme[normal-control-font], and slightly larger than
|
||||
@scheme[small-control-font]. Under Windows and X, it is the same size
|
||||
as @scheme[normal-control-font].
|
||||
|
||||
}
|
100
collects/scribblings/gui/global-draw-funcs.scrbl
Normal file
100
collects/scribblings/gui/global-draw-funcs.scrbl
Normal file
|
@ -0,0 +1,100 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@title{Global Graphics}
|
||||
|
||||
@defproc[(flush-display)
|
||||
void?]{
|
||||
|
||||
Under X and Mac OS X, flushes pending display messages such that the
|
||||
user's display reflects the actual state of the windows. Under
|
||||
Windows, the procedure has no effect.
|
||||
|
||||
}
|
||||
|
||||
@defproc[(get-display-depth)
|
||||
nonnegative-exact-integer?]{
|
||||
|
||||
Returns the depth of the main display (a value of 1 denotes a monochrome display).
|
||||
|
||||
}
|
||||
|
||||
@defproc[(get-display-left-top-inset [avoid-bars? bool @scheme[#f]])
|
||||
(values nonnegative-exact-integer? nonnegative-exact-integer?)]{
|
||||
|
||||
When the optional argument is @scheme[#f] (the default), this function
|
||||
returns the offset of the main screen's origin from the
|
||||
top-left of the physical screen. Under X and Windows, the result is
|
||||
always @scheme[0] and @scheme[0]; under Mac OS X, the result is
|
||||
@scheme[0] and the height of the menu bar.
|
||||
|
||||
When the optional argument is true, this function returns the amount
|
||||
space at the left and top of the main screen that is occupied by the
|
||||
task bar (Windows) or menu bar and dock (Mac OS X). Under X, the
|
||||
result is always @scheme[0] and @scheme[0].
|
||||
|
||||
}
|
||||
|
||||
@defproc[(get-display-size [full-screen? bool @scheme[#f]])
|
||||
(values nonnegative-exact-integer? nonnegative-exact-integer?)]{
|
||||
|
||||
@index["screen resolution"]{Gets} the physical size of the display in
|
||||
pixels. Under Windows, this size does not include the task bar by
|
||||
default. Under Mac OS X, this size does not include the menu bar or
|
||||
dock area by default.
|
||||
|
||||
Under Windows and Mac OS X, if the optional argument is true, then
|
||||
the task bar, menu bar, and dock area are included in the result.
|
||||
|
||||
Returns the screen's width and height.
|
||||
|
||||
}
|
||||
|
||||
@defproc[(is-color-display?)
|
||||
boolean?]{
|
||||
|
||||
Returns @scheme[#t] if the main display has color, @scheme[#f]
|
||||
otherwise.
|
||||
|
||||
}
|
||||
|
||||
@defproc[(register-collecting-blit [canvas (is-a?/c canvas%)]
|
||||
[x real?]
|
||||
[y real?]
|
||||
[w (and/c real? (not/c negative?))]
|
||||
[h (and/c real? (not/c negative?))]
|
||||
[on (is-a?/c bitmap%)]
|
||||
[off (is-a?/c bitmap%)]
|
||||
[on-x real? 0]
|
||||
[on-y real? 0]
|
||||
[off-x real? 0]
|
||||
[off-y real? 0])
|
||||
void?]{
|
||||
|
||||
Registers a blit to occur when garbage collection starts or ends.
|
||||
|
||||
When garbage collection starts, @scheme[(send (send canvas #,(::
|
||||
canvas<%> get-dc)) #,(:: dc<%> draw-bitmap-section) on on-x on-y x y w
|
||||
h)] is called. When garbage collection ends, @scheme[(send (send
|
||||
canvas #,(:: canvas<%> get-dc)) #,(:: dc<%> draw-bitmap-section) off
|
||||
off-x off-y x y w h)] is called. If @scheme[canvas]'s device context
|
||||
has a scale, the scale may or may not be temporarily disabled during
|
||||
the bitmap drawing.
|
||||
|
||||
The @scheme[canvas] is registered weakly, so it will be automatically
|
||||
unregistered if the canvas becomes invisible and inaccessible.
|
||||
Multiple registrations can be installed for the same canvas.
|
||||
|
||||
See also @scheme[unregister-collecting-blit].
|
||||
|
||||
}
|
||||
|
||||
@defproc[(unregister-collecting-blit [canvas (is-a?/c canvas%)])
|
||||
void?]{
|
||||
|
||||
Unregisters a blit request installed with See also
|
||||
@scheme[register-collecting-blit].
|
||||
|
||||
Unregisters all blits for @scheme[canvas].
|
||||
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@title{PLT Scheme GUI Reference}
|
||||
@title{PLT Scheme GUI Toolbox}
|
||||
|
||||
This manual describes MrEd.
|
||||
|
||||
|
@ -12,67 +12,8 @@ This manual describes MrEd.
|
|||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@section{GUI Toolbox Organization}
|
||||
|
||||
For documentation purposes, the MrEd toolbox is organized into three
|
||||
parts:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{The @deftech{windowing} toolbox, for implementing form-filling
|
||||
GUI programs (such as a database query window) using buttons, menus,
|
||||
text fields, and events. The windowing toolbox is documented in
|
||||
@secref["mr:windowing"].}
|
||||
|
||||
@item{The @deftech{drawing} toolbox, for drawing pictures or
|
||||
implementing dynamic GUI programs (such as a video game) using
|
||||
drawing canvases, pens, and brushes. The drawing toolbox is
|
||||
documented in @secref["mr:drawing"].}
|
||||
|
||||
@item{The @deftech{editor} toolbox, for developing traditional text
|
||||
editors, editors that mix text and graphics, or free-form layout
|
||||
editors (such as a word processor, HTML editor, or icon-based file
|
||||
browser). The editor toolbox is documented in @secref["mr:editor"].}
|
||||
|
||||
}
|
||||
|
||||
These three parts roughly represent layers of increasing
|
||||
sophistication. Simple GUI programs access only the windowing toolbox
|
||||
directly, more complex programs use both the windowing and drawing
|
||||
toolboxes, and large-scale applications rely on all three
|
||||
toolboxes. This three-layer view of the toolbox breaks down under
|
||||
close scrutiny, because the windowing, drawing, and editor toolboxes
|
||||
are actually interdependent and intertwined. Nevertheless, the
|
||||
layered separation is a good approximation.
|
||||
|
||||
All three parts are immediately available when MrEd is started, as
|
||||
well as the base class system from MzLib. The @indexed-file{mred.ss}
|
||||
library module of the @file{mred} collection provides all of the
|
||||
class, interface, and procedure names defined in this manual. When
|
||||
MrEd starts up, it imports the @file{mred.ss} module and MzLib's
|
||||
@indexed-file{class.ss} module into the initial namespace (so no
|
||||
knowledge about modules is required to understand this manual).
|
||||
|
||||
The module @indexed-scheme[#%mred-kernel] is built into the MrEd
|
||||
executable, and intended for use only by @file{mred.ss}. Attempting
|
||||
to require @file{mred.ss} in a plain MzScheme executable will result
|
||||
in a run-time error, because @scheme[#%mred-kernel] will not be
|
||||
available.
|
||||
|
||||
To create a namespace in which the @file{mred.ss} module will be used,
|
||||
call the @scheme[make-namespace-with-mred] procedure. That
|
||||
procedure attaches the @file{mred.ss} instance of the current
|
||||
namespace to the created namespace. Otherwise, different namespaces
|
||||
create different instances of the @file{mred.ss} module, which in
|
||||
turn generate distinct classes.
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@include-section["windowing.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@include-section["drawing.scrbl"]
|
||||
@include-section["guide.scrbl"]
|
||||
@include-section["reference.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
|
|
58
collects/scribblings/gui/guide.scrbl
Normal file
58
collects/scribblings/gui/guide.scrbl
Normal file
|
@ -0,0 +1,58 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@title[#:style 'toc]{Guide}
|
||||
|
||||
For documentation purposes, the MrEd toolbox is organized into three
|
||||
parts:
|
||||
|
||||
@itemize{
|
||||
|
||||
@item{The @deftech{windowing} toolbox, for implementing form-filling
|
||||
GUI programs (such as a database query window) using buttons, menus,
|
||||
text fields, and events. The windowing toolbox is described in
|
||||
@secref["mr:windowing-overview"].}
|
||||
|
||||
@item{The @deftech{drawing} toolbox, for drawing pictures or
|
||||
implementing dynamic GUI programs (such as a video game) using
|
||||
drawing canvases, pens, and brushes. The drawing toolbox is
|
||||
described in @secref["mr:drawing-overview"].}
|
||||
|
||||
@item{The @deftech{editor} toolbox, for developing traditional text
|
||||
editors, editors that mix text and graphics, or free-form layout
|
||||
editors (such as a word processor, HTML editor, or icon-based file
|
||||
browser). The editor toolbox is described in
|
||||
@secref["mr:editor-overview"].}
|
||||
|
||||
}
|
||||
|
||||
These three parts roughly represent layers of increasing
|
||||
sophistication. Simple GUI programs access only the windowing toolbox
|
||||
directly, more complex programs use both the windowing and drawing
|
||||
toolboxes, and large-scale applications rely on all three
|
||||
toolboxes. This three-layer view of the toolbox breaks down under
|
||||
close scrutiny, because the windowing, drawing, and editor toolboxes
|
||||
are actually interdependent and intertwined. Nevertheless, the
|
||||
layered separation is a good approximation.
|
||||
|
||||
All three parts are immediately available when MrEd is started, as
|
||||
well as the base class system from MzLib. The @indexed-file{mred.ss}
|
||||
library module of the @file{mred} collection provides all of the
|
||||
class, interface, and procedure names defined in this manual. When
|
||||
MrEd starts up, it imports the @file{mred.ss} module and MzLib's
|
||||
@indexed-file{class.ss} module into the initial namespace (so no
|
||||
knowledge about modules is required to understand this manual).
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@include-section["win-overview.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@include-section["draw-overview.scrbl"]
|
||||
|
||||
@;------------------------------------------------------------------------
|
||||
|
||||
@include-section["editor-overview.scrbl"]
|
33
collects/scribblings/gui/printer-dc-class.scrbl
Normal file
33
collects/scribblings/gui/printer-dc-class.scrbl
Normal file
|
@ -0,0 +1,33 @@
|
|||
#reader(lib "defreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@defclass[printer-dc% object% (dc<%>)]{
|
||||
|
||||
A @scheme[printer-dc%] object is a Windows or Mac OS X printer
|
||||
device context. The class cannot be instantiated under X (an
|
||||
@scheme[exn:misc:unsupported] exception is raised).
|
||||
|
||||
Under Mac OS X, a newly created @scheme[printer-dc%] object obtains
|
||||
orientation (portrait versus landspace) and scaling information from
|
||||
the current @scheme[ps-setup%] object, as determined by the
|
||||
@scheme[current-ps-setup] parameter. This information can be
|
||||
configured by the user through a dialog shown by
|
||||
@scheme[get-page-setup-from-user].
|
||||
|
||||
@|PrintNote|
|
||||
|
||||
See also @scheme[post-script-dc%].
|
||||
|
||||
When a @scheme[printer-dc%] object is created, the user gets
|
||||
platform-specific modal dialogs for configuring the output.
|
||||
If the user cancels the dialog, the @method[dc<%> ok?] method
|
||||
of the object returns @scheme[#f].
|
||||
|
||||
@defconstructor[([parent (or/c (is-a?/c frame%) (is-a?/c dialog%) false/c) #f])]{
|
||||
|
||||
If @scheme[parent] is not @scheme[#f], it is used as the parent window
|
||||
of the configuration dialog.
|
||||
|
||||
|
||||
}}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
@require["diagrams.ss"]
|
||||
|
||||
@title[#:tag "mr:windowing" #:style 'toc]{Windowing Toolbox}
|
||||
@title[#:style 'toc]{Reference}
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
@include-section["win-overview.scrbl"]
|
||||
@include-section["win-classes.scrbl"]
|
||||
@include-section["win-funcs.scrbl"]
|
||||
@include-section["draw-classes.scrbl"]
|
||||
@include-section["draw-funcs.scrbl"]
|
||||
@include-section["editor-classes.scrbl"]
|
|
@ -1,7 +1,7 @@
|
|||
#reader(lib "docreader.ss" "scribble")
|
||||
@require["common.ss"]
|
||||
|
||||
@title[#:style 'toc]{Windowing Function Reference}
|
||||
@title{Windowing Function Reference}
|
||||
|
||||
@local-table-of-contents[]
|
||||
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
@require["common.ss"]
|
||||
@require["diagrams.ss"]
|
||||
|
||||
@title[#:tag "mr:windowing-overview" #:style 'toc]{Windowing Toolbox Overview}
|
||||
|
||||
@local-table-of-contents[]
|
||||
@title[#:tag "mr:windowing-overview"]{Windowing Guide}
|
||||
|
||||
@section{Basic GUI Building Blocks}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user