GW_VER$="v5.7" % This is the 'GW' include file for RFO BASIC! for Android. % It allows to easily create nice GUIs with Web technologies. % % Written by Nicolas MOUGIN mougino@free.fr http://mougino.free.fr % You can use, modify, and redistribute this file without restriction. % % Important notes for the programer: % Robert A. Rioja wrote a full online documentation for the GW lib: % >> http://mougino.free.fr/tmp/GW/doc << % >> http://rvadlist.com/GW/doc << (backup site) % There is also a PDF version available at % http://mougino.free.fr/tmp/GW/doc.pdf % http://rvadlist.com/GW/doc.pdf % These docs + all their 112 examples are accessible through an Android companion app: % https://play.google.com/store/apps/details?id=com.rfo.gwdoc % % In case of questions, you can find help at https://www.tapatalk.com/groups/rfobasic/gw-lib-f27/ % % Complete list of APIs: % ! --> before loading the lib with INCLUDE "GW.bas": % GW_COLOR$="black" % to display a dark page at startup % GW_SILENT_LOAD=1 % to hide GW lib loading bar % GW_ORIENTATION$="landscape|portrait|reverse-landscape|reverse-portrait" % % ! --> specify page settings before page creation: % GW_ZOOM_INPUT(0|1) % disable/enable zoom in input controls when being edited (default:1) % theme_name$=GW_THEME$[1] ..to GW_THEME$[9] % see list at http://mougino.free.fr/tmp/GW/ % test=GW_THEME_EXISTS (theme_name$) % return true|false if full set of theme-files are on device % GW_DOWNLOAD_THEME (theme_name$) % download all theme files to device % GW_LOAD_THEME (theme_name$) % load a theme to be used by all newly created pages % GW_UNLOAD_THEME () % equivalent to GW_LOAD_THEME ("default") % GW_DEFAULT_TRANSITIONS ("PAGE=fx, PANEL=fx, DIALOG=fx") % :ELEMENT :FX VALUES % :PAGE :fade|pop|flip|turn |flow|slidefade|slide |slideup|slidedown|none % :PANEL :push|reveal|overlay % :DIALOG :fade|pop|flip|turn |flow|slidefade|slide |slideup|slidedown|none % % ! --> create a new page: % mypage=GW_NEW_PAGE () % % ! --> transform the page: % GW_ADD_LOADING_IMG (mypage, "local.gif", dark) % display image when page loads % GW_USE_FONT (mypage, "font.ttf") % use a default font for the whole page % GW_CENTER_PAGE_VER (mypage) % to center vertically the page content % GW_SET_TRANSITION (mypage|mypnl|mydlg, fx$) % fx$: see table above % GW_PREVENT_SELECT (mypage) % prevent text-selection after a long-press % GW_ALLOW_SELECT (mypage) % allow back select after a long-press (default) % % ! --> change layout of controls before adding them: % GW_OPEN_COLLAPSIBLE (mypage, "Title") % to expand/collapse a group of controls % GW_CLOSE_COLLAPSIBLE (mypage) % GW_OPEN_GROUP (mypage) % to visually group checkbox or radio control (custo "inline" possible) % GW_CLOSE_GROUP (mypage) % GW_START_CENTER (mypage) % to visually center elements % GW_STOP_CENTER (mypage) % GW_SHELF_OPEN (mypage) % to organize controls on a same line % GW_SHELF_NEWCELL (mypage) % next control on the line % GW_SHELF_NEWROW (mypage) % go to a new line % GW_SHELF_CLOSE (mypage) % % ! --> apply customization to controls: % myfont$=GW_ADD_FONT$ (mypage, "font.ttf") % class=GW_NEW_CLASS ("myclass") % to apply 1 custo on multiple controls % GW_USE_THEME_CUSTO_ONCE ("param1=value1 param2=value2 ...") % mycusto=GW_NEW_THEME_CUSTO ("param1=value1 param2=value2 ...") % GW_CUSTO_DLGBTN (mypage, mydlg, "Button label", "param1=value1 param2=value2 ...") % GW_USE_THEME_CUSTO (mycusto) % GW_RESET_THEME_CUSTO () % :PARAM :VALUES % :wrap : wrap words in control % :valign :top|middle|bottom % :align :left|center|right|justify % :alpha :from 0% to 100% % :big : increase size of notext button % :class :'myclass' as defined in GW_NEW_CLASS () % :color :a|b|c|d|e|f|g (pgbar|slider|button depending on theme) % :fit-screen : forces image width <= screen width % :font :myfont$ as returned by GW_ADD_FONT$ () % :hover :N|S|E|W|NE|NW|SE|SW % :icon :see http://demos.jquerymobile.com/1.4.5/icons/#Iconset % :iconpos :left|right|top|bottom % :inline : (group|button|dialog*|selectbox) % :mini : decrease size of text button % :notext : (button) % :position :left|right (panel) % :rows :integer (inputbox) % :style :'color:blue' or any other CSS-formatted string % % ! --> add page elements: % myttl$=GW_ADD_BAR_TITLE$ ("My titlebar / footbar") % mylbt$=GW_ADD_BAR_LBUTTON$ ("L-Button>ACTION1") % myrbt$=GW_ADD_BAR_RBUTTON$ ("R-Button>ACTION2") % mylmnu$=GW_ADD_BAR_LMENU$ (values$[]) % like a SELECTBOX but in the title/footbar % myrmnu$=GW_ADD_BAR_RMENU$ (values$[]) % add LISTENER on "l|rmenuchange" to track action % mytbar=GW_ADD_TITLEBAR (mypage, mylbt$ + myttl$ + myrmnu$) % myfbar=GW_ADD_FOOTBAR (mypage, mylmnu$ + myttl$ + myrbt$) % mypanl=GW_ADD_PANEL (mypage, "My panel content") % myspin=GW_ADD_SPINNER (mypage, "Message") % mydlgm=GW_ADD_DIALOG_MESSAGE (mypage, "Title", "Message", buttons_and_actions$[]) % "Btn 1>ACTION1" % mydlgc=GW_ADD_DIALOG_CHECKBOX (mypage, "Title", "Message", "Checkbox label", buttons_and_actions$[]) % mydlgi=GW_ADD_DIALOG_INPUT (mypage, "Title", "Message", "Default input", buttons_and_actions$[]) % :DEFAULT INPUT :INPUT TYPE % :".."|"A>.." :Input Line % :"0>.."|"1>.." :Input Number % :"*>.." :Input Password % :"@>.." :Input E-mail % :"<>.." :Input Url % % ! --> add standard controls: % myttl=GW_ADD_TITLE (mypage, "My section title") % mytbx=GW_ADD_TEXTBOX (mypage, s_ini$) % mytxt=GW_ADD_TEXT (mypage, s_ini$) % mylnk=GW_ADD_LINK (mypage, "My link label", "http://www.mylink.com | USER_ACTION") % mybtn=GW_ADD_BUTTON (mypage, "My button label", "http://www.mylink.com | USER_ACTION") % GW_SHOW_PANEL$ (mypnl) % use it as a link in GW_ADD_LINK() or GW_ADD_BUTTON() % GW_SHOW_DIALOG$ (mydlg) % idem for any dialog (message /input /checkbox) % myimg=GW_ADD_IMAGE (mypage, "mypicture.png") % use ">"+action$ after pic name e.g. "exit.png>BYE" % myico=GW_ADD_ICON (mypage, ico$, width, height) % GW_ICON$ (myico) % use it in a titlebar/footbar % mypgb=GW_ADD_PROGRESSBAR (mypage, "My progress bar label") % mytbl=GW_ADD_TABLE (mypage, n_cols, table$[]) % start first element with ">" to indicate a title line % myaud=GW_ADD_AUDIO (mypage, link_to_audio$) % local or webradio % myvid=GW_ADD_VIDEO (mypage, link_to_video$) % local or streaming, add ">" + img_url$ for poster image % my_lv=GW_ADD_LISTVIEW (mypage, values_and_actions$[]) % :ARRAY :LISTVIEW TYPE % :"~.." (1st elt) :sortable list % :"#.." (1st elt) :ordered list % :"Opt1|..|Opt2" :swipe element (new!) % :"..@@ico.png" :inline icon (new!) % :"..@bigpic.jpg" :thumbnail % :".. {bbl}" :count bubble (new!) % :">.." :title|separator % :"..\n.." :2-line cell % :"..>AXN" :action % % ! --> add user input controls: % mychk=GW_ADD_CHECKBOX (mypage, "My checkbox") % use ">" to check by default % myradio=GW_ADD_RADIO (mypage, radio_parent, "My radio button") % use ">" to select by default % myflip=GW_ADD_FLIPSWITCH (mypage, "My flip switch", s_opt1$, s_opt2$) % use ">" to select default option % myslid=GW_ADD_SLIDER (mypage, "My slider label", n_min, n_max, n_step, n_ini) % myselbx=GW_ADD_SELECTBOX (mypage, "My selectbox", values$[]) % listview-popup, use "#" for title/separator % myinpln=GW_ADD_INPUTLINE (mypage, "My input line label", s_ini$) % myinpbx=GW_ADD_INPUTBOX (mypage, "My input box label", s_ini$) % myinpmi=GW_ADD_INPUTMINI (mypage, "1") % 1=initial value % myinpls=GW_ADD_INPUTLIST (mypage, "Hint message", values_and_actions$[]) % use it as a search-bar % myinpnb=GW_ADD_INPUTNUMBER (mypage, "Input Number", s_ini$) % myinppw=GW_ADD_INPUTPASSWORD (mypage, "Input Password", s_ini$) % myinpml=GW_ADD_INPUTEMAIL (mypage, "Input eMail", s_ini$) % myinpurl=GW_ADD_INPUTURL (mypage , "Input URL", s_ini$) % myinptel=GW_ADD_INPUTTEL (mypage , "Input Tel", s_ini$) % myinpdati=GW_ADD_INPUTDATETIME (mypage, "Input Date and Time", s_ini$) % myinpdat=GW_ADD_INPUTDATE (mypage, "Input Date", s_ini$) % myinptim=GW_ADD_INPUTTIME (mypage, "Input Time", s_ini$) % myinpmo=GW_ADD_INPUTMONTH (mypage, "Input Month", s_ini$) % myinpwk=GW_ADD_INPUTWEEK (mypage, "Input Week", s_ini$) % myinpcol=GW_ADD_INPUTCOLOR (mypage, "Input Color", s_ini$) % mycolpik=GW_ADD_COLORPICKER (mypage, "Hint message", ini_color$) % ini_color$: hexadecimal "RRGGBB" % mylock=GW_ADD_LOCK_PATTERN (mypage, "options") % options=hide-pattern|4x4... % % ! --> add advanced stuff (custom control, listener): % GW_ADD_DEBUGGER(mypage) % add a powerful debugger to the page % p_h=GW_ADD_PLACEHOLDER (mypage) % to dynamically change parts of the page % GW_FILL_PLACEHOLDER (mypage, p_h, "<some>code</some>") % GW_INJECT_HTML (mypage, "<some>code</some>") % add custom HTML code % GW_INJECT_CSS (mypage, "file.css"|".css{style;}") % add custom CSS style % GW_INJECT_JS (mypage, "file.js"|"var a++;") % add custom javascript % GW_ADD_LISTENER (mypage, ctl_id, event$, action$) % ctl_id=0 listens the whole page % :CONTROL :EVENT % :TITLEBAR :"lmenuchange|rmenuchange" % :FOOTBAR :"lmenuchange|rmenuchange" % :PANEL :"close" % :INPUT* :"keydown|clear" % :CHECKBOX|FLIPSWITCH|COLORPICKER... :"change" % :0|Any control :"swipeleft|swiperight|longpress" % :0 (page) :"swipedown|idleN" (N in seconds) % % ! --> render and interact with the page: % GW_RENDER (mypage) % GW_CLOSE_PAGE (mypage) % r$=GW_WAIT_ACTION$ () % Back-key press is returned as "BACK" % r$=GW_ACTION$ () % read input buffer and returns immediately % GW_CLOSE_INPUTLIST (myinpls) % close it after user made a selection % GW_SHOW_DIALOG (mydlg) % manually display a dialog (message /input /checkbox) % GW_CLOSE_DIALOG (mydlg) % manually close a dialog (message /input /checkbox) % GW_SHOW_SPINNER (myspin) % display the spinner manually % GW_HIDE_SPINNER () % manually hide any spinner currently displayed % GW_SHOW_WRONG_PATTERN () % show a wrong lock pattern input % GW_CLEAR_LOCK_PATTERN () % clear the lock pattern % GW_SET_PROGRESSBAR (mypgb, n) % n between 0 and 100 % GW_SHOW_PANEL (mypanl) % display the panel manually % GW_CLOSE_PANEL (mypanl) % manually close opened panel % e$=GW_GET_VALUE$ (ctl_id) % n=GW_GET_VALUE (ctl_id) % ctl_name$=GW_ID$ (ctl_id) % ctl_id=GW_ID (ctl_name$) % ctl_id=GW_LAST_ID () % test=GW_CHECKBOX_CHECKED (ctl_id) % to test if a checkbox is checked % test=GW_RADIO_SELECTED (ctl_id) % to test if a radio button is selected % test=GW_FLIPSWITCH_CHANGED (ctl_id, s_opt1$) % test=GW_LISTVIEW_CHANGED (ctl_id) % to test change of sortable listview % order$=GW_GET_LISTVIEW_ORDER$ (ctl_id) % get new order of sortable listview % GW_HIDE_LISTVIEW_ROW (ctl_id, row) % hide listview row e.g. 'delete' swipe option % GW_REORDER_ARRAY (listview_array$[], order$) % GW_FOCUS (ctl_id) % GW_DISABLE (ctl_id) % called after GW_RENDER() % GW_ENABLE (ctl_id) % GW_HIDE (ctl_id) % called after GW_RENDER() % GW_SHOW (ctl_id) % GW_MODIFY (ctl_id, key$, "new value") % key$="value"...|"style:subkey" % GW_AMODIFY (ctl_id, key$, new_values$[]) % Array-Modify % :CONTROL (GW_MODIFY) :KEYS :VALUES % :all (inc. CLASS) :style :css_property:new_value;.. % :PANEL :content : % :TITLEBAR :title|lbutton|rbutton : % :FOOTBAR :title|lbutton|rbutton : % :CHECKBOX :checked|text :"0"|"1" % :FLIPSWITCH :selected|text :s_opt1$|s_opt2$ % :RADIO :selected|text :"0"|"1" % :SELECTBOX :selected|text :INT$(index) % :SLIDER :val|min|max|step|text : % :IMAGE :content : % :AUDIO :content : % :VIDEO :content : % :DIALOG_MESSAGE :text|title : % :DIALOG_INPUT :text|title|input :"A>"|"1>"|"*>"|"@>"|"<>" % :DIALOG_CHECKBOX :text|title|checked :"0"|"1" % :LINK :text|link : % :BUTTON :text|link : % :INPUT* :text|input : % :COLORPICKER :text|input : % :TEXT :text : % :TEXTBOX :text : % :TITLE :text : % :SPINNER :text : % % :CONTROL (GW_AMODIFY) :KEYS :VALUES % :TITLEBAR :lmenu|rmenu :array$[] % :FOOTBAR :lmenu|rmenu :array$[] % :LISTVIEW :content :array$[] % :TABLE :content :array$[] % :SELECTBOX :content :array$[] % :INPUTLIST :list :array$[] % :DIALOG_* :buttons :array$[] % % ! --> other special functions: % ?GW_VER$() % print GW library version % GW_LOG("some log") % add entry in console log (visible in debugger) % JS ("some java script") % execute a JavaScript snippet on the current page % mode=IS_APK () % return 1 if program is running as a user APK, 0 otherwise % GW_DUMP_TO_FILE (mypage, "myfile.html") % GW_DUMP (mypage) % print page content to console % h$=GW_CODE_HIGHLIGHT$ (raw_code$, black$[], blue$[], red$[]) % wxh$=GW_GET_IMAGE_DIM$ (path_to_img$) % return image dimensions "WxH" % mytxt$+=GW_LINK$ ("url") % % TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO % * ? % TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO % % Changelog: % [v5.7] 29-SEP-2022 % * Fixed GW_GET_VALUE$() when the control contains a percentage character, thanks to Bob Black % [v5.6] 15-MAR-2021 % * /!\ Removed unused legacy control GW_ADD_SUBMIT and internal function GW_OPEN_INPUTFORM() % * Fixed orphan RADIO controls when put in different cells/rows of a SHELF % * Fixed sortable and swipeable LISTVIEW controls broken in v5.5 % * Fixed LOCK_PATTERN control broken when added into a PLACEHOLDER % * Fixed COLORPICKER control broken when added into a PLACEHOLDER % * Fixed TABLE control broken when added into a PLACEHOLDER % [v5.5] 20-FEB-2021 % * Added a powerful debugger via GW_ADD_DEBUGGER(page) % * Added new function GW_LOG(data$) to add a log in the web console (visible in the debugger) % * Added new function GW_VER$() that returns the library version % * Added CUSTO parameter "wrap" to wrap words inside a control (e.g. in a BUTTON) % * Added CUSTO "valign=top|middle|bottom" to vertically center elements inside a SHELF % * Added the possibility to GW_HIDE() a PLACEHOLDER % * Fixed CUSTO problem when "align" was not the first parameter (e.g. "mini align=left") % * Fixed GW_MODIFY of a LINK/BUTTON "link" (did not work or even made the page disappear) % * Fixed swipeable LISTVIEW broken when added into a PLACEHOLDER % [v5.4] 01-FEB-2021 % * Fixed the GW_MODIFY of an INPUTBOX 'input', preserving multi-line text ('\n' character) % * Fixed unscrollable DIALOG_INPUT controls % * Added new LISTENER event "swipedown" for a PAGE, typically used to refresh the content of the page % * Added support for SPINNER customization "icon="+GW_ID$(ico) with ico=GW_ADD_ICON(..) % * Added new form of CSS style modification: GW_MODIFY(ctl_id, "style", "param1:value1;param2:value2;..") % The old form (unitary modification): GW_MODIFY(ctl_id, "style:param1", "value1") is still valid % [v5.3] 07-JAN-2021 % * /!\ Changed GW resource server from laughton.com to rvadlist.com thanks to Robert A. Rioja! % * /!\ Consecutive spaces in user strings are now preserved in all controls % * /!\ Action messages received by GW_ACTION$() and GW_WAIT_ACTION$() are now URL-decoded % This allows to use messages with spaces and exotic characters in them (although it's not recommended) % * /!\ Links created with GW_ADD_LINK() now sit on one row. For inline links, use GW_LINK$() % * /!\ GW_DUMP() now copies the page content to the clipboard as well as printing it on the console % * Added new function GW_INJECT_CSS(page, css$) where css$ is a local/remote .css file or some CSS style code % * Added new function GW_INJECT_JS(page, js$) where js$ is a local/remote .js file or some java script % * Added GW_MODIFY() of a PANEL "content" % * Added new CUSTO parameter 'align' for text-alignment, with values 'left', 'center', 'right' and 'justify' % * Added GW_ORIENTATION$ variable to lock the screen orientation before loading the GW lib % Possible values are: "landscape", "portrait", "reverse-landscape", and "reverse-portrait" % (default value is empty string = variable by sensors) % * Fixed 'alpha' customization that was backwards (applying opacity, not transparency) % * Fixed adding GW controls to a panel via their second form GW_ADD_*$(param1...) % * Fixed GW Gallery viewer broken when the page is rendered without any GW_AMODIFY of the gallery % * Fixed the broken (transparent) swipeable LISTVIEW when using a native-droid-* THEME % * Fixed GW_KEYWORD_NB() and GW_POPULATE_KEYWORD_ARRAY() functions (were broken) % * Fixed GW_HIDE() of SLIDER and PROGRESSBAR controls % * Fixed GW_DISABLE() and GW_ENABLE() of CHECKBOX and RADIO controls % * Fixed missing elements in TABLE when the array dimension is not a multiple of the number of columns % * Fixed TITLEBAR/FOOTBAR not showing when created with only L/RBUTTON or L/RMENU but no TITLE % * Fixed notext icon-only buttons in TITLEBAR/FOOTBAR showing rectangular instead of round % * Fixed first space after new line not showing in a multi-line TEXTBOX % * Fixed GW_SHOW_DIALOG() not showing dialog when a previous dialog closed shortly before % * Fixed GW_ADD_INPUTBOX() of a multi-line text (containing "\n") % * Fixed correct height of an INPUTBOX with a custo "rows=n" (n integer) % * Fixed GW demo to download 3gp video from laughton.com via HTTP rather than FTP % * Removed deprecated SUBMIT controls from the GW demo and used more flexible BUTTON controls instead % [v5.2] 19-AUG-2019 % * /!\ Changed count bubble indicator in LISTVIEW from '(bbl)' to '{bbl}' (breaks compatibility) % The reason is when listing folders or files, too many had the characters '()' in their name % * Added support for *swipe* LISTVIEW with 1 or 2 options at the left (orange) and/or right (red), % Use "Opt1|..|Opt2" in your arrays. See the updated demo > GW basic controls > Listview % * Added function GW_HIDE_LISTVIEW_ROW() useful with a 'Delete' option from a swipe LISTVIEW typically % * Added support for *inline icons* in a LISTVIEW: use "..@@icon.png" in your array % [v5.1] 11-JUL-2019 % * Fixed GW_MODIFY() of an INPUTMINI (before you had to use key 'val' instead of 'input') % * Listview count bubbles '(bbl)' are now searched from the end of each listview element % * Replaced all comments in "GW.bas" and "GW_demo.bas" to use '%' only instead of a '!'/'%' mix % [v5.0] 25-JUN-2019 % * Fixed GitHub issue #179 time/date pickers had prehistoric look (available in the BASIC! Compiler) % * Fixed sortable listview at first Editor run or in a user APK % * Fixed selection of INPUTLIST, broken when compiling against SDK Target 28 % * Improved listview thumbnails in user APKs (embedded images are now automatically copied to sdcard) % * Added debug traces when failing to download a theme or a third party lib % [v4.9] 17-JUN-2019 % * Fixed incorrect caching of remote images in APK mode % * Added support for *sortable* LISTVIEW and its support functions: GW_LISTVIEW_CHANGED(), % GW_GET_LISTVIEW_ORDER$() and GW_REORDER_ARRAY(). See the updated demo > GW basic controls > Listview % [v4.8] 24-APR-2019 % * Added support for CUSTO 'color=a..f' for SLIDER controls (same colors as for PROGRESSBAR) % * Added new control INPUTMINI which is a small inline INPUTNUMBER % [v4.7] 08-MAR-2019 % * /!\ Added a third parameter to GW_ADD_LOADING_IMG(page, img$, dark) (breaks compatibility) % * Added new control GW_ADD_PLACEHOLDER and its function GW_FILL_PLACEHOLDER % * Fixed update of PROGRESSBAR, broken when compiling against SDK Target 27 % * Fixed 'content' change of IMAGE controls, broken when compiling against SDK Target 27 % * Fixed 'input' change of INPUT controls, broken when compiling against SDK Target 27 % * Fixed modify of DIALOGs (MESSAGE/INPUT/CHECKBOX), broken when compiling against SDK Target 27 % * Fixed GW_GET_IMAGE_DIM$() function, broken when compiling against SDK Target 27 % [v4.6] 12-DEC-2016 % * Fixed "Bad control id out of range (last control id: 0)" when using GW_MODIFY() in an ONTIMER: interrupt % * Added support for thumbnails and 2-line cells for LISTVIEW control. See cheatsheet + updated demo % * Improved adaptiveness of GW pages: INPUT controls act same on small smartphone / bigger tablet screens % [v4.5] 09-DEC-2016 % * /!\ Changed architecture of GW lib to get rid of lists. Before, there could be conflicts if user % created some lists before calling INCLUDE "GW.bas", now not anymore. Third-party libs, like % GW_GALLERY.bas or GW_UTILS.bas have also been changed and need to be updated if you use them. % * Fixed GW update system when running from a custom BASIC! Editor (<> com.rfo.basic) % * Added support for ">" + img_url$ in a VIDEO to display a poster image. See demo Advanced > Video % * Added third-party lib "GW_UTILS.bas" to the GW demo > Third party GW libs % [v4.4] 03-DEC-2016 % * Fixed videos % * Fixed PANEL transitions % * Added 2 new controls GW_ADD_BAR_LMENU$ and GW_ADD_BAR_RMENU$ to be used in a TITLEBAR/FOOTBAR % * Added a new control: GW_ADD_AUDIO() see demo > Advanced > Audio/Video for an example with a webradio % * Added support of '#' character in SELECTBOX & GW_ADD_BAR_LMENU$/RMENU$ to make a title/separator % * Added GW_MODIFY of AUDIO and VIDEO 'content' (local file or internet streaming source) % [v4.3] 29-NOV-2016 % * /!\ Changed location of all GW resources: they are now in a data/GW subfolder (existing files are moved) % * Fixed GW halt "Divide by zero at: html.load.url javascript.document.getElementById('slider1')..." % * Fixed CUSTO of GW_ADD_BAR_LBUTTON and RBUTTON to show their 'icon' when 'iconpos' is not specified % * Improved download of GW themes: now silent, with fallback, do not need to restart the GW program % [v4.2] 18-NOV-2016 % * /!\ Changed GW_MODIFY keys of INPUTBOX to 'text' (label) and 'input' (now same as all other INPUT* controls) % * Fixed GW_CUSTO_DLGBTN of DIALOG* buttons with a CUSTO 'notext' % * Fixed SLIDER input hidden by soft keyboard when being edited (especially at the bottom of the page) % * Fixed screen scrolling when touching a SUBMIT button (linked to zoom on INPUT*) % * Added function GW_ZOOM_INPUT(0|1) to disable/enable zoom in INPUT* controls when being edited, set this % setting for a page *before* creating it with GW_NEW_PAGE() (zoom is enabled by default) % * Improved the LISTENER to detect a "change" when re-selecting the already active SELECTBOX option % [v4.1] 10-NOV-2016 % * /!\ Changed notification of COLORPICKER: v3.9 notification was of the type "COLOR:#rrggbb", forbidding % to differentiate between several colorpickers on a same page. Changed notification is now of the type % GW_ID$(my_color_picker) + ":#rrggbb" % * Fixed input lines/boxes hidden by soft keyboard when being edited (especially at the bottom of the page) % * Fixed titles in titled + linked LISTVIEWs % * Fixed having a PROGRESSBAR and a SLIDER coexist in a same page + improved stability of PROGRESSBAR control % * Improved COLORPICKER control to show a rainbow-wheel (more user friendly than the old hue-picker) % * Added CUSTO 'color=a' up to 'color=f' for a PROGRESSBAR to change its background color + updated demo % [v4.0] 02-NOV-2016 % * /!\ Changed GW_MODIFY keys for INPUT* and COLORPICKER controls: key 'text' now refers to the label above the % control, while new key 'input' refers to the value in the input bar (now in line with DIALOG_INPUT controls), % before that change it was simply not possible to change the label of such controls... % * Changed the GW lib logo for a material design logo + fixed centering of the logo in the loading page % * Fixed GW_SHOW_DIALOG() of a DIALOG MESSAGE in iOS/android-holo/metro themes % * Fixed bad RENDER of pages with no page transition containing a DIALOG MESSAGE in iOS/android-holo/metro themes % * Fixed GW_HIDE() and GW_SHOW() of all controls with a label (INPUT*, COLORPICKER, RADIO, CHECKBOX, SLIDER...) % * Fixed select/unselect of radio buttons via GW_MODIFY(radio, "selected", "0|1") + improved radio/checkbox demo % [v3.9] 16-OCT-2016 % * /!\ Changed behavior of COLORPICKER to always send a notification when user changes a color (Vs before % tedious code was needed: prepare a LISTENER$, RENDER the page, activate the LISTENER$ after RENDER..) % Notifications are of the type "COLOR:#rrggbb", see updated GW demo > Advanced controls > Colorpicker/Class % * Fixed HTML.CLOSE bug when juggling between GW programs with GW_SILENT_LOAD set to 1 % * Fixed CUSTO 'inline' of DIALOGs (MESSAGE/INPUT/CHECKBOX), broken in v3.8 % * Fixed GW_LOAD_THEME() when specifying a theme in a case other than lower case % * Fixed TITLEBAR/FOOTBAR title alignment for themes native-droid-* % * Fixed TITLEBAR/FOOTBAR and DIALOGS for themes iOS, android-holo, and metro + vastly improved iOS demo % * Improved check of GW update: now limited to 1 per day. Accelerates consecutive startups in Editor mode % * Improved GW programs debugging a lot by showing last GW command when throwing an error (bad page/control) % * Added new commands GW_PREVENT_SELECT() and GW_ALLOW_SELECT() to handle text-select when long-pressing in a page % * Added new commands GW_OPEN_COLLAPSIBLE() and GW_CLOSE_COLLAPSIBLE() to expand/collapse a group of controls % * Added new commands GW_SHELF_OPEN() GW_SHELF_NEWCELL() GW_SHELF_NEWROW() and GW_SHELF_CLOSE() to organize % several controls on a same line. See the new section of the GW demo > Basic controls > Collapsible/Shelf % * Added new command GW_CUSTO_DLGBTN() to customize a button from a DIALOG once it is added to the page % [v3.8] 05-OCT-2016 % * Fixed regression in GW_ADD_TEXT() and GW_ADD_TEXTBOX() that would cause weird page truncations % * Re-added legacy functions GW_SHOW_DIALOG_MESSAGE$(), GW_SHOW_DIALOG_INPUT$(), GW_SHOW_DIALOG_MESSAGE(), % GW_SHOW_DIALOG_INPUT(), GW_CLOSE_DIALOG_MESSAGE() and GW_CLOSE_DIALOG_INPUT(), respective aliases % to GW_SHOW_DIALOG$(), GW_SHOW_DIALOG() and GW_CLOSE_DIALOG() (for backward compatibility) % [v3.7] 28-SEP-2016 % * /!\ Merged GW_SHOW_DIALOG_MESSAGE$() and GW_SHOW_DIALOG_INPUT$(), merged GW_SHOW_DIALOG_MESSAGE() and % GW_SHOW_DIALOG_INPUT(), and merged GW_CLOSE_DIALOG_MESSAGE() and GW_CLOSE_DIALOG_INPUT(), now all DIALOG types % (DIALOG_MESSAGE, DIALOG_INPUT, DIALOG_CHECKBOX) share the same commands: GW_SHOW_DIALOG$(), GW_SHOW_DIALOG() % and GW_CLOSE_DIALOG() % * Added new control GW_ADD_DIALOG_CHECKBOX() + updated demo (advanced controls > Dialog Message) % * Fixed GW_MODIFY of key 'style' for TEXT and TEXTBOX % * Added new command GW_ADD_FONT$() to be used in a CUSTO with the "font" key % [v3.6] 23-SEP-2016 % * Fixed GW loading bar in a user APK + accelerated further the loading of the library! % * Replaced third party lib GW_PICK_FOLDER with much improved GW_PICK_FILE (+FOLDER), see updated demo % [v3.5] 20-SEP-2016 % * Removed GW splash screen. Added loading bar of GW lib. Use GW_SILENT_LOAD=1 to hide it (old behavior) % * Added auto-upgrade mechanism of GW lib and GW demo (in Editor mode only, blocked in user APK) % * Fixed GW_AMODIFY() of "content" (array of options) for SELECTBOX and of "list" for INPUTLIST (thanks to Michel) % * Fixed GW_AMODIFY() of "content" (array of images) for a GALLERY (broken in v3.3) % * Fixed (again) GW_CENTER_PAGE_VER() fixed in v2.0 but broken again in v2.8 % * Added GW_CLOSE_INPUTLIST() as per discussion at http://rfobasic.freeforums.org/clear-gw-inputlist-t4375.html % * Added GW_MODIFY() of key "text" for a SPINNER + updated demo % [v3.4] 31-AUG-2016 % * /!\ Removed mention of GW_ADD_INPUTFILE() in the documentation (control does nothing since Android 4.4) % * Fixed GW_MODIFY() of key "text" for a COLORPICKER % * Fixed GW_ENABLE() and GW_DISABLE() of a class % * [APK mode] Enhanced GW_MODIFY() to handle a new IMAGE that is in assets but not on sd-card % * [APK mode] Enhanced the following functions to support their js/css files in assets but not on sd: % GW_ADD_COLORPICKER(), GW_ADD_LOCK_PATTERN(), GW_ADD_SPINNER() % * Added new function GW_ADD_LOADING_IMG() to display an image (animated gif) when the page loads % * Added new function GW_FOCUS() to set the focus to a control % [v3.3] 21-JUL-2016 % * /!\ (internal) Changed the javascript HTML -> BASIC! link-function from doDataLink() to RFO() % * /!\ Re-integrated 2 resources into GW.bas: basic.js, styles.css. No more need to attach them in APK % * Fixed GW_SET_PROGRESSBAR() of a non-integer value % * Added new function JS(script$) to execute a javascript snippet on the page currently displayed % * Added new function IS_APK() to tell if the app runs in APK mode % * Added new function GW_GET_IMAGE_DIM$() to get the dimensions of an image in the form "WxH" % * Added new functions GW_HIDE() and GW_SHOW() to change visibility of a control % * [APK mode] Enhanced the following functions to handle files that are in assets but not on sd-card: % GW_LOAD_THEME(), GW_ADD_IMAGE(), GW_ADD_ICON(), GW_ADD_VIDEO(), GW_USE_FONT(), % now, when compiling your APK, you don't have to select the files for copy to sd-card at startup, % all you have to do is make sure you attach the resources in your APK % [v3.2] 05-JUL-2016 % * Added new control GW_ADD_DIALOG_INPUT() very similar to DIALOG_MESSAGE but with an input line: % the input line can be text (by default) or number, password, email, or url (see demo) % [v3.1] 23-JUN-2016 % * Fixed key "selected" for GW_MODIFY() of RADIO buttons % * Fixed key "selected" for GW_MODIFY() of CHECKBOXES % * Fixed GW_GET_VALUE$() and GW_RADIO_SELECTED() of RADIO buttons % * Added key "text" for GW_MODIFY() of CHECKBOX, FLIPSWITCH, SLIDER, SELECTBOX, and RADIO buttons % * Added key "selected" for GW_MODIFY() of SELECTBOX % * Added CUSTO property "mini" for BUTTONS % [v3.0] 29-APR-2016 % * Added LISTENER event "close" for a PANEL % * Added function GW_CLOSE_PANEL() to manually close an opened PANEL % * Added function GW_CLOSE_DIALOG_MESSAGE() to manually close an opened DIALOG_MESSAGE (see demo) % * Improved GW_AMODIFY() of a GALLERY to make it synchronous % * Rewrote (clarified) the list of APIs, cheatsheet, and demo for LISTENERs and for handling of Back key % [v2.9] 22-APR-2016 % * Fixed PAGE transition "none" % * Added function GW_DEFAULT_TRANSITIONS() e.g. "page=slide, panel=overlay, dialog_message=flip" % [v2.8] 21-APR-2016 % * Fixed support for PAGE transitions with GW_SET_TRANSITION() % * Added new function GW_CLOSE_PAGE() to manually show a closing transition (e.g. before leaving the app) % [v2.7] 20-APR-2016 % * Improved support for chaining a DIALOG_MESSAGE from another DIALOG_MESSAGE % * Fixed PANEL transitions in case of several panels in a page % * Improved individual transition management for each PANEL and DIALOG_MESSAGE % [v2.6] 14-APR-2016 % * Fixed GW_AMODIFY() of "buttons" for DIALOG_MESSAGE controls % * Fixed GW_MODIFY() of "title" for DIALOG_MESSAGE controls % * Fixed GW_SET_TRANSITION() of PANEL and DIALOG_MESSAGE controls after a page RENDER % * Changed DIALOG_MESSAGE to have vertical buttons by default, for horizontal (inline) buttons, use % GW_USE_THEME_CUSTO_ONCE("inline") before your GW_ADD_DIALOG_MESSAGE() % * Added support for chaining DIALOG_MESSAGEs with a button/action set to "My Button>"+GW_SHOW_DIALOG_MESSAGE$() % [v2.5] 09-APR-2016 % * /!\ Exported GW GALLERY to a third party lib, if you use it you now need to do: INCLUDE "GW_GALLERY.bas" % * /!\ Exported GW Aliases and Shortcuts to a third party lib. To use them: INCLUDE "GW_ALIASES_SHORTCUTS.bas" % To download the lib beforehand: GW_DOWNLOAD_THIRD_PARTY("GW_ALIASES_SHORTCUTS.bas") % * Added support for colored page during GW lib loading e.g. use GW_COLOR$="black" before your INCLUDE "GW.bas" % * Added new LISTENER events "swipeleft|swiperight|longpress|idleN": use them on a control, or on the page (ctl_id=0) % * Added new control GW_ADD_COLORPICKER(), you get color with GW_ADD_LISTENER$("change") or GW_GET_VALUE$() % * Added new special key to GW_MODIFY(): "style:subkey" to change the style (CSS) of a control % * Added GW_NEW_CLASS(): several controls can share a same class with a CUSTO "class='myclass'" % * Added GW_MODIFY() support for a whole class to change multiple controls with only 1 command % * Updated demo > Advanced > "Colorpicker + Class" to demonstrate the last 4 new features above % [v2.4] 06-APR-2016 % * Removed support for PAGE Transitions, broken (and unrecoverable) with the GW v1.8 "gray circle" fix % Calling GW_SET_TRANSITION() on a page will not throw an error but will do nothing (same as before) % * Fixed GW_WAIT_ACTION$() broken in v2.1 (and all functions using it e.g. GW_GET_VALUE$()) % * Fixed URL-encoding of user links in GW elements (buttons, listviews) especially when link contains % or + % * Fixed CUSTO of BAR_LBUTTON$() and BAR_RBUTTON$() when said custo contained a style='...' % * Added CUSTO "position=right|left", applied to panels in the first screens of the demo % * Added support for third party libs via GW_DOWNLOAD_THIRD_PARTY(). First one is "GW_PICK_FOLDER.bas" (see demo) % Users can upload their GW third party lib in laughton.com FTP > html > GW (GUI-Web lib) > third-party-libs % * Added GW_GALLERY_IS_OPEN() to programmatically know if a gallery is open % * Added GW_CLOSE_GALLERY() to programmatically close an opened gallery, demo is updated % [v2.3] 26-MAR-2016 % * Fixed customization of IMAGE, SLIDER and PROGRESSBAR controls % * Added 4 new customizations: 'hover=N' |S|E|W|NE|NW|SE|SW ; 'alpha=0% to 100% ; 'big' ; and 'fit-screen' % * Improved performance of GALLERY control, particularly in case of Base64 images % * Re-organized GW demo into 3 categories: basic/input/advanced to simplify navigation % [v2.2] 22-MAR-2016 % * Added a new control GW_ADD_GALLERY() taking an array of images as parameter (+demo updated) % * Added a new control GW_ADD_LOCK_PATTERN() and its companion functions GW_SHOW_WRONG_PATTERN(), and % GW_CLEAR_LOCK_PATTERN() (+demo updated). User pattern is returned as "pattern:NNNN" in GW_WAIT_ACTION$() % * Extended GW_MODIFY() to support any kind of key (=HTML attribute) to be modified, even ones unknown to GW % [v2.1] 13-MAR-2016 % * Added new function GW_ACTION$() equivalent to GW_WAIT_ACTION$() but asynchronous (non-blocking) % * Improved GW-progs debugging by throwing a more convenient error in case of bad control id or bad page id % [v2.0] 11-MAR-2016 % * Fixed GW_CENTER_PAGE_VER() % * Fixed GW_MODIFY() of slider value (key "val") % * Improved GW_RENDER() to be synchronous! % * Added a new page element: GW_ADD_SPINNER() and its functions GW_SHOW_SPINNER() and GW_HIDE_SPINNER() % * Added a new control GW_ADD_PROGRESSBAR() and its function GW_SET_PROGRESSBAR() % * Added 2 new functions: GW_DISABLE() and GW_ENABLE() mainly for use with buttons % [v1.9] 18-DEC-2015 % * /!\ Removed the GW_FORCE_MODE() function, now obsolete since the "gray circle" fix in GW lib v1.8 % * /!\ Added support for Back key: now it doesn't stop the lib anymore but returns "BACK" in GW_WAIT_ACTION$() % * Added GW_THEME_EXISTS() and GW_DOWNLOAD_THEME() to allow theme files to be downloaded programmatically % * Enhanced low-level handling of missing themes: there is now a popup proposing to automatically download files % * Cleaned-up the "Important notes" in the header of the lib % [v1.8] 14-DEC-2015 % * Added a script that fix gray circle issue for Android System WebView > 44.0.2403.117 % [v1.7] 29-NOV-2015 % * Added GW_MODIFY() of the "title" and "text" of a DIALOG_MESSAGE % * Added GW_MODIFY() of a "selected" FLIPSWITCH option (s_opt1$ or s_opt2$) % [v1.6] 13-JUN-2015 % * /!\ Renamed GW_ADD_TITLE$() to GW_ADD_BAR_TITLE$() ; renamed GW_ADD_LEFT_BUTTON$() to GW_ADD_BAR_LBUTTON$() ; % and finally renamed GW_ADD_RIGHT_BUTTON$() to GW_ADD_BAR_RBUTTON$() % * Fixed a bug when GW_MODIFYing a new content with double quotes and/or single quotes in it (esp. in a TABLE) % * Added a new control: GW_ADD_IMAGE() to display an image (with an hyperlink option) % * Added a whole new set of functions for all the GW_ADD_*(page, ...) functions: GW_ADD_*$(...) (1 less parameter) % returns the string result of the function without adding it to the page. E.g. GW_ADD_TEXT(p,t$) -> GW_ADD_TEXT$(t$) % * Added function GW_LAST_ID() (no argument) to get the Id of the last control created with GW_ADD_*$(...) % * Added function GW_ID(ctl_name$) to get the Id of a control known only from its name % * Added function GW_USE_FONT() to make use of a local font (TTF or other) % * Added GW_ENABLE_LISTENER() to enable listener of dynamically created content, typically after a GW_MODIFY/GW_AMODIFY % * Added support of GW_MODIFY for TITLEBARs and FOOTBARs, see the corresponding changeable keys in the cheatsheet % * Improved GW_ADD_TITLEBAR/FOOTBAR/DIALOG_MESSAGE/PANEL: they can be added anytime even after creating some controls % [v1.5] 07-MAY-2015 % * Fixed creation of *linked* listviews with GW_ADD_LISTVIEW(), the links now work from the start % * Added aliases / shortcuts for all GW functions, shorter and easier to write from mobile device % [v1.4] 21-APR-2015 % * Added a new control: GW_ADD_LISTVIEW() based on the work from forum user Gyula % * Fixed an Android 5.0 bug when setting GW_SET_TRANSITION() of a page without controls % [v1.3] 12-FEB-2015 % * Added GW_ADD_FOOTBAR() counterpart of a TITLEBAR but at the bottom of the page % * Added 3 new functions to build a TITLEBAR or FOOTBAR: GW_ADD_LEFT_BUTTON$() GW_ADD_TITLE$() GW_ADD_RIGHT_BUTTON$() % * Added a new control: GW_ADD_ICON() that allows with GW_ICON$() to add custom icons in TITLEBAR or FOOTBAR % * Added function GW_ADD_LISTENER() that triggers an action when a certain event occurs on a control % * Improved GW_GET_VALUE() and GW_GET_VALUE$() to retrieve the live content of a control! (without submit) % [v1.2] 15-JAN-2015 % * Added new standard control GW_ADD_TABLE() to make tables with (">") or w/o a title line % * Added GW_AMODIFY() (ARRAY-MODIFY) for controls taking an array as a parameter: TABLE, INPUTLIST, % SELECTBOX and DIALOG_MESSAGE % [v1.1] 14-JAN-2015 % * Added GW_SHOW_DIALOG_MESSAGE() to display a dialog message manually % * Added GW_SHOW_PANEL() to open a panel manually % * Added GW_MODIFY() of the state of a CHECKBOX and of a RADIO button % * Added GW_SET_TRANSITION() to change the transition animation of DIALOG_MESSAGE, PAGE, or PANEL % * Added GW_ADD_INPUTDATETIME() as a workaround for the INPUTTIME bug on Android Lollipop % ( see https://code.google.come/p/chromium/issues/detail?id=434695 ) % [v1.0] 12-JAN-2015 % * Added support of videos! both local or online with GW_ADD_VIDEO() % * Added 2 new user input controls: GW_ADD_INPUTLIST() and GW_ADD_SELECTBOX() % * Added GW_MODIFY() to modify properties of already ADDed controls % * Removed GW_SET_CONTENT(), the functionality of which is now merged (and extended) in GW_MODIFY() % [v0.9] 11-JAN-2015 % * Added a new page element: GW_ADD_DIALOG_MESSAGE() and its 'trigger' link GW_SHOW_DIALOG_MESSAGE$() % * Added function GW_CENTER_PAGE_VER() to center vertically the page content % * Added GW_PREVENT_LANDSCAPE() and GW_PREVENT_PORTRAIT(), undocumented because HTML.ORIENTATION is prefered % [v0.8] 08-JAN-2015 % * Fixed the usage of GW_USE_THEME_CUSTO_ONCE() for a first control in the page % * Fixed the possibility to enter a decimal number with GW_ADD_INPUTNUMBER() % * Added 2 functions to be used after GW_WAIT_ACTION$(): GW_CHECKBOX_CHECKED() and GW_RADIO_SELECTED() % * Added GW_LINK$() to embed a link into a string used in a control (TEXTBOX, TEXT, TITLE, etc.) % * Created a GW APis cheat sheet available at http://mougino.free.fr/tmp/GW/cheatsheet.html % [v0.7] 06-JAN-2015 % * Fixed GW_GET_VALUE() of an empty control, it now returns 0 (zero) % * Added GW_INJECT_HTML() to add custom HTML/CSS/JavaScript code to the page % * Added GW_START_CENTER() and GW_STOP_CENTER() to center elements on the page % [v0.6] 04-JAN-2015 % * Changed the number of parameters of GW_ADD_INPUTBOX(): n-rows and n-cols are no longer needed % * Fixed the rendering of the "native-droid-*" theme family % * Fixed inline comments highlighting with GW_CODE_HIGHLIGHT$() % * Added GW_OPEN_GROUP() and GW_CLOSE_GROUP() to visually group CHECKBOX or RADIO controls % * Added 11 new user input controls: GW_ADD_INPUTDATE(), GW_ADD_INPUTTIME(), GW_ADD_INPUTMONTH(), % GW_ADD_INPUTWEEK(), GW_ADD_INPUTURL(), GW_ADD_INPUTEMAIL(), GW_ADD_INPUTCOLOR(), GW_ADD_INPUTNUMBER(), % GW_ADD_INPUTTEL(), GW_ADD_INPUTPASSWORD(), GW_ADD_INPUTFILE() % * Added a 'reset' button (X) to the input controls that support it=INPUTLINE and the 11 new controls % * Added the compatibility mode FORCE_MODE(1) for Android devices that otherwise show empty GW pages % [v0.5] 31-DEC-2014 % * Added full support for the "native-droid-*" theme family, composed of % 10 themes: 5 colors blue/green/purple/red/yellow in 2 flavours light/dark (recommended) % * Added full support for the "square-ui" theme (recommended) % * Added limited support for the "android-holo" theme (deprecated, not recommended) % * Added limited support for the "metro" theme (deprecated, not recommended) % [v0.4] 30-DEC-2014 % * Added 2 new input controls: GW_ADD_CHECKBOX() and GW_ADD_RADIO() % * Fixed and improved the rendering of the themes % * Added full support for the "bootstrap" theme (recommended) % * Added limited support for the "iOS" theme (deprecated, not recommended) % [v0.3] 29-DEC-2014 % * Added themes and theme-customization! persistent or 1-shot (GW_USE_THEME_CUSTO /.._ONCE) % * Added full support for the "flat-ui" theme (recommended) % * Added limited support for the "classic" jQuery Mobile theme (deprecated, not recommended) % * Added initial selection of FLIPSWITCH second state (s_opt2$) if it begins with ">" % [v0.2] 28-DEC-2014 % * Renamed the lib to 'GW' (GUI-Web) % * Created GW_demo.bas % * Added 3 new standard controls: GW_ADD_BUTTON() GW_ADD_LINK() and GW_ADD_TEXT() % * Added 3 new input controls: GW_ADD_FLIPSWITCH(), GW_ADD_INPUTLINE() and GW_ADD_INPUTBOX() % * Added a new page element: GW_ADD_PANEL() and its 'trigger' link GW_SHOW_PANEL$() % * Added GW_GET_VALUE() -> returns a number (Vs GW_GET_VALUE$() returns a string) % * Added GW_CODE_HIGHLIGHT$() for syntax highlighting % * Renamed all GW_NEW* control creation functions to GW_ADD_* % * Renamed GW_SET_SECTION_TEXT() to GW_SET_CONTENT() % * GW_GET_VALUE() GW_GET_VALUE$() and GW_SET_CONTENT() now take only 1 param (ctl_id) % * SLIDER control now takes an extra parameter: n_step % [v0.1] 24-DEC-2014 % * Initial release FN.DEF MAKE_SURE_IS_ON_SD(f$) % (internal) make sure file$ is on sd-card, else try to copy it from asset. FILE.EXISTS onSd, f$ % This function is to be used after testing: IF IS_APK() THEN ... IF IS_IN("data:", f$)=1 THEN FN.RTN 1 % do not treat base64-encoded media IF !onSd BYTE.OPEN r, fid, f$ % open from assets IF fid<0 THEN FN.RTN 0 % file does not exist PRINT "Unpacking " + f$ j=IS_IN("/", f$) WHILE j % create subfolder hierarchy for this file, if any FILE.MKDIR LEFT$(f$, j) j=IS_IN("/", f$, j+1) REPEAT BYTE.COPY fid, f$ ENDIF FN.RTN 1 FN.END % FN.END not followed by \n --> do no count this function in GW_NFN IF GW_SILENT_LOAD=2 THEN GOTO gw_super_silent_load % http://rfobasic.freeforums.org/super-silent-load-t4748.html GRABFILE gw$, "../source/GW.bas" IF gw$="" THEN END "Error misplaced or renamed library: cannot find \"source/GW.bas\"" BUNDLE.CREATE gwbundle % name is insignificant, we need at least one bundle IF GW_ORIENTATION$="landscape" BUNDLE.PUT 1, "gw-init-orient", 0 ELSEIF GW_ORIENTATION$="portrait" BUNDLE.PUT 1, "gw-init-orient", 1 ELSEIF GW_ORIENTATION$="reverse-landscape" BUNDLE.PUT 1, "gw-init-orient", 2 ELSEIF GW_ORIENTATION$="reverse-portrait" BUNDLE.PUT 1, "gw-init-orient", 3 ELSE % default: variable by sensors BUNDLE.PUT 1, "gw-init-orient", -1 ENDIF FN.DEF GW_ORIENTGET() % (internal) get screen orientation defined with GW_ORIENTATION$ BUNDLE.GET 1, "gw-init-orient", o FN.RTN o FN.END % FN.END not followed by \n --> do no count this function in GW_NFN HTML.OPEN 0, GW_ORIENTGET() % hide status bar, else JQM header is masked (bug) IF GW_SILENT_LOAD GW_LPG$="" IF LEN(GW_COLOR$) THEN GW_LPG$=REPLACE$(GW_LPG$, "

Loading the lib...
 

http://mougino.free.fr

" GW_LOGO$="" % free 2.25KB of memory IF LEN(GW_COLOR$) GW_LPG$=REPLACE$(GW_LPG$, "html *", "p,a{-webkit-filter:invert(100%)} html {background:"+GW_COLOR$+"} html *") ENDIF HTML.LOAD.STRING GW_LPG$ GW_LPG$="" % free 3KB of memory DO: HTML.GET.DATALINK data$: PAUSE 1: UNTIL data$="DAT:ready" ! (internal) count number of GW functions i=IS_IN("FN.END\n", gw$) WHILE i GW_NFN++ % Number of GW functions i=IS_IN("FN.END\n", gw$, i+1) REPEAT ENDIF gw$="" % free 160KB of memory gw_super_silent_load: FN.DEF GW_LOAD_PG(n, tot) % (internal) update GW lib loading progress IF tot>0 THEN HTML.LOAD.URL "javascript:$('#slider1').val("+STR$(INT(n/tot*1000)/10)+")" FN.END % FN.END not followed by \n --> do no count this function in GW_NFN ARRAY.LOAD GW_THEME$[], "default", "flat-ui", "classic", "ios", ~ "bootstrap", "android-holo", "square-ui", "metro", "native-droid" BUNDLE.PUT 1, "gw-theme", "default" % <-- change if you want another theme by default BUNDLE.PUT 1, "gw-ver", GW_VER$ BUNDLE.PUT 1, "gw-last-edited-page", 0 BUNDLE.PUT 1, "gw-last-rendered-page", 0 BUNDLE.PUT 1, "gw-last-displayed-dialog", 0 BUNDLE.PUT 1, "gw-default-page-transition", "none" BUNDLE.PUT 1, "gw-default-panel-transition", "push" BUNDLE.PUT 1, "gw-default-dlg-transition", "pop" BUNDLE.PUT 1, "gw-last-command", "" BUNDLE.PUT 1, "gw-zoom-input", 1 BUNDLE.PUT 1, "gw-theme-custo", 0 BUNDLE.PUT 1, "gw-theme-custo-token", 0 % zero token=no customization BUNDLE.PUT 1, "gw-theme-1-files", "jquery-2.1.1.min.js, jquery.mobile-1.4.5.min.css, jquery.mobile-1.4.5.min.js" BUNDLE.PUT 1, "gw-no-transition-script", "RFO('GwReady')" BUNDLE.PUT 1, "gw-transition-script", "$(window).load(function(){setTimeout(function(){$('#openthispage').click();},10)}); $('#page0').on('animationend webkitAnimationEnd',function(e){$('#page0').off(e); setTimeout(function(){RFO('open-endanim');},10);});" BUNDLE.PUT 1, "gw-swipedown-script", "document.addEventListener('touchstart',handleTouchStart,!1),document.addEventListener('touchmove',handleTouchMove,!1);var xDown=null,yDown=null;function getTouches(n){return n.touches||n.originalEvent.touches}function handleTouchStart(n){const o=getTouches(n)[0];xDown=o.clientX,yDown=o.clientY}function handleTouchMove(n){if(xDown&&yDown){var o=n.touches[0].clientX,t=n.touches[0].clientY,e=xDown-o,u=yDown-t;Math.abs(e)<=Math.abs(u)&&(u<0?AxD:null),xDown=null,yDown=null}}" BUNDLE.PUT 1, "gw-theme-2-files", "flatui/jquery.mobile.flatui.css, flatui/fonts/Flat-UI-Icons-24.ttf, flatui/fonts/Flat-UI-Icons-24.woff, flatui/fonts/lato-black.ttf, flatui/fonts/lato-black.woff, flatui/fonts/lato-bold.ttf, flatui/fonts/lato-bold.woff, flatui/fonts/lato-italic.ttf, flatui/fonts/lato-italic.woff, flatui/fonts/lato-regular.ttf, flatui/fonts/lato-regular.woff, flatui/images/ajax-loader.gif, flatui/images/icons-18-black.png, flatui/images/icons-18-white.png, flatui/images/icons-36-black.png, flatui/images/icons-36-white.png" BUNDLE.PUT 1, "gw-theme-3-files", "jquery-2.1.1.min.js, jquery.mobile-1.4.5.min.css, jquery.mobile-1.4.5.min.js, theme-classic.css" BUNDLE.PUT 1, "gw-theme-4-files", "ios/ios.css, ios/jquery-1.7.1.min.js, ios/jquery.mobile-1.2.0.min.css, ios/jquery.mobile-1.2.0.min.js, ios/images/ajax-loader.gif, ios/images/arrow_right.png, ios/images/arrow_right@2x.png, ios/images/backButtonSprite.png, ios/images/backButtonSprite@2x.png, ios/images/icons-18-black.png, ios/images/icons-18-white.png, ios/images/icons-36-black.png, ios/images/icons-36-white.png, ios/images/iconSprite.png, ios/images/tabSprite.png, ios/images/tick.png, ios/images/tiling_stripes.gif" BUNDLE.PUT 1, "gw-theme-5-files", "bootstrap/Bootstrap.min.css, bootstrap/images/ajax-loader.gif, bootstrap/images/icons-png/action-black.png, bootstrap/images/icons-png/action-white.png, bootstrap/images/icons-png/alert-black.png, bootstrap/images/icons-png/alert-white.png, bootstrap/images/icons-png/arrow-d-black.png, bootstrap/images/icons-png/arrow-d-l-black.png, bootstrap/images/icons-png/arrow-d-l-white.png, bootstrap/images/icons-png/arrow-d-r-black.png, bootstrap/images/icons-png/arrow-d-r-white.png, bootstrap/images/icons-png/arrow-d-white.png, bootstrap/images/icons-png/arrow-l-black.png, bootstrap/images/icons-png/arrow-l-white.png, bootstrap/images/icons-png/arrow-r-black.png, bootstrap/images/icons-png/arrow-r-white.png, bootstrap/images/icons-png/arrow-u-black.png, bootstrap/images/icons-png/arrow-u-l-black.png, bootstrap/images/icons-png/arrow-u-l-white.png, bootstrap/images/icons-png/arrow-u-r-black.png, bootstrap/images/icons-png/arrow-u-r-white.png, bootstrap/images/icons-png/arrow-u-white.png, bootstrap/images/icons-png/audio-black.png, bootstrap/images/icons-png/audio-white.png, bootstrap/images/icons-png/back-black.png, bootstrap/images/icons-png/back-white.png, bootstrap/images/icons-png/bars-black.png, bootstrap/images/icons-png/bars-white.png, bootstrap/images/icons-png/bullets-black.png, bootstrap/images/icons-png/bullets-white.png, bootstrap/images/icons-png/calendar-black.png, bootstrap/images/icons-png/calendar-white.png, bootstrap/images/icons-png/camera-black.png, bootstrap/images/icons-png/camera-white.png, bootstrap/images/icons-png/carat-d-black.png, bootstrap/images/icons-png/carat-d-white.png, bootstrap/images/icons-png/carat-l-black.png, bootstrap/images/icons-png/carat-l-white.png, bootstrap/images/icons-png/carat-r-black.png, bootstrap/images/icons-png/carat-r-white.png, bootstrap/images/icons-png/carat-u-black.png, bootstrap/images/icons-png/carat-u-white.png, bootstrap/images/icons-png/check-black.png, bootstrap/images/icons-png/check-white.png, bootstrap/images/icons-png/clock-black.png, bootstrap/images/icons-png/clock-white.png, bootstrap/images/icons-png/cloud-black.png, bootstrap/images/icons-png/cloud-white.png, bootstrap/images/icons-png/comment-black.png, bootstrap/images/icons-png/comment-white.png, bootstrap/images/icons-png/delete-black.png, bootstrap/images/icons-png/delete-white.png, bootstrap/images/icons-png/edit-black.png, bootstrap/images/icons-png/edit-white.png, bootstrap/images/icons-png/eye-black.png, bootstrap/images/icons-png/eye-white.png, bootstrap/images/icons-png/forbidden-black.png, bootstrap/images/icons-png/forbidden-white.png, bootstrap/images/icons-png/forward-black.png, bootstrap/images/icons-png/forward-white.png, bootstrap/images/icons-png/gear-black.png, bootstrap/images/icons-png/gear-white.png, bootstrap/images/icons-png/grid-black.png, bootstrap/images/icons-png/grid-white.png, bootstrap/images/icons-png/heart-black.png, bootstrap/images/icons-png/heart-white.png, bootstrap/images/icons-png/home-black.png, bootstrap/images/icons-png/home-white.png, bootstrap/images/icons-png/info-black.png, bootstrap/images/icons-png/info-white.png, bootstrap/images/icons-png/location-black.png, bootstrap/images/icons-png/location-white.png, bootstrap/images/icons-png/lock-black.png, bootstrap/images/icons-png/lock-white.png, bootstrap/images/icons-png/mail-black.png, bootstrap/images/icons-png/mail-white.png, bootstrap/images/icons-png/minus-black.png, bootstrap/images/icons-png/minus-white.png, bootstrap/images/icons-png/navigation-black.png, bootstrap/images/icons-png/navigation-white.png, bootstrap/images/icons-png/phone-black.png, bootstrap/images/icons-png/phone-white.png, bootstrap/images/icons-png/plus-black.png, bootstrap/images/icons-png/plus-white.png, bootstrap/images/icons-png/power-black.png, bootstrap/images/icons-png/power-white.png, bootstrap/images/icons-png/recycle-black.png, bootstrap/images/icons-png/recycle-white.png, bootstrap/images/icons-png/refresh-black.png, bootstrap/images/icons-png/refresh-white.png, bootstrap/images/icons-png/search-black.png, bootstrap/images/icons-png/search-white.png, bootstrap/images/icons-png/shop-black.png, bootstrap/images/icons-png/shop-white.png, bootstrap/images/icons-png/star-black.png, bootstrap/images/icons-png/star-white.png, bootstrap/images/icons-png/tag-black.png, bootstrap/images/icons-png/tag-white.png, bootstrap/images/icons-png/user-black.png, bootstrap/images/icons-png/user-white.png, bootstrap/images/icons-png/video-black.png, bootstrap/images/icons-png/video-white.png" BUNDLE.PUT 1, "gw-theme-6-files", "android-holo/android-holo-light.min.css, android-holo/jquery-1.7.1.min.js, android-holo/jquery.mobile-1.1.0.min.js, android-holo/jquery.mobile.structure-1.1.0.min.css, android-holo/images/ajax-loader.gif, android-holo/images/icons-18-black.png, android-holo/images/icons-18-white.png, android-holo/images/icons-36-black.png, android-holo/images/icons-36-white.png" BUNDLE.PUT 1, "gw-theme-7-files", "squareui/jquery.mobile.squareui.min.css, squareui/fonts/Flat-UI-Icons-24.woff, squareui/fonts/lato-black.woff, squareui/fonts/lato-bold.woff, squareui/fonts/lato-italic.woff, squareui/fonts/lato-regular.woff, squareui/images/ajax-loader.gif, squareui/images/icons-18-black.png, squareui/images/icons-18-white.png, squareui/images/icons-36-black.png, squareui/images/icons-36-white.png" BUNDLE.PUT 1, "gw-theme-8-files", "metro/jquery-1.7.1.min.js, metro/jquery.mobile-1.1.0.min.js, metro/jquery.mobile.metro.theme.css, metro/jquery.mobile.metro.theme.init.js, metro/jquery.mobile.structure-1.1.0.min.css, metro/images/ajax-loader.png, metro/images/checkbox-disabled.png, metro/images/checkbox.png, metro/images/icons-18-black.png, metro/images/icons-18-white.png, metro/images/icons-36-black.png, metro/images/icons-36-white.png, metro/images/radiobtn-disabled.png, metro/images/radiobtn.png, metro/images/wait-indicator.gif" BUNDLE.PUT 1, "gw-theme-9-files", "nativedroid/font-awesome.min.css, nativedroid/fonts.css, nativedroid/jquery-1.9.1.min.js, nativedroid/jquery.mobile-1.4.2.min.css, nativedroid/jquery.mobile-1.4.2.min.js, nativedroid/jquerymobile.nativedroid.color.blue.css, nativedroid/jquerymobile.nativedroid.color.green.css, nativedroid/jquerymobile.nativedroid.color.purple.css, nativedroid/jquerymobile.nativedroid.color.red.css, nativedroid/jquerymobile.nativedroid.color.yellow.css, nativedroid/jquerymobile.nativedroid.css, nativedroid/jquerymobile.nativedroid.dark.css, nativedroid/jquerymobile.nativedroid.light.css, nativedroid/nativedroid.script.js, nativedroid/fonts/fontawesome-webfont.eot, nativedroid/fonts/fontawesome-webfont.svg, nativedroid/fonts/fontawesome-webfont.ttf, nativedroid/fonts/fontawesome-webfont.woff, nativedroid/fonts/FontAwesome.otf" %--------------------------------------------------------------------------------------------- % FUNCTIONS TO BE CALLED BEFORE CREATING A PAGE %--------------------------------------------------------------------------------------------- FN.DEF IS_APK() % (internal) return true (1) if we are in apk mode, false (0) otherwise FILE.EXISTS Editor, "../source/GW.bas" FN.RTN (!Editor) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF JS(script$) % (internal) execute a javascript code HTML.LOAD.URL "javascript:console.log(\"JS: "+script$+"\")" HTML.LOAD.URL "javascript:"+script$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ZOOM_INPUT(zoom) BUNDLE.PUT 1, "gw-zoom-input", zoom FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF MAKE_FULL_PATH(f$) % create subfolder hierarchy for a file (if any) j=IS_IN("/", f$) WHILE j FILE.MKDIR LEFT$(f$, j) j=IS_IN("/", f$, j+1) REPEAT FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF DEL_FULL_PATH(f$) % delete subfolder hierarchy (if any) j=IS_IN("/", f$, -1) WHILE j f$=LEFT$(f$, j-1) FILE.DELETE deleted, f$ IF !deleted THEN FN.RTN 0 j=IS_IN("/", f$, -1) REPEAT FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CHECK_AND_DOWNLOAD(f$) % (internal) Download a single file to the device (except if it already exists) IF 1=IS_IN("GW/", UPPER$(f$)) THEN f$=MID$(f$, 4) lf$="GW/" + f$ % new: put every GW resources inside data/GW subfolder ; lf$=local file FILE.EXISTS fe, lf$ IF fe THEN FN.RTN 1 % already on device! FILE.EXISTS fe, f$ IF fe % already on device but at old place (not in 'GW' subfolder) MAKE_FULL_PATH(lf$) FILE.RENAME f$, lf$ IF IS_IN("/", f$) THEN DEL_FULL_PATH(f$) % remove old folder hierarchy if possible (and if it's not the data/ root) FN.RTN 1 ENDIF % else file is not on device -> download it from mougino or rvadlist servers BYTE.OPEN r, fid, "http://mougino.free.fr/tmp/GW/" + f$ IF fid<0 THEN BYTE.OPEN r, fid, "http://www.rvadlist.com/GW/" + f$ % fallback IF fid<0 THEN FN.RTN 0 % could not access file on both mougino & rvadlist servers PRINT "Downloading " + f$ MAKE_FULL_PATH(lf$) BYTE.COPY fid, lf$ FN.RTN 1 FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_DOWNLOAD_THIRD_PARTY(f$) % Download 3rd party lib from mougino.free.fr (fallback: rvadlist.com) to source/ FILE.EXISTS fe, "../source/" + f$ IF fe THEN FN.RTN 1 % already on device! BYTE.OPEN r, fid, "http://mougino.free.fr/tmp/GW/third-party-libs/" + f$ IF fid<0 THEN BYTE.OPEN r, fid, "http://www.rvadlist.com/GW/third-party-libs/" + f$ IF fid<0 THEN END "Error: GW was unable to download 3rd party lib " + f$ + "\n" + GETERROR$() PRINT "Downloading 3rd party lib " + f$ BYTE.COPY fid, "../source/" + f$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CHECK_THEME(theme$) % (internal) Check existence on the device of main .css file for a theme IF GW_THEME_EXISTS(theme$) THEN FN.RTN 1 % already on device! IF IS_IN("native-droid", theme$)=1 THEN theme$="native-droid" IF !GW_DOWNLOAD_THEME(theme$) END "There was a problem downloading GW theme '"+theme$+"'.\n" + GETERROR$() ENDIF FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_DOWNLOAD_THEME(e$) % Download to device all files for a given theme idx=GW_THEME_INDEX(e$) IF idx THEN FN.RTN GW_DOWNLOAD_THEME_FILES(idx) ELSE FN.RTN 0 FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_DOWNLOAD_THEME_FILES(theme) % (internal) Download theme #theme (full set of files) to the device BUNDLE.GET 1, "gw-theme-" + INT$(theme) + "-files", allfiles$ SPLIT file$[], allfiles$, "," ARRAY.LENGTH nfiles, file$[] res=1 FOR i=1 TO nfiles res *= GW_CHECK_AND_DOWNLOAD("GW/"+TRIM$(file$[i])) NEXT FN.RTN res FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_INDEX(e$) % (internal) return index of GW theme e$=LOWER$(e$) IF e$="default" THEN FN.RTN 1 IF e$="flat-ui" THEN FN.RTN 2 IF e$="classic" THEN FN.RTN 3 IF e$="ios" THEN FN.RTN 4 IF e$="bootstrap" THEN FN.RTN 5 IF e$="android-holo" THEN FN.RTN 6 IF e$="square-ui" THEN FN.RTN 7 IF e$="metro" THEN FN.RTN 8 IF IS_IN("native-droid", e$)=1 THEN FN.RTN 9 FN.RTN 0 % any other case=illegal theme FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_OF_PAGE$(page) % (internal) return the theme of the page 'page' e$=GW_PAGE$(page) % each command calling GW_THEME_OF_PAGE$() must have checked validity of 'page' ARRAY.LOAD thm$[], "default", "flat-ui", "classic", "ios", ~ "bootstrap", "android-holo", "square-ui", "metro", "native-droid" ARRAY.LENGTH nthm, thm$[] FOR i=1 TO nthm IF IS_IN(GW_THEME_CSS$(thm$[i]), e$) THEN F_N.BREAK NEXT FN.RTN thm$[i] FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_LOAD_THEME(e$) IF GW_THEME_INDEX(e$)=0 % Throw an error e$="Illegal GW theme: '"+e$+"'.\n" e$+="Should be: 'default', 'flat-ui', 'classic', 'ios', 'bootstrap', " e$+="'android-holo', 'square-ui', 'metro', or 'native-droid'." END e$ ENDIF % Change 'theme' property in the global bundle BUNDLE.PUT 1, "gw-theme", LOWER$(e$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_UNLOAD_THEME() % Reset theme to default FN.RTN GW_LOAD_THEME("default") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_EXISTS(e$) % Return true|false depending if theme's full set of files exist on device idx=GW_THEME_INDEX(e$) IF idx THEN FN.RTN GW_THEME_FILES_EXIST(idx) ELSE FN.RTN 0 FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_FILES_EXIST(theme) % (internal) Check existence of theme #theme (full set of files) on the device BUNDLE.GET 1, "gw-theme-" + INT$(theme) + "-files", allfiles$ SPLIT file$[], allfiles$, "," ARRAY.LENGTH nfiles, file$[] exists=1 FOR i=1 TO nfiles file$=TRIM$(file$[i]) IF IS_APK() THEN MAKE_SURE_IS_ON_SD("GW/" + file$) % in APK mode: if theme file is not on sdcard, copy it from assets FILE.EXISTS fe, "GW/" + file$ % is the theme file in the new 'GW' subfolder? IF !fe FILE.EXISTS fe, file$ % if no is it at the old place? IF fe % yes -> move it! MAKE_FULL_PATH("GW/" + file$) FILE.RENAME file$, "GW/" + file$ IF IS_IN("/", file$) THEN DEL_FULL_PATH(file$) % remove old folder hierarchy if possible (and if it's not the data/ root) ENDIF ENDIF exists *= fe NEXT FN.RTN exists FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_CSS$(e$) % (internal) Return path to main .css file for a desired theme IF e$="default" THEN FN.RTN "jquery.mobile-1.4.5.min.css" IF e$="classic" THEN FN.RTN "theme-classic.css" IF e$="flat-ui" THEN FN.RTN "flatui/jquery.mobile.flatui.css" IF e$="ios" THEN FN.RTN "ios/ios.css" IF e$="bootstrap" THEN FN.RTN "bootstrap/Bootstrap.min.css" IF e$="android-holo" THEN FN.RTN "android-holo/android-holo-light.min.css" IF e$="square-ui" THEN FN.RTN "squareui/jquery.mobile.squareui.min.css" IF e$="metro" THEN FN.RTN "metro/jquery.mobile.metro.theme.css" IF IS_IN("native-droid", e$)=1 THEN FN.RTN "nativedroid/jquerymobile.nativedroid.css" FN.RTN "" % any other case=illegal theme FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % FUNCTION TO CREATE A NEW GW PAGE %--------------------------------------------------------------------------------------------- FN.DEF GW_NEW_PAGE() % Return an index (<0)to a new GW page script$="" % Check presence of theme CSS and load it BUNDLE.GET 1, "gw-theme", theme$ GW_CHECK_THEME(theme$) css$=GW_THEME_CSS$(theme$) % Build beginning of HTML string e$ ="" e$+="" e$+="" e$+="" e$+="" % The following themes need another CSS to work IF theme$="ios" e$+="" e$+="" e$+="" e$+=script$+"" ELSEIF theme$="android-holo" e$+="" e$+="" e$+="" e$+=script$+"" ELSEIF theme$="metro" e$+="" e$+="" e$+="" e$+="" e$+=script$+"" ELSEIF IS_IN("native-droid", theme$)=1 e$=LEFT$(e$, IS_IN("", " .ui-listview sup{font-size:0.6em;color:#cc0000;} .ios-dlg{color:#fff;text-shadow:0 -1px 0 #4c596a}") e$=REPLACE$(e$, "", " .ui-listview sup{font-size:0.6em;color:#cc0000;} .ios-dlg{color:#fff;text-shadow:0 -1px 0 #4c596a}") ENDIF e$+="function populate(my_id,my_txt){document.getElementById(my_id).innerHTML=my_txt;} " e$+="function RFO(data){Android.dataLink(data);} " e$+="function replace(ctlid, tag){var obj=document.getElementById(ctlid); var regex=new RegExp('<'+obj.tagName,'i'); var newTag=obj.outerHTML.replace(regex,'<'+tag); regex=new RegExp('" e$+="" % Add the page to the list of GW pages ls=GW_KEY_IDX("page") + 1 % The 3 following calls to GW_THEME_CUSTO$() do NOT reset GW_USE_THEME_CUSTO_ONCE token e$+="
" e$+="
" e$+="
" GW_ADD_SKEY("page", e$) BUNDLE.GET 1, "gw-default-page-transition", dpt$ GW_ADD_SKEY("transition", dpt$) % fade|pop|flip|turn|flow|slidefade|slide|slideup|slidedown|none BUNDLE.PUT 1, "gw-last-edited-page", -ls FN.RTN -ls % index to a PAGE is < 0 to differentiate from indexes to CONTROLs FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % FUNCTIONS TO TRANSFORM PAGE - TO BE INSERTED BEFORE CONTENT %--------------------------------------------------------------------------------------------- FN.DEF GW_INSERT_BEFORE(page, main$, ins$) % (internal) insert element before another (content, head...) e$=GW_PAGE$(page) % each command calling GW_INSERT_BEFORE() must have REGISTERED its name sens=1 : IF IS_IN("^", main$)=1 THEN sens=-1 : main$=MID$(main$, 2) i=IS_IN(main$, e$, sens) IF !i THEN FN.RTN 0 e$=LEFT$(e$, i-1) + ins$ + MID$(e$, i) GW_SET_SKEY("page", page, e$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_PREVENT_SELECT(page) GW_REGISTER("GW_PREVENT_SELECT") e$=GW_PAGE$(page) IF IS_IN("body{-webkit-user-select:none}", e$) THEN FN.RTN 1 i=IS_IN("" GW_REGISTER("GW_USE_FONT") FN.RTN GW_INSERT_BEFORE(page, "", ins$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_TRANSITIONS_PARSE(all$, elt$) i=IS_IN(elt$+"=", all$) IF !i THEN FN.RTN 0 i += LEN(elt$+"=") j=IS_IN(",", all$, i) IF !j THEN j=LEN(all$)+1 fx$=MID$(all$, i, j-i) BUNDLE.PUT 1, "gw-default-"+elt$+"-transition", fx$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_DEFAULT_TRANSITIONS(fxs$) % set default transitions: fx$="page=fx, panel=fx, dialog_message=fx" e$=LOWER$(REPLACE$(fxs$, " ", "")) e$=REPLACE$(e$, "dialog_message", "dlg") e$=REPLACE$(e$, "dialog_input", "dlg") e$=REPLACE$(e$, "dialog_checkbox", "dlg") e$=REPLACE$(e$, "dialog", "dlg") GW_TRANSITIONS_PARSE(e$, "page") GW_TRANSITIONS_PARSE(e$, "panel") GW_TRANSITIONS_PARSE(e$, "dlg") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SET_TRANSITION(ctl_id, fx$) % set transition of PAGE, DIALOG or PANEL (during build or after render) IF ctl_id=0 END "Bad page id or control id: '0' in command GW_SET_TRANSITION().\nUndefined id." ELSEIF ctl_id < 0 % Transition of a PAGE page=-ctl_id ls=GW_KEY_IDX("page") IF page > ls e$="Bad page id: '"+INT$(page)+"' in command GW_SET_TRANSITION().\n" e$+="Out of range (last page id is '-"+INT$(ls)+"')." END e$ ENDIF GW_SET_SKEY("transition", page, fx$) % register transition of PAGE. It will be used in GW_RENDER() FN.RTN 1 % done -> exit function ENDIF % Else get Unique IDentifier of the control (PANEL or DIALOG) GW_REGISTER("GW_SET_TRANSITION") ctl$=GW_ID$(ctl_id) BUNDLE.GET 1, "gw-last-edited-page", page IF page % setting transition needs an existing page page$=GW_PAGE$(page) % 'page' is sure to exist -> no need to REGISTER command IF IS_IN("", page$) % page already rendered -> modify transition via dynamic javascript IF IS_IN("panel", ctl$)=1 % PANEL JS("$('#"+ctl$+"').panel({display:'"+fx$+"'})") ELSE % DIALOG JS("var effect"+ctl$+"='"+fx$+"'") ENDIF ELSE % page under construction -> set transition via static html IF IS_IN("panel", ctl$)=1 % PANEL i=IS_IN("id='"+ctl$, page$) i=IS_IN("data-display='", page$, i) + LEN("data-display=") j=IS_IN("'", page$, i+1) page$=LEFT$(page$, i) + fx$ + MID$(page$, j) GW_SET_SKEY("page", page, page$) ELSE % DIALOG i=IS_IN("effect"+ctl$+"='", page$) IF i % existing transition -> modify it i+=LEN("effect"+ctl$+"=") j=IS_IN("'", page$, i+1) page$=LEFT$(page$, i) + fx$ + MID$(page$, j) GW_SET_SKEY("page", page, page$) ELSE % newly set transition -> create it script$="" GW_INSERT_BEFORE(page, " no need to REGISTER command ENDIF % /transition of new/existing dialog ENDIF % /panel/dialog ENDIF % /page already-rendered/under-construction ENDIF % /last-edited-page exists FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CUSTO_DLGBTN(page, dlg, btn$, custo$) i=IS_IN(">", btn$) : IF i THEN btn$=LEFT$(btn$, i-1) custo$=LOWER$(custo$) IF IS_IN("icon=", custo$) & !IS_IN("iconpos", custo$) ~ & !IS_IN("notext", custo$) THEN custo$="iconpos=left "+custo$ GW_REGISTER("GW_CUSTO_DLGBTN") e$=GW_PAGE$(page) i=IS_IN("id='"+GW_ID$(dlg), e$) : IF 0=i THEN FN.RTN 0 i=IS_IN("'>"+WEB$(btn$)+"<", e$, i) : IF 0=i THEN FN.RTN 0 j=IS_IN("class='", e$, i-LEN(e$)) : IF 0=j THEN FN.RTN 0 j=IS_IN("'", e$, j+LEN("class='")) GW_USE_THEME_CUSTO_ONCE(custo$) e$=LEFT$(e$, j-1) + " " + GW_THEME_CUSTO$("hfbtn") + MID$(e$, j) GW_SET_SKEY("page", page, e$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG$(ctl_id) % BUTTON link to display a DIALOG (MESSAGE/INPUT/CHECKBOX) % Get Unique IDentifier of the control GW_REGISTER("GW_SHOW_DIALOG$") ctl$=GW_ID$(ctl_id) FN.RTN "#"+ctl$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG_MESSAGE$(ctl_id) % legacy FN.RTN GW_SHOW_DIALOG$(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG_INPUT$(ctl_id) % legacy FN.RTN GW_SHOW_DIALOG$(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG(ctl_id) % manually trigger a DIALOG (MESSAGE/INPUT/CHECKBOX) % Check that any previous dialog is fully closed GW_REGISTER("GW_SHOW_DIALOG") BUNDLE.GET 1, "gw-last-displayed-dialog", last IF last last$=GW_ID$(last) script$="if(!$('#"+last$+"').parent()" script$+=".hasClass('ui-popup-hidden')){" script$+="$('#"+last$+"').on('popupafterclose'," script$+="function(){RFO('"+last$+"_closed');})}" script$+="else{RFO('"+last$+"_closed');}" JS(script$) GW_WAIT_ACTION$() % "popup_closed" JS("$('#"+last$+"').off('popupafterclose')") ENDIF % Get Unique IDentifier of the control ctl$=GW_ID$(ctl_id) BUNDLE.GET 1, "gw-last-rendered-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" JS("$('#show"+ctl$+"')[0].click()") ELSE JS("$('#"+ctl$+"').popup('open',{transition:effect"+ctl$+"})") ENDIF BUNDLE.PUT 1, "gw-last-displayed-dialog", ctl_id FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG_MESSAGE(ctl_id) % legacy FN.RTN GW_SHOW_DIALOG(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_DIALOG_INPUT(ctl_id) % legacy FN.RTN GW_SHOW_DIALOG(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_DIALOG(ctl_id) % manually close a DIALOG (MESSAGE/INPUT/CHECKBOX) % Get Unique IDentifier of the control GW_REGISTER("GW_CLOSE_DIALOG") ctl$=GW_ID$(ctl_id) script$="$('#"+ctl$+"')" script$+=".popup('close',{transition:" script$+="effect"+ctl$+"})" script$+=".on('popupafterclose'," script$+="function(){RFO('"+ctl$+"_closed');})" JS(script$) GW_WAIT_ACTION$() % "popup_closed" JS("$('#"+ctl$+"').off('popupafterclose')") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_DIALOG_MESSAGE(ctl_id) % legacy FN.RTN GW_CLOSE_DIALOG(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_DIALOG_INPUT(ctl_id) % legacy FN.RTN GW_CLOSE_DIALOG(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_DLG_BTN$(btn_axn$[], hor_btns) % (internal) for DIALOGs (MESSAGE/INPUT/CHECKBOX) ARRAY.LENGTH al, btn_axn$[] FOR i=1 TO al k=IS_IN(">", btn_axn$[i], -1) IF !k THEN k=LEN(btn_axn$[i])+1 bt$=WEB$(LEFT$(btn_axn$[i], k-1)) ax$=MID$(btn_axn$[i], k+1) IF IS_IN("#dlg", ax$)=1 % chaining popups v$="show"+MID$(ax$,2) % js one-time variable script$="javascript:var "+v$+"=1;" script$+="$("[data-role=popup]").on("popupafterclose",function(){" script$+="if("+v$+"){"+v$+"=0;" script$+="$(""+ax$+"").popup("open"" script$+=",{transition:effect"+MID$(ax$,2) script$+="});}})' data-ajax='false" ax$=script$ ELSE % any other (normal) link ax$=WEB$(GW_FORMAT_LINK$(ax$)) ENDIF BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" e$+="" ELSE e$+=""+bt$+"" ENDIF NEXT FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_DLG_TITLE$(title$) % (internal) for DIALOGs (MESSAGE/INPUT/CHECKBOX) IF title$="" THEN FN.RTN "" BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" FN.RTN "

"+WEB$(title$)+"

" ELSE FN.RTN "

"+WEB$(title$)+"

" ENDIF FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_DIALOG_MESSAGE$(title$, msg$, btn_axn$[]) % Create the control u$=GW_NEWID$("dlgmsg") BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) custo$=GW_THEME_CUSTO$("dlgmsg") hor=IS_IN("inline", LOWER$(custo$)) % CUSTO 'inline' means horizontal buttons, else vertical buttons IF hor THEN custo$=LEFT$(custo$,hor-1)+MID$(custo$,hor+6) IF theme$="ios" | theme$="android-holo" | theme$="metro" e$="
" e$+="
"+GW_NEW_DLG_TITLE$(title$)+"
" e$+="

"+WEB$(msg$)+"

" e$+="
"+GW_NEW_DLG_BTN$(btn_axn$[], hor)+"
" e$+="
" % e$+="" ELSE e$="
" e$+="
"+GW_NEW_DLG_TITLE$(title$)+"
" e$+="

"+WEB$(msg$)+"

" e$+="
"+GW_NEW_DLG_BTN$(btn_axn$[], hor)+"
" e$+="
" % ENDIF % Create the default control transition IF page % setting transition needs an existing page (being built since user calls GW_ADD_*) BUNDLE.GET 1, "gw-default-dlg-transition", ddt$ script$="" % fade|pop|flip|turn|flow|slidefade|slide|slideup|slidedown|none GW_INSERT_BEFORE(page, " no need to REGISTER the command ENDIF % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_DIALOG_MESSAGE(page, title$, msg$, btn_axn$[]) % Add to the page before page-content GW_REGISTER("GW_ADD_DIALOG_MESSAGE") ctl$=GW_ADD_DIALOG_MESSAGE$(title$, msg$, btn_axn$[]) theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" GW_INSERT_BEFORE(page, "^
"|"1>"=number ; "*>"=password ; "@>"=email ; "<>"=url cod$=LEFT$(inpu$,1) IF cod$="0" | cod$="1" THEN typ$="number" IF cod$="*" THEN typ$="password" IF cod$="@" THEN typ$="email" IF cod$="<" THEN typ$="url" inpu$=MID$(inpu$,3) ENDIF e$="
" e$+="
"+GW_NEW_DLG_TITLE$(title$)+"
" e$+="

"+WEB$(msg$)+"

" e$+="" e$+="
" e$+=GW_NEW_DLG_BTN$(btn_axn$[], hor) e$+="
" % % Position input popup at top of screen + focus in input field e$+="" e$+="" % Create the default control transition BUNDLE.GET 1, "gw-last-edited-page", page IF page % setting transition needs an existing page (being built since user calls GW_ADD_*) BUNDLE.GET 1, "gw-default-dlg-transition", ddt$ script$="" % fade|pop|flip|turn|flow|slidefade|slide|slideup|slidedown|none GW_INSERT_BEFORE(page, " no need to REGISTER the command ENDIF % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_DIALOG_INPUT(page, title$, msg$, inpu$, btn_axn$[]) % Add to the page before page-content GW_REGISTER("GW_ADD_DIALOG_INPUT") ctl$=GW_ADD_DIALOG_INPUT$(title$, msg$, inpu$, btn_axn$[]) theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" GW_INSERT_BEFORE(page, "^
" e$+="
"+GW_NEW_DLG_TITLE$(title$)+"
" e$+="

"+WEB$(msg$)+"

" r$=WEB$(chk_lbl$) IF LEFT$(r$,1)=">" checked$="checked='' " r$=MID$(r$,2) ENDIF IF LEN(r$) THEN e$+="" e$+="" e$+="
" e$+=GW_NEW_DLG_BTN$(btn_axn$[], hor) e$+="
" % % Create the default control transition BUNDLE.GET 1, "gw-last-edited-page", page IF page % setting transition needs an existing page (being built since user calls GW_ADD_*) BUNDLE.GET 1, "gw-default-dlg-transition", ddt$ script$="" % fade|pop|flip|turn|flow|slidefade|slide|slideup|slidedown|none GW_INSERT_BEFORE(page, " no need to REGISTER the command ENDIF % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_DIALOG_CHECKBOX(page, title$, msg$, chk_lbl$, btn_axn$[]) % Add to the page before page-content GW_REGISTER("GW_ADD_DIALOG_CHECKBOX") ctl$=GW_ADD_DIALOG_CHECKBOX$(title$, msg$, chk_lbl$, btn_axn$[]) theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" GW_INSERT_BEFORE(page, "^
"+WEB$(e$)+"" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_BTN$(ba$, type$) % (internal) for TITLEBAR and FOOTBAR (type$="left"|"right") k=IS_IN(">", ba$, -1) IF 0=k THEN k=LEN(ba$)+1 bt$=WEB$(LEFT$(ba$, k-1)) ax$=GW_FORMAT_LINK$(MID$(ba$, k+1)) cs$=GW_THEME_CUSTO$("hfbtn") IF IS_IN(" ui-icon-icon", bt$) cs$+=bt$ bt$="" ENDIF BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" e$=""+bt$+"" % id will become title|footbar1-lbutton|rbutton FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_LBUTTON$(ba$) % for TITLEBAR and FOOTBAR FN.RTN GW_ADD_BAR_BTN$(ba$, "left") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_RBUTTON$(ba$) % for TITLEBAR and FOOTBAR FN.RTN GW_ADD_BAR_BTN$(ba$, "right") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_MENU$(bna$[], type$) % (internal) for TITLEBAR and FOOTBAR (type$="left"|"right") e$="
" e$+="
" % FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_LMENU$(bna$[]) % for TITLEBAR and FOOTBAR FN.RTN GW_ADD_BAR_MENU$(bna$[], "left") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BAR_RMENU$(bna$[]) % for TITLEBAR and FOOTBAR FN.RTN GW_ADD_BAR_MENU$(bna$[], "right") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TITLEBAR$(content$) % Create the control u$=GW_NEWID$("titlebar") e$="
" IF LEFT$(content$, 1)="<" e$+=REPLACE$(content$,"id='","id='"+u$) ELSE e$=e$+"

"+WEB$(content$)+"

" ENDIF IF !IS_IN("" IF LEFT$(content$, 1)="<" e$+=REPLACE$(content$,"id='","id='"+u$) ELSE e$=e$+"

"+WEB$(content$)+"

" ENDIF IF !IS_IN(""<" THEN ini$="

"+content$+"

" ELSE ini$=content$ % Get the default control transition BUNDLE.GET 1, "gw-default-panel-transition", dpt$ % push|reveal|overlay % Create the control u$=GW_NEWID$("panel") e$="
"+ini$+"
" % (5.3) No WEB$(ini$)! % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_PANEL(page, content$) % Add to the page before page-content ctl$=GW_ADD_PANEL$(content$) GW_REGISTER("GW_ADD_PANEL") GW_INSERT_BEFORE(page, "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_START_CENTER(page) % Add the center div to the page GW_REGISTER("GW_START_CENTER") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_START_CENTER$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_STOP_CENTER$() FN.RTN "
" % FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_STOP_CENTER(page) GW_REGISTER("GW_STOP_CENTER") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_STOP_CENTER$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CENTER_PAGE_VER$(page) e$="" FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CENTER_PAGE_VER(page) GW_REGISTER("GW_CENTER_PAGE_VER") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_CENTER_PAGE_VER$(page)) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_OPEN_GROUP$() % for CHECKBOX or RADIO controls FN.RTN "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_OPEN_GROUP(page) % Add the group to the page GW_REGISTER("GW_OPEN_GROUP") e$=GW_PAGE$(page) + GW_OPEN_GROUP$() GW_SET_SKEY("page", page, e$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_GROUP$() FN.RTN "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_GROUP(page) GW_REGISTER("GW_CLOSE_GROUP") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_CLOSE_GROUP$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_OPEN$() % Create the control u$=GW_NEWID$("shelf") e$="" e$+="
" % Add shelf to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_OPEN(page) % Add the shelf to the page and return its index GW_REGISTER("GW_SHELF_OPEN") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_SHELF_OPEN$()) FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_NEWCELL$() FN.RTN "" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_NEWCELL(page) GW_REGISTER("GW_SHELF_NEWCELL") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_SHELF_NEWCELL$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_NEWROW$() FN.RTN "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_NEWROW(page) GW_REGISTER("GW_SHELF_NEWROW") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_SHELF_NEWROW$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_CLOSE$() FN.RTN "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHELF_CLOSE(page) GW_REGISTER("GW_SHELF_CLOSE") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_SHELF_CLOSE$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_OPEN_COLLAPSIBLE$(t$) % to expand/collapse a group of controls e$="
"+WEB$(t$)+"" FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_OPEN_COLLAPSIBLE(page, t$) % Add the collapsible to the page GW_REGISTER("GW_OPEN_COLLAPSIBLE") e$=GW_PAGE$(page) + GW_OPEN_COLLAPSIBLE$(t$) GW_SET_SKEY("page", page, e$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_COLLAPSIBLE$() FN.RTN "
" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_COLLAPSIBLE(page) GW_REGISTER("GW_CLOSE_COLLAPSIBLE") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_CLOSE_COLLAPSIBLE$()) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % FUNCTIONS TO CREATE AND USE THEME-CUSTOMIZATIONS ON CONTROLS %--------------------------------------------------------------------------------------------- FN.DEF GW_NEW_CLASS(class$) % Add the class to the list of controls and return its index ls=GW_ADD_SKEY("control", "." + class$) FN.RTN ls FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_FONT$(page, fnt$) IF IS_APK() THEN MAKE_SURE_IS_ON_SD(fnt$) % in APK mode: if font file is not on sdcard, copy it from assets i=IS_IN("/", fnt$, -1) IF i THEN ff$=MID$(fnt$, i+1) ELSE ff$=fnt$ i=IS_IN(".", ff$) IF i THEN ff$=LEFT$(ff$, i-1) ff$=REPLACE$(ff$, " ", "") ins$="" GW_REGISTER("GW_ADD_FONT$") GW_INSERT_BEFORE(page, "", ins$) FN.RTN ff$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_THEME_CUSTO(e$) % Add the theme customization to the list + return its index ls=GW_ADD_SKEY("custo", LOWER$(e$)) FN.RTN ls FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_USE_THEME_CUSTO(custo) % Change 'theme-custo' properties in the global bundle BUNDLE.PUT 1, "gw-theme-custo", custo BUNDLE.PUT 1, "gw-theme-custo-token", -1 % -1=unlimited tokens=persistent theme customization FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_USE_THEME_CUSTO_ONCE(e$) % Add the theme-customization to the list custo=GW_NEW_THEME_CUSTO(e$) % Change 'theme-custo' properties in the global bundle BUNDLE.PUT 1, "gw-theme-custo", custo BUNDLE.PUT 1, "gw-theme-custo-token", 1 % 1 token=1-shot theme customization FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_RESET_THEME_CUSTO() % Change 'theme-custo' properties in the global bundle BUNDLE.PUT 1, "gw-theme-custo", 0 BUNDLE.PUT 1, "gw-theme-custo-token", 0 % zero token=no customization FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_REPLACE_IN_STYLE(custo$, del$, add$) % (internal) Add a 'style' string to a theme customization IF !IS_IN(del$, custo$) THEN FN.RTN 0 i=IS_IN("style='", custo$) IF i custo$=LEFT$(custo$,i+6)+add$+";"+REPLACE$(MID$(custo$,i+7), del$, "") ELSE custo$=REPLACE$(custo$, del$, "style='"+add$+"'") ENDIF FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_THEME_CUSTO$(ctl$) % (internal) Return a formated theme customization for this control family BUNDLE.GET 1, "gw-theme", theme$ BUNDLE.GET 1, "gw-theme-custo-token", tct IF !tct % No theme customization -> return empty string IF ctl$="pgbar" | ctl$="slider" FN.RTN "from(#5393c5),to(#6facd5)" % except for progressbars/sliders: blue gradient by default ELSEIF IS_IN("native-droid", theme$)=1 & IS_IN(ctl$, "page|panel|titlebar") FN.RTN "data-theme=b" % and except for native-droid theme=data-theme-b by default ELSE FN.RTN "" ENDIF ENDIF BUNDLE.GET 1, "gw-theme-custo", custo r$=GW_THEME$(custo) % Get the theme-customization string % Format it for the desired control IF ctl$="hfbtn" % button for TITLEBAR or FOOTBAR or DIALOG* r$=REPLACE$(r$, "icon=", "ui-icon-") r$=REPLACE$(r$, "iconpos=notext", "notext") r$=REPLACE$(r$, "iconpos=", "ui-btn-icon-") r$=REPLACE$(r$, "notext", "ui-btn-icon-notext") r$=REPLACE$(r$, "inline", "") % because inline by default r$=REPLACE$(r$, "color=", "' data-theme='") i=IS_IN("style='", LOWER$(r$)) IF i THEN r$=LEFT$(r$,i-1)+"' "+REPLACE$(MID$(r$,i), "''", "'") ELSEIF ctl$="group" % group of checkboxes/radios r$=REPLACE$(r$, "inline", "data-type='horizontal' data-mini='true'") ELSEIF ctl$="spinner" r$=REPLACE$(r$, "color=", "") ELSEIF ctl$="pgbar" | ctl$="slider" % progressbar and slider r$=REPLACE$(r$,"align=","text-align:") i=IS_IN("color=",LOWER$(r$)) IF !i THEN r$+=" color=a" r$=REPLACE$(r$,"color=a", "from(#5393c5),to(#6facd5)") % 'color=a': blue gradient (by default) r$=REPLACE$(r$,"color=b", "from(#4e9d4e),to(#5cb85c)") % 'color=b': green gradient r$=REPLACE$(r$,"color=c", "from(#b94743),to(#d9534f)") % 'color=c': red gradient r$=REPLACE$(r$,"color=d", "from(#cc9342),to(#f0ad4e)") % 'color=d': orange gradient r$=REPLACE$(r$,"color=e", "from(#c21e63),to(#e57eaa)") % 'color=e': pink gradient r$=REPLACE$(r$,"color=f", "from(#2b689c),to(#337ab7)") % 'color=f': dark blue gradient ELSE % default: all other controls r$=REPLACE$(r$, "color=", "data-theme=") r$=REPLACE$(r$, "icon=", "data-icon=") r$=REPLACE$(r$, "iconpos=notext", "notext") r$=REPLACE$(r$, "iconpos=", "data-iconpos=") r$=REPLACE$(r$, "position=", "data-position=") r$=REPLACE$(r$, "notext", "data-iconpos=notext") r$=REPLACE$(r$, "mini", "data-mini=true") IF IS_IN("dlg", ctl$)=0 THEN r$=REPLACE$(r$, "inline", "data-inline='true'") BUNDLE.GET 1, "gw-last-edited-page", page IF page % hover=X custo need an existing page for which we know if it has TITLEBAR/FOOTBAR or not IF IS_IN("id='titlebar", GW_PAGE$(page)) THEN top$="50px" ELSE top$="5px" % 'page' is sure to exist -> no need to REGISTER command IF IS_IN("id='footbar", GW_PAGE$(page)) THEN bot$="60px" ELSE bot$="5px" % idem GW_REPLACE_IN_STYLE(&r$, "hover=ne", "position:fixed;top:"+top$+";right:5px") GW_REPLACE_IN_STYLE(&r$, "hover=nw", "position:fixed;top:"+top$+";left:5px") GW_REPLACE_IN_STYLE(&r$, "hover=se", "position:fixed;bottom:"+bot$+";right:5px") GW_REPLACE_IN_STYLE(&r$, "hover=sw", "position:fixed;bottom:"+bot$+";left:5px") IF ctl$="button" & IS_IN("notext", r$) style$="50%;margin:auto;margin-left:" IF IS_IN("big", r$) THEN style$+="-21px" ELSE style$+="-12px" ELSE style$="60px;right:60px;width:auto" ENDIF GW_REPLACE_IN_STYLE(&r$, "hover=n", "position:fixed;top:"+top$+";left:"+style$) GW_REPLACE_IN_STYLE(&r$, "hover=s", "position:fixed;bottom:"+bot$+";left:"+style$) GW_REPLACE_IN_STYLE(&r$, "hover=e", "position:fixed;top:50%;right:5px") GW_REPLACE_IN_STYLE(&r$, "hover=w", "position:fixed;top:50%;left:5px") ENDIF IF ctl$="button" THEN GW_REPLACE_IN_STYLE(&r$, "big", "width:42px;height:42px") % 'big' BUTTON % shelf vertical-alignment (5.5) i=IS_IN("valign=", r$) IF i j=IS_IN(" ", r$, i+1) IF !j THEN j=LEN(r$)+1 a$=MID$(r$,i,j+1-i) j=IS_IN("=", a$) GW_REPLACE_IN_STYLE(&r$, a$, "vertical-align:"+MID$(a$,j+1)) ENDIF % text-alignment (5.3) i=IS_IN("align=", r$) IF i j=IS_IN(" ", r$, i+1) IF !j THEN j=LEN(r$)+1 a$=MID$(r$,i,j+1-i) j=IS_IN("=", a$) % (5.5) GW_REPLACE_IN_STYLE(&r$, a$, "text-align:"+MID$(a$,j+1)) ENDIF i=IS_IN("alpha=", r$) IF i % transparency of control j=IS_IN("%", r$, i+1) alpha=VAL(MID$(r$, i+6, j-i-6)) GW_REPLACE_IN_STYLE(&r$, MID$(r$,i,j+1-i), "opacity:"+ENT$((100-alpha)/100)) ENDIF GW_REPLACE_IN_STYLE(&r$, "fit-screen", "max-width:100%;height:auto") % image fit screen width (if too big) i=IS_IN("font=", r$) IF i j=IS_IN(" ", r$, i+1) IF!j THEN j=LEN(r$)+1 ff$=MID$(r$, i+5, j-i-5) GW_REPLACE_IN_STYLE(&r$, MID$(r$,i,j-i), "font-family:"+ff$) ENDIF GW_REPLACE_IN_STYLE(&r$, "wrap", "word-wrap:break-word;white-space:normal") % (5.5) ENDIF % Flush use of 1-shot theme customization (GW_USE_THEME_CUSTO_ONCE), for a control! (don't flush for page/content) IF tct=1 & ctl$<>"page" & ctl$<>"content" THEN GW_RESET_THEME_CUSTO() % Return the formatted string (5.3) followed by a space FN.RTN TRIM$(r$)+" " FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % FUNCTIONS TO ADD STANDARD CONTROLS %--------------------------------------------------------------------------------------------- FN.DEF GW_ADD_DEBUGGER(page) % Add a powerful debugger to the page % Check resources IF IS_APK() MAKE_SURE_IS_ON_SD("GW/eruda.js") MAKE_SURE_IS_ON_SD("GW/eruda-dom.js") ENDIF GW_CHECK_AND_DOWNLOAD("GW/eruda.js") GW_CHECK_AND_DOWNLOAD("GW/eruda-dom.js") % Add 'eruda' reference to the page GW_REGISTER("GW_ADD_DEBUGGER") GW_INJECT_JS(page, "GW/eruda.js") GW_INJECT_JS(page, "GW/eruda-dom.js") PROGRAM.INFO nfo: BUNDLE.GET nfo, "BasName", b$: BUNDLE.GET nfo, "UserApk", a % Add initialization script js$ ="eruda.init({tool:['console', 'dom', 'info', 'elements', " js$+="'resources', 'snippets'], defaults:{displaySize:50}});" js$+="eruda.get('resources').config.set('hideErudaSetting', true);" js$+="var snip=eruda.get('snippets'); snip.add('Reload Page',function(){" js$+="RFO('555544444C524C524241');" js$+="},'Force page to reload in its initial state');snip.run('ReloadPage');" js$+="eruda.add(erudaDom);var ab=eruda.get('about');ab.clear();" js$+="ab.text('GW library "+GW_VER$()+" - http://mougino.free.fr');" js$+="ab.text('Debugger powered by eruda v2.4.1 - https://eruda.liriliri.io');" IF a THEN n$="APK" ELSE n$="editor" js$+="ab.text(\"BASIC! v"+VERSION$()+" running ""+b$+"" from "+n$+"\");" % js$+="eruda.remove('about');" GW_INJECT_JS(page, js$) % Return success FN.RTN 1 FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_LOG(data$) % Add a record in the webview console log JS("console.log("+DQP$(data$)+")") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_COLORPICKER$(lbl$, ini_col$) % (5.6) Check resources IF IS_APK() MAKE_SURE_IS_ON_SD("GW/colorpicker/jquery.minicolors.css") MAKE_SURE_IS_ON_SD("GW/colorpicker/jquery.minicolors.min.js") MAKE_SURE_IS_ON_SD("GW/colorpicker/jquery.minicolors.png") ENDIF GW_CHECK_AND_DOWNLOAD("GW/colorpicker/jquery.minicolors.css") GW_CHECK_AND_DOWNLOAD("GW/colorpicker/jquery.minicolors.min.js") GW_CHECK_AND_DOWNLOAD("GW/colorpicker/jquery.minicolors.png") % (5.6) Add 'minicolors' reference to the page BUNDLE.GET 1, "gw-last-edited-page", page IF !page THEN END "Error page needed in GW_ADD_COLORPICKER$()" % (5.6) IF !IS_IN("colorpicker/jquery.minicolors", GW_PAGE$(page)) GW_INJECT_CSS(page, "GW/colorpicker/jquery.minicolors.css") GW_INJECT_JS(page, "GW/colorpicker/jquery.minicolors.min.js") script$ ="$(document).on('pagebeforeshow',function()" script$+="{$.minicolors.defaults.control='wheel';});" GW_INJECT_JS(page, script$) ENDIF % Create the control u$=GW_NEWID$("colorpicker") IF LEFT$(ini_col$, 1) <> "#" THEN ini_col$="#"+ini_col$ e$ ="" e$+="" % Add color picker to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_COLORPICKER(page, lbl$, ini_col$) % Add the element to the page and return its index GW_REGISTER("GW_ADD_COLORPICKER") cp$=GW_ADD_COLORPICKER$(lbl$, ini_col$) GW_SET_SKEY("page", page, GW_PAGE$(page) + cp$) FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LOCK_PATTERN$(opt$) % (5.6) Check resources IF IS_APK() MAKE_SURE_IS_ON_SD("GW/patternlock/patternLock.css") MAKE_SURE_IS_ON_SD("GW/patternlock/patternLock.min.js") ENDIF GW_CHECK_AND_DOWNLOAD("GW/patternlock/patternLock.css") GW_CHECK_AND_DOWNLOAD("GW/patternlock/patternLock.min.js") % (5.6) Add PatternLock .css and .js reference to the page BUNDLE.GET 1, "gw-last-edited-page", page IF !page THEN END "Error page needed in GW_ADD_LOCK_PATTERN$()" % (5.6) IF !IS_IN("patternlock/patternLock", GW_PAGE$(page)) GW_INJECT_CSS(page, "GW/patternlock/patternLock.css") GW_INJECT_JS(page, "GW/patternlock/patternLock.min.js") script$ ="function resizeLock(lock){var ldim=lock.option('matrix');" script$+="var lmax=Math.max(ldim[0],ldim[1]);" script$+="var lpmargin=0.5*($(window).width()-10*lmax)/(3*lmax-1);" script$+="var lpradius=lpmargin+5;lock.option('margin',lpmargin);" script$+="lock.option('radius',lpradius);}" GW_INJECT_JS(page, script$) ENDIF % Create the control + script u$=GW_NEWID$("lock") e$="
" opt$=LOWER$(opt$) IF IS_IN("hide-pattern", opt$) o$="patternVisible:false;" opt$=TRIM$(REPLACE$(opt$, "hide-pattern", "")) ENDIF IF IS_IN("x", opt$)=2 % 4x4, 5x7 ... 9x9 o$+="matrix:["+LEFT$(opt$,1)+","+RIGHT$(opt$,1)+"];" ENDIF e$+="" % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LOCK_PATTERN(page, opt$) % Add the element to the page GW_REGISTER("GW_ADD_LOCK_PATTERN") lp$=GW_ADD_LOCK_PATTERN$(opt$) GW_SET_SKEY("page", page, GW_PAGE$(page) + lp$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_WRONG_PATTERN(ctl_id) % show a wrong lock pattern input % Get Unique IDentifier of the control GW_REGISTER("GW_SHOW_WRONG_PATTERN") ctl$=GW_ID$(ctl_id) JS(ctl$+".error()") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLEAR_LOCK_PATTERN(ctl_id) % clear the lock pattern % Get Unique IDentifier of the control GW_REGISTER("GW_CLEAR_LOCK_PATTERN") ctl$=GW_ID$(ctl_id) JS(ctl$+".reset()") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_SPINNER$(msg$) % Initialize the script theme$=GW_THEME_CUSTO$("spinner") IF !IS_IN("icon=",theme$) THEN th$=theme$ script$="var h='',to=false,th='"+th$+"'," IF msg$="" THEN script$+="tv=false;" ELSE script$+="tv=true;" % Create the control u$=GW_NEWID$("spinner") js$="var tx"+u$+"="+CHR$(34)+WEB$(msg$)+CHR$(34)+";" js$+="function show"+u$+"(){"+script$+"$.mobile.loading('show'," js$+="{text:tx"+u$+",textVisible:tv,theme:th,textonly:to,html:h});}" % (5.4) Icon custo IF IS_IN("icon=",theme$)=1 ico$=TRIM$(MID$(theme$,6)) js$=LEFT$(js$,-1) js$+="$('.ui-loader .ui-icon-loading').css('background-color','transparent');" js$+="$('.ui-loader-default').css('opacity','1');" js$+="$('.ui-icon-loading').css('background','url("+ico$+")');" js$+="$('.ui-icon-loading').css('background-size','100% 100%');}" ENDIF % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN "" FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_SPINNER(page, msg$) % Check resource IF IS_APK() THEN MAKE_SURE_IS_ON_SD("GW/images/ajax-loader.gif") GW_CHECK_AND_DOWNLOAD("GW/images/ajax-loader.gif") % Add the element to the page GW_REGISTER("GW_ADD_SPINNER") e$=GW_PAGE$(page) IF !IS_IN("hideloader()", e$) e$+="" ENDIF e$+=GW_ADD_SPINNER$(msg$) % (5.4) Icon custo IF IS_IN("url(icon",e$) i=IS_IN("url(icon", e$, -1) +4 j=IS_IN(")", e$, i) ico$=MID$(e$, i, j-i) i=IS_IN(".ui-icon-"+ico$, e$) IF !i THEN END "GW_ADD_SPINNER() error: '.ui-icon-"+ico$+"' not found!\n" i=IS_IN("url(", e$, i) j=IS_IN(")", e$, i) url$=MID$(e$, i, j-i+1) e$=REPLACE$(e$, "url("+ico$+")", url$) ENDIF GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_SHOW_SPINNER(ctl_id) % manually trigger a SPINNER % Get Unique IDentifier of the control GW_REGISTER("GW_SHOW_SPINNER") ctl$=GW_ID$(ctl_id) JS("show"+ctl$+"()") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_HIDE_SPINNER() % manually hide the SPINNER currently displayed JS("hideloader()") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LOADING_IMG(page, img$, dark) % Check resource IF IS_APK() THEN MAKE_SURE_IS_ON_SD(img$) % Declare div html$="
" % Declare CSS css$ =".no-js #loader {display:none}" css$ += ".js #loader {display:block;position:absolute;left:100px;top:0}" css$ += ".se-pre-con {position:fixed;left:0px;top:0px;width:100%;height:100%;z-index:9999;" css$ += "background:url(" + img$ + ") center no-repeat " IF dark THEN css$ += "#000}" ELSE css$ += "#fff}" % Declare JS script$ ="$(window).load(function(){$('.se-pre-con').fadeOut('slow');})" % Add the 3 elements to the page GW_REGISTER("GW_ADD_LOADING_IMG") GW_INSERT_BEFORE(page, "" + css$ + "") GW_INSERT_BEFORE(page, "" + script$ + "") GW_INSERT_BEFORE(page, "", img$, -1) IF i lnk$=MID$(img$, i+1) img$=LEFT$(img$, i-1) ENDIF IF IS_APK() & !STARTS_WITH("http",img$) THEN MAKE_SURE_IS_ON_SD(img$) % in APK mode: if image is not on sdcard, copy it from assets % Create the control u$=GW_NEWID$("image") IF LEN(lnk$) e$="" %TODO: might bug -> change to WEB$(GW_FORMAT_LINK$()) e$+="" ELSE e$="" ENDIF % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_IMAGE(page, img$) % Add the control to the page GW_REGISTER("GW_ADD_IMAGE") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_IMAGE$(img$)) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_GET_IMAGE_DIM$(img$) % return dimension of image in the form "WxH" script$ ="$('').attr('src','"+img$+"').on('load'," script$+="function(){RFO(this.width+'x'+this.height);});" JS(script$) FN.RTN GW_WAIT_ACTION$() FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ICON$(ctl_id) GW_REGISTER("GW_ICON$") FN.RTN " ui-btn-icon-notext ui-nodisc-icon ui-icon-"+GW_ID$(ctl_id) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_ICON(page, ico$, w, h) % in APK mode: if icon is not on sdcard, copy it from assets IF IS_APK() & !IS_IN("http", ico$) THEN MAKE_SURE_IS_ON_SD(ico$) % Add the icon style to the page (in the header) u$=GW_NEWID$("icon") css$=".ui-icon-"+u$+":after{" css$+="background-image:url("+ico$+");" css$+="background-size:"+INT$(w)+"px "+INT$(h)+"px;}" GW_REGISTER("GW_ADD_ICON") GW_INJECT_CSS(page, css$) % Add the control to the list of controls + return its index GW_ADD_SKEY("control", u$) FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_TBL$(n_cols, table$[]) % (internal) firstrow=1 IF LEFT$(table$[1], 1)=">" e$="" FOR col=1 TO n_cols IF LEFT$(table$[++cell], 1)=">" THEN t$=MID$(table$[cell], 2) ELSE t$=table$[cell] e$+=""+t$+"" NEXT e$+="" firstrow=2 ENDIF e$+="" ARRAY.LENGTH al, table$[] FOR row=firstrow TO al/n_cols e$+="" FOR col=1 to n_cols e$+=""+table$[++cell]+"" NEXT e$+="" NEXT IF cell" NEXT e$+="" ENDIF e$+="" FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TABLE$(n_cols, table$[]) % (5.6) Add table style and js to the page BUNDLE.GET 1, "gw-last-edited-page", page IF !page THEN END "Error page needed in GW_ADD_TABLE$()" % (5.6) IF !IS_IN("columntoggle-btn", GW_PAGE$(page)) % hide tables' column-toggle button css$=".ui-table-columntoggle-btn{display:none !important}" % tables styling css$+="th{border-bottom:1px solid #d6d6d6}" css$+="tr:nth-child(even){background:#e9e9e9}" GW_INJECT_CSS(page, css$) ENDIF % Create the control u$=GW_NEWID$("table") e$="" e$+=GW_NEW_TBL$(n_cols, table$[]) e$+="
" % Add the table's number of columns to the dedicated list GW_ADD_NKEY("table-column", n_cols) % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TABLE(page, n_cols, table$[]) % Add the control to the page GW_REGISTER("GW_ADD_TABLE") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_TABLE$(n_cols, table$[])) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_VIDEO$(video$) % In APK mode: if video is not on sdcard, copy it from assets IF IS_APK() & !IS_IN("http", video$) THEN MAKE_SURE_IS_ON_SD(video$) % Poster parameter specified ? i=IS_IN(">", video$, -1) IF i THEN poster$=" poster='"+MID$(video$, i+1)+"'" : video$=LEFT$(video$, i-1) % Create the control u$=GW_NEWID$("video") e$="" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_VIDEO(page, video$) % Add the video to the page GW_REGISTER("GW_ADD_VIDEO") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_VIDEO$(video$)) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_AUDIO$(audio$) % In APK mode: if audio is not on sdcard, copy it from assets IF IS_APK() & !IS_IN("http", audio$) THEN MAKE_SURE_IS_ON_SD(audio$) % Add the audio to the page u$=GW_NEWID$("audio") e$="" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_AUDIO(page, audio$) % Add the audio to the page GW_REGISTER("GW_ADD_AUDIO") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_AUDIO$(audio$)) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_FORMAT_LINK$(link$) % (internal) IF IS_IN("#dlg", link$)=1 BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" href$=link$+"' data-rel='dialog' data-transition='slideup" ELSE href$="#' onclick="+CHR$(34)+"$('"+link$+"').popup('open',{transition:" href$+="effect"+MID$(link$, 2)+"})"+CHR$(34)+" data-ajax='false" ENDIF ELSEIF IS_IN("#panel", link$)=1 href$=link$ % TODO: double-check if commenting line below is ok % href$="#' onclick="+CHR$(34)+"javascript:$('"+link$+"').panel('open')"+CHR$(34)+" data-ajax='false" ELSEIF LEFT$(link$, 4)="http" | LEFT$(link$,1)="#" href$=link$+"' data-ajax='false" ELSEIF link$<>"" href$="javascript:RFO("+CHR$(34)+URL_ENCODE$(link$)+CHR$(34)+");' data-ajax='false" ELSE % empty link href$="#" ENDIF FN.RTN href$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_MODIFY_LINK(ctl$, link$) % (internal) IF IS_IN("#dlg", link$)=1 BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" JS("$('#"+ctl$+"').attr('href',"+DQP$(link$)+")") ELSE js$="$('#"+ctl$+"').click(function(){" js$+="$('"+link$+"').popup('open',{" js$+="transition:effect"+MID$(link$,2) js$+="})})" JS(js$) ENDIF ELSEIF IS_IN("#panel", link$)=1 JS("$('#"+ctl$+"').attr('href',"+DQP$(link$)+")") ELSEIF LEFT$(link$, 4)="http" | LEFT$(link$,1)="#" JS("$('#"+ctl$+"').attr('href',"+DQP$(link$)+")") ELSE JS("$('#"+ctl$+"').attr('href','#')") IF link$<>"" js$="RFO("+CHR$(34)+URL_ENCODE$(link$)+CHR$(34)+")" JS("$('#"+ctl$+"').click(function(){"+js$+"})") ELSE JS("$('#"+ctl$+"').unbind('click')") ENDIF ENDIF FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BUTTON$(label$, link$) % First treat the link: web hyperlink or user command? href$=GW_FORMAT_LINK$(link$) % Create the control u$=GW_NEWID$("button") e$="" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_BUTTON(page, label$, link$) % Add the control to the page GW_REGISTER("GW_ADD_BUTTON") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_BUTTON$(label$, link$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LINK$(label$, link$) % First treat the link: web hyperlink or user command? href$=GW_FORMAT_LINK$(link$) % Create the control u$=GW_NEWID$("link") e$="

" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LINK(page, label$, link$) % Add the control to the page GW_REGISTER("GW_ADD_LINK") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_LINK$(label$, link$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TITLE$(title$) % Create the control u$=GW_NEWID$("title") e$="

" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TITLE(page, title$) % Add the control to the page GW_REGISTER("GW_ADD_TITLE") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_TITLE$(title$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TEXT$(txt$) % Create the control u$=GW_NEWID$("text") e$="
" IF LEFT$(txt$,1)="<" i=IS_IN(">", txt$) e$+=LEFT$(txt$, i-1)+" id='"+u$+"' "+GW_THEME_CUSTO$("text")+MID$(txt$,i) ELSE e$+="

"+WEB$(txt$)+"

" ENDIF e$+="
" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TEXT(page, txt$) % Add the control to the page GW_REGISTER("GW_ADD_TEXT") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_TEXT$(txt$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TEXTBOX$(txt$) % Create the control u$=GW_NEWID$("textbox") e$="
" IF LEFT$(txt$,1)="<" i=IS_IN(">", txt$) e$+=LEFT$(txt$,i-1)+" id='"+u$+"' "+GW_THEME_CUSTO$("textbox")+MID$(txt$,i) ELSE e$+="

"+WEB$(txt$)+"

" ENDIF e$+="
" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_TEXTBOX(page, txt$) % Add the control to the page GW_REGISTER("GW_ADD_TEXTBOX") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_TEXTBOX$(txt$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_FLIPSWITCH$(label$, s_opt1$, s_opt2$) u$=GW_NEWID$("flipswitch") % Add the javascript snippet e$="" % Create the control % e$+="
" e$+="" BUNDLE.GET 1, "gw-last-edited-page", page IF page THEN theme$=GW_THEME_OF_PAGE$(page) IF theme$="ios" | theme$="android-holo" | theme$="metro" e$+="" ENDIF e$+="" e$+="" e$+="" % e$+="
" % % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_FLIPSWITCH(page, label$, s_opt1$, s_opt2$) % Add the control to the page GW_REGISTER("GW_ADD_FLIPSWITCH") GW_SET_SKEY("page", page, GW_PAGE$(page) + GW_ADD_FLIPSWITCH$(label$, s_opt1$, s_opt2$)) % Return the index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % LISTVIEWS %--------------------------------------------------------------------------------------------- FN.DEF GW_LV_CELL$(e$) % (internal) listview-cell parser % Test against "..@@ICO" --> inline icon j=IS_IN("@@", e$) IF j ico$=MID$(e$, j+2) IF IS_APK() & !IS_IN("http", ico$) THEN MAKE_SURE_IS_ON_SD(ico$) thb$="" e$=LEFT$(e$, j-1) ENDIF % Test against "..@IMG" --> thumbnail j=IS_IN("@", e$) IF j img$=MID$(e$, j+1) IF IS_APK() & !IS_IN("http", img$) THEN MAKE_SURE_IS_ON_SD(img$) thb$="" e$=LEFT$(e$, j-1) ENDIF % Test against "..{NN}" --> count bubble m=IS_IN("{", e$, -1) n=IS_IN("}", e$, m) IF m & n & n>m % "bla bla (12)" bbl$="" bbl$+=MID$(e$, m+1, n-m-1)+"" e$=LEFT$(e$, m-1)+MID$(e$, n+1) ENDIF % Test against ".. \n .." --> 2-line listview (BOLD \n Normal) k=IS_IN("\n", e$) IF k THEN e$="

"+LEFT$(e$, k-1)+"

"+MID$(e$, k+1)+"

" FN.RTN thb$ + WEB$(e$) + bbl$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_LV$(txt_axn$[]) % (internal) new listview ARRAY.LENGTH al, txt_axn$[] IF IS_IN("~", txt_axn$[1])=1 THEN sortable=1 % first element starts with '~' --> sortable list % Scan listview for links FOR i=1 TO al IF IS_IN(">", txt_axn$[i], -1)>2 linked=1 % At least 1 'link' value means a 'linked' listview F_N.BREAK ENDIF NEXT % Create listview elements, 1 by 1 FOR i=1 TO al ar$=txt_axn$[i] IF i=1 & sortable THEN ar$=MID$(ar$,2) % (5.6) ignore 'sortable' switch IF i=1 & IS_IN("#", ar$)=1 THEN ar$=MID$(ar$, 2) % ignore 'ordered' switch k=IS_IN(">", ar$) IF k=1 % ">Listview title" --> divider ar$=MID$(ar$, 2) IF i=1 & IS_IN("#", ar$)=1 THEN ar$=MID$(ar$, 2) % ignore 'ordered' switch k=IS_IN(">", ar$, -1) % link separator "Bla bla>AXN" IF k>0 THEN ar$=LEFT$(ar$, k-1) e$+="
  • "+GW_LV_CELL$(ar$)+"
  • " ELSE % not a divider --> regular cell swipe1=IS_IN("|", ar$) : swipe2=0 % "Opt1|Bla bla" --> swipe w/ at least 1 option IF swipe1 THEN swipe2=IS_IN("|", ar$, swipe1+1) % "Opt1|Bla bla|Opt2" --> swipe w/ 2 options swiped=swipe1+swipe2 : opt1$="" : opt2$="" IF swipe2 % handle swipe w/ 2 options (easiest) opt2$=MID$(ar$, swipe2+1) ar$=LEFT$(ar$, swipe2-1) opt1$=LEFT$(ar$, swipe1-1) ar$=MID$(ar$, swipe1+1) ELSEIF swipe1 % handle swipe w/ only 1 option (harder) ar1$=LEFT$(ar$, swipe1-1) ar2$=MID$(ar$, swipe1+1) IF IS_IN(" ", ar1$) & !IS_IN(" ", ar2$) % "Bla bla|Opt2" --> swipe with only right option opt2$=ar2$ : ar$=ar1$ ELSEIF !IS_IN(" ", ar1$) & IS_IN(" ", ar2$) % "Opt1|Bla bla" --> swipe with only left option opt1$=ar1$ : ar$=ar2$ ELSEIF LEN(ar1$)>LEN(ar2$) % "Blabla|Opt2" --> swipe with only right option opt2$=ar2$ : ar$=ar1$ ELSE % "Opt1|Blabla" --> swipe with only left option opt1$=ar1$ : ar$=ar2$ ENDIF ENDIF j=IS_IN("@", ar$, -1) % "Bla bla@IMG" or "Bla bla@@ICO" --> thumbnail/icon IF j>1 & "@"=MID$(ar$, j-1, 1) THEN j-- k=IS_IN(">", ar$, -1) % "Bla bla>AXN" --> link separator IF j & k & j>k % "Bla bla>AXN@IMG" --> turn AXN and IMG the other way around ar$=LEFT$(ar$, k-1)+MID$(ar$, j)+MID$(ar$, k, j-k) k=IS_IN(">", ar$, -1) % now in the form "Bla bla@IMG>AXN" ENDIF IF 0=k THEN k=LEN(ar$)+1 tx$=LEFT$(ar$, k-1) e$+="
  • " IF swiped % Create swipe options e$=LEFT$(e$,-1)+" data-icon='carat-l'>
    " IF swipe2 e$+=""+opt2$+"" e$+=""+opt1$+"" ELSEIF swipe1 IF opt2$<>"" e$+=""+opt2$+"" ELSE e$+=""+opt1$+"" ENDIF ENDIF e$+="
    " ENDIF IF linked | swiped ax$=MID$(ar$, k+1) IF ax$="" THEN ax$="#" ELSE ax$=GW_FORMAT_LINK$(ax$) ax$=REPLACE$(ax$, CHR$(34), CHR$(92,34)) % protect double quotes with a backslash e$+="" ENDIF IF sortable THEN e$+= " " e$+=GW_LV_CELL$(tx$) IF linked | swiped THEN e$+="" e$+="
  • " ENDIF NEXT FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LISTVIEW$(txt_axn$[]) BUNDLE.GET 1, "gw-last-edited-page", page IF !page THEN END "Error page needed in GW_ADD_LISTVIEW$()" % (5.6) % Create the control u$=GW_NEWID$("listview") % (5.6) Add the swipeable css and javascript to the page IF !IS_IN("swipe_lv", GW_PAGE$(page)) IF IS_APK() MAKE_SURE_IS_ON_SD("GW/swipe_lv.css") MAKE_SURE_IS_ON_SD("GW/swipe_lv.js") ENDIF GW_CHECK_AND_DOWNLOAD("GW/swipe_lv.css") GW_CHECK_AND_DOWNLOAD("GW/swipe_lv.js") GW_INSERT_BEFORE(page, "", "") GW_INSERT_BEFORE(page, "", "") ENDIF % (5.6) Add the sortable css and javascript to the page IF !IS_IN("jquery-ui.min", GW_PAGE$(page)) IF IS_APK() MAKE_SURE_IS_ON_SD("GW/jquery.ui.touch-punch.min.js") MAKE_SURE_IS_ON_SD("GW/jquery-ui.min.js") ENDIF GW_CHECK_AND_DOWNLOAD("GW/jquery.ui.touch-punch.min.js") GW_CHECK_AND_DOWNLOAD("GW/jquery-ui.min.js") GW_INSERT_BEFORE(page, "", "") GW_INSERT_BEFORE(page, "", "") GW_INSERT_BEFORE(page, "", "") ENDIF % Prepare swipeable listview element ARRAY.LENGTH al, txt_axn$[] FOR i=1 TO al IF IS_IN("|", txt_axn$[i])>1 opt$="class='swipe-delete' " % Special case for native-droid themes IF GW_THEME_OF_PAGE$(page)="native-droid" IF IS_IN(".light.css",GW_PAGE$(page)) THEN c$="ffffff" ELSE c$="000000" css$="#"+u$+" li>a:not(:hover){background-color:#"+c$+" !important}" GW_INJECT_CSS(page, css$) ENDIF F_N.BREAK ENDIF NEXT % Prepare sortable listview element IF IS_IN("~", txt_axn$[1])=1 sortable=1 js$ ="var "+u$+"changed=0;" js$+="$(document).bind('pageinit',function(){" js$+="$('#"+u$+" li').each(function(){" js$+="$(this).attr('id',$(this).index());});" js$+="$('#"+u$+"').sortable();" js$+="$('#"+u$+"').disableSelection();" js$+="$('#"+u$+"').bind('sortstop',function(){" js$+="$('#"+u$+"').listview('refresh');" js$+=u$+"changed=1;});});" ENDIF % Fill the control IF IS_IN("#", txt_axn$[1])=1 THEN ordered=1 % first element starting with '#' --> means ordered list IF ordered THEN e$="
      " e$+=REPLACE$(GW_NEW_LV$(txt_axn$[]), CHR$(92,34), CHR$(34)) % unprotect double quotes IF ordered THEN e$=e$+"
    " ELSE e$=e$+"" % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) IF sortable THEN e$+="" FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_LISTVIEW(page, txt_axn$[]) % Add the element to the page GW_REGISTER("GW_ADD_LISTVIEW") lv$=GW_ADD_LISTVIEW$(txt_axn$[]) GW_SET_SKEY("page", page, GW_PAGE$(page) + lv$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_LISTVIEW_CHANGED(ctl_id) % return if sortable listview has been changed by user or not ctl$=GW_ID$(ctl_id) JS("RFO("+ctl$+"changed)") chg$=GW_WAIT_ACTION$() JS(ctl$+"changed=0") IF !IS_NUMBER(chg$) THEN chg$="0" FN.RTN VAL(chg$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_GET_LISTVIEW_ORDER$(ctl_id) % return sortable listview order, as changed by the user ctl$=GW_ID$(ctl_id) % Get order of sortable listview js$="var t=[];$('#"+ctl$+" li').each(function(){" js$+="t.push($(this).attr('id'));});" js$+="RFO(t.join(' '));" JS(js$) r$=GW_WAIT_ACTION$() % Reset index-based ids of listview js$="$('#"+ctl$+" li').each(function(){" js$+="$(this).attr('id',$(this).index());})" JS(js$) FN.RTN r$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_REORDER_ARRAY(a$[],order$) % sort BASIC array according to user change of sortable listview SPLIT o$[], order$ ARRAY.LENGTH n, o$[] DIM tmp$[n] FOR i=1 TO n k=VAL(o$[i])+1 tmp$[i]=a$[k] NEXT ARRAY.COPY tmp$[], a$[] FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_HIDE_LISTVIEW_ROW(ctl_id, row) % hide a listview row typically from a 'Delete' swipe option ctl$=GW_ID$(ctl_id) js$ ="$('#"+ctl$+" li:nth-child("+INT$(row)+")')" js$+=".slideUp('fast',function(){$(this).remove()})" JS(js$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) %--------------------------------------------------------------------------------------------- % FUNCTIONS TO ADD USER INPUT CONTROLS %--------------------------------------------------------------------------------------------- FN.DEF GW_ADD_INPUTMINI$(v$) t$=GW_THEME_CUSTO$("mini") e$=GW_ADD_SLIDER$("", 0, 9E9, 1, VAL(v$)) % min, max, step, ini e$=REPLACE$(e$,"", txt_axn$[i], -1) IF !k THEN k=LEN(txt_axn$[i])+1 tx$=WEB$(LEFT$(txt_axn$[i], k-1)) ax$=GW_FORMAT_LINK$(MID$(txt_axn$[i], k+1)) %TODO: might be a bug -> change to WEB$(GW_FORMAT_LINK$()) e$+="
  • "+tx$+"
  • " NEXT FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTLIST$(hint$, txt_axn$[]) % Create the control u$=GW_NEWID$("inputlist") e$="" e$+="
      " e$+=GW_NEW_LI$(txt_axn$[]) e$+="
    " % Add to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTLIST(page, hint$, txt_axn$[]) % Add the element to the page GW_REGISTER("GW_ADD_INPUTLIST") e$=GW_PAGE$(page) + GW_ADD_INPUTLIST$(hint$, txt_axn$[]) GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_CLOSE_INPUTLIST(ctl_id) JS("$('ul[data-filter=\"true\"]').children().addClass('ui-screen-hidden')") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_NEW_OPT$(txt$[]) % (internal) ARRAY.LENGTH al, txt$[] FOR i=1 TO al e$+="" NEXT FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_SELECTBOX$(label$, txt$[]) % Create the control u$=GW_NEWID$("selectbox") % e$="
    " % e$+="" e$+="" %
    % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_SELECTBOX(page, label$, txt$[]) % Add the control to the page GW_REGISTER("GW_ADD_SELECTBOX") e$=GW_PAGE$(page) + GW_ADD_SELECTBOX$(label$, txt$[]) GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_RADIO$(parent, label$) % Create the control u$=GW_NEWID$("radio") GW_REGISTER("GW_ADD_RADIO$") IF !parent THEN v$=u$ ELSE v$=GW_ID$(parent) r$=WEB$(label$) IF LEFT$(r$,1)=">" checked$="checked='checked' " r$=MID$(r$,2) ENDIF e$="" e$+="" % Add the parent to the list of radio parents ls=GW_KEY_IDX("control") ls++ IF !parent THEN parent=ls GW_ADD_NKEY("radio-parent", parent) % Add the child to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_RADIO(page, parent, label$) % Add the control to the page GW_REGISTER("GW_ADD_RADIO") e$=GW_PAGE$(page) + GW_ADD_RADIO$(parent, label$) GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_RADIO_PARENT(ctl_id) % (internal) % Returns the radio parent id for a given radio child id GW_REGISTER("GW_RADIO_PARENT") e$=GW_ID$(ctl_id) % "radioN" child_id=VAL(MID$(e$, 6)) % N parent_id=GW_GET_NKEY("radio-parent", child_id) FN.RTN parent_id FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_CHECKBOX$(label$) % Create the control u$=GW_NEWID$("checkbox") r$=WEB$(label$) IF LEFT$(r$,1)=">" checked$="checked='' " r$=MID$(r$,2) ENDIF IF LEN(r$) THEN e$="" e$+="" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_CHECKBOX(page, label$) % Add the control to the page GW_REGISTER("GW_ADD_CHECKBOX") e$=GW_PAGE$(page) + GW_ADD_CHECKBOX$(label$) GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_SLIDER$(label$, n_min, n_max, n_step, n_ini) % Create the control u$=GW_NEWID$("slider") t$=GW_THEME_CUSTO$("slider") i=IS_IN("text-align:",t$) IF i j=IS_IN(" ",t$,i) IF !j THEN j=LEN(t$)+1 tt$=MID$(t$,i,j-i) t$=LEFT$(t$,i-1)+MID$(t$,j+1) ENDIF e$+="" e$+=" % Add the control to the list of controls + return its content GW_ADD_SKEY("control", u$) FN.RTN e$ FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUT(type$, page, label$, s_ini$) % (internal) generic class for input controls % Add the control to the page e$=GW_PAGE$(page) % specific commands GW_ADD_INPUT* must have already REGISTERED their name e$+=GW_ADD_INPUT$(type$, label$, s_ini$) GW_SET_SKEY("page", page, e$) % Return index of the control FN.RTN GW_KEY_IDX("control") FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTLINE$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("text", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTDATE$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("date", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTTIME$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("time", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTDATETIME$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("datetime-local", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTMONTH$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("month", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTWEEK$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("week", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTURL$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("url", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTEMAIL$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("email", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTCOLOR$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("color", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTNUMBER$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("number", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTTEL$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("tel", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTPASSWORD$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("password", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTFILE$(label$, s_ini$) FN.RTN GW_ADD_INPUT$("file", label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTLINE(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTLINE") FN.RTN GW_ADD_INPUT("text", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTDATE(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTDATE") FN.RTN GW_ADD_INPUT("date", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTTIME(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTTIME") FN.RTN GW_ADD_INPUT("time", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTDATETIME(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTDATETIME") FN.RTN GW_ADD_INPUT("datetime-local", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTMONTH(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTMONTH") FN.RTN GW_ADD_INPUT("month", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTWEEK(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTWEEK") FN.RTN GW_ADD_INPUT("week", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTURL(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTURL") FN.RTN GW_ADD_INPUT("url", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTEMAIL(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTEMAIL") FN.RTN GW_ADD_INPUT("email", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTCOLOR(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTCOLOR") FN.RTN GW_ADD_INPUT("color", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTNUMBER(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTNUMBER") FN.RTN GW_ADD_INPUT("number", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTTEL(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTTEL") FN.RTN GW_ADD_INPUT("tel", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTPASSWORD(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTPASSWORD") FN.RTN GW_ADD_INPUT("password", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTFILE(page, label$, s_ini$) GW_REGISTER("GW_ADD_INPUTFILE") FN.RTN GW_ADD_INPUT("file", page, label$, s_ini$) FN.END IF !GW_SILENT_LOAD THEN GW_LOAD_PG(++GW_CFN, GW_NFN) FN.DEF GW_ADD_INPUTBOX$(label$, s_ini$) % Create the control u$=GW_NEWID$("inpbox") custo$=GW_THEME_CUSTO$("inpbox") e$+="" e$+="