Python implementation of PCell helper with callback

This commit is contained in:
Matthias Koefferlein 2022-10-30 00:15:48 +02:00
parent 1b666e1cc8
commit 8aa135b964
1 changed files with 108 additions and 28 deletions

View File

@ -162,6 +162,51 @@ It is supposed to adjust parameters to render a consistent parameter set and to
parameter range errors. This method is called for example inside the PCell user interface to
compute the actual parameters when "Apply" is pressed.
@method callback_impl(name)
@brief Provides a callback on a parameter change
This method applies to user interface changes only. Whenever a parameter is changed
on the parameter page, this method is called with the name of the parameter.
On some occasions, this method called to establish a configuration unspecifically.
In this case, the name is an empty string - indicating "all parameters may have changed".
This method can change the state of this or any other parameter. For this, the
state objects are supplied instead of the parameter values. For example to enable
parameter "b" when a boolean parameter "a" is true, use the following code:
@code
def callback_impl(self, name):
if name == "a" or name == "":
b.enabled = a.value
@/code
The "enabled" attribute of the \\PCellParameterState object indicates whether the
parameter is enabled in the user interface. "a.value" delivers the value of the
(boolean type assumed) parameter "a".
Note that the above code also checks for empty name to consider the case of a
global refresh.
Further useful attributes of the parameters are:
@ul
@li
@b enabled @/b: the parameter entry is grayed out if false
@/li
@li
@b readonly @/b: the parameter cannot be edited (less strict than enabled)
@/li
@li
@b visible @/b: the parameter entry is not visible if false
@/li
@li
@b icon @/b: Sets an icon in front of the parameter indicating an error or a
warning (use \\PCellParameterState#WarningIcon or \\PCellParameterState#ErrorIcon).
@/li
@/ul
@method can_create_from_shape_impl
@brief Returns true if the PCell can be created from the given shape
@ -232,13 +277,16 @@ class _PCellDeclarationHelperParameterDescriptor(object):
the descriptor acts as a value holder (self.value)
"""
def __init__(self, param_index):
def __init__(self, param_index, param_name):
self.param_index = param_index
self.param_name = param_name
self.value = None
def __get__(self, obj, type = None):
if obj._param_values:
return obj._param_values[self.param_index]
elif obj._param_states:
return obj._param_states.parameter(self.param_name)
else:
return self.value
@ -261,6 +309,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
# "private" attributes
self._param_decls = []
self._param_values = None
self._param_states = None
self._layer_param_index = []
self._layers = []
# public attributes
@ -290,7 +339,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
# create accessor methods for the parameters
param_index = len(self._param_decls)
setattr(type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index))
setattr(type(self), name, _PCellDeclarationHelperParameterDescriptor(param_index, name))
if value_type == type(self).TypeLayer:
setattr(type(self), name + "_layer", _PCellDeclarationHelperLayerDescriptor(len(self._layer_param_index)))
@ -323,8 +372,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
implementation of display_text
"""
self._param_values = parameters
text = self.display_text_impl()
self._param_values = None
try:
text = self.display_text_impl()
finally:
self._param_values = None
return text
def get_parameters(self):
@ -341,7 +392,7 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
self._param_values = None
return v
def init_values(self, values = None, layers = None):
def init_values(self, values = None, layers = None, states = None):
"""
initializes the temporary parameter values
"values" are the original values. If "None" is given, the
@ -349,7 +400,11 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
"layers" are the layer indexes corresponding to the layer
parameters.
"""
if not values:
self._param_values = None
self._param_states = None
if states:
self._param_states = states
elif not values:
self._param_values = []
for pd in self._param_decls:
self._param_values.append(pd.default)
@ -359,29 +414,48 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
def finish(self):
"""
Needs to be called at the end of produce() after init_values was used
Needs to be called at the end of an implementation
"""
self._param_values = None
self._param_states = None
self._layers = None
self._cell = None
self._layout = None
self._layer = None
self._shape = None
def get_layers(self, parameters):
"""
get the layer definitions
gets the layer definitions
"""
layers = []
for i in self._layer_param_index:
layers.append(parameters[i])
return layers
def callback(self, layout, name, states):
"""
callback (change state on parameter change)
"""
self.init_values(states = states)
self.layout = layout
try:
self.callback_impl(name)
finally:
self.finish()
def coerce_parameters(self, layout, parameters):
"""
coerce parameters (make consistent)
"""
self.init_values(parameters)
self.layout = layout
self.coerce_parameters_impl()
self.layout = None
return self.get_values()
try:
self.coerce_parameters_impl()
parameters = self.get_values()
finally:
self.finish()
return parameters
def produce(self, layout, layers, parameters, cell):
"""
@ -390,10 +464,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
self.init_values(parameters, layers)
self.cell = cell
self.layout = layout
self.produce_impl()
self.cell = None
self.layout = None
self.finish()
try:
self.produce_impl()
finally:
self.finish()
def can_create_from_shape(self, layout, shape, layer):
"""
@ -402,10 +476,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
self.layout = layout
self.shape = shape
self.layer = layer
ret = self.can_create_from_shape_impl()
self.layout = None
self.shape = None
self.layer = None
try:
ret = self.can_create_from_shape_impl()
finally:
self.finish()
return ret
def transformation_from_shape(self, layout, shape, layer):
@ -415,10 +489,10 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
self.layout = layout
self.shape = shape
self.layer = layer
t = self.transformation_from_shape_impl()
self.layout = None
self.shape = None
self.layer = None
try:
t = self.transformation_from_shape_impl()
finally:
self.finish()
return t
def parameters_from_shape(self, layout, shape, layer):
@ -430,11 +504,11 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
self.layout = layout
self.shape = shape
self.layer = layer
self.parameters_from_shape_impl()
param = self.get_values()
self.layout = None
self.shape = None
self.layer = None
try:
self.parameters_from_shape_impl()
param = self.get_values()
finally:
self.finish()
return param
def display_text_impl(self):
@ -449,6 +523,12 @@ class _PCellDeclarationHelper(pya.PCellDeclaration):
"""
pass
def callback_impl(self, name):
"""
default implementation
"""
pass
def produce_impl(self):
"""
default implementation