Skip to content

Commit

Permalink
Merge pull request #18 from tgree/tkinter_windows
Browse files Browse the repository at this point in the history
Tkinter windows
  • Loading branch information
tgree authored Feb 15, 2022
2 parents 6996b3c + 66d56be commit 1c0b0d5
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 142 deletions.
3 changes: 3 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ disable=bad-whitespace,
useless-super-delegation,
consider-using-f-string,
R0801

[TYPECHECK]
generated-members=xplat.*
13 changes: 9 additions & 4 deletions stm_layout/chip_stm.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,17 +234,22 @@ def make_chip(part):
# full names:
#
# PA0
# PA11 [PA9]
# PC14-OSC32_IN (PC14)
# PC14/OSC32_IN
# PC2_C
# PA11 [PA9] (stm32g050f6p6)
# PC14-OSC32_IN (PC14) (stm32u585qii3)
# PC14/OSC32_IN (stm32f767zit6)
# PC14OSC32_IN (stm32f091rch6)
# PC15OSC32_OUT (stm32f091rch6)
# PF11BOOT0 (stm32f091rch6)
# PC2_C (stm32h745xgh6 has PC2 and PC2_C)
#
# The short name is the initial prefix except in the case of an "_C"
# suffix, in which case the short name includes the suffix. The GPIO
# key is always strictly the prefix.
short_name = full_name.split('-')[0]
short_name = short_name.split('/')[0]
short_name = short_name.split(' ')[0]
short_name = short_name.split('OSC32_')[0]
short_name = short_name.split('BOOT0')[0]
gpio_key = short_name.split('_')[0]

# Extract the alternate (digital) functions and additional (analog)
Expand Down
43 changes: 38 additions & 5 deletions stm_layout/stm_layout_tk.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,43 @@
import stm_layout.tk


FONT = ('Monaco', 10)
FONT_PIN_NUM = ('Monaco', 9)
FONT_INFO = ('Monaco', 10)
stm_layout.tk.xplat.register(
windows={
'LABEL_FONT' : ('Courier New', 10),
'INFO_FONT' : ('Courier New', 10),
'PIN_FONT' : ('Courier New', 9),
'EDGE_PIN_H_KEY_DX' : 0,
'EDGE_PIN_H_KEY_DY' : 1,
'EDGE_PIN_V_KEY_DX' : 1,
'BGA_PIN_NAME_DY' : 1,
'BGA_PIN_KEY_DX' : 0,
'BGA_PIN_KEY_DY' : 1,
},
darwin={
'LABEL_FONT' : ('Monaco', 10),
'INFO_FONT' : ('Monaco', 10),
'PIN_FONT' : ('Monaco', 9),
'EDGE_PIN_H_KEY_DX' : 1,
'EDGE_PIN_H_KEY_DY' : 0,
'EDGE_PIN_V_KEY_DX' : 0,
'BGA_PIN_NAME_DY' : 0,
'BGA_PIN_KEY_DX' : 1,
'BGA_PIN_KEY_DY' : 0,
},
linux={
# TBD.
'LABEL_FONT' : ('Courier', 10),
'INFO_FONT' : ('Courier', 10),
'PIN_FONT' : ('Courier', 9),
'EDGE_PIN_H_KEY_DX' : 0,
'EDGE_PIN_H_KEY_DY' : 1,
'EDGE_PIN_V_KEY_DX' : 1,
'BGA_PIN_NAME_DY' : 1,
'BGA_PIN_KEY_DX' : 0,
'BGA_PIN_KEY_DY' : 1,
},
)

RECT_FILL = 'white'
HILITE_FILL = 'lightblue'
SELECT_FILL = 'yellow'
Expand All @@ -25,8 +59,7 @@ def main(chip, regex):
else:
raise Exception('Unsupported chip package.')

ws = cls(chip, FONT, FONT_PIN_NUM, FONT_INFO, RECT_FILL, HILITE_FILL,
SELECT_FILL, RE_FILL)
ws = cls(chip, RECT_FILL, HILITE_FILL, SELECT_FILL, RE_FILL)
if regex:
ws.set_regex(regex)

Expand Down
23 changes: 18 additions & 5 deletions stm_layout/tk/tk_bga.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from . import tk_workspace
from . import xplat
from .. import chip_db


PIN_DIAM = 30
Expand All @@ -10,19 +12,20 @@ class BGAWorkspace(tk_workspace.Workspace):
def __init__(self, *args):
super().__init__(*args)

dy = self.label_font.metrics('linespace')
cw = self.chip.width
ch = self.chip.height
w = cw*PIN_DELTA + PIN_SPACE
h = ch*PIN_DELTA + PIN_SPACE + self.label_font.metrics('ascent')
pad = 15
self.set_geometry(50, 50, w + 2*pad + self.info_width,
max(h + 2*pad, self.info_height))
max(h + 2*pad + dy, self.info_height))

c = self.mcu_canvas = self.add_canvas(w + 2*pad, h + 2*pad)
c = self.mcu_canvas = self.add_canvas(w + 2*pad, h + 2*pad + dy)
self._root.columnconfigure(0, weight=1)
self._root.rowconfigure(0, weight=1)

m = c.add_rectangle(pad, pad, w, h, fill=self.elem_fill)
m = c.add_rectangle(pad, pad + dy, w, h, fill=self.elem_fill)
for x in range(cw):
for y in range(ch):
p = self.chip.chip.pins[x][y]
Expand All @@ -36,9 +39,19 @@ def __init__(self, *args):
fill=self.elem_fill)
self.pin_elems.append(o)
c.add_text(
o.x + o.width / 2, o.y + o.height,
o.x + o.width / 2,
o.y + o.height + xplat.BGA_PIN_NAME_DY,
font=self.label_font, text=p.name, anchor='n')
c.add_text(
o.x + o.width / 2 + 1, o.y + o.height / 2,
o.x + o.width / 2 + xplat.BGA_PIN_KEY_DX,
o.y + o.height / 2 + xplat.BGA_PIN_KEY_DY,
font=self.pin_font, text=p.key, anchor='c')
o.pin = p

package_name = chip_db.package(self.chip.part)
c.add_text(m.x, m.y, font=self.label_font, text=self.chip.name,
anchor='sw')
c.add_text(m.x + m.width / 2, m.y, font=self.label_font,
text=self.max_freq_mhz, anchor='s')
c.add_text(m.rx, m.y, font=self.label_font, text=package_name,
anchor='se')
66 changes: 66 additions & 0 deletions stm_layout/tk/tk_edgy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from . import tk_workspace
from . import xplat


PIN_WIDTH = 12
PIN_DELTA = 2*PIN_WIDTH
PIN_LENGTH = 20
PIN_LABEL_OFFSET = 2


def pin_d(t0, t1, i):
if t0 < t1:
return t0 + PIN_WIDTH + i*PIN_DELTA
return t0 - (i + 1)*PIN_DELTA


class Workspace(tk_workspace.Workspace):
def __init__(self, *args):
super().__init__(*args)
self.pin_width = PIN_WIDTH
self.pin_length = PIN_LENGTH
self.pin_label_offset = PIN_LABEL_OFFSET

def add_h_pin(self, p, x, y):
c = self.mcu_canvas
r = c.add_rectangle(x, y, PIN_LENGTH, PIN_WIDTH, fill=self.elem_fill)
c.add_text(x + PIN_LENGTH / 2 + xplat.EDGE_PIN_H_KEY_DX,
y + PIN_WIDTH / 2 + xplat.EDGE_PIN_H_KEY_DY,
font=self.pin_font, text=p.key, anchor='c')
return r

def add_v_pin(self, p, x, y):
c = self.mcu_canvas
r = c.add_rectangle(x, y, PIN_WIDTH, PIN_LENGTH, fill=self.elem_fill)
c.add_text(x + PIN_WIDTH / 2 + xplat.EDGE_PIN_V_KEY_DX,
y + PIN_LENGTH / 2, font=self.pin_font, text=p.key,
anchor='c', angle=90)
return r

def add_l_pin(self, p, x, y0, y1, i):
y = pin_d(y0, y1, i)
self.mcu_canvas.add_text(x - PIN_LABEL_OFFSET, y + PIN_WIDTH / 2,
font=self.label_font, text=p.name, anchor='e')
return self.add_h_pin(p, x, y)

def add_r_pin(self, p, x, y0, y1, i):
y = pin_d(y0, y1, i)
self.mcu_canvas.add_text(x + PIN_LENGTH + 1 + PIN_LABEL_OFFSET,
y + PIN_WIDTH / 2, font=self.label_font,
text=p.name, anchor='w')
return self.add_h_pin(p, x, y)

def add_t_pin(self, p, x0, x1, i, y):
x = pin_d(x0, x1, i)
self.mcu_canvas.add_text(x + PIN_WIDTH / 2, y - PIN_LABEL_OFFSET,
font=self.label_font, text=p.name, anchor='w',
angle=90)
return self.add_v_pin(p, x, y)

def add_b_pin(self, p, x0, x1, i, y):
x = pin_d(x0, x1, i)
self.mcu_canvas.add_text(x + PIN_WIDTH / 2,
y + PIN_LENGTH + 1 + PIN_LABEL_OFFSET,
font=self.label_font, text=p.name, anchor='e',
angle=90)
return self.add_v_pin(p, x, y)
13 changes: 13 additions & 0 deletions stm_layout/tk/tk_elems.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import tkinter
import ctypes


class Elem:
Expand All @@ -14,8 +15,12 @@ def __init__(self, canvas, elem_id, x, y, width=None, height=None):
self.y = y
if width is not None:
self.width = width
self.lx = x
self.rx = x + width
if height is not None:
self.height = height
self.ty = y
self.by = y + height

def bbox(self):
return self._canvas._bbox(self)
Expand Down Expand Up @@ -113,8 +118,16 @@ def add_entry(self, **kwargs):

class TKBase:
def __init__(self):
# Windows hack #1.
try:
ctypes.windll.shcore.SetProcessDpiAwareness(1)
except AttributeError:
pass
self._root = tkinter.Tk()

# Windows hack #2.
self._root.tk.call('tk', 'scaling', 1.0)

def set_geometry(self, x, y, width, height):
self._root.geometry('%ux%u+%u+%u' % (width, height, x, y))

Expand Down
89 changes: 16 additions & 73 deletions stm_layout/tk/tk_lqfp.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
from . import tk_workspace
from . import tk_edgy
from .. import chip_db


PIN_WIDTH = 12
PIN_LENGTH = 20
PIN_LABEL_OFFSET = 2


class LQFPWorkspace(tk_workspace.Workspace):
class LQFPWorkspace(tk_edgy.Workspace):
def __init__(self, *args):
super().__init__(*args)

cw = self.chip.width - 2
ch = self.chip.height - 2
w = 2*PIN_WIDTH*cw + PIN_WIDTH
h = 2*PIN_WIDTH*ch + PIN_WIDTH
w = 2*self.pin_width*cw + self.pin_width
h = 2*self.pin_width*ch + self.pin_width

pad = 0
for _, p in self.chip.pins.items():
pad = max(pad, self.label_font.measure(p.name))
pad += PIN_LENGTH + 5 + PIN_LABEL_OFFSET
pad += self.pin_length + 5 + self.pin_label_offset
self.set_geometry(50, 50, w + 2*pad + self.info_width,
max(h + 2*pad, self.info_height))

Expand All @@ -32,80 +27,28 @@ def __init__(self, *args):
r0 = b0 + cw
t0 = r0 + ch
m = c.add_rectangle(pad, pad, w, h, fill=self.elem_fill)
for i, p in self.chip.pins.items():
i = int(i)
for _, p in self.chip.pins.items():
i = int(p.key)
if l0 <= i < b0:
# Left row.
r = c.add_rectangle(
m.x - PIN_LENGTH,
m.y + PIN_WIDTH*(2*(i - l0) + 1),
PIN_LENGTH, PIN_WIDTH, fill=self.elem_fill)
c.add_text(
r.x - PIN_LABEL_OFFSET, r.y + r.height / 2,
font=self.label_font, text=p.name, anchor='e')
c.add_text(
r.x + r.width / 2 + 1, r.y + r.height / 2,
font=self.pin_font, text='%u' % i, anchor='c')
self.pin_elems.append(r)

r = self.add_l_pin(p, m.x - self.pin_length, m.ty, m.by, i - l0)
elif b0 <= i < r0:
# Bottom row.
r = c.add_rectangle(
m.x + PIN_WIDTH*(2*(i - b0) + 1),
m.y + m.height,
PIN_WIDTH, PIN_LENGTH, fill=self.elem_fill)
c.add_text(
r.x + r.width / 2,
r.y + r.height + 1 + PIN_LABEL_OFFSET,
font=self.label_font, text=p.name, anchor='e',
angle=90)
c.add_text(
r.x + r.width / 2, r.y + r.height / 2,
font=self.pin_font, text='%u' % i,
anchor='c', angle=90)
self.pin_elems.append(r)

r = self.add_b_pin(p, m.lx, m.rx, i - b0, m.y + m.height)
elif r0 <= i < t0:
# Right row.
r = c.add_rectangle(
m.x + m.width,
m.y + m.height - PIN_WIDTH*(2*(i - r0) + 2),
PIN_LENGTH, PIN_WIDTH, fill=self.elem_fill)
c.add_text(
r.x + r.width + 1 + PIN_LABEL_OFFSET,
r.y + r.height / 2,
font=self.label_font, text=p.name, anchor='w')
c.add_text(
r.x + r.width / 2, r.y + r.height / 2,
font=self.pin_font, text='%u' % i,
anchor='c')
self.pin_elems.append(r)

r = self.add_r_pin(p, m.x + m.width, m.by, m.ty, i - r0)
else:
# Top row.
r = c.add_rectangle(
m.x + m.width - PIN_WIDTH*(2*(i - t0) + 2),
m.y - PIN_LENGTH,
PIN_WIDTH, PIN_LENGTH, fill=self.elem_fill)
c.add_text(
r.x + r.width / 2, r.y - PIN_LABEL_OFFSET,
font=self.label_font,
text=p.name, anchor='w', angle=90)
c.add_text(
r.x + r.width / 2, r.y + r.height / 2,
font=self.pin_font, text='%u' % i,
anchor='c', angle=90)
self.pin_elems.append(r)
r = self.add_t_pin(p, m.rx, m.lx, i - t0, m.y - self.pin_length)

self.pin_elems.append(r)
r.pin = p

package_name = chip_db.package(self.chip.part)
c.add_text(
m.x + m.width / 2, m.y + m.height / 2,
font=self.label_font,
text='%s\n%s' % (self.chip.name, package_name),
text='%s\n%s\n%s' % (self.chip.name, package_name,
self.max_freq_mhz),
anchor='c')

if 'LQFP' not in package_name:
m.resize(pad - PIN_LENGTH, pad - PIN_LENGTH,
w + 2*PIN_LENGTH, h + 2*PIN_LENGTH)
m.resize(pad - self.pin_length, pad - self.pin_length,
w + 2*self.pin_length, h + 2*self.pin_length)
Loading

0 comments on commit 1c0b0d5

Please sign in to comment.