3.3. Graphical Dialer¶
The goal of this example is to create a simple graphical application on which the user can initiate a call on the selected speech unit to the supplied number.
3.3.1. UI mockup¶
3.3.2. Plan¶
In order to send actions to the turret we need to connect to it first. The C# example solution has this functionality, so building upon that I propose that after a successful connection we open a new window showing the dialer.
3.3.3. Creating and designing the new window¶
In Visual Studio we can add a new window by selecting Project/Add Windows Form..., entering a name for it eg. GuiDialer.cs.
Now we can use the designer to create the user interface or do it from the source code. I decided to use the designer; in a 3x2 TableLayoutPanel created this nifty little interface:
3.3.4. Showing the window after connection¶
To show the window we will need to extend the ThriftDemo class with a new member.
21 22 23 24 25 | public partial class ThriftDemo : Form
{
private GuiDialer Dialer;
private TurretRequestService.Client Client;
|
The buttonConnectToTurret_Click method handles clicking the Connect button. Creating and showing our form there should just do the trick.
Since we are planning on requesting an action we should pass the Client to the GuiDialer object as well.
143 144 145 146 147 148 149 150 151 152 153 | textBoxResponse.AppendText("Server exception: " + ex + "\n Server did not start. \n");
}
try
{
Transport = new TSocket(textBoxIpAddr.Text, 9007);
Transport.Open();
Protocol = new TBinaryProtocol(new TFramedTransport(Transport));
Client = new TurretRequestService.Client(Protocol);
Dialer = new GuiDialer(Client);
Dialer.Show();
|
13 14 15 16 17 18 19 20 21 | public partial class GuiDialer : Form
{
private TurretRequestService.Client Client;
public GuiDialer(TurretRequestService.Client client)
{
Client = client;
InitializeComponent();
}
|
3.3.5. Handling dial button click¶
In the designer, clicking on a UI element twice automatically adds a click event handler to our class. We could do this manually as well, by adding a new method to our class and setting the Click property of the button to a System.EventHandler which calls our function.
When creating the interface the button was named dialerButton so upon double-clicking on it designer creates a dialerButton_Click method in the GuiDialer class. The speech unit selector was named suSelector and the editable textbox for the number was named numberTextBox.
Upon inspecting the API we can find a method TurretApi.TurretRequestService.makeCall which needs two parameters: the speech unit ID and the number to dial. Conveniently we have fields on the UI hopefully with just the right information and could make the call by calling the makeCall method on our client.
private void dialerButton_Click(object sender, EventArgs e)
{
Client.makeCall((short)suSelector.Value, numberTextBox.Text);
}
Now this is awfully optimistic so some form of failure handling would be desirable.
The speech unit selector is limited to the values 1-4 and (for now) we can not check for the available speech units.
Dialing with the number field empty is unnecessary.
There is also a situation of making a call from a logged out turret so we should check that as well.
Moreover in the API reference we can read:
Requests the turret to dial the given number from the specified speech unit. TurretApi.TurretApiException is thrown if speech unit id is invalid, the speech unit is busy or there is no free line to initiate a call from.
So catching those exceptions we get the following method:
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | private void dialerButton_Click(object sender, EventArgs e)
{
string number = numberTextBox.Text;
if (number.Length == 0)
{
return;
}
if (Client.getLoginState() != TurretState.Login)
{
MessageBox.Show("Turret is not logged in");
return;
}
try
{
Client.makeCall((short)suSelector.Value, number);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
|