>  Docs Center  >  Libraries  >  Motley  >  MGH_GUI_BASE__DEFINE






  This class encapsulates a base widget as an object.


  As a non-blocking top-level base:
    mgh_new, 'mgh_gui_base'
  As a blocking top-level base:
    mgh_new, 'mgh_gui_base', /BLOCK, RESULT=ogui
    obj_destroy, ogui
  See discussion on widget life cycles below.
  As a child of another MGH_GUI_BASE object:
    ochild = oparent->NewChild('MGH_GUI_Base', /OBJECT)


  The following properties (ie keywords to the Init, GetProperty &
  SetProperty methods) are supported:
    ALL (Get)
      This property is a structure wrapping the object's other
      gettable properties, with the exception of UVALUE.
    BLOCK (Init, Get)
      Set this property to 1 to create a blocking widget. Default
      (0) is non-blocking. This property is passed to XMANAGER when
      it is called by the Manage method. Note the section on
      blocking environments in RESTRICTIONS below.
    FRAME (Init)
      Specify the width of the frame around the base. Default is 0.
    GEOMETRY (Get)
      This keyword returns a WIDGET_GEOMETRY structure that
      describes the offset and size information for the GUI base. It
      combines geometry data from the main and layout bases in an
      attempt to preserve the illusion for children that they belong
      to a single base. I'm not sure if it is 100% successful in
      this respect, but then I'm not sure that the geometry data
      reported by IDL for the bases themsleves is 100% correct.
    GROUP_LEADER (Init, Set)
      The widget ID of an existing widget that serves as "group
      leader" for the newly-created widget. When a group leader is
      killed, for any reason, all widgets in the group are also
      destroyed. The widget can be in more than one group. Each time
      the SetProperty method is used to specify a group leader this
      adds to the existing list of group leaders. Group leader
      associations cannot be destroyed.
    MBAR (Init)
      This is a flag that should be set to create a menu bar. Unlike
      the keyword of the same name to WIGET_CONTROL, it does NOT
      return the menu bar ID.
    MODAL (Init, Get)
      Set this property to 1 to create a modal widget. Default (0)
      is non-modal. If the MODAL property is set, then a
      GROUP_LEADER must also be specified at initialisation.
    MANAGED (Get, Set)
      This property applies only to a top-level base. It equals 1 if
      the base is currently being managed by XMANAGER, otherwise
      0. If it is set during or after initialisation then the Manage
      method is called. Once a based is being managed, attempts to
      set or unset the property have no effect. Default is 1.
    NOTIFY_REALIZE (Init, Get)
      Set this property to 1 to specify that the object's
      NotifyRealize method will be called when its base is
      realized. Default (0) is not to call NotifyRealize. Note that
      this property is an integer, not a string like the
      NOTIFY_REALIZE keyword to IDL's widget routines. Also note
      that if the base is a child whose parent is already realised
      at the time the child is created, then the NotifyRealize
      method will never be called! (This is a "feature" of IDL's
      widget routines.)
    PROCESS_EVENTS (Init, Get, Set)
      This property applies only to a child base. Set it to 0 to
      specify that the base will *not* intercept and process events
      from its children. Default (1) is to process. An MGH_CW_Base
      with PROCESS_EVENTS equal to 0 is essentially a base widget
      with a few useful widget-management methods.
    REALIZED (Init, Get, Set)
      This property equals 1 if the base has been realised,
      otherwise 0. If it is set during or after initialisation then
      the Realize method is called. Once a based has been realised,
      attempts to set or unset the property have no effect. Default
      is 1 for top-level bases and 0 for child bases.
    SENSITIVE (Init, Get, Set)
      This property equals 1 if the base is sensitive, otherwise
      0. Note that a base will be reported as insensitive if any of
      its parents is insensitive.
    TITLE (Init, Get, Set)
      This property applies only to a top-level base. It specifies
      the title, which appears in the title bar.
    TLB_SIZE_EVENTS (Init, Get, Set)
      This property equals 1 if the base reports events when
      resized, otherwise 0. Behaviour for non-top-level bases is
      undefined; as far as I can tell, the property can
      be changed and retrieved but has no effect.
    UPDATE (Get, Set)
      Set this property to 1 to enable display updates, 0 to disable
      them. As far as I can tell, the UPDATE status of a widget
      cannot be changed until it has been realised.
    VALID (Get)
      This property equals 1 if the base has a valid ID, otherwise
      0. Note that a GUI base object can persist after its
      associated widgets have been destroyed, so it is possible to
      have VALID equal to 0
    VISIBLE (Init, Get, Set)
      Set this property to 1 to make the widget base visible, 0 to
      make it invisible. A modal widget cannot be made
      invisible--this is a limitation of WIDGET_CONTROL--and
      attempts to do so will be ignored.


  In addition to Init, Cleanup, GetProperty, SetProperty...
    About (Procedure)
      Print information about the object & its environment to the
      console. This method is conventionally invoked via a
      "Help.About" menu item. Subclasses of MGH_GUI_Base may call
      the superclass's method then add information of their own.
    Align (Procedure)
      Reposition the main base relative to the screen or to another
      widget. This method is intended to be used on top-level bases
      only. It might be useful to extend it to child bases.
    Dispose (Procedure)
      Add one or more objects to the disposal container. They will
      be destroyed when the object is destroyed.
    Event (Function)
        Default event handler. See the section below on
        event-handler functions.
    EventBase (Function)
    EventMenuBar (Function)
      Handles events from the main base and menu bar,
      respectively. For an MGH_GUI_Base object, these methods call
      EventUnexpected. Note that EventMenuBar only handles events
      received form the menu-bar base itself, not from its
      children. To ensure that events generated by the menu-bar
      children do get handled by EventMenuBar, install a
      MGH_GUI_PDMenu object or CW_PDMENU compound widget on the
      menu-bar base.
    EventGeneric (Function)
      This method wraps the events it receives and passes them
      on. It is intended to be called only by child bases to provide
      generic event handling. An event structure is created with ID
      equal to self.base and the original event is stored in tag
      EVENT. EventGeneric is called from EventUnexpected when the
      current object is a child and is of class "MGH_CW_Base' (not a
      subclass). It can also be called selectively by subclasses. If
      it is called by a top-level base object the event will be
      swallowed by the event-handler procedure.
    EventUnexpected (Function)
      Handle events that have not otherwise been handled. If the
      current object is a child of class "MGH_CW_Base' (not a
      subclass) then this method employs EventGeneric (see above) to
      carry out generic processing, then passes the event
      on. Otherwise the method prints a warning message and returns
    Finalize (Procedure)
      This is my attempt to resolve widget initialisation and
      destruction issues in a simple and robust way. I think I'm
      almost there! The Finalize method is normally called at the
      end of the Init method and sets up the widget object so it can
      interact with other widgets. For a non-blocking, top-level
      base it calls the Realize and Manage methods. For a
      blocking/modal top-level base it calls the Realize method
      only; the creator of the object is expected to call
      Manage. For child widgets it calls the NotifyRealize method *if*
      the parent has already been realized.
      Finalize accepts a single, optional, string parameter. If this
      parameter is specifed an object, will be finalised only if its
      class name matches the argument (case-insensitively). Normally
      the Init method of a subclass of MGH_GUI_Base (say
      MGH_GUI_MyClass) will end with
        self->Finalize, 'MGH_GUI_MyClass'
      Then finalisation will be carried out for members of
      MGH_GUI_MyClass, but for all subclasses it will be postponed,
      leaving the subclass's Init method to carry out finalisation.
      There are some cases where one will need to call Finalize
      unconditionally. This should be done, for example, in classes
      that want to allow the user to interact with the object during
      the Init method (see MGH_Surface_Movie). It is also
      recommended when one wishes to set the alignment of a
      top-level base, because this cannot be done until the base has
      been realised (see MGH_Conductor).
    FindChild (Function)
      Find a child widget by name.
    FlushEvents (Procedure)
      The FlushEvents method causes all events queued for the
      top-level base to be processed. It can be called periodically
      by a routine that is controlling the widget, to allow the user
      to interact with the widget. This allows the user to do
      inappropriate things but is sometimes very valuable.
    GetBase (Function)
      Shorthand for GetProperty, BASE=...
    Iconify (Procedure)
      Minimise or restore the top-level base.
    IsTLB (Function)
      Return 1 if the base is a top-level base, 0 if it is a child.
    Kill (Procedure)
      Kill the widget hierarchy.
    Manage (Procedure)
      Submit the widget hierarchy to XMANAGER; if it is already
      managed, return without error. If the applicaton is blocking
      or modal, then this method returns only when the widget
      hierarchy is destroyed.
      This method will normally be called, if necessary, from the
      Finalize method, with the important exception of a blocking or
      modal top-level base, where the creator is reponsible for
      calling Manage. (There's a good reason for this, but I keep
      forgetting what it is.)
    NewChild (Function & Procedure)
      Create a new widget, either invoking a function or creating an
      object. Optionally return the widget ID (function) or object
      reference (object). Note that NewChild passes keywords to the
      widget creator by reference; this is required because some
      widget-creation functions (CW_BGROUP for one) pass information
      back to the caller via keyword arguments.
    Realize (Procedure)
      Realise the widget hierarchy;; if it is already realised,
      return without error.
    Show (Procedure)
      Show or hide the top-level base.
    Update (Procedure)
      Revise the widget appearance so that it agrees with the state
      of the associated object. MGH_GUI_Base's Update procedure does
      nothing and may be overridden as necessary in subclasses. It
      is defined here to guarantee that all subclasses support this
  When running an object widget application, it is important to know
  whether the Manage method (which calls XMANAGER) will return
  immediately, or whether it will return only when the widget tree
  has been destroyed. I will call the former non-blocking operation
  and the latter blocking operation, but note that when the terms
  blocking and non-blocking are discussed in the IDL documentation
  they refer to whether the command-line is available, which is not
  quite the same thing.
  The DESTROY property of an MGH_GUI_Base (and any subclass thereof)
  controls whether the object is destroyed in the widget cleanup
  method. The default is to set DESTROY to 1 for non-blocking
  operation and 0 for blocking. The rationale is that for
  non-blocking operation, destruction of the widget hierarchy will
  occur some indefinite time after the Manage method returns, by
  which time the creator will have exited or forgotten the object
  reference. So the creator cannot be responsible for destroying the
  object. On the other hand for blocking operation, destruction of
  the widget hierarchy will have occurred before the Manage method
  returns. If the object is left intact (though widget-less) then
  the creator has an opportunity to query it before destroying
  it. Furthermore if Manage has been called from an object's Init
  method, then destroying the object inside the Manage method leads
  to an error (though there is a workaround for this).
  In setting the default value for the DESTROY property, it is
  assumed that blocking will occur if either the BLOCK or the MODAL
  property has been set, otherwise it won't. This seems to work fine
  on the only platform I have used, i.e. IDLDE for Windows. I expect
  that it would work on most other platforms but NOT on a platform
  (like the VMS tty) that doesn't support non-blocking operation. (I
  don't know about run-time IDL--I may getting around to checking
  this out some day.) I don't know how to detect if a platform
  supports non-blocking operation. In XMANAGER there is a call to
  WIDGET_INFO using an undocumented keyword (/XMANAGER_BLOCK) that
  looks as if it should do the trick, but what it returns is whether
  the command line is active, i.e. the second sense of blocking
  rather than the first.
  Therefore the advice is: on platforms that do not support
  non-blocking operation, always set the BLOCK property to 1.
  MGH_GUI_Base taps into the event-handling framework supported by
  IDL's widget routines, notably XMANAGER and WIDGET_EVENT, as
  follows. An event is a structure with, as a minimum, the tags ID,
  TOP and HANDLER. Events are generated by widget elements and are
  passed up through the widget tree. At any level in the tree, a
  widget event can be intercepted by an event-handler function or
  procedure. An event-handler function takes an event as its
  argument and outputs an event (which may or may not be the same
  one) as its return value. An event-handler function indicates that
  an event has finally been handled by returning a non-structure
  value. Otherwise the event is passed further up the tree. An
  event-handler procedure never passes events on.
  An MGH_GUI_Base intercepts events generated by its children by
  registering an event procedure with XMANAGER (called by the Manage
  method). This event procedure (which is called MGH_GUI_BASE_EVENT,
  though this should not be be of any interest outside the
  MGH_GUI_Base class) is passed the widget ID of the top-level base
  and from this retrieves an object reference. (The convention that
  supports this is documented in the MGH_WIDGET_SELF function.) It
  then calls the object's Event method.
  MGH_GUI_Base's Event method supports a generic method of event
  handling known as callbacks. A callback stores an object-method
  pair inside a structure, attached to the UVALUE of an
  event-originating widget or compound
  widget. MGH_GUI_Base::Event(event) tests the widget pointed to by
  the ID field of each event to see if it contains a callback
  structure. If it does, then the Event method checks to ensure that
  the callback's object is the same as "self". If not, this is
  treated as a non-fatal error. (The obvious alternative is to call
  the object-method pair specified in the callback. There may be
  situations where this is attractive but on the whole I think it
  represents a major violation of encapsulation and sho should be
  avoided). If all checks have been passed
  MGH_GUI_Base::Event(event) evaluates
    call_method(method, self, event)
  and returns the result to IDL's event-handler framework. In the
  case of an MGH_GUI_Base this is a procedure so it swallows the
  event whatever its value.
  Callbacks are named structures of type MGH_WIDGET_CALLBACK. The
  structure is defined by MGH_WIDGET_CALLBACK__Define, they are
  created by the widget base's Callback method, and the question,
  "Is this a callback" is answered by the function MGH_IS_CALLBACK.
  If MGH_GUI_Base::Event() fails to find a callback associated with
  an event, and this event is still valid, then it expresses its
  surprise by calling self->EventUnexpected(event). As defined for
  MGH_GUI_Base, this prints a warning and swallows the event. This
  could be overridden in a subclass, I guess.
  Realization of the widget creates problems in the case where a
  child base is added to an already-realized parent. In this case
  the child is immediately realized, but in IDL 5.5 and earlier the
  NOTIFY_REALIZE procedure was never called. In IDL 5.6 the child's
  NOTIFY_REALIZE procedure *is* called, provided it is specified in
  the call to WIDGET_BASE that creates the child. The latter
  behaviour is more correct, but creates problems when the child is
  an MGH_GUI_BASE object, because MGH_GUI_BASE_NOTIFY_REALIZE needs
  to retrieve an object reference, and that is not known when the
  base is first created by a call to WIDGET_BASE. So the sequence is
    - Create the objects base widget with a call to WIDGET_BASE,
      *without* specifying the NOTIFY_REALIZE property.
    - Create the invisible child widget and store the reference to
      "self" there.
    - Set the base's NOTIFY_REALIZE property with a call to
    - In the Finalize method, check if the parent has been
      realized. If so, call NotifyRealize.
  This sequence should work with IDL versions before 5.6
  This software is provided subject to the following conditions:
  1. NIWA makes no representations or warranties regarding the
    accuracy of the software, the use to which the software may
    be put or the results to be obtained from the use of the
    software. Accordingly NIWA accepts no liability for any loss
    or damage (whether direct of indirect) incurred by any person
    through the use of or reliance on the software.
  2. NIWA is to be acknowledged as the original author of the
    software where the software is used or presented in any form.

Modification History

  Mark Hadfield, 1999-11:
    Written as MGHwidgetBase, borrowing freely from ideas of Struan
    Gray (http://www.sljus.lu.se/stm/IDL/Obj_Widgets/).
  Mark Hadfield, 2000-07:
    Added the DESTROY property, as part of a general re-think of
    widget object life cycles.
  Mark Hadfield, 2001-06:
    Renamed MGH_GUI_Base and thoroughly overhauled:
    - Operation as a child base now supported
    - Handling of keywords is more robust.
    - Several standard event handling functions are specified. Event
      handling methods for each child widget can now be specified
      via callbacks.
  Mark Hadfield, 2001-10:
    - Increased maximum number of arguments in NewChild method to 3.
    - Updated for IDL 5.5.
  Mark Hadfield, 2002-10:
    - Changes were made to the initialisation sequence wrt the
      NOTIFY_REALIZE procedure. See "A note on realization" above.
    - Updated for IDL 5.6

© 2020 Harris Geospatial Solutions, Inc. |  Legal
My Account    |    Store    |    Contact Us