feat(editor): the dark scheme everywhere — the surface, documentation, mode buttons, program windows
The surface turns dark with light labels and cables and a faint light outline round Java's icons; documentation rectangles become a tint of their colour and texts are drawn towards light; the mode buttons use Java's pictures freed from their grey ground (tools/dark-pictures/make.py); native controls follow color-scheme; the desktop's program windows paint through Java-look tokens whose light values are Java's own. The exported image and the report keep Java's colours. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
"""The mode buttons' pictures for the editor's dark scheme (packages/editor/src/assets/modes/*_dunkel.png).
|
||||
|
||||
Java's pictures are 50 x 50 buttons: a frame and a vertical grey gradient (light blue and flat when the mode is
|
||||
on) around the icon. On a dark button that ground would stand as a light tile, so it is freed: the outer ring of
|
||||
RING pixels goes, and from there every pixel within GROUND of its row's ground colour (the gradient is row by row)
|
||||
becomes transparent, flooding inwards; a pixel up to EDGE from it (the icon's edge, blended with the grey) keeps its
|
||||
colour and fades with its likeness. Needs Pillow; run from the repository's root:
|
||||
|
||||
python3 tools/dark-pictures/make.py
|
||||
"""
|
||||
|
||||
from collections import deque
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
MODES = Path(__file__).resolve().parents[2] / 'packages/editor/src/assets/modes'
|
||||
RING = 3
|
||||
GROUND = 8
|
||||
EDGE = 48
|
||||
|
||||
|
||||
def freed(picture: Image.Image) -> Image.Image:
|
||||
image = picture.convert('RGBA')
|
||||
width, height = image.size
|
||||
pixels = image.load()
|
||||
ground = [pixels[RING, y] for y in range(height)]
|
||||
for y in range(RING):
|
||||
ground[y] = ground[RING]
|
||||
for y in range(height - RING, height):
|
||||
ground[y] = ground[height - RING - 1]
|
||||
seen = set()
|
||||
queue = deque()
|
||||
for x in range(width):
|
||||
for y in range(height):
|
||||
if x < RING or y < RING or x >= width - RING or y >= height - RING:
|
||||
pixels[x, y] = (0, 0, 0, 0)
|
||||
seen.add((x, y))
|
||||
queue.extend([(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)])
|
||||
while queue:
|
||||
x, y = queue.popleft()
|
||||
if (x, y) in seen or not (0 <= x < width and 0 <= y < height):
|
||||
continue
|
||||
seen.add((x, y))
|
||||
colour = pixels[x, y]
|
||||
distance = max(abs(colour[index] - ground[y][index]) for index in range(3))
|
||||
if distance <= GROUND:
|
||||
pixels[x, y] = (*colour[:3], 0)
|
||||
queue.extend([(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)])
|
||||
elif distance <= EDGE:
|
||||
pixels[x, y] = (*colour[:3], min(255, int(255 * (distance - GROUND) / (EDGE - GROUND))))
|
||||
return image
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
for source in sorted(MODES.glob('*.png')):
|
||||
if source.stem.endswith('_dunkel'):
|
||||
continue
|
||||
freed(Image.open(source)).save(source.with_name(f'{source.stem}_dunkel.png'))
|
||||
print(source.with_name(f'{source.stem}_dunkel.png').name)
|
||||
Reference in New Issue
Block a user