COMP 160 Lab 1b: GUI Programming

This tutorial covers:


GUI Programming

In this lab we will continue to learn more about C# by doing some basic GUI programming. We will create a program that plots a few simple 1D functions. Here are the first steps you need to follow:


The picture in the center is the plot of a constant function (f(x)=k). We can plot a linear function (f(x)=x) by selecting "Linear" in the "Function: " combo box. We can left-click-and-drag on the plot to pan the plot.

The next section describes the code layout. You can skip this section if you are already familiar with C# constructs and have no problem understanding the code base.

Code Base

The code is separated into two files: Function1D.cs and MainForm.cs. Function1D.cs contains respresentation for 1D functions while MainForm.cs contains the code to create GUI elements and handle user interactions.

[Function1D.cs]

To create new 1D functions, we need to subclass the Function1D class and override the evalIntern and ToString functions. The two provided functions are fairly self explanatory in their structure.

--Properties--

A point of interest is lines like:

public double m { get; set; }.

get and set are keywords in C# used as implicit property accessor functions. This code is equalivalent to

public double m;
public double getm() { return m; }
public void setm(v) { m=v; }

This is simply a short hand for property functions in languages like Java. Using get and set abstracts out the internal representation of m. While this feature is not of great importance in this context, you might find it a useful tool in future projects. You will see similar application in the other source file. You can find more information about get/set here.

[MainForm.cs]

MainForm.cs contains the creation and interaction of the GUI elements. Most of the code should be easy to understand, but we will go over some of the more important details here.

The PlotForm class represents the graph element in the middle of the program. PlotForm extends from the class PictureBox, which is a C# GUI object is used for arbitrary 2D picture. The plot function draws the our function by breaking it up into small pieces of lines. The drawTicks function draws the x and y axes along with ticks on the axes. Both of these functions use the screenToPlot and/or the plotToScreen function to transform screen coordinates to plot coordinate or vice-versa.

The MainForm class is the main window element that contains all the GUI components. It contains the Main function, which is the entry point of the program. Furthermore, MainForm has two corresponding member objects: _plotform and _funcCombo. They correspond to the two GUI elements in the window: one is the plot picture, and the other is the combo box for selecting the different plot functions.

--Pass-by-reference--

We see in MainForm.cs the following function declaration:

private void screenToPlot(float sx, float sy, out float x, out float y)

The out keyword here is a special feature of C#, not available in Java or C/C++. It is essentially a pass-by-reference declaration for the variables x and y. This allows us to return more than a single value (e.g. two values for x and y) per function. It is different from the call-by-reference in C/C++ in that screenToPlot must assign values to x and y before the function exits. Otherwise, it is an compilation error. Much like how if a function is declared to return an integer, then not returning an integer before the function ends will cause a compilation error. You can learn more about different ways of parameter passing in C# here.

--Delegates or Call-back Functions--

A delegate in C# is a pointer to a function. Essentially, it allows us to treat functions as variables and pass them as arguments to other functionsand/or use them as we would regular variables. C# handles user interaction in two primary ways.

First, if we are subclassing a C# windowing object (such as PlotForm subclassing PictureBox), then we can override reactive functions (OnMouseMove) that are called when an event occurs (mouse moving on the picture).

Second, if we decide to use an C# supplied GUI object without modification (such as ComboBox _funcCombo), then we can provide the object with a delegate (funcSelectionChanged) that will be called when an event occurs (function selection changes from Constant to Linear). The way we provide such a delegate is through this line:

_funcCombo.SelectedIndexChanged+=new EventHandler(funcSelectionChanged);

SelectedIndexChanged is just one of many events associated with the ComboBox object. More information about delegates can be found here.

Assignment

Your assignment for this lab is divided into a primary part and a secondary part. You need to complete all of the primary requirements. The secondary part has a small set features that you can implement; you will only need to implement a subset of these secondary requirements. The primary requirements are fairly easy, and you should have little problem completing it before the end of class. The secondary part will likely require you to complete it outside of the lab time. As always, you're welcome to add your own cool feature after you completed all the requirments. An example implementation with all of the following features can be found here

Primary

Complete these three features.

Secondary

Choose one of the following for implementation

Upon Completion

Complete both the primary and secondary requirements before the start of the next lab. Show the completed project to one of the TAs either during this lab period or at the beginning of the next one to have your name checked off.