Syntax Highlighing:
comments, key words, predefined symbols, class members & methods, functions & classes
################################################################
#
# PLANTER2.SML
#
# Demonstration SML script
#
# Requires a tntdisp dated 3-Feb-98 or later
#
################################################################
class XmForm form;
raster Composite, PopulationA, PopulationB;
class GRE_VIEW view;
class GRE_LAYER_RASTER layer, poplayerA, poplayerB;
class PORT portA, portB;
class PromptNum nominalA, pctchangeA;
class PromptNum nominalB, pctchangeB;
class ButtonItem button1, button2;
class XmForm button_row;
class GRE_GROUP group;
numeric height, width;
numeric version = round(_context.Version * 10);
if (version < 74) {
PopupMessage("This version requires that you are using TNTmips2008:74 or later");
Exit();
}
numeric olda, oldb;
numeric fakePorts = 0; # Set to 1 to debug without the device attached
if (!fakePorts) {
portA = PortOpen("com1"); # Com port for Channel A
portB = PortOpen("com2"); # Com port for Channel B
portA.settings = "9600:8:none:1:no_flow_control";
portB.settings = "9600:8:none:1:no_flow_control";
}
#####################################################
# 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;
#------------ Channel A -------------
class POINT2D pt = ViewTransPointViewToLayer(view, poplayerA, view.Mouse);
rate = PopulationA[pt.y, pt.x];
if (IsNull(rate)) {
val = 32 + olda; # Sending a 32 turns off the planter
}
else {
# Compute the code to send to the planter controller
nomrate = nominalA.value;
unitsPerStep = pctchangeA.value * nomrate / 100.0;
val = (nomrate - rate) / unitsPerStep + 16;
val = Bound(val, 0, 31); # Force to valid range
olda = val;
}
if (fakePorts) {
printf("Mouse = %d,%d, rate=%d, val=%d\n", pt.x, pt.y, rate, val);
}
else {
fwritebyte(portA, val); # Write the value to the port
}
#------------ Channel B -------------
pt = ViewTransPointViewToLayer(view, poplayerB, view.Mouse);
rate = PopulationB[pt.y, pt.x];
if (IsNull(rate)) {
val = 32 + oldb; # Sending a 32 turns off the planter
}
else {
# Compute the code to send to the planter controller
nomrate = nominalB.value;
unitsPerStep = pctchangeB.value * nomrate / 100.0;
val = (nomrate - rate) / unitsPerStep + 16;
val = Bound(val, 0, 31); # Force to valid range
oldb = val;
}
if (fakePorts) {
printf("Mouse = %d,%d, rate=%d, val=%d\n", pt.x, pt.y, rate, val);
}
else {
fwritebyte(portB, val); # Write the value to the port
}
}
#####################################################
# Callback for when the "Exit" button is pressed
#
proc cbQuit(class widget widget) {
DialogClose(form);
}
#####################################################
# MAIN PROGRAM
GetInputRasters(Composite, PopulationA, PopulationB);
form = CreateModalFormDialog("Planter Control");
nominalB = CreatePromptNum(form, "Ch B -- Nominal Rate:", 10, 0, 25000);
nominalB.LeftWidget = form;
nominalB.LeftOffset = 3;
nominalB.BottomWidget = form;
nominalB.value = IniReadNumber("planter", "nominalB", 25000);
pctchangeB = CreatePromptNum(form, "% Change:", 5, 1, 2);
pctchangeB.LeftWidget = nominalB;
pctchangeB.LeftOffset = 6;
pctchangeB.BottomWidget = form;
pctchangeB.value = IniReadNumber("planter", "pctchangeB", 2);
nominalA = CreatePromptNum(form, "Ch A -- Nominal Rate:", 10, 0, 25000);
nominalA.LeftWidget = form;
nominalA.LeftOffset = 3;
nominalA.BottomWidget = nominalB;
nominalA.value = IniReadNumber("planter", "nominalA", 25000);
pctchangeA = CreatePromptNum(form, "% Change:", 5, 1, 2);
pctchangeA.LeftWidget = nominalA;
pctchangeA.LeftOffset = 6;
pctchangeA.BottomWidget = pctchangeB;
pctchangeA.value = IniReadNumber("planter", "pctchangeA", 2);
button2 = CreatePushButtonItem("Exit", cbQuit);
button_row = CreateButtonRow(form, button2);
button_row.BottomWidget = form;
button_row.BottomOffset = 1;
button_row.RightOffset = 1;
button_row.LeftWidget = pctchangeA;
group = DispCreate2DGroup();
layer = GroupQuickAddRasterVar(group, Composite);
poplayerA = GroupQuickAddRasterVar(group, PopulationA);
poplayerB = GroupQuickAddRasterVar(group, PopulationB);
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 = pctchangeA;
LayerHide(poplayerA, view);
LayerHide(poplayerB, view);
layer.ShowDataTips = 0;
poplayerA.ShowDataTips = 1;
poplayerB.ShowDataTips = 1;
poplayerA.DataTip.Suffix = "Sds/A";
poplayerB.DataTip.Suffix = "Sds/A";
DispAddCallback(view.DataTipShownCallback, cbMouseStop);
#DispAddCallback(view.MouseMoveCallback, cbMouseStop);
#view.ScalePosVisible = 0;
view.ShowDataTips = 2;
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);
#
# Remember our prompt settings for next time
#
IniWriteNumber("planter", "nominalA", nominalA.value);
IniWriteNumber("planter", "nominalB", nominalB.value);
IniWriteNumber("planter", "pctchangeA", pctchangeA.value);
IniWriteNumber("planter", "pctchangeB", pctchangeB.value);
#
# Destroy our form to free up its memory.
#
ViewDestroy(view);
DestroyWidget(form);
if (!fakePorts) {
PortClose(portA);
PortClose(portB);
}