diff --git a/rhino/_startup_splash.py b/rhino/_startup_splash.py new file mode 100644 index 0000000..8bc4c7b --- /dev/null +++ b/rhino/_startup_splash.py @@ -0,0 +1,156 @@ +#! python 3 +# -*- coding: utf-8 -*- +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (C) 2026 Karim Gabriele Varano +""" +_startup_splash.py +Petrol-grüner Splash-Screen waehrend des DOSSIER-Plugin-Startups. +Borderless Eto-Form mit WebView + Inline-HTML im selben Stil wie der +Launcher-Splash. Bedeckt visuell die 3+ Sekunden waehrend Rhino die +Panels registriert + WindowLayout neu anwendet. + +Wird von startup.py beim ersten Idle gezeigt und nach Layout-Apply +(oder Timeout) wieder versteckt. +""" +import scriptcontext as sc + +_SPLASH_KEY = "_dossier_startup_splash" +_SAFETY_TIMEOUT_SEC = 8.0 # spaetestens nach 8s wegmachen, falls Hide-Hook nicht feuert + + +_SPLASH_HTML = ''' +Dossier laedt + + + + +
+
+
DOSSIER.
+
Rhino 8 Plugin
+
+
+
+ + Plugin laedt — Panels werden platziert +
+
+
+
+ AGPL-3.0 · Karim Gabriele Varano + CPython 3.9 +
+
+''' + + +def show(): + """Zeigt den Splash. Idempotent — zweiter Aufruf bringt das bestehende + Fenster nur in den Vordergrund. Auto-Hide nach _SAFETY_TIMEOUT_SEC + als Fallback falls hide() vergessen wird.""" + if sc.sticky.get(_SPLASH_KEY) is not None: + return + try: + import Eto.Forms as ef + import Eto.Drawing as ed + form = ef.Form() + form.Title = "Dossier" + # WindowStyle.None — "None" ist Python-keyword, daher via getattr + try: form.WindowStyle = getattr(ef.WindowStyle, "None") + except Exception: pass + try: form.Resizable = False + except Exception: pass + try: form.Topmost = True + except Exception: pass + try: form.ShowInTaskbar = False + except Exception: pass + try: form.Size = ed.Size(420, 160) + except Exception: pass + try: + # Hintergrund weiss, das WebView-content hat seine eigene + # gerundete Petrol-Box — Form muss nur kein graues Border zeigen + form.BackgroundColor = ed.Color(0.18, 0.50, 0.45) + except Exception: pass + wv = ef.WebView() + try: + wv.LoadHtml(_SPLASH_HTML) + except Exception as ex: + print("[SPLASH] LoadHtml:", ex) + form.Content = wv + try: + # Center on screen + screen = ef.Screen.PrimaryScreen + sb = screen.Bounds + x = int(sb.X + (sb.Width - form.Size.Width) / 2) + y = int(sb.Y + (sb.Height - form.Size.Height) / 2 - 100) + form.Location = ed.Point(x, y) + except Exception as ex: + print("[SPLASH] center:", ex) + try: form.Show() + except Exception as ex: + print("[SPLASH] Show:", ex); return + sc.sticky[_SPLASH_KEY] = form + # Safety-Timeout — wenn nach 8s niemand hide() ruft, automatisch weg + try: + import threading + def _auto_hide(): + try: hide() + except Exception: pass + threading.Timer(_SAFETY_TIMEOUT_SEC, _auto_hide).start() + except Exception: pass + except Exception as ex: + print("[SPLASH] show:", ex) + + +def hide(): + """Versteckt + entsorgt den Splash. Idempotent.""" + form = sc.sticky.get(_SPLASH_KEY) + if form is None: + return + try: + sc.sticky[_SPLASH_KEY] = None + try: form.Close() + except Exception: + try: form.Visible = False + except Exception: pass + except Exception as ex: + print("[SPLASH] hide:", ex) diff --git a/rhino/oberleiste.py b/rhino/oberleiste.py index ee3f4ec..e317519 100644 --- a/rhino/oberleiste.py +++ b/rhino/oberleiste.py @@ -1380,6 +1380,15 @@ class OberleisteBridge(panel_base.BaseBridge): sc.sticky["_dossier_view_colors_applied"] = True except Exception as ex: print("[OBERLEISTE] auto-apply (layout/colors):", ex) + # Splash-Screen (falls noch offen) jetzt wegmachen — Layout-Apply ist + # durch, Panels sind in finaler Position. Lazy via Timer 200ms damit + # die Layout-Animation kurz auf den finalen Panels sichtbar wird. + try: + import threading + import _startup_splash as _ss + threading.Timer(0.2, _ss.hide).start() + except Exception as ex: + print("[OBERLEISTE] splash hide:", ex) self._send_state(force=True) def handle(self, data): diff --git a/rhino/startup.py b/rhino/startup.py index eb38489..b3bfda4 100644 --- a/rhino/startup.py +++ b/rhino/startup.py @@ -240,6 +240,13 @@ def _load_all(sender, e): Rhino.RhinoApp.Idle -= _load_all except Exception: pass + # Splash zeigen bevor irgendwas laeuft — verdeckt visuell die ~3s + # Panel-Init + WindowLayout-Apply + try: + import _startup_splash + _startup_splash.show() + except Exception as ex: + print("[STARTUP] splash show:", ex) print("[STARTUP] Lade DOSSIER-Panels...") # Migration einmal fuer das beim Start aktive Doc _migrate_active_doc()