• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. Select cell view from lib manager

Stats

  • Locked Locked
  • Replies 19
  • Subscribers 143
  • Views 22111
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Select cell view from lib manager

netbug
netbug over 8 years ago

Dear all,

I have a script which allows the user to select a cell view from the library manager, without opening prompting the user. The user selects, in first place, the cell view from the library manager and only then the user should press the button for the script to run. As this is counter-intuitive for some, I would like to have the opposite. When user clicks the "select" button it will open the lib manager, so the user can choose the cell view.

This is described in Cadence documentation, and an example is given for the "ddsUpdateSyncWithForm" command. However this method uses three text boxes (string fields) which get the values for lib, cell and view. But in my case, I would like to use a single text box instead of three, and I can't do it. I've tried to pass the values (lib,cell,view) with variables but it didn't work.

Second question. In the code, you can see that I have to identical "procedures". The only difference is that one is executed when button 1 is pressed and the second when button 2 is pressed. How can I detect which button has been pressed, so I can do a generic function for both.

 

Thanks in advance.

Best regards,

José

 

My code


;==============================================================================
;============================== main function ================================
;==============================================================================

procedure(main()
let((retValue)

; Create the form
retValue=CreateMainForm()
putprop( 'settingsForm 'myHelpCB 'hiHelpAction) ; Customize the information displayed by the Help button

declare(selectedViewArray[2])
selectedViewArray[0]=""
selectedViewArray[1]=""
);end let
) ; end procedure

;==============================================================================
;=============== Display main Form - Create Main form" =======================
;==============================================================================

procedure(CreateMainForm()
let((label1 doneButton settingsForm cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1)
; template loading and saving

label1=hiCreateLabel(
?name 'label1
?labelText "SUMMARY FILE'S COMPARISON"
?justification 'center
)

sep1=hiCreateSeparatorField(?name 'sep1)

cellView1 = hiCreateStringField(
?name 'cellView1
?prompt "Summary file 1 :"
?value "Please select a summary file"
?editable nil

)

cellView2 = hiCreateStringField(
?name 'cellView2
?prompt "Summary file 2 :"
?value "Please select a summary file"
?editable nil
)

selectButton1=hiCreateButton(
?name 'selectButton1
?buttonText "Select"
?callback "cb_button1_pressed()"
)

selectButton2=hiCreateButton(
?name 'selectButton2
?buttonText "Select"
?callback "cb_button2_pressed()"
)

selectButton3=hiCreateButton(
?name 'selectButton3
?buttonText "Compare !"
?callback "cb_button3_pressed()"
)


hiCreateAppForm(
?name 'settingsForm
?formTitle "Compare summary files"
;?callback list("testOK()" "testCancel()")
?buttonLayout 'Close
?fields list(
list(label1 10:10 600:0 40)
list(sep1 0:35 600:0)
list(cellView1 15:50 500:30 100)
list(cellView2 15:85 500:30 100)
;list(cellView2 300:8 55:30)
;list(selectLabel 15:70 45:20 200)
list(selectButton1 520:50 50:30)
list(selectButton2 520:85 50:30)
list(selectButton3 120:120 90:30)
) ; end list
) ; create form

hiDisplayForm(settingsForm) ; Display form
); end let
); end procedure


;==============================================================================
;=============== Select button1 pressed "cb_button1_pressed" ====================
;==============================================================================
procedure(cb_button1_pressed()
let((selectedView libName cellName viewName pathToSelectedView)
;printf("Test!")
selectedView=ddsGetLibManLCV() ; list containing the the "lib", "cell" and "view", when clicked in lib manager

; separate the list into different variables
libName=nth(0 selectedView)
cellName=nth(1 selectedView)
viewName=nth(2 selectedView)

if(rexMatchp("small_sum" viewName)==t then ; checks if "small_sum" exist in the name of the cell view
; outputs the path to the cell view in the list
pathToSelectedView=ddGetObjReadPath(ddGetObj(libName cellName viewName "*"))

; creates a string in the format "cellname -> viewName" and copies it to the textbox
sprintf(cellViewStr "\n%s -> %s" cellName viewName)
get(settingsForm settingsForm->cellView1->value=cellViewStr)
;printf("Button 1 pressed\n")
;printf(pathToSelectedView)

selectedViewArray[0]=pathToSelectedView

else
dispMessage("Cellview must be text !")

) ;end if
) ;end let

) ;end procedure


;==============================================================================
;=============== Select button2 pressed "cb_button2_pressed" ====================
;==============================================================================
procedure(cb_button2_pressed()
let((selectedView libName cellName viewName pathToSelectedView)
;printf("Test!")
selectedView=ddsGetLibManLCV() ; list containing the the "lib", "cell" and "view", when clicked in lib manager

; separate the list into different variables
libName=nth(0 selectedView)
cellName=nth(1 selectedView)
viewName=nth(2 selectedView)

if(rexMatchp("small_sum" viewName)==t then

; outputs the path to the cell view in the list
pathToSelectedView=ddGetObjReadPath(ddGetObj(libName cellName viewName "*"))

; creates a string in the format "cellname -> viewName" and copies it to the textbox
sprintf(cellViewStr "\n%s -> %s" cellName viewName)
get(settingsForm settingsForm->cellView2->value=cellViewStr)

;printf("Button 2 pressed\n")
;printf(pathToSelectedView)
selectedViewArray[1]=pathToSelectedView

else
dispMessage("Cellview must be text !")
) ;end if


) ;end let
) ;end procedure

;==============================================================================
;=============== Compare Button "cb_button3_pressed" ====================
;==============================================================================
procedure(cb_button3_pressed()
let((str)

; checks if both textboxes aren't empty
if(cellView1->value!="Please select a summary file" && cellView2->value!="Please select a summary file" then
str=sprintf(test "tkdiff %s %s" selectedViewArray[0] selectedViewArray[1]) ; string having the full command to be executed in the shell

csh(str) ; executes the command on linux shell

; Re-initialise text boxes after closing tkdiff editor
get(settingsForm settingsForm->cellView1->value="Please select a summary file")
get(settingsForm settingsForm->cellView2->value="Please select a summary file")
else
dispMessage("Please select two views to be compared !!" )
) ;end if

) ;end let
) ;end procedure

;==============================================================================
;===================== Display Message "dispMessage" =========================
;==============================================================================
procedure(dispMessage( message )
hiDisplayAppDBox(
?name gensym('mybox)
?dboxBanner "Message"
?dboxText message
?dialogStyle 'modeless
?dialogType hicMessageDialog
?buttonLayout 'Close
) ; hiDisplayAppDBox
); End procedure


;==============================================================================
;===================== Building myHelpCB funtion =============================
;==============================================================================

procedure(myHelpCB(arg1 arg2 arg3 arg4)
let((helpStrMsg)

; Help Message
helpStrMsg="\n\
DESCRIPTION\n\
\tSummary file 1 - first summary view selected from the lib manager\n\
\tSummary file 2 - second summary view selected from the lib manager\n\
\t\"Select\" buttons- retrieve the name of the selected views from the lib manager\n\
\t\"Compare\" button - triggers \"tkdiff\" from linux in order to compare both views\n\n\
SUMMARY: \n\
\t1 - Click on the desired cell view from the \"Library manager\"\n\
\t2 - Click the correspondent \"Select\" button.\n\
\t3 - Hit the \"Compare\" button.\n"


hiDisplayAppDBox(
?name gensym("dbox")
?dboxBanner "compViews script HELP"
?dboxText helpStrMsg
?dialogType hicInformationDialog
?dialogStyle 'modeless
?buttonLayout 'Close
)
)
)



  • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Yes, your use model is certainly not the way it's normally done. If you really want to have a single box (which is not how it is done in the rest of the UI, as allowing users to type in the lib/cell/view is useful for those who prefer typing to clicking), then you could create three string fields, but have them be invisible - and have a callback on each which is used to update your single visible text field (which is not editable as right now).

    Or you could use the new ddHiCreateLibraryComboField ddHiCreateCellComboField ddHiCreateViewComboField functions which allow auto-completion as you type (but these would then be three separate fields on the form).

    To answer your section question, simply define your callback function with an argument which indicates the button that was pressed and have the code update the appropriate field. It could pass the destination field in as an argument - up to you. Then the button callbacks would be (say) "cb_button1_pressed('button1)" or "cb_button1_pressed('cellView1)"

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago

    Dear Andrew,

    I would like to add a toggle field and String field. The string field will appear/disappear according to the value of the toggle field.

    I went through your oferExample code, but I am not really able to get the same result as you. I didn't understand how do the "extraFields" work. More over I can't understand how the form can be refreshed on-the-fly.

    Please find below an excerpt of my code. Please let me know if you need the full code.

    Thanks in advance.

    Best regards,

    José

    ;==============================================================================

    ;===============  Display main Form - Create Main form" =======================

    ;==============================================================================

    procedure(CreateMainForm()

       let((label1 doneButton settingsForm cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1 myToggle)

       myToggle = hiCreateToggleField(

     ?name 'myToggle

     ?choices list('(toggleLabel "Save summary file ?"))

     ?value '(nil)

     ?numSelect 1

     ?callback list("cb_checkbox()")

       )

       userPath = hiCreateStringField(

     ?name 'userPath

     ?prompt "Save the file to :"

     ?value "Please enter the path"

     ;?editable nil

     ?invisible '(t)

       )

       hiCreateAppForm(

    ?name 'settingsForm

    ?formTitle "Compare summary files"

    ?buttonLayout 'Close

    ?fields list(

       list(myToggle 250:155 -1:-1) ; -1 indicates fields that aren't used, so they can take any value

       list(userPath 15:120 500:30 100)

    ) ; end list

       ) ; create form

       ; store the extra fields on the form, ready for later

       ;settingsForm->extraFields=list(nil 'userPath userPath)

       hiDisplayForm(settingsForm) ; Display form

    ); end let

    ); end procedure

    ;==============================================================================

    ;=====================  Display Message "cb_checkbox" =========================

    ;==============================================================================

    procedure(cb_checkbox()

     let(( (oldOffset 0) (newOffset 0) (currentOffset 0) (fieldHeight 30))

       printf("\ncheckbox clicked")

       ; stores checkbox value into valueBox variable

       valueBox=car(myToggle->value)

       if(valueBox==t then

    printf("\nTrue\n")

    ;userPath->invisible='(nil)

    ;hiAddField(settingsForm

    ;let(settingsForm->extraFields->userPath 0:0 10:20 20))

       else

    printf("\nFalse\n")

       )

         ) ; end let

     ) ; end procedure

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Rather than dynamically adding and deleting the fields, I updated the code to do what you had attempted to do - just make the field invisible or visible. The key things I altered:

    • Make the invisible slot on the field either t or nil (not '(t) or '(nil) - not sure why you were doing that, but it wouldn't have worked)
    • Access the values via the settingsForm variable (rather than via the dynamically scoped myToggle or userPath variables). In fact your code only works because of the fact that hiDisplayForm is called from the same scope as where the form is created, and because the form is blocking. In general it's best to not make the top level form variable (settingsForm) not a local variable - you just have top-level user interface objects such as forms, menus etc be global, everything else can be local, and then you are not dependent upon this dynamic scoping or blocking behaviour.
    • Not sure why you have the field size of the toggle box being -1:-1 (that's a bit odd). Doesn't break, but it's a bit odd.

    Anyway, here's the modified code (I changed the indentation because it was hard to read as I was working through the code):

    ;==============================================================================
    ;===============  Display main Form - Create Main form" =======================
    ;==============================================================================
    procedure(CreateMainForm()
      let((label1 doneButton settingsForm cellView1 cellView2 selectButton1 selectButton2 selectButton3 sep1 myToggle)
        myToggle = hiCreateToggleField(
          ?name 'myToggle
          ?choices list('(toggleLabel "Save summary file ?"))
          ?value '(nil)
          ?numSelect 1
          ?callback list("cb_checkbox()")
        )
        userPath = hiCreateStringField(
          ?name 'userPath
          ?prompt "Save the file to :"
          ?value "Please enter the path"
          ;?editable nil
          ?invisible t
        )
        hiCreateAppForm(
          ?name 'settingsForm
          ?formTitle "Compare summary files"
          ?buttonLayout 'Close
          ?fields list(
          list(myToggle 250:155 -1:-1) ; -1 indicates fields that aren't used, so they can take any value
          list(userPath 15:120 500:30 100)
          ) ; end list
        ) ; create form
        ; store the extra fields on the form, ready for later
        ;settingsForm->extraFields=list(nil 'userPath userPath)
        hiDisplayForm(settingsForm) ; Display form
      ); end let
    ); end procedure
    
    ;==============================================================================
    ;=====================  Display Message "cb_checkbox" =========================
    ;==============================================================================
    procedure(cb_checkbox()
      let(( (oldOffset 0) (newOffset 0) (currentOffset 0) (fieldHeight 30))
        printf("\ncheckbox clicked")
        ; stores checkbox value into valueBox variable
        valueBox=car(settingsForm->myToggle->value)
        if(valueBox==t then
          printf("\nTrue\n")
        else
          printf("\nFalse\n")
        )
        settingsForm->userPath->invisible=!valueBox
      ) ; end let
    ) ; end procedure
    

     

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago

    Hi Andrew,

    Thanks for your answer.

    Using '(t)and '(nil), it's a stupid error from my side, since I am still learning SKILL. Regarding the "-1" values, it is just a note for me as, in the future, if I had put some value there I wouldn't remember the meaning.

    Now I have a new problem: the form is not closing when I click the "Close" button.

    I would like to ask a question more, if you please. It it possible to block the user to enter some characters in the textbox as he writes them.

    Apart from Cadence's documentation, which I use a lot, is there any other reference for SKILL programming with more examples maybe ?

    Thank you in advance.

    Best regards,

    Pedro

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Pedro,

    If the form is not closing when you click the Close button, it's probably because you have declared the variable containing the form structure as a local variable; I mentioned this before - the point is that any interactions with the form have to be recorded in the CDS.log as a SKILL expression - so in essence when you interact with the form it generates a SKILL expression to complete the task. If the variable containing the form (as specified by the ?name argument to the hiCreateAppForm function) is not visible from the scope in which you are interacting the form (i.e. where you call hiDisplayForm from) then it will all go horribly wrong. So the best thing is to make the form variable global (i.e. don't put it in the let()). 

    I don't understand what you mean by "block the user to enter some characters in the text box". If you're saying that you want to disallow certain characters, then perhaps you want to specify a ?modifyCallback on the field which is a SKILL function that is called whenever there is a change in the field, but before it's displayed - so you can use this to modify what is actually entered.

    As for examples, there are lots on this form, and lots on support.cadence.com including the Resources->SKILL Information on the support site which has some code libraries to help you get started.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago

    Hi Andrew,
    Is there a way to clean/delete all global variables from the CIW, that have been created by the script ? You see, the close button doesn't work anymore for some reason after testing the scripts over and over again. I can only make it working again by restarting Cadence.

    Another question if you don't mind. I have generated a text file that I would like to add lib manager as a cell view, how can I do this ? I've tried to find the functions from the log file, but even using those I cannot make it work.

    By "block the user to enter some characters in the text box" I mean to not echo some characters to the text box, allowing the user to enter for the filename only valid characters.
    Best regards,
    Pedro

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Pedro,

    The answer is no to your first question. You can unbind specific variables, but not all (that would be very hard, as we can't really distinguish between what is yours and what is ours). You can do:

    myVar='unbound

    to make a variable undefined (in essence).

    For your second question, didn't I already answer that in this earlier reply to you in another post.

    For the final point, that does sound like the ?modifyCallback is the way to save that.

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago
    Hi Andrew,
    Regarding creating a cell view, which is a text file I have entered the following commands(copied from the log file):
    dssCreateCellViewForm->viewType->value="text"
    dssCreateCellViewForm->newViewName->value="test.txt"
    hiFormDone(dssCreateCellViewForm)

    The only problem that I've got with this, is that it opens a text editor so I enter the text I want to save. However, I would like to pass an existing file instead.
    From the link you've sent me I cannot understand the way it is done (lack of practice I guess. I am sorry for that) :-( .

    Best regards,
    Pedro
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Pedro,

    The code pointed to by that other thread would allow you to simply do:

    cv=abOpenTextCellView("mylib" "mycell" "testtxt" "a")
    fprintf(cv->port "Testing 123\n")
    abCloseTextCellView(cv)

    (this is in the comments at the top of that code). If you want to put in the contents of an existing file,  you'd do:

    existPort=infile("existing.txt")
    cv=abOpenTextCellView("mylib" "mycell" "newtext" "a")
    while(gets(line existPort)
      fprintf(cv->port "%s" line)
    )
    close(existPort)
    abCloseTextCellView(cv)

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • netbug
    netbug over 8 years ago
    Hi Andrew,
    Thanks for that.
    In the same way, for eg, C allows it, is it possible to have functions stored into a file, and call them from there, pointing to that file (including the file) ?
    Best regards,
    Pedro
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
>

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information