# # ToolScript for recording "viewpoint position" as center and zoom. # # The following symbols are predefined # class VIEW View {use to access the view the tool script is attached to} # class GROUP Group {use to access the group being viewed if the script is run from a group view} # class LAYOUT Layout {use to access the layout being viewed if the script is run from a layout view} # number ToolIsActive Will be 0 if tool is inactive or 1 if tool is active # class XmForm dlgform; class XmList poslist; class MAPPROJ projLatLon; class TRANSPARM transMapToView; class FILE posfile; numeric ischanged; numeric setDefaultWhenClose; numeric numpos; array numeric posX[1]; array numeric posY[1]; array numeric posScale[1]; # Save the list to a file. func DoSave () { if (numpos == 0) return false; string posfilename$ = GetOutputFileName("","Select position file to save as:","pos"); # If you get an error that fopen() is being passed too many parameters, # get a new tntdisp.exe. The 3rd parameter was added 01-Feb-2001 posfile = fopen(posfilename$,"w", "UTF8"); if (posfile == 0) return (false); local i; for i = 1 to numpos { fprintf(posfile,"%s,%f,%f,%f\n",poslist.GetItemAtPos(i),posX[i],posY[i],posScale[i]); } fclose(posfile); ischanged = false; return (true); } func AskSave () { if (!ischanged || numpos == 0) return (true); local answer; answer = PopupYesNoCancel("Save current point list?",1); if (answer < 0) return (false); if (answer == 0) return (true); return (DoSave()); } # Zoom to selected position proc DoZoom () { local selpos; if (numpos == 0) return; selpos = poslist.GetFirstSelectedPos(); if (selpos > 0) { transMapToView = ViewGetTransMapToView(View,projLatLon); if (transMapToView == 0) { PopupMessage("Cannot obtain map/view transformation."); return; } class POINT2D zpoint; zpoint.x = posX[selpos]; zpoint.y = posY[selpos]; zpoint = TransPoint2D(zpoint,transMapToView,false); class RECT vextents; vextents = View.Extents; if (zpoint.x < vextents.x1 || zpoint.x > vextents.x2 || zpoint.y < vextents.y1 || zpoint.y > vextents.y2) { PopupMessage("Point is outside extents of objects being viewed."); return; } View.DisableRedraw = true; View.CurrentMapScale = posScale[selpos]; View.Center = zpoint; View.DisableRedraw = false; ViewRedraw(View); } } # Add current viewpoint to list proc DoAdd () { transMapToView = ViewGetTransMapToView(View,projLatLon); if (transMapToView == 0) { PopupMessage("Cannot obtain map/view transformation."); return; } class POINT2D cpoint; cpoint = TransPoint2D(View.Center,transMapToView,true); numpos = numpos + 1; ResizeArrayPreserve(posX,numpos); ResizeArrayPreserve(posY,numpos); ResizeArrayPreserve(posScale,numpos); posX[numpos] = cpoint.x; posY[numpos] = cpoint.y; posScale[numpos] = View.CurrentMapScale; local string namestr$ = sprintf("1:%.0f %f %f",posScale[numpos],posX[numpos],posY[numpos]); namestr$ = PopupString("Enter view position name:",namestr$); while (poslist.ItemExists(namestr$)) { namestr$ = PopupString("Name already used.\nEnter view position name:",namestr$); } poslist.AddItem(namestr$); ischanged = true; } # Remove selected item from list proc DoRemove () { local selpos; local i; if (numpos == 0) return; selpos = poslist.GetFirstSelectedPos(); if (selpos > 0) { poslist.DeletePos(selpos); for i = selpos to numpos - 1 { posX[i] = posX[i+1]; posY[i] = posY[i+1]; posScale[i] = posScale[i+1]; } numpos = numpos - 1; ischanged = true; } } # Clear the list proc DoNew () { if (!AskSave()) return; numpos = 0; poslist.DeleteAllItems(); ischanged = false; } # Open file containing list. proc DoOpen () { if (!AskSave()) return; # If you get an error that GetInputTExtFile() is being passed too many # parameters, get a new tntdisp.exe. The 3rd parameter was added # 01-Feb-2001 posfile = GetInputTextFile("","Select positions file to open:","pos", "UTF8"); if (posfile == 0) return; numpos = 0; poslist.DeleteAllItems(); ischanged = false; string filestr$; while (!feof(posfile)) { filestr$ = fgetline$(posfile); if (NumberTokens(filestr$,",") < 4) continue; numpos = numpos + 1; ResizeArrayPreserve(posX,numpos); ResizeArrayPreserve(posY,numpos); ResizeArrayPreserve(posScale,numpos); poslist.AddItem(GetToken(filestr$,",",1)); posX[numpos] = StrToNum(GetToken(filestr$,",",2)); posY[numpos] = StrToNum(GetToken(filestr$,",",3)); posScale[numpos] = StrToNum(GetToken(filestr$,",",4)); } fclose(posfile); } # Close the window, switching to default tool proc DoClose () { if (setDefaultWhenClose) { setDefaultWhenClose = false; View.SetDefaultTool(); } } # Called the first time the tool is activated. func OnInitialize () { # We have to start with a local MAPPROJ instance so that it will be initialized. # Since ToolScripts are not "Run" the global class instances are not initialized. class MAPPROJ tempLatLon; tempLatLon.System = "LatLon"; tempLatLon.Datum = "WGS84"; projLatLon = tempLatLon; dlgform = CreateFormDialog("Viewpoint List",View.Form); WidgetAddCallback(dlgform.Shell.PopdownCallback,DoClose); class PushButtonItem btnItemNew; class PushButtonItem btnItemOpen; class PushButtonItem btnItemSave; class PushButtonItem btnItemAdd; class PushButtonItem btnItemRemove; class PushButtonItem btnItemZoom; class PushButtonItem btnItemClose; btnItemNew = CreatePushButtonItem("New",DoNew); btnItemNew.IconName = "new"; btnItemOpen = CreatePushButtonItem("Open...",DoOpen); btnItemOpen.IconName = "open_"; btnItemSave = CreatePushButtonItem("Save...",DoSave); btnItemSave.IconName = "save"; btnItemAdd = CreatePushButtonItem("Add",DoAdd); btnItemAdd.IconName = "add_sel"; btnItemRemove = CreatePushButtonItem("Remove",DoRemove); btnItemRemove.IconName = "remove_sel"; btnItemZoom = CreatePushButtonItem("Zoom",DoZoom); btnItemZoom.IconName = "apply"; btnItemClose = CreatePushButtonItem("Close",DoClose); btnItemClose.IconName = "delete"; # Icon button rows are automatically attached to their parent form on the left # and right. The "right" widget is unattached by setting the attachment to itself. class XmRowColumn btnrowfile; btnrowfile = CreateIconButtonRow(dlgform,btnItemNew,btnItemOpen,btnItemSave); btnrowfile.TopWidget = dlgform; btnrowfile.TopOffset = 4; btnrowfile.LeftOffset = 4; btnrowfile.RightWidget = btnrowfile; # Unattach class XmRowColumn btnrowlist; btnrowlist = CreateIconButtonRow(dlgform,btnItemAdd,btnItemRemove); btnrowlist.TopWidget = dlgform; btnrowlist.TopOffset = 4; btnrowlist.LeftWidget = btnrowfile; btnrowlist.LeftOffset = 8; btnrowlist.RightWidget = btnrowlist; # Unattach class XmRowColumn btnrowaction; btnrowaction = CreateIconButtonRow(dlgform,btnItemZoom,btnItemClose); btnrowaction.TopWidget = dlgform; btnrowaction.TopOffset = 4; btnrowaction.LeftWidget = btnrowlist; btnrowaction.LeftOffset = 8; btnrowaction.RightOffset = 4; class XmSeparator btnsep; btnsep = CreateHorizontalSeparator(dlgform); btnsep.TopWidget = btnrowfile; btnsep.TopOffset = 4; btnsep.LeftWidget = dlgform; btnsep.RightWidget = dlgform; poslist = CreateScrolledList(dlgform); poslist.TopOffset = 4; poslist.SelectionPolicy = "BROWSE_SELECT"; poslist.VisibleItemCount = 5; WidgetAddCallback(poslist.DefaultActionCallback,DoZoom); class XmScrolledWindow sw; sw = poslist.parent; sw.TopWidget = btnsep; sw.LeftWidget = dlgform; sw.RightWidget = dlgform; sw.BottomWidget = dlgform; } # end of OnInitialize # Called when tool is to be destroyed, will not be called if tool was never activated. func OnDestroy () { DestroyWidget(dlgform); } # end of OnDestroy # Called when tool is activated. proc OnActivate () { dlgform.managed = 1; SetPopupDialogParent(dlgform); setDefaultWhenClose = true; } # end of OnActivate # Called when tool is deactivated (usually when switching to another tool). proc OnDeactivate () { setDefaultWhenClose = false; # SetPopupDialogParent(0); dlgform.managed = 0; } # end of OnDeactivate