From 0b986eeb0c23610028d39de75b3352e199f3d806 Mon Sep 17 00:00:00 2001 From: caleb crome Date: Thu, 2 Mar 2023 15:14:50 +0100 Subject: [PATCH] TrayLayout: Make generation a one step operation in the web UI Add Java Script for generating the layout from sx and sy Drop special handling in boxesserver Add .UI attribute to Boxes class to allow behaving differntly on different UIs Traylayout is still filtered out from Inkscape INX file generation Slightly adjust layout format of GridfinityTrayLayout Co-authored-by: Florian Festi --- boxes/__init__.py | 1 + boxes/generators/gridfinitytraylayout.py | 4 +- boxes/generators/traylayout.py | 22 +++--- scripts/boxesserver | 21 +----- static/self.js | 96 +++++++++++++++++++++++- 5 files changed, 108 insertions(+), 36 deletions(-) diff --git a/boxes/__init__.py b/boxes/__init__.py index 9b79b59..7d400a6 100755 --- a/boxes/__init__.py +++ b/boxes/__init__.py @@ -285,6 +285,7 @@ class Boxes: webinterface = True ui_group = "Misc" + UI = "" description: str = "" # Markdown syntax is supported diff --git a/boxes/generators/gridfinitytraylayout.py b/boxes/generators/gridfinitytraylayout.py index 883bc6d..d0a2253 100644 --- a/boxes/generators/gridfinitytraylayout.py +++ b/boxes/generators/gridfinitytraylayout.py @@ -1,10 +1,10 @@ import boxes from boxes import Boxes -from boxes.generators.traylayout import TrayLayout, TrayLayout2 +from boxes.generators.traylayout import TrayLayout from boxes.Color import Color from boxes import restore -class GridfinityTrayLayout(TrayLayout2): +class GridfinityTrayLayout(TrayLayout): """A Gridfinity Tray Generator based on TrayLayout""" description = """ diff --git a/boxes/generators/traylayout.py b/boxes/generators/traylayout.py index 02b96db..b119456 100644 --- a/boxes/generators/traylayout.py +++ b/boxes/generators/traylayout.py @@ -19,7 +19,7 @@ import boxes from boxes import * -class TrayLayout(Boxes): +class TrayLayoutFile(Boxes): """Generate a layout file for a typetray.""" # This class generates the skeleton text file that can then be edited # to describe the actual box @@ -29,7 +29,7 @@ The layout is based on a grid of sizes in x and y direction. Choose how many distances you need in both directions. The actual sizes and all other settings can be entered in the second step.""" - webinterface = True + webinterface = False ui_group = "Tray" @@ -83,13 +83,13 @@ The actual sizes and all other settings can be entered in the second step.""" f.write(str(self)) -class TrayLayout2(Boxes): +class TrayLayout(Boxes): """Generate a typetray from a layout file.""" # This class reads in the layout either from a file (with --input) or # as string (with --layout) and turns it into a drawing for a box. - webinterface = True + ui_group = "Tray" description = """This is a two step process. This is step 2. Edit the layout text graphics to adjust your tray. @@ -98,19 +98,19 @@ vertical bars representing the walls with a space character to remove the walls. You can replace the space characters representing the floor by a "X" to remove the floor for this compartment. """ - def __init__(self, input=None, webargs=False) -> None: - Boxes.__init__(self) + def __init__(self) -> None: + super().__init__() self.addSettingsArgs(boxes.edges.FingerJointSettings) - self.buildArgParser("h", "hi", "outside") - if not webargs: + self.buildArgParser("h", "hi", "outside", "sx", "sy") + if self.UI == "web": + self.argparser.add_argument( + "--layout", action="store", type=str, default="") + else: self.argparser.add_argument( "--input", action="store", type=argparse.FileType('r'), default="traylayout.txt", help="layout file") self.layout = None - else: - self.argparser.add_argument( - "--layout", action="store", type=str, default="") def vWalls(self, x: int, y: int) -> int: """Number of vertical walls at a crossing.""" diff --git a/scripts/boxesserver b/scripts/boxesserver index e066cea..b43b7d0 100755 --- a/scripts/boxesserver +++ b/scripts/boxesserver @@ -113,11 +113,11 @@ class BServer: def __init__(self, url_prefix="", static_url="static") -> None: self.boxes = {b.__name__: b for b in boxes.generators.getAllBoxGenerators().values() if b.webinterface} - self.boxes['TrayLayout2'] = boxes.generators.traylayout.TrayLayout2 # type: ignore # no attribute "traylayout" self.groups = boxes.generators.ui_groups self.groups_by_name = boxes.generators.ui_groups_by_name for name, box in self.boxes.items(): + box.UI = "web" self.groups_by_name.get(box.ui_group, self.groups_by_name["Misc"]).add(box) @@ -351,8 +351,6 @@ class BServer:
\n
    \n''') for box in group.generators: name = box.__name__ - if name in ("TrayLayout2",): - continue docs = "" if box.__doc__: docs = " - " + _(box.__doc__) @@ -595,10 +593,7 @@ class BServer: self._cache[lang_name] = list(self.genPageMenu(lang)) return self._cache[lang_name] - if name == "TrayLayout2": - box = box_cls(self, webargs=True) - else: - box = box_cls() + box = box_cls() box.translations = lang @@ -618,18 +613,6 @@ class BServer: except ArgumentParserError as e: start_response(status, headers) return self.genPageError(name, e, lang) - if name == "TrayLayout": - start_response(status, headers) - box.fillDefault(box.sx, box.sy) - layout2 = boxes.generators.traylayout.TrayLayout2(self, webargs=True) - layout2.argparser.set_defaults(layout=str(box)) - return self.args2html(name, layout2, lang, action="TrayLayout2") - if name == "TrayLayout2": - try: - box.parse(box.layout.split("\n")) - except Exception as e: - start_response(status, headers) - return self.genPageError(name, e, lang) try: fd, box.output = tempfile.mkstemp() diff --git a/static/self.js b/static/self.js index dded00d..30719ab 100644 --- a/static/self.js +++ b/static/self.js @@ -108,7 +108,7 @@ function GridfinityTrayLayout_GenerateLayout(x, y, nx, ny, countx, county) { } for (i = 0; i < county; i++) { layout += "+-".repeat(countx) + "+\n"; - layout += "| ".repeat(countx) + `|${stepy}mm\n`; + layout += "| ".repeat(countx) + `| ${stepy}mm\n`; } layout += "+-".repeat(countx) + "+\n"; return layout @@ -157,16 +157,104 @@ function GridfinityTrayLayoutInit() { layout_id.rows = 20; layout_id.cols = 24; } + +function ParseSections(s) { + var sections = []; + for (var section of s.split(":")) { + var operands = section.split("/"); + if (operands.length > 2) return sections; + if (operands.length == 2) { + for (var i=0; i 2) return sections; + if (operands.length == 2) { + for (var i=0; i ${sx[i].toFixed(2)}mm\n`; + layout += line; + } + for (i = 0; i < ny; i++) { + layout += "+-".repeat(nx) + "+\n"; + layout += "| ".repeat(nx) + `| ${sy[i].toFixed(2)}mm\n`; + } + layout += "+-".repeat(nx) + "+\n"; + return layout +} + +function TrayUpdateLayout(event) { + if (window.layoutUpdated == true) { + // Don't do the update if the layout has been manually touched. + if (confirm("You have manually updated the Layout. Do you wish to regenerate it?")) { + window.layoutUpdated = false; + } else { + return; + } + } + sx = document.getElementById('sx').value; + sy = document.getElementById('sy').value; + layout_id = document.getElementById('layout'); + layout_id.value = TrayLayout_GenerateLayout(sx, sy); +} + + +function TrayLayoutInit() { + ids = ['sx', 'sy']; + window.layoutUpdated=false; + for (id_string of ids) { + id = document.getElementById(id_string); + id.addEventListener('input', TrayUpdateLayout); + } + TrayUpdateLayout(); + layout_id = document.getElementById('layout'); + layout_id.addEventListener('change', setUpdated); + layout_id.addEventListener('input', setUpdated); + layout_id.rows = 20; + layout_id.cols = 24; +} + function addCallbacks() { - if (window.location.href.includes("/GridfinityTrayLayout")) - GridfinityTrayLayoutInit(); + page_callbacks = { + "TrayLayout": TrayLayoutInit, + "GridfinityTrayLayout": GridfinityTrayLayoutInit, + }; + loc = new URL(window.location.href); + pathname = loc.pathname; + page = pathname.substr(pathname.lastIndexOf('/')+1); + if (page in page_callbacks) { + callback = page_callbacks[page]; + callback(); + } } document.addEventListener('DOMContentLoaded', function() { addCallbacks(); }, false); - function collapseAll() { const h = document.getElementsByClassName("toggle"); for (let el of h) {