ghoetker
2018-5-28 19:11:06

I am working through creation of a GUI app and am stuck on a something hopefully simple. My goal is to display text (around 15 lines) that the user can copy, but not edit. A message% is non-editable, but also appears to be non-copyable. A text%, such as below, is copyable, but user-editable. Is their either (a) a third option or (b) a way to make a text% non-editable, while keeping its copyability? Thank you very much.

#lang racket/gui

(define f (new frame% [label "Simple Edit"]
                      [width 200]
                      [height 200]))
(define c (new editor-canvas% [parent f]))
(define t (new text%))
(send c set-editor t)
(send t insert "Money, get away\n")
(send t insert "Get a good job with more pay and you're okay\n")
(send f show #t)

spdegabrielle
2018-5-28 19:18:02

Quick question- why do some packages have a separate package for documentation? (Also separate -lib & -tests packages in some cases)


notjack
2018-5-28 19:35:55

@spdegabrielle to avoid test and doc build dependencies. I’d recommend against doing it though


shu--hung
2018-5-28 19:57:46

@ghoetker (send t lock #t) can lock edit operations. However, I can’t find how to make text% copy-able


shu--hung
2018-5-28 19:58:40

frame:text% seems to have implemented everything, but it is a frame.. #lang racket/gui (require framework) (define f (new frame:text% [width 200] [height 200])) (define c (send f get-editor)) (send c insert "Money, get away\n") (send c insert "Get a good job with more pay and you're okay\n") (send c lock #t) (send f show #t)


ghoetker
2018-5-28 21:20:59

@shu—hung Thank you very much. I had not found lock. A bit of experimenting showed me how to combine it with the ability to copy. Adding a menu with editor operations menu items (see below), provides the ability to copy a locked editor% with either the menu or Cmd-C (or Ctrl-C, depending on your platform.

In investigating lock, I came up with a related question. Section 5.9, Internal Editor Locks, of The Racket Graphical Interface Toolkit discusses three levels of internal locking, locked-for-write?, locked-for-flow? and locked-for-read?. I see how I can check is an editor is locked-for-write, etc. But, I’m not clear: are these states are something that I can set? If not, what determines the internal locking state of an editor?

#lang racket/gui


(define f (new frame% [label "Simple Edit"]
                      [width 200]
                      [height 200]))
(define c (new editor-canvas% [parent f]))
(define t (new text%))
(send c set-editor t)
(send t insert "Money, it's a gas\n")
(send t insert "Grab that cash with both hands and make a stash")
(send t lock #t)
(send f show #t)


(define mb (new menu-bar% [parent f]))
(define m-edit (new menu% [label "Edit"] [parent mb]))
(append-editor-operation-menu-items m-edit #f)

shu--hung
2018-5-28 21:31:35

@ghoetker I’m new to Racket GUI too. The doc of lock says > This method does not affect internal locks, as discussed in Internal Editor Locks. so I guess they are not related (maybe)?


philip.mcgrath
2018-5-28 22:53:53

I am very much not a GUI expert, but I develop an internal tool used by some of collaborators for which I wanted this feature. I also used lock in my initial implementation, but there were problems with that. (Unfortunately I don’t remember what they were.) The approach I found is to define a subclass of text% that augments the can-delete? and can-insert? methods. The overview in the docs (http://docs.racket-lang.org/gui/editor-overview.html\|docs.racket-lang.org/gui/editor-overview.html) talks a bit about this in the context of implementing an append-only editor.


philip.mcgrath
2018-5-28 22:59:00

@ghoetker Here a class that I use for this. It takes a string or list of strings for its content arg, inserts that during initialization, then forbids any insertion/deletion. I’m not sure everything I’ve done here is ideal, but it works. #lang racket/gui (define t% (class text% (init [content '()] [auto-wrap #t]) (super-new [auto-wrap auto-wrap]) (inherit insert begin-edit-sequence end-edit-sequence) (define initializing? #t) (begin-edit-sequence) (if (string? content) (insert content) (for ([str (in-list content)]) (insert str))) (end-edit-sequence) (scroll-editor-to-top this) (set! initializing? #f) (define/augment (can-delete? start len) #f) (define/augment (can-insert? start len) initializing?) #\|END t%\|#)) (define (scroll-editor-to-top ed) (let loop ([wait 1]) (cond [(send ed locked-for-flow?) (unless (> wait 5) (sleep wait) (loop (add1 wait)))] [else (send ed scroll-to-position 0)])))


ghoetker
2018-5-29 06:31:06

@philip.mcgrath Thank you. That code actually helps me with several issues I was facing. Much appreciated.