mirror of https://github.com/KLayout/klayout.git
commit
4a80a10a2d
|
|
@ -157,6 +157,53 @@ 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(name)
|
||||
if name == "a" || name == ""
|
||||
b.enabled = a.value
|
||||
end
|
||||
end
|
||||
@/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
|
||||
|
|
@ -227,12 +274,13 @@ module RBA
|
|||
def initialize
|
||||
@param_decls = []
|
||||
@param_values = nil
|
||||
@param_states = nil
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
@cell = nil
|
||||
@layer_param_index = []
|
||||
@layers = []
|
||||
@layers = nil
|
||||
end
|
||||
|
||||
# provide accessors for the current layout and cell (for prod)
|
||||
|
|
@ -244,6 +292,40 @@ module RBA
|
|||
def _layout; @layout; end
|
||||
def _cell; @cell; end
|
||||
def _shape; @shape; end
|
||||
|
||||
# A helper method to access the nth parameter
|
||||
|
||||
def _get_param(nth, name)
|
||||
if @param_states
|
||||
if ! @param_states.has_parameter?(name)
|
||||
return RBA::PCellParameterState::new
|
||||
else
|
||||
return @param_states.parameter(name)
|
||||
end
|
||||
else
|
||||
@param_values || raise("No parameters available.")
|
||||
while @param_values.size <= nth
|
||||
@param_values << nil
|
||||
end
|
||||
return @param_values[nth]
|
||||
end
|
||||
end
|
||||
|
||||
# A helper method to set the nth parameter
|
||||
|
||||
def _set_param(nth, value)
|
||||
@param_values || raise("Cannot set parameter - inside 'callback_impl' use 'param_name.value = ...' to set the parameter's value.")
|
||||
if @param_values.size > nth
|
||||
@param_values[nth] = value
|
||||
end
|
||||
end
|
||||
|
||||
# A helper method to access the nth layer
|
||||
|
||||
def _get_layer(nth)
|
||||
@layers || raise("No layer index available - layers can be used only inside 'produce_impl'.")
|
||||
@layers[nth]
|
||||
end
|
||||
|
||||
# define a parameter
|
||||
# name -> the short name of the parameter
|
||||
|
|
@ -267,14 +349,18 @@ module RBA
|
|||
# param_{name}_layer
|
||||
|
||||
def param(name, type, description, args = {})
|
||||
|
||||
if name !~ /^[_A-Za-z]\w*$/
|
||||
raise "Invalid parameter name #{name} (needs to be a word)"
|
||||
end
|
||||
|
||||
# create accessor methods for the parameters
|
||||
param_index = @param_decls.length
|
||||
self.instance_eval("def #{name.to_s}; @param_values[#{param_index}]; end")
|
||||
self.instance_eval("def set_#{name.to_s}(v); @param_values[#{param_index}] = v; end")
|
||||
self.instance_eval("def #{name.to_s}=(v); @param_values[#{param_index}] = v; end")
|
||||
self.instance_eval("def #{name.to_s}; self._get_param(#{param_index}, '#{name}'); end")
|
||||
self.instance_eval("def set_#{name.to_s}(v); self._set_param(#{param_index}, v); end")
|
||||
self.instance_eval("def #{name.to_s}=(v); self._set_param(#{param_index}, v); end")
|
||||
if type == TypeLayer
|
||||
self.instance_eval("def #{name.to_s}_layer; @layers[#{@layer_param_index.length}]; end")
|
||||
self.instance_eval("def #{name.to_s}_layer; self._get_layer(#{@layer_param_index.length}); end")
|
||||
@layer_param_index.push(param_index)
|
||||
end
|
||||
|
||||
|
|
@ -307,8 +393,11 @@ module RBA
|
|||
# implementation of display_text
|
||||
def display_text(parameters)
|
||||
@param_values = parameters
|
||||
text = display_text_impl
|
||||
@param_values = nil
|
||||
begin
|
||||
text = display_text_impl
|
||||
ensure
|
||||
@param_values = nil
|
||||
end
|
||||
text
|
||||
end
|
||||
|
||||
|
|
@ -326,9 +415,28 @@ module RBA
|
|||
def coerce_parameters(layout, parameters)
|
||||
@param_values = parameters
|
||||
@layout = layout
|
||||
coerce_parameters_impl
|
||||
@layout = nil
|
||||
@param_values
|
||||
ret = parameters
|
||||
begin
|
||||
coerce_parameters_impl
|
||||
ensure
|
||||
@layout = nil
|
||||
ret = @param_values
|
||||
@param_values = nil
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
# parameter change callback
|
||||
def callback(layout, name, states)
|
||||
@param_values = nil
|
||||
@param_states = states
|
||||
@layout = layout
|
||||
begin
|
||||
callback_impl(name)
|
||||
ensure
|
||||
@param_states = nil
|
||||
@layout = nil
|
||||
end
|
||||
end
|
||||
|
||||
# produce the layout
|
||||
|
|
@ -337,22 +445,29 @@ module RBA
|
|||
@cell = cell
|
||||
@param_values = parameters
|
||||
@layout = layout
|
||||
produce_impl
|
||||
@layers = nil
|
||||
@cell = nil
|
||||
@param_values = nil
|
||||
@layout = nil
|
||||
begin
|
||||
produce_impl
|
||||
ensure
|
||||
@layers = nil
|
||||
@cell = nil
|
||||
@param_values = nil
|
||||
@layout = nil
|
||||
end
|
||||
end
|
||||
|
||||
# produce a helper for can_create_from_shape
|
||||
def can_create_from_shape(layout, shape, layer)
|
||||
ret = false
|
||||
@layout = layout
|
||||
@shape = shape
|
||||
@layer = layer
|
||||
ret = can_create_from_shape_impl
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
begin
|
||||
ret = can_create_from_shape_impl
|
||||
ensure
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
|
|
@ -361,10 +476,13 @@ module RBA
|
|||
@layout = layout
|
||||
@shape = shape
|
||||
@layer = layer
|
||||
t = transformation_from_shape_impl
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
begin
|
||||
t = transformation_from_shape_impl
|
||||
ensure
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
end
|
||||
t
|
||||
end
|
||||
|
||||
|
|
@ -375,10 +493,13 @@ module RBA
|
|||
@layout = layout
|
||||
@shape = shape
|
||||
@layer = layer
|
||||
parameters_from_shape_impl
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
begin
|
||||
parameters_from_shape_impl
|
||||
ensure
|
||||
@layout = nil
|
||||
@shape = nil
|
||||
@layer = nil
|
||||
end
|
||||
@param_values
|
||||
end
|
||||
|
||||
|
|
@ -391,6 +512,10 @@ module RBA
|
|||
def coerce_parameters_impl
|
||||
end
|
||||
|
||||
# default implementation
|
||||
def callback_impl(name)
|
||||
end
|
||||
|
||||
# default implementation
|
||||
def produce_impl
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -795,6 +795,8 @@ Layout::delete_cells (const std::set<cell_index_type> &cells_to_delete)
|
|||
}
|
||||
}
|
||||
|
||||
db::LayoutLocker locker (this);
|
||||
|
||||
// Clear all instances
|
||||
for (std::set<cell_index_type>::const_iterator c = cells_to_delete.begin (); c != cells_to_delete.end (); ++c) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1414,7 +1414,7 @@ get_merged_shapes_of_net (const db::hier_clusters<db::NetShape> &clusters, db::c
|
|||
db::PolygonRef::polygon_edge_iterator e = pr.begin_edge ();
|
||||
if (! e.at_end ()) {
|
||||
// pick one reference point for the label
|
||||
if (! any_ref && (*e).p1 () < ref) {
|
||||
if (! any_ref || (*e).p1 () < ref) {
|
||||
ref = (*e).p1 ();
|
||||
any_ref = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,80 @@
|
|||
namespace db
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// ParameterStates implementation
|
||||
|
||||
ParameterStates::ParameterStates ()
|
||||
: m_states ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ParameterStates::ParameterStates (const ParameterStates &other)
|
||||
: m_states (other.m_states)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ParameterStates::ParameterStates (ParameterStates &&other)
|
||||
: m_states (std::move (other.m_states))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ParameterStates &
|
||||
ParameterStates::operator= (const ParameterStates &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_states = other.m_states;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
ParameterStates::set_parameter (const std::string &name, const ParameterState &ps)
|
||||
{
|
||||
m_states [name] = ps;
|
||||
}
|
||||
|
||||
ParameterState &
|
||||
ParameterStates::parameter (const std::string &name)
|
||||
{
|
||||
return m_states [name];
|
||||
}
|
||||
|
||||
const ParameterState &
|
||||
ParameterStates::parameter (const std::string &name) const
|
||||
{
|
||||
auto i = m_states.find (name);
|
||||
if (i == m_states.end ()) {
|
||||
static ParameterState empty;
|
||||
return empty;
|
||||
} else {
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ParameterStates::has_parameter (const std::string &name) const
|
||||
{
|
||||
return m_states.find (name) != m_states.end ();
|
||||
}
|
||||
|
||||
bool
|
||||
ParameterStates::values_are_equal (const db::ParameterStates &other) const
|
||||
{
|
||||
auto i = m_states.begin (), j = other.m_states.begin ();
|
||||
while (i != m_states.end () && j != other.m_states.end () && i->first == j->first && i->second.value () == j->second.value ()) {
|
||||
++i; ++j;
|
||||
}
|
||||
return i == m_states.end () && j == other.m_states.end ();
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// PCellDeclaration implementation
|
||||
|
||||
PCellDeclaration::PCellDeclaration ()
|
||||
: m_ref_count (0), m_id (0), mp_layout (0), m_has_parameter_declarations (false)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public:
|
|||
t_layer, // a layer (value is a db::LayerProperties object)
|
||||
t_shape, // a shape (a db::Point, db::Box, db::Polygon, db::Edge or db::Path) rendering a guiding shape
|
||||
t_list, // a list of strings
|
||||
t_callback, // callback only (button)
|
||||
t_none // no specific type
|
||||
};
|
||||
|
||||
|
|
@ -323,6 +324,193 @@ public:
|
|||
std::string symbolic;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the dynamic state of a single parameter
|
||||
*/
|
||||
class DB_PUBLIC ParameterState
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief A enum describing the icon type
|
||||
*/
|
||||
enum Icon {
|
||||
NoIcon = 0,
|
||||
InfoIcon = 1,
|
||||
ErrorIcon = 2,
|
||||
WarningIcon = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameterized constructor
|
||||
*/
|
||||
ParameterState ()
|
||||
: m_value (), m_visible (true), m_enabled (true), m_readonly (false), m_icon (NoIcon)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the value
|
||||
*/
|
||||
const tl::Variant &value () const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the value
|
||||
*/
|
||||
void set_value (const tl::Variant &v)
|
||||
{
|
||||
m_value = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the visibility state
|
||||
*/
|
||||
bool is_visible () const
|
||||
{
|
||||
return m_visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the visibility
|
||||
*/
|
||||
void set_visible (bool v)
|
||||
{
|
||||
m_visible = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the enabled state
|
||||
*/
|
||||
bool is_enabled () const
|
||||
{
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the enabled state
|
||||
*/
|
||||
void set_enabled (bool v)
|
||||
{
|
||||
m_enabled = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the parameter is read-only
|
||||
*/
|
||||
bool is_readonly () const
|
||||
{
|
||||
return m_readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a value indicating whether the parameter is read-only
|
||||
*/
|
||||
void set_readonly (bool f)
|
||||
{
|
||||
m_readonly = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the tooltip for the parameter
|
||||
*/
|
||||
const std::string &tooltip () const
|
||||
{
|
||||
return m_tooltip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the tooltip
|
||||
*/
|
||||
void set_tooltip (const std::string &s)
|
||||
{
|
||||
m_tooltip = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the icon
|
||||
*/
|
||||
Icon icon () const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the icon
|
||||
*/
|
||||
void set_icon (Icon i)
|
||||
{
|
||||
m_icon = i;
|
||||
}
|
||||
|
||||
private:
|
||||
tl::Variant m_value;
|
||||
bool m_visible, m_enabled, m_readonly;
|
||||
std::string m_tooltip;
|
||||
Icon m_icon;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents the state of call parameters for the callback implementation
|
||||
*/
|
||||
class DB_PUBLIC ParameterStates
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
ParameterStates ();
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
ParameterStates (const ParameterStates &other);
|
||||
|
||||
/**
|
||||
* @brief Move constructor
|
||||
*/
|
||||
ParameterStates (ParameterStates &&other);
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
ParameterStates &operator= (const ParameterStates &other);
|
||||
|
||||
/**
|
||||
* @brief Sets a parameter from a given state
|
||||
*/
|
||||
void set_parameter (const std::string &name, const ParameterState &ps);
|
||||
|
||||
/**
|
||||
* @brief Gets the parameter state for the parameter with the given name
|
||||
*
|
||||
* If the name is not a valid parameter name, the behavior is undefined.
|
||||
*/
|
||||
ParameterState ¶meter (const std::string &name);
|
||||
|
||||
/**
|
||||
* @brief Gets the parameter state for the parameter with the given name
|
||||
*
|
||||
* If the name is not a valid parameter name, the behavior is undefined.
|
||||
*/
|
||||
const ParameterState ¶meter (const std::string &name) const;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether a parameter with that name is present
|
||||
*/
|
||||
bool has_parameter (const std::string &name) const;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the values of the parameter states are equal
|
||||
*/
|
||||
bool values_are_equal (const db::ParameterStates &other) const;
|
||||
|
||||
public:
|
||||
std::map<std::string, ParameterState> m_states;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A declaration for a PCell
|
||||
*/
|
||||
|
|
@ -374,7 +562,25 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Produce a layout for the given parameter set and using the given layers.
|
||||
* @brief Callback on parameter change
|
||||
*
|
||||
* This method allows implementing dynamic behavior on the change of a parameter value.
|
||||
* A ParameterStatus object is supplied that allows changing parameter enabled status, visibility and value.
|
||||
* The callback also acts as receiver for t_callback type parameters which only present a button.
|
||||
*
|
||||
* The callback function receives the name of the parameter that was changed.
|
||||
* On some occasions, the callback is called unspecifically, for example for the initialization.
|
||||
* In that case, the parameter name is empty.
|
||||
*
|
||||
* Exceptions from this implementation are ignored.
|
||||
*/
|
||||
virtual void callback (const db::Layout & /*layout*/, const std::string & /*name*/, ParameterStates & /*states*/) const
|
||||
{
|
||||
// the default implementation does nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Produces a layout for the given parameter set and using the given layers.
|
||||
*
|
||||
* A reimplementation of that method should produce the desired layout for the given parameter set.
|
||||
* The layout shall be put into the given cell. This code may create cell instances to other cells
|
||||
|
|
|
|||
|
|
@ -124,6 +124,11 @@ public:
|
|||
*/
|
||||
virtual void put (const db::Edge &e);
|
||||
|
||||
/**
|
||||
* @brief Implementation of the EdgeSink interface
|
||||
*/
|
||||
virtual void put (const db::Edge & /*e*/, int /*tag*/) { }
|
||||
|
||||
/**
|
||||
* @brief Sets the way how holes are resolved dynamically
|
||||
*
|
||||
|
|
@ -261,6 +266,11 @@ public:
|
|||
*/
|
||||
virtual void put (const db::Edge &e);
|
||||
|
||||
/**
|
||||
* @brief Implementation of the EdgeSink interface
|
||||
*/
|
||||
virtual void put (const db::Edge & /*e*/, int /*tag*/) { }
|
||||
|
||||
private:
|
||||
db::Coord m_y;
|
||||
PolygonSink *mp_psink;
|
||||
|
|
|
|||
|
|
@ -911,6 +911,7 @@ class ErrorCatchingEdgeSink
|
|||
// TODO: we should not use exceptions to indicate a condition, but right now, there is no good alternative
|
||||
// and this is considered an error anyway.
|
||||
virtual void put (const db::Edge &) { throw OddPolygonException (); }
|
||||
virtual void put (const db::Edge &, int) { }
|
||||
virtual void crossing_edge (const db::Edge &) { throw OddPolygonException (); }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -248,6 +248,26 @@ public:
|
|||
end_edge_differences_event ();
|
||||
}
|
||||
|
||||
virtual void begin_edge_pair_differences ()
|
||||
{
|
||||
begin_edge_pair_differences_event ();
|
||||
}
|
||||
|
||||
virtual void detailed_diff (const db::PropertiesRepository & /*pr*/, const std::vector <std::pair <db::EdgePair, db::properties_id_type> > &a, const std::vector <std::pair <db::EdgePair, db::properties_id_type> > &b)
|
||||
{
|
||||
for (std::vector <std::pair <db::EdgePair, db::properties_id_type> >::const_iterator i = a.begin (); i != a.end (); ++i) {
|
||||
edge_pair_in_a_only_event (i->first, i->second);
|
||||
}
|
||||
for (std::vector <std::pair <db::EdgePair, db::properties_id_type> >::const_iterator i = b.begin (); i != b.end (); ++i) {
|
||||
edge_pair_in_b_only_event (i->first, i->second);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void end_edge_pair_differences ()
|
||||
{
|
||||
end_edge_pair_differences_event ();
|
||||
}
|
||||
|
||||
virtual void begin_text_differences ()
|
||||
{
|
||||
begin_text_differences_event ();
|
||||
|
|
@ -353,6 +373,10 @@ public:
|
|||
tl::event<const db::Edge & /*anotb*/, db::properties_id_type /*prop_id*/> edge_in_a_only_event;
|
||||
tl::event<const db::Edge & /*bnota*/, db::properties_id_type /*prop_id*/> edge_in_b_only_event;
|
||||
tl::Event end_edge_differences_event;
|
||||
tl::Event begin_edge_pair_differences_event;
|
||||
tl::event<const db::EdgePair & /*anotb*/, db::properties_id_type /*prop_id*/> edge_pair_in_a_only_event;
|
||||
tl::event<const db::EdgePair & /*bnota*/, db::properties_id_type /*prop_id*/> edge_pair_in_b_only_event;
|
||||
tl::Event end_edge_pair_differences_event;
|
||||
tl::Event begin_text_differences_event;
|
||||
tl::event<const db::Text & /*anotb*/, db::properties_id_type /*prop_id*/> text_in_a_only_event;
|
||||
tl::event<const db::Text & /*bnota*/, db::properties_id_type /*prop_id*/> text_in_b_only_event;
|
||||
|
|
@ -671,6 +695,29 @@ gsi::Class<LayoutDiff> decl_LayoutDiff ("db", "LayoutDiff",
|
|||
gsi::event ("on_end_edge_differences", &LayoutDiff::end_edge_differences_event,
|
||||
"@brief This signal indicates the end of sequence of edge differences\n"
|
||||
) +
|
||||
gsi::event ("on_begin_edge_pair_differences", &LayoutDiff::begin_edge_pair_differences_event,
|
||||
"@brief This signal indicates differences in the edge pairs on the current layer\n"
|
||||
"The current layer is indicated by the \\begin_layer_event signal or can be obtained from the diff object "
|
||||
"through \\LayoutDiff#layer_info_a, \\LayoutDiff#layer_index_a, \\LayoutDiff#layer_info_b and \\LayoutDiff#layer_index_b. "
|
||||
"In verbose mode (see \\Verbose flag) more signals will be emitted for edge pairs that are different between the two layouts."
|
||||
"\n"
|
||||
"This event has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::event ("on_edge_pair_in_a_only", &LayoutDiff::edge_pair_in_a_only_event, gsi::arg ("anotb"), gsi::arg ("prop_id"),
|
||||
"@brief This signal indicates an edge pair that is present in the first layout only"
|
||||
"\n"
|
||||
"This event has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::event ("on_edge_pair_in_b_only", &LayoutDiff::edge_pair_in_b_only_event, gsi::arg ("bnota"), gsi::arg ("prop_id"),
|
||||
"@brief This signal indicates an edge pair that is present in the second layout only"
|
||||
"\n"
|
||||
"This event has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::event ("on_end_edge_pair_differences", &LayoutDiff::end_edge_pair_differences_event,
|
||||
"@brief This signal indicates the end of sequence of edge pair differences\n"
|
||||
"\n"
|
||||
"This event has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::event ("on_begin_text_differences", &LayoutDiff::begin_text_differences_event,
|
||||
"@brief This signal indicates differences in the texts on the current layer\n"
|
||||
"The current layer is indicated by the \\begin_layer_event signal or can be obtained from the diff object "
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
|
||||
#include "gsiDecl.h"
|
||||
#include "gsiEnums.h"
|
||||
#include "dbLayout.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "dbPCellDeclaration.h"
|
||||
|
|
@ -276,15 +277,16 @@ static db::pcell_parameters_type coerce_parameters_native (const db::PCellDeclar
|
|||
|
||||
// Provide a binding for db::PCellDeclaration for native PCell implementations
|
||||
Class<db::PCellDeclaration> decl_PCellDeclaration_Native ("db", "PCellDeclaration_Native",
|
||||
gsi::method_ext ("get_layers", &get_layer_declarations_native) +
|
||||
gsi::method_ext ("get_layers", &get_layer_declarations_native, gsi::arg ("parameters")) +
|
||||
gsi::method ("get_parameters", &db::PCellDeclaration::get_parameter_declarations) +
|
||||
gsi::method ("produce", &db::PCellDeclaration::produce) +
|
||||
gsi::method_ext ("coerce_parameters", &coerce_parameters_native) +
|
||||
gsi::method ("can_create_from_shape", &db::PCellDeclaration::can_create_from_shape) +
|
||||
gsi::method ("parameters_from_shape", &db::PCellDeclaration::parameters_from_shape) +
|
||||
gsi::method ("transformation_from_shape", &db::PCellDeclaration::transformation_from_shape) +
|
||||
gsi::method ("produce", &db::PCellDeclaration::produce, gsi::arg ("layout"), gsi::arg ("layers"), gsi::arg ("parameters"), gsi::arg ("cell")) +
|
||||
gsi::method ("callback", &db::PCellDeclaration::callback, gsi::arg ("layout"), gsi::arg ("name"), gsi::arg ("states")) +
|
||||
gsi::method_ext ("coerce_parameters", &coerce_parameters_native, gsi::arg ("layout"), gsi::arg ("parameters")) +
|
||||
gsi::method ("can_create_from_shape", &db::PCellDeclaration::can_create_from_shape, gsi::arg ("layout"), gsi::arg ("shape"), gsi::arg ("layer")) +
|
||||
gsi::method ("parameters_from_shape", &db::PCellDeclaration::parameters_from_shape, gsi::arg ("layout"), gsi::arg ("shape"), gsi::arg ("layer")) +
|
||||
gsi::method ("transformation_from_shape", &db::PCellDeclaration::transformation_from_shape, gsi::arg ("layout"), gsi::arg ("shape"), gsi::arg ("layer")) +
|
||||
gsi::method ("wants_lazy_evaluation", &db::PCellDeclaration::wants_lazy_evaluation) +
|
||||
gsi::method ("display_text", &db::PCellDeclaration::get_display_name) +
|
||||
gsi::method ("display_text", &db::PCellDeclaration::get_display_name, gsi::arg ("parameters")) +
|
||||
gsi::method ("layout", &db::PCellDeclaration::layout,
|
||||
"@brief Gets the Layout object the PCell is registered in or nil if it is not registered yet.\n"
|
||||
"This attribute has been added in version 0.27.5."
|
||||
|
|
@ -299,6 +301,97 @@ Class<db::PCellDeclaration> decl_PCellDeclaration_Native ("db", "PCellDeclaratio
|
|||
"@hide\n@alias PCellDeclaration\n"
|
||||
);
|
||||
|
||||
// Provide a binding for db::ParameterState for native PCell implementations
|
||||
Class<db::ParameterState> decl_PCellParameterState ("db", "PCellParameterState",
|
||||
gsi::method("value=", &db::ParameterState::set_value, gsi::arg ("v"),
|
||||
"@brief Sets the value of the parameter\n"
|
||||
) +
|
||||
gsi::method("value", &db::ParameterState::value,
|
||||
"@brief Gets the value of the parameter\n"
|
||||
) +
|
||||
gsi::method("visible=", &db::ParameterState::set_visible, gsi::arg ("f"),
|
||||
"@brief Sets a value indicating whether the parameter is visible in the parameter form\n"
|
||||
) +
|
||||
gsi::method("is_visible?", &db::ParameterState::is_visible,
|
||||
"@brief Gets a value indicating whether the parameter is visible in the parameter form\n"
|
||||
) +
|
||||
gsi::method("enabled=", &db::ParameterState::set_enabled, gsi::arg ("f"),
|
||||
"@brief Sets a value indicating whether the parameter is enabled in the parameter form\n"
|
||||
) +
|
||||
gsi::method("is_enabled?", &db::ParameterState::is_enabled,
|
||||
"@brief Gets a value indicating whether the parameter is enabled in the parameter form\n"
|
||||
) +
|
||||
gsi::method("readonly=", &db::ParameterState::set_readonly, gsi::arg ("f"),
|
||||
"@brief Sets a value indicating whether the parameter is made read-only (not editable) in the parameter form\n"
|
||||
) +
|
||||
gsi::method("is_readonly?", &db::ParameterState::is_readonly,
|
||||
"@brief Gets a value indicating whether the parameter is read-only (not editable) in the parameter form\n"
|
||||
) +
|
||||
gsi::method("tooltip=", &db::ParameterState::set_tooltip, gsi::arg ("s"),
|
||||
"@brief Sets the tool tip text\n"
|
||||
"\n"
|
||||
"The tool tip is shown when hovering over the parameter label or edit field."
|
||||
) +
|
||||
gsi::method("tooltip", &db::ParameterState::tooltip,
|
||||
"@brief Gets the tool tip text\n"
|
||||
) +
|
||||
gsi::method("icon=", &db::ParameterState::set_icon, gsi::arg ("i"),
|
||||
"@brief Sets the icon for the parameter\n"
|
||||
) +
|
||||
gsi::method("tooltip", &db::ParameterState::tooltip,
|
||||
"@brief Gets the icon for the parameter\n"
|
||||
),
|
||||
"@brief Provides access to the attributes of a single parameter within \\PCellParameterStates.\n"
|
||||
"\n"
|
||||
"See \\PCellParameterStates for details about this feature.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.28."
|
||||
);
|
||||
|
||||
gsi::EnumIn<db::ParameterState, db::ParameterState::Icon> decl_PCellParameterState_Icon ("db", "ParameterStateIcon",
|
||||
gsi::enum_const ("NoIcon", db::ParameterState::NoIcon,
|
||||
"@brief No icon is shown for the parameter\n"
|
||||
) +
|
||||
gsi::enum_const ("InfoIcon", db::ParameterState::InfoIcon,
|
||||
"@brief A general 'information' icon is shown\n"
|
||||
) +
|
||||
gsi::enum_const ("ErrorIcon", db::ParameterState::ErrorIcon,
|
||||
"@brief An icon indicating an error is shown\n"
|
||||
) +
|
||||
gsi::enum_const ("WarningIcon", db::ParameterState::WarningIcon,
|
||||
"@brief An icon indicating a warning is shown\n"
|
||||
),
|
||||
"@brief This enum specifies the icon shown next to the parameter in PCell parameter list.\n"
|
||||
"\n"
|
||||
"This enum was introduced in version 0.28.\n"
|
||||
);
|
||||
|
||||
// Inject the NetlistCrossReference::Status declarations into NetlistCrossReference:
|
||||
gsi::ClassExt<db::ParameterState> inject_PCellParameterState_Icon_in_parent (decl_PCellParameterState_Icon.defs ());
|
||||
|
||||
// Provide a binding for db::ParameterStates for native PCell implementations
|
||||
Class<db::ParameterStates> decl_PCellParameterStates ("db", "PCellParameterStates",
|
||||
gsi::method ("has_parameter?", &db::ParameterStates::has_parameter, gsi::arg ("name"),
|
||||
"@brief Gets a value indicating whether a parameter with that name exists\n"
|
||||
) +
|
||||
gsi::method ("parameter", static_cast<db::ParameterState & (db::ParameterStates::*) (const std::string &name)> (&db::ParameterStates::parameter), gsi::arg ("name"),
|
||||
"@brief Gets the parameter by name\n"
|
||||
"\n"
|
||||
"This will return a \\PCellParameterState object that can be used to manipulate the "
|
||||
"parameter state."
|
||||
),
|
||||
"@brief Provides access to the parameter states inside a 'callback' implementation of a PCell\n"
|
||||
"\n"
|
||||
"Example: enables or disables a parameter 'n' based on the value:\n"
|
||||
"\n"
|
||||
"@code\n"
|
||||
"n_param = states.parameter(\"n\")\n"
|
||||
"n_param.enabled = n_param.value > 1.0\n"
|
||||
"@/code\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.28."
|
||||
);
|
||||
|
||||
class PCellDeclarationImpl
|
||||
: public db::PCellDeclaration
|
||||
{
|
||||
|
|
@ -359,6 +452,20 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void callback_fb (const db::Layout &layout, const std::string &name, db::ParameterStates &states) const
|
||||
{
|
||||
db::PCellDeclaration::callback (layout, name, states);
|
||||
}
|
||||
|
||||
virtual void callback (const db::Layout &layout, const std::string &name, db::ParameterStates &states) const
|
||||
{
|
||||
if (cb_callback.can_issue ()) {
|
||||
cb_callback.issue<db::PCellDeclaration, const db::Layout &, const std::string &, db::ParameterStates &> (&db::PCellDeclaration::callback, layout, name, states);
|
||||
} else {
|
||||
db::PCellDeclaration::callback (layout, name, states);
|
||||
}
|
||||
}
|
||||
|
||||
void produce_fb (const db::Layout &layout, const std::vector<unsigned int> &layer_ids, const db::pcell_parameters_type ¶meters, db::Cell &cell) const
|
||||
{
|
||||
return db::PCellDeclaration::produce (layout, layer_ids, parameters, cell);
|
||||
|
|
@ -451,6 +558,7 @@ public:
|
|||
gsi::Callback cb_transformation_from_shape;
|
||||
gsi::Callback cb_wants_lazy_evaluation;
|
||||
gsi::Callback cb_coerce_parameters;
|
||||
gsi::Callback cb_callback;
|
||||
gsi::Callback cb_get_display_name;
|
||||
};
|
||||
|
||||
|
|
@ -458,6 +566,7 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
|
|||
// fallback implementations to reroute Ruby calls to the base class:
|
||||
gsi::method ("get_parameters", &PCellDeclarationImpl::get_parameter_declarations_fb, "@hide") +
|
||||
gsi::method ("produce", &PCellDeclarationImpl::produce_fb, "@hide") +
|
||||
gsi::method ("callback", &PCellDeclarationImpl::callback_fb, "@hide") +
|
||||
gsi::method ("can_create_from_shape", &PCellDeclarationImpl::can_create_from_shape_fb, "@hide") +
|
||||
gsi::method ("parameters_from_shape", &PCellDeclarationImpl::parameters_from_shape_fb, "@hide") +
|
||||
gsi::method ("transformation_from_shape", &PCellDeclarationImpl::transformation_from_shape_fb, "@hide") +
|
||||
|
|
@ -493,6 +602,25 @@ Class<PCellDeclarationImpl> decl_PCellDeclaration (decl_PCellDeclaration_Native,
|
|||
"\n"
|
||||
"It can raise an exception to indicate that something is not correct.\n"
|
||||
) +
|
||||
gsi::callback ("callback", &PCellDeclarationImpl::callback, &PCellDeclarationImpl::cb_callback, gsi::arg ("layout"), gsi::arg ("name"), gsi::arg ("states"),
|
||||
"@brief Indicates a parameter change and allows implementing actions based on the parameter value\n"
|
||||
"@param layout The layout object in which the PCell will be produced\n"
|
||||
"@param name The name of the parameter which has changed or an empty string if all parameters need to be considered\n"
|
||||
"@param states A \\PCellParameterStates object which can be used to manipulate the parameter states\n"
|
||||
"This method may be reimplemented to implement parameter-specific actions upon value change or button callbacks. "
|
||||
"Whenever the value of a parameter is changed in the PCell parameter form, this method is called with the name of the parameter "
|
||||
"in 'name'. The implementation can manipulate values or states (enabled, visible) or parameters using the "
|
||||
"\\PCellParameterStates object passed in 'states'.\n"
|
||||
"\n"
|
||||
"Initially, this method will be called with an empty parameter name to indicate a global change. The implementation "
|
||||
"may then consolidate all states. The initial state is build from the 'readonly' (disabled) or 'hidden' (invisible) parameter "
|
||||
"declarations.\n"
|
||||
"\n"
|
||||
"This method is also called when a button-type parameter is present and the button is pressed. In this case the parameter "
|
||||
"name is the name of the button.\n"
|
||||
"\n"
|
||||
"This feature has been introduced in version 0.28."
|
||||
) +
|
||||
gsi::callback ("produce", &PCellDeclarationImpl::produce, &PCellDeclarationImpl::cb_produce, gsi::arg ("layout"), gsi::arg ("layer_ids"), gsi::arg ("parameters"), gsi::arg ("cell"),
|
||||
"@brief The production callback\n"
|
||||
"@param layout The layout object where the cell resides\n"
|
||||
|
|
@ -634,6 +762,11 @@ static unsigned int pd_type_list ()
|
|||
return (unsigned int) db::PCellParameterDeclaration::t_list;
|
||||
}
|
||||
|
||||
static unsigned int pd_type_callback ()
|
||||
{
|
||||
return (unsigned int) db::PCellParameterDeclaration::t_callback;
|
||||
}
|
||||
|
||||
static unsigned int pd_type_none ()
|
||||
{
|
||||
return (unsigned int) db::PCellParameterDeclaration::t_none;
|
||||
|
|
@ -763,7 +896,8 @@ Class<db::PCellParameterDeclaration> decl_PCellParameterDeclaration ("db", "PCel
|
|||
gsi::method ("TypeList", &pd_type_list, "@brief Type code: a list of variants") +
|
||||
gsi::method ("TypeLayer", &pd_type_layer, "@brief Type code: a layer (a \\LayerInfo object)") +
|
||||
gsi::method ("TypeShape", &pd_type_shape, "@brief Type code: a guiding shape (Box, Edge, Point, Polygon or Path)") +
|
||||
gsi::method ("TypeNone", &pd_type_none, "@brief Type code: unspecific type")
|
||||
gsi::method ("TypeCallback", &pd_type_callback, "@brief Type code: a button triggering a callback\n\nThis code has been introduced in version 0.28.") +
|
||||
gsi::method ("TypeNone", &pd_type_none, "@brief Type code: unspecific type")
|
||||
,
|
||||
"@brief A PCell parameter declaration\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -2452,7 +2452,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2491,7 +2490,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2535,7 +2533,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2574,7 +2571,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2617,7 +2613,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2667,7 +2662,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2716,7 +2710,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
@ -2765,7 +2758,6 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"\"metrics\" can be one of the constants \\Euclidian, \\Square or \\Projection. See there for "
|
||||
"a description of these constants.\n"
|
||||
"Use nil for this value to select the default (Euclidian metrics).\n"
|
||||
"\n"
|
||||
"\"ignore_angle\" specifies the angle limit of two edges. If two edges form an angle equal or "
|
||||
"above the given value, they will not contribute in the check. "
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@
|
|||
<p>
|
||||
Custom fonts are installed by copying the font file to a folder named "fonts"
|
||||
in one of the places in KLayout's path. The standard font can be found in
|
||||
"src/std_font.gds" in the source package.
|
||||
"src/db/db/std_font.gds" in the source package.
|
||||
</p>
|
||||
|
||||
<h2>CIRCLE and ELLIPSE</h2>
|
||||
|
|
|
|||
|
|
@ -1125,6 +1125,25 @@ A more compact way of writing this is:
|
|||
p = fill_pattern("FILL_CELL").shape(1, 0, box(0.0, 0.0, 1.0, 1.0))
|
||||
</pre>
|
||||
</p><p>
|
||||
The "shape" method takes several forms:
|
||||
</p><p>
|
||||
<ul>
|
||||
<li><tt>shape(layer, object, object ...) </tt>(1) </li>
|
||||
<li><tt>shape(layer, datatype, object, object ...) </tt>(2) </li>
|
||||
<li><tt>shape(name, object, object ...) </tt>(3) </li>
|
||||
<li><tt>shape(layer_info, object, object ...) </tt>(4) </li>
|
||||
</ul>
|
||||
</p><p>
|
||||
The first form takes a GDS2 layer number. The datatype is assumed to be 0.
|
||||
The second form takes a GDS layer and datatype number.
|
||||
The third form takes a layer name for layout systems with named layers
|
||||
(like Magic, CIF or DXF).
|
||||
The forth form takes a <class_doc href="LayerInfo">LayerInfo</class_doc> object to specify the layer.
|
||||
All forms take one to many geometry objects which are written to the respective layer.
|
||||
Geometry objects can either be created using the generator functions
|
||||
(<a href="/about/drc_ref_global.xml#box">box</a>, <a href="/about/drc_ref_global.xml#polygon">polygon</a>, <a href="/about/drc_ref_global.xml#path">path</a>). The core classes <class_doc href="DBox">DBox</class_doc>, <class_doc href="DPolygon">DPolygon</class_doc>, <class_doc href="DPath">DPath</class_doc> or
|
||||
<class_doc href="DText">DText</class_doc> are also accepted as geometry objects.
|
||||
</p><p>
|
||||
The fill pattern can be given a reference point which is used for placing the pattern. The reference point
|
||||
is the one which is aligned with the pattern origin. The following code will assign (-0.5, -0.5) as the reference
|
||||
point for the 1x1 micron rectangle. Hence the reference point is a little below and left of the rectangle which
|
||||
|
|
|
|||
|
|
@ -34,20 +34,35 @@
|
|||
|
||||
<p>
|
||||
Before nets can be extracted, a layer stack must be specified. Press "Layer Stack" on the user interface to open the
|
||||
layer stack dialog. Layers must be specified in the "layer/datatype" notation. The
|
||||
layer stack dialog or use "Edit Layer Stack" in the "Tools" menu. Layers must be specified in the "layer/datatype" notation. The
|
||||
via specification is optional. If no via layer is specified, both metal layer shapes are required to touch in order to form a
|
||||
connection. If a via layer is specified, a via shape must be present to form the connection.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
KLayout allows specification of symbolic layers and to use boolean expressions. That way it is possible to
|
||||
The layer stack (also referred to as "Connectivity") is also a technology component. This means
|
||||
if you select a technology for layout, the technology specific stack is selected. To edit the stack
|
||||
for all technologies, use the Technology Manager ("Tools/Manage Technologies") and use the
|
||||
"Connectivity" section from the technologies.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A connectivity definition can specify multiple stacks, out of which one has to be selected.
|
||||
This is useful, if your technology setup features multiple routing metal schemes for example.
|
||||
You do not need to setup different technologies for each scheme. If you have declared multiple
|
||||
stacks, you can choose one in the "Trace Net" dialog in the drop-down button right of the
|
||||
"Layer Stack" and the "Configuration" button at the bottom left.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Within the stack definition, KLayout allows specification of symbolic layers and to use boolean expressions. That way it is possible to
|
||||
assign meaningful names to layers (i.e. "POLY" or "VIA1") and to use derived layers (i.e. "ACTIVE-POLY" for
|
||||
the source and drain regions of a CMOS transistor). Read more about these features in <link href="/about/connectivity.xml"/>
|
||||
and <link href="/about/symbolic_layers.xml"/>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a layer stack has been defined, a net can be traced by pressing the "Trace Net" button and clicking on a point in the
|
||||
Once a layer stack has been defined and selected, a net can be traced by pressing the "Trace Net" button and clicking on a point in the
|
||||
layout. Starting from shapes found under this point, the net is extracted and listed in the net list on the left side of the
|
||||
net tracing dialog. If "Lock" is checked, another net can be traced by clicking at another point without having to press
|
||||
the "Trace Net" button again.
|
||||
|
|
|
|||
|
|
@ -4712,6 +4712,25 @@ CODE
|
|||
# p = fill_pattern("FILL_CELL").shape(1, 0, box(0.0, 0.0, 1.0, 1.0))
|
||||
# @/code
|
||||
#
|
||||
# The "shape" method takes several forms:
|
||||
#
|
||||
# @ul
|
||||
# @li @tt shape(layer, object, object ...) @/tt (1) @/li
|
||||
# @li @tt shape(layer, datatype, object, object ...) @/tt (2) @/li
|
||||
# @li @tt shape(name, object, object ...) @/tt (3) @/li
|
||||
# @li @tt shape(layer_info, object, object ...) @/tt (4) @/li
|
||||
# @/ul
|
||||
#
|
||||
# The first form takes a GDS2 layer number. The datatype is assumed to be 0.
|
||||
# The second form takes a GDS layer and datatype number.
|
||||
# The third form takes a layer name for layout systems with named layers
|
||||
# (like Magic, CIF or DXF).
|
||||
# The forth form takes a RBA::LayerInfo object to specify the layer.
|
||||
# All forms take one to many geometry objects which are written to the respective layer.
|
||||
# Geometry objects can either be created using the generator functions
|
||||
# (\global#box, \global#polygon, \global#path). The core classes RBA::DBox, RBA::DPolygon, RBA::DPath or
|
||||
# RBA::DText are also accepted as geometry objects.
|
||||
#
|
||||
# The fill pattern can be given a reference point which is used for placing the pattern. The reference point
|
||||
# is the one which is aligned with the pattern origin. The following code will assign (-0.5, -0.5) as the reference
|
||||
# point for the 1x1 micron rectangle. Hence the reference point is a little below and left of the rectangle which
|
||||
|
|
|
|||
|
|
@ -256,6 +256,10 @@ module DRC
|
|||
else
|
||||
raise("Argument ##{ai+1} not understood for FillCell#shape")
|
||||
end
|
||||
elsif a.is_a?(RBA::LayerInfo)
|
||||
layer = a.layer
|
||||
datatype = a.datatype
|
||||
name = a.name
|
||||
elsif a.is_a?(String)
|
||||
if !name
|
||||
name = a
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_none_32px.png</normaloff>:/align_none_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_left_32px.png</normaloff>:/align_left_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_hcenter_32px.png</normaloff>:/align_hcenter_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_right_32px.png</normaloff>:/align_right_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_none_32px.png</normaloff>:/align_none_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -221,7 +221,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_top_32px.png</normaloff>:/align_top_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -238,7 +238,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_vcenter_32px.png</normaloff>:/align_vcenter_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -308,7 +308,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_bottom_32px.png</normaloff>:/align_bottom_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -432,7 +432,7 @@
|
|||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AreaAndPerimeterDialog</class>
|
||||
<widget class="QDialog" name="AreaAndPerimeterDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>367</width>
|
||||
<height>205</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Area And Perimeter</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>11</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="perimeter_le">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Area</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>µm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>µm²</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Perimeter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="area_le">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Note: area and perimeter are computed in "merged mode". This means, overlapping shapes are counted once for area calculation.
|
||||
The perimeter calculation only takes true outside edges into account. Internal edges are ignored.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AreaAndPerimeterDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>303</x>
|
||||
<y>185</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>311</x>
|
||||
<y>201</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
@ -278,7 +278,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_none_32px.png</normaloff>:/align_none_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -311,7 +311,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_left_32px.png</normaloff>:/align_left_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -344,7 +344,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_hcenter_32px.png</normaloff>:/align_hcenter_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -377,7 +377,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_right_32px.png</normaloff>:/align_right_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -456,7 +456,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_none_32px.png</normaloff>:/align_none_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -489,7 +489,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_top_32px.png</normaloff>:/align_top_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -522,7 +522,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_vcenter_32px.png</normaloff>:/align_vcenter_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -555,7 +555,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/align_bottom_32px.png</normaloff>:/align_bottom_32px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -676,7 +676,7 @@
|
|||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/find_16px.png</normaloff>:/find_16px.png</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
|
|
@ -549,7 +549,7 @@
|
|||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
<font>
|
||||
<family>Sans Serif</family>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
<underline>false</underline>
|
||||
|
|
@ -731,7 +730,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../lay/lay/layResources.qrc">:/warn_16px@2x.png</pixmap>
|
||||
<pixmap resource="../../icons/icons.qrc">:/warn_16px@2x.png</pixmap>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
|
|
@ -899,7 +898,7 @@
|
|||
<tabstop>inst_pb</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/ct_31px.png</normaloff>:/ct_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -164,7 +164,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/lt_31px.png</normaloff>:/lt_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -184,7 +184,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/rt_31px.png</normaloff>:/rt_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/lc_31px.png</normaloff>:/lc_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -224,7 +224,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/cc_31px.png</normaloff>:/cc_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -244,7 +244,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/rc_31px.png</normaloff>:/rc_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -264,7 +264,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/lb_31px.png</normaloff>:/lb_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -284,7 +284,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/cb_31px.png</normaloff>:/cb_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -304,7 +304,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../icons/icons.qrc">
|
||||
<normaloff>:/rb_31px.png</normaloff>:/rb_31px.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
|
|
@ -366,7 +366,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ DEFINES += MAKE_EDT_LIBRARY
|
|||
RoundCornerOptionsDialog.ui \
|
||||
TextPropertiesPage.ui \
|
||||
DistributeOptionsDialog.ui \
|
||||
EditorOptionsInstPCellParam.ui
|
||||
EditorOptionsInstPCellParam.ui \
|
||||
AreaAndPerimeterDialog.ui
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -683,6 +683,29 @@ BEGIN_PROTECTED;
|
|||
END_PROTECTED;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// AreaAndPerimeterDialog implementation
|
||||
|
||||
AreaAndPerimeterDialog::AreaAndPerimeterDialog (QWidget *parent)
|
||||
: QDialog (parent)
|
||||
{
|
||||
setupUi (this);
|
||||
}
|
||||
|
||||
AreaAndPerimeterDialog::~AreaAndPerimeterDialog ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool
|
||||
AreaAndPerimeterDialog::exec_dialog (double area, double perimeter)
|
||||
{
|
||||
area_le->setText (tl::to_qstring (tl::sprintf ("%.12g", area)));
|
||||
perimeter_le->setText (tl::to_qstring (tl::sprintf ("%.12g", perimeter)));
|
||||
|
||||
return exec () != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "ui_MakeCellOptionsDialog.h"
|
||||
#include "ui_MakeArrayOptionsDialog.h"
|
||||
#include "ui_RoundCornerOptionsDialog.h"
|
||||
#include "ui_AreaAndPerimeterDialog.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -205,6 +206,22 @@ private:
|
|||
bool m_has_extracted;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Result dialog for "area and perimeter"
|
||||
*/
|
||||
class AreaAndPerimeterDialog
|
||||
: public QDialog,
|
||||
private Ui::AreaAndPerimeterDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AreaAndPerimeterDialog (QWidget *parent);
|
||||
~AreaAndPerimeterDialog ();
|
||||
|
||||
bool exec_dialog (double area, double perimeter);
|
||||
};
|
||||
|
||||
} // namespace edt
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ InstPropertiesPage::create_applicator (db::Cell & /*cell*/, const db::Instance &
|
|||
tl_assert (mp_pcell_parameters);
|
||||
|
||||
std::vector<tl::Variant> param = mp_pcell_parameters->get_parameters (0);
|
||||
const std::vector<tl::Variant> &initial_param = mp_pcell_parameters->initial_parameters ();
|
||||
std::vector<tl::Variant> initial_param = mp_pcell_parameters->initial_parameters ();
|
||||
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_parameters->pcell_decl ()->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "dbPolygonTools.h"
|
||||
#include "dbLibrary.h"
|
||||
#include "dbLibraryManager.h"
|
||||
#include "dbRegion.h"
|
||||
#include "tlExceptions.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "laySelector.h"
|
||||
|
|
@ -82,6 +83,7 @@ MainService::MainService (db::Manager *manager, lay::LayoutViewBase *view, lay::
|
|||
{
|
||||
#if defined(HAVE_QT)
|
||||
mp_round_corners_dialog = 0;
|
||||
mp_area_and_perimeter_dialog = 0;
|
||||
mp_align_options_dialog = 0;
|
||||
mp_distribute_options_dialog = 0;
|
||||
mp_flatten_inst_options_dialog = 0;
|
||||
|
|
@ -106,6 +108,15 @@ MainService::round_corners_dialog ()
|
|||
return mp_round_corners_dialog;
|
||||
}
|
||||
|
||||
edt::AreaAndPerimeterDialog *
|
||||
MainService::area_and_perimeter_dialog ()
|
||||
{
|
||||
if (! mp_area_and_perimeter_dialog) {
|
||||
mp_area_and_perimeter_dialog = new edt::AreaAndPerimeterDialog (lay::widget_from_view (view ()));
|
||||
}
|
||||
return mp_area_and_perimeter_dialog;
|
||||
}
|
||||
|
||||
edt::AlignOptionsDialog *
|
||||
MainService::align_options_dialog ()
|
||||
{
|
||||
|
|
@ -168,6 +179,8 @@ MainService::menu_activated (const std::string &symbol)
|
|||
cm_tap ();
|
||||
} else if (symbol == "edt::sel_round_corners") {
|
||||
cm_round_corners ();
|
||||
} else if (symbol == "edt::sel_area_perimeter") {
|
||||
cm_area_perimeter ();
|
||||
} else if (symbol == "edt::sel_convert_to_pcell") {
|
||||
cm_convert_to_pcell ();
|
||||
} else if (symbol == "edt::sel_convert_to_cell") {
|
||||
|
|
@ -1346,6 +1359,67 @@ MainService::cm_convert_to_pcell ()
|
|||
}
|
||||
}
|
||||
|
||||
void MainService::cm_area_perimeter ()
|
||||
{
|
||||
#if ! defined(HAVE_QT)
|
||||
tl_assert (false); // see TODO
|
||||
#endif
|
||||
|
||||
double dbu = 0.0;
|
||||
|
||||
std::vector<edt::Service *> edt_services = view ()->get_plugins <edt::Service> ();
|
||||
|
||||
db::Region region;
|
||||
|
||||
// get (common) cellview index of the primary selection
|
||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); es != edt_services.end (); ++es) {
|
||||
|
||||
for (edt::Service::obj_iterator s = (*es)->selection ().begin (); s != (*es)->selection ().end (); ++s) {
|
||||
|
||||
if (s->is_cell_inst ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
db::Polygon poly;
|
||||
if (!s->shape ().polygon (poly)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
double shape_dbu = view ()->cellview (s->cv_index ())->layout ().dbu ();
|
||||
|
||||
if (dbu == 0.0) {
|
||||
// first CV is used for reference DBU
|
||||
dbu = shape_dbu;
|
||||
}
|
||||
|
||||
if (fabs (shape_dbu - dbu) < db::epsilon) {
|
||||
region.insert (s->trans () * poly);
|
||||
} else {
|
||||
region.insert ((db::ICplxTrans (shape_dbu / dbu) * s->trans ()) * poly);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (region.count () > 100000) {
|
||||
if (QMessageBox::warning (lay::widget_from_view (view ()), tr ("Warning: Big Selection"),
|
||||
tr ("The selection contains many shapes. Area and perimeter computation may take a long time.\nContinue anyway?"),
|
||||
QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
double area = region.area () * dbu * dbu;
|
||||
double perimeter = region.perimeter () * dbu;
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
area_and_perimeter_dialog ()->exec_dialog (area, perimeter);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool extract_rad (std::vector <db::Polygon> &poly, double &rinner, double &router, unsigned int &n)
|
||||
{
|
||||
std::vector <db::Point> new_pts;
|
||||
|
|
@ -1356,7 +1430,7 @@ static bool extract_rad (std::vector <db::Polygon> &poly, double &rinner, double
|
|||
db::Polygon new_poly;
|
||||
|
||||
new_pts.clear ();
|
||||
if (! extract_rad_from_contour (p->begin_hull (), p->end_hull (), rinner, router, n, &new_pts) &&
|
||||
if (! extract_rad_from_contour (p->begin_hull (), p->end_hull (), rinner, router, n, &new_pts) &&
|
||||
! extract_rad_from_contour (p->begin_hull (), p->end_hull (), rinner, router, n, &new_pts, true)) {
|
||||
// ultimate fallback: assign original contour
|
||||
new_poly.assign_hull (p->begin_hull (), p->end_hull (), false /*don't compress*/);
|
||||
|
|
@ -1368,7 +1442,7 @@ static bool extract_rad (std::vector <db::Polygon> &poly, double &rinner, double
|
|||
for (unsigned int h = 0; h < p->holes (); ++h) {
|
||||
|
||||
new_pts.clear ();
|
||||
if (! extract_rad_from_contour (p->begin_hole (h), p->end_hole (h), rinner, router, n, &new_pts) &&
|
||||
if (! extract_rad_from_contour (p->begin_hole (h), p->end_hole (h), rinner, router, n, &new_pts) &&
|
||||
! extract_rad_from_contour (p->begin_hole (h), p->end_hole (h), rinner, router, n, &new_pts, true)) {
|
||||
// ultimate fallback: assign original contour
|
||||
new_poly.insert_hole (p->begin_hole (h), p->end_hole (h), false /*don't compress*/);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class Service;
|
|||
class EditorOptionsPages;
|
||||
class EditorOptionsPage;
|
||||
class RoundCornerOptionsDialog;
|
||||
class AreaAndPerimeterDialog;
|
||||
class MakeCellOptionsDialog;
|
||||
class MakeArrayOptionsDialog;
|
||||
class AlignOptionsDialog;
|
||||
|
|
@ -104,6 +105,11 @@ public:
|
|||
*/
|
||||
void cm_round_corners ();
|
||||
|
||||
/**
|
||||
* @brief Show area and perimeter of selection
|
||||
*/
|
||||
void cm_area_perimeter ();
|
||||
|
||||
/**
|
||||
* @brief Convert selection to PCell
|
||||
*/
|
||||
|
|
@ -223,6 +229,7 @@ private:
|
|||
bool m_undo_before_apply;
|
||||
#if defined(HAVE_QT)
|
||||
edt::RoundCornerOptionsDialog *mp_round_corners_dialog;
|
||||
edt::AreaAndPerimeterDialog *mp_area_and_perimeter_dialog;
|
||||
edt::AlignOptionsDialog *mp_align_options_dialog;
|
||||
edt::DistributeOptionsDialog *mp_distribute_options_dialog;
|
||||
lay::FlattenInstOptionsDialog *mp_flatten_inst_options_dialog;
|
||||
|
|
@ -234,6 +241,7 @@ private:
|
|||
void check_no_guiding_shapes ();
|
||||
#if defined(HAVE_QT)
|
||||
edt::RoundCornerOptionsDialog *round_corners_dialog ();
|
||||
edt::AreaAndPerimeterDialog *area_and_perimeter_dialog ();
|
||||
edt::AlignOptionsDialog *align_options_dialog ();
|
||||
edt::DistributeOptionsDialog *distribute_options_dialog ();
|
||||
lay::FlattenInstOptionsDialog *flatten_inst_options_dialog ();
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ static void set_value (const db::PCellParameterDeclaration &p, QWidget *widget,
|
|||
}
|
||||
|
||||
PCellParametersPage::PCellParametersPage (QWidget *parent, bool dense)
|
||||
: QFrame (parent), m_dense (dense), dm_parameter_changed (this, &PCellParametersPage::do_parameter_changed)
|
||||
: QFrame (parent), m_dense (dense), m_show_parameter_names (false), dm_parameter_changed (this, &PCellParametersPage::do_parameter_changed)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ PCellParametersPage::init ()
|
|||
frame_layout->setContentsMargins (0, 0, 0, 0);
|
||||
setLayout (frame_layout);
|
||||
|
||||
mp_update_frame = new QFrame ();
|
||||
mp_update_frame = new QFrame (this);
|
||||
mp_update_frame->setFrameShape (QFrame::NoFrame);
|
||||
frame_layout->addWidget (mp_update_frame, 0, 0, 1, 1);
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ PCellParametersPage::init ()
|
|||
|
||||
update_frame_layout->setColumnStretch (2, 1);
|
||||
|
||||
mp_error_frame = new QFrame ();
|
||||
mp_error_frame = new QFrame (this);
|
||||
mp_error_frame->setFrameShape (QFrame::NoFrame);
|
||||
frame_layout->addWidget (mp_error_frame, 1, 0, 1, 1);
|
||||
|
||||
|
|
@ -224,6 +224,13 @@ PCellParametersPage::init ()
|
|||
error_frame_layout->addWidget (mp_error_label, 1, 1, 1, 2);
|
||||
|
||||
error_frame_layout->setColumnStretch (2, 1);
|
||||
|
||||
mp_show_parameter_names_cb = new QCheckBox (this);
|
||||
mp_show_parameter_names_cb->setText (tr ("Show parameter names"));
|
||||
mp_show_parameter_names_cb->setChecked (m_show_parameter_names);
|
||||
frame_layout->addWidget (mp_show_parameter_names_cb, 3, 0, 1, 1);
|
||||
|
||||
connect (mp_show_parameter_names_cb, SIGNAL (clicked (bool)), this, SLOT (show_parameter_names (bool)));
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -232,19 +239,34 @@ PCellParametersPage::lazy_evaluation ()
|
|||
return mp_pcell_decl.get () && mp_pcell_decl->wants_lazy_evaluation ();
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::show_parameter_names (bool f)
|
||||
{
|
||||
if (m_show_parameter_names == f) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_show_parameter_names = f;
|
||||
mp_show_parameter_names_cb->setChecked (f);
|
||||
setup (mp_view, m_cv_index, mp_pcell_decl.get (), get_parameters ());
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::PCellDeclaration *pcell_decl, const db::pcell_parameters_type ¶meters)
|
||||
{
|
||||
mp_pcell_decl.reset (const_cast<db::PCellDeclaration *> (pcell_decl)); // no const weak_ptr ...
|
||||
mp_view = view;
|
||||
m_cv_index = cv_index;
|
||||
m_parameters = parameters;
|
||||
m_states = db::ParameterStates ();
|
||||
m_initial_states = db::ParameterStates ();
|
||||
|
||||
if (mp_parameters_area) {
|
||||
delete mp_parameters_area;
|
||||
}
|
||||
|
||||
m_widgets.clear ();
|
||||
m_icon_widgets.clear ();
|
||||
m_all_widgets.clear ();
|
||||
|
||||
mp_parameters_area = new QScrollArea (this);
|
||||
mp_parameters_area->setFrameShape (QFrame::NoFrame);
|
||||
|
|
@ -268,6 +290,12 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
QWidget *main_frame = inner_frame;
|
||||
QGridLayout *main_grid = inner_grid;
|
||||
|
||||
if (! mp_pcell_decl) {
|
||||
mp_parameters_area->setWidget (main_frame);
|
||||
update_current_parameters ();
|
||||
return;
|
||||
}
|
||||
|
||||
int main_row = 0;
|
||||
int row = 0;
|
||||
std::string group_title;
|
||||
|
|
@ -276,8 +304,23 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
|
||||
|
||||
if (p->is_hidden () || p->get_type () == db::PCellParameterDeclaration::t_shape) {
|
||||
tl::Variant value;
|
||||
if (r < int (parameters.size ())) {
|
||||
value = parameters [r];
|
||||
} else {
|
||||
value = p->get_default ();
|
||||
}
|
||||
|
||||
db::ParameterState &ps = m_states.parameter (p->get_name ());
|
||||
ps.set_value (value);
|
||||
ps.set_readonly (p->is_readonly ());
|
||||
ps.set_visible (! p->is_hidden ());
|
||||
|
||||
m_all_widgets.push_back (std::vector<QWidget *> ());
|
||||
|
||||
if (p->get_type () == db::PCellParameterDeclaration::t_shape) {
|
||||
m_widgets.push_back (0);
|
||||
m_icon_widgets.push_back (0);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +340,7 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
// create a new group
|
||||
QGroupBox *gb = new QGroupBox (main_frame);
|
||||
gb->setTitle (tl::to_qstring (gt));
|
||||
main_grid->addWidget (gb, main_row, 0, 1, 2);
|
||||
main_grid->addWidget (gb, main_row, 0, 1, 3);
|
||||
|
||||
inner_grid = new QGridLayout (gb);
|
||||
if (m_dense) {
|
||||
|
|
@ -324,13 +367,28 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
|
||||
}
|
||||
|
||||
inner_grid->addWidget (new QLabel (tl::to_qstring (description), inner_frame), row, 0);
|
||||
QLabel *icon_label = new QLabel (QString (), inner_frame);
|
||||
inner_grid->addWidget (icon_label, row, 0);
|
||||
m_icon_widgets.push_back (icon_label);
|
||||
m_all_widgets.back ().push_back (icon_label);
|
||||
|
||||
if (p->get_type () != db::PCellParameterDeclaration::t_callback) {
|
||||
|
||||
std::string leader;
|
||||
if (m_show_parameter_names) {
|
||||
leader = tl::sprintf ("[%s] ", p->get_name ());
|
||||
}
|
||||
|
||||
QLabel *l = new QLabel (tl::to_qstring (leader + description), inner_frame);
|
||||
inner_grid->addWidget (l, row, 1);
|
||||
m_all_widgets.back ().push_back (l);
|
||||
|
||||
} else if (m_show_parameter_names) {
|
||||
|
||||
QLabel *l = new QLabel (tl::to_qstring (tl::sprintf ("[%s]", p->get_name ())), inner_frame);
|
||||
inner_grid->addWidget (l, row, 1);
|
||||
m_all_widgets.back ().push_back (l);
|
||||
|
||||
tl::Variant value;
|
||||
if (r < int (parameters.size ())) {
|
||||
value = parameters [r];
|
||||
} else {
|
||||
value = p->get_default ();
|
||||
}
|
||||
|
||||
if (p->get_choices ().empty ()) {
|
||||
|
|
@ -347,7 +405,6 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
f->setFrameShape (QFrame::NoFrame);
|
||||
|
||||
QLineEdit *le = new QLineEdit (f);
|
||||
le->setEnabled (! p->is_readonly ());
|
||||
hb->addWidget (le);
|
||||
le->setMaximumWidth (150);
|
||||
le->setObjectName (tl::to_qstring (p->get_name ()));
|
||||
|
|
@ -357,21 +414,37 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
hb->addWidget (ul, 1);
|
||||
ul->setText (tl::to_qstring (p->get_unit ()));
|
||||
|
||||
inner_grid->addWidget (f, row, 1);
|
||||
inner_grid->addWidget (f, row, 2);
|
||||
m_all_widgets.back ().push_back (f);
|
||||
|
||||
connect (le, SIGNAL (editingFinished ()), this, SLOT (parameter_changed ()));
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_callback:
|
||||
{
|
||||
QPushButton *pb = new QPushButton (inner_frame);
|
||||
pb->setObjectName (tl::to_qstring (p->get_name ()));
|
||||
pb->setText (tl::to_qstring (description));
|
||||
pb->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred);
|
||||
m_widgets.push_back (pb);
|
||||
|
||||
inner_grid->addWidget (pb, row, 2);
|
||||
m_all_widgets.back ().push_back (pb);
|
||||
|
||||
connect (pb, SIGNAL (clicked ()), this, SLOT (parameter_changed ()));
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_string:
|
||||
case db::PCellParameterDeclaration::t_shape:
|
||||
case db::PCellParameterDeclaration::t_list:
|
||||
{
|
||||
QLineEdit *le = new QLineEdit (inner_frame);
|
||||
le->setEnabled (! p->is_readonly ());
|
||||
le->setObjectName (tl::to_qstring (p->get_name ()));
|
||||
m_widgets.push_back (le);
|
||||
inner_grid->addWidget (le, row, 1);
|
||||
inner_grid->addWidget (le, row, 2);
|
||||
m_all_widgets.back ().push_back (le);
|
||||
|
||||
connect (le, SIGNAL (editingFinished ()), this, SLOT (parameter_changed ()));
|
||||
}
|
||||
|
|
@ -380,12 +453,12 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
case db::PCellParameterDeclaration::t_layer:
|
||||
{
|
||||
lay::LayerSelectionComboBox *ly = new lay::LayerSelectionComboBox (inner_frame);
|
||||
ly->setEnabled (! p->is_readonly ());
|
||||
ly->set_no_layer_available (true);
|
||||
ly->set_view (mp_view, m_cv_index, true /*all layers*/);
|
||||
ly->setObjectName (tl::to_qstring (p->get_name ()));
|
||||
m_widgets.push_back (ly);
|
||||
inner_grid->addWidget (ly, row, 1);
|
||||
inner_grid->addWidget (ly, row, 2);
|
||||
m_all_widgets.back ().push_back (ly);
|
||||
|
||||
connect (ly, SIGNAL (activated (int)), this, SLOT (parameter_changed ()));
|
||||
}
|
||||
|
|
@ -396,10 +469,10 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
QCheckBox *cbx = new QCheckBox (inner_frame);
|
||||
// this makes the checkbox not stretch over the full width - better when navigating with tab
|
||||
cbx->setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Preferred));
|
||||
cbx->setEnabled (! p->is_readonly ());
|
||||
cbx->setObjectName (tl::to_qstring (p->get_name ()));
|
||||
m_widgets.push_back (cbx);
|
||||
inner_grid->addWidget (cbx, row, 1);
|
||||
inner_grid->addWidget (cbx, row, 2);
|
||||
m_all_widgets.back ().push_back (cbx);
|
||||
|
||||
connect (cbx, SIGNAL (stateChanged (int)), this, SLOT (parameter_changed ()));
|
||||
}
|
||||
|
|
@ -426,16 +499,14 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
|
||||
connect (cb, SIGNAL (activated (int)), this, SLOT (parameter_changed ()));
|
||||
|
||||
cb->setEnabled (! p->is_readonly ());
|
||||
cb->setMinimumContentsLength (30);
|
||||
cb->setSizeAdjustPolicy (QComboBox::AdjustToMinimumContentsLengthWithIcon);
|
||||
m_widgets.push_back (cb);
|
||||
inner_grid->addWidget (cb, row, 1);
|
||||
inner_grid->addWidget (cb, row, 2);
|
||||
m_all_widgets.back ().push_back (cb);
|
||||
|
||||
}
|
||||
|
||||
set_value (*p, m_widgets.back (), value);
|
||||
|
||||
++row;
|
||||
if (inner_frame == main_frame) {
|
||||
++main_row;
|
||||
|
|
@ -443,6 +514,22 @@ PCellParametersPage::setup (lay::LayoutViewBase *view, int cv_index, const db::P
|
|||
|
||||
}
|
||||
|
||||
// initial callback
|
||||
|
||||
try {
|
||||
mp_pcell_decl->callback (mp_view->cellview (m_cv_index)->layout (), std::string (), m_states);
|
||||
} catch (tl::Exception &ex) {
|
||||
// potentially caused by script errors in callback implementation
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::runtime_error &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
// ignore other errors
|
||||
}
|
||||
|
||||
m_initial_states = m_states;
|
||||
update_widgets_from_states (m_states);
|
||||
|
||||
mp_parameters_area->setWidget (main_frame);
|
||||
main_frame->show ();
|
||||
|
||||
|
|
@ -458,6 +545,8 @@ PCellParametersPage::get_state ()
|
|||
s.vScrollPosition = mp_parameters_area->verticalScrollBar ()->value ();
|
||||
s.hScrollPosition = mp_parameters_area->horizontalScrollBar ()->value ();
|
||||
|
||||
s.show_parameter_names = m_show_parameter_names;
|
||||
|
||||
if (focusWidget ()) {
|
||||
s.focusWidget = focusWidget ()->objectName ();
|
||||
}
|
||||
|
|
@ -473,6 +562,10 @@ PCellParametersPage::set_state (const State &s)
|
|||
mp_parameters_area->verticalScrollBar ()->setValue (s.vScrollPosition);
|
||||
mp_parameters_area->horizontalScrollBar ()->setValue (s.hScrollPosition);
|
||||
|
||||
if (s.show_parameter_names != m_show_parameter_names) {
|
||||
show_parameter_names (s.show_parameter_names);
|
||||
}
|
||||
|
||||
if (! s.focusWidget.isEmpty ()) {
|
||||
QWidget *c = findChild<QWidget *> (s.focusWidget);
|
||||
if (c) {
|
||||
|
|
@ -483,18 +576,58 @@ PCellParametersPage::set_state (const State &s)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
void
|
||||
PCellParametersPage::parameter_changed ()
|
||||
{
|
||||
if (! mp_pcell_decl) {
|
||||
return;
|
||||
}
|
||||
if (! mp_view->cellview (m_cv_index).is_valid ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
const db::PCellParameterDeclaration *pd = 0;
|
||||
for (auto w = m_widgets.begin (); w != m_widgets.end (); ++w) {
|
||||
if (*w == sender ()) {
|
||||
pd = &pcp [w - m_widgets.begin ()];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
db::ParameterStates states = m_states;
|
||||
|
||||
bool edit_error = false;
|
||||
// Silent and without coerce - this will be done later in do_parameter_changed().
|
||||
// This is just about providing the inputs for the callback.
|
||||
get_parameters_internal (states, edit_error);
|
||||
|
||||
if (! edit_error) {
|
||||
mp_pcell_decl->callback (mp_view->cellview (m_cv_index)->layout (), pd ? pd->get_name () : std::string (), states);
|
||||
m_states = states;
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
// potentially caused by script errors in callback implementation
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::runtime_error &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
// ignore other errors
|
||||
}
|
||||
|
||||
dm_parameter_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::do_parameter_changed ()
|
||||
{
|
||||
// does a coerce and update
|
||||
bool ok = false;
|
||||
std::vector<tl::Variant> parameters = get_parameters (&ok);
|
||||
bool ok = true;
|
||||
db::ParameterStates states = m_states;
|
||||
get_parameters (states, &ok); // includes coerce
|
||||
update_widgets_from_states (states);
|
||||
if (ok && ! lazy_evaluation ()) {
|
||||
emit edited ();
|
||||
}
|
||||
|
|
@ -511,159 +644,166 @@ PCellParametersPage::update_button_pressed ()
|
|||
bool
|
||||
PCellParametersPage::update_current_parameters ()
|
||||
{
|
||||
bool ok = false;
|
||||
std::vector<tl::Variant> parameters = get_parameters (&ok);
|
||||
bool ok = true;
|
||||
db::ParameterStates states = m_states;
|
||||
get_parameters (states, &ok); // includes coerce
|
||||
if (ok) {
|
||||
m_current_parameters = parameters;
|
||||
m_current_states = states;
|
||||
mp_update_frame->hide ();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
std::vector<tl::Variant>
|
||||
PCellParametersPage::get_parameters (bool *ok)
|
||||
void
|
||||
PCellParametersPage::get_parameters_internal (db::ParameterStates &states, bool &edit_error)
|
||||
{
|
||||
std::vector<tl::Variant> parameters;
|
||||
edit_error = false;
|
||||
|
||||
int r = 0;
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
|
||||
|
||||
db::ParameterState &ps = states.parameter (p->get_name ());
|
||||
|
||||
if (! ps.is_visible () || ! ps.is_enabled () || ps.is_readonly () || p->get_type () == db::PCellParameterDeclaration::t_shape) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p->get_choices ().empty ()) {
|
||||
|
||||
switch (p->get_type ()) {
|
||||
|
||||
case db::PCellParameterDeclaration::t_int:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
|
||||
try {
|
||||
|
||||
int v = 0;
|
||||
tl::from_string_ext (tl::to_string (le->text ()), v);
|
||||
|
||||
ps.set_value (tl::Variant (v));
|
||||
lay::indicate_error (le, (tl::Exception *) 0);
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
|
||||
lay::indicate_error (le, &ex);
|
||||
edit_error = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_double:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
|
||||
try {
|
||||
|
||||
double v = 0;
|
||||
tl::from_string_ext (tl::to_string (le->text ()), v);
|
||||
|
||||
ps.set_value (tl::Variant (v));
|
||||
lay::indicate_error (le, (tl::Exception *) 0);
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
|
||||
lay::indicate_error (le, &ex);
|
||||
edit_error = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_string:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
ps.set_value (tl::Variant (tl::to_string (le->text ())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_list:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
std::vector<std::string> values = tl::split (tl::to_string (le->text ()), ",");
|
||||
ps.set_value (tl::Variant (values.begin (), values.end ()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_layer:
|
||||
{
|
||||
lay::LayerSelectionComboBox *ly = dynamic_cast<lay::LayerSelectionComboBox *> (m_widgets [r]);
|
||||
if (ly) {
|
||||
ps.set_value (tl::Variant (ly->current_layer_props ()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case db::PCellParameterDeclaration::t_boolean:
|
||||
{
|
||||
QCheckBox *cbx = dynamic_cast<QCheckBox *> (m_widgets [r]);
|
||||
if (cbx) {
|
||||
ps.set_value (tl::Variant (cbx->isChecked ()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
QComboBox *cb = dynamic_cast<QComboBox*> (m_widgets [r]);
|
||||
if (cb && cb->currentIndex () >= 0 && cb->currentIndex () < int (p->get_choices ().size ())) {
|
||||
ps.set_value (p->get_choices () [cb->currentIndex ()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::get_parameters (db::ParameterStates &states, bool *ok)
|
||||
{
|
||||
try {
|
||||
|
||||
if (! mp_pcell_decl) {
|
||||
throw tl::Exception (tl::to_string (tr ("PCell no longer valid.")));
|
||||
}
|
||||
|
||||
bool edit_error = true;
|
||||
bool edit_error = false;
|
||||
|
||||
int r = 0;
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
|
||||
get_parameters_internal (states, edit_error);
|
||||
|
||||
if (p->is_hidden () || p->get_type () == db::PCellParameterDeclaration::t_shape) {
|
||||
|
||||
if (r < (int) m_parameters.size ()) {
|
||||
parameters.push_back (m_parameters [r]);
|
||||
} else {
|
||||
parameters.push_back (p->get_default ());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
parameters.push_back (tl::Variant ());
|
||||
|
||||
if (p->get_choices ().empty ()) {
|
||||
|
||||
switch (p->get_type ()) {
|
||||
|
||||
case db::PCellParameterDeclaration::t_int:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
|
||||
try {
|
||||
|
||||
int v = 0;
|
||||
tl::from_string_ext (tl::to_string (le->text ()), v);
|
||||
|
||||
parameters.back () = tl::Variant (v);
|
||||
lay::indicate_error (le, (tl::Exception *) 0);
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
|
||||
lay::indicate_error (le, &ex);
|
||||
edit_error = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_double:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
|
||||
try {
|
||||
|
||||
double v = 0;
|
||||
tl::from_string_ext (tl::to_string (le->text ()), v);
|
||||
|
||||
parameters.back () = tl::Variant (v);
|
||||
lay::indicate_error (le, (tl::Exception *) 0);
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
|
||||
lay::indicate_error (le, &ex);
|
||||
edit_error = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_string:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
parameters.back () = tl::Variant (tl::to_string (le->text ()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_list:
|
||||
{
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [r]);
|
||||
if (le) {
|
||||
std::vector<std::string> values = tl::split (tl::to_string (le->text ()), ",");
|
||||
parameters.back () = tl::Variant (values.begin (), values.end ());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case db::PCellParameterDeclaration::t_layer:
|
||||
{
|
||||
lay::LayerSelectionComboBox *ly = dynamic_cast<lay::LayerSelectionComboBox *> (m_widgets [r]);
|
||||
if (ly) {
|
||||
parameters.back () = tl::Variant (ly->current_layer_props ());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case db::PCellParameterDeclaration::t_boolean:
|
||||
{
|
||||
QCheckBox *cbx = dynamic_cast<QCheckBox *> (m_widgets [r]);
|
||||
if (cbx) {
|
||||
parameters.back () = tl::Variant (cbx->isChecked ());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
QComboBox *cb = dynamic_cast<QComboBox*> (m_widgets [r]);
|
||||
if (cb && cb->currentIndex () >= 0 && cb->currentIndex () < int (p->get_choices ().size ())) {
|
||||
parameters.back () = p->get_choices () [cb->currentIndex ()];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! edit_error) {
|
||||
if (edit_error) {
|
||||
throw tl::Exception (tl::to_string (tr ("There are errors. See the highlighted edit fields for details.")));
|
||||
}
|
||||
|
||||
// coerce the parameters
|
||||
// coerces the parameters and writes the changed values back
|
||||
if (mp_view->cellview (m_cv_index).is_valid ()) {
|
||||
|
||||
auto parameters = parameter_from_states (states);
|
||||
auto before_coerce = parameters;
|
||||
mp_pcell_decl->coerce_parameters (mp_view->cellview (m_cv_index)->layout (), parameters);
|
||||
|
||||
if (parameters != before_coerce) {
|
||||
states_from_parameters (states, parameters);
|
||||
set_parameters_internal (states, lazy_evaluation ());
|
||||
}
|
||||
|
||||
}
|
||||
set_parameters_internal (parameters, lazy_evaluation ());
|
||||
|
||||
if (ok) {
|
||||
*ok = true;
|
||||
|
|
@ -691,19 +831,112 @@ PCellParametersPage::get_parameters (bool *ok)
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return parameters;
|
||||
std::vector<tl::Variant>
|
||||
PCellParametersPage::get_parameters (bool *ok)
|
||||
{
|
||||
db::ParameterStates states = m_states;
|
||||
get_parameters (states, ok);
|
||||
|
||||
return parameter_from_states (states);
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::set_parameters (const std::vector<tl::Variant> ¶meters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
set_parameters_internal (parameters, false);
|
||||
if (! mp_pcell_decl) {
|
||||
return;
|
||||
}
|
||||
|
||||
states_from_parameters (m_states, parameters);
|
||||
|
||||
try {
|
||||
if (mp_view->cellview (m_cv_index).is_valid ()) {
|
||||
mp_pcell_decl->callback (mp_view->cellview (m_cv_index)->layout (), std::string (), m_states);
|
||||
}
|
||||
} catch (tl::Exception &ex) {
|
||||
// potentially caused by script errors in callback implementation
|
||||
tl::error << ex.msg ();
|
||||
} catch (std::runtime_error &ex) {
|
||||
tl::error << ex.what ();
|
||||
} catch (...) {
|
||||
// ignore other errors
|
||||
}
|
||||
|
||||
m_initial_states = m_states;
|
||||
set_parameters_internal (m_states, false);
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::set_parameters_internal (const std::vector<tl::Variant> ¶meters, bool tentatively)
|
||||
PCellParametersPage::update_widgets_from_states (const db::ParameterStates &states)
|
||||
{
|
||||
if (! mp_pcell_decl) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end () && i < m_widgets.size (); ++p, ++i) {
|
||||
|
||||
const std::string &name = p->get_name ();
|
||||
const db::ParameterState &ps = states.parameter (name);
|
||||
|
||||
if (m_widgets [i]) {
|
||||
QLineEdit *le = dynamic_cast<QLineEdit *> (m_widgets [i]);
|
||||
if (le) {
|
||||
le->setEnabled (ps.is_enabled ());
|
||||
le->setReadOnly (ps.is_readonly ());
|
||||
} else {
|
||||
m_widgets [i]->setEnabled (ps.is_enabled () && ! ps.is_readonly ());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto w = m_all_widgets [i].begin (); w != m_all_widgets [i].end (); ++w) {
|
||||
if (*w != m_widgets [i]) {
|
||||
(*w)->setEnabled (ps.is_enabled ());
|
||||
}
|
||||
if (*w != m_icon_widgets [i]) {
|
||||
(*w)->setVisible (ps.is_visible ());
|
||||
}
|
||||
(*w)->setToolTip (tl::to_qstring (ps.tooltip ()));
|
||||
}
|
||||
|
||||
if (m_icon_widgets [i]) {
|
||||
|
||||
static QPixmap error (":/error_16px@2x.png");
|
||||
static QPixmap info (":/info_16px@2x.png");
|
||||
static QPixmap warning (":/warn_16px@2x.png");
|
||||
|
||||
switch (ps.icon ()) {
|
||||
case db::ParameterState::NoIcon:
|
||||
default:
|
||||
m_icon_widgets [i]->setPixmap (QPixmap ());
|
||||
m_icon_widgets [i]->hide ();
|
||||
break;
|
||||
case db::ParameterState::InfoIcon:
|
||||
m_icon_widgets [i]->setPixmap (info);
|
||||
m_icon_widgets [i]->show ();
|
||||
break;
|
||||
case db::ParameterState::WarningIcon:
|
||||
m_icon_widgets [i]->setPixmap (warning);
|
||||
m_icon_widgets [i]->show ();
|
||||
break;
|
||||
case db::ParameterState::ErrorIcon:
|
||||
m_icon_widgets [i]->setPixmap (error);
|
||||
m_icon_widgets [i]->show ();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set_parameters_internal (states, lazy_evaluation ());
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::set_parameters_internal (const db::ParameterStates &states, bool tentatively)
|
||||
{
|
||||
if (! mp_pcell_decl) {
|
||||
return;
|
||||
|
|
@ -713,8 +946,8 @@ PCellParametersPage::set_parameters_internal (const std::vector<tl::Variant> &pa
|
|||
size_t r = 0;
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
|
||||
if (r < parameters.size () && m_widgets [r]) {
|
||||
set_value (*p, m_widgets [r], parameters [r]);
|
||||
if (m_widgets [r]) {
|
||||
set_value (*p, m_widgets [r], states.parameter (p->get_name ()).value ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -723,14 +956,53 @@ PCellParametersPage::set_parameters_internal (const std::vector<tl::Variant> &pa
|
|||
bool update_needed = false;
|
||||
|
||||
if (! tentatively) {
|
||||
m_current_parameters = parameters;
|
||||
m_current_states = states;
|
||||
} else {
|
||||
update_needed = (m_current_parameters != parameters);
|
||||
update_needed = ! m_current_states.values_are_equal (states);
|
||||
}
|
||||
|
||||
mp_update_frame->setVisible (update_needed);
|
||||
}
|
||||
|
||||
std::vector<tl::Variant>
|
||||
PCellParametersPage::parameter_from_states (const db::ParameterStates &states) const
|
||||
{
|
||||
std::vector<tl::Variant> parameters;
|
||||
if (mp_pcell_decl) {
|
||||
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (auto p = pcp.begin (); p != pcp.end (); ++p) {
|
||||
if (! states.has_parameter (p->get_name ())) {
|
||||
parameters.push_back (p->get_default ());
|
||||
} else {
|
||||
parameters.push_back (states.parameter (p->get_name ()).value ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
void
|
||||
PCellParametersPage::states_from_parameters (db::ParameterStates &states, const std::vector<tl::Variant> ¶meters)
|
||||
{
|
||||
if (! mp_pcell_decl) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t r = 0;
|
||||
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
|
||||
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
|
||||
db::ParameterState &ps = states.parameter (p->get_name ());
|
||||
if (r < parameters.size ()) {
|
||||
ps.set_value (parameters [r]);
|
||||
} else {
|
||||
ps.set_value (p->get_default ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <QScrollArea>
|
||||
#include <QLabel>
|
||||
#include <QToolButton>
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
|
@ -52,9 +53,10 @@ Q_OBJECT
|
|||
public:
|
||||
struct State
|
||||
{
|
||||
State () : valid (false), hScrollPosition (0), vScrollPosition (0) { }
|
||||
State () : valid (false), show_parameter_names (false), hScrollPosition (0), vScrollPosition (0) { }
|
||||
|
||||
bool valid;
|
||||
bool show_parameter_names;
|
||||
int hScrollPosition;
|
||||
int vScrollPosition;
|
||||
QString focusWidget;
|
||||
|
|
@ -93,7 +95,7 @@ public:
|
|||
void set_state (const State &s);
|
||||
|
||||
/**
|
||||
* @brief Get the current parameters
|
||||
* @brief Gets the current parameters
|
||||
*
|
||||
* *ok is set to true, if there is no error. In case of an error it's set to false.
|
||||
* The error is indicated in the error label in the editor page.
|
||||
|
|
@ -102,13 +104,24 @@ public:
|
|||
std::vector<tl::Variant> get_parameters (bool *ok = 0);
|
||||
|
||||
/**
|
||||
* @brief Gets the initial parameters
|
||||
* @brief Gets the current parameters into a ParameterStates object
|
||||
*
|
||||
* The initial parameters are the ones present on "setup".
|
||||
* *ok is set to true, if there is no error. In case of an error it's set to false.
|
||||
* The error is indicated in the error label in the editor page.
|
||||
* If ok is null, an exception is thrown.
|
||||
*
|
||||
* The value fields of the ParameterState members is set to the parameter value.
|
||||
* The other attributes are not changed. Parameters not present inside the
|
||||
* ParameterStates object are created with their corresponding name.
|
||||
*/
|
||||
const std::vector<tl::Variant> &initial_parameters () const
|
||||
void get_parameters (db::ParameterStates &states, bool *ok = 0);
|
||||
|
||||
/**
|
||||
* @brief Gets the initial parameters
|
||||
*/
|
||||
std::vector<tl::Variant> initial_parameters () const
|
||||
{
|
||||
return m_parameters;
|
||||
return parameter_from_states (m_initial_states);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -127,6 +140,9 @@ public:
|
|||
signals:
|
||||
void edited ();
|
||||
|
||||
public slots:
|
||||
void show_parameter_names (bool f);
|
||||
|
||||
private slots:
|
||||
void parameter_changed ();
|
||||
void update_button_pressed ();
|
||||
|
|
@ -139,20 +155,27 @@ private:
|
|||
QLabel *mp_changed_icon;
|
||||
QToolButton *mp_update_button;
|
||||
QFrame *mp_error_frame, *mp_update_frame;
|
||||
QCheckBox *mp_show_parameter_names_cb;
|
||||
tl::weak_ptr<db::PCellDeclaration> mp_pcell_decl;
|
||||
std::vector<QWidget *> m_widgets;
|
||||
std::vector<QLabel *> m_icon_widgets;
|
||||
std::vector<std::vector<QWidget *> > m_all_widgets;
|
||||
lay::LayoutViewBase *mp_view;
|
||||
int m_cv_index;
|
||||
db::pcell_parameters_type m_parameters;
|
||||
bool m_dense;
|
||||
bool m_dense, m_show_parameter_names;
|
||||
tl::DeferredMethod<PCellParametersPage> dm_parameter_changed;
|
||||
std::vector<tl::Variant> m_current_parameters;
|
||||
db::ParameterStates m_current_states, m_initial_states;
|
||||
db::ParameterStates m_states;
|
||||
|
||||
void init ();
|
||||
void do_parameter_changed ();
|
||||
bool lazy_evaluation ();
|
||||
void set_parameters_internal (const std::vector<tl::Variant> &values, bool tentatively);
|
||||
void set_parameters_internal (const db::ParameterStates &states, bool tentatively);
|
||||
bool update_current_parameters ();
|
||||
void update_widgets_from_states (const db::ParameterStates &states);
|
||||
void get_parameters_internal (db::ParameterStates &states, bool &edit_error);
|
||||
std::vector<tl::Variant> parameter_from_states (const db::ParameterStates &states) const;
|
||||
void states_from_parameters (db::ParameterStates &states, const std::vector<tl::Variant> ¶meters);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,6 +342,8 @@ public:
|
|||
menu_entries.push_back (lay::menu_item ("edt::sel_make_cell_variants", "make_cell_variants:edit_mode", "edit_menu.selection_menu.end", tl::to_string (tr ("Make Cell Variants"))));
|
||||
menu_entries.push_back (lay::menu_item ("edt::sel_convert_to_pcell", "convert_to_pcell:edit_mode", "edit_menu.selection_menu.end", tl::to_string (tr ("Convert To PCell"))));
|
||||
menu_entries.push_back (lay::menu_item ("edt::sel_convert_to_cell", "convert_to_cell:edit_mode", "edit_menu.selection_menu.end", tl::to_string (tr ("Convert To Static Cell"))));
|
||||
menu_entries.push_back (lay::separator ("hier_group:edit_info", "edit_menu.selection_menu.end"));
|
||||
menu_entries.push_back (lay::menu_item ("edt::sel_area_perimeter", "area_perimeter", "edit_menu.selection_menu.end", tl::to_string (tr ("Area and Perimeter"))));
|
||||
|
||||
menu_entries.push_back (lay::menu_item ("edt::combine_mode", "combine_mode:edit_mode", "@toolbar.end_modes", tl::to_string (tr ("Combine{Select background combination mode}"))));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,8 +52,9 @@ public:
|
|||
virtual size_t count () const;
|
||||
virtual void select_entries (const std::vector<size_t> &entries);
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual QIcon icon (size_t entry, int w, int h) const;
|
||||
virtual std::string description () const;
|
||||
virtual QIcon icon (size_t entry, int w, int h) const;
|
||||
virtual QIcon icon (int w, int h) const { return lay::PropertiesPage::icon (w, h); }
|
||||
virtual void leave ();
|
||||
|
||||
protected:
|
||||
|
|
@ -105,6 +106,7 @@ public:
|
|||
PolygonPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
|
|
@ -129,6 +131,7 @@ public:
|
|||
BoxPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
|
|
@ -159,6 +162,7 @@ public:
|
|||
TextPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
|
|
@ -177,6 +181,7 @@ public:
|
|||
PathPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
|
|
@ -198,6 +203,7 @@ public:
|
|||
EditablePathPropertiesPage (edt::Service *service, db::Manager *manager, QWidget *parent);
|
||||
|
||||
virtual std::string description (size_t entry) const;
|
||||
virtual std::string description () const { return ShapePropertiesPage::description (); }
|
||||
virtual void do_update (const db::Shape &shape, double dbu, const std::string &lname);
|
||||
virtual ChangeApplicator *create_applicator (db::Shapes &shapes, const db::Shape &shape, double dbu);
|
||||
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ public:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(TRACE_METHOD_CALLS)
|
||||
|
||||
public:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -130,6 +130,11 @@ equals(HAVE_CRONOLOGY, "1") {
|
|||
INCLUDEPATH += $$CRONOLOGY_INCLUDE
|
||||
}
|
||||
|
||||
!lessThan(QT_MAJOR_VERSION, 6) {
|
||||
# internal resource readers to not support zstd so far
|
||||
QMAKE_RESOURCE_FLAGS += --compress-algo zlib
|
||||
}
|
||||
|
||||
msvc {
|
||||
|
||||
QMAKE_CXXFLAGS += \
|
||||
|
|
@ -162,16 +167,25 @@ msvc {
|
|||
QMAKE_CXXFLAGS_WARN_ON += \
|
||||
-pedantic \
|
||||
-Woverloaded-virtual \
|
||||
-Wsign-promo \
|
||||
-Wsynth \
|
||||
-Wno-deprecated \
|
||||
-Wno-long-long \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-deprecated-declarations \
|
||||
-Wno-reserved-user-defined-literal \
|
||||
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
# too noisy on Qt:
|
||||
# QMAKE_CXXFLAGS_WARN_ON += \
|
||||
# -Wsign-promo \
|
||||
# -Wno-reserved-user-defined-literal \
|
||||
#
|
||||
|
||||
lessThan(QT_MAJOR_VERSION, 6) {
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
} else {
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++17
|
||||
}
|
||||
|
||||
win32 {
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="mode_tab">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
|
|
@ -217,6 +217,12 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<bold>true</bold>
|
||||
|
|
@ -227,6 +233,19 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="detailed_view">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>More details</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="enabled">
|
||||
|
|
@ -515,6 +534,12 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<bold>true</bold>
|
||||
|
|
@ -525,6 +550,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="detailed_view2">
|
||||
<property name="text">
|
||||
<string>More details</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton_2">
|
||||
<property name="enabled">
|
||||
|
|
@ -935,8 +967,21 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="lay::SaltGrainDetailsTextWidget" name="details_text">
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<bold>true</bold>
|
||||
|
|
@ -947,7 +992,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="edit_button">
|
||||
<property name="toolTip">
|
||||
<string>Edit Package Details</string>
|
||||
|
|
@ -964,10 +1009,10 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="lay::SaltGrainDetailsTextWidget" name="details_text">
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="detailed_view3">
|
||||
<property name="text">
|
||||
<string>More details</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -1157,20 +1202,33 @@
|
|||
<class>lay::SaltGrainDetailsTextWidget</class>
|
||||
<extends>QTextBrowser</extends>
|
||||
<header>laySaltGrainDetailsTextWidget.h</header>
|
||||
<slots>
|
||||
<slot>show_detailed_view(bool)</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mode_tab</tabstop>
|
||||
<tabstop>mark_new_button</tabstop>
|
||||
<tabstop>search_new_edit</tabstop>
|
||||
<tabstop>salt_mine_view_new</tabstop>
|
||||
<tabstop>detailed_view</tabstop>
|
||||
<tabstop>toolButton</tabstop>
|
||||
<tabstop>details_new_text</tabstop>
|
||||
<tabstop>mark_update_button</tabstop>
|
||||
<tabstop>search_update_edit</tabstop>
|
||||
<tabstop>salt_mine_view_update</tabstop>
|
||||
<tabstop>detailed_view2</tabstop>
|
||||
<tabstop>toolButton_2</tabstop>
|
||||
<tabstop>details_update_text</tabstop>
|
||||
<tabstop>search_installed_edit</tabstop>
|
||||
<tabstop>salt_view</tabstop>
|
||||
<tabstop>details_text</tabstop>
|
||||
<tabstop>detailed_view3</tabstop>
|
||||
<tabstop>edit_button</tabstop>
|
||||
<tabstop>search_new_edit</tabstop>
|
||||
<tabstop>mark_new_button</tabstop>
|
||||
<tabstop>salt_mine_view_new</tabstop>
|
||||
<tabstop>details_new_text</tabstop>
|
||||
<tabstop>toolButton</tabstop>
|
||||
<tabstop>details_text</tabstop>
|
||||
<tabstop>create_button</tabstop>
|
||||
<tabstop>apply_new_button</tabstop>
|
||||
<tabstop>apply_update_button</tabstop>
|
||||
<tabstop>scrollArea</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
|
@ -1193,5 +1251,53 @@
|
|||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>detailed_view</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>details_new_text</receiver>
|
||||
<slot>show_detailed_view(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>588</x>
|
||||
<y>57</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>578</x>
|
||||
<y>121</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>detailed_view2</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>details_update_text</receiver>
|
||||
<slot>show_detailed_view(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>616</x>
|
||||
<y>58</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>615</x>
|
||||
<y>96</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>detailed_view3</sender>
|
||||
<signal>clicked(bool)</signal>
|
||||
<receiver>details_text</receiver>
|
||||
<slot>show_detailed_view(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>602</x>
|
||||
<y>58</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>603</x>
|
||||
<y>91</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -328,6 +328,10 @@ MacroController::drop_url (const std::string &path_or_url)
|
|||
void
|
||||
MacroController::show_editor (const std::string &cat, bool force_add)
|
||||
{
|
||||
if (macro_categories ().empty ()) {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("Application has not been compiled with scripting support - no macro IDE available")));
|
||||
}
|
||||
|
||||
if (mp_macro_editor) {
|
||||
mp_macro_editor->show (cat, force_add);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,14 +36,15 @@ namespace lay
|
|||
{
|
||||
|
||||
SaltGrainDetailsTextWidget::SaltGrainDetailsTextWidget (QWidget *w)
|
||||
: QTextBrowser (w), mp_grain ()
|
||||
: QTextBrowser (w), mp_grain (), m_detailed_view (false)
|
||||
{
|
||||
setOpenLinks (false);
|
||||
setOpenExternalLinks (false);
|
||||
connect (this, SIGNAL (anchorClicked (const QUrl &)), this, SLOT (open_link (const QUrl &)));
|
||||
}
|
||||
|
||||
void SaltGrainDetailsTextWidget::set_grain (const SaltGrain *g)
|
||||
void
|
||||
SaltGrainDetailsTextWidget::set_grain (const SaltGrain *g)
|
||||
{
|
||||
if (g) {
|
||||
mp_grain.reset (new SaltGrain (*g));
|
||||
|
|
@ -53,6 +54,15 @@ void SaltGrainDetailsTextWidget::set_grain (const SaltGrain *g)
|
|||
setHtml (details_text ());
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrainDetailsTextWidget::show_detailed_view (bool f)
|
||||
{
|
||||
if (m_detailed_view != f) {
|
||||
m_detailed_view = f;
|
||||
setHtml (details_text ());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SaltGrainDetailsTextWidget::open_link (const QUrl &url)
|
||||
{
|
||||
|
|
@ -276,32 +286,36 @@ SaltGrainDetailsTextWidget::details_text ()
|
|||
stream << "<h3>" << QObject::tr ("Screenshot") << "</h3><p><img src=\":/screenshot\"/></p>";
|
||||
}
|
||||
|
||||
stream << "<br/>";
|
||||
stream << "<h3>" << QObject::tr ("Installation") << "</h3>";
|
||||
if (m_detailed_view) {
|
||||
|
||||
if (! g->url ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Download URL: ") << "</b>" << tl::to_qstring (tl::escaped_to_html (g->url ())) << "</p>";
|
||||
}
|
||||
if (! g->path ().empty () && ! g->installed_time ().isNull ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Installed: ") << "</b>" << g->installed_time ().toString () << "</p>";
|
||||
}
|
||||
if (! g->dependencies ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Depends on: ") << "</b><br/>";
|
||||
for (std::vector<lay::SaltGrainDependency>::const_iterator d = g->dependencies ().begin (); d != g->dependencies ().end (); ++d) {
|
||||
stream << " " << tl::to_qstring (tl::escaped_to_html (d->name)) << " ";
|
||||
stream << tl::to_qstring (tl::escaped_to_html (d->version));
|
||||
if (! d->url.empty ()) {
|
||||
stream << " - ";
|
||||
stream << "[" << tl::to_qstring (tl::escaped_to_html (d->url)) << "]<br/>";
|
||||
}
|
||||
stream << "<br/>";
|
||||
stream << "<h3>" << QObject::tr ("Installation") << "</h3>";
|
||||
|
||||
if (! g->url ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Download URL: ") << "</b>" << tl::to_qstring (tl::escaped_to_html (g->url ())) << "</p>";
|
||||
}
|
||||
if (! g->path ().empty () && ! g->installed_time ().isNull ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Installed: ") << "</b>" << g->installed_time ().toString () << "</p>";
|
||||
}
|
||||
if (! g->dependencies ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Depends on: ") << "</b><br/>";
|
||||
for (std::vector<lay::SaltGrainDependency>::const_iterator d = g->dependencies ().begin (); d != g->dependencies ().end (); ++d) {
|
||||
stream << " " << tl::to_qstring (tl::escaped_to_html (d->name)) << " ";
|
||||
stream << tl::to_qstring (tl::escaped_to_html (d->version));
|
||||
if (! d->url.empty ()) {
|
||||
stream << " - ";
|
||||
stream << "[" << tl::to_qstring (tl::escaped_to_html (d->url)) << "]<br/>";
|
||||
}
|
||||
}
|
||||
stream << "</p>";
|
||||
}
|
||||
|
||||
if (! g->path ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Installed files: ") << "</b></p><p>";
|
||||
produce_listing (stream, QDir (tl::to_qstring (g->path ())), 0);
|
||||
stream << "</p>";
|
||||
}
|
||||
stream << "</p>";
|
||||
}
|
||||
|
||||
if (! g->path ().empty ()) {
|
||||
stream << "<p><b>" << QObject::tr ("Installed files: ") << "</b></p><p>";
|
||||
produce_listing (stream, QDir (tl::to_qstring (g->path ())), 0);
|
||||
stream << "</p>";
|
||||
}
|
||||
|
||||
stream << "</td></tr></table>";
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ public:
|
|||
protected:
|
||||
virtual QVariant loadResource (int type, const QUrl &url);
|
||||
|
||||
public slots:
|
||||
void show_detailed_view (bool f);
|
||||
|
||||
private slots:
|
||||
void open_link (const QUrl &url);
|
||||
|
||||
|
|
@ -62,6 +65,7 @@ private:
|
|||
std::unique_ptr<lay::SaltGrain> mp_grain;
|
||||
|
||||
QString details_text ();
|
||||
bool m_detailed_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ ObjectInstPath::is_valid (lay::LayoutViewBase *view) const
|
|||
}
|
||||
|
||||
if (! is_cell_inst ()) {
|
||||
if (! ly.is_valid_layer (layer ())) {
|
||||
if (! ly.is_valid_layer (layer ()) && layer () != ly.guiding_shape_layer ()) {
|
||||
return false;
|
||||
}
|
||||
if (! ly.cell (ci).shapes (layer ()).is_valid (shape ())) {
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ private:
|
|||
std::string m_text;
|
||||
};
|
||||
|
||||
#if defined(HAVE_RUBY)
|
||||
|
||||
static std::string np (const std::string &s)
|
||||
{
|
||||
return tl::replaced (s, "\\", "/");
|
||||
}
|
||||
|
||||
#if defined(HAVE_RUBY)
|
||||
|
||||
TEST(1_BasicRuby)
|
||||
{
|
||||
tl_assert (rba::RubyInterpreter::instance () != 0);
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/clear_16px.png</normaloff>:/clear_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/add_16px.png</normaloff>:/add_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -218,7 +218,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/up_16px.png</normaloff>:/up_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -232,7 +232,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/down_16px.png</normaloff>:/down_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -298,7 +298,7 @@
|
|||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/clear_16px.png</normaloff>:/clear_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/down_16px.png</normaloff>:/down_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -175,7 +175,7 @@
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/add_16px.png</normaloff>:/add_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -197,7 +197,7 @@ You can use expressions inside the path components for variable paths</string>
|
|||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<iconset resource="../../../../icons/icons.qrc">
|
||||
<normaloff>:/up_16px.png</normaloff>:/up_16px.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
|
|
@ -315,7 +315,7 @@ You can use expressions inside the path components for variable paths</string>
|
|||
<tabstop>read_all_cbx</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/warn_16px@2x.png</pixmap>
|
||||
<pixmap resource="../../../../icons/icons.qrc">:/warn_16px@2x.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -379,7 +379,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../../../lay/lay/layResources.qrc">:/warn_16px@2x.png</pixmap>
|
||||
<pixmap resource="../../../../icons/icons.qrc">:/warn_16px@2x.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -430,7 +430,7 @@
|
|||
<tabstop>subst_char</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
<include location="../../../../icons/icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
|
|||
|
|
@ -22,3 +22,4 @@ SOURCES = \
|
|||
|
||||
FORMS = \
|
||||
OASISWriterOptionPage.ui \
|
||||
|
||||
|
|
|
|||
|
|
@ -202,13 +202,13 @@ public:
|
|||
|
||||
} else {
|
||||
|
||||
int y2 = m_pixmap_size - 1 - (iy * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int y1 = m_pixmap_size - 1 - ((iy + 1) * m_pixmap_size + m_pixmap_size / 2) / ny;
|
||||
int x1 = (ix * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
int x2 = ((ix + 1) * m_pixmap_size + m_pixmap_size / 2) / nx;
|
||||
int y2 = std::min (m_pixmap_size - 1, m_pixmap_size - 1 - (iy * m_pixmap_size + ny / 2) / ny);
|
||||
int y1 = std::max (0, m_pixmap_size - 1 - ((iy + 1) * m_pixmap_size + ny / 2) / ny);
|
||||
int x1 = std::max (0, (ix * m_pixmap_size + nx / 2) / nx);
|
||||
int x2 = std::min (m_pixmap_size - 1, ((ix + 1) * m_pixmap_size + nx / 2) / nx);
|
||||
|
||||
// "draw" the field
|
||||
for (int y = y1; y <= y2 && y >= 0 && y < m_pixmap_size; ++y) {
|
||||
for (int y = y1; y <= y2; ++y) {
|
||||
*((uint32_t *) img->scanLine (y)) &= (((1 << x1) - 1) | ~((1 << (x2 + 1)) - 1));
|
||||
}
|
||||
|
||||
|
|
@ -319,8 +319,8 @@ public:
|
|||
grad.setColorAt (0.0, QColor (248, 248, 248));
|
||||
grad.setColorAt (1.0, QColor (224, 224, 224));
|
||||
painter.setBrush (QBrush (grad));
|
||||
painter.setPen (QPen (Qt::black));
|
||||
painter.drawRect (QRect (QPoint (x, y - 2), QSize (m_pixmap_size + 3, m_pixmap_size + 3)));
|
||||
painter.setPen (QPen (Qt::black, 1.0, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
|
||||
painter.drawRect (QRectF (QPointF (x + 1, y - 1), QSizeF (m_pixmap_size + 2, m_pixmap_size + 2)));
|
||||
|
||||
painter.setBackgroundMode (Qt::TransparentMode);
|
||||
painter.setPen (QColor (128, 255, 128));
|
||||
|
|
|
|||
|
|
@ -408,19 +408,19 @@ struct PythonClassClientData
|
|||
: public gsi::PerClassClientSpecificData
|
||||
{
|
||||
PythonClassClientData (const gsi::ClassBase *_cls, PyTypeObject *_py_type, PyTypeObject *_py_type_static)
|
||||
: py_type_object (_py_type), py_type_object_static (_py_type_static), method_table (_cls)
|
||||
: py_type_object ((PyObject *) _py_type), py_type_object_static ((PyObject *) _py_type_static), method_table (_cls)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
PyTypeObject *py_type_object;
|
||||
PyTypeObject *py_type_object_static;
|
||||
PythonPtr py_type_object;
|
||||
PythonPtr py_type_object_static;
|
||||
MethodTable method_table;
|
||||
|
||||
static PyTypeObject *py_type (const gsi::ClassBase &cls_decl, bool as_static)
|
||||
{
|
||||
PythonClassClientData *cd = dynamic_cast<PythonClassClientData *>(cls_decl.data (gsi::ClientIndex::Python));
|
||||
return cd ? (as_static ? cd->py_type_object_static : cd->py_type_object) : 0;
|
||||
return (PyTypeObject *) (cd ? (as_static ? cd->py_type_object_static.get () : cd->py_type_object.get ()) : 0);
|
||||
}
|
||||
|
||||
static void initialize (const gsi::ClassBase &cls_decl, PyTypeObject *py_type, bool as_static)
|
||||
|
|
@ -428,9 +428,9 @@ struct PythonClassClientData
|
|||
PythonClassClientData *cd = dynamic_cast<PythonClassClientData *>(cls_decl.data (gsi::ClientIndex::Python));
|
||||
if (cd) {
|
||||
if (as_static) {
|
||||
cd->py_type_object_static = py_type;
|
||||
cd->py_type_object_static = (PyObject *) py_type;
|
||||
} else {
|
||||
cd->py_type_object = py_type;
|
||||
cd->py_type_object = (PyObject *) py_type;
|
||||
}
|
||||
} else {
|
||||
cls_decl.set_data (gsi::ClientIndex::Python, new PythonClassClientData (&cls_decl, as_static ? NULL : py_type, as_static ? py_type : NULL));
|
||||
|
|
@ -2475,7 +2475,11 @@ public:
|
|||
|
||||
PyTypeObject *type = (PyTypeObject *) PyObject_Call ((PyObject *) &PyType_Type, args.get (), NULL);
|
||||
if (type == NULL) {
|
||||
check_error ();
|
||||
try {
|
||||
check_error ();
|
||||
} catch (tl::Exception &ex) {
|
||||
tl::error << ex.msg ();
|
||||
}
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,20 +79,28 @@ LIBS += -L$$LIBDIR -lklayout_db
|
|||
|
||||
!msvc {
|
||||
|
||||
# Some standard compiler warnings on
|
||||
QMAKE_CXXFLAGS_WARN_ON += \
|
||||
-pedantic \
|
||||
-Woverloaded-virtual \
|
||||
-Wsign-promo \
|
||||
-Wsynth \
|
||||
-Wno-deprecated \
|
||||
-Wno-long-long \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-deprecated-declarations \
|
||||
-Wno-reserved-user-defined-literal \
|
||||
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
# too noisy on Qt:
|
||||
# QMAKE_CXXFLAGS_WARN_ON += \
|
||||
# -Wsign-promo \
|
||||
# -Wno-reserved-user-defined-literal \
|
||||
#
|
||||
|
||||
lessThan(QT_MAJOR_VERSION, 6) {
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++11
|
||||
} else {
|
||||
# because we use unordered_map/unordered_set:
|
||||
QMAKE_CXXFLAGS += -std=c++17
|
||||
}
|
||||
|
||||
# Python is somewhat sloppy and relies on the compiler initializing fields
|
||||
# of strucs to 0:
|
||||
|
|
|
|||
|
|
@ -212,9 +212,9 @@ InputStream::InputStream (const std::string &abstract_path)
|
|||
|
||||
QByteArray data;
|
||||
#if QT_VERSION >= 0x60000
|
||||
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
|
||||
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
|
||||
#else
|
||||
if (res.isCompressed ()) {
|
||||
if (res.isCompressed ()) {
|
||||
#endif
|
||||
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ to_fill = extent - l1
|
|||
fp1 = fill_pattern("FP1").shape(10, 0, box(0, 0, 800.nm, 800.nm)).origin(-100.nm, -100.nm)
|
||||
to_fill = to_fill.fill_with_left(fp1, hstep(1.um), vstep(200.nm, 1.um), multi_origin)
|
||||
|
||||
fp2 = fill_pattern("FP2").shape(10, 0, box(0, 0, 400.nm, 400.nm)).origin(-50.nm, -50.nm)
|
||||
fp2 = fill_pattern("FP2").shape(10, box(0, 0, 400.nm, 400.nm)).origin(-50.nm, -50.nm)
|
||||
to_fill = to_fill.fill_with_left(fp2, hstep(0.5.um), vstep(100.nm, 0.5.um), multi_origin)
|
||||
|
||||
fp3 = fill_pattern("FP3").shape(10, 0, box(0, 0, 200.nm, 200.nm)).origin(-25.nm, -25.nm)
|
||||
fp3 = fill_pattern("FP3").shape(RBA::LayerInfo::new(10, 0), box(0, 0, 200.nm, 200.nm)).origin(-25.nm, -25.nm)
|
||||
to_fill = to_fill.fill_with_left(fp3, hstep(0.25.um), vstep(50.nm, 0.25.um), multi_origin)
|
||||
|
||||
to_fill.output(100, 0)
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue