qdex Workshop
Follow these step-by-step instructions to create your first module using images, buttons, animations and simulations. If you haven't already done so, setup Visual Studio and create a qdex account by following the steps here.
By default the error messages in the qdex Play app are generic. If you would like to enable debug messages, open the qdex Play app on your device and navigate to Settings > Manage Account > Manage Options > Display debug messages.
1. Setup Visual Studio and qdex Create
In Visual Studio, navigate to qdex > Update Intellisense. This gives you access to the qdex App template and implements intelligent code completion.
2. Create a New qdex Project
In Visual Studio, navigate to File > New > Project. A window will pop up. In the sidebar of that window, open Installed > Templates > qdex. Change the name of the project, and create a name for the solution. These names will be used to organise the files on your computer; app users will not see these names.
Projects are the individual modules that you will be creating; each module requires its own project. Solutions are collections of modules. Multiple projects can be inside of one solution.
In our example, the name of my project is Quick Start, and the solution is called Test Apps. Click Ok.
3. The qdex App Template
A qdex App template will appear in the main Visual Studio window. It contains two key elements: the module metadata and an example section. The metadata contains all of the fields that your users will see when using your module, including the title, creator, and abstract.
The example section contains a title (<title>) and a paragraph (<p>). There is also a comment above the section (in green text) contained by <!-- and -->. Comments do not affect the output of your code, and can be used to keep the code organised.
If your line numbering is not turned on by default, you can turn it on by navigating to Tools > Options > Text Editor > XML > General and checking the Line numbers box.
4. Change the Content
Let's start by changing some of the default text. Alter the title of the section, and change some of the text in the paragraph.
5. Publish the Module
Now that we have adjusted the content we should try publishing the module. Frequent publishing ensures that you don't spend too much time debugging any errors. You can publish your app by navigating to qdex > Publish, or by using the shortcut Alt + Q. If you are not signed in to your qdex account you will be prompted to do so.
Look at your published module by opening up the qdex Play app on your phone or tablet. Find your module in the list and tap on it to download and open. If you can't find your module in the list, try the following:
- Ensure that you are signed into your qdex account. Navigate to the Settings menu then tap on Log in.
- Refresh the qdex Play library by pulling from the top of the app.
- Ensure that the module published successfully. After publishing a module in Visual Studio an Output window will appear in the bottom of the screen. Ensure that the message says that Publish was successful.
6. Add a photo
We're going to update our module to include a photo. Start by downloading an image, or finding an image on your computer that you would like to use. Open up the image location in Windows Explorer.
Before we can insert the image, we need to put the image in a place where qdex can access it, i.e. in the project folder. You can use the Solution Explorer in Visual Studio to see the project folder. Open it up using View > Solution Explorer. I recommend pinning the Solution Explorer inside Visual Studio using the thumb tack symbol at the top of the Solution Explorer window.
To put the image in the project folder, drag and drop it from Windows Explorer directly into the resources folder.
Now the image is in a location that your qdex module can access.
We can now specify where in the module we would like to include the image. Let's insert the image in between the title and the first paragraph.
Note: You should see a dropdown menu each time you type an open bracket (<) in Visual Studio. This dropdown contains a list of valid tags for that area, as well as an explanation of each tag and its properties. If you don't see the dropdown list, navigate to qdex > Update Intellisense.
We insert an image using the image tag, then specify the source of the image by using the name of the folder and of the image (resources, and qdex logo.png, respectively).
Publish the module again. Open up qdex Play on your mobile device and find your module in the list. When you tap on the module to open it, it will automatically download the update.
7. Add a Button to Show/Hide Content
Next we will add a button that we can use to show/hide some content. I'd like to put this button on a new page, so I'm going to create a new top-level section. Top-level sections are sections that appear directly inside of the document tags, and not inside other tags (e.g. inside of another section, a sectionNoTitle, etc).
I'm going to start by defining the content that I would like to show/hide. I would like to toggle the visibility of a few elements, so I'm going to put them inside of a container (i.e. section, sectionNoTitle, stack, or table). Putting all the elements inside of a container allows me to show/hide the entire container, and not each element individually; this reduces the amount of code we need to write.
Start by creating a stack on the new page that we defined earlier, then put some content inside of it. I'm going to put a paragraph and the same image that we used before. Note that we don't need to add the image to the resources folder again.
I've also added some space above and below my new code. This is to make it easier for me to read; it will not add space in your published module.
Now that the content is defined, I'm going to name my stack and initialise it to be collapsed when the module is opened. We need to name the stack so that we can access it via script to show and hide it.
We initialised the stack to be "collapsed" when it is opened. This means that it will be completely hidden from view, and will take up no space. This is an example of a built-in style.
Let's add a button to toggle the visibility of that collapsed stack. I'm going to name the button so that we can access it from script, and I'm going to define the words that will appear on the button using the content attribute.
I also wrote some lua script inside of the onClick event inside of the button. The onClick event runs each time the button is pressed. I wrote a simple if-elseif statement that checks the content of the button, then toggles the stack accordingly. The first time the button is pressed, the stack will be made visible and the button text will update to say Hide. The second time the button is pressed, the stack will collapse again and the button text will change to Show.
Publish the module again and test out the new button. Remember that it is on the second page of the module. If you get any errors when you press the button, go back to the code and ensure that your lua script is as shown in the image above (words are capitalised where specified, etc).
You may also have noticed that the word elseif has a squiggly pink line underneath it in the above image. That's due to an extension called Visual Studio Spell Checker that I have downloaded. I recommend downloading a spellchecker if you will be writing a lot of content.
8. Animation
Next we will add a simple animation to the third page. The animation will use two sliders to adjust the (x,y) values of a shape on a plot. I will start by creating a third page, and adding an xyPlot to it. Note that I have named the plot and defined the range of the axes. I have also minimized the other two sections to reduce the code on the page (the first two sections will still appear when you publish).
The x- and y-axis are fixed to the range -10 to 10. If we add points outside of those ranges they will not appear on the plot.
I will now create a series inside of the plot to store the points of our animation. Plots can contain multiple series (i.e. sets of data) inside of them. I will also create two sliders and define their ranges and starting values.
Before we define the script to put inside of the sliders, let's discuss what we want the sliders to do. I would like xSlider and ySlider to define the values of the x- and y-coordinates, respectively. Therefore each time the slider is moved, the shape on the plot will need to be updated. I'm going to put this update code inside of a lua function.
Inside of my script I have defined two variables (x and y) to hold the values of the center point of my square. I then defined a function called myShapeFunction that adds the points of the square to the series. Notice how the points are added to the series by first calling the name of the plot (animationPlot), then the name of the series (shape). The Add method is used to add my (x,y) points to the series. Before I added any points however, I used the Clear method to remove any previously plotted points from the series. If I do not use the Clear method first, all of my previously plotted points would be connected to any new points that are drawn. Remove line 54 if you would like to see what this looks like.
Now that the function is defined, the last thing that we need to do is update the x and y values, and call the function each time the sliders are moved. You do both of these tasks inside of the onValueChanged event in each slider.
Each time xSlider is moved, my variable x is updated to the current value of the slider (value). I then call the drawing function to update the drawing on the plot. The same happens with ySlider.
Publish the module again. You should see something similar to the below image when you move the sliders.
Let's update this animation to draw a little more smoothly. Currently the points are drawn on the plot one-by-one. This can result in some lag if the sliders are moved very quickly. You can improve the animation by setting the manual attribute inside of the series to true, and adding an Update method at the end of your animation function.
The manual drawing mode allows you to specify exactly when the plot will be updated. All commands are essentially stored in a buffer, then executed when the update method is called. This improves animation as the plots are updated less often. Publish the module and take a look. The animation will not lag behind the movements of the sliders.
9. Simulation Engine
Let's move onto a more complicated example. One of the powerful features of qdex is it's advanced simulation engine. With a mathematical solver and expression evaluator you have the ability to develop real-time technical simulations. We will use this simulation engine to create a simple sine wave simulation.
Let's start by defining a simulation on a new page. Note that I used a sectionNoTitle instead of a section; the only difference between the two is that the sectionNoTitle construct does not require you to title your section.
I started by giving my simulation a name (mySim) and defining the period (i.e. how often we sample the data that the simulation generates). Our simulation will include a sine wave so I set the period to be reasonably tiny, 0.01 seconds or 100 Hz.
I then want to specify that I would like to use a mathematical solver in my simulation. I will also specify that I would like my simulation elements in series, i.e. sequential.
We need to define how we would like the elements connected, or else they will not be connected at all. Simulation elements can be connected in series, parallel, or in more complicated configurations. I want my simulation elements to be connected one after the other, so I added a series tag.
Now that the structure of my simulation is set up I can begin to add my block diagram elements. I'm going to start with a simple sine wave, which will act as the input signal to the rest of my system. I'm going to define that sine wave to have an amplitude of 1.5.
This example is going to be a simple system that simply outputs the sine wave. To output a simulation to a plot we need to define the plot that the signal is being sent to, and the element that will be sending the signal.
The plot that we need to define is a timePlot. In contrast to the xyPlot that we used in the animation example, a timePlot is a plot where the x-axis is defined as time. Start by adding a timePlot to your page. You can add it above or below the simulation.
Now we can send the signal to the plot using the probe element. We need to tell the probe which plot to send the signal to. This is done by telling the probe the name of the page to look at, then the name of the plot. Give a name to your sectionNoTitle element, then reference it from the ref parameter inside the simulation probe.
We're almost done. If we published now, the page would contain an empty plot and nothing would happen. We need to tell the simulation to start, or to begin running. This can be done with the use of a button, or automatically through a simulation event like onActivePageChanged.
The onActivePageChanged event runs whenever the page loads in the module. You can use it to start a simulation when the page is open, then stop the simulation when the user swipes to a new page. Let's try that now using an if statement.
Publish the module and take a look. You should see a sine wave continuously drawing on a plot.
Let's make the example more interesting by adding a slider that adjusts the amplitude of the sine wave. To do that we need to define a slider, then give a name to some of the element that we need to access (i.e. the sine element). We also need to name the solver, so we can tell the slider exactly where to look.
Now we can set the amplitude of the sine wave to the value of the slider. The amplitude parameter expects a vector, so we need to convert the value element to a vector before assigning it to the amplitude.
Publish the module and take a look on your device. The slider now controls the amplitude of the slider. If you get an error when moving the slider, ensure that the word Amplitude is capitalized and that the name of your simulation, solver and sine wave elements are spelled correctly.
10. MAke it your own
Now that you've been exposed to qdex you are ready to start creating your own modules. Visit the Knowledge Base for code examples and explanations, or head over to the forum if you need help along the way.
When you are ready to share your modules, read through Distributing Modules on the Knowledge Base.
Happy authoring!