Defining the Interaction between a UI Plugin and STK

The UI plugin defines the interaction with the STK Desktop application by implementing required interfaces.

This interaction between STK and all the plugins is done through string commands. Each toolbar button or context menu entry defines the string value of the entry. When the entry is clicked, the STK application broadcasts the string value to all UI plugins currently loaded in the application. Since all UI plugins will receive the string value of your command, you need to make sure that the value will be relatively unique. For example, you can make the string values similar to your plugin name.

For more information on using interfaces to interact with STK, see the IAgUiPlugin Interface and IAgUiPlugin3DNotify Interface below.

IAgUiPlugin Interface

The IAgUiPlugin interface defines how the plugin is added to toolbars and menus. The IAgUiPlugin2 interface is an extension of the IAgUiPlugin. All parts of the interface have to be implemented to build your plugin. So, you need to implement the  OnInitializeToolbar method even if you do not plan to create a new toolbar (but you can leave the method blank). The interfaces require six methods:

To prevent this interference, isolate your root using the Isolate method, then set unit preferences:

[C#]
OnDisplayConfigurationPage(IAgUiPluginConfigurationPageBuilder ConfigPageBuilder)

OnDisplayContextMenu(IAgUiPluginMenuBuilder MenuBuilder)

OnInitializeToolbar(IAgUiPluginToolbarBuilder ToolbarBuilder)

OnDisplayMenu(string MenuTitle, AgEUiPluginMenuBarKind MenuBarKind, IAgUiPluginMenuBuilder2 MenuBuilder)

OnShutdown()

OnStartup(IAgUiPluginSite PluginSite)

The method names are pretty self-explanatory. The OnStartup method input parameter contains a link (pointer) to the host application, in this case the STK Desktop Application.

The Second required interface is IAgUiPluginCommandTarget that implements two methods:

[C#]
Exec(string CommandName, IAgProgressTrackCancel TrackCancel, IAgUiPluginCommandParameters Parameters)

QueryState(string CommandName)

The QueryState method controls whether your command is enabled. The Exec method receives the broadcasted message from STK that the user clicked on a custom button. Again, your plugin will be notified when any custom button is clicked, so your code has to be able to recognize if any of your plugin buttons are clicked.

String literals are used in the examples for UI Plugins. It is a good programming practice to define string literals in a central location, but it is crucial to do it when developing UI Plugins. Each command string is used up to four times in the code. Even copying and pasting string values can introduce an error that cannot be detected by the compiler. We recommend creating member (global) variables for each command string in your UI Plugin.

IAgUiPlugin3DNotify Interface (Detect Mouse Events)

The IAgUiPlugin3DNotify interface allows the UI Plugins to interact with the STK globe. This interface allows UI Plugins to detect mouse events on the globe window.

The IAgUiPlugin3DNotify contains two methods: OnMouseClick and OnPickInfo. As the names imply, OnMouseClick is triggered when the user clicks on the 3D Graphics window and OnPickInfo is triggered after the pick event is completed.

OnMouseClick is triggered by every mouse button action inside the 3D globe window. You most likely will not need to respond on every single click. You have two options. The first option is that you can respond to a specific keyboard/mouse combination. For examples, you can check if the user is holding the “CTRL” key at the same time as left clicking on the globe. The other way is to allow the user to turn on the functionality, respond to any action, and turn off the feature. I believe the second option provides grater affordance.

OnMouseClick signature is as follows:

[C#]
OnMouseClick(IAgUiPlugin3DMouseEventArgs EventArgs, IAgUiPlugin3DNotifyContext Context)

The EventArgs parameter contains the information about the mouse click. KeyState is an enumeration that contains information about which mouse and keyboard keys are pressed. EventArgs also provides the current mouse coordinates and 3D window ID.

The second parameter for both OnMouseClick and OnPickInfo is “Context” of the type IAgUiPlugin3DNotifyContext. Even though the Context looks like a local variable for the methods, it is actually the pointer to the interface that controls the pick interface in the STK Desktop application. In STK engine, most objects are passed by reference. The Context parameter is used to initiate the pick event with the OnMouseClick method and to respond to the pick event in the OnPickInfo method.

Sample Code

The following code creates an enumeration to enable certain behaviors.

[C#]
public enum GlobeEventType

{

Location,

Object,

Globe,

Screen,

None

}

You can choose to get position coordinates (Location), select individual objects (Object), and start pick selection in screen space (Screen) or on the globe (Globe). Your application may not need all these options.

The first three lines of code gets the scene object that corresponds to the Globe window where the mouse click originated:

[C#]
public void OnMouseClick(IAgUiPlugin3DMouseEventArgs EventArgs,

IAgUiPlugin3DNotifyContext
Context)

{

IAgScenario scenario = (IAgScenario)CommonData.StkRoot.CurrentScenario;

IAgStkGraphicsSceneManager sceneManager = scenario.SceneManager;

IAgStkGraphicsScene scene = scenario.SceneManager.Scenes[EventArgs.SceneID - 1];

List<string> objectPaths = new List<string>();

switch (m_globeEventType)

{

case GlobeEventType.Location:

The following code is an example of getting a cartographic location from mouse coordinates:

[C#]
Array position = newobject[] { EventArgs.X, EventArgs.Y };

object[] cartographic = (object[])scene.Camera.WindowToCartographic(“Earth”, ref position);

string latitudeString = cartographic.GetValue(0).ToString();

string longitudeString = cartographic.GetValue(1).ToString();

double altitude = double.Parse(cartographic.GetValue(2).ToString());

break;

Note that we are getting the latitude and longitude as string values and the altitude as a numeric value. You cannot assume that latitude and longitude are numeric because STK accepts units, such as DMS (degrees minutes seconds) as valid angle units. In that case, the default latitude (angle) value would be 40:02:18.9960.


The next example selects an individual object.

The IAgUiPlugin3DNotifyContext interface includes the “Pick” method that returns objects at specified coordinates. We recommend making the selected area a little bigger so that the user does not have to click on the exact pixel.

[C#]
case GlobeEventType.Object:

var objects = Context.PickRectangular(EventArgs.X – 5,EventArgs.Y + 5, EventArgs.X + 5, EventArgs.Y – 5);

foreach; (string s in objects) { objectPaths.Add(s); }

break;

The following two examples start object selections on the globe and in the screen space, respectively. It is also possible to control the appearance of the selection rectangle.

[C#]
case GlobeEventType.Globe:

Context.RubberBandLineWidth = 2;

Context.RubberBandColor = System.Drawing.Color.White;

Context.ActivateRubberBandOnCentralBody();

break;

case GlobeEventType.Screen:

Context.RubberBandLineWidth = 2;

Context.RubberBandColor = System.Drawing.Color.Yellow;

Context.ActivateRubberBand();

break;

case GlobeEventType.None:

break;

default:

break;

}

}

Once the rubber band selection is finished, the OnPickInfo method is called.

[C#]

public void OnPickInfo(IAgUiPlugin3DPickEventArgs EventArgs, IAgUiPlugin3DNotifyContext Context)

{

Array region = EventArgs.SelectedRegion;

List<string> objectPaths = new List<string>();

switch (EventArgs.PickType)


{

case AgEUiPlugin3DPickType>.eUiPlugin3DPickTypeProjectedOnCentralBody:

double west = (double)region.GetValue(0);

double south = (double)region.GetValue(1);

double east = (double))region.GetValue(2);

double north = (double))region.GetValue(3);

var; objects = Context.PickExtent(west, south, east, north);

foreach; (string s in objects) { objectPaths.Add(s); }

break;

case; AgEUiPlugin3DPickType.eUiPlugin3DPickTypeRubberBand:

int; left = (int)(double)region.GetValue(0);

int; bottom = (int)(double)region.GetValue(1);

int; right = (int)(double)region.GetValue(2);

int; top = (int)(double)region.GetValue(3);

var; objects1 = Context.PickRectangular(left, bottom, right, top);

foreach; (string s in objects1) { objectPaths.Add(s); }

break;

default:

break;

}

}

STK 11.2.1 Programming Interface