diff --git a/klayout/pymacros/klive.lym b/klayout/pymacros/klive.lym index 77132f0..8c95d6b 100644 --- a/klayout/pymacros/klive.lym +++ b/klayout/pymacros/klive.lym @@ -18,7 +18,7 @@ import pya from pathlib import Path -from klive_server import server, toggle_ports, update_icon +from klive_server import server, update_icon app = pya.Application.instance() mw = app.main_window() @@ -33,13 +33,6 @@ reset_server.icon_text = "Restart klive" reset_server.icon = off menu.insert_item("@toolbar.end", "reset_server", reset_server) -port_action = pya.Action() -port_action.icon = poff -port_action.on_triggered = lambda: toggle_ports(port_action) -port_action.icon_text = "Show Ports" -menu.insert_item("@toolbar.end", "klive_action", port_action) -mw.on_current_view_changed = lambda: update_icon(port_action) - # Start the server server.reset(reset_server) diff --git a/klayout/python/klive_server.py b/klayout/python/klive_server.py index bc40eba..d3d8273 100644 --- a/klayout/python/klive_server.py +++ b/klayout/python/klive_server.py @@ -18,8 +18,6 @@ dpolygon_dict = {} shapes_shown = {} -prefix = "kfactory:ports:" - class ServerInstance(pya.QTcpServer): """ @@ -185,58 +183,7 @@ def close(self): def __del__(self): self.close() super(ServerInstance, self).__del__() - - -@dataclass -class KliveServer: - instance: Optional[ServerInstance] = None - - def reset(self, action): - app = pya.Application.instance() - mw = app.main_window() - if self.instance is not None and self.instance.isListening(): - self.instance.close() - app.process_events() - sleep(0.1) - self.instance = ServerInstance(self, parent=mw, action=action) - - -def toggle_ports(action): - acv = pya.CellView.active() - idx = acv.index() - cell = acv.cell - - if cell is not None: - cidx = cell.cell_index() - layout = acv.layout() - - if idx not in shapes_shown: - shapes_shown[idx] = {} - - if cidx in shapes_shown[idx]: - shapes = shapes_shown[idx][cidx] - for layer, shapes in shapes_shown[idx][cidx].items(): - lidx = cell.layout().layer(layer) - for shape in shapes: - if cell.shapes(lidx).is_valid(shape): - cell.shapes(lidx).erase(shape) - # del shapes_shown[idx][cidx][lidx] - del shapes_shown[idx][cidx] - update_icon(action) - else: - shapes_shown[idx][cidx] = {} - ports = portdict_from_meta(cell) - for port in ports.values(): - shapes = show_port(port, cell) - if port["layer"] not in shapes_shown[idx][cidx]: - shapes_shown[idx][cidx][port["layer"]] = [] - - shapes_shown[idx][cidx][port["layer"]].extend(shapes) - update_icon(action) - - def update_icon(action): - print("updating") acv = pya.CellView.active() idx = acv.index() cell = acv.cell @@ -252,70 +199,19 @@ def update_icon(action): action.tool_tip = "Current Status: Hidden" -def portdict_from_meta(cell): - ports = {} - for meta in cell.each_meta_info(): - if meta.name.startswith(prefix): - name = meta.name.removeprefix(prefix) - index, _type = name.split(":", 1) - if index not in ports: - ports[index] = {} - - if _type == "width": - ports[index]["width"] = meta.value - elif _type == "trans": - ports[index]["trans"] = pya.Trans.from_s(meta.value) - elif _type == "dcplx_trans": - ports[index]["dcplx_trans"] = pya.DCplx_Trans.from_s(meta.value) - elif _type == "layer": - ports[index]["layer"] = pya.LayerInfo.from_string(meta.value) - elif _type == "name": - ports[index]["name"] = meta.value - - return ports - - -def show_port(port, cell): - if "width" in port and "layer" in port and "trans" in port: - lidx = cell.layout().layer(port["layer"]) - trans = pya.Trans(port["trans"]) - shapes = [ - cell.shapes(lidx).insert(get_polygon(port["width"]).transformed(trans)) - ] - if "name" in port: - shapes.append(cell.shapes(lidx).insert(pya.Text(port["name"], trans))) - return shapes - elif "width" in port and "layer" in port and "dcplx_trans" in port: - lidx = cell.layout().layer(port["layer"]) - trans = pya.DCplxTrans(port["dcplx_trans"]) - shape = shapes = [ - cell.shapes(lidx).insert( - get_polygon(port["width"]).to_dtype(layout.dbu).transformed() - ) - ] - if "name" in port: - shapes.append(cell.shapes(lidx).insert(pya.DText(port["name"], trans))) - return shapes - - -def get_polygon(width): - if width in polygon_dict: - return polygon_dict[width] - else: - poly = pya.Polygon( - [ - pya.Point(0, width // 2), - pya.Point(0, -width // 2), - pya.Point(width // 2, 0), - ] - ) - - hole = pya.Region(poly).sized(-int(width * 0.05) or -1) - hole -= pya.Region(pya.Box(0, 0, width // 2, -width // 2)) - - poly.insert_hole(list(list(hole.each())[0].each_point_hull())) - polygon_dict[width] = poly - return poly +@dataclass +class KliveServer: + instance: Optional[ServerInstance] = None + + def reset(self, action): + app = pya.Application.instance() + mw = app.main_window() + if self.instance is not None and self.instance.isListening(): + self.instance.close() + app.process_events() + sleep(0.1) + self.instance = ServerInstance(self, parent=mw, action=action) + server = KliveServer()