planter.sml

  Download

More scripts: Advanced

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)