Omniflo Boegen und Weichen auch durch .py erzeugen und ändern.
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
# omniflo_weichen.py
|
||||
# Omniflo Weichen-Auswahl-Dialog (wx) und Weichen-Commands
|
||||
# Ersetzt die Weichen-Teile von OmniModulInsert.lsp + omniflo_weichen.dcl
|
||||
# ============================================
|
||||
|
||||
import wx
|
||||
|
||||
import PyRx as Rx
|
||||
import PyDb as Db
|
||||
import PyEd as Ed
|
||||
|
||||
from elemente.omniflo import (
|
||||
load_weichen,
|
||||
filter_by,
|
||||
insert_from_entry,
|
||||
sivasnr_to_str,
|
||||
)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Weichen-Auswahl-Dialog (ersetzt omniflo_weichen.dcl)
|
||||
# ============================================================
|
||||
|
||||
class WeichenSelectDialog(wx.Dialog):
|
||||
"""Weichen-Auswahl-Dialog mit Filtern.
|
||||
|
||||
Layout:
|
||||
- Dropdown: ProfilTyp (gefiltert)
|
||||
- Filter-Gruppe Schaltungstyp: Alle / M / P (wx.RadioBox)
|
||||
- Filter-Gruppe Richtung: Alle / Links / Rechts (wx.RadioBox)
|
||||
- Detail-Felder (readonly): SivasNr, Winkel, Breite, Laenge
|
||||
- OK / Abbrechen
|
||||
"""
|
||||
|
||||
def __init__(self, parent, basis_liste):
|
||||
super().__init__(parent, title="Omniflo Weiche auswaehlen",
|
||||
size=(500, 320),
|
||||
style=wx.DEFAULT_DIALOG_STYLE)
|
||||
self._basis = basis_liste
|
||||
self._gefiltert = list(basis_liste)
|
||||
self._selected_idx = 0
|
||||
|
||||
panel = wx.Panel(self)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
# Dropdown: ProfilTyp
|
||||
row_profil = wx.BoxSizer(wx.HORIZONTAL)
|
||||
row_profil.Add(wx.StaticText(panel, label="Profiltyp:"), 0,
|
||||
wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
|
||||
self.cb_profil = wx.Choice(panel, choices=[])
|
||||
self.cb_profil.Bind(wx.EVT_CHOICE, self._on_selection)
|
||||
row_profil.Add(self.cb_profil, 1)
|
||||
sizer.Add(row_profil, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
# Filter-Gruppe: Schaltungstyp + Richtung nebeneinander
|
||||
filter_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
self.rb_schaltung = wx.RadioBox(panel, label="Schaltungstyp",
|
||||
choices=["Alle", "M", "P"],
|
||||
majorDimension=1,
|
||||
style=wx.RA_SPECIFY_COLS)
|
||||
self.rb_schaltung.Bind(wx.EVT_RADIOBOX, self._apply_filter)
|
||||
filter_sizer.Add(self.rb_schaltung, 1, wx.EXPAND | wx.RIGHT, 5)
|
||||
|
||||
self.rb_richtung = wx.RadioBox(panel, label="Richtung",
|
||||
choices=["Alle", "Links", "Rechts"],
|
||||
majorDimension=1,
|
||||
style=wx.RA_SPECIFY_COLS)
|
||||
self.rb_richtung.Bind(wx.EVT_RADIOBOX, self._apply_filter)
|
||||
filter_sizer.Add(self.rb_richtung, 1, wx.EXPAND)
|
||||
|
||||
sizer.Add(filter_sizer, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
# Detail-Felder (2 Spalten)
|
||||
grid = wx.FlexGridSizer(cols=4, hgap=10, vgap=5)
|
||||
grid.AddGrowableCol(1)
|
||||
grid.AddGrowableCol(3)
|
||||
|
||||
grid.Add(wx.StaticText(panel, label="SivasNr:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
self.txt_sivasnr = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(140, -1))
|
||||
grid.Add(self.txt_sivasnr, 0)
|
||||
|
||||
grid.Add(wx.StaticText(panel, label="Winkel:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
self.txt_winkel = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
||||
grid.Add(self.txt_winkel, 0)
|
||||
|
||||
grid.Add(wx.StaticText(panel, label="Breite:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
self.txt_breite = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
||||
grid.Add(self.txt_breite, 0)
|
||||
|
||||
grid.Add(wx.StaticText(panel, label="Laenge:"), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
self.txt_laenge = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(100, -1))
|
||||
grid.Add(self.txt_laenge, 0)
|
||||
|
||||
sizer.Add(grid, 0, wx.EXPAND | wx.ALL, 5)
|
||||
|
||||
# OK / Cancel
|
||||
btn_sizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL)
|
||||
sizer.Add(btn_sizer, 0, wx.EXPAND | wx.ALL, 10)
|
||||
|
||||
panel.SetSizer(sizer)
|
||||
self.Fit()
|
||||
self.CenterOnScreen()
|
||||
|
||||
# Initiale Befuellung
|
||||
self._refresh_dropdown()
|
||||
|
||||
def _apply_filter(self, event=None):
|
||||
"""Filter anwenden und Dropdown neu befuellen."""
|
||||
self._refresh_dropdown()
|
||||
|
||||
def _refresh_dropdown(self):
|
||||
"""Dropdown mit gefilterter Liste neu fuellen."""
|
||||
sch_idx = self.rb_schaltung.GetSelection()
|
||||
ri_idx = self.rb_richtung.GetSelection()
|
||||
|
||||
# Schaltungstyp-Filter
|
||||
sch_filter = {0: None, 1: "M", 2: "P"}.get(sch_idx)
|
||||
# Richtungs-Filter (1=links, 2=rechts)
|
||||
ri_filter = {0: None, 1: 1, 2: 2}.get(ri_idx)
|
||||
|
||||
self._gefiltert = []
|
||||
for e in self._basis:
|
||||
if sch_filter and e.get("Schaltungstyp") != sch_filter:
|
||||
continue
|
||||
if ri_filter and e.get("KurvenRichtung") != ri_filter:
|
||||
continue
|
||||
self._gefiltert.append(e)
|
||||
|
||||
# Dropdown neu befuellen
|
||||
self.cb_profil.Clear()
|
||||
for e in self._gefiltert:
|
||||
self.cb_profil.Append(e.get("ProfilTyp", "?"))
|
||||
|
||||
if self._gefiltert:
|
||||
self.cb_profil.SetSelection(0)
|
||||
self._selected_idx = 0
|
||||
self._update_details(0)
|
||||
else:
|
||||
self._selected_idx = -1
|
||||
self.txt_sivasnr.SetValue("---")
|
||||
self.txt_winkel.SetValue("---")
|
||||
self.txt_breite.SetValue("---")
|
||||
self.txt_laenge.SetValue("---")
|
||||
|
||||
def _on_selection(self, event):
|
||||
self._selected_idx = self.cb_profil.GetSelection()
|
||||
self._update_details(self._selected_idx)
|
||||
|
||||
def _update_details(self, idx):
|
||||
if idx < 0 or idx >= len(self._gefiltert):
|
||||
return
|
||||
e = self._gefiltert[idx]
|
||||
self.txt_sivasnr.SetValue(sivasnr_to_str(e.get("Sivasnr")))
|
||||
wkl = e.get("KurvenWinkel", 0)
|
||||
self.txt_winkel.SetValue(f"{wkl} Grad")
|
||||
self.txt_breite.SetValue(str(e.get("Breite", "?")))
|
||||
self.txt_laenge.SetValue(str(e.get("Länge", "?")))
|
||||
|
||||
def get_selected(self):
|
||||
"""Gewaehlten Weichen-Eintrag zurueckgeben."""
|
||||
if 0 <= self._selected_idx < len(self._gefiltert):
|
||||
return self._gefiltert[self._selected_idx]
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Generische Weichen-Einfuege-Logik
|
||||
# ============================================================
|
||||
|
||||
def _weichen_command(winkel, weichentyp):
|
||||
"""Weichen-Dialog oeffnen, Auswahl einfuegen."""
|
||||
alle = load_weichen()
|
||||
|
||||
# Nach Winkel filtern (None = alle Winkel)
|
||||
if winkel is not None:
|
||||
basis = filter_by(alle, "KurvenWinkel", winkel)
|
||||
else:
|
||||
basis = list(alle)
|
||||
|
||||
# Nach WeichenTyp filtern
|
||||
if weichentyp:
|
||||
basis = [e for e in basis if e.get("WeichenTyp") == weichentyp]
|
||||
|
||||
if not basis:
|
||||
wkl_str = "alle Winkel" if winkel is None else f"{winkel} Grad"
|
||||
typ_str = f" / {weichentyp}" if weichentyp else ""
|
||||
print(f"\nKeine Weichen fuer {wkl_str}{typ_str} gefunden.")
|
||||
return
|
||||
|
||||
dlg = WeichenSelectDialog(None, basis)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
eintrag = dlg.get_selected()
|
||||
dlg.Destroy()
|
||||
if eintrag:
|
||||
insert_from_entry(eintrag)
|
||||
else:
|
||||
print("\n[WEICHE] Kein Eintrag ausgewaehlt.")
|
||||
else:
|
||||
dlg.Destroy()
|
||||
print("\n[WEICHE] Abgebrochen.")
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Weichen-Commands (gleiche Namen wie LISP)
|
||||
# ============================================================
|
||||
|
||||
# --- 90 Grad ---
|
||||
@Rx.command("OMNI_W90_Einfach")
|
||||
def cmd_w90_einfach():
|
||||
_weichen_command(90, "Einzelweiche")
|
||||
|
||||
@Rx.command("OMNI_W90_Doppel")
|
||||
def cmd_w90_doppel():
|
||||
_weichen_command(90, "Doppelweiche")
|
||||
|
||||
@Rx.command("OMNI_W90_Dreiwege")
|
||||
def cmd_w90_dreiwege():
|
||||
_weichen_command(90, "Dreiwegeweiche")
|
||||
|
||||
# --- 45 Grad ---
|
||||
@Rx.command("OMNI_W45_Einfach")
|
||||
def cmd_w45_einfach():
|
||||
_weichen_command(45, "Einzelweiche")
|
||||
|
||||
@Rx.command("OMNI_W45_Doppel")
|
||||
def cmd_w45_doppel():
|
||||
_weichen_command(45, "Doppelweiche")
|
||||
|
||||
@Rx.command("OMNI_W45_Dreiwege")
|
||||
def cmd_w45_dreiwege():
|
||||
_weichen_command(45, "Dreiwegeweiche")
|
||||
|
||||
# --- Parallel (KurvenWinkel=0) ---
|
||||
@Rx.command("OMNI_WP_Einfach")
|
||||
def cmd_wp_einfach():
|
||||
_weichen_command(0, "Einzelweiche")
|
||||
|
||||
@Rx.command("OMNI_WP_Doppel")
|
||||
def cmd_wp_doppel():
|
||||
_weichen_command(0, "Doppelweiche")
|
||||
|
||||
@Rx.command("OMNI_WP_Dreiwege")
|
||||
def cmd_wp_dreiwege():
|
||||
_weichen_command(0, "Dreiwegeweiche")
|
||||
|
||||
# --- Weichenkoerper (KurvenWinkel=22.5) ---
|
||||
@Rx.command("OMNI_WK_Einfach")
|
||||
def cmd_wk_einfach():
|
||||
_weichen_command(22.5, "Einzelweiche")
|
||||
|
||||
@Rx.command("OMNI_WK_Doppel")
|
||||
def cmd_wk_doppel():
|
||||
_weichen_command(22.5, "Doppelweiche")
|
||||
|
||||
@Rx.command("OMNI_WK_Dreiwege")
|
||||
def cmd_wk_dreiwege():
|
||||
_weichen_command(22.5, "Dreiwegeweiche")
|
||||
|
||||
# --- Weichenkombinationen ---
|
||||
@Rx.command("OMNI_WKomb_Delta")
|
||||
def cmd_wkomb_delta():
|
||||
_weichen_command(None, "Deltaweiche")
|
||||
|
||||
@Rx.command("OMNI_WKomb_Star")
|
||||
def cmd_wkomb_star():
|
||||
_weichen_command(None, "Sternweiche")
|
||||
Reference in New Issue
Block a user