Logo in den Programmfarben, einen Tick groesser

Gleiche Umstellung wie im Rechnungstool (gemeinsame wasserzeichen.py): das
Blaugruen wird Tuerkis (#06C6A4), die zweite Haelfte weiss im Dunkeln und
dunkelgrau im Hellen, unterschieden nach Saettigung.

"beim steuertool koennte es ein tick groesser sein" - 28 -> 34 Pixel, wie im
Rechnungstool. Die Stelle bleibt rechts in der Kopfleiste: links stehen die
Bedienelemente (Jahr, Einlesen, Bericht), ein Logo davor wuerde sie alle nach
rechts schieben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
TheMockTv 2026-09-07 01:02:04 +02:00
parent 755c844ee4
commit 319c680a62
3 changed files with 29 additions and 22 deletions

4
app.py
View file

@ -407,7 +407,9 @@ class App(theme.ThemeMixin, tk.Tk):
# Das Programmlogo rechts in der Kopfzeile - das Erkennungszeichen.
# Es steht rechts, damit es die Bedienelemente nicht nach hinten
# schiebt, wenn es einmal fehlt.
self._kopf_bild = wasserzeichen.kopf(28, master=self, melden=log.info,
# 34 Pixel wie im Rechnungstool - bei 28 war es ihm zu klein
# ("beim steuertool koennte es ein tick groesser sein", 07.09.2026).
self._kopf_bild = wasserzeichen.kopf(34, master=self, melden=log.info,
dunkel=getattr(self, "_dark_mode", False))
if self._kopf_bild is not None:
ttk.Label(leiste, image=self._kopf_bild).pack(side="right")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Before After
Before After

View file

@ -66,7 +66,7 @@ def symbol_datei_dunkel():
ziel = os.path.join(os.path.dirname(quelle), "programm_dunkel.ico")
try:
from PIL import Image
bild = _fuer_dunkel(Image.open(quelle).convert("RGBA"))
bild = _umfaerben(Image.open(quelle).convert("RGBA"), True)
groessen = [(g, g) for g in (16, 24, 32, 48, 64, 128, 256)]
try:
bild.save(ziel, sizes=groessen)
@ -101,39 +101,45 @@ def symbol_setzen(fenster, melden=print, dunkel=False):
return False
def _fuer_dunkel(bild):
"""Das Logo fuer die dunkle Darstellung aufhellen.
# Die Farben des Logos - gemessen, nicht geraten:
# #004860 das dunkle Blaugruen (Wolke, Pfeile)
# #181818 das fast schwarze Grau (Dokument bzw. Paragraphenzeichen)
#
# Seine Ansage am 07.09.2026: *"das dunkel blaue machen wir in unserm tuerkis
# gruen und die andere seite in weiss ... wenn es dunkel ist, und beim hellen
# machen wir weiss in dunkel grau"*. Das Zeichen traegt damit dieselbe Farbe
# wie das Programm - und die zweite Haelfte steht in beiden Darstellungen im
# Kontrast statt unterzugehen.
TUERKIS = (0x06, 0xC6, 0xA4) # die Programmfarbe, wie col_accent
NEUTRAL_DUNKEL = (0xF2, 0xF3, 0xF5) # fast weiss - auf dunklem Grund
NEUTRAL_HELL = (0x33, 0x36, 0x3B) # dunkelgrau - auf hellem Grund
Sein Befund am 07.09.2026: *"wir muessen mal schauen das wir die svg fuer
das dunkle heller machen weil die geht nun unter"*.
Gemessen sind es zwei Farben: das Petrol #004860 (Helligkeit 53) und ein
fast schwarzes #181818 (Helligkeit 24). Der zweite Wert liegt genau auf der
Kachelfarbe #15171b - deshalb verschwindet die Haelfte des Zeichens.
def _umfaerben(bild, dunkel):
"""Das Logo auf die Programmfarben umsetzen.
Umgestellt wird nur die HELLIGKEIT, Farbton und Saettigung bleiben: sonst
waere es nicht mehr sein Logo, sondern ein anderes. Aus dunkel wird hell,
aus hell dunkel (L -> 1-L), und weil eine reine Umkehr das kraeftige Petrol
fast weiss werden liesse, wird sie auf 0.78 gedeckelt.
Unterschieden wird nach SAETTIGUNG, nicht nach dem genauen Farbwert: das
Blaugruen ist kraeftig gesaettigt, das Grau gar nicht. So bleibt die
Zuordnung auch dann richtig, wenn die Vorlage einmal in einem anderen Ton
gezeichnet wird - und die weichen Kanten aus dem Skalieren gehen denselben
Weg wie die Flaeche, zu der sie gehoeren.
Die Kanten (halbdurchsichtige Punkte aus dem Skalieren) gehen denselben Weg
- deshalb Pixel fuer Pixel und nicht ein Farbtausch mit Toleranz.
Die Deckkraft bleibt unangetastet; die Form kommt aus dem Alphakanal.
"""
import colorsys
bild = bild.convert("RGBA")
neutral = NEUTRAL_DUNKEL if dunkel else NEUTRAL_HELL
punkte = list(bild.getdata())
neu = []
zwischen = {}
neu = []
for r, g, b, a in punkte:
if a == 0:
neu.append((r, g, b, a))
continue
schluessel = (r, g, b)
if schluessel not in zwischen:
h, l, s2 = colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
hell = min(1.0 - l, 0.78)
r2, g2, b2 = colorsys.hls_to_rgb(h, hell, s2)
zwischen[schluessel] = (int(r2 * 255), int(g2 * 255), int(b2 * 255))
_, _, saettigung = colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
zwischen[schluessel] = TUERKIS if saettigung > 0.25 else neutral
neu.append(zwischen[schluessel] + (a,))
bild.putdata(neu)
return bild
@ -162,8 +168,7 @@ def hole(groesse=240, deckkraft=0.06, master=None, melden=print, dunkel=False):
try:
from PIL import Image, ImageTk
bild = Image.open(p).convert("RGBA").resize((groesse, groesse), Image.LANCZOS)
if dunkel:
bild = _fuer_dunkel(bild)
bild = _umfaerben(bild, dunkel)
bild.putalpha(bild.getchannel("A").point(lambda w: int(w * deckkraft)))
fertig = ImageTk.PhotoImage(bild, master=fenster)
except Exception as e: # noqa: BLE001 - ein Wasserzeichen darf nichts blockieren