function CW_itMultiDataLevel, Parent, oUI, $ COLORS=colors, $ COLUMN=column, $ DATA_LABEL=dataLabel, $ DATA_USE_INDEX=useDataIndex, $ DATA_OBJECTS=dataObjects, $ DATA_RANGE=dataRange, $ EXTENDABLE_RANGES=extendRanges, $ INITIAL_VALUES=initialValues, $ LEVEL_NAMES=levelNames, $ NLEVELS=nLevels, $ PALETTE_OBJECTS=paletteObjects, $ UVALUE=uvalue, $ VERTICAL=vertical, $ XSIZE=xSize, $ YSIZE=ySize ;; Pragmas compile_opt idl2, hidden nparams = 2 ; must be defined for cw_iterror @cw_iterror if N_ELEMENTS(xSize) eq 0 then $ xSize = 256 if N_ELEMENTS(ySize) eq 0 then $ ySize = 128 ;; Make sure that there is at least one level nLevels = N_ELEMENTS(nLevels) eq 0 ? 1 : nLevels nDataSets = N_ELEMENTS(dataObjects) ;; Check to be sure data objects are valid. for i=0, nDataSets-1 do $ if ~OBJ_VALID(dataObjects[i]) then return, 0 bHaveInitValues = 0b if (N_ELEMENTS(initialValues) gt 0) then begin if N_ELEMENTS(initialValues) ne nLevels*nDataSets then begin oTool = oUI->GetTool() if (OBJ_VALID(oTool)) then $ oTool->SignalError, $ IDLitLangCatQuery('UI:cwMultDataLevel:BadInitVal') endif else $ bHaveInitValues = 1b endif ;; main base wBase = WIDGET_BASE(Parent, /COLUMN, /FRAME, SPACE=0, $ EVENT_FUNC='CW_itMultiDataLevel_Event', UVALUE=uvalue, $ PRO_SET_VALUE='CW_itMultiDataLevel_SetValue', $ FUNC_GET_VALUE='CW_itMultiDataLevel_GetValue') ;; Prepare selection drop list wRow = WIDGET_BASE(wBase, /ROW, YPAD=0) if (N_ELEMENTS(dataLabel) ne 0) then $ wLabel = WIDGET_LABEL(wRow, VALUE=dataLabel) if (KEYWORD_SET(useDataIndex)) then $ dropValue = ['000'] $ else $ dynamicResize = 1 wDropList = WIDGET_DROPLIST(wRow, VALUE=dropValue, $ DYNAMIC_RESIZE=dynamicResize) if nDataSets gt 0 then begin dataNames = STRARR(nDataSets) if (KEYWORD_SET(useDataIndex)) then begin for i=0, nDataSets-1 do $ dataNames[i] = STRTRIM(STRING(i),2) endif else begin for i=0, nDataSets-1 do begin dataObjects[i]->GetProperty, NAME=dataName dataNames[i] = dataName endfor endelse WIDGET_CONTROL, wDropList, SET_VALUE=dataNames endif WIDGET_CONTROL, wDropList, SENSITIVE=nDataSets gt 1 ;; Apply all button wApplyBase = WIDGET_BASE(wBase, /NONEXCLUSIVE, YPAD=0, SPACE=0) wApplyAll = WIDGET_BUTTON(wApplyBase, $ VALUE=IDLitLangCatQuery('UI:cwMultDataLevel:ApplyAll'), $ SENSITIVE = nDataSets gt 1) ;; Now the data level widget. wDataLevel = CW_ITDATALEVEL(wBase, oUI, $ COLORS=colors, $ COLUMN=column, $ DATA_RANGE=dataRange, $ EXTENDABLE_RANGES=KEYWORD_SET(extendRanges), $ INITIAL_VALUES=(bHaveInitValues ? $ initialValues[*,0] : $ notDefined), $ LEVEL_NAMES=levelNames, $ NLEVELS=nLevels, $ VERTICAL=vertical, $ XSIZE=xsize, $ YSIZE=ysize, YPAD=0) ;; Build our state structure state = { $ oUI: oUI, $ pDataObjects: PTR_NEW(), $ pDataNames: PTR_NEW(), $ pLevelNames: PTR_NEW(), $ pLevelData: PTR_NEW(), $ pPaletteObjects: PTR_NEW(), $ currentDataset: 0, $ wDropList: wDropList, $ wDataLevel: wDataLevel, $ wApplyAll: wApplyAll, $ useDataIndex: KEYWORD_SET(useDataIndex), $ minMax: [0.0d, 0] $ } ;; Create dynamic state data if (N_ELEMENTS(levelNames) ne 0) then $ state.pLevelNames = PTR_NEW(levelNames) $ else $ state.pLevelNames = PTR_NEW(/ALLOC) if nDataSets gt 0 then begin state.pDataObjects = PTR_NEW(dataObjects) state.pDataNames = PTR_NEW(dataNames) state.pLevelData = PTR_NEW(DBLARR(nLevels, nDataSets)) if N_ELEMENTS(paletteObjects) eq nDataSets then begin state.pPaletteObjects = PTR_NEW(paletteObjects) endif else begin state.pPaletteObjects = PTR_NEW(OBJARR(nDataSets)) endelse endif else begin state.pDataObjects = PTR_NEW(/ALLOC) state.pDataNames = PTR_NEW(/ALLOC) state.pLevelData = PTR_NEW(/ALLOC) state.pPaletteObjects = PTR_NEW(/ALLOC) endelse ;; Fill in our array of level data if bHaveInitValues then begin *state.pLevelData = initialValues endif else begin for i=0, nDataSets-1 do begin ;; This trick lets the DataLevel widget do the work ;; of setting initial values for us. value = {DATA_OBJECT:dataObjects[i]} WIDGET_CONTROL, wDataLevel, SET_VALUE=value WIDGET_CONTROL, wDataLevel, GET_VALUE=value (*state.pLevelData)[*, i] = value.level_Values endfor endelse ;; Now set the values for dataset 0 in the DataLevel widget if nDataSets gt 0 then begin if N_ELEMENTS(paletteObjects) ne nDataSets then begin value = {DATA_OBJECT:dataObjects[0], $ LEVEL_VALUES: DOUBLE((*state.pLevelData)[*, 0])} endif else begin value = {DATA_OBJECT:dataObjects[0], $ LEVEL_VALUES: DOUBLE((*state.pLevelData)[*, 0]), $ PALETTE_OBJECT:paletteObjects[0]} endelse WIDGET_CONTROL, wDataLevel, SET_VALUE=value endif wChild = WIDGET_INFO(wBase, /CHILD) WIDGET_CONTROL, wChild, SET_UVALUE=state, /NO_COPY WIDGET_CONTROL, wChild, KILL_NOTIFY='CW_itMultiDataLevel_KillNotify' return, wBase end