Tutorial 01: Getting started (NETMF) - osre77/Tinkr GitHub Wiki
Scope of this tutorial
This tutorial will show how to:
- Create a new plain NETMF project using Tinkr
- Initialize Tinkr
- Calibrate the touch screen
- Create and show a simple form with a label and a button
- React to the button tap event
- Showing a prompt from a button tap event
Prerequisites
This tutorial assumes that you have installed Visual Studio 2012 (2010 should work as well) and the NETMF SKD as well as any SDK required to use your hardware. Make sure you have a matching firmware on your board and the display is configured correctly.
Hardware requirements
This tutorial should work on any hardware that is power full enough to run GUI applications on a native LCD display. The minimum screen resolution is 320x240. Touch is required. This sample runs in Emulator without any problems. The Hardware used for creation of this tutorial:
- GHI Cobra II (G120)
- GHI TE35 touch display
Create the project
1. Start Visual Studio and create a new project
Select a 'Console Application' project in the category 'Micro Framework', enter the name of your project and confirm with 'Ok' button. The new solution should like this in the Solution Explorer:
2. Open the project properties by double clicking on the 'Properties' item in Solution Explorer.
3. Switch to correct Target framework version
The default in VS 2012 is currently 4.3. If your device runs for example on 4.2, you have to change this (prebuilt Tinkr dll's are targeted at 4.2).
4. Add references to Tinkr dll's
Right click on the 'References' entry in Solution Explorer and select 'Add Reference...'. If you have installed Tinkr by the installer, the dll's will show up on the '.NET' tab. If you have downloaded the prebuilt dll's or if you built Tinkr on your own, you have to look for the dll's using the 'Browse' tab.
For this tutorial the following Tinkr dll's are needed:
- Skewworks.NETMF.Core.dll
- Skewworks.NETMF.Controls.dll
- Skewworks.NETMF.Resources.dll
- Skewworks.NETMF.Modal.dll
To be able to reboot the device after Touch screen calibration the following NETMF dll from the '.NET' tab is also needed:
- Microsoft.SPOT.Hardware
5. Open the 'Program.cs' by double clicking it in Solution Explorer
6. Remove the initial code from the Main() method
public static void Main()
{
}
Adding code step by step
You can pull the whole example from the repository:
´Tinkr/Tinkr2/Tutorials/T01GettingStartedNetmf`
It might be necessary to remove and add the references to the Tinkr dll's when you download the whole project.
Go to the end of this page to see the whole code of this tutorial.
1. Add the needed namespaces to the top of the file
using System.Threading;
using Microsoft.SPOT.Hardware;
using Skewworks.NETMF;
using Skewworks.NETMF.Controls;
using Skewworks.NETMF.Resources;
using Skewworks.NETMF.Modal;
1.1 Add a using statement for the Button class to avoid an ambiguous reference
Since there is also a class called Button in the namespace Microsoft.SPOT.Hardware, we define the Tinkr Button explicitly.
using Button = Skewworks.NETMF.Controls.Button;
2. Initialize Tinkr
Add the following code to the Main method:
Core.Initialize(TouchCollection.NativeSingleTouch);
3. Calibrate touch screen if necessary
Add the following code to the Main method:
CalibrateTouch();
Now add an additional method to the Program class:
private static void CalibrateTouch()
{
}
All code snippets in steps 3.x goes into the CalibrateTouch method.
3.1 Check if LCD is already calibrated
if (SettingsManager.LCD == null)
{
// No calibration found
// steps 3.2 to 3.4 goes here
}
else
{
// calibration found -> restore it
// step 3.5 goes here
}
3.2 Start calibration
SettingsManager.CalibrateTouch(new CalibrationConfiguration());
3.3 Wait for settings to save
Calibration is saved using ExtendedWeakReference (EWR) into the onborad flash memory.
Thread.Sleep(100);
3.4 Restart device
PowerState.RebootDevice(true);
3.5 Restore existing calibration
SettingsManager.RestoreLCDCalibration();
4. Create and show a simple form
Add the following code to the Main method:
SetupMainForm();
Now add an additional method to the Program class:
private static void SetupMainForm()
{
}
4.1 Create the main form
var frm = new Form("mainForm", Colors.DarkGray);
"mainForm": Every control in Tinkr has a name. Colors.DarkGray: Every Form has also a background color. The width and height of a form is automatically set to screen size.
4.2 Create a simple label
var label = new Label("label", "Tutorial 01: Getting started (NETMF)", Fonts.Droid12Bold, 10, 10);
"label": The name of the label. "Tutorial...": Text of the label. Fonts.Droid12Bold: The font used to render the label. 10, 10: The top left x and y coordinates of the label. The size of the label is automatically calculated acoording to the content when using this constructor.
4.3 Add the label to the form
frm.AddChild(label);
Every control needs to be added to the form. Every control derived from Container can hold controls. These contols are rendered recursively.
4.4 Create a button
var button = new Button("button", "Show prompt", Fonts.Droid11, 10, 40);
"button": The name of the button. "Show prompt": The content text of the button. Fonts.Droid11: The font used to render the content text. 10, 40: The top left x and y coordinates of the button. The size of the button is automatically calculated according to the content when using this constructor.
4.5 Add a tap handler to the button
button.Tap += ButtonOnTap;
The tap event is like the click event in a desktop application. But since NETMF devices usually have a touch screen it's called tap.
Create a new method in Program:
private static void ButtonOnTap(object sender, point point1)
{
}
4.6 Add the button to the form
frm.AddChild(button);
4.7 Set the form as the active container.
Core.ActiveContainer = frm;
The active container is rendered and all touch events are directed to it.
5. Open a prompt (MessageBox) when the button is taped
The following code snippets goes into the ButtonOnTap method.
5.1 Spawn a new thread for the prompt
new Thread(() =>
{
/// Step 5.2 goes here
}).Start(); // don't forget to start the thread!
Because new touch events can only be processed when the last one (like this tap) has finished, we need to show the prompt asynchrony. To do so we start a new thread that does nothing else than displaying the prompt. If the prompt is shown directly from a touch event handler, the buttons in the prompt would not respond!
5.2 Show the prompt
Prompt.Show("My 1st prompt", "Proudly presented by Tinkr", Fonts.Droid9, Fonts.Droid11);
A prompt is a modal window, that is rendered above the ActiveContainer and will receive all touch events as long as it's open.
"My 1st prompt": Title of the prompt. "Proudly pr...": Message of the prompt. Fonts.Droid9: The font used to render the title of the prompt Fonts.Droid11: The font used to render the message of the prompt
Run the program
By default a new created program is started in the Emulator. Please be aware that the performance of the Emulator is usually quite poor. Before the 1st click is accepted it can take several seconds.
When starting the program for the 1st time, it will automatically start the touch calibration. This will also happen in Emulator.
After the calibration the Emulator will automatically exit. Start the program again to continue.
If the program runs on a device, it will reboot automatically.
The program will look as follows:
Run program on device
Connect your device and open the project properties by double clicking the 'Properties' element in the Solution Explorer.
Open the '.NET Micro Framework' tab and select the Transport and then the Device. If the program is started, the it is 1st deployed to the device and then started.
The complete code of Program.cs
using System;
using Microsoft.SPOT;
// Step 1: Add needed namespaces
using System.Threading;
using Microsoft.SPOT.Hardware;
using Skewworks.NETMF;
using Skewworks.NETMF.Controls;
using Skewworks.NETMF.Resources;
using Skewworks.NETMF.Modal;
// Step 1.1: Since there is also class called Button in the namespace Microsoft.SPOT.Hardware, we define the Tinkr Button explicitly
using Button = Skewworks.NETMF.Controls.Button;
namespace T01GettingStartedNetmf
{
public class Program
{
public static void Main()
{
// Step 2: Initialize Tinkr
Core.Initialize(TouchCollection.NativeSingleTouch);
// Step 3: Calibrate touch screen if necessary
CalibrateTouch();
// Step 4: Create and show a simple form
SetupMainForm();
}
private static void CalibrateTouch()
{
// Step 3.1: Check if LCD is already calibrated
if (SettingsManager.LCD == null)
{
// No calibration found
// Step 3.2: calibrate now
SettingsManager.CalibrateTouch(new CalibrationConfiguration());
// Step 3.3: Wait for settings to save
// Calibration is saved using ExtendedWeakReference (EWR) into the onborad flash memory
Thread.Sleep(100);
// Step 3.4: Restart device
PowerState.RebootDevice(true);
}
else
{
// calibration found -> restore it
// Step 3.5: Restore existing calibration
SettingsManager.RestoreLCDCalibration();
}
}
private static void SetupMainForm()
{
// Step 4.1: Create the main form
// "mainForm": Every control in Tinkr has a name
// Colors.DarkGray: Every Form has also a background color
// The width and height of a form is automatically set to screen size
var frm = new Form("mainForm", Colors.DarkGray);
// Step 4.2: Create a simple label
// "label": The name of the label
// "Tutorial...": Text of the label
// Fonts.Droid12Bold: The font used to render the label
// 10, 10: The top left x and y coordinates of the label
// The size of the label is automatically calculated acoording to the content when using this constructor
var label = new Label("label", "Tutorial 01: Getting started (NETMF)", Fonts.Droid12Bold, 10, 10);
// Step 4.3: Add the label to the form
// Every control needs to be added to the form.
// Every control derived from Container can hold controls
// These contols are rendered recursively
frm.AddChild(label);
// Step 4.4: Create a button
// "button": The name of the button
// "Show prompt": The content text of the button
// Fonts.Droid11: The font used to render the content text
// 10, 40: The top left x and y coordinates of the button
// The size of the button is automatically calculated according to the content when using this constructor
var button = new Button("button", "Show prompt", Fonts.Droid11, 10, 40);
// Step 4.5: Add a tap handler to the button
// The tap event is like the click event in a desktop application.
// But since NETMF devices usually have a touch screen it's called tap.
button.Tap += ButtonOnTap;
// Step 4.6: Add the button to the form
frm.AddChild(button);
// Step 4.7: Set the form as the active container.
// The active container is rendered and all touch events are directed to it.
Core.ActiveContainer = frm;
}
private static void ButtonOnTap(object sender, point point1)
{
// Step 5: Open a prompt (MessageBox) when the button is taped
// Step 5.1: Spawn a new thread for the prompt
// Because new touch events can only be processed when the last one (like this tap) has finished,
// we need to show the prompt asynchrony.
// To do so we start a new thread that does nothing else than displaying the prompt.
// If the prompt is shown directly from a touch event handler, the buttons in the prompt would not respond!
new Thread(() =>
{
// Step 5.1: Show the prompt
// A prompt is a modal window, that is rendered above the ActiveContainer
// and will receive all touch events as long as it's open.
// "My 1st prompt": Title of the prompt
// "Proudly pr...": Message of the prompt
// Fonts.Droid9: The font used to render the title of the prompt
// Fonts.Droid11: The font used to render the message of the prompt
Prompt.Show("My 1st prompt", "Proudly presented by Tinkr", Fonts.Droid9, Fonts.Droid11);
}).Start(); // don't forget to start the thread!
}
}
}