Product Documentation
Virtuoso Studio Design Environment SKILL Reference
Product Version IC23.1, November 2023

Custom Library Browser Template

The following may be used as a template for a custom Library Browser integration (browser in this template refers to the Library Browser).

;;***************************************************************************
;; The sample syncronization routines for the sample browser integration.
;; 1998 Cadence Design systems, Inc. - All Rights Reserved.
;;
;; The code below is for example only and is not intended for production
;; usage by customers. Users integrating their own custom browsers with DFII
;; may use this file as a template for their own integration.
;;
;; The sample browser uses the prefix "dsb" for DAG-Simple-Browser. This
;; browser only supports the expansion of a library, its cells, and views of
;; a selected cell. Category display is not supported. There is no intention
;; of extending the capabilities of this browser any further nor to make the
;; source available except for what is listed here.
;;***************************************************************************
;; The following global variable is used to designate when the browser is ;; doing a selection of a library, cell, or cellview. When 't, the code will ;; know not to try re-expand itself in case the form currently in sync has ;; field callbacks that call ddsUpdateSyncWithForm (which ends up calling ;; the dsbUpdateBrowser routine below). dsbvIsSelecting = nil

;;***************************************************************************
;; dsbSyncForm - This is the routine registered via ddsRegCustomLibSelect
;; to syncronize a form to the dsb. It takes the same arguments as the
;; ddsSyncWithForm routine. From this call until the dsbEndFormSync routine
;; is called, the browser will seed or be seeded from the given form
;; fields. Applications are required to call ddsEndSyncWithForm when they
;; are done with a browser otherwise the user may experience strange
;; browser behavior.
;;
;; dsb does not support the filtering of cellviews by viewType so the
;; viewTypes arg from ddsSyncWithForm is ignored. If viewType filtering
;; were to be supported, the browser would only display those cellviews
;; whose viewType were in the given list. To get a cellview's viewType,
;; you would call ddGetObj to get the master file in the cellview, and
;; then ddMapGetFileViewType to get the viewType. For example,
;;
;;     id = ddGetObj(lib cell view "*") ; '*' gets the master file
;;     viewType = ddMapGetFileViewType(id)
;; ;; Some forms within DFII only syncronize the library field so it is the ;; only required field from ddsSyncWithForm. Some forms only syncronize the ;; library and cell fields (e.g., the CDF editor). This routine and the ;; updateBrowser routine must be aware of this. ;;*************************************************************************** procedure( dsbSyncForm(form action libField      cellField viewField _viewTypes "rssggl")
prog((fn)
     ;; Verify that the specified fields exist on the given form.
;; This is extra precaution against callers passing in misstyped
;; field names. We also check that if a viewField is given, a
;; valid cellField is also given.
     fn = "dsbSyncForm"
unless(get(form libField)
warn("%s: %L not a field on form %L\n" fn libField form->hiFormSym)
return()
)
when(cellField && !get(form cellField)
warn("%s: %L not a field on form %L\n" fn cellField form->hiFormSym)
)
when(viewField && !get(form viewField)
warn("%s: %L not a field on form %L\n" fn viewField form->hiFormSym)
)
when(viewField && !cellField
warn("%s: cellField required when specifying a viewField\n" fn)
return()
)
     ;; Validate the browser action. If the browser action is one of
;; 'open, 'place, or 'other and the user has set the corresponding
;; ddserv environment variable to 'nil, the routine will return
;; at this point. If the user specifies a value of 't, the code
;; continues on and opens the browser. This control allows some
;; specific applications to support bringing up the browser when
;; specific commands are invoked.
     unless(ddsBrowserAction(action)
return(t)
)
     ;; Open the browser and save the form and field symbols.
;; Then call the update routine to expand the browser to anything
;; the user may have entered in these fields on the form.
;;
;; dsbvBrowser is a global variable that contains all the
;; information for the dsb. It is only defined/bound when the
;; browser is open; it does not exist otherwise.
     dsbOpenBrowser()
dsbvBrowser->form = form
dsbvBrowser->lib = libField
dsbvBrowser->cell = cellField
dsbvBrowser->view = viewField
dsbUpdateBrowser()
return(t)
)
)

;;***************************************************************************
;; dsbEndFormSync - Terminates syncronization between the browser and the
;; form. This is called when ddsEndSyncWithForm is called. When the browser
;; is closed, the dsbvBrowser variable is purged and marked unbound; this
;; clears any form and field information as well so it is not necessary to
;; explicitly do it here. If the form and field information were stored
;; differently, we would clear out the information to signify the browser
;; wasn't sync'd to any form.
;;
;; This and the other routines below only act if a) there is a browser
;; open and b) there is a form syncronized to it.
;;***************************************************************************

procedure( dsbEndFormSync()
    when( boundp('dsbvBrowser) && dsbvBrowser->form
     dsbCloseBrowser()
)
t
)

;;***************************************************************************
;; dsbGetCurrentLib - Returns the current library selected in the browser.
;; This is called when ddsGetCurrentLib is called. The browser code sets
;; the dsbvCurrentLib global variable whenever the library selection
;; changes. This is possible because only 1 library can be expanded at any
;; given time.
;;***************************************************************************

procedure( dsbGetCurrentLib()
    when( boundp('dsbvBrowser) && dsbvBrowser->form
     dsbvCurrentLib
)
)

;;***************************************************************************
;; dsbUpdateBrowser - This is the workhorse routine that expands/updates the
;; browser with the values from the registered form fields. Some apps only
;; register the lib or lib & cell fields.
;;***************************************************************************

procedure( dsbUpdateBrowser()
    cond(
     ;;
;; If there isn't a browser around or there isn't a form registred
;; or we got here because the browser did a selection and a call-
;; back for the form is doing an update, we return.
;;
(!boundp('dsbvBrowser) || !dsbvBrowser->form || dsbvIsSelecting
t
)
;;
;; Some apps (more historical from the 4.3.4 days) call the update
;; routine in their cancel callbacks. Since the form should be
;; going away, there really isn't anything to do as the next thing
;; that should happen is a ddsEndSyncWithForm call.
;;
(hiIsInFieldCancel()
t
)
;;
;; Get any lib/cell/view values from the respective form fields.
;; The assumption has always been (from 4.3.4) that these fields
;; are string fields. If other types of fields were to be supported,
;; the code below would have to be able to process them.
;;
;; The routine dsbExpandFromForm is a special routine that expands
;; the browser to a given lib/cell/view. If all three values are
;; 'nil, it only expands the libraries pruning back the display
;; if it has to. A different browser may have to have a different
;; behavior, but isolating it to a single function call helps
;; keep it modular.
;;
(t
let( (tool lib cell view cellF viewF)
tool = dsbvBrowser
lib = get(tool->form tool->lib)->value
when( lib
lib = (when (lib && lib != "") lib)

when( tool->cell && (cellF = get(tool->form tool->cell))
cell = (when (cellF->value && cellF->value != "")
cellF->value)
)
     when( cell && tool->view &&
(viewF = get(tool->form tool->view))
view = (when (viewF->value && viewF->value != "")
viewF->value)
)
     dsbExpandFromForm(tool lib cell view)
)
)
t
)
)
)

;;***************************************************************************
;; dsbServeSelect - This routine is called by the browser code whenever a
;; library, cell, or cellview is selected. It is listed here along with the
;; others as an example. It's purpose is complimentary to the above
;; dsbUpdateBrowser routine; it fills in the registered form fields with
;; the selection in the browser.
;;
;; The variable dsbvIsSelecting is first set to 't before updating the
;; form field value. In the case where the form field has a callback that
;; calls ddsUpdateSyncWithForm, the update routine above will not try to
;; expand the form again since it was already expanded by the user. This
;; variable is reset once the fields have been updated.
;;
;; The code below is specific to the dsb but conceptually, it gets
;; the current library, cell, and cellview selections and sets the
;; respective form field values.
;;***************************************************************************

procedure( dsbServeSelect(obj fromWhere "ws")
    let( (tool node libF cellF viewF tmp)
     tool = dsbvBrowser
when(obj && tool->form
dsbvIsSelecting = t
caseq( fromWhere
(lib
libF = get(tool->form tool->lib)
libF->value = obj->name
when( (cellF = get(tool->form tool->cell))
node = dsbGetExpandNode(tool->expandPath
tool->cellClass)
unless(node
dsbGetExpandNode(tool->expandPath
tool->cellviewClass)
)
cellF->value = (if node node->name "")
)
when( (tool->view && (viewF = get(tool->form tool->view)))
node = dsbGetExpandNode(tool->expandPath
tool->cellviewClass)
unless(node
dsbGetExpandNode(tool->expandPath
tool->cellviewClass)
)
viewF->value = (if node node->name "")
)
)
(cell
tmp = dsbiGetLibParent(obj)
libF = get(tool->form tool->lib)
libF->value = tmp->name
when( (cellF = get(tool->form tool->cell))
cellF->value = obj->name
)
)
(view
tmp = dsbiGetLibCellview(obj)
libF = get(tool->form tool->lib)
libF->value = car(tmp)
when( (cellF = get(tool->form tool->cell))
cellF->value = cadr(tmp)
)
when( (viewF = get(tool->form tool->view))
viewF->value = caddr(tmp)
)
)
)
dsbvIsSelecting = nil
)
)
)

The following is a form example exercising the browser synchronization.

;;
;; This file contains a command that takes library, cell, view, and
;; mode values and performs an open using deOpen. The associated form
;; also contains a 'Browse' button to exercise the custom library
;; browser integration although it will also work with DFII's default
;; browser as well.
;;
procedure(myOpen()
    if( boundp('myOpenForm) && hiIsForm(myOpenForm) then
     hiSetCurrentField(myOpenForm 'libName)
else
let((itemL)
itemL = tconc(itemL list(hiCreateStringField(
?name 'libName
?prompt "Library"
?value ""
?callback "myOpenLibCB()"
) 5:0 200:30 60))
itemL = tconc(itemL list(hiCreateStringField(
?name 'cellName
?prompt "Cell"
?value ""
?callback "myOpenCellCB()"
) 5:30 200:30 60))
itemL = tconc(itemL list(hiCreateStringField(
?name 'viewName
?prompt "View"
?value ""
?callback "myOpenViewCB()"
) 5:60 200:30 60))
itemL = tconc(itemL list(hiCreateRadioField(
?name 'mode
?prompt "Mode"
?choices '("edit" "read")
?value "read"
) 5:90 200:30 60))
itemL = tconc(itemL list(hiCreateFormButton(
?name 'browse
?buttonText "Browse"
?callback "myOpenBrowseCB()"
) 5:120 60:25))
     hiCreateAppForm(
?name 'myOpenForm
?formTitle "Open Cellview"
?fields car(itemL)
?help ""
?buttonLayout 'OKCancelApply
?formType 'nonOptions
?callback '("myOpenCB('ok)" "myOpenCB('cancel)")
?unmapAfterCB t
)
)
)
    ddsSyncWithForm(myOpenForm 'open 'libName 'cellName 'viewName)     hiDisplayForm(myOpenForm) ) procedure( myOpenBrowseCB()     ddsSyncWithForm(myOpenForm 'browse 'libName 'cellName 'viewName) ) procedure( myOpenLibCB()     let( (form libN)      form = myOpenForm
libN = form->libName->value
     hiHighlightField(form 'cellName hicBackground)
hiHighlightField(form 'viewName hicBackground)
when( libN != "" && ddGetObj(libN)
hiHighlightField(form 'libName hicBackground)
)
ddsUpdateSyncWithForm()
)
) procedure( myOpenCellCB()     let( (form libN cellN)      form = myOpenForm
libN = form->libName->value
cellN = form->cellName->value
     hiHighlightField(form 'libName hicBackground)
hiHighlightField(form 'viewName hicBackground)
when( libN != "" && cellN != "" && ddGetObj(libN cellN)
hiHighlightField(form 'cellName hicBackground)
)
ddsUpdateSyncWithForm()
)
) procedure( myOpenViewCB()     let( (form libN cellN viewN)      form = myOpenForm
libN = form->libName->value
cellN = form->cellName->value
viewN = form->viewName->value
     hiHighlightField(form 'libName hicBackground)
hiHighlightField(form 'cellName hicBackground)
when( libN != "" && cellN != "" && viewN != "" &&
ddGetObj(libN cellN viewN)
hiHighlightField(form 'viewName hicBackground)
)
ddsUpdateSyncWithForm()
)
) procedure( myOpenCB(okOrCan "s")     prog( (form fspec libN cellN viewN id vType)      when(eq(okOrCan 'cancel)
ddsEndSyncWithForm()
return()
)
form = myOpenForm
libN = form->libName->value
cellN = form->cellName->value
viewN = form->viewName->value
cond(
(libN == ""
hiSetCallbackStatus(form nil)
hiSetCurrentField(form 'libName)
hiHighlightField(form 'libName hicError)
myOpenDBox("Need Library Name" "enter a library name.")
return()
)
(cellN == ""
hiSetCallbackStatus(form nil)
hiSetCurrentField(form 'cellName)
hiHighlightField(form 'cellName hicError)
myOpenDBox("Need Cell Name" "enter a cell name.")
return()
)
(viewN == ""
hiSetCallbackStatus(form nil)
hiSetCurrentField(form 'viewName)
hiHighlightField(form 'viewName hicError)
myOpenDBox("Need View Name" "enter a view name.")
return()
)
(!ddGetObj(libN cellN viewN)
hiSetCallbackStatus(form nil)
hiSetCurrentField(form 'viewName)
hiHighlightField(form 'viewName hicError)
myOpenDBox("Not Found"
sprintf(nil strcat("Cellview '%s/%s/%s' does not exist.\n"
"check your entries.")
libN cellN viewN))
return()
)
)
hiSetCallbackStatus(form t)
hiFormUnmap(form)
ddsEndSyncWithForm()
     fspec = list(nil
'libName libN
'cellName cellN
'viewName viewN
'viewType nil
'accessMode form->mode->value)
     return( deOpen(fspec nil) )
)
) procedure( myOpenDBox(banner msg "tt")     hiDisplayAppDBox(      ?name 'myDBox
?dboxBanner banner
?dboxText msg
?dialogType hicErrorDialog
?buttonLayout 'Close
)
)

Return to top
 ⠀
X