From b9acd30e39a94f484fae7ca49e2e42ea1214775f Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Fri, 17 Aug 2007 21:13:50 +0000 Subject: [PATCH] checkpoint GUI docs svn: r7110 original commit: cac6aa498d041b0b4e32780bb696aee4ee676c21 --- collects/scribblings/gui/blurbs.ss | 8 +- .../scribblings/gui/editor-admin-class.scrbl | 301 +++ .../scribblings/gui/editor-canvas-class.scrbl | 367 +++ collects/scribblings/gui/editor-classes.scrbl | 30 +- .../gui/editor-data-class-class.scrbl | 44 + .../gui/editor-data-class-list-intf.scrbl | 46 + .../scribblings/gui/editor-data-class.scrbl | 51 + collects/scribblings/gui/editor-funcs.scrbl | 432 ++++ .../scribblings/gui/editor-overview.scrbl | 6 +- .../scribblings/gui/editor-snip-class.scrbl | 349 +++ .../gui/editor-snip-editor-admin-intf.scrbl | 18 + .../gui/editor-stream-in-base-class.scrbl | 56 + .../editor-stream-in-bytes-base-class.scrbl | 14 + .../gui/editor-stream-in-class.scrbl | 137 ++ .../gui/editor-stream-out-base-class.scrbl | 44 + .../editor-stream-out-bytes-base-class.scrbl | 20 + .../gui/editor-stream-out-class.scrbl | 97 + .../gui/editor-wordbreak-map-class.scrbl | 62 + .../scribblings/gui/image-snip-class.scrbl | 144 ++ collects/scribblings/gui/keymap-class.scrbl | 437 ++++ .../scribblings/gui/mult-color-intf.scrbl | 78 + .../scribblings/gui/pasteboard-class.scrbl | 1157 ++++++++++ .../scribblings/gui/readable-snip-intf.scrbl | 25 + collects/scribblings/gui/reference.scrbl | 2 + .../scribblings/gui/snip-admin-class.scrbl | 323 +++ .../scribblings/gui/snip-class-class.scrbl | 146 ++ .../gui/snip-class-list-intf.scrbl | 49 + collects/scribblings/gui/snip-class.scrbl | 845 +++++++ .../scribblings/gui/string-snip-class.scrbl | 46 + .../scribblings/gui/style-delta-class.scrbl | 569 +++++ collects/scribblings/gui/style-intf.scrbl | 216 ++ .../scribblings/gui/style-list-class.scrbl | 167 ++ collects/scribblings/gui/tab-snip-class.scrbl | 23 + collects/scribblings/gui/text-class.scrbl | 2035 +++++++++++++++++ collects/scribblings/gui/win-overview.scrbl | 2 +- 35 files changed, 8325 insertions(+), 21 deletions(-) create mode 100644 collects/scribblings/gui/editor-admin-class.scrbl create mode 100644 collects/scribblings/gui/editor-canvas-class.scrbl create mode 100644 collects/scribblings/gui/editor-data-class-class.scrbl create mode 100644 collects/scribblings/gui/editor-data-class-list-intf.scrbl create mode 100644 collects/scribblings/gui/editor-data-class.scrbl create mode 100644 collects/scribblings/gui/editor-funcs.scrbl create mode 100644 collects/scribblings/gui/editor-snip-class.scrbl create mode 100644 collects/scribblings/gui/editor-snip-editor-admin-intf.scrbl create mode 100644 collects/scribblings/gui/editor-stream-in-base-class.scrbl create mode 100644 collects/scribblings/gui/editor-stream-in-bytes-base-class.scrbl create mode 100644 collects/scribblings/gui/editor-stream-in-class.scrbl create mode 100644 collects/scribblings/gui/editor-stream-out-base-class.scrbl create mode 100644 collects/scribblings/gui/editor-stream-out-bytes-base-class.scrbl create mode 100644 collects/scribblings/gui/editor-stream-out-class.scrbl create mode 100644 collects/scribblings/gui/editor-wordbreak-map-class.scrbl create mode 100644 collects/scribblings/gui/image-snip-class.scrbl create mode 100644 collects/scribblings/gui/keymap-class.scrbl create mode 100644 collects/scribblings/gui/mult-color-intf.scrbl create mode 100644 collects/scribblings/gui/pasteboard-class.scrbl create mode 100644 collects/scribblings/gui/readable-snip-intf.scrbl create mode 100644 collects/scribblings/gui/snip-admin-class.scrbl create mode 100644 collects/scribblings/gui/snip-class-class.scrbl create mode 100644 collects/scribblings/gui/snip-class-list-intf.scrbl create mode 100644 collects/scribblings/gui/snip-class.scrbl create mode 100644 collects/scribblings/gui/string-snip-class.scrbl create mode 100644 collects/scribblings/gui/style-delta-class.scrbl create mode 100644 collects/scribblings/gui/style-intf.scrbl create mode 100644 collects/scribblings/gui/style-list-class.scrbl create mode 100644 collects/scribblings/gui/tab-snip-class.scrbl create mode 100644 collects/scribblings/gui/text-class.scrbl diff --git a/collects/scribblings/gui/blurbs.ss b/collects/scribblings/gui/blurbs.ss index db486c96..f556a96a 100644 --- a/collects/scribblings/gui/blurbs.ss +++ b/collects/scribblings/gui/blurbs.ss @@ -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} diff --git a/collects/scribblings/gui/editor-admin-class.scrbl b/collects/scribblings/gui/editor-admin-class.scrbl new file mode 100644 index 00000000..9b634507 --- /dev/null +++ b/collects/scribblings/gui/editor-admin-class.scrbl @@ -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. + +}}} + diff --git a/collects/scribblings/gui/editor-canvas-class.scrbl b/collects/scribblings/gui/editor-canvas-class.scrbl new file mode 100644 index 00000000..8c6fd304 --- /dev/null +++ b/collects/scribblings/gui/editor-canvas-class.scrbl @@ -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). + +}} diff --git a/collects/scribblings/gui/editor-classes.scrbl b/collects/scribblings/gui/editor-classes.scrbl index df7386fb..b3437448 100644 --- a/collects/scribblings/gui/editor-classes.scrbl +++ b/collects/scribblings/gui/editor-classes.scrbl @@ -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%] diff --git a/collects/scribblings/gui/editor-data-class-class.scrbl b/collects/scribblings/gui/editor-data-class-class.scrbl new file mode 100644 index 00000000..aa92ae85 --- /dev/null +++ b/collects/scribblings/gui/editor-data-class-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/editor-data-class-list-intf.scrbl b/collects/scribblings/gui/editor-data-class-list-intf.scrbl new file mode 100644 index 00000000..5537dc15 --- /dev/null +++ b/collects/scribblings/gui/editor-data-class-list-intf.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/editor-data-class.scrbl b/collects/scribblings/gui/editor-data-class.scrbl new file mode 100644 index 00000000..8d72adc1 --- /dev/null +++ b/collects/scribblings/gui/editor-data-class.scrbl @@ -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]. + +}}} + diff --git a/collects/scribblings/gui/editor-funcs.scrbl b/collects/scribblings/gui/editor-funcs.scrbl new file mode 100644 index 00000000..921843ed --- /dev/null +++ b/collects/scribblings/gui/editor-funcs.scrbl @@ -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. + +} diff --git a/collects/scribblings/gui/editor-overview.scrbl b/collects/scribblings/gui/editor-overview.scrbl index 7771b6d4..c0c10628 100644 --- a/collects/scribblings/gui/editor-overview.scrbl +++ b/collects/scribblings/gui/editor-overview.scrbl @@ -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. diff --git a/collects/scribblings/gui/editor-snip-class.scrbl b/collects/scribblings/gui/editor-snip-class.scrbl new file mode 100644 index 00000000..25f5de6c --- /dev/null +++ b/collects/scribblings/gui/editor-snip-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/editor-snip-editor-admin-intf.scrbl b/collects/scribblings/gui/editor-snip-editor-admin-intf.scrbl new file mode 100644 index 00000000..d1ce183a --- /dev/null +++ b/collects/scribblings/gui/editor-snip-editor-admin-intf.scrbl @@ -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). + +}} + diff --git a/collects/scribblings/gui/editor-stream-in-base-class.scrbl b/collects/scribblings/gui/editor-stream-in-base-class.scrbl new file mode 100644 index 00000000..ada6b585 --- /dev/null +++ b/collects/scribblings/gui/editor-stream-in-base-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/editor-stream-in-bytes-base-class.scrbl b/collects/scribblings/gui/editor-stream-in-bytes-base-class.scrbl new file mode 100644 index 00000000..0723e9bb --- /dev/null +++ b/collects/scribblings/gui/editor-stream-in-bytes-base-class.scrbl @@ -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]. + +}} diff --git a/collects/scribblings/gui/editor-stream-in-class.scrbl b/collects/scribblings/gui/editor-stream-in-class.scrbl new file mode 100644 index 00000000..88ab0b8f --- /dev/null +++ b/collects/scribblings/gui/editor-stream-in-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/editor-stream-out-base-class.scrbl b/collects/scribblings/gui/editor-stream-out-base-class.scrbl new file mode 100644 index 00000000..3b309407 --- /dev/null +++ b/collects/scribblings/gui/editor-stream-out-base-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/editor-stream-out-bytes-base-class.scrbl b/collects/scribblings/gui/editor-stream-out-bytes-base-class.scrbl new file mode 100644 index 00000000..e68796ba --- /dev/null +++ b/collects/scribblings/gui/editor-stream-out-bytes-base-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/editor-stream-out-class.scrbl b/collects/scribblings/gui/editor-stream-out-class.scrbl new file mode 100644 index 00000000..eed960e0 --- /dev/null +++ b/collects/scribblings/gui/editor-stream-out-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/editor-wordbreak-map-class.scrbl b/collects/scribblings/gui/editor-wordbreak-map-class.scrbl new file mode 100644 index 00000000..4615e1d7 --- /dev/null +++ b/collects/scribblings/gui/editor-wordbreak-map-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/image-snip-class.scrbl b/collects/scribblings/gui/image-snip-class.scrbl new file mode 100644 index 00000000..a63924da --- /dev/null +++ b/collects/scribblings/gui/image-snip-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/keymap-class.scrbl b/collects/scribblings/gui/keymap-class.scrbl new file mode 100644 index 00000000..77d5409e --- /dev/null +++ b/collects/scribblings/gui/keymap-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/mult-color-intf.scrbl b/collects/scribblings/gui/mult-color-intf.scrbl new file mode 100644 index 00000000..af74e017 --- /dev/null +++ b/collects/scribblings/gui/mult-color-intf.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/pasteboard-class.scrbl b/collects/scribblings/gui/pasteboard-class.scrbl new file mode 100644 index 00000000..678664db --- /dev/null +++ b/collects/scribblings/gui/pasteboard-class.scrbl @@ -0,0 +1,1157 @@ +#reader(lib "defreader.ss" "scribble") +@require["common.ss"] + +@defclass[pasteboard% object% (editor<%>)]{ + +A @scheme[pasteboard%] object is an editor for displaying snips with + arbitrary @techlink{location}s. + +@defconstructor[()]{ + +The editor will not be displayed until it is attached to an + @scheme[editor-canvas%] object or some other @techlink{display}. + +A new @scheme[keymap%] object is created for the new editor. See also + @method[editor<%> get-keymap] and @method[editor<%> set-keymap]. + +A new @scheme[style-list%] object is created for the new editor. See + also @method[editor<%> get-style-list] and @method[editor<%> + set-style-list]. + +} + + +@defmethod*[([(add-selected [snip (is-a?/c snip%)]) + void?] + [(add-selected [x real?] + [y real?] + [w (and/c real? (not/c negative?))] + [h (and/c real? (not/c negative?))]) + void?])]{ + +Selects snips without deselecting other snips. When coordinates are + given, this method selects all snips that intersect with the given + rectangle (in editor coordinates). + +@|OnSelectNote| + +} + + +@defmethod[#:mode 'pubment + (after-delete [snip (is-a?/c snip%)]) + void?]{ +@methspec{ + +Called after a snip is deleted from the editor (and after the + @techlink{display} is refreshed; use @method[pasteboard% on-delete] + and @method[editor<%> begin-edit-sequence] to avoid extra refreshes + when @method[pasteboard% after-delete] modifies the editor). + +See also @method[pasteboard% can-delete?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ +Does nothing. +} +} + + +@defmethod[#:mode 'pubment + (after-insert [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)] + [x real?] + [y real?]) + void?]{ + +@methspec{ + +Called after a snip is inserted into the editor (and after the + @techlink{display} is refreshed; use @method[pasteboard% on-insert] + and @method[editor<%> begin-edit-sequence] to avoid extra refreshes + when @method[pasteboard% after-insert] modifies the editor). + +See also @method[pasteboard% can-insert?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ +Does nothing. +} +} + + +@defmethod[#:mode 'pubment + (after-interactive-move [event (is-a?/c mouse-event%)]) + void?]{ +@methspec{ + +Called after the user stops interactively dragging snips (the ones + that are selected; see @method[pasteboard% + find-next-selected-snip]). The mouse event that terminated the move + (usually a button-up event) is provided. + +See also @method[pasteboard% can-interactive-move?] and + @method[pasteboard% on-interactive-move]. + +} +@methimpl{ + +Does nothing. + +} +} + + +@defmethod[#:mode 'pubment + (after-interactive-resize [snip (is-a?/c snip%)]) + void?]{ +@methspec{ + +Called after the user stops interactively resizing a snip (the one + that is currently selected; see @method[pasteboard% + find-next-selected-snip]). The @scheme[snip] argument is the snip + that was resized. + +See also @method[pasteboard% can-interactive-resize?] and + @method[pasteboard% on-interactive-resize]. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (after-move-to [snip (is-a?/c snip%)] + [x real?] + [y real?] + [dragging? any/c]) + void?]{ +@methspec{ + +Called after a given snip is moved within the editor (and after the + @techlink{display} is refreshed; use @method[pasteboard% on-move-to] + and @method[editor<%> begin-edit-sequence] to avoid extra refreshes + when @method[pasteboard% after-move-to] modifies the editor). + +If @scheme[dragging?] is not @scheme[#f], then this move was a temporary + move for dragging. + +See also + @method[pasteboard% can-move-to?] and + @method[editor<%> on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (after-reorder [snip (is-a?/c snip%)] + [to-snip (is-a?/c snip%)] + [before? any/c]) + boolean?]{ +@methspec{ + +Called before a snip is moved in the pasteboard's front-to-back snip + order (and after the @techlink{display} is refreshed; use + @method[pasteboard% on-reorder] and @method[editor<%> + begin-edit-sequence] to avoid extra refreshes when + @method[pasteboard% after-reorder] modifies the editor). + +If @scheme[before?] is @scheme[#t], then @scheme[snip] was moved before + @scheme[to-snip], otherwise @scheme[snip] was moved after @scheme[to-snip]. + +See also @method[pasteboard% can-reorder?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (after-resize [snip (is-a?/c snip%)] + [w (and/c real? (not/c negative?))] + [h (and/c real? (not/c negative?))] + [resized? any/c]) + void?]{ +@methspec{ + +Called after a given snip is resized (and after the @techlink{display} + is refreshed; use @method[pasteboard% on-resize] and + @method[editor<%> begin-edit-sequence] to avoid extra refreshes when + @method[pasteboard% after-resize] modifies the editor), or after an + unsuccessful resize attempt was made. + +If @scheme[resized?] is not @scheme[#f], the snip was successfully + resized. + +See also @method[pasteboard% can-resize?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (after-select [snip (is-a?/c snip%)] + [on? any/c]) + void?]{ + +@methspec{ + +Called after a snip in the pasteboard is selected or deselected. See + also @method[pasteboard% on-select]. This method is not called after + selected snip is deleted (and thus de-selected indirectly); see also + @method[pasteboard% after-delete]. + +If @scheme[on?] is @scheme[#t], then @scheme[snip] was just selected, + otherwise @scheme[snip] was just deselected. + +See also @method[pasteboard% can-select?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (can-delete? [snip (is-a?/c snip%)]) + boolean?]{ + +@methspec{ + +Called before a snip is deleted from the editor. + If the return value is @scheme[#f], then the + delete will be aborted. + +See also @method[pasteboard% on-delete] and @method[pasteboard% + after-delete]. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +} +} + +@defmethod[#:mode 'pubment + (can-insert? [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)] + [x real?] + [y real?]) + boolean?]{ + +@methspec{ + +Called before a snip is inserted from the editor. If the return value + is @scheme[#f], then the insert will be aborted. + +See also @method[pasteboard% on-insert] and @method[pasteboard% + after-insert]. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +} +} + + +@defmethod[#:mode 'pubment + (can-interactive-move? [event (is-a?/c mouse-event%)]) + boolean?]{ + +@methspec{ + +Called when the user starts interactively dragging snips (the ones + that are selected; see @method[pasteboard% + find-next-selected-snip]). All of the selected snips will be + moved. If @scheme[#f] is returned, the interactive move is + disallowed. The mouse event that started the move (usually a + button-down event) is provided. + +See also @method[pasteboard% on-interactive-move], @method[pasteboard% + after-interactive-move], and @method[pasteboard% + interactive-adjust-move]. + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[#:mode 'pubment + (can-interactive-resize? [snip (is-a?/c snip%)]) + boolean?]{ +@methspec{ + +Called when the user starts interactively resizing a snip (the one + that is selected; see @method[pasteboard% + find-next-selected-snip]). If @scheme[#f] is returned, the + interactive resize is disallowed. + +The @scheme[snip] argument is the snip that will be resized. + +See also @method[pasteboard% after-interactive-resize], + @method[pasteboard% after-interactive-resize], and + @method[pasteboard% interactive-adjust-resize]. + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[#:mode 'pubment + (can-move-to? [snip (is-a?/c snip%)] + [x real?] + [y real?] + [dragging? any/c]) + boolean?]{ +@methspec{ + +Called before a snip is moved in the editor. If the return value is + @scheme[#f], then the move will be aborted. + +If @scheme[dragging?] is not @scheme[#f], then this move is a + temporary move for dragging. + +See also @method[pasteboard% on-move-to] and @method[pasteboard% + after-move-to]. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[#:mode 'pubment + (can-reorder? [snip (is-a?/c snip%)] + [to-snip (is-a?/c snip%)] + [before? any/c]) + boolean?]{ +@methspec{ + +Called before a snip is moved in the pasteboard's front-to-back snip + order. If the return value is @scheme[#f], then the reordering will + be aborted. + +If @scheme[before?] is @scheme[#t], then @scheme[snip] is to be moved before + @scheme[to-snip], otherwise @scheme[snip] is to be moved after + @scheme[to-snip]. + +See also @method[pasteboard% on-reorder] and @method[pasteboard% + after-reorder]. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[#:mode 'pubment + (can-resize? [snip (is-a?/c snip%)] + [w (and/c real? (not/c negative?))] + [h (and/c real? (not/c negative?))]) + boolean?]{ + +@methspec{ + +Called before a snip is resized in the editor. If the return value is + @scheme[#f], then the resize will be aborted. + +See also @method[pasteboard% on-resize] and @method[pasteboard% + after-resize]. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + +@defmethod[#:mode 'pubment + (can-select? [snip (is-a?/c snip%)] + [on? any/c]) + boolean?]{ +@methspec{ + +This method is called before a snip in the pasteboard is selected or + deselected. If @scheme[#f] is returned, the selection change is + disallowed. This method is not called when a selected snip is to be + deleted (and thus de-selected indirectly); see also + @method[pasteboard% can-delete?]. + +If @scheme[on?] is @scheme[#t], then @scheme[snip] will be selected, +otherwise @scheme[snip] will be deselected. + +See also @method[pasteboard% on-select] and @method[pasteboard% + after-select]. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod*[#:mode 'add + ([(change-style [style (or/c (is-a?/c style<%>) false/c)] + [snip (or/c (is-a?/c snip%) false/c) #f]) + void?] + [(change-style [delta (or/c (is-a?/c style-delta%) false/c)] + [snip (is-a?/c snip%)]) + void?])]{ + +Changes the style of @scheme[style] to a specific style or by applying + a style delta. If @scheme[snip] is @scheme[#f], then all currently + selected snips are changed. + +When a @scheme[style] is provided: @InStyleListNote[] + +} + + +@defmethod[#:mode 'auto-super + (copy-self-to [dest (or/c (is-a?/c text%) (is-a?/c pasteboard%))]) + void?]{ + +The dragability, selection visibility state, and scroll step of + @this-obj[] are installed into @scheme[dest]. + +} + + +@defmethod*[([(delete) + void?] + [(delete [snip (is-a?/c snip%)]) + void?])]{ + +Deletes @scheme[snip] when provided, or deletes the currently selected + snips from the editor when @scheme[snip] is not provided. + +@MonitorMethod[@elem{The content of an editor} @elem{the + system in response to other method + calls} @elem{@method[pasteboard% on-delete]} @elem{content deletion}] + +} + + +@defmethod[(do-copy [time (and/c exact? integer?)] + [extend? any/c]) + void?]{ + +@methspec{ + +Called to copy the editor's current selection into the clipboard. + This method is provided so that it can be overridden by subclasses. + Do not call this method directly; instead, call @method[editor<%> + copy]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Copies the current selection, extending the current clipboard contexts + if @scheme[extend?] is true. + +}} + + +@defmethod[(do-paste [time (and/c exact? integer?)]) + void?]{ +@methspec{ + +Called to paste the current contents of the clipboard into the editor. + This method is provided so that it can be overridden by subclasses. + Do not call this method directly; instead, call @method[editor<%> + paste]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Pastes. + +}} + + +@defmethod[(do-paste-x-selection [time (and/c exact? integer?)]) + void?]{ +@methspec{ + +Called to paste the current contents of the X selection under X (or + the clipboard under Windows and Mac OS X) into the editor. This + method is provided so that it can be overridden by subclasses. Do + not call this method directly; instead, call @method[editor<%> + paste-x-selection]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Pastes. + +}} + + +@defmethod[(erase) + void?]{ + +Deletes all snips from the editor. + +See also @method[pasteboard% delete]. + +} + + +@defmethod[(find-next-selected-snip [start (or/c (is-a?/c snip%) false/c)]) + (or/c (is-a?/c snip%) false/c)]{ + +Returns the next selected snip in the editor, starting the search + after @scheme[start]. (@|seesniporderdiscuss|) If @scheme[start] is @scheme[#f], + then the search starts with the first snip in the editor (and thus + returns the first selected snip, if any are selected). If no more + selected snips are available, or if @scheme[start] is not in the + pasteboard, @scheme[#f] is returned. + +} + + +@defmethod[(find-snip [x real?] + [y real?] + [after (or/c (is-a?/c snip%) false/c) #f]) + (or/c (is-a?/c snip%) false/c)]{ + +Finds the frontmost snip (after a given snip) that intersects a given + @techlink{location}. @|seesniporderdiscuss| + +The @scheme[x] and @scheme[y] arguments are in editor coordinates. If + @scheme[after] is not supplied, the frontmost snip at @scheme[x] and + @scheme[y] is returned, otherwise the frontmost snip behind @scheme[after] + is returned. If @scheme[after] is a snip that is not in the pasteboard, + @scheme[#f] is returned. + +@|OVD| + +} + + +@defmethod[(get-center [x (box/c real?)] + [y (box/c real?)]) + void?]{ + +Returns the center of the pasteboard in pasteboard coordinates. + +The @scheme[x] box is filled with the x-coordinate of the center and +@scheme[y] is filled with the y-coordinate of the center. + +} + + +@defmethod[(get-dragable) + boolean?]{ + +Returns whether snips in the editor can be interactively dragged by + event handling in @method[pasteboard% on-default-event]: @scheme[#t] + if dragging is allowed, @scheme[#f] otherwise. By default, dragging + is allowed. See also @method[pasteboard% set-dragable]. + +} + +@defmethod[(get-scroll-step) + (and/c real? (not/c negative?))]{ + +Gets the editor @techlink{location} offset for each vertical scroll + position. See also @method[pasteboard% set-scroll-step]. + +} + + +@defmethod[(get-selection-visible) + boolean?]{ + +Returns whether selection dots are drawn around the edge of selected + snips in the pasteboard. By default, selection dots are on. See also + @method[pasteboard% set-selection-visible]. + +} + + +@defmethod*[#:mode 'add + ([(insert [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)] + [x real?] + [y real?]) + void?] + [(insert [snip (is-a?/c snip%)] + [x real?] + [y real?]) + void?] + [(insert [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)]) + void?])]{ + +Inserts @scheme[snip] at @techlink{location} @math{(@scheme[x], + @scheme[y])} just in front of + @scheme[before]. (@|seesniporderdiscuss|) If @scheme[before] is nor + provided or is @scheme[#f], then @scheme[snip] is inserted behind all + other snips. + +} + + +@defmethod[(interactive-adjust-mouse [x (box/c real?)] + [y (box/c real?)]) + void?]{ + +@methspec{ + +This method is called during interactive dragging and resizing (of the + currently selected snips; see @method[pasteboard% + find-next-selected-snip]) to preprocess the current mouse + @techlink{location} (in editor coordinates). The snip and actual x + and y coordinates are passed into the method (boxed); the resulting + coordinates are used instead of the actual mouse @techlink{location}. + +See also + @method[pasteboard% interactive-adjust-resize]. + +} +@methimpl{ + +A negative value for either @scheme[x] or @scheme[y] is replaced with + @scheme[0]. + +}} + + +@defmethod[(interactive-adjust-move [snip (is-a?/c snip%)] + [x (box/c real?)] + [y (box/c real?)]) + void?]{ +@methspec{ + +This method is called during an interactive move (for each selected + snip) to preprocess the user-determined snip @techlink{location} for each + selected snip. The snip and mouse-determined @techlink{location}s (in editor + coordinates) are passed into the method (boxed); the resulting + @techlink{location}s are used for graphical feedback to the user during moving. + +The actual mouse coordinates are first sent through + @method[pasteboard% interactive-adjust-mouse] before determining the + @techlink{location}s passed into this method. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[(interactive-adjust-resize [snip (is-a?/c snip%)] + [width (box/c (and/c real? (not/c negative?)))] + [height (box/c (and/c real? (not/c negative?)))]) + void?]{ +@methspec{ + +This method is called during interactive resizing of a snip to + preprocess the user-determined snip size. The snip and + mouse-determined height and width are passed into the method (boxed); + the resulting height and width are used for graphical feedback to the + user during resizing. + +The actual mouse coordinates are first sent through + @method[pasteboard% interactive-adjust-mouse] before determining the + sizes passed into this method. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[(is-selected? [snip (is-a?/c snip%)]) + boolean?]{ + +Returns @scheme[#t] if a specified snip is currently selected or + @scheme[#f] otherwise. + +} + +@defmethod[(lower [snip (is-a?/c snip%)]) + void?]{ + +Moves the snip one level deeper (i.e., behind one more other snip) in + the pasteboard's snip order. @|seesniporderdiscuss| + +See also @method[pasteboard% raise], @method[pasteboard% set-before], + and @method[pasteboard% set-after]. + +} + + +@defmethod*[([(move [snip (is-a?/c snip%)] + [x real?] + [y real?]) + void?] + [(move [x real?] + [y real?]) + void?])]{ + +Moves @scheme[snip] right @scheme[x] pixels and down @scheme[y] + pixels. If @scheme[snip] is not provided, then all selected snips + are moved. + +@|OnMoveNote| + +} + + +@defmethod[(move-to [snip (is-a?/c snip%)] + [x real?] + [y real?]) + void?]{ + +Moves @scheme[snip] to a given @techlink{location} in the editor. + +@|OnMoveNote| + +} + + +@defmethod[(no-selected) + void?]{ + +Deselects all selected snips in the editor. + +@|OnSelectNote| + +} + + +@defmethod[#:mode 'override + (on-default-event [event (is-a?/c mouse-event%)]) + void?]{ + +Selects, drags, and resizes snips: + +@itemize{ + +@item{Clicking on a snip selects the snip. Shift-clicking extends +the current selection with the snip.} + +@item{Clicking in the space between snips drags a selection +box; once the mouse button is released, all snips touching the +box are selected. Shift-clicking extends the current selection +with the new snips.} + +@item{Double-clicking on a snip calls +@method[pasteboard% on-double-click].} + +@item{Clicking on a selected snip drags the selected snip(s) to a new +@techlink{location}.} + +@item{Clicking on a hiliting tab for a selected object resizes the +object.} + +} +} + + +@defmethod[#:mode 'pubment + (on-delete [snip (is-a?/c snip%)]) + void?]{ + +Called before a snip is deleted from the editor, after + @method[pasteboard% can-delete?] is called to verify that the + deletion is allowed. The @method[pasteboard% after-delete] method is + guaranteed to be called after the delete has completed. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). Use @method[pasteboard% after-delete] to + modify the editor, if necessary. + +} + + +@defmethod[(on-double-click [snip (is-a?/c snip%)] + [event (is-a?/c mouse-event%)]) + void?]{ +@methspec{ + +This method is called when the user double-clicks on a snip in the + editor. The clicked-on snip and event records are passed to the + method. + +} +@methimpl{ + +If @scheme[snip] accepts events, it is designated as the caret owner + and all snips in the editor are unselected. + +}} + + +@defmethod[#:mode 'pubment + (on-insert [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)] + [x real?] + [y real?]) + void?]{ + + +Called before a snip is inserted from the editor, after + @method[pasteboard% can-insert?] is called to verify that the + insertion is allowed. The @method[pasteboard% after-insert] method is + guaranteed to be called after the insert has completed. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). Use @method[pasteboard% after-insert] to + modify the editor, if necessary. + +} + + +@defmethod[#:mode 'pubment + (on-interactive-move [event (is-a?/c mouse-event%)]) + void?]{ +@methspec{ + +Called when the user starts interactively dragging snips (the ones + that are selected; see @method[pasteboard% find-next-selected-snip]), + after @method[pasteboard% can-interactive-move?] is called to verify + that the move is allowed. The @method[pasteboard% + after-interactive-move] method is guaranteed to be called after the + move has completed. All of the selected snips will be moved. The + mouse event that started the move (usually a button-down event) is + provided. + +See also @method[pasteboard% interactive-adjust-move]. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (on-interactive-resize [snip (is-a?/c snip%)]) + void?]{ +@methspec{ + +Called when the user starts interactively resizing a snip (the one + that is selected; see @method[pasteboard% find-next-selected-snip]), + after @method[pasteboard% can-interactive-resize?] is called to + verify that the resize is allowed. The @method[pasteboard% + after-interactive-resize] method is guaranteed to be called after the + resize has completed. + +The @scheme[snip] argument is the snip that will be resized. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (on-move-to [snip (is-a?/c snip%)] + [x real?] + [y real?] + [dragging? any/c]) + void?]{ +@methspec{ + +Called before a snip is moved in the editor, after @method[pasteboard% + can-move-to?] is called to verify that the move is allowed. The + @method[pasteboard% after-move-to] method is guaranteed to be called + after the move has completed. + +If @scheme[dragging?] is not @scheme[#f], then this move is a + temporary move for dragging. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). Use @method[pasteboard% after-move-to] to + modify the editor, if necessary. See also @method[pasteboard% + on-interactive-move] and @method[pasteboard% + interactive-adjust-move]. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (on-reorder [snip (is-a?/c snip%)] + [to-snip (is-a?/c snip%)] + [before? any/c]) + boolean?]{ +@methspec{ + +Called before a snip is moved in the pasteboard's front-to-back snip + order, after @method[pasteboard% can-reorder?] is called to verify + that the reorder is allowed. The @method[pasteboard% after-reorder] + method is guaranteed to be called after the reorder has completed. + +If @scheme[before?] is @scheme[#t], then @scheme[snip] is to be moved + before @scheme[to-snip], otherwise @scheme[snip] is to be moved after + @scheme[to-snip]. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). Use @method[pasteboard% after-reorder] to + modify the editor, if necessary. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (on-resize [snip (is-a?/c snip%)] + [w (and/c real? (not/c negative?))] + [h (and/c real? (not/c negative?))]) + void?]{ + +@methspec{ + +Called before a snip is resized by the editor, after + @method[pasteboard% can-resize?] is called to verify that the resize + is allowed. The @method[pasteboard% after-resize] method is + guaranteed to be called after the resize has completed. + +The editor is internally locked for writing when this method is called (see + also @|lockdiscuss|). Use +@method[pasteboard% after-resize] to modify the editor, if necessary. + +Note that a snip calls +@method[editor<%> resized], not this method, to notify the pasteboard that the snip resized + itself. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (on-select [snip (is-a?/c snip%)] + [on? any/c]) + void?]{ +@methspec{ + +Called before a snip in the pasteboard is selected or deselected, + after @method[pasteboard% can-select?] is called to verify that the + selection is allowed. The @method[pasteboard% after-select] method is + guaranteed to be called after the selection has completed. This + method is not called when a selected snip is to be deleted (and thus + de-selected indirectly); see also @method[pasteboard% on-delete] . + +If @scheme[on?] is @scheme[#t], then @scheme[snip] will be selected, + otherwise @scheme[snip] will be deselected. + +The editor is internally locked for writing when this method is called + (see also @|lockdiscuss|). Use @method[pasteboard% after-select] to + modify the editor, if necessary. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[(raise [snip (is-a?/c snip%)]) + void?]{ + +Moves a snip one level shallower (i.e., in front of one more other + snip) in the pasteboard's snip order. @|seesniporderdiscuss| + +See also @method[pasteboard% lower], @method[pasteboard% set-before], + and @method[pasteboard% set-after]. + +} + + +@defmethod[(remove [snip (is-a?/c snip%)]) + void?]{ + +Removes the specified snip from the editor in a non-undoable manner + (so the snip is completely free of the pasteboard can be used in + other editors). + +See also @method[pasteboard% delete]. + +} + + +@defmethod[(remove-selected [snip (is-a?/c snip%)]) + void?]{ + +Deselects @scheme[snip] (if it is currently selected) without + deselecting any other snips. + +@|OnSelectNote| + +} + + +@defmethod[(resize [snip (is-a?/c snip%)] + [w (and/c real? (not/c negative?))] + [h (and/c real? (not/c negative?))]) + boolean?]{ + +Attempts to resize a given snip. If the snip allows resizing, + @scheme[#t] is returned, otherwise @scheme[#f] is returned. Using + this method instead of calling the snip's @method[snip% resize] + method directly will make the resize undo-able. + +} + + +@defmethod[(set-after [snip (is-a?/c snip%)] + [after (or/c (is-a?/c snip%) false/c)]) + void?]{ + +Changes the depth of @scheme[snip] moving it just behind + @scheme[after]. If @scheme[after] is @scheme[#f], @scheme[snip] is + moved to the back. @|seesniporderdiscuss| + +See also @method[pasteboard% raise], @method[pasteboard% lower], and + @method[pasteboard% set-before]. + +} + + +@defmethod[(set-before [snip (is-a?/c snip%)] + [before (or/c (is-a?/c snip%) false/c)]) + void?]{ + +Changes the depth of @scheme[snip] moving it just in front of + @scheme[before]. If @scheme[before] is @scheme[#f], @scheme[snip] is + moved to the front. @|seesniporderdiscuss| + +See also @method[pasteboard% raise], @method[pasteboard% lower], and + @method[pasteboard% set-after]. + +} + + +@defmethod[(set-dragable [allow-drag? any/c]) + void?]{ + +Sets whether snips in the editor can be interactively dragged by event + handling in @method[pasteboard% on-default-event]: a true value + allows dragging, @scheme[#f] disallows dragging. See also + @method[pasteboard% get-dragable]. + +} + +@defmethod[(set-scroll-step [stepsize (and/c real? (not/c negative?))]) + void?]{ + +Sets the editor @techlink{location} offset for each vertical scroll + position. See also @method[pasteboard% get-scroll-step]. + +} + +@defmethod[(set-selected [snip (is-a?/c snip%)]) + void?]{ + +Selects a specified snip (deselecting all others). + +@|OnSelectNote| + +} + +@defmethod[(set-selection-visible [visible? any/c]) + void?]{ + +Sets whether selection dots are drawn around the edge of selected + snips in the pasteboard. See also @method[pasteboard% + get-selection-visible]. + +}} diff --git a/collects/scribblings/gui/readable-snip-intf.scrbl b/collects/scribblings/gui/readable-snip-intf.scrbl new file mode 100644 index 00000000..6e3f6638 --- /dev/null +++ b/collects/scribblings/gui/readable-snip-intf.scrbl @@ -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. + + +}} + diff --git a/collects/scribblings/gui/reference.scrbl b/collects/scribblings/gui/reference.scrbl index de750d2c..a49b019f 100644 --- a/collects/scribblings/gui/reference.scrbl +++ b/collects/scribblings/gui/reference.scrbl @@ -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"] diff --git a/collects/scribblings/gui/snip-admin-class.scrbl b/collects/scribblings/gui/snip-admin-class.scrbl new file mode 100644 index 00000000..bd9e2b8a --- /dev/null +++ b/collects/scribblings/gui/snip-admin-class.scrbl @@ -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. + +}}} diff --git a/collects/scribblings/gui/snip-class-class.scrbl b/collects/scribblings/gui/snip-class-class.scrbl new file mode 100644 index 00000000..cf5010e2 --- /dev/null +++ b/collects/scribblings/gui/snip-class-class.scrbl @@ -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]. + +}} +} \ No newline at end of file diff --git a/collects/scribblings/gui/snip-class-list-intf.scrbl b/collects/scribblings/gui/snip-class-list-intf.scrbl new file mode 100644 index 00000000..92d90193 --- /dev/null +++ b/collects/scribblings/gui/snip-class-list-intf.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/snip-class.scrbl b/collects/scribblings/gui/snip-class.scrbl new file mode 100644 index 00000000..d3a4332e --- /dev/null +++ b/collects/scribblings/gui/snip-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/string-snip-class.scrbl b/collects/scribblings/gui/string-snip-class.scrbl new file mode 100644 index 00000000..d4796dfd --- /dev/null +++ b/collects/scribblings/gui/string-snip-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/style-delta-class.scrbl b/collects/scribblings/gui/style-delta-class.scrbl new file mode 100644 index 00000000..9568cbee --- /dev/null +++ b/collects/scribblings/gui/style-delta-class.scrbl @@ -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%]. +}} diff --git a/collects/scribblings/gui/style-intf.scrbl b/collects/scribblings/gui/style-intf.scrbl new file mode 100644 index 00000000..eb63aa06 --- /dev/null +++ b/collects/scribblings/gui/style-intf.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/style-list-class.scrbl b/collects/scribblings/gui/style-list-class.scrbl new file mode 100644 index 00000000..30a73d11 --- /dev/null +++ b/collects/scribblings/gui/style-list-class.scrbl @@ -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. + +}} + diff --git a/collects/scribblings/gui/tab-snip-class.scrbl b/collects/scribblings/gui/tab-snip-class.scrbl new file mode 100644 index 00000000..5f3d0403 --- /dev/null +++ b/collects/scribblings/gui/tab-snip-class.scrbl @@ -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. + +}} diff --git a/collects/scribblings/gui/text-class.scrbl b/collects/scribblings/gui/text-class.scrbl new file mode 100644 index 00000000..622859b9 --- /dev/null +++ b/collects/scribblings/gui/text-class.scrbl @@ -0,0 +1,2035 @@ +#reader(lib "defreader.ss" "scribble") +@require["common.ss"] + +@defclass[text% object% (editor<%>)]{ + +A @scheme[text%] object is a standard text editor. A text editor is + displayed on the screen through an @scheme[editor-canvas%] object or + some other @techlink{display}. + + +@defconstructor[([line-spacing (and/c real? (not/c negative?)) 1.0] + [tab-stops (listof real?)] + [auto-wrap any/c #f])]{ + +The @scheme[line-spacing] argument sets the additional amount of space + (in DC units) inserted between each line in the editor when the + editor is displayed. This spacing is included in the reported height + of each line. + +See @method[text% set-tabs] for information about @scheme[tabstops]. + +If @scheme[auto-wrap] is true, then auto-wrapping is enabled via + @method[editor<%> auto-wrap]. + +A new @scheme[keymap%] object is created for the new editor. See also + @method[editor<%> get-keymap] and @method[editor<%> set-keymap]. + +A new @scheme[style-list%] object is created for the new editor. See + also @method[editor<%> get-style-list] and @method[editor<%> + set-style-list]. + +} + + +@defmethod[#:mode 'pubment + (after-change-style [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called after the style is changed for a given range (and after the + @techlink{display} is refreshed; use @method[text% on-change-style] + and @method[editor<%> begin-edit-sequence] to avoid extra refreshes + when @method[text% after-change-style] modifies the editor). + +See also @method[text% can-change-style?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (after-delete [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called after a given range is deleted from the editor (and after the + @techlink{display} is refreshed; use @method[text% on-delete] and + @method[editor<%> begin-edit-sequence] to avoid extra refreshes when + @method[text% after-delete] modifies the editor). + +The @scheme[start] argument specifies the starting @techlink{position} + of the deleted range. The @scheme[len] argument specifies number of + deleted @techlink{item}s (so @math{@scheme[start]+@scheme[len]} is + the ending @techlink{position} of the deleted range). + +See also @method[text% can-delete?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (after-insert [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called after @techlink{item}s are inserted into the editor (and after + the @techlink{display} is refreshed; use @method[text% on-insert] and + @method[editor<%> begin-edit-sequence] to avoid extra refreshes when + @method[text% after-insert] modifies the editor). + +The @scheme[start] argument specifies the @techlink{position} of the insert. The + @scheme[len] argument specifies the total length (in @techlink{position}s) of + the inserted @techlink{item}s. + +See also @method[text% can-insert?] and @method[editor<%> + on-edit-sequence]. + +No internals locks are set when this method is called. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (after-merge-snips [pos nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called after adjacent snips in the editor are combined into one. + +The @scheme[pos] argument specifies the @techlink{position} within the editor + where the snips were merged (i.e., one old snip was just before + @scheme[pos], one old was just after @scheme[pos], and the new snip spans + @scheme[pos]). + +See also @method[snip% merge-with]. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (after-set-position) + void?]{ + +@methspec{ + +Called after the start and end @techlink{position} have been moved (but not + when the @techlink{position} is moved due to inserts or deletes). + +See also +@method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[#:mode 'pubment + (after-set-size-constraint) + void?]{ + +@methspec{ + +Called after the editor's maximum or minimum height or width is + changed (and after the @techlink{display} is refreshed; use + @method[text% on-set-size-constraint] and @method[editor<%> + begin-edit-sequence] to avoid extra refreshes when @method[text% + after-set-size-constraint] modifies the editor). + +(This callback method is provided because setting an editor's maximum + width may cause lines to be re-flowed with soft carriage returns.) + +See also @method[text% can-set-size-constraint?] and @method[editor<%> + on-edit-sequence]. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (after-split-snip [pos nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called after a snip in the editor is split into two, either through a + call to @method[text% split-snip] or during some other action, such + as inserting. + +The @scheme[pos] argument specifies the @techlink{position} within the editor + where a snip was split. + +} +@methimpl{ + +Does nothing. + +}} + +@defmethod[(call-clickback [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?]) + void?]{ + +Simulates a user click that invokes a clickback, if the given range of + @techlink{position}s is within a clickback's region. See also + @|clickbackdiscuss|. + +} + +@defmethod[#:mode 'pubment + (can-change-style? [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + boolean?]{ + +@methspec{ + +Called before the style is changed in a given range of the editor. If + the return value is @scheme[#f], then the style change will be + aborted. + +The editor is internally locked for writing during a call to this + method (see also @|lockdiscuss|). Use @method[text% + after-change-style] to modify the editor, if necessary. + +See also @method[text% on-change-style], @method[text% + after-change-style], and @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Returns @scheme[#t]. + +} +} + +@defmethod[#:mode 'pubment + (can-delete? [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + boolean?]{ +@methspec{ + +Called before a range is deleted from the editor. +If the return value is @scheme[#f], then the +delete will be aborted. + +The @scheme[start] argument specifies the starting @techlink{position} + of the range to delete. The @scheme[len] argument specifies number of + @techlink{item}s to delete (so @math{@scheme[start]+@scheme[len]} is + the ending @techlink{position} of the range to delete). + +The editor is internally locked for writing during a call to this method +(see also @|lockdiscuss|). Use +@method[text% after-delete] to modify the editor, if necessary. + +See also @method[text% on-delete], @method[text% after-delete], and + @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + +@defmethod[#:mode 'pubment + (can-insert? [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + boolean?]{ +@methspec{ + +Called before @techlink{item}s are inserted into the editor. If the + return value is @scheme[#f], then the insert will be aborted. + +The @scheme[start] argument specifies the @techlink{position} of the potential + insert. The @scheme[len] argument specifies the total length (in + @techlink{position}s) of the @techlink{item}s to be inserted. + +The editor is internally locked for writing during a call to this + method (see also @|lockdiscuss|). Use @method[text% after-insert] to + modify the editor, if necessary. + +See also @method[text% on-insert], @method[text% after-insert], and + @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[#:mode 'pubment + (can-set-size-constraint?) + boolean?]{ + +@methspec{ + +Called before the editor's maximum or minimum height or width +is changed. If the return value is @scheme[#f], then the +change will be aborted. + +(This callback method is provided because setting an editor's maximum +width may cause lines to be re-flowed with soft carriage returns.) + +See also @method[text% on-set-size-constraint], @method[text% + after-set-size-constraint], and @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Returns @scheme[#t]. + +}} + + +@defmethod[(caret-hidden?) + boolean?]{ + +Returns @scheme[#t] if the caret is hidden for this editor or @scheme[#f] +otherwise. + +See also @method[text% hide-caret]. + +} + + +@defmethod*[#:mode 'add + ([(change-style [delta (or/c (is-a?/c style-delta%) false/c)] + [start (or/c nonnegative-exact-integer? (one/of 'start))] + [end (or/c nonnegative-exact-integer? (one/of 'end)) 'end] + [counts-as-mod? any/c @scheme[#t]]) + void?] + [(change-style [style (or/c (is-a?/c style<%>) false/c)] + [start (or/c nonnegative-exact-integer? (one/of 'start)) 'start] + [end (or/c nonnegative-exact-integer? (one/of 'end)) 'end] + [counts-as-mod? any/c @scheme[#t]]) + void?])]{ + +Changes the style for a region in the editor by applying a style delta + or installing a specific style. If @scheme[start] is @scheme['start] + and @scheme[end] is @scheme['end], then the currently selected + @techlink{item}s are changed. Otherwise, if @scheme[end] is + @scheme['end], then the style is changed from @scheme[start] until + the end of the selection. If @scheme[counts-as-mod?] is @scheme[#f], + then @method[editor<%> set-modified] is not called after applying the + style change. + +When @scheme[style] is provided: @InStyleListNote[] + +} + + +@defmethod[#:mode 'add + (copy [extend? any/c] + [time (and/c exact? integer?)] + [start (or/c nonnegative-exact-integer? (one/of 'start))] + [end (or/c nonnegative-exact-integer? (one/of 'end)) 'end]) + void?]{ + +Copies specified range of text into the clipboard. If @scheme[extend?] is + not @scheme[#f], the old clipboard contents are appended. If + @scheme[start] is @scheme['start] or @scheme[end] is @scheme['end], then the + current selection start/end is used. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + + +} + + +@defmethod[#:mode 'auto-super + (copy-self-to [dest (or/c (is-a?/c text%) (is-a?/c pasteboard%))]) + void?]{ + +This editor's file format, wordbreak function, wordbreak map, + click-between-threshold, caret visibility state, overwrite mode + state, and autowrap bitmap are installed into @scheme[dest]. + +} + + +@defmethod[#:mode 'add + (cut [extend? any/c] + [time (and/c exact? integer?)] + [start (or/c nonnegative-exact-integer? (one/of 'start))] + [end (or/c nonnegative-exact-integer? (one/of 'end)) 'end]) + void?]{ + +Copies and then deletes the specified range. If @scheme[extend?] is not + @scheme[#f], the old clipboard contents are appended. If @scheme[start] is + @scheme['start] or @scheme[end] is @scheme['end], then the current + selection start/end is used. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} + + +@defmethod*[([(delete [start (or/c nonnegative-exact-integer? (one/of 'start))] + [end (or/c nonnegative-exact-integer? (one/of 'back)) 'back] + [scroll-ok? any/c #t]) + void?] + [(delete) + void?])]{ + +Deletes the specified range or the currently selected text (when no + range is provided) in the editor. If @scheme[start] is + @scheme['start], then the starting selection @techlink{position} is + used; if @scheme[end] is @scheme['back], then only the character + preceding @scheme[start] is deleted. If @scheme[scroll-ok?] is not + @scheme[#f] and @scheme[start] is the same as the current caret + @techlink{position}, then the editor's @techlink{display} may be + scrolled to show the new selection @techlink{position}. + + +@MonitorMethod[@elem{The content of an editor} @elem{the + system in response to other method + calls} @elem{@method[text% on-delete]} @elem{content deletion}] + +} + +@defmethod[(do-copy [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?] + [time (and/c exact? integer?)] + [extend? any/c]) + void?]{ +@methspec{ + +Called to copy a region of the editor into the clipboard. This method + is provided so that it can be overridden by subclasses. Do not call + this method directly; instead, call @method[text% copy]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Copy the data from @scheme[start] to @scheme[end], extending the current + clipboard contexts if @scheme[extend?] is not @scheme[#f]. + +}} + + +@defmethod[(do-paste [start nonnegative-exact-integer?] + [time (and/c exact? integer?)]) + void?]{ +@methspec{ + +Called to paste the current contents of the clipboard into the editor. + This method is provided so that it can be overridden by subclasses. + Do not call this method directly; instead, call @method[text% paste]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Pastes into the @techlink{position} @scheme[start]. + +}} + + +@defmethod[(do-paste-x-selection [start nonnegative-exact-integer?] + [time (and/c exact? integer?)]) + void?]{ +@methspec{ + +Called to paste the current contents of X selection under X (or the + clipboard under Windows or Mac OS X) into the editor. This method is + provided so that it can be overridden by subclasses. Do not call + this method directly; instead, call @method[text% paste-x-selection]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} +@methimpl{ + +Pastes into the @techlink{position} @scheme[start]. + +}} + + +@defmethod[(erase) + void?]{ + +Erases the contents of the editor. + +See also @method[text% delete]. + +} + + +@defmethod[(find-line [y real?] + [on-it? (or/c (box/c any/c) false/c) #f]) + nonnegative-exact-integer?]{ + +Given a @techlink{location} in the editor, returns the line at the + @techlink{location}. @|LineNumbering| + +@boxisfillnull[(scheme on-it?) @elem{@scheme[#t] if the line actually + touches this @techlink{position}, or @scheme[#f] otherwise}] (A large + enough @scheme[y] will always return the last line number, but will + set @scheme[on-it?] to @scheme[#f].) + +@|OVD| @|FCA| + +} + + +@defmethod[(find-next-non-string-snip [after (or/c (is-a?/c snip%) false/c)]) + (or/c (is-a?/c snip%) false/c)]{ + +Given a snip, returns the next snip in the editor (after the given + one) that is not an instance of @scheme[string-snip%]. If + @scheme[#f] is given as the snip, the result is the first non-string + snip in the editor (if any). If no non-string snip is found after the + given snip, the result is @scheme[#f]. + +} + + +@defmethod[(find-position [x real?] + [y real?] + [at-eol? (or/c (box/c any/c) false/c) #f] + [on-it? (or/c (box/c any/c) false/c) #f] + [edge-close? (or/c (box/c real?) false/c) #f]) + nonnegative-exact-integer?]{ + +Given a @techlink{location} in the editor, returns the @techlink{position} at the + @techlink{location}. + +See @|ateoldiscuss| for a discussion of the @scheme[at-eol?] argument. + @boxisfillnull[(scheme on-it?) @elem{@scheme[#t] if the line actually touches this + @techlink{position}, or @scheme[#f] otherwise}] + +@boxisfillnull[(scheme edge-close?) @elem{it will be filled in with a value + indicating how close the point is to the vertical edges of the @techlink{item} + when the point falls on the @techlink{item}}] If the point is closest to the left + edge of the @techlink{item}, the value will be negative; otherwise, the value + will be positive. In either case, then absolute value of the returned + result is the distance from the point to the edge of the @techlink{item}. The + values 100 and -100 indicate infinity. + +@|OVD| @|FCA| + +} + + +@defmethod[(find-position-in-line [line nonnegative-exact-integer?] + [x real?] + [at-eol? (or/c (box/c any/c) false/c) #f] + [on-it? (or/c (box/c any/c) false/c) #f] + [edge-close? (or/c (box/c real?) false/c) #f]) + nonnegative-exact-integer?]{ + +Given a @techlink{location} within a line of the editor, returns the + @techlink{position} at the @techlink{location}. @|LineNumbering| + +See @|ateoldiscuss| for a discussion of the @scheme[at-eol?] argument. + @boxisfillnull[(scheme on-it?) @elem{@scheme[#t] if the line actually + touches this @techlink{position}, or @scheme[#f] otherwise}] + +See @method[text% find-position] for a discussion of + @scheme[edge-close?]. + +@|OVD| @|FCA| + +} + + +@defmethod[(find-snip [pos nonnegative-exact-integer?] + [direction (one-of/c 'before-or-none 'before 'after 'after-or-none)] + [s-pos (or/c (box/c nonnegative-exact-integer?) false/c) #f]) + (or/c (is-a?/c snip%) false/c)]{ + +Returns the snip at a given @techlink{position}, or @scheme[#f] if an appropriate + snip cannot be found. + +If the @techlink{position} @scheme[pos] is between +two snips, @scheme[direction] specifies which snip to return; @scheme[direction] +can be any of the following: +@itemize{ + + @item{@scheme['before-or-none] --- returns the snip before the + @techlink{position}, or @scheme[#f] if @scheme[pos] is @scheme[0]} + + @item{@scheme['before] --- returns the snip before the @techlink{position}, + or the first snip if @scheme[pos] is @scheme[0]} + + @item{@scheme['after] --- returns the snip after the @techlink{position}, or + the last snip if @scheme[pos] is the last @techlink{position}} + + @item{@scheme['after-or-none] -- returns the snip after the + @techlink{position}, or @scheme[#f] if @scheme[pos] is the last @techlink{position} or larger} + +} + +@boxisfillnull[(scheme s-pos) @elem{the @techlink{position} where the returned snip starts}] + +} + + +@defmethod[(find-string [str string?] + [direction (one-of/c 'forward 'backward) 'forward] + [start (or/c nonnegative-exact-integer? (one/of 'start)) 'start] + [end (or/c nonnegative-exact-integer? (one/of 'eof)) 'eof] + [get-start? any/c #t] + [case-sensitive? any/c #t]) + (or/c nonnegative-exact-integer? false/c)]{ + +Finds an exact-match string in the editor and returns its @techlink{position}. + If the string is not found, @scheme[#f] is returned. + +The @scheme[direction] argument can be @scheme['forward] or + @scheme['backward], indicating a forward search or backward + search respectively. In the case of a forward search, the return + value is the starting @techlink{position} of the string; for a backward search, + the ending @techlink{position} is returned. However, if @scheme[get-start?] is + @scheme[#f], then the other end of the string @techlink{position} will be + returned. + +The @scheme[start] and @scheme[end] arguments set the starting and ending + @techlink{position}s of a forward search (use @scheme[start] > @scheme[end] for a + backward search). If @scheme[start] is @scheme['start], then the search + starts at the start of the selection. If @scheme[end] is @scheme['eof], + then the search continues to the end (for a forward search) or start + (for a backward search) of the editor. + +If @scheme[case-sensitive?] is @scheme[#f], then an uppercase and lowercase + of each alphabetic character are treated as equivalent. + +} + + +@defmethod[(find-string-all [str string?] + [direction (one-of/c 'forward 'backward) 'forward] + [start (or/c nonnegative-exact-integer? (one/of 'start)) 'start] + [end (or/c nonnegative-exact-integer? (one/of 'eof)) 'eof] + [get-start? any/c #t] + [case-sensitive any/c #t]) + (listof nonnegative-exact-integer?)]{ + +Finds all occurrences of a string using @method[text% find-string]. If + no occurrences are found, the empty list is returned. The arguments + are the same as for @method[text% find-string]. + +} + + +@defmethod[(find-wordbreak [start (or/c (box/c nonnegative-exact-integer?) false/c)] + [end (or/c (box/c nonnegative-exact-integer?) false/c)] + [reason (one-of/c 'caret 'line 'selection 'user1 'user2)]) + void?]{ + +Finds wordbreaks in the editor using the current wordbreak procedure. + See also @method[text% set-wordbreak-func]. + +The contents of the @scheme[start] argument specifies an @techlink{position} to start + searching backwards to the next word start; its will be filled with + the starting @techlink{position} of the word that is found. If @scheme[start] is + @scheme[#f], no backward search is performed. + +The contents of the @scheme[end] argument specifies an @techlink{position} to start + searching forwards to the next word end; its will be filled with the + ending @techlink{position} of the word that is found. If @scheme[end] is + @scheme[#f], no forward search is performed. + +The @scheme[reason] argument specifies more information about what the + wordbreak is used for. For example, the wordbreaks used to move the + caret may be different from the wordbreaks used to break lines. The + possible values of @scheme[reason] are: + +@itemize{ +@item{@scheme['caret] --- find a wordbreak suitable for moving the caret} +@item{@scheme['line] --- find a wordbreak suitable for breaking lines} +@item{@scheme['selection] --- find a wordbreak suitable for selecting the closest word} +@item{@scheme['user1] --- for other (not built-in) uses} +@item{@scheme['user2] --- for other (not built-in) uses} +} + +The actual handling of @scheme[reason] is controlled by the current + wordbreak procedure; see @method[text% set-wordbreak-func]for + details. The default handler and default wordbreak map treats + alphanumeric characters the same for @scheme['caret], @scheme['line], + and @scheme['selection]. Non-alphanumeric, non-space, non-hyphen + characters do not break lines, but do break caret and selection + words. For example a comma should not be counted as part of the + preceding word for moving the caret past the word or double-clicking + the word, but the comma should stay on the same line as the word (and + thus counts in the same ``line word''). + +} + + +@defmethod[(flash-off) + void?]{ + +Turns off the hiliting and shows the normal selection range again; see + @method[text% flash-on]. There is no effect if this method is called + when flashing is already off. + +} + + +@defmethod[(flash-on [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?] + [at-eol? any/c #f] + [scroll? any/c #t] + [timeout nonnegative-exact-integer? 500]) + void?]{ + +Temporarily hilites a region in the editor without changing the + current selection. + +See @|ateoldiscuss| for a discussion of the @scheme[at-eol?] argument. If + @scheme[scroll?] is not @scheme[#f], the editor's @techlink{display} will be scrolled + if necessary to show the hilited region. If @scheme[timeout] is greater + than 0, then the hiliting will be automatically turned off after the + given number of milliseconds. + +See also @method[text% flash-off]. + +} + + +@defmethod[(get-anchor) + boolean?]{ + +Returns @scheme[#t] if the selection is currently auto-extending. See + also @method[text% set-anchor]. + +} + + +@defmethod[(get-between-threshold) + (and/c real? (not/c negative?))]{ + +Returns an amount used to determine the meaning of a user click. If + the click falls within the threshold of a position between two + @techlink{item}s, then the click registers on the space between the + @techlink{item}s rather than on either @techlink{item}. + +See also @method[text% set-between-threshold]. + +} + + +@defmethod[(get-character [start nonnegative-exact-integer?]) + char?]{ + +Returns the character following the @techlink{position} + @scheme[start]. The character corresponds to getting non-flattened + text from the editor. + +If @scheme[start] is greater than or equal to the last + @techlink{position}, @scheme[#\nul] is returned. + +} + + +@defmethod[(get-end-position) + nonnegative-exact-integer?]{ + +Returns the ending @techlink{position} of the current selection. See + also @method[text% get-position]. + +} + + +@defmethod[(get-file-format) + (one-of/c 'standard 'text 'text-force-cr)]{ + +Returns the format of the last file saved from or loaded into this + editor. See also @method[editor<%> load-file]. + +} + + +@defmethod[(get-line-spacing) + (and/c real? (not/c negative?))]{ + +Returns the spacing inserted by the editor between each line. This + spacing is included in the reported height of each line. + +} + +@defmethod[(get-overwrite-mode) + boolean?]{ + +Returns @scheme[#t] if the editor is in overwrite mode, @scheme[#f] + otherwise. Overwrite mode only affects the way that @method[editor<%> + on-default-char] handles keyboard input for insertion characters. See + also @method[text% set-overwrite-mode]. + +} + + +@defmethod[(get-position [start (or/c (box/c nonnegative-exact-integer?) false/c)] + [end (or/c (box/c nonnegative-exact-integer?) false/c) #f]) + void?]{ + +Returns the current selection range in @techlink{position}s. See also + @method[text% get-start-position] and @method[text% + get-end-position]. + +@boxisfillnull[(scheme start) @elem{the starting @techlink{position} of the selection}] +@boxisfillnull[(scheme end) @elem{the ending @techlink{position} of the selection}] + +} + + +@defmethod[(get-region-data [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?]) + (or/c (is-a?/c editor-data%) false/c)]{ + +Gets extra data associated with a given region. See + @|editordatadiscuss| for more information. + +This method is @italic{not} called when the whole editor is saved to a + file. In such cases, the information can be stored in the header or + footer; see @|globaleditordatadiscuss|. + +This method is meant to be overridden; the default @method[text% + set-region-data] method does not store information to be retrieved by + this method. + +} + + +@defmethod[(get-revision-number) + (and/c real? (not/c negative?))]{ + +Returns an inexact number that increments every time the editor is + changed in one 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]). + +} + + +@defmethod[(get-snip-position [snip (is-a?/c snip%)]) + (or/c nonnegative-exact-integer? false/c)]{ + +Returns the starting @techlink{position} of a given snip or + @scheme[#f] if the snip is not in this editor. + +} + +@defmethod[(get-snip-position-and-location [snip (is-a?/c snip%)] + [pos (or/c (box/c nonnegative-exact-integer?) false/c)] + [x (or/c (box/c real?) false/c) #f] + [y (or/c (box/c real?) false/c) #f]) + boolean?]{ + +Gets a snip's @techlink{position} and top left @techlink{location} in editor + coordinates. The return value is @scheme[#t] if the snip is found, + @scheme[#f] otherwise. + +@boxisfillnull[(scheme pos) @elem{starting @techlink{position} of @scheme[snip]}] +@boxisfillnull[(scheme x) @elem{left @techlink{location} of @scheme[snip] in editor coordinates}] +@boxisfillnull[(scheme y) @elem{top @techlink{location} of @scheme[snip] in editor coordinates}] + +When @techlink{location} information is requested: @|OVD| @|FCA| + +} + + +@defmethod[(get-start-position) + nonnegative-exact-integer?]{ + +Returns the starting @techlink{position} of the current selection. See also + @method[text% get-position]. + +} + + +@defmethod[(get-styles-sticky) + boolean?]{ + +In the normal mode for a text editor, style settings are sticky. With + sticky styles, when a string or character is inserted into an editor, + it gets the style of the snip preceding the insertion point (or the + snip that includes the insertion point if text is inserted into an + exiting string snip). Alternatively, if @method[text% change-style] + is called to set the style at the caret @techlink{position} (when it + is not a range), then the style is remembered; if the editor is not + changed before text is inserted at the caret, then the text gets the + remembered style. + +With non-sticky styles, text inserted into an editor always gets the + style in the editor's style list named by @method[editor<%> + default-style-name]. + +See also @method[text% set-styles-sticky]. + +} + + +@defmethod[(get-tabs [length (or/c (box/c nonnegative-exact-integer?) false/c) #f] + [tab-width (or/c (box/c real?) false/c) #f] + [in-units (or/c (box/c any/c) false/c) #f]) + (listof real?)]{ + +Returns the current tab-position array as a list. + +@boxisfillnull[(scheme length) @elem{the length of the tab array (and therefore the returned +list)}] +@boxisfillnull[(scheme tab-width) @elem{the width used for tabs past the +end of the tab array}] +@boxisfillnull[(scheme in-units) @elem{@scheme[#t] if the tabs are specified in +canvas units or @scheme[#f] if they are specified in space-widths}] + +See also +@method[text% set-tabs]. + +} + + +@defmethod[(get-text [start nonnegative-exact-integer? 0] + [end (or/c nonnegative-exact-integer? (one/of 'eof)) 'eof] + [flattened? any/c #f] + [force-cr? any/c #f]) + string?]{ + +Gets the text from @scheme[start] to @scheme[end]. If @scheme[end] is + @scheme['eof], then the contents are returned from @scheme[start] until the + end of the editor. + +If @scheme[flattened?] is not @scheme[#f], then flattened text is returned. + See @|textdiscuss| for a discussion of flattened vs. non-flattened + text. + +If @scheme[force-cr?] is not @scheme[#f] and @scheme[flattened?] is not + @scheme[#f], then automatic carriage returns (from word-wrapping) are + written into the return string as real carriage returns. + +} + + +@defmethod[(get-top-line-base) + (and/c real? (not/c negative?))]{ + +Returns the distance from the top of the editor to the alignment + baseline of the top line. This method is primarily used when an + editor is an @techlink{item} within another editor. + +@|OVD| @|FCAME| + +} + + +@defmethod[(get-visible-line-range [start (or/c (box/c nonnegative-exact-integer?) false/c)] + [end (or/c (box/c nonnegative-exact-integer?) false/c)] + [all? any/c #t]) + void?]{ + +Returns the range of lines which are currently visible (or partially + visible) to the user. @|LineNumbering| + +@boxisfillnull[(scheme start) @elem{first line visible to the user}] +@boxisfillnull[(scheme end) @elem{last line visible to the user}] + +If the editor is displayed by multiple canvases and @scheme[all?] is + @scheme[#t], then the computed range includes all visible lines in all + @techlink{display}s. Otherwise, the range includes only the visible lines in the + current @techlink{display}. + +@|OVD| @|FCA| + +} + + +@defmethod[(get-visible-position-range [start (or/c (box/c nonnegative-exact-integer?) false/c)] + [end (or/c (box/c nonnegative-exact-integer?) false/c)] + [all? any/c #t]) + void?]{ + +Returns the range of @techlink{position}s that are currently visible (or + partially visible) to the user. + +@boxisfillnull[(scheme start) @elem{first @techlink{position} visible to the user}] +@boxisfillnull[(scheme end) @elem{last @techlink{position} visible to the user}] + +If the editor is displayed by multiple canvases and @scheme[all?] is + @scheme[#t], then the computed range includes all visible @techlink{position}s in + all @techlink{display}s. Otherwise, the range includes only the visible + @techlink{position}s in the current @techlink{display}. + +@|OVD| @|FCA| + +} + + +@defmethod[(get-wordbreak-map) + (is-a?/c editor-wordbreak-map%)]{ + +Returns the wordbreaking map that is used by the standard wordbreaking + function. See @scheme[editor-wordbreak-map%] for more information. + +} + + +@defmethod[(hide-caret [hide? any/c]) + void?]{ + +Determines whether the caret is shown when the editor has the keyboard + focus. + +If @scheme[hide?] is not @scheme[#f], then the caret or selection hiliting + will not be drawn for the editor. The editor can still own the + keyboard focus, but no caret will be drawn to indicate the focus. + +See also @method[text% caret-hidden?] and @method[editor<%> lock]. + +} + + +@defmethod*[#:mode 'override + ([(insert [str string?] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [scroll-ok? any/c #t]) + void?] + [(insert [n nonnegative-exact-integer?] + [str string?] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [scroll-ok? any/c #t]) + void?] + [(insert [str string?]) + void?] + [(insert [n nonnegative-exact-integer?] + [str string?]) + void?] + [(insert [snip (is-a?/c snip%)] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [scroll-ok? any/c #t]) + void?] + [(insert [snip (is-a?/c snip%)]) + void?] + [(insert [char char?]) + void?] + [(insert [char char?] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same]) + void?])]{ + +Inserts text or a snip into @this-obj[] at @techlink{position} + @scheme[start]. If @scheme[n] is provided, the only the first + @scheme[n] characters of @scheme[str] are inserted. + +When a @scheme[snip] is provided: The snip cannot be inserted into + multiple editors or multiple times within a single editor. As the + snip is inserted, its current style is converted to one in the + editor's style list; see also @method[style-list% convert]. + +When a @scheme[char] is provided: @|insertcharundos| + +When @scheme[start] is not provided, the current selection start is + used. If the current selection covers a range of @techlink{item}s, + then @scheme[char] replaces the selected text. The selection's start + and end @techlink{position}s are moved to the end of the inserted + character. + +For a case where @scheme[end] is not provided and has no default, the + current selection end is used. Otherwise, if @scheme[end] is not + @scheme['same], then the inserted value replaces the region from + @scheme[start] to @scheme[end], and the selection is left at the end + of the inserted text. Otherwise, if the insertion @techlink{position} + is before or equal to the selection's start/end @techlink{position}, + then the selection's start/end @techlink{position} is incremented by + the length of @scheme[str]. + +If @scheme[scroll-ok?] is not @scheme[#f] and @scheme[start] is the + same as the current selection's start @techlink{position}, then the + editor's @techlink{display} is scrolled to show the new selection + @techlink{position}. + +See also @method[text% get-styles-sticky]. + +} + + +@defmethod[#:mode 'add + (kill [time (and/c exact? integer?)] + [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?]) + void?]{ + +Cuts the text in the given region. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} + + +@defmethod[(last-line) + nonnegative-exact-integer?]{ + +Returns the number of the last line in the editor. Lines are numbered + starting with @scheme[0], so this is one less than the number of lines + in the editor. + +@LineToPara[(scheme last-paragraph)] + +@|FCAMW| @|EVD| +} + + +@defmethod[(last-paragraph) + nonnegative-exact-integer?]{ + +Returns the number of the last paragraph in the editor. Paragraphs are + numbered starting with @scheme[0], so this is one less than the + number of paragraphs in the editor. + +@|FCAMW| + +} + +@defmethod[(last-position) + nonnegative-exact-integer?]{ + +Returns the last selection @techlink{position} in the editor. This is + also the number of @techlink{item}s in the editor. + +} + +@defmethod[(line-end-position [line nonnegative-exact-integer?] + [visible? any/c #t]) + nonnegative-exact-integer?]{ + +Returns the last @techlink{position} of a given line. @|LineNumbering| + +If there are fewer than @math{@scheme[line]-1} lines, the end of the + last line is returned. If @scheme[line] is less than 0, then the end + of the first line is returned. + +If the line ends with invisible @techlink{item}s (such as a carriage + return) and @scheme[visible?] is not @scheme[#f], the first + @techlink{position} before the invisible @techlink{item}s is + returned. + +@LineToPara[(scheme paragraph-end-position)] + +@|FCAMW| @|EVD| + +} + + +@defmethod[(line-length [i nonnegative-exact-integer?]) + nonnegative-exact-integer?]{ + +Returns the number of @techlink{item}s in a given +line. @|LineNumbering| + +@|FCAMW| @|EVD| + +} + + +@defmethod[(line-location [line nonnegative-exact-integer?] + [top? any/c #t]) + real?]{ + +Given a line number, returns the @techlink{location} of the line. @|LineNumbering| + +If @scheme[top?] is not @scheme[#f], the @techlink{location} for the + top of the line is returned; otherwise, the @techlink{location} for + the bottom of the line is returned. + +@LineToPara[(scheme paragraph-location)] + +@|OVD| @|FCA| + +} + +@defmethod[(line-paragraph [start nonnegative-exact-integer?]) + nonnegative-exact-integer?]{ + +Returns the paragraph number of the paragraph containing the line. + @|LineNumbering| @|ParagraphNumbering| + +@|FCAMW| @|EVD| + +} + +@defmethod[(line-start-position [line nonnegative-exact-integer?] + [visible? any/c #t]) + nonnegative-exact-integer?]{ + +Returns the first @techlink{position} of the given line. @|LineNumbering| + +If there are fewer than @math{@scheme[line]-1} lines, the start of the +last line is returned. If @scheme[line] is less than 0, then +the start of the first line is returned. + +If the line starts with invisible @techlink{item}s and @scheme[visible?] is not + @scheme[#f], the first @techlink{position} past the invisible @techlink{item}s is + returned. + +@LineToPara[(scheme paragraph-start-position)] + +@|FCAMW| + +To calculate lines, if the following are true: +@itemize{ + + @item{the editor is not displayed (see @secref["mr:tb:miaoverview"]),} + + @item{a maximum width is set for the editor, and} + + @item{the editor has never been viewed} + +} + +then this method ignores the editor's maximum width and any automatic + line breaks it might imply. If the first two of the above conditions + are true and the editor was @italic{formerly} displayed, this method + uses the line breaks from the most recent display of the + editor. (Insertions or deletions since the display shift line breaks + within the editor in the same way as @techlink{item}s.) + +} + + +@defmethod[(move-position [code (one-of/c 'home 'end 'right 'left 'up 'down)] + [extend? any/c #f] + [kind (one-of/c 'simple 'word 'page 'line) 'simple]) + void?]{ + +Moves the current selection. + +The possible values for @scheme[code] are: + +@itemize{ +@item{@scheme['home] --- go to start of file} +@item{@scheme['end] --- go to end of file} +@item{@scheme['right] --- move right} +@item{@scheme['left] --- move left} +@item{@scheme['up] --- move up} +@item{@scheme['down] --- move down} +} + +If @scheme[extend?] is not @scheme[#f], the selection range is + extended instead of moved. If anchoring is on (see @method[text% + get-anchor] and @method[text% set-anchor]), then @scheme[extend?] is + effectively forced to @scheme[#t]. + +The possible values for @scheme[kind] are: + +@itemize{ +@item{@scheme['simple] --- move one item or line} +@item{@scheme['word] --- works with @scheme['right] or @scheme['left]} +@item{@scheme['page] --- works with @scheme['up] or @scheme['down]} +@item{@scheme['line] --- works with @scheme['right] or @scheme['left]; moves to the start or end of the line} +} + +See also @method[text% set-position]. + +} + + +@defmethod[#:mode 'pubment + (on-change-style [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ + +@methspec{ + +Called before the style is changed in a given range of the editor, + after @method[text% can-change-style?] is called to verify that the + change is ok. The @method[text% after-change-style] method is + guaranteed to be called after the change has completed. + +The editor is internally locked for writing during a call to this method + (see also @|lockdiscuss|). Use +@method[text% after-change-style] to modify the editor, if necessary. + +See also @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Does nothing. + +} +} + + +@defmethod[#:mode 'override + (on-default-char [event (is-a?/c key-event%)]) + void?]{ + +Handles the following: + +@itemize{ + + @item{Delete and Backspace --- calls @method[text% delete].} + + @item{The arrow keys, Page Up, Page Down, Home, and End (including + shifted versions) --- moves the selection @techlink{position} with + @method[text% move-position].} + + @item{Any other character in the range @scheme[(integer->char 32)] to + @scheme[(integer->char 255)] --- inserts the character into the + editor.} + +} + +Note that an editor's @scheme[editor-canvas%] normally handles mouse + wheel events (see also @method[editor-canvas% on-char] ). + +} + + +@defmethod[#:mode 'override + (on-default-event [event (is-a?/c mouse-event%)]) + void?]{ + +Tracks clicks on a clickback (see @method[text% set-clickback]) of + changes the selection. Note that @method[editor<%> on-event] + dispatches to a caret-owning snip and detects a click on an + event-handling snip before calling to this method. + +@itemize{ + + @item{Clicking on a clickback region starts clickback tracking. See + @method[text% set-clickback] for more information. Moving over a + clickback changes the shape of the mouse cursor.} + + @item{Clicking anywhere else moves the caret to the closest @techlink{position} + between @techlink{item}s. Shift-clicking extends the current selection.} + + @item{Dragging extends the selection, scrolling if possible when the + selection is dragged outside the editor's visible region.} + +} +} + + +@defmethod[#:mode 'pubment + (on-delete [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called before a range is deleted from the editor, after @method[text% + can-delete?] is called to verify that the deletion is ok. The + @method[text% after-delete] method is guaranteed to be called after + the delete has completed. + +The @scheme[start] argument specifies the starting @techlink{position} + of the range to delete. The @scheme[len] argument specifies number of + @techlink{item}s to delete (so @math{@scheme[start]+@scheme[len]} is + the ending @techlink{position} of the range to delete). + +The editor is internally locked for writing during a call to this + method (see also @|lockdiscuss|). Use @method[text% after-delete] to + modify the editor, if necessary. + +See also @method[editor<%> on-edit-sequence]. + + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[#:mode 'pubment + (on-insert [start nonnegative-exact-integer?] + [len nonnegative-exact-integer?]) + void?]{ +@methspec{ + +Called before @techlink{item}s are inserted into the editor, after + @method[text% can-insert?] is called to verify that the insertion is + ok. The @method[text% after-insert] method is guaranteed to be called + after the insert has completed. + +The @scheme[start] argument specifies the @techlink{position} of the insert. The + @scheme[len] argument specifies the total length (in @techlink{position}s) of the + @techlink{item}s to be inserted. + +The editor is internally locked for writing during a call to this + method (see also @|lockdiscuss|). Use @method[text% after-insert] to + modify the editor, if necessary. + +See also @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[(on-new-string-snip) + (is-a?/c string-snip%)]{ + +@methspec{ + +Called by @method[text% insert] when a string or character is inserted +into the editor, this method creates and returns a new instance of +@scheme[string-snip%] to store inserted text. The returned string snip +is empty (i.e., its @techlink{count} is zero). + +} +@methimpl{ + +Returns a @scheme[string-snip%] instance. + +}} + +@defmethod[(on-new-tab-snip) + (is-a?/c tab-snip%)]{ + +@methspec{ + +Creates and returns a new instance of @scheme[tab-snip%] to store an + inserted tab. The returned tab snip is empty (i.e., its @techlink{count} + is zero). + +} +@methimpl{ + +Returns a @scheme[tab-snip%] instance. + +}} + + +@defmethod[#:mode 'pubment + (on-set-size-constraint) + void?]{ + +@methspec{ + +Called before the editor's maximum or minimum height or width is + changed, after @method[text% can-set-size-constraint?] is called to + verify that the change is ok. The @method[text% + after-set-size-constraint] method is guaranteed to be called after + the change has completed. + +(This callback method is provided because setting an editor's maximum + width may cause lines to be re-flowed with soft carriage returns.) + +See also @method[editor<%> on-edit-sequence]. + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[(paragraph-end-line [paragraph nonnegative-exact-integer?]) + nonnegative-exact-integer?]{ + +Returns the ending line of a given paragraph. @|ParagraphNumbering| @|LineNumbering| + +@|FCAMW| @|EVD| + +} + + +@defmethod[(paragraph-end-position [paragraph nonnegative-exact-integer?] + [visible? any/c #f]) + nonnegative-exact-integer?]{ + +Returns the ending @techlink{position} of a given paragraph. @|ParagraphNumbering| + +If there are fewer than @math{@scheme[paragraph]-1} paragraphs, the + end of the last paragraph is returned. If @scheme[paragraph] is less + than 0, then the end of the first paragraph is returned. + +If the paragraph ends with invisible @techlink{item}s (such as a carriage + return) and @scheme[visible?] is not @scheme[#f], the first @techlink{position} + before the invisible @techlink{item}s is returned. + +} + + +@defmethod[(paragraph-start-line [paragraph nonnegative-exact-integer?]) + nonnegative-exact-integer?]{ + +Returns the starting line of a given paragraph. @|ParagraphNumbering| @|LineNumbering| + +@|FCAMW| @|EVD| + +} + + +@defmethod[(paragraph-start-position [paragraph nonnegative-exact-integer?] + [visible? any/c #f]) + nonnegative-exact-integer?]{ + +Returns the starting @techlink{position} of a given paragraph. @|ParagraphNumbering| + +If there are fewer than @math{@scheme[paragraph]-1} paragraphs, the + start of the last paragraph is returned. + +If the paragraph starts with invisible @techlink{item}s and @scheme[visible?] is + not @scheme[#f], the first @techlink{position} past the invisible @techlink{item}s is + returned. + +} + + +@defmethod[#:mode 'add + (paste [time (and/c exact? integer?)] + [start (or/c nonnegative-exact-integer? (one/of 'end))] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same]) + void?]{ + +Pastes into the specified range. If @scheme[start] is @scheme['end], then + the current selection end @techlink{position} is used. If @scheme[end] is + @scheme['same], then @scheme[start] is used for @scheme[end]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} + + +@defmethod[(paste-next) + void?]{ + +Editors collectively maintain a copy ring that holds up to 30 previous + copies (and cuts) among the editors. When it is called as the next + method on an editor after a paste, the @method[text% paste-next] + method replaces the text from a previous paste with the next data in + the copy ring, incrementing the ring pointer so that the next + @method[text% paste-next] pastes in even older data. + +It is a copy ``ring'' because the ring pointer wraps back to the most + recent copied data after the oldest remembered data is pasted. Any + cut, copy, or (regular) paste operation resets the copy ring pointer + back to the beginning. + +If the previous operation on the editor was not a paste, calling + @method[text% paste-next] has no effect. + +} + + +@defmethod[#:mode 'add + (paste-x-selection [time (and/c exact? integer?)] + [start (or/c nonnegative-exact-integer? (one/of 'end))] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same]) + void?]{ + +Pastes into the specified range. If @scheme[start] is @scheme['end], then + the current selection end @techlink{position} is used. If @scheme[end] is + @scheme['same], then @scheme[start] is used for @scheme[end]. + +See @|timediscuss| for a discussion of the @scheme[time] argument. If + @scheme[time] is outside the platform-specific range of times, + @|MismatchExn|. + +} + +@defmethod[(position-line [start nonnegative-exact-integer?] + [at-eol? any/c #f]) + nonnegative-exact-integer?]{ + +Returns the line number of the line containing a given @techlink{position}. @|LineNumbering| + +@LineToPara[(scheme position-paragraph)] + +See @|ateoldiscuss| for a discussion of @scheme[at-eol?]. + +@|FCAMW| @|EVD| + +} + + +@defmethod[(position-location [start nonnegative-exact-integer?] + [x (or/c (box/c real?) false/c) #f] + [y (or/c (box/c real?) false/c) #f] + [top? any/c #t] + [at-eol? any/c #f] + [whole-line? any/c #f]) + void?]{ + +Returns the @techlink{location} of a given @techlink{position}. + +@boxisfillnull[(scheme x) @elem{the x-@techlink{location} of the @techlink{position} @scheme[start] in editor +coordinates} ] +@boxisfillnull[(scheme y) @elem{the y-@techlink{location} (top or bottom; see below) of the +@techlink{position} @scheme[start] in editor coordinates}] + +See @|ateoldiscuss| for a discussion of @scheme[at-eol?]. + +If @scheme[top?] is not @scheme[#f], the top coordinate of the @techlink{location} +is returned, otherwise the bottom coordinate of the +@techlink{location} is returned. + +The top @scheme[y] @techlink{location} may be different for different @techlink{position}s +within a line when different-sized graphic objects are used. If +@scheme[whole-line?] is not @scheme[#f], the minimum top @techlink{location} or +maximum bottom @techlink{location} for the whole line is returned in @scheme[y]. + +@|OVD| @|FCA| + +} + + +@defmethod[(position-paragraph [start nonnegative-exact-integer?] + [at-eol? any/c #f]) + nonnegative-exact-integer?]{ + +See @|ateoldiscuss| for a discussion of @scheme[at-eol?]. + +Returns the paragraph number of the paragraph containing a given @techlink{position}. + +} + + +@defmethod[#:mode 'add + (read-from-file [stream (is-a?/c editor-stream-in%)] + [start (or/c nonnegative-exact-integer? (one/of 'start))] + [overwrite-styles? any/c #t]) + boolean?]{ + +New data is inserted at the @techlink{position} indicated by @scheme[start], or at + the current @techlink{position} if @scheme[start] is @scheme['start]. + +} + + +@defmethod[(remove-clickback [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?]) + void?]{ + +Removes all clickbacks installed for exactly the range @scheme[start] + to @scheme[end]. See also @|clickbackdiscuss|. + +} + + +@defmethod[(scroll-to-position [start nonnegative-exact-integer?] + [at-eol? any/c #f] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [bias (one-of/c 'start 'end 'none) 'none]) + boolean?]{ + +Scrolls the editor so that a given @techlink{position} is visible. + +If @scheme[end] is @scheme['same] or equal to @scheme[start], then @techlink{position} + @scheme[start] is made visible. See @|ateoldiscuss| for a discussion of + @scheme[at-eol?]. + +If @scheme[end] is not @scheme['same] and not the same as @scheme[start], + then the range @scheme[start] to @scheme[end] is made visible and + @scheme[at-eol?] is ignored. + +When the specified range cannot fit in the visible area, @scheme[bias] + indicates which end of the range to display. When @scheme[bias] is + @scheme['same], then the start of the range is displayed. When + @scheme[bias] is @scheme['end], then the end of the range is + displayed. Otherwise, @scheme[bias] must be @scheme['none]. + +If the editor is scrolled, then the editor is redrawn and the return + value is @scheme[#t]; otherwise, the return value is @scheme[#f]. + +Scrolling is disallowed when the editor is internally locked for + reflowing (see also @|lockdiscuss|). + +The system may scroll the editor without calling this method. + +} + + +@defmethod[(set-anchor [on? any/c]) + void?]{ + +Turns anchoring on or off. This method can be overridden to affect or + detect changes in the anchor state. See also + @method[text% get-anchor]. + +If @scheme[on?] is not @scheme[#f], then the selection will be + automatically extended when cursor keys are used (or, more generally, + when @method[text% move-position] is used to move the selection), + otherwise anchoring is turned off. Anchoring is automatically turned + off if the user does anything besides cursor movements. + +} + + +@defmethod[(set-autowrap-bitmap [bitmap (or/c (is-a?/c bitmap%) false/c)]) + (or/c (is-a?/c bitmap%) false/c)]{ + +Sets the bitmap that is drawn at the end of a line when it is + automatically line-wrapped. + +If @scheme[bitmap] is @scheme[#f], no autowrap indicator is drawn + (this is the default). The previously used bitmap (possibly + @scheme[#f]) is returned. + +The bitmap will not be modified. It may be selected into a + @scheme[bitmap-dc%] object, but it will be selected out if this + method is called again. + +Setting the bitmap is disallowed when the editor is internally locked + for reflowing (see also @|lockdiscuss|). + +} + + +@defmethod[(set-between-threshold [threshold (and/c real? (not/c negative?))]) + void?]{ + +Sets the graphical distance used to determine the meaning of a user + click. If a click falls within @scheme[threshold] of a position + between two @techlink{item}s, then the click registers on the space + between the @techlink{item}s rather than on either @techlink{item}. + +See also +@method[text% get-between-threshold]. + +} + + +@defmethod[(set-clickback [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?] + [f ((is-a?/c text% + nonnegative-exact-integer? + nonnegative-exact-integer?) + . -> . any)] + [hilite-delta (or/c (is-a?/c style-delta%) false/c) #f] + [call-on-down? any/c #f]) + void?]{ + +Installs a clickback for a given region. If a clickback is already + installed for an overlapping region, this clickback takes precedence. + +The callback procedure @scheme[f] is called when the user selects the + clickback. The arguments to @scheme[f] are this editor and the starting + and ending range of the clickback. + +The @scheme[hilite-delta] style delta is applied to the clickback text + when the user has clicked and is still holding the mouse over the + clickback. If @scheme[hilite-delta] is @scheme[#f], then the clickback + region's style is not changed when it is being selected. + +If @scheme[call-on-down?] is not @scheme[#f], the clickback is called + immediately when the user clicks the mouse button down, instead of + after a mouse-up event. The @scheme[hilite-delta] argument is not used + in this case. + +See also @|clickbackdiscuss|. + } + +@defmethod[(set-file-format [format (one-of/c 'standard 'text 'text-force-cr)]) + void?]{ + +Set the format of the file saved from this editor. + +The legal formats are: + +@itemize{ +@item{@scheme['standard] --- a standard editor file} +@item{@scheme['text] --- a text file} +@item{@scheme['text-force-cr] --- a text file; when writing, change automatic newlines (from word-wrapping) into real carriage returns} +} + +@MonitorMethod[@elem{The file format of an editor} @elem{the + system in response to file loading and saving + method calls} @elem{@method[editor<%> on-load-file] and + @method[editor<%> on-save-file]} @elem{such file format}] +} + + +@defmethod[(set-line-spacing [space (and/c real? (not/c negative?))]) + void?]{ + +Sets the spacing inserted by the editor between each line. This + spacing is included in the reported height of each line. + +} + +@defmethod[(set-overwrite-mode [on? any/c]) + void?]{ + +Enables or disables overwrite mode. See @method[text% + get-overwrite-mode]. This method can be overridden to affect or + detect changes in the overwrite mode. + +} + + +@defmethod[(set-paragraph-alignment [paragraph nonnegative-exact-integer?] + [alignment (one-of/c 'left 'center 'right)]) + void?]{ + +Sets a paragraph-specific horizontal alignment. The alignment is only + used when the editor has a maximum width, as set with + @method[editor<%> set-max-width]. @|ParagraphNumbering| + +@italic{This method is experimental.} It works reliably only when the + paragraph is not merged or split. Merging or splitting a paragraph + with alignment settings causes the settings to be transfered + unpredictably (although other paragraphs in the editor can be safely + split or merged). If the last paragraph in an editor is empty, + settings assigned to it are ignored. + +} + + +@defmethod[(set-paragraph-margins [paragraph nonnegative-exact-integer?] + [first-left (and/c real? (not/c negative?))] + [left (and/c real? (not/c negative?))] + [right (and/c real? (not/c negative?))]) + void?]{ + +Sets a paragraph-specific margin. @|ParagraphNumbering| + +The first line of the paragraph is indented by @scheme[first-left] points + within the editor. If the paragraph is line-wrapped (when the editor + has a maximum width), subsequent lines are indented by @scheme[left] + points. If the editor has a maximum width, the paragraph's maximum + width for line-wrapping is @scheme[right] points smaller than the + editor's maximum width. + +@italic{This method is experimental.} See @method[text% + set-paragraph-alignment] for more information. + +} + + +@defmethod[(set-position [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [at-eol? any/c #f] + [scroll? any/c #t] + [seltype (one-of/c 'default 'x 'local) 'default]) + void?]{ + +Sets the current selection in the editor. + +If @scheme[end] is @scheme['same] or less than or equal to @scheme[start], + the current start and end @techlink{position}s are both set to + @scheme[start]. Otherwise the given range is selected. + +See @|ateoldiscuss| for a discussion of @scheme[at-eol?]. If + @scheme[scroll?] is not @scheme[#f], then the @techlink{display} is + scrolled to show the selection if necessary. + +The @scheme[seltype] argument is only used when the X Window System + selection mechanism is enabled. The possible values are: +@itemize{ + + @item{@scheme['default] --- if this window has the keyboard focus + and given selection is non-empty, make it the current X selection} + + @item{@scheme['x] --- if the given selection is non-empty, make + it the current X selection} + + @item{@scheme['local] --- do not change the + current X selection} + +} + +Setting the @techlink{position} is disallowed when the editor is internally + locked for reflowing (see also @|lockdiscuss|). + +The system may change the selection in an editor without calling this + method (or any visible method). + +See also @scheme[editor-set-x-selection-mode]. + +} + + +@defmethod[(set-position-bias-scroll [bias (one-of/c 'start-only 'start 'none 'end 'end-only)] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'same)) 'same] + [ateol? any/c #f] + [scroll? any/c #t] + [seltype (one-of/c 'default 'x 'local) 'default]) + void?]{ + +Like @method[text% set-position], but a scrolling bias can be specified. + +The possible values for @scheme[bias] are: +@itemize{ +@item{@scheme['start-only] --- only insure that the starting @techlink{position} is visible} +@item{@scheme['start] --- if the range doesn't fit in the visible area, show the starting @techlink{position}} +@item{@scheme['none] --- no special scrolling instructions} +@item{@scheme['end] --- if the range doesn't fit in the visible area, show the ending @techlink{position}} +@item{@scheme['end-only] --- only insure that the ending @techlink{position} is visible} +} + +See also @method[text% scroll-to-position]. + +} + + +@defmethod[(set-region-data [start nonnegative-exact-integer?] + [end nonnegative-exact-integer?] + [data (is-a?/c editor-data%)]) + void?]{ + +@methspec{ + +Sets extra data associated with a given region. See + @|editordatadiscuss| and @method[text% get-region-data] for more + information. + +This method is meant to be overridden in combination with + @method[text% get-region-data] . + +} +@methimpl{ + +Does nothing. + +}} + + +@defmethod[(set-styles-sticky [sticky? any/c]) + void?]{ + +See @method[text% get-styles-sticky] for information about sticky + styles. + +} + + +@defmethod[(set-tabs [tabs (listof real?)] + [tab-width real? 20] + [in-units? any/c #t]) + void?]{ + +Sets the tabbing array for the editor. + +The @scheme[tabs] list determines the tabbing array. The tabbing array + specifies the x-@techlink{location}s where each tab occurs. Tabs beyond the last + specified tab are separated by a fixed amount @scheme[tab-width]. If + @scheme[in-units?] is not @scheme[#f], then tabs are specified in canvas + units; otherwise, they are specified as a number of spaces. (If tabs + are specified in spaces, then the graphic tab positions will change + with the font used for the tab.) + +Setting tabs is disallowed when the editor is internally locked for + reflowing (see also @|lockdiscuss|). + +} + + +@defmethod[(set-wordbreak-func [f ((is-a?/c text%) (or/c (box/c nonnegative-exact-integer?) false/c) + (or/c (box/c nonnegative-exact-integer?) false/c) + symbol? + . -> . any)]) + void?]{ + +Sets the word-breaking function for the editor. For information about + the arguments to the word-breaking function, see @method[text% + find-wordbreak]. + +The standard wordbreaking function uses the editor's + @scheme[editor-wordbreak-map%] object to determine which characters + break a word. See also @scheme[editor-wordbreak-map%] and + @method[text% set-wordbreak-map]. + +Since the wordbreak function will be called when line breaks are being + determined (in an editor that has a maximum width), there is a + constrained set of @scheme[text%] methods that the wordbreak + function is allowed to invoke. It cannot invoke a member function + that uses information about @techlink{location}s or lines (which are + identified in this manual with ``@|OVD|''), but it can still invoke + member functions that work with snips and @techlink{item}s. + +} + + +@defmethod[(set-wordbreak-map [map (or/c (is-a?/c editor-wordbreak-map%) false/c)]) + void?]{ + +Sets the wordbreaking map that is used by the standard wordbreaking + function. See @scheme[editor-wordbreak-map%] for more information. + +If @scheme[map] is @scheme[#f], then the standard map + (@scheme[the-editor-wordbreak-map]) is used. + +} + + +@defmethod[(split-snip [pos nonnegative-exact-integer?]) + void?]{ + +Given a @techlink{position}, splits the snip that includes the + @techlink{position} (if any) so that the @techlink{position} is + between two snips. The snip may refuse to split, although none of the + built-in snip classes will ever refuse. + +Splitting a snip is disallowed when the editor is internally locked + for reflowing (see also @|lockdiscuss|). + +} + + +@defmethod[#:mode 'add + (write-to-file [stream (is-a?/c editor-stream-out%)] + [start nonnegative-exact-integer?] + [end (or/c nonnegative-exact-integer? (one/of 'eof)) 'eof]) + boolean?]{ + +If @scheme[start] is 0 and @scheme[end] is @scheme['eof] negative, + then the entire contents are written to the stream. If @scheme[end] + is @scheme['eof], then the contents are written from @scheme[start] + until the end of the editor. Otherwise, the contents of the given + range are written. + +}} diff --git a/collects/scribblings/gui/win-overview.scrbl b/collects/scribblings/gui/win-overview.scrbl index 16681599..66adf361 100644 --- a/collects/scribblings/gui/win-overview.scrbl +++ b/collects/scribblings/gui/win-overview.scrbl @@ -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.