Created with the Personal Edition of HelpNDoc: Free EBook and documentation generator
Basic IDE Suite is a set of Android applications that provides an on-device IDE for programming in a Basic-like language, an on-device visual designer to create view layouts and a launcher to quickly invoke programs developed in the IDE. This help file document documents the following application versions.
Basic IDE version 6.00
Basic IDE Designer version 1.50
Basic IDE Launcher version 1.90
Basic IDE uses the BasicLib B4A library to provide the language interpreter for the IDE. It enables programs written in a syntax very similar to Basic4ppc to be edited and executed with some facilities for debugging that program. The program is interpreted but the code has been carefully optimised and so performance is quite high.
The B4AScript language can be extended to include Subs in the host application that can be called from B4AScript programs as though they were an intrinsic part of the language. These extensions are located in the Script Activity Module of the Basic IDE application. This may be modified and extended as required.
A companion application, Basic IDE Designer is an Android application that can graphically produce, on the device, view layouts for use in Basic IDE programs. See the Basic IDE Designer topic in this help file.
Another companion application, Basic IDE Launcher is an Android application that can quickly run a Basic IDE program selected from those located in the Launcher sub-folder of the main BasicIDE folder. See the Basic IDE Launcher topic in this help file.
Programs produced by Basic IDE can support device rotation in a similar manner to B4A programs by using some of the extensions in the Script module. However a separate layout for each orientation is needed together with some trivial program logic to load the correct layout. The Template.b4s file included in Scripts folder implements such logic and Basic IDE Designer can produce both portrait and landscape layout variants.
Storage Access
Basic IDE, Basic IDE Designer and Basic IDE Launcher use a folder named BasicIDE in the root of the external storage for their storage. Such storage will survive a de-install and re-install of the apps. Presently all three target API 28 so allowing continued access to external storage on Android 10 and later devices.
Targeting API 29 with an 'ApplicationAttribute' manifest entry specifying 'android:requestLegacyExternalStorage' as 'true' will allow continued access to external storage using the WRITE_EXTERNAL_STORAGE permission. This is only necessary for apps that will go in the Play Store that are required to target API 29. It is not relevant to non-store apps that can continue to target API 28,
To target API versions higher than API 29 a switch to using either GetSafeDirDefault or ExternalStorage (Storage Access Framework) to access the external storage will be necessary. As well as impacting access to the BasicIDE folder this would also mandate additions the File Functions in the Basic IDE Script module. As higher target APIs are only needed for an app to list in the Play Store any such changes are not currently planned.
Note that apps that target API level 30 and use Storage Access Framework will no longer be able to grant access to directories, such as the root directory of the SD card. the Android directory and the Download directory. However when targeting API 30 or higher a new permission, MANAGE_EXTERNAL_STORAGE, is available to allow apps like File managers, Backup and restore and Document managers to work as before. Apps employing this will only be accepted in the Play Store if their core function requires it. However for non-store apps this is not a consideration so when, and if, Basic IDE and Basic IDE Designer are re-targeted it is likely that they will go directly to API 30 and replace the WRITE_EXTERNAL_STORAGE with the MANAGE_EXTERNAL_STORAGE permission.
Help
There are various forms of help documentation provided in the BasicIDEHelp.zip. Before extracting the BasicIDEHelp zip file it should be unblocked by right clicking on it in File Explorer, selecting Properties and checking Unblock at the lower right of the General tab. In particular this allows the .chm help files to be properly displayed by Windows. If the .chm files are not unblocked their content will not be available in the Windows help viewer.
The Help folder in this file should be copied to your BasicIDE project folder as described below. It contains the following files.
A copy of this compiled help file, BasicIDE.chm, which documents Basic IDE, Basic IDE Designer and Basic IDE launcher. The content of this file is also available in HTML format in B4AScript.html which is generated from B4AScriptHtml.html by running B4AScript.exe, which UpdateHelp.exe does automatically.
Documentation for the B4AScript language implemented by the interpreter in the BasicLib library in the B4AScript.chm help file. The content of this file is also available in HTML format in B4AScript.html which is generated from BasicIDEHtml.html by running BasicIDE.exe, which UpdateHelp.exe does automatically
Documentation for the language extensions in the Script module in the BasicIDEScript.html file which is generated from comments in the BasicIDE project Script module by running UpdateHelp.exe
Documentation for the BasicLib library used to implement the BasicIDE interpreter is available in the BasicLib.chm compiled help file but this is not copied to the device Help folder.
Desktop Installation
The Basic IDE project is provided in the BasicIDE zip file.
The Basic IDE Designer project is provided in the BasicIDEDesigner zip file
The Basic IDE Launcher project is provided in the BasicIDELauncher zip file. The Basic IDE Launcher project includes all the modules from the Basic IDE project by relative reference except for Syntax which is not needed. For this reason the Basic IDE and Basic IDE Launcher projects should be installed side by side in a common parent folder on the desktop. See the introduction to the Basic IDE Launcher topic. The suggested name for this common folder is BasicIDE Suite. For convenience also install the BasicIDEDesigner project in this same folder.
Copy the Help folder in the BasicIDEHelp zip file file to your BasicIDE project folder, not the common BasicIDE Suite folder. Before extracting the BasicIDEHelp zip file it should be unblocked by right clicking on it in File Explorer, selecting Properties and checking Unblock at the lower right of the General tab. In particular this allows the .chm help files to be properly displayed by Windows and allows UpdateHelp.exe to run without a security warning. If the .chm files are not unblocked their content will not be available in the Windows help viewer. The files may be individually unlock later if this step is omitted.
IMORTANT: Before compiling BasicIDE run UpdateHelp.exe in the Help folder to copy the help files to the project Files folder. These are omitted from the BasicIDE zip to keep the zip size within the B4A forum upload limits.
The BasicIDE projects compiles a full set of help files into DirAssets of the resulting app. When UpdateHelp.exe is run it creates BasicIDEScriptAutocomplete.txt, BasicIDEScriptHighlight.txt and BasicIDEHelpUpdated.date. These updated files are automatically copied to the BasicIDE project Files pane, together with the B4AScript and BasicIDE chm and html help files, so they can be copied to the device Help folder when BasicIDE is run. See the more complete description of this in the Documentation section of the Basic IDE Script Module topic of this help.
UpdateHelp.exe invokes two helper programs, B4AScript.exe and BasicIDE.exe to produce theB4AScript and BasicIDE chm and html help files and the IDE invokes Reminder.exe on compilation. These program all are written in Basic4ppc and the source code for them is available in their Basic4ppc .sbp project files. The Basic4ppc language, on which B4AScript is based, was the predecessor to B4X and shares many similarities. They are not complicated programs and if required it would be easy to translate them to B4J.
The additional libraries required by the BasicIDE Suite projects are provided in the BasicIDELibraries zip file
Basic IDE requires the BasicLib, CodeEditorView, CollectionsExtra, Dialogs2, GPStoOSGB, IME2, ScaleImageView and ScrollView2D additional libraries. To save locating these in the forum they are available in the BasicIDELibraries zip file. Any not already there should be added to your B4A Additional Libraries folder. BasicIDE also requires the BitmapCreator, JavaObject, Phone, RandomAccessFile, Reflection, RuntimePermissions, Serial, StringUtils and XUI Views standard libraries.
Basic IDE Designer requires the Dialogs2 additional library and also the JavaObject, Phone, Reflection and XUI Views standard libraries.
Basic IDE Launcher requires the BasicLib, CodeEditorView, CollectionsExtra, Dialogs2, GPStoOSGB, IME2, ScaleImageView and ScrollView2D additional libraries and also the BitmapCreator, JavaObject, Phone, RandomAccessFile, Reflection, RuntimePermissions, Serial and StringUtils standard libraries.
Device Installation
On the device programs are loaded into the IDE and saved from the IDE to a folder named 'Basic IDE' which must be located in the root of the external storage (not the SD Card) of the Android device. To set up the device follow these instructions which are most easily done using the FTP capability of B4A-Bridge.
Make a folder 'Basic IDE' in the root of the device external memory and copy the files from the BasicIDE project Scripts folder into it.
Make a folder 'Layouts' in the device Basic IDE folder and copy the files from the BasicIDEDesigner project Layouts folder into it. The Layouts folder is used to hold the layouts created by Basic IDE Designer. These layouts that can be accessed from Basic IDE by the 'Add layout' menu option or in Basic IDE Designer by the 'Open Layout' menu option.
Make a folder 'Launcher' in the device Basic IDE folder and copy into it any programs you want Basic IDE Launcher to be able to run. Programs may be saved to this folder in Basic IDE by invoking the 'Save Program To Launcher' menu option
Compile Basic IDE in Release mode with B4A, install to the device and run Basic IDE there. Note that on compiling a reminder dialog will be shown to to update the autocomplete files if changes have been made to the Script module by running UpdateHelp.exe and then recompile. Press the OK button to resume the compilation. On the device load (via the Open Program menu item) and run IdeTest.b4s, pressing the Run button, to see a demo of most of what is implemented for the GUI.
Compile Basic IDE Designer in Release mode with B4A, install to the device and run Basic IDE Designer there. On the device load (via the 'Open Layout' menu option) one of the existing layouts in the Layout folder and start playing.
Compile Basic IDE Launcher in Release mode with B4A, install to the device and run Basic IDE Launcher there. Load one of the programs presented and start playing.
DO NOT run Basic IDE or Basic IDE Launcher in Release(obfuscated) mode in the B4A IDE. It will not work unless you go through the Script module code and hyphenate the names of all the additional Subs.
DO NOT run Basic IDE or Basic IDE Launcher in Debug mode in the B4A IDE unless you have selected the legacy debugger. They will not work with the normal debugger for unavoidable technical reasons explained below.
Basic IDE Designer and Basic IDE will both create the Basic IDE folder and the folders Help and Layouts in the Basic IDE folder if they do not exist. Basic IDE and Basic IDE Launcher will both create the Launcher folder if it does not exist. BasicIDE when run will copy the help files compiled into DirAssets to the Help folder if there is no BasicIDEHelpUpdated.date file in that folder or if the one in DirAssets is newer than the existing one.
Debugging the Basic IDE App
Should it be necessary to debug Basic IDE itself it is necessary to use the legacy debugger. The rapid debugger works by running most of the compiled Java code on the desktop which communicates with a shell program running on the device which performs the device dependent operations. For efficiency the desktop bundles many operations together before sending them to the shell and needs to know which operations are events that must complete before performing the next operation. In a library or a compiled Class module such events must be marked with the RaisesSynchronousEvents attribute and in order for the debugger to identify these events the attribute must be present in the library XML which will only happen for public events. The BasicLib library uses the event mechanism in internal private methods to implement the language extensions and so will not work correctly with the rapid debugger. However the legacy debugger does work well with the BasicLib library and so if a debugger is needed for Basic IDE orBasic IDE Launcher the legacy debugger should be used instead of the rapid debugger.
(c) Andrew Graham - 2020
Created with the Personal Edition of HelpNDoc: Free EPub producer
BasicIDE uses the BasicLib library. For detailed help on the B4AScript programming language implemented by this library see the separate B4AScript.chm file. A synopsis is presented here.
Most operations and names are case-insensitive.
There is no Globals Sub. It is replaced by the initial code section at the beginning of a program. All Subs must follow this code section. Execution commences at the first line of this initial code section and ends when a following Sub declaration is found.
Variable and Sub names may contain letters, numbers, underscores (_) and hashes (#). Any variables used in the first (non Sub) block of code are global variables. Any used for the first time in a Sub that are not global are local to that Sub. A local variable name may not be the same as a global variable name so if a global name is used as a parameter name then an error occurs.
A point to beware of is that global variable names may be unwittingly, particularly if simply named like i or j, used as local variables. Normally the fact that these are global is immaterial but if, for example, i is used as a For loop index in the initial code block and so becomes global, and a Sub called by an event uses i as a For loop index and a Sub called within that For loop also uses i as a For loop index then problems will arise. It is recommended to use some prefix for global variables that identify them as such to avoid such problems.
All global variables can be Dimmed as multi-dimension arrays of up to three dimensions as many times as required anywhere in the program. Variable 'A()' or 'A' is always equivalent 'A(0)' , 'A(0, 0)', 'A(0, 0, 0)'or 'A()'. Where an array reference, as opposed to the value of an array element, is required then A or A() or A(x) are all accepted. Local variables can never be arrays. Multi-dimensioned arrays may also be accessed as single dimensioned arrays using the length returned by ArrayTotalLen or GetTotalLen when an array name is passed as a parameter.
For convenience arrays may be addressed by the '.' convention, Array.Variable, where the variable contains the required index into the array. This facility is provided to emulate the Basic4pp structure type and the Dim Type(...) statement is also provided. However despite the syntax being the same as Basic4ppc the implementation differs. In Basic4ppc the indexer names declared by 'Type' are constants associated only with that array. In B4AScript the indexers are in fact true local or global variables with their values automatically assigned so care needs to be taken not to unwittingly use the indexer names as normal variable names unless this is what is really intended.
Although arrays, as opposed to the value of a single item of an array, cannot be passed as parameters the same functionality can be achieved by passing the array name and then using GetItem, GetLen, GetRank, GetTotalLen and SetItem which provide indirect access to an array specified byname at runtime.
There is a pre-defined global array, Args(), that contains the argument array passed at program runtime. Note that this array is actually shared with the host and so may be used to pass results back if required. Arrays may also be shared by ShareArray but sharing will be broken by a Dim operation on a shared array by a program or a reassignment of the array by the host application. In contrast the arrays used in the GetArray and SetArray methods are not shared but are copied.
The Msgbox statement takes one or two parameters and causes a Message event. The first parameter is found in MessageString and the optional second parameter is found in SubjectString. If the program is running on a thread then the Message event is raised on the main thread of the application which is the only thread permitted to touch any GUI elements. In this case the call to Msgbox returns immediately and the event Sub is run asynchronously.
The Print statement formats a string and causes a Message event with the string in MessageString and SubjectString property set to 'Print'. Print accepts multiple items to print separated by either a semi-colon or a comma. Semi-colon causes the following item to be concatenated with the previous item, comma inserts a space character between items. The traditional '?' is also provided as a synonym for Print. If the program is running on a thread then the Message event is raised on the main thread of the application which is the only thread permitted to touch any GUI elements. In this case the call to Msgbox or Print returns immediately and the event Sub is run asynchronously.
CallHostSub, and its synonym Sys, allows B4A host program Subs to be directly called from within a program and provide a return value. However a down side to this is that if the program is being run on a Thread the Sub being called must not manipulate any GUI elements. If GUI access is required from a program running on a thread then CallHostGuiSub, or its synonym SysGui, must be used which runs the Sub on the main thread of the application which is the only thread permitted to touch any GUI elements. In this case the call to CallHostGuiSub returns immediately and the called Sub is run asynchronously so there can be no return value. There is no limit to the numbers of parameters a called Sub may have. Called Subs must have all their parameters of String type and must return a String type. Sys is provided as a convenient synonym for CallHostSub and SysGui is a synonym for CallHostGuiSub.
Strings can be either single or double quotes delimited for convenience in manipulating them within B4A code. The opening delimiter is matched to the closing delimiter permitting the use of the other delimiter character within strings.
Only multi-line If statements are allowed.
Rem is provided but must start a statement on a new line.
# at the beginning of a line is interpreted as a Rem keyword.
The colon statement separator is not supported.
Global variables are always cleared to an empty string at the the start of program execution. Local variables are not guaranteed to be be cleared and so should always be explicitly initialised.
Select ... End Select structures cannot be directly nested. That is code in a Case may not contain another Select ... End Select although it is permissible to call a Sub that does contain another Select ... End Select structure.
Goto can only be used to jump within a scope or to an outer scope. That is it cannot be used to jump into a For...Next, Do...Loop, If...End If or Select ... End Select structure. It is permissible to jump out of or over such structures but not land within them. Use of Goto is deprecated and is always unnecessary, usually indicating badly structured code.
Created with the Personal Edition of HelpNDoc: Produce online help for Qt applications
After setting up as detailed in the Overview topic of this help compile BasicIDE in B4A, install it to the device and run it. On the device load (via the 'Open Program' menu option) and run IdeTest.b4s, pressing the Run button, to see a demo of most of the UI capabilities implemented in the device IDE. Press the buttons and check the check boxes in the demo Activity to see more and examine the program code.
A comprehensive set of host platform functions is provided by the Basic IDE Script module for programs to use. Additional functions are readily provided by adding them to the Script module of the IDE source where they can be accessed by the 'Sys' or 'CallHostSub' functions or they can be called as keywords by their name is they are added to the Script module AddNewSysCalls Sub. See the Basic IDE Script Module topic in this help file for more information.
A program consists of an initial code block optionally followed by one or more Subs. This initial code block is called whenever the Script module activity Activity_Create occurs. GetFirstTime returns True when the program is run for the first time. On subsequent invocations of Activity_Create it returns False. Note that GetFirstTime for a program is not the same as FirstTime in the Script module Activity_Create. A new program, or the same program, might be run again while the Script activity still exists so a separate flag is needed to indicate the first run of a program as against the creation of the Script activity.
When the Script activity pauses the program 'Sub activity_pause(userclosed)' is called if it is present.
When the Script activity resumes the program 'Sub activity_resume' is called if it is present.
A program that comprises only the code in the initial code block, and any Subs, and does not wait for events after running the initial code block can be closed by calling CloseAfterThis at any point in the initial code block. Note that this bypasses the normal Blib_Ended code that will display any Print output and any error message.
A program waiting for events can terminate itself by calling either the AppClose or the ActivityFinish functions. ActivityFinish closes the Activity and returns directly to the editor. This may sometimes be required but it bypasses the normal Blib_Ended code that will display any Print output and any error message. AppClose is the recommended way of closing a program.
A template called Template.b4s that can help in creating a new B4AScript program is provided in the Scripts folder of the Basic IDE project. This template provides the outline of a program that includes empty event code for all possible events that can be raised in a program as well as code that saves and restores the activity view states on Activity Create and Pause. The template assumes the existence of a Sub LoadLayout, not provided in the template, that creates the views for the program. The template can be opened in Basic IDE and the menu option Load Layout invoked when a list of layouts in the Layouts folder will be displayed for selection. When a layout is selected it will append a Sub LoadLayout and a Sub LoadLayoutLandscape to the code in the editor and prepend a list of global variable definitions. These global variables can be used instead of literal strings to refer to views by name so avoiding the typing of quotation characters. Any existing layout subs and set of view global variables will be automatically replaced so enabling adjustment to layouts in already written programs, providing that the global variable declarations are at the beginning of the code and that Sub LoadLayout is the last Sub in the code or is followed only by Sub LoadLayoutLandscape. It is recommended that further view initialisation is not coded into Sub LoadLayout or Sub LoadLayoutLandscape but is included in another Sub run immediately after the layout Sub. The recommended name for this is Sub AdjustLayout or Sub AdjustLayoutLandscape.
To ease saving state during device rotation when the Script activity is recreated the extension functions SaveState and RestoreState are provided. Template.b4s includes the code for doing this with the saved state identified as 'BasicIDE'. For the final program this is best changed to an identifier unique to the program. If required the state reset invoked when the activity is used closed can be removed to allow state to persist indefinitely between program invocations.
If the program is to run locked to a single orientation then it is recommended to invoke SetOrientation(orientation) before LoadLayout in the initial code block where 'Orientation is -1 = unspecified, 0 = Landscape, 1 = Portrait.
The Script module supports the '#include' directive when loading programs to enable modularisation within a program to control the size of individual parts of a program for more convenient editing. See the BasicIDE include Directive in this help file for more information.
BasicIDe supports project sub-folders to assist the compartmentalisation of layouts into separate projects. See the 'Select Project', 'Create Project' and Remove Project' menu option descriptions below.
BasicIDE persists the chosen values for Autocomplete Mode, Autocomplete Height, Autocomplete Threshold, Font, Font Size, Small Font Size and Indent Size. These settings are saved in the file BasicIDE.ini in the BasicIDE folder. To quickly restore the default values for all these settings just delete this file with a file manager and the next run of BasicIDE will recreate it with the default values.
Note that the editor activity is locked to the portrait orientation. This is because of the many problems different devices and keyboards have of generating IME height changed events with strange values when the activity resumed after being paused with the keyboard open. As the editor uses these height values to re-size itself so that the last lines are always accessible above the keyboard when open these wrong heights set the editor size wrongly. Compensating for these effects became insuperable when allowing rotation. However programs do support rotation of the device if this is required.
Syntax Highlighting
The editor used in Basic IDE provides syntax highlighting for comments, strings, numbers, B4AScript keywords, Script module additional functions, variable and Sub names in the current program. The syntax highlighting for variable and Sub names is updated whenever the Enter key is pressed.
Auto-completion
The editor used in Basic IDE provides auto-completions for both the intrinsic B4AScript functions and for those additional functions added by the Basic IDE Script module. It also provides auto-completion for all the variables and Subs declared in the current program. Auto-completion is updated every time the Enter key is pressed in the editor.
There are four levels of auto-completion available including none. These options are selected by the 'Autocomplete' menu option. 'None' disables auto-complete entirely. 'Basic' provides auto-completion of the name of the function and a pair of parentheses if the function takes parameters. 'Parameters' shows parentheses and a number of commas to indicate the number of parameters required and 'Full' provides a full parameter list with helpful parameter names indicating their use. There is a definable threshold for the number of characters typed in a word before showing the matching options. The default for this is three but this may be changed using the 'Autocomplete Threshold' menu option.
The beginning of character sequences that are valid for consideration for auto-completion are determined by a set of leading boundary characters. The end of a character sequence is the present position of the cursor.. The boundary characters recognised by the CodeEditorView library are :
Tab Space Newline ( = ^ + - * / & < > , . ; : [{
Any auto-completion item whose start matches the character sequence under consideration will be presented in list in a pop up window from which the required one may be selected. Backspacing to delete a character after selecting an item for insertion will delete the inserted characters and offer the pop up list again. The autocomplete list that pops up once the specified threshold number of characters has been typed is scrollable if there are more matches available than can fit in the autocomplete window.
Auto-indentation
The editor has a measure of automatic indentation. A new line following another line will inherit the same indentation as that previous line. When additional indentation of the lines following keywords such as Then and While is required entering an additional space character will cause the additional indentation on the following line. To out-dent a line use the backspace key. After a while the code will probably be looking a bit scrappy so invoking the 'Format Code' menu option will correct the indentation of all the code in the editor according to the present setting of 'Tab Size'.
Auto-indent is not active when appending characters to the end of the text in the editor. This seems to be because the auto-indent mechanism is triggered by an insertion into the text in the editor and adding characters at the end of the text is not seen as an insertion. In practice the final line will be an unindented 'End Sub' so when adding a new Sub at the end of the editor it is better to type both the Sub declaration and the terminating End Sub and then fill in the Sub contents where auto-indenting will be effective. In practice the layout Subs will be appended to the end of the code so this is normally of no consideration.
The editor is implemented using the CodeEditorView library which may be used in other projects if required. It is a B4A custom view that uses a MultiAutoCompleteTextView which is an extension to EditText so the normal EditText functions are all available together with those specific to CodeEditorView. As usual documentation is provided within the library xml file.
Menu Options
The 'Select Project', 'Create Project' and Remove Project' select, save and remove project sub-folders located in the BasicIDE folder. These folders are named with the project name plus a '_project' suffix. The suffix is never visible within the IDE. The selected project is displayed at the top of the editor window together with the name of the program in the editor. Use of a project is optional. If no project folder is selected then programs will be loaded, saved and deleted in the BasicIDE folder.
The 'Open Program', 'Save Program', 'Save Program As' and 'Delete Program' options open, save and delete program files in the BasicIDE folder or in the current project folder.
The 'Save Program To Launcher' menu option will save the current program to the Launcher folder where it will be available to Basic IDE Launcher. If the program has not already been named then 'Save As' will be invoked and a copy so named will be saved to the BasicIDE or the current project folder as well as to the Launcher folder.
The 'Clear Program' option will clear the editing area, prompting the user to save any unsaved changes.
The 'LoadLayout' option will show a list of projects in the Layout folder. Selecting a project will then show the layouts available in that project folder. When a layout is selected it will append code to layout views to the code in the editor and also prepend a list of global variable definitions if the layout global definitions file exists. These global variables can be used instead of literal strings to refer to views by name so avoiding the typing of quotation characters. Any existing layouts and set of view global variables will be automatically replaced so enabling adjustment to layouts in already written programs, providing that the global variable declarations are at the beginning of the code and the layouts are at the end. It is recommended that further view initialisation is not coded into the layout Subs but is included in other Subs run immediately after running a layout Sub. The recommended name for these are Sub AdjustLayout and Sub Sub AdjustLayoutLandscape
The 'Run Program' option will run the selected script from the current project folder without loading it into the editor. This enables a chained or included program to be present in the editor for development while the host program can be started from the main menu to ensure that the chained or included script executes in the expected environment.
The 'Print Program' option will create a hard copy printout of the current program. This requires that the device Bluetooth is switched on, a Bluetooth connected printer supporting the ESC/POS protocol is paired to the device and that the printer is switched on and connected. If the Shrink checkbox is checked then the printout is made using the smaller printer font otherwise the normal, larger, font is used.
The 'Autocomplete' option selects the level of auto-completion provided in the editor. 'None' disables auto-completion entirely. 'Basic' provides auto-completion of the name of the function and a pair of parentheses if the function takes parameters. 'Parameters' shows parentheses and a number of commas to indicate the number of parameters required and 'Full' provides a full parameter list with helpful parameter names indicating their use.
The 'Autocomplete Height menu option selects the height of the autocomplete popup window. The numeric sizes are somewhat arbitrary but are implemented as a proportion of the screen height. The Auto option will auto-size the popup window to accommodate the available options, and is scrollable if the number of options exceeds the maximum height available for the popup window. The default for this is three.
The 'Autocomplete Threshold' menu option selects the threshold for the number of characters typed in a word before showing the matching options. The default for this is three.
The 'Add Line Nos.' and 'Remove Line Nos'.menu options do what they imply. In general the display of line numbers is discouraged as their presence disrupts the auto-indenting and they are not in general needed as a runtime error line will be highlighted on return to the editor. When editing a line numbered program there is no need to manually type in any line numbers. After finishing the edit just select 'Add Line Nos.' again and the program will be renumbered. There is no need to remove the line numbers before running the program and line numbers are never saved with the program. Note that these menu options will add a newline character to the last line of code if one is not already present.
The 'Format Code' menu option will neatly format all the code in the editor indenting and out-denting it as necessary to provide a consistent view of its structure. The default indenting is two spaces but this may be changed using the 'Tab Size' menu option. It also removes any line numbers if present.
The 'Font' and 'Font Size' menu options allow selection of the editor font and normal font size.
The 'Small Font Size' menu option allows selection of the editor font size when the 'Shrink' checkbox is checked..
The 'Change IME' menu option displays for selection all the keyboards installed and enabled on the device.
The 'Help'' menu option displays for selection the files in the Basic IDE Help folder. TheHTML files require Microsoft Edge tp be present on the device as this seems to provide the best default viewing experience of the commonly available browsers. A message will be shown if this is not so.
In the lower pane of the editor the "Wrap" checkbox determines whether the editor wraps long lines or not.
In the lower pane of the editor the "Shrink" checkbox determines whether the editor uses the normal font size or the small font size. Shrinking the text in the editor allows the larger structure of the program to be seen and facilitates locating specific areas of the source code. Tapping the editor will position the insertion point of the editor to that location and will open the keyboard, setting the font size to normal. Closing the keyboard will set the editor font to the small size if 'Shrink' was checked when it was opened.
In the lower pane of the editor the two buttons with bold single line up and down chevron emblems will position the editor insertion point at the beginning or end of the present program.
In the lower pane of the editor the 'Shrink' checkbox controls the size of the text in the editor. The code can be quickly zoomed out by checking it give an overview of the code. The cursor can be positioned where the next edit is required by shrinking the code then tapping on the editor at the required insertion position. The keyboard will then open and the text size will be restored to the size it was before Shrink was checked. When the keyboard is subsequently closed the code will again be zoomed out if Shrink was checked when the keyboard opened.
Search
In the lower pane of the editor the 'Search' button allows a search to be made in the editor for a given search term. As the B4AScript interpreter is case-insensitive all searches are also case-insensitive. When the search dialog is displayed the search term will be filled with the contents of the system clipboard. This enables an item of text to be copied in the editor and then used as a search term. After a search all the instances of the search term will be highlighted in the source code by the syntax highlighting mechanism and the editor text positioned to display the first occurrence.. The colour of the search highlighting is deliberately similar but not identical to that of selected text. Typing any character into the editor or using the up or down buttons will remove all the search highlighting.
In the lower pane of the editor the two buttons with two-line up and down chevron emblems will search again for the latest search term used in either the up or the down direction and if found will select the item for editing. The syntax highlighting for all the other search item instances will be cancelled and the editor will be scrolled to put the selected text in view.
Replace
In the lower pane of the editor the Replace button allows a search to be made in the editor for a given search term and for the found item to be replaced. When the replace search dialog is displayed the replace search term will be filled with the contents of the system clipboard. This enables an item of text to be copied in the editor and then used as a search term for replacement. As the B4AScript interpreter is case-insensitive all searches for replacement are also case-insensitive.
A replace search without the 'Replace All' checkbox checked will be made forward from the present insertion point. After a replacement of the first instance found of the search term the replacement will be highlighted in the source code by the syntax highlighting mechanism and the text in the editor will be scrolled to make the replacement visible. Typing any character into the editor will remove all the search highlighting.Typing any character into the editor or using the up or down buttons will remove all the search highlighting.
A replace search with the 'Replace All' checkbox checked will search the entire source code from the beginning to the end and all found search items will be replaced. After a replacement all the instances of the replacement term will be highlighted in the source code by the syntax highlighting mechanism and the text in the editor will be scrolled to make the last replacement visible.. The colour of the replacement highlighting is deliberately similar but not identical to that of selected text. Typing any character into the editor or using the up or down buttons will remove all the search highlighting.
In the lower pane of the editor the two buttons with two-line up and down chevron emblems will search again for the latest replacement term used in either the up or the down direction and if found will select the item for editing. The syntax highlighting for all the other replacement item instances will be cancelled and the editor will be scrolled to put the selected text in view.
Running and Debugging Programs
To run the program in the editor just press the Run button in the lower pane of the editor.
The 'Alongside' checkbox only affects Basic IDE if it is running in split screen mode. If this is checked then when the Run button is pressed the script will be run in the other part of the split screen. If unchecked then the script screen will replace the Basic IDE editor screen as normal.
If an error occurs a message dialog will be displayed describing the error and its location in the programs. On dismissing the dialog the program code will be displayed with the error line highlighted. Editing the code will remove the error highlight from the line.
As always Msgbox provides an interactive way to help with debugging. The Print keyword, and Msgbox with a subject of 'Print', also support debugging but in a different way. Anything output by using Print is saved and will be displayed whenever the program stops at a break line or is single stepped. The output from Print, if any, is also displayed at the termination of the program after any error message has been displayed. A CRLF is added to the end of any Print output to separate printed lines.
The accumulated Print output may be cleared by putting '<clear>', without quotation marks, at the start of printed item list. Anything after '<clear>' is added to the now empty buffer and a CRLF is added.
The last line printed may be deleted by putting '<delete>', without quotation marks, at the start of the printed item list. Anything after '<delete>' is then added to the buffer and a CRLF is added.
The BasicLib library supports a single breakpoint which can be set programmatically by invoking the Break, BreakAt, BreakAndPrint, BreakAndPrintIf and BreakIf functions defined in the B4AScript module. Once the break line is hit the program stops and displays a modal dialogue containing the present value of both Global and Local variables together with any Print output made by the program. The program enters single stepping mode and after each step the variable and Print modal dialog is redisplayed. The stepping mode may be cancelled in this dialog and the program allowed to run freely.
The Msgbox, Print and BreakXxxx functions above rely on a modal dialog to halt program execution while debugging. As modal dialogs are deprecated in B4A there is a discussion about mitigating the effects of this in the Modal and Non-modal Dialogs topic of this help file. At the moment these modal dialogs are available and their use seems to cause no problems. However if modality problems are experienced DebugSnapShot, AsyncMsgbox and AsyncMsgbox2 are alternatives.
See the Debugging section in the Script Module topic of this help file for more information.
Stand-alone Script Programs
It is possible to rapidly invoke script programs without using Basic IDE and to also create a stand-alone script program that can be installed on a device and execute independently of the IDE. See the Basic IDE Launcher topic in this help file.
External Editors
The editor used in Basic IDE versions 5.2 and later is much improved over the previous editor so the need for an external editor is therefore much reduced but one of course can still be used if this is preferred.
The author has used both QuickEdit+ and DroidEdit Pro from the Play Store. QuickEdit+ is probably the preferred editor as it is still maintained whereas DroidEdit seems to be abandoned as it has not had an update since September 2017.
If you cannot find QuickEdit+, which presently seems to be titled as QuickEdit Pro, in the Play Store install QuickEdit Free, open Help and scroll down to find 'Remove Ads'. You can of course just use the free version if you can cope with ads. You will need to uncheck Settings -> File Type Filter to see .b4s files and use Settings -> File Associations to add default Visual Basic highlighting for b4s files.
You can make DroidEdit always use Visual Basic syntax highlighting by selecting 'Force Syntax' from the rightmost lower File Actions button with a .b4s file open in the editor, selecting Force Syntax, selecting Visual Basic and then selecting Yes to 'Always open ...'.
The DroidEdit custom theme settings used by the author are
Background = White = #FFFFFF
ReservedKeyWord ='Blue' = #0000FF
DataType = Purple = #800080 (Literal Numbers)
Literal = Purple = #800080 ('quoted' Strings)
Variable =Orange = #FFA500
PreProcessor = Grey = #808080
Comment = Green = #008000 (Comments and 'quoted' Strings)
ParsingError = Red = #FF0000
Function = DarkBlue = #00008B
Operator = Black = #000000
Remember that on most Android devices double-tapping the Recent button will switch between the two latest apps. This makes it simple to swap between an external editor and Basic IDE but remember to save the file in the external editor and reopen it in Basic IDE when switching between the two.
Created with the Personal Edition of HelpNDoc: Create HTML Help, DOC, PDF and print manuals from 1 single source
Basic IDE Designer is an Android application that can graphically produce, on the device, both portrait and landscape view layouts for use in Basic IDE programs.
Like BasicIDe itself the Designer supports project sub-folders to assist the compartmentalisation of layouts into separate projects. See the 'Select Project', 'Create Project' and Remove Project' menu option descriptions below.
Use of the Designer
Hopefully use of the Designer is fairly intuitive. An explanation of the menu options available in the drop down menu at the top right of the Designer follows. The primary layout management mode of Basic IDE Designer is portrait and some menu options are only available in portrait mode.
The 'Select Project', 'Create Project' and Remove Project' select, save and remove project sub-folders located in the Layouts folder. These folders are named with the project name plus a '_project' suffix. The suffix is never visible within the Designer. The selected project is displayed at the top of the layout window together with the name of the layout. Use of a project is optional. If no project folder is selected then layouts will be loaded, saved and deleted in the Layouts folder.
The 'Open Layout ...' menu option displays a list of layouts available in the selected project folder and will load the selected layout into the Designer.
The 'Save Layout ...' and 'Save Layout As ...' menu options will save the present layout to the selected project folder.
The Delete Layout ...' menu option displays a list of layouts available in the selected project folder and will delete the selected layout from that folder.
The 'Clear Layout ' menu option will clear both the present portrait and landscape layouts in the Designer.
The 'Copy To Landscape' menu option copies the present portrait layout to the landscape layout. See the Portrait and Landscape layouts section of this topic for more information.
The 'AddView ...' menu option allows views to be added to the layout. If a view supports the display of text then that text will be requested when it is added. Once a view has been added new text for a view may be entered by tapping the right side of the view. MenuItems are not views and do not have normally have or need view names, but the Designer assigns a name like 'MenuItemX' to each MenuItem as they are added or reloaded from a layout. These arbitrary names are used only within the Designer to refer to each MenuItem and will not be saved in the layout file.
The Find View ...' menu option will display a list of the current views in the layout together with their text property, if any, and their parent if not the Activity. Pressing a view in the list will bring it to the front and colour it red to make it more obvious. This is a convenient way of locating lost views hiding behind others. If the view is parent to other views those child views will not be brought to the front. This is a deliberate design decision allowing a cluttered panel to be selected and easily moved or resized without interference from its children.
The 'Reset View ...' menu option will display a list of the current views in the layout together with their text property, if any, and their parent if not the Activity. Pressing a view in the list will bring it to the front and reset its position and size to the defaults used when adding it. This is a convenient way of relocating lost views hiding behind others or off screen. The view will retain any parent so to change the parent tap the view and select a new parent from the list of parents. If the ALL item is selected all the views in the layout will be reset. This might be convenient after loading in landscape orientation a view originally laid out in portrait. All the views will be positioned as if just added and may then be laid out in an appropriate way for the new orientation.
The 'Grid Size ...' menu option lets the size of an invisible grid be selected. View positions and dimensions will snap to to the grid.
The 'Toggle Borders' menu option toggles the display of the borders of the view in the Designer layout.
The 'Change IME' menu option displays for selection all the keyboards installed and enabled on the device.
The 'Help ...' menu option displays for selection the files in the BsicIDE Help folder.
The Designer does not support a classical 'select then drag the edges' type of view resizing as small displays and big fingers make this difficult. Instead a long press on the middle half of a view will turn the view gold and dragging will move it. A long press on the left quarter of a view will turn the view green and dragging will resize it vertically. A long press on the right quarter of a view will turn the view red and dragging will resize it horizontally. If the view being moved has children the child views will be moved with the parent.
To delete a view resize it in width or height to zero when it will be removed from the layout. Note that any children of the view are removed as well so to keep them, if required, remove them as children from the view by re-specifying their parent before deleting the view.
Menu items cannot be resized vertically and will be added at the top right of the layout. They may be moved anywhere in the layout if required but their position in the layout has no significance in the final layout except that the vertical order of the items in the layout will determine their order in the drop down menu at runtime.
The Designer supports nesting of views on Panels. See the 'Saving the Layout' section below. To add a view as a child of a panel tap the left half of the view when a choice of panels to host the view will be displayed. To remove the view from its parent panel click it again and select Activity as the parent. While a view is hosted by a parent the position and size displayed in the title bar and in the view are relative to the parent. The Designer will only present possible parents that will not create a circular parent/child reference.
A tap on the right half of a view can perform two functions. For views that support text a dialog will be shown displaying the existing text which can be edited if required. After cancelling or accepting the text dialog a colour dialog will be displayed that allows the selection of the background colour of the view. Tapping on the right of views that do not support text immediately displays the colour selection dialog.
There seems to be a bug or behaviour change with soft keyboards in Android 11, at least on my Pixel 4a, that doesn't manifest itself on my Android 10 device - I haven't tested earlier versions but I think they were OK as well. It seems that with some keyboards if you tap on a view that has text then if you dismiss the Input Dialog by pressing OK or Cancel WITHOUT pressing Done on the keyboard the keyboard will pop up next time you tap a view even if it doesn't have any text to edit and will keep doing so, until you tap on a view with text then press Done before closing the dialog. This seems to happen with Hackers Keyboard and Smart Keyboard Pro (my favourite :() but not with Gboard or Microsoft SwiftKey. Interestingly neither of these replace the Enter key symbol with Done when displaying the Input Dialog.
It is possible to copy colours from one view to another if required, including from portrait to landscape and vice versa. Whenever OK on the colour dialog is pressed that colour is remembered as the last colour used. When LAST is pressed on the colour dialog it is that saved colour that is applied to the view instead of the displayed colour. As the current colour of a view is pre-set in the colour dialog when it is opened it is possible to pick up a colour from a view by pressing OK and then applying that same colour to other views using LAST.
Like the B4A Designer, Basic IDE Designer uses the same magic colour of 0xFFF0F8FF as an indicator to use the default colour for for a view. This is an almost fully desaturated light bluish tone as will be seen in the colour dialog and a view will never be able to be this exact colour. When the default color for a view is indicated by this value the Basic IDE Designer will use white for the colour of the view in the Designer.
Note that although ToggleButton does implement SetText the Designer does not offer the text option for this type of view. This is because this will only set the displayed text of a ToggleButton until the state changes when the text set by SetTextOff/On appropriate to the state of the button will be displayed. Also at runtime, as SetText is not invoked by LoadLayout the ToggleButton will not display any text until its state is changed. For this reason the Designer outputs 'SetChecked(tglname, False)' in the layout. If SetTextOff/On are not invoked then the displayed texts default to ON and OFF.
Portrait and Landscape Layouts
The Designer supports both portrait and landscape layouts. The primary layout management mode is portrait and some menu options are only available in portrait mode. Landscape mode is primarily intended for laying out views that have already been added in portrait mode.
Adding a view is only available in portrait mode and the view is also added to the landscape layout with its text if any. Further changes to the text, colour or parent in either of the layout modes does not propagate to the other. Similarly deleting view from one mode does not delete it from the other layout.
Therefore the recommended way of using the Designer to generate landscape layouts is to layout and test the app in portrait mode and only once the portrait layout is finalised to then complete the landscape layout by copying across the portrait layout by invoking the menu item 'Copy To Landscape', only available in portrait mode. This will copy the existing portrait layout to the landscape layout also ensuring that all the views and their parent, text and colour properties are copied across with them. Once the device is in landscape mode the views sizes and positions can be reset with 'Reset View' to ensure all the views are on screen and then the final sizes and positions of the views in landscape mode determined. Then, as well as the size and position, the colour and text, of a view can also be changed if required.
Saving the Layout
The layout in the Designer can be saved by invoking either the 'Save' or 'Save As' menu options. This will cause three files to be saved to the Layouts folder that when the Basic IDE menu option 'Load Layout' is invoked will be added to the present code in the Basic IDE editor. One file, named 'XXX.glbl' contains global variable declarations that will be prepended to the code and another file, named 'XXX.ptrt' contains a Sub LoadLayout for portrait mode that will be appended to the code. The third file is named 'XXX.land' and contains a Sub LoadLayoutLandscape that will be appended to the code after Sub LoadLayout.
As well as the view names the globals file includes the declaration of file global variables whose final values are set by Sub Loadlayout or Sub LoadLayoutLandscape.
g_width contains the current activity width in pixels
g_height contains the current activity height in pixels
g_scale contains the current activity pixels per layout device Dip
g_hdips contains the layout device activity width in Dips.
g_vdips contains the layout device activity height in Dips.
View sizes and positions in a saved layout are expressed as Dip values for the activity on the device that generated the layout where the width in pixels of the activity divided by the device scale gets the value of the width in Dips. This width Dip value is saved in the layout as g_hdips. Similarly the activity height values in Dips is saved in g_vdips.
Because different devices have different widths when expressed as Dip values for that device, Sub LoadLayout scales the size and position of each view to fit the width of the current device so maintaining the same visual layout across devices. Note that heights are scaled by the same factor as the widths so the layout may be contained within the height of one device but truncated on another depending upon the aspect ratio of the screen of the device. If required view Top values and maybe Heights can be further scaled programmatically to adjust the layout to suit the height of the present device. The scaling works as follows
On the layout device
LayoutWidthDips =LayoutWidthPixels / LayoutDeviceScale
LayoutHeightDips =LayoutHeightPixels / LayoutDeviceScale
All view size and position values are saved as layout device Dip values multiplied by a constant to be determined at runtime to scale the layout width to the current device width.
LayoutViewDips = LayoutValuePixels / LayoutDeviceScale
LayoutWidthDips is saved as a constant in code.
g_hdips = LayoutWidthDips
LayoutHeightDips is saved as a constant in code.
g_vdips = LayoutHeightDips
The runtime calculation for the scaling constant, g_scale is saved as code.
g_scale = g_width / g_hdips
On the current device
Scaling is calculated for the current screen width and the saved LayoutWidthDips
g_width = GetWidth('activity')
g_height = GetHeight('activity')
g_scale = g_width / g_hdips
The value of g_scale is current device pixels per layout device width Dip. So if a layout device Dips value is multiplied by this factor it will scale that value to display horizontally exactly as on the layout device. So saved view LayoutViewDip values are converted in LoadLayout to current screen pixel values.
CurrentValuePixels = LayoutValueDips * g_scale
This works because
CurrentValuePixels = LayoutValueDips * (CurrentWidthPixels / LayoutWidthDips)
CurrentValuePixels =( LayoutValueDips / LayoutWidthDips) * CurrentWidthPixels
Which is equivalent to scaling the width of the current device to the width of the layout device. The same scaling is applied to Height and Top values to maintain the same aspect ratio of the views and the layout on the current device as on the layout device.
If for some reason it is required to treat layout Dips values as current device Dip values then alter the scaling factor calculation in the layout Subs as follows. Get ScreenScale returns the current device density which is approximately the ratio of the size of a Dip on the current screen to the size of a Dip on a standard screen which is 160 pixels per inch.
g_scale = GetScreenScale
It is recommended that further view initialisation is not coded into Sub LoadLayout or Sub LoadLayoutLandscape but is included in another Sub run immediately after the layout Sub. The recommended name for these are Sub AdjustLayout and Sub AdjustLayoutLandscape.
If it is further required to reposition the views vertically to suit the current device it can be done by calculating a scaling factor to apply to view Top values, and possibly also Height values, to fit them within the current display height, at the expense of altering the aspect ratio of the original layout. An array containing all the view names can be obtained from GetAllViews(arrayname) and it can then be iterated to set the new values for each view. The first view should be skipped as it is the Activity so the iterator index should start at one. Views that are children of other views might not need their position and/or height changed and such views can be identified using GetParent.
NewTopPixels = CurrentTopPixels * VerticalScalingFactor
VerticalScalingFactor =( g_height / GetScreenScale) / g_vdips
This works because
VerticalScalingFactor = CurrentHeightDips / LayoutHeightDips
CurrentHeightDips = CurrentHeightPixels / CurrentDeviceScale
VerticalScalingFactor = (CurrentHeightPixels / CurrentDeviceScale) / LayoutHeightDips
The Designer keeps track of the 'generation' level of each view and automatically reorders the addViewname statements in Sub LoadLayout accordingly. Every view that has children will be added before those children to ensure that the parents exist so that their children can be added to them. After the views are added the statements adding menu items are added in the order in which they are vertically positioned in the layout.
Created with the Personal Edition of HelpNDoc: Generate Kindle eBooks with ease
The Basic IDE Launcher program provides a half-way house to making a program a fully independent app. Basic IDE Launcher will, on starting, display a list of programs that are available in the Launcher folder of the Basic IDE folder and on selecting one of them will immediately launch that program.
The Basic IDE Launcher project includes all the modules from the Basic IDE project by relative reference except for Syntax which is not needed. For this reason the Basic IDE and Basic IDE Launcher projects should be installed side by side in a common parent folder on the desktop. Using module references ensures that the latest versions of all the modules, most importantly the Script module, are available to Basic IDE Launcher without manual intervention. Whenever a new version of Basic IDE is compiled and installed on a device then Basic IDE Launcher should also be recompiled and reinstalled. It is recommended to not work on both projects simultaneously - finish testing any modifications to Basic IDE and then recompile and reinstall Basic IDE Launcher as a final step.
Compiling stand-alone programs
Also it is possible to create a stand-alone script program that can be installed on a device and execute independently of the IDE. It requires copying the Basic IDE Launcher project, changing its package name and icon and stripping out the Main module to immediately load and run a script. Only the Main module Sub RunProgram code needs to be changed. It is important to change the package name in Project -> Build Configurations otherwise this new project will overwrite Basic IDE Launcher on the device. The comments below detail the steps in this process.
Copy the Basic IDE Launcher project and rename it as required.
Locate an appropriate icon and set it as the project icon in Project -> Choose Icon
Set an appropriate package name in Project -> BuildConfigurations
Define an appropriate #ApplicationLabel: name in the Main module Module Attributes region.
Copy the target Basic IDE program and any chained and included programs to the Files Manager pane
Modify Sub RunProgram to load and immediately run the program from File.DirAssets. Set Script.ScriptDir to File.DirAssets which might be needed for Chain to locate the next program or #include to locate the included files.
If not needed the permissions and folder checking code in Activity_Create could also be removed together with the checks for GNSSavailability and storage access in Activity_Resume and the unused variables in Process_Globals.
Example code for Sub RunProgram is shown below.
Sub RunProgram
Script.Program = File.ReadString(File.DirAssets, "scriptname.b4s")
Script.FirstRunFlag = True
Script.ScriptDir = File.DirAssets ' For Chain or #include, if used, to locate the next program
StartActivity("Script")
End Sub
Created with the Personal Edition of HelpNDoc: Generate Kindle eBooks with ease
The Script module in the Basic IDE project is an Activity module that implements the GUI for the program running in the BasicLib interpreter. It is started by the Main Activity when a program is required to be run and is passed the source code of that program in the Process_Global Program variable. The Main activity has nothing else to do with the program until the program ends when the Script Activity closes and the Main Activity is resumed.
The Script activity is structured so that a program can deal with normal Android activity lifetime events such as rotation. There is no supported Activity_Create Sub, instead the initial block of code block from the beginning of the program up to the first Sub statement is run when the Activity is created. GetFirstTime returns True the first time the initial code block is run after a program is started. This block of code will be run again whenever the Activity is recreated so this code is the equivalent of Activity_Create. A StateManager is provided to support saving view states on Pause and Resume.
If a Sub Activity_Pause(userclosed) is implemented in the program it will be called when the activity pauses. userclosed will be True if the Back button was pressed.
If a Sub Activity_Resume is implemented in the program it will be called when the activity resumes. As in a B4A program if a non-modal asynchronous function is called in the initial code block then Activity_Resume may be called before the asynchronous callback is invoked.
If a Sub Activity_Keypress(keycode) is implemented in the program it will be called when the activity receives a key press. Keycode will contain the system key code of the key pressed, and may be tested using the Keycode function and constants. Returning True from Activity_Keypress(keycode) causes the activity to consume the keystroke (i.e. not allow the system to continue processing it.)
Sometimes a simple program will be required to complete after just running the initial code block as it will not implement any UI related events. In this case calling the CloseAfterThis keyword anywhere in the initial code block will ensure that it closes at the conclusion of the initial block of code. Without this the program will be left waiting for an event that won"t come and the back button will be needed to close the activity. A program that does use events can end by calling AppClose.
The first part of the code in the Script module deals with handling events raised by the program and provides some facilities to aid debugging that program.
The rest of the code in the Script module implements the B4AScript language extensions that allow B4AScript programs to interact with the device and with the user.
These extensions may be amended and new ones added as required provided they follow two simple rules.
1) All Subs that are to be called from a program must have parameters of type String and return a String value.
2) In order for the Sub to be available to a program it must be specified in a Blib.AddSysCalls(...) statement in the Sub AddNewSysCalls at the end of the Script module.
If a new function that takes parameters has been added to the Script module but invoking it in a B4AScript program causes an "Array: local variable cannot be an array" error then it it likely that step 2 above has been overlooked. Note that calling a non-existent Sub from a program will not always result in an error. In particular if the call has no parameters then the program will assume that the missing Sub is a local variable name and so will not raise an error.
There are many methods in the Script module that require a string containing the name of a view or an array. In code it is very easy to forget this and type the name of a view or array without quotation marks in which case the interpreter will assume it to be a variable. For this reason BasicIDE Designer outputs global variable definitions for variables named as, and containing, the name of each view. This of course does not protect any views added programmatically, such as those in a Custom Dialog, or arrays. To help detect these possible errors most view accesses check that the passed view name exists and raises an alert dialog if not. To prevent similar errors occurring with arrays any array accesses are checked that the passed array name exists and references an array with a length greater than zero as there is never a reason to pass a zero length array to a Script function.
Save/RestoreGlobal and Save/RestoreArray can used to persist program variable values across activity pause and resume. Save/RestoreState will persist view state across activity pause and resume, and between program invocations if required.
Comments in the Script module provide the basis for the documentation for the extensions and will provide further information. It is recommended that any additional extensions are documented in a similar manner. Also the demo program, IdeTest.src, although not the highest art in UI design does exercise a large proportion of the GUI extensions provided.
Use Template.b4s in the Basic IDE project Scripts folder as a starting point for a program because this includes outline Subs for all the events. Write the event code as required. Template.b4s also includes code to save and restore the state of views in the layout on Activity Create and Pause.
The Basic IDE Designer utility can be used to generate the view layout code for a project. It can be used in conjunction with Template.b4s to provide the starting point for a project with the views and events already defined in code so saving a lot of time.
It is recommended that any additions or alterations made to the Script module code be located in separate code regions at the end of the existing code and that they are specified in their own Blib.AddSysCalls(...) statements. Doing this will enable the contributions of several people to be more easily integrated should this be required in the future.
The Script module supports the '#include directive when loading programs to enable modularisation within a program to control the size of individual parts of a program for more convenient editing. See the BasicIDE'include Directive in this help file for more information.
Predefined Objects
The Script module provides provides one each of the following predefined objects for programs to use. Bitmap, Canvas, List, Map, Regex Matcher, Typeface, StringBuilder and Timer. It is entirely possible to reimplement all these as objects to be added like views and addressed by name like views but for the relatively simple programs likely to be written in Basic IDE predefining these objects keeps thing simple.
Map and List can be readily loaded from and saved to arrays whenever required so making the use of a single one of each quite practical.
StringBuilder can be used as many times as needed and reinitialized as required.
Regex Matcher can also be used many times by invoking RegexMatcher or RegexMatcher2 with new text patterns to match.
Bitmap, Canvas and Typeface are not limited to a single use and may be re-initialised as new objects and the new incarnation used as required.
There is a single Timer available. If different time intervals are required then it will be necessary for them to be counted down from a faster Timer frequency e.g counting a one second Sub invocation from a 100mS Timer tick frequency. TheTimer should not be relied on for precision timing, and counting down to a longer interval from a shorter interval will add further imprecision. The Timer is automatically disabled on activity pause and, if it was running when paused, re-enabled on activity resume.
Documentation
Located in the Help folder of the BasicLib project BasicIDEScript.html is a help file that has been produced from comments in the Script.bas file by running UpdateHelp.exe. If changes are made to customise the Script module the file can be re-generated by running UpdateHelp.exe that is located in that same folder. Suitably formatted comments in the program module are then output to BasicIDEScript.html in a simple HTML style.
The formatting of the comments is very simple. Any comment in Script.bas beginning with two apostrophes is output to Basic IDEScript.html.
Any line beginning ''@H:is output underlined in bold with a preceding "Contents" html link to the top of the file and two newlines followed by the line contents. 'H' implies that the use of this is as a as section header.
Any such line beginning ''@N: is output in bold with a preceding newline. 'N' implying a new line.
Any other line beginning ''@ is output in bold.
Any other line beginning with two apostrophes is output as-is and may include further html code if required.
As well as BasicIDEScript.html UpdateHelp.exe generates another two files from Script.bas which are used for syntax highlighting and auto-completion. If changes are made to the Script module then after the changes are saved UpdateHelp.exe should be run .
Basic IDEScriptHighlight.txt is produced by scanning the code of the Script module for AddNewSysCall invocations to create a list of additional function names that is used by the Basic IDE Syntax module to provide syntax highlighting.
Basic IDEScriptAutocomplete.txt is produced by iterating Basic IDEScriptHighlight.txt and searching the Script module comments for the parameter list, if any, for each function. This file is used by the Basic IDE Syntax module for auto-completion.
Finally UpdateHelp.exe generates BasicIDEHelpUpdated.date which contains the date and time value when these help files were generated.
UpdateHelp.exe copies BasicIDEScript.html, BasicIDEScriptAutocomplete.txt, BasicIDEScriptHighlight.txt and BasicIDEHelpUpdated.date to the project Files pane, together with any updated B4AScript or BasicIDE chm and html files, so they can be copied to the device Help folder when BasicIDE is run.
BasicIdeKeywordsAutocomplete.txt, BasicIdeKeywordsHighlight.txt provide the Intellisense for B4AScript keywords. They will probably never need to be updated but are also copied by UpdateHelp.exe to the Files pane of the BasicIDE project.
UpdateHelp.sbp which is also in the Help folder contains the source code for UpdateHelp.exe but this will be of use only to those who have a copy of Basic4ppc, the Windows Mobile/Desktop IDE that was the predecessor and progenitor of the B4X product line.
BasicIDE includes the full set of help and associated data files into DirAssets and updates the contents of the Help folder if the contents of BasicIDEHelpUpdated.date indicate that they are newer than the existing versions.
Script Chaining
The Script module also supports the chaining of programs. That is it allows a program to terminate and immediately invoke another program using the Chain keyword. The chained program has access to any values in the List, Map, StringBuilder and any saved Global arrays or variables so allowing data to be passed between programs.
This facility is not like an B4A program invoking another Activity where the original Activity is saved on a stack, to be returned to when the invoked Activity terminates. Instead a chained program runs in a new instance of the Script Activity and as the original instance has been terminated there is no Activity to return to. Instead a chained program needs to be aware that it is chained and to chain back to the original program if the design of the application requires this. This will involve trapping the Back key-press and taking appropriate action to consume it and chain back to the originating program otherwise the Script Activity will close and return to the IDE.
The Scripts folder of the Basic IDE project contains 'chaintestmain.b4's and 'chaintestslave.b4s' that demonstrate how to chain from the main module of a program to a slave module and return to the main when the Back key is pressed in the slave. These two program also demonstrate saving their state between invocations and passing the state from an instance of aTable in one program to an instance of another Table in a chained program.
Debugging
The IDE implements some minimal debugging capabilities. When running a program a single breakpoint line can be specified and when the program reaches this line it will halt and display the values of the current local and global variables together with any "Print" output from the program as described below. The program may then be single stepped a line at a time, or released to run.
You can always use the good old Msgbox style of debugging as well. Also Print statements, and Msgbox statements with a subject "Print" will not halt the program but will add the message to a message buffer together with a terminating new line. If not empty the contents of this buffer will be displayed when the program ends. It will also be displayed whenever the program breaks or is stepped.
Note that if your program uses Print and the expected output dialog is not displayed when the program ends then the program has probably exited without error by the user pressing the back button which will close the program activity immediately without running the interpreter ended event. In this case detecting the exit in Activity_KeyPress and adding an AppClose statement, without returning True, should force the ended event and display the output.
The message buffer can be cleared by prefixing a message with the string "<clear>", without quotes. Any content following "<clear>" will be added as a new line to the cleared buffer.
The last line printed can be deleted by prefixing a message with the string "<deleted>", without quotes. Any content following "<deleted>" will be added as a new line to the cleared buffer.
More sophisticated debugging can be accomplished by coding it in the program itself with the use of these extension methods which are included in the Script module. The BreakXxxx functions below rely on a modal dialog to halt program execution while debugging. At the moment these are available and their use cause no problems. However if modality problems are experienced DebugSnapShot, AsyncMsgbox and AsyncMsgbox2 are alternatives. As modal dialogs are deprecated in B4A there is a discussion about mitigating the effects of this in the Modal and Non-modal Dialogs topic of this help file.
Blog(message)
Logs the provided message to the B4A IDE Log window. The project must be running in Debug mode in the B4A IDE or with '#BridgeLogger: True' in the Main module and running in Release mode in the B4A IDE.
Break
Halt the program and display the local and global variable values and any Print output. This is the same as setting the break line to the line following this statement. Only one breakpoint can be active at any one time so this overwrites any Break set by BreakAt.
BreakAt(linenumber)
Halt the program before executing the specified line and display the local and global variable values and any Print output. This is the same as setting the break line to the line number specified. Only one breakpoint can be active at any one time. A breakpoint set by BreakAt can be disabled by invoking BreakAt(0).
BreakAndPrint(message)
Halt the program and display the local and global variable values and any Print output. This is the same as calling Break except that message is added to the Print output as though Printed.
BreakAndPrintIf(break, message)
Halt the program and display the local and global variable values and any Print output if boolbreak is True. This is the same as calling BreakIf except that message is added to the Print output as though Printed if break is True.
BreakIf(break)
Halt the program and display the local and global variable values and any Print output if boolbreak is True. This is the same as setting the break line to the line following this statement if break is True otherwise it is set to 0. Only one breakpoint can be active at any one time so this overwrites any Break set by BreakAt.
DebugSnapShot(message, showglobals)
Display the local, and optionally global, variable values and any Print output in a non-modal dialog. If showglobals is false then global variables are not included, this can be useful if there are many globals. message will be prepended to the variable and Print data. Unlike the BreakXxxx functions this is not a modal display and is provided for use if modality problems are experienced. The program will carry on running while the dialog is displayed. The non-modal AsyncMsgbox and AsyncMsgbox2 can also be used for displaying debug data if modality problems are experienced.
Created with the Personal Edition of HelpNDoc: Free help authoring tool
In order to enable programs to be modularised for more convenient editing the #include directive is implemented by the Script module, this is seen by the language interpreter as just another comment. The #include directive must be in lower case and must be followed by a space character and then the name of the script file to be included. No other characters should follow the file name. The filename to include must have the suffix '.b4s'. If this is missing then it will be added automatically before opening the file. Multiple files may be included as required and duplicated files will only be included once.
Included files, as with those used for chaining programs, will be loaded from the folder specified by the Script module ScriptDir global variable which is set to the device project folder by BasicIDE or, typically, File.DirAssets by BacicIDE Launcher
Importantly note that nesting of included files is NOT supported. If an included file has '#include' directives present they will be treated as comments and ignored. The additional complications in supporting nesting were not thought appropriate for the occasional times for when it might be required because the inclusions are all under the control of the programmer who can easily arrange for all the inclusions to be specified at a single level in the main program.
Included files are loaded one after another into the interpreter after the main program file to make one long program. Their line numbering will not therefore be the same when executed as they are when edited in the editor but if an error occurs in included code the line number reported will be adjusted to that expected if the file was being edited. The order of the include directives in the program file is not important because all the included files will be loaded as one long program, regardless of declaration order, before execution begins.
Because the included code is at the end of the main program any code present in the initial code section before the first Sub of the included file will NOT be executed. This means that arrays and global variables cannot be declared by an included program. As included code Subs may need to keep persistent values between invocations the SaveValue and RestoreValue functions are provided for use by included programs as a private replacement for global variables. SaveValue and RestoreValue use the same persistence mechanism as SaveGlobal and RestoreGlobal so care should be taken to avoid a named value clash with an already declared Global variable name. Included Subs can of course directly access arrays and global variables defined by the main program in which they are included.
In the case of an error occurring in an included file the included filename, line number and line of code will be displayed in a dialog if it is not present in the editor window, though it could conceivably be if the main progam was invoked by the 'Run Program ...' menu option. Intended to be useful for debugging chained programs this ability is also useful in debugging included programs.
Importantly note that included programs are ALWAYS loaded from memory, even if present in the editor so confusion might be caused if care is not taken to save any included file edits before running the main program. For this reason the editor always prompts to save a changed program when the Run button is pressed or the 'Run Program ...' menu option is selected.
Created with the Personal Edition of HelpNDoc: Create HTML Help, DOC, PDF and print manuals from 1 single source
In later versions of B4A DoEvents and modal dialogs are deprecated. Erel said, announcing the deprecation of modal dialogs:
The reasons for deprecating DoEvents are:
...
With that said, DoEvents is still there and existing applications will work exactly as before.
However as the Android message loop handling has got more complicated over time the B4A modality mechanism has got increasingly fragile and has had to be modified, and is now strongly deprecated. Except for debugging purposes it is recommended to use only non-modal dialogs in BasicIDE programs. However, as the use of modal dialogs within BasicIDE is so trivial, as long as Erel supports the present simplified (over the original) modality mechanism in B4A then future problems are unlikely as their use here is always to halt further execution of code and not to try to run other events during that halt - which is really what causes the problems.
A corollary of this is that it is probably safe, and convenient, to continue to use the modal dialogs in BasicIDE programs, especially those for ones own use where any problems will merely be an annoyance.
Presently the Script module in Basic IDE uses modal dialogs for three things. The Msgbox and other user interactions, the program debugging break and step implementation and the error and print output dialogs.
User interactions
To avoid the use of the modal versions the Script module implements non-modal versions of all the modal user interaction dialogs, except InputMultiListBox, as well as the asynchronous Sleep function.The non-modal equivalent to InputMultiListBox is AsyncInputMultiMapBox which has the ability to preselect multiple items as opposed to the single item permitted by InputMultiListBox. IDEScriptHelp.html, generated from the Script source code has a section, Async User Interaction Functions, documenting these functions.
Non-modal dialogs need a specific programming style within a B4AScript program as these asynchronous functions return immediately and invoke a callback when complete. Any local program state required for further processing will need to be saved as global values or passed to the non-modal function to be be provided as parameters to the callback method. There are examples for each non-modal dialog in the AsyncTest.b4s script supplied with Basic IDE.
For the time being, for reasons outlined above, it is probably fine to carry on using the modal versions.
Break and Step a Program
At the moment the debugging break and step mechanism relies on the modality of the Msgbox used to display debugging information to prevent a return to the executing program until the user dismisses it. This can be seen in the Java method below which is called to execute each line in the B4AScript program.
private Token executeline(boolean infactor)
{
linenum = currenttokenvalue;
getnexttoken();
if (stepping)
SteppedEvent(); // halts program execution until return from modal notification
if (linenum == breakline)
BreakEvent(); // halts program execution until return from modal notification
Token token = statement(infactor);
return token;
}
A B4AScript program, once it has completed executing the initial code block is event driven and the executeline() method above is part of complex sequence of code that starts with the call from the Script module view event to the BasicLib B4AScript Sub that implements the programs' event code. This complex code takes account of the fact that events can cascade, calling back out to the Script module and then recursively back in to another event Sub in the program with it all eventually unwinding back to the message loop event call that started the process. These recursive calls occur because not all Android view events pass through the message loop and some are a direct call from other events.
To avoid the the use of modal dialogs to halt program execution while debugging some sort of halt and resume mechanism would need to be implemented within the BasicLib library code. To remove the modality from this would be a highly non-trivial task and probably not possible without a complex multi-threaded solution involving locks or mutexes which can't be used on the main thread where the program is running and so is unlikely to ever happen!
However, as long as non-modal dialogs are used within a program for all user interaction, modal dialogs will only be needed while debugging, so any problems, if in fact any do occur, with this simplistic use, will happen during development and then the non-modal DebugSnapshot function is available. Together with the use of AsyncMsgbox and AsyncMsgbox2 this should provide a means of adequately debugging programs, although the programs will no longer be halted until the dialogs are dismissed.
Error and Print Output Dialogs
The error and print output dialogs in Blib_Ended event use Msgbox to cope with the situation where the user closes the program, without error, by pressing the back button. In this situation the the interpreter Blib_Ended event is not raised and so any debug print output is lost. The Blib_Ended event can be raised by adding a check for the Back button in Sub Activity_Keypress, without returning True which would cause the close request to be ignored, and adding an AppClode statement. AppClose will stop the interpreter and run the Blib_Ended event code but if MsgboxAsync is used to display an error or the print output the return to the message loop that occurs in Wait For will let it carry on and close the Activity as the user requested, and with it the dialog that will not then be seen by the developer.
As with breaking and stepping these modal dialogs will only be needed during development. If it becomes a problem changing to MsgboxAsync for the error and print dialogs will only affect the user closing scenario described above. Errors in execution will still cause the error and output dialogs to be displayed as the interpreter will exit because of the error and the Activity closure will not have been requested.
Created with the Personal Edition of HelpNDoc: Easily create Qt Help files
Copyright © <Dates> by <Authors>. All Rights Reserved.