From 8608508e0237b06bea5aac7558c695fd7bc8492b Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Tue, 24 Apr 2018 00:22:45 -0400 Subject: [PATCH] allow selection of a different thread palette --- embroider_print.py | 34 ++++++++++++++++++++++++++++++-- inkstitch/extensions.py | 4 ++-- inkstitch/threads/catalog.py | 11 +++++++++-- print/resources/inkstitch.js | 38 ++++++++++++++++++++++++------------ 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/embroider_print.py b/embroider_print.py index 43efa7584..ee9193a87 100644 --- a/embroider_print.py +++ b/embroider_print.py @@ -99,6 +99,7 @@ class PrintPreviewServer(Thread): def __init__(self, *args, **kwargs): self.html = kwargs.pop('html') self.metadata = kwargs.pop('metadata') + self.stitch_plan = kwargs.pop('stitch_plan') Thread.__init__(self, *args, **kwargs) self.daemon = True self.last_request_time = None @@ -178,6 +179,35 @@ class PrintPreviewServer(Thread): save_defaults(request.json['value']) return "OK" + @self.app.route('/palette', methods=['POST']) + def set_palette(): + name = request.json['name'] + catalog = ThreadCatalog() + palette = catalog.get_palette_by_name(name) + catalog.apply_palette(self.stitch_plan, palette) + + # clear any saved color or thread names + for field in self.metadata: + if field.startswith('color-') or field.startswith('thread-'): + del self.metadata[field] + + self.metadata['thread-palette'] = name + + return "OK" + + @self.app.route('/threads', methods=['GET']) + def get_threads(): + threads = [] + for color_block in self.stitch_plan: + threads.append({ + 'hex': color_block.color.hex_digits, + 'name': color_block.color.name, + 'manufacturer': color_block.color.manufacturer, + 'number': color_block.color.number, + }) + + return jsonify(threads) + def stop(self): # for whatever reason, shutting down only seems possible in # the context of a flask request, so we'll just make one @@ -291,7 +321,7 @@ class Print(InkstitchExtension): patches = self.elements_to_patches(self.elements) stitch_plan = patches_to_stitch_plan(patches) - palette = ThreadCatalog().match_and_apply_palette(stitch_plan) + palette = ThreadCatalog().match_and_apply_palette(stitch_plan, self.get_inkstitch_metadata()['thread-palette']) render_stitch_plan(self.document.getroot(), stitch_plan) self.strip_namespaces() @@ -354,7 +384,7 @@ class Print(InkstitchExtension): # metadata into it. self.document = deepcopy(self.original_document) - print_server = PrintPreviewServer(html=html, metadata=self.get_inkstitch_metadata()) + print_server = PrintPreviewServer(html=html, metadata=self.get_inkstitch_metadata(), stitch_plan=stitch_plan) print_server.start() time.sleep(1) diff --git a/inkstitch/extensions.py b/inkstitch/extensions.py index 5befec9fa..c02cc5792 100644 --- a/inkstitch/extensions.py +++ b/inkstitch/extensions.py @@ -75,11 +75,11 @@ class InkStitchMetadata(MutableMapping): try: return json.loads(item.text) - except ValueError: + except (ValueError, TypeError): return None def __delitem__(self, name): - item = self[name] + item = self._find_item(name) if item: self.metadata.remove(item) diff --git a/inkstitch/threads/catalog.py b/inkstitch/threads/catalog.py index db50e6784..6ff09674c 100644 --- a/inkstitch/threads/catalog.py +++ b/inkstitch/threads/catalog.py @@ -38,8 +38,11 @@ class _ThreadCatalog(Sequence): return sum(1 for thread in threads if thread in palette) - def match_and_apply_palette(self, stitch_plan): - palette = self.match_palette(stitch_plan) + def match_and_apply_palette(self, stitch_plan, palette=None): + if palette is None: + palette = self.match_palette(stitch_plan) + else: + palette = self.get_palette_by_name(palette) if palette is not None: self.apply_palette(stitch_plan, palette) @@ -75,6 +78,10 @@ class _ThreadCatalog(Sequence): color_block.color.number = nearest.number color_block.color.manufacturer = nearest.manufacturer + def get_palette_by_name(self, name): + for palette in self: + if palette.name == name: + return palette _catalog = None diff --git a/print/resources/inkstitch.js b/print/resources/inkstitch.js index 60d17f61c..daa2cf4bb 100644 --- a/print/resources/inkstitch.js +++ b/print/resources/inkstitch.js @@ -178,11 +178,11 @@ $(function() { $('[data-field-name="' + field_name + '"]').each(function(i, item) { var item = $(item); if (item.is(':checkbox')) { - item.prop('checked', value).trigger('change'); + item.prop('checked', value).trigger('initialize'); } else if (item.is('img')) { item.attr('src', value); } else if (item.is('select')) { - item.val(value).trigger('change'); + item.val(value).trigger('initialize'); } else if (item.is('figure.inksimulation')) { setSVGTransform(item, value); } else { @@ -249,10 +249,10 @@ $(function() { /* Settings */ // Paper Size - $('select#printing-size').change(function(){ - var size = $(this).find(':selected').val(); - $('.page').toggleClass('a4', size == 'a4'); - $.postJSON('/settings/paper-size', {value: size}); + $('select#printing-size').on('change initialize', function(){ + $('.page').toggleClass('a4', $(this).find(':selected').val() == 'a4'); + }).on('change', function() { + $.postJSON('/settings/paper-size', {value: $(this).find(':selected').val()}); }); // Thread Palette @@ -260,13 +260,26 @@ $(function() { $('.modal').show(); }).on('update', function() { $(this).data('current-value', $(this).find(':selected').val()); - console.log("selected: " + $(this).data('current-value')); }).trigger('update'); $('#modal-yes').on('click', function(){ - // do shit with the newly-selected palette... $("select#thread-palette").trigger("update"); $('.modal').hide(); + var body = {'name': $('select#thread-palette').find(':selected').val()}; + $.postJSON('/palette', body, function() { + $.getJSON('/threads', function(threads) { + console.log("threads: " + JSON.stringify(threads)); + $.each(threads, function(i, thread) { + console.log("doing: " + JSON.stringify(thread)); + $('[data-field-name="color-' + thread.hex + '"]').text(thread.name); + var thread_description = thread.manufacturer; + if (thread.number) { + thread_description += " #" + thread.number; + } + $('[data-field-name="thread-' + thread.hex + '"]').text(thread_description); + }); + }); + }); }); $('#modal-no').on('click', function(){ @@ -276,14 +289,13 @@ $(function() { }); //Checkbox - $(':checkbox').change(function() { - var checked = $(this).prop('checked'); + $(':checkbox').on('change initialize', function() { var field_name = $(this).attr('data-field-name'); - $('.' + field_name).toggle(checked); + $('.' + field_name).toggle($(this).prop('checked')); setPageNumbers(); - - $.postJSON('/settings/' + field_name, {value: checked}); + }).on('change', function() { + $.postJSON('/settings/' + field_name, {value: $(this).prop('checked')}); }); // Logo