-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
stm_layout_tk: Add Tkinter-based version of stm_layout.
- Loading branch information
Showing
10 changed files
with
686 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/usr/bin/env python3 | ||
import argparse | ||
import sys | ||
|
||
from stm_layout import chip_db, chip_stm, chip_package | ||
import stm_layout.tk | ||
|
||
|
||
FONT = ('Monaco', 10) | ||
FONT_PIN_NUM = ('Monaco', 9) | ||
FONT_INFO = ('Monaco', 10) | ||
RECT_FILL = 'white' | ||
HILITE_FILL = 'lightblue' | ||
SELECT_FILL = 'yellow' | ||
RE_FILL = 'lightgreen' | ||
|
||
|
||
def main(chip, regex): | ||
if isinstance(chip.chip, chip_package.LQFP): | ||
cls = stm_layout.tk.LQFPWorkspace | ||
elif isinstance(chip.chip, chip_package.BGA): | ||
cls = stm_layout.tk.BGAWorkspace | ||
elif isinstance(chip.chip, chip_package.TSSOP): | ||
cls = stm_layout.tk.TSSOPWorkspace | ||
else: | ||
raise Exception('Unsupported chip package.') | ||
|
||
ws = cls(chip, FONT, FONT_PIN_NUM, FONT_INFO, RECT_FILL, HILITE_FILL, | ||
SELECT_FILL, RE_FILL) | ||
if regex: | ||
ws.set_regex(regex) | ||
|
||
ws.mainloop() | ||
|
||
|
||
def _main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--chip', '-c', required=True) | ||
parser.add_argument('--regex') | ||
rv = parser.parse_args() | ||
|
||
parts = chip_db.find(rv.chip) | ||
if not parts: | ||
print('No devices found for "%s"' % rv.chip) | ||
sys.exit(1) | ||
part = next( (p for p in parts if rv.chip == p.partname), None) | ||
if part is None: | ||
print('Multiple devices found for "%s"' % rv.chip) | ||
for p in parts: | ||
print('%s - %s' % (p, chip_db.package(p))) | ||
sys.exit(1) | ||
else: | ||
chip = chip_stm.make_chip(part) | ||
main(chip, rv.regex) | ||
|
||
|
||
if __name__ == '__main__': | ||
_main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from .tk_bga import BGAWorkspace | ||
from .tk_lqfp import LQFPWorkspace | ||
from .tk_tssop import TSSOPWorkspace | ||
|
||
|
||
__all__ = ['BGAWorkspace', | ||
'LQFPWorkspace', | ||
'TSSOPWorkspace', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
from . import tk_workspace | ||
|
||
|
||
PIN_DIAM = 30 | ||
PIN_SPACE = 22 | ||
PIN_DELTA = (PIN_DIAM + PIN_SPACE) | ||
|
||
|
||
class BGAWorkspace(tk_workspace.Workspace): | ||
def __init__(self, *args): | ||
super().__init__(*args) | ||
|
||
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)) | ||
|
||
c = self.mcu_canvas = self.add_canvas(w + 2*pad, h + 2*pad) | ||
self._root.columnconfigure(0, weight=1) | ||
self._root.rowconfigure(0, weight=1) | ||
|
||
m = c.add_rectangle(pad, pad, w, h, fill=self.elem_fill) | ||
for x in range(cw): | ||
for y in range(ch): | ||
p = self.chip.chip.pins[x][y] | ||
if p is None: | ||
continue | ||
|
||
o = c.add_oval( | ||
m.x + PIN_SPACE + x*PIN_DELTA, | ||
m.y + PIN_SPACE + y*PIN_DELTA, | ||
PIN_DIAM, PIN_DIAM, | ||
fill=self.elem_fill) | ||
self.pin_elems.append(o) | ||
c.add_text( | ||
o.x + o.width / 2, o.y + o.height, | ||
font=self.label_font, text=p.name, anchor='n') | ||
c.add_text( | ||
o.x + o.width / 2 + 1, o.y + o.height / 2, | ||
font=self.pin_font, text=p.key, anchor='c') | ||
o.pin = p |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import tkinter | ||
|
||
|
||
class Elem: | ||
def __init__(self, elem_id): | ||
self._elem_id = elem_id | ||
|
||
|
||
class CanvasElem(Elem): | ||
def __init__(self, canvas, elem_id, x, y, width=None, height=None): | ||
super().__init__(elem_id) | ||
self._canvas = canvas | ||
self.x = x | ||
self.y = y | ||
if width is not None: | ||
self.width = width | ||
if height is not None: | ||
self.height = height | ||
|
||
def bbox(self): | ||
return self._canvas._bbox(self) | ||
|
||
def tag_lower(self, bottom_elem): | ||
self._canvas._tag_lower(self, bottom_elem) | ||
|
||
def set_fill(self, fill): | ||
self._canvas._set_fill(self, fill) | ||
|
||
def contains(self, x, y): | ||
w = getattr(self, 'width', 0) | ||
h = getattr(self, 'height', 0) | ||
return self.x <= x <= self.x + w and self.y <= y <= self.y + h | ||
|
||
def distance_squared(self, x, y): | ||
cx = self.x + getattr(self, 'width', 0) / 2 | ||
cy = self.y + getattr(self, 'height', 0) / 2 | ||
dx = (x - cx) | ||
dy = (y - cy) | ||
return dx*dx + dy*dy | ||
|
||
def move_to(self, x, y): | ||
self.x = x | ||
self.y = y | ||
if self.height is not None: | ||
self._canvas._move_to(self, x, y, x + self.width, y + self.height) | ||
else: | ||
self._canvas._move_to(self, x, y) | ||
|
||
def resize(self, x, y, width, height): | ||
assert self.width is not None | ||
assert self.height is not None | ||
self.x = x | ||
self.y = y | ||
self.width = width | ||
self.height = height | ||
self._canvas._move_to(self, x, y, width, height) | ||
|
||
|
||
class TextElem(CanvasElem): | ||
def set_text(self, text): | ||
self._canvas._set_text(self, text) | ||
|
||
|
||
class Widget: | ||
def __init__(self, widget): | ||
self._widget = widget | ||
|
||
|
||
class Entry(Widget): | ||
def focus_set(self): | ||
self._widget.focus_set() | ||
|
||
|
||
class Canvas: | ||
def __init__(self, canvas): | ||
self._canvas = canvas | ||
|
||
def _bbox(self, elem): | ||
return self._canvas.bbox(elem._elem_id) | ||
|
||
def _tag_lower(self, bottom_elem, top_elem): | ||
self._canvas.tag_lower(bottom_elem._elem_id, top_elem._elem_id) | ||
|
||
def _set_fill(self, elem, fill): | ||
self._canvas.itemconfig(elem._elem_id, fill=fill) | ||
|
||
def _move_to(self, elem, *args): | ||
self._canvas.coords(elem._elem_id, *args) | ||
|
||
def _set_text(self, elem, text): | ||
self._canvas.itemconfig(elem._elem_id, text=text) | ||
|
||
def add_rectangle(self, x, y, width, height, **kwargs): | ||
elem_id = self._canvas.create_rectangle( | ||
(x, y, x + width, y + height), **kwargs) | ||
return CanvasElem(self, elem_id, x, y, width=width, height=height) | ||
|
||
def add_oval(self, x, y, width, height, **kwargs): | ||
elem_id = self._canvas.create_oval( | ||
(x, y, x + width, y + height), **kwargs) | ||
return CanvasElem(self, elem_id, x, y, width=width, height=height) | ||
|
||
def add_text(self, x, y, **kwargs): | ||
elem_id = self._canvas.create_text((x, y), **kwargs) | ||
return TextElem(self, elem_id, x, y) | ||
|
||
def add_window(self, x, y, widget, **kwargs): | ||
self._canvas.create_window(x, y, window=widget._widget, **kwargs) | ||
|
||
def add_entry(self, **kwargs): | ||
return Entry(tkinter.Entry(self._canvas, **kwargs)) | ||
|
||
|
||
class TKBase: | ||
def __init__(self): | ||
self._root = tkinter.Tk() | ||
|
||
def set_geometry(self, x, y, width, height): | ||
self._root.geometry('%ux%u+%u+%u' % (width, height, x, y)) | ||
|
||
def mainloop(self): | ||
self._root.mainloop() | ||
|
||
def add_canvas(self, width, height, column=0, row=0, sticky=None): | ||
c = tkinter.Canvas(self._root, bd=0, highlightthickness=0, width=width, | ||
height=height) | ||
c.grid(column=column, row=row, sticky=sticky) | ||
return Canvas(c) | ||
|
||
def register_handler(self, event_type, handler): | ||
self._root.bind(event_type, lambda e: handler(self, e, e.x, e.y)) | ||
|
||
def register_mouse_moved(self, handler): | ||
self.register_handler('<Motion>', handler) | ||
|
||
def register_mouse_down(self, handler): | ||
self.register_handler('<Button-1>', handler) | ||
|
||
def register_mouse_up(self, handler): | ||
self.register_handler('<ButtonRelease-1>', handler) |
Oops, something went wrong.