; $Id: dm_propsheet__define.pro,v 1.3 2005/02/07 20:03:59 qiuym Exp $
;#######################################################################
;
; NAME:
;  dm_propsheet
;
; PURPOSE:
;  an object that generates a property sheet for an idl graphics object
;  handles all registered properties of the idl graphics object
;
; CATEGORY:
;  object
;
; AUTHOR:
;  Yiming Qiu
;  NIST Center for Neutron Research
;  100 Bureau Drive, Gaithersburg, MD 20899-8562
;  United States
;  yiming.qiu@nist.gov
;  Feb, 2005
;
; LICENSE:
;  The software in this file is written by an employee of
;  National Institute of Standards and Technology
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used or if the code in this file is
;  included in another product.
;
;#######################################################################

;if widget is killed
pro dm_propsheet_Exit,tlb
    ;do nothing, killing the object has to be done by obj_destroy
end

;widget event handler
pro dm_propsheet_event,event
    widget_control,event.handler,get_uvalue=self
    if obj_valid(self) then self->event,event
end

;object event handler
pro dm_propsheet::event,event
    catch, myerror
    if myerror ne 0 then begin
       catch,/cancel
       ok=dialog_message(!error_state.msg,/error)
       return
    end
    uname=widget_info(event.id,/uname)
    case strlowcase(uname) of
        'tlb':       begin  ;resize event
                ok      =   widget_info(self.tlb,find_by_uname='okBut')
                geom1   =   widget_info(ok,/geometry)
                geom2   =   widget_info(self.tlb,/geometry)
                sheet   =   widget_info(self.tlb,find_by_uname='propSheet')
                widget_control,sheet,scr_xsize=event.x-2*geom2.xpad,$
                    scr_ysize=event.y-geom1.scr_ysize-4*geom2.ypad-geom2.space
            end
        'propsheet': begin
                if event.type eq 0 then begin   ;property changed
                    value   =   widget_info(event.id,component=event.component,property_value=event.identifier)
                    event.component->setpropertybyidentifier,event.identifier,value
                    if obj_valid(self.parentobject) then self.parentobject->draw,_extra=*self.extra
                    widget_control,self.tlb,/input_focus,/show
                endif
            end
        'okbut':widget_control,self.tlb,/destroy
        'cancelbut': begin
                self.object->setproperty,_extra=*self.oldprop
                if obj_valid(self.parentobject) then self.parentobject->draw,_extra=*self.extra
                widget_control,self.tlb,/destroy
            end
    endcase
end

;cleanup, life cycle method
pro dm_propsheet::Cleanup
    if widget_info(self.extbase,/valid_id) then widget_control,self.extbase,/destroy
    if widget_info(self.tlb,/valid_id) then widget_control,self.tlb,/destroy
    ptr_free,self.oldprop,self.extra
end

;initialization, life cycle method
;usuage:
;   newsheet=obj_new('dm_propsheet',object)
;parameters:
;   object:         an object or array of objects whose properties are to be shown,register_properties keyword should be set for
;                   this object during initialization
;keywords:
;   group_leader:   widget id of the groupleader
;   no_block:       if not set, the dialog is a modal dialog window, which will block all other activities
;   parentobject:   parent object where object is drawn
;   title:          title of the widget window
;   _extra:         extra keywords that you want to use when calling parentobject->draw
function dm_propsheet::Init,object,group_leader=group_leader,no_block=no_block,parentobject=parentobject,title=title,_extra=extra
    if float(!version.release) lt 6.0 then return,0 ;has to be IDL6.0 or later
    catch, myerror
    if myerror ne 0 then begin
       catch,/cancel
       ok=dialog_message(!error_state.msg,/error)
       return,0  ;indicating that an error occurs
    end
    if n_elements(object) eq 0 then return,0 $
    else if obj_valid(object) then  self.object=object[0] $
    else return,0
    if n_elements(parentobject) ne 0 then $
        if obj_valid(parentobject) then begin
            self.parentobject=parentobject
            if n_elements(group_leader) eq 0 then parentobject->getproperty,tlb=group_leader
        endif
    if n_elements(title) eq 0 then title='Property Sheet'
    if n_elements(extra) ne 0 then self.extra=ptr_new(extra) else self.extra=ptr_new(/allocate_heap)
    self.object->getproperty,all=all
    self.oldprop=   ptr_new(all,/no_copy)
    if not keyword_set(no_block) then begin
        self.extbase=widget_base(group_leader=group_leader,map=0)
        self.tlb    =widget_base(group_leader=self.extbase,/col,uname='tlb',/tlb_size_event,title=title,/modal)
    endif else $
        self.tlb    =widget_base(group_leader=group_leader,/col,uname='tlb',/tlb_size_event,title=title)
;    void        =   widget_propertysheet(self.tlb,value=self.object,uname='propSheet')
    void     =    call_function('widget_propertysheet',self.tlb,value=self.object,uname='propSheet')
    geom        =   widget_info(void,/geom)
    widget_control,void,scr_xsize=geom.scr_xsize+30
    row         =   widget_base(self.tlb,/row,/align_center)
    void        =   widget_button(row,value='Cancel',uname='cancelBut')
    void        =   widget_label(row,value='',xsize=15)
    void        =   widget_button(row,value='Ok',uname='okBut')

    dm_center_kid,self.tlb,group_leader
    widget_control,self.tlb,/realize
    widget_control,self.tlb,set_uvalue=self
    xmanager,'dm_propsheet',self.tlb,cleanup='dm_propsheet_Exit',/no_block
    return,1
end

;class definition
pro dm_propsheet__define
    void={dm_propsheet            ,$        ;class name
        extbase:                0L,$        ;extra group leader for the modal widget
        tlb:                    0L,$        ;top level base
        object:          obj_new(),$        ;target object
        parentobject:    obj_new(),$        ;where target object is drawn
        oldprop:         ptr_new(),$        ;old properties,in case cancel button is pressed
        extra:           ptr_new() $        ;point to a structure of extra keywords used in parentobject->draw
    }
end