I've found elsewhere how to add a button to the toolbar (http://klayout.de/forum/comments.php?DiscussionID=361) and I've made a number of PCells that are useful to me, personally. I'm wondering if there is an easy way to make a button that acts as a shortcut to a specific PCell? It basically would save the time of clicking on "Instance", selecting the library, and then selecting the PCell. I don't want to automatically add the PCell without user input, so ideally clicking the button would ask for the parameters. I'm not sure which is the best route (if either would work):
1) Figure out a keyboard shortcut to the PCell window
2) Create a script that prompts for the parameters and then calls the PCell
Does that make any sense?
Thanks!
Comments
I think #1 may be possible but difficult.
Just go with #2. For that you need to:
(Shameless plug: Make sure to share your script on the hopefully upcoming community script sharing site when it is complete! :-)
OK, I think I made pretty good progress based on the links you posted, and some other things I found on the forums (and a detour through Qt tutorials that didn't help much).
If I run this script in the IDE I get the button on the toolbar that I want. When I click it the user is prompted for the parameters I know I need, and then I pass them to the script to create the PCell, but I get this error:
"Object cannot be copied here in layout::add_pcell_variant in Action::triggered"
I'm guessing the code calling the PCell is in the wrong area of the script?
Also, how can I get the macro to run at startup so the button is on the tool bar to begin with? I got another error there.
Many thanks!
Hi NMF,
I'm impressed :-)
To be frank, I can't reproduce the problem you had with "Object cannot be copied here in layout::add_pcell_variant in Action::triggered". I don't have your PCell code but I think it's related to that code. Maybe you can try to use the debugger to locate the problem.
I found a tiny bug in the script: the line
should be
Using the Basic.CIRCLE PCell works for me with that patch.
You can configure to run the macro at startup using the "Macro properties" dialog: to open the dialog use the properties tool button above the macro text left to the "wrench" icon. Check "Run on startup". Please be aware that your macro needs "MenuAction" which appears to be defined somewhere else. If you have that class in another file, make sure this file is executed as startup too, preferably with "Run early on startup" so it's executed before your main macro, or load this file through "require".
Matthias
Matthias - you're too kind! If I have coded further it is by standing on the shoulders of giants.
Fixed the bug but still get the same error- debug pointed to another script I had installed (density_map.lym) Removed that and I get a new error:
uninitialized constant PhotonicsButtons::MenuAction
Which I guess is what you were talking about. I don't have that class defined anywhere, and found the following in the forums and inserted it:
But I still get an error at the same line...
I guess I can only copy and paste together so much!
Can you post your PCell code too? Then I can reproduce your error or fix the code.
I don't have time right now to try, but it's possible just replacing the word "MenuAction" with "Action" may work. (And remove the class MenuAction you pasted at the top).
Also, as a general statement, the whole MenuAction.new(...) do ... end part, and the last three lines, are perhaps not the best way to do it in my opinion. I know you copied from another example so it's not your fault. But in general you can leave off any menu manipulation whatsoever from your code and just use the Properties button that Matthias talked about. Set "Show in menu" to true, set Menu Path to "@toolbar.end" (without the quotes), click OK. (Make sure you use .lym file though, which supports this with nothing required to be typed in the script itself).
Anyway, post your PCell code and I will help get it working.
Thanks,
David
I'll give that a try in a few minutes. Below is the PCell code:
OK, I did some more reading and I see that the code wrapper I was using was from old scripts before macros. (From http://klayout.de/forum/comments.php?DiscussionID=310&Focus=1425#Comment_1425). Right now I have:
But now the button doesn't do anything. If I remove:
It will run when I hit the play button in the IDE but I still get the original error message pointing to the line:
Yes, the only down-side of .lym is you can't call one .lym from another .lym using the ruby "load" command. (You can call .rb files though.) Otherwise, .lym and its associated benefits (like "Show in menu") is preferred.
BTW Matthias, is that an option for a future release? (Adding the ability to 'load' one lym from another.)
Thanks for posting the PCell. I can't try it right now but will in a few hours and let you know what the issue is.
You were very close!
Search for the string "#DNH" to see what I added. Basically,
Here is the PCell, and then I'll paste the calling .lym file afterwards.
Here is the calling .lym file:
Lastly, you could put some error checking on the input values, and also I'd recommend wrapping the bulk of the calling .lym file in
Incidentally, I use KL for photonics too. Glad to see another photonics user on the forum.
Outstanding! Got it working, thank you!
Next step question: the script drops the PCell at 0,0. Is it possible for the user to place the PCell with the mouse (same as when you insert an instance?) I remember reading it is non-trivial for scripts to interact with mouse clicks. I guess I could add those as inputs as well (user defined x and y). Or maybe make it so the PCell is dropped in the center of the screen?
And small world! I found your "TheRedToolbox" which is more or less what I'm trying to create. I want to add a few PCell buttons to the toolbar for repetitive structures we want to vary on the wafer. Then, package it up so my co-workers could use it as well. Spending a week (so far) now learning PCells and scripting will save us a ton of time in layout.
You are right, it's nontrivial. I wanted to do that once and gave up (though, I didn't spend a huge amount of time on it).
If you get it working, post it here so I can see how it works.
I'd add x and y as user inputs.
Where did you find TheRedToolbox? It's likely it's a very old and buggy version -- email me on david.n.hutch att gmail and we can discuss more.
Hi all,
I really like what is going on here :-)
I have a suggestion how to enter the instance. Instead of creating the instance at 0,0 you can configure the editor with the requested parameters and enter Instance mode. This code will do this configuration (for Basic.CIRCLE) and enters instance mode:
After the last statement, the mouse drags the instance you have configured and you can drop it. A slightly ugly side effect is that the property window will open too, but you can close it with Ok.
Implementing a mouse drop scheme directly in Ruby is possible but that involves creating a "Plugin" which adds some other level of complexity here. In the end that solution is capable of integrating rich functionality into the KLayout framework (as a matter of fact, the editor functions are based on the same interface), but if the above scheme is sufficient that is by far the easiest solution.
Matthias
Thanks Matthias, I'll take a crack at that tomorrow.
Sending email now David.
Ah ha, I see now. This is what I meant when I originally posted "Figure out a keyboard shortcut to the PCell window". I kind of like using the built in PCell/Instance window instead of reinventing the wheel with my own input window. Here, the PCell/Instance window works as the input form and the user can place the instance with the mouse.
Related:
Is it possible to make the PCell tab active? I assume it must have an attribute associated with it since the window remember which tab I had selected.
Matthias,
That's really neat, I had no idea you could do that.
Is it possible to employ a similar trick to draw a shape? Say I wanted to recreate the "Box" button that is already on the toolbar. (I know it exists already, but I'm imagining adding to it some complicated functionality such as programmatically choosing the layer based on what is nearby.) Is the only way to achieve this through Plugins, or is there a way similar to your app.set_config lines above?
Thanks,
David
Well, sorry for mentioning this simple solution so late .. the "action...trigger" trick is basically just simulating the button click on the "Instance" button. No more and no less. That gives no control over what is happening afterwards.
The wish to select the PCell page is such a case. Unless KLayout selects the PCell page by itself there are only crude hacks to select the PCell page: one solution would involve locating the child widgets in the instance dialog using the Qt binding inside Ruby and directly manipulating them. But that solution will be invalid as soon as tiny things change on the user interface - such as widget names. So that will be a solution which might require a lot of maintenance to keep track of KLayout updates.
The other solution is the big Plugin one. If you're interested in that: there is a brief description here: http://klayout.de/doc/programming/application_api.html#h2-783. The box functionality can be reimplementation using that scheme, but I don't have sample code at hand.
I don't dare to recommend any of these solutions. Both are not straightforward to use. You got pretty far with your custom user interface solution already.
Best regards
Matthias
That makes sense- its such a minor issue I'm not worried about it.
Slightly bigger question: how can you assign icon's to menu items this way? I've Matthias post the code below:
But if you add it to the menu bar through the IDE I haven't been able to figure out how to assign an icon. Is that not possible with this shortcut?
You can use the a.icon = "file path" line which you commented out?
But I guess you are asking a way to assign this via GUI, for which there is no way that I know of.
In fact, I think it cannot be possible, because there is no xml tag contained in the .lym file, and all the macro properties window does is add metadata to the .lym file.
My first reaction was to suggest to add an xml tag to .lym specification. That seems to be some information you would want to store within the .lym script itself... But then, the icon.png (or whatever) file is still a separate file and if you copy the .lym to another location or computer then the link to the .png can break. So, this doesn't make it any more self-contained, which is perhaps the point of .lym over .rb.
However it is possible to represent an image as a string, inside the .lym file. For small images such as icons this may be a reasonable approach. Though then you start needing to check the image size before conversion to a string, or to scale the image down prior to converting to string, and it starts to become more complicated.
Anyway just some thoughts...
Hi NMF,
by "assign icon in IDE" you mean in the macro properties, right?
Right now you cannot assign an icon that way. That's because the function was intended to create menu entries.
But that's a nice feature suggestion.
Matthias