Text-Editor 3 echte Bugs gefixt (aus User-Log)
1. Dialog-Positionierung: vp.WorldToScreen existiert nicht auf dieser Rhino-Version. Ersetzt durch vp.WorldToClient → System.Drawing.Point (viewport-lokale Pixel) + view.ScreenRectangle fuer absolute Position. → Dialog poppt jetzt wirklich neben dem Frame statt random. 2. TextArea-Hoehe: DynamicLayout expandiert die TextArea nicht zuverlaessig (zeigte sich als 1-Zeilen-Streifen mit Buttons riesig daneben). Fix: ta.Size = drawing.Size(...) explizit setzen. 3. 5-arg Font(face, FontWeight, FontStyle, underline, strike): Python.NET 3.0 erlaubt keinen bool→Enum-Cast mehr (Log: "int can not be converted to Enum implicitly"). Fix: echte Enums Rhino.DocObjects.Font.FontWeight. Bold/Normal + FontStyle.Italic/Upright benutzen. Damit funktioniert auch Underline-Support endlich. apply_settings_to_selection: kompletter Rewrite — statt Duplicate-Modify wird eine FRESH TextEntity gebaut + alle Properties (Plane, PlainText, TextHeight, Font, Align) gesetzt + per Replace eingebunden. DimStyle wird auf Guid.Empty entkoppelt damit nicht die Style das Font-Setting ueberschreibt. Sollte Bold/Italic-Un-Toggle-Bug fixen. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+64
-43
@@ -211,20 +211,18 @@ def _inline_editor(p1, p2, initial=""):
|
|||||||
try:
|
try:
|
||||||
view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView
|
view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView
|
||||||
vp = view.ActiveViewport
|
vp = view.ActiveViewport
|
||||||
ok1, x1, y1 = vp.WorldToScreen(p1)
|
# WorldToClient → System.Drawing.Point (viewport-lokale Pixel)
|
||||||
ok2, x2, y2 = vp.WorldToScreen(p2)
|
c1 = vp.WorldToClient(p1)
|
||||||
if ok1 and ok2:
|
c2 = vp.WorldToClient(p2)
|
||||||
view_rect = view.ScreenRectangle
|
view_rect = view.ScreenRectangle # absolute Viewport-Position
|
||||||
fx = view_rect.X + min(x1, x2)
|
fx = view_rect.X + int(min(c1.X, c2.X))
|
||||||
fy = view_rect.Y + min(y1, y2)
|
fy = view_rect.Y + int(min(c1.Y, c2.Y))
|
||||||
fw = abs(x2 - x1); fh = abs(y2 - y1)
|
fw = abs(int(c2.X - c1.X))
|
||||||
# Dialog rechts neben dem Frame platzieren (oder darunter wenn
|
fh = abs(int(c2.Y - c1.Y))
|
||||||
# rechts kein Platz). Falls Frame klein, Dialog hat eigene Min-
|
sx = int(fx + fw + 20)
|
||||||
# Groesse.
|
sy = int(fy)
|
||||||
sx = int(fx + fw + 20)
|
sw = max(360, fw)
|
||||||
sy = int(fy)
|
sh = max(180, fh)
|
||||||
sw = max(360, fw)
|
|
||||||
sh = max(180, fh)
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("[TEXT] viewport-coords:", ex)
|
print("[TEXT] viewport-coords:", ex)
|
||||||
|
|
||||||
@@ -248,6 +246,11 @@ def _inline_editor(p1, p2, initial=""):
|
|||||||
ta.Text = initial or ""
|
ta.Text = initial or ""
|
||||||
try: ta.Font = drawing.Font("Helvetica", 13)
|
try: ta.Font = drawing.Font("Helvetica", 13)
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
|
# Explizit Groesse setzen — DynamicLayout expandiert TextArea sonst
|
||||||
|
# nicht zuverlaessig (zeigte sich als 1-Zeilen-Streifen)
|
||||||
|
try:
|
||||||
|
ta.Size = drawing.Size(int(sw) - 20, max(120, int(sh) - 70))
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
result = {"text": None, "committed": False}
|
result = {"text": None, "committed": False}
|
||||||
|
|
||||||
@@ -381,9 +384,14 @@ def _apply_font(te, face, bold, italic, underline=False):
|
|||||||
face = face[:-len(suffix)].strip(); break
|
face = face[:-len(suffix)].strip(); break
|
||||||
print("[TEXT] _apply_font face={!r} bold={} italic={} underline={}".format(
|
print("[TEXT] _apply_font face={!r} bold={} italic={} underline={}".format(
|
||||||
face, bold, italic, underline))
|
face, bold, italic, underline))
|
||||||
# Pfad 1: 5-arg Font-Konstruktor (mit underline+strikethrough)
|
# Pfad 1: 5-arg Font-Konstruktor mit echten Enums (Python.NET 3 erlaubt
|
||||||
|
# keinen impliziten bool→Enum-Cast mehr). Underline-Support nur hier.
|
||||||
try:
|
try:
|
||||||
font = Rhino.DocObjects.Font(face, bold, italic, underline, False)
|
FW = Rhino.DocObjects.Font.FontWeight
|
||||||
|
FS = Rhino.DocObjects.Font.FontStyle
|
||||||
|
weight = FW.Bold if bold else FW.Normal
|
||||||
|
style = FS.Italic if italic else FS.Upright
|
||||||
|
font = Rhino.DocObjects.Font(face, weight, style, underline, False)
|
||||||
if font is not None:
|
if font is not None:
|
||||||
te.Font = font
|
te.Font = font
|
||||||
return True
|
return True
|
||||||
@@ -454,37 +462,50 @@ def apply_settings_to_selection(doc, patch):
|
|||||||
if doc is None or not isinstance(patch, dict): return 0
|
if doc is None or not isinstance(patch, dict): return 0
|
||||||
selected = _selected_text_objects(doc)
|
selected = _selected_text_objects(doc)
|
||||||
if not selected: return 0
|
if not selected: return 0
|
||||||
|
import System
|
||||||
n = 0
|
n = 0
|
||||||
for obj in selected:
|
for obj in selected:
|
||||||
try:
|
try:
|
||||||
te = obj.Geometry.Duplicate()
|
old = obj.Geometry
|
||||||
if "size" in patch:
|
# Aktuelle Werte lesen (vor Modifikation)
|
||||||
try: te.TextHeight = float(patch["size"])
|
cur = old.Font
|
||||||
|
try: cur_face = cur.QuartetName if cur else "Helvetica"
|
||||||
|
except Exception: cur_face = "Helvetica"
|
||||||
|
try: cur_bold = bool(cur.Bold) if cur else False
|
||||||
|
except Exception: cur_bold = False
|
||||||
|
try: cur_italic = bool(cur.Italic) if cur else False
|
||||||
|
except Exception: cur_italic = False
|
||||||
|
try: cur_underline = bool(cur.Underlined) if cur else False
|
||||||
|
except Exception: cur_underline = False
|
||||||
|
|
||||||
|
# Neue Werte aus Patch + Fallback auf aktuell
|
||||||
|
face = patch.get("font") or cur_face
|
||||||
|
bold = patch["bold"] if "bold" in patch else cur_bold
|
||||||
|
italic = patch["italic"] if "italic" in patch else cur_italic
|
||||||
|
underline = patch["underline"] if "underline" in patch else cur_underline
|
||||||
|
size = float(patch["size"]) if "size" in patch else float(old.TextHeight)
|
||||||
|
align = patch["align"] if patch.get("align") in _ALIGNS else None
|
||||||
|
|
||||||
|
# FRESH TextEntity bauen statt Duplicate-Modify. Bypassed
|
||||||
|
# Probleme wo te.Font-Setter wegen Rich-Text-Runs oder
|
||||||
|
# DimensionStyle-Override nicht greift.
|
||||||
|
te = rg.TextEntity()
|
||||||
|
te.Plane = old.Plane
|
||||||
|
try: te.PlainText = old.PlainText
|
||||||
|
except Exception: pass
|
||||||
|
te.TextHeight = size
|
||||||
|
# DimensionStyle entkoppeln damit unser Font nicht von Style
|
||||||
|
# ueberschrieben wird.
|
||||||
|
try: te.DimensionStyleId = System.Guid.Empty
|
||||||
|
except Exception: pass
|
||||||
|
_apply_font(te, face, bool(bold), bool(italic), bool(underline))
|
||||||
|
# Alignment: aus Patch oder vom alten Entity uebernehmen
|
||||||
|
if align:
|
||||||
|
_apply_align(te, align)
|
||||||
|
else:
|
||||||
|
try: te.TextHorizontalAlignment = old.TextHorizontalAlignment
|
||||||
except Exception: pass
|
except Exception: pass
|
||||||
# Font: bei jeder Aenderung neu setzen. Vorher PlainText-
|
|
||||||
# Reset damit eventuelle RichText-Formatierungs-Runs nicht
|
|
||||||
# das neue te.Font ueberschreiben.
|
|
||||||
if any(k in patch for k in ("font", "bold", "italic", "underline")):
|
|
||||||
try:
|
|
||||||
plain = te.PlainText
|
|
||||||
te.PlainText = plain # reset zu plain-mode
|
|
||||||
except Exception: pass
|
|
||||||
cur = te.Font
|
|
||||||
try: cur_face = cur.QuartetName if cur else "Helvetica"
|
|
||||||
except Exception: cur_face = "Helvetica"
|
|
||||||
try: cur_bold = bool(cur.Bold) if cur else False
|
|
||||||
except Exception: cur_bold = False
|
|
||||||
try: cur_italic = bool(cur.Italic) if cur else False
|
|
||||||
except Exception: cur_italic = False
|
|
||||||
try: cur_underline = bool(cur.Underlined) if cur else False
|
|
||||||
except Exception: cur_underline = False
|
|
||||||
face = patch.get("font") or cur_face
|
|
||||||
bold = patch["bold"] if "bold" in patch else cur_bold
|
|
||||||
italic = patch["italic"] if "italic" in patch else cur_italic
|
|
||||||
underline = patch["underline"] if "underline" in patch else cur_underline
|
|
||||||
_apply_font(te, face, bool(bold), bool(italic), bool(underline))
|
|
||||||
if "align" in patch and patch["align"] in _ALIGNS:
|
|
||||||
_apply_align(te, patch["align"])
|
|
||||||
doc.Objects.Replace(obj.Id, te)
|
doc.Objects.Replace(obj.Id, te)
|
||||||
n += 1
|
n += 1
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
|
|||||||
Reference in New Issue
Block a user