;; =================================================== ;; Script: tface.r ;; downloaded from: www.REBOL.org ;; on: 28-Mar-2024 ;; at: 18:41:45.221416 UTC ;; owner: swhite [script library member who can update ;; this script] ;; =================================================== REBOL [ Title: "TFACE: Scrolling text face" Author: "Steven White with help from Carl" File: %tface.r Date: 3-Nov-2011 Purpose: {This is a module that can be included in a larger program with the command 'do %tface.r' and it will provide a function (TFACE-SHOW-TEXT ' that will display a passed text string in a scrolling window. This code was copied from the REBOL cookbook and annotated so that the copier could understand it.} library: [ level: 'intermediate platform: 'all type: [tutorial tool] domain: [gui vid] tested-under: none support: none license: none see-also: none ] ] ;; [---------------------------------------------------------------------------] ;; [ This module was modified from a scroller demo that was modified from ] ;; [ an example in the REBOL cookbook. ] ;; [ ] ;; [ This module provides a function that accepts a big text string and ] ;; [ displays it in a scrolling face. It is like a "printing" module that ] ;; [ "prints" to the screen in a way that can be scrolled. The formatting ] ;; [ of the text string is up to the caller. ] ;; [---------------------------------------------------------------------------] ;; [---------------------------------------------------------------------------] ;; [ This is a scroller demo from the REBOL cookbook, with annotations to ] ;; [ describe some of the obscure points. ] ;; [ ] ;; [The key understanding is that T1 it an interface object, and its text value] ;; [can be envisioned as a rectangle of pixels, with the text "displayed" on ] ;; [it. ] ;; [ ] ;; [Only a part shows through the window. The para/scroll/y value shows the ] ;; [starting point from which text is displayed. This value starts at zero when] ;; [the text is displayed at the top, and "increases" in a negative direction ] ;; [because the text area can be envisioned as a grid with the top left corner ] ;; [being 0x0--thus "down" the text would be in a negative y direction like ] ;; [the coordinates in algebra. The display window also is a rectangle of ] ;; [pixels, and displaying in it starts at 0x0. ] ;; [ ] ;; [The size/y value is the vertical size of the text window. The user-data ] ;; [value is the vertical size of the text. The (user-data minus size/y) ] ;; [expression is evaluated first. The result of that calculation represents ] ;; [a point in the text value somewhere back from the maximum value, that is, ] ;; [back from the end. That point, back from the end, is back by a distance ] ;; [equal to the size of the display window. In other words, it is the point ] ;; [in the text value where, if the text is displayed from that point forward, ] ;; [you will hit the end of the text when you hit the end of the window. In ] ;; [other words, it is the point where you start to display text when you are ] ;; [displaying the last page. ] ;; [ ] ;; [The para/scroll/y value is going to vary from zero (the top of the text) ] ;; [to the result of the above calculation (the last page), as you operate ] ;; [the scroller. That is why the (user-data minus size/y) result is ] ;; [multiplied by the data value of the scroller (which is a fraction in ] ;; [the range of zero to one). Somewhere in that range of zero through ] ;; [(user-data minus size/y) is where we want to start displaying a window ] ;; [of text. ] ;; [ ] ;; [The reason for the max function is that it could happen that the text ] ;; [is SMALLER than the window. In that case, (user-data minus size/y) will ] ;; [be negative (and will be negated later giving a positive value), and we ] ;; [don't want that. Instead, we want to display from the top all the time, ] ;; [and thus want para/scroll/y to be zero. ] ;; [ ] ;; [We negate the para/scroll/y value because we are going "down" the ] ;; [text in a negative y direction. ] ;; [---------------------------------------------------------------------------] ;; [---------------------------------------------------------------------------] ;; [ In the functions below, TXT and BAR are internal names to refer to ] ;; [ the text area and the scroller that get passed to the functions. ] ;; [---------------------------------------------------------------------------] ;; [---------------------------------------------------------------------------] ;; [ This is the viewing screen with a text area and a scroller to scroll ] ;; [ through the text area. ] ;; [---------------------------------------------------------------------------] TFACE-OUT: center-face layout [ ;; "across" means that interface objects will be side-by-side, ;; and the "return" command will go down. across h3 "Program Output" return ;; This makes the scroller tight up next to the text box. space 0 ;; a text box and a scroller right next to it. T1: text 700x600 wrap green black font-name font-fixed S1: scroller 16x600 [TFACE-SCROLL T1 S1] return ;; Go down 5 pixels pad 0x5 ;; Set inter-object spacing to 5 pixels. space 5 ;; Make our operating and debugging buttons. button "Close" [TFACE-CLOSE T1 S1] ] ;; [---------------------------------------------------------------------------] ;; [ This function is called every time the scroller is moved. ] ;; [ In general, it modifies the properties that indicate where the text ] ;; [ should be displayed from, and the redisplays the text. ] ;; [ But how does it do that? ] ;; [ The para/scroll/y attribute is a number that shows the position in ] ;; [ in the text that is at the top of the display area. It varies from ] ;; [ zero, when the text is shown from the beginning, to some maximum ] ;; [ value when the and of the text is in the window. ] ;; [ What is that maximum value? It is size of the text minus the size ] ;; [ of the the display area. In other words, it is a point back from the ] ;; [ end equal to the size of the box. If the text is displayed from that ] ;; [ point, when you run out of text you will run out of box. ] ;; [ The para/scroll/y value becomes a negative value, with an increasing ] ;; [ absolute value, as we move down through the text. ] ;; [ The "data" attribute of the scroller varies from zero, when the ] ;; [ scroller is at the top, to 1 when the scroller is at the bottom. ] ;; [ This fractional value is applied to the maximum possible size of ] ;; [ para/scroll/y to set it to a point from which text will be displayed. ] ;; [ The "max" function is used to account for the situation where the ] ;; [ text is smaller than the size of the box. In that case, the ] ;; [ calculation of (text size) minus (box size) will be negative, and ] ;; [ negating that will be positive, which is a value we don't want to ] ;; [ see for para/scroll/y because it is in the "wrong direction" so to ] ;; [ speak. ] ;; [---------------------------------------------------------------------------] TFACE-SCROLL: func [TXT BAR][ TXT/para/scroll/y: negate BAR/data * (max 0 TXT/user-data - TXT/size/y) show TXT ] ;; [---------------------------------------------------------------------------] ;; [ This is the function used by the caller. It loads the text area ] ;; [ with the contents of a passed text wtring, so that we have something ] ;; [ to scroll through. Then is displays a window containing the text. ] ;; [---------------------------------------------------------------------------] TFACE-SHOW-TEXT: func [TFACE-TEXT-IN][ ;; Load the text area of the screen with the text passed from ;; the caller. T1/text: TFACE-TEXT-IN ;; Set para/scroll/y so we display from the top of the text. T1/para/scroll/y: 0 ;; Set the initial scroller position to the top. S1/data: 0 ;; This must be done whenever you load up a test area. T1/line-list: none ;; Store the "y" size of the text in the user-data attribute. T1/user-data: second size-text T1 ;; Set the size of the thing you grab in the scroller. ;; It is the size of the text area divided by the size of the ;; text in that area. In other words, if the size of the ;; text in the area gets bigger, the little grabby thing ;; has to get smaller. S1/redrag T1/size/y / T1/user-data ;; Display the window. view TFACE-OUT ] ;; [---------------------------------------------------------------------------] ;; [ This function responds to the "Close"button. ] ;; [ Parameters are passed in case of some future need, but at this time ] ;; [ all the procedure does is close the window. ] ;; [---------------------------------------------------------------------------] TFACE-CLOSE: func [TXT BAR] [ unview ] ;; [---------------------------------------------------------------------------] ;; [ End of module. ] ;; [---------------------------------------------------------------------------] ;; [---------------------------------------------------------------------------] ;; [ To use this module, remove or comment-out the code from here to the ] ;; [ the end. The code below is present just so that if you execute ] ;; [ this module, it will produce a result so you can see what it does. ] ;; [ Normally, this would not be a stand-alone program, but would be ] ;; [ a re-usable function that one would call from a larger program. ] ;; [---------------------------------------------------------------------------] DEMO-TEXT: #{ 789CD55AFF6FDBB612FF5D7F05216078C9603B091EBA07643F0C6D96ED05489A 2276D10D453050166DB395453D928AE3FDF5EFEEF845946CB7E9900C9880A28E 441E8F779F3BDEE7A4D9D5ECFA329BCEB5AA2A592F99158F962DF85C64D9F4FD CDCDEBBBDFB3D94A1AB656655B09D668F5204B6118671BBE6556B1529AA6829F 7043D6A5DA30B57042EC8A5B36E77556086648BE28278C5D5906E25A23166DC5 164AC344782A443D2EB81125D3A251DA4EB2ECE7DB8BF737976F67AF6757B76F B35F945E833CEE641BAB49595C62AB5AD0A5B6893293CCAD6257827D5205A904 3FE71C74D0386EE1A459DC9997256B1A037B935A9419EC0E944DB7FEA935362C 60D8069796962D85353897FB3DA2286708D8C2AFC292502F41D6B034A8ABD18C 4BCDD730D2AECEB3AC54ECBB93EB938BDB377FDC5DBEB9BDFEC34D3027163D31 D159F661259C7EB26EDAB87F504E0B5E6E47B4B57429BB6A4DB505D1B35F5E5F 5C8EA7FFBDFD309E5DFE3673F3C76E3E3C8519DE6D64CB8D0431BC6904D7EEF7 8A3F08D85B7E5129237256B4D6AA9AC666F43C6FEB07293639AD1DF73DBDB8BB 7A37CB682FEC63C6E09A495B897396933EE76C0FE0F2EC3ECB7EFC917D1C3FDF 754F027B6EDC70FA291712C0B6D06A1D5D07D028C55A794BEC0CA3CB0BE43513 8F7CDD905369EF6EAF73A53E17F06FC29E7A7981CF77EDD97212B48BB69E5BE9 5DC8F87C2E1A8BF70BB9EC4516AFCB81C0887C00FD00EF04D210D995FC4C8869 408E85A7790749583111E846981CE3112DE8B280934DB9C5E70FD6CF1F085917 BE283D15E8A33CDD06669A262CE0C2FF29AEB97F7E1CBE24B2A5D9C130217617 9723CA38E0DD5A598E3830689C9E9B0508926872B516C1A4AA30F3560390147A EC89E07E2164A3FF3F8B2D6BEB52686301A8DED18497D919E293238CACD0084C 50FE9398DB11415A02D8091F0FBC6AC53D23891E63023299019340BC7334A886 59BC5E566485463E8ACA78F34594E53E2844993388A9A0A2B44F8FFF27EDF9B9 A44581B775852776C33584CA4A6DD07A5AB5CB559AC729D460083F71D83AD93A B3C519A213088ED0148F041107BFCD4ACE57CE50E09E68AA8903AD1785F3C0DA 96FD29B48229A2F65E89464EE732EE0E54AB1AE7D05CD69036A070803C4299A3 164B00361C5AA5440762AAF32A1662CEA1ECE8BCC761223BE0FCA59665E26CD5 B04A2C201D295D43880581B8E1D3C7D3F1188F5B4083DAD479277FA3DAAA44E1 7DC5B6896A942CA311294929A501D1DC0A5756544B5168EE7C114A2D7F62F3CA 2817FB3DA8266E0EA8454BF9C9BED49136313D6CE1AB807DC16836F24F11B1E5 ABB607017082844D0F7B993D0527B8538F4B6E390974B8799A1837FFA813B096 35B8D0A972DC53513C365A1804074A15281FBC03458184F4E3E4C0F3B6B24E3E 1D5AD5BCAD28BF62390B4F05A4CD2890FB20F19543978F28E7420840A62DF8FC 7397C4D7FC51AEDBB51B35728B48F06B00626FB0A829C460082D33623B8F47B8 11BA5B60160064007AE60910C5FF5AB059389713D3F5113861573553701F8A45 402D282463D9EDB61833E2CE56699B3021F16C2FD0BDBE611778E46FB806D59D 402AFAA94095366CAB0F132C9871D49E0189F651C32F6EC3F904A551D0A4B4A7 BF18A49420308937145471600F0D5F8ABF703478643F4BD8A5C83E94DF61EF4B 458A2BB8A3B7CE1994A08F423A4C6C7D1C057AC4A4E100B560A11E442F268E7A 06391E61CA45EBA9466808AD44435F172A57B8CD1CEEC1DC5B927C307CBD02D2 EC6C790DF7655361515F382134DDEDDB2B1C2BA9237782518A5D68EE52B6AC7B 0269BF907B693699088C00E7C8F1844D63344B5F6F0F06FA23B7AFE1C14DD1C6 51DA4644BEEBE098402DB2F04EA0E7E3CF5192BCE02180873858171B023EE375 5C251477120F603C53574851BD4D63C4270261C2F4E6F5F5F5E51D8EA98741EF 93B481FC73D0DA945C58573B74E7F7119EA6F438DC053001B201304BF9E09CD0 2823693001EBD89DC09B24C396AAFE97F56E046D502D6381CA8F52EF861C1373 37065E20FA56AE41FF281017A02A8426F7A31A4481AA88B92781E085BCFC2158 CB25D63D7927546860024CA42E0725555527D09788746A1C2AAEBE09F0FF1CC6 77E5E01C82030E7251A9CD88CD7E9B11CADEBCBE23EB1101AAE118AFF95A10CD D362E1BA5FBD3D0FEA6187A3240952B02C0562CA607FCEE7F8B8FEE49F68C440 9BA94694628340F3FD074790071649E835665DFA3D3062479FE2D4BF94725FC2 88AE0978FB7E76CEE602713126660CB945B5D637E8F08295730E9B33C0A6D682 D721EF0EB8B489E9CFC8528C8BED18FF1FA562028C722D6CAB217EE76ABD8E89 7309B90DA27A1267B845B3F8F7EADF2C7FE77BA4B7AD6D5A9BB3F8D0898C7FA6 CBBAAE17FF2CCC00C472B9B2D80AAAA933AD3A3F15EAB153C334B8C9D3ACB793 386E88044D42834420FD71DAECECDCCDFACFE9E9E30FA7A76CA379039C12F155 54548EABDA8E3132DDAF0510B5B2DBC914E6C765CE7E20111F7D27F7E2EEF6FA 1AFB1CD3B3FBA14952BD7F753666AF7CEF223E6B78098CEF15DB6BC0A9F0EE1E 3B5793497C2918240DEDF5AAB7EE0D589F618FDB5573A199588AA25D2EF12FD7 434EA4F8A672E831FB8D5E5CDF4E2FD37DBE6C32488B0D6A149640F504D4BE78 CEF6C1448DD5076A460EAE2E452F450DBBAF884AF836B227141AED62DD9F145B 251054EB09D1A09A0902CD2AB412FA046914E34C8BD89FED28EE9ECB0B7C0361 BF822AB154821ABAA5EB7AFFB46FCA97AF68C3E191CEADD5125C2B5CFD5CB7EB 229C265DFFC8D54969551D04A68CD1F3DDA4F933E4A33EDB5E21BBD468DBAE63 1F0462F933724C2D659CA84BDD555885008CD600D311257AEC8106F23DDC72E4 B14E201F105069C21E42E5F9351B7EF0DBA4EDF628FF4FA1B9BED30D71456BA4 E97D8161E01E43EDE5EDA131D16F18240291431FEC0D602605C95F27F48940DF A188FC59B7A0586BE33BC448F393076E9D27E33096966A4D6F4062A9E89B29BE 21CE7C2331BC53886F7A0AA32A44B11F0E54752328FE5D7A1D1EFC87DD9C6898 23E1C893101932CF14C503E0EE084CF352DA1E05179D75D3F68C2A14E4DDF54E FDE6F3A1E7BBE0EBD81400D645CCD93B3F401482D8C8A2EAD03014B8C3468C20 3207BFF8818671283092AEF1D086B07CDE4BDBAD2F4FF91C58A26B197990DAD6 351EBA1C3BD0306683350F456F7D08E03DFED8F74827306D77C0F423F7520A84 1DFB903DC282C2DDE8714940E6287DFB1604BA87E19D77981278E68825AD0A9F 9810A01DC954438146D07BB481730205936902CB375AC1CA9159E59018777984 6904FF86179F5FB89EBF0466F14538954FE7841BA8348033015FBAEF2A60B873 D2B3C87920AD30EE84FA04DF67A9AE47D8A938A5795D2B614C7FFB5642572DE1 890B0FFE866AC6539B181D141ABEE1155F83C29152295E761583E33B43A0C4B7 2073A854A9910D80E6910E52B4D2DBD611C182E029DC8703787EDAD530A5760C CA274FF756B74ECE0BD335B270552EEBD047EDE5D817E04A83EF252252E836DE 195FBDEDF0D28302E8720DF61C98B34BED915DC601DE8694FC86A2BEED8DF5AE 36B3B3135CE39CF5548741C385A662D82F02376EC4FEEE53FA0A65B8DC206E4E F7AEE4BE6181A4852F65C29914CBC0C0CC54D3973E3DA3D8DB27D4513EFC36A7 A08CE74A32ACDDA97A408423F1431A673C2D1F2A5EC95A8C2B69C0583508D8D5 DB2A7F6CE4DB7CB706F359B20BFF78AEEFAC14C700BF838A04D23C4A1B9398D9 D94183F596A478C2AD013B2EC2E2B1493E14D17D08B5A337C1B394F869484C0E C9A01D40C6BD727BB08E5C3C5D8A700AD00754855C2E8576C76925AD85620277 474AE1874A03212B4E0D2DEC4AF9137BC286780146A4F9128DEEDF2F9EF41CB0 63EB9FC30B9DAE62EF0DC136118B8D94BF93916A611A808A09D1E189B2A3CD5F 490E5EE03B084D48C5421BEA0DFABC036EC02A063D454C67D15AFCCAA316A21C 212B67E11339E2C03D81A10B0D74762E4A9CE5A824906754EE69BC2711F8AC36 CC920EC2F0A8F7DD2EF7D91A7E7196FD1FAC687A5C02290000 } TFACE-SHOW-TEXT decompress DEMO-TEXT