diff --git a/collects/drscheme/acks.ss b/collects/drscheme/acks.ss index d0fa090ad0..eafbfb9dbd 100644 --- a/collects/drscheme/acks.ss +++ b/collects/drscheme/acks.ss @@ -1,84 +1,85 @@ -(module acks mzscheme - (provide get-general-acks - get-translating-acks - get-authors) - - (define (get-authors) - (get-general-acks)) - - (define (get-general-acks) - (string-append - "The following individuals contributed to the implementation" - " and documentation of PLT Scheme: " - "Yavuz Arkun, " - "Ian Barland, " - "Eli Barzilay, " - "Gann Bierner, " - "Filipe Cabecinhas, " - "Richard Cleis, " - "John Clements, " - "Richard Cobbe, " - "Greg Cooper, " - "Ryan Culpepper, " - "Carl Eastlund, " - "Moy Easwaran, " - "Will Farr, " - "Matthias Felleisen, " - "Robby Findler, " - "Kathi Fisler, " - "Cormac Flanagan, " - "Matthew Flatt, " - "Sebastian Good, " - "Paul Graunke, " - "Kathy Gray, " - "Dan Grossman, " - "Dave Gurnell, " - "Bruce Hauman, " - "Dave Herman, " - "Geoffrey S. Knauth, " - "Mark Krentel, " - "Shriram Krishnamurthi, " - "Mario Latendresse, " - "Guillaume Marceau, " - "Jacob Matthews, " - "Jay McCarthy, " - "Mike T. McHenry, " - "Philippe Meunier, " - "Scott Owens, " - "Jamie Raymond, " - "Grant Rettke, " - "Paul Schlie, " - "Dorai Sitaram, " - "Mike Sperber, " - "Paul Steckler, " - "Jens Axel Søgaard, " - "Francisco Solsona, " - "Sam Tobin-Hochstadt, " - "Neil W. Van Dyke, " - "David Van Horn, " - "Anton van Straaten, " - "Dale Vaillancourt, " - "Dimitris Vyzovitis, " - "Stephanie Weirich, " - "Noel Welsh, " - "Adam Wick, " - "Danny Yoo, " - "and " - "ChongKai Zhu.")) +#lang scheme/base - (define (get-translating-acks) - (string-append - "Thanks to " - "ChongKai Zhu, " - "Ian Barland, " - "Biep Durieux, " - "Tim Hanson, " - "Chihiro Kuraya, " - "Philippe Meunier, " - "Jens Axel Søgaard, " - "Francisco Solsona, " - "Mike Sperber, " - "Reini Urban, " - "and " - "Paolo Zoppetti " - "for their help translating DrScheme's GUI to other languages."))) +(provide get-general-acks + get-translating-acks + get-authors) + +(define (get-authors) + (get-general-acks)) + +(define (get-general-acks) + (string-append + "The following individuals contributed to the implementation" + " and documentation of PLT Scheme: " + "Yavuz Arkun, " + "Ian Barland, " + "Eli Barzilay, " + "Gann Bierner, " + "Filipe Cabecinhas, " + "Richard Cleis, " + "John Clements, " + "Richard Cobbe, " + "Greg Cooper, " + "Ryan Culpepper, " + "Carl Eastlund, " + "Moy Easwaran, " + "Will Farr, " + "Matthias Felleisen, " + "Robby Findler, " + "Kathi Fisler, " + "Cormac Flanagan, " + "Matthew Flatt, " + "Sebastian Good, " + "Paul Graunke, " + "Kathy Gray, " + "Dan Grossman, " + "Dave Gurnell, " + "Bruce Hauman, " + "Dave Herman, " + "Geoffrey S. Knauth, " + "Mark Krentel, " + "Shriram Krishnamurthi, " + "Mario Latendresse, " + "Guillaume Marceau, " + "Jacob Matthews, " + "Jay McCarthy, " + "Mike T. McHenry, " + "Philippe Meunier, " + "Scott Owens, " + "Jamie Raymond, " + "Grant Rettke, " + "Paul Schlie, " + "Dorai Sitaram, " + "Mike Sperber, " + "Paul Steckler, " + "Jens Axel Søgaard, " + "Francisco Solsona, " + "Sam Tobin-Hochstadt, " + "Neil W. Van Dyke, " + "David Van Horn, " + "Anton van Straaten, " + "Dale Vaillancourt, " + "Dimitris Vyzovitis, " + "Stephanie Weirich, " + "Noel Welsh, " + "Adam Wick, " + "Danny Yoo, " + "and " + "ChongKai Zhu.")) + +(define (get-translating-acks) + (string-append + "Thanks to " + "ChongKai Zhu, " + "Ian Barland, " + "Biep Durieux, " + "Tim Hanson, " + "Chihiro Kuraya, " + "Philippe Meunier, " + "Jens Axel Søgaard, " + "Francisco Solsona, " + "Mike Sperber, " + "Reini Urban, " + "and " + "Paolo Zoppetti " + "for their help translating DrScheme's GUI to other languages.")) diff --git a/collects/drscheme/arrow.ss b/collects/drscheme/arrow.ss index 64501ef4ee..3c27480bce 100644 --- a/collects/drscheme/arrow.ss +++ b/collects/drscheme/arrow.ss @@ -1,195 +1,194 @@ +#lang scheme/base -(module arrow mzscheme - (require mzlib/class - mzlib/list - mzlib/math - mred) - - (provide draw-arrow) - - (define largest 16383) - (define smallest -16383) - - (define arrow-head-angle (/ pi 8)) - (define cos-arrow-head-angle (cos arrow-head-angle)) - (define sin-arrow-head-angle (sin arrow-head-angle)) - - (define arrow-head-size 8) - (define arrow-head-size-cos-arrow-head-angle (* arrow-head-size cos-arrow-head-angle)) - (define arrow-head-size-sin-arrow-head-angle (* arrow-head-size sin-arrow-head-angle)) - - (define arrow-root-radius 2.5) - (define arrow-root-diameter (* 2 arrow-root-radius)) - - ; If alpha is the angle between the x axis and the Start->End vector: - ; - ; p2-x = end-x + arrow-head-size * cos(alpha + pi - arrow-head-angle) - ; = end-x - arrow-head-size * cos(alpha - arrow-head-angle) - ; = end-x - arrow-head-size * (cos(alpha) * cos(arrow-head-angle) + sin(alpha) * sin(arrow-head-angle)) - ; = end-x - arrow-head-size-cos-arrow-head-angle * cos-alpha - arrow-head-size-sin-arrow-head-angle * sin-alpha - ; = end-x - arrow-head-size-cos-arrow-head-angle-cos-alpha - arrow-head-size-sin-arrow-head-angle-sin-alpha - ; - ; p2-y = end-y + arrow-head-size * sin(alpha + pi - arrow-head-angle) - ; = end-y - arrow-head-size * sin(alpha - arrow-head-angle) - ; = end-y - arrow-head-size * (sin(alpha) * cos(arrow-head-angle) - cos(alpha) * sin(arrow-head-angle)) - ; = end-y - arrow-head-size-cos-arrow-head-angle * sin-alpha + arrow-head-size-sin-arrow-head-angle * cos-alpha - ; = end-y - arrow-head-size-cos-arrow-head-angle-sin-alpha + arrow-head-size-sin-arrow-head-angle-cos-alpha - ; - ; p3-x = end-x + arrow-head-size * cos(alpha + pi + arrow-head-angle) - ; = end-x - arrow-head-size * cos(alpha + arrow-head-angle) - ; = end-x - arrow-head-size * (cos(alpha) * cos(arrow-head-angle) - sin(alpha) * sin(arrow-head-angle)) - ; = end-x - arrow-head-size-cos-arrow-head-angle * cos-alpha + arrow-head-size-sin-arrow-head-angle * sin-alpha - ; = end-x - arrow-head-size-cos-arrow-head-angle-cos-alpha + arrow-head-size-sin-arrow-head-angle-sin-alpha - ; - ; p3-y = end-y + arrow-head-size * sin(alpha + pi + arrow-head-angle) - ; = end-y - arrow-head-size * sin(alpha + arrow-head-angle) - ; = end-y - arrow-head-size * (sin(alpha) * cos(arrow-head-angle) + cos(alpha) * sin(arrow-head-angle)) - ; = end-y - arrow-head-size-cos-arrow-head-angle * sin-alpha - arrow-head-size-sin-arrow-head-angle * cos-alpha - ; = end-y - arrow-head-size-cos-arrow-head-angle-sin-alpha - arrow-head-size-sin-arrow-head-angle-cos-alpha - - ; dc<%> real real real real real real -> void - ; draw one arrow - ; The reason of the "-0.5" in the definition of start-x and end-x in the let - ; right below is because, well, after numerous experiments done under carefully - ; controlled conditions by a team of independent experts, it was thought to - ; be The Right Thing for the arrows to be drawn correctly, maybe. - (define (draw-arrow dc uncropped-pre-start-x uncropped-pre-start-y uncropped-pre-end-x uncropped-pre-end-y dx dy) - (let ([uncropped-start-x (+ uncropped-pre-start-x dx -0.5)] - [uncropped-start-y (+ uncropped-pre-start-y dy)] - [uncropped-end-x (+ uncropped-pre-end-x dx -0.5)] - [uncropped-end-y (+ uncropped-pre-end-y dy)] - [old-smoothed (send dc get-smoothing)]) - (let*-values ([(start-x start-y) (crop-to uncropped-start-x uncropped-start-y uncropped-end-x uncropped-end-y)] - [(end-x end-y) (crop-to uncropped-end-x uncropped-end-y uncropped-start-x uncropped-start-y)]) - (send dc set-smoothing 'aligned) - (send dc draw-line start-x start-y end-x end-y) - (when (and (< smallest start-x largest) - (< smallest end-x largest)) - (send dc draw-ellipse - (- start-x arrow-root-radius) (- start-y arrow-root-radius) - arrow-root-diameter arrow-root-diameter)) - (when (and (< smallest end-x largest) - (< smallest end-y largest)) - (unless (and (= start-x end-x) (= start-y end-y)) - (let* ([offset-x (- end-x start-x)] - [offset-y (- end-y start-y)] - [arrow-length (sqrt (+ (* offset-x offset-x) (* offset-y offset-y)))] - [cos-alpha (/ offset-x arrow-length)] - [sin-alpha (/ offset-y arrow-length)] - [arrow-head-size-cos-arrow-head-angle-cos-alpha (* arrow-head-size-cos-arrow-head-angle cos-alpha)] - [arrow-head-size-cos-arrow-head-angle-sin-alpha (* arrow-head-size-cos-arrow-head-angle sin-alpha)] - [arrow-head-size-sin-arrow-head-angle-cos-alpha (* arrow-head-size-sin-arrow-head-angle cos-alpha)] - [arrow-head-size-sin-arrow-head-angle-sin-alpha (* arrow-head-size-sin-arrow-head-angle sin-alpha)] - ; pt1 is the tip of the arrow, pt2 is the first point going clockwise from pt1 - [pt1 (make-object point% end-x end-y)] - [pt2 (make-object point% - (- end-x arrow-head-size-cos-arrow-head-angle-cos-alpha arrow-head-size-sin-arrow-head-angle-sin-alpha) - (+ end-y (- arrow-head-size-cos-arrow-head-angle-sin-alpha) arrow-head-size-sin-arrow-head-angle-cos-alpha))] - [pt3 (make-object point% - (+ end-x (- arrow-head-size-cos-arrow-head-angle-cos-alpha) arrow-head-size-sin-arrow-head-angle-sin-alpha) - (- end-y arrow-head-size-cos-arrow-head-angle-sin-alpha arrow-head-size-sin-arrow-head-angle-cos-alpha))]) - (send dc draw-polygon (list pt1 pt2 pt3))))) - (send dc set-smoothing old-smoothed)))) - - ;; crop-to : number number number number -> (values number number) - ;; returns x,y if they are in the range defined by largest and smallest - ;; otherwise returns the coordinates on the line from x,y to ox,oy - ;; that are closest to x,y and are in the range specified by - ;; largest and smallest - (define (crop-to x y ox oy) - (cond - [(and (< smallest x largest) (< smallest y largest)) - (values x y)] - [else - (let* ([xy-pr (cons x y)] - [left-i (find-intersection x y ox oy smallest smallest smallest largest)] - [top-i (find-intersection x y ox oy smallest smallest largest smallest)] - [right-i (find-intersection x y ox oy largest smallest largest largest)] - [bottom-i (find-intersection x y ox oy smallest largest largest largest)] - [d-top (and top-i (dist top-i xy-pr))] - [d-bottom (and bottom-i (dist bottom-i xy-pr))] - [d-left (and left-i (dist left-i xy-pr))] - [d-right (and right-i (dist right-i xy-pr))]) - (cond - [(smallest? d-top d-bottom d-left d-right) - (values (car top-i) (cdr top-i))] - [(smallest? d-bottom d-top d-left d-right) - (values (car bottom-i) (cdr bottom-i))] - [(smallest? d-left d-top d-bottom d-right) - (values (car left-i) (cdr left-i))] - [(smallest? d-right d-top d-bottom d-left) - (values (car right-i) (cdr right-i))] - [else - ;; uh oh... if this case happens, that's bad news... - (values x y)]))])) - - ;; smallest? : (union #f number)^4 -> boolean - ;; returns #t if can is less and o1, o2, and o3 - ;; if can is #f, return #f. If o1, o2, or o3 is #f, assume that can is smaller than them - (define (smallest? can o1 o2 o3) - (and can - (andmap (λ (x) (< can x)) - (filter (λ (x) x) - (list o1 o2 o3))))) - - - ;; inside? : (union #f (cons number number)) -> (union #f (cons number number)) - ;; returns the original pair if the coordinates are between smallest and largest - ;; and returns #f if the pair is #f or the coordinates are outside. - (define (inside? pr) - (and pr - (let ([x (car pr)] - [y (cdr pr)]) - (if (and (< smallest x largest) - (< smallest y largest)) - pr - #f)))) - - ;; find-intersection : (number^2)^2 -> (union (cons number number) #f) - ;; finds the intersection between the lines specified by - ;; (x1,y1) -> (x2,y2) and (x3,y3) -> (x4,y4) - (define (find-intersection x1 y1 x2 y2 x3 y3 x4 y4) - (cond - [(and (= x1 x2) (= x3 x4)) - #f] - [(and (= x1 x2) (not (= x3 x4))) - (let* ([m2 (/ (- y3 y4) (- x3 x4))] - [b2 (- y3 (* m2 x3))]) - (cons x1 - (+ (* m2 x1) b2)))] - [(and (not (= x1 x2)) (= x3 x4)) - (let* ([m1 (/ (- y1 y2) (- x1 x2))] - [b1 (- y1 (* m1 x1))]) - (cons x3 - (+ (* m1 x3) b1)))] - [(and (not (= x1 x2)) (not (= x3 x4))) - (let* ([m1 (/ (- y1 y2) (- x1 x2))] - [b1 (- y1 (* m1 x1))] - [m2 (/ (- y3 y4) (- x3 x4))] - [b2 (- y3 (* m2 x3))]) - (if (= m1 m2) - #f - (let* ([x (/ (- b1 b2) (- m2 m1))] - [y (+ (* m1 x) b1)]) - (cons x y))))])) - - ;; dist : (cons number number) (cons number number) -> number - (define (dist p1 p2) - (sqrt (+ (sqr (- (car p1) (car p2))) - (sqr (- (cdr p1) (cdr p2)))))) - - ;; localled defined test code.... :( - ;; use module language to run tests - (define (tests) - (and (equal? (find-intersection 0 1 0 10 0 2 0 20) #f) - (equal? (find-intersection 0 1 0 10 0 0 10 10) (cons 0 0)) - (equal? (find-intersection 0 0 10 10 0 1 0 10) (cons 0 0)) - (equal? (find-intersection 0 0 3 3 2 2 4 4) #f) - (equal? (find-intersection -3 3 3 -3 -3 -3 3 3) (cons 0 0)) - (equal? (smallest? 3 1 2 3) #f) - (equal? (smallest? 0 1 2 3) #t) - (equal? (smallest? 1 0 2 3) #f) - (equal? (smallest? 1 0 #f 4) #f) - (equal? (smallest? 1 #f #f 4) #t) - (equal? (smallest? 1 #f #f #f) #t) - (equal? (dist (cons 1 1) (cons 4 5)) 5)))) +(require scheme/class + scheme/math + scheme/gui/base) + +(provide draw-arrow) + +(define largest 16383) +(define smallest -16383) + +(define arrow-head-angle (/ pi 8)) +(define cos-arrow-head-angle (cos arrow-head-angle)) +(define sin-arrow-head-angle (sin arrow-head-angle)) + +(define arrow-head-size 8) +(define arrow-head-size-cos-arrow-head-angle (* arrow-head-size cos-arrow-head-angle)) +(define arrow-head-size-sin-arrow-head-angle (* arrow-head-size sin-arrow-head-angle)) + +(define arrow-root-radius 2.5) +(define arrow-root-diameter (* 2 arrow-root-radius)) + +; If alpha is the angle between the x axis and the Start->End vector: +; +; p2-x = end-x + arrow-head-size * cos(alpha + pi - arrow-head-angle) +; = end-x - arrow-head-size * cos(alpha - arrow-head-angle) +; = end-x - arrow-head-size * (cos(alpha) * cos(arrow-head-angle) + sin(alpha) * sin(arrow-head-angle)) +; = end-x - arrow-head-size-cos-arrow-head-angle * cos-alpha - arrow-head-size-sin-arrow-head-angle * sin-alpha +; = end-x - arrow-head-size-cos-arrow-head-angle-cos-alpha - arrow-head-size-sin-arrow-head-angle-sin-alpha +; +; p2-y = end-y + arrow-head-size * sin(alpha + pi - arrow-head-angle) +; = end-y - arrow-head-size * sin(alpha - arrow-head-angle) +; = end-y - arrow-head-size * (sin(alpha) * cos(arrow-head-angle) - cos(alpha) * sin(arrow-head-angle)) +; = end-y - arrow-head-size-cos-arrow-head-angle * sin-alpha + arrow-head-size-sin-arrow-head-angle * cos-alpha +; = end-y - arrow-head-size-cos-arrow-head-angle-sin-alpha + arrow-head-size-sin-arrow-head-angle-cos-alpha +; +; p3-x = end-x + arrow-head-size * cos(alpha + pi + arrow-head-angle) +; = end-x - arrow-head-size * cos(alpha + arrow-head-angle) +; = end-x - arrow-head-size * (cos(alpha) * cos(arrow-head-angle) - sin(alpha) * sin(arrow-head-angle)) +; = end-x - arrow-head-size-cos-arrow-head-angle * cos-alpha + arrow-head-size-sin-arrow-head-angle * sin-alpha +; = end-x - arrow-head-size-cos-arrow-head-angle-cos-alpha + arrow-head-size-sin-arrow-head-angle-sin-alpha +; +; p3-y = end-y + arrow-head-size * sin(alpha + pi + arrow-head-angle) +; = end-y - arrow-head-size * sin(alpha + arrow-head-angle) +; = end-y - arrow-head-size * (sin(alpha) * cos(arrow-head-angle) + cos(alpha) * sin(arrow-head-angle)) +; = end-y - arrow-head-size-cos-arrow-head-angle * sin-alpha - arrow-head-size-sin-arrow-head-angle * cos-alpha +; = end-y - arrow-head-size-cos-arrow-head-angle-sin-alpha - arrow-head-size-sin-arrow-head-angle-cos-alpha + +; dc<%> real real real real real real -> void +; draw one arrow +; The reason of the "-0.5" in the definition of start-x and end-x in the let +; right below is because, well, after numerous experiments done under carefully +; controlled conditions by a team of independent experts, it was thought to +; be The Right Thing for the arrows to be drawn correctly, maybe. +(define (draw-arrow dc uncropped-pre-start-x uncropped-pre-start-y uncropped-pre-end-x uncropped-pre-end-y dx dy) + (let ([uncropped-start-x (+ uncropped-pre-start-x dx -0.5)] + [uncropped-start-y (+ uncropped-pre-start-y dy)] + [uncropped-end-x (+ uncropped-pre-end-x dx -0.5)] + [uncropped-end-y (+ uncropped-pre-end-y dy)] + [old-smoothed (send dc get-smoothing)]) + (let*-values ([(start-x start-y) (crop-to uncropped-start-x uncropped-start-y uncropped-end-x uncropped-end-y)] + [(end-x end-y) (crop-to uncropped-end-x uncropped-end-y uncropped-start-x uncropped-start-y)]) + (send dc set-smoothing 'aligned) + (send dc draw-line start-x start-y end-x end-y) + (when (and (< smallest start-x largest) + (< smallest start-y largest)) + (send dc draw-ellipse + (- start-x arrow-root-radius) (- start-y arrow-root-radius) + arrow-root-diameter arrow-root-diameter)) + (when (and (< smallest end-x largest) + (< smallest end-y largest)) + (unless (and (= start-x end-x) (= start-y end-y)) + (let* ([offset-x (- end-x start-x)] + [offset-y (- end-y start-y)] + [arrow-length (sqrt (+ (* offset-x offset-x) (* offset-y offset-y)))] + [cos-alpha (/ offset-x arrow-length)] + [sin-alpha (/ offset-y arrow-length)] + [arrow-head-size-cos-arrow-head-angle-cos-alpha (* arrow-head-size-cos-arrow-head-angle cos-alpha)] + [arrow-head-size-cos-arrow-head-angle-sin-alpha (* arrow-head-size-cos-arrow-head-angle sin-alpha)] + [arrow-head-size-sin-arrow-head-angle-cos-alpha (* arrow-head-size-sin-arrow-head-angle cos-alpha)] + [arrow-head-size-sin-arrow-head-angle-sin-alpha (* arrow-head-size-sin-arrow-head-angle sin-alpha)] + ; pt1 is the tip of the arrow, pt2 is the first point going clockwise from pt1 + [pt1 (make-object point% end-x end-y)] + [pt2 (make-object point% + (- end-x arrow-head-size-cos-arrow-head-angle-cos-alpha arrow-head-size-sin-arrow-head-angle-sin-alpha) + (+ end-y (- arrow-head-size-cos-arrow-head-angle-sin-alpha) arrow-head-size-sin-arrow-head-angle-cos-alpha))] + [pt3 (make-object point% + (+ end-x (- arrow-head-size-cos-arrow-head-angle-cos-alpha) arrow-head-size-sin-arrow-head-angle-sin-alpha) + (- end-y arrow-head-size-cos-arrow-head-angle-sin-alpha arrow-head-size-sin-arrow-head-angle-cos-alpha))]) + (send dc draw-polygon (list pt1 pt2 pt3))))) + (send dc set-smoothing old-smoothed)))) + +;; crop-to : number number number number -> (values number number) +;; returns x,y if they are in the range defined by largest and smallest +;; otherwise returns the coordinates on the line from x,y to ox,oy +;; that are closest to x,y and are in the range specified by +;; largest and smallest +(define (crop-to x y ox oy) + (cond + [(and (< smallest x largest) (< smallest y largest)) + (values x y)] + [else + (let* ([xy-pr (cons x y)] + [left-i (find-intersection x y ox oy smallest smallest smallest largest)] + [top-i (find-intersection x y ox oy smallest smallest largest smallest)] + [right-i (find-intersection x y ox oy largest smallest largest largest)] + [bottom-i (find-intersection x y ox oy smallest largest largest largest)] + [d-top (and top-i (dist top-i xy-pr))] + [d-bottom (and bottom-i (dist bottom-i xy-pr))] + [d-left (and left-i (dist left-i xy-pr))] + [d-right (and right-i (dist right-i xy-pr))]) + (cond + [(smallest? d-top d-bottom d-left d-right) + (values (car top-i) (cdr top-i))] + [(smallest? d-bottom d-top d-left d-right) + (values (car bottom-i) (cdr bottom-i))] + [(smallest? d-left d-top d-bottom d-right) + (values (car left-i) (cdr left-i))] + [(smallest? d-right d-top d-bottom d-left) + (values (car right-i) (cdr right-i))] + [else + ;; uh oh... if this case happens, that's bad news... + (values x y)]))])) + +;; smallest? : (union #f number)^4 -> boolean +;; returns #t if can is less and o1, o2, and o3 +;; if can is #f, return #f. If o1, o2, or o3 is #f, assume that can is smaller than them +(define (smallest? can o1 o2 o3) + (and can + (andmap (λ (x) (< can x)) + (filter (λ (x) x) + (list o1 o2 o3))))) + + +;; inside? : (union #f (cons number number)) -> (union #f (cons number number)) +;; returns the original pair if the coordinates are between smallest and largest +;; and returns #f if the pair is #f or the coordinates are outside. +(define (inside? pr) + (and pr + (let ([x (car pr)] + [y (cdr pr)]) + (if (and (< smallest x largest) + (< smallest y largest)) + pr + #f)))) + +;; find-intersection : (number^2)^2 -> (union (cons number number) #f) +;; finds the intersection between the lines specified by +;; (x1,y1) -> (x2,y2) and (x3,y3) -> (x4,y4) +(define (find-intersection x1 y1 x2 y2 x3 y3 x4 y4) + (cond + [(and (= x1 x2) (= x3 x4)) + #f] + [(and (= x1 x2) (not (= x3 x4))) + (let* ([m2 (/ (- y3 y4) (- x3 x4))] + [b2 (- y3 (* m2 x3))]) + (cons x1 + (+ (* m2 x1) b2)))] + [(and (not (= x1 x2)) (= x3 x4)) + (let* ([m1 (/ (- y1 y2) (- x1 x2))] + [b1 (- y1 (* m1 x1))]) + (cons x3 + (+ (* m1 x3) b1)))] + [(and (not (= x1 x2)) (not (= x3 x4))) + (let* ([m1 (/ (- y1 y2) (- x1 x2))] + [b1 (- y1 (* m1 x1))] + [m2 (/ (- y3 y4) (- x3 x4))] + [b2 (- y3 (* m2 x3))]) + (if (= m1 m2) + #f + (let* ([x (/ (- b1 b2) (- m2 m1))] + [y (+ (* m1 x) b1)]) + (cons x y))))])) + +;; dist : (cons number number) (cons number number) -> number +(define (dist p1 p2) + (sqrt (+ (sqr (- (car p1) (car p2))) + (sqr (- (cdr p1) (cdr p2)))))) + +;; localled defined test code.... :( +;; use module language to run tests +(define (tests) + (and (equal? (find-intersection 0 1 0 10 0 2 0 20) #f) + (equal? (find-intersection 0 1 0 10 0 0 10 10) (cons 0 0)) + (equal? (find-intersection 0 0 10 10 0 1 0 10) (cons 0 0)) + (equal? (find-intersection 0 0 3 3 2 2 4 4) #f) + (equal? (find-intersection -3 3 3 -3 -3 -3 3 3) (cons 0 0)) + (equal? (smallest? 3 1 2 3) #f) + (equal? (smallest? 0 1 2 3) #t) + (equal? (smallest? 1 0 2 3) #f) + (equal? (smallest? 1 0 #f 4) #f) + (equal? (smallest? 1 #f #f 4) #t) + (equal? (smallest? 1 #f #f #f) #t) + (equal? (dist (cons 1 1) (cons 4 5)) 5))) diff --git a/collects/drscheme/private/first-line-text.ss b/collects/drscheme/private/first-line-text.ss deleted file mode 100644 index f1d670827d..0000000000 --- a/collects/drscheme/private/first-line-text.ss +++ /dev/null @@ -1,225 +0,0 @@ -#lang scheme/base - -(require scheme/gui/base - scheme/class - framework) - -(provide first-line-text-mixin - first-line-text-mixin<%>) - -(define first-line-text-mixin<%> - (interface () - highlight-first-line)) - -(define dark-color (make-object color% 50 0 50)) -(define dark-wob-color (make-object color% 255 200 255)) - -(define first-line-text-mixin - (mixin ((class->interface text%)) (first-line-text-mixin<%>) - (inherit get-text paragraph-end-position get-admin invalidate-bitmap-cache position-location - scroll-to local-to-global get-dc) - (define bx (box 0)) - (define by (box 0)) - (define bw (box 0)) - - (define fancy-first-line? #f) - - (define first-line "") - (define end-of-first-line 0) - (define first-line-is-lang? #f) - - (define/private (show-first-line?) - (and fancy-first-line? first-line-is-lang?)) - - (define/private (update-first-line) - (set! end-of-first-line (paragraph-end-position 0)) - (set! first-line (get-text 0 end-of-first-line)) - (set! first-line-is-lang? (is-lang-line? first-line))) - - (define/augment (after-insert start len) - (when (<= start end-of-first-line) - (update-first-line)) - (inner (void) after-insert start len)) - (define/augment (after-delete start len) - (when (<= start end-of-first-line) - (update-first-line)) - (inner (void) after-delete start len)) - - (define/private (fetch-first-line-height) - (let-values ([(_1 h _2 _3) (send (get-dc) get-text-extent first-line (get-font))]) - h)) - - (define/override (scroll-editor-to localx localy width height refresh? bias) - (let ([admin (get-admin)]) - (cond - [(not admin) - #f] - [(show-first-line?) - (let ([h (fetch-first-line-height)]) - (set-box! by localy) - (local-to-global #f by) - (cond - [(<= (unbox by) h) - ;; the max is relevant when we're already scrolled to the top. - (send admin scroll-to localx (max 0 (- localy h)) width height refresh? bias)] - [else - (send admin scroll-to localx localy width height refresh? bias)]))] - [else - (send admin scroll-to localx localy width height refresh? bias)]))) - - (define/public (highlight-first-line on?) - (unless (equal? fancy-first-line? on?) - (set! fancy-first-line? on?) - (invalidate-bitmap-cache) - (let ([canvas (send this get-canvas)]) - (when canvas - (send canvas refresh))))) - - (define/override (on-event event) - (cond - [(or (send event moving?) - (send event leaving?) - (send event entering?)) - (super on-event event)] - [else - (let ([y (send event get-y)] - [h (fetch-first-line-height)] - [admin (get-admin)]) - (unless admin (send admin get-view #f by #f #f #f)) - (cond - [(and admin - (< y h) - (not (= (unbox by) 0))) - (send admin scroll-to (send event get-x) 0 0 0 #t) - (super on-event event)] - [else - (super on-event event)]))])) - - - (define/override (on-paint before? dc left top right bottom dx dy draw-caret) - (unless before? - (when (show-first-line?) - (let ([admin (get-admin)]) - (when admin - (send admin get-view bx by bw #f #f) - (unless (= (unbox by) 0) - (let ([first-line (get-text 0 (paragraph-end-position 0))] - [old-pen (send dc get-pen)] - [old-brush (send dc get-brush)] - [old-smoothing (send dc get-smoothing)] - [old-α (send dc get-alpha)] - [old-font (send dc get-font)] - [old-text-foreground (send dc get-text-foreground)] - [w-o-b? (preferences:get 'framework:white-on-black?)]) - (send dc set-font (get-font)) - (send dc set-smoothing 'aligned) - (let-values ([(tw th _1 _2) (send dc get-text-extent first-line)]) - (let ([line-height (+ (unbox by) dy th 1)] - [line-left (+ (unbox bx) dx)] - [line-right (+ (unbox bx) dx (unbox bw))]) - - (if w-o-b? - (send dc set-pen "white" 1 'solid) - (send dc set-pen "black" 1 'solid)) - (send dc draw-line line-left line-height line-right line-height) - - (when (eq? (send dc get-smoothing) 'aligned) - (let ([start (if w-o-b? 6/10 3/10)] - [end 0] - [steps 10]) - (send dc set-pen - (if w-o-b? dark-wob-color dark-color) - 1 - 'solid) - (let loop ([i steps]) - (unless (zero? i) - (let ([alpha-value (+ start (* (- end start) (/ i steps)))]) - (send dc set-alpha alpha-value) - (send dc draw-line - line-left - (+ line-height i) - line-right - (+ line-height i)) - (loop (- i 1)))))))) - - (send dc set-alpha 1) - (send dc set-pen "gray" 1 'transparent) - (send dc set-brush (if w-o-b? "black" "white") 'solid) - (send dc draw-rectangle - (+ (unbox bx) dx) - (+ (unbox by) dy) - (unbox bw) - th) - (send dc set-text-foreground - (send the-color-database find-color - (if w-o-b? "white" "black"))) - (send dc draw-text first-line (+ (unbox bx) dx) (+ (unbox by) dy))) - - (send dc set-text-foreground old-text-foreground) - (send dc set-font old-font) - (send dc set-pen old-pen) - (send dc set-brush old-brush) - (send dc set-alpha old-α) - (send dc set-smoothing old-smoothing))))))) - (super on-paint before? dc left top right bottom dx dy draw-caret)) - - (inherit get-style-list) - (define/private (get-font) - (let* ([style-list (get-style-list)] - [std (or (send style-list find-named-style "Standard") - (send style-list find-named-style "Basic"))]) - (send std get-font))) - - (super-new))) - -;; is-lang-line? : string -> boolean -;; given the first line in the editor, this returns #t if it is a #lang line. -(define (is-lang-line? l) - (let ([m (regexp-match #rx"^#(!|(lang ))([-+_/a-zA-Z0-9]+)(.|$)" l)]) - (and m - (let ([lang-name (list-ref m 3)] - [last-char (list-ref m 4)]) - (and (not (char=? #\/ (string-ref lang-name 0))) - (not (char=? #\/ (string-ref lang-name (- (string-length lang-name) 1)))) - (or (string=? "" last-char) - (char-whitespace? (string-ref last-char 0)))))))) - -;; test cases for is-lang-line? -#; -(list (is-lang-line? "#lang x") - (is-lang-line? "#lang scheme") - (is-lang-line? "#lang scheme ") - (not (is-lang-line? "#lang schemeα")) - (not (is-lang-line? "#lang scheme/ ")) - (not (is-lang-line? "#lang /scheme ")) - (is-lang-line? "#lang sch/eme ") - (is-lang-line? "#lang r6rs") - (is-lang-line? "#!r6rs") - (is-lang-line? "#!r6rs ") - (not (is-lang-line? "#!/bin/sh"))) - -#; -(begin - (define f (new frame% [label ""] [width 200] [height 200])) - ;(define t (new (editor:standard-style-list-mixin (first-line-text-mixin text%)))) - (define t - (new - (scheme:text-mixin - (text:autocomplete-mixin - (color:text-mixin - (mode:host-text-mixin - (values ; text:delegate-mixin - (text:foreground-color-mixin - (first-line-text-mixin - text:info%))))))))) - (require scheme/runtime-path) - (define-runtime-path here ".") - (send t load-file (build-path (build-path here 'up 'up "framework" "private" "text.ss"))) - #; - (send t insert (apply string-append (map (λ (x) (build-string 100 (λ (i) (if (= i 99) #\newline x)))) - (string->list "abcdefghijklnopqrstuvwxyz")))) - (define c (new editor-canvas% [parent f] [editor t])) - (define b (new button% [callback (λ (c dc) (send t highlight-first-line #t))] [label "on"] [parent f])) - (define b2 (new button% [callback (λ (c dc) (send t highlight-first-line #f))] [label "off"] [parent f])) - (send c focus) - (send f show #t)) \ No newline at end of file diff --git a/collects/drscheme/private/main.ss b/collects/drscheme/private/main.ss index e01ad2bbf7..5c3b30fe55 100644 --- a/collects/drscheme/private/main.ss +++ b/collects/drscheme/private/main.ss @@ -53,6 +53,8 @@ (finder:default-filters))) (application:current-app-name (string-constant drscheme)) +(preferences:set-default 'drscheme:module-language-first-line-special? #t boolean?) + (preferences:set-default 'drscheme:defns-popup-sort-by-name? #f boolean?) (preferences:set-default 'drscheme:toolbar-state @@ -242,6 +244,11 @@ (make-check-box 'drscheme:defs/ints-horizontal (string-constant interactions-beside-definitions) editor-panel) + + (make-check-box 'drscheme:module-language-first-line-special? + (string-constant ml-always-show-#lang-line) + editor-panel) + ;; come back to this one. #; (letrec ([hp (new horizontal-panel% diff --git a/collects/drscheme/private/unit.ss b/collects/drscheme/private/unit.ss index e99c9ccd95..120629aa17 100644 --- a/collects/drscheme/private/unit.ss +++ b/collects/drscheme/private/unit.ss @@ -26,7 +26,6 @@ module browser threading seems wrong. "drsig.ss" "auto-language.ss" "insert-large-letters-typed.ss" - "first-line-text.ss" mrlib/switchable-button mrlib/cache-image-snip @@ -428,7 +427,7 @@ module browser threading seems wrong. (define (make-definitions-text%) (let ([definitions-super% ((get-program-editor-mixin) - (first-line-text-mixin + (text:first-line-mixin (drscheme:module-language:module-language-put-file-mixin (scheme:text-mixin (color:text-mixin @@ -671,6 +670,10 @@ module browser threading seems wrong. (set! needs-execution-state (string-constant needs-execute-defns-edited))) (inner (void) after-delete x y)) + (define/override (is-special-first-line? l) + (and (preferences:get 'drscheme:module-language-first-line-special?) + (is-lang-line? l))) + (inherit get-filename) (field [tmp-date-string #f]) @@ -789,6 +792,32 @@ module browser threading seems wrong. (inherit set-max-undo-history) (set-max-undo-history 'forever)))) + ;; is-lang-line? : string -> boolean + ;; given the first line in the editor, this returns #t if it is a #lang line. + (define (is-lang-line? l) + (let ([m (regexp-match #rx"^#(!|(lang ))([-+_/a-zA-Z0-9]+)(.|$)" l)]) + (and m + (let ([lang-name (list-ref m 3)] + [last-char (list-ref m 4)]) + (and (not (char=? #\/ (string-ref lang-name 0))) + (not (char=? #\/ (string-ref lang-name (- (string-length lang-name) 1)))) + (or (string=? "" last-char) + (char-whitespace? (string-ref last-char 0)))))))) + + ;; test cases for is-lang-line? + #; + (list (is-lang-line? "#lang x") + (is-lang-line? "#lang scheme") + (is-lang-line? "#lang scheme ") + (not (is-lang-line? "#lang schemeα")) + (not (is-lang-line? "#lang scheme/ ")) + (not (is-lang-line? "#lang /scheme ")) + (is-lang-line? "#lang sch/eme ") + (is-lang-line? "#lang r6rs") + (is-lang-line? "#!r6rs") + (is-lang-line? "#!r6rs ") + (not (is-lang-line? "#!/bin/sh"))) + (define (get-module-language/settings) (let* ([module-language (and (preferences:get 'drscheme:switch-to-module-language-automatically?) diff --git a/collects/drscheme/syncheck.ss b/collects/drscheme/syncheck.ss index e5fe29a1a5..45dd510e6c 100644 --- a/collects/drscheme/syncheck.ss +++ b/collects/drscheme/syncheck.ss @@ -223,7 +223,8 @@ If the namespace does not, they are colored the unbound color. get-pos/text position-location get-canvas last-position dc-location-to-editor-location find-position begin-edit-sequence end-edit-sequence - highlight-range unhighlight-range) + highlight-range unhighlight-range + paragraph-end-position first-line-currently-drawn-specially?) @@ -300,19 +301,6 @@ If the namespace does not, they are colored the unbound color. (define cursor-location #f) (define cursor-text #f) (define cursor-eles #f) - (define/private (find-poss text left-pos right-pos) - (let ([xlb (box 0)] - [ylb (box 0)] - [xrb (box 0)] - [yrb (box 0)]) - (send text position-location left-pos xlb ylb #t) - (send text position-location right-pos xrb yrb #f) - (let*-values ([(xl-off yl-off) (send text editor-location-to-dc-location (unbox xlb) (unbox ylb))] - [(xl yl) (dc-location-to-editor-location xl-off yl-off)] - [(xr-off yr-off) (send text editor-location-to-dc-location (unbox xrb) (unbox yrb))] - [(xr yr) (dc-location-to-editor-location xr-off yr-off)]) - (values (/ (+ xl xr) 2) - (/ (+ yl yr) 2))))) ;; find-char-box : text number number -> (values number number number number) ;; returns the bounding box (left, top, right, bottom) for the text range. @@ -377,7 +365,20 @@ If the namespace does not, they are colored the unbound color. (set-arrow-start-y! arrow start-y) (set-arrow-end-x! arrow end-x) (set-arrow-end-y! arrow end-y))) - + + (define/private (find-poss text left-pos right-pos) + (let ([xlb (box 0)] + [ylb (box 0)] + [xrb (box 0)] + [yrb (box 0)]) + (send text position-location left-pos xlb ylb #t) + (send text position-location right-pos xrb yrb #f) + (let*-values ([(xl-off yl-off) (send text editor-location-to-dc-location (unbox xlb) (unbox ylb))] + [(xl yl) (dc-location-to-editor-location xl-off yl-off)] + [(xr-off yr-off) (send text editor-location-to-dc-location (unbox xrb) (unbox yrb))] + [(xr yr) (dc-location-to-editor-location xr-off yr-off)]) + (values (/ (+ xl xr) 2) + (/ (+ yl yr) 2))))) ;; syncheck:init-arrows : -> void (define/public (syncheck:init-arrows) @@ -522,7 +523,6 @@ If the namespace does not, they are colored the unbound color. (loop (- n 1))))))) (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) (when (and arrow-vectors (not before)) (let ([draw-arrow2 (λ (arrow) @@ -589,7 +589,11 @@ If the namespace does not, they are colored the unbound color. (send dc set-pen old-pen) (send dc set-font old-font) (send dc set-text-foreground old-text-foreground) - (send dc set-text-mode old-text-mode)))) + (send dc set-text-mode old-text-mode))) + + ;; do the drawing before calling super so that the arrows don't + ;; cross the "#lang ..." line, if it is present. + (super on-paint before dc left top right bottom dx dy draw-caret)) ;; for-each-tail-arrows : (tail-arrow -> void) tail-arrow -> void (define/private (for-each-tail-arrows f tail-arrow) diff --git a/collects/framework/private/sig.ss b/collects/framework/private/sig.ss index 605ccf038d..89193fa597 100644 --- a/collects/framework/private/sig.ss +++ b/collects/framework/private/sig.ss @@ -159,6 +159,7 @@ (define-signature text-class^ (basic<%> + first-line<%> foreground-color<%> hide-caret/selection<%> nbsp->space<%> @@ -192,6 +193,7 @@ input-box% basic-mixin + first-line-mixin foreground-color-mixin hide-caret/selection-mixin nbsp->space-mixin diff --git a/collects/framework/private/text.ss b/collects/framework/private/text.ss index 436802bad6..813a0319bc 100644 --- a/collects/framework/private/text.ss +++ b/collects/framework/private/text.ss @@ -561,6 +561,185 @@ WARNING: printf is rebound in the body of the unit to always (super-new) (set-autowrap-bitmap (initial-autowrap-bitmap)))) +(define first-line<%> + (interface () + highlight-first-line + get-first-line-height + first-line-currently-drawn-specially? + is-special-first-line?)) + +(define dark-color (make-object color% 50 0 50)) +(define dark-wob-color (make-object color% 255 200 255)) + +(define first-line-mixin + (mixin ((class->interface text%)) (first-line<%>) + (inherit get-text paragraph-end-position get-admin invalidate-bitmap-cache position-location + scroll-to local-to-global get-dc) + (define bx (box 0)) + (define by (box 0)) + (define bw (box 0)) + + (define fancy-first-line? #f) + + (define first-line "") + (define end-of-first-line 0) + (define first-line-is-lang? #f) + + (define/public-final (highlight-first-line on?) + (unless (equal? fancy-first-line? on?) + (set! fancy-first-line? on?) + (invalidate-bitmap-cache) + (let ([canvas (send this get-canvas)]) + (when canvas + (send canvas refresh))))) + + (define/public-final (get-first-line-height) + (let-values ([(_1 h _2 _3) (send (get-dc) get-text-extent first-line (get-font))]) + h)) + + (define/public-final (first-line-currently-drawn-specially?) + (and (show-first-line?) + (let ([admin (get-admin)]) + (and admin + (begin + (send admin get-view #f by #f #f #f) + (not (= (unbox by) 0))))))) + + (define/public (is-special-first-line? l) #f) + + (define/private (show-first-line?) + (and fancy-first-line? first-line-is-lang?)) + + (define/private (update-first-line) + (set! end-of-first-line (paragraph-end-position 0)) + (set! first-line (get-text 0 end-of-first-line)) + (set! first-line-is-lang? (is-special-first-line? first-line))) + + (define/augment (after-insert start len) + (when (<= start end-of-first-line) + (update-first-line)) + (inner (void) after-insert start len)) + (define/augment (after-delete start len) + (when (<= start end-of-first-line) + (update-first-line)) + (inner (void) after-delete start len)) + + (define/override (scroll-editor-to localx localy width height refresh? bias) + (let ([admin (get-admin)]) + (cond + [(not admin) + #f] + [(show-first-line?) + (let ([h (get-first-line-height)]) + (set-box! by localy) + (local-to-global #f by) + (cond + [(<= (unbox by) h) + ;; the max is relevant when we're already scrolled to the top. + (send admin scroll-to localx (max 0 (- localy h)) width height refresh? bias)] + [else + (send admin scroll-to localx localy width height refresh? bias)]))] + [else + (send admin scroll-to localx localy width height refresh? bias)]))) + + (define/override (on-event event) + (cond + [(or (send event moving?) + (send event leaving?) + (send event entering?)) + (super on-event event)] + [else + (let ([y (send event get-y)] + [h (get-first-line-height)] + [admin (get-admin)]) + (unless admin (send admin get-view #f by #f #f #f)) + (cond + [(and admin + (< y h) + (not (= (unbox by) 0))) + (send admin scroll-to (send event get-x) 0 0 0 #t) + (super on-event event)] + [else + (super on-event event)]))])) + + + (define/override (on-paint before? dc left top right bottom dx dy draw-caret) + (unless before? + (when (show-first-line?) + (let ([admin (get-admin)]) + (when admin + (send admin get-view bx by bw #f #f) + (unless (= (unbox by) 0) + (let ([first-line (get-text 0 (paragraph-end-position 0))] + [old-pen (send dc get-pen)] + [old-brush (send dc get-brush)] + [old-smoothing (send dc get-smoothing)] + [old-α (send dc get-alpha)] + [old-font (send dc get-font)] + [old-text-foreground (send dc get-text-foreground)] + [w-o-b? (preferences:get 'framework:white-on-black?)]) + (send dc set-font (get-font)) + (send dc set-smoothing 'aligned) + (let-values ([(tw th _1 _2) (send dc get-text-extent first-line)]) + (let ([line-height (+ (unbox by) dy th 1)] + [line-left (+ (unbox bx) dx)] + [line-right (+ (unbox bx) dx (unbox bw))]) + + (if w-o-b? + (send dc set-pen "white" 1 'solid) + (send dc set-pen "black" 1 'solid)) + (send dc draw-line line-left line-height line-right line-height) + + (when (eq? (send dc get-smoothing) 'aligned) + (let ([start (if w-o-b? 6/10 3/10)] + [end 0] + [steps 10]) + (send dc set-pen + (if w-o-b? dark-wob-color dark-color) + 1 + 'solid) + (let loop ([i steps]) + (unless (zero? i) + (let ([alpha-value (+ start (* (- end start) (/ i steps)))]) + (send dc set-alpha alpha-value) + (send dc draw-line + line-left + (+ line-height i) + line-right + (+ line-height i)) + (loop (- i 1)))))))) + + (send dc set-alpha 1) + (send dc set-pen "gray" 1 'transparent) + (send dc set-brush (if w-o-b? "black" "white") 'solid) + (send dc draw-rectangle + (+ (unbox bx) dx) + (+ (unbox by) dy) + (unbox bw) + th) + (send dc set-text-foreground + (send the-color-database find-color + (if w-o-b? "white" "black"))) + (send dc draw-text first-line (+ (unbox bx) dx) (+ (unbox by) dy))) + + (send dc set-text-foreground old-text-foreground) + (send dc set-font old-font) + (send dc set-pen old-pen) + (send dc set-brush old-brush) + (send dc set-alpha old-α) + (send dc set-smoothing old-smoothing))))))) + (super on-paint before? dc left top right bottom dx dy draw-caret)) + + (inherit get-style-list) + (define/private (get-font) + (let* ([style-list (get-style-list)] + [std (or (send style-list find-named-style "Standard") + (send style-list find-named-style "Basic"))]) + (send std get-font))) + + (super-new))) + + (define foreground-color<%> (interface (basic<%> editor:standard-style-list<%>) )) diff --git a/collects/scribblings/framework/text.scrbl b/collects/scribblings/framework/text.scrbl index e38e470bd4..39c9774615 100644 --- a/collects/scribblings/framework/text.scrbl +++ b/collects/scribblings/framework/text.scrbl @@ -167,9 +167,88 @@ } } + +@definterface[text:first-line<%> (text%)]{ + + Objects implementing this interface, when + @method[text:first-line<%> highlight-first-line] + is invoked with @scheme[#t], always show their + first line, even with scrolled (as long as + @method[text:first-line<%> first-line-currently-drawn-specially?] + returns @scheme[#t]). + + @defmethod[#:mode public-final (highlight-first-line [on? boolean?]) void?]{ + Call this method to enable special treatment of the first line in the editor. + } + + @defmethod[#:mode public-final (first-line-currently-drawn-specially?) boolean?]{ + Returns @scheme[#t] if @method[text:first-line<%> is-special-first-line?] + returned @scheme[#t] for the current first line + and if the buffer is scrolled down so that the first + line would not (ordinarily) be visible. + } + + @defmethod[#:mode public-final (get-first-line-height) number?]{ + Returns the height, in pixels, of the first line. + } + + @defmethod[(is-special-first-line? [line string?]) boolean?]{ + Override this method to control when the first line is always + visible. The argument is the first line, as a string. + } + +} + +@defmixin[text:first-line-mixin (text%) (text:first-line<%>)]{ + Provides the implementation of @scheme[text:first-line<%>]. + Does so by just painting the text of the first + line over top of what is already there and overriding + @method[text:first-line-mixin scroll-editor-to] to patch + up scrolling and + @method[text:first-line-mixin on-event] to patch up + mouse handling. + + @defmethod[#:mode override + (on-paint [before? any/c] + [dc (is-a?/c dc<%>)] + [left real?] + [top real?] + [right real?] + [bottom real?] + [dx real?] + [dy real?] + [draw-caret (one-of/c 'no-caret 'show-inactive-caret 'show-caret)]) + void?]{ + + Based on the various return values of the methods in @scheme[text:first-line], + draws the first actual line of the editor over top of the first + visible line in the editor. + } + + @defmethod[#:mode override + (on-event [event (is-a?/c mouse-event%)]) + void?]{ + Clicks in the first line cause the editor to scroll to the + actual first line. + } + + @defmethod[#:mode override + (scroll-editor-to [localx real?] + [localy real?] + [width (and/c real? (not/c negative?))] + [height (and/c real? (not/c negative?))] + [refresh? any/c] + [bias (one-of/c 'start 'end 'none)]) + void?]{ + Scrolls a little bit more, when a scroll would be requested + that scrolls something so that it is line underneath the first line. + } +} + @definterface[text:foreground-color<%> (text:basic<%> editor:standard-style-list<%>)]{ } + @defmixin[text:foreground-color-mixin (text:basic<%> editor:standard-style-list<%>) (text:foreground-color<%>)]{ This mixin changes the default text style to have the foreground color controlled by diff --git a/collects/string-constants/english-string-constants.ss b/collects/string-constants/english-string-constants.ss index 53810673f8..2b8eb40dca 100644 --- a/collects/string-constants/english-string-constants.ss +++ b/collects/string-constants/english-string-constants.ss @@ -1263,6 +1263,8 @@ please adhere to these guidelines: (ml-cp-remove "Remove") (ml-cp-raise "Raise") (ml-cp-lower "Lower") + + (ml-always-show-#lang-line "Always show #lang line in the Module language") ;; Profj (profj-java "Java")