logical_layers/backend/thumbnails.py

89 lines
3.4 KiB
Python

# backend/thumbnails.py
import wx
import pcbnew
from .resolvers import find_item_by_uuid
class ThumbnailGenerator:
@staticmethod
def generate_thumbnail(item_list, board, width=80, height=40):
"""
Generates a simple preview bitmap of the items.
"""
bmp = wx.Bitmap(width, height)
dc = wx.MemoryDC(bmp)
# Background
dc.SetBackground(wx.Brush(wx.Colour(30, 30, 30)))
dc.Clear()
# Collect items
items = []
min_x, min_y = float('inf'), float('inf')
max_x, max_y = float('-inf'), float('-inf')
has_items = False
for entry in item_list:
uuid = entry['uuid']
item = find_item_by_uuid(board, uuid)
if item:
items.append(item)
bb = item.GetBoundingBox()
min_x = min(min_x, bb.GetX())
min_y = min(min_y, bb.GetY())
max_x = max(max_x, bb.GetRight())
max_y = max(max_y, bb.GetBottom())
has_items = True
if has_items:
content_w = max_x - min_x
content_h = max_y - min_y
if content_w == 0: content_w = 1
if content_h == 0: content_h = 1
# Scale to fit in width x height with some padding
scale_x = (width * 0.9) / content_w
scale_y = (height * 0.9) / content_h
scale = min(scale_x, scale_y)
off_x = (width - (content_w * scale)) / 2
off_y = (height - (content_h * scale)) / 2
pen_track = wx.Pen(wx.Colour(0, 200, 0), 1)
brush_pad = wx.Brush(wx.Colour(200, 0, 0))
pen_pad = wx.Pen(wx.Colour(200, 0, 0), 1)
for item in items:
cls = item.GetClass()
if cls == "PCB_TRACK":
dc.SetPen(pen_track)
t = pcbnew.Cast_to_PCB_TRACK(item)
start = t.GetStart()
end = t.GetEnd()
x1 = int((start.x - min_x) * scale + off_x)
y1 = int((start.y - min_y) * scale + off_y)
x2 = int((end.x - min_x) * scale + off_x)
y2 = int((end.y - min_y) * scale + off_y)
dc.DrawLine(x1, y1, x2, y2)
elif cls == "PCB_VIA":
dc.SetPen(pen_track)
dc.SetBrush(wx.Brush(wx.Colour(200, 200, 0)))
v = pcbnew.Cast_to_PCB_VIA(item)
pos = v.GetPosition()
x = int((pos.x - min_x) * scale + off_x)
y = int((pos.y - min_y) * scale + off_y)
r = max(1, int((v.GetWidth() / 2) * scale))
dc.DrawCircle(x, y, r)
else:
dc.SetPen(pen_pad)
dc.SetBrush(brush_pad)
bb = item.GetBoundingBox()
x = int((bb.GetX() - min_x) * scale + off_x)
y = int((bb.GetY() - min_y) * scale + off_y)
w = int(bb.GetWidth() * scale)
h = int(bb.GetHeight() * scale)
if w < 2: w = 2
if h < 2: h = 2
dc.DrawRectangle(x, y, w, h)
dc.SelectObject(wx.NullBitmap)
return bmp