From f30dba6728faf9c3ce8ad948a8ef5af6dfb83a95 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Fri, 8 Mar 2019 19:55:13 -0500 Subject: don't do density compensation in underlay --- lib/elements/satin_column.py | 83 +++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 40 deletions(-) (limited to 'lib') diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index 4dea0534..bfa39384 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -590,7 +590,7 @@ class SatinColumn(EmbroideryElement): return spacings, paths - def plot_points_on_rails(self, spacing, offset): + def plot_points_on_rails(self, spacing, offset, compensation=True): # Take a section from each rail in turn, and plot out an equal number # of points on both rails. Return the points plotted. The points will # be contracted or expanded by offset using self.offset_points(). @@ -625,43 +625,44 @@ class SatinColumn(EmbroideryElement): pos0, index0 = self.walk(paths[0], pos0, index0, spacing0) pos1, index1 = self.walk(paths[1], pos1, index1, spacing1) - try: - # Adjust for rails that contract or expand from each other. - # Without any compensation, rail sections that spread out or come - # together are longer than parallel rails, and we'll plot stitches - # too densely as a result. We can compensate by using some trig, - # as described here: - # - # https://github.com/inkstitch/inkstitch/issues/379#issuecomment-467262685 - stitch_direction = (pos1 - pos0).unit() - peak_to_peak0 = pos0 - old_pos0 - peak_to_peak1 = pos1 - old_pos1 - - # The dot product of two unit vectors is the cosine of the angle - # between them. We want the cosine of the angle minus 90 degrees, - # so we rotate left by 90 degrees first. - # - # We take the absolute value to correct for the different direction - # of the angles on the opposing rails. - cos1 = abs(peak_to_peak0.unit() * stitch_direction.rotate_left()) - cos2 = abs(peak_to_peak1.unit() * stitch_direction.rotate_left()) - - # Use the smaller of the two angles to avoid spacing out - # too far on the other rail. Note that the cosine of 0 - # is 1, so we use min here to mean a bigger angle. - cos = min(cos1, cos2) - - # Beyond 0.55 (about 56 degrees), we end up distorting the - # stitching and it looks bad. - cos = max(cos, 0.55) - - pos0, index0 = self.walk(paths[0], pos0, index0, spacing0 / cos - spacing0) - pos1, index1 = self.walk(paths[1], pos1, index1, spacing1 / cos - spacing1) - except ZeroDivisionError: - # These can occur in unit() if the vector has a length of zero, - # which can happen in certain cases. We'll just skip the - # compensation. - continue + if compensation: + try: + # Adjust for rails that contract or expand from each other. + # Without any compensation, rail sections that spread out or come + # together are longer than parallel rails, and we'll plot stitches + # too densely as a result. We can compensate by using some trig, + # as described here: + # + # https://github.com/inkstitch/inkstitch/issues/379#issuecomment-467262685 + stitch_direction = (pos1 - pos0).unit() + peak_to_peak0 = pos0 - old_pos0 + peak_to_peak1 = pos1 - old_pos1 + + # The dot product of two unit vectors is the cosine of the angle + # between them. We want the cosine of the angle minus 90 degrees, + # so we rotate left by 90 degrees first. + # + # We take the absolute value to correct for the different direction + # of the angles on the opposing rails. + cos1 = abs(peak_to_peak0.unit() * stitch_direction.rotate_left()) + cos2 = abs(peak_to_peak1.unit() * stitch_direction.rotate_left()) + + # Use the smaller of the two angles to avoid spacing out + # too far on the other rail. Note that the cosine of 0 + # is 1, so we use min here to mean a bigger angle. + cos = min(cos1, cos2) + + # Beyond 0.55 (about 56 degrees), we end up distorting the + # stitching and it looks bad. + cos = max(cos, 0.55) + + pos0, index0 = self.walk(paths[0], pos0, index0, spacing0 / cos - spacing0) + pos1, index1 = self.walk(paths[1], pos1, index1, spacing1 / cos - spacing1) + except ZeroDivisionError: + # These can occur in unit() if the vector has a length of zero, + # which can happen in certain cases. We'll just skip the + # compensation. + continue # We're off by one in the algorithm above, so we need one more # pair of points. We'd like to add points at the very end to @@ -678,7 +679,8 @@ class SatinColumn(EmbroideryElement): # "contour walk" underlay: do stitches up one side and down the # other. forward, back = self.plot_points_on_rails(self.contour_underlay_stitch_length, - -self.contour_underlay_inset) + -self.contour_underlay_inset, + compensation=False) return Patch(color=self.color, stitches=(forward + list(reversed(back)))) def do_center_walk(self): @@ -687,7 +689,8 @@ class SatinColumn(EmbroideryElement): # Do it like contour underlay, but inset all the way to the center. forward, back = self.plot_points_on_rails(self.center_walk_underlay_stitch_length, - -100000) + -100000, + compensation=False) return Patch(color=self.color, stitches=(forward + list(reversed(back)))) def do_zigzag_underlay(self): -- cgit v1.3.1 From f435520663d59378546426ea7263e78d51362c44 Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Tue, 26 Mar 2019 18:24:02 +0100 Subject: Add Custom Page to Print PDF (#418) --- lib/extensions/print_pdf.py | 8 +- print/resources/inkstitch-logo.svg | 125 ++++++++++++++++++------ print/resources/inkstitch.js | 170 +++++++++++++++++++-------------- print/resources/style.css | 139 ++++++++++++++++----------- print/templates/custom-page.html | 40 ++++++++ print/templates/index.html | 19 ++-- print/templates/operator_overview.html | 2 +- print/templates/ui.html | 67 ++++++++----- 8 files changed, 378 insertions(+), 192 deletions(-) create mode 100644 print/templates/custom-page.html (limited to 'lib') diff --git a/lib/extensions/print_pdf.py b/lib/extensions/print_pdf.py index c718fa09..4913a32a 100644 --- a/lib/extensions/print_pdf.py +++ b/lib/extensions/print_pdf.py @@ -353,7 +353,13 @@ class Print(InkstitchExtension): template = env.get_template('index.html') return template.render( - view={'client_overview': False, 'client_detailedview': False, 'operator_overview': True, 'operator_detailedview': True}, + view={ + 'client_overview': False, + 'client_detailedview': False, + 'operator_overview': True, + 'operator_detailedview': True, + 'custom_page': False + }, logo={'src': '', 'title': 'LOGO'}, date=date.today(), client="", diff --git a/print/resources/inkstitch-logo.svg b/print/resources/inkstitch-logo.svg index d9a298cf..138318b9 100644 --- a/print/resources/inkstitch-logo.svg +++ b/print/resources/inkstitch-logo.svg @@ -1,27 +1,98 @@ - - - - - - - - - - - - - - - - - + + + +image/svg+xml + + + + + + + + + + + + + \ No newline at end of file diff --git a/print/resources/inkstitch.js b/print/resources/inkstitch.js index ac8c72b4..79c6d9c3 100644 --- a/print/resources/inkstitch.js +++ b/print/resources/inkstitch.js @@ -285,7 +285,7 @@ $(function() { /* Contendeditable Fields */ - $('body').on('focusout', '[contenteditable="true"]:not(.footer-info)', function() { + $('body').on('focusout', '[contenteditable="true"]:not(.info-text)', function() { /* change svg scale */ var content = $(this).text(); var field_name = $(this).attr('data-field-name'); @@ -326,6 +326,8 @@ $(function() { } else if (item.is('div.footer-info')) { $('#footer-info-text').html(value); item.html(value); + } else if (item.is('#custom-page-content')) { + $('#custom-page-content').html(value); } else { item.text(value); } @@ -339,7 +341,7 @@ $(function() { }, 500); }); - $('body').on('keypress', '[contenteditable="true"]:not(#footer-info-text)', function(e) { + $('body').on('keypress', '[contenteditable="true"]:not(.info-text)', function(e) { if (e.which == 13) { // pressing enter defocuses the element this.blur(); @@ -360,8 +362,8 @@ $(function() { } }); - $('#footer-info-text[contenteditable="true"]').focusout(function() { - updateFooter(); + $('.info-text[contenteditable="true"]').focusout(function() { + updateEditableText($(this)); }); /* Settings Bar */ @@ -415,119 +417,142 @@ $(function() { }); // Footer - function getEditMode(){ - return $('#switch-mode').prop('checked'); + function getEditMode(element){ + return element.closest('fieldset').find('.switch-mode').prop('checked'); } - $('#switch-mode').change(function() { - var editMode = getEditMode(); + $('.switch-mode').change(function() { + var element = $(this); + var info_text = element.closest('fieldset').find('.info-text'); + var editMode = getEditMode(element); if (editMode) { - $('#footer-info-text').text( $('#footer-info-text' ).html()); - $('#tool-bar .edit-only').prop("disabled", true); + info_text.text( info_text.html() ); + element.closest('.tool-bar').find('.tb-button.edit-only').prop("disabled", true); } else { - $('#footer-info-text').css('display', 'block'); - var sourceText = $('#footer-info-text').text(); - $('#footer-info-text').html( sourceText ); - $('#tool-bar .tb-button.edit-only').prop('disabled', false); + info_text.css('display', 'block'); + var sourceText = info_text.text(); + info_text.html( sourceText ); + element.closest('.tool-bar').find('.tb-button.edit-only').prop('disabled', false); } }); - function updateFooter() { - var editMode = getEditMode(); - var footerText = ''; + function updateEditableText(element) { + var editMode = getEditMode(element); + var info_text = element.closest('fieldset').find('.info-text'); + var content = info_text.html(); + var editableText = ''; + if (editMode) { - footerText = $('#footer-info-text' ).text(); + editableText = info_text.text(); + } else { + editableText = info_text.html(); + } + + if(info_text.is('#footer-info-text')) { + $('div.footer-info').html(editableText); + $.postJSON('/settings/footer-info', {value: content}); } else { - footerText = $('#footer-info-text').html(); + $.postJSON('/settings/custom-page-content', {value: content}); } - $('.footer-info').html(footerText); - var content = $('.footer-info').html(); - $.postJSON('/settings/footer-info', {value: content}); } function formatText(selection, value) { - var htmlMode = getEditMode(); - if(!htmlMode) { if(window.getSelection().toString()){ document.execCommand(selection, false, value); - updateFooter(); } - } } - $('#tb-bold').click(function(selection) { - formatText('bold'); + $('.tb-bold').click(function() { + if(!getEditMode($(this))) { + formatText('bold'); + updateEditableText($(this)); + } }); - $('#tb-italic').click(function() { - formatText('italic'); + $('.tb-italic').click(function() { + if(!getEditMode($(this))) { + formatText('italic'); + updateEditableText($(this)); + } }); - $('#tb-underline').click(function() { - formatText('underline'); + $('.tb-underline').click(function() { + if(!getEditMode($(this))) { + formatText('underline'); + updateEditableText($(this)); + } }); - $('#tb-remove').click(function() { - formatText('removeFormat'); + $('.tb-remove').click(function() { + if(!getEditMode($(this))) { + formatText('removeFormat'); + updateEditableText($(this)); + } }); - $('#tb-hyperlink').click(function() { - formatText('createlink', 'tempurl'); - $('#footer-url').css('display', 'block'); + $('.tb-hyperlink').click(function() { + if(!getEditMode($(this))) { + formatText('createlink', 'tempurl'); + updateEditableText($(this)); + $(this).closest('.tool-bar').children('.url-window').css('display', 'block'); + } }); - $('#url-ok').click(function() { - var link = $('#footer-link').val(); - $('#footer-info-text a[href="tempurl"]').attr('href', link); - $('#footer-link').val('https://'); - $('#footer-url').css('display', 'none'); - updateFooter(); + $('.url-ok').click(function() { + var link = $(this).closest('.tool-bar').find('.user-url').val(); + $(this).closest('fieldset').find('.info-text').find('a[href="tempurl"]').attr('href', link); + $('.user-url').val('https://'); + $('.url-window').css('display', 'none'); + updateEditableText($(this)); }); - $('#url-cancel').click(function() { - $('#footer-info-text a[href="tempurl"]').contents().unwrap(); - $('#footer-link').val('https://'); - $('#footer-url').css('display', 'none'); - updateFooter(); + $('.url-cancel').click(function() { + $(this).closest('fieldset').find('.info-text').find('a[href="tempurl"]').contents().unwrap(); + $('.user-url').val('https://'); + $('.url-window').css('display', 'none'); + updateEditableText($(this)); }); - $('#tb-mail').click(function() { - formatText('createlink', 'tempurl'); - $('#footer-email').css('display', 'block'); + $('.tb-mail').click(function() { + if(!getEditMode($(this))) { + formatText('createlink', 'tempurl'); + updateEditableText($(this)); + $(this).closest('.tool-bar').find('.mail-window').css('display', 'block'); + } }); - $('#mail-ok').click(function() { - var link = 'mailto:' + $('#footer-mail').val(); - $('#footer-info-text a[href="tempurl"]').attr('href', link); - $('#footer-mail').val('@'); - $('#footer-email').css('display', 'none'); - updateFooter(); + $('.mail-ok').click(function() { + var link = 'mailto:' + $(this).closest('.tool-bar').find('.user-mail').val(); + $(this).closest('fieldset').find('.info-text').find('a[href="tempurl"]').attr('href', link); + $('.user-mail').val('@'); + $('.mail-window').css('display', 'none'); + updateEditableText($(this)); }); - $('#mail-cancel').click(function() { - $('#footer-info-text a[href="tempurl"]').contents().unwrap(); - $('#footer-mail').val('@'); - $('#footer-email').css('display', 'none'); - updateFooter(); + $('.mail-cancel').click(function() { + $(this).closest('fieldset').find('.info-text').find('a[href="tempurl"]').contents().unwrap(); + $('.user-mail').val('@'); + $('.mail-window').css('display', 'none'); + updateEditableText($(this)); }); - $('#tb-reset').click(function() { - $('#footer-reset').css('display', 'block'); + $('.tb-reset').click(function() { + $(this).closest('.tool-bar').find('.reset-window').css('display', 'block'); }); - $('#reset-ok').click(function() { - var htmlMode = getEditMode(); + $('.reset-ok').click(function() { + var htmlMode = getEditMode($(this)); if(!htmlMode) { - $('#footer-info-text').html($('#footer-info-original').html()); + $(this).closest('fieldset').find('.info-text').html($(this).closest('.tool-bar').find('.original-info').html()); } else { - $('#footer-info-text').text($('#footer-info-original').html()); + $(this).closest('fieldset').find('.info-text').text($(this).closest('.tool-bar').find('.original-info').html()); } - $('#footer-reset').css('display', 'none'); - updateFooter(); + $('.reset-window').css('display', 'none'); + updateEditableText($(this)); }); - $('#reset-cancel').click(function() { - $('#footer-reset').css('display', 'none'); + $('.reset-cancel').click(function() { + $('.reset-window').css('display', 'none'); }); $('body').on("click", ".edit-footer-link", function() { @@ -713,6 +738,7 @@ $(function() { settings["operator-overview"] = $("[data-field-name='operator-overview']").is(':checked'); settings["operator-detailedview"] = $("[data-field-name='operator-detailedview']").is(':checked'); settings["operator-detailedview-thumbnail-size"] = $("[data-field-name='operator-detailedview-thumbnail-size']").val(); + settings["custom-page"] = $("[data-field-name='custom-page']").is(':checked'); settings["paper-size"] = $('select#printing-size').find(':selected').val(); var logo = $("figure.brandlogo img").attr('src'); diff --git a/print/resources/style.css b/print/resources/style.css index f697c7dc..9ffff07d 100644 --- a/print/resources/style.css +++ b/print/resources/style.css @@ -66,30 +66,6 @@ body { position: relative; } -/* Printing Size */ - .page.a4 { - width: 205mm; - height: 292mm; - padding: 15mm; - } - - .page.client-overview.a4 header, .page.operator-overview.a4 header { - height: 50mm; - flex-direction: row; - } - - .page.client-overview.a4 div.job-details, .page.operator-overview.a4 div.job-details { - width: 100%; - } - - .page.client-overview.a4 .client-overview-main figure.inksimulation { - height: 150mm; - } - - .page.client-overview.a4 figure.brandlogo, .page.operator-overview.a4 figure.brandlogo { - margin: -6mm 2.5mm; - } - /* Settings */ .ui { @@ -289,7 +265,7 @@ body { position: relative; } - #footer-info-text { + .info-text { width: 100%; min-height: 5em; border: 1px solid darkgrey; @@ -298,23 +274,25 @@ body { background: white; } - #tool-bar .tb-button { - border: 1px solid darkgrey; + .tb-button { + border: 1px solid darkgrey !important; border-bottom: none; margin-bottom: -0.2em; - cursor: pointer; - color: #413232; height: 2.2em; vertical-align: top; + padding: 5px; + cursor: pointer; + background: white; + color: black; } - #tool-bar .tb-button:disabled { - background: #eaeaea; - color: white; - cursor: auto; + .tb-button:disabled { + background: #eaeaea !important; + color: white !important; + cursor: auto !important; } - #edit-mode { + .edit-mode { display: inline; position: relative; border: 1px solid darkgray; @@ -322,18 +300,18 @@ body { vertical-align: top; } - #edit-mode input { + .edit-mode input { visibility: hidden; } - #edit-mode label { + .edit-mode label { cursor: pointer; vertical-align: middle; background: white; color: #413232; } - #edit-mode label:after { + .edit-mode label:after { opacity: 0.1; content: ''; position: absolute; @@ -348,21 +326,21 @@ body { transform: rotate(-45deg); } - #edit-mode label:hover::after { + .edit-mode label:hover::after { opacity: 0.5; } - #edit-mode input[type=checkbox]:checked + label:after { + .edit-mode input[type=checkbox]:checked + label:after { opacity: 1; } - #edit-mode span { + .edit-mode span { margin-left: 1em; } - div#footer-url, div#footer-email, div#footer-reset { + div.tb-popup { display: none; - position: absolute; + position: absolute !important; background: white; border: 1px solid black; padding: 5mm; @@ -371,7 +349,7 @@ body { z-index: 10; } - div#footer-info-original { + div.original-info { visibility: hidden; width: 0; height: 0; @@ -418,7 +396,6 @@ body { /* Header */ - header { width: 100%; height: 40mm; @@ -434,13 +411,11 @@ body { figure.brandlogo { height: 30mm; width: 30mm; - margin: 2.5mm; + margin: 0 4mm 0 0; } figure.brandlogo label { display: block; - width: 100%; - height: 100%; text-align: center; position: relative; } @@ -472,13 +447,6 @@ body { cursor: pointer; } - .operator-detailedview figure.brandlogo { - height: 20mm; - width: 30mm; - margin: 0 2.5mm; - text-align: left; - } - .operator-detailedview figure.brandlogo img { max-width: 30mm; max-height: 20mm; @@ -488,7 +456,7 @@ body { display: flex; display: -webkit-flex; /* old webkit */ display: -ms-flexbox; /* IE 10 */ - width: calc(100% - 50mm); + width: calc(100% - 40mm); height: 50%; flex-grow: 1; } @@ -515,6 +483,10 @@ body { padding-top: 6mm; } + .operator-overview figure.inksimulation { + height: 210mm; + } + .operator-overview div.job-details, .client-overview div.job-details { padding-top: 2mm; } @@ -904,6 +876,11 @@ body { .opd-color-block.large { display: block; margin: 5mm 0; + font-size: 14pt; + } + + .opd-color-block.large .operator-colorswatch { + font-size: 8pt; } .opd-color-block.large:first-child { @@ -987,6 +964,23 @@ body { display: none; } +/* Custom information sheet */ + .custom-page header { + height: 30mm; + } + + .custom-page main { + height: 230mm + } + #custom-page-tool-bar { + margin-bottom: 0.5em; + } + + #custom-page-content { + height: 200mm; + overflow-y: hidden; + text-align: left; + } /* Color Swatch Logic */ /* reference : http://jsfiddle.net/jrulle/btg63ezy/3/ */ @@ -1120,7 +1114,33 @@ body { height: calc(100% / 5); width: calc(100% / 12); } - + + +/* Print Size A4 */ + + .page.a4 { + width: 210mm; + height: 296mm; + padding: 15mm; + } + + .page.client-overview.a4 header, .page.operator-overview.a4 header { + height: 50mm; + flex-direction: row; + } + + .page.client-overview.a4 div.job-details, .page.operator-overview.a4 div.job-details { + width: 100%; + } + + .page.client-overview.a4 .client-overview-main figure.inksimulation { + height: 150mm; + } + + .page.client-overview.a4 figure.brandlogo, .page.operator-overview.a4 figure.brandlogo { + margin: 0 4mm -2mm 0; + } + @media screen { .page { margin-top: 20mm !important; @@ -1153,8 +1173,11 @@ body { .ui, #settings-ui, #errors, - span.logo-instructions { - display: none; + span.logo-instructions, + #custom-page-tool-bar, + #custom-page-content, + .notice--warning { + display: none !important; } .header-field:not(:empty)::before { diff --git a/print/templates/custom-page.html b/print/templates/custom-page.html new file mode 100644 index 00000000..1ed15dae --- /dev/null +++ b/print/templates/custom-page.html @@ -0,0 +1,40 @@ +
+ {% include 'headline.html' %} +
+
+
+
+ + + + + + + +

+ + +

+
+

{{ _("Enter URL") }}:

+

+
+
+

{{ _("Enter E-Mail") }}:

+

+
+
{{ _("Custom Information Sheet") }}
+
+

{{ _("This will reset your custom text to the default.") }}

+

{{ _("All changes will be lost.") }}

+

+
+
+
{{ _("Custom Information Sheet") }}
+

Note: If you are using Firefox, use visible URLs. Links will not be printed to PDF with this browser.

+
+
+ {% include 'footer.html' %} diff --git a/print/templates/index.html b/print/templates/index.html index c7fa5d74..d0ab848f 100644 --- a/print/templates/index.html +++ b/print/templates/index.html @@ -9,22 +9,23 @@ {% include 'ui.html' %} - {# client overview #} -
{% include 'print_overview.html' %}
+
{% include 'print_overview.html' %}
{# client detailedview #} - {% set printview = 'detailedview' %} - {% for color_block in color_blocks %} - {% set outer_loop = loop %} -
{% include 'print_detail.html' %}
- {% endfor %} + {% set printview = 'detailedview' %} + {% for color_block in color_blocks %} + {% set outer_loop = loop %} +
{% include 'print_detail.html' %}
+ {% endfor %} {# operator overview #} -
{% include 'operator_overview.html' %}
+
{% include 'operator_overview.html' %}
{# operator detailed view #} - {% include 'operator_detailedview.html' %} + {% include 'operator_detailedview.html' %} +{# custom pages #} +
{% include 'custom-page.html' %}
diff --git a/print/templates/operator_overview.html b/print/templates/operator_overview.html index 8f70b4f0..a3090c1f 100644 --- a/print/templates/operator_overview.html +++ b/print/templates/operator_overview.html @@ -25,7 +25,7 @@
-
+
{{ svg_overview|replace("
  • ", "")|replace("
  • ", "")|safe }} {% include 'ui_svg_action_buttons.html' %}
    diff --git a/print/templates/ui.html b/print/templates/ui.html index 71908b52..23e39145 100644 --- a/print/templates/ui.html +++ b/print/templates/ui.html @@ -36,11 +36,30 @@
    {{ _('Print Layouts') }} -

    -

    -

    -

    -

    {{ _('Thumbnail size') }}: 15mm

    +

    + + +

    +

    + + +

    +

    + + +

    +

    + + +

    +

    {{ _('Thumbnail size') }}: + + 15mm +

    +

    + + +

    @@ -58,31 +77,31 @@ -- cgit v1.3.1 From 211561eabc1444135e0a000d8ec4ba822c2ebbd5 Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Tue, 2 Apr 2019 06:27:33 +0200 Subject: simulator stitch box improvement (#402) --- lib/gui/simulator.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/gui/simulator.py b/lib/gui/simulator.py index e0d78983..d64e50c0 100644 --- a/lib/gui/simulator.py +++ b/lib/gui/simulator.py @@ -74,8 +74,12 @@ class ControlPanel(wx.Panel): self.slider = wx.Slider(self, -1, value=1, minValue=1, maxValue=2, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.slider.Bind(wx.EVT_SLIDER, self.on_slider) - self.stitchBox = IntCtrl(self, -1, value=1, min=1, max=2, limited=True, allow_none=False) - self.stitchBox.Bind(wx.EVT_TEXT, self.on_stitch_box) + self.stitchBox = IntCtrl(self, -1, value=1, min=1, max=2, limited=True, allow_none=True, style=wx.TE_PROCESS_ENTER) + self.stitchBox.Bind(wx.EVT_LEFT_DOWN, self.on_stitch_box_focus) + self.stitchBox.Bind(wx.EVT_SET_FOCUS, self.on_stitch_box_focus) + self.stitchBox.Bind(wx.EVT_TEXT_ENTER, self.on_stitch_box_focusout) + self.stitchBox.Bind(wx.EVT_KILL_FOCUS, self.on_stitch_box_focusout) + self.Bind(wx.EVT_LEFT_DOWN, self.on_stitch_box_focusout) # Layout self.vbSizer = vbSizer = wx.BoxSizer(wx.VERTICAL) @@ -120,15 +124,15 @@ class ControlPanel(wx.Panel): (wx.ACCEL_NORMAL, wx.WXK_SPACE, self.on_pause_start_button), (wx.ACCEL_NORMAL, ord('q'), self.animation_quit)] - accel_entries = [] + self.accel_entries = [] for shortcut_key in shortcut_keys: eventId = wx.NewId() - accel_entries.append((shortcut_key[0], shortcut_key[1], eventId)) + self.accel_entries.append((shortcut_key[0], shortcut_key[1], eventId)) self.Bind(wx.EVT_MENU, shortcut_key[2], id=eventId) - accel_table = wx.AcceleratorTable(accel_entries) - self.SetAcceleratorTable(accel_table) + self.accel_table = wx.AcceleratorTable(self.accel_entries) + self.SetAcceleratorTable(self.accel_table) self.SetFocus() def set_drawing_panel(self, drawing_panel): @@ -186,6 +190,8 @@ class ControlPanel(wx.Panel): if self.drawing_panel: self.drawing_panel.set_current_stitch(stitch) + self.parent.SetFocus() + def on_current_stitch(self, stitch, command): if self.current_stitch != stitch: self.current_stitch = stitch @@ -193,8 +199,20 @@ class ControlPanel(wx.Panel): self.stitchBox.SetValue(stitch) self.statusbar.SetStatusText(COMMAND_NAMES[command], 1) - def on_stitch_box(self, event): + def on_stitch_box_focus(self, event): + self.animation_pause() + self.SetAcceleratorTable(wx.AcceleratorTable([])) + event.Skip() + + def on_stitch_box_focusout(self, event): + self.SetAcceleratorTable(self.accel_table) stitch = self.stitchBox.GetValue() + self.parent.SetFocus() + + if stitch is None: + stitch = 1 + self.stitchBox.SetValue(1) + self.slider.SetValue(stitch) if self.drawing_panel: @@ -629,6 +647,7 @@ class EmbroiderySimulator(wx.Frame): if self.on_close_hook: self.on_close_hook() + self.SetFocus() self.Destroy() def go(self): -- cgit v1.3.1 From c94a28756d805aad2ec6bda946e37099ce46310d Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Sun, 7 Apr 2019 21:00:14 +0200 Subject: simulate needle penetration points --- lib/gui/simulator.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'lib') diff --git a/lib/gui/simulator.py b/lib/gui/simulator.py index d64e50c0..3c51c7f2 100644 --- a/lib/gui/simulator.py +++ b/lib/gui/simulator.py @@ -68,6 +68,9 @@ class ControlPanel(wx.Panel): self.restartBtn = wx.Button(self, -1, label=_('Restart')) self.restartBtn.Bind(wx.EVT_BUTTON, self.animation_restart) self.restartBtn.SetToolTip(_('Restart (R)')) + self.nppBtn = wx.ToggleButton(self, -1, label=_('O')) + self.nppBtn.Bind(wx.EVT_TOGGLEBUTTON, self.toggle_npp) + self.nppBtn.SetToolTip(_('Display needle penetration point (O)')) self.quitBtn = wx.Button(self, -1, label=_('Quit')) self.quitBtn.Bind(wx.EVT_BUTTON, self.animation_quit) self.quitBtn.SetToolTip(_('Quit (Q)')) @@ -95,6 +98,7 @@ class ControlPanel(wx.Panel): hbSizer2.Add(self.directionBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.pauseBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.restartBtn, 0, wx.EXPAND | wx.ALL, 2) + hbSizer2.Add(self.nppBtn, 0, wx.EXPAND | wx.ALL, 2) hbSizer2.Add(self.quitBtn, 0, wx.EXPAND | wx.ALL, 2) vbSizer.Add(hbSizer2, 0, wx.EXPAND | wx.ALL, 3) self.SetSizerAndFit(vbSizer) @@ -120,6 +124,7 @@ class ControlPanel(wx.Panel): (wx.ACCEL_NORMAL, wx.WXK_SUBTRACT, self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, wx.WXK_NUMPAD_SUBTRACT, self.animation_one_stitch_backward), (wx.ACCEL_NORMAL, ord('r'), self.animation_restart), + (wx.ACCEL_NORMAL, ord('o'), self.on_toggle_npp_shortcut), (wx.ACCEL_NORMAL, ord('p'), self.on_pause_start_button), (wx.ACCEL_NORMAL, wx.WXK_SPACE, self.on_pause_start_button), (wx.ACCEL_NORMAL, ord('q'), self.animation_quit)] @@ -259,6 +264,15 @@ class ControlPanel(wx.Panel): def animation_restart(self, event): self.drawing_panel.restart() + def on_toggle_npp_shortcut(self, event): + self.nppBtn.SetValue(not self.nppBtn.GetValue()) + self.toggle_npp(event) + + def toggle_npp(self, event): + if self.pauseBtn.GetLabel() == _('Start'): + stitch = self.stitchBox.GetValue() + self.drawing_panel.set_current_stitch(stitch) + class DrawingPanel(wx.Panel): """""" @@ -364,11 +378,13 @@ class DrawingPanel(wx.Panel): stitch += len(stitches) if len(stitches) > 1: canvas.DrawLines(stitches) + self.draw_needle_penetration_points(canvas, pen, stitches) last_stitch = stitches[-1] else: stitches = stitches[:self.current_stitch - stitch] if len(stitches) > 1: canvas.DrawLines(stitches) + self.draw_needle_penetration_points(canvas, pen, stitches) last_stitch = stitches[-1] break self.last_frame_duration = time.time() - start @@ -383,6 +399,12 @@ class DrawingPanel(wx.Panel): canvas.DrawLines(((x - crosshair_radius, y), (x + crosshair_radius, y))) canvas.DrawLines(((x, y - crosshair_radius), (x, y + crosshair_radius))) + def draw_needle_penetration_points(self, canvas, pen, stitches): + if self.control_panel.nppBtn.GetValue(): + npp_pen = wx.Pen(pen.GetColour(), width=int(0.3 * PIXELS_PER_MM * self.PIXEL_DENSITY)) + canvas.SetPen(npp_pen) + canvas.StrokeLineSegments(stitches, stitches) + def clear(self): dc = wx.ClientDC(self) dc.Clear() @@ -719,6 +741,14 @@ class SimulatorPreview(Thread): def update_patches(self): patches = self.parent.generate_patches(self.refresh_needed) + try: + patches = self.parent.generate_patches(self.refresh_needed) + except: # noqa: E722 + # If something goes wrong when rendering patches, it's not great, + # but we don't really want the simulator thread to crash. Instead, + # just swallow the exception and abort. It'll show up when they + # try to actually embroider the shape. + return if patches and not self.refresh_needed.is_set(): stitch_plan = patches_to_stitch_plan(patches) -- cgit v1.3.1