Skip to content

Commit 6588568

Browse files
committed
WIP: started adding max-paragraph-width
1 parent 77b93c0 commit 6588568

File tree

8 files changed

+235
-14
lines changed

8 files changed

+235
-14
lines changed

gui-doc/scribblings/framework/text.scrbl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,25 @@
352352
preference changes.
353353
}
354354

355+
@definterface[text:max-paragraph-width<%> ()]{
356+
357+
Text objects implementing this interface track the width of
358+
the widest line.
359+
360+
@defmethod[#:mode public-final (get-max-width-paragraph) natural?]{
361+
Returns the index of the widest paragraph, i.e. the value of
362+
@racket[para] that maximizes the expression
363+
@racketblock[(- (#,(method text% paragraph-end-position) para)
364+
(#,(method text% paragraph-start-position) para))]
365+
366+
}
367+
@history[#:added "1.78"]
368+
}
369+
370+
@defmixin[text:max-paragraph-width-mixin (text%) (text:max-paragraph-width<%>)]{
371+
@history[#:added "1.78"]
372+
}
373+
355374
@definterface[text:ascii-art-enlarge-boxes<%> ()]{
356375
@defmethod[(set-ascii-art-enlarge [e? any/c]) void?]{
357376
Enables or disables the ascii art box enlarging mode based on @racket[e?]'s true value.

gui-lib/framework/private/sig.rkt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
(open text-first-line^)
187187
(open text-inline-overview^)
188188
(open text-indent-guides^)
189+
(open text-max-width-paragraph^)
189190
(open text-mixed-in-classes^)))
190191

191192
(define-signature text^ extends text-class^

gui-lib/framework/private/text-inline-overview.rkt

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323

2424
(define-unit text-inline-overview@
2525
(import mred^
26-
[prefix color-prefs: framework:color-prefs^])
26+
[prefix color-prefs: framework:color-prefs^]
27+
[prefix text: text-max-width-paragraph^])
2728
(export text-inline-overview^)
29+
(init-depend text-max-width-paragraph^)
2830

2931
(define transparent-color (make-object color% 255 255 255 0))
3032
(define extra-blue-parts-margin 10)
@@ -35,8 +37,13 @@
3537
set-inline-overview-enabled?
3638
is-inline-overview-work-pending?
3739
))
38-
(define inline-overview-mixin
39-
(mixin ((class->interface text%)) (inline-overview<%>)
40+
41+
(define (inline-overview-mixin super%)
42+
(inline-overview-mpw-mixin
43+
(text:max-width-paragraph-mixin super%)))
44+
45+
(define inline-overview-mpw-mixin
46+
(mixin ((class->interface text%) text:max-width-paragraph<%>) (inline-overview<%>)
4047
(define is-do-a-little-work-enqueued? #f)
4148
(define invalid-start #f)
4249
(define invalid-end #f)
@@ -78,7 +85,7 @@
7885
(set! known-blank 0))
7986
(union-invalid 0 h)
8087
(maybe-queue-do-a-little-work?))
81-
88+
8289
(define/public (get-primary-bmp) primary-bmp)
8390
(define/public (get-secondary-bmp) secondary-bmp)
8491

@@ -92,6 +99,14 @@
9299
(inner (void) after-load-file success?)
93100
(set! loading-file? #f)
94101
(reset-entire-overview))
102+
103+
(define/augment (after-max-width-paragraph-change)
104+
(when enabled?
105+
;; avoid churn if someone is deleting, say, one
106+
;; character at a time from the widest line
107+
(unless (<= (abs (- (get-max-width-paragraph) bmp-width)) 10)
108+
(reset-entire-overview)))
109+
(inner (void) after-max-width-paragraph-change))
95110

96111
(define/augment (after-insert start len)
97112
(inner (void) after-insert start len)
@@ -411,7 +426,8 @@
411426
set-position
412427
scroll-editor-to
413428
begin-edit-sequence
414-
end-edit-sequence)
429+
end-edit-sequence
430+
get-max-width-paragraph)
415431

416432
(define/private (xy-to-paragraph x y)
417433
(position-paragraph (find-position x y)))
@@ -438,11 +454,8 @@
438454
(set! invalid-end #f))
439455

440456
(define/private (update-bmp-width ps pe)
441-
;; initialize this to `1` so that we always have a non-empty bitmap
442-
(define text-width 1)
443-
(for ([i (in-range ps (+ 1 pe))])
444-
(define w (- (paragraph-end-position i) (paragraph-start-position i)))
445-
(set! text-width (max text-width w)))
457+
;; use `max` to ensure that we always have a non-empty bitmap
458+
(define text-width (max 1 (get-max-width-paragraph)))
446459
(when (> text-width bmp-width)
447460
(set! bmp-width (min maximum-bitmap-width (+ 20 text-width))))
448461
(when (or (not scratch-string)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#lang racket/base
2+
3+
(require racket/class
4+
"sig.rkt"
5+
mred/mred-sig
6+
racket/unit
7+
"text-sig.rkt")
8+
9+
(provide text-max-width-paragraph@)
10+
11+
(define-unit text-max-width-paragraph@
12+
(import mred^
13+
text-basic^
14+
[prefix editor: framework:editor^]
15+
[prefix frame: framework:frame^])
16+
(export text-max-width-paragraph^)
17+
18+
(define max-width-paragraph<%>
19+
(interface ()
20+
get-max-width-paragraph
21+
after-max-width-paragraph-change))
22+
23+
(define max-width-paragraph-mixin
24+
(mixin ((class->interface text%)) (max-width-paragraph<%>)
25+
(inherit last-paragraph
26+
paragraph-end-position
27+
paragraph-start-position
28+
position-paragraph)
29+
30+
(define max-width-paragraph #f)
31+
(define max-width #f)
32+
33+
(define/public-final (get-max-width-paragraph)
34+
(unless max-width-paragraph
35+
(calc-max-width-paragraph))
36+
max-width-paragraph)
37+
38+
(define/private (set-max-widths _max-width-paragraph _max-width)
39+
(printf "set-max-widths\n")
40+
(set! max-width-paragraph _max-width-paragraph)
41+
(set! max-width _max-width)
42+
(after-max-width-paragraph-change))
43+
44+
(define/augment (after-insert start len)
45+
(inner (void) after-insert start len)
46+
(define insert-start-para (position-paragraph start))
47+
(define insert-end-para (position-paragraph (+ start len)))
48+
(when max-width-paragraph
49+
(cond
50+
[(< insert-start-para insert-end-para)
51+
;; multi-paragraph insertion, just give up on the cache
52+
(set-max-widths #f #f)]
53+
[(= insert-start-para max-width-paragraph)
54+
;; we made the max paragraph wider
55+
(set-max-widths insert-start-para (get-paragraph-width max-width-paragraph))]
56+
[else
57+
;; made some other paragraph wider
58+
(define paragraph-new-width (get-paragraph-width insert-start-para))
59+
;; if it got wider than the previous max one or the same but earlier
60+
;; in the file, it is the new widest
61+
(when (or (and (= max-width paragraph-new-width)
62+
(< insert-start-para max-width-paragraph))
63+
(< max-width paragraph-new-width))
64+
(set-max-widths insert-start-para
65+
paragraph-new-width))])))
66+
67+
(define/augment (on-delete start len)
68+
(inner (void) on-delete start len)
69+
(define delete-start-para (position-paragraph start))
70+
(define delete-end-para (position-paragraph (+ start len)))
71+
(when max-width-paragraph
72+
(cond
73+
[(< delete-start-para delete-end-para)
74+
;; multi-paragraph deletion, just give up on the cache
75+
(set-max-widths #f #f)]
76+
[(= delete-start-para max-width-paragraph)
77+
;; we made the max paragraph narrower
78+
(set-max-widths #f #f)]
79+
[else
80+
;; made some other paragraph narrower
81+
(void)])))
82+
83+
(define/private (get-paragraph-width para)
84+
(- (paragraph-end-position para)
85+
(paragraph-start-position para)))
86+
87+
(define/private (calc-max-width-paragraph)
88+
(set!-values
89+
(max-width max-width-paragraph)
90+
(for/fold ([width 0]
91+
[para-with-max-width 0])
92+
([this-para (in-inclusive-range 0 (last-paragraph))])
93+
(define this-width (get-paragraph-width this-para))
94+
(cond
95+
[(<= this-width width)
96+
(values width para-with-max-width)]
97+
[else
98+
(values this-width this-para)]))))
99+
100+
(define/pubment (after-max-width-paragraph-change)
101+
(inner (void) after-max-width-paragraph-change))
102+
(super-new))))

gui-lib/framework/private/text-sig.rkt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
text-column-guide^
1313
text-ascii-art^
1414
text-misc^
15+
text-max-width-paragraph^
1516
text-delegate^
1617
text-port^
1718
text-port-class^
@@ -95,7 +96,8 @@
9596

9697
(define-signature text-inline-overview^
9798
(inline-overview<%>
98-
inline-overview-mixin))
99+
inline-overview-mixin
100+
inline-overview-mpw-mixin))
99101

100102
(define-signature text-first-line^
101103
(first-line<%>
@@ -125,6 +127,10 @@
125127
overwrite-disable<%>
126128
overwrite-disable-mixin))
127129

130+
(define-signature text-max-width-paragraph^
131+
(max-width-paragraph-mixin
132+
max-width-paragraph<%>))
133+
128134
(define-signature text-mixed-in-classes^
129135
(basic%
130136
line-spacing%

gui-lib/framework/private/text.rkt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"text-port.rkt"
1717
"text-search.rkt"
1818
"text-inline-overview.rkt"
19+
"text-max-width-paragraph.rkt"
1920
"text-sig.rkt"
2021
"srcloc-snip.rkt"
2122
"sig.rkt")
@@ -48,14 +49,16 @@
4849
text-misc^
4950
text-normalize-paste^
5051
text-port^
51-
text-search^)
52+
text-search^
53+
text-max-width-paragraph^)
5254

5355
(link text-ascii-art@
5456
text-autocomplete@
5557
text-basic@
5658
text-column-guide@
5759
text-delegate@
5860
text-first-line@
61+
text-max-width-paragraph@
5962
text-inline-overview@
6063
text-line-numbers@
6164
text-indent-guides@
@@ -90,6 +93,7 @@
9093
text-line-numbers^
9194
text-indent-guides^
9295
text-misc^
96+
text-max-width-paragraph^
9397
text-normalize-paste^
9498
text-port^
9599
text-search^)

gui-lib/info.rkt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
(define pkg-authors '(mflatt robby))
3737

38-
(define version "1.77")
38+
(define version "1.78")
3939

4040
(define license
4141
'(Apache-2.0 OR MIT))

gui-test/framework/tests/text.rkt

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
(move/copy-to-edit-tests)
2121
(move/copy-to-edit-random-tests)
2222
(ascii-art-tests)
23-
(autocomplete-tests)))
23+
(autocomplete-tests)
24+
(get-max-width-paragraph-tests)))
2425

2526
(define (highlight-range-tests)
2627
(check-equal?
@@ -1147,3 +1148,78 @@
11471148
[key-code #\return]))
11481149

11491150
(check-equal? (send t get-text) "pqr abcd xyz"))
1151+
1152+
(define (get-max-width-paragraph-tests)
1153+
(struct ins (str pos) #:transparent)
1154+
1155+
(define (calc-widest t)
1156+
(define-values (widest-para widest-width)
1157+
(for/fold ([widest-para 0]
1158+
[widest-width 0])
1159+
([para (in-inclusive-range 0 (send t last-paragraph))])
1160+
(define this-width (- (send t paragraph-end-position para)
1161+
(send t paragraph-start-position para)))
1162+
(cond
1163+
[(<= this-width widest-width)
1164+
(values widest-para widest-width)]
1165+
[else
1166+
(values para this-width)])))
1167+
widest-para)
1168+
1169+
(define (try loins)
1170+
(define t (new (text:max-width-paragraph-mixin text:basic%)))
1171+
(for ([a-ins (in-list loins)])
1172+
(match-define (ins str pos) a-ins)
1173+
(send t insert str pos))
1174+
(define should-be (calc-widest t))
1175+
(define is (send t get-max-width-paragraph))
1176+
(unless (equal? should-be is)
1177+
(eprintf "test failed; got ~s expected ~s\n" is should-be)
1178+
(pretty-print loins (current-error-port))
1179+
(eprintf "~s\n" (send t get-text))))
1180+
1181+
(try '())
1182+
(try (list (ins "a" 0)))
1183+
(try (list (ins "a" 0)
1184+
(ins "\n" 0)
1185+
(ins "aa" 0)))
1186+
(try (list (ins "aaaa" 0)
1187+
(ins "\n" 0)
1188+
(ins "aa" 0)))
1189+
(try (list (ins "aaaa" 0)
1190+
(ins "\n" 4)
1191+
(ins "aa" 5)))
1192+
(try (list (ins "aaaa" 0)
1193+
(ins "\n" 4)
1194+
(ins "aa" 5)
1195+
(ins "a" 0)))
1196+
1197+
(define (mk)
1198+
(let loop ([s 0])
1199+
(cond
1200+
[(zero? (random 10)) '()]
1201+
[else
1202+
(define str
1203+
(make-string (+ (random 3) 1)
1204+
(case (random 4)
1205+
[(0) #\a]
1206+
[(1) #\b]
1207+
[(2) #\c]
1208+
[(3) #\newline])))
1209+
(cons (ins str (random (+ s 1)))
1210+
(loop (+ s (string-length str))))])))
1211+
1212+
(for ([i (in-range 100)])
1213+
(try (mk)))
1214+
1215+
(let ()
1216+
(define mw #f)
1217+
(define t (new (class (text:max-width-paragraph-mixin text:basic%)
1218+
(inherit get-max-width-paragraph)
1219+
(define/augment (after-max-width-paragraph-change)
1220+
(printf "called\n")
1221+
(set! mw (get-max-width-paragraph)))
1222+
(super-new))))
1223+
(send t insert "a")
1224+
(check-equal? mw 0))
1225+
)

0 commit comments

Comments
 (0)