This example creates a custom task with a custom UI class named Multiple_Outputs_UI to wrap two different export tasks in one workflow step.

Create a Custom UI


Copy and paste this code into the IDL Editor. Save the file as multiple_outputs_ui_define.pro.

FUNCTION Multiple_Outputs_UI::Init, _REF_EXTRA=refExtra
COMPILE_OPT IDL2, HIDDEN
 
; Build and customize the UI container
self.oContainer = IDLContainer_UI(/COLUMN)
 
self.oContainer['raster'] = IDLContainer_UI(/CAN_TOGGLE, $
  TOGGLE_LABEL='Export Image')
self.oContainer['raster', 'raster_uri'] = ENVIURI_UI($
  TITLE='File:')
 
self.oContainer['vector'] = IDLContainer_UI(/CAN_TOGGLE, $
  TOGGLE_LABEL='Export Vector')
self.oContainer['vector', 'vector_uri'] = ENVIURI_UI($
  TITLE='File:')
 
return, self.ENVIParameterUI::Init(_EXTRA=refExtra)
END
 
;-------------------------------------------------
PRO Multiple_Outputs_UI::Cleanup
COMPILE_OPT IDL2, HIDDEN
 
IF (Obj_Valid(self.oContainer)) THEN BEGIN
  Obj_Destroy, self.oContainer
ENDIF
 
self.ENVIParameterUI::Cleanup
END
 
;-------------------------------------------------
; Populate the UI with parameters based on the 
; supplied value
PRO Multiple_Outputs_UI::SetValue, value
COMPILE_OPT IDL2, HIDDEN
 
self.oContainer.SetValue, value
END
 
;--------------------------------------------------
; Return the parameter value defined by the user and
; stored by the UI
FUNCTION Multiple_Outputs_UI::GetValue, ERROR=error
COMPILE_OPT IDL2, HIDDEN
 
error = ''
 
Return, self.oContainer.GetValue(ERROR=error)
END
;--------------------------------------------------
; Build and display the UI
PRO Multiple_Outputs_UI::BuildUI, wBase, xSize
COMPILE_OPT IDL2, HIDDEN
 
self.oContainer.BuildUI, wBase, xSize
END
;--------------------------------------------------
PRO Multiple_Outputs_UI__Define
COMPILE_OPT IDL2, HIDDEN
 
!null = {Multiple_Outputs_UI, $
  inherits  ENVIParameterUI, $
  oContainer: Obj_New() $
  }
END

Create a Custom Task


Copy and paste this code into the IDL Editor. Save the file as multiple_outputs.pro. Then compile and run the program.

; This is a callback routine to invoke before Step 2 executes.
; Create a hash of user-specified values.
PRO multiple_outputs_step2_PrebuildUI, workflow, _REF_EXTRA=refExtra
COMPILE_OPT IDL2
 
IF (Isa(workflow.CURRENT_STEP.task.input_filenames, /NULL)) THEN BEGIN
  hValue = Hash()
  hValue['raster'] = Hash()
  hValue['raster', 'raster_uri'] = !null
  hValue['vector'] = !null
  workflow.CURRENT_STEP.task.input_filenames = hValue
ENDIF
END
 
;--------------------------------------------------------------
; This is a callback routine to execute Step 2, where two
; export tasks are managed in one step
PRO multiple_outputs_step2_execute, $
  INPUT_RASTER=inputRaster, INPUT_FILENAMES=inputFilenames
COMPILE_OPT IDL2
 
IF (~Isa(inputFilenames, 'Hash')) THEN BEGIN
  return
ENDIF
 
IF (Isa(inputFilenames['raster'], 'Hash')) THEN BEGIN
  task = ENVITask('ExportRasterToENVI')
  task.INPUT_RASTER = inputRaster
  task.OUTPUT_RASTER_URI = inputFilenames['raster', 'raster_uri']
  task.Execute
ENDIF ELSE BEGIN
  Print, 'skipping raster
ENDELSE
 
IF (Isa(inputFilenames['vector'], 'Hash')) THEN BEGIN
  task = ENVITask('ClassificationToShapefile')
  task.INPUT_RASTER = inputRaster
  task.OUTPUT_VECTOR_URI = inputFilenames['vector', 'vector_uri']
  task.Execute
ENDIF ELSE BEGIN
  Print, 'skipping vector
ENDELSE
 
END
 
;---------------------------------------------------------------
; This is a callback for modifying the task style sheet
PRO multiple_outputs_step2_apply_stylesheet, styleSheet, $
  _REF_EXTRA=refExtra
COMPILE_OPT IDL2
 
styleSheet['show_titles'] = !false
 
ENVIWorkflowStep.StyleSheetSetUIClass, styleSheet, $
'input_filenames', 'Multiple_Outputs_UI'
END
 
;---------------------------------------------------------------
; This is the main workflow routine
PRO multiple_outputs
COMPILE_OPT IDL2
 
; Start the application
e = ENVI()
 
; This is only necessary because this UI class is not 
; part of the ENVI distribution.
cd, ROUTINE_DIR(), current=current
resolve_routine, 'multiple_outputs_ui__define'
cd, current
                
; Create and customize the workflow
workflow = ENVIWorkflow()
workflow.TITLE = 'Custom Task Workflow'
 
; Add a step for ISODATA classification
step1 = ENVIWorkflowStep()
step1.TASK = ENVITask('ISODATAClassification')
step1.TIMELINE_TITLE = 'Classify'
 
; Add a step for exporting results
step2 = ENVIWorkflowStep()
step2.TITLE = 'Export Results'
step2.SUBTITLE = 'This step wraps the work of two different tasks.'
step2.TIMELINE_TITLE = 'Export'
step2.SHOW_DISPLAY_RESULT = 0
step2.TASK.AddParameter, ENVIParameterENVIRaster($
  NAME='input_raster', $
  DISPLAY_NAME='Input Raster', $
  DIRECTION='input', $
  /REQUIRED)
step2.Task.AddParameter, IDLParameterHash($
  NAME='input_filenames', $
  DIRECTION='input')
step2.callback_apply_stylesheet = 'multiple_outputs_step2_apply_stylesheet'
step2.callback_preBuildUI = 'multiple_outputs_step2_PrebuildUI'
step2.callback_execute = 'multiple_outputs_step2_execute'
 
; Connect workflow steps
workflow.Connect, step1, 'output_raster', step2, 'input_raster'
 
; Build and display the UI
e.UI.CreateWorkflowDialog, workflow
END

Result:

See Also


Customize Workflows