| 171 | # ── scene ───────────────────────────────────────────────────────────────────── |
| 172 | |
| 173 | class SchematicScene(QGraphicsScene): |
| 174 | |
| 175 | placing_started = Signal() |
| 176 | placing_cancelled = Signal() |
| 177 | wire_mode_started = Signal() |
| 178 | wire_mode_ended = Signal() |
| 179 | data_changed = Signal() # emitted on every new undo snapshot |
| 180 | group_move_started = Signal() |
| 181 | group_move_ended = Signal() |
| 182 | |
| 183 | def __init__(self): |
| 184 | super().__init__() |
| 185 | self.setSceneRect(-2000, -2000, 4000, 4000) |
| 186 | self.setBackgroundBrush(QColor(255, 255, 255)) |
| 187 | |
| 188 | self._mode = _Mode.NORMAL |
| 189 | self._ghost = None |
| 190 | self._placing_name = None |
| 191 | self._placing_svg = None |
| 192 | self._counters: dict[str, int] = {} |
| 193 | |
| 194 | self._wire_points: list[QPointF] = [] |
| 195 | self._wire_preview: QGraphicsPathItem | None = None |
| 196 | self._wire_h_first = True |
| 197 | self._last_cursor: QPointF | None = None |
| 198 | |
| 199 | self._vdrag_wire: WireItem | None = None |
| 200 | self._vdrag_idx: int | None = None |
| 201 | self._vdrag_rb: list = [] # [(wire, endpoint_index, original_QPointF)] |
| 202 | self._vdrag_pin_anchor: tuple | None = None # (comp, (lx, ly)) if vertex was on a pin |
| 203 | self._vdrag_pin_preview: WireItem | None = None |
| 204 | |
| 205 | self._wire_move_wires: list = [] |
| 206 | self._wire_move_origins: list = [] |
| 207 | self._wire_move_others: list = [] |
| 208 | self._wire_move_start: QPointF | None = None |
| 209 | self._wire_move_moved: bool = False |
| 210 | self._wire_move_rb: list = [] # [(wire, {idx: orig_QPointF})] |
| 211 | self._wire_move_junctions: list = [] # [(JunctionItem, orig_QPointF)] |
| 212 | self._pin_anchors: list = [] # [(anchor_QPointF, comp, (lx,ly))] |
| 213 | self._wire_pin_anchors: list = [] # [(comp, (lx,ly), wire, idx)] — wire ends on a pin |
| 214 | self._wire_pin_preview_wires: list = [] # preview WireItems for bridge wires during drag |
| 215 | |
| 216 | self._border_pending: tuple | None = None # (width, height, show_in_export) |
| 217 | self._library_pending: tuple | None = None # (file_path, directive, simulator, corner) |
| 218 | self._image_pending: tuple | None = None # (file_path, width, height) |
| 219 | self._latex_pending: tuple | None = None # (code, preamble, w, h) |
| 220 | self._param_pending: tuple | None = None # (params, preamble, w, h) |
| 221 | self._analysis_pending: tuple | None = None # (source, detector, lgref) |
| 222 | self._placing_text: str | None = None # text for PLACING_TEXT mode |
| 223 | self._hyperlink_pending: tuple | None = None # (url, label) |
| 224 | self._model_pending: tuple | None = None # (name, type, sim, params, preamble, w, h) |
| 225 | |
| 226 | # shape drawing state |
| 227 | self._draw_kind: str | None = None # "line"|"rect"|"circle" |
| 228 | self._draw_anchor: QPointF | None = None # first click (scene coords) |
| 229 | self._draw_pts: list = [] # accumulated scene pts (polyline) |
| 230 | self._draw_ghost: object | None = None # preview ShapeItem |
no outgoing calls
no test coverage detected