| 293 | | str: copy/part start end |
| 294 | | unless tail? str [ |
| 295 | | color: any [select colors type color select colors 'default! 0.0.0] |
| 296 | | abs-x: x * f/x + f/origine-x |
| 297 | | either save-color <> color [ |
| 298 | | if block? color [ |
| 299 | | out-style: insert insert insert insert insert insert insert insert out-style |
| 300 | | 'pen color/2 'fill-pen color/2 'box |
| 301 | | as-pair abs-x 7 as-pair (f/x * length? str) + abs-x 7 + f/y 3 |
| 302 | | type: none |
| 303 | | color: color/1 |
| 304 | | ] |
| 305 | | out-style: insert insert insert insert insert out-style |
| 306 | | 'pen color [text edit] as-pair abs-x + f/xy/x 5 str |
| 307 | | |
| | 292 | str: copy/part start end |
| | 293 | unless tail? str [ |
| | 294 | color: any [select colors type color select colors 'default! 0.0.0] |
| | 295 | either save-color <> color [ |
| | 296 | out-style: insert insert insert insert insert out-style |
| | 297 | 'pen color [text edit] as-pair x * f/x + f/xy/x + f/origine-x 5 str |
| | 298 | ][ |
| | 299 | insert tail pick out-style -1 str |
| | 300 | ] |
| | 301 | if type = 'error! [ |
| | 302 | out-style: insert/only insert out-style 'expand |
| | 303 | reduce ['pen red 'text 'vectorial as-pair x * f/x + f/origine-x 5 + f/y reform [value/id value/arg1]] |
| | 304 | ] |
| | 305 | x: x + length? str |
| | 306 | save-color: color |
| | 307 | if type = 'error! [grow?: true] |
| | 308 | ] |
| | 309 | )] |
| | 310 | tab1: next tab2: next tab3: next tab4: " " |
| | 311 | what: none |
| | 312 | gen-tab: [( |
| | 313 | what: pick [tab4 tab3 tab2 tab1] x // 4 + 1 ;** align tabs |
| | 314 | out-style: insert insert insert out-style |
| | 315 | [text edit] as-pair x * f/x + f/xy/x + f/origine-x 5 what |
| | 316 | x: x + length? get what |
| | 317 | save-color: none |
| | 318 | )] |
| | 319 | |
| | 320 | spaces: exclude charset [#"^(1)" - #" "] charset "^/^-" ;** treat like space |
| | 321 | braquets: charset "[]()" |
| | 322 | |
| | 323 | ;** rule to detect rebol values (uses load/next) |
| | 324 | ;** (heavy, because we handle errors too) |
| | 325 | rebol-value: [skip ( |
| | 326 | error? set/any [value end] try [load/next start] |
| | 327 | either error? :value [ |
| | 328 | value: disarm :value |
| | 329 | either value/arg2/1 = #"{" [ |
| | 330 | end: any [find start newline tail start] |
| | 331 | type: 'multi! |
| | 332 | multi: case [ |
| | 333 | multi < 2 [3] |
| | 334 | multi = 2 [4] |
| | 335 | 'else [multi] |
| | 336 | ] |
| | 337 | ][ |
| | 338 | end: skip start length? value/arg2 |
| | 339 | type: 'error! |
| | 340 | ] |
| 351 | | case/all [ |
| 352 | | path? :value [value: first :value] |
| 353 | | all [word? :value value? :value][value: get value] |
| 354 | | any-string? :value [ |
| 355 | | if find/part start newline end [ |
| 356 | | end: find/part start newline end |
| 357 | | multi: case [ |
| 358 | | multi < 2 [3] |
| 359 | | multi = 2 [4] |
| 360 | | 'else [multi] |
| 361 | | ] |
| 362 | | type: 'multi! |
| 363 | | ] |
| 364 | | ] |
| 365 | | ] |
| 366 | | type: type?/word :value |
| 367 | | color: none |
| | 371 | color: save-color: grow?: none |
| | 372 | f: face |
| | 373 | x: 0 |
| | 374 | orig: out-style: out |
| | 375 | |
| | 376 | ;** multi = -1, free text before REBOL header |
| | 377 | ;** multi = 0, code not parsed |
| | 378 | ;** multi = 1, normal code |
| | 379 | ;** multi = 2, end of multi-line string |
| | 380 | ;** multi = 3, begin of multi-line string |
| | 381 | ;** multi = 4, full multi-line string |
| | 382 | |
| | 383 | lvl: lvl-start |
| | 384 | multi: case [ |
| | 385 | head? line [-1] |
| | 386 | 2 < val: first pline: pick line -1 [4] |
| | 387 | val = -1 [-1] |
| | 388 | 'else [1] |
| | 389 | ] |
| | 390 | lvl: lvl-start: either pline [pline/3/2][1] |
| | 391 | line: line/1 |
| | 392 | |
| | 393 | check-multi: either multi = 4 [none][[end skip]] |
| | 394 | check-free-text: [(cont: either multi = -1 [none][[end skip]]) cont] |
| | 395 | |
| | 396 | ;**all [char? line/2 print line] |
| | 397 | parse/all line/2 [ |
| | 398 | start: |
| | 399 | check-free-text "rebol" any #" " #"[" (multi: 1) end skip |
| | 400 | | check-free-text (type: 'free-text!) gen-to-end |
| | 401 | | opt [ |
| | 402 | check-multi start: some [ |
| | 403 | some multi-chars |
| | 404 | | #"^^" [skip | end] |
| | 405 | | end: tab :end (type: 'multi!) gen-draw some [tab gen-tab] start: |
| | 406 | | #"}" (multi: 2) break ;** end of multi-line |
| | 407 | | break ;** newline |
| | 408 | ] |
| | 409 | (type: 'multi!) gen-draw |
| | 410 | ] |
| | 411 | any [ |
| | 412 | start: [newline | end] break |
| | 413 | | some spaces (type: 'blank!) gen-draw |
| | 414 | | tab gen-tab |
| | 415 | | [#"[" | #"("] (type: 'block! lvl: lvl + 1) gen-draw |
| | 416 | | [#"]" | #")"] (type: 'block! lvl: lvl - 1) gen-draw |
| | 417 | | #";"(type: 'comment!) gen-to-end |
| | 418 | | rebol-value gen-draw |
| | 419 | ] |
| | 420 | ] |
| | 421 | |
| | 422 | line/1: multi |
| | 423 | line/3: as-pair lvl-start lvl |
| | 424 | |
| | 425 | |
| | 426 | f/h-scroller/max-x: max f/h-scroller/max-x x * f/x + f/origine-x + (f/x * 10) |
| | 427 | f/cursor/len: x |
| | 428 | |
| | 429 | case [ |
| | 430 | empty? orig [ ;** if the text contains no chars, add a dummy line |
| | 431 | append orig compose [text edit (as-pair f/origine-x + f/xy/x 5) (copy "")] |
| | 432 | ] |
| | 433 | not same? back start find/reverse start any-char [ |
| | 434 | insert insert insert tail orig |
| | 435 | [pen blue text no-edit] |
| | 436 | as-pair x * f/x + f/origine-x + f/xy/x 5 |
| | 437 | "�" |
| | 438 | ] |
| | 439 | ] |
| | 440 | grow? ;** notices if it's a simple line or a double-size line |
| 369 | | ) :end |
| 370 | | ] |
| 371 | | |
| 372 | | no-tabs: complement charset "^/^-" |
| 373 | | gen-to-end: [any [some no-tabs | end: tab :end gen-draw some [tab gen-tab] start:] gen-draw] |
| 374 | | any-char: complement charset " ^-" |
| 375 | | |
| 376 | | ;** construct a draw block for one line |
| 377 | | set 'colorize func [ |
| 378 | | face line out |
| 379 | | /local check-multi check-free-text orig lvl-start lvl val cont pline pos |
| 380 | | ][ |
| 381 | | color: save-color: grow?: none |
| 382 | | f: face |
| 383 | | x: 0 |
| 384 | | orig: out-style: out |
| 385 | | |
| 386 | | ;** multi = -1, free text before REBOL header |
| 387 | | ;** multi = 0, code not parsed |
| 388 | | ;** multi = 1, normal code |
| 389 | | ;** multi = 2, end of multi-line string |
| 390 | | ;** multi = 3, begin of multi-line string |
| 391 | | ;** multi = 4, full multi-line string |
| 392 | | |
| 393 | | lvl: lvl-start |
| 394 | | multi: case [ |
| 395 | | head? line [-1] |
| 396 | | 2 < val: first pline: pick line -1 [4] |
| 397 | | val = -1 [-1] |
| 398 | | 'else [1] |
| | 442 | |
| | 443 | ;** cut text into lines |
| | 444 | set 'build-data func [ |
| | 445 | text f /local out |
| | 446 | ][ |
| | 447 | out: f/data |
| | 448 | clear out |
| | 449 | parse/all text [any [pos: (out: insert/only out reduce [0 pos 0x0] ) thru newline]] |
| | 450 | f/origine-x: f/x * (1 + length? to string! length? head out) |
| | 451 | recycle |
| | 452 | out: head out |
| 400 | | lvl: lvl-start: either pline [pline/3/2][1] |
| 401 | | line: line/1 |
| 402 | | |
| 403 | | check-multi: if multi <> 4 [[end skip]] |
| 404 | | check-free-text: [(cont: if multi <> -1 [[end skip]]) cont] |
| 405 | | |
| 406 | | ;**all [char? line/2 print line] |
| 407 | | parse/all line/2 [ |
| 408 | | start: |
| 409 | | check-free-text "rebol" any #" " #"[" (multi: 1) end skip |
| 410 | | | check-free-text (type: 'free-text!) gen-to-end |
| 411 | | | opt [ |
| 412 | | check-multi start: some [ |
| 413 | | some multi-chars |
| 414 | | | #"^^" [skip | end] |
| 415 | | | end: tab :end (type: 'multi!) gen-draw some [tab gen-tab] start: |
| 416 | | | #"}" (multi: 2) break ;** end of multi-line |
| 417 | | | break ;** newline |
| 418 | | ] |
| 419 | | (type: 'multi!) gen-draw |
| 420 | | ] |
| 421 | | any [ |
| 422 | | start: [newline | end] break |
| 423 | | | some spaces (type: 'blank!) gen-draw |
| 424 | | | tab gen-tab |
| 425 | | | [#"[" | #"("] (type: 'block! lvl: lvl + 1) gen-draw |
| 426 | | | [#"]" | #")"] (type: 'block! lvl: lvl - 1) gen-draw |
| 427 | | | #";"(type: 'comment!) gen-to-end |
| 428 | | | rebol-value gen-draw |
| 429 | | ] |
| 430 | | ] |
| 431 | | |
| 432 | | line/1: multi |
| 433 | | line/3: as-pair lvl-start lvl |
| 434 | | |
| 435 | | |
| 436 | | f/h-scroller/max-x: max f/h-scroller/max-x x * f/x + f/origine-x + (f/x * 10) |
| 437 | | ;**f/cursor/len: x |
| 438 | | |
| 439 | | case [ |
| 440 | | empty? orig [ ;** if the text contains no chars, add a dummy line |
| 441 | | append orig compose [text edit (as-pair f/origine-x + f/xy/x 5) (copy "")] |
| 442 | | ] |
| 443 | | not same? back start find/reverse start any-char [ |
| 444 | | insert insert insert tail orig |
| 445 | | [pen blue text no-edit] |
| 446 | | as-pair x * f/x + f/origine-x + f/xy/x 5 |
| 447 | | "�" |
| 448 | | ] |
| 449 | | ] |
| 450 | | grow? ;** notices if it's a simple line or a double-size line |
| 451 | | ] |
| 452 | | |
| 453 | | ;** cut text into lines |
| 454 | | set 'build-data func [ |
| 455 | | text f /local out |
| 456 | | ][ |
| 457 | | out: f/data |
| 458 | | clear out |
| 459 | | parse/all text [any [pos: (out: insert/only out reduce [0 pos 0x0]) thru newline]] |
| 460 | | f/origine-x: f/x * (1 + length? to string! length? head out) |
| 461 | | recycle/on |
| 462 | | out: head out |
| | 454 | |
| 475 | | |
| 476 | | ;** contruct draw blocks, only for new lines inserted |
| 477 | | set 'render-text func [ |
| 478 | | f inc |
| 479 | | /stay |
| 480 | | /local pos char color draw-txt |
| 481 | | prev-col draw-sblk nb line data n decal |
| 482 | | ][ |
| 483 | | ;start: now/precise |
| 484 | | ;f/current-line: f/current-line + inc |
| 485 | | prev-col: none |
| 486 | | case [ |
| 487 | | stay [ |
| 488 | | inc: inc - 1 |
| 489 | | data: skip f/data inc |
| 490 | | ] |
| 491 | | inc < 0 [ |
| 492 | | inc: negate min abs inc ((index? f/data) - 1) |
| 493 | | data: f/data: skip f/data inc |
| 494 | | ] |
| 495 | | inc > 0 [ |
| 496 | | inc: min max 0 ((length? f/data) - f/nb-lines) inc |
| 497 | | data: f/data: skip f/data inc |
| 498 | | ] |
| 499 | | 'else [data: f/data] |
| | 467 | render-text: func [ |
| | 468 | f inc |
| | 469 | /stay |
| | 470 | /local pos char color draw-txt |
| | 471 | prev-col draw-sblk nb line data n decal |
| | 472 | ][ |
| | 473 | ;start: now/precise |
| | 474 | prev-col: none |
| | 475 | case [ |
| | 476 | stay [ |
| | 477 | inc: inc - 1 |
| | 478 | data: skip f/data inc |
| | 479 | ] |
| | 480 | inc < 0 [ |
| | 481 | inc: negate min abs inc ((index? f/data) - 1) |
| | 482 | data: f/data: skip f/data inc |
| | 483 | ] |
| | 484 | inc > 0 [ |
| | 485 | inc: min max 0 ((length? f/data) - f/nb-lines) inc |
| | 486 | data: f/data: skip f/data inc |
| | 487 | ] |
| | 488 | 'else [data: f/data] |
| | 489 | ] |
| | 490 | |
| | 491 | draw-txt: any [find f/effect/draw 'push tail f/effect/draw] |
| | 492 | |
| | 493 | case [ |
| | 494 | stay [ |
| | 495 | draw-txt: clear skip draw-txt max 0 inc * 4 |
| | 496 | nb: min f/nb-lines f/nb-lines - inc |
| | 497 | ] |
| | 498 | empty? draw-txt [ |
| | 499 | nb: f/nb-lines |
| | 500 | ] |
| | 501 | inc > 0 [ |
| | 502 | remove/part draw-txt 4 * inc |
| | 503 | draw-txt: tail draw-txt |
| | 504 | nb: min f/nb-lines inc |
| | 505 | data: skip data either f/nb-lines > inc [f/nb-lines - inc][0] |
| | 506 | ;** A FAIRE, si inc d�passe le nombre de lignes affich�es, |
| | 507 | ;** parser les lignes skip�es (non affich�es) |
| | 508 | ;** pour d�tecter les strings multi-ligne |
| | 509 | ] |
| | 510 | inc < 0 [ |
| | 511 | clear skip draw-txt max 0 4 * (f/nb-lines + inc) |
| | 512 | nb: min f/nb-lines abs inc |
| | 513 | ] |
| | 514 | 'else [return true] |
| | 515 | ] |
| | 516 | nb: min nb length? data |
| | 517 | n: 1 |
| | 518 | decal: as-pair 0 f/y |
| | 519 | while [n <= nb][ |
| | 520 | line: at data n |
| | 521 | draw-txt: insert draw-txt 'push |
| | 522 | draw-sblk: insert insert insert make block! 50 |
| | 523 | [hilight none pen 128.128.128 text no-edit] as-pair f/xy/x 5 |
| | 524 | reverse copy/part reverse head insert change clear "" " " (n - 1 + index? data) (f/origine-x - f/x / f/x) |
| | 525 | if colorize f line draw-sblk [ |
| | 526 | decal: as-pair 0 2 * f/y |
| | 527 | ] |
| | 528 | draw-txt: insert insert insert/only draw-txt head draw-sblk 'translate decal |
| | 529 | decal: as-pair 0 f/y |
| | 530 | n: n + 1 |
| | 531 | ] |
| | 532 | |
| | 533 | set-y f 5 ;** recalc all y offset of texts (which can be absolute only) |
| | 534 | unless f/cursor/selection? [show f] |
| | 535 | ;** probe difference now/precise start |
| 502 | | draw-txt: any [find f/effect/draw 'push tail f/effect/draw] |
| 503 | | |
| 504 | | case [ |
| 505 | | stay [ |
| 506 | | draw-txt: clear skip draw-txt max 0 inc * 4 |
| 507 | | nb: min f/nb-lines f/nb-lines - inc |
| 508 | | ] |
| 509 | | empty? draw-txt [ |
| 510 | | nb: f/nb-lines |
| 511 | | ] |
| 512 | | inc > 0 [ |
| 513 | | remove/part draw-txt 4 * inc |
| 514 | | draw-txt: tail draw-txt |
| 515 | | nb: min f/nb-lines inc |
| 516 | | data: skip data either f/nb-lines > inc [f/nb-lines - inc][0] |
| 517 | | ;** A FAIRE, si inc d�passe le nombre de lignes affich�es, |
| 518 | | ;** parser les lignes skip�es (non affich�es) |
| 519 | | ;** pour d�tecter les strings multi-ligne |
| 520 | | ] |
| 521 | | inc < 0 [ |
| 522 | | clear skip draw-txt max 0 4 * (f/nb-lines + inc) |
| 523 | | nb: min f/nb-lines abs inc |
| 524 | | ] |
| 525 | | 'else [return true] |
| | 538 | set-y: func [f y /local blk pair line idx gb lgb chg-y][ |
| | 539 | blk: f/effect/draw |
| | 540 | blk: find f/effect/draw 'push |
| | 541 | lgb: index? f/data |
| | 542 | gb: f/cursor/global-idx |
| | 543 | idx: 2 |
| | 544 | f/cursor/show?: false |
| | 545 | chg-y: [thru 'text ['edit | 'no-edit] pair: pair! (pair/1/y: y)] |
| | 546 | foreach [cmd value] blk [ |
| | 547 | switch cmd [ |
| | 548 | translate [y: y + value/y] |
| | 549 | push [ |
| | 550 | if gb = lgb [ |
| | 551 | f/cursor/xy/y: y |
| | 552 | f/cursor/data: at blk idx |
| | 553 | f/cursor/show?: true |
| | 554 | ] |
| | 555 | parse value [ |
| | 556 | any chg-y |
| | 557 | any [thru 'push into [any chg-y to end break]] |
| | 558 | ] |
| | 559 | lgb: lgb + 1 |
| | 560 | ] |
| | 561 | |
| | 562 | ] |
| | 563 | idx: idx + 2 |
| | 564 | ] |
| 578 | | ] |
| 579 | | |
| 580 | | move-x: func [f x /local blk pair chg-x][ |
| 581 | | blk: f/effect/draw |
| 582 | | blk: find f/effect/draw 'push |
| 583 | | chg-x: [thru 'text ['edit | 'no-edit] pair: pair! (pair/1/x: x + pair/1/x)] |
| 584 | | foreach [cmd value] blk [ |
| 585 | | switch cmd [ |
| 586 | | translate [x: x + value/x] |
| 587 | | push [ |
| 588 | | parse value [ |
| 589 | | any chg-x |
| 590 | | any [thru 'push into [any chg-x to end break]] |
| 591 | | ] |
| 592 | | ] |
| 593 | | ] |
| 594 | | ] |
| 595 | | f/cursor/xy/x: f/cursor/xy/x + x |
| 596 | | ] |
| 597 | | |
| 598 | | |
| 599 | | ;** return the inner face matching the point |
| 600 | | map-inner: func [face point /local pane][ |
| 601 | | unless pane: face/pane [return face] |
| 602 | | unless block? pane [pane: to block! pane] |
| 603 | | foreach face pane [ |
| 604 | | if within? point face/offset face/size [return map-inner face point - face/offset] |
| 605 | | ] |
| 606 | | face |
| 607 | | ] |
| 608 | | |
| 609 | | get*: func [v][do back change/only [none] v] ;** if v is a word, get value in the world |
| 610 | | any-char: complement space: charset " ^-" |
| 611 | | |
| 612 | | ;** find a free place in the whole area to display the info box |
| 613 | | find-free-places: func [ |
| 614 | | f |
| 615 | | /local data end x len l-len r-pos stack-l stack-r |
| 616 | | ][ |
| 617 | | stack-l: clear [] |
| 618 | | stack-r: clear [] |
| 619 | | data: f/data |
| 620 | | loop len: f/nb-lines [ |
| 621 | | line: data/1/2 |
| 622 | | end: any [find line newline tail line] |
| 623 | | |
| 624 | | ;** length of the left free zone |
| 625 | | pos: any [find/part line space end line] |
| 626 | | l-len: -1 + index? pos |
| 627 | | |
| 628 | | ;** start of the rigth free zone |
| 629 | | pos: ant [find/reverse end any-char end] |
| 630 | | r-start: index? pos |
| 631 | | |
| 632 | | stack-l: insert stack-l l-len |
| 633 | | stack-r: insert stack-r r-len |
| 634 | | data: next data |
| 635 | | ] |
| 636 | | x: maximum-of stack-l |
| 637 | | loop len [ |
| 638 | | |
| 639 | | stack-l: next stack-l |
| 640 | | ] |
| 641 | | ] |
| 642 | | |
| 643 | | event-func: use [ |
| 644 | | origin off-mem save-size 0x0 drag track |
| 645 | | ][ |
| | 595 | |
| | 596 | get*: func [v][do back change/only [none] v] ;** if v is a word, get value in the world |
| | 597 | any-char: complement space: charset " ^-" |
| | 598 | |
| | 599 | context [ |
| 796 | | area-tc: box with [ |
| 797 | | style: 'area-tc |
| 798 | | rate: 1 |
| 799 | | text: none |
| 800 | | para: make para [origin: 0x0 margin: 0x0] |
| 801 | | delay: 0 |
| 802 | | ask: 'recycle ;** command to delay |
| 803 | | color: pref/bg_color |
| 804 | | x: 8 ;** current x size of 1 char |
| 805 | | y: 18 ;** current y size of a line |
| 806 | | origine-x: 4 * x ;** stock la position a la quelle le texte d�marre apres le rendu des num�ro de ligne |
| 807 | | data: [] |
| 808 | | font-obj: make face/font [name: "lucida console" size: 14 style: none offset: 0x0] |
| 809 | | nb-lines: 0 |
| 810 | | xy: 0x0 ;** scroll offset |
| 811 | | move-offset: 0x0 |
| 812 | | save-x: 0 |
| 813 | | splited?: none |
| 814 | | file-name: none |
| 815 | | effect: [draw [pen none font font-obj line-width 1 translate xy]] |
| 816 | | open-file: func [ file [file! none!] /local ][ |
| 817 | | if any [file file: request-file ][ |
| 818 | | ;** data: build-data detab/size read file 4 self |
| 819 | | if block? file [file: first file] |
| 820 | | data: build-data read/direct file self |
| 821 | | file-name: file |
| 822 | | render-text/stay self 1 |
| 823 | | feel/inc-font-size self 0 ; replace le curseur au bon endroit apres la modif du block draw |
| 824 | | l/draw-list self |
| 825 | | ] |
| 826 | | ] |
| 827 | | new-file: func [][ |
| | 782 | area-tc: box with [ |
| | 783 | style: 'area-tc |
| | 784 | rate: 1 |
| | 785 | text: none |
| | 786 | para: make para [origin: 0x0 margin: 0x0] |
| | 787 | delay: 0 |
| | 788 | ask: 'recycle ;** command to delay |
| | 789 | color: pref/bg_color |
| | 790 | x: 8 ;** current x size oh 1 char |
| | 791 | y: 18 ; ** current y size of a line |
| | 792 | origine-x: 3 * x ;** stock la position a la quelle le texte d�marre apres le rendu des num�ro de ligne |
| | 793 | data: [] |
| | 794 | fnt-sz: 14 |
| | 795 | font-obj: make face/font [ name: "Lucida Console" style: none offset: 0x0 size: 14 align: 'left valign: 'top ] |
| | 796 | nb-lines: 0 |
| | 797 | xy: 0x0 ;** scroll offset |
| | 798 | move-offset: 0x0 |
| | 799 | effect: [draw [pen none font font-obj line-width 0 translate xy]] |
| | 800 | open-file: func [ file [file! none!] /local ][ |
| | 801 | if any [file file: first request-file][ |
| | 802 | ;** data: build-data detab/size read file 4 self |
| | 803 | data: build-data read file self |
| | 804 | render-text/stay t 1 |
| | 805 | feel/inc-font-size self 0 ; on replace le curseur apres chargement du fichier |
| | 806 | l/draw-list self |
| | 807 | ] |
| | 808 | ] |
| | 809 | new-file: func [][ |
| 929 | | goto-line: func [ line-gt /local move-to current-line][ |
| 930 | | current-line: index? data |
| 931 | | either line-gt > current-line [ |
| 932 | | move-to: line-gt - current-line |
| 933 | | current-line: line-gt |
| 934 | | ][ |
| 935 | | move-to: negate current-line - line-gt |
| 936 | | current-line: line-gt |
| 937 | | ] |
| 938 | | ;probe move-to |
| 939 | | render-text self move-to |
| 940 | | show self |
| 941 | | ] |
| 942 | | v-scroller: make face [ |
| 943 | | offset: 0x0 size: 13x0 color: none edge: none |
| 944 | | size-box: 0x0 |
| 945 | | para: none |
| 946 | | effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]] |
| | 911 | |
| | 912 | |
| | 913 | |
| | 914 | goto-line: func [ line-gt /local move-to current-line][ |
| | 915 | current-line: index? data |
| | 916 | either line-gt > current-line [ |
| | 917 | move-to: line-gt - current-line |
| | 918 | current-line: line-gt |
| | 919 | ][ |
| | 920 | move-to: negate current-line - line-gt |
| | 921 | current-line: line-gt |
| | 922 | ] |
| | 923 | ;probe move-to |
| | 924 | render-text self move-to |
| | 925 | show self |
| | 926 | ] |
| | 927 | |
| | 928 | v-scroller: make face [ |
| | 929 | offset: 0x0 size: 13x0 color: none edge: none |
| | 930 | size-box: 0x0 |
| | 931 | para: none |
| | 932 | effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]] |
| | 933 | feel: make feel [ |
| | 934 | redraw: func [f a /local p l][ |
| | 935 | if all ['show = a p: f/parent-face 0 < l: length? head p/data][ |
| | 936 | f/size/y: max 25 p/nb-lines / l * p/size/y |
| | 937 | f/offset/y: (index? p/data) / (l - p/nb-lines) * (p/size/y - f/size/y) |
| | 938 | f/size-box: f/size - 2x2 |
| | 939 | ] |
| | 940 | ] |
| | 941 | drag: func [f offset /track /local coeff][ |
| | 942 | f/parent-face/delay: 3 ;** don't perturb the scroll please |
| | 943 | if track [return f] |
| | 944 | if 1 <= abs coeff: offset/y / (f/size/y / f/parent-face/nb-lines) [ |
| | 945 | render-text f/parent-face to integer! coeff |
| | 946 | if f/parent-face/cursor/selection? [ |
| | 947 | f/parent-face/feel/expand-selector f/parent-face/cursor |
| | 948 | show f/parent-face |
| | 949 | ] |
| | 950 | ] |
| | 951 | ] |
| | 952 | engage: func [f a e][false] ;** don't send events to the area |
| | 953 | ] |
| | 954 | ] |
| | 955 | h-scroller: make face [ |
| | 956 | offset: 0x0 size: 0x13 color: none edge: none |
| | 957 | size-box: 0x0 |
| | 958 | text: none |
| | 959 | edge: none |
| | 960 | font: make font [align: 'right size: 10 style: 'bold color: red] |
| | 961 | para: make para [origin: 0x0] |
| | 962 | max-x: 1 |
| | 963 | effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]] |
| | 964 | feel: make feel [ |
| | 965 | redraw: func [f a /local parent][ |
| | 966 | if 'show = a [ |
| | 967 | f/show?: if f/max-x > f/parent-face/size/x [ |
| | 968 | parent: f/parent-face |
| | 969 | f/offset/x: to integer! negate parent/xy/x / f/max-x * parent/size/x |
| | 970 | f/size/x: to integer! (parent/size/x ** 2) / f/max-x |
| | 971 | f/size-box: f/size - 2x2 |
| | 972 | true |
| | 973 | ] |
| | 974 | ] |
| | 975 | ] |
| | 976 | drag: func [scroller offset /track /local parent save-x decal x][ |
| | 977 | f: scroller/parent-face |
| | 978 | f/delay: 3 ;** don't perturb the scroll please |
| | 979 | if track [return scroller] |
| | 980 | if f/x <= abs offset/x [ |
| | 981 | offset/x: to integer! offset/x + 4 / f/x * f/x |
| | 982 | save-x: f/xy/x |
| | 983 | x: f/xy/x: min 0 max |
| | 984 | f/size/x - scroller/max-x |
| | 985 | f/xy/x - offset/x |
| | 986 | |
| | 987 | ;** change change skip tail boxline -2 |
| | 988 | ;** as-pair negate x 1 as-pair 32 - x 18 |
| | 989 | |
| | 990 | if 0 <> decal: x - save-x [move-x f decal] |
| | 991 | show f |
| | 992 | ] |
| | 993 | ] |
| | 994 | engage: func [f a e][false] ;** don't send events to the area |
| | 995 | ] |
| | 996 | ] |
| | 997 | cursor: make face [ |
| | 998 | offset: 0x5 size: 2x18 para: color: edge: none |
| | 999 | xy: as-pair origine-x 5 |
| | 1000 | ; len et old len ont �t� renom� en col et old-col apparement ... dans les version suivante |
| | 1001 | sub-string: idx: global-idx: col: old-col: len: old-len: |
| | 1002 | old-idx: tmp-offset: pos-len: old-pos-len: none |
| | 1003 | selection?: false |
| | 1004 | selector-xy: [0x0] |
| | 1005 | head?: false |
| | 1006 | data: pos-blk: [] |
| | 1007 | blink-color: red |
| | 1008 | size-box: 2x16 |
| | 1009 | effect: [draw [pen blink-color fill-pen blink-color box 0x1 size-box]] |
| | 1010 | feel: make feel [ |
| | 1011 | redraw: func [f a][ |
| | 1012 | if a = 'show [ |
| | 1013 | f/offset: f/xy |
| | 1014 | if f/selection? [ |
| | 1015 | f/selector-xy/1/x: f/xy/x - f/parent-face/xy/x |
| | 1016 | ] |
| | 1017 | ] |
| | 1018 | ] |
| | 1019 | engage: func [f a e][] ;** disable events |
| | 1020 | ] |
| | 1021 | ] |
| 948 | | redraw: func [f a /local p l][ |
| 949 | | if all ['show = a p: f/parent-face 0 < l: length? head p/data][ |
| 950 | | f/size/y: max 25 p/nb-lines / l * p/size/y |
| 951 | | f/offset/y: (index? p/data) / (l - p/nb-lines) * (p/size/y - f/size/y) |
| 952 | | f/size-box: f/size - 2x2 |
| 953 | | ] |
| 954 | | ] |
| 955 | | drag: func [f offset /track /local coeff][ |
| 956 | | f/parent-face/delay: 3 ;** don't perturb the scroll please |
| 957 | | if track [return f] |
| 958 | | if 1 <= abs coeff: offset/y / (f/size/y / f/parent-face/nb-lines) [ |
| 959 | | render-text f/parent-face to integer! coeff |
| 960 | | if f/parent-face/cursor/selection? [ |
| 961 | | f/parent-face/feel/expand-selector f/parent-face/cursor |
| 962 | | show f/parent-face |
| 963 | | ] |
| 964 | | ] |
| 965 | | ] |
| 966 | | engage: func [f a e][false] ;** don't send events to the area |
| 967 | | ] |
| 968 | | ] |
| 969 | | h-scroller: make face [ |
| 970 | | offset: 0x0 size: 0x13 color: none edge: none |
| 971 | | size-box: 0x0 |
| 972 | | text: none |
| 973 | | edge: none |
| 974 | | font: make font [align: 'right size: 10 style: 'bold color: red] |
| 975 | | para: make para [origin: 0x0] |
| 976 | | max-x: 1 |
| 977 | | effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]] |
| 978 | | feel: make feel [ |
| 979 | | redraw: func [f a /local parent][ |
| 980 | | if 'show = a [ |
| 981 | | f/show?: if f/max-x > f/parent-face/size/x [ |
| 982 | | parent: f/parent-face |
| 983 | | f/offset/x: to integer! negate parent/xy/x / f/max-x * parent/size/x |
| 984 | | f/size/x: to integer! (parent/size/x ** 2) / f/max-x |
| 985 | | f/size-box: f/size - 2x2 |
| 986 | | true |
| 987 | | ] |
| 988 | | ] |
| 989 | | ] |
| 990 | | drag: func [scroller offset /track /local f parent save-x decal x][ |
| 991 | | f: scroller/parent-face |
| 992 | | f/delay: 3 ;** don't perturb the scroll please |
| 993 | | if track [return scroller] |
| 994 | | if f/x <= abs offset/x [ |
| 995 | | offset/x: to integer! offset/x + 4 / f/x * f/x |
| 996 | | save-x: f/xy/x |
| 997 | | x: f/xy/x: min 0 max |
| 998 | | f/size/x - scroller/max-x |
| 999 | | f/xy/x - offset/x |
| 1000 | | |
| 1001 | | ;** change change skip tail boxline -2 |
| 1002 | | ;** as-pair negate x 1 as-pair 32 - x 18 |
| 1003 | | |
| 1004 | | if 0 <> decal: x - save-x [move-x f decal] |
| 1005 | | show f |
| 1006 | | ] |
| 1007 | | ] |
| 1008 | | engage: func [f a e][false] ;** don't send events to the area |
| 1009 | | ] |
| 1010 | | ] |
| 1011 | | cursor: make face [ |
| 1012 | | offset: 0x5 size: 2x18 para: color: edge: none |
| 1013 | | xy: as-pair origine-x 5 |
| 1014 | | sub-string: idx: global-idx: col: old-col: |
| 1015 | | old-idx: tmp-offset: pos-len: old-pos-len: none |
| 1016 | | selection?: false |
| 1017 | | selector-xy: [0x0] |
| 1018 | | head?: false |
| 1019 | | data: pos-blk: [] |
| 1020 | | blink-color: red |
| 1021 | | size-box: 2x16 |
| 1022 | | effect: [draw [pen blink-color fill-pen blink-color box 0x1 size-box]] |
| 1023 | | feel: make feel [ |
| 1024 | | redraw: func [f a][ |
| 1025 | | if a = 'show [ |
| 1026 | | f/offset: f/xy |
| 1027 | | if f/selection? [ |
| 1028 | | f/selector-xy/1/x: f/xy/x - f/parent-face/xy/x |
| 1029 | | ] |
| 1030 | | ] |
| 1031 | | ] |
| 1032 | | engage: func [f a e][] ;** disable events |
| 1033 | | ] |
| 1034 | | ] |
| 1035 | | feel: make feel [ |
| 1036 | | scrollwheel: func [f event offset] [ |
| 1037 | | f/delay: 3 |
| 1038 | | dir: either event/offset/y > 0 ['down]['up] |
| 1039 | | switch dir [ |
| 1040 | | down [render-text f 3] |
| 1041 | | up [render-text f -3] |
| 1042 | | ] |
| 1043 | | if f/cursor/selection? [expand-selector f/cursor show f] |
| 1044 | | ] |
| 1045 | | resize: func [f size+][ |
| 1046 | | f/size: f/size + size+ |
| 1047 | | f/nb-lines: to-integer (f/size/y - 10 / f/y) |
| 1048 | | f/v-scroller/offset: as-pair f/size/x - 13 2 |
| 1049 | | f/h-scroller/offset: as-pair 2 f/size/y - 13 |
| 1050 | | render-text/stay f 1 |
| 1051 | | if f/cursor/selection? [expand-selector f/cursor show f] |
| 1052 | | ] |
| 1053 | | begin-selection: func [ |
| | 1023 | scrollwheel: func [f event offset] [ |
| | 1024 | f/delay: 3 |
| | 1025 | dir: either event/offset/y > 0 ['down]['up] |
| | 1026 | switch dir [ |
| | 1027 | down [render-text f 3] |
| | 1028 | up [render-text f -3] |
| | 1029 | ] |
| | 1030 | if f/cursor/selection? [expand-selector f/cursor show f] |
| | 1031 | ] |
| | 1032 | resize: func [f size+][ |
| | 1033 | f/size: f/size + size+ |
| | 1034 | f/nb-lines: to-integer (f/size/y - 10 / f/y) |
| | 1035 | f/v-scroller/offset: as-pair f/size/x - 13 2 |
| | 1036 | f/h-scroller/offset: as-pair 2 f/size/y - 13 |
| | 1037 | render-text/stay f 1 |
| | 1038 | if f/cursor/selection? [expand-selector f/cursor show f] |
| | 1039 | ] |
| | 1040 | |
| | 1041 | begin-selection: func [ |
| 1084 | | ] |
| 1085 | | |
| 1086 | | detect: func [f e][ |
| 1087 | | ;**print remold [e/1 e/2 e/3 e/4 e/5 e/6] |
| 1088 | | if e/type = 'move [ |
| 1089 | | ;** because of the timer, 'move events are received, even if there is no move |
| 1090 | | if all [find [info-position recycle] f/ask f/move-offset <> e/offset][ |
| 1091 | | f/ask: 'info-position |
| 1092 | | f/delay: 2 |
| 1093 | | f/move-offset: e/offset |
| 1094 | | ] |
| 1095 | | return false |
| 1096 | | ] |
| 1097 | | e |
| 1098 | | ] |
| 1099 | | engage: func [f a e /local key tmp cursor select?][ |
| 1100 | | ;**print remold [a e/type e/key e/1 e/2 e/3 e/4 e/5 e/6] |
| 1101 | | cursor: f/cursor |
| 1102 | | if a = 'time [ |
| 1103 | | ;print [now/time f/ask f/delay] |
| 1104 | | either all [cursor/show? find [recycle info-position] f/ask] [ |
| 1105 | | f/cursor/blink-color: get first reverse [red none] |
| 1106 | | show f/cursor |
| 1107 | | ][f/cursor/blink-color: red] |
| 1108 | | case [ |
| 1109 | | 0 > f/delay: f/delay - 1 [ |
| 1110 | | ;** if f/ask <> 'show [print ["timer:" now/time f/ask] ] |
| 1111 | | switch f/ask [ |
| 1112 | | show [] |
| 1113 | | recycle [recycle] |
| | 1070 | ] |
| | 1071 | save-x: 0 |
| | 1072 | detect: func [f e][ |
| | 1073 | ;**print remold [e/1 e/2 e/3 e/4 e/5 e/6] |
| | 1074 | if e/type = 'move [ |
| | 1075 | ;** because of the timer, 'move events are received, even if there is no move |
| | 1076 | if all [find [info-position recycle] f/ask f/move-offset <> e/offset][ |
| | 1077 | f/ask: 'info-position |
| | 1078 | f/delay: 2 |
| | 1079 | f/move-offset: e/offset |
| | 1080 | ] |
| | 1081 | return false |
| | 1082 | ] |
| | 1083 | e |
| | 1084 | ] |
| | 1085 | engage: func [f a e /local key tmp cursor select?][ |
| | 1086 | ;**print remold [a e/type e/key e/1 e/2 e/3 e/4 e/5 e/6] |
| | 1087 | if a = 'time [ |
| | 1088 | ;print [now/time f/ask f/delay] |
| | 1089 | either find [recycle info-position] f/ask [ |
| | 1090 | f/cursor/blink-color: get first reverse [red none] |
| | 1091 | show f/cursor |
| | 1092 | ][f/cursor/blink-color: red] |
| | 1093 | case [ |
| | 1094 | 0 > f/delay: f/delay - 1 [ |
| | 1095 | ;** if f/ask <> 'show [print ["timer:" now/time f/ask] ] |
| | 1096 | switch f/ask [ |
| | 1097 | show [] |
| | 1098 | recycle [recycle] |
| | 1099 | ] |
| | 1100 | f/ask: 'recycle |
| | 1101 | f/rate: 1 ;** default rate, 1 event per second |
| | 1102 | f/delay: 5 ;** recycle after 5 secs of inactivity |
| | 1103 | show f ;** DON't remove the show here (needed to update the face rate) |
| 1120 | | ] |
| 1121 | | return false |
| 1122 | | ] |
| 1123 | | select?: cursor/selection? |
| 1124 | | unless find [up down] key: e/key [f/save-x: 0] |
| 1125 | | if f/ask <> 'show [f/ask: 'info-cursor f/delay: 3] |
| 1126 | | cursor/blink-color: red |
| 1127 | | |
| 1128 | | if all [e/5 not select? any [word? key key < #" "]][ |
| 1129 | | select?: true |
| 1130 | | begin-selection cursor |
| 1131 | | ] |
| 1132 | | switch a [ |
| 1133 | | down [click f e/offset] |
| 1134 | | key [ |
| 1135 | | ;** e/6 = true for ctrl |
| 1136 | | switch/default key[ |
| 1137 | | page-up [render-text f negate f/nb-lines] |
| 1138 | | page-down [render-text f f/nb-lines] |
| 1139 | | #"^P" [inc-font-size f 1] ;** increase font size |
| 1140 | | #"^L" [inc-font-size f -1] ;** decrease font size |
| 1141 | | #"^B" [bold f] |
| | 1106 | return false |
| | 1107 | ] |
| | 1108 | cursor: f/cursor |
| | 1109 | select?: cursor/selection? |
| | 1110 | |
| | 1111 | if f/ask <> 'show [f/ask: 'info-cursor f/delay: 3] |
| | 1112 | cursor/blink-color: red |
| | 1113 | unless find [up down] key: e/key [save-x: 0] |
| | 1114 | if all [e/5 not select? any [word? key key < #" "]][ |
| | 1115 | select?: true |
| | 1116 | begin-selection cursor |
| | 1117 | ] |
| | 1118 | |
| | 1119 | switch a [ |
| | 1120 | down [click f e/offset] |
| | 1121 | key [ |
| | 1122 | ;probe key |
| | 1123 | ;** e/6 = true for ctrl |
| | 1124 | switch/default key[ |
| | 1125 | page-up [render-text f negate f/nb-lines] |
| | 1126 | page-down [render-text f f/nb-lines] |
| | 1127 | #"^P" [inc-font-size f 1] ;** increase font size |
| | 1128 | #"^L" [inc-font-size f -1] ;** decrease font size |
| | 1129 | #"^B" [bold f] |
| | 1130 | ][ |
| | 1131 | locate-cursor cursor |
| | 1132 | ] |
| | 1133 | switch/default key [ |
| | 1134 | #"^M" [split-line f] |
| | 1135 | #"^[" [] |
| | 1136 | #"^~" [ ;** delete |
| | 1137 | either select? [ |
| | 1138 | do-selection/delete f |
| | 1139 | ][ |
| | 1140 | delete-char cursor |
| | 1141 | recolorize cursor |
| | 1142 | show f |
| | 1143 | ] |
| | 1144 | ] |
| | 1145 | #"^H" [ ;** backtab |
| | 1146 | either select? [ |
| | 1147 | do-selection/delete f |
| | 1148 | ][ |
| | 1149 | move-cursor/left cursor |
| | 1150 | delete-char cursor |
| | 1151 | recolorize cursor |
| | 1152 | show f |
| | 1153 | ] |
| | 1154 | ] |
| | 1155 | right [ |
| | 1156 | either e/6 [ |
| | 1157 | right-word cursor |
| | 1158 | ][ |
| | 1159 | move-cursor/right cursor |
| | 1160 | ] |
| | 1161 | show cursor ] |
| | 1162 | left [ |
| | 1163 | either e/6 [ |
| | 1164 | left-word cursor |
| | 1165 | ][ |
| | 1166 | move-cursor/left cursor |
| | 1167 | ] |
| | 1168 | show cursor |
| | 1169 | ] |
| | 1170 | ;page-up [render-text f negate f/nb-lines] |
| | 1171 | ;page-down [render-text f f/nb-lines] |
| | 1172 | down [down-cursor cursor] |
| | 1173 | up [up-cursor cursor] |
| | 1174 | end [ |
| | 1175 | constraint f as-pair 100000 cursor/xy/y |
| | 1176 | show cursor |
| | 1177 | ] |
| | 1178 | home [ |
| | 1179 | constraint f as-pair f/origine-x + f/xy/x cursor/xy/y |
| | 1180 | show cursor |
| | 1181 | ] |
| | 1182 | #"^S" [ if request "Save file ? " [ f/save-file] ] |
| | 1183 | #"^O" [ if request "Open a file?" [ f/open-file none]] |
| | 1184 | #"^N" [ if request "Start a new file?" [f/data: build-data "" f render-text/stay f 1 ]] |
| | 1185 | ;#"^P" [inc-font-size f 1] ;** increase font size |
| | 1186 | ;#"^L" [inc-font-size f -1] ;** decrease font size |
| | 1187 | #"^C" [do-selection/clip f] |
| | 1188 | #"^X" [do-selection/clip/delete f] |
| | 1189 | #"^V" [;** TO-DO insert multi-lines text |
| | 1190 | insert-char f/cursor tmp: first parse read clipboard:// "^/" |
| | 1191 | show f |
| | 1192 | ] |
| | 1193 | #"^F" [ view/new search-win ] ;[t/search f] |
| | 1194 | #"^G" [ view/new goto-win ] |
| | 1195 | ][ |
| | 1196 | if all [char? key find key-to-insert key ][ |
| | 1197 | if select? [ |
| | 1198 | do-selection/delete f |
| | 1199 | ] |
| | 1200 | ;** insert a char |
| | 1201 | locate-cursor f/cursor |
| | 1202 | insert-char f/cursor e/key |
| | 1203 | recolorize f/cursor |
| | 1204 | ;** auto-scroll horizontaly |
| | 1205 | if f/x * 10 + cursor/xy/x > f/size/x [ |
| | 1206 | scroll-x f f/x * 10 |
| | 1207 | ] |
| | 1208 | show f |
| | 1209 | ] |
| | 1210 | ] |
| | 1211 | ] |
| | 1212 | ] |
| | 1213 | if select? [ |
| | 1214 | either any [e/5 e/6 a = 'up] [ |
| | 1215 | expand-selector cursor |
| | 1217 | remove-selector cursor |
| | 1218 | ] |
| | 1219 | show f |
| | 1220 | ] |
| | 1221 | ] |
| | 1222 | |
| | 1223 | bold: func [f][ |
| | 1224 | f/font-obj/style: either f/font-obj/style [none]['bold] |
| | 1225 | inc-font-size f 0 |
| | 1226 | ] |
| | 1227 | |
| | 1228 | split-line: func [f /local tmp str blanks][ |
| | 1229 | insert-char f/cursor "^/" |
| | 1230 | |
| | 1231 | tmp: at f/data f/cursor/idx |
| | 1232 | str: tmp/1/2 |
| | 1233 | |
| | 1234 | blanks: copy/part str find str any-char |
| | 1235 | insert str: find/tail str newline blanks |
| | 1236 | insert/only next tmp reduce [0 str 0x0] |
| | 1237 | |
| | 1238 | render-text/stay f f/cursor/idx |
| | 1239 | replace/all blanks tab " " |
| | 1240 | f/cursor/xy/x: f/origine-x + f/xy/x + (f/x * length? blanks) |
| | 1241 | down-cursor f/cursor |
| | 1242 | save-x: 0 |
| | 1243 | ] |
| | 1244 | |
| | 1245 | inc-font-size: func [f inc /local tmp][ |
| | 1246 | f/font-obj/size: max 10 min 30 f/font-obj/size + inc |
| | 1247 | f/origine-x: f/origine-x / f/x |
| | 1248 | f/xy/x: f/xy/x / f/x |
| | 1249 | ;this is didec way used to compute the X size of a char on screen |
| | 1250 | fa: make face [ font: f/font-obj text: "MM" |
| | 1251 | size: 100x100 para: make face/para [origin: 0x0 margin: 0x0] |
| | 1252 | edge: make face/edge [size: 0x0]] |
| | 1253 | tx-test: fa/text |
| | 1254 | forall tx-test [ |
| | 1255 | tmp: caret-to-offset fa tx-test |
| | 1256 | ;probe tmp |
| | 1257 | ] |
| | 1258 | ; we use size-tex for Y size of a char on screen |
| | 1259 | tmp2: size-text fa |
| | 1260 | ;probe tmp2 |
| | 1261 | tmp/y: tmp2/y |
| | 1262 | ;f/x: round to integer! tmp/x / 2 |
| | 1263 | f/x: to integer! tmp/x |
| | 1264 | f/y: tmp/y + 4 ; make the margin more spaced and easier to read |
| | 1265 | f/xy/x: f/xy/x * f/x |
| | 1266 | f/origine-x: f/origine-x * f/x |
| | 1267 | f/cursor/size/y: f/y |
| | 1268 | f/cursor/size-box/y: f/y - 2 |
| | 1269 | tmp: f/cursor/xy |
| | 1270 | resize f 0 |
| | 1271 | click f tmp |
| | 1272 | ] |
| | 1273 | |
| | 1274 | do-selection: func [ |
| | 1275 | f |
| | 1276 | /delete /clip |
| | 1277 | /local cursor data idx old-idx start end str start-col end-col scroll n y |
| | 1278 | ][ |
| | 1279 | cursor: f/cursor |
| | 1280 | if clip [clip: make string! 256] |
| | 1281 | idx: cursor/global-idx |
| | 1282 | old-idx: cursor/old-idx |
| | 1283 | get-col cursor |
| | 1284 | either old-idx < idx [ |
| | 1285 | set [start end] reduce [old-idx idx] |
| | 1286 | set [start-col end-col] reduce [cursor/old-col cursor/col] |
| | 1287 | either start < index? f/data [ |
| | 1288 | scroll: start - index? f/data |
| | 1289 | n: -1 + min start to-integer f/nb-lines / 2 |
| | 1290 | scroll: scroll - n |
| | 1291 | y: n * f/y + 2 |
| | 1292 | ][ |
| | 1293 | y: cursor/xy/y +(start - end * f/y) |
| | 1294 | ] |
| | 1295 | ][ |
| | 1296 | set [start end] reduce [idx old-idx] |
| | 1297 | set [start-col end-col] reduce [cursor/col cursor/old-col] |
| | 1298 | ] |
| | 1299 | data: at head f/data start |
| | 1300 | if start = end [ |
| | 1301 | set [start-col end-col] sort reduce [start-col end-col] |
| | 1302 | ] |
| | 1303 | if delete [ |
| 1158 | | #"^H" [ ;** backtab |
| 1159 | | either select? [ |
| 1160 | | do-selection/delete f |
| 1161 | | ][ |
| 1162 | | move-cursor/left cursor |
| 1163 | | delete-char cursor |
| 1164 | | recolorize cursor |
| 1165 | | ] |
| 1166 | | show f |
| 1167 | | ] |
| 1168 | | right [ |
| 1169 | | either e/6 [ |
| 1170 | | right-word cursor |
| 1171 | | ][ |
| 1172 | | move-cursor/right cursor |
| 1173 | | ] |
| 1174 | | show cursor ] |
| 1175 | | left [ |
| 1176 | | either e/6 [ |
| 1177 | | left-word cursor |
| 1178 | | ][ |
| 1179 | | move-cursor/left cursor |
| 1180 | | ] |
| 1181 | | show cursor |
| 1182 | | ] |
| 1183 | | down [down-cursor cursor] |
| 1184 | | up [up-cursor cursor] |
| 1185 | | end [ |
| 1186 | | constraint f as-pair 100000 cursor/xy/y |
| 1187 | | show cursor |
| 1188 | | ] |
| 1189 | | home [ |
| 1190 | | constraint f as-pair f/origine-x + f/xy/x cursor/xy/y |
| 1191 | | show cursor |
| 1192 | | ] |
| 1193 | | #"^S" [ if request "Save file ? " [ f/save-file] ] |
| 1194 | | #"^O" [ if request "Open a file?" [ f/open-file none]] |
| 1195 | | #"^N" [ if request "Start a new file?" [f/data: build-data "" f render-text/stay f 1 ]] |
| 1196 | | #"^C" [do-selection/clip f] |
| 1197 | | #"^X" [do-selection/clip/delete f] |
| 1198 | | #"^V" [;** TO-DO insert multi-lines text |
| 1199 | | insert-char f/cursor tmp: first parse read clipboard:// "^/" |
| 1200 | | show f |
| 1201 | | ] |
| 1202 | | #"^F" [ view/new search-win ] ;[t/search f] |
| 1203 | | #"^G" [ view/new goto-win ] |
| 1204 | | |
| 1205 | | ][ |
| 1206 | | if all [char? key find key-to-insert key ][ |
| 1207 | | insert-char f/cursor e/key |
| 1208 | | recolorize f/cursor |
| 1209 | | ;** auto-scroll horizontaly |
| 1210 | | if f/x * 10 + cursor/xy/x > f/size/x [ |
| 1211 | | scroll-x f f/x * 10 |
| 1212 | | ] |
| 1213 | | show f |
| 1214 | | ] |
| 1215 | | ] |
| 1216 | | ] |
| 1217 | | ] |
| 1218 | | if select? [ |
| 1219 | | either any [e/5 e/6 a = 'up] [ |
| 1220 | | expand-selector cursor |
| 1221 | | ][ |
| 1222 | | remove-selector cursor |
| 1223 | | ] |
| 1224 | | show f |
| 1225 | | ] |
| 1226 | | ] |
| 1227 | | bold: func [f][ |
| 1228 | | f/font-obj/style: either f/font-obj/style [none]['bold] |
| 1229 | | inc-font-size f 0 |
| 1230 | | ] |
| 1231 | | ;search: func [f][ |
| 1232 | | ; ;what: read clipboard:// |
| 1233 | | ;] |
| 1234 | | |
| 1235 | | split-line: func [f /local tmp str blanks][ |
| 1236 | | insert-char f/cursor "^/" |
| 1237 | | |
| 1238 | | tmp: at f/data f/cursor/idx |
| 1239 | | str: tmp/1/2 |
| 1240 | | |
| 1241 | | blanks: copy/part str find str any-char |
| 1242 | | insert str: find/tail str newline blanks |
| 1243 | | insert/only next tmp reduce [0 str 0x0] |
| 1244 | | |
| 1245 | | render-text/stay f f/cursor/idx |
| 1246 | | replace/all blanks tab " " |
| 1247 | | f/cursor/xy/x: f/origine-x + f/xy/x + (f/x * length? blanks) |
| 1248 | | down-cursor f/cursor |
| 1249 | | f/save-x: 0 |
| 1250 | | ] |
| 1251 | | |
| 1252 | | inc-font-size: func [f inc /local tmp][ |
| 1253 | | f/font-obj/size: max 10 min 30 f/font-obj/size + inc |
| 1254 | | f/origine-x: f/origine-x / f/x |
| 1255 | | f/xy/x: f/xy/x / f/x |
| 1256 | | tmp: size-text make face [ |
| 1257 | | text: "MM" |
| 1258 | | size: 300x300 |
| 1259 | | font: f/font-obj |
| 1260 | | para: f/para |
| 1261 | | ] |
| 1262 | | f/x: to integer! tmp/x / 2 |
| 1263 | | f/y: tmp/y + 2 |
| 1264 | | f/xy/x: f/xy/x * f/x |
| 1265 | | f/origine-x: f/origine-x * f/x |
| 1266 | | f/cursor/size/y: f/y |
| 1267 | | f/cursor/size-box/y: f/y - 2 |
| 1268 | | tmp: f/cursor/xy |
| 1269 | | resize f 0 |
| 1270 | | click f tmp |
| 1271 | | ] |
| 1272 | | |
| 1273 | | do-selection: func [ |
| 1274 | | f |
| 1275 | | /delete /clip |
| 1276 | | /local cursor data idx old-idx start end str start-col end-col scroll n y |
| 1277 | | ][ |
| 1278 | | cursor: f/cursor |
| 1279 | | if clip [clip: make string! 256] |
| 1280 | | idx: cursor/global-idx |
| 1281 | | old-idx: cursor/old-idx |
| 1282 | | get-col cursor |
| 1283 | | either old-idx < idx [ |
| 1284 | | set [start end] reduce [old-idx idx] |
| 1285 | | set [start-col end-col] reduce [cursor/old-col cursor/col] |
| 1286 | | either start < index? f/data [ |
| 1287 | | scroll: start - index? f/data |
| 1288 | | n: -1 + min start to-integer f/nb-lines / 2 |
| 1289 | | scroll: scroll - n |
| 1290 | | y: n * f/y + 2 |
| 1291 | | ][ |
| 1292 | | y: cursor/xy/y +(start - end * f/y) |
| 1293 | | ] |
| 1294 | | ][ |
| 1295 | | set [start end] reduce [idx old-idx] |
| 1296 | | set [start-col end-col] reduce [cursor/col cursor/old-col] |
| 1297 | | ] |
| 1298 | | data: at head f/data start |
| 1299 | | if start = end [ |
| 1300 | | set [start-col end-col] sort reduce [start-col end-col] |
| 1301 | | ] |
| 1302 | | if delete [ |
| 1303 | | locate-cursor cursor |
| 1304 | | delete: copy/part data/1/2 start-col - 1 |
| 1305 | | ] |
| 1306 | | loop end - start [ |
| 1307 | | if clip [ |
| 1308 | | append clip append copy/part at data/1/2 start-col |
| 1309 | | any [find data/1/2 newline tail data/1/2] |
| 1310 | | newline |
| 1311 | | |
| 1312 | | ] |
| 1313 | | either delete [remove data][data: next data] |
| 1314 | | start-col: 1 |
| 1315 | | ] |
| 1316 | | |
| 1317 | | str: data/1/2 |
| 1318 | | case/all [ |
| 1319 | | clip [ |
| 1320 | | append clip copy/part at str start-col at str end-col |
| 1321 | | write clipboard:// clip |
| 1322 | | clip: none |
| 1323 | | ] |
| 1324 | | delete [ |
| 1325 | | data/1/2: delete |
| 1326 | | case [ |
| 1327 | | scroll [render-text f scroll] |
| 1328 | | start <> end [render-text/stay f 1] |
| 1329 | | 'else [recolorize cursor] |
| 1330 | | ] |
| 1331 | | if y [cursor/xy/y: y] |
| 1332 | | constraint f cursor/xy |
| 1333 | | append delete copy/part at str end-col any [find str newline tail str] |
| 1334 | | recolorize cursor |
| 1335 | | ] |
| 1336 | | ] |
| 1337 | | ] |
| 1338 | | |
| 1339 | | click: func [f offset][ |
| 1340 | | ;** We don't use the focus function to avoid this dummy system caret (whe have our own) |
| 1341 | | unless same? system/view/focal-face f [ |
| 1342 | | if system/view/focal-face [unfocus] |
| 1343 | | system/view/focal-face: f |
| 1344 | | ] |
| 1345 | | constraint f either offset/x - f/xy/x < f/origine-x |
| 1346 | | [as-pair f/origine-x offset/y][offset] |
| 1347 | | show f/cursor |
| 1348 | | ] |
| 1349 | | expand-selector: func [ |
| 1350 | | cursor |
| | 1337 | ] |
| | 1338 | ] |
| | 1339 | ; f |
| | 1340 | ; /delete /clip |
| | 1341 | ; /local cursor data idx old-idx start end str start-len end-len |
| | 1342 | ; ][ |
| | 1343 | ; cursor: f/cursor |
| | 1344 | ; if clip [clip: make string! 256] |
| | 1345 | ; idx: cursor/global-idx |
| | 1346 | ; old-idx: cursor/old-idx |
| | 1347 | ; either old-idx <= idx [ |
| | 1348 | ; set [start end] reduce [old-idx idx] |
| | 1349 | ; set [start-len end-len] reduce [cursor/old-pos-len cursor/pos-len] |
| | 1350 | ; ][ |
| | 1351 | ; set [start end] reduce [idx old-idx] |
| | 1352 | ; set [start-len end-len] reduce [cursor/pos-len cursor/old-pos-len] |
| | 1353 | ; ] |
| | 1354 | ; data: at head f/data start |
| | 1355 | ; |
| | 1356 | ; ;**print [start-len end-len] |
| | 1357 | ; |
| | 1358 | ; if start <> end [ |
| | 1359 | ; str: data/1/2 |
| | 1360 | ; case [ |
| | 1361 | ; clip [append clip append copy/part skip str start-len any [find str newline tail str] newline] |
| | 1362 | ; delete [data/1/2: copy/part str start-len] |
| | 1363 | ; ] |
| | 1364 | ; data: next data |
| | 1365 | ; start-len: 0 |
| | 1366 | ; ] |
| | 1367 | ; loop end - start - 1 [ |
| | 1368 | ; case [ |
| | 1369 | ; clip [ |
| | 1370 | ; append clip append |
| | 1371 | ; copy/part data/1/2 any [find data/1/2 newline tail data/1/2] |
| | 1372 | ; newline |
| | 1373 | ; data: next data |
| | 1374 | ; ] |
| | 1375 | ; delete [remove data] |
| | 1376 | ; ] |
| | 1377 | ; ] |
| | 1378 | ; str: data/1/2 |
| | 1379 | ; case [ |
| | 1380 | ; clip [ |
| | 1381 | ; append clip copy/part skip str start-len skip str end-len |
| | 1382 | ; probe clip |
| | 1383 | ; write clipboard:// clip |
| | 1384 | ; clip: none |
| | 1385 | ; ] |
| | 1386 | ; delete [ |
| | 1387 | ; data/1/2: str: copy/part str any [find str newline tail str] |
| | 1388 | ; remove/part skip str start-len skip str end-len |
| | 1389 | ; render-text/stay f 1 |
| | 1390 | ; ] |
| | 1391 | ; ] |
| | 1392 | ; ] |
| | 1393 | |
| | 1394 | click: func [f offset][ |
| | 1395 | ;** We don't use the focus function to avoid this dummy system caret (whe have our own) |
| | 1396 | unless same? system/view/focal-face f [ |
| | 1397 | if system/view/focal-face [unfocus] |
| | 1398 | system/view/focal-face: f |
| | 1399 | ] |
| | 1400 | |
| | 1401 | constraint f either offset/x - f/xy/x < f/origine-x |
| | 1402 | [as-pair f/origine-x offset/y][offset] |
| | 1403 | show f/cursor |
| | 1404 | ] |
| | 1405 | expand-selector: func [ |
| | 1406 | cursor |
| 1421 | | insert-selector: func [f where x][ |
| 1422 | | ;** append an highlight box in the current block at relative x position |
| 1423 | | change/only where |
| 1424 | | compose [pen 255.200.10 fill-pen 250.200.10 box (as-pair x 7) (as-pair x f/y + 7)] |
| 1425 | | ] |
| 1426 | | remove-selector: func [cursor /local f tmp][ |
| 1427 | | cursor/selection?: false |
| 1428 | | parse cursor/parent-face/effect/draw [ |
| 1429 | | any [thru 'push into ['hilight tmp: (change tmp none) to end]] |
| 1430 | | ] |
| 1431 | | ] |
| 1432 | | left-word: func [cursor /local f x str blk pos s-blk][ |
| 1433 | | f: cursor/parent-face |
| 1434 | | str: get-sub-string cursor |
| 1435 | | blk: skip s-blk: cursor/pos-blk -2 |
| 1436 | | |
| 1437 | | case [ |
| 1438 | | find/reverse blk 'edit none ;** not head of line |
| 1439 | | not head? str none ;** neither |
| 1440 | | 'else [ |
| 1441 | | cursor/xy/x: 100000 |
| 1442 | | if up-cursor cursor [left-word cursor] |
| 1443 | | exit |
| 1444 | | ] |
| 1445 | | ] |
| 1446 | | x: 0 |
| 1447 | | foreach stuff reduce [any-char space][ |
| 1448 | | while [ |
| 1449 | | all [ |
| 1450 | | not find/reverse str stuff |
| 1451 | | blk |
| 1452 | | blk: find/reverse blk 'edit |
| 1453 | | ] |
| 1454 | | ][ |
| 1455 | | x: x - 1 + index? str |
| 1456 | | str: tail get* blk/3 |
| 1457 | | ] |
| 1458 | | x: x - length? str |
| 1459 | | str: any [find/reverse str stuff str] |
| 1460 | | x: x + length? str |
| 1461 | | ] |
| 1462 | | either str/1 = #" " [x: x - 1][x: x + (index? str) - index? head str] |
| 1463 | | if x = 0 [x: -1 + index? str] |
| 1464 | | constraint f cursor/xy + as-pair x * negate f/x 0 |
| 1465 | | ] |
| 1466 | | |
| 1467 | | get-sub-string: func [cursor][ |
| 1468 | | at head do back change [none] cursor/sub-string cursor/pos-len |
| 1469 | | ] |
| 1470 | | |
| 1471 | | right-word: func [cursor /local f x str blk pos][ |
| 1472 | | f: cursor/parent-face |
| 1473 | | blk: s-blk: cursor/pos-blk |
| 1474 | | str: get-sub-string cursor |
| 1475 | | |
| 1476 | | case [ |
| 1477 | | find blk 'edit none ;** not tail of line |
| 1478 | | not tail? str none ;** neither |
| 1479 | | 'else [ |
| 1480 | | cursor/xy/x: f/origine-x + f/xy/x |
| 1481 | | if down-cursor cursor [right-word cursor] |
| 1482 | | exit |
| 1483 | | ] |
| 1484 | | ] |
| 1485 | | x: 0 |
| 1486 | | foreach stuff reduce [space any-char][ |
| 1487 | | while [ |
| 1488 | | all [ |
| 1489 | | not find str stuff |
| 1490 | | blk |
| 1491 | | blk: find/tail blk 'edit |
| 1492 | | ] |
| 1493 | | ][ |
| 1494 | | x: x + length? str |
| 1495 | | str: get* blk/2 |
| 1496 | | ] |
| 1497 | | x: x - index? str |
| 1498 | | str: any [find str stuff str] |
| 1499 | | x: x + index? str |
| 1500 | | ] |
| 1501 | | if str/1 = #" " [x: x + length? str] |
| 1502 | | if x = 0 [x: length? str] |
| 1503 | | constraint f cursor/xy + as-pair x * f/x 0 |
| 1504 | | ] |
| 1505 | | |
| 1506 | | scroll-x: func [f x][ |
| 1507 | | f/h-scroller/feel/drag f/h-scroller as-pair x 0 |
| 1508 | | ] |
| 1509 | | |
| 1510 | | locate-cursor: func [cursor /local x idx f][ |
| 1511 | | f: cursor/parent-face |
| 1512 | | unless cursor/show? [ |
| 1513 | | either (idx: cursor/global-idx) < index? f/data [ |
| 1514 | | render-text f idx - index? f/data |
| 1515 | | ][ |
| 1516 | | render-text f idx - f/nb-lines + 1 - index? f/data |
| 1517 | | ] |
| 1518 | | ] |
| 1519 | | x: cursor/xy/x |
| 1520 | | if any [ |
| 1521 | | x > (f/size/x - f/x) |
| 1522 | | x < f/x |
| 1523 | | ][scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x ] |
| 1524 | | ] |
| 1525 | | |
| 1526 | | |
| 1527 | | move-cursor: func [ |
| 1528 | | cursor |
| 1529 | | /left /right |
| 1530 | | /local f pos offset len |
| 1531 | | ][ |
| 1532 | | f: cursor/parent-face |
| 1533 | | ;** locate-cursor cursor |
| 1534 | | ;** print remold [cursor/pos-len cursor/sub-string] |
| 1535 | | case [ |
| 1536 | | left [ |
| 1537 | | if len: either string? cursor/sub-string [ |
| 1538 | | either cursor/pos-len = 1 [1][ |
| 1539 | | cursor/pos-len: cursor/pos-len - 1 |
| 1540 | | cursor/sub-string: back cursor/sub-string |
| 1541 | | cursor/xy/x: cursor/xy/x - f/x |
| 1542 | | false |
| | 1477 | insert-selector: func [f where x][ ;** append an highlight box in the current block at relative x position |
| | 1478 | change/only where |
| | 1479 | compose [pen 255.200.10 fill-pen 250.200.10 box (as-pair x 7) (as-pair x f/y + 7)] |
| | 1480 | ] |
| | 1481 | remove-selector: func [cursor /local f tmp][ |
| | 1482 | cursor/selection?: false |
| | 1483 | parse cursor/parent-face/effect/draw [ |
| | 1484 | any [thru 'push into ['hilight tmp: (change tmp none) to end]] |
| | 1485 | ] |
| | 1486 | ] |
| | 1487 | left-word: func [cursor /local f x str blk pos s-blk][ |
| | 1488 | f: cursor/parent-face |
| | 1489 | str: get-sub-string cursor |
| | 1490 | blk: skip s-blk: cursor/pos-blk -2 |
| | 1491 | |
| | 1492 | case [ |
| | 1493 | find/reverse blk 'edit none ;** not head of line |
| | 1494 | not head? str none ;** neither |
| | 1495 | 'else [ |
| | 1496 | cursor/xy/x: 100000 |
| | 1497 | if up-cursor cursor [left-word cursor] |
| | 1498 | exit |
| | 1499 | ] |
| | 1500 | ] |
| | 1501 | x: 0 |
| | 1502 | foreach stuff reduce [any-char space][ |
| | 1503 | while [ |
| | 1504 | all [ |
| | 1505 | not find/reverse str stuff |
| | 1506 | blk |
| | 1507 | blk: find/reverse blk 'edit |
| 1551 | | either pos: find/tail/reverse skip cursor/pos-blk -2 'edit [ |
| 1552 | | either string? pos/2 [ |
| 1553 | | len: length? pos/2 |
| 1554 | | cursor/sub-string: at pos/2 len |
| | 1549 | x: x + length? str |
| | 1550 | str: get* blk/2 |
| | 1551 | ] |
| | 1552 | x: x - index? str |
| | 1553 | str: any [find str stuff str] |
| | 1554 | x: x + index? str |
| | 1555 | ] |
| | 1556 | if str/1 = #" " [x: x + length? str] |
| | 1557 | if x = 0 [x: length? str] |
| | 1558 | constraint f cursor/xy + as-pair x * f/x 0 |
| | 1559 | ] |
| | 1560 | |
| | 1561 | scroll-x: func [f x][ |
| | 1562 | f/h-scroller/feel/drag f/h-scroller as-pair x 0 |
| | 1563 | ] |
| | 1564 | |
| | 1565 | locate-cursor: func [cursor /local x idx f][ |
| | 1566 | f: cursor/parent-face |
| | 1567 | unless cursor/show? [ |
| | 1568 | either (idx: cursor/global-idx) < index? f/data [ |
| | 1569 | render-text f idx - index? f/data |
| | 1570 | ][ |
| | 1571 | render-text f idx - f/nb-lines + 1 - index? f/data |
| | 1572 | ] |
| | 1573 | ] |
| | 1574 | x: cursor/xy/x |
| | 1575 | if any [ |
| | 1576 | x > (f/size/x - f/x) |
| | 1577 | x < f/x |
| | 1578 | ][scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x ] |
| | 1579 | ] |
| | 1580 | |
| | 1581 | |
| | 1582 | move-cursor: func [ |
| | 1583 | cursor |
| | 1584 | /left /right |
| | 1585 | /local f pos offset len |
| | 1586 | ][ |
| | 1587 | f: cursor/parent-face |
| | 1588 | locate-cursor cursor |
| | 1589 | ;** print remold [cursor/pos-len cursor/sub-string] |
| | 1590 | case [ |
| | 1591 | left [ |
| | 1592 | if len: either string? cursor/sub-string [ |
| | 1593 | either cursor/pos-len = 1 [1][ |
| | 1594 | cursor/pos-len: cursor/pos-len - 1 |
| | 1595 | cursor/sub-string: back cursor/sub-string |
| | 1596 | cursor/xy/x: cursor/xy/x - f/x |
| | 1597 | false |
| | 1598 | ] |
| | 1599 | ][ |
| | 1600 | either cursor/pos-len = 1 [1][ |
| | 1601 | cursor/pos-len: 1 |
| | 1602 | cursor/xy/x: cursor/xy/x - (f/x * length? get cursor/sub-string) |
| | 1603 | false |
| | 1604 | ] |
| | 1605 | ][ |
| | 1606 | either pos: find/tail/reverse skip cursor/pos-blk -2 'edit [ |
| | 1607 | either string? pos/2 [ |
| | 1608 | len: length? pos/2 |
| | 1609 | cursor/sub-string: at pos/2 len |
| | 1610 | ][ |
| | 1611 | cursor/sub-string: pos/2 |
| | 1612 | ] |
| | 1613 | cursor/pos-len: len |
| | 1614 | cursor/xy/x: pos/1/1 + (len - 1 * f/x) |
| | 1615 | cursor/pos-blk: skip pos 1 |
| 1568 | | ] |
| 1569 | | right [ |
| 1570 | | if len: either string? cursor/sub-string [ |
| 1571 | | either tail? cursor/sub-string [2][ |
| 1572 | | cursor/pos-len: cursor/pos-len + 1 |
| 1573 | | cursor/sub-string: next cursor/sub-string |
| 1574 | | cursor/xy/x: cursor/xy/x + f/x |
| 1575 | | false |
| | 1624 | right [ |
| | 1625 | if len: either string? cursor/sub-string [ |
| | 1626 | either tail? cursor/sub-string [2][ |
| | 1627 | cursor/pos-len: cursor/pos-len + 1 |
| | 1628 | cursor/sub-string: next cursor/sub-string |
| | 1629 | cursor/xy/x: cursor/xy/x + f/x |
| | 1630 | false |
| | 1631 | ] |
| | 1632 | ][ |
| | 1633 | either cursor/pos-len > 1 [2][ |
| | 1634 | cursor/pos-len: index? tail get cursor/sub-string |
| | 1635 | cursor/xy/x: cursor/xy/x + (f/x * length? get cursor/sub-string) |
| | 1636 | false |
| | 1637 | ] |
| | 1638 | ][ |
| | 1639 | either pos: find/tail cursor/pos-blk 'edit [ |
| | 1640 | either string? pos/2 [ |
| | 1641 | cursor/sub-string: at pos/2 len |
| | 1642 | ][ |
| | 1643 | len: index? tail get pos/2 |
| | 1644 | cursor/sub-string: pos/2 |
| | 1645 | ] |
| | 1646 | cursor/pos-len: len |
| | 1647 | cursor/xy/x: pos/1/1 + (len - 1 * f/x) |
| | 1648 | cursor/pos-blk: skip pos 1 |
| | 1649 | ][ |
| | 1650 | if cursor/global-idx < index? back tail f/data [ |
| | 1651 | cursor/xy/x: f/origine-x + f/xy/x |
| | 1652 | down-cursor cursor |
| | 1653 | ] |
| | 1654 | ] |
| | 1655 | ] |
| | 1656 | ] |
| | 1657 | ] |
| | 1658 | ] |
| | 1659 | delay-show: func [f][ |
| | 1660 | f/ask: 'show ;** delay the show event, speed issue |
| | 1661 | f/delay: 1 ; wait 2 checks |
| | 1662 | f/rate: 10 ; check 10 times per second |
| | 1663 | ] |
| | 1664 | down-cursor: func [cursor /local p tmp][ |
| | 1665 | p: cursor/parent-face |
| | 1666 | if cursor/global-idx < index? back tail p/data [ |
| | 1667 | if cursor/idx = p/nb-lines [ |
| | 1668 | delay-show p |
| | 1669 | render-text p 1 |
| | 1670 | ] |
| | 1671 | tmp: cursor/xy + third cursor/data |
| | 1672 | if save-x = 0 [save-x: tmp/x] |
| | 1673 | constraint p as-pair save-x tmp/y |
| | 1674 | unless p/ask = 'show [show cursor] |
| | 1675 | true |
| | 1676 | ] |
| | 1677 | ] |
| | 1678 | up-cursor: func [cursor /local p tmp][ |
| | 1679 | p: cursor/parent-face |
| | 1680 | if cursor/global-idx > 1 [ |
| | 1681 | if cursor/idx = 1 [ |
| | 1682 | delay-show p |
| | 1683 | render-text p -1 |
| | 1684 | ] |
| | 1685 | tmp: cursor/xy - pick cursor/data -2 |
| | 1686 | if save-x = 0 [save-x: tmp/x] |
| | 1687 | constraint p as-pair save-x tmp/y |
| | 1688 | unless p/ask = 'show [show cursor] |
| | 1689 | true |
| | 1690 | ] |
| | 1691 | ] |
| | 1692 | |
| | 1693 | insert-char: func [cursor char /local f text refresh?][ |
| | 1694 | f: cursor/parent-face |
| | 1695 | if cursor/selection? [ |
| | 1696 | do-selection/delete f |
| | 1697 | locate-cursor cursor |
| | 1698 | refresh?: true |
| | 1699 | ] |
| | 1700 | text: cursor/sub-string |
| | 1701 | either string? text [ |
| | 1702 | insert text char |
| | 1703 | ][ |
| | 1704 | insert insert |
| | 1705 | either cursor/pos-len = 1 [cursor/pos-blk][next cursor/pos-blk] |
| | 1706 | 'new |
| | 1707 | char |
| | 1708 | ] |
| | 1709 | collect cursor |
| | 1710 | cursor/xy/x: cursor/xy/x + either char = tab [4 * f/x][f/x * length? form char] |
| | 1711 | |
| | 1712 | if refresh? [ |
| | 1713 | render-text/stay f 1 |
| | 1714 | constraint f cursor/xy |
| | 1715 | ] |
| | 1716 | |
| | 1717 | ; f: cursor/parent-face |
| | 1718 | ; text: cursor/sub-string |
| | 1719 | ; either string? text [ |
| | 1720 | ; insert text char |
| | 1721 | ; ][ |
| | 1722 | ; insert insert |
| | 1723 | ; either cursor/pos-len = 1 [cursor/pos-blk][next cursor/pos-blk] |
| | 1724 | ; 'new |
| | 1725 | ; char |
| | 1726 | ; ] |
| | 1727 | ; collect cursor |
| | 1728 | ; cursor/xy/x: cursor/xy/x + either char = tab [4 * f/x][f/x] |
| | 1729 | ; if f/x * 10 + cursor/xy/x > f/size/x [ |
| | 1730 | ; scroll-x f f/x * 10 |
| | 1731 | ; ] |
| | 1732 | ] |
| | 1733 | |
| | 1734 | delete-char: func [cursor /local pos f data str1 str2 end][ |
| | 1735 | text: cursor/sub-string |
| | 1736 | unless either string? text [ |
| | 1737 | unless tail? text [remove text] |
| | 1738 | ][ |
| | 1739 | if cursor/pos-len = 1 [remove back cursor/pos-blk] ;**remove the offset |
| | 1740 | ][ |
| | 1741 | either pos: find/tail cursor/pos-blk 'edit [ |
| | 1742 | either string? pos/2 [ |
| | 1743 | remove pos/2 |
| | 1744 | ][ |
| | 1745 | remove pos ;** remove the offset |
| 1578 | | either cursor/pos-len > 1 [2][ |
| 1579 | | cursor/pos-len: 1 + length? get cursor/sub-string |
| 1580 | | cursor/xy/x: cursor/xy/x + (f/x * length? get cursor/sub-string) |
| 1581 | | false |
| 1582 | | ] |
| 1583 | | ][ |
| 1584 | | either pos: find/tail cursor/pos-blk 'edit [ |
| 1585 | | either string? pos/2 [ |
| 1586 | | cursor/sub-string: at pos/2 len |
| 1587 | | ][ |
| 1588 | | len: 1 + length? get pos/2 |
| 1589 | | cursor/sub-string: pos/2 |
| 1590 | | ] |
| 1591 | | cursor/pos-len: len |
| 1592 | | cursor/xy/x: pos/1/1 + (len - 1 * f/x) |
| 1593 | | cursor/pos-blk: skip pos 1 |
| 1594 | | ][ |
| 1595 | | if cursor/global-idx < index? back tail f/data [ |
| 1596 | | cursor/xy/x: f/origine-x + f/xy/x |
| 1597 | | down-cursor cursor |
| 1598 | | ] |
| 1599 | | ] |
| 1600 | | ] |
| 1601 | | ] |
| 1602 | | ] |
| 1603 | | ] |
| 1604 | | delay-show: func [f][ |
| 1605 | | f/ask: 'show ;** delay the show event, speed issue |
| 1606 | | f/delay: 1 ; wait 2 checks |
| 1607 | | f/rate: 10 ; check 10 times per second |
| 1608 | | ] |
| 1609 | | down-cursor: func [cursor /local f tmp][ |
| 1610 | | f: cursor/parent-face |
| 1611 | | if cursor/global-idx < index? back tail f/data [ |
| 1612 | | if cursor/idx = f/nb-lines [ |
| 1613 | | delay-show f |
| 1614 | | render-text f 1 |
| 1615 | | ] |
| 1616 | | tmp: cursor/xy + third cursor/data |
| 1617 | | if f/save-x = 0 [f/save-x: tmp/x] |
| 1618 | | constraint f as-pair f/save-x tmp/y |
| 1619 | | unless f/ask = 'show [show cursor] |
| 1620 | | true |
| 1621 | | ] |
| 1622 | | ] |
| 1623 | | up-cursor: func [cursor /local f tmp][ |
| 1624 | | f: cursor/parent-face |
| 1625 | | if cursor/global-idx > 1 [ |
| 1626 | | if cursor/idx = 1 [ |
| 1627 | | delay-show f |
| 1628 | | render-text f -1 |
| 1629 | | ] |
| 1630 | | tmp: cursor/xy - pick cursor/data -2 |
| 1631 | | if f/save-x = 0 [f/save-x: tmp/x] |
| 1632 | | constraint f as-pair f/save-x tmp/y |
| 1633 | | unless f/ask = 'show [show cursor] |
| 1634 | | true |
| 1635 | | ] |
| 1636 | | ] |
| 1637 | | |
| 1638 | | insert-char: func [cursor char /local f text refresh?][ |
| 1639 | | f: cursor/parent-face |
| 1640 | | if cursor/selection? [ |
| 1641 | | do-selection/delete f |
| 1642 | | locate-cursor cursor |
| 1643 | | refresh?: true |
| 1644 | | ] |
| 1645 | | text: cursor/sub-string |
| 1646 | | either string? text [ |
| 1647 | | insert text char |
| 1648 | | ][ |
| 1649 | | insert insert |
| 1650 | | either cursor/pos-len = 1 [cursor/pos-blk][next cursor/pos-blk] |
| 1651 | | 'new |
| 1652 | | char |
| 1653 | | ] |
| 1654 | | collect cursor |
| 1655 | | cursor/xy/x: cursor/xy/x + either char = tab [4 * f/x][f/x * length? form char] |
| 1656 | | if refresh? [ |
| 1657 | | render-text/stay f 1 |
| 1658 | | constraint f cursor/xy |
| 1659 | | ] |
| 1660 | | ] |
| 1661 | | |
| 1662 | | delete-char: func [cursor /local pos f data str1 str2 end][ |
| 1663 | | text: cursor/sub-string |
| 1664 | | unless either string? text [ |
| 1665 | | unless tail? text [remove text] |
| 1666 | | ][ |
| 1667 | | if cursor/pos-len = 1 [remove back cursor/pos-blk] ;**remove the offset |
| 1668 | | ][ |
| 1669 | | either pos: find/tail cursor/pos-blk 'edit [ |
| 1670 | | either string? pos/2 [ |
| 1671 | | remove pos/2 |
| 1672 | | ][ |
| 1673 | | remove pos ;** remove the offset |
| 1674 | | ] |
| 1675 | | ][ |
| 1676 | | regroup-2-lines cursor |
| 1677 | | exit |
| 1678 | | ] |
| 1679 | | ] |
| 1680 | | |
| 1681 | | collect cursor |
| 1682 | | ] |
| 1683 | | get-col: func [cursor /local col pos][ |
| | 1748 | regroup-2-lines cursor |
| | 1749 | exit |
| | 1750 | ] |
| | 1751 | ] |
| | 1752 | |
| | 1753 | collect cursor |
| | 1754 | ] |
| | 1755 | get-col: func [cursor /local col pos][ |
| 1695 | | |
| 1696 | | collect: func [cursor /local full txt pos][ |
| 1697 | | full: clear {} |
| 1698 | | add-full: [(full: insert full either word? txt [#"^-"][txt])] |
| 1699 | | parse cursor/data/1 [ |
| 1700 | | any [thru 'edit opt [ |
| 1701 | | pair! |
| 1702 | | opt ['new set txt skip add-full] |
| 1703 | | set txt skip add-full |
| 1704 | | opt ['new set txt skip add-full] |
| 1705 | | ]] |
| 1706 | | ] |
| 1707 | | poke first at cursor/parent-face/data cursor/idx 2 copy head full |
| 1708 | | ] |
| 1709 | | regroup-2-lines: func [cursor /local f][ |
| 1710 | | f: cursor/parent-face |
| 1711 | | data: at head f/data cursor/global-idx |
| 1712 | | unless tail? next data [ |
| 1713 | | str1: either end: find data/1/2 newline [copy/part data/1/2 end][data/1/2] |
| 1714 | | str2: either end: find data/2/2 newline [copy/part data/2/2 end][data/2/2] |
| 1715 | | append str1 str2 |
| 1716 | | poke data/1 2 str1 |
| 1717 | | remove next data |
| 1718 | | render-text/stay f cursor/idx |
| 1719 | | ] |
| 1720 | | ] |
| 1721 | | |
| 1722 | | ;*** Reconstruct a line (draw block) after an insert |
| 1723 | | ;*** (which contains modified sub-strings) |
| 1724 | | ;* if the line contains a multi-line string, then other lines below |
| 1725 | | ;* may be reconstructed too. |
| 1726 | | recolorize: func [ |
| 1727 | | cursor |
| 1728 | | /local line f multi-p multi data pos-head |
| 1729 | | ][ |
| 1730 | | f: cursor/parent-face |
| 1731 | | data: cursor/data |
| 1732 | | line: at f/data cursor/idx |
| 1733 | | |
| 1734 | | change skip data 2 |
| 1735 | | either colorize f line clear find/tail data/1 string! |
| 1736 | | [as-pair 0 2 * f/y][as-pair 0 f/y] |
| 1737 | | |
| 1738 | | loop f/nb-lines - cursor/idx [ |
| 1739 | | if tail? next line [break] |
| 1740 | | |
| 1741 | | multi-p: line/1/1 |
| 1742 | | multi: line/2/1 |
| 1743 | | if any [ |
| 1744 | | all [find [1 2] multi-p find [1 3] multi] |
| 1745 | | all [find [3 4] multi-p find [2 4] multi] |
| 1746 | | ][break] |
| 1747 | | |
| 1748 | | data: find/tail data 'push |
| 1749 | | line: next line |
| 1750 | | change skip data 2 |
| 1751 | | either colorize f line clear find/tail data/1 string! |
| | 1767 | collect: func [cursor /local full txt pos len][ |
| | 1768 | full: clear {} |
| | 1769 | len: 0 |
| | 1770 | add-full: [( |
| | 1771 | len: len + either char? txt [1][length? get* txt] |
| | 1772 | full: insert full either word? txt [#"^-"][txt] |
| | 1773 | )] |
| | 1774 | parse cursor/data/1 [ |
| | 1775 | any [thru 'edit opt [ |
| | 1776 | pair! |
| | 1777 | opt ['new set txt skip add-full] |
| | 1778 | set txt skip add-full |
| | 1779 | opt ['new set txt skip add-full] |
| | 1780 | ]] |
| | 1781 | ] |
| | 1782 | cursor/old-len: len |
| | 1783 | poke first at cursor/parent-face/data cursor/idx 2 copy head full |
| | 1784 | ] |
| | 1785 | regroup-2-lines: func [cursor][ |
| | 1786 | f: cursor/parent-face |
| | 1787 | data: at head f/data cursor/global-idx |
| | 1788 | unless tail? next data [ |
| | 1789 | str1: either end: find data/1/2 newline [copy/part data/1/2 end][data/1/2] |
| | 1790 | str2: either end: find data/2/2 newline [copy/part data/2/2 end][data/2/2] |
| | 1791 | append str1 str2 |
| | 1792 | poke data/1 2 str1 |
| | 1793 | remove next data |
| | 1794 | render-text/stay f cursor/idx |
| | 1795 | ] |
| | 1796 | ] |
| | 1797 | |
| | 1798 | ;*** Reconstruct a line (draw block) after an insert |
| | 1799 | ;*** (which contains modified sub-strings) |
| | 1800 | ;* if the line contains a multi-line string, then other lines below |
| | 1801 | ;* may be reconstructed too. |
| | 1802 | recolorize: func [ |
| | 1803 | cursor |
| | 1804 | /local line f multi-p multi data pos-head |
| | 1805 | ][ |
| | 1806 | f: cursor/parent-face |
| | 1807 | data: cursor/data |
| | 1808 | line: at f/data cursor/idx |
| | 1809 | |
| | 1810 | change skip data 2 |
| | 1811 | either colorize f line clear find/tail data/1 string! |
| 1753 | | ] |
| 1754 | | constraint f cursor/xy |
| 1755 | | set-y f 5 |
| 1756 | | ] |
| 1757 | | |
| 1758 | | constraint: func [ |
| 1759 | | f offset |
| 1760 | | /local cursor y blk pair text cont? idx save-pair at-tail? len |
| 1761 | | ][ |
| 1762 | | y: idx: 0 |
| 1763 | | cont?: none |
| 1764 | | cursor: f/cursor |
| 1765 | | at-tail?: false |
| 1766 | | parse f/effect/draw [ |
| 1767 | | some [ |
| 1768 | | thru 'push blk: block! skip set pair pair! |
| 1769 | | (idx: idx + 1 cont?: if offset/y <= (y + pair/y) ['break]) |
| 1770 | | cont? (y: y + pair/y) |
| 1771 | | ] |
| 1772 | | :blk into [ |
| 1773 | | (cont?: none) |
| 1774 | | thru 'edit set pair pair! pos-head: text: skip |
| 1775 | | any [ |
| 1776 | | thru 'edit set save-pair pair! |
| 1777 | | (cont?: if offset/x < save-pair/x ['break]) |
| 1778 | | cont? |
| 1779 | | text: skip (pair: save-pair) |
| 1780 | | ] |
| 1781 | | opt [to 'edit | (at-tail?: true)] |
| 1782 | | ] |
| 1783 | | ] |
| 1784 | | either string? text/1 [ |
| 1785 | | offset: min length? text/1 to integer! offset/x - pair/x / f/x |
| 1786 | | cursor/xy: as-pair |
| 1787 | | offset * f/x + pair/x |
| 1788 | | y + 7 |
| 1789 | | cursor/sub-string: skip text/1 offset |
| 1790 | | cursor/pos-len: offset + 1 |
| | 1813 | |
| | 1814 | ;** move the cursor, after insertion |
| | 1815 | ;**cursor/xy/x: cursor/xy/x + probe (cursor/len - cursor/old-len * f/x) |
| | 1816 | |
| | 1817 | loop f/nb-lines - cursor/idx [ |
| | 1818 | if tail? next line [break] |
| | 1819 | |
| | 1820 | multi-p: line/1/1 |
| | 1821 | multi: line/2/1 |
| | 1822 | if any [ |
| | 1823 | all [find [1 2] multi-p find [1 3] multi] |
| | 1824 | all [find [3 4] multi-p find [2 4] multi] |
| | 1825 | ][break] |
| | 1826 | |
| | 1827 | data: find/tail data 'push |
| | 1828 | line: next line |
| | 1829 | change skip data 2 |
| | 1830 | either colorize f line clear find/tail data/1 string! |
| | 1831 | [as-pair 0 2 * f/y][as-pair 0 f/y] |
| | 1832 | ] |
| | 1833 | constraint f cursor/xy |
| | 1834 | set-y f 5 |
| | 1835 | ] |
| | 1836 | |
| | 1837 | constraint: func [ |
| | 1838 | f offset |
| | 1839 | /local cursor y blk pair text cont stop idx save-pair |
| 1792 | | ;** special case, for tags (like tabulations) |
| 1793 | | len: length? get text/1 |
| 1794 | | len: either offset/x < (f/x * len / 2 + pair/x) [0][len] |
| 1795 | | cursor/xy: as-pair f/x * len + pair/x y + 7 |
| 1796 | | cursor/sub-string: text/1 |
| 1797 | | cursor/pos-len: 1 + len |
| 1798 | | ] |
| 1799 | | cursor/head?: pos-head |
| 1800 | | cursor/data: blk |
| 1801 | | cursor/pos-blk: text |
| 1802 | | cursor/idx: idx |
| 1803 | | cursor/global-idx: idx - 1 + index? f/data |
| 1804 | | |
| 1805 | | case [ |
| 1806 | | cursor/xy/x < 0 [scroll-x f -20 * f/x + cursor/xy/x] |
| 1807 | | cursor/xy/x > f/size/x [scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x] |
| 1808 | | ] |
| 1809 | | ] |
| 1810 | | ] |
| 1811 | | append init [ |
| 1812 | | data: append/only make block! 1000 reduce [0 ""] |
| 1813 | | v-scroller: make v-scroller [] |
| 1814 | | h-scroller: make h-scroller [] |
| 1815 | | cursor: make cursor [] |
| 1816 | | pane: reduce [cursor v-scroller h-scroller] |
| 1817 | | edge: make edge [] |
| 1818 | | data: build-data [""] self |
| 1819 | | feel/resize self first reduce [size size: 0] |
| 1820 | | feel/inc-font-size f 0 |
| 1821 | | ; ;** remove the event handler if found |
| 1822 | | foreach func system/view/screen-face/feel/event-funcs [ |
| 1823 | | if {area-tc handler} = pick third :func 1 [ |
| 1824 | | remove-event-func :func |
| 1825 | | ] |
| 1826 | | ] |
| 1827 | | insert-event-func :event-func |
| 1828 | | ] |
| 1829 | | export: context [ |
| 1830 | | font+: func [f][f/feel/inc-font-size f +1] |
| 1831 | | font-: func [f][f/feel/inc-font-size f -1] |
| 1832 | | bold: func [f][f/feel/bold f] |
| 1833 | | ] |
| 1834 | | ] |
| 1835 | | |
| 1836 | | ] |
| | 1841 | y: idx: 0 |
| | 1842 | cont: none |
| | 1843 | stop: [cont: 'break] |
| | 1844 | cursor: f/cursor |
| | 1845 | parse f/effect/draw [ |
| | 1846 | some [ |
| | 1847 | thru 'push blk: block! skip set pair pair! |
| | 1848 | (idx: idx + 1 if offset/y <= (y + pair/y) stop) cont (y: y + pair/y) |
| | 1849 | ] |
| | 1850 | :blk into [ |
| | 1851 | (cont: none) |
| | 1852 | thru 'edit set pair pair! pos-head: text: skip |
| | 1853 | any [ |
| | 1854 | thru 'edit set save-pair pair! |
| | 1855 | (if offset/x < save-pair/x stop) cont |
| | 1856 | text: skip (pair: save-pair) |
| | 1857 | ] |
| | 1858 | ] |
| | 1859 | ] |
| | 1860 | either string? text/1 [ |
| | 1861 | offset: min length? text/1 to integer! offset/x - pair/x / f/x |
| | 1862 | cursor/xy: as-pair |
| | 1863 | offset * f/x + pair/x |
| | 1864 | y + 7 |
| | 1865 | cursor/sub-string: skip text/1 offset |
| | 1866 | cursor/pos-len: offset + 1 |
| | 1867 | ][ |
| | 1868 | ;** special case, for tabulation |
| | 1869 | cursor/xy: as-pair pair/x y + 7 |
| | 1870 | cursor/sub-string: text/1 |
| | 1871 | cursor/pos-len: either find text 'edit [1][index? tail get text/1] |
| | 1872 | ] |
| | 1873 | cursor/head?: pos-head |
| | 1874 | cursor/data: blk |
| | 1875 | cursor/pos-blk: text |
| | 1876 | cursor/idx: idx |
| | 1877 | cursor/global-idx: idx - 1 + index? f/data |
| | 1878 | |
| | 1879 | case [ |
| | 1880 | cursor/xy/x < 0 [scroll-x f -20 * f/x + cursor/xy/x] |
| | 1881 | cursor/xy/x > f/size/x [scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x] |
| | 1882 | ] |
| | 1883 | ] |
| | 1884 | ]; fin feel |
| | 1885 | append init [ |
| | 1886 | data: append/only make block! 1000 reduce [0 ""] |
| | 1887 | v-scroller: make v-scroller [] |
| | 1888 | h-scroller: make h-scroller [] |
| | 1889 | cursor: make cursor [] |
| | 1890 | pane: reduce [cursor v-scroller h-scroller] |
| | 1891 | edge: make edge [] |
| | 1892 | data: build-data "" self |
| | 1893 | feel/resize self first reduce [size size: 0] |
| | 1894 | ] |
| | 1895 | export: context [ |
| | 1896 | font+: func [f][f/feel/inc-font-size f +1] |
| | 1897 | font-: func [f][f/feel/inc-font-size f -1] |
| | 1898 | bold: func [f][f/feel/bold f] |
| | 1899 | ] |
| | 1900 | ]; fin feel: |