macro-stepper: faster step rendering
- lazily build on-click mapping - more precise un-styling on refresh original commit: 199450dd0cacb2d8c3e5290b68d9b2d0aa1650fe
This commit is contained in:
parent
0cad27438d
commit
847c0c67a7
|
@ -3,6 +3,7 @@
|
||||||
racket/gui/base
|
racket/gui/base
|
||||||
racket/list
|
racket/list
|
||||||
racket/pretty
|
racket/pretty
|
||||||
|
racket/promise
|
||||||
data/interval-map
|
data/interval-map
|
||||||
framework
|
framework
|
||||||
unstable/class-iop
|
unstable/class-iop
|
||||||
|
@ -71,42 +72,68 @@
|
||||||
(define base-style
|
(define base-style
|
||||||
(code-style text (send/i config config<%> get-syntax-font-size)))
|
(code-style text (send/i config config<%> get-syntax-font-size)))
|
||||||
|
|
||||||
|
;; on-next-refresh : (listof (cons stx style-delta))
|
||||||
|
;; Styles to be applied on next refresh only. (eg, underline)
|
||||||
|
(define on-next-refresh null)
|
||||||
|
|
||||||
|
;; extra-styles : hash[stx => (listof style-delta)]
|
||||||
|
;; Styles to be re-applied on every refresh.
|
||||||
(define extra-styles (make-hasheq))
|
(define extra-styles (make-hasheq))
|
||||||
|
|
||||||
(define auto-refresh? #f) ;; FIXME: delete or make init arg
|
;; to-undo-styles : (listof (cons nat nat))
|
||||||
|
;; Ranges to unbold or unhighlight when selection changes.
|
||||||
|
;; FIXME: ought to be managed by text:region-data (to auto-update ranges)
|
||||||
|
;; until then, positions are relative
|
||||||
|
(define to-undo-styles null)
|
||||||
|
|
||||||
;; initialize : -> void
|
;; initialize : -> void
|
||||||
(define/private (initialize)
|
(define/private (initialize)
|
||||||
(uninterruptible
|
(uninterruptible
|
||||||
(send text change-style base-style start-position end-position #f))
|
(send text change-style base-style start-position end-position #f))
|
||||||
(uninterruptible (apply-primary-partition-styles))
|
(uninterruptible (apply-primary-partition-styles))
|
||||||
(uninterruptible (add-clickbacks))
|
(uninterruptible (add-clickbacks)))
|
||||||
(when auto-refresh? (refresh)))
|
|
||||||
|
|
||||||
;; add-clickbacks : -> void
|
;; add-clickbacks : -> void
|
||||||
(define/private (add-clickbacks)
|
(define/private (add-clickbacks)
|
||||||
(define mapping (send text get-region-mapping 'syntax))
|
(define mapping (send text get-region-mapping 'syntax))
|
||||||
(define (the-callback position)
|
(define lazy-interval-map-init
|
||||||
(send/i controller selection-manager<%> set-selected-syntax
|
(delay
|
||||||
(interval-map-ref mapping position #f)))
|
(uninterruptible
|
||||||
(for ([range (send/i range range<%> all-ranges)])
|
(for ([range (send/i range range<%> all-ranges)])
|
||||||
(let ([stx (range-obj range)]
|
(let ([stx (range-obj range)]
|
||||||
[start (range-start range)]
|
[start (range-start range)]
|
||||||
[end (range-end range)])
|
[end (range-end range)])
|
||||||
(interval-map-set! mapping (+ start-position start) (+ start-position end) stx)))
|
(interval-map-set! mapping (+ start-position start) (+ start-position end) stx))))))
|
||||||
|
(define (the-callback position)
|
||||||
|
(force lazy-interval-map-init)
|
||||||
|
(send/i controller selection-manager<%> set-selected-syntax
|
||||||
|
(interval-map-ref mapping position #f)))
|
||||||
(send text set-clickregion start-position end-position the-callback))
|
(send text set-clickregion start-position end-position the-callback))
|
||||||
|
|
||||||
;; refresh : -> void
|
;; refresh : -> void
|
||||||
;; Clears all highlighting and reapplies all non-foreground styles.
|
;; Clears all highlighting and reapplies all non-foreground styles.
|
||||||
(define/public (refresh)
|
(define/public (refresh)
|
||||||
(uninterruptible
|
|
||||||
(with-unlock text
|
(with-unlock text
|
||||||
(send text change-style (unhighlight-d) start-position end-position)
|
(uninterruptible
|
||||||
(apply-extra-styles)
|
(let ([undo-select/highlight-d (get-undo-select/highlight-d)])
|
||||||
|
(for ([r (in-list to-undo-styles)])
|
||||||
|
(send text change-style undo-select/highlight-d
|
||||||
|
(relative->text-position (car r))
|
||||||
|
(relative->text-position (cdr r)))))
|
||||||
|
(set! to-undo-styles null))
|
||||||
|
(uninterruptible
|
||||||
|
(for ([stx+delta (in-list on-next-refresh)])
|
||||||
|
(for ([r (in-list (send/i range range<%> get-ranges (car stx+delta)))])
|
||||||
|
(restyle-range r (cdr stx+delta) #f)))
|
||||||
|
(set! on-next-refresh null))
|
||||||
|
(uninterruptible
|
||||||
|
(apply-extra-styles))
|
||||||
(let ([selected-syntax
|
(let ([selected-syntax
|
||||||
(send/i controller selection-manager<%>
|
(send/i controller selection-manager<%>
|
||||||
get-selected-syntax)])
|
get-selected-syntax)])
|
||||||
(apply-secondary-relation-styles selected-syntax)
|
(uninterruptible
|
||||||
|
(apply-secondary-relation-styles selected-syntax))
|
||||||
|
(uninterruptible
|
||||||
(apply-selection-styles selected-syntax)))))
|
(apply-selection-styles selected-syntax)))))
|
||||||
|
|
||||||
;; get-range : -> range<%>
|
;; get-range : -> range<%>
|
||||||
|
@ -120,22 +147,16 @@
|
||||||
|
|
||||||
;; highlight-syntaxes : (list-of syntax) string -> void
|
;; highlight-syntaxes : (list-of syntax) string -> void
|
||||||
(define/public (highlight-syntaxes stxs hi-color)
|
(define/public (highlight-syntaxes stxs hi-color)
|
||||||
(let ([style-delta (highlight-style-delta hi-color #f)])
|
(let ([delta (highlight-style-delta hi-color)])
|
||||||
(for ([stx stxs])
|
(for ([stx (in-list stxs)])
|
||||||
(add-extra-styles stx (list style-delta))))
|
(hash-set! extra-styles stx
|
||||||
(when auto-refresh? (refresh)))
|
(cons delta (hash-ref extra-styles stx null))))))
|
||||||
|
|
||||||
;; underline-syntaxes : (listof syntax) -> void
|
;; underline-syntaxes : (listof syntax) -> void
|
||||||
(define/public (underline-syntaxes stxs)
|
(define/public (underline-syntaxes stxs)
|
||||||
(for ([stx stxs])
|
(for ([stx (in-list stxs)])
|
||||||
(add-extra-styles stx (list underline-style-delta)))
|
(set! on-next-refresh
|
||||||
(when auto-refresh? (refresh)))
|
(cons (cons stx underline-d) on-next-refresh))))
|
||||||
|
|
||||||
;; add-extra-styles : syntax (listof style) -> void
|
|
||||||
(define/public (add-extra-styles stx styles)
|
|
||||||
(hash-set! extra-styles stx
|
|
||||||
(append (hash-ref extra-styles stx null)
|
|
||||||
styles)))
|
|
||||||
|
|
||||||
;; Primary styles
|
;; Primary styles
|
||||||
;; (Done once on initialization, never repeated)
|
;; (Done once on initialization, never repeated)
|
||||||
|
@ -187,10 +208,16 @@
|
||||||
;; apply-extra-styles : -> void
|
;; apply-extra-styles : -> void
|
||||||
;; Applies externally-added styles (such as highlighting)
|
;; Applies externally-added styles (such as highlighting)
|
||||||
(define/private (apply-extra-styles)
|
(define/private (apply-extra-styles)
|
||||||
(for ([(stx style-deltas) extra-styles])
|
(for ([(stx deltas) (in-hash extra-styles)])
|
||||||
(for ([r (send/i range range<%> get-ranges stx)])
|
(for ([r (in-list (send/i range range<%> get-ranges stx))])
|
||||||
(for ([style-delta style-deltas])
|
(for ([delta (in-list deltas)])
|
||||||
(restyle-range r style-delta)))))
|
(restyle-range r delta #t)))))
|
||||||
|
|
||||||
|
;; apply-selection-styles : syntax -> void
|
||||||
|
;; Styles subterms eq to the selected syntax
|
||||||
|
(define/private (apply-selection-styles selected-syntax)
|
||||||
|
(for ([r (in-list (send/i range range<%> get-ranges selected-syntax))])
|
||||||
|
(restyle-range r select-d #t)))
|
||||||
|
|
||||||
;; apply-secondary-relation-styles : selected-syntax -> void
|
;; apply-secondary-relation-styles : selected-syntax -> void
|
||||||
;; If the selected syntax is an identifier, then styles all identifiers
|
;; If the selected syntax is an identifier, then styles all identifiers
|
||||||
|
@ -200,25 +227,17 @@
|
||||||
(let* ([name+relation
|
(let* ([name+relation
|
||||||
(send/i controller secondary-relation<%>
|
(send/i controller secondary-relation<%>
|
||||||
get-identifier=?)]
|
get-identifier=?)]
|
||||||
[relation (and name+relation (cdr name+relation))])
|
[relation (and name+relation (cdr name+relation))]
|
||||||
|
[secondary-highlight-d (get-secondary-highlight-d)])
|
||||||
(when relation
|
(when relation
|
||||||
(for ([id (send/i range range<%> get-identifier-list)])
|
(for ([id (in-list (send/i range range<%> get-identifier-list))])
|
||||||
(when (relation selected-syntax id)
|
(when (relation selected-syntax id)
|
||||||
(draw-secondary-connection id)))))))
|
(for ([r (in-list (send/i range range<%> get-ranges id))])
|
||||||
|
(restyle-range r secondary-highlight-d #t))))))))
|
||||||
|
|
||||||
;; apply-selection-styles : syntax -> void
|
;; restyle-range : (cons num num) style-delta% boolean -> void
|
||||||
;; Styles subterms eq to the selected syntax
|
(define/private (restyle-range r style need-undo?)
|
||||||
(define/private (apply-selection-styles selected-syntax)
|
(when need-undo? (set! to-undo-styles (cons r to-undo-styles)))
|
||||||
(for ([r (send/i range range<%> get-ranges selected-syntax)])
|
|
||||||
(restyle-range r (select-highlight-d))))
|
|
||||||
|
|
||||||
;; draw-secondary-connection : syntax -> void
|
|
||||||
(define/private (draw-secondary-connection stx2)
|
|
||||||
(for ([r (send/i range range<%> get-ranges stx2)])
|
|
||||||
(restyle-range r (select-sub-highlight-d))))
|
|
||||||
|
|
||||||
;; restyle-range : (cons num num) style-delta% -> void
|
|
||||||
(define/private (restyle-range r style)
|
|
||||||
(send text change-style style
|
(send text change-style style
|
||||||
(relative->text-position (car r))
|
(relative->text-position (car r))
|
||||||
(relative->text-position (cdr r))))
|
(relative->text-position (cdr r))))
|
||||||
|
@ -352,34 +371,38 @@
|
||||||
|
|
||||||
;; Styles
|
;; Styles
|
||||||
|
|
||||||
(define (highlight-style-delta raw-color em?
|
(define select-d
|
||||||
#:translate-color? [translate-color? #t])
|
(make-object style-delta% 'change-weight 'bold))
|
||||||
(let* ([sd (new style-delta%)])
|
|
||||||
(unless em?
|
(define underline-d
|
||||||
(send sd set-delta-background
|
(make-object style-delta% 'change-underline #t))
|
||||||
(if translate-color? (translate-color raw-color) raw-color)))
|
|
||||||
(when em? (send sd set-weight-on 'bold))
|
(define (highlight-style-delta raw-color #:translate-color? [translate-color? #t])
|
||||||
(unless em?
|
(let ([sd (new style-delta%)]
|
||||||
;; (send sd set-underlined-off #t)
|
[color (if translate-color? (translate-color raw-color) raw-color)])
|
||||||
(send sd set-weight-off 'bold))
|
(send sd set-delta-background color)
|
||||||
sd))
|
sd))
|
||||||
|
|
||||||
(define underline-style-delta
|
(define (mk-2-constant-style bow-color [wob-color (translate-color bow-color)])
|
||||||
(let ([sd (new style-delta%)])
|
(let ([wob-version (highlight-style-delta wob-color #:translate-color? #f)]
|
||||||
(send sd set-underlined-on #t)
|
[bow-version (highlight-style-delta bow-color #:translate-color? #f)])
|
||||||
sd))
|
|
||||||
|
|
||||||
(define (mk-2-constant-style bow-color em? [wob-color (translate-color bow-color)])
|
|
||||||
(let ([wob-version (highlight-style-delta wob-color em? #:translate-color? #f)]
|
|
||||||
[bow-version (highlight-style-delta bow-color em? #:translate-color? #f)])
|
|
||||||
(λ ()
|
(λ ()
|
||||||
(if (pref:invert-colors?)
|
(if (pref:invert-colors?)
|
||||||
wob-version
|
wob-version
|
||||||
bow-version))))
|
bow-version))))
|
||||||
|
|
||||||
(define select-highlight-d
|
(define get-secondary-highlight-d
|
||||||
(mk-2-constant-style "yellow" #t "darkgoldenrod"))
|
(mk-2-constant-style "yellow" "darkgoldenrod"))
|
||||||
(define select-sub-highlight-d
|
|
||||||
(mk-2-constant-style "yellow" #f "darkgoldenrod"))
|
|
||||||
|
|
||||||
(define unhighlight-d (mk-2-constant-style "white" #f #|"black"|#))
|
#|
|
||||||
|
(define undo-select-d
|
||||||
|
(make-object style-delta% 'change-weight 'normal))
|
||||||
|
(define get-undo-highlight-d
|
||||||
|
(mk-2-constant-style "white" "black"))
|
||||||
|
|#
|
||||||
|
|
||||||
|
(define (get-undo-select/highlight-d)
|
||||||
|
(let ([sd (make-object style-delta% 'change-weight 'normal)]
|
||||||
|
[bg (if (pref:invert-colors?) "black" "white")])
|
||||||
|
(send sd set-delta-background bg)
|
||||||
|
sd))
|
||||||
|
|
|
@ -67,6 +67,12 @@
|
||||||
(send dc set-text-background old-background)
|
(send dc set-text-background old-background)
|
||||||
(send dc set-text-mode old-mode))))
|
(send dc set-text-mode old-mode))))
|
||||||
|
|
||||||
|
;; Interfaces
|
||||||
|
|
||||||
|
(define text:region-data<%>
|
||||||
|
(interface (text:basic<%>)
|
||||||
|
get-region-mapping))
|
||||||
|
|
||||||
(define text:hover<%>
|
(define text:hover<%>
|
||||||
(interface (text:basic<%>)
|
(interface (text:basic<%>)
|
||||||
update-hover-position))
|
update-hover-position))
|
||||||
|
@ -74,8 +80,7 @@
|
||||||
(define text:hover-drawings<%>
|
(define text:hover-drawings<%>
|
||||||
(interface (text:basic<%>)
|
(interface (text:basic<%>)
|
||||||
add-hover-drawing
|
add-hover-drawing
|
||||||
get-position-drawings
|
get-position-drawings))
|
||||||
delete-all-drawings))
|
|
||||||
|
|
||||||
(define text:arrows<%>
|
(define text:arrows<%>
|
||||||
(interface (text:hover-drawings<%>)
|
(interface (text:hover-drawings<%>)
|
||||||
|
@ -83,9 +88,27 @@
|
||||||
add-question-arrow
|
add-question-arrow
|
||||||
add-billboard))
|
add-billboard))
|
||||||
|
|
||||||
(define text:region-data<%>
|
;; Mixins
|
||||||
(interface (text:basic<%>)
|
|
||||||
get-region-mapping))
|
(define text:region-data-mixin
|
||||||
|
(mixin (text:basic<%>) (text:region-data<%>)
|
||||||
|
|
||||||
|
(define table (make-hasheq))
|
||||||
|
|
||||||
|
(define/public (get-region-mapping key)
|
||||||
|
(hash-ref! table key (lambda () (make-interval-map))))
|
||||||
|
|
||||||
|
(define/augment (after-delete start len)
|
||||||
|
(for ([im (in-hash-values table)])
|
||||||
|
(interval-map-contract! im start (+ start len)))
|
||||||
|
(inner (void) after-delete))
|
||||||
|
|
||||||
|
(define/augment (after-insert start len)
|
||||||
|
(for ([im (in-hash-values table)])
|
||||||
|
(interval-map-expand! im start (+ start len)))
|
||||||
|
(inner (void) after-insert))
|
||||||
|
|
||||||
|
(super-new)))
|
||||||
|
|
||||||
(define text:hover-mixin
|
(define text:hover-mixin
|
||||||
(mixin (text:basic<%>) (text:hover<%>)
|
(mixin (text:basic<%>) (text:hover<%>)
|
||||||
|
@ -108,13 +131,15 @@
|
||||||
(super-new)))
|
(super-new)))
|
||||||
|
|
||||||
(define text:hover-drawings-mixin
|
(define text:hover-drawings-mixin
|
||||||
(mixin (text:hover<%>) (text:hover-drawings<%>)
|
(mixin (text:hover<%> text:region-data<%>) (text:hover-drawings<%>)
|
||||||
(inherit dc-location-to-editor-location
|
(inherit dc-location-to-editor-location
|
||||||
find-position
|
find-position
|
||||||
invalidate-bitmap-cache)
|
invalidate-bitmap-cache
|
||||||
|
get-region-mapping)
|
||||||
|
(super-new)
|
||||||
|
|
||||||
;; interval-map of Drawings
|
;; interval-map of Drawings
|
||||||
(define drawings-list (make-interval-map))
|
(define drawings-list (get-region-mapping 'hover-drawings))
|
||||||
|
|
||||||
(field [hover-position #f])
|
(field [hover-position #f])
|
||||||
|
|
||||||
|
@ -132,9 +157,6 @@
|
||||||
drawing
|
drawing
|
||||||
null)))
|
null)))
|
||||||
|
|
||||||
(define/public (delete-all-drawings)
|
|
||||||
(interval-map-remove! drawings-list -inf.0 +inf.0))
|
|
||||||
|
|
||||||
(define/override (on-paint before? dc left top right bottom dx dy draw-caret)
|
(define/override (on-paint before? dc left top right bottom dx dy draw-caret)
|
||||||
(super on-paint before? dc left top right bottom dx dy draw-caret)
|
(super on-paint before? dc left top right bottom dx dy draw-caret)
|
||||||
(unless before?
|
(unless before?
|
||||||
|
@ -147,9 +169,7 @@
|
||||||
(define/private (same-drawings? old-pos pos)
|
(define/private (same-drawings? old-pos pos)
|
||||||
;; relies on order drawings added & list-of-eq?-struct equality
|
;; relies on order drawings added & list-of-eq?-struct equality
|
||||||
(equal? (get-position-drawings old-pos)
|
(equal? (get-position-drawings old-pos)
|
||||||
(get-position-drawings pos)))
|
(get-position-drawings pos)))))
|
||||||
|
|
||||||
(super-new)))
|
|
||||||
|
|
||||||
(define text:tacking-mixin
|
(define text:tacking-mixin
|
||||||
(mixin (text:basic<%> text:hover-drawings<%>) ()
|
(mixin (text:basic<%> text:hover-drawings<%>) ()
|
||||||
|
@ -303,28 +323,6 @@
|
||||||
|
|
||||||
(super-new)))
|
(super-new)))
|
||||||
|
|
||||||
(define text:region-data-mixin
|
|
||||||
(mixin (text:basic<%>) (text:region-data<%>)
|
|
||||||
|
|
||||||
(define table (make-hasheq))
|
|
||||||
|
|
||||||
(define/public (get-region-mapping key)
|
|
||||||
(hash-ref! table key (lambda () (make-interval-map))))
|
|
||||||
|
|
||||||
(define/augment (after-delete start len)
|
|
||||||
(for ([im (in-hash-values table)])
|
|
||||||
(interval-map-contract! im start (+ start len)))
|
|
||||||
(inner (void) after-delete))
|
|
||||||
|
|
||||||
(define/augment (after-insert start len)
|
|
||||||
(for ([im (in-hash-values table)])
|
|
||||||
(interval-map-expand! im start (+ start len)))
|
|
||||||
(inner (void) after-insert))
|
|
||||||
|
|
||||||
(super-new)))
|
|
||||||
|
|
||||||
(define clickregion-key (gensym 'text:clickregion))
|
|
||||||
|
|
||||||
#|
|
#|
|
||||||
text:clickregion-mixin
|
text:clickregion-mixin
|
||||||
|
|
||||||
|
@ -335,7 +333,6 @@ Like clickbacks, but:
|
||||||
- different rules for removal
|
- different rules for removal
|
||||||
- TODO: extend to double-click
|
- TODO: extend to double-click
|
||||||
|#
|
|#
|
||||||
|
|
||||||
(define text:clickregion-mixin
|
(define text:clickregion-mixin
|
||||||
(mixin (text:region-data<%>) ()
|
(mixin (text:region-data<%>) ()
|
||||||
(inherit get-admin
|
(inherit get-admin
|
||||||
|
@ -344,7 +341,7 @@ Like clickbacks, but:
|
||||||
find-position)
|
find-position)
|
||||||
|
|
||||||
(super-new)
|
(super-new)
|
||||||
(define clickbacks (get-region-mapping clickregion-key))
|
(define clickbacks (get-region-mapping 'clickregion))
|
||||||
(define tracking #f)
|
(define tracking #f)
|
||||||
|
|
||||||
(define/public (set-clickregion start end callback)
|
(define/public (set-clickregion start end callback)
|
||||||
|
|
|
@ -203,8 +203,7 @@
|
||||||
|
|
||||||
(define/public (erase-all)
|
(define/public (erase-all)
|
||||||
(with-unlock -text
|
(with-unlock -text
|
||||||
(send -text erase)
|
(send -text erase))
|
||||||
(send -text delete-all-drawings))
|
|
||||||
(send/i controller displays-manager<%> remove-all-syntax-displays))
|
(send/i controller displays-manager<%> remove-all-syntax-displays))
|
||||||
|
|
||||||
(define/public (get-text) -text)
|
(define/public (get-text) -text)
|
||||||
|
@ -245,11 +244,11 @@
|
||||||
(define browser-text%
|
(define browser-text%
|
||||||
(let ([browser-text-default-style-name "widget.rkt::browser-text% basic"])
|
(let ([browser-text-default-style-name "widget.rkt::browser-text% basic"])
|
||||||
(class (text:clickregion-mixin
|
(class (text:clickregion-mixin
|
||||||
(text:region-data-mixin
|
|
||||||
(text:arrows-mixin
|
(text:arrows-mixin
|
||||||
(text:tacking-mixin
|
(text:tacking-mixin
|
||||||
(text:hover-drawings-mixin
|
(text:hover-drawings-mixin
|
||||||
(text:hover-mixin
|
(text:hover-mixin
|
||||||
|
(text:region-data-mixin
|
||||||
(text:hide-caret/selection-mixin
|
(text:hide-caret/selection-mixin
|
||||||
(text:foreground-color-mixin
|
(text:foreground-color-mixin
|
||||||
(editor:standard-style-list-mixin text:basic%)))))))))
|
(editor:standard-style-list-mixin text:basic%)))))))))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user