In this entry, we will learn how to create user interfaces or UIs, which can adjust to fit different screen sizes. We will also look at how to use the data that we can obtain from different elements of the UI.
Typical elements of a UI
To create a UI, there are a few elements that will help us to achieve a comprehensive and functional interface, such as buttons and text entry boxes. To design the user interface, we need to write the corresponding code for each element, adjusting the parameters to suit our requirements. Here is the code for some of the most interesting elements used to create interfaces:
Button:
1 2 3 |
var nombre = ui.addButton("texto", posX, posY, ancho, alto).onClick(function() { // The code for the function }); |
Checkbox: (mode can be true or false, which determines whether the box will be ticked or not)
1 2 |
var nombre = ui.addCheckbox("texto", posX, posY, ancho, alto, modo).onChange(function(val) { }); |
Text: Prints a text on the screen:
1 |
var nombre = ui.addText("texto", posX, posY, ancho, alto); |
Slider: Creates a bar to be used as a slider to give us a value between the minimum and maximum that we set.
1 2 3 |
var nombre = ui.addSlider(posX, posY, ancho, alto, min, max).onChange(function(val) { // The code for the function }); |
Input: Creates a text box for entering text.
1 2 3 |
var nombre = ui.addInput("Texto",posX, posY, ancho, alto).onChange(function(val) { // The code for the function }); |
Toggle could be used for the checkbox, as it creates a button to change the status, meaning a switch or “sliding” button, but without being able to add text to the button. This means that a text element is needed to indicate what the switch does. The basic functionality of the three elements is the same, but we will use one or the other, depending on the features of the application or our preferences. To see how the rest of the functions are written, we can use the quick reference and search within the UI (which could cause errors if not updated) or within the examples. A good practice for creating interfaces is to fix the height of the elements, so that we know where to place the next element. For example, if the height of an element is h = 150, we can place the next element at a slightly greater distance to the end, changing position y of the next element by the height of the first element plus a certain margin.
Creating UIs that adapt to different screen sizes
As we can access the terminal data which is being used to execute the code, we can use it to generate interfaces that can be adapted to different types of screen. To generate the code, we can use the ui.screenWidth and ui.screenHeightfunctions, which respectively return the width and height of the screen. The code that can be used to generate this kind of program is:
1 2 3 |
var margin = 10; var w = ui.screenWidth - 2 * margin; var h = 150; |
First we set a margin to separate the elements of the UI from the vertical border, and we also set a margin between the different elements, so that they don´t overlap. Depending on the number and the size of the elements included in the interface, the text that they contain might not be displayed correctly. So it´s better to fix the height (h in the previous code) of the elements than to use adaptable heights (in the previous code, we made the width of the elements adaptable to different screen sizes). If we make the position on “axis X” of the elements the margin, as we have set w = ui.screenWidth – 2 * margin, the elements will stop at the “end” of the screen with the same margin on both sides, which results in an interface that appears to have been carefully designed.
Variables in Protocoder
Variables in Protocoder are different to the Arduino language, in that we don´t have to determine the type of data stored in the variable. For example, in Arduino, when we want to save a whole number, we would use:
1 |
int margin = 10; |
And in Protocoder:
1 |
var margin = 10; |
This enables us to avoid errors caused by compatibility issues with the data that we enter and the data that the variable expects to receive.
Functions in Protocoder
To generate a function in Protocoder, we use a code that looks something like this:
1 2 3 |
function nombre_funcion(variable1,variable2){ // The code for the function } |
For example a function that displays a toast, a hovering Android message, would be like this:
1 2 3 |
function showToast (string){ showToast(string); } |
With showToast being the name of the function and string being the parameter that must be passed to the function. For example, to use this function we come use this line of code:
1 2 3 |
showToast("El curso de programación para makers con Arduino y Protocoder mola!");{ // The Programming with Arduino and Protocoder for makers course is cool! } |
Creating the UI and programming an application
Here we will generate an application that simulates a screen for users to access an interface, which requests a username and password after hitting a button. We will also include a checkbox that will change the transparency of an image in order to learn how to use it ,and a button with an image that leads to an info pop-up. First, we will change the background colour and include the code in the previous section, which will help us to create the application:
1 2 3 4 5 |
ui.backgroundColor(55, 155, 155); var margin = 10; var w = ui.screenWidth - 2 * margin; var h = 150; |
Before we start to include elements, it´s worth taking a minute to reflect or even to make a sketch of the elements that we will include and where we will place them. In this case, we will include two text inputs and a button to manage the username and password, a checkbox and an image, and the button to display the pop-up.
Password manager
First we create the variables for storing the data that the user enters on the screen and the correct username and password:
1 2 3 4 |
var userName = ""; var password = ""; var rightUser = "bq"; var rightPass = "bq"; |
Now we generate the codes for the two text inputs:
1 2 3 4 5 6 7 |
var userText = ui.addInput("Username",margin,margin,w,h).onChange(function(val){ userName = val; }); var pass = ui.addInput("Password", margin, h + margin, w, h).onChange(function(val){ password = val; }); |
In the element pass, we have used position Y of the element as h + margin, due to the fact that the size of the previous element is equal to h and we need to separate them. Now we will use 2*h + margin, 3*h +margin, etc. We use the val variable in both elements to store userName or password in the variable, which is entered on the keyboard. To finish the password manager, we finally include a button to check that the username and password are correct:
1 2 3 4 5 6 7 8 9 10 11 12 |
ui.addButton("Log in",margin,2* h +margin,w,h).onClick(function() { username = userText; if (userName == rightUser && password == rightPass){ showToast("Right username & password"); }else if(userName == rightUser && password != rightPass){ showToast("Wrong password"); }else if (userName != rightUser && password == rightPass){ ui.toast("Wrong username"); }else{ showToast("Wrong username & password"); } }); |
Checkbox and transparency change in elements
The checkbox is an element which allows options to be ticked or unticked. They are usually used to change a condition, for example, to switch a light on or off, or to select or unselect an option. In this Protocoder program, we will use the checkbox to change the transparency, alpha, of an image but it can be done with practically any element, view. First we create the checkbox and assign the name alpha to it:
1 2 3 4 5 6 7 |
var aplha = ui.addCheckbox("Change Alpha Logo",margin,3.5* h +margin,w,h, false).onChange(function(val) { if (val){ img.setAlpha(0); }else{ img.setAlpha(255); } }); |
The checkbox is usually accompanied by the option we are going to change, which is represented as text in quotation marks at the beginning of the parameters. The val value returned by the function will be true or false, depending on whether or not the boxes are ticked. To modify the transparency of an element, or view, we use this syntax:
1 |
nombreView.setAlpha(número) |
To change the transparency of an element, we need to change the nombreView for the variable name we have assigned to the visual element and we also change número to a number between 0 and 255, with 0 being transparent and 255 being opaque.
Button with image and Pop-up
Finally, we will include a button with an image, which is included in the downloads, to be used to display information via the dialogue box. We will need to upload the image to the upload box on the bottom right,, move it to the Protocoder folder on Android or connect to our terminal via FTP (this can be enabled in the Protocoder settings). Once the image has been uploaded, we will write the code to include the button with the image:
1 2 3 |
var imgBtn = ui.addImageButton(w/2 + w/4,9* h +margin,2*imgSize,2*imgSize,"about_icon.png").onClick(function() { }); |
Where the parameters: position X, position Y, size X, size Y, name of the image, respectively. The program is the same as for any button, so when you press it, it will execute the code written in its definition. To create a pop-up window feature, we will use the following code:
1 2 3 |
ui.popupInfo("Título", "Texto", "Respuesta_si", "Respuesta_no", function(e) { // The code for the function }); |
This time, we are using this code:
1 2 3 4 5 6 7 8 |
ui.popupInfo("About", "Protocoder rocks?", "Yes", "No", function(e) { console.log("you pressed " + e); if (e){ showToast("You are right!"); }else{ showToast("Wrooong!"); } }); |
As we can know that the option pressed can work with the answer, it will be true or false, if Respuesta_si o Respuesta_no has been pressed.