Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
#
# Open the com port with the planter control unit on it
#
#port = PortOpen("com2");
#port.settings = "9600:8:none:1:no_flow_control"
#
# This is how to declare a global variable so that
# they can be used in functions before it's assigned.
# Without the explicit declaration, the variable will
# be assumed to be numeric or a Raster (depending on
# the case of the first letter).
#
class XmForm form; # The main form dialog
raster Composite, Population;
class GRE_VIEW view;
class GRE_LAYER_RASTER layer, poplayer; # Our base layer
class PromptNum nominal, pctchange; # Numeric prompts
class ButtonItem button1, button2;
class XmForm button_row;
class GRE_GROUP group;
class XmPushButton testbutton;
numeric height, width;
numeric doingtest = 1;
numeric version = round(_context.Version * 10);
if (version < 74) {
PopupMessage("This version requires that you are using TNTmips2008:74 or later");
Exit();
}
#
# This is the callback function which will be called
# when button1 is pressed. All widget callbacks get
# two parameters (for now). The first is the widget
# generating the callback. The second is an optional
# "cbdata" and will be whatever was passed to
# WidgetAddCallback for the last parameter. It isn't
# really supported yet.
# When done, callbacks will also get a 3rd parameter
# which is the Callback Struct that the XmWidget passes
# There's currently no way to declare these things
#
proc cbQuit(class widget widget) {
DialogClose(form);
}
proc cbTest(class widget widget) {
doingtest = !doingtest;
printf("DoingTest = %d\n", doingtest);
}
#
# This is the callback for when the mouse stops moving
# It will be called when a data-tip is shown.
#
proc cbMouseStop(class GRE_VIEW aview) {
local numeric rate, val, unitsPerStep, nomrate;
if (doingtest) {
class POINT2D pt = ViewTransPointViewToLayer(view, poplayer, view.Mouse);
rate = Population[pt.y, pt.x];
if (IsNull(rate)) {
val = 32; # Sending a 32 turns off the planter
}
else {
# Compute the code to send to the planter controller
nomrate = nominal.value;
unitsPerStep = pctchange.value * nomrate / 100.0;
val = (nomrate - rate) / unitsPerStep + 16;
val = Bound(val, 0, 31); # Force to valid range
}
# fwritebyte(port, val); # Write the value to the port
printf("Mouse = %d,%d, rate=%d, val=%d\n", pt.x, pt.y, rate, val);
}
}
#####################################################
#
# MAIN PROGRAM
#
# Get an input raster. We will use it's size to determine
# how big to make our window
GetInputRasters(Composite, Population);
# Create a modal dialog (aka "window"). A modal dialog
# prevents other windows from accepting input until it
# goes away. This is the easiest kind to work with.
# Non-modal dialogs will be supported later
#
# This function returns a form that can be used as a
# parent for other widgets
#
# If we had another dialog which we wanted to use as
# a "parent" to this one, we would pass it as the
# 2nd parameter to CreateModalFormDialog().
form = CreateModalFormDialog("test");
nominal = CreatePromptNum(form, "Nominal Rate:", 10, 0, 25000);
nominal.BottomWidget = form;
nominal.BottomOffset = 9;
nominal.LeftWidget = form;
nominal.LeftOffset = 3;
pctchange = CreatePromptNum(form, "% Change:", 5, 1, 2);
pctchange.BottomWidget = form;
pctchange.BottomOffset = 9;
pctchange.LeftWidget = nominal;
pctchange.LeftOffset = 6;
button1 = CreatePushButtonItem("button1", cbQuit);
button2 = CreatePushButtonItem("Exit", cbQuit);
button_row = CreateButtonRow(form, button1, button2);
button_row.BottomWidget = form;
button_row.BottomOffset = 1;
button_row.RightOffset = 1;
button_row.LeftWidget = pctchange;
#
# Create a 2D group to display the raster in and quick-add it.
#
group = DispCreate2DGroup();
layer = GroupQuickAddRasterVar(group, Composite);
poplayer = GroupQuickAddRasterVar(group, Population);
#
# Create a view for this group in our form. Default its size to
# the size of the raster. For a real program, you'd want to
# limit this to something reasonable.
#
height = NumLins(Composite);
width = NumCols(Composite);
while (height > 700 or width > 1000) {
height /= 2;
width /= 2;
}
view = GroupCreateView(group, form, "view", height, width);
form.BottomWidget = button_row;
LayerHide(poplayer, view);
layer.ShowDataTips = 0;
poplayer.ShowDataTips = 1;
DispAddCallback(view.DataTipShownCallback, cbMouseStop);
DispAddCallback(view.MouseMoveCallback, cbMouseStop);
#view.ScalePosVisible = 0;
view.ShowDataTips = 2;
testbutton = CreatePushButton(view.ToolBarPane.GetWidget(), "test");
WidgetAddCallback(testbutton.ActivateCallback, cbTest);
#
# Have to call this after adding any tools of our own
#
ViewAddStandardTools(view);
#
# Open the dialog.
#
DialogOpen(form);
ViewRedraw(view);
ViewSetMessage(view, "Move the mouse over the field to control the planter");
#
# Wait for the dialog to close. This function will
# not return until the dialog closes.
# The normal way to do this is have a button or menu
# item who's callback calls DialogClose(form).
# Clicking on the "X" button on the title bar will
# close it (although I plan to let you override that
# too)
#
DialogWaitForClose(form);
#
# Destroy our form to free up its memory. Destroying the
# main form will also destroy all its children.
# Need to destroy the view before the form because
# otherwise the tool gets destroyed before the view
# and the view tries to disable a nonexistant tool.
# Result: IllOP!
#
ViewDestroy(view);
DestroyWidget(form);
#PortClose(port)