Text-Editor: V-Align + Mask-Type/Color + Case-Transform

Erweitert den Editor um die fehlenden Rhino-Text-Optionen:

- Vertical Alignment (Top/Middle/Bottom) als 3 Pill-Buttons in Row 2.
  Backend: text_create._apply_valign mit TextVerticalAlignment-Enum.
- Mask-Type Dropdown (None/Viewport/Solid). Bei Solid erscheint ein
  Mask-Color-Picker. MaskMargin disabled wenn Type=none.
  Backend: schaltet te.MaskEnabled + te.MaskUsesViewportColor +
  te.MaskColor entsprechend.
- Case-Dropdown in Row 2: upper/lower/capitalize/invert. Wirkt nur
  auf die Selektion via execCommand insertText.

open_for_edit liest valign + maskType/Color/Margin aus bestehendem
TextEntity zurueck, damit beim Re-Open der Zustand erhalten bleibt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 13:08:51 +02:00
parent de6f84346c
commit 6b3421e7af
3 changed files with 137 additions and 7 deletions
+16
View File
@@ -799,6 +799,22 @@ def _apply_align(te, align):
return False
def _apply_valign(te, valign):
"""Setzt TextVerticalAlignment (Top/Middle/Bottom)."""
try:
m = {
"top": Rhino.DocObjects.TextVerticalAlignment.Top,
"middle": Rhino.DocObjects.TextVerticalAlignment.Middle,
"bottom": Rhino.DocObjects.TextVerticalAlignment.Bottom,
}
if valign in m:
te.TextVerticalAlignment = m[valign]
return True
except Exception as ex:
print("[TEXT] apply valign:", ex)
return False
def apply_settings_to_selection(doc, patch):
"""Wendet font/size/bold/italic/align auf alle selektierten
TextEntities an. Returns Anzahl der geaenderten Objekte."""
+37 -2
View File
@@ -162,6 +162,7 @@ class TextEditorBridge(panel_base.BaseBridge):
try: te.TextHeight = float(st.get("size") or 0.2)
except Exception: pass
text_create._apply_align(te, st.get("align") or "left")
text_create._apply_valign(te, st.get("valign") or "top")
# Content. Bei RichText KEIN _apply_font — sonst ueberschreibt
# te.Font die per-Run-Fonts aus der RTF. Stattdessen lassen
@@ -225,12 +226,27 @@ class TextEditorBridge(panel_base.BaseBridge):
)
except Exception as ex:
print("[TEXT-EDITOR] frame:", ex)
# Mask: Type entscheidet ob/wie maskiert wird. Margin gilt
# nur wenn Maske aktiv. Solid-Color erst dann setzen wenn
# Type=solid (sonst dominiert Viewport-Color).
try:
mask_type = (st.get("maskType") or "none").lower()
mask_m = float(st.get("maskMargin") or 0)
if mask_m > 0:
if mask_type == "none":
te.MaskEnabled = False
else:
te.MaskEnabled = True
te.MaskOffset = mask_m
te.MaskUsesViewportColor = True
if mask_type == "solid":
te.MaskUsesViewportColor = False
mc = st.get("maskColor") or [255, 255, 255]
try:
te.MaskColor = System.Drawing.Color.FromArgb(
int(mc[0]), int(mc[1]), int(mc[2]))
except Exception as ex:
print("[TEXT-EDITOR] mask color:", ex)
else:
te.MaskUsesViewportColor = True
except Exception as ex:
print("[TEXT-EDITOR] mask:", ex)
@@ -497,6 +513,25 @@ def open_for_edit(obj):
settings["align"] = "right"
else: settings["align"] = "left"
except Exception: pass
try:
v = te.TextVerticalAlignment
VA = Rhino.DocObjects.TextVerticalAlignment
if v == VA.Middle: settings["valign"] = "middle"
elif v == VA.Bottom: settings["valign"] = "bottom"
else: settings["valign"] = "top"
except Exception: pass
try:
if te.MaskEnabled:
settings["maskType"] = "solid" if not te.MaskUsesViewportColor else "viewport"
try: settings["maskMargin"] = float(te.MaskOffset)
except Exception: pass
try:
mc = te.MaskColor
settings["maskColor"] = [mc.R, mc.G, mc.B]
except Exception: pass
else:
settings["maskType"] = "none"
except Exception: pass
initial_text = ""
try: initial_text = te.PlainText or ""