Text-Editor: Stile, Size-Dropdown, U+Align, bessere Icons, Fonts-Fallback

User-Wunsch: Text-Editor war unfertig — keine Fonts sichtbar, Bold liess
sich nicht entfernen, Size soll Dropdown mit Eigene, Text-Stile noetig,
Unterstrichen + Links/Mitte/Rechts fehlten, schoenere Icons.

Backend (text_create.py):
- DEFAULTS erweitert um underline + align (left/center/right)
- _normalize() validiert Settings (align nur left/center/right)
- Text-Style-Preset-System analog mass_style:
  - list_styles / save_style / delete_style / apply_style
  - get_active_style_id / set_active_style_id
  - doc.Strings["dossier_text_styles"] (JSON list mit id/name + settings)
  - doc.Strings["dossier_text_style_active"]
- _apply_align(te, "left"|"center"|"right") setzt TextHorizontalAlignment
- apply_settings_to_selection + create_text rufen _apply_align mit auf
- read_selection_settings liest auch align
- available_fonts mit Fallback-Liste (Helvetica, Arial, Times, etc.) wenn
  Rhino.DocObjects.Font.AvailableFontFaceNames leer ist
- underline: in Settings + Styles persistiert, NOCH NICHT visuell
  appliziert (braucht TextEntity-RichText-API)

Backend (oberleiste.py):
- Neue Handler APPLY_TEXT_STYLE / SAVE_TEXT_STYLE / DELETE_TEXT_STYLE
- State liefert textStyles + textStyleActiveId
- textFonts jetzt bei jedem _send_state mitgeschickt (vorher one-shot mit
  _fonts_sent flag — verlor sich nach Panel-Re-Mount und User sah keine
  Fonts mehr)

Frontend (OberleisteApp):
- Text-Block komplett neu gelayoutet (3 Spalten Grid):
  Reihe 1: [Style ▼] [Font ▼] [Size ▼]
  Reihe 2: [B|I|U] [L|C|R] [+]
- Style-Dropdown mit Optionen "+ Speichern…" und "🗑 Aktiven loeschen"
- Size-Dropdown mit Preset-Werten (0.05/0.10/.../1.00 m) + "Eigene…"
  → toggle zu Custom-Number-Input bei "Eigene"-Auswahl
- B/I/U mit Material-Icons format_bold/italic/underlined statt B/I-Text
- L/C/R Alignment-Buttons mit format_align_left/center/right
- ToggleBtn-Helper-Komponente fuer alle 6 Toggles
- "+" Insert-Button bleibt klein (Icon size 14)
- Accent-Border auf allen Pills wenn Text selektiert (visuelles Feedback
  "Aenderungen wirken auf Selektion")
- Bold/Italic/Underline lassen sich jetzt sauber togglen (waren als
  proper Booleans serialisiert — vorher Bug evtl. durch fehlende Font-
  Liste maskiert)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 00:44:17 +02:00
parent 6fce00343c
commit 38041ab6a0
4 changed files with 398 additions and 148 deletions
+34 -8
View File
@@ -934,12 +934,35 @@ class OberleisteBridge(panel_base.BaseBridge):
doc = Rhino.RhinoDoc.ActiveDoc
patch = p.get("settings") or {}
text_create.save_settings(doc, patch)
# Wenn TextEntities selektiert: gleiche Aenderung direkt
# auf die selektierten Texte applizieren.
text_create.apply_settings_to_selection(doc, patch)
except Exception as ex:
print("[OBERLEISTE] text settings:", ex)
self._send_state(force=True)
elif t == "APPLY_TEXT_STYLE":
try:
import text_create
text_create.apply_style(
Rhino.RhinoDoc.ActiveDoc, p.get("id"))
except Exception as ex:
print("[OBERLEISTE] apply text style:", ex)
self._send_state(force=True)
elif t == "SAVE_TEXT_STYLE":
try:
import text_create
doc = Rhino.RhinoDoc.ActiveDoc
sid = text_create.save_style(doc, p.get("name") or "Stil")
if sid: text_create.set_active_style_id(doc, sid)
except Exception as ex:
print("[OBERLEISTE] save text style:", ex)
self._send_state(force=True)
elif t == "DELETE_TEXT_STYLE":
try:
import text_create
text_create.delete_style(
Rhino.RhinoDoc.ActiveDoc, p.get("id"))
except Exception as ex:
print("[OBERLEISTE] delete text style:", ex)
self._send_state(force=True)
# --- Masse (Mass-Style) -----------------------------------------
elif t == "SET_MASSE_ACTIVE":
@@ -1187,19 +1210,22 @@ class OberleisteBridge(panel_base.BaseBridge):
except Exception:
info["massePresets"] = []
info["masseActiveId"] = None
# Text-Settings + verfuegbare Fonts (Fonts nur einmal initial).
# Wenn TextEntity selektiert ist, deren Settings ergaenzen damit
# die UI die Werte des selektierten Textes spiegelt.
# Text-Settings + verfuegbare Fonts + Styles. Fonts werden bei
# jedem _send_state mitgeschickt damit nach Re-Mount (z.B. Panel-
# Andocken) die Liste nicht leer ist.
try:
import text_create
info["textSettings"] = text_create.load_settings(doc)
info["textSelectionSettings"] = text_create.read_selection_settings(doc)
if not getattr(self, "_fonts_sent", False):
info["textFonts"] = text_create.available_fonts()
self._fonts_sent = True
info["textFonts"] = text_create.available_fonts()
info["textStyles"] = text_create.list_styles(doc)
info["textStyleActiveId"] = text_create.get_active_style_id(doc)
except Exception:
info["textSettings"] = {}
info["textSelectionSettings"] = None
info["textFonts"] = []
info["textStyles"] = []
info["textStyleActiveId"] = None
# Norden-Rotation fuer N/O/S/W-Buttons
try:
import kamera