iNetwork Tutorial #3.2: Drawing Board 2.0

INetwork.Tutorial3-2 History

Hide minor edits - Show changes to output

August 29, 2012, at 03:53 PM by 136.159.18.232 -
Added line 69:
August 22, 2012, at 02:20 PM by 136.159.18.232 -
Changed lines 42-43 from:
'''Reminder:''' The ''executable file'', called ''DrawClientWithTelepointer'', for this example has been provided when the iNetwork Toolkit was installed. You will find this file in a folder called '''Tutorial Examples''' within the iNetwork Toolkit directory. Be sure to extract the file before opening it.
to:
'''Reminder:''' The ''executable file'', called ''DrawClient'', for this example has been provided in a folder named ''Tutotrial3.2'' when the toolkit was installed. You will find this in the ''Tutorial Examples'' folder within the ''GroupLab iNetwork Toolkit'' directory. Be sure to extract the files before opening them.
August 22, 2012, at 11:46 AM by 136.159.18.232 -
Deleted lines 14-22:
>>yellowbox<<

%lfloat% Attach:warning.gif
'+'''WARNING! AVERTISSEMENT! ¡CUIDADO!'''+' \\
'+'''This project page is under construction!'''+'

>><<
August 02, 2012, at 10:59 AM by 136.159.18.232 -
Changed line 123 from:
# %item value=4% Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
to:
# %item value=4% In the '''OnMessageReceived''' event handler method add the following cases: \\
Changed line 152 from:
# The brush color is currently a ''string'' object and needs to be available as a ''Color'' object. Convert the brush color then call the '''CreateTelepointer''' method. \\
to:
# The brush color is currently a ''string'' object and needs to be a ''Color'' object in order to be of use. Convert the brush color then call the '''CreateTelepointer''' method. \\
Changed line 206 from:
# Within ''delegate()'' [''line 6, step 14''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
to:
# Within ''delegate()'' [''line 6, step 14''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepointershould appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
Changed line 344 from:
# %item value=3% Only three message cases need to be added to the '''OnConnectionMessage''' event handler method. \\
to:
# %item value=3% Added the following message cases to the '''OnConnectionMessage''' event handler method. \\
August 01, 2012, at 11:50 AM by 136.159.18.232 -
Changed lines 394-395 from:
'''Note:''' Running this tutorial is similar to that of the ''Chat'' tutorial example. First, right click on ''DrawServer'' in '''Solution Explorer''' and select '''Set as StartUp Project'''. This will guarantee that the server will run before the client. In order to run and or add instances of the client simply right click on ''DrawClient'' in the '''Solution Explorer'''. Select '''Debug''' then '''Start a new instance'''.
to:
'''Reminder:''' Right click on ''DrawServer'' in '''Solution Explorer''' and select '''Set as StartUp Project'''. Now run the server then right click on ''DrawClient'' in the '''Solution Explorer''' and select '''Debug''' then '''Start a new instance''' to run/add a new instance of the client.
July 30, 2012, at 04:40 PM by 136.159.18.232 -
Changed lines 376-377 from:
int clientID1 = msg.GetIntField("client");
string fill1 = msg.GetStringField("fill");
to:
int clientID = msg.GetIntField("client");
string fill = msg.GetStringField("fill");
Changed line 382 from:
this._clientIDs[clientID1] = fill1;
to:
this._clientIDs[clientID] = fill;
July 30, 2012, at 04:18 PM by 136.159.18.232 -
Changed line 344 from:
# %item value=3% Only three message cases need to be added to the '''OnConnectionMessage''' event handler method, which is in the '''''Main Body''''' region. \\
to:
# %item value=3% Only three message cases need to be added to the '''OnConnectionMessage''' event handler method. \\
July 30, 2012, at 03:36 PM by 136.159.18.232 -
Added lines 342-343:
Note: This region is called ''Drawing'' within the executable files provided during installation.
July 30, 2012, at 03:36 PM by 136.159.18.232 -
Changed lines 311-314 from:
# Create a dictionary in the '''''Class Instance Variables''''' region that will contain client ID's and color codes. \\
to:
>>whitebox<<

!!!!!Class Instance Variables Region
# Create a dictionary
that will contain client ID's and color codes. \\
Changed lines 319-325 from:
# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. This allows the client to create a telepointer for each client that was already connected before it. Within the '''''Initialization''''' region find this event handler method and ad the following code: \\
to:
>><<


>>whitebox<<

!!!!!Initialization Region
# %item value=2% Before calling the
'''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. This allows the client to create a telepointer for each client that was already connected before it. \\
Changed lines 336-342 from:
# Only three message cases need to be added to the '''OnConnectionMessage''' event handler method, which is in the '''''Main Body''''' region. \\
to:
>><<


>>whitebox<<

!!!!!Main Body Region
# %item value=3%
Only three message cases need to be added to the '''OnConnectionMessage''' event handler method, which is in the '''''Main Body''''' region. \\
Added lines 384-385:
>><<
July 30, 2012, at 03:23 PM by 136.159.18.232 -
Changed line 102 from:
# In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID. \\
to:
# %item value=2% In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID. \\
Changed line 123 from:
# Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
to:
# %item value=4% Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
July 30, 2012, at 03:23 PM by 136.159.18.232 -
Changed lines 84-87 from:
# Begin by declaring the following within the '''''Class Instance Variables''''' region: \\
to:
>>whitebox<<

!!!!!Class Instance Variables Region
# Begin by declaring
the following: \\
Changed lines 96-102 from:
# In the '''OnConnectionDiscovered''' event handler method in the '''''Initialization''''' region randomly generate an integer and assign it to be the client's ID. \\
to:
>><<


>>whitebox<<

!!!!!Initialization Region
#
In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID. \\
Changed lines 115-123 from:
# Open the '''''Main Body''''' region. Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
to:
>><<


>>whitebox<<

!!!!!Main Body Region
Note: This region is called
''Drawing'' within the executable files provided during installation.

#
Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
Added lines 301-302:
>><<
July 30, 2012, at 10:21 AM by 136.159.18.232 -
Changed line 84 from:
# Begin by declaring the following class instance variables: \\
to:
# Begin by declaring the following within the '''''Class Instance Variables''''' region: \\
Changed line 93 from:
# In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID. \\
to:
# In the '''OnConnectionDiscovered''' event handler method in the '''''Initialization''''' region randomly generate an integer and assign it to be the client's ID. \\
Changed line 106 from:
# Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
to:
# Open the '''''Main Body''''' region. Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
Changed line 292 from:
# Create a dictionary that will contain client ID's and color codes. \\
to:
# Create a dictionary in the '''''Class Instance Variables''''' region that will contain client ID's and color codes. \\
Changed line 297 from:
# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. This allows the client to create a telepointer for each client that was already connected before it. \\
to:
# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. This allows the client to create a telepointer for each client that was already connected before it. Within the '''''Initialization''''' region find this event handler method and ad the following code: \\
Changed line 308 from:
# Only three message cases need to be added to the '''OnConnectionMessage''' event handler method. \\
to:
# Only three message cases need to be added to the '''OnConnectionMessage''' event handler method, which is in the '''''Main Body''''' region. \\
July 26, 2012, at 09:28 AM by 136.159.18.232 -
Changed lines 356-361 from:
to:
'''Note:''' Running this tutorial is similar to that of the ''Chat'' tutorial example. First, right click on ''DrawServer'' in '''Solution Explorer''' and select '''Set as StartUp Project'''. This will guarantee that the server will run before the client. In order to run and or add instances of the client simply right click on ''DrawClient'' in the '''Solution Explorer'''. Select '''Debug''' then '''Start a new instance'''.

You should get something like the following: \\
\\
Attach:drawTelepointerResult.jpg
July 26, 2012, at 09:18 AM by 136.159.18.232 -
Changed lines 51-56 from:
!!!!Download
As this is an extended version
, we recommend that you try building the Drawing Board 1.0 application first, then try building this extension with the given instructions below before downloading the executable file provided.

The ''Drawing Board 2.0'' tutorial Example executable
file:
* [[Attach:drawFinalv2.zip | Drawing Board 2.0]]
to:
'''Reminder:''' The ''executable file'', called ''DrawClientWithTelepointer'', for this example has been provided when the iNetwork Toolkit was installed. You will find this file in a folder called '''Tutorial Examples''' within the iNetwork Toolkit directory. Be sure to extract the file before opening it.
July 20, 2012, at 11:20 AM by 136.159.18.232 -
Changed lines 2-3 from:
to:
!!!!!![[Toolkits/iNetwork | back to '''iNetwork''']]
Deleted lines 34-35:
!!!!!![[Toolkits/iNetwork | back to '''iNetwork''']]
July 13, 2012, at 02:07 PM by 136.159.18.232 -
Changed line 194 from:
# Within ''delegate()'' [''line 6, step 13''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
to:
# Within ''delegate()'' [''line 6, step 14''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
Changed line 200 from:
# Now within that ''if'' statement [''line 2, step 14''], create a ''SolidBrushColor'' object using the fill input to assign the color and a new ''Ellipse'' object. \\
to:
# Now within that ''if'' statement [''line 2, step 15''], create a ''SolidBrushColor'' object using the fill input to assign the color and a new ''Ellipse'' object. \\
Changed line 232 from:
# In the ''delegate()'' section [''line 6, step 18''], add an ''if'' statement that checks that ''_telepointers'' contains the client ID and that the ID given as input does not belong to the current client. \\
to:
# In the ''delegate()'' section [''line 6, step 19''], add an ''if'' statement that checks that ''_telepointers'' contains the client ID and that the ID given as input does not belong to the current client. \\
Changed line 238 from:
# Within the above conditional statement [''line 2, step 19''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. The off set values ('x-5' and 'y+25') compensate for the placement of the ''_extraCanvas'' that was added in the form. It ensures that the center of the telepointer is where the tip of the mouse cursor would be. \\
to:
# Within the above conditional statement [''line 2, step 20''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. The off set values ('x-5' and 'y+25') compensate for the placement of the ''_extraCanvas'' that was added in the form. It ensures that the center of the telepointer is where the tip of the mouse cursor would be. \\
Changed line 257 from:
# Again, within ''delegate()'' [''line 6, step 21''], create a ''SolidColorBrush'' object, grab the appropriate telepointer ellipse and change its fill color. \\
to:
# Again, within ''delegate()'' [''line 6, step 22''], create a ''SolidColorBrush'' object, grab the appropriate telepointer ellipse and change its fill color. \\
July 13, 2012, at 02:05 PM by 136.159.18.232 -
Changed line 127 from:
# Before anything else, declare the following instance variables before the ''if'' statement in the '''OnMessageReceived''' event handler method: \\
to:
# Before anything else, declare the following instance variables before the ''if'' statement in the '''OnMessageReceived''' event handler method: \\
July 13, 2012, at 02:00 PM by 136.159.18.232 -
Added lines 127-133:
# Before anything else, declare the following instance variables before the ''if'' statement in the '''OnMessageReceived''' event handler method: \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID;
string colorCode;
Color colorFill;
=]
Changed lines 136-137 from:
int clientID1 = msg.GetIntField("client");
string colorcode1 = msg.GetStringField("fill");
to:
clientID = msg.GetIntField("client");
colorCode = msg.GetStringField("fill");
Changed lines 142-143 from:
Color fill1 = (Color)ColorConverter.ConvertFromString(colorcode1);
CreateTelepointer(clientID1, fill1);
to:
colorFill = (Color)ColorConverter.ConvertFromString(colorCode);
CreateTelepointer(clientID, colorFill);
Changed lines 148-151 from:
int clientID2 = msg.GetIntField("client");
string colorcode2 = msg.GetStringField("fill");
Color fill2 = (Color)ColorConverter.ConvertFromString(colorcode2);
CreateTelepointer(clientID2, fill2);
to:
clientID = msg.GetIntField("client");
colorCode = msg.GetStringField("fill");
colorFill = (Color)ColorConverter.ConvertFromString(colorCode);
CreateTelepointer(clientID, colorFill);
Changed line 156 from:
int clientID3 = msg.GetIntField("client");
to:
clientID = msg.GetIntField("client");
Changed lines 172-174 from:
int clientID4 = msg.GetIntField("client");
string colorcode3 = msg.GetStringField("fill");
Color fill3 = (Color)ColorConverter.ConvertFromString(colorcode3);
to:
clientID = msg.GetIntField("client");
colorCode = msg.GetStringField("fill");
colorFill = (Color)ColorConverter.ConvertFromString(colorCode);
Changed line 179 from:
ChangePointerColor(clientID4, fill3);
to:
ChangePointerColor(clientID, colorFill);
July 13, 2012, at 11:52 AM by 136.159.18.232 -
Changed line 290 from:
# Create a dictionary of integers and strings that will contain client ID's and color codes as strings. \\
to:
# Create a dictionary that will contain client ID's and color codes. \\
Changed line 295 from:
# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. \\
to:
# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. This allows the client to create a telepointer for each client that was already connected before it. \\
Added lines 306-347:
# Only three message cases need to be added to the '''OnConnectionMessage''' event handler method. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
case "OnConnect":
...
break;
case "MoveTelepointer":
...
break;
case "ColorSelect":
...
break;
=]

# If the message is the ''OnConnect'' message retrieve the client ID and add a new field containing the color code for black as a ''string''. The color of the telepointer is added in the server code to ensure that a newly connect client will always start with a black telepointer, as default. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID = msg.GetIntField("client");
msg.AddField("fill", Brushes.Black.ToString());
=]

# Add both the client ID and the color code to the dictionary and broadcast the message to all clients except for the client who sent the message. \\
(:source lang=csharp tabwidth=2 linenum=3 :) [=
this._clientIDs.Add(clientID, Brushes.Black.ToString());
this._server.BroadcastMessage(msg, (Connection)sender);
=]

# If the message is the ''MoveTelepointer'' message simply broadcast the message to all clients. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
this._server.BroadcastMessage(msg);
=]

# If the message is the ''ColorSelect'' message retrieve both the client ID and the color code. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID1 = msg.GetIntField("client");
string fill1 = msg.GetStringField("fill");
=]

# Update the color code for the given client ID in the dictionary then broadcast the message to all clients except for the one who sent the message. \\
(:source lang=csharp tabwidth=2 linenum=3 :) [=
this._clientIDs[clientID1] = fill1;
this._server.BroadcastMessage(msg, (Connection)sender);
=]
July 13, 2012, at 11:29 AM by 136.159.18.232 -
Added line 85:
[[#client]]
Added line 286:
[[#server]]
July 13, 2012, at 11:28 AM by 136.159.18.232 -
Changed lines 288-306 from:
to:
# Create a dictionary of integers and strings that will contain client ID's and color codes as strings. \\
(:source lang=csharp tabwidth=2 :) [=
private Dictionary<int, string> _clientIDs;
=]

# Before calling the '''RedrawPath''' method in the '''OnServerConnection''' event handler method, a message needs to be sent to the connecting client for each available client within the ID and colors dictionary. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
foreach (var pair in this._clientIDs)
{
Message teleMsg = new Message("AddOtherPointers");
teleMsg.AddField("client", pair.Key);
teleMsg.AddField("fill", pair.Value);
this._server.BroadcastMessage(teleMsg, this._clients.Where(client => client != e.Connection).ToList());
}
=]

!!!!!![[#top | back to top]]
July 13, 2012, at 11:21 AM by 136.159.18.232 -
Changed lines 283-288 from:
to:
----

!!!!Server
Open up the C# code file for the server.
July 13, 2012, at 11:18 AM by 136.159.18.232 -
Changed line 158 from:
(:source lang=chsharp tabwidth=2 linenum=4 :) [=
to:
(:source lang=csharp tabwidth=2 linenum=4 :) [=
July 13, 2012, at 11:17 AM by 136.159.18.232 -
Changed line 152 from:
(:source lang=csharp tabwidth=2 linenum:=2 :) [=
to:
(:source lang=csharp tabwidth=2 linenum=2 :) [=
July 13, 2012, at 11:13 AM by 136.159.18.232 -
Added lines 273-280:
# Lastly, in each event handler method that looks after color selections, create and send a message called ''ColorSelect'' containing the client's ID and the current selected color. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
Message msg = new Message("ColorSelect");
msg.AddField("client", this._clientID);
msg.AddField("fill", this._selectedColor.ToString());
this._connection.SendMessage(msg);
=]
July 13, 2012, at 11:09 AM by 136.159.18.232 -
Added lines 256-272:
# In order for the telepointers to work a message needs to be sent containing mouse coordinates during a '''MouseMove''' event. In the '''OnMouseMove''' event handler, before the ''if'' statement, create a message called ''MoveTelepointer''. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
Message teleMsg = new Message("MoveTelepointer");
=]

# Add the client's ID, and the 'x' and 'y' values for the mouse coordinates to the message. \\
(:source lang=csharp tabwidth=2 linenum=2 :) [=
teleMsg.AddField("client", this._clientID);
teleMsg.AddField("x", e.GetPosition(this._drawingCanvas).X;
teleMsg.AddField("y", e.GetPosition(this._drawingCanvas).Y;
=]

# Then make sure to send the message to the server. \\
(:source lang=csharp tabwidth=2 linenum=5 :) [=
this._connection.SendMessage(teleMsg);
=]
July 13, 2012, at 11:04 AM by 136.159.18.232 -
Changed line 224 from:
# In the ''delegate()'' section [''line 6, step 17''], add an ''if'' statement that checks that ''_telepointers'' contains the client ID and that the ID given as input does not belong to the current client. \\
to:
# In the ''delegate()'' section [''line 6, step 18''], add an ''if'' statement that checks that ''_telepointers'' contains the client ID and that the ID given as input does not belong to the current client. \\
Changed line 230 from:
# Within the above conditional statement [''line 2, step 18''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. The off set values ('x-5' and 'y+25') compensate for the placement of the ''_extraCanvas'' that was added in the form. It ensures that the center of the telepointer is where the tip of the mouse cursor would be. \\
to:
# Within the above conditional statement [''line 2, step 19''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. The off set values ('x-5' and 'y+25') compensate for the placement of the ''_extraCanvas'' that was added in the form. It ensures that the center of the telepointer is where the tip of the mouse cursor would be. \\
Changed line 249 from:
# Again, within ''delegate()'' [''line 6, step 20''], create a ''SolidColorBrush'' object, grab the appropriate telepointer ellipse and change its fill color. \\
to:
# Again, within ''delegate()'' [''line 6, step 21''], create a ''SolidColorBrush'' object, grab the appropriate telepointer ellipse and change its fill color. \\
July 13, 2012, at 10:58 AM by 136.159.18.232 -
Changed line 205 from:
# Change its opacity to ''0'' so that it remains invisible for now then add it to both the telepointer dictionary and the ''_extraCanvas''. \\
to:
# Change its opacity to ''0'' so that it remains invisible for now then add it to both the telepointer dictionary and the ''_extraCanvas''. The reason the telepointers are added to the ''_extraCanvas'' canvas is to make sure that the they remain ''on top'' of the path drawings, meaning a high z index. Using this canvas, which is already on top of the ''_drawingCanvas'' canvas, ensures that the telepointers will never be obscured from view by any drawn path.\\
Added lines 237-255:
# Next, create the ''' ChangePointerColor''' method, which, via the GUI thread, changes the color of the telepointer for a certain client according to that client's color choice through the palette. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
private void ChangePointerColor(int id, Color fill)
{
this.Dispatcher.Invoke(
new Action(
delegate()
(...}
));
}
=]

# Again, within ''delegate()'' [''line 6, step 20''], create a ''SolidColorBrush'' object, grab the appropriate telepointer ellipse and change its fill color. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
SolidColorBrush brushColor = new SolidColorBrush(fill);
Ellipse pointer = this._telepointers[id];
pointer.Fill = brushColor;
=]
July 13, 2012, at 10:44 AM by 136.159.18.232 -
Changed lines 74-77 from:
to:
** Ensure that ''IsHitTestVisible'' is '''not''' selected. \\
\\
Attach:drawHitTest.jpg
July 13, 2012, at 10:37 AM by 136.159.18.232 -
Changed lines 66-69 from:
# Given the form that had been created in the ''Drawing Board 1.0'' tutorial example, in the '''desginer view (XAML)''' add a new '''Canvas'''. Be sure to place and size it so that it does not cover any of the other elements on the UI.
to:
# Given the form that had been created in the ''Drawing Board 1.0'' tutorial example, in the '''desginer view (XAML)''' add a new '''Canvas'''. Be sure to place and size it so that it does not cover any of the other elements on the UI. \\
\\
Attach:extraCanvas.jpg
July 13, 2012, at 10:35 AM by 136.159.18.232 -
Changed line 68 from:
(:source lang=xaml tabwidth=2 :) [=
to:
(:source lang=xml tabwidth=2 :) [=
July 13, 2012, at 10:33 AM by 136.159.18.232 -
Changed line 68 from:
(:source lang=csharp tabwidth=2 :) [=
to:
(:source lang=xaml tabwidth=2 :) [=
July 13, 2012, at 10:33 AM by 136.159.18.232 -
Changed lines 67-71 from:
to:
** In the '''XAML''' file the code for this new canvas should look something like the following: \\
(:source lang=csharp tabwidth=2 :) [=
<Canvas Canvas.Left="12" Canvas.Top="104" Height="24" Name="_extraCanvas" Width="35" Background="White" IsHitTestVisible="False" AllowDrop="True" Opacity="1"></Canvas>
=]
Changed line 224 from:
# Within the above conditional statement [''line 2, step 18''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. \\
to:
# Within the above conditional statement [''line 2, step 18''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. The off set values ('x-5' and 'y+25') compensate for the placement of the ''_extraCanvas'' that was added in the form. It ensures that the center of the telepointer is where the tip of the mouse cursor would be. \\
July 12, 2012, at 05:29 PM by 136.159.18.232 -
Changed lines 64-65 from:
''Note'': If you had
to:
''Note'': If you had completed the ''Drawing Board 1.0'' tutorial example as recommended then you no longer have to build the form from scratch. If you did not complete the aforementioned tutorial example, please do so before attempting this tutorial.

# Given the form that had been created in the ''Drawing Board 1.0'' tutorial example, in the '''desginer view (XAML)''' add a new '''Canvas'''. Be sure to place and size it so that it does not cover any of the other elements on the UI.
July 12, 2012, at 05:25 PM by 136.159.18.232 -
Added lines 200-224:
# Next, create the '''MoveTelepointer''' method which, through the GUI thread, ensures that the telepointer that corresponds to a particular client is visible and moves according to the coordinates given from the mouse movements. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
private void MoveTelepointer(int id, double x, double y)
{
this.Dispatcher.Invoke(
new Action(
delegate()
{...}
));
}
=]

# In the ''delegate()'' section [''line 6, step 17''], add an ''if'' statement that checks that ''_telepointers'' contains the client ID and that the ID given as input does not belong to the current client. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
if (this._telepointers.ContainsKey(id) && id != this._clientID)
{...}
=]

# Within the above conditional statement [''line 2, step 18''], retrieve the ellipse from the telepointers dictionary that corresponds to the client ID provided. then change its opacity to '1' so that it becomes visible and, via ''TranslateTransform'', move the telepointer to the given 'x' and 'y' coordinate values. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
Ellipse pointerToMove = this._telepointers[id];
pointerToMove.Opacity = 1;
pointerToMove.RenderTransform = new TranslateTransform(x - 5, y + 25);
=]
July 12, 2012, at 04:44 PM by 136.159.18.232 -
Changed lines 64-65 from:
to:
''Note'': If you had
July 12, 2012, at 04:42 PM by 136.159.18.232 -
Changed lines 193-194 from:
# Change its opacity to ''0'' so that it remains invisible for now then add it to both the telepointer dictionary and the extra
to:
# Change its opacity to ''0'' so that it remains invisible for now then add it to both the telepointer dictionary and the ''_extraCanvas''. \\
(:source lang=csharp tabwidth=2 linenum=6 :) [=
pointer.Opacity = 0;
this._telepointers.Add(id, pointer);
this._extraCanvas.Children.Add(pointer);
=]
July 12, 2012, at 04:41 PM by 136.159.18.232 -
Added line 28:
* [[#form | Setting Up the Form]]
Added lines 61-68:
[[#form]]
!!Setting Up the Form



!!!!!![[#top | back to top]]
Changed line 174 from:
# Within ''delegate()'' [''line 6, step ''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
to:
# Within ''delegate()'' [''line 6, step 13''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
Changed lines 180-181 from:
# Now within that ''if'' statement [''line 2, step 14'']
to:
# Now within that ''if'' statement [''line 2, step 14''], create a ''SolidBrushColor'' object using the fill input to assign the color and a new ''Ellipse'' object. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
SolidColorBrush brush = new SolidColorBrush(fill);
Ellipse pointer = new Ellipse();
=]

# Create the ellipse to be a circle with a diameter of 10 pixels and use the ''SolidBrushColor'' object to assign the fill color of the ellipse. \\
(:source lang=csharp tabwidth=2 linenum=3 :) [=
pointer.Width = 10;
pointer.Height = 10;
pointer.Fill = brush;
=]

# Change its opacity to ''0'' so that it remains invisible for now then add it to both the telepointer dictionary and the extra
July 12, 2012, at 04:35 PM by 136.159.18.232 -
Changed lines 171-172 from:
# Now within that ''if'' statement [''line 2, step '']
to:
# Now within that ''if'' statement [''line 2, step 14'']
July 12, 2012, at 04:34 PM by 136.159.18.232 -
Added lines 153-172:
# Create the methods mentioned above, starting with the '''CreateTelepointer''' method, which is responsible for, using the GUI thread, creating the circles that will stand in as each client's telepointer. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
private void CreateTelepointer(int id, Color fill)
{
this.Dispatcher.Invoke(
new Action(
delegate()
{...}
));
}
=]

# Within ''delegate()'' [''line 6, step ''], impose the following conditions where the client ID given as input is not equal to the current client's ID and a pre-existing telepointer has not already been made for the ID. The former condition ensures that a user does not see their own telepointer. A client's telepoint should appear on all other clients' UI but not their own. The latter condition ensures that a duplicate telepointer is not made. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
if (id != this._clientID && !this._telepointers.ContainsKey(id))
{...}
=]

# Now within that ''if'' statement [''line 2, step '']
July 12, 2012, at 04:13 PM by 136.159.18.232 -
Added lines 105-152:
# If the message is the ''OnConnect'' message the client ID and the brush color is retrieved. \\
(:source lang=csharp tabwidth=2 linenum=1:) [=
int clientID1 = msg.GetIntField("client");
string colorcode1 = msg.GetStringField("fill");
=]

# The brush color is currently a ''string'' object and needs to be available as a ''Color'' object. Convert the brush color then call the '''CreateTelepointer''' method. \\
(:source lang=csharp tabwidth=2 linenum=3 :) [=
Color fill1 = (Color)ColorConverter.ConvertFromString(colorcode1);
CreateTelepointer(clientID1, fill1);
=]

# If the message is the ''AddOtherPointers'' message add the exact same tasks as in the case of the ''OnConnect'' message. Retrieve both the client ID and the brush color and convert it into a ''Color'' object then call the '''CreateTelepointer''' method. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID2 = msg.GetIntField("client");
string colorcode2 = msg.GetStringField("fill");
Color fill2 = (Color)ColorConverter.ConvertFromString(colorcode2);
CreateTelepointer(clientID2, fill2);
=]

# If the message is the ''MoveTelepointer'' message, again retrieve the client's ID. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID3 = msg.GetIntField("client");
=]

# This time, instead of retrieving brush color, get the 'x' and 'y' values that are to be use to set the coordinates for the telepointer. \\
(:source lang=csharp tabwidth=2 linenum:=2 :) [=
double teleX = msg.GetDoubleField("x");
double teleY = msg.GetDoubleField("y");
=]

# Then call the '''MoveTelepointer''' method. \\
(:source lang=chsharp tabwidth=2 linenum=4 :) [=
MoveTelepointer(clientID3, teleX, teleY);
=]

# Lastly, if the message is the ''ColorSelect'' message, just as both the ''OnConnect'' and ''AddOtherPointers'' messages, retrieve the client ID and the brush color and convert it into a ''Color'' object. \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
int clientID4 = msg.GetIntField("client");
string colorcode3 = msg.GetStringField("fill");
Color fill3 = (Color)ColorConverter.ConvertFromString(colorcode3);
=]

# This time call the '''ChangePointerColor''' method. \\
(:source lang=csharp tabwidth=2 linenum=4 :) [=
ChangePointerColor(clientID4, fill3);
=]
July 12, 2012, at 03:31 PM by 136.159.18.232 -
Changed line 82 from:
# Next create and send a message called ''OnConnect''. This message will contain the client's ID. \\
to:
# Next create and send a message called ''OnConnect'' to the server. This message will contain the client's ID. \\
Added lines 89-104:
# Four different messages need to be handled in the '''OnMessageReceived''' event handler method. Add the following cases: \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
case "OnConnect":
...
break;
case "AddOtherPointers":
...
break;
case "MoveTelepointer":
...
break;
case "ColorSelect":
...
break;
=]
July 12, 2012, at 03:20 PM by 136.159.18.232 -
Changed line 76 from:
# In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID.
to:
# In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID. \\
Changed line 82 from:
# Next create and send a message called ''OnConnect''. This message will contain the client's ID.
to:
# Next create and send a message called ''OnConnect''. This message will contain the client's ID. \\
July 12, 2012, at 12:37 PM by 136.159.18.232 -
Changed lines 76-77 from:
#
to:
# In the '''OnConnectionDiscovered''' event handler method randomly generate an integer and assign it to be the client's ID.
(:source lang=csharp tabwidth=2 linenum=1 :) [=
Random rand = new Random();
this._clientID = rand.Next();
=]

# Next create and send a message called ''OnConnect''. This message will contain the client's ID.
(:source lang=csharp tabwidth=2 linenum=3 :) [=
Message newMsg = new Message("OnConnect");
newMsg.AddField("client", this._clientID);
this._connection.SendMessage(newMsg);
=]
July 12, 2012, at 12:33 PM by 136.159.18.232 -
Added lines 76-77:
#
July 12, 2012, at 12:27 PM by 136.159.18.232 -
Added lines 67-75:
# Begin by declaring the following class instance variables: \\
(:source lang=csharp tabwidth=2 linenum=1 :) [=
private int _clientID;
private Dictionary<int, Ellipse> _telepointers;
=]

** ''_clientID'' is an integer chosen at random to be the client's ID number.
** ''_telepointers'' is a dictionary that keeps track of client ID's and their corresponding telepointers.
July 12, 2012, at 12:16 PM by 136.159.18.232 -
Changed lines 62-63 from:
to:
This part of the tutorial will build on the code provided in the ''Drawing Board 1.0'' tutorial example.

!!!!Client
Open the C# file for the client.
July 12, 2012, at 12:13 PM by 136.159.18.232 -
Changed lines 60-62 from:
!!!!Adding the Code
to:
[[#code]]
!!Adding the Code
Changed lines 67-69 from:
!!!!Result
to:
[[#result]]
!!Result
July 12, 2012, at 12:13 PM by 136.159.18.232 -
Added lines 58-69:


!!!!Adding the Code


!!!!!![[#top | back to top]]


!!!!Result


!!!!!![[#top | back to top]]
July 12, 2012, at 12:12 PM by 136.159.18.232 -
Changed lines 47-49 from:
...

!
!!!!Download
to:
When a client connects a telepointer is created which is tracked by the client's ID number. This telepointer defaults to black, since the default brush color is also black, and is shown to all other clients. This means that everyone can see the telepointer with the exception of the client itself. During a ''MouseMove'' coordinates are given out according to client ID's which allows the telepointers to track the user's mouse movements. The telepointers are still available when users are drawing on the board, on a ''MouseDown''. Selecting a color, ''MouseLeftButtonDown'', from the palette also changes a client's telepointer accordingly.

In the case that a client connects in the middle of an on going session, the server, which has been keeping track of client ID's and color selections sends the most recent information to this client. Therefore they are also able to see the telepointers for clients who have been previously connected.

!!!!Download
July 12, 2012, at 12:00 PM by 136.159.18.232 -
Changed line 41 from:
!!!!!Summary
to:
!!!!Summary
Changed line 46 from:
!!!!!High Level Overview
to:
!!!!High Level Overview
July 12, 2012, at 12:00 PM by 136.159.18.232 -
Added line 41:
!!!!!Summary
Added lines 44-54:
Just as the previous version, this example simulates a communal drawing board the allows for multiple users to draw collaboratively in the same space. As far as functionality goes version 2.0 is exactly the same as version 1.0 with the exception of one additional feature: ''telepointers''. These telepointers are used to show and track the mouse movements of other users on a particular users screen. This way each user is able to see where on the canvas the other users are. A user's telepointer also changes in color according to the color, from the palette, they are using.

!!!!!High Level Overview
...

!!!!!Download
As this is an extended version, we recommend that you try building the Drawing Board 1.0 application first, then try building this extension with the given instructions below before downloading the executable file provided.

The ''Drawing Board 2.0'' tutorial Example executable file:
* [[Attach:drawFinalv2.zip | Drawing Board 2.0]]
July 12, 2012, at 11:43 AM by 136.159.18.232 -
Changed lines 41-42 from:
This ''Drawing Board 2.0'' tutorial example is an extension of [[Toolkits/iNetwork/Tutorial3 | ''Drawing Board 1.0'']] and thus builds on its code and composition.
to:
This ''Drawing Board 2.0'' tutorial example is an extension of [[Toolkits/iNetwork/Tutorial3 | '''''Drawing Board 1.0''''']] and thus builds on its code and composition.
July 12, 2012, at 11:43 AM by 136.159.18.232 -
Changed lines 38-43 from:
!!Introduction
to:
[[#intro]]
!!Introduction

This ''Drawing Board 2.0'' tutorial example is an extension of [[Toolkits/iNetwork/Tutorial3 | ''Drawing Board 1.0'']] and thus builds on its code and composition.

!!!!!![[#top | back to top]]
July 12, 2012, at 11:36 AM by 136.159.18.232 -
Changed lines 35-38 from:
>><<
to:
>><<


!!Introduction
July 12, 2012, at 11:36 AM by 136.159.18.232 -
Deleted line 26:
* [[#read | Readings]]
Deleted line 27:
* [[#form | Setting-Up the Form]]
July 12, 2012, at 11:35 AM by 136.159.18.232 -
Added lines 1-37:
(:title iNetwork Tutorial #3.2: Drawing Board 2.0:)

%define=box padding-left=1em padding-right=1em margin='3px 3px 0'%
%define=yellowbox box bgcolor=#fdfaea border='1px solid #ffad80'%
%define=redbox box bgcolor=#fff3f3 border='1px solid #ffc9c9'%
%define=bluebox box bgcolor=#f4fbff border='1px solid #a1cae6'%
%define=skybox box bgcolor=#f8fcff border='1px solid #aaaaaa'%
%define=greybox box bgcolor=#fbfbfb border='1px solid #aaaaaa'%
%define=greenbox box bgcolor=#e6f3e5 border='1px solid #8fd586'%
%define=whitebox box bgcolor=#ffffff border='1px solid #999999'%


[[#top]]
>>yellowbox<<

%lfloat% Attach:warning.gif
'+'''WARNING! AVERTISSEMENT! ¡CUIDADO!'''+' \\
'+'''This project page is under construction!'''+'

>><<


>>greybox<<

!!!Contents

* [[#read | Readings]]
* [[#intro | Introduction]]
* [[#form | Setting-Up the Form]]
* [[#code |Adding Code]]
** [[#client| Client Code]]
** [[#server | Server Code]]
* [[#result | Result]]

!!!!!![[Toolkits/iNetwork | back to '''iNetwork''']]

>><<