diff options
-rw-r--r-- | gerbonara/cad/protoboard.py | 4 | ||||
-rw-r--r-- | gerbonara/cad/protoserve.py | 30 | ||||
-rw-r--r-- | gerbonara/cad/protoserve_data/protoserve.html | 24 |
3 files changed, 46 insertions, 12 deletions
diff --git a/gerbonara/cad/protoboard.py b/gerbonara/cad/protoboard.py index a3d616f..b61a0ed 100644 --- a/gerbonara/cad/protoboard.py +++ b/gerbonara/cad/protoboard.py @@ -116,6 +116,10 @@ class PropLayout: return [ unit(leftover * (value or 1.0) / sum_props if not isinstance(value, str) else calculated, MM) for value, calculated in zip(self.proportions, out) ] + @property + def single_sided(self): + return all(elem.single_sided for elem in self.content) + def __str__(self): children = ', '.join( f'{elem}:{width}' for elem, width in zip(self.content, self.proportions)) return f'PropLayout[{self.direction.upper()}]({children})' diff --git a/gerbonara/cad/protoserve.py b/gerbonara/cad/protoserve.py index b594196..a210e91 100644 --- a/gerbonara/cad/protoserve.py +++ b/gerbonara/cad/protoserve.py @@ -41,12 +41,21 @@ def deserialize(obj, unit): pitch_y = float(obj.get('pitch_y', 1.27)) clearance = float(obj.get('clearance', 0.2)) + mil = lambda x: x/1000 if unit == Inch else x + match obj['type']: case 'layout': + if not obj.get('children'): + return pb.EmptyProtoArea() + proportions = [float(child['layout_prop']) for child in obj['children']] content = [deserialize(child, unit) for child in obj['children']] return pb.PropLayout(content, obj['direction'], proportions) + case 'twoside': + top, bottom = obj['children'] + return pb.TwoSideLayout(deserialize(top, unit), deserialize(bottom, unit)) + case 'placeholder': return pb.EmptyProtoArea() @@ -59,7 +68,7 @@ def deserialize(obj, unit): return pb.PatternProtoArea(pitch_x, pitch_y, obj=pad, unit=unit) case 'tht': - hole_dia = float(obj['hole_dia']) + hole_dia = mil(float(obj['hole_dia'])) match obj['plating']: case 'plated': oneside, plated = False, True @@ -85,16 +94,16 @@ def deserialize(obj, unit): return pb.PatternProtoArea(pitch_x, pitch_y, obj=pb.ManhattanPads(pitch_x, pitch_y, clearance, unit=unit), unit=unit) case 'powered': - pitch = float(obj.get('pitch', 2.54)) - hole_dia = float(obj['hole_dia']) - via_drill = float(obj['via_hole_dia']) - trace_width = float(obj['trace_width']) + pitch = mil(float(obj.get('pitch', 2.54))) + hole_dia = mil(float(obj['hole_dia'])) + via_drill = mil(float(obj['via_hole_dia'])) + trace_width = mil(float(obj['trace_width'])) return pb.PatternProtoArea(pitch, pitch, pb.PoweredProto(pitch, hole_dia, clearance, via_size=via_drill, trace_width=trace_width, unit=unit), unit=unit) case 'flower': - pitch = float(obj.get('pitch', 2.54)) - hole_dia = float(obj['hole_dia']) - pattern_dia = float(obj['pattern_dia']) + pitch = mil(float(obj.get('pitch', 2.54))) + hole_dia = mil(float(obj['hole_dia'])) + pattern_dia = mil(float(obj['pattern_dia'])) return pb.PatternProtoArea(2*pitch, 2*pitch, pb.THTFlowerProto(pitch, hole_dia, pattern_dia, unit=unit), unit=unit) case 'rf': @@ -113,7 +122,10 @@ def to_board(obj): mounting_hole_dia = float(holes.get('diameter', unit(3.2, MM))) mounting_hole_offset = float(holes.get('offset', unit(5, MM))) - content = deserialize(obj['children'][0], unit) + if obj.get('children'): + content = deserialize(obj['children'][0], unit) + else: + content = [pb.EmptyProtoArea()] return pb.ProtoBoard(w, h, content, corner_radius=corner_radius, diff --git a/gerbonara/cad/protoserve_data/protoserve.html b/gerbonara/cad/protoserve_data/protoserve.html index 7bc9a30..3afeb5c 100644 --- a/gerbonara/cad/protoserve_data/protoserve.html +++ b/gerbonara/cad/protoserve_data/protoserve.html @@ -15,6 +15,7 @@ html, body { margin: 0; width: 100%; height: 100%; + font-family: Helvetica, Segoe UI, Sans-Serif; } body { @@ -161,6 +162,7 @@ input { #preview { grid-area: main; + padding: 20px; } #preview-image { @@ -171,6 +173,18 @@ input { #links { grid-area: links; + display: flex; + justify-content: center; + padding: 5px; +} + +#link-gerbers { + background-color: #0d6efd; + color: white; + font-weight: bold; + box-shadow: 0px 0px 1px 1px hsl(0, 0%, 0% / 20%); + border-radius: .5em; + padding: 1em 2em 1em 2em; } .layout-area { @@ -203,6 +217,10 @@ input { color: hsl(0 0% 60%); } +.narrow-only { + display: none; +} + </style> </head> <body> @@ -266,8 +284,8 @@ input { <img id="preview-image" alt="Automatically generated preview image"/> </div> <div id="links"> - <a href="#controls">Settings</a> - <a href="#preview">Preview</a> + <a class="narrow-only" href="#controls">Settings</a> + <a class="narrow-only" href="#preview">Preview</a> <a id="link-gerbers" href='#'> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="1em"> <title>Download</title> @@ -313,7 +331,7 @@ input { </template> <template id="tpl-g-twoside"> - <div class="group split-sides"> + <div data-type='twoside' class="group split-sides"> <h4>Split front and back</h4> <span class="content area-controls">(<a href="#" class="area-remove">Remove</a><a href="#" class="area-move">Move</a>)</span> <label class="proportion">Proportion |