root/area-tc-03-menu.r

Revision 50, 48.5 KB (checked in by Shadwolf, 3 years ago)
Line 
1REBOL [
2        TITLE: "Enhanced area"
3        auteurs: "Shadwolf, Steeve"
4        start-date: 07/04/2009
5        release-date: 22/04/2009
6        credits: { Carl sassenrath, Steeve, Maxim, Coccinelle, Cyphre (AGG guru ^^)}
7        purpose: { construct a new style "area-tc",
8        with rendering dynamic colorized text using draw/agg}
9        Download: http://my-svn.assembla.com/svn/shadwolforge/
10        Docstrack: { docs, source diff and time tracs available on
11        http://my-trac.assembla.com/shadwolforge/
12        }
13]
14;print ""
15; LOAD MENU WIDGET Cyphre(TM)
16do load decompress #{
17789CB51B6B73DAB8F67B7E85BA3B770237430CE4D12EDD6EC6109A92266D499A
18B629E3CE1810C6606C6A9BE074BBFFFD9E23C9B66CCB84A477C384C8B2747474
195E3A0FE5EF5118D516D45DB5C8C29C53E20D6774143E23839D6F357B615A3468
20119F8E5723CABABED55EE260329C5B646D875342C71665FD8E678EC9F1E1EF7F
21DB9FDAEFAFD6F5B76796A7C3CFBBEB9B69F7C68256BB87CFD71DFD161F3EFFF0
228EBE6047FB6CDCFE78D3D5F58BB3F7930FE1D5CE7C0DBD9DF6ECFAF5F93B787D
237CDED775AB77A9EB1F5C0D5EE8C7F07AFC11BEDE2F11ECB103E35F37F7BE7CFF
24EADE20C09DE6DCE9F63F5D1DBA67172F34ED85A6FFB8D1FB7A27B27A33FFD38B
25BDABAFE7DF17E1B43B5B4DA7B06AD7BABE3A773AEFDAD7FE7BC07074D5DDB1E7
26776BC4D25B2EDB00BBFBEE1656F7ACC08AACAF67572BBDD9A6BDC6E7B6ADEB6F
27BAD6FCC5E91B5B3F8F2EBFF6FBD142BFA6D6E71D58EDEAF8C7CDF2EB25ECA0D3
28D1DFBEE95E754EEFDF74FA7AB7FBEEA67376DFD1BF9FDDF6FBFA69FBEEF6D68F
29AE7A17BADEEB0DDB9DE69DFEFEEDCE17EB6BEFB6F7767D7EEE0125EF69AF1FE8
30EDB61E5993FAE5349AF5828B4B86E17A31E97FBC9E863F7AFACDFBFACCBA38EF
31996DA0FBCE6D70F5E58D7DE67EE94CFBFDD7A3D3C6C58B8B2BFDB2DB7D7D7C7A
32AD03B5FBB7FAC5DC72BF1EDE6B07EDBECE5873F3E9FDD5DBA3CE6DAFF7EA1F89
33D9A3291DCD413CFCF9969CD6D9578F73FAB47BFAFCF8E2DFE1F44D3DE6F4F97C
344FDFEBAE7AB0F41A609DBE99CED7FDB6A5B7EDFECAB4AE0F7B20017A74DBB7EC
35B707CF3F009C7EFFEDF4F38ED75D74901A97D7AF7FD43B9FDAC8ACB3CBCE9ED5
36EDB65FB70F6F75ABDFEF358EEE74EB3540EEEA7BF3E0CB878F079ED6EE3292ED
37E46966C06F10DE3BF60FAA2DCC20A4BED01BAE6313131489290EEFFD561B798E
38E7B788EBB954F44C3C3714DA88CD64643276E898A379D2E94D26018509F5A89E
39F4055373ECAD33500DF117155640C7A6043D009C5BA41135F2EB359E37F71BC7
402FF61B4707DF6A39706BCF1F838948A18CCDD0240397AE356CC18E6D3F08894B
41A39098BE15A42D2399623ACBA92981F856C3E9ACB7305F1A04066A42827BA0F1
42421BAE6C678C2B52F22769366AE7A65B6BD6EB8719A839C8CDA323522324E9C9
438C34A4A70C62793C8C1C41BC498617410838B5083029E5376C8A711824A236C9
44304960164F9E50EAC492004D69333EE5DC9AACDC11190019E069CF90374B41C8
4540F896A6ED9F90898603C84034B4A895B4C81E9F0C2D79CFF1D078603C4C1E13
464CBD35991428912388EDDA612B2BC42D62BAF764C0C48B6D3F850A2C75BD90F0
4757032180CD83E3FDE6C1C17EB3719C8E5C9A2E6037F2960029ED659445B5497B
483C9F9A2350389B0C0DC2C553DA84ED06D40F4968DA0E419082DCE688E6642704
49D6B7889DE9E3CA243130A337857E3835F93BE9503DFC63BF513FDE6FFCF13C47
50098EBB1B1666ACA73688393302C5D1B1B8A0DD301DDB725B64D7A193303B7269
51FAA618894D80E99BCB13344F4E003E806F5B364C6C46F5EC342E1087D1214883
5245C35AC84408D7B271C5CCD8D82C813E64FAB9551812FCC9625F2AEC02E01DF5
535381378967E44730E9311D986A82D4C2C628500F39A9312DCCF571F55300E1B6
545A0315A321CC4184156354C0346F19DA9E1B2858BF6152B85872ABA10629E858
5559DBAE202AE873153850A9470DF25FA19F553065F5E870DB353927033AF2DC31
560940EE4FD4AB732563D695D9AB7887822E894CEE7285CDC2803EB28BD231D1D8
5741B6CB0D7D7610EB33B6C55B9C29654CE1164931B130B6B8E244136ABBB4C1DB
589968A9B292E2527C47B91992B62AA6E4ACA51A0DEA5AA6456531A70A090DC083
59008B661674842998B776952FF2241547139A5BC50B0500159756CB92B5401555
603AA81E0C16C99BE715945963DB1DD3088413FEAA5E8324536722AC066F0F5468
61E2671BAD8E1905F82C574B0D740EC8A9996BF35E2956ADD2D342FE240AFECBBA
622C84447DEAC89FB2132823289B7549880C3B53F2C63D4356738426A1852702B0
632B4B27D079F6B67476A981798C7979BC71119C2E5A41C4A7743CC8346C50B89C
6477365D935D90135CA9A63CB232847CE078933F78368E1C2FA0357A077B41FF9A
653D96EF84CF015FC61ED393C47C2003180483B75FF1270D1F1E82B5F4BD110D82
669AB70A1128C74405F90138F8B3721D00C59578B080839C84F68212148D3B5471
67D198D37BC2AC5730F23DC7A93936F84302E5F07E097230454C986A3E843EFEB0
68990F8C7B900CDEB236A6211D852DE0E153362F1C71C11B92CE7E5004721018F9
6964B128210DF723C980A3B8C51AC6D698288542DAD2368BFD0243CADF95BD3118
70D56ADC8E174EDFF8B336EDB0FCDC509E9ACC53564E508129F6E57BB2CFF293DC
7116A74888274623AAC3895129F1C6C12456AB85D0EC5BEDE543364F0C38AED7A3
72669A504093A5F1A093B0539687E5B17DE6FD6C621232C47F172B27B485E5636D
7349DA26B643333665E8CC334A0516973957D04F1A393165ECE087184B49719460
74A4927859B40C96AA81AF8470311AEC7510FAECAF961E7C136F38C3497C804FC3
7595EFB22DB3C050E107A003844A9E49E70C672067312A22E152879F887D8B7E1E
7669C638705459582D7248299ECC0B49CEEFF8EC640F041E44EF24CE56404BF42D
77CD702A3A97A2C55D23DE74BC91E9B0E65D92E0F55760C4590BED329F0381E842
7838D7E355DC0A5643DE630727AC319ACE79C35E58ECEFD0F44547B8607FC1F2B3
79BF3402591CF377AE07E6920F172C8D43C9241309188340C95CC1E76C5200D8C0
803616B305741942DC847004B605C76BE0C1793440C0102F7B2EA960536BE0C304
811CB49F04BD4614C2219066FE8C543818EC010055783FB79706093D42DD315F98
82E076EC30E16192DB40DA275282BB0CB2181B29E15BE4203A48C99BA65114C1F0
83D843E72476C2B82E9818976C769D779937B28B001F31CBC41457925254052DBF
84860E07F92884A84C3D2E982AF7BCE03C6F4CC0629E2A3172D4013700F52A753B
858DE4D478446E67DBAC4E2E7768A4CA9718F0ACDDFFEDF237C277AE2529B08CD0
8681AEC7B2561766881D29A9962BD4834AF95DAE278951455A0C7641D1CDA14349
870535BE45427F45AB06A3D380E5F976E1B4421B205E8136EDD6E21E768E560D31
881CB50C8C0419B0D2D33318892704FE45FC9FC5C376C180900A5A91643536335C
89A0D5B45DEB191FF73BEB46B75274C7F3C144910A33300900AEFB0916C21211BE
906134093F992D90314DED81412AD2A1C3625926B43CAB08946F908A8864719DAA
9134384E59A1809C24CBB22E84CF90348C814853E26C8E471604235AE674147C67
92843C89896A89A3125A598783BD0A3D5EF293B5466887E553EA92547738DC1683
934B2713748F4129C08B4A8A08E09B3051355E368E23396F9BF568004D9040ED1E
94629383FC0EA4CC2CB7EC04F896D169F2127A588D0A9F732E15FAC580557C1CC9
959B15B86379536BBC64E2CEAB214390217349FE634D2216E2EF2F5D2B373BDEEE
96C85B2CC117073F3B0AC1E813166B8283432A65468347A8CDA323A3CA13DCE835
97958E96B2E3D5BCB7581EDE97E606D4E97289090119A439DB20DCCE218599A886
981B3807E4D7F27975C2EB8A63EAD80BB057BE9A710058BD6DA91EB5EDEE13574B
99AA6E091396E6A9C18F06A7B774DF19F73B9F9FE1C6281F156448554A146EB213
100B2E06306B6A047B19F5724C2450E4975E2DDF73CF42A73DA90398B44A089669C
1010C061299659283319226955720BC7C098208F649B3B5E653EA12982B83238599
1021730331008E51444442251B31819C11191A90E31A9111A1D47EA92C92C0820D3
103796D4CE9920CC6BEB9164715BA4360E2175695D4F741C3F7EB464E81F2A0C462
104780A2AC2EF0C6C0CF184B16A9680572C80BE65410FCAB51A04741C0903B14C82
10503C1D6C79666088F20C88C848B25FE7AF815E0976D902C150B68C3A0B2F89A1F
1066A35FA7D653A2719416AC822AACC673C2ABFFFA40C7F31CA57E6FCE532154FBE
107A36A663CDB3809FA0A5E025BD4099AF2792D3EAD300742928A0A12F4CFD2AA73
108EE4D5C3F75B96CB08045890FC12F803303ADCB5BD9FCCE2B0E78F8E1F484235A
109257FBE2249975B65647193DD6FCCAC7307AE74048421C9415D0107074C638DF9
110C2E2C89D79109E0C7621F0406292DD4CEE1A3D6003F1C97B5CD98F4F594ED30C
111057166A52319756AA5D4512D414A324A55456745D127EC4CD6A1243CBC050AB3
1129D95E4FF4AD3829BC98E32A3F1B43F999448221B97C4C9998D0D54BD6011D5DD
1136A188AF594F42A2D5DA1D92AABA115B44E594C2D8CDA504A2D8C55153F846F28
11446F3334B7889E8472A0AADEA19B19F5A26CF42602A251B65374614EF44910B5E
115436CC7E3F624F89732B0E08F6385AB4AFE22F50D69676081642294B44410F994
11660414C3DB55993463063A95C406B8AE23BDBF231D90CC756C249A8B261726C60
1176D7ECBA9049B8D3B4DB8868800B2B68CB91DF3ED2FF2105F1E5824DE285BA526
118AF524B567900403AA7C5FD8274261279E3EC8DE51625F03DEE76D41E02BCF12D
1191792ADF6C7252E4563C3E027D432CAB7AF7205124A3C412CCB5040B5E47BE492
120C4BF379A3C38DB376A7A2AFD4F117C99E319A1378781E7AC42CAE4E0D1A4FE05
1218A72992B5FF297CE8F47B24B5C87C983528EDED2C9D85CB7FA3F5E6099C49536
122F022CA2E9EB03B26E25E49DEE530480A41EDBCB15B1D83CDA3B62FD32519371E
1233DE7E6C57724A452D79DE9AC681C28452C32F5E154264A874DE5A2257EADCAB3
124D9E0EA32D7B6D4DB85D80FFDDDE28D8D2D02CE38B0F35CE75E89166C92DF81D6
1253077A118C0D3CF6C448953C4CA354A09CEE5A6B39F48DC39DDDD63E96783D1BB
126126189870B2344A31313738CD047067B301206D57082610CA04FE970E3E72789
1275AB9B21082C0B250E90CAC16A9B550949054CAA85415520119C92F14D7DAD574
1285CC48A9248E12F887D2E1988B9F6C7E602C14AF9E1681516135F49EA2BAE0FA6
1299FF20CE813EFB666925752112549812B2EDC6E4838F2DC5C116F6EEB9B8AD414
130922E5FBC493FE2F0B96FF174791EF55C82262DC6AA39086B15B0CE7172B3FD79
13198ABA6EFC3E153CE52F67E6BA696D239CEDD0DF87AF5FDE7F00B1FE27BEC5CF8
132A3C0E64285E25FA474194DE3320FC6DFAEA1222DB7A18CBE3CA9A04CCCB14A13
133D697E25889D79AF68863825F961FAD28A8F0407412B00B0149448A28629A9B9D
1341808B25E128C4A858A5D9E5E4DF5261B84A605906DEEB6F0DB9095B20CAEB44C
13555B67D80774148784D32D7C9CA5DB93E5E8FCC750A4615FA45ED30D39B629231
136F0F11E25C3CEBBC41D92F412C30EBBE4C13204995B1EE9058FF45E867C3323BD
1371921DFCDE0D1C84E725067FE312577BBE0A1A23262A03552BB943AED99FFA7B0
138852B5B6902F7D81278B735E3D8DAB21F2B7BEF7238920BA3EEF3C3EFE597B082
139ACA8316A33B194FC0F4EDCEB9C891B73123B8BC7D62C1358A4898F38807E8040
14079F1CE5F8A5253AAD26477BA18373653EE49BB44B5891369E93EE37F084A7659
14193B0D222BC8C7CA8DC1378B5CCE66E41B81A99A54D01B8042696F69F80E28B52
14224C4202067732BD6487628BE646727D7B20587528E714B85025B2DAAB6505CE9
143F69674D5077ACCF13873A72BBDFD1697FB714A72A52D003F4943CBA2C141A2A1
144B30D5E5D6C99F9D04301C9244363202209FC77431B040804940CD96F930C307B
1458BB782C12732E21B663C8F5D82914872B36B38325AB011E325D6BFBD0989FF97
14678E79FFF0120649CE6573C0000
147}
148; END of ctx-menu
149area-tc: context [      ;** global context
150
151colors: [
152        char!           0.120.40
153        date!           0.120.150
154        decimal!        0.120.150
155        email!          0.120.40
156        file!           0.120.40
157        integer!        0.120.150
158        issue!          0.120.40
159        money!          0.120.150
160        pair!           0.120.150
161        string!         0.120.40
162        tag!            0.120.40
163        time!           0.120.150
164        tuple!          0.120.150
165        url!            250.120.40
166        refinement!     160.120.40
167        comment!        10.10.160
168        block!          0.0.0
169        datatype!       120.60.100
170        function!       140.0.0
171        native!         140.0.0
172        action!         140.0.0
173        error!          255.0.0
174        multi!          0.120.40
175        free-text!      0.0.200
176        default!        0.0.0
177
178]
179;func-list: make string! 5000
180;foreach fun bind first system/words system/words [
181;       if all [value? :fun any-function? get :fun][
182;               insert insert tail func-list #" " form fun
183;       ]
184;]
185;**print length? func-list
186multi-chars: complement charset "^^}^/^-"       ;** to detect end of rebol strings
187save-color: color: start: end: out-style: x:
188str: type: f: value: multi: grow?: none
189
190;** markers used in replacement of the draw comman PUSH. Much easy to track them.
191expand:         ;** marker for info messages (like errors)
192hilight: 'push  ;** marker for hilight background
193no-edit: edit: 'aliased
194
195edit-mode: none
196
197abs-x: 0
198;** rule to output draw dialect
199gen-draw: [end: (
200        str: copy/part start end
201        unless tail? str [
202                color: any [select colors type color select colors 'default! 0.0.0]
203                abs-x: x * f/x + f/origine-x
204                either save-color <> color [
205                        if block? color [
206                                out-style: insert insert insert insert insert insert insert insert out-style
207                                        'pen color/2 'fill-pen color/2 'box
208                                        as-pair abs-x 7 as-pair (f/x * length? str) + abs-x 7 + f/y 3
209                                type: none
210                                color: color/1
211                        ]
212                        out-style: insert insert insert insert insert out-style
213                                'pen color [text edit] as-pair abs-x + f/xy/x 5 str
214
215                ][
216                        insert tail pick out-style -1 str
217                ]
218                if type = 'error! [
219                        out-style: insert/only insert out-style 'expand
220                                reduce ['pen red 'text 'vectorial as-pair abs-x 5 + f/y reform [value/id value/arg1]]
221                ]
222                x: x + length? str
223                save-color: color
224                if type = 'error! [grow?: true]
225        ]
226)]
227tab1: next tab2: next tab3: next tab4: "    "
228what: none
229gen-tab: [(
230                what: pick [tab4 tab3 tab2 tab1] x // 4 + 1             ;** align tabs
231                out-style: insert insert insert out-style
232                        [text edit] as-pair x * f/x + f/xy/x + f/origine-x 5 what
233                x: x + length? get what
234                save-color: none
235)]
236
237spaces: exclude charset [#"^(1)" - #" "] charset "^/^-" ;** treat like space
238
239;** rule to detect rebol values (uses load/next)
240;** (heavy, because we handle errors too)
241rebol-value: [skip (
242        error? set/any [value end] try [load/next start]
243        either error? :value [
244                value: disarm :value
245                either value/arg2/1 = #"{" [
246                        end: any [find start newline tail start]
247                        type: 'multi!
248                        multi: case [
249                                multi < 2 [3]
250                                multi = 2 [4]
251                                'else [multi]
252                        ]
253                ][
254                        end: skip start length? value/arg2
255                        type: 'error!
256                ]
257        ][
258                case/all [
259                        path? :value [value: first :value]
260                        all [word? :value value? :value][value: get value]
261                        any-string? :value [
262                                if find/part start newline end [
263                                        end: find/part start newline end
264                                        multi: case [
265                                                multi < 2 [3]
266                                                multi = 2 [4]
267                                                'else [multi]
268                                        ]
269                                        type: 'multi!
270                                ]
271                        ]
272                ]
273                type: type?/word :value
274                color: none
275        ]
276) :end
277]
278
279no-tabs: complement charset "^/^-"
280gen-to-end: [any [some no-tabs | end: tab :end gen-draw some [tab gen-tab] start:] gen-draw]
281any-char: complement charset " ^-"
282
283;** construct a draw block for one line
284set 'colorize func [
285        face line out
286        /local check-multi check-free-text orig lvl-start lvl val cont pline pos
287][
288        color: save-color: grow?: none
289        f: face
290        x: 0
291        orig: out-style: out
292
293        ;** multi = -1, free text before REBOL header
294        ;** multi = 0, code not parsed
295        ;** multi = 1, normal code
296        ;** multi = 2, end of multi-line string
297        ;** multi = 3, begin of multi-line string
298        ;** multi = 4, full multi-line string
299
300        lvl: lvl-start
301        multi: case [
302                head? line                                                      [-1]
303                2 < val: first pline: pick line -1      [4]
304                val = -1                                                        [-1]
305                'else                                                           [1]
306        ]
307        lvl: lvl-start: either pline [pline/3/2][1]
308        line: line/1
309
310        check-multi: if multi <> 4 [[end skip]]
311        check-free-text: [(cont: if multi <> -1 [[end skip]]) cont]
312
313        ;**all [char? line/2 print line]
314        parse/all line/2 [
315                start:
316                check-free-text "rebol" any #" " #"[" (multi: 1) end skip
317                | check-free-text (type: 'free-text!) gen-to-end
318                | opt [
319                        check-multi start: some [
320                                some multi-chars
321                                | #"^^" [skip | end]
322                                |  end: tab :end (type: 'multi!) gen-draw some [tab gen-tab] start:
323                                | #"}" (multi: 2) break ;** end of multi-line
324                                | break                                 ;** newline
325                        ]
326                        (type: 'multi!) gen-draw
327                ]
328                any [
329                        start: [newline | end] break
330                        | some spaces (type: 'blank!) gen-draw
331                        | tab  gen-tab
332                        | [#"[" | #"("] (type: 'block! lvl: lvl + 1) gen-draw
333                        | [#"]" | #")"] (type: 'block! lvl: lvl - 1) gen-draw
334                        | #";"(type: 'comment!) gen-to-end
335                        | rebol-value gen-draw
336                ]
337        ]
338
339        line/1: multi
340        line/3: as-pair lvl-start lvl
341
342
343        f/h-scroller/max-x: max f/h-scroller/max-x x * f/x + f/origine-x + (f/x * 10)
344        ;**f/cursor/len: x
345
346        case [
347                empty? orig [ ;** if the text contains no chars, add a dummy line
348                        append orig compose [text edit (as-pair f/origine-x + f/xy/x 5) (copy "")]
349                ]
350                not same? back start find/reverse start any-char [
351                        insert insert insert tail orig
352                                [pen blue text no-edit]
353                                as-pair x * f/x + f/origine-x + f/xy/x 5
354                                "�"
355                ]
356        ]
357        grow?   ;** notices if it's a simple line or a double-size line
358]
359
360;** cut text into lines
361set 'build-data func [
362        text f /local out
363][
364        out: f/data
365        clear out
366        parse/all text [any [pos: (out: insert/only out reduce [0 pos 0x0]) thru newline]]
367        f/origine-x: f/x * (1 + length? to string! length? head out)
368        recycle/on
369        out: head out
370]
371
372;** boxline: [pen red fill-pen red box 0x1 32x18]
373
374;** debug: display where show occurs
375;show: func [f][print either in f 'cursor ['area-tc]['cursor-only] system/words/show f]
376
377;** markers used in replacement of the draw comman PUSH. Much easy to track them with parse.
378expand:                 ;** marker for info messages (like errors)
379hilight: 'push  ;** marker for hilight background
380no-edit:        ;** marker for text no editable
381edit: 'aliased
382
383;** contruct draw blocks, only for new lines inserted
384set 'render-text func [
385        f inc
386        /stay
387        /local pos char color draw-txt
388        prev-col draw-sblk nb line data n decal
389][
390        start: now/precise
391        prev-col: none
392        case [
393                stay [
394                        inc: inc - 1
395                        data: skip f/data inc
396                ]
397                inc < 0 [
398                        inc: negate min abs inc ((index? f/data) - 1)
399                        data: f/data: skip f/data inc
400                ]
401                inc > 0 [
402                        inc: min max 0 ((length? f/data) - f/nb-lines) inc
403                        data: f/data: skip f/data inc
404                ]
405                'else [data: f/data]
406        ]
407
408        draw-txt: any [find f/effect/draw 'push tail f/effect/draw]
409
410        case [
411                stay [
412                        draw-txt: clear skip draw-txt max 0 inc * 4
413                        nb: min f/nb-lines f/nb-lines - inc
414                ]
415                empty? draw-txt [
416                        nb: f/nb-lines
417                ]
418                inc > 0 [
419                        remove/part draw-txt 4 * inc
420                        draw-txt: tail draw-txt
421                        nb: min f/nb-lines inc
422                        data: skip data either f/nb-lines > inc [f/nb-lines - inc][0]
423                        ;** A FAIRE, si inc d�passe le nombre de lignes affich�es,
424                        ;** parser les lignes skip�es (non affich�es)
425                        ;** pour d�tecter les strings multi-ligne
426                ]
427                inc < 0 [
428                        clear skip draw-txt max 0 4 * (f/nb-lines + inc)
429                        nb: min f/nb-lines abs inc
430                ]
431                'else [return true]
432        ]
433        nb: min nb length? data
434        n: 1
435        decal: as-pair 0 f/y
436        while [n <= nb][
437                line: at data n
438                draw-txt: insert draw-txt 'push
439                draw-sblk: insert insert insert make block! 50
440                        [hilight none pen 128.128.128 text no-edit] as-pair f/xy/x 5
441                        reverse copy/part reverse head insert change
442                                clear "" "       " (n - 1 + index? data) (f/origine-x - f/x / f/x)
443                if colorize f line draw-sblk [
444                        decal: as-pair 0 2 * f/y
445                ]
446                draw-txt: insert insert insert/only draw-txt head draw-sblk 'translate decal
447                decal: as-pair 0 f/y
448                n: n + 1
449        ]
450       
451        set-y f 5   ;** recalc all y offset of texts (which can be absolute only)
452        unless f/cursor/selection? [show f]
453        ;** probe difference now/precise start
454]
455
456;** recalc of all y offset after verstical scroll
457set-y: func [f y /local blk pair line idx gb lgb chg-y][
458        blk: f/effect/draw
459        blk: find f/effect/draw 'push
460        lgb: index? f/data
461        gb: f/cursor/global-idx
462        idx: 2
463        f/cursor/show?: false
464        chg-y: [thru 'text ['edit | 'no-edit] pair: pair! (pair/1/y: y)]
465        foreach [cmd value] blk [
466                switch cmd [
467                        translate [y: y + value/y]
468                        push [
469                                if gb = lgb [
470                                        f/cursor/xy/y: y
471                                        f/cursor/data: at blk idx
472                                        f/cursor/show?: true
473                                ]
474                                parse value [
475                                        any chg-y
476                                        any [thru 'push into [any chg-y to end break]]
477                                ]
478                                lgb: lgb + 1
479                        ]
480
481                ]
482                idx: idx + 2
483        ]
484]
485
486move-x: func [f x /local blk pair chg-x][
487        blk: f/effect/draw
488        blk: find f/effect/draw 'push
489        chg-x: [thru 'text ['edit | 'no-edit] pair: pair! (pair/1/x: x + pair/1/x)]
490        foreach [cmd value] blk [
491                switch cmd [
492                        translate [x: x + value/x]
493                        push [
494                                parse value [
495                                        any chg-x
496                                        any [thru 'push into [any chg-x to end break]]
497                                ]
498                        ]
499                ]
500        ]
501        f/cursor/xy/x: f/cursor/xy/x + x
502]
503
504
505;** return the inner face matching the point
506map-inner: func [face point /local pane][
507        unless pane: face/pane [return face]
508        unless block? pane [pane: to block! pane]
509        foreach face pane [
510                if within? point face/offset face/size [return map-inner face point - face/offset]
511        ]
512        face
513]
514
515get*: func [v][do back change/only [none] v]    ;** if v is a word, get value in the world
516any-char: complement space: charset " ^-"
517
518;** find a free place in the whole area to display the info box
519find-free-places: func [
520        f
521        /local data end x len l-len r-pos stack-l stack-r
522][
523        stack-l: clear []
524        stack-r: clear []
525        data: f/data
526        loop len: f/nb-lines [
527                line: data/1/2
528                end: any [find line newline tail line]
529
530                ;** length of the left free zone
531                pos: any [find/part line space end line]
532                l-len: -1 + index? pos
533
534                ;** start of the rigth free zone
535                pos: ant [find/reverse end any-char end]
536                r-start: index? pos
537
538                stack-l: insert stack-l l-len
539                stack-r: insert stack-r r-len
540                data: next data
541        ]
542        x: maximum-of stack-l
543        loop len [
544
545                stack-l: next stack-l
546        ]
547]
548
549event-func: use [
550        origin off-mem save-size 0x0 drag track
551][
552        origin: off-mem: save-size: 0x0
553        drag: track: false
554        func [
555                {area-tc handler}       ;** don't remove or change this text, it's used to identify the handler
556                face event /local tmp
557        ][
558                                        ;**print [event/type event/key]
559                switch event/type [
560                        time   none     ;** a lot of 'time events are sent, check it first
561                        key     [
562                                        ;** key handler for faces without text and caret (actually only for areat-tc)
563                                        if event/1 = 'time [return event]   ;** FUUUUUCK, why we receive that crap event here ???
564                                        if all [
565                                                tmp: system/view/focal-face
566                                                in tmp 'style
567                                                tmp/style = 'area-tc
568                                        ][
569                                                tmp/feel/engage tmp 'key event
570                                        ]
571                        ]
572                        move [
573                                either drag [
574                                        tmp: track/offset
575                                        drag/feel/drag drag event/offset - origin
576                                        origin: origin + track/offset - tmp     ;** correct the origin, if the tracked face has moved
577                                        return false                            ;** disable move event
578                                ][off-mem: event/offset  ]                      ;** for mouse wheel motion
579                        ]
580                        resize [
581                                tmp: negate saved-size - saved-size: face/pane/1/size
582                                foreach face face/pane/1/pane [
583                                        if in face/feel 'resize [face/feel/resize face tmp]
584                                ]
585                        ]
586                        down [
587                                face: map-inner event/face event/offset
588                                if in face/feel 'drag [
589                                        ;** the draging face which contains the pointer may be different from the draged (track) face
590                                        drag: face
591                                        origin: event/offset
592                                        track: drag/feel/drag/track drag event/offset
593                                ]
594                        ]
595                        up [if drag [recycle drag: false]]
596                        scroll-line [
597                                face: event/face
598                                face: map-inner event/face off-mem
599                                if in face/feel 'scrollwheel [
600                                        face/feel/scrollwheel face event off-mem - win-offset? face
601                                ]
602                        ]
603                        active [saved-size: face/pane/1/size]
604                ]
605                ;**[print [event/type event/offset]]
606                event
607        ]
608]
609key-to-insert: make bitset! #{
610        01000000FFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
611}
612
613stylize/master [
614        area-tc: box with [
615                style: 'area-tc
616                rate: 1
617                text: none
618                para: make para [origin: 0x0 margin: 0x0]
619                delay: 0
620                ask: 'recycle           ;** command to delay
621                color: white
622                x: 8                            ;** current x size oh 1 char
623                y: 18                           ;** current y size of a line
624                origine-x: 3 * x   ;** stock la position a la quelle le texte d�marre apres le rendu des num�ro de ligne
625                data: []
626                font-obj: make face/font [name: "lucida console" size: 14 style: none offset: 0x0]
627                nb-lines: 0
628                xy: 0x0         ;** scroll offset
629                move-offset: 0x0
630                save-x: 0
631                file-name: none
632                effect: [draw [pen none font font-obj line-width 1 translate xy]]
633                open-file: func [ file [file! none!] /local ][
634                        if any [file file: request-file ][
635                                ;** data: build-data detab/size read file 4 self
636                                if block? file [file:  first file]
637                                data: build-data read/direct file self
638                                file-name: file
639                                render-text/stay t 1
640                        ]
641                ]
642                write-file: func [/local str-tmp n line nbline] [
643                        str-tmp: "" n: 1 nbline: length? data
644                                while [n <= nbline ] [
645                                        line: second data/:n ; on transfert le  pointeur vers le document dans data vers un autre pointeur 
646                                        append str-tmp copy/part  line any [ find line newline tail line] ;on copy jusqu'a newline ou jusqu'a la fin
647                                        append str-tmp newline
648                                        n: n + 1
649                        ]
650                        write file-name str-tmp
651                ]
652                save-file: func [] [
653                        if 0 <> length? data  [
654                                either  none? file-name [ ; data is full but we don't have a file-name
655                                    if   file-name:  request-file/save/title "Save as..." "save"
656                                     [
657                                     if block? file [file:  first file]
658                                     write-file ]
659                                     
660                                ] [     
661                                ; data is full and we have a file name
662                                        write-file
663                                ]         
664                        ]                               
665                ]
666                v-scroller: make face [
667                        offset: 0x0 size: 13x0 color: none edge: none
668                        size-box: 0x0
669                        para: none
670                        effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]]
671                        feel: make feel [
672                                redraw: func [f a /local p l][
673                                        if all ['show = a p: f/parent-face 0 < l: length? head p/data][
674                                                f/size/y: max 25 p/nb-lines / l * p/size/y
675                                                f/offset/y: (index? p/data) / (l - p/nb-lines) * (p/size/y - f/size/y)
676                                                f/size-box: f/size - 2x2
677                                        ]
678                                ]
679                                drag: func [f offset /track /local coeff][
680                                        f/parent-face/delay: 3  ;** don't perturb the scroll please
681                                        if track [return f]
682                                        if 1 <= abs coeff: offset/y / (f/size/y / f/parent-face/nb-lines) [
683                                                render-text f/parent-face to integer! coeff
684                                                if f/parent-face/cursor/selection? [
685                                                        f/parent-face/feel/expand-selector f/parent-face/cursor
686                                                        show f/parent-face
687                                                ]
688                                        ]
689                                ]
690                                engage: func [f a e][false] ;** don't send events to the area
691                        ]
692                ]
693                h-scroller: make face [
694                        offset: 0x0 size: 0x13 color: none edge: none
695                        size-box: 0x0
696                        text: none
697                        edge: none
698                        font: make font [align: 'right size: 10 style: 'bold color: red]
699                        para: make para [origin: 0x0]
700                        max-x: 1
701                        effect: [draw [pen sky line-width 2 fill-pen none box 0x0 size-box 2]]
702                        feel: make feel [
703                                redraw: func [f a /local parent][
704                                        if 'show = a [
705                                                f/show?: if f/max-x > f/parent-face/size/x [
706                                                        parent: f/parent-face
707                                                        f/offset/x: to integer! negate parent/xy/x / f/max-x * parent/size/x
708                                                        f/size/x: to integer! (parent/size/x ** 2) / f/max-x
709                                                        f/size-box: f/size - 2x2
710                                                        true
711                                                ]
712                                        ]
713                                ]
714                                drag: func [scroller offset /track /local parent save-x decal x][
715                                        f: scroller/parent-face
716                                        f/delay: 3  ;** don't perturb the scroll please
717                                        if track [return scroller]
718                                        if f/x <= abs offset/x [
719                                                offset/x: to integer! offset/x + 4 / f/x * f/x
720                                                save-x: f/xy/x
721                                                x: f/xy/x: min 0 max
722                                                        f/size/x - scroller/max-x
723                                                        f/xy/x - offset/x
724
725                                                ;** change change skip tail boxline -2
726                                                ;**             as-pair negate x 1 as-pair 32 - x 18
727
728                                                if 0 <> decal: x - save-x [move-x f decal]
729                                                show f
730                                        ]
731                                ]
732                                engage: func [f a e][false] ;** don't send events to the area
733                        ]
734                ]
735                cursor: make face [
736                        offset: 0x5 size: 2x18 para: color: edge: none
737                        xy: as-pair origine-x 5
738                        sub-string: idx: global-idx: col: old-col:
739                        old-idx: tmp-offset: pos-len: old-pos-len: none
740                        selection?: false
741                        selector-xy: [0x0]
742                        head?: false
743                        data: pos-blk: []
744                        blink-color: red
745                        size-box: 2x16
746                        effect: [draw [pen blink-color fill-pen blink-color box 0x1 size-box]]
747                        feel: make feel [
748                                redraw: func [f a][
749                                        if a = 'show [
750                                                f/offset: f/xy
751                                                if f/selection? [
752                                                        f/selector-xy/1/x: f/xy/x - f/parent-face/xy/x
753                                                ]
754                                        ]
755                                ]
756                                engage: func [f a e][] ;** disable events
757                        ]
758                ]
759                feel: make feel [
760                        scrollwheel: func [f event offset] [
761                                f/delay: 3
762                                dir: either event/offset/y > 0 ['down]['up]
763                                switch dir [
764                                        down [render-text f 3]
765                                        up [render-text f -3]
766                                ]
767                                if f/cursor/selection? [expand-selector f/cursor show f]
768                        ]
769                        resize: func [f size+][
770                                f/size: f/size + size+
771                                f/nb-lines: to-integer (f/size/y - 10 / f/y)
772                                f/v-scroller/offset: as-pair f/size/x - 13 2
773                                f/h-scroller/offset: as-pair 2 f/size/y - 13
774                                render-text/stay f 1
775                                if f/cursor/selection? [expand-selector f/cursor show f]
776                        ]
777                        begin-selection: func [
778                                cursor /local f
779                        ][
780
781                                f: cursor/parent-face
782                                cursor/selection?: true
783                                insert-selector f next cursor/data/1 cursor/xy/x + f/xy/x
784                                cursor/selector-xy: back tail cursor/data/1/2
785                                cursor/old-idx: cursor/global-idx
786                                cursor/old-pos-len: cursor/pos-len
787                                get-col cursor
788                                cursor/old-col: cursor/col
789                        ]
790
791                        ;** drag = activate selection
792                        drag: func [f offset /track /local cursor][
793
794                                ;** beware, it's the cursor which moves, not the area.
795                                if track [return f/cursor]
796                                unless f/cursor/selection? [begin-selection f/cursor]
797
798                                ;** not enough displacement to move the cursor
799                                if all [f/x > abs offset/x  f/y > abs offset/y][exit]
800
801                                case [
802                                        all [positive? offset/y f/cursor/idx = f/nb-lines][render-text f 1]     ;** scroll down
803                                        all [negative? offset/y f/cursor/idx = 1][render-text f -1]     ;** scroll up
804                                ]
805                                click f f/cursor/xy + offset
806                                expand-selector f/cursor
807                                show f
808                        ]
809
810                        detect: func [f e][
811                                ;**print remold [e/1 e/2 e/3 e/4 e/5 e/6]
812                                if e/type = 'move [
813                                        ;** because of the timer, 'move events are received, even if there is no move
814                                        if all [find [info-position recycle] f/ask f/move-offset <> e/offset][
815                                                f/ask: 'info-position
816                                                f/delay: 2
817                                                f/move-offset: e/offset
818                                        ]
819                                        return false
820                                ]
821                                e
822                        ]
823                        engage: func [f a e /local key tmp cursor select?][
824                                ;**print remold [a e/type e/key e/1 e/2 e/3 e/4 e/5 e/6]
825                                cursor: f/cursor
826                                if a = 'time [
827                                                ;print [now/time f/ask f/delay]
828                                                either all [cursor/show? find [recycle info-position] f/ask] [
829                                                        f/cursor/blink-color: get first reverse [red none]
830                                                        show f/cursor
831                                                ][f/cursor/blink-color: red]
832                                                case [
833                                                        0 > f/delay: f/delay - 1  [
834                                                                ;** if f/ask <> 'show [print ["timer:" now/time f/ask] ]
835                                                                switch f/ask [
836                                                                        show            []
837                                                                        recycle [recycle]
838                                                                ]
839                                                                f/ask: 'recycle
840                                                                f/rate: 1       ;** default rate, 1 event per second
841                                                                f/delay: 5      ;** recycle after 5 secs of inactivity
842                                                                show f          ;** DON't remove the show here (needed to update the face rate)
843                                                        ]
844                                                ]
845                                                return false
846                                ]
847                                select?: cursor/selection?
848                                unless find [up down] key: e/key [f/save-x: 0]
849                                if f/ask <> 'show [f/ask: 'info-cursor  f/delay: 3]
850                                cursor/blink-color: red
851
852                                if all [e/5 not select? any [word? key key < #" "]][
853                                        select?: true
854                                        begin-selection cursor
855                                ]
856                                switch a [
857                                        down [click f e/offset]
858                                        key [
859                                                ;** e/6 = true for ctrl
860                                                switch/default key[
861                                                        page-up [render-text f negate f/nb-lines]
862                                                        page-down [render-text f f/nb-lines]
863                                                        #"^P" [inc-font-size f 1]  ;** increase font size
864                                                        #"^L" [inc-font-size f -1] ;** decrease font size
865                                                        #"^B" [bold f]
866                                                ][
867                                                        locate-cursor cursor
868                                                ]
869                                                switch/default key [
870                                                        #"^M" [split-line f]
871                                                        #"^[" []
872                                                        #"^~" [ ;** delete
873                                                                either select? [
874                                                                        do-selection/delete f
875                                                                ][
876                                                                        delete-char cursor
877                                                                        recolorize cursor
878                                                                ]
879                                                                show f
880                                                        ]
881                                                        #"^H" [ ;** backtab
882                                                                either select? [
883                                                                        do-selection/delete f
884                                                                ][
885                                                                        move-cursor/left cursor
886                                                                        delete-char cursor
887                                                                        recolorize cursor
888                                                                ]
889                                                                show f
890                                                        ]
891                                                        right [
892                                                                either e/6 [
893                                                                        right-word cursor
894                                                                ][
895                                                                        move-cursor/right cursor
896                                                                ]
897                                                                show cursor                                                             ]
898                                                        left [
899                                                                either e/6 [
900                                                                        left-word cursor
901                                                                ][
902                                                                        move-cursor/left cursor
903                                                                ]
904                                                                show cursor
905                                                        ]
906                                                        down [down-cursor cursor]
907                                                        up [up-cursor cursor]
908                                                        end [
909                                                                constraint f as-pair 100000 cursor/xy/y
910                                                                show cursor
911                                                        ]
912                                                        home [
913                                                                constraint f as-pair f/origine-x + f/xy/x cursor/xy/y
914                                                                show cursor
915                                                        ]
916                                                        #"^S" [ if request "Save file ? " [ f/save-file] ]
917                                                        #"^O" [ if request "Open a file?" [ f/open-file none]]
918                                                        #"^N" [ if request "Start a new file?" [f/data: build-data "" f  render-text/stay f 1 ]]
919                                                        #"^C" [do-selection/clip f]
920                                                        #"^X" [do-selection/clip/delete f]
921                                                        #"^V" [;** TO-DO insert multi-lines text
922                                                                insert-char f/cursor tmp: first parse read clipboard:// "^/"
923                                                                show f
924                                                        ]
925                                                        #"^F" [search f]
926
927                                                ][
928                                                        if all [char? key find key-to-insert key ][
929                                                                insert-char f/cursor e/key
930                                                                recolorize f/cursor
931                                                                ;** auto-scroll horizontaly
932                                                                if f/x * 10 + cursor/xy/x > f/size/x [
933                                                                        scroll-x f f/x * 10
934                                                                ]
935                                                                show f
936                                                        ]
937                                                ]
938                                        ]
939                                ]
940                                if select? [
941                                        either any [e/5 e/6 a = 'up] [
942                                                expand-selector cursor
943                                        ][
944                                                remove-selector cursor
945                                        ]
946                                        show f
947                                ]
948                        ]
949                        bold: func [f][
950                                f/font-obj/style: either f/font-obj/style [none]['bold]
951                                inc-font-size f 0
952                        ]
953                        search: func [f][
954                                ;what: read clipboard://
955                        ]
956
957                        split-line: func [f /local tmp str blanks][
958                                insert-char f/cursor "^/"
959
960                                tmp: at f/data f/cursor/idx
961                                str: tmp/1/2
962
963                                blanks: copy/part str find str any-char
964                                insert str: find/tail str newline blanks
965                                insert/only next tmp reduce [0 str 0x0]
966
967                                render-text/stay f f/cursor/idx
968                                replace/all blanks tab "    "
969                                f/cursor/xy/x: f/origine-x + f/xy/x + (f/x * length? blanks)
970                                down-cursor f/cursor
971                                f/save-x: 0
972                        ]
973
974                        inc-font-size: func [f inc /local tmp][
975
976                                f/font-obj/size: max 10 min 30 f/font-obj/size + inc
977                                f/origine-x: f/origine-x / f/x
978                                f/xy/x: f/xy/x / f/x
979                                tmp: size-text make face [
980                                        text: "MM"
981                                        size: 300x300
982                                        font: f/font-obj
983                                        para: f/para
984                                ]
985                                f/x: to integer! tmp/x / 2
986                                f/y: tmp/y + 2
987                                f/xy/x: f/xy/x * f/x
988                                f/origine-x: f/origine-x * f/x
989                                f/cursor/size/y: f/y
990                                f/cursor/size-box/y: f/y - 2
991                                tmp: f/cursor/xy
992                                resize f 0
993                                click f tmp
994                        ]
995
996                        do-selection: func [
997                                f
998                                /delete /clip
999                                /local cursor data idx old-idx start end str start-col end-col scroll n y
1000                        ][
1001                                cursor: f/cursor
1002                                if clip [clip: make string! 256]
1003                                idx: cursor/global-idx
1004                                old-idx: cursor/old-idx
1005                                get-col cursor
1006                                either old-idx < idx [
1007                                        set [start end] reduce [old-idx idx]
1008                                        set [start-col end-col] reduce [cursor/old-col  cursor/col]
1009                                        either start < index? f/data [
1010                                                scroll: start - index? f/data
1011                                                n: -1 + min start to-integer f/nb-lines / 2
1012                                                scroll: scroll - n
1013                                                y: n * f/y + 2
1014                                        ][
1015                                                y: cursor/xy/y +(start - end * f/y)
1016                                        ]
1017                                ][
1018                                        set [start end] reduce [idx old-idx]
1019                                        set [start-col end-col] reduce [cursor/col  cursor/old-col]
1020                                ]
1021                                data: at head f/data start
1022                                if start = end [
1023                                        set [start-col end-col] sort reduce [start-col end-col]
1024                                ]
1025                                if delete [
1026                                        locate-cursor cursor
1027                                        delete: copy/part data/1/2 start-col - 1
1028                                ]
1029                                loop end - start [
1030                                        if clip [
1031                                                append clip append copy/part at data/1/2 start-col
1032                                                        any [find data/1/2 newline tail data/1/2]
1033                                                        newline
1034
1035                                        ]
1036                                        either delete [remove data][data: next data]
1037                                        start-col: 1
1038                                ]
1039
1040                                str: data/1/2
1041                                case/all [
1042                                        clip [
1043                                                append clip copy/part at str start-col at str end-col
1044                                                write clipboard:// clip
1045                                                clip: none
1046                                        ]
1047                                        delete [
1048                                                data/1/2: delete
1049                                                case [
1050                                                        scroll [render-text f scroll]
1051                                                        start <> end [render-text/stay f 1]
1052                                                        'else [recolorize cursor]
1053                                                ]
1054                                                if y [cursor/xy/y: y]
1055                                                constraint f cursor/xy
1056                                                append delete copy/part at str end-col any [find str newline tail str]
1057                                                recolorize cursor
1058                                        ]
1059                                ]
1060                        ]
1061
1062                        click: func [f offset][
1063                                        ;** We don't use the focus function to avoid this dummy system caret (whe have our own)
1064                                        unless same? system/view/focal-face f [
1065                                                if system/view/focal-face [unfocus]
1066                                                system/view/focal-face: f
1067                                        ]
1068
1069                                constraint f either offset/x - f/xy/x < f/origine-x
1070                                        [as-pair f/origine-x offset/y][offset]
1071                                show f/cursor
1072                        ]
1073                        expand-selector: func [
1074                                cursor
1075                                /local idx f pos curr-idx add-selector del-selector upd-selector str
1076                                        x upd-tail upd-head add-tail add-head calc-tail add-middle upd-middle old-idx
1077                        ][
1078
1079                                f: cursor/parent-face
1080                                idx: cursor/global-idx
1081                                old-idx: cursor/old-idx
1082                                curr-idx: index? f/data
1083                                del-selector: [change pos none]
1084                                calc-tail: [
1085                                        x: 0
1086                                        parse pos [some [
1087                                                thru 'text skip pair! [set str string! | set str word! (str: get str)]
1088                                                (x: x + length? str)
1089                                        ]]
1090                                        x: x + 1 * f/x
1091                                ]
1092                                upd-middle: [cursor/selector-xy: back tail pos/1]
1093                                upd-tail: [do calc-tail change back tail pos/1 as-pair x f/y + 7]
1094                                upd-head: [change back tail pos/1 as-pair f/origine-x f/y + 7]
1095                                add-head: [insert-selector f pos f/origine-x]
1096                                add-tail: [do calc-tail insert-selector f pos x]
1097                                add-middle: [print "Beginning of the selection lost, TO DO !!!"]
1098
1099                                upd-selector: [(
1100                                        either old-idx < idx [
1101                                                case [
1102                                                        curr-idx < old-idx  del-selector
1103                                                        curr-idx > idx  del-selector
1104                                                        curr-idx = idx  upd-middle              ;** cover until the position of the cursor
1105                                                        'else                   upd-tail                ;** cover the tail of the line
1106                                                ]
1107                                        ][
1108                                                case [
1109                                                        curr-idx < idx  del-selector
1110                                                        curr-idx > old-idx  del-selector
1111                                                        curr-idx = idx  upd-middle              ;** cover until the position of the cursor
1112                                                        'else                   upd-head                ;** cover the head of the line
1113                                                ]
1114                                        ]
1115                                        curr-idx: curr-idx + 1
1116                                )]
1117
1118                                add-selector: [(
1119                                        either old-idx < idx [
1120                                                case [
1121                                                        curr-idx < old-idx  none
1122                                                        curr-idx > idx  none
1123                                                        curr-idx = idx  [do add-head do upd-middle]             ;** cover tail
1124                                                        curr-idx = old-idx  [do add-middle 'do upd-tail];** cover middle to tail
1125                                                        'else                   [do add-head do upd-tail]               ;** cover the whole line
1126                                                ]
1127                                        ][
1128                                                case [
1129                                                        curr-idx < idx  none
1130                                                        curr-idx > old-idx  none
1131                                                        curr-idx = idx  [do add-tail do upd-middle]             ;** cover tail
1132                                                        curr-idx = old-idx  [do add-middle 'do upd-head];** cover middle to head
1133                                                        'else                   [do add-tail do upd-head]               ;** cover the whole line
1134                                                ]
1135                                        ]
1136                                        curr-idx: curr-idx + 1
1137                                )]
1138
1139                                parse f/effect/draw [
1140                                        any [
1141                                                thru 'push into ['hilight pos: [block! upd-selector | add-selector ] to end]
1142                                        ]
1143                                ]
1144                        ]
1145                        insert-selector: func [f where x][
1146                                ;** append an highlight box in the current block at relative x position
1147                                change/only where
1148                                        compose [pen 255.200.10 fill-pen 250.200.10 box (as-pair x 7) (as-pair x f/y + 7)]
1149                        ]
1150                        remove-selector: func [cursor /local f tmp][
1151                                cursor/selection?: false
1152                                parse cursor/parent-face/effect/draw [
1153                                        any [thru 'push into ['hilight tmp: (change tmp none) to end]]
1154                                ]
1155                        ]
1156                        left-word: func [cursor /local f x str blk pos s-blk][
1157                                f: cursor/parent-face
1158                                str: get-sub-string cursor
1159                                blk: skip s-blk: cursor/pos-blk -2
1160
1161                                case [
1162                                        find/reverse blk 'edit                          none    ;** not head of line
1163                                        not head? str                                           none    ;** neither
1164                                        'else [
1165                                                cursor/xy/x: 100000
1166                                                if up-cursor cursor [left-word cursor]
1167                                                exit
1168                                        ]
1169                                ]
1170                                x: 0
1171                                foreach stuff reduce [any-char space][
1172                                        while [
1173                                                all [
1174                                                        not find/reverse str stuff
1175                                                        blk
1176                                                        blk: find/reverse blk 'edit
1177                                                ]
1178                                        ][
1179                                                        x: x - 1 + index? str
1180                                                        str: tail get* blk/3
1181                                        ]
1182                                        x: x - length? str
1183                                        str: any [find/reverse str stuff str]
1184                                        x: x + length? str
1185                                ]
1186                                either str/1 = #" " [x: x - 1][x: x + (index? str) - index? head str]
1187                                if x = 0 [x: -1 + index? str]
1188                                constraint f cursor/xy + as-pair x * negate f/x 0
1189                        ]
1190
1191                        get-sub-string: func [cursor][
1192                                at head do back change [none] cursor/sub-string cursor/pos-len
1193                        ]
1194
1195                        right-word: func [cursor /local x str blk pos][
1196                                f: cursor/parent-face
1197                                blk: s-blk: cursor/pos-blk
1198                                str: get-sub-string cursor
1199
1200                                case [
1201                                        find blk 'edit                  none    ;** not tail of line
1202                                        not tail? str                   none    ;** neither
1203                                        'else [
1204                                                cursor/xy/x: f/origine-x + f/xy/x
1205                                                if down-cursor cursor [right-word cursor]
1206                                                exit
1207                                        ]
1208                                ]
1209                                x: 0
1210                                foreach stuff reduce [space any-char][
1211                                        while [
1212                                                all [
1213                                                        not find str stuff
1214                                                        blk
1215                                                        blk: find/tail blk 'edit
1216                                                ]
1217                                        ][
1218                                                        x: x + length? str
1219                                                        str: get* blk/2
1220                                        ]
1221                                        x: x - index? str
1222                                        str: any [find str stuff str]
1223                                        x: x + index? str
1224                                ]
1225                                if str/1 = #" " [x: x + length? str]
1226                                if x = 0 [x: length? str]
1227                                constraint f cursor/xy + as-pair x * f/x 0
1228                        ]
1229
1230                        scroll-x: func [f x][
1231                                f/h-scroller/feel/drag f/h-scroller as-pair x 0
1232                        ]
1233
1234                        locate-cursor: func [cursor /local x idx f][
1235                                f: cursor/parent-face
1236                                unless cursor/show? [
1237                                        either (idx: cursor/global-idx) < index? f/data [
1238                                                render-text f idx - index? f/data
1239                                        ][
1240                                                render-text f idx - f/nb-lines + 1 - index? f/data
1241                                        ]
1242                                ]
1243                                x: cursor/xy/x
1244                                if any [
1245                                        x > (f/size/x - f/x)
1246                                        x < f/x
1247                                ][scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x ]
1248                        ]
1249
1250
1251                        move-cursor: func [
1252                                cursor
1253                                /left /right
1254                                /local f pos offset len
1255                        ][
1256                                f: cursor/parent-face
1257                                ;** locate-cursor cursor
1258                                ;** print remold [cursor/pos-len cursor/sub-string]
1259                                case [
1260                                        left [
1261                                                if len: either string? cursor/sub-string [
1262                                                        either cursor/pos-len = 1 [1][
1263                                                                cursor/pos-len: cursor/pos-len - 1
1264                                                                cursor/sub-string: back cursor/sub-string
1265                                                                cursor/xy/x: cursor/xy/x - f/x
1266                                                                false
1267                                                        ]
1268                                                ][
1269                                                        either cursor/pos-len = 1 [1][
1270                                                                cursor/pos-len: 1
1271                                                                cursor/xy/x: cursor/xy/x - (f/x * length? get cursor/sub-string)
1272                                                                false
1273                                                        ]
1274                                                ][
1275                                                        either pos: find/tail/reverse skip cursor/pos-blk -2 'edit [
1276                                                                either string? pos/2 [
1277                                                                        len: length? pos/2
1278                                                                        cursor/sub-string: at pos/2 len
1279                                                                ][
1280                                                                        cursor/sub-string: pos/2
1281                                                                ]
1282                                                                cursor/pos-len: len
1283                                                                cursor/xy/x: pos/1/1 + (len - 1 * f/x)
1284                                                                cursor/pos-blk: skip pos 1
1285                                                        ][
1286                                                                if cursor/global-idx > 1 [
1287                                                                        cursor/xy/x: 100000
1288                                                                        up-cursor cursor
1289                                                                ]
1290                                                        ]
1291                                                ]
1292                                        ]
1293                                        right [
1294                                                if len: either string? cursor/sub-string [
1295                                                        either tail? cursor/sub-string [2][
1296                                                                cursor/pos-len: cursor/pos-len + 1
1297                                                                cursor/sub-string: next cursor/sub-string
1298                                                                cursor/xy/x: cursor/xy/x + f/x
1299                                                                false
1300                                                        ]
1301                                                ][
1302                                                        either cursor/pos-len > 1 [2][
1303                                                                cursor/pos-len: 1 + length? get cursor/sub-string
1304                                                                cursor/xy/x: cursor/xy/x + (f/x * length? get cursor/sub-string)
1305                                                                false
1306                                                        ]
1307                                                ][
1308                                                        either pos: find/tail cursor/pos-blk 'edit [
1309                                                                either string? pos/2 [
1310                                                                        cursor/sub-string: at pos/2 len
1311                                                                ][
1312                                                                        len: 1 + length? get pos/2
1313                                                                        cursor/sub-string: pos/2
1314                                                                ]
1315                                                                cursor/pos-len: len
1316                                                                cursor/xy/x: pos/1/1 + (len - 1 * f/x)
1317                                                                cursor/pos-blk: skip pos 1
1318                                                        ][
1319                                                                if cursor/global-idx < index? back tail f/data [
1320                                                                        cursor/xy/x: f/origine-x + f/xy/x
1321                                                                        down-cursor cursor
1322                                                                ]
1323                                                        ]
1324                                                ]
1325                                        ]
1326                                ]
1327                        ]
1328                        delay-show: func [f][
1329                                f/ask: 'show            ;** delay the show event, speed issue
1330                                f/delay: 1              ;   wait 2 checks
1331                                f/rate: 10              ;   check 10 times per second
1332                        ]
1333                        down-cursor: func [cursor /local f tmp][
1334                                f: cursor/parent-face
1335                                if cursor/global-idx < index? back tail f/data [
1336                                        if cursor/idx = f/nb-lines [
1337                                                delay-show f
1338                                                render-text f 1
1339                                        ]
1340                                        tmp: cursor/xy + third cursor/data
1341                                        if f/save-x = 0 [f/save-x: tmp/x]
1342                                        constraint f as-pair f/save-x tmp/y
1343                                        unless f/ask = 'show [show cursor]
1344                                        true
1345                                ]
1346                        ]
1347                        up-cursor: func [cursor /local f tmp][
1348                                f: cursor/parent-face
1349                                if cursor/global-idx > 1 [
1350                                        if cursor/idx = 1 [
1351                                                delay-show f
1352                                                render-text f -1
1353                                        ]
1354                                        tmp: cursor/xy - pick cursor/data -2
1355                                        if f/save-x = 0 [f/save-x: tmp/x]
1356                                        constraint f as-pair f/save-x tmp/y
1357                                        unless f/ask = 'show [show cursor]
1358                                        true
1359                                ]
1360                        ]
1361
1362                        insert-char: func [cursor char /local f text refresh?][
1363                                f: cursor/parent-face
1364                                if cursor/selection? [
1365                                        do-selection/delete f
1366                                        locate-cursor cursor
1367                                        refresh?: true
1368                                ]
1369                                text: cursor/sub-string
1370                                either string? text [
1371                                        insert text char
1372                                ][
1373                                        insert insert
1374                                                either cursor/pos-len = 1 [cursor/pos-blk][next cursor/pos-blk]
1375                                                'new
1376                                                char
1377                                ]
1378                                collect cursor
1379                                cursor/xy/x: cursor/xy/x + either char = tab [4 * f/x][f/x * length? form char]
1380                                if refresh? [
1381                                        render-text/stay f 1
1382                                        constraint f cursor/xy
1383                                ]
1384                        ]
1385
1386                        delete-char: func [cursor /local pos f data str1 str2 end][
1387                                text: cursor/sub-string
1388                                unless either string? text [
1389                                        unless tail? text [remove text]
1390                                ][
1391                                        if cursor/pos-len = 1 [remove back cursor/pos-blk] ;**remove the offset
1392                                ][
1393                                        either pos: find/tail cursor/pos-blk 'edit [
1394                                                either string? pos/2 [
1395                                                        remove pos/2
1396                                                ][
1397                                                        remove pos      ;** remove the offset
1398                                                ]
1399                                        ][
1400                                           regroup-2-lines cursor
1401                                           exit
1402                                        ]
1403                                ]
1404
1405                                collect cursor
1406                        ]
1407                        get-col: func [cursor /local col pos][
1408                                col: 0
1409                                pos: cursor/data/1
1410                                while [pos: find/tail pos 'edit][
1411                                        if same? pos: next pos cursor/pos-blk [break]
1412                                        col: col + either string? pos/1 [length? head pos/1][1]
1413                                ]
1414                                col: col + either string? cursor/sub-string
1415                                        [cursor/pos-len]
1416                                        [either cursor/pos-len > 1 [2][1]]
1417                                cursor/col: col
1418                        ]
1419
1420                        collect: func [cursor /local full txt pos][
1421                                full: clear {}
1422                                add-full: [(full: insert full either word? txt [#"^-"][txt])]
1423                                parse cursor/data/1 [
1424                                        any [thru 'edit opt [
1425                                                        pair!
1426                                                        opt ['new set txt skip add-full]
1427                                                        set txt skip add-full
1428                                                        opt ['new set txt skip add-full]
1429                                        ]]
1430                                ]
1431                                poke first at cursor/parent-face/data cursor/idx 2 copy head full
1432                        ]
1433                        regroup-2-lines: func [cursor][
1434                                f: cursor/parent-face
1435                                data: at head f/data cursor/global-idx
1436                                unless tail? next data [
1437                                        str1: either end: find data/1/2 newline [copy/part data/1/2 end][data/1/2]
1438                                        str2: either end: find data/2/2 newline [copy/part data/2/2 end][data/2/2]
1439                                        append str1 str2
1440                                        poke data/1 2 str1
1441                                        remove next data
1442                                        render-text/stay f cursor/idx
1443                                ]
1444                        ]
1445
1446                        ;*** Reconstruct a line (draw block) after an insert
1447                        ;*** (which contains modified sub-strings)
1448                        ;* if the line contains a multi-line string, then other lines below
1449                        ;* may be reconstructed too.
1450                        recolorize: func [
1451                                cursor
1452                                /local line f multi-p multi data pos-head
1453                        ][
1454                                f: cursor/parent-face
1455                                data: cursor/data
1456                                line: at f/data cursor/idx
1457
1458                                change skip data 2
1459                                        either colorize f line clear find/tail data/1 string!
1460                                        [as-pair 0 2 * f/y][as-pair 0 f/y]
1461
1462                                loop f/nb-lines - cursor/idx [
1463                                        if tail? next line [break]
1464
1465                                        multi-p: line/1/1
1466                                        multi: line/2/1
1467                                        if any [
1468                                                all [find [1 2] multi-p find [1 3] multi]
1469                                                all [find [3 4] multi-p find [2 4] multi]
1470                                        ][break]
1471
1472                                        data: find/tail data 'push
1473                                        line: next line
1474                                        change skip data 2
1475                                                either colorize f line clear find/tail data/1 string!
1476                                                [as-pair 0 2 * f/y][as-pair 0 f/y]
1477                                ]
1478                                constraint f cursor/xy
1479                                set-y f 5
1480                        ]
1481
1482                        constraint: func [
1483                                f offset
1484                                /local cursor y blk pair text cont? idx save-pair at-tail? len
1485                        ][
1486                                y: idx: 0
1487                                cont?: none
1488                                cursor: f/cursor
1489                                at-tail?: false
1490                                parse f/effect/draw [
1491                                        some [
1492                                                thru 'push blk: block! skip set pair pair!
1493                                                (idx: idx + 1 cont?: if offset/y <= (y + pair/y) ['break])
1494                                                cont? (y: y + pair/y)
1495                                        ]
1496                                        :blk into [
1497                                                (cont?: none)
1498                                                thru 'edit set pair pair! pos-head: text: skip
1499                                                any [
1500                                                        thru 'edit set save-pair pair!
1501                                                        (cont?: if offset/x < save-pair/x ['break])
1502                                                        cont?
1503                                                        text: skip (pair: save-pair)
1504                                                ]
1505                                                opt [to 'edit | (at-tail?: true)]
1506                                        ]
1507                                ]
1508                                either string? text/1 [
1509                                        offset: min length? text/1 to integer! offset/x - pair/x / f/x
1510                                        cursor/xy: as-pair
1511                                                offset * f/x + pair/x
1512                                                y + 7
1513                                        cursor/sub-string: skip text/1 offset
1514                                        cursor/pos-len: offset + 1
1515                                ][
1516                                        ;** special case, for tags (like tabulations)
1517                                        len: length? get text/1
1518                                        len: either offset/x < (f/x * len / 2 + pair/x) [0][len]
1519                                        cursor/xy: as-pair f/x * len + pair/x   y + 7
1520                                        cursor/sub-string: text/1
1521                                        cursor/pos-len: 1 + len
1522                                ]
1523                                cursor/head?: pos-head
1524                                cursor/data: blk
1525                                cursor/pos-blk: text
1526                                cursor/idx: idx
1527                                cursor/global-idx: idx - 1 + index? f/data
1528
1529                                case [
1530                                        cursor/xy/x < 0 [scroll-x f -20 * f/x + cursor/xy/x]
1531                                        cursor/xy/x > f/size/x [scroll-x f f/x * 20 + f/xy/x + cursor/xy/x - f/size/x]
1532                                ]
1533                        ]
1534                ]
1535                append init [
1536                        data: append/only make block! 1000 reduce [0 ""]
1537                        v-scroller: make v-scroller []
1538                        h-scroller: make h-scroller []
1539                        cursor: make cursor []
1540                        pane: reduce [cursor v-scroller h-scroller]
1541                        edge: make edge []
1542                        data: build-data [""] self
1543                        feel/resize self first reduce [size size: 0]
1544                        feel/inc-font-size f 0
1545                        ;** remove the event handler if found
1546                        foreach func system/view/screen-face/feel/event-funcs [
1547                                if {area-tc handler} = pick third :func 1 [
1548                                        remove-event-func :func
1549                                ]
1550                        ]
1551                        insert-event-func :event-func
1552                ]
1553                export: context [
1554                        font+: func [f][f/feel/inc-font-size f +1]
1555                        font-: func [f][f/feel/inc-font-size f -1]
1556                        bold: func [f][f/feel/bold f]
1557                ]
1558        ]
1559
1560]
1561] ;** end of global context
1562
1563
1564;** TEST
1565do test: does [
1566        unview/all
1567        view/new/options layout  [
1568                across space 0x0 origin 0x0
1569                mn: menu with [
1570                        size: 650x20 data: compose/deep [
1571                                "File" [
1572                                        "New"  # "Ctrl+N" [if request "Start a new file?" [t/data: build-data "" t  render-text/stay t 1 ]]
1573                                        "Open" # "Ctrl+O" [t/open-file none]
1574                                        "Close" # "Ctrl+W"
1575                                        bar
1576                                        "Save" # "Ctrl+S" [ if request "Save file ? " [ t/save-file]]
1577                                        bar
1578                                        "Exit" [quit]
1579                                ]
1580                                "View" [
1581                                        "Text Size" sub [
1582                                                "Text +" [t/export/font+ t]
1583                                                "Text -" [t/export/font- t]
1584                                        ]
1585                                        "BOLD/NORMAL" [t/export/bold t]
1586                                ]
1587                                "Help" [
1588                                        "About..." [alert "WEB: http://my-trac.assembla.com/shadwolforge"]
1589                                ]
1590                        ]
1591                ]
1592                below t: area-tc 650x500
1593        ][resize]
1594        if exists? %area-tc-03.r [t/open-file %area-tc-03.r]
1595        do-events
1596]
1597halt
Note: See TracBrowser for help on using the browser.