checkpoint GUI docs

svn: r7110

original commit: cac6aa498d041b0b4e32780bb696aee4ee676c21
This commit is contained in:
Matthew Flatt 2007-08-17 21:13:50 +00:00
parent 9f6f51f064
commit b9acd30e39
35 changed files with 8325 additions and 21 deletions

View File

@ -35,7 +35,7 @@
bitmap has a mask (see @xmethod[bitmap% get-loaded-mask])
that is the same size as the bitmap, then the mask is used for the
label; furthermore, in contrast to the limitations of
@xmethod[dc% draw-bitmap], non-monochrome label masks work
@xmethod[dc<%> draw-bitmap], non-monochrome label masks work
consistently on all platforms.})
(define-syntax bitmaplabeluse
@ -66,9 +66,9 @@
@method[popup-menu% get-popup-target]
for more information.}
(if (string=? more "")
(if (equal? more "")
null
@p{@|more|}))))
(list @p{@|more|})))))
(define insertcharundos
@elem{Multiple calls to the character-inserting method are grouped together
@ -96,7 +96,7 @@ start/end @techlink{position} is incremented by @|what|.})
(define OVD
@elem{The result is only valid when the editor is displayed (see
@secref["tb:miaoverview"]).})
@secref["mr:tb:miaoverview"]).})
(define (FCAX c details)
@elem{@|c|alling this method may force the recalculation of @techlink{location}

View File

@ -0,0 +1,301 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-admin% object% ()]{
See @|admindiscuss| for information about the role of administrators.
The @scheme[editor-admin%] class is never instantiated directly. It
is not even instantiated through derived classes by most programmers;
each @scheme[editor-canvas%] and @scheme[editor-snip%] object
creates its own administrator. However, it may be useful to derive a
new instance of this class to display editors in a new context. Also,
it may be useful to call the methods of an existing administrator
from an owned editor.
To create a new @scheme[editor-admin%] class, all methods described
here must be overridden. They are all invoked by the administrator's
editor.
@defconstructor/make[()]{
Creates a (useless) editor administrator.
}
@defmethod[(get-dc [x (or/c (box/c real?) false/c) #f]
[y (or/c (box/c real?) false/c) #f])
(or/c (is-a?/c dc<%>) false/c)]{
@methspec{
Returns either the drawing context into which the editor is displayed,
or the context into which it is currently being drawn. When the
editor is not embedded, the returned context is always the drawing
content into which the editor is displayed. If the editor is not
displayed, @scheme[#f] is returned.
The origin of the drawing context is also returned, translated into
the local coordinates of the editor. For an embedded editor, the
returned origin is reliable only while the editor is being drawn, or
while it receives a mouse or keyboard event.
@boxisfillnull[(scheme x) @elem{the x-origin of the DC in editor coordinates}]
@boxisfillnull[(scheme y) @elem{the y-origin of the DC in editor coordinates}]
See also @xmethod[editor<%> editor-location-to-dc-location] and
@xmethod[editor<%> dc-location-to-editor-location].
}
@methimpl{
Fills all boxes with @scheme[0.0] and returns @scheme[#f].
}}
@defmethod[(get-max-view [x (or/c (box/c real?) false/c)]
[y (or/c (box/c real?) false/c)]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[h (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[full? any/c #f])
void?]{
@methspec{
Same as @method[editor-admin% get-view] unless the editor is visible
in multiple standard @techlink{display}s. If the editor has multiple
@techlink{display}s, a region is computed that includes the visible
region in all @techlink{display}s.
See @method[editor-admin% get-view].
}
@methimpl{
Fills all boxes with @scheme[0.0].
}}
@defmethod[(get-view [x (or/c (box/c real?) false/c)]
[y (or/c (box/c real?) false/c)]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[h (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[full? any/c #f])
void?]{
@methspec{
Gets the visible region of the editor within its @techlink{display} (in
editor coordinates), or the overall size of the viewing region in the
editor's top-level @techlink{display} (for an embedded editor).
If the @techlink{display} is an editor canvas, see also
@method[area-container<%> reflow-container]. The viewing area within
an editor canvas is not the full client area of the canvas, because
an editor canvas installs a whitespace border around a displayed
editor within the client area.
The calculation of the editor's visible region is based on the current
size and scrollbar values of the top-level @techlink{display}. For an
editor canvas @techlink{display}, the region reported by
@method[editor-admin% get-view] does not depend on whether the canvas
is hidden, obscured by other windows, or moved off the edge of the
screen.
@boxisfillnull[(scheme x) @elem{the left edge of the visible region in editor coordinates}]
@boxisfillnull[(scheme y) @elem{the top edge of the visible region in editor coordinates}]
@boxisfillnull[(scheme w) @elem{the width of the visible region, which may be larger than the editor itself}]
@boxisfillnull[(scheme h) @elem{the height of the visible region, which may be larger than the editor itself}]
If an editor is fully visible and @scheme[full?] is @scheme[#f], then
@scheme[x] and @scheme[y] will both be filled with @scheme[0].
If @scheme[full?] is a true value, then the returned area is the view
area of the top-level @techlink{display} for the editor. This result
is different only when the editor is embedded in another editor; in
that case, the @scheme[x] and @scheme[y] values may be meaningless,
because they are in the coordinate system of the immediate editor
within the top-level @techlink{display}.
}
@methimpl{
Fills all boxes with @scheme[0.0].
}}
@defmethod[(grab-caret [domain (one-of/c 'immediate 'display 'global) 'global])
void?]{
@methspec{
Called by the editor to request the keyboard focus. If the request is
granted, then the administered editor's @method[editor<%> own-caret]
method will be called.
See @method[editor<%> set-caret-owner] for information about the
possible values of @scheme[domain].
}
@methimpl{
Does nothing.
}}
@defmethod[(modified [modified? any/c])
void?]{
@methspec{
Called by the editor to report that its modification state has
changed to either modified or unmodified.
See also @xmethod[editor<%> set-modified].
}
@methimpl{
Does nothing.
}}
@defmethod[(needs-update [localx real?]
[localy real?]
[w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))])
void?]{
@methspec{
Called by the editor to request a refresh to its displayed
representation. When the administrator decides that the displayed
should be refreshed, it calls the editor's @method[editor<%> refresh]
method.
The @scheme[localx], @scheme[localy], @scheme[w], and @scheme[h]
arguments specify a region of the editor to be updated (in editor
coordinates).
}
@methimpl{
Does nothing.
}}
@defmethod[(popup-menu [menu (is-a?/c popup-menu%)]
[x real?]
[y real?])
boolean?]{
@methspec{
@popupmenuinfo[@elem{administrator's @techlink{display}}
@elem{top-level editor in this administrator's @techlink{display}}
@elem{The result is @scheme[#t] if the popup succeeds,
@scheme[#f] otherwise (independent of whether the
user selects an item in the popup menu).}]
The menu is displayed at @scheme[x] and @scheme[y] in editor coordinates.
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(refresh-delayed?)
boolean?]{
@methspec{
Returns @scheme[#t] if updating on this administrator's
@techlink{display} is currently delayed (usually by
@xmethod[editor<%> begin-edit-sequence] in an enclosing editor).
}
@methimpl{
Returns Scheme[#f].
}}
@defmethod[(resized [refresh? any/c])
void?]{
@methspec{
Called by the editor to notify its @techlink{display} that the
editor's size or scroll count has changed, so the scrollbars need to
be adjusted to reflect the new size. The editor generally needs to be
updated after a resize, but the editor decides whether the update
should occur immediately. If @scheme[refresh?] is not @scheme[#f],
then the editor is requesting to be updated immediately.
}
@methimpl{
Does nothing.
}}
@defmethod[(scroll-to [localx real?]
[localy real?]
[w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))]
[refresh? any/c #t]
[bias (one-of/c 'start 'end 'none) 'none])
boolean?]{
@methspec{
Called by the editor to request scrolling so that the given region is
visible. The editor generally needs to be updated after a scroll, but
the editor decides whether the update should occur immediately.
The @scheme[localx], @scheme[localy], @scheme[w], and @scheme[h]
arguments specify a region of the editor to be made visible by the
scroll (in editor coordinates).
If @scheme[refresh?] is not @scheme[#f], then the editor is requesting
to be updated immediately.
The @scheme[bias] argument is one of:
@itemize{
@item{@scheme['start] --- if the range doesn't fit in the visible area, show the top-left region}
@item{@scheme['none] --- no special scrolling instructions}
@item{@scheme['end] --- if the range doesn't fit in the visible area, show the bottom-right region}
}
The return value is @scheme[#t] if the @techlink{display} is scrolled,
@scheme[#f] if not (either because the requested region is already
visible, because the @techlink{display} has zero size, or because the
editor is currently printing.)
}
@methimpl{
Return @scheme[#f]
}}
@defmethod[(update-cursor)
void?]{
@methspec{
Queues an update for the cursor in the @techlink{display} for this
editor. The actual cursor used will be determined by calling the
editor's @method[editor<%> adjust-cursor] method.
}
@methimpl{
Does nothing.
}}}

View File

@ -0,0 +1,367 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-canvas% object% (canvas<%>)]{
An @scheme[editor-canvas%] object manages and displays a
@scheme[text%] or @scheme[pasteboard%] object.
@defconstructor[([parent (or/c (is-a?/c frame%) (is-a?/c dialog%)
(is-a?/c panel%) (is-a?/c pane%))]
[editor (or/c (or/c @scheme[text%] (is-a?/c pasteboard%)) false/c) #f]
[style (listof (one-of/c 'no-border 'control-border 'combo
'no-hscroll 'no-vscroll
'hide-hscroll 'hide-vscroll
'auto-vscroll 'auto-hscroll
'resize-corner 'deleted 'transparent)) null]
[scrolls-per-page (integer-in 1 10000) 100]
[label (or/c label-string? false/c) #f]
[wheel-step (or/c (integer-in 1 10000) false/c) 3]
[line-count (or/c (integer-in 1 1000) false/c) #f]
[horizontal-inset (integer-in 0 1000) 5]
[vertical-inset (integer-in 0 1000) 5]
[enabled any/c #t]
[vert-margin (integer-in 0 1000) 0]
[horiz-margin (integer-in 0 1000) 0]
[min-width (integer-in 0 10000) _graphical-minimum-width]
[min-height (integer-in 0 10000) _graphical-minimum-height]
[stretchable-width any/c #t]
[stretchable-height any/c #t])]{
If a canvas is initialized with @scheme[#f] for @scheme[editor],
install an editor later with @method[editor-canvas% set-editor].
The @scheme[style] list can contain the following flags:
@itemize{
@item{@scheme['no-border] --- omits a border around the canvas}
@item{@scheme['control-border] --- gives the canvas a border that is
like a @scheme[text-field%] control}
@item{@scheme['combo] --- gives the canvas a combo button that is like
a @scheme[combo-field%] control; this
style is intended for use with
@scheme['control-border],
@scheme['hide-hscroll], and
@scheme['hide-vscroll]}
@item{@scheme['no-hscroll] --- disallows horizontal scrolling and hides the horizontal scrollbar}
@item{@scheme['no-vscroll] --- disallows vertical scrolling and hides the vertical scrollbar}
@item{@scheme['hide-hscroll] --- allows horizontal scrolling, but hides the horizontal scrollbar}
@item{@scheme['hide-vscroll] --- allows vertical scrolling, but hides the vertical scrollbar}
@item{@scheme['auto-hscroll] --- automatically hides the horizontal scrollbar when unneeded
(unless @scheme['no-hscroll] or @scheme['hide-hscroll] is specified)}
@item{@scheme['auto-vscroll] --- automatically hides the vertical scrollbar when unneeded
(unless @scheme['no-vscroll] or @scheme['hide-vscroll] is specified)}
@item{@scheme['resize-corner] --- leaves room for a resize control at the canvas's
bottom right when only one scrollbar is visible}
@item{@scheme['deleted] --- creates the canvas as initially hidden and without affecting
@scheme[parent]'s geometry; the canvas can be made active
later by calling @scheme[parent]'s @method[area-container<%> add-child]
method}
@item{@scheme['transparent] --- the canvas is ``erased'' before an
update using it's parent window's background}
}
While vertical scrolling of text editors is based on lines,
horizontal scrolling and pasteboard vertical scrolling is based on a
fixed number of steps per horizontal page. The @scheme[scrolls-per-page]
argument sets this value.
@index["wheel on mouse"]{If} provided, the @scheme[wheel-step]
argument is passed on to the @method[editor-canvas% wheel-step]
method. The default wheel step can be overridden globally though the
@ResourceFirst{wheelStep}; see @|mrprefsdiscuss|.
If @scheme[line-count] is not @scheme[#f], it is passed on to the
@method[editor-canvas% set-line-count] method.
If @scheme[horizontal-inset] is not @scheme[5], it is passed on to the
@method[editor-canvas% horizontal-inset] method. Similarly, if
@scheme[vertical-inset] is not @scheme[5], it is passed on to the
@method[editor-canvas% vertical-inset] method.
@WindowKWs[] @SubareaKWs[] @AreaKWs[]
}
@defmethod*[([(allow-scroll-to-last)
boolean?]
[(allow-scroll-to-last [on? any/c])
void?])]{
Enables or disables last-line scrolling, or gets the current enable
state. If last-line scrolling is enabled, then an editor displayed
in this canvas can be scrolled so that the last line of text is at
the top of the canvas (or bottom of the canvas when bottom-based
scrolling is enabled; see @method[editor-canvas%
scroll-with-bottom-base]). By default, an editor can only be scrolled
until the last line is at the bottom (or top) of the canvas.
}
@defmethod*[([(allow-tab-exit)
boolean?]
[(allow-tab-exit [on? any/c])
void?])]{
@index['("keyboard focus" "navigation")]{Gets} or sets whether
tab-exit is enabled for the editor canvas. When tab-exit is enabled,
the user can move the keyboard focus out of the editor using the Tab
and arrow keys, or invoke the default button using the Enter/Return
key. By default, tab-exit is disabled.
When tab-exit is enabled for an editor canvas, Tab, arrow, and Enter
keyboard events are consumed by a frame's default
@method[top-level-window<%> on-traverse-char] method. (In addition, a
dialog's default method consumes Escape key events.) Otherwise,
@method[top-level-window<%> on-traverse-char] allows the keyboard
events to be propagated to the canvas.
}
@defmethod[(call-as-primary-owner [f (-> any)])
any]{
Calls a thunk and returns the value. While the thunk is being called,
if the canvas has an editor, the editor's @method[editor<%>
get-admin] method returns the administrator for this canvas. This
method is only useful when an editor is displayed in multiple
canvases.
}
@defmethod*[([(force-display-focus)
boolean?]
[(force-display-focus [on? any/c])
void?])]{
Enables or disables force-focus mode. In force-focus mode, the caret
of the editor displayed in this canvas will always be visible, even
when the canvas does not actually have the keyboard focus.
}
@defmethod[(get-editor)
(or/c (or/c @scheme[text%] (is-a?/c pasteboard%)) false/c)]{
Returns the editor currently displayed by this canvas, or @scheme[#f]
if the canvas does not have an editor.
}
@defmethod[(get-line-count)
(or/c (integer-in 1 1000) false/c)]{
Returns a line count installed with @method[editor-canvas%
set-line-count], or @scheme[#f] if no minimum line count is set.
}
@defmethod*[([(horizontal-inset)
(integer-in 1 10000)]
[(horizontal-inset [step (integer-in 1 10000)])
void?])]{
Gets or sets the number of pixels within the canvas reserved to
the left and right of editor content. The default is @scheme[5].
}
@defmethod*[([(lazy-refresh)
boolean?]
[(lazy-refresh [on? any/c])
void?])]{
Enables or disables lazy-refresh mode, or gets the current enable
state. In lazy-refresh mode, the canvas's @method[window<%> refresh]
method is called when the window needs to be updated, rather than
@method[editor-canvas% on-paint]. By default, an
@scheme[editor-canvas%] object is @italic{not} in lazy-refresh mode.
}
@defmethod[#:mode 'override
(on-char [event (is-a?/c key-event%)])
void?]{
Handles @scheme['wheel-up] and @scheme['wheel-down] events by
scrolling vertically. Otherwise, passes the event to the canvas's
editor, if any, by calling its @method[editor<%> on-char] method.
See also @method[editor-canvas% get-editor].
}
@defmethod[#:mode 'override
(on-event [event (is-a?/c mouse-event%)])
void?]{
Passes the event to the canvas's editor, if any, by calling its
@method[editor<%> on-event] method.
See also @method[editor-canvas% get-editor].
}
@defmethod[#:mode 'override
(on-focus [on? any/c])
void?]{
Enables or disables the caret in the @techlink{display}'s editor, if
there is one.
}
@defmethod[#:mode 'override
(on-paint)
void?]{
Repaints the editor.
}
@defmethod[#:mode 'override
(on-size [width (integer-in 0 10000)]
[height (integer-in 0 10000)])
void?]{
If the canvas is displaying an editor, its @method[editor<%>
on-display-size] method is called.
}
@defmethod[(scroll-to [localx real?]
[localy real?]
[w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))]
[refresh? any/c]
[bias (one-of/c 'start 'end 'none) 'none])
boolean?]{
Requests scrolling so that the given region in the currently displayed
editor is made visible.
The @scheme[localx], @scheme[localy], @scheme[w], and @scheme[h] arguments specify
a region of the editor to be made visible by the scroll (in editor
coordinates).
If @scheme[refresh?] is not @scheme[#f], then the editor is updated
immediately after a successful scroll.
The @scheme[bias] argument is one of:
@itemize{
@item{@scheme['start] --- if the range doesn't fit in the visible
area, show the top-left region}
@item{@scheme['none] --- no special scrolling instructions}
@item{@scheme['end] --- if the range doesn't fit in the visible area,
show the bottom-right region}
}
The return value is @scheme[#t] if the @techlink{display} is scrolled, @scheme[#f]
if not (either because the requested region is already visible,
because the @techlink{display} has zero size, or because the editor is currently
printing).
}
@defmethod*[([(scroll-with-bottom-base)
boolean?]
[(scroll-with-bottom-base [on? any/c])
void?])]{
Enables or disables bottom-base scrolling, or gets the current enable
state. If bottom-base scrolling is on, then scroll positions are
determined by line boundaries aligned with the bottom of the viewable
area (rather than with the top of the viewable area). If last-line
scrolling is also enabled (see @method[editor-canvas%
allow-scroll-to-last]), then the editor is bottom-aligned in the
@techlink{display} area even when the editor does not fill the
viewable area.
}
@defmethod[(set-editor [edit (or/c (or/c @scheme[text%] (is-a?/c pasteboard%)) false/c)]
[redraw? any/c #t])
void?]{
Sets the editor that is displayed by the canvas, releasing the current
editor (if any). If the new editor already has an administrator that
is not associated with an @scheme[editor-canvas%], then the new
editor is @italic{not} installed into the canvas.
If @scheme[redraw?] is @scheme[#f], then the editor is not immediately
drawn; in this case, something must force a redraw later (e.g., a
call to the @method[editor-canvas% on-paint] method).
If the canvas has a line count installed with @method[editor-canvas%
set-line-count], the canvas's minimum height is adjusted.
}
@defmethod[(set-line-count [count (or/c (integer-in 1 1000) false/c)])
void?]{
Sets the canvas's graphical minimum height to display a particular
number of lines of text. The line height is determined by measuring
the difference between the top and bottom of a displayed editor's
first line. The minimum height is not changed until the canvas gets
an editor. When the canvas's editor is changed, the minimum height is
recalculated.
If the line count is set to @scheme[#f], then the canvas's graphical
minimum height is restored to its original value.
}
@defmethod*[([(vertical-inset)
(integer-in 1 10000)]
[(vertical-inset [step (integer-in 1 10000)])
void?])]{
Gets or sets the number of pixels within the canvas reserved above
and below editor content. The default is @scheme[5].
}
@defmethod*[([(wheel-step)
(or/c (integer-in 1 10000) false/c)]
[(wheel-step [step (or/c (integer-in 1 10000) false/c)])
void?])]{
Gets or sets the number of vertical scroll steps taken for one click
of the mouse wheel via a @scheme['wheel-up] or @scheme['wheel-down]
@scheme[key-event%]. A @scheme[#f] value disables special handling
for wheel events (i.e., wheel events are passed on to the canvas's
editor).
}}

View File

@ -8,20 +8,10 @@
@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"]
@ -30,15 +20,29 @@
@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<%>]
@include-class[editor-admin%]
@include-class[editor-canvas%]
@include-class[editor-snip%]
@include-class[editor-wordbreak-map%]
@include-class[image-snip%]
@include-class[keymap%]
@include-class[mult-color<%>]
@include-class[pasteboard%]
@include-class[readable-snip<%>]
@include-class[snip%]
@include-class[snip-admin%]
@include-class[string-snip%]
@include-class[style<%>]
@include-class[style-delta%]
@include-class[style-list%]
@include-class[tab-snip%]
@include-class[text%]

View File

@ -0,0 +1,44 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-data-class% object% ()]{
An @scheme[editor-data-class%] object defines a type for
@scheme[editor-data%] objects. See also @|editordatadiscuss|.
@defconstructor[()]{
Creates a (useless) instance.
}
@defmethod[(get-classname)
string?]{
Gets the name of the class. Names starting with @litchar{wx} are reserved for
internal use.
}
@defmethod[(read [f (is-a?/c editor-stream-in%)])
(or/c (is-a?/c editor-data%) false/c)]{
Reads a new data object from the given stream, returning @scheme[#f] if
there is an error.
}
@defmethod[(set-classname [v string?])
void?]{
Sets the name of the class. Names starting with @litchar{wx} are
reserved for internal use.
An editor data class name should usually have the form @scheme["(lib
...)"] to enable on-demand loading of the class; see
@|editordatadiscuss| for details.
}}

View File

@ -0,0 +1,46 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[editor-data-class-list<%> ()]{
Each eventspace has an instance of @scheme[editor-data-class-list<%>],
obtained with @scheme[(get-the-editor-data-class-list)]. New
instances cannot be created directly. This list keeps a list of
editor data classes; this list is needed for loading snips from a
file. See also @|editordatadiscuss|.
@defmethod[(add [snipclass (is-a?/c editor-data-class%)])
void?]{
Adds a snip data class to the list. If a class with the same name already
exists in the list, this one will not be added.
}
@defmethod[(find [name string?])
(or/c (is-a?/c snip-class%) false/c)]{
Finds a snip data class from the list with the given name, returning
@scheme[#f] if none can be found.
}
@defmethod[(find-position [class (is-a?/c editor-data-class%)])
nonnegative-exact-integer?]{
Returns an index into the list for the specified class.
}
@defmethod[(nth [n nonnegative-exact-integer?])
(or/c (is-a?/c editor-data-class%) false/c)]{
Returns the @scheme[n]th class in the list (counting from 0), returning
@scheme[#f] if the list has @scheme[n] or less classes.
}
@defmethod[(number)
nonnegative-exact-integer?]{
Returns the number of editor data classes in the list.
}}

View File

@ -0,0 +1,51 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-data% object% ()]{
An @scheme[editor-data%] object contains extra data associated to a
snip or region in an editor. See also @|editordatadiscuss|.
@defconstructor/make[()]{
The element returned by @method[editor-data% get-next] is initialized
to @scheme[#f].
}
@defmethod[(get-dataclass)
(or/c (is-a?/c editor-data-class%) false/c)]{
Gets the class for this data.
}
@defmethod[(get-next)
(or/c (is-a?/c editor-data%) false/c)]{
Gets the next editor data element in a list of editor data elements.
A @scheme[#f] terminates the list.
}
@defmethod[(set-dataclass [v (is-a?/c editor-data-class%)])
void?]{Sets the class for this data.
}
@defmethod[(set-next [v (or/c (is-a?/c editor-data%) false/c)])
void?]{Sets the next editor data element in a list of editor data elements.
A @scheme[#f] terminates the list.
}
@defmethod[(write [f (is-a?/c editor-stream-out%)])
boolean?]{
@methspec{
Writes the data to the specified stream, returning @scheme[#t] if data
is written successfully or @scheme[#f] otherwise.
}
@methimpl{
Returns @scheme[#f].
}}}

View File

@ -0,0 +1,432 @@
#reader(lib "docreader.ss" "scribble")
@require["common.ss"]
@require[(lib "bnf.ss" "scribble")]
@title{Editor Functions}
@defproc[(add-editor-keymap-functions [keymap (is-a?/c keymap%)])
void?]{
Given a @scheme[keymap%] object, the keymap is loaded with mappable
functions that apply to all @scheme[editor<%>] objects:
@itemize{
@item{@scheme["copy-clipboard"]}
@item{@scheme["copy-append-clipboard"]}
@item{@scheme["cut-clipboard"]}
@item{@scheme["cut-append-clipboard"]}
@item{@scheme["paste-clipboard"]}
@item{@scheme["paste-x-selection"]}
@item{@scheme["delete-selection"]}
@item{@scheme["clear-selection"]}
@item{@scheme["undo"]}
@item{@scheme["redo"]}
@item{@scheme["select-all"]}
}
}
@defproc[(add-pasteboard-keymap-functions [keymap (is-a?/c keymap%)])
void?]{
Given a @scheme[keymap%] object, the table is loaded with mappable
functions that apply to @scheme[pasteboard%] objects. Currently,
there are no such functions.
See also
@scheme[add-editor-keymap-functions].
}
@defproc[(add-text-keymap-functions [keymap (is-a?/c keymap%)])
void?]{
Given a @scheme[keymap%] object, the table is loaded with functions
that apply to all @scheme[text%] objects:
@itemize{
@item{@scheme["forward-character"]}
@item{@scheme["backward-character"]}
@item{@scheme["previous-line"]}
@item{@scheme["next-line"]}
@item{@scheme["previous-page"]}
@item{@scheme["next-page"]}
@item{@scheme["forward-word"]}
@item{@scheme["backward-word"]}
@item{@scheme["forward-select"]}
@item{@scheme["backward-select"]}
@item{@scheme["select-down"]}
@item{@scheme["select-up"]}
@item{@scheme["select-page-up"]}
@item{@scheme["select-page-down"]}
@item{@scheme["forward-select-word"]}
@item{@scheme["backward-select-word"]}
@item{@scheme["beginning-of-file"]}
@item{@scheme["end-of-file"]}
@item{@scheme["beginning-of-line"]}
@item{@scheme["end-of-line"]}
@item{@scheme["select-to-beginning-of-file"]}
@item{@scheme["select-to-end-of-file"]}
@item{@scheme["select-to-beginning-of-line"]}
@item{@scheme["select-to-end-of-line"]}
@item{@scheme["copy-clipboard"]}
@item{@scheme["copy-append-clipboard"]}
@item{@scheme["cut-clipboard"]}
@item{@scheme["cut-append-clipboard"]}
@item{@scheme["paste-clipboard"]}
@item{@scheme["paste-x-selection"]}
@item{@scheme["delete-selection"]}
@item{@scheme["delete-previous-character"]}
@item{@scheme["delete-next-character"]}
@item{@scheme["clear-selection"]}
@item{@scheme["delete-to-end-of-line"]}
@item{@scheme["delete-next-word"]}
@item{@scheme["delete-previous-word"]}
@item{@scheme["delete-line"]}
@item{@scheme["undo"]}
@item{@scheme["redo"]}
}
See also
@scheme[add-editor-keymap-functions].
}
@defproc[(append-editor-font-menu-items [menu (or/c @scheme[menu%] (is-a?/c popup-menu%))])
void?]{
Appends menu items to a given menu (not a popup menu) to implement a
standard set of font-manipulation operations, such as changing the
font face or style. The callback for each menu item uses
@xmethod[top-level-window<%> get-edit-target-object] (finding the frame by following a chain of parents until a frame is
reached); if the result is an @scheme[editor<%>] object,
@xmethod[editor<%> change-style] is called on the editor.
}
@defproc[(append-editor-operation-menu-items [menu (or/c @scheme[menu%] (is-a?/c popup-menu%))]
[text-only? any/c @scheme[#t]])
void?]{
Appends menu items to a given menu (not a popup menu) to implement the
standard editor operations, such as cut and paste. The callback for
each menu item uses
@xmethod[top-level-window<%> get-edit-target-object] (finding the frame by following a chain of parents until a frame is
reached); if the result is an @scheme[editor<%>] object,
@xmethod[editor<%> do-edit-operation] is called on the editor.
If @scheme[text-only?] is @scheme[#f], then menu items that insert
non-text snips (such as @onscreen{Insert Image...}) are appended to
the menu.
}
@defparam[current-text-keymap-initializer proc ((is-a?/c keymap%) . -> . any/c)]{
Parameter that specifies a keymap-initialization procedure. This
procedure is called to initialize the keymap of a
@scheme[text-field%] object or a @scheme[text%] object created by
@scheme[graphical-read-eval-print-loop].
The initializer takes a keymap object and returns nothing. The default
initializer chains the given keymap to an internal keymap that
implements standard text editor keyboard and mouse bindings for cut,
copy, paste, undo, and select-all. The right mouse button is mapped
to popup an edit menu when the button is released. Under X,
start-of-line (Ctl-A) and end-of-line (Ctl-E) are also mapped.
}
@defproc[(editor-set-x-selection-mode [on any/c])
void?]{
Under X Windows, editor selections conform to the X Windows selection
conventions instead of a clipboard-based convention. If @scheme[on] is
@scheme[#f], the behavior is switched to the clipboard-based convention
(where copy must be explicitly requested before a paste).
}
@defproc[(get-the-editor-data-class-list)
(is-a?/c editor-data-class-list<%>)]{
Gets the editor data class list instance for the current eventspace.
}
@defproc[(get-the-snip-class-list)
(is-a?/c snip-class-list<%>)]{
Gets the snip class list instance for the current eventspace.
}
@defproc*[([(map-command-as-meta-key [on? any/c])
void?]
[(map-command-as-meta-key)
boolean?])]{
Determines the interpretation of @litchar{m:} for a @scheme[keymap%]
mapping under Mac OS X. See also
@xmethod[keymap% map-function].
First case:
If @scheme[on?] is @scheme[#t], @litchar{m:} corresponds to the Command key. If
@scheme[on?] is @scheme[#f], then @litchar{m:} corresponds to no key under Mac OS
X.
Second case:
Returns @scheme[#t] if @litchar{m:} corresponds to Command,
@scheme[#f] otherwise.
}
@defproc[(open-input-graphical-file [filename string?])
input-port]{
Opens @scheme[filename] (in @scheme['binary] mode) and checks whether it looks
like a ``graphical'' file in editor format. If the file does not
appear to be an editor file, the file port is returned with line
counting enabled. Otherwise, the file is loaded into an editor, and
the result port is created with
@scheme[open-input-text-editor].
}
@defproc[(open-input-text-editor [text-editor (is-a?/c text%)]
[start-position nonnegative-exact-integer? 0]
[end-position (or/c nonnegative-exact-integer? (one/of 'end)) 'end]
[snip-filter ((is-a?/c snip%) . -> . any/c) (lambda (s) s)]
[port-name any/c @scheme[text-editor]]
[expect-to-read-all? any/c #f])
input-port]{
Creates an input port that draws its content from @scheme[text-editor].
The editor content between positions @scheme[start-position] and
@scheme[end-position] is the content of the port. If @scheme[end-position]
is @scheme['end], the content runs until the end of the editor. If a
snip that is not a @scheme[string-snip%] object spans
@scheme[start-position] or @scheme[end-position], the entire snip
contributes to the port. If a @scheme[string-snip%] instance spans
@scheme[start-position], only the part of the snip after
@scheme[start-position] contributes, and if a @scheme[string-snip%]
object spans @scheme[end-position], only the part before
@scheme[end-position] contributes.
An instance of @scheme[string-snip%] in @scheme[text-editor] generates
a character sequence in the resulting port. All other kinds of snips
are passed to @scheme[snip-filter] to obtain a ``special'' value for
the port. If a snip is returned as the first result from
@scheme[snip-filter], and if the snip is an instance of
@scheme[readable-snip<%>], the snip generates a special value for the
port through the @method[readable-snip<%> read-special] method. If
@scheme[snip-filter] returns any other kind of snip, it is copied for
the special result. Finally, a non-snip first result from
@scheme[snip-filter] is used directly as the special result.
The @scheme[port-name] argument is used for the input port's name. The
@scheme[expect-to-read-all?] argument is a performance hint; use
@scheme[#t] if the entire port's stream will be read.
The result port must not be used if @scheme[text-editor] changes in any
of the following ways: a snip is inserted (see
@method[text% after-insert]), a snip is deleted (see
@method[text% after-delete]), a snip is split (see
@method[text% after-split-snip]), snips are merged (see
@method[text% after-merge-snips]), or a snip changes its count (which is rare; see
@method[snip-admin% recounted]). The
@method[text% get-revision-number] method can be used to detect any of these changes.
}
@defproc[(open-output-text-editor [text-editor (is-a?/c text%)]
[start-position (or/c nonnegative-exact-integer? (one/of 'end)) 'end]
[special-filter (any/c . -> . any/c) (lambda (x) x)]
[port-name any/c @scheme[text-editor]])
output-port]{
Creates an output port that delivers its content to @scheme[text-editor].
The content is written to @scheme[text-editor] starting at the position
@scheme[start-position], where @scheme['end] indicates that output should
start at the text editor's current end position.
If @scheme[special-filter] is provided, it is applied to any value
written to the port with @scheme[write-special], and the result is
inserted in its place. If a special value is a @scheme[snip%]
object, it is inserted into the editor. Otherwise, the special value
is @scheme[display]ed into the editor.
If line counting is enabled for the resulting output port, then the
port will report the line, offset from the line's start, and position
within the editor at which the port writes data.
}
@defproc[(read-editor-global-footer [in (is-a?/c editor-stream-in%)])
boolean?]{
See
@scheme[read-editor-global-header]. Call
@scheme[read-editor-global-footer] even if
@scheme[read-editor-global-header] returns @scheme[#f].
}
@defproc[(read-editor-global-header [in (is-a?/c editor-stream-in%)])
boolean?]{
Reads data from @scheme[in] to initialize for reading editors from the
stream. The return value is @scheme[#t] if the read succeeds, or @scheme[#f]
otherwise.
One or more editors can be read from the stream by calling
the editor's
@method[editor<%> read-from-file] method. (The number of editors to be
read must be known by the application beforehand.) When all editors
are read, call
@scheme[read-editor-global-footer]. Calls to
@scheme[read-editor-global-header] and
@scheme[read-editor-global-footer] must bracket any call to
@method[editor<%> read-from-file], and only one stream at a time
can be read using these methods or written using
@scheme[write-editor-global-header] and
@scheme[write-editor-global-footer].
When reading from streams that span MrEd versions, use
@scheme[read-editor-version] before this procedure.
}
@defproc[(read-editor-version [in (is-a?/c editor-stream-in%)]
[in-base (is-a?/c editor-stream-in-base%)]
[parse-format? any/c]
[raise-errors? any/c @scheme[#t]])
boolean?]{
Reads version information from @scheme[in-base], where @scheme[in-base] is
the base for @scheme[in]. The version information parsed from
@scheme[in-base] is recorded in @scheme[in] for later version-sensitive
parsing. The procedure result is true if the version information was
read successfully and if the version is supported.
If @scheme[parse-format?] is true, then @scheme[in-base] is checked for an
initial @scheme["WXME"] format indicator. Use @scheme[#f] when
@scheme["WXME"] has been consumed already by format-dispatching code.
If @scheme[raise-errors?] is true, then an error in reading triggers an
exception, instead of a @scheme[#f] result.
}
@defproc[(text-editor-load-handler [filename path string]
[expected-module-name (or/c symbol false/c)])
any/c]{
This procedure is a load handler for use with @scheme[current-load].
The handler recognizes MrEd editor-format files (see
@secref["mr:editorfileformat"]) and decodes them for loading. It is
normally installed as MrEd starts (see
@secref["mr:startupsequence"]).
The handler recognizes editor files by the first twelve characters of
the file: @litchar{WXME01}@nonterm{digit}@nonterm{digit}@litchar{ ## }.
Such a file is opened for loading by creating a @scheme[text%]
object, loading the file into the object with @method[editor<%>
insert-file], and then converting the editor content into a port with
@scheme[open-input-text-editor]. After obtaining a port in this way,
the content is read in essentially the same way as by the default
MzScheme load handler. The difference is that the editor may contain
instances of @scheme[readable-snip<%>], which are ``read'' though the
snips' @method[readable-snip<%> read-special] method; see
@scheme[open-input-text-editor] for details.
}
@defthing[the-editor-wordbreak-map (is-a?/c editor-wordbreak-map%)]{
See @scheme[editor-wordbreak-map%].
}
@defthing[the-style-list (is-a?/c style-list%)]{
See @scheme[style-list%].
}
@defproc[(write-editor-global-footer [out (is-a?/c editor-stream-out%)])
boolean?]{
See @scheme[write-editor-global-header]. Call
@scheme[write-editor-global-footer] even if
@scheme[write-editor-global-header] returns @scheme[#f].
}
@defproc[(write-editor-global-header [out (is-a?/c editor-stream-out%)])
boolean?]{
Writes data to @scheme[out], initializing it for writing editors to
the stream. The return value is @scheme[#t] if the write succeeds, or
@scheme[#f] otherwise.
One or more editors can be written to the stream by calling the
editor's @method[editor<%> write-to-file] method. When all editors
are written, call @scheme[write-editor-global-footer]. Calls to
@scheme[write-editor-global-header] and
@scheme[write-editor-global-footer] must bracket any call to
@method[editor<%> write-to-file], and only one stream at a time can
be written using these methods or read using
@scheme[read-editor-global-header] and
@scheme[read-editor-global-footer].
To support streams that span MrEd versions, use
@scheme[write-editor-version] before this procedure.
See also @secref["mr:editorfileformat"].
}
@defproc[(write-editor-version [out (is-a?/c editor-stream-out%)]
[out-base (is-a?/c editor-stream-out-base%)])
boolean?]{
Writes version information to @scheme[out-base] in preparation for
writing editor information to the stream @scheme[out].
The @scheme[out] argument is currently not used, but @scheme[out-base]
should be the base for @scheme[out]. In the future, @scheme[out] may record
information about the version for later version-sensitive output.
The result is @scheme[#t] if the write succeeded, @scheme[#f] otherwise.
}

View File

@ -120,7 +120,7 @@ We can insert the old text editor (which we recently removed from the
@schemeblock[
(define s (make-object editor-snip% t)) (code:comment #, @t{@scheme[t] is the old text editor})
(send pb #,(:: editor:<%> insert) s)
(send pb #,(:: editor<%> insert) s)
]
An individual snip cannot be inserted into different editors at the
@ -666,7 +666,7 @@ Instances of @scheme[editor<%>] have three levels of internal
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
@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
@ -689,7 +689,7 @@ 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
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.

View File

@ -0,0 +1,349 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-snip% snip% ()]{
An @scheme[editor-snip%] object is a @scheme[snip%] object that
contains and displays an @scheme[editor<%>] object. This snip class
is used to insert an editor as a single @techlink{item} within
another editor.
@defconstructor[([editor (or/c (is-a?/c text%) false/c) #f]
[with-border? any/c #t]
[left-margin nonnegative-exact-integer? 5]
[top-margin nonnegative-exact-integer? 5]
[right-margin nonnegative-exact-integer? 5]
[bottom-margin nonnegative-exact-integer? 5]
[left-inset nonnegative-exact-integer? 1]
[top-inset nonnegative-exact-integer? 1]
[right-inset nonnegative-exact-integer? 1]
[bottom-inset nonnegative-exact-integer? 1]
[min-width (or/c (and/c real? (not/c negative?)) (one/of 'none)) 'none]
[max-width (or/c (and/c real? (not/c negative?)) (one/of 'none)) 'none]
[min-height (or/c (and/c real? (not/c negative?)) (one/of 'none)) 'none]
[max-height (or/c (and/c real? (not/c negative?)) (one/of 'none)) 'none])]{
If @scheme[editor] is non-@scheme[#f], then it will be used as the
editor contained by the snip. See also @method[editor-snip%
set-editor].
If @scheme[with-border?] is not @scheme[#f], then a border will be drawn
around the snip. The editor display will be inset in the snip area by
the amounts specified in the @scheme[-margin] arguments. The border
will be drawn with an inset specified by the @scheme[-inset] arguments.
See @method[editor-snip% get-inset] and @method[editor-snip%
get-margin] for information about the inset and margin arguments.
}
@defmethod[#:mode 'override
(adjust-cursor [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[editorx real?]
[editory real?]
[event (is-a?/c mouse-event%)])
(or/c (is-a?/c cursor%) false/c)]{
Gets a cursor from the embedded editor by calling its
@method[editor<%> adjust-cursor] method.
}
@defmethod[(border-visible?)
boolean?]{
Returns @scheme[#t] if the snip has a border draw around it,
@scheme[#f] otherwise.
See also @method[editor-snip% show-border].
}
@defmethod[(get-align-top-line)
boolean?]{
Reports whether the snip is in align-top-line mode. See
@method[editor-snip% get-extent] for more information.
See also @method[editor-snip% set-align-top-line].
}
@defmethod[(get-editor)
(or/c (or/c @scheme[text%] (is-a?/c pasteboard%)) false/c)]{
Returns the editor contained by the snip, or @scheme[#f] is there is
no editor.
}
@defmethod[#:mode 'override
(get-extent [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[h (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[descent (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[space (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[lspace (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[rspace (or/c (box/c (and/c real? (not/c negative?))) false/c) #f])
void?]{
Calls its editor's @method[editor<%> get-extent] method, then adds the
editor snip's margins.
The top space always corresponds to the space of the editor's top
line, plus the snip's top margin. Normally, the descent corresponds
to the descent of the editor's last line plus the snip's bottom
margin. However, if the snip is in align-top-line mode (see
@method[editor-snip% set-align-top-line]), the descent corresponds to
the descent of the top line, plus the height rest of the editor's
lines, plus the snip's bottom margin.
If the editor is a text editor, then @scheme[1] is normally subtracted
from the editor's width as returned by @method[editor<%> get-extent],
because the result looks better for editing. If the snip is in
tight-text-fit mode (see @method[editor-snip% set-tight-text-fit])
then @scheme[2] is subtracted from a text editor's width, eliminating
the two pixels that the text editor reserves for the blinking
caret. In addition, tight-text-fit mode subtracts an amount equal to
the line spacing from the editor's height. By default, tight-text-fit
mode is disabled.
}
@defmethod[(get-inset [l (box/c nonnegative-exact-integer?)]
[t (box/c nonnegative-exact-integer?)]
[r (box/c nonnegative-exact-integer?)]
[b (box/c nonnegative-exact-integer?)])
void?]{
Gets the current border insets for the snip. The inset sets how much space
is left between the edge of the snip and the border.
@boxisfill[(scheme l) @elem{left inset}]
@boxisfill[(scheme t) @elem{top inset}]
@boxisfill[(scheme r) @elem{right inset}]
@boxisfill[(scheme b) @elem{bottom inset}]
}
@defmethod[(get-margin [l (box/c nonnegative-exact-integer?)]
[t (box/c nonnegative-exact-integer?)]
[r (box/c nonnegative-exact-integer?)]
[b (box/c nonnegative-exact-integer?)])
void?]{
Gets the current margins for the snip. The margin sets how much space
is left between the edge of the editor's contents and the edge of the
snip.
@boxisfill[(scheme l) @elem{left margin}]
@boxisfill[(scheme t) @elem{top margin}]
@boxisfill[(scheme r) @elem{right margin}]
@boxisfill[(scheme b) @elem{bottom margin}]
}
@defmethod[(get-max-height)
(or/c (and/c real? (not/c negative?)) (one/of 'none))]{
Gets the maximum display height of the snip; zero or @scheme['none]
indicates that there is no maximum.
}
@defmethod[(get-max-width)
(or/c (and/c real? (not/c negative?)) (one/of 'none))]{
Gets the maximum display width of the snip; zero or @scheme['none]
indicates that there is no maximum.
}
@defmethod[(get-min-height)
(or/c (and/c real? (not/c negative?)) (one/of 'none))]{
Gets the minimum display height of the snip; zero or @scheme['none]
indicates that there is no minimum.
}
@defmethod[(get-min-width)
(or/c (and/c real? (not/c negative?)) (one/of 'none))]{
Gets the minimum display width of the snip; zero or @scheme['none]
indicates that there is no minimum.
}
@defmethod[(get-tight-text-fit)
boolean?]{
Reports whether the snip is in tight-text-fit mode. See
@method[editor-snip% get-extent] for more information.
See also @method[editor-snip% set-tight-text-fit].
}
@defmethod[#:mode 'override
(resize [w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))])
boolean?]{
Sets the snip's minimum and maximum width and height to the specified
values minus the snip border space. See also @method[editor-snip%
set-min-width] @method[editor-snip% set-max-width]
@method[editor-snip% set-max-height] @method[editor-snip%
set-min-height].
Also sets the minimum and maximum width of the editor owned by the
snip to the given width (minus the snip border space) via
@method[editor<%> set-max-width] and @method[editor<%>
set-min-width].
}
@defmethod[(set-align-top-line [tight? any/c])
void?]{
Enables or disables align-top-line mode. See @method[editor-snip%
get-extent] for more information.
See also @method[editor-snip% get-align-top-line].
}
@defmethod[(set-editor [editor (or/c (or/c @scheme[text%] (is-a?/c pasteboard%)) false/c)])
void?]{
Sets the editor contained by the snip, releasing the old editor in the
snip (if any). If the new editor already has an administrator, then
the new editor is {\em not} installed into the snip.
When an @scheme[editor-snip%] object is not inserted in an editor, it
does not have an administrator. During this time, it does not give
its contained editor an administrator, either. The administratorless
contained editor can therefore ``defect'' to some other
@techlink{display} with an administrator. When a contained editor
defects and the snip is eventually inserted into a different editor,
the snip drops the traitor contained editor, setting its contained
editor to @scheme[#f].
}
@defmethod[(set-inset [l nonnegative-exact-integer?]
[t nonnegative-exact-integer?]
[r nonnegative-exact-integer?]
[b nonnegative-exact-integer?])
void?]{
Sets the current border insets for the snip. The inset sets how much
space is left between the edge of the snip and the border.
}
@defmethod[(set-margin [l nonnegative-exact-integer?]
[t nonnegative-exact-integer?]
[r nonnegative-exact-integer?]
[b nonnegative-exact-integer?])
void?]{
Sets the current margins for the snip. The margin sets how much space
is left between the edge of the editor's contents and the edge of the
snip.
}
@defmethod[(set-max-height [h (or/c (and/c real? (not/c negative?)) (one/of 'none))])
void?]{
@edsnipmax[(scheme height)]
Zero or @scheme['none] disables the limit.
}
@defmethod[(set-max-width [w (or/c (and/c real? (not/c negative?)) (one/of 'none))])
void?]{
@edsnipmax[(scheme width)] The contained editor's width limits are not
changed by this method.
Zero or @scheme['none] disables the limit.
}
@defmethod[(set-min-height [h (or/c (and/c real? (not/c negative?)) (one/of 'none))])
void?]{
@edsnipmin[(scheme height) @elem{top}]
Zero or @scheme['none] disables the limit.
}
@defmethod[(set-min-width [w (or/c (and/c real? (not/c negative?)) (one/of 'none))])
void?]{
@edsnipmin[(scheme width) @elem{left}] The contained editor's width
limits are not changed by this method.
Zero or @scheme['none] disables the limit.
}
@defmethod[(set-tight-text-fit [tight? any/c])
void?]{
Enables or disables tight-text-fit mode. See @method[editor-snip%
get-extent] for more information.
See also @method[editor-snip% get-tight-text-fit].
}
@defmethod[(show-border [show? any/c])
void?]{
Shows or hides the snip's border.
}
@defmethod[(style-background-used?)
boolean?]{
Returns @scheme[#t] if the snip uses its style's background and
transparency informaiton when drawing, @scheme[#f] otherwise.
See also @method[editor-snip% use-style-background].
}
@defmethod[(use-style-background [use? any/c])
void?]{
Causes the snip to use or not used (the default) its style's
background and transparency information for drawing the background
within the snip's border.
If @scheme[use?] is @scheme[#f], the style background and transparency
information is ignored, otherwise is it used.
}}

View File

@ -0,0 +1,18 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[editor-snip-editor-admin<%> ()]{
An instance of this administrator interface is created with each
@scheme[editor-snip%] object; new instances cannot be
created directly.
@defmethod[(get-snip)
(is-a?/c editor-snip%)]{
Returns the snip that owns this administrator (and displays the
editor controlled by the administrator, if any).
}}

View File

@ -0,0 +1,56 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-in-base% object% ()]{
An @scheme[editor-stream-in-base%] object is used by an
@scheme[editor-stream-in%] object to perform low-level reading of
data.
The @scheme[editor-stream-in-base%] class is never instantiated
directly, but the derived class @scheme[editor-stream-in-bytes-base%]
can be instantiated. New derived classes must override all of the
methods described in this section.
@defmethod[(bad?)
boolean?]{
Returns @scheme[#t] if there has been an error reading from the
stream, @scheme[#f] otherwise.
}
@defmethod[(read [data (and/c bytes? (not/c immutable?))])
nonnegative-exact-integer?]{
Reads characters to fill the supplied vector. The return value is the
number of characters read, which may be less than the number
requested if the stream is emptied. If the stream is emptied, the
next call to @method[editor-stream-in-base% bad?] must return
@scheme[#t].
}
@defmethod[(seek [pos nonnegative-exact-integer?])
void?]{
Moves to the specified absolute position in the stream.
}
@defmethod[(skip [n nonnegative-exact-integer?])
void?]{
Skips past the next @scheme[n] characters in the stream.
}
@defmethod[(tell)
nonnegative-exact-integer?]{
Returns the current stream position.
}}

View File

@ -0,0 +1,14 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-in-bytes-base% editor-stream-in-base% ()]{
An @scheme[editor-stream-in-bytes-base%] object can be used to
read editor data from a byte string.
@defconstructor/make[([s bytes?])]{
Creates a stream base that reads from @scheme[s].
}}

View File

@ -0,0 +1,137 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-in% object% ()]{
An @scheme[editor-stream-in%] object is used to read editor
information from a file or other input stream (such as the
clipboard).
@defconstructor/make[([base (is-a?/c editor-stream-in-base%)])]{
An in-stream base---possibly an @scheme[editor-stream-in-bytes-base%]
object---must be supplied in @scheme[base].
}
@defmethod*[([(get [v (box/c (and/c exact? integer?))])
(is-a?/c editor-stream-in%)]
[(get [v (box/c real?)])
(is-a?/c editor-stream-in%)])]{
Reads data from the stream, returning itself.
Reading from a bad stream always gives @scheme[0].
@boxisfill[(scheme v) @elem{the next integer or floating-point value in the stream}]
}
@defmethod[(get-bytes [len (or/c (box/c nonnegative-exact-integer?) false/c) #f])
(or/c bytes? false/c)]{
Like @method[editor-stream-in% get-unterminated-bytes], but the last
read byte is assumed to be a nul terminator and discarded. Use this
method when data is written by a call to @method[editor-stream-out%
put] without an explicit byte count, and use
@method[editor-stream-in% get-unterminated-bytes] when data is
written with an explicit byte count.
@boxisfillnull[(scheme len) @elem{the length of the byte string plus one (to indicate the terminator)}]
}
@defmethod[(get-exact)
(and/c exact? integer?)]{
Returns the next integer value in the stream.
}
@defmethod[(get-fixed [v (box/c (and/c exact? integer?))])
(is-a?/c editor-stream-in%)]{
Gets a fixed-sized integer from the stream. See
@method[editor-stream-out% put-fixed] for more information.
Reading from a bad stream always gives @scheme[0].
@boxisfill[(scheme v) @elem{the fixed-size integer from the stream}]
}
@defmethod[(get-inexact)
real?]{
Returns the next floating-point value in the stream.
}
@defmethod[(get-unterminated-bytes [len (or/c (box/c nonnegative-exact-integer?) false/c) #f])
(or/c bytes? false/c)]{
Returns the next byte string from the stream. Reading from a bad
stream returns @scheme[#f] or @scheme[""].
Note that when @method[editor-stream-out% put] is not given a byte
length, it includes an extra byte for a nul terminator; use
@method[editor-stream-in% get-bytes] to read such byte strings.
@boxisfillnull[(scheme len) @elem{the length of the byte string}]
}
@defmethod[(jump-to [pos nonnegative-exact-integer?])
void?]{
Jumps to a given position in the stream.
}
@defmethod[(ok?)
boolean?]{
Returns @scheme[#t] if the stream is ready for reading, @scheme[#f] otherwise.
Reading from a bad stream always returns @scheme[0] or @scheme[""].
}
@defmethod[(remove-boundary)
void?]{
See @method[editor-stream-in% set-boundary].
}
@defmethod[(set-boundary [n nonnegative-exact-integer?])
void?]{
Sets a file-reading boundary at @scheme[n] bytes past the current
stream location. If there is an attempt to read past this boundary,
an error is signaled. The boundary is removed with a call to
@method[editor-stream-in% remove-boundary]. Every call to
@method[editor-stream-in% set-boundary] must be balanced by a call to
@method[editor-stream-in% remove-boundary].
Boundaries help keep a subroutine from reading too much data leading
to confusing errors. However, a malicious subroutine can call
@method[editor-stream-in% remove-boundary] on its own.
}
@defmethod[(skip [n nonnegative-exact-integer?])
void?]{
Skips past the next @scheme[n] bytes in the stream.
}
@defmethod[(tell)
nonnegative-exact-integer?]{
Returns the current stream position.
}}

View File

@ -0,0 +1,44 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-out-base% object% ()]{
An @scheme[editor-stream-out-base%] object is used by an
@scheme[editor-stream-out%] object to perform low-level writing of
data.
The @scheme[editor-stream-out-base%] class is never instantiated
directly, but the derived class
@scheme[editor-stream-out-bytes-base%] can be instantiated. New
derived classes must override all of the methods described in this
section.
@defmethod[(bad?)
boolean?]{
Returns @scheme[#t] if there has been an error writing to the stream,
@scheme[#f] otherwise.
}
@defmethod[(seek [pos nonnegative-exact-integer?])
void?]{
Moves to the specified absolute position in the stream.
}
@defmethod[(tell)
nonnegative-exact-integer?]{
Returns the current stream position.
}
@defmethod[(write [data bytes?])
void?]{
Writes data to the stream.
}}

View File

@ -0,0 +1,20 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-out-bytes-base% editor-stream-out-base% ()]{
An @scheme[editor-stream-out-bytes-base%] object can be used to write
editor data into a byte string.
@defconstructor[()]{
Creates an empty stream.
}
@defmethod[(get-bytes)
bytes?]{
Returns the current contents of the stream.
}}

View File

@ -0,0 +1,97 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-stream-out% object% ()]{
An @scheme[editor-stream-out%] object is used to write editor
information to a file or other output stream (such as the
clipboard).
@defconstructor/make[([base (is-a?/c editor-stream-out-base%)])]{
An out-stream base---possibly an
@scheme[editor-stream-out-bytes-base%] object---must be supplied in
@scheme[base].
}
@defmethod[(jump-to [pos nonnegative-exact-integer?])
void?]{
Jumps to a given position in the stream.
}
@defmethod[(ok?)
boolean?]{
Returns @scheme[#t] if the stream is ready for writing, @scheme[#f] otherwise.
Writing to a bad stream has no effect.
}
@defmethod[(pretty-finish)
void?]{
Ensures that the stream ends with a newline.
This method is called by
@scheme[write-editor-global-footer].
}
@defmethod[(pretty-start)
void?]{
Writes a ``comment'' into the stream that identifies the file format.
This method is called by @scheme[write-editor-global-header].
}
@defmethod*[([(put [n nonnegative-exact-integer?]
[v bytes?])
(is-a?/c editor-stream-out%)]
[(put [v bytes?])
(is-a?/c editor-stream-out%)]
[(put [v (and/c exact? integer?)])
(is-a?/c editor-stream-out%)]
[(put [v real?])
(is-a?/c editor-stream-out%)])]{
Writes @scheme[v], or @scheme[n] bytes of @scheme[v].
When @scheme[n] is supplied, use @method[editor-stream-in%
get-unterminated-bytes] to read the bytes later.
If @scheme[n] is not supplied and @scheme[v] is a byte string, then
for historical reasons, the actual number of bytes written includes a
@scheme[#\nul] terminator, so use @method[editor-stream-in%
get-bytes] instead of @method[editor-stream-in%
get-unterminated-bytes] to read the bytes later.
}
@defmethod[(put-fixed [v (and/c exact? integer?)])
(is-a?/c editor-stream-out%)]{
Puts a fixed-sized integer into the stream. This method is needed
because numbers are usually written in a way that takes varying
numbers of bytes. In some cases it is useful to temporary write a
@scheme[0] to a stream, write more data, and then go back and change
the @scheme[0] to another number; such a process requires a
fixed-size number.
Numbers written to a stream with @method[editor-stream-out% put-fixed]
must be read with @method[editor-stream-in% get-fixed].
}
@defmethod[(tell)
nonnegative-exact-integer?]{
Returns the current stream position.
}}

View File

@ -0,0 +1,62 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[editor-wordbreak-map% object% ()]{
An @scheme[editor-wordbreak-map%] objects is used with a
@scheme[text%] objects to specify word-breaking criteria for the
default wordbreaking function. See also @method[text%
set-wordbreak-map], @method[text% get-wordbreak-map], @method[text%
find-wordbreak], and @method[text% set-wordbreak-func].
A global object @scheme[the-editor-wordbreak-map] is created
automatically and used as the default map for all @scheme[text%]
objects.
A wordbreak objects implements a mapping from each character to a list
of symbols. The following symbols are legal elements of the list:
@itemize{
@item{@indexed-scheme['caret]}
@item{@indexed-scheme['line]}
@item{@indexed-scheme['selection]}
@item{@indexed-scheme['user1]}
@item{@indexed-scheme['user2]}
}
The presence of a flag in a character's value indicates that the
character does not break a word when searching for breaks using the
corresponding reason. For example, if @scheme['caret] is present,
then the character is a non-breaking character for caret-movement
words. (Each stream of non-breaking characters is a single word.)
@defconstructor/make[()]{
All ASCII alpha-numeric characters are initialized with
@scheme['(caret line selection)]. All other ASCII non-whitespace
characters except @litchar{-} are initialized with
@scheme['(line)]. All ASCII whitespace characters and @litchar{-} are
initialized with @scheme[null].
}
@defmethod[(get-map [char char?])
(listof symbol?)]{
Gets the mapping value for @scheme[char]. See
@scheme[editor-wordbreak-map%] for more information.
}
@defmethod[(set-map [char char?]
[value (listof symbol?)])
void?]{
Sets the mapping value for @scheme[char] to @scheme[value]. See
@scheme[editor-wordbreak-map%] for more information.
}}

View File

@ -0,0 +1,144 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[image-snip% snip% ()]{
An @scheme[image-snip%] is a snip that can display bitmap images
(usually loaded from a file). When the image file cannot be found, a
box containing an ``X'' is drawn.
@defconstructor*/make[(([filename (or/c path-string? false/c) #f]
[kind (one-of/c 'unknown 'unknown/mask
'gif 'gif/mask
'jpeg 'png 'png/mask
'xbm 'xpm 'bmp 'pict) 'unknown]
[relative-path? any/c #f]
[inline? any/c #t])
([bitmap (is-a?/c bitmap%)]
[mask (or/c (is-a?/c bitmap%) false/c) #f]))]{
Creates an image snip, loading the image @scheme[filename] if
specified (see also @method[image-snip% load-file]), or using the
given @scheme[bitmap].
}
@defmethod[(get-bitmap)
(or/c (is-a?/c bitmap%) false/c)]{
Returns the bitmap that is displayed by the snip, whether set through
@method[image-snip% set-bitmap] or @method[image-snip% load-file]. If
no bitmap is displayed, the result is @scheme[#f].
The returned bitmap cannot be selected into a @scheme[bitmap-dc%] as
long as it belongs to the snip, but it can be used as a pen or
brush stipple.
}
@defmethod[(get-bitmap-mask)
(or/c (is-a?/c bitmap%) false/c)]{
Returns the mask bitmap that is used for displaying by the snip, if
one was installed with @method[image-snip% set-bitmap]. If no mask
is used, the result is @scheme[#f].
The returned bitmap cannot be selected into a @scheme[bitmap-dc%] as
long as it belongs to the snip, but it can be used as a pen or
brush stipple.
}
@defmethod[(get-filename [relative-path (or/c (box/c any/c) false/c) #f])
(or/c path-string? false/c)]{
Returns the name of the currently loaded, non-inlined file, or
@scheme[#f] if a file is not loaded or if a file was loaded with
inlining (the default).
@boxisfillnull[(scheme relative-path) @elem{@scheme[#t] if the loaded file's path is
relative to the owning editor's path}]
}
@defmethod[(get-filetype)
(one-of/c 'unknown 'unknwon/mask
'gif 'gif/mask
'jpeg 'png 'png/mask 'xbm 'xpm 'bmp 'pict)]{
Returns the kind used to load the currently loaded, non-inlined file,
or @scheme['unknown] if a file is not loaded or if a file was loaded
with inlining (the default).
}
@defmethod[(load-file [filename (or/c path-string? false/c)]
[kind (one-of/c 'unknown 'unknown/mask
'gif 'gif/mask
'jpeg 'png 'png/mask
'xbm 'xpm 'bmp 'pict) 'unknown]
[relative-path? any/c #f]
[inline? any/c #t])
void?]{
Loads the file by passing @scheme[filename] and @scheme[kind] to
@method[bitmap% load-file] If a bitmap had previously been specified
with @method[image-snip% set-bitmap], that bitmap (and mask) will no
longer be used. If @scheme[filename] is @scheme[#f], then the current
image is cleared.
When @scheme['unknown/mask], @scheme['gif/mask], or @scheme['png/mask]
is specified and the loaded bitmap object includes a mask (see
@method[bitmap% get-loaded-mask]), the mask is used for drawing the
bitmap (see @method[dc<%> draw-bitmap]).
If @scheme[relative-path?] is not @scheme[#f] and @scheme[filename] is a
relative path, then the file will be read using the path of the
owning editor's filename. If the image is not inlined, it will be
saved as a relative pathname.
If @scheme[inline?] is not @scheme[#f], the image data will be saved
directly to the file or clipboard when the image is saved or copied
(preserving the bitmap's mask, if any). The source filename and kind
is no longer relevant.
}
@defmethod[#:mode 'override
(resize [w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))])
void?]{
The bitmap will be cropped to fit in the given dimensions.
}
@defmethod[(set-bitmap [bm (is-a?/c bitmap%)]
[mask (or/c (is-a?/c bitmap%) false/c) #f])
void?]{
Sets the bitmap that is displayed by the snip. This method also
accepts an optional mask to be used when drawing the bitmap (see
@method[dc<%> draw-bitmap]), but supplying the mask directly is now
deprecated. Instead, if no mask is supplied but the bitmap's
@method[bitmap% get-loaded-mask] method produces a bitmap of the same
dimensions, it is used as the mask. Furthermore, such a mask is saved
with the snip when it is saved to a file or copied (whereas a
directly supplied mask is not saved).
The supplied bitmap must not be selected into a @scheme[bitmap-dc%]
object, otherwise @|MismatchExn|, and it cannot be selected into
a @scheme[bitmap-dc%] as long as it belongs to the snip, but it
can be used as a pen or brush stipple.
}
@defmethod[(set-offset [dx real?]
[dy real?])
void?]{
Sets a graphical offset for the bitmap within the image snip.
}}

View File

@ -0,0 +1,437 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[keymap% object% ()]{
A @scheme[keymap%] object is used by @scheme[editor<%>] objects to
map keyboard and mouse sequences to arbitrary functions in an
extensible way. Keymaps can be used without editors, as well. A
@scheme[keymap%] object contains
@itemize{
@item{a mapping from function names to event-handling procedures; and}
@item{a mapping from key and mouse sequences to function names.}
}
A handler procedure in a keymap is invoked with a @scheme[key-event%]
object or a @scheme[mouse-event%] object. It is also given another
value that depends on the context in which the keymap is used (or,
more specifically, the arguments to @method[keymap% handle-key-event]
or @method[keymap% handle-mouse-event]). For keymaps associated with
@scheme[editor<%>] objects, the extra parameter is generally the
@scheme[editor<%>] object that received the keyboard or mouse event.
@defconstructor/make[()]{
Creates an empty keymap.
}
@defmethod[(add-function [name string?]
[func (any/c (is-a?/c event%) . -> . any/c)])
void?]{
Names a new function to handle events, called in response to
@method[keymap% handle-key-event], @method[keymap%
handle-mouse-event], or @method[keymap% call-function]. The return
value is of the procedure is ignored.
If there was already a function mapped to this name, it will be
replaced with the given function.
When the function is called, it gets the arguments that were passed to
@method[keymap% handle-key-event], @method[keymap%
handle-mouse-event], or @method[keymap% call-function]. For keymaps
associated with an editor, this is normally the target editor.
}
@defmethod[(break-sequence)
void?]{
Clears the state of the keymap if it is in the middle of a key
sequence. For example, the user may have hit escape, and then changed
to another window; if escape is part of a keyboard sequence, the
keymap state needs to be cleared because the user is not going to
complete the sequence.
A break callback function can be installed with @method[keymap%
set-break-sequence-callback].
}
@defmethod[(call-function [name string?]
[in any/c]
[event (is-a?/c event%)]
[try-chain? any/c #f])
boolean?]{
Calls a named event handler directly. If the function cannot be found
or the found handler did not want to handle the event, @scheme[#f] is
returned. Otherwise, the return value is the boolean return value of
the event handler.
The @scheme[in] and @scheme[event] arguments are passed on to the keymap
handler procedure if one is found.
If @scheme[try-chain?] is not @scheme[#f], keymaps chained to this one
are searched for the function name. If the function is not found and
@scheme[try-chain?] is @scheme[#f]; an exception is also raised, but
the exception handler cannot escape (see
@secref["mr:evtcontjump"]).
}
@defmethod[(chain-to-keymap [next (is-a?/c keymap%)]
[prefix? any/c])
void?]{
Chains @scheme[next] off @this-obj[] The @scheme[next] keymap will be
used to handle events which are not handled by @this-obj[]. If
@scheme[prefix?] is a true value, then @scheme[next] will take
precedence over other keymaps already chained to @this-obj[].
Multiple keymaps can be chained off one keymap using @method[keymap%
chain-to-keymap]. When keymaps are chained off a main keymap, events
not handled by the main keymap are passed to the chained keymaps
until some chained keymap handles the events. Keymaps can be chained
together in an arbitrary acyclic graph.
Keymap chaining is useful because multiple-event sequences are handled
correctly for chained groups. Without chaining, a sequence of events
can produce state in a keymap that must be reset when a callback is
invoked in one of the keymaps. This state can be manually cleared
with @method[keymap% break-sequence], though calling the
@method[keymap% break-sequence] method also invokes the handler
installed by @method[keymap% set-break-sequence-callback].
}
@defmethod[(get-double-click-interval)
(integer-in 0 1000000)]{
Returns the maximum number of milliseconds that can separate the
clicks of a double-click.
The default interval is determined in a platform-specific way, but it
can be overridden globally though the
@ResourceFirst{doubleClickTime}; see @|mrprefsdiscuss|.
}
@defmethod[(handle-key-event [in any/c]
[event (is-a?/c key-event%)])
boolean?]{
Attempts to handle a keyboard event, returning @scheme[#t] if the event
was handled (i.e., a handler was found and it returned a true value),
@scheme[#f] otherwise.
See also @method[keymap% call-function].
}
@defmethod[(handle-mouse-event [in any/c]
[event (is-a?/c mouse-event%)])
boolean?]{
Attempts to handle a mouse event, returning @scheme[#t] if the event
was handled (i.e., a handler was found and it returned a true value),
@scheme[#f] otherwise.
See also @method[keymap% call-function].
}
@defmethod[(map-function [keyname string?]
[fname string?])
void?]{
Maps an input state sequence to a function name using a string-encoded
sequence in @scheme[keyname]. The format of @scheme[keyname] is a
sequence of semicolon-delimited input states; each state is made up
of a sequence of modifier identifiers followed by a key identifier.
The modifier identifiers are:
@itemize{
@item{@litchar{s:} --- All platforms: Shift}
@item{@litchar{c:} --- All platforms: Control}
@item{@litchar{a:} --- Mac OS X: Option}
@item{@litchar{m:} --- Windows: Alt; X: Meta; Mac OS X: Command, when
@scheme[map-command-as-meta-key] produces @scheme[#t]}
@item{@litchar{d:} --- Mac OS X: Command}
@item{@litchar{l:} --- All platforms: Caps Lock}
@item{@litchar{?:} --- All platforms: allow match to character produced by opposite
use of Shift, AltGr/Option, and/or Caps Lock, when available; see
@xmethod[key-event% get-other-shift-key-code]}
}
If a particular modifier is not mentioned in a state string, it
matches states whether that modifier is pressed or not pressed. A
@litchar{~} preceding a modifier makes the string match only states
where the corresponding modifier is not pressed. If the state string
begins with @litchar{:}, then the string matches a state only if
modifiers (other than Caps Lock) not mentioned in the string are not
pressed.
A key identifier can be either a character on the keyboard (e.g.,
@litchar["a"], @litchar["2"], @litchar["?"]) or a special name. The
special names are as follows:
@itemize{
@item{@litchar["leftbutton"] (button down)}
@item{@litchar["rightbutton"]}
@item{@litchar["middlebutton"]}
@item{@litchar["leftbuttondouble"] (button down for double-click)}
@item{@litchar["rightbuttondouble"]}
@item{@litchar["middlebuttondouble"]}
@item{@litchar["leftbuttontriple"] (button down for triple-click)}
@item{@litchar["rightbuttontriple"]}
@item{@litchar["middlebuttontriple"]}
@item{@litchar["leftbuttonseq"] (all events from button down through button up)}
@item{@litchar["rightbuttonseq"]}
@item{@litchar["middlebuttonseq"]}
@item{@litchar["wheelup"]}
@item{@litchar["wheeldown"]}
@item{@litchar["esc"]}
@item{@litchar["delete"]}
@item{@litchar["del"] (same as @litchar["delete"])}
@item{@litchar["insert"]}
@item{@litchar["ins"] (same as @litchar["insert"])}
@item{@litchar["add"]}
@item{@litchar["subtract"]}
@item{@litchar["multiply"]}
@item{@litchar["divide"]}
@item{@litchar["backspace"]}
@item{@litchar["back"]}
@item{@litchar["return"]}
@item{@litchar["enter"] (same as @litchar["return"])}
@item{@litchar["tab"]}
@item{@litchar["space"]}
@item{@litchar["right"]}
@item{@litchar["left"]}
@item{@litchar["up"]}
@item{@litchar["down"]}
@item{@litchar["home"]}
@item{@litchar["end"]}
@item{@litchar["pageup"]}
@item{@litchar["pagedown"]}
@item{@litchar["semicolon"] (since @litchar{;} separates sequence steps)}
@item{@litchar["colon"] (since @litchar{:} separates modifiers)}
@item{@litchar["numpad0"]}
@item{@litchar["numpad1"]}
@item{@litchar["numpad2"]}
@item{@litchar["numpad3"]}
@item{@litchar["numpad4"]}
@item{@litchar["numpad5"]}
@item{@litchar["numpad6"]}
@item{@litchar["numpad7"]}
@item{@litchar["numpad8"]}
@item{@litchar["numpad9"]}
@item{@litchar["numpadenter"]}
@item{@litchar["f1"]}
@item{@litchar["f2"]}
@item{@litchar["f3"]}
@item{@litchar["f4"]}
@item{@litchar["f5"]}
@item{@litchar["f6"]}
@item{@litchar["f7"]}
@item{@litchar["f8"]}
@item{@litchar["f9"]}
@item{@litchar["f10"]}
@item{@litchar["f11"]}
@item{@litchar["f12"]}
@item{@litchar["f13"]}
@item{@litchar["f14"]}
@item{@litchar["f15"]}
@item{@litchar["f16"]}
@item{@litchar["f17"]}
@item{@litchar["f18"]}
@item{@litchar["f19"]}
@item{@litchar["f20"]}
@item{@litchar["f21"]}
@item{@litchar["f22"]}
@item{@litchar["f23"]}
@item{@litchar["f24"]}
}
For a special keyword, the capitalization does not matter. However,
capitalization is important for single-letter keynames. Furthermore,
single-letter ASCII keynames are treated specially: @litchar["A"] and
@litchar["s:a"] are both treated as @litchar["s:A"]. However, when
@litchar["c:"] is inclued under Windows without @litchar["m:"], or when
@litchar["d:"] is included under Mac OS X, then ASCII letters are not
upcased with @litchar["s:"], since the upcasing behavior of the Shift key
is cancelled by Control without Alt (under Windows) or by Command
(under Mac OS X).
A state can match multiple state strings mapped in a keymap (or keymap
chain); when a state matches multiple state strings, a mapping is
selected by ranking the strings according to specificity. A state
string that mentions more pressed modifiers ranks higher than other
state strings, and if two strings mention the same number of pressed
modifiers, the one that mentions more unpressed modifiers ranks
higher. Finally, a state string that includes @litchar{?:} and
matches only with the opposite use of Shift, AltGr/Option, and/or
Caps Lock ranks below all matches that do not depend on @litchar{?:},
and one that requires the opposite use of both Shift and AltGr/Option
ranks even lower. In the case that multiple matching strings have the
same rank, a match is selected arbitrarily.
Examples:
@itemize{
@item{@scheme["space"] --- matches whenever the space bar is pressed,
regardless of the state of modifiers keys.}
@item{@scheme["~c:space"] --- matches whenever the space bar is pressed
and the Control key is not pressed.}
@item{@scheme["a"] --- matches whenever @litchar{a} is typed, regardless of
the state of modifiers keys (other than Shift).}
@item{@scheme[":a"] --- matches only when @litchar{a} is typed with no
modifier keys pressed.}
@item{@scheme["~c:a"] --- matches whenever @litchar{a} is typed and neither
the Shift key nor the Control key is pressed.}
@item{@scheme[":esc;:c:c"] --- matches an Escape key press (no
modifiers) followed by a Control-C press (no modifiers other than
Control).}
@item{@scheme["?:d:+"] --- matches when Command is pressed with key
that produces @litchar{+}, even if producing @litchar{+} normally requires
pressing Shift.}
}
A call to @method[keymap% map-function] that would map a particular
key sequence both as a prefix and as a complete sequence raises an
exception, but the exception handler cannot escape (see
@secref["mr:mr:evtcontjump"]).
A function name does not have to be mapped to a handler before input
states are mapped to the name; the handler is dispatched by name at
the time of invocation. The event handler mapped to a function name
can be changed without affecting the map from input states to
function names.
}
@defmethod[(remove-chained-keymap [keymap (is-a?/c keymap%)])
void?]{
If @scheme[keymap] was previously chained from this keymap (through
@method[keymap% chain-to-keymap]), then it is removed from the
chain-to list.
}
@defmethod[(remove-grab-key-function)
void?]{
Removes a callback installed with @method[keymap%
set-grab-key-function].
}
@defmethod[(remove-grab-mouse-function)
void?]{
Removes a callback installed with @method[keymap%
set-grab-mouse-function].
}
@defmethod[(set-break-sequence-callback [f (-> any)])
void?]{
Installs a callback procedure that is invoked when @method[keymap%
break-sequence] is called. After it is invoked once, the callback is
removed from the keymap. If another callback is installed before
@method[keymap% break-sequence] is called, the old callback is
invoked immediately before the new one is installed.
}
@defmethod[(set-double-click-interval [n (integer-in 0 1000000)])
void?]{
Sets the maximum number of milliseconds that can separate the clicks
of a double-click.
}
@defmethod[(set-grab-key-function [f ((or/c string? false?)
(is-a?/c keymap%)
any/c
(is-a?/c key-event%)
. -> . any)])
void?]{
Installs a callback procedure that is invoked after the keymap matches
input to a function name or fails to match an input. Only one
keyboard grab function can be installed at a time. When keymaps are
chained to a keymap with a grab callback, the callback is invoked for
matches in the chained keymap (when the chained keymap does not have
its own grab callback).
If a grab callback returns a true value for a matching or non-matching
callback, the event is considered handled. If the callback returns a
true value for a matching callback, then the matching keymap function
is not called by the keymap.
The callback procedure @scheme[f] will be invoked as:
@schemeblock[
(f _str _keymap _editor _event)
]
The @scheme[_str] argument is the name of a function for a matching
callback, or @scheme[#f] for a non-matching callback. The
@scheme[_keymap] argument is the keymap that matched (possibly a
keymap chained to the one in which the callback was installed) or the
keymap in which the callback was installed. The @scheme[_editor] and
@scheme[_event] arguments are the same as passed on to the matching
keymap function.
Key grab callback functions are de-installed with @method[keymap%
remove-grab-key-function].
}
@defmethod[(set-grab-mouse-function [f ((or/c string? false?)
(is-a?/c keymap%)
any/c
(is-a?/c mouse-event%)
. -> . any)])
void?]{
Like @method[keymap% set-grab-key-function], but for mouse events.
}}

View File

@ -0,0 +1,78 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[mult-color<%> ()]{
A @scheme[mult-color<%>] object is used to scale the RGB values of a
@scheme[color%] object. A @scheme[mult-color<%>] object exist only
within a @scheme[style-delta%] object.
See also @method[style-delta% get-foreground-mult] and
@method[style-delta% get-background-mult].
@defmethod[(get [r (box/c real?)]
[g (box/c real?)]
[b (box/c real?)])
void?]{
Gets all of the scaling values.
@boxisfill[(scheme r) @elem{the scaling value for the red component of the color}]
@boxisfill[(scheme g) @elem{the scaling value for the green component of the color}]
@boxisfill[(scheme b) @elem{the scaling value for the blue component of the color}]
}
@defmethod[(get-b)
real?]{
Gets the multiplicative scaling value for the blue component of the color.
}
@defmethod[(get-g)
real?]{
Gets the multiplicative scaling value for the green component of the color.
}
@defmethod[(get-r)
real?]{
Gets the multiplicative scaling value for the red component of the color.
}
@defmethod[(set [r real?]
[g real?]
[b real?])
void?]{
Sets all of the scaling values.
}
@defmethod[(set-b [v real?])
void?]{
Sets the multiplicative scaling value for the blue component of the color.
}
@defmethod[(set-g [v real?])
void?]{
Sets the multiplicative scaling value for the green component of the
color.
}
@defmethod[(set-r [v real?])
void?]{
Sets the additive value for the red component of the color.
}}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[readable-snip<%> ()]{
A @scheme[readable-snip<%>] object is treated specially by the port
generated by @scheme[open-input-text-editor]. When a
@scheme[readable-snip<%>] object is encountered for the input stream,
its @method[readable-snip<%> read-special] method is called to
generate the read result for the snip.
@defmethod[(read-special [source any/c]
[line (or/c nonnegative-exact-integer? false/c)]
[column (or/c nonnegative-exact-integer? false/c)]
[position (or/c nonnegative-exact-integer? false/c)])
any/c]{
The arguments are the same as the arguments to a procedure returned by
a custom input port's @scheme[read]; see @secref["mz:customport"] for
details. The result is also the same as the result from a
@scheme[read]-produced procedure.
}}

View File

@ -10,3 +10,5 @@
@include-section["draw-classes.scrbl"]
@include-section["draw-funcs.scrbl"]
@include-section["editor-classes.scrbl"]
@include-section["editor-stream-classes.scrbl"]
@include-section["editor-funcs.scrbl"]

View File

@ -0,0 +1,323 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[snip-admin% object% ()]{
See @|admindiscuss| for information about the role of administrators.
The @scheme[snip-admin%] class is never instantiated directly. It
is not even instantiated through derived classes by most programmers;
each @scheme[text%] or @scheme[pasteboard%] object
creates its own administrator. However, it may be useful to derive a
new instance of this class to display snips in a new context. Also,
it may be useful to call the methods of an existing administrator
from an owned snip.
To create a new @scheme[snip-admin%] class, all methods described here
must be overridden. They are all invoked by the administrator's snip.
Because a @scheme[snip-admin%] object typically owns more than one
snip, many methods require a @scheme[snip%] object as an argument.
@defconstructor/make[()]{
Creates a (useless) editor administrator.
}
@defmethod[(get-dc)
(or/c (is-a?/c dc<%>) false/c)]{
Gets a drawing context suitable for determining display size
information. If the snip is not displayed, @scheme[#f] is returned.
}
@defmethod[(get-editor)
(or/c @scheme[text%] (is-a?/c pasteboard%))]{
Returns the editor that this administrator reports to (directly or
indirectly).
}
@defmethod[(get-view [x (or/c (box/c real?) false/c)]
[y (or/c (box/c real?) false/c)]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[h (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[snip (or/c (is-a?/c snip%) false/c) #f])
void?]{
@methspec{
Gets the @techlink{location} and size of the visible region of a snip in snip
coordinates. The result is undefined if the given snip is not managed
by this administrator.
If @scheme[snip] is not @scheme[#f], the current visible region of the
snip is installed in the boxes @scheme[x], @scheme[y], @scheme[w],
and @scheme[h]. The @scheme[x] and @scheme[y] values are relative to
the snip's top-left corner. The @scheme[w] and @scheme[h] values may
be larger than the snip itself.
If @scheme[snip] is @scheme[#f], the total visible region of the
snip's top-level @techlink{display} is returned in editor
coordinates. Using @scheme[#f] for @scheme[snip] is analogous to
using @scheme[#t] for @scheme[full?] in @xmethod[editor-admin%
get-view].
If no snip is specified, then the @techlink{location} and size of the snip's
editor are returned, instead, in editor coordinates.
See also @xmethod[editor-admin% get-view].
}
@methimpl{
Fills all boxes with @scheme[0.0].
}}
@defmethod[(get-view-size [h (or/c (box/c (and/c real? (not/c negative?))) false/c)]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c)])
void?]{
@methspec{
Gets the visible size of the administrator's @techlink{display} region.
If the @techlink{display} is an editor canvas, see also
@method[area-container<%> reflow-container].
}
@methimpl{
Fills all boxes with @scheme[0.0].
}
}
@defmethod[(modified [snip (is-a?/c snip%)]
[modified? any/c])
void?]{
@methspec{
Called by a snip to report that its modification state has changed to
either modified or unmodified.
}
@methimpl{
Does nothing.
}}
@defmethod[(needs-update [snip (is-a?/c snip%)]
[localx real?]
[localy real?]
[w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))])
void?]{
@methspec{
Called by the snip to request that the snip's display needs to be
updated. The administrator determines when to actually update the
snip; the snip's @method[snip% draw] method is eventually called.
The @scheme[localx], @scheme[localy], @scheme[w], and @scheme[h]
arguments specify a region of the snip to be refreshed (in snip
coordinates).
No update occurs if the given snip is not managed by this
administrator.
}
@methimpl{
Does nothing.
}}
@defmethod[(popup-menu [menu (is-a?/c popup-menu%)]
[snip (is-a?/c snip%)]
[x real?]
[y real?])
boolean?]{
@methspec{
Opens a popup menu in the @techlink{display} for this snip's editor. The result
is @scheme[#t] if the popup succeeds, @scheme[#f] otherwise (independent
of whether the user selects an item in the popup menu).
The menu is placed at @scheme[x] and @scheme[y] in @scheme[snip]
coordinates.
While the menu is popped up, its target is set to the top-level editor
in the @techlink{display} for this snip's editor. See
@method[popup-menu% get-popup-target] for more information.
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(recounted [snip (is-a?/c snip%)]
[refresh? any/c])
void?]{
@methspec{
Called by a snip to notify the administrator that the specified snip
has changed its @techlink{count}. The snip generally needs to be updated after
changing its @techlink{count}, but the snip decides whether the update should
occur immediately.
If @scheme[refresh?] is not @scheme[#f], then the snip is requesting
to be updated immediately. Otherwise, @method[snip-admin%
needs-update] must eventually be called as well.
The method call is ignored if the given snip is not managed by this
administrator.
}
@methimpl{
Does nothing.
}}
@defmethod[(release-snip [snip (is-a?/c snip%)])
boolean?]{
@methspec{
Requests that the specified snip be released. If this administrator is
not the snip's owner or if the snip cannot be released, then
@scheme[#f] is returned. Otherwise, @scheme[#t] is returned and the
snip is no longer owned.
See also @xmethod[editor<%> release-snip] .
The result is @scheme[#f] if the given snip is not managed by this
administrator.
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(resized [snip (is-a?/c snip%)]
[refresh? any/c])
void?]{
@methspec{
Called by a snip to notify the administrator that the specified snip
has changed its display size. The snip generally needs to be updated
after a resize, but the snip decides whether the update should occur
immediately.
If @scheme[refresh?] is not @scheme[#f], then the snip is requesting
to be updated immediately, as if calling @method[snip-admin%
needs-update]. Otherwise, @method[snip-admin% needs-update] must
eventually be called as well.
The method call is ignored if the given snip is not managed by this
administrator.
}
@methimpl{
Does nothing.
}}
@defmethod[(scroll-to [snip (is-a?/c snip%)]
[localx real?]
[localy real?]
[w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))]
[refresh? any/c]
[bias (one-of/c 'start 'end 'none) 'none])
boolean?]{
@methspec{
Called by the snip to request scrolling so that the given region is
visible. The snip generally needs to be updated after a scroll, but
the snip decides whether the update should occur immediately.
The @scheme[localx], @scheme[localy], @scheme[w], and @scheme[h] arguments specify
a region of the snip to be made visible by the scroll (in snip
coordinates).
If @scheme[refresh?] is not @scheme[#f], then the editor is requesting to
be updated immediately.
The @scheme[bias] argument is one of:
@itemize{
@item{@scheme['start] --- if the range doesn't fit in the visible area, show the top-left region}
@item{@scheme['none] --- no special scrolling instructions}
@item{@scheme['end] --- if the range doesn't fit in the visible area, show the bottom-right region}
}
The result is @scheme[#t] if the editor is scrolled, @scheme[#f]
otherwise.
The method call is ignored (and the result is @scheme[#f]) if the given
snip is not managed by this administrator.
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(set-caret-owner [snip (is-a?/c snip%)]
[domain (one-of/c 'immediate 'display 'global)])
void?]{
@methspec{
Requests that the keyboard focus is assigned to the specified snip.
If the request is granted, the @method[snip% own-caret] method of the
snip is called.
See @method[editor<%> set-caret-owner] for information about the
possible values of @scheme[domain].
The method call is ignored if the given snip is not managed by this
administrator.
}
@methimpl{
Does nothing.
}}
@defmethod[(update-cursor)
void?]{
@methspec{
Queues an update for the cursor in the @techlink{display} for this
snip's editor. The actual cursor used will be determined by calling
the snip's @method[snip% adjust-cursor] method as appropriate.
}
@methimpl{
Does nothing.
}}}

View File

@ -0,0 +1,146 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[snip-class% object% ()]{
Useful snip classes are defined by instantiating derived subclasses of
@scheme[snip-class%]. A class derived from @scheme[snip-class%]
serves as a kind of ``meta-class'' for snips; each snip is associated
with an instance of @scheme[snip-class%] as its snip class.
In deriving a new @scheme[snip-class%] class, override the
@method[snip-class% read] method. Then, for each instance of the
derived class (where each instance corresponds to a single snip
class):
@itemize{
@item{Set the classname using @method[snip-class% set-classname].}
@item{Set the version using
@method[snip-class% set-version].}
@item{Install the class into the list returned by
@scheme[get-the-snip-class-list] using the
@method[snip-class-list<%> add] method. Note that if the same
name is inserted into the same class list multiple times, all
but the first insertion is ignored.}
}
See also @|snipclassdiscuss|.
@defconstructor/make[()]{
Creates a (useless) snip class.
}
@defmethod[(get-classname)
string?]{
Returns the class's name, a string uniquely designating this snip
class. For example, the standard text snip classname is
@scheme["wxtext"]. Names beginning with @litchar{wx} are reserved.
A snip class name should usually have the form @scheme["(lib ...)"] to
enable on-demand loading of the class; see @|snipclassdiscuss| for
details.
}
@defmethod[(get-version)
(and/c exact? integer?)]{
Returns the version of this snip class. When attempting to load a file
containing a snip with the same class name but a different version,
the user is warned.
}
@defmethod[(read [f (is-a?/c editor-stream-in%)])
(or/c (is-a?/c snip%) false/c)]{
@methspec{
Reads a snip from a given stream, returning a newly created snip as
the result or @scheme[#f] if there is an error.
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(read-header [f (is-a?/c editor-stream-in%)])
boolean?]{
@methspec{
Called to read header information that may be useful for every snip
read in this class. This method is only called once per editor read
session, and only if the stream contains header information for this
class.
The return value is @scheme[#f] if a read error occurs or anything else
otherwise.
See also @method[snip-class% write-header].
}
@methimpl{
Returns @scheme[#t].
}}
@defmethod[(reading-version [stream (is-a?/c editor-stream-in%)])
(and/c exact? integer?)]{
Returns the version number specified for this snip class for snips
currently being read from the given stream.
}
@defmethod[(set-classname [name string?])
void?]{
Sets the class's name. See also @method[snip-class% get-classname].
}
@defmethod[(set-version [v (and/c exact? integer?)])
void?]{
Sets the version of this class. See @method[snip-class% get-version].
}
@defmethod[(write-header [stream (is-a?/c editor-stream-out%)])
boolean?]{
@methspec{
Called to write header information that may be useful for every snip
written for this class. This method is only called once per editor
write session, and only if the editor contains snips in this class.
When reading the snips back in, @method[snip-class% read-header] will
only be called if @method[snip-class% write-header] writes some data
to the stream.
The return value is @scheme[#f] if a write error occurs or anything else
otherwise.
}
@methimpl{
Returns @scheme[#t].
}}
}

View File

@ -0,0 +1,49 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[snip-class-list<%> ()]{
Each eventspace has its own instance of @scheme[snip-class-list<%>],
obtained with @scheme[(get-the-snip-class-list)]. New instances
cannot be created directly. Each instance keeps a list of snip
classes. This list is needed for loading snips from a file. See also
@|snipclassdiscuss|.
@defmethod[(add [snipclass (is-a?/c snip-class%)])
void?]{
Adds a snip class to the list. If a class with the same name already
exists in the list, this one will not be added.
}
@defmethod[(find [name string?])
(or/c (is-a?/c snip-class%) false/c)]{
Finds a snip class from the list with the given name, returning
@scheme[#f] if none is found.
}
@defmethod[(find-position [class (is-a?/c snip-class%)])
nonnegative-exact-integer?]{
Returns an index into the list for the specified class.
}
@defmethod[(nth [n nonnegative-exact-integer?])
(or/c (is-a?/c snip-class%) false/c)]{
Returns the @scheme[n]th class in the list, or @scheme[#f] if
the list has @scheme[n] classes or less.
}
@defmethod[(number)
nonnegative-exact-integer?]{
Returns the number of snip classes in the list.
}}

View File

@ -0,0 +1,845 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[snip% object% ()]{
A direct instance of @scheme[snip%] is uninteresting. Useful snips are
defined by instantiating derived subclasses, but this class defines
the basic functionality.
In deriving a new snip class, these methods must be overridden to
create a useful snip:
@itemize{
@item{@method[snip% get-extent]}
@item{@method[snip% draw]}
@item{@method[snip% resize] if the snip can be resized by the user}
@item{@method[snip% partial-offset] if the snip can contain more than
one @techlink{item}}
@item{@method[snip% split] if the snip can contain more than one @techlink{item}}
@item{@method[snip% size-cache-invalid] if the snip caches the result to@method[snip% get-extent]}
@item{@method[snip% get-text] (not required)}
@item{@method[snip% find-scroll-step], @method[snip%
get-num-scroll-steps], and @method[snip%
get-scroll-step-offset] if the snip can contain more than one
scroll position}
@item{@method[snip% set-unmodified] if the snip's internal state can
be modified by the user, and call @method[snip-admin% modified]
in the snip's administrator when the state changes the first
time}
}
If a snip can contain more than one @techlink{item}, then the snip's @techlink{count}
must be maintained as well.
To define a class of snips that can be saved or cut-and-pasted:
@itemize{
@item{Create an instance of @scheme[snip-class%], implementing the
@method[snip-class% read] method.}
@item{For each instance of the snip class, set the snip's class object
with @method[snip% set-snipclass].}
@item{Override the @method[snip% copy] method.}
@item{Override the @method[snip% write] method.}
}
To define a class of snips that read specially with
@scheme[open-input-text-editor]:
@itemize{
@item{Make your @scheme[snip%] class implement @scheme[readable-snip<%>].}
@item{Implement the @method[readable-snip<%> read-special] method.}
}
@defconstructor/make[()]{
Creates a plain snip of length 1 with the @scheme["Basic"] style of
@scheme[the-style-list].
}
@defmethod[(adjust-cursor [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[editorx real?]
[editory real?]
[event (is-a?/c mouse-event%)])
(or/c (is-a?/c cursor%) false/c)]{
@methspec{
Called to determine the cursor image used when the cursor is moved
over the snip in an editor. If @scheme[#f] is returned, a default
cursor is selected by the editor. (See @xmethod[editor<%>
adjust-cursor] for more information.)
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(blink-caret [dc (is-a?/c dc<%>)]
[x real?]
[y real?])
void?]{
Tells the snip to blink the selection caret. This method is called
periodically when the snips's editor's @techlink{display} has the
keyboard focus, and the snip has the editor-local focus.
The drawing context and snip's @techlink{location}s in drawing context
coordinates are provided.
}
@defmethod[#:mode 'pubment
(can-do-edit-operation? [op (one-of/c 'undo 'redo 'clear 'cut 'copy
'paste 'kill 'select-all
'insert-text-box 'insert-pasteboard-box
'insert-image)]
[recursive? any/c #t])
boolean?]{
See @xmethod[editor<%> can-do-edit-operation?].
Called when the snip's editor's method is called, @scheme[recursive?]
is not @scheme[#f], and this snip owns the caret.
}
@defmethod[(copy)
(is-a?/c snip%)]{
Creates and returns a copy of this snip. The @method[snip% copy]
method is responsible for copying this snip's style (as returned by
@method[snip% get-style]) to the new snip.
}
@defmethod[(do-edit-operation [op (one-of/c 'undo 'redo 'clear 'cut 'copy
'paste 'kill 'select-all
'insert-text-box 'insert-pasteboard-box
'insert-image)]
[recursive? any/c #t]
[time (and/c exact? integer?) 0])
void?]{
See @xmethod[editor<%> do-edit-operation].
Called when the snip's editor's method is called,
@scheme[recursive?] is not @scheme[#f], and this snip owns the caret.
}
@defmethod[(draw [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[left real?]
[top real?]
[right real?]
[bottom real?]
[dx real?]
[dy real?]
[draw-caret (one-of/c 'no-caret 'show-inactive-caret 'show-caret)])
void?]{
@methspec{
Called (by an editor) to draw the snip into the given drawing context
with the snip's top left corner at @techlink{location} (@scheme[x],
@scheme[y]) in DC coordinates.
The arguments @scheme[left], @scheme[top], @scheme[right], and @scheme[bottom]
define a clipping region (in DC coordinates) that the snip can use to
optimize drawing, but it can also ignore these arguments.
The @scheme[dx] and @scheme[dy] argument provide numbers that can be
subtracted from @scheme[x] and @scheme[y] to obtain the snip's @techlink{location} in
editor coordinates (as opposed to DC coordinates, which are used for
drawing).
See @|drawcaretdiscuss| for information about @scheme[draw-caret].
Before this method is called, the correct font, text color, and pen
color for the snip's style will have been set in the drawing context
already. (This is @italic{not} true for @method[snip% get-extent] or
@method[snip% partial-offset].) The @method[snip% draw] method must
not make any other assumptions about the state of the drawing
context, except that the clipping region is already set to something
appropriate. Before @method[snip% draw] returns, it must restore any
drawing context settings that it changes.
See also @xmethod[editor<%> on-paint].
The snip's editor is usually internally locked for
writing and reflowing when this method is called
(see also @|lockdiscuss|).
}
@methimpl{
Draws nothing.
}}
@defmethod[(find-scroll-step [y real?])
nonnegative-exact-integer?]{
@methspec{
If a snip contains more than one vertical scroll step (see
@method[snip% get-num-scroll-steps]) then this method is called to
find a scroll step offset for a given y-offset into the snip.
}
@methimpl{
Returns @scheme[0].
}}
@defmethod[(get-admin)
(or/c (is-a?/c snip-admin%) false/c)]{
Returns the administrator for this snip. (The administrator can be
@scheme[#f] even if the snip is owned but not visible in the editor.)
}
@defmethod[(get-count)
(integer-in 0 100000)]{
Returns the snip's @techlink{count} (i.e., number of @techlink{item}s
within the snip).
}
@defmethod[(get-extent [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[w (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[h (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[descent (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[space (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[lspace (or/c (box/c (and/c real? (not/c negative?))) false/c) #f]
[rspace (or/c (box/c (and/c real? (not/c negative?))) false/c) #f])
void?]{
@methspec{
Calculates the snip's width, height, descent (amount of height which
is drawn below the baseline), space (amount of height which is
``filler'' space at the top), and horizontal spaces (amount of width
which is ``filler'' space at the left and right).
This method is called by the snip's administrator; it is not normally
called directly by others. To get the extent of a snip, use
@xmethod[editor<%> get-snip-location] .
A drawing context is provided for the purpose of finding font sizes,
but no drawing should occur. The @method[snip% get-extent] and
@method[snip% partial-offset] methods must not make any assumptions
about the state of the drawing context, except that it is scaled
properly. In particular, the font for the snip's style is not
automatically set in the drawing context before the method is
called.\footnote{Many snips cache their size information, so
automatically setting the font would be wasteful.} If @method[snip%
get-extent] or @method[snip% partial-offset] changes the drawing
context's setting, it must restore them before returning. However,
the methods should not need to change the drawing context; only font
settings can affect measurement results from a device context, and
@xmethod[dc<%> get-text-extent] accepts a @scheme[font%] argument for
sizing that overrides that device context's current font.
The snip's left and top @techlink{location}s are provided in editor
coordinates. In a text editor, the y-coordinate is the {\em line's}
top @techlink{location}; the snip's actual top @techlink{location} is potentially
undetermined until its height is known.
If a snip caches the result size for future replies, it should
invalidate its cached size when @method[snip% size-cache-invalid] is
called (especially if the snip's size depends on any device context
properties).
If a snip's size changes after receiving a call to
@method[snip% get-extent] and before receiving a call to
@method[snip% size-cache-invalid], then the snip must notify its administrator of the size change, so
that the administrator can recompute its derived size information.
Notify the administrator of a size change by call its
@method[snip-admin% resized] method.
The snip's editor is usually internally locked for writing and
reflowing when this method is called (see also @|lockdiscuss|).
}
@methimpl{
Fills in all boxes with @scheme[0.0].
}}
@defmethod[(get-flags)
(listof symbol?)]{
Returns flags defining the behavior of the snip, a list of the
following symbols:
@itemize{
@item{@indexed-scheme['is-text] --- this is a text snip derived from
@scheme[string-snip%]; do not set this flag}
@item{@indexed-scheme['can-append] --- this snip can be merged with
another snip of the same type}
@item{@indexed-scheme['invisible] --- the user doesn't ``see'' this snip;
e.g.: a carriage return}
@item{@indexed-scheme['hard-newline] --- a newline must follow the snip}
@item{@indexed-scheme['newline] --- a newline currently follows the
snip; only an owning editor should set this flag}
@item{@indexed-scheme['handles-events] --- this snip can handle
keyboard and mouse events}
@item{@indexed-scheme['width-depends-on-x] --- this snip's display
width depends on the snip's x-@techlink{location} within the
editor; e.g.: tab}
@item{@indexed-scheme['height-depends-on-y] --- this snip's display
height depends on the snip's y-@techlink{location} within the editor}
@item{@indexed-scheme['width-depends-on-y] --- this snip's display
width depends on the snip's y-@techlink{location} within the editor}
@item{@indexed-scheme['height-depends-on-x] --- this snip's display
height depends on the snip's x-@techlink{location} within the editor}
@item{@indexed-scheme['uses-editor-path] --- this snip uses its
editor's pathname and should be notified when the name changes;
notification is given as a redundant call to @method[snip%
set-admin]}
}}
@defmethod[(get-num-scroll-steps)
nonnegative-exact-integer?]{
@methspec{
Returns the number of horizontal scroll steps within the snip. For
most snips, this is @scheme[1]. Embedded editor snips use this method so that
scrolling in the owning editor will step through the lines in the
embedded editor.
}
@methimpl{
Returns @scheme[1].
}}
@defmethod[(get-scroll-step-offset [offset nonnegative-exact-integer?])
(and/c real? (not/c negative?))]{
@methspec{
If a snip contains more than one vertical scroll step (see
@method[snip% get-num-scroll-steps]) then this method is called to
find the y-offset into the snip for a given scroll offset.
}
@methimpl{
Returns @scheme[0.0].
}}
@defmethod[(get-snipclass)
(is-a?/c snip-class%)]{
Returns the snip's class, which is used for file saving and
cut-and-paste.
Since this method returns the snip class stored by @method[snip%
set-snipclass], it is not meant to be overridden.
}
@defmethod[(get-style)
(is-a?/c style<%>)]{
Returns the snip's style. See also @method[snip% set-style].
}
@defmethod[(get-text [offset nonnegative-exact-integer?]
[num nonnegative-exact-integer?]
[flattened? any/c #f])
string?]{
@methspec{
Returns the text for this snip starting with the @techlink{position}
@scheme[offset] within the snip, and continuing for a total length of
@scheme[num] @techlink{item}s. If @scheme[offset] is greater than the snip's
@techlink{count}, then @scheme[""] is returned. If @scheme[num] is greater than the
snip's @techlink{count} minus the offset, then text from the offset to the end
of the snip is returned.
If @scheme[flattened?] is not @scheme[#f], then flattened text is returned.
See @|textdiscuss| for a discussion of flattened vs. non-flattened
text.
}
@methimpl{
Returns @scheme[""].
}}
@defmethod[(get-text! [buffer mutable string]
[offset nonnegative-exact-integer?]
[num nonnegative-exact-integer?]
[buffer-offset nonnegative-exact-integer?])
void?]{
@methspec{
Like @method[snip% get-text] in non-flattened mode, except that the
characters are put into the given mutable string, instead of returned
in a newly allocated string.
The @scheme[buffer] string is filled starting at position
@scheme[buffer-offset]. The @scheme[buffer] string must be at least
@math{@scheme[num]+@scheme[buffer-offset]} characters long.
}
@methimpl{
Calls @method[snip% get-text], except in the case of a
@scheme[string-snip%], in which case @scheme[buffer] is filled
directly.
}}
@defmethod[(is-owned?)
boolean?]{
Returns @scheme[#t] if this snip has an owner, @scheme[#f] otherwise.
Note that a snip may be owned by an editor if it was inserted and
then deleted from the editor, if it's still in the editor's undo
history.
}
@defmethod[(match? [snip (is-a?/c snip%)])
boolean?]{
@methspec{
Return @scheme[#t] if @this-obj[] ``matches'' @scheme[snip],
@scheme[#f] otherwise.
}
@methimpl{
Returns @scheme[#t] if the @scheme[snip] and @this-obj[] are from the
same class and have the same length.
}}
@defmethod[(merge-with [prev (is-a?/c snip%)])
(or/c (is-a?/c snip%) false/c)]{
@methspec{
Merges @this-obj[] with @scheme[prev], returning @scheme[#f] if the
snips cannot be merged or a new merged snip otherwise. This method
will only be called if both snips are from the same class and both
have the @indexed-scheme['can-append] flag.
If the returned snip does not have the expected @techlink{count}, its
@techlink{count} is forcibly modified. If the returned snip is
already owned by another administrator, a surrogate snip is created.
The snip's editor is usually internally locked for reading when this
method is called (see also @|lockdiscuss|).
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(next)
(or/c (is-a?/c snip%) false/c)]{
Returns the next snip in the editor owning this snip, or @scheme[#f]
if this is the last snip.
In a text editor, the next snip is the snip at the @techlink{position}
following this snip's (last) @techlink{position}. In a pasteboard,
the next snip is the one immediately behind this
snip. (@|seesniporderdiscuss|)
}
@defmethod[(on-char [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[editorx real?]
[editory real?]
[event (is-a?/c key-event%)])
void?]{
@methspec{
Called to handle keyboard events when this snip has the keyboard focus
and can handle events. The drawing context is provided, as well as
the snip's @techlink{location} in @techlink{display} coordinates (the
event uses @techlink{display} coordinates), and the snip's
@techlink{location} in editor coordinates.
The @scheme[x] and @scheme[y] arguments are the snip's
@techlink{location} in @techlink{display} coordinates. The
@scheme[editorx] and @scheme[editory] arguments are the snip's
@techlink{location} in editor coordinates. To get @scheme[event]'s x
@techlink{location} in snip coordinates, subtract @scheme[x] from
@scheme[(send @scheme[event] get-x)].
See also @indexed-scheme['handles-events] in @method[snip% get-flags].
}
@methimpl{
Does nothing.
}}
@defmethod[(on-event [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[editorx real?]
[editory real?]
[event (is-a?/c mouse-event%)])
void?]{
@methspec{
Called to handle mouse events on the snip when this snip can handle
events and when the snip has the keyboard focus. See @method[snip%
on-char] for information about the arguments.
The @scheme[x] and @scheme[y] arguments are the snip's
@techlink{location} in @techlink{display} coordinates. The
@scheme[editorx] and @scheme[editory] arguments are the snip's
@techlink{location} in editor coordinates. To get @scheme[event]'s x
@techlink{location} in snip coordinates, subtract @scheme[x] from
@scheme[(send @scheme[event] get-x)].
See also @indexed-scheme['handles-events] in @method[snip% get-flags].
}
@methimpl{
Does nothing.
}}
@defmethod[(own-caret [own-it? any/c])
void?]{
@methspec{
Notifies the snip that it is or is not allowed to display the caret
(indicating ownership of keyboard focus) in some
@techlink{display}. This method is @italic{not} called to request
that the caret is actually shown or hidden; the @method[snip% draw]
method is called for all display requests.
The @scheme[own-it?] argument is @scheme[#t] if the snip owns the
keyboard focus or @scheme[#f] otherwise.
}
@methimpl{
Does nothing.
}}
@defmethod[(partial-offset [dc (is-a?/c dc<%>)]
[x real?]
[y real?]
[len nonnegative-exact-integer?])
real?]{
@methspec{
Calculates a partial width for the snip, starting from the first snip
@techlink{item} and continuing for @scheme[len] @techlink{item}s. The
drawing context and snip's @techlink{location}s in editor coordinates
are provided. See also @method[snip% get-extent].
The snip's editor is usually internally locked for writing and
reflowing when this method is called (see also @|lockdiscuss|).
}
@methimpl{
Returns @scheme[0.0].
}}
@defmethod[(previous)
(or/c (is-a?/c snip%) false/c)]{
Returns the previous snip in the editor owning this snip, or @scheme[#f] if this
is the first snip.
}
@defmethod[(release-from-owner)
boolean?]{
@methspec{
Asks the snip to try to release itself from its owner. If the snip is
not owned or the release is successful, then @scheme[#t] is
returned. Otherwise, @scheme[#f] is returned and the snip remains
owned. See also @method[snip% is-owned?].
Use this method for moving a snip from one editor to another. This
method notifies the snip's owning editor that someone else really
wants control of the snip. It is not necessary to use this method for
"cleaning up" a snip when it is deleted from an editor.
}
@methimpl{
Requests a low-level release from the snip's owning administrator.
}}
@defmethod[(resize [w (and/c real? (not/c negative?))]
[h (and/c real? (not/c negative?))])
boolean?]{
@methspec{
Resizes the snip. The snip can refuse to be resized by returning
@scheme[#f]. Otherwise, the snip will resize (it must call its
administrator's @method[snip-admin% resized] method) and return
@scheme[#t].
See also @xmethod[pasteboard% on-interactive-resize].
}
@methimpl{
Returns @scheme[#f].
}}
@defmethod[(set-admin [admin (or/c (is-a?/c snip-admin%) false/c)])
void?]{
Sets the snip's administrator. Only an administrator should call this
method.
The default method sets the internal state of a snip to record its
administrator. It will not modify this state if the snip is already
owned by an administrator and the administrator has not blessed the
transition. If the administrator state of a snip is not modified as
expected during a sensitive call to this method by an instance of
@scheme[text%] or @scheme[pasteboard%], the
internal state may be forcibly modified (if the new administrator was
@scheme[#f]) or a surrogate snip may be created (if the snip was
expected to receive a new administrator).
The snip's (new) editor is usually internally locked for reading when
this method is called (see also @|lockdiscuss|).
}
@defmethod[(set-count [c (integer-in 1 100000)])
void?]{
@methspec{
Sets the snip's @techlink{count} (i.e., the number of @techlink{item}s
within the snip).
The snip's @techlink{count} may be changed by the system (in extreme cases to
maintain consistency) without calling this method.
}
@methimpl{
Sets the snip's @techlink{count} and notifies the snip's administrator
that the snip's size has changed.
}}
@defmethod[(set-flags [flags (listof symbol?)])
void?]{
@methspec{
Sets the snip's flags. See @method[snip% get-flags].
}
@methimpl{
Sets the snip flags and notifies the snip's editor that its flags have
changed.
}}
@defmethod[(set-snipclass [class (is-a?/c snip-class%)])
void?]{
Sets the snip's class, used for file saving and cut-and-paste.
This method stores the snip class internally; other editor objects may
access the snip class directly, instead of through the @method[snip%
get-snipclass] method.
}
@defmethod[(set-style [style (is-a?/c style<%>)])
void?]{
Sets the snip's style if it is not owned by any editor. See also
@method[snip% get-style] and @method[snip% is-owned?].
The snip's style may be changed by the system without calling this method.
}
@defmethod[(set-unmodified)
void?]{
@methspec{
Called by the snip's administrator to notify the snip that its changed
have been saved. The next time snip's internal state is modified by
the user, it should call @method[snip-admin% modified] to report the
state change (but only on the first change after this method is
called, or the first change after the snip acquires a new
administrator).
}
@methimpl{
Does nothing.
}}
@defmethod[(size-cache-invalid)
void?]{
@methspec{
Called to notify the snip that it may need to recalculate its display
arguments (width, height, etc.) when it is next asked, because the
style or @techlink{location} of the snip has changed.
The snip's (new) editor is usually internally locked for reflowing
when this method is called (see also @|lockdiscuss|).
}
@methimpl{
Does nothing.
}}
@defmethod[(split [position nonnegative-exact-integer?]
[first (box/c (is-a?/c snip%))]
[second (box/c (is-a?/c snip%))])
void?]{
@methspec{
Splits the snip into two snips. This is called when a snip has more
than one @techlink{item} and something is inserted between two
@techlink{item}s.
The arguments are a relative @techlink{position} integer and two
boxes. The @techlink{position} integer specifies how many
@techlink{item}s should be given to the new first snip; the rest go
to the new second snip. The two boxes must be filled with two new
snips. (The old snip is no longer used, so it can be recycled as a
new snip.)
If the returned snips do not have the expected @techlink{count}s, their
@techlink{count}s are forcibly modified. If either returned snip is already
owned by another administrator, a surrogate snip is created.
The snip's editor is usually internally locked for reading when this
method is called (see also @|lockdiscuss|).
}
@methimpl{
Creates a new @scheme[snip%] instance while @scheme[position]
elements, and modifies @this-obj[] to decrement its count by
@scheme[position]. The nest snip is installed into @scheme[first] and
@this-obj[] is installed into @scheme[second].
}}
@defmethod[(write [f (is-a?/c editor-stream-out%)])
void?]{
Writes the snip to the given stream. (Snip reading is handled by the
snip class.) Style information about the snip (i.e., the content of
@method[snip% get-style]) will be saved and restored automatically.
}}

View File

@ -0,0 +1,46 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[string-snip% snip% ()]{
An instance of @scheme[string-snip%] is created automatically when
text is inserted into a text editor. See also @xmethod[text%
on-new-string-snip].
@defconstructor*/make[(([allocsize nonnegative-exact-integer? 0])
([s string?]))]{
Creates a string snip whose initial content is @scheme[s], if
supplied, empty otherwise. In the latter case, the optional
@scheme[allocsize] argument is a hint about how much storage space
for text should be initially allocated by the snip.
}
@defmethod[(insert [s string?]
[len nonnegative-exact-integer?]
[pos nonnegative-exact-integer? 0])
void?]{
Inserts @scheme[s] (with length @scheme[len]) into the snip at relative
@techlink{position} @scheme[pos] within the snip.
}
@defmethod[(read [len nonnegative-exact-integer?]
[f (is-a?/c editor-stream-in%)])
void?]{
Reads the snip's data from the given stream.
The @scheme[len] argument specifies the maximum length of the text to
be read. (When a text snip is written to a file, the very first
field is the length of the text contained in the snip.) This method
is usually invoked by the text snip class's @method[snip-class% read]
method.
}}

View File

@ -0,0 +1,569 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[style-delta% object% ()]{
A @scheme[style-delta%] object encapsulates a style change. The changes expressible
by a delta include:
@itemize{
@item{changing the font family}
@item{changing the font face}
@item{changing the font size to a new value}
@item{enlarging the font by an additive amount}
@item{enlarging the font by a multiplicative amount, etc.}
@item{changing the font style (normal, {\it italic}, or {\sl slant})}
@item{toggling the font style}
@item{changing the font to {\it italic} if it is currently {\sl slant}, etc.}
@item{changing the font weight, etc.}
@item{changing the underline, etc.}
@item{changing the vertical alignment, etc.}
@item{changing the foreground color}
@item{dimming or brightening the foreground color, etc.}
@item{changing the background color, etc.}
@item{changing text backing transparency}
}
The @method[style-delta% set-delta] method is convenient for most
style delta settings; it takes a high-level delta specification and
sets the internal delta information.
To take full advantage of a style delta, it is necessary to understand
the internal on/off settings that can be manipulated through methods
such as @method[style-delta% set-weight-on]. For example, the font
weight change is specified through the @scheme[weight-on] and
@scheme[weight-off] internal settings. Roughly, @scheme[weight-on]
turns on a weight setting when it is not present and
@scheme[weight-off] turns off a weight setting when it is
present. These two interact precisely in the following way:
@itemize{
@item{If both @scheme[weight-on] and @scheme[weight-off] are set to @scheme['base],
then the font weight is not changed.}
@item{If @scheme[weight-on] is not @scheme['base], then the weight is set to
@scheme[weight-on].}
@item{If @scheme[weight-off] is not @scheme['base], then the weight will be set back
to @scheme['normal] when the base style has the weight @scheme[weight-off].}
@item{If both @scheme[weight-on] and @scheme[weight-off] are set to the same
value, then the weight is toggled with respect to that value: if
the base style has the weight @scheme[weight-on], then weight is changed to
@scheme['normal]; if the base style has a different weight, it is changed to
@scheme[weight-on].}
@item{If both @scheme[weight-on] and @scheme[weight-off] are set, but to
different values, then the weight is changed to @scheme[weight-on]
only when the base style has the weight @scheme[weight-off].}
}
Font styles, smoothing, underlining, and alignment work in an analogous manner.
The possible values for @scheme[alignment-on] and @scheme[alignment-off] are:
@itemize{
@item{@indexed-scheme['base]}
@item{@indexed-scheme['top]}
@item{@indexed-scheme['center]}
@item{@indexed-scheme['bottom]}
}
The possible values for @scheme[style-on] and @scheme[style-off] are:
@itemize{
@item{@indexed-scheme['base]}
@item{@indexed-scheme['normal]}
@item{@indexed-scheme['italic]}
@item{@indexed-scheme['slant]}
}
The possible values for @scheme[smoothing-on] and @scheme[smoothing-off] are:
@itemize{
@item{@indexed-scheme['base]}
@item{@indexed-scheme['default]}
@item{@indexed-scheme['partly-smoothed]}
@item{@indexed-scheme['smoothed]}
@item{@indexed-scheme['unsmoothed]}
}
The possible values for @scheme[underlined-on] and @scheme[underlined-off] are:
@itemize{
@item{@scheme[#f] (acts like @scheme['base])}
@item{@scheme[#t]}
}
The possible values for @scheme[size-in-pixels-on] and @scheme[size-in-pixels-off] are:
@itemize{
@item{@scheme[#f] (acts like @scheme['base])}
@item{@scheme[#t]}
}
The possible values for @scheme[transparent-text-backing-on] and
@scheme[transparent-text-backing-off] are:
@itemize{
@item{@scheme[#f] (acts like @scheme['base])}
@item{@scheme[#t]}
}
The possible values for @scheme[weight-on] and @scheme[weight-off] are:
@itemize{
@item{@indexed-scheme['base]}
@item{@indexed-scheme['normal]}
@item{@indexed-scheme['bold]}
@item{@indexed-scheme['light]}
}
The family and face settings in a style delta are interdependent:
@itemize{
@item{When a delta's face is @scheme[#f] and its family is
@scheme['base], then neither the face nor family are modified by
the delta.}
@item{When a delta's face is a string and its family is
@scheme['base], then only face is modified by the delta.}
@item{When a delta's family is not @scheme['base], then both the face
and family are modified by the delta. If the delta's face is
@scheme[#f], then applying the delta sets a style's face to
@scheme[#f], so that the family setting prevails in choosing a
font.}
}
@defconstructor*/make[(([change-command (one-of/c 'change-nothing
'change-normal
'change-toggle-underline
'change-toggle-size-in-pixels
'change-normal-color
'change-bold)
'change-nothing])
([change-command (one-of/c 'change-family
'change-style
'change-toggle-style
'change-weight
'change-toggle-weight
'change-smoothing
'change-toggle-smoothing
'change-alignment)]
[v symbol])
([change-command (one-of/c 'change-size
'change-bigger
'change-smaller)]
[v (integer-in 0 255)])
([change-command (one-of/c 'change-underline
'change-size-in-pixels)]
[v any/c]))]{
The initialization arguments are passed on to
@method[style-delta% set-delta].
}
@defmethod[(collapse [delta (is-a?/c style-delta%)])
boolean?]{
Tries to collapse into a single delta the changes that would be made
by applying this delta after a given delta. If the return value is
@scheme[#f], then it is impossible to perform the
collapse. Otherwise, the return value is @scheme[#t] and this delta
will contain the collapsed change specification.
}
@defmethod[(copy [delta (is-a?/c style-delta%)])
void?]{
Copies the given style delta's settings into this one.
}
@defmethod[(equal? [delta (is-a?/c style-delta%)])
boolean?]{
Returns @scheme[#t] if the given delta is equivalent to this one in
all contexts or @scheme[#f] otherwise.
}
@defmethod[(get-alignment-off)
(one-of/c 'base 'top 'center 'bottom)]{
See @scheme[style-delta%].
}
@defmethod[(get-alignment-on)
(one-of/c 'base 'top 'center 'bottom)]{
See @scheme[style-delta%].
}
@defmethod[(get-background-add)
(is-a?/c add-color<%>)]{
Gets the object additive color shift for the background (applied after
the multiplicative factor). Call this @scheme[add-color<%>] object's
methods to change the style delta's additive background color shift.
}
@defmethod[(get-background-mult)
(is-a?/c mult-color<%>)]{
Gets the multiplicative color shift for the background (applied before
the additive factor). Call this @scheme[mult-color<%>] object's
methods to change the style delta's multiplicative background color
shift.
}
@defmethod[(get-face)
(or/c string? false/c)]{
Gets the delta's font face string. If this string is @scheme[#f] and the
family is @indexed-scheme['base] when the delta is applied to a style,
the style's face and family are not changed. However, if the face
string is @scheme[#f] and the family is not @indexed-scheme['base], then
the style's face is changed to @scheme[#f].
See also @method[style-delta% get-family].
}
@defmethod[(get-family)
(one-of/c 'base 'default 'decorative 'roman 'script
'swiss 'modern 'symbol 'system)]{
Returns the delta's font family. The possible values are
@itemize{
@item{@indexed-scheme['base] --- no change to family}
@item{@indexed-scheme['default]}
@item{@indexed-scheme['decorative]}
@item{@indexed-scheme['roman]}
@item{@indexed-scheme['script]}
@item{@indexed-scheme['swiss]}
@item{@indexed-scheme['modern] (fixed width)}
@item{@indexed-scheme['symbol] (Greek letters)}
@item{@indexed-scheme['system] (used to draw control labels)}
}
See also
@method[style-delta% get-face].
}
@defmethod[(get-foreground-add)
(is-a?/c add-color<%>)]{
Gets the additive color shift for the foreground (applied after the
multiplicative factor). Call this @scheme[add-color<%>] object's
methods to change the style delta's additive foreground color shift.
}
@defmethod[(get-foreground-mult)
(is-a?/c mult-color<%>)]{
Gets the multiplicative color shift for the foreground (applied before
the additive factor). Call this @scheme[mult-color<%>] object's
methods to change the style delta's multiplicative foreground color
shift.
}
@defmethod[(get-size-add)
(integer-in 0 255)]{
Gets the additive font size shift (applied after the multiplicative factor).
}
@defmethod[(get-size-in-pixels-off)
boolean?]{
See @scheme[style-delta%].
}
@defmethod[(get-size-in-pixels-on)
boolean?]{
See @scheme[style-delta%].
}
@defmethod[(get-size-mult)
real?]{
Gets the multiplicative font size shift (applied before the additive factor).
}
@defmethod[(get-smoothing-off)
(one-of/c 'base 'default 'partly-smoothed 'smoothed 'unsmoothed)]{
See @scheme[style-delta%].
}
@defmethod[(get-smoothing-on)
(one-of/c 'base 'default 'partly-smoothed 'smoothed 'unsmoothed)]{See
@scheme[style-delta%].
}
@defmethod[(get-style-off)
(one-of/c 'base 'normal 'italic 'slant)]{See
@scheme[style-delta%].
}
@defmethod[(get-style-on)
(one-of/c 'base 'normal 'italic 'slant)]{See
@scheme[style-delta%].
}
@defmethod[(get-transparent-text-backing-off)
boolean?]{See
@scheme[style-delta%].
}
@defmethod[(get-transparent-text-backing-on)
boolean?]{See
@scheme[style-delta%].
}
@defmethod[(get-underlined-off)
boolean?]{See
@scheme[style-delta%].
}
@defmethod[(get-underlined-on)
boolean?]{See
@scheme[style-delta%].
}
@defmethod[(get-weight-off)
(one-of/c 'base 'normal 'bold 'light)]{See
@scheme[style-delta%].
}
@defmethod[(get-weight-on)
(one-of/c 'base 'normal 'bold 'light)]{See
@scheme[style-delta%].
}
@defmethod[(set-alignment-off [v (one-of/c 'base 'top 'center 'bottom)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-alignment-on [v (one-of/c 'base 'top 'center 'bottom)])
void?]{See
@scheme[style-delta%].
}
@defmethod*[([(set-delta [change-command (one-of/c 'change-nothing
'change-normal
'change-toggle-underline
'change-toggle-size-in-pixels
'change-normal-color
'change-bold)
'change-nothing])
(is-a?/c style-delta%)]
[(set-delta [change-command (one-of/c 'change-family
'change-style
'change-toggle-style
'change-weight
'change-toggle-weight
'change-smoothing
'change-toggle-smoothing
'change-alignment)]
[param symbol])
(is-a?/c style-delta%)]
[(set-delta [change-command (one-of/c 'change-size
'change-bigger
'change-smaller)]
[param (integer-in 0 255)])
(is-a?/c style-delta%)]
[(set-delta [change-command (one-of/c 'change-underline
'change-size-in-pixels)]
[on? any/c])
(is-a?/c style-delta%)])]{
Configures the delta with high-level specifications. The return value
is the delta itself.
Except for @scheme['change-nothing] and
@scheme['change-normal], the command only changes part of the
delta. Thus, applying @scheme['change-bold] and then
@scheme['change-italic] sets the delta for both the style and
weight change.
The @scheme[change-command] argument specifies how the delta is changed;
the possible values are:
@itemize{
@item{@scheme['change-nothing] --- reset all changes}
@item{@scheme['change-normal] --- turn off all styles and resizings}
@item{@scheme['change-toggle-underline] --- underline regions that are currently not underlined, and vice-versa}
@item{@scheme['change-toggle-size-in-pixels] --- interpret sizes in pixels for regions that are currently interpreted in points, and vice-versa}
@item{@scheme['change-normal-color] --- change the foreground and background to black and white, respectively}
@item{@scheme['change-italic] --- change the style of the font to {\it italic}}
@item{@scheme['change-bold] --- change the weight of the font to {\bf bold}}
@item{@scheme['change-family] --- change the font family (@scheme[param] is a family; see
@scheme[font%]); see also
@method[style-delta% get-family]} @item{@scheme['change-style] --- change the style of the font (@scheme[param] is a style; see
@scheme[font%])}
@item{@scheme['change-toggle-style] --- toggle the style of the font (@scheme[param] is a style; see
@scheme[font%])}
@item{@scheme['change-weight] --- change the weight of the font (@scheme[param] is a weight; see
@scheme[font%])}
@item{@scheme['change-toggle-weight] --- toggle the weight of the font (@scheme[param] is a weight; see
@scheme[font%])}
@item{@scheme['change-smoothing] --- change the smoothing of the font (@scheme[param] is a smoothing; see
@scheme[font%])}
@item{@scheme['change-toggle-smoothing] --- toggle the smoothing of the font (@scheme[param] is a smoothing; see
@scheme[font%])}
@item{@scheme['change-alignment] --- change the alignment (@scheme[param] is an alignment; see
@scheme[style-delta%])}
@item{@scheme['change-size] --- change the size to an absolute value (@scheme[param] is a size)}
@item{@scheme['change-bigger] --- make the text larger (@scheme[param] is an additive amount)}
@item{@scheme['change-smaller] --- make the text smaller (@scheme[param] is an additive amount)}
@item{@scheme['change-underline] --- set the underline status to either underlined or plain}
@item{@scheme['change-size-in-pixels] --- set the size interpretation to pixels or points}
}
}
@defmethod*[([(set-delta-background [name string?])
(is-a?/c style-delta%)]
[(set-delta-background [color (is-a?/c color%)])
(is-a?/c style-delta%)])]{
Makes the delta encode a background color change to match the absolute
color given; that is, it sets the multiplicative factors to
@scheme[0.0] in the result of @method[style-delta%
get-background-mult], and it sets the additive values in the result
of @method[style-delta% get-background-add] to the specified color's
values. The return value of the method is the delta itself.
For the case that a string color name is supplied, see
@scheme[color-database<%>].
}
@defmethod[(set-delta-face [name string?]
[family (one-of/c 'base 'default 'decorative 'roman
'script 'swiss 'modern 'symbol 'system)
'default])
(is-a?/c style-delta%)]{
Like @method[style-delta% set-face], but sets the family at the same
time.
The return value is @this-obj[].
}
@defmethod*[([(set-delta-foreground [name string?])
(is-a?/c style-delta%)]
[(set-delta-foreground [color (is-a?/c color%)])
(is-a?/c style-delta%)])]{
Makes the delta encode a foreground color change to match the absolute
color given; that is, it sets the multiplicative factors to
@scheme[0.0] in the result of @method[style-delta%
get-foreground-mult], and it sets the additive values in the result
of @method[style-delta% get-foreground-add] to the specified color's
values. The return value of the method is the delta itself.
For the case that a string color name is supplied, see
@scheme[color-database<%>].
}
@defmethod[(set-face [v (or/c string? false/c)])
void?]{See
@method[style-delta% get-face]. See also
@method[style-delta% set-delta-face].
}
@defmethod[(set-family [v (one-of/c 'base 'default 'decorative 'roman 'script
'swiss 'modern 'symbol 'system)])
void?]{
Sets the delta's font family. See
@method[style-delta% get-family].
}
@defmethod[(set-size-add [v (integer-in 0 255)])
void?]{Sets the additive font size shift (applied
after the multiplicative factor).
}
@defmethod[(set-size-in-pixels-off [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-size-in-pixels-on [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-size-mult [v real?])
void?]{Sets the multiplicative font size shift (applied
before the additive factor).
}
@defmethod[(set-smoothing-off [v (one-of/c 'base 'default 'partly-smoothed 'smoothed 'unsmoothed)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-smoothing-on [v (one-of/c 'base 'default 'partly-smoothed 'smoothed 'unsmoothed)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-style-off [v (one-of/c 'base 'normal 'italic 'slant)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-style-on [v (one-of/c 'base 'normal 'italic 'slant)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-transparent-text-backing-off [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-transparent-text-backing-on [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-underlined-off [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-underlined-on [v any/c])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-weight-off [v (one-of/c 'base 'normal 'bold 'light)])
void?]{See
@scheme[style-delta%].
}
@defmethod[(set-weight-on [v (one-of/c 'base 'normal 'bold 'light)])
void?]{See
@scheme[style-delta%].
}}

View File

@ -0,0 +1,216 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@definterface[style<%> ()]{
A @scheme[style<%>] object encapsulates drawing information (font,
color, alignment, etc.) in a hierarchical manner. A @scheme[style<%>]
object always exists within the context of a @scheme[style-list%]
object and is never created except by a @scheme[style-list%] object.
See also @|stylediscuss|.
@defmethod[(get-alignment)
(one-of/c 'top 'center 'bottom)]{
Returns the style's alignment: @scheme['top], @scheme['center], or
@scheme['bottom].
}
@defmethod[(get-background)
(is-a?/c color%)]{
Returns the style's background color.
}
@defmethod[(get-base-style)
(or/c (is-a?/c style<%>) false/c)]{
Returns the style's base style. See @|stylediscuss| for more
information. The return value is @scheme[#f] only for the basic style
in the list.
}
@defmethod[(get-delta [delta (is-a?/c style-delta%)])
void?]{
Returns the style's delta information if the style is not a join
style. See @|stylediscuss| for more information.
}
@defmethod[(get-face)
(or/c string? false/c)]{
Returns the style's face name. See @scheme[font%].
}
@defmethod[(get-family)
(one-of/c 'default 'decorative 'roman 'script
'swiss 'modern 'symbol 'system)]{
Returns the style's font family. See @scheme[font%].
}
@defmethod[(get-font)
(is-a?/c font%)]{
Returns the style's font information.
}
@defmethod[(get-foreground)
(is-a?/c color%)]{
Returns the style's foreground color.
}
@defmethod[(get-name)
(or/c string? false/c)]{
Returns the style's name, or @scheme[#f] if it is unnamed. Style names
are only set through the style's @scheme[style-list%] object.
}
@defmethod[(get-shift-style)
(is-a?/c style<%>)]{
Returns the style's shift style if it is a join style. Otherwise, the
root style is returned. See @|stylediscuss| for more information.
}
@defmethod[(get-size)
(integer-in 0 255)]{
Returns the style's font size.
}
@defmethod[(get-size-in-pixels)
boolean?]{
Returns @scheme[#t] if the style size is in pixels, instead of points,
or @scheme[#f] otherwise.
}
@defmethod[(get-smoothing)
(one-of/c 'default 'partly-smoothed 'smoothed 'unsmoothed)]{
Returns the style's font smoothing. See @scheme[font%].
}
@defmethod[(get-style)
(one-of/c 'normal 'italic 'slant)]{
Returns the style's font style. See @scheme[font%].
}
@defmethod[(get-text-descent [dc (is-a?/c dc<%>)])
(and/c real? (not/c negative?))]{
Returns the descent of text using this style in a given DC.
}
@defmethod[(get-text-height [dc (is-a?/c dc<%>)])
(and/c real? (not/c negative?))]{
Returns the height of text using this style in a given DC.
}
@defmethod[(get-text-space [dc (is-a?/c dc<%>)])
(and/c real? (not/c negative?))]{
Returns the vertical spacing for text using this style in a given DC.
}
@defmethod[(get-text-width [dc (is-a?/c dc<%>)])
(and/c real? (not/c negative?))]{
Returns the width of a space character using this style in a given
DC.
}
@defmethod[(get-transparent-text-backing)
boolean?]{
Returns @scheme[#t] if text is drawn without erasing the
text background or @scheme[#f] otherwise.
}
@defmethod[(get-underlined)
boolean?]{
Returns @scheme[#t] if the style is underlined or @scheme[#f]
otherwise.
}
@defmethod[(get-weight)
(one-of/c 'normal 'bold 'light)]{
Returns the style's font weight. See @scheme[font%].
}
@defmethod[(is-join?)
boolean?]{
Returns @scheme[#t] if the style is a join style or @scheme[#f]
otherwise. See @|stylediscuss| for more information.
}
@defmethod[(set-base-style [base-style (is-a?/c style<%>)])
void?]{
Sets the style's base style and recomputes the style's font, etc. See
@|stylediscuss| for more information.
}
@defmethod[(set-delta [delta (is-a?/c style-delta%)])
void?]{
Sets the style's delta (if it is not a join style) and recomputes the
style's font, etc. See @|stylediscuss| for more information.
}
@defmethod[(set-shift-style [style (is-a?/c style<%>)])
void?]{
Sets the style's shift style (if it is a join style) and recomputes
the style's font, etc. See @|stylediscuss| for more information.
}
@defmethod[(switch-to [dc (is-a?/c dc<%>)]
[old-style (or/c (is-a?/c style<%>) false/c)])
void?]{
Sets the font, pen color, etc. of the given drawing context. If
@scheme[oldstyle] is not @scheme[#f], only differences between the
given style and this one are applied to the drawing context.
}}

View File

@ -0,0 +1,167 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[style-list% object% ()]{
A @scheme[style-list%] object contains a set of @scheme[style<%>]
objects and maintains the hierarchical relationships between them. A
@scheme[style<%>] object can only be created through the methods of a
@scheme[style-list%] object. There is a global style list object,
@indexed-scheme[the-style-list], but any number of independent lists can be
created for separate style hierarchies. Each editor creates its own
private style list.
See @|stylediscuss| for more information.
@defconstructor/make[()]{
The root style, named @scheme["Basic"], is automatically created.
}
@defmethod[(basic-style)
(is-a?/c style<%>)]{
Returns the root style. Each style list has its own root style.
See also @|mrprefsdiscuss| for information about the
@ResourceFirst{default-font-size}.
}
@defmethod[(convert [style (is-a?/c style<%>)])
(is-a?/c style<%>)]{
Converts @scheme[style], which can be from another style list, to a style
in this list. If @scheme[style] is already in this list, then @scheme[ style]
is returned. If @scheme[style] is named and a style by that name is
already in this list, then the existing named style is returned.
Otherwise, the style is converted by converting its base style
(and shift style if @scheme[style] is a join style) and then creating
a new style in this list.
}
@defmethod[(find-named-style [name string?])
(or/c (is-a?/c style<%>) false/c)]{
Finds a style by name. If no such style can be found, @scheme[#f] is
returned.
}
@defmethod[(find-or-create-join-style [base-style (is-a?/c style<%>)]
[shift-style (is-a?/c style<%>)])
(is-a?/c style<%>)]{
Creates a new join style, or finds an appropriate existing one. The
returned style is always unnamed. See @|stylediscuss| for more
information.
The @scheme[base-style] argument must be a style within this style
list.
}
@defmethod[(find-or-create-style [base-style (is-a?/c style<%>)]
[delta (is-a?/c style-delta%)])
(is-a?/c style<%>)]{
Creates a new derived style, or finds an appropriate existing one.
The returned style is always unnamed. See @|stylediscuss| for more
information.
The @scheme[base-style] argument must be a style within this style list.
}
@defmethod[(forget-notification [key any/c])
void?]{
See @method[style-list% notify-on-change].
The @scheme[key] argument is the value returned by @method[style-list%
notify-on-change].
}
@defmethod[(index-to-style [i nonnegative-exact-integer?])
(or/c (is-a?/c style<%>) false/c)]{
Returns the style associated with the given index, or @scheme[#f] for
a bad index. See also @method[style-list% style-to-index].
}
@defmethod[(new-named-style [name string?]
[like-style (is-a?/c style<%>)])
(is-a?/c style<%>)]{
Creates a new named style, unless the name is already being used.
If @scheme[name] is already being used, then @scheme[like-style] is
ignored and the old style associated to the name is
returned. Otherwise, a new style is created for @scheme[name] with
the same characteristics (i.e., the same base style and same style
delta or shift style) as @scheme[like-style].
The @scheme[like-style] style must be in this style list, otherwise
the named style is derived from the basic style with an empty style
delta.
}
@defmethod[(notify-on-change [f ((or/c (is-a?/c style<%> false/c)) . -> . any)])
any/c]{
Attaches a callback to the style list. The callback is invoked
whenever a style is modified.
Often, a change in one style will trigger a change in several other
derived styles; to allow clients to handle all the changes in a
batch, @scheme[#f] is passed in as the changing style after a set of
styles has been processed.
The return value from @method[style-list% notify-on-change] is an
opaque key to be used with @method[style-list% forget-notification].
}
@defmethod[(number)
nonnegative-exact-integer?]{
Returns the number of styles in the list.
}
@defmethod[(replace-named-style [name string?]
[like-style (is-a?/c style<%>)])
(is-a?/c style<%>)]{
Like @method[style-list% new-named-style], except that if the name is
already mapped to a style, the existing mapping is replaced.
}
@defmethod[(style-to-index [style (is-a?/c style<%>)])
(or/c nonnegative-exact-integer? false/c)]{
Returns the index for a particular style. The index for a style's base
style (and shift style, if it is a join style) is guaranteed to be
lower than the style's own index. (As a result, the root style's
index is always @scheme[0].) A style's index can change whenever a new
style is added to the list, or the base style or shift style of
another style is changed.
If the given style is not in this list, @scheme[#f] is returned.
}}

View File

@ -0,0 +1,23 @@
#reader(lib "defreader.ss" "scribble")
@require["common.ss"]
@defclass[tab-snip% string-snip% ()]{
An instance of @scheme[tab-snip%] is created automatically when a
tab is inserted into an editor.
@defconstructor/make[()]{
Creates a snip for a single tab, though the tab is initially empty.
Normally, a single tab is inserted into a @scheme[tab-snip%] object
using the @method[string-snip% insert] method.
The tab's content is not drawn, through it is used when determining
the size of a single character in editors where tabbing is determined
by the character width (see @method[text% set-tabs]); if the content
is a single tab character (the normal case), then the average
character width of snip's font is used as the tab's width.
}}

File diff suppressed because it is too large Load Diff

View File

@ -864,7 +864,7 @@ When an eventspace is created, it is placed under the management of
the @tech{current custodian}. When a custodian shuts down an
eventspace, all frames and dialogs associated with the eventspace are
destroyed (without calling @method[top-level-window<%> can-close?]
or @xmethod[top-level-window% on-close]), all timers in the
or @xmethod[top-level-window<%> on-close]), all timers in the
eventspace are stopped, and all enqueued callbacks are removed.
Attempting to create a new window, timer, or explicitly queued event
in a shut-down eventspace raises the @scheme[exn:misc] exception.