/* Copyright (C) 2011, Stephane Bisaro, aka iri License : you can do what you want with this source code This code is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. */ /* Create a text fields interface with the 2dOS Scol API. These text object are managed by the system (win32 api on MS Windows, GTK+ on GNU/Linux). They are faster than the 2dGraphic api, they are more customizable than simple text object (ObjText). Documentation : Text API : http://www.scolring.org/files/doc_html/richtext.html This GUI has two fields : - an input field (editable line only) - an output field which displays what has been written Few keywords ae predefined to run actions : - load, save the content - reset - change the first line displayed - and more (see below) */ /* ObjRichText are managed by the system but they can be partially customized. They must be inside a window object. The resize is not automatic. If the parent window can be resized by the user or the program, you should define a callback (_CBwinSize) and, in the reflex, define the rich text size behavior. */ typeof window = ObjWin;; // main window typeof cText = ObjRichText;; // output text field typeof cLine = ObjText;; // input text field var prompt = "$ ";; var fileContent = "tutorials/text/content.txt";; var rFont = "Arial";; // the name of used font var mainBgColor = 0x555555;; // background color var mainFoColor = 0xdddddd;; // foreground color var promptColor = 0x1111ee;; // prompt color var sFont = 10;; // font size /* Add a string to the output field. _ADDtextRichText just concatenates the previous content with any string. If you want a new line, you must do this explicitely ("\n") You can define font and foreground text color : _ADDtextRichText : rich text object, content, name of font, color and a flag (see doc above) Prototype : fun [S] I */ fun addContent (string)= _ADDtextRichText cText prompt rFont sFont promptColor 0; _ADDtextRichText cText string rFont sFont mainFoColor 0; 0;; /* Set a string to the output field. _SETtextRichText overwrites the previous content and replace it by a new string. If you want a new line, you must do this explicitely ("\n") You can define font and foreground text color : _SETtextRichText : rich text object, content, name of font, color and a flag (see doc above) _ADDtextRichText : see above Prototype : fun [S] I */ fun setContent (string)= _SETtextRichText cText prompt rFont sFont promptColor 0; _ADDtextRichText cText string rFont sFont mainFoColor 0; 0;; /* Build a simple help / usage and display it in the output field Prototype : fun [] I */ fun displayHelp ()= let "Welcome in this small example of Scol application\n help : show this help\n save : save the content to a predefined file (old content will be overwritten)\n load : load the old content from a predefined file\n reset : content becomes empty\n top : display the top of the content, if any\n bottom : display the bottom of the content, if any\n up : up to 10 lines\n down : down to 20 lines\n" -> help in addContent help; 0;; /* Save the current content of the output field to a predefined file. _GETrichText returns this content. _createpack saves any content in any file, the file must be in a write-reference file only (_getmodifypack) See : http://www.scolring.org/files/doc_html/file_system.html Prototype : fun [] I */ fun saveContent ()= let _GETrichText cText -> content in _createpack content _getmodifypack fileContent; 0;; /* Load a saved content and display it in the output field. If any, the old content will be deleted _getpack reads the full content of any file, file must be in a read-reference file (_checkpack) See : http://www.scolring.org/files/doc_html/file_system.html Prototype : fun [] I */ fun loadContent ()= let _getpack _checkpack fileContent -> content in setContent content; 0;; /* The output field becomes empty Prototype : fun [] I */ fun reset ()= setContent ""; 0;; /* Display the top of the content _SCROLLrichText sets the first visible column/line. If the column is 0 then the left of the text will be visible If the line is 0 then the top of the text will be visible _SCROLLrichText : rich text object, column, line Prototype : fun [] I */ fun displayTop ()= _SCROLLrichText cText 0 0; 0;; /* Display the bottom of the content _GETlineCountRichText returns the total number of lines _SCROLLrichText : see above The bottom of text will be visible Prototype : fun [] I */ fun displayBottom ()= _SCROLLrichText cText 0 (_GETlineCountRichText cText)-1; 0;; /* Up to ten lines _GETrichTextFirstLine returns the current first visible line Prototype : fun [] I */ fun displayUp ()= let (_GETrichTextFirstLine cText) - 10 -> n in ( set n = if n < 0 then 0 else n; _SCROLLrichText cText 0 n; 0 );; /* Down to 20 lines See comments above Prototype : fun [] I */ fun displayDown ()= let (_GETrichTextFirstLine cText) + 20 -> n in ( set n = if n > _GETlineCountRichText cText then (_GETlineCountRichText cText)-1 else n; _SCROLLrichText cText 0 n; 0 );; /* Reflex called when the user hits the return key Some keywords are defined. Il the user enters one of them, a special function is called and ran. Otherwise, the content of the input field is added to the content of output field. In all cases, the input field is reset (empty). Prototype : fun [ObjRichText I S] I */ fun CBlineOK (obj, user_parameter, content)= if (!strcmp content "help") then displayHelp else if (!strcmp content "save") then saveContent else if (!strcmp content "load") then loadContent else if (!strcmp content "reset") then reset else if (!strcmp content "top") then displayTop else if (!strcmp content "bottom") then displayBottom else if (!strcmp content "up") then displayUp else if (!strcmp content "down") then displayDown else let strcat content "\n" -> string in addContent string; _SETtext cLine ""; 0;; /* Add all graphics components to the main window _CRrichText create a no-editable rich text field : it will be the output field (cText) _CReditLine create an editable simple text line field : it will be the input field (cLine) You must define the channel where they'll be created, typically, this is the current channel, returned by the Scol function "_channel". After, the mother window where they'll be inside. Next, you give its position and size (position x, position y, width and height). Any flags : here, we add horizontal and vertical scrollbar and a border around the text field. To finish, the initial content is defined (may be nil). Here, _SCROLLrichText allows to display the bottom of ouput field and _SETtextFocus gives the focus at this text object. _SETbkgColorRichText defines the background of color of a rich text object. Finaly, a callback is defined when the users validates his input message. Prototype : fun [] I */ fun create2dOs ()= let _GETwindowSizePosition window -> [wWin hWin _ _] in ( set cText = _CRrichText _channel window 5 5 wWin-10 hWin-35 ET_HSCROLL|ET_VSCROLL|ET_ALIGN_LEFT|ET_BORDER ""; set cLine = _CReditLine _channel window 5 hWin-25 wWin-10 20 ET_DOWN|ET_AHSCROLL|ET_ALIGN_LEFT "Enter your message here"; _SCROLLrichText cText 0 _GETlineCountRichText cText; _SETbkgColorRichText cText mainBgColor; addContent ">>> Hello\n"; _SETtextFocus cLine; _CBlineOk cLine @CBlineOK 0; 0 );; /* Function called when the main windoww is resized _SIZErichText and _SIZEtext allow to ... resize a text object because the resize is NOT automatic when the mother window is resized. Prototype : fun [ObjWin I I I] I */ fun CBwinResize (win, user_parameter, newWidth, newHeight)= _SIZErichText cText newWidth-10 newHeight-35 5 5; _SIZEtext cLine newWidth-10 20 5 newHeight-25; 0;; // Destroy the virtual Scol machine - fun [] I fun end ()= _closemachine;; // Function called when the main window is destroyed - fun [ObjWin I] I fun CBwinEnd (win, user_parameter)= // we destroy all graphics components _DSrichText cText; _DStext cLine; end;; /* Main function. The main window is created. _SETwindowMinSize and _SETwindowMaxSize define the minimal (respectively maximale) size of the window Prototype : fun [] I */ fun main ()= _showconsole; // we create a window in the center of the screen let _GETscreenSize -> [wScreen hScreen] in let [500 437] -> [width height] in let [(wScreen/2)-(width/2) (hScreen/2)-(height/2)] -> [x y] in ( set window = _CRwindow _channel nil x y width height WN_MENU|WN_SIZEBOX " Example : 2D Graphic > Text"; let _GETwindowExSizePosition window -> [wall hall _ _] in ( _SETwindowMinSize window wall hall; _SETwindowMaxSize window wScreen hall; ) ); // we define the window callbacks _CBwinDestroy window @CBwinEnd 0; // window is destroyed _CBwinSize window @CBwinResize 0; // window is resized create2dOs; 0;;