Rotate display
RotateDisplay.cpp
// Copyright 2011 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

  
#include "RotateDisplay.h"

// Motif Widgets
Widget toplevel;                // application
Widget mainwindow;              
Widget mainform;      
Widget toppanel;
Widget loadbutton;
Widget loadtext;
Widget bottompanel;
Widget fulldatabutton;
Widget howtolabel;
Widget mapwidget;
Widget selectfile;

// Control Interfaces
IMapControl2Ptr ipMapControl;

// Interfaces
IPointPtr ipPoint;

bool bRotating;

int main(int argc, char* argv[])
{
  // Initialize the engine
  ::AoInitialize(NULL);
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    esriLicenseStatus status;
    ipInit->Initialize(esriLicenseProductCodeEngine, &status);
  }

  XtSetLanguageProc(NULL, NULL, NULL);
  XtAppContext app_context;
  
  // Initialize the Motif toolkit and create the parent widget
  toplevel = XtVaAppInitialize(&app_context, "XApplication", 
                               NULL, 0, &argc, argv, NULL, NULL);
  XtVaSetValues(toplevel, 
                XmNtitle, "Motif Widget Engine Controls Example",
                NULL);
  
  // Set the application size by resizing the created widget
  XtResizeWidget(toplevel, 600, 480, 1);
  
  mainwindow = XtVaCreateWidget("mainwindow", 
                                xmMainWindowWidgetClass, toplevel,
                                NULL);
  
  mainform = XtVaCreateWidget("mainform",
                              xmFormWidgetClass,        mainwindow,
                              XmNtopAttachment,         XmATTACH_WIDGET,
                              XmNtopWidget,             mainwindow,
                              XmNbottomAttachment,      XmATTACH_WIDGET,
                              XmNbottomWidget,          mainwindow,
                              XmNleftAttachment,        XmATTACH_WIDGET,
                              XmNleftWidget,            mainwindow,
                              XmNrightAttachment,       XmATTACH_WIDGET,
                              XmNrightWidget,           mainwindow,
                              XmNfractionBase,          100,
                              NULL);
  
  // Create and place toppanel
  toppanel = XtVaCreateWidget("toppanel",
            xmFormWidgetClass,    mainform,
            XmNtopAttachment,     XmATTACH_FORM,
            XmNrightAttachment,   XmATTACH_FORM,
            XmNleftAttachment,    XmATTACH_FORM,
            XmNheight,            70,
            NULL);

  // Create and place loadbutton
  XmString label = XmStringCreateLocalized("Load Map Document");
  loadbutton = XtVaCreateWidget("loadbutton",
        xmPushButtonWidgetClass, toppanel,
        XmNlabelString,          label,
        XmNleftAttachment,       XmATTACH_FORM,
        XmNheight,               35,
        XmNwidth,                150,
        NULL);
  XmStringFree(label);
  XtAddCallback(loadbutton, XmNactivateCallback, LoadClick, NULL);

  // Create and place loadtext
  loadtext = XtVaCreateWidget("loadtext",
            xmTextFieldWidgetClass,   toppanel,
            XmNleftAttachment,        XmATTACH_FORM,
            XmNrightAttachment,       XmATTACH_FORM,
            XmNbottomAttachment,      XmATTACH_FORM,
            XmNtopAttachment,         XmATTACH_WIDGET,
            XmNtopWidget,             loadbutton,
            XmNeditable,              False,
            XmNcursorPositionVisible, False,
            XmNheight,                35,
            NULL);

  // Create and place bottompanel
  bottompanel = XtVaCreateWidget("bottompanel",
         xmFormWidgetClass,    mainform,
         XmNbottomAttachment,  XmATTACH_FORM,
         XmNrightAttachment,   XmATTACH_FORM,
         XmNleftAttachment,    XmATTACH_FORM,
         XmNheight,            35,
         NULL);

  // Create and place fulldatabutton
  label = XmStringCreateLocalized("Zoom to Full Data");
  fulldatabutton = XtVaCreateWidget("fulldatabutton",
                                    xmPushButtonWidgetClass, bottompanel,
            XmNlabelString,          label,
            XmNleftAttachment,       XmATTACH_FORM,
            XmNheight,               35,
            XmNwidth,                150,
            NULL);
  XmStringFree(label);
  XtAddCallback(fulldatabutton, XmNactivateCallback, FullDataClick, NULL);

  // Create and place howtolabel
  label = XmStringCreateLocalized("   Left mouse button to zoom in on a selection.\n   Right mouse button to rotate the display.");
  howtolabel = XtVaCreateWidget("howtolabel",
        xmLabelWidgetClass,  bottompanel,
        XmNlabelString,      label,
        XmNalignment,        XmALIGNMENT_BEGINNING,
        XmNleftAttachment,   XmATTACH_WIDGET,
        XmNleftWidget,       fulldatabutton,
        XmNrightAttachment,  XmATTACH_FORM,
        XmNtopAttachment,    XmATTACH_FORM,
        XmNbottomAttachment, XmATTACH_FORM,
        XmNheight,           100,
        NULL);
  XmStringFree(label);

  // Create and place the MapControl
  mapwidget = XtVaCreateWidget("mapwidget",
                               mwCtlWidgetClass,        mainform,
                               XmNtopAttachment,        XmATTACH_WIDGET,
             XmNtopWidget,            toppanel,
                               XmNleftAttachment,       XmATTACH_FORM,
                               XmNrightAttachment,      XmATTACH_FORM,
             XmNbottomAttachment,     XmATTACH_WIDGET,
                               XmNbottomWidget,         bottompanel,
             MwNprogID,               AoPROGID_MapControl,
                               NULL);
  MwCtlGetInterface(mapwidget, (IUnknown**)&ipMapControl);

  // Create a file selection dialog with a *.mxd mask
  XmString mask;
  Arg args[1];
  mask  = XmStringCreateLocalized("*.mxd");
  XtSetArg(args[0], XmNdirMask, mask);
  selectfile = XmCreateFileSelectionDialog(mainform, "Select File", args, 1);
  XtAddCallback(selectfile, XmNokCallback, FileSelected, NULL);
  XtAddCallback(selectfile, XmNnoMatchCallback, FileSelected, NULL);
  XtAddCallback(selectfile, XmNcancelCallback, FileSelected, NULL);

  // Disable the Help button
  XtSetSensitive(XmFileSelectionBoxGetChild(selectfile, XmDIALOG_HELP_BUTTON), 
                 False);

  // Set the name of the FileSelectionDialog  
  XmString title;
  title = XmStringCreateLocalized("Browse to Map Document");
  XtVaSetValues(selectfile, XmNdialogTitle, title, NULL);
  XmStringFree(title);

  XtManageChild(mainwindow);              
  XtManageChild(mainform);      
  XtManageChild(toppanel);
  XtManageChild(loadbutton);
  XtManageChild(loadtext);
  XtManageChild(bottompanel);
  XtManageChild(fulldatabutton);
  XtManageChild(howtolabel);
  XtManageChild(mapwidget);

  // Handle the window manager message that the window is about to be closed 
  Atom wm_delete_window = XmInternAtom(XtDisplay(toplevel), 
                                       "WM_DELETE_WINDOW", 
                                       FALSE);
  XmAddWMProtocolCallback(toplevel, wm_delete_window, 
                          CloseAppCallback, NULL);

  // Listen for MapControlEvents
  MapControlEvents2* mapEvents = new MapControlEvents2();
  IEventListenerHelperPtr 
    ipMapControlEvent2Helper(CLSID_MapControlEvents2Listener);
  ipMapControlEvent2Helper->Startup(
    static_cast<IMapControlEvents2Helper*> (mapEvents));
  ipMapControlEvent2Helper->AdviseEvents(ipMapControl, NULL);

  // Disable the map control???????
  //ipMapControl->put_Enabled(VARIANT_FALSE);
  
  // Get the IPoint interface
  ipPoint = IPointPtr(CLSID_Point);

  // Start the application running 
  XtRealizeWidget(toplevel);
  MwCtlAppMainLoop(app_context);
}

// Function called when WM_DELETE_WINDOW protocol is passed
void CloseAppCallback(Widget w, XtPointer client_data, XtPointer call_data)
{
  // Uninitialize the engine
  {
    IAoInitializePtr ipInit(CLSID_AoInitialize);
    ipInit->Shutdown();
  }
  ::AoUninitialize();

  exit(0);
}

void LoadClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  XtManageChild(selectfile);
}

void FileSelected(Widget w, XtPointer client_data, XtPointer call_data)
{
    char* fileName;
  XmFileSelectionBoxCallbackStruct *cbs;
  cbs = (XmFileSelectionBoxCallbackStruct *)call_data;
  
  // Hide the dialog if they canceled
  if (cbs->reason == XmCR_CANCEL)
    {
      XtUnmanageChild(w);
      return;
    }

  // Get the file name and check for errors
  if (!XmStringGetLtoR(cbs->value, XmFONTLIST_DEFAULT_TAG, &fileName))
    {
      ShowMessage("File Open Error", "INTERNAL ERROR PROCESSING FILE");
      XtUnmanageChild(w);
      return;
    }
  if (!*fileName) 
    {
      ShowMessage("File Open Error", "NO FILE SELECTED");
      XtUnmanageChild(w);
      return;
    }

  // Try to add the layer to the MapControl
  if (cbs->reason != XmCR_NO_MATCH)
    {
      VARIANT_BOOL varbool;
      ipMapControl->CheckMxFile(CComBSTR(fileName), &varbool);
      if (varbool)
        {
          // Set mouse pointers
          ipMapControl->put_MousePointer(esriPointerHourglass);

          // Set the text box to the file path    
          XmTextFieldSetString(loadtext, fileName);
          
          // Load the map document
          ipMapControl->LoadMxFile(CComBSTR(fileName));

          // Set mouse pointers
          ipMapControl->put_MousePointer(esriPointerDefault);
        }
      else
        {
          ShowMessage("Invalid MXD", "Not a valid ArcMap Document");
          XtUnmanageChild(w);
          return;
        }
 
      // Hide file selection dialog
      XtUnmanageChild(w);
    }
}

void FullDataClick(Widget w, XtPointer client_data, XtPointer call_data)
{
  IEnvelopePtr ipFullExt;
  ipMapControl->get_FullExtent(&ipFullExt);
  ipMapControl->put_Extent(ipFullExt);
}

// Dispay a MessageDialog
void ShowMessage(char *dialogtitle, char *text)
{
  // Create a MessageDialog
  Widget err;
  Arg args[1];
  XmString str;
  int n = 0;
  str = XmStringCreateLocalized(text);
  XtSetArg(args[n], XmNmessageString, str);
  n++;
  err = XmCreateMessageDialog(mainwindow, "error", args, n);
  
  // Remove the help and cancel buttons
  Widget remove1; 
  remove1 = XmMessageBoxGetChild(err, XmDIALOG_HELP_BUTTON);
  XtUnmanageChild(remove1);
  Widget remove2; 
  remove2 = XmMessageBoxGetChild(err, XmDIALOG_CANCEL_BUTTON);
  XtUnmanageChild(remove2);
  
  // Set the title of the MessageDialog
  XmString title;
  title = XmStringCreateLocalized(dialogtitle);
  XtVaSetValues(err, XmNdialogTitle, title, NULL);
  XmStringFree(title);
  
  XtManageChild(err);
  XmStringFree(str);
}