;$Id: db_txtlabel.pro,v 1.10 2005/02/08 17:01:16 azuah Exp $
;###############################################################################
;
; NAME:
;   DB_TxtLabel
;
; PURPOSE:
;   Widget dialog program (non-blocking) for editing text annotations
;   in a plot.
;
; CATEGORY:
;   Data Browser
;
; AUTHOR:
;   Richard Tumanjong Azuah
;   NIST Center for Neutron Research
;   100 Bureau Drive, Gaithersburg, MD 20899
;   United States
;   azuah@nist.gov; (301) 9755604
;   May, 2003
;
; 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.
;
;###############################################################################




;===============================================================================
; DB_TxtLabel_Cleanup
;
; PURPOSE:
;   Main cleanup routine called when the main widget is destroyed
;
; PARAMETERS:
;   tlb [in] - the widget id of the top-level-base that is being
;              killed.
;
pro DB_TxtLabel_Cleanup, tlb

widget_control, tlb, get_uvalue=sPtr

ptr_free, sPtr

end
;-------------------------------------------------------------------------------



;===============================================================================
; DB_TxtLabel_Event
;
; PURPOSE:
;   Event handler for events originating from the main UI
;
; PARAMETERS:
;   event [in] - the event structure to be handled
;
pro DB_TxtLabel_Event, event

widget_control,event.top,get_uvalue = sPtr
uname = widget_info(event.id,/uname)

switch uname of
    'TEXT': begin
        widget_control, event.id, get_value=value
        (*sPtr).labText = strtrim(value,2)

        ((*sPtr).atomRef)->setProperty, strings=(*sPtr).labText

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 

        break
    end

    'FNAME': begin
        (*sPtr).labFontName = event.str
        boldID = widget_info(event.top,find_by_uname='BOLD')
        italicID = widget_info(event.top,find_by_uname='ITALIC')
        case strmid(event.str,0,6) of
            'SYMBOL': begin
                widget_control, boldID, sensitive=0
                widget_control, italicID, sensitive=0
            end
            'HERSHE': begin
                widget_control, boldID, sensitive=0
                widget_control, italicID, sensitive=0
            end 
            else: begin
                widget_control, boldID, sensitive=1
                widget_control, italicID, sensitive=1
            end
        endcase

        font = (*sPtr).labFontName
        if (strmid(font,0,6) ne 'SYMBOL') then begin
            if ((*sPtr).labBold) then $
              font = font+'*'+'BOLD'
            if ((*sPtr).labItalic) then $
              font = font+'*'+'ITALIC'
        endif

        ((*sPtr).atomRef)->getProperty, font=fontRef
        fontRef->setProperty, name=font

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 

        break
    end

    'BOLD': begin
        (*sPtr).labBold = 1 - (*sPtr).labBold
        font = (*sPtr).labFontName
        if (strmid(font,0,6) ne 'SYMBOL') then begin
            if ((*sPtr).labBold) then $
              font = font+'*'+'BOLD'
            if ((*sPtr).labItalic) then $
              font = font+'*'+'ITALIC'
        endif

        ((*sPtr).atomRef)->getProperty, font=fontRef
        fontRef->setProperty, name=font

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 

        break
    end

    'ITALIC': begin
        (*sPtr).labItalic = 1 - (*sPtr).labItalic
        font = (*sPtr).labFontName
        if (strmid(font,0,6) ne 'SYMBOL') then begin
            if ((*sPtr).labBold) then $
              font = font+'*'+'BOLD'
            if ((*sPtr).labItalic) then $
              font = font+'*'+'ITALIC'
        endif

        ((*sPtr).atomRef)->getProperty, font=fontRef
        fontRef->setProperty, name=font

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 

        break
    end

    'COLOR': begin
        widget_control, event.id, get_uvalue=colors
        (*sPtr).labColor = colors[*,event.index]

        ((*sPtr).atomRef)->setProperty, color=(*sPtr).labColor

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 
        break
    end

    'ZLOC': if (n_elements(index) eq 0) then index = 2
    'YLOC': if (n_elements(index) eq 0) then index = 1
    'XLOC': begin
        if (n_elements(index) eq 0) then index = 0
        (*sPtr).labPosition[index] = event.value

        ((*sPtr).atomRef)->setProperty, location=(*sPtr).labPosition

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 
        break
    end

    'SIZE': begin
        if (event.index eq -1) then begin ; add a new entry to the list
            widget_control, event.id, get_value=strArray, get_uvalue=intArray
            index = insertValueInArray(intArray, fix(event.str))
            insertStringInStringArray, strArray, event.str, index
            widget_control, event.id, set_value=strArray,set_uvalue=intArray,set_combobox_select=index
        endif
        (*sPtr).labFontSize = float(event.str)

        ((*sPtr).atomRef)->getProperty, font=fontRef
        fontRef->setProperty, size=(*sPtr).labFontSize

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 
        break
    end

    'ALIGN': begin
        case strupcase(event.str) of 
            'LEFT': (*sPtr).labAlignment = 0.0
            'CENTER': (*sPtr).labAlignment = 0.5
            'RIGHT': (*sPtr).labAlignment = 1.0
        endcase
        ((*sPtr).atomRef)->setProperty, alignment=(*sPtr).labAlignment

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 
        break
    end

    'APPLY': begin
        font = (*sPtr).labFontName
        if (strmid(font,0,6) ne 'SYMBOL') then begin
            if ((*sPtr).labBold) then $
              font = font+'*'+'BOLD'
            if ((*sPtr).labItalic) then $
              font = font+'*'+'ITALIC'
        endif
        (*sPtr).label.text = (*sPtr).labText
        (*sPtr).label.position = (*sPtr).labPosition
        (*sPtr).label.alignment = (*sPtr).labAlignment
        (*sPtr).label.color = (*sPtr).labColor
        (*sPtr).label.font = font
        (*sPtr).label.fontSize = (*sPtr).labFontSize

        if (!debug) then help,(*sPtr).label, /struct

        if ((not obj_valid((*sPtr).atomRef)) or (not obj_valid((*sPtr).daveGrRef)) ) then begin
            widget_control,event.top,/destroy
            return
        endif

        ;; Apply changes
        ((*sPtr).atomRef)->getProperty, font=fontRef
        fontRef->setProperty, name=font, size=(*sPtr).labFontSize
        ((*sPtr).atomRef)->setProperty, strings=(*sPtr).labText,alignment=(*sPtr).labAlignment $
          ,color=(*sPtr).labColor,location=(*sPtr).labPosition

        ((*sPtr).widObjRef)->noRenew
        ((*sPtr).widObjRef)->refresh 

        ;; Save changes
        case ((*sPtr).labelIndex) of
            -1: if (not ((*sPtr).daveGrRef)->set(title=(*sPtr).label)) then return
            else: begin         ; misc label
                if (not ((*sPtr).daveGrRef)->get(label=labelArray)) then return
                labelArray[(*sPtr).labelIndex] = (*sPtr).label
                if (not ((*sPtr).daveGrRef)->set(label=labelArray)) then return
            end
        endcase 

        widget_control,event.top,/destroy
        
        break
    end

    'EXIT': begin
        ((*sPtr).widObjRef)->Renew
        ((*sPtr).widObjRef)->refresh 
        widget_control,event.top,/destroy
        break
    end

    else:

endswitch

end
;-------------------------------------------------------------------------------



;===============================================================================
; DB_TxtLabel
;
; PURPOSE:
;   Entry point and dialog builder for application.
;
; PARAMETERS
;   AxisIndex [in] - Flag indicating annotation type: -1=>title text
;
;   atomRef [in|out;req] - Object reference of annotation to be edited.
;
;   daveGrRef [in;req] - The DaveGr object reference currently on
;                             display.
;
;   widObjRef [in;req] - The object reference of the display (view)
;                        from which the edit request originated from.
;
; KEYWORDS:
;   group_leader [in] - the ID of the parent widget from which this
;                       dialog was launched.
;
;   xrange [in] - range of x values used for positioning the text
;                 annotation in the plot.
;
;   yrange [in] - range of y values used for positioning the text
;                 annotation in the plot.
;
;   zrange [in] - range of z values used for positioning the text
;                 annotation in the plot.
;
pro DB_TxtLabel, labelIndex,atomRef,daveGrRef,widObjRef,group_leader=glder $
                 ,xrange=xrange,yrange=yrange,zrange=zrange

validGrObjects = ['DAVEGR1D','DAVEGR2D']
res = where(validGrObjects eq vartype(daveGrRef), okay)
if (not okay) then return

if (not obj_valid(atomRef)) then return

if (not obj_valid(widObjRef)) then return
  
title = 'DATABROWSER - Edit Title'
case labelIndex of
    -1: if (not daveGrRef->get(title=labelStr)) then return
    else: begin                 ; misc label
        if (not daveGrRef->get(label=labelStrArray)) then return
        labelStr = labelStrArray[labelIndex]
        title = 'DATABROWSER - Edit Text'
    end
endcase

if n_elements(glder) eq 0 then begin
    group_leader = 0L
    modal = 0
    tlb = widget_base(/col,title=title)
endif else begin
    modal = 1
    tlb = widget_base(group_leader=glder,/col,title=title);,modal=modal)
endelse

; Split the dialog base into
; - one tab base
; - one control base
tabBase = widget_tab(tlb)
ansBase = widget_base(tlb,/row,/align_center)

; Create two tab widgets
tab1 = widget_base(tabBase,title='Attributes',/col)
tab2 = widget_base(tabBase,title='Location',/col)

dropSize = 150
labSize = 70
lab2Size = 150
textSize = 50
locSize = 17
gap0 = 10
gap1 = dropSize + labSize + gap0
gap2 = gap1 + labSize
; Create control bases for first tab
cb1 = widget_base(tab1,/row,/align_center)
cb2 = widget_base(tab1,/row)
cb21 = widget_base(cb2,/row)
cb22 = widget_base(cb2,/row,/align_left)
cb3 = widget_base(tab1,/row)
cb31 = widget_base(cb3,/row)
cb32 = widget_base(cb3,/row,/align_left)
cb33 = widget_base(cb3,/row,xoffset=gap1)
cb34 = widget_base(cb3,/row,/align_right,xoffset=gap2,/nonexclusive)
cb4 = widget_base(tab1,/row)
cb41 = widget_base(cb4,/row)
cb42 = widget_base(cb4,/row,/align_left)
cb43 = widget_base(cb4,/row,xoffset=gap1)
cb44 = widget_base(cb4,/row,/align_right,xoffset=gap2,/nonexclusive)
cb5 = widget_base(tab1,/row)
cb51 = widget_base(cb5,/row)
cb52 = widget_base(cb5,/row,/align_left)
; Create control bases for second tab
;cb6 = widget_base(tab2,/row,/align_center)
cb7 = widget_base(tab2,/row)
cb71 = widget_base(cb7,/row)
cb72 = widget_base(cb7,/row,/align_left)

; First Tab
;-------------------------------------------------
; analyse input label structure
labText = strtrim(labelStr.text,2)
labPosition = labelStr.position
labAlignment = labelStr.alignment
labColor = labelStr.color
labFont = strtrim(labelStr.font,2)
labFontSize = labelStr.fontSize
labBold = 0b
labItalic = 0b
labFontName = 'HELVETICA'
if (strlen(labFont) gt 0) then begin
    toks = strsplit(labFont,'*',/extract)
    labFontName = toks[0]
    if (n_elements(toks) gt 1) then begin
        case toks[1] of
            'BOLD': labBold = 1b
            'ITALIC': labItalic = 1b
        endcase
    endif
    if (n_elements(toks) gt 2) then begin
        case toks[2] of
            'BOLD': labBold = 1b
            'ITALIC': labItalic = 1b
        endcase
    endif
endif

void = widget_label(cb1,value='(To commit changes, use Apply button below!)')

; Text edit widget
void = widget_label(cb21,value='Text:',xsize=labSize,/align_right)
textID = widget_text(cb22,/editable,/all_events,value=labText,xsize=textSize,uname='TEXT')

; Font Color
void = widget_label(cb31,value='Color:',xsize=labSize,/align_right)
colorNames = ['Aqua','Black','Blue','Fuchsia','Gray','Green','Lime','Maroon', $
              'Navy','Olive','Purple','Red','Silver','Teal','White','Yellow']
colorIndices = [[0,255,255],[0,0,0],[0,0,255],[255,0,255],$
                [128,128,128],[0,128,0],[0,255,0],[128,0,0], $
                [0,0,128],[128,128,0],[128,0,128],[255,0,0], $
                [192,192,192],[0,128,128],[255,255,255],[255,255,0]]
fcolorID = widget_combobox(cb32,value=colorNames,uname='COLOR',uvalue=colorIndices,xsize=dropSize)
if (n_elements(labColor) gt 0) then begin
    for i=0,(size(colorIndices))[2]-1 do begin
        void = where(colorIndices[*,i] eq labColor, count)
        if (count eq 3) then begin
            widget_control, fcolorID, set_combobox_select=i
            break
        endif
    endfor
endif

; Font modifiers - bold, italics
void = widget_label(cb33,value='Bold:',xsize=labSize,/align_right)
mod1ID = widget_button(cb34,uname='BOLD',value=' ')
widget_control, mod1ID, set_button=labBold
void = widget_label(cb43,value='Italic:',xsize=labSize,/align_right)
mod2ID = widget_button(cb44,uname='ITALIC',value=' ')
widget_control, mod2ID, set_button=labItalic
str = strmid(labFontName,0,6)
if ((str eq 'SYMBOL') or (str eq 'HERSHE')) then begin
    widget_control, mod1ID, sensitive=0
    widget_control, mod2ID, sensitive=0
endif



; Fontname droplist
void = widget_label(cb41,value='Font:',xsize=labSize,/align_right)
fonts = ['HELVETICA','COURIER','TIMES','SYMBOL','HERSHEY']
fnameID = widget_combobox(cb42,value=fonts,uname='FNAME',xsize=dropSize)
if (strlen(labFontName) gt 0) then begin
    index = where(fonts eq labFontName)
    widget_control, fnameID, set_combobox_select=index
endif

; Font Size
void = widget_label(cb51,value='Fontsize:',xsize=labSize,/align_right)
sizes = [8,10,12,14,16,18,20,22,24,26,28,30]
fSizes = ['8','10','12','14','16','18','20','22','24','26','28','30']
fsizeID = widget_combobox(cb52,/editable,value=fSizes,uname='SIZE',uvalue=sizes,xsize=dropSize)
if (n_elements(labFontSize) gt 0) then begin
    res = where(sizes eq labFontSize, count)
    if (count gt 0) then begin
        widget_control, fsizeID, set_combobox_select=res[0]
    endif else begin            ; add unknown fontsize to list
        index = insertValueInArray(sizes, fix(labFontSize))
        insertStringInStringArray, fSizes,strtrim(string(fix(labFontSize)),2), index
        widget_control, fsizeID, set_value=fSizes,set_uvalue=sizes,set_combobox_select=index
    endelse
endif


; Second Tab
;-------------------------------------------------

;widget_control, void,sensitive=0 ; desensitize z-axis button if necessary
if (n_elements(xrange) le 0) then xrange=[0.0,1.0]
if (n_elements(yrange) le 0) then yrange=[0.0,1.0]
if (n_elements(zrange) le 0) then zrange=[0.0,1.0]

res = widget_info(tab1,/geometry)
xsize = 0.90*res.xsize
void = cw_fslider(tab2,format='(F5.2)',/frame,minimum=xrange[0],maximum=xrange[1],xsize=xsize,/drag $
                  ,title='X location',uname='XLOC',value=labPosition[0])
void = cw_fslider(tab2,format='(F5.2)',/frame,minimum=yrange[0],maximum=yrange[1],xsize=xsize,/drag $
                  ,title='Y location',uname='YLOC',value=labPosition[1])
void = cw_fslider(tab2,format='(F5.2)',/frame,minimum=zrange[0],maximum=zrange[1],xsize=xsize,/drag $
                  ,title='Z location',uname='ZLOC',value=labPosition[2])



; label text alignment
void = widget_label(cb71,value='Text alignment:',/align_right,xsize=lab2Size)
options = ['Left','Center','Right']
case labAlignment of
    0.0: index=0
    0.5: index=1
    1.0: index=2
endcase
falignID = widget_combobox(cb72,value=options,uname='ALIGN',xsize=dropSize)
widget_control, falignID, set_combobox_select=index

; 
keepTip = 'Save changes made before exiting'
dismTip = 'Disregard all changes made and exit'
void = widget_button(ansBase,value = 'Keep Changes',uname = 'APPLY',tooltip=keepTip)
void = widget_button(ansBase,value = 'Dismiss',uname = 'EXIT',tooltip=dismTip)

; tlb uvalue
sPtr = ptr_new({labelIndex:labelIndex, $
                label:labelStr, $
                atomRef:atomRef, $
                davegrRef:daveGrRef, $
                widObjRef:widObjRef, $
                labText:labText, $
                labAlignment:labAlignment, $
                labPosition:labPosition, $
                labColor:labColor, $
                labFontName:labFontName, $
                labFontSize:labFontSize, $
                labBold:labBold, $
                labItalic:labItalic $
                })

;----------------------------------------------------------------------------
; realize widgets
widget_control, tlb,/realize, set_uvalue=sPtr


registerName = 'db_txtlabel'
xmanager,registerName,tlb,/no_block,event_handler='db_txtlabel_event',cleanup='db_txtlabel_cleanup'


end
