/* ********************************************************************* This source file is a part of the standard library of Scol For the latest info, see http://www.scolring.org Copyright (c) 2013 Stephane Bisaro aka Iri, based on a work of Loïc Berthelot This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ********************************************************************* */ /* * Simple console to display any message * See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage * for more informations */ /*! \file console.pkg * \author Scol team * \version 0.2 * \copyright GNU Lesser General Public License 2.0 or later * \brief Easy Console API * * \details This API provides an high level method to easily include a console. * * Create and manage a simple text window (console) to display any message. * Several Console can be used in a same application. * * For the application users, a contextual menu is available by right clicking * in the bottom of the graphical user interface (below the text field). * **/ var CONSOLE_HIDE_LINENUM = 0;; // number message ! var CONSOLE_SHOW_LINENUM = 1;; // number message ! /*! \struct CONSOLE * \ingroup console * \brief Internal structure. You should not call it directly, use * API instead ! * **/ struct CONSOLE = [ CSL_win : ObjWin, /*!< console window object */ CSL_txt : S, /*!< text content */ CSL_objTxt : ObjText, /*!< text field object */ CSL_font : ObjFont, /*!< used font object */ CSL_menu : ObjMenu, /*!< contextual menu object */ CSL_searchtxt : S, /*!< text to find, TODO */ CSL_searchPos : I, /*!< text found to this position, TODO */ CSL_num : I, /*!< number of messagee printed (from the creation or from the last reset)*/ CSL_flag : I /*!< flag (show or hide the line number message) */ ] mkCONSOLE;; /* last console object created */ typeof csl_last = CONSOLE;; var csl_linecount = 0;; /* ? */ proto console_save = fun [CONSOLE W] I;; proto console_printtxt = fun [CONSOLE] I;; /* save / load */ fun console_CBsave (objsave, csl, w)= console_save csl w;; fun console_save2 (csl)= _DLGrflsave _DLGSaveFile _channel csl.CSL_win "" "" "All\0*.*\0\0" @console_CBsave csl; 0;; fun console_CBload (objload, csl, p)= if p == nil then 1 else ( set csl.CSL_txt = strcatn csl.CSL_txt :: "\n" :: (_getpack p) :: nil; _SETtext csl.CSL_objTxt csl.CSL_txt; 0 );; fun console_addFromFile (csl)= _DLGrflopen _DLGOpenFile _channel csl.CSL_win "" "" "All\0*.*\0\0" @console_CBload csl; 0;; fun console_goToLine (csl, line)= _SETfirstLine csl.CSL_objTxt line; // _SCROLLtext csl.CSL_objTxt 0 line; 0;; /* POPUP */ fun console_CBpopup (objtext, tuple, str)= let tuple -> [csl win flag] in ( if ((str != nil) && (0 != strcmp str "")) then if flag == 0 then // search ( set csl.CSL_searchtxt = str; set csl.CSL_searchPos = 0; let strfind csl.CSL_searchtxt csl.CSL_txt 0 -> pos in if pos == nil then ( _DLGMessageBox _channel csl.CSL_win " Search" strcatn "The string '" :: csl.CSL_searchtxt :: "' is not found from the position " :: (itoa csl.CSL_searchPos) :: nil 0; 1 ) else 0; // to do flag ) else if flag == 2 then // go to line let atoi str -> line in ( console_goToLine csl line; flag ) else nil else nil; _DSwindow win; 0 );; fun console_crPopup (csl, title, flag)= let _GETwindowPositionSize csl.CSL_win -> [x y _ _] in let _CRwindow _channel csl.CSL_win x + 25 y + 25 250 30 WN_NORMAL title -> win in let _CReditLine _channel win 5 5 240 20 ET_DOWN|ET_AHSCROLL nil -> objtext in ( _SETtextFocus objtext; _CBlineOk objtext @console_CBpopup [csl win flag]; 0 );; /* MENU */ fun console_CBmenu (a, tuple)= let tuple -> [csl id] in ( if id == 0 then // search console_crPopup csl "search" id else if id == 1 then // search next 0 // to do else if id == 2 then // go to line console_crPopup csl "go to line" id else if id == 3 then // save as console_save2 csl else if id == 4 then // add from file console_addFromFile csl else if id == 5 then // print console_printtxt csl else 0 );; fun console_crMenu (csl)= set csl.CSL_menu =_CRpopupMenu _channel; _CBmenu _APPitem _channel csl.CSL_menu ME_DISABLED "Search" @console_CBmenu [csl 0]; _CBmenu _APPitem _channel csl.CSL_menu ME_DISABLED "Search next" @console_CBmenu [csl 1]; _CBmenu _APPitem _channel csl.CSL_menu ME_ENABLED "Go to line" @console_CBmenu [csl 2]; _CBmenu _APPitem _channel csl.CSL_menu ME_ENABLED "Save as" @console_CBmenu [csl 3]; _CBmenu _APPitem _channel csl.CSL_menu ME_ENABLED "Add from file" @console_CBmenu [csl 4]; _CBmenu _APPitem _channel csl.CSL_menu ME_ENABLED "Print" @console_CBmenu [csl 5]; 0;; fun console_destroy2 (a, csl) = _DSfont csl.CSL_font; _DStext csl.CSL_objTxt; _DSmenu csl.CSL_menu; 0;; fun console_resize (win, csl, w, h) = let _GETtextPositionSize csl.CSL_objTxt -> [x y _ _] in _SIZEtext csl.CSL_objTxt (w-20) (h-50) x y; 0;; fun console_click (win, csl, x, y, btn)= if btn == RBUTTON then _DRAWmenu csl.CSL_win csl.CSL_menu x y PM_LEFT_ALIGN|PM_TOP_ALIGN else nil; 0;; fun console_paint (o, csl)= let _GETtextPositionSize csl.CSL_objTxt -> [_ _ w h] in _TXTout csl.CSL_win csl.CSL_font w/2 h-10 TD_BASELINE|TD_CENTER 0xFF0000 "Right-click here -> contextual menu"; 0;; /*! \brief Return the content of a console * * \ingroup console * Prototype: fun [CONSOLE] I * * \param CONSOLE : a console. if nil, the last created console is used * * \return S : the content (can be empty) **/ fun console_getContent (csl)= set csl = if csl == nil then csl_last else csl; csl.CSL_txt;; /*! \brief Scroll the graphical interface to a line ** * \ingroup console * Prototype: fun [CONSOLE I] I * * \param CONSOLE : a console. if nil, the last created console is used * \param I : line number (the line number is not necessary equal to the message number) * * \return I : always 0 **/ fun console_gotoline (csl, line)= set csl = if csl == nil then csl_last else csl; console_goToLine csl line;; /*! \brief Save the content of a console in a file. * If the file will be overwritten, if any * * \ingroup console * Prototype: fun [CONSOLE W] I * * \param CONSOLE : a console. if nil, the last created console is used * \param W : a write-reference file * * \return I : always 0 **/ fun console_save (csl, w)= set csl = if csl == nil then csl_last else csl; _createpack csl.CSL_txt w; 0;; /*! \brief Try to print (on the default printer) the content of a console * This function should NOT be used ! * * \ingroup console * Prototype: fun [CONSOLE] I * * \param CONSOLE : a console. if nil, the last created console is used * * \return I : always 0 **/ fun console_printtxt (csl)= set csl = if csl == nil then csl_last else csl; _lineprint csl.CSL_txt; 0;; /*! \brief Destroy a console * * \ingroup console * Prototype: fun [CONSOLE] I * * \param CONSOLE : a console. if nil, the last created console is used * * \return I : always 0 **/ fun console_destroy (csl)= set csl = if csl == nil then csl_last else csl; console_destroy2 nil csl;; /*! \brief Return the total message number. * * \ingroup console * Prototype: fun [CONSOLE] I * * \param CONSOLE : a console. if nil, the last created console is used * * \return I : always 0 **/ fun console_getMessageNumber (csl)= set csl = if csl == nil then csl_last else csl; csl.CSL_num;; fun console_getLineNum_old () = let if (csl_linecount < 10) then strcat strcat " " (itoa csl_linecount) " : " else if (csl_linecount < 100) then strcat strcat " " (itoa csl_linecount) " : " else strcat (itoa csl_linecount) " : " -> linenum in ( set csl_linecount=csl_linecount+1; linenum; );; fun console_getLineNum (csl) = set csl = if csl == nil then csl_last else csl; if (csl.CSL_num < 10) then strcat strcat " " (itoa csl.CSL_num) " : " else if (csl.CSL_num < 100) then strcat strcat " " (itoa csl.CSL_num) " : " else strcat (itoa csl.CSL_num) " : ";; /*! \brief Change the title of a console * * \ingroup console * Prototype: fun [CONSOLE S] I * * \param CONSOLE : a console. if nil, the last created console is used * \param S : a new title * * \return I : always 0 **/ fun console_setTitle (csl, title)= set csl = if csl == nil then csl_last else csl; _SETwindowName csl.CSL_win title; 0;; /*! \brief Clear a console * * \ingroup console * Prototype: fun [CONSOLE] I * * \param CONSOLE : a console. if nil, the last created console is used * * \return I : always 0 **/ fun console_clear (csl) = let if (csl == nil) then csl_last else csl -> csl in ( set csl.CSL_num = 0; set csl.CSL_txt = ""; _SETtext csl.CSL_objTxt csl.CSL_txt; 0 );; /*! \brief Add (print) a message in the given console * * \ingroup console * Prototype: fun [CONSOLE S] I * * \param CONSOLE : a console. if nil, the last created console is used * \param S : a message * * \return I : always 0 **/ fun console_print (csl, msg) = let if (csl == nil) then csl_last else csl -> csl in ( if ((csl.CSL_flag == CONSOLE_SHOW_LINENUM) || (csl.CSL_flag == nil)) then set csl.CSL_txt = strcat strcat strcat csl.CSL_txt "\n" console_getLineNum csl msg else set csl.CSL_txt = strcat csl.CSL_txt msg; _SETtext csl.CSL_objTxt csl.CSL_txt; _SCROLLtext csl.CSL_objTxt 0 (_GETlineCount csl.CSL_objTxt)-1; set csl.CSL_num = csl.CSL_num + 1; ); 0;; /*! \brief Initialize the console and create the graphical user interface * * \ingroup console * Prototype: fun [Chn I I I I I] CONSOLE * * \param Chn : a channel (typically, the current channel (_channel)) * \param I : the X position on the screen * \param I : the Y position on the screen * \param I : the width * \param I : the height * \param I : a flag : CONSOLE_SHOW_LINENUM = Display the number (nth) message * CONSOLE_HIDE_LINENUM = Hide the number (nth) message * * \return CONSOLE : the new CONSOLE object **/ fun console_create (chn, x, y, w, h, flag) = let mkCONSOLE [nil nil nil nil nil nil 0 0 flag] -> csl in ( console_crMenu csl; set csl.CSL_win = _CRwindow chn nil x y w h WN_MENU|WN_SIZEBOX|WN_MINBOX "console"; _CBwinDestroy csl.CSL_win @console_destroy2 csl; _CBwinSize csl.CSL_win @console_resize csl; _CBwinClick csl.CSL_win @console_click csl; // _CBwinPaint csl.CSL_win @console_paint csl; set csl.CSL_font = _CRfont _channel 12 0 FF_WEIGHT "arial"; set csl.CSL_objTxt = _CRtext _channel csl.CSL_win 10 10 w-20 h-50 ET_AHSCROLL|ET_AVSCROLL|ET_ALIGN_LEFT|ET_BORDER|ET_HSCROLL|ET_VSCROLL nil; // _PAINTwindow csl.CSL_win; set csl_last = csl; csl; );;