Compare commits
3 Commits
96778ac47d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b41e312a80 | |||
| 0d3b55f252 | |||
| f780c7f5b4 |
@@ -1,13 +1,19 @@
|
||||
# rackedit
|
||||
|
||||
`rackedit` opens a simple Racket editor window for a file. It can be used from
|
||||
DrRacket, from a Racket program, or from the Racket command line.
|
||||
`rackedit` opens a simple Racket editor window, optionally with a file. It can be
|
||||
used from DrRacket, from a Racket program, or from the Racket command line.
|
||||
|
||||
The package exports one procedure:
|
||||
The package exports one procedure. With no filename, `rkdt` opens an empty editor:
|
||||
|
||||
```racket
|
||||
(require rackedit)
|
||||
|
||||
(rkdt)
|
||||
```
|
||||
|
||||
Pass a filename to open an existing file:
|
||||
|
||||
```racket
|
||||
(rkdt "notes.rkt")
|
||||
```
|
||||
|
||||
@@ -22,7 +28,12 @@ The initial window geometry can be specified with `#:width`, `#:height`, `#:x`,
|
||||
and `#:y`. Window positions and sizes are remembered per internal editor number
|
||||
and per screen configuration.
|
||||
|
||||
The frame can be customized with `#:frame-cb`. For example:
|
||||
The frame can be observed or customized with `#:frame-cb`. The callback receives
|
||||
an event symbol and the editor frame. It is called at the lifecycle points
|
||||
`'before-show`, `'after-show`, `'wait-for-close`, and `'on-close`.
|
||||
`'wait-for-close` is emitted only when `#:wait? #t` is used.
|
||||
|
||||
For example, the window title can be changed before the frame becomes visible:
|
||||
|
||||
```racket
|
||||
(require racket/class
|
||||
@@ -30,12 +41,24 @@ The frame can be customized with `#:frame-cb`. For example:
|
||||
|
||||
(rkdt "notes.rkt"
|
||||
#:frame-cb
|
||||
(λ (frame)
|
||||
(send frame set-label "Notes")))
|
||||
(λ (event frame)
|
||||
(when (eq? event 'before-show)
|
||||
(send frame set-label "Notes"))))
|
||||
```
|
||||
|
||||
The standard File menu does not contain the Exit/Quit command, so closing one
|
||||
editor window does not imply exiting the application that opened it.
|
||||
|
||||
## Headless environments
|
||||
|
||||
Requiring `rackedit` does not initialize Racket's GUI subsystem. This means that
|
||||
`(require rackedit)` is safe in a headless Racket process, for example a server
|
||||
process without access to an X11 or Wayland display.
|
||||
|
||||
The GUI implementation is loaded only when `rkdt` is actually called. Calling
|
||||
`rkdt` still requires a usable graphical environment. Programs that also support
|
||||
a terminal editor can therefore choose that editor before calling `rkdt`, without
|
||||
merely requiring `rackedit` causing GTK initialization.
|
||||
|
||||
Full API documentation is included as Scribble documentation in
|
||||
`scrbl/rkdt.scrbl`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#lang info
|
||||
|
||||
(define pkg-authors '(hnmdijkema))
|
||||
(define version "0.1.5")
|
||||
(define version "0.1.8")
|
||||
(define license 'MIT) ;
|
||||
(define collection "rackedit")
|
||||
(define pkg-desc "rackedit exports the rkdt procedure, that can be used to open an editor window with a given file")
|
||||
|
||||
@@ -1,164 +1,33 @@
|
||||
#lang racket/base
|
||||
|
||||
(require framework
|
||||
racket/gui/base
|
||||
racket/class
|
||||
simple-ini/class
|
||||
)
|
||||
|
||||
(require racket/runtime-path)
|
||||
(provide rkdt)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Internal stuff
|
||||
;; Public interface
|
||||
;;
|
||||
;; Keep the GUI implementation out of this module. This allows packages to
|
||||
;; require rackedit in a headless environment without initializing GTK.
|
||||
;; The GUI is loaded only when rkdt is actually called.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define open-editor-counter 0)
|
||||
(define open-editor-free-list '())
|
||||
(define open-editor-use-list '())
|
||||
(define-runtime-path rkdt-gui-path "private/gui.rkt")
|
||||
|
||||
(define ini (new ini% [file 'rackedit]))
|
||||
|
||||
(define editor-frame%
|
||||
(frame:text-mixin
|
||||
(frame:editor-mixin
|
||||
(frame:standard-menus-mixin
|
||||
(frame:basic-mixin frame%)))))
|
||||
|
||||
(define (make-editor-frame% closed close-cb)
|
||||
(class editor-frame%
|
||||
|
||||
(define my-number -1)
|
||||
(define my-x -1)
|
||||
(define my-y -1)
|
||||
(define my-w -1)
|
||||
(define my-h -1)
|
||||
|
||||
(define/override (on-move x y)
|
||||
(set! my-x x)
|
||||
(set! my-y y)
|
||||
(super on-move x y)
|
||||
)
|
||||
|
||||
(define/override (on-size w h)
|
||||
(set! my-w w)
|
||||
(set! my-h h)
|
||||
(super on-size w h)
|
||||
)
|
||||
|
||||
(define/override (file-menu:create-quit?)
|
||||
#f)
|
||||
|
||||
(define cb (λ args #t))
|
||||
|
||||
(define/public (set-frame-cb! frame-cb)
|
||||
(set! cb frame-cb)
|
||||
)
|
||||
|
||||
(define/augment (on-close)
|
||||
(close-cb my-number my-x my-y my-w my-h)
|
||||
(set! open-editor-use-list
|
||||
(filter (λ (x)
|
||||
(when (= x my-number)
|
||||
(set! open-editor-free-list
|
||||
(sort (cons x open-editor-free-list) <)))
|
||||
(not (= x my-number)))
|
||||
open-editor-use-list))
|
||||
(semaphore-post closed)
|
||||
(cb 'on-close this)
|
||||
(inner (void) on-close))
|
||||
|
||||
(define/public (get-num)
|
||||
my-number)
|
||||
|
||||
(super-new)
|
||||
|
||||
(begin
|
||||
(if (null? open-editor-free-list)
|
||||
(begin
|
||||
(set! open-editor-counter (+ open-editor-counter 1))
|
||||
(set! my-number open-editor-counter))
|
||||
(begin
|
||||
(set! my-number (car open-editor-free-list))
|
||||
(set! open-editor-free-list (cdr open-editor-free-list))))
|
||||
(set! open-editor-use-list (cons my-number open-editor-use-list))
|
||||
)
|
||||
|
||||
))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Goal: start an editor window for a given file
|
||||
;; pre : *
|
||||
;; post: editor started
|
||||
;; result: An editor window that can be used.
|
||||
;;
|
||||
;; The editor windows are numbered internally and for each editor
|
||||
;; number, a window position x, y, w, h is stored.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(define (rkdt filename
|
||||
#:wait? [wait? #f]
|
||||
#:width [width 900]
|
||||
#:height [height 650]
|
||||
#:x [x 100]
|
||||
#:y [y 100]
|
||||
(define (rkdt [filename #f]
|
||||
#:wait? [wait? #f]
|
||||
#:width [width 900]
|
||||
#:height [height 650]
|
||||
#:x [x 100]
|
||||
#:y [y 100]
|
||||
#:frame-cb [frame-cb (λ (call-time frame) #t)])
|
||||
|
||||
(let* ((store-cfg #f)
|
||||
(closed (make-semaphore 0))
|
||||
(frame (new (make-editor-frame% closed
|
||||
(λ (num x y w h) (store-cfg num x y w h)))
|
||||
[filename (format "~a" filename)]
|
||||
[editor% racket:text%]
|
||||
[width 900]
|
||||
[height 650]
|
||||
[x 100]
|
||||
[y 100]))
|
||||
(editor (send frame get-editor))
|
||||
(my-num -1)
|
||||
)
|
||||
|
||||
(define (get-win-id num)
|
||||
(letrec ((displ (λ (i n)
|
||||
(if (= i n)
|
||||
""
|
||||
(let-values (((w h) (get-display-size #:monitor i)))
|
||||
(string-append
|
||||
(format "-~a-~a-~a" i w h)
|
||||
(displ (+ i 1) n)))))))
|
||||
(string->symbol
|
||||
(format "win-~a~a" num (displ 0 (get-display-count))))))
|
||||
|
||||
(set! store-cfg (λ (num x y w h)
|
||||
(let ((win (get-win-id num)))
|
||||
(send ini set! 'geoms win (list x y w h)))))
|
||||
|
||||
(send editor set-max-undo-history 100)
|
||||
|
||||
(let* ((win-num (send frame get-num))
|
||||
(geom (send ini get 'geoms
|
||||
(get-win-id win-num)
|
||||
(list x y width height))))
|
||||
|
||||
(send frame move (car geom) (cadr geom))
|
||||
(send frame resize (caddr geom) (cadddr geom))
|
||||
|
||||
(send frame set-label (format "~a (~a)"
|
||||
(send frame get-label)
|
||||
win-num))
|
||||
|
||||
(send frame set-frame-cb! frame-cb)
|
||||
(frame-cb 'before-show frame)
|
||||
(send frame show #t)
|
||||
(frame-cb 'after-show frame)
|
||||
|
||||
(when wait?
|
||||
(frame-cb 'wait-for-close frame)
|
||||
(yield closed)
|
||||
)
|
||||
|
||||
(void))))
|
||||
|
||||
|
||||
(define gui-rkdt
|
||||
(dynamic-require rkdt-gui-path 'rkdt))
|
||||
|
||||
(gui-rkdt filename
|
||||
#:wait? wait?
|
||||
#:width width
|
||||
#:height height
|
||||
#:x x
|
||||
#:y y
|
||||
#:frame-cb frame-cb))
|
||||
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
#lang racket/base
|
||||
|
||||
(require framework
|
||||
racket/gui/base
|
||||
racket/class
|
||||
simple-ini/class
|
||||
)
|
||||
|
||||
(provide rkdt)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Internal stuff
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define open-editor-counter 0)
|
||||
(define open-editor-free-list '())
|
||||
(define open-editor-use-list '())
|
||||
|
||||
(define ini (new ini% [file 'rackedit]))
|
||||
|
||||
(define editor-frame%
|
||||
(frame:text-mixin
|
||||
(frame:editor-mixin
|
||||
(frame:standard-menus-mixin
|
||||
(frame:basic-mixin frame%)))))
|
||||
|
||||
(define (make-editor-frame% closed close-cb)
|
||||
(class editor-frame%
|
||||
|
||||
(define my-number -1)
|
||||
(define my-x -1)
|
||||
(define my-y -1)
|
||||
(define my-w -1)
|
||||
(define my-h -1)
|
||||
|
||||
(define/override (on-move x y)
|
||||
(set! my-x x)
|
||||
(set! my-y y)
|
||||
(super on-move x y)
|
||||
)
|
||||
|
||||
(define/override (on-size w h)
|
||||
(set! my-w w)
|
||||
(set! my-h h)
|
||||
(super on-size w h)
|
||||
)
|
||||
|
||||
(define/override (file-menu:create-quit?)
|
||||
#f)
|
||||
|
||||
(define cb (λ args #t))
|
||||
|
||||
(define/public (set-frame-cb! frame-cb)
|
||||
(set! cb frame-cb)
|
||||
)
|
||||
|
||||
(define/augment (on-close)
|
||||
(close-cb my-number my-x my-y my-w my-h)
|
||||
(set! open-editor-use-list
|
||||
(filter (λ (x)
|
||||
(when (= x my-number)
|
||||
(set! open-editor-free-list
|
||||
(sort (cons x open-editor-free-list) <)))
|
||||
(not (= x my-number)))
|
||||
open-editor-use-list))
|
||||
(semaphore-post closed)
|
||||
(cb 'on-close this)
|
||||
(inner (void) on-close))
|
||||
|
||||
(define/public (get-num)
|
||||
my-number)
|
||||
|
||||
(super-new)
|
||||
|
||||
(begin
|
||||
(if (null? open-editor-free-list)
|
||||
(begin
|
||||
(set! open-editor-counter (+ open-editor-counter 1))
|
||||
(set! my-number open-editor-counter))
|
||||
(begin
|
||||
(set! my-number (car open-editor-free-list))
|
||||
(set! open-editor-free-list (cdr open-editor-free-list))))
|
||||
(set! open-editor-use-list (cons my-number open-editor-use-list))
|
||||
)
|
||||
|
||||
))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Goal: start an editor window for a given file
|
||||
;; pre : *
|
||||
;; post: editor started
|
||||
;; result: An editor window that can be used.
|
||||
;;
|
||||
;; The editor windows are numbered internally and for each editor
|
||||
;; number, a window position x, y, w, h is stored.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
(define (rkdt [filename #f]
|
||||
#:wait? [wait? #f]
|
||||
#:width [width 900]
|
||||
#:height [height 650]
|
||||
#:x [x 100]
|
||||
#:y [y 100]
|
||||
#:frame-cb [frame-cb (λ (call-time frame) #t)])
|
||||
|
||||
(let* ((store-cfg #f)
|
||||
(closed (make-semaphore 0))
|
||||
(frame (new (make-editor-frame% closed
|
||||
(λ (num x y w h) (store-cfg num x y w h)))
|
||||
[filename (if (eq? filename #f)
|
||||
#f
|
||||
(format "~a" filename))]
|
||||
[editor% racket:text%]
|
||||
[width 900]
|
||||
[height 650]
|
||||
[x 100]
|
||||
[y 100]))
|
||||
(editor (send frame get-editor))
|
||||
(my-num -1)
|
||||
)
|
||||
|
||||
(define (get-win-id num)
|
||||
(letrec ((displ (λ (i n)
|
||||
(if (= i n)
|
||||
""
|
||||
(let-values (((w h) (get-display-size #:monitor i)))
|
||||
(string-append
|
||||
(format "-~a-~a-~a" i w h)
|
||||
(displ (+ i 1) n)))))))
|
||||
(string->symbol
|
||||
(format "win-~a~a" num (displ 0 (get-display-count))))))
|
||||
|
||||
(set! store-cfg (λ (num x y w h)
|
||||
(let ((win (get-win-id num)))
|
||||
(send ini set! 'geoms win (list x y w h)))))
|
||||
|
||||
(send editor set-max-undo-history 100)
|
||||
|
||||
(let* ((win-num (send frame get-num))
|
||||
(geom (send ini get 'geoms
|
||||
(get-win-id win-num)
|
||||
(list x y width height))))
|
||||
|
||||
(send frame move (car geom) (cadr geom))
|
||||
(send frame resize (caddr geom) (cadddr geom))
|
||||
|
||||
(send frame set-label (format "~a (~a)"
|
||||
(send frame get-label)
|
||||
win-num))
|
||||
|
||||
(send frame set-frame-cb! frame-cb)
|
||||
(frame-cb 'before-show frame)
|
||||
(send frame show #t)
|
||||
(frame-cb 'after-show frame)
|
||||
|
||||
(when wait?
|
||||
(frame-cb 'wait-for-close frame)
|
||||
(yield closed)
|
||||
)
|
||||
|
||||
(void))))
|
||||
|
||||
|
||||
|
||||
+110
-40
@@ -2,66 +2,121 @@
|
||||
|
||||
@(require (for-label racket/base
|
||||
racket/class
|
||||
racket/contract
|
||||
"../main.rkt"))
|
||||
|
||||
@title{rackedit}
|
||||
@author[@author+email["Hans Dijkema" "hans@dijkewijk.nl"]]
|
||||
|
||||
|
||||
@defmodule[rackedit]
|
||||
|
||||
@tt{rackedit} provides a small editor window based on Racket's GUI framework.
|
||||
It is intended for situations where a program, DrRacket interaction, or command
|
||||
line session needs to open a file in a simple Racket editor without starting a
|
||||
separate full editor application.
|
||||
line session needs a simple Racket editor, optionally for a specific file, without
|
||||
starting a separate full editor application.
|
||||
|
||||
@section{Opening an editor}
|
||||
|
||||
@defproc[(rkdt [filename path-string?]
|
||||
@defproc[(rkdt [filename (or/c path-string? #f) #f]
|
||||
[#:wait? wait? boolean? #f]
|
||||
[#:width width exact-positive-integer? 900]
|
||||
[#:height height exact-positive-integer? 650]
|
||||
[#:x x exact-integer? 100]
|
||||
[#:y y exact-integer? 100]
|
||||
[#:frame-cb frame-cb procedure? (λ (frame) #t)])
|
||||
[#:frame-cb frame-cb procedure?
|
||||
(λ (call-time frame) #t)])
|
||||
void?]{
|
||||
|
||||
Opens an editor window for @racket[filename]. The file name is passed to the
|
||||
Racket editor frame and the editor is shown immediately.
|
||||
@bold{Purpose.} Opens an editor window. When @racket[filename] is a path or
|
||||
string, that file is opened. When @racket[filename] is @racket[#f], which is the
|
||||
default, an empty editor is opened.
|
||||
|
||||
@bold{Preconditions.} When supplied, @racket[filename] identifies the file to
|
||||
open. @racket[frame-cb] must accept two arguments: a lifecycle symbol and the
|
||||
editor frame. The geometry arguments specify valid dimensions and screen
|
||||
coordinates.
|
||||
|
||||
@bold{Postconditions.} An editor frame has been created and shown. When
|
||||
@racket[wait?] is @racket[#f], @racket[rkdt] returns after the frame has been
|
||||
shown and the @racket['after-show] callback has run. When @racket[wait?] is
|
||||
@racket[#t], @racket[rkdt] waits until the frame is closed.
|
||||
|
||||
@bold{Result.} The procedure returns @racket[(void)]. The editor frame itself is
|
||||
made available to @racket[frame-cb] during its lifecycle callbacks.
|
||||
|
||||
@bold{Internal workings.} A non-false @racket[filename] is converted to a
|
||||
string before it is supplied to the Framework editor frame. A false filename is
|
||||
passed through as @racket[#f], causing the frame to start without a file.
|
||||
|
||||
Each open editor receives an internal number. That
|
||||
number is appended to the window title and is used to distinguish stored window
|
||||
geometry. Numbers belonging to closed editors are reused. On close, the current
|
||||
position and size are stored for that internal number and the current screen
|
||||
configuration.
|
||||
|
||||
The @racket[#:width], @racket[#:height], @racket[#:x], and @racket[#:y]
|
||||
arguments specify the initial geometry for a window for which no stored geometry
|
||||
is available. When an editor window is closed, @tt{rackedit} stores its position
|
||||
and size. A later editor window with the same internal window number restores
|
||||
that geometry.
|
||||
arguments specify the initial geometry when no stored geometry is available.
|
||||
Stored geometry is associated with the screen configuration derived from the
|
||||
number and dimensions of the displays visible to Racket. Changing the monitor
|
||||
configuration therefore selects a different set of stored geometry values.
|
||||
|
||||
Stored geometry is associated with the current screen configuration. The screen
|
||||
configuration is derived from the number and dimensions of the displays visible
|
||||
to Racket. Consequently, changing the monitor configuration causes the default
|
||||
geometry, or geometry previously stored for that configuration, to be used.
|
||||
|
||||
If @racket[wait?] is @racket[#f], the procedure returns after the editor has
|
||||
been shown. If @racket[wait?] is @racket[#t], the current event handler waits
|
||||
until the editor window is closed before the procedure continues.
|
||||
|
||||
The @racket[frame-cb] procedure receives the editor frame. With the default
|
||||
@racket[#:wait?] value it is called after the frame has been shown and can be
|
||||
used to customize the frame, for example to change its title. When
|
||||
@racket[wait?] is @racket[#t], the callback is called only after the window has
|
||||
been closed. Its return value is ignored.
|
||||
|
||||
Each open editor has an internal number. That number is shown in the window
|
||||
title and is also used to distinguish stored window geometries. Numbers of
|
||||
closed editor windows are reused.
|
||||
The standard File menu does not contain the @onscreen{Exit} or
|
||||
@onscreen{Quit} command. Closing an editor window closes only that window.
|
||||
}
|
||||
|
||||
@section{Headless environments}
|
||||
|
||||
Loading @racketmodname[rackedit] does not initialize Racket's GUI subsystem.
|
||||
The GUI implementation is loaded dynamically only when @racket[rkdt] is
|
||||
actually called. This allows another package to depend on @tt{rackedit} and to
|
||||
be loaded in a headless process without immediately attempting to initialize
|
||||
GTK or connect to a graphical display.
|
||||
|
||||
Calling @racket[rkdt] itself still requires a usable graphical environment. A
|
||||
program that supports both graphical and terminal editors can therefore select
|
||||
a terminal editor before calling @racket[rkdt], while safely keeping
|
||||
@tt{rackedit} as a dependency.
|
||||
|
||||
@section{Frame callback lifecycle}
|
||||
|
||||
The procedure supplied with @racket[#:frame-cb] is called as
|
||||
@racket[(frame-cb call-time frame)]. Its return value is ignored. The
|
||||
@racket[call-time] argument has the following meanings.
|
||||
|
||||
@itemlist[
|
||||
@item{@racket['before-show] is called after the frame has been fully created,
|
||||
positioned, resized, numbered, and supplied with the callback, but before
|
||||
@racket[show] is called. This is the preferred point for changes that
|
||||
should already be visible when the window first appears, such as changing
|
||||
the title.}
|
||||
@item{@racket['after-show] is called immediately after @racket[show] has been
|
||||
called. It can be used for actions that require a shown frame.}
|
||||
@item{@racket['wait-for-close] is called only when @racket[#:wait? #t] is in
|
||||
effect, immediately before @racket[rkdt] starts waiting for the frame to
|
||||
close.}
|
||||
@item{@racket['on-close] is called while the frame's close event is being
|
||||
handled. At that point its geometry has been stored, its internal number
|
||||
has been released for reuse, and the close semaphore has been posted.}
|
||||
]
|
||||
|
||||
Thus, without waiting, the normal lifecycle is
|
||||
@racket['before-show], @racket['after-show], and eventually
|
||||
@racket['on-close]. With @racket[#:wait? #t], @racket['wait-for-close] occurs
|
||||
between @racket['after-show] and @racket['on-close].
|
||||
|
||||
@section{Examples}
|
||||
|
||||
The simplest use opens a file and returns immediately:
|
||||
The simplest use opens an empty editor and returns immediately:
|
||||
|
||||
@racketblock[
|
||||
(require rackedit)
|
||||
|
||||
(rkdt)
|
||||
]
|
||||
|
||||
Supply a filename to open a file:
|
||||
|
||||
@racketblock[
|
||||
(rkdt "notes.rkt")
|
||||
]
|
||||
|
||||
@@ -72,7 +127,7 @@ closed:
|
||||
(rkdt "notes.rkt" #:wait? #t)
|
||||
]
|
||||
|
||||
A frame callback can customize the editor frame:
|
||||
A frame callback can customize the editor before it becomes visible:
|
||||
|
||||
@racketblock[
|
||||
(require racket/class
|
||||
@@ -80,8 +135,30 @@ A frame callback can customize the editor frame:
|
||||
|
||||
(rkdt "notes.rkt"
|
||||
#:frame-cb
|
||||
(λ (frame)
|
||||
(send frame set-label "Notes")))
|
||||
(λ (call-time frame)
|
||||
(when (eq? call-time 'before-show)
|
||||
(send frame
|
||||
set-label
|
||||
(string-append (send frame get-label)
|
||||
" - Rash")))))
|
||||
]
|
||||
|
||||
The same callback can react to multiple lifecycle moments:
|
||||
|
||||
@racketblock[
|
||||
(rkdt "notes.rkt"
|
||||
#:wait? #t
|
||||
#:frame-cb
|
||||
(λ (call-time frame)
|
||||
(case call-time
|
||||
[(before-show)
|
||||
(displayln "Editor will be shown")]
|
||||
[(after-show)
|
||||
(displayln "Editor is shown")]
|
||||
[(wait-for-close)
|
||||
(displayln "Waiting for the editor to close")]
|
||||
[(on-close)
|
||||
(displayln "Editor is closing")])))
|
||||
]
|
||||
|
||||
The initial window geometry can be supplied explicitly:
|
||||
@@ -93,10 +170,3 @@ The initial window geometry can be supplied explicitly:
|
||||
#:x 50
|
||||
#:y 50)
|
||||
]
|
||||
|
||||
@section{Window behavior}
|
||||
|
||||
The editor uses Racket's standard editor menus, except that the standard
|
||||
@onscreen{Exit} or @onscreen{Quit} command is not added to the File menu.
|
||||
Closing an editor window closes only that window and releases its internal
|
||||
window number for reuse by a later editor window.
|
||||
|
||||
Reference in New Issue
Block a user