/collects/scribblings/framework/frame.scrbl

http://github.com/gmarceau/PLT · Racket · 948 lines · 758 code · 190 blank · 0 comment · 34 complexity · f8724d16ec67c72c95e7f867849887bb MD5 · raw file

  1. #lang scribble/doc
  2. @(require scribble/manual scribble/extract scheme/include)
  3. @(require (for-label framework))
  4. @(require (for-label scheme/gui))
  5. @(require (for-syntax (prefix-in s: scribble/reader)))
  6. @title{Frame}
  7. @definterface[frame:basic<%> (frame%)]{
  8. Classes matching this interface support the basic
  9. @racket[frame%]
  10. functionality required by the framework.
  11. @defmethod*[(((get-area-container%) (implementation?/c area-container<%>)))]{
  12. The class that this method returns is used to create the
  13. @racket[area-container<%>]
  14. in this frame.
  15. }
  16. @defmethod*[(((get-area-container) (is-a?/c area-container<%>)))]{
  17. This returns the main
  18. @racket[area-container<%>]
  19. in the frame
  20. }
  21. @defmethod*[(((get-menu-bar%) (subclass?/c menu-bar%)))]{
  22. The result of this method is used to create the initial menu bar for
  23. this frame.
  24. Return @racket[menu-bar%].
  25. }
  26. @defmethod*[(((make-root-area-container (class (implementation?/c area-container<%>)) (parent (is-a?/c area-container<%>))) (is-a?/c area-container<%>)))]{
  27. Override this method to insert a panel in between the panel used by
  28. the clients of this frame and the frame itself. For example, to insert
  29. a status line panel override this method with something like this:
  30. @racketblock[
  31. (class ...
  32. ...
  33. (define status-panel #f)
  34. (define/override (make-root-area-container cls parent)
  35. (set! status-panel
  36. (super make-root-area-container vertical-panel% parent))
  37. (let ([root (make-object cls status-panel)])
  38. (code:comment "... add other children to status-panel ...")
  39. root))
  40. ...)]
  41. In this example, status-panel will contain a root panel for the other
  42. classes, and whatever panels are needed to display status information.
  43. The searching frame is implemented using this method.
  44. Calls @racket[make-object] with @racket[class] and @racket[parent].
  45. }
  46. @defmethod*[(((close) void?))]{
  47. This method closes the frame by calling the
  48. @method[top-level-window<%> can-close?],
  49. @method[top-level-window<%> on-close], and
  50. @method[top-level-window<%> show]
  51. methods.
  52. It's implementation is:
  53. @racketblock[
  54. (inherit can-close? on-close)
  55. (public
  56. [show
  57. (lambda ()
  58. (when (can-close?)
  59. (on-close)
  60. (show #f)))])]
  61. }
  62. @defmethod*[(((editing-this-file? (filename path?)) boolean?))]{
  63. Indicates if this frame contains this buffer (and can edit
  64. that file).
  65. Returns @racket[#f].
  66. }
  67. @defmethod*[(((get-filename (temp (or/c #f (box boolean?)) #f)) (or/c #f path?)))]{
  68. This returns the filename that the frame is currently being saved as,
  69. or @racket[#f] if there is no appropriate filename.
  70. Returns @racket[#f] by default.
  71. If @racket[temp] is a box, it is filled with @racket[#t] or @racket[#f],
  72. depending if the filename is a temporary filename.
  73. }
  74. @defmethod*[(((make-visible (filename string?)) void?))]{
  75. Makes the file named by @racket[filename] visible (intended for
  76. use with tabbed editing).
  77. }
  78. }
  79. @defmixin[frame:basic-mixin (frame%) (frame:basic<%>)]{
  80. This mixin provides the basic functionality that the framework expects. It
  81. helps manage the list of frames in the @racket[group:%] object returned by
  82. @racket[group:get-the-frame-group].
  83. Do not give @racket[panel%] or @racket[control<%>] objects this frame as
  84. parent. Instead, use the result of the @method[frame:basic<%>
  85. get-area-container] method.
  86. @index{Windows menu}
  87. This mixin also creates a menu bar for the frame, as the
  88. frame is initialized. It uses the class returned by
  89. @method[frame:basic<%> get-menu-bar%]. It only passes the frame as an
  90. initialization argument. In addition, it creates the windows menu in the
  91. menu bar.
  92. This mixin calls its @method[window<%> accept-drop-files] with @racket[#t].
  93. It also calls its @method[frame% set-icon] method according to the current
  94. value of @racket[frame:current-icon].
  95. See also @racket[frame:reorder-menus].
  96. @defmethod*[#:mode override (((show (on? boolean?)) void?))]{
  97. Calls the super method.
  98. When @racket[on?] is @racket[#t], inserts the frame into the
  99. frame group and when it is @racket[#f], removes the frame
  100. from the group.
  101. }
  102. @defmethod*[#:mode override (((can-exit?) boolean?))]{
  103. This, together with @method[frame:basic-mixin on-exit] mimics
  104. @racket[exit:exit].
  105. First, it calls @racket[exit:set-exiting] with @racket[#t]. Then, it calls
  106. @racket[exit:can-exit?]. If it returns @racket[#t], so does this method. If
  107. it returns @racket[#f], this method calls @racket[exit:set-exiting] with
  108. @racket[#f].
  109. }
  110. @defmethod*[#:mode override (((on-exit) void?))]{
  111. Together with @method[frame:basic-mixin can-exit?] this mimics the
  112. behavior of @racket[exit:exit].
  113. Calls @racket[exit:on-exit] and then queues a callback to call Racket's
  114. @racket[exit] function. If that returns, it calls @racket[exit:set-exiting]
  115. to reset that flag to @racket[#f].
  116. }
  117. @defmethod*[#:mode override (((on-superwindow-show (shown? any/c)) void?))]{
  118. Notifies the result of @racket[(group:get-the-frame-group)] that a frame
  119. has been shown, by calling the @method[group:% frame-shown/hidden] method.
  120. }
  121. @defmethod*[#:mode override (((on-drop-file (pathname string?)) void?))]{
  122. Calls @racket[handler:edit-file] with @racket[pathname] as an argument.
  123. }
  124. @defmethod*[#:mode override (((after-new-child) void?))]{
  125. Raises an exception if attempting to add a child to this frame (except if
  126. using the @method[frame:basic<%> make-root-area-container] method).
  127. }
  128. }
  129. @definterface[frame:size-pref<%> (frame:basic<%>)]{
  130. }
  131. @defmixin[frame:size-pref-mixin (frame:basic<%>) (frame:size-pref<%>)]{
  132. @defconstructor[((size-preferences-key symbol?)
  133. (label label-string?)
  134. (parent (or/c (is-a?/c frame%) false/c) #f)
  135. (x (or/c (integer-in -10000 10000) false/c) #f)
  136. (y (or/c (integer-in -10000 10000) false/c) #f)
  137. (style (listof (or/c 'no-resize-border 'no-caption 'no-system-menu 'hide-menu-bar 'mdi-parent 'mdi-child 'toolbar-button 'float 'metal)) null)
  138. (enabled any/c #t)
  139. (border (integer-in 0 1000) 0)
  140. (spacing (integer-in 0 1000) 0)
  141. (alignment (list/c (or/c 'left 'center 'right) (or/c 'top 'center 'bottom)) '(center top))
  142. (min-width (integer-in 0 10000) graphical-minimum-width)
  143. (min-height (integer-in 0 10000) graphical-minimum-height)
  144. (stretchable-width any/c #t) (stretchable-height any/c #t))]{
  145. The size @racket[size-preferences-key] symbol is used with
  146. @racket[preferences:get] and @racket[preferences:set] to track the current
  147. size.
  148. Passes the @racket[width] and @racket[height] initialization arguments to
  149. the superclass based on the current value of the preference.
  150. See also @racket[frame:setup-size-pref].
  151. }
  152. @defmethod*[#:mode override (((on-size (width number?) (height number?)) void?))]{
  153. Updates the preferences, according to the width and
  154. height. The preferences key is the one passed
  155. to the initialization argument of the class.
  156. }
  157. }
  158. @definterface[frame:register-group<%> ()]{
  159. Frames that implement this interface are registered with the group. See
  160. @racket[group:get-the-frame-group] and @racket[frame:register-group-mixin].
  161. }
  162. @defmixin[frame:register-group-mixin (frame:basic<%>) (frame:register-group<%>)]{
  163. During initialization, calls
  164. @method[group:% insert-frame]with @racket[this].
  165. @defmethod*[#:mode augment (((can-close?) boolean?))]{
  166. Calls the inner method, with a default of @racket[#t]. If that returns
  167. @racket[#t], it checks for one of the these three conditions:
  168. @itemize[
  169. @item{@racket[exit:exiting?] returns @racket[#t]}
  170. @item{there is more than one frame in the group returned by
  171. @racket[group:get-the-frame-group], or}
  172. @item{the procedure @racket[exit:user-oks-exit] returns @racket[#t].}]
  173. If any of those conditions hold, the method returns @racket[#t].
  174. }
  175. @defmethod*[#:mode augment (((on-close) void?))]{
  176. First calls the inner method. Next, calls the @method[group:%
  177. remove-frame] method of the result of @racket[group:get-the-frame-group]
  178. with @racket[this] as an argument. Finally, unless @racket[exit:exiting?]
  179. returns @racket[#t], and if there are no more frames open, it calls
  180. @racket[exit:exit].
  181. }
  182. @defmethod*[#:mode override (((on-activate (on? boolean?)) void?))]{
  183. Calls @method[group:% set-active-frame] with @racket[this] when
  184. @racket[on?] is true.
  185. }
  186. }
  187. @definterface[frame:status-line<%> (frame:basic<%>)]{
  188. The mixin that implements this interface provides an interface to a set of
  189. status lines at the bottom of this frame.
  190. Each status line must be opened with @method[frame:status-line<%>
  191. open-status-line] before any messages are shown in the status line and once
  192. @method[frame:status-line<%> close-status-line] is called, no more messages
  193. may be displayed, unless the status line is re-opened.
  194. The screen space for status lines is not created until
  195. @method[frame:status-line<%> update-status-line] is called with a
  196. string. Additionally, the screen space for one status line is re-used when by
  197. another status line when the first passes @racket[#f] to
  198. @method[frame:status-line<%> update-status-line]. In this manner, the status
  199. line frame avoids opening too many status lines and avoids flashing the
  200. status lines open and closed too often.
  201. @defmethod*[(((open-status-line (id symbol?)) void?))]{
  202. Creates a new status line identified by the symbol
  203. argument. The line will not appear in the frame until a
  204. message is put into it, via
  205. @method[frame:status-line<%> update-status-line].
  206. }
  207. @defmethod*[(((close-status-line (id symbol?)) void?))]{
  208. Closes the status line @racket[id].
  209. }
  210. @defmethod*[(((update-status-line (id symbol?) (status (or/c #f string))) void?))]{
  211. Updates the status line named by @racket[id] with @racket[status]. If
  212. @racket[status] is @racket[#f], the status line is becomes blank (and may
  213. be used by other ids).
  214. }
  215. }
  216. @defmixin[frame:status-line-mixin (frame:basic<%>) (frame:status-line<%>)]{
  217. @defmethod*[#:mode override (((make-root-area-container (class (subclass?/c panel%)) (parent (is-a?/c panel%))) (is-a?/c panel%)))]{
  218. Adds a panel at the bottom of the frame to hold the status
  219. lines.
  220. }
  221. }
  222. @definterface[frame:info<%> (frame:basic<%>)]{
  223. Frames matching this interface support a status line.
  224. The preference @racket['framework:show-status-line] controls the visibility
  225. of the status line. If it is @racket[#t], the status line is visible and if
  226. it is @racket[#f], the status line is not visible (see
  227. @racket[preferences:get] for more info about preferences)
  228. @defmethod*[(((determine-width (str string) (canvas (is-a?/c editor-canvas%)) (text (is-a?/c text%))) integer))]{
  229. This method is used to calculate the size of an @racket[editor-canvas%]
  230. with a particular set of characters in it. It is used to calculate the
  231. sizes of the edits in the status line.
  232. }
  233. @defmethod*[(((lock-status-changed) void?))]{
  234. This method is called when the lock status of the @racket[editor<%>]
  235. changes.
  236. Updates the lock icon in the status line panel.
  237. }
  238. @defmethod*[(((update-info) void?))]{
  239. This method updates all of the information in the panel.
  240. }
  241. @defmethod*[(((set-info-canvas (canvas (or/c (is-a?/c canvas:basic%) #f))) void?))]{
  242. Sets this canvas to be the canvas that the info frame shows info about. The
  243. @method[canvas:info-mixin% on-focus] and @method[canvas:info-mixin%
  244. set-editor] methods call this method to ensure that the info canvas is set
  245. correctly.
  246. }
  247. @defmethod*[(((get-info-canvas) (or/c (is-a?/c canvas:basic%) #f)))]{
  248. Returns the canvas that the @racket[frame:info<%>] currently shows info
  249. about. See also @method[frame:info<%> set-info-canvas]
  250. }
  251. @defmethod*[(((get-info-editor) (or/c #f (is-a?/c editor<%>))))]{
  252. Override this method to specify the editor that the status line
  253. contains information about.
  254. Returns the result of @method[frame:editor<%> get-editor].
  255. }
  256. @defmethod*[(((get-info-panel) (is-a?/c horizontal-panel%)))]{
  257. This method returns the panel where the information about this editor is
  258. displayed.
  259. }
  260. @defmethod*[(((show-info) void?))]{
  261. Shows the info panel.
  262. See also @method[frame:info<%> is-info-hidden?].
  263. }
  264. @defmethod*[(((hide-info) void?))]{
  265. Hides the info panel.
  266. See also @method[frame:info<%> is-info-hidden?].
  267. }
  268. @defmethod*[(((is-info-hidden?) boolean?))]{
  269. Result indicates if the show info panel has been explicitly hidden with
  270. @method[frame:info<%> hide-info].
  271. If this method returns @racket[#t] and @racket[(preferences:get
  272. 'framework:show-status-line)] is @racket[#f], then the info panel will not
  273. be visible. Otherwise, it is visible.
  274. }
  275. }
  276. @defmixin[frame:info-mixin (frame:basic<%>) (frame:info<%>)]{
  277. This mixin provides support for displaying various info in the status line of
  278. the frame.
  279. The result of this mixin uses the same initialization arguments as the
  280. mixin's argument.
  281. @defmethod*[#:mode override (((make-root-area-container (class (subclass?/c area-container<%>)) (parent (is-a?/c area-container<%>))) (is-a?/c area-container<%>)))]{
  282. Builds an extra panel for displaying various information.
  283. }
  284. @defmethod*[#:mode augment (((on-close) void?))]{
  285. Removes the GC icon with @racket[unregister-collecting-blit] and cleans up
  286. other callbacks.
  287. }
  288. }
  289. @definterface[frame:text-info<%> (frame:info<%>)]{
  290. Objects matching this interface receive information from editors constructed
  291. with @racket[editor:info-mixin] and display it.
  292. @defmethod*[(((set-macro-recording (on? boolean?)) void?))]{
  293. Shows/hides the icon in the info bar that indicates if a macro recording is
  294. in progress.
  295. }
  296. @defmethod*[(((overwrite-status-changed) void?))]{
  297. This method is called when the overwrite mode is turned either on or off in
  298. the @racket[editor<%>] in this frame.
  299. }
  300. @defmethod*[(((anchor-status-changed) void?))]{
  301. This method is called when the anchor is turned either on or off in the
  302. @racket[editor<%>]
  303. in this frame.
  304. }
  305. @defmethod*[(((editor-position-changed) void?))]{
  306. This method is called when the position in the @racket[editor<%>] changes.
  307. }
  308. @defmethod[(add-line-number-menu-items [menu (is-a?/c menu-item-container<%>)]) void?]{
  309. This method is called when the line/column display in the info bar is
  310. clicked. It is passed a @racket[menu-item-container<%>] that can be filled
  311. in with menu items; those menu items will appear in the menu that appears
  312. when line/colun display is clicked.
  313. }
  314. }
  315. @defmixin[frame:text-info-mixin (frame:info<%>) (frame:text-info<%>)]{
  316. This mixin adds status information to the info panel relating to an
  317. edit.
  318. @defmethod*[#:mode augment (((on-close) void?))]{
  319. removes a preferences callback for @racket['framework:line-offsets].
  320. See @racket[preferences:add-callback] for more information.
  321. }
  322. @defmethod*[#:mode override (((update-info) void?))]{
  323. Calls
  324. @method[frame:text-info<%> overwrite-status-changed],
  325. @method[frame:text-info<%> anchor-status-changed], and
  326. @method[frame:text-info<%> editor-position-changed].
  327. }
  328. }
  329. @definterface[frame:pasteboard-info<%> (frame:info<%>)]{
  330. }
  331. @defmixin[frame:pasteboard-info-mixin (frame:basic<%>) (frame:pasteboard-info<%>)]{
  332. }
  333. @(include/reader "standard-menus.scrbl" s:read-syntax)
  334. @defmixin[frame:standard-menus-mixin (frame:basic<%>) (frame:standard-menus<%>)]{
  335. The result of this mixin implements @racket[frame:standard-menus<%>].
  336. @defmethod*[#:mode augment (((on-close) void?))]{
  337. Removes the preferences callbacks for the menu items
  338. }
  339. }
  340. @definterface[frame:editor<%> (frame:standard-menus<%>)]{
  341. Frame classes matching this interface support embedded editors.
  342. @defmethod*[(((get-entire-label) string))]{
  343. This method returns the entire label for the frame. See also
  344. @method[window<%> set-label] and @method[frame:editor<%> set-label-prefix].
  345. }
  346. @defmethod*[(((get-label-prefix) string?))]{
  347. This returns the prefix for the frame's label.
  348. }
  349. @defmethod*[(((set-label-prefix (prefix string?)) void?))]{
  350. Sets the prefix for the label of the frame.
  351. }
  352. @defmethod*[(((get-canvas%) (subclass?/c editor-canvas%)))]{
  353. The result of this method is used to create the canvas for the
  354. @racket[editor<%>] in this frame.
  355. Returns @racket[editor-canvas%].
  356. }
  357. @defmethod*[(((get-canvas<%>) (is-a?/c canvas:basic%)))]{
  358. The result of this method is used to guard the result of the
  359. @method[frame:editor<%> get-canvas%] method.
  360. }
  361. @defmethod*[(((get-editor%) (implementation?/c editor<%>)))]{
  362. The result of this class is used to create the @racket[editor<%>] in this
  363. frame.
  364. Override this method to specify a different editor class.
  365. Returns the value of the init-field @racket[editor%].
  366. }
  367. @defmethod*[(((get-editor<%>) interface?))]{
  368. The result of this method is used by @method[frame:editor<%> make-editor]
  369. to check that @method[frame:editor<%> get-editor%] is returning a
  370. reasonable editor.
  371. Returns @racket[editor<%>].
  372. }
  373. @defmethod*[(((make-editor) (is-a?/c editor<%>)))]{
  374. This method is called to create the editor in this frame. It calls
  375. @method[frame:editor<%> get-editor<%>] and uses that interface to make sure
  376. the result of @method[frame:editor<%> get-editor%] is reasonable.
  377. Calls @racket[(make-object @#,method[frame:editor<%> get-editor%])].
  378. }
  379. @defmethod*[(((revert) void?))]{
  380. Loads the most recently saved version of the file to the disk. If the
  381. @racket[editor<%>] is a @racket[text%], the start and end positions are
  382. restored.
  383. }
  384. @defmethod*[(((save (format (or/c 'guess 'standard 'text 'text-force-cr 'same 'copy) 'same))
  385. boolean?))]{
  386. Saves the file being edited, possibly calling
  387. @method[frame:editor<%> save-as]
  388. if the editor has no filename yet.
  389. Returns @racket[#f] if the user cancels this operation (only possible when
  390. the file has not been saved before and the user is prompted for a new
  391. filename) and returns @racket[#t] if not.
  392. }
  393. @defmethod*[(((save-as (format (or/c 'guess 'standard 'text 'text-force-cr 'same 'copy) 'same))
  394. boolean?))]{
  395. Queries the use for a file name and saves the file with that name.
  396. Returns @racket[#f] if the user cancells the file-choosing
  397. dialog and returns @racket[#t] otherwise.
  398. }
  399. @defmethod*[(((get-canvas) (is-a?/c canvas%)))]{
  400. Returns the canvas used to display the
  401. @racket[editor<%>]
  402. in this frame.
  403. }
  404. @defmethod*[(((get-editor) (is-a?/c editor<%>)))]{
  405. Returns the editor in this frame.
  406. }
  407. }
  408. @defmixin[frame:editor-mixin (frame:standard-menus<%>) (frame:editor<%>)]{
  409. This mixin adds functionality to support an
  410. @racket[editor<%>]
  411. in the frame. This
  412. includes management of the title, implementations of some of the menu
  413. items, a reasonable initial size, and access to the
  414. @racket[editor<%>]
  415. itself.
  416. The size of this frame with be either 600 by 650 or 65 less than the
  417. width and height of the screen, whichever is smaller.
  418. @defconstructor[((filename string?)
  419. (editor% (is-a?/c editor<%>))
  420. (parent (or/c (is-a?/c frame%) false/c) #f)
  421. (width (or/c (integer-in 0 10000) false/c) #f)
  422. (height (or/c (integer-in 0 10000) false/c) #f)
  423. (x (or/c (integer-in -10000 10000) false/c) #f)
  424. (y (or/c (integer-in -10000 10000) false/c) #f)
  425. (style (listof (or/c 'no-resize-border 'no-caption 'no-system-menu 'hide-menu-bar 'mdi-parent 'mdi-child 'toolbar-button 'float 'metal)) null)
  426. (enabled any/c #t)
  427. (border (integer-in 0 1000) 0)
  428. (spacing (integer-in 0 1000) 0)
  429. (alignment (list/c (or/c 'left 'center 'right) (or/c 'top 'center 'bottom)) '(center top))
  430. (min-width (integer-in 0 10000) graphical-minimum-width)
  431. (min-height (integer-in 0 10000) graphical-minimum-height)
  432. (stretchable-width any/c #t)
  433. (stretchable-height any/c #t))]{
  434. }
  435. @defmethod*[#:mode override (((get-filename) (or/c #f path?)))]{
  436. Returns the filename in the editor returned by
  437. @method[frame:editor<%> get-editor].
  438. }
  439. @defmethod*[#:mode override (((editing-this-file? (filename path?)) boolean?))]{
  440. Returns @racket[#t] if the filename is the file that this frame is editing.
  441. }
  442. @defmethod*[#:mode augment (((on-close) void?))]{
  443. Calls the @racket[editor:basic<%>]'s method @method[editor:basic<%>
  444. on-close].
  445. }
  446. @defmethod*[#:mode augment (((can-close?) void?))]{
  447. Calls the @racket[editor:basic<%>]'s method @method[editor:basic<%>
  448. can-close?].
  449. }
  450. @defmethod*[#:mode override (((get-label) string?))]{
  451. Returns the portion of the label after the hyphen. See also
  452. @method[frame:editor<%> get-entire-label].
  453. }
  454. @defmethod*[#:mode override (((set-label (label string?)) void?))]{
  455. Sets the label, but preserves the label's prefix. See also
  456. @method[frame:editor<%> set-label-prefix].
  457. }
  458. @defmethod*[#:mode override (((file-menu:open-callback (item (is-a?/c menu-item<%>)) (evt (is-a?/c mouse-event%))) void?))]{
  459. Calls @racket[handler:open-file] with the directory of the saved file
  460. associated with this editor (if any).
  461. }
  462. @defmethod*[#:mode override (((file-menu:revert-on-demand) void?))]{
  463. Disables the menu item when the editor is locked.
  464. }
  465. @defmethod*[#:mode override (((file-menu:revert-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  466. Informs the user that this action is not undoable and, if they still want
  467. to continue, calls @method[frame:editor<%> revert].
  468. }
  469. @defmethod*[#:mode override (((file-menu:create-revert?) boolean?))]{
  470. returns @racket[#t].
  471. }
  472. @defmethod*[#:mode override (((file-menu:save-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  473. Saves the file in the editor.
  474. }
  475. @defmethod*[#:mode override (((file-menu:create-save?) boolean?))]{
  476. returns @racket[#t].
  477. }
  478. @defmethod*[#:mode override (((file-menu:save-as-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  479. Prompts the user for a file name and uses that filename to save the buffer.
  480. Calls @method[frame:editor<%> save-as] with no arguments.
  481. }
  482. @defmethod*[#:mode override (((file-menu:create-save-as?) boolean?))]{
  483. returns @racket[#t].
  484. }
  485. @defmethod*[#:mode override (((file-menu:print-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  486. Calls the @method[editor<%> print] method of @racket[editor<%>] with the
  487. default arguments, except that the @racket[output-mode] argument is the
  488. result of calling @racket[preferences:get] with
  489. @racket['framework:print-output-mode].
  490. }
  491. @defmethod*[#:mode override (((file-menu:create-print?) boolean?))]{
  492. returns @racket[#t].
  493. }
  494. @defmethod*[#:mode override (((file-menu:between-save-as-and-print (file-menu (is-a?/c menu%))) void?))]{
  495. Creates a Print Setup menu item.
  496. }
  497. @defmethod*[#:mode override (((edit-menu:between-select-all-and-find (edit-menu (is-a?/c menu%))) void?))]{
  498. Adds a menu item for toggling @method[editor<%> auto-wrap] in the focused
  499. text.
  500. }
  501. @defmethod*[#:mode override (((help-menu:about-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  502. Calls @racket[message-box] with a message welcoming the user to the
  503. application named by @racket[application:current-app-name]
  504. }
  505. @defmethod*[#:mode override (((help-menu:about-string) string))]{
  506. Returns the result of (@racket[application:current-app-name])
  507. }
  508. @defmethod*[#:mode override (((help-menu:create-about?) boolean?))]{
  509. returns @racket[#t].
  510. }
  511. }
  512. @definterface[frame:open-here<%> (frame:editor<%>)]{
  513. Frames implementing this mixin can change the file they are displaying.
  514. The frame is only re-used when the @racket['framework:open-here?] preference
  515. is set (see @racket[preferences:get] and @racket[preferences:set] for details
  516. on preferences).
  517. The @racket[frame:open-here-mixin] implements this interface.
  518. @defmethod*[(((get-open-here-editor) (is-a?/c editor<%>)))]{
  519. When the user switches the visible file in this frame, the of this method
  520. is the editor that gets switched.
  521. By Default, returns the result of @method[frame:editor<%> get-editor].
  522. }
  523. @defmethod*[(((open-here (filename string)) void?))]{
  524. Opens @racket[filename] in the current frame, possibly prompting the user
  525. about saving a file (in which case the frame might not get switched).
  526. }
  527. }
  528. @defmixin[frame:open-here-mixin (frame:editor<%>) (frame:open-here<%>)]{
  529. Provides an implementation of @racket[frame:open-here<%>]
  530. @defmethod*[#:mode override (((file-menu:new-on-demand (item (is-a?/c menu-item%))) void?))]{
  531. Sets the label of @racket[item] to @racket["New..."] if the preference
  532. @racket['framework:open-here?] is set.
  533. }
  534. @defmethod*[#:mode override (((file-menu:new-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  535. When the preference @racket['framework:open-here?] preference is set, this
  536. method prompts the user, asking if they would like to create a new frame,
  537. or just clear out this one. If they clear it out and the file hasn't been
  538. saved, they are asked about saving.
  539. }
  540. @defmethod*[#:mode override (((file-menu:open-on-demand (item (is-a?/c menu-item%))) void?))]{
  541. Sets the label of @racket[item] to "Open Here..." if the preference
  542. @racket['framework:open-here?] is set.
  543. }
  544. @defmethod*[#:mode augment (((on-close) void?))]{
  545. Calls @method[group:% set-open-here-frame] with @racket[#f] if the result
  546. of @method[group:% get-open-here-frame] is @racket[eq?] to @racket[this].
  547. }
  548. @defmethod*[#:mode override (((on-activate (on? boolean?)) void?))]{
  549. When @racket[on?] is @racket[#t], calls @method[group:%
  550. set-open-here-frame] with @racket[this].
  551. }
  552. }
  553. @definterface[frame:text<%> (frame:editor<%>)]{
  554. Frames matching this interface provide support for @racket[text%]s.
  555. }
  556. @defmixin[frame:text-mixin (frame:editor<%>) (frame:text<%>)]{
  557. This mixins adds support for @racket[text%]s in the frame.
  558. @defconstructor[((editor% (extends text%)))]{
  559. Calls the super initialization with either the value of the
  560. @racket[editor%] init or, if none was supplied, it passes @racket[text%].
  561. }
  562. @defmethod*[#:mode override (((get-editor<%>) interface))]{
  563. Returns @racket[(class->interface text%)].
  564. }
  565. }
  566. @definterface[frame:pasteboard<%> (frame:editor<%>)]{
  567. Frames matching this interface provide support for
  568. @racket[pasteboard%]s.
  569. }
  570. @defmixin[frame:pasteboard-mixin (frame:editor<%>) (frame:pasteboard<%>)]{
  571. This mixin provides support for pasteboards in a frame.
  572. @defconstructor[((editor% (extends pasteboard%)))]{
  573. Calls the super initialization with either the value of the
  574. @racket[editor%] init or, if none was supplied, it passes
  575. @racket[pasteboard%].
  576. }
  577. @defmethod*[#:mode override (((get-editor<%>) interface))]{
  578. Returns @racket[(class->interface pasteboard%)].
  579. }
  580. }
  581. @definterface[frame:delegate<%> (frame:status-line<%> frame:text<%>)]{
  582. Frames that implement this interface provide a 20,000 feet overview of the
  583. text in the main editor. The term @bold{delegate} in these method
  584. descriptions refers to the original editor and the term @bold{delegatee}
  585. refers to the editor showing the 20,000 feet overview.
  586. @defmethod*[(((get-delegated-text) (is-a?/c text:delegate<%>)))]{
  587. Returns the delegate text.
  588. }
  589. @defmethod*[(((delegated-text-shown?) boolean?))]{
  590. Returns @racket[#t] if the delegate is visible, and @racket[#f] if it
  591. isn't.
  592. }
  593. @defmethod*[(((hide-delegated-text) void?))]{
  594. Hides the delegated text.
  595. When the delegated text is hidden, it is not being updated. This is
  596. accomplished by calling the @method[text:delegate<%> set-delegate] method
  597. of @method[frame:editor<%> get-editor]with @racket[#f].
  598. See also @method[frame:delegate<%> show-delegated-text]
  599. }
  600. @defmethod*[(((show-delegated-text) void?))]{
  601. Makes the delegated text visible.
  602. When the delegated text is shown, the @method[text:delegate<%>
  603. set-delegate] method of @method[frame:delegate<%> get-delegated-text]is
  604. called with the text to delegate messages to.
  605. See also @method[frame:delegate<%> hide-delegated-text].
  606. }
  607. @defmethod*[(((delegate-moved) void?))]{
  608. This method is called when the visible region of the delegate editor
  609. changes, so that the blue region in the delegatee is updated.
  610. }
  611. }
  612. @defmixin[frame:delegate-mixin (frame:status-line<%> frame:text<%>) (frame:delegate<%>)]{
  613. Adds support for a 20,000-feet view via @racket[text:delegate<%>] and
  614. @racket[text:delegate-mixin].
  615. @defmethod*[#:mode override (((make-root-area-container (class (subclass?/c panel%)) (parent (is-a?/c panel%))) (is-a?/c panel%)))]{
  616. Adds a panel outside to hold the delegate @racket[editor-canvas%] and
  617. @racket[text%].
  618. }
  619. @defmethod*[#:mode override (((get-editor<%>) interface))]{
  620. Returns @racket[text:delegate].
  621. }
  622. @defmethod*[#:mode override (((get-editor%) (is-a?/c text:delegate<%>)))]{
  623. returns the super result, with the @racket[text:delegate-mixin] mixed in.
  624. }
  625. }
  626. @definterface[frame:searchable<%> (frame:basic<%>)]{
  627. Frames that implement this interface support searching.
  628. @defmethod[(search (direction (symbols 'forward 'backward))) void?]{
  629. Searches for the text in the search edit in the result of
  630. @method[frame:searchable<%> get-text-to-search].
  631. If the text is found and it sets the selection to the found text.
  632. }
  633. @defmethod[(search-replace) boolean?]{
  634. If there is a dark purple bubble (ie, if the replace portion of the search
  635. bar is visible and there is a search hit after the insertion point), then
  636. this will replace it with the contents of the replace editor and move the
  637. insertion point to just after that, or to the end of the editor (if there
  638. are no more search hits after the insertion point, but there are search
  639. hits before it).
  640. }
  641. @defmethod[(replace-all) void?]{
  642. Loops through the text from the beginning to the end, replacing all
  643. occurrences of the search string with the contents of the replace edit.
  644. }
  645. @defmethod[(get-text-to-search) (is-a?/c text%)]{
  646. Returns the last value passed to
  647. @method[frame:searchable<%> set-text-to-search].
  648. }
  649. @defmethod[(set-text-to-search [txt (or/c false/c (is-a?/c (subclass?/c text%)))]) void?]{
  650. Sets the current text to be searched.
  651. }
  652. @defmethod[(search-hidden?) boolean?]{
  653. Returns @racket[#t] if the search subwindow is visiable and @racket[#f]
  654. otherwise.
  655. }
  656. @defmethod[(hide-search) void?]{
  657. This method hides the searching information on the bottom of the frame.
  658. }
  659. @defmethod[(unhide-search [move-focus? boolean?]) void?]{
  660. When the searching sub window is hidden, makes it visible. If
  661. @racket[move-focus?] is @racket[#f], the focus is not moved, but if it is
  662. any other value, the focus is moved to the find window.
  663. }
  664. @defmethod[(get-case-sensitive-search?) boolean?]{
  665. Returns @racket[#t] if the search is currently case-sensitive. (This
  666. method's value depends on the preference
  667. @racket['framework:case-sensitive-search?], but the preference is only
  668. consulted when the frame is created.)
  669. }
  670. @defmethod[#:mode public-final (search-hits-changed) void?]{
  671. This method is called when the number of search matches changes and it
  672. updates the GUI.
  673. }
  674. }
  675. @defmixin[frame:searchable-mixin (frame:standard-menus<%>) (frame:searchable<%>)]{
  676. This mixin adds support for searching in the @racket[editor<%>] in this
  677. frame.
  678. @defmethod*[#:mode override (((edit-menu:find-callback) boolean?))]{
  679. Toggles the focus between the find window and the window being searched.
  680. When moving to the window with the search string, selects the entire range
  681. in the buffer.
  682. }
  683. @defmethod*[#:mode override (((edit-menu:create-find?) boolean?))]{
  684. returns @racket[#t].
  685. }
  686. @defmethod*[#:mode override
  687. (((edit-menu:find-again-callback (item (is-a?/c menu-item%))
  688. (evt (is-a?/c control-event%)))
  689. void?))]{
  690. Calls @method[frame:searchable unhide-search] and then
  691. @method[frame:searchable<%> search].
  692. }
  693. @defmethod*[#:mode override (((edit-menu:create-find-again?) boolean?))]{
  694. returns @racket[#t].
  695. }
  696. @defmethod*[#:mode override (((edit-menu:find-again-backwards-callback (item (is-a?/c menu-item%)) (evt (is-a?/c control-event%))) void?))]{
  697. Calls @method[frame:searchable unhide-search] and then
  698. @method[frame:searchable<%> search].
  699. }
  700. @defmethod*[#:mode override (((edit-menu:create-find-again-backwards?) boolean?))]{
  701. returns @racket[#t].
  702. }
  703. @defmethod*[#:mode override (((edit-menu:replace-all-callback) boolean?))]{
  704. Calls @method[frame:searchable<%> replace-all].
  705. }
  706. @defmethod*[#:mode override (((edit-menu:replace-all-on-demand (item menu-item%)) void?))]{
  707. Disables @racket[item] when @method[frame:searchable<%> search-hidden?]
  708. returns @racket[#t] and enables it when that method returns @racket[#f].
  709. }
  710. @defmethod*[#:mode override (((edit-menu:create-replace-all?) boolean?))]{
  711. returns @racket[#t].
  712. }
  713. @defmethod*[#:mode override (((edit-menu:find-case-sensitive-callback) boolean?))]{
  714. Updates the state of the case-sensitive searching for this frame, and sets
  715. the @racket['framework:case-sensitive-search?] preference for later
  716. frames.
  717. }
  718. @defmethod*[#:mode override (((edit-menu:find-case-sensitive-on-demand (item menu-item%)) void?))]{
  719. Checks @racket[item] when searching is case-sensitive and unchecks it
  720. otherwise.
  721. }
  722. @defmethod*[#:mode override (((edit-menu:create-find-case-sensitive?) boolean?))]{
  723. returns @racket[#t].
  724. }
  725. @defmethod*[#:mode override (((make-root-area-container) (is-a?/c area-container<%>)))]{
  726. Builds a panel for the searching information.
  727. }
  728. @defmethod*[#:mode augment (((on-close) void?))]{
  729. Cleans up after the searching frame.
  730. }
  731. }
  732. @definterface[frame:searchable-text<%> (frame:searchable<%> frame:text<%>)]{
  733. }
  734. @defmixin[frame:searchable-text-mixin (frame:text<%> frame:searchable<%>) (frame:searchable-text<%>)]{
  735. @defmethod*[#:mode override-final (((get-text-to-search) (is-a?/c text%)))]{
  736. Returns the result of @method[frame:editor<%> get-editor].
  737. }
  738. @defmethod*[#:mode override (((get-editor<%>) (is-a?/c editor<%>)))]{
  739. Returns @racket[text:searching<%>].
  740. }
  741. @defmethod*[#:mode override (((get-editor%) (is-a?/c editor<%>)))]{
  742. Returns @racket[(text:searching-mixin (super get-editor%))].
  743. }
  744. }
  745. @defclass[frame:basic% (frame:register-group-mixin (frame:basic-mixin frame%)) ()]{}
  746. @defclass[frame:size-pref% (frame:size-pref-mixin frame:basic%) ()]{}
  747. @defclass[frame:info% (frame:info-mixin frame:basic%) ()]{}
  748. @defclass[frame:text-info% (frame:text-info-mixin frame:info%) ()]{}
  749. @defclass[frame:pasteboard-info% (frame:pasteboard-info-mixin frame:text-info%) ()]{}
  750. @defclass[frame:status-line% (frame:status-line-mixin frame:text-info%) ()]{}
  751. @defclass[frame:standard-menus% (frame:standard-menus-mixin frame:status-line%) ()]{}
  752. @defclass[frame:editor% (frame:editor-mixin frame:standard-menus%) ()]{}
  753. @defclass[frame:open-here% (frame:open-here-mixin frame:editor%) ()]{}
  754. @defclass[frame:text% (frame:text-mixin frame:open-here%) ()]{}
  755. @defclass[frame:searchable% (frame:searchable-text-mixin (frame:searchable-mixin frame:text%)) ()]{}
  756. @defclass[frame:delegate% (frame:delegate-mixin frame:searchable%) ()]{}
  757. @defclass[frame:pasteboard% (frame:pasteboard-mixin frame:open-here%) ()]{}
  758. @(include-previously-extracted "main-extracts.rkt" #rx"^frame:")