Show page in simulator (#3120)

* add exception logging helpers

* wip

* show page and drop shadow from SVG

* allow toggling page

* add page icon

* add dark mode icon

* showpageshadow

* refresh after background change (fix for macOS)

* fix params sim background

* try a native GraphicsBrush for windows

* show page button in standalone simulator only and adapt shadow color

* remove doubled line

---------

Co-authored-by: Kaalleen <reni@allenka.de>
pull/3086/head
Lex Neva 2024-08-08 09:43:36 -04:00 zatwierdzone przez GitHub
rodzic 17b88ce2c1
commit 47ad76f513
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
9 zmienionych plików z 217 dodań i 2 usunięć

BIN
icons/page.png 100644

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 3.1 KiB

97
icons/page.svg 100644
Wyświetl plik

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
id="svg8375"
version="1.1"
inkscape:version="1.3 (1:1.3+202307231459+0e150ed6c4)"
sodipodi:docname="page.svg"
inkscape:export-filename="page.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs8377">
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Blur"
id="filter2"
x="-0.10779408"
y="-0.10779408"
width="1.2155882"
height="1.2155882">
<feGaussianBlur
stdDeviation="4 4"
result="fbSourceGraphic"
id="feGaussianBlur2" />
<feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix2" />
<feGaussianBlur
id="feGaussianBlur3"
stdDeviation="6 6"
result="blur"
in="fbSourceGraphic" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="94.449262"
inkscape:cy="142.68405"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="mm"
inkscape:window-width="1366"
inkscape:window-height="705"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1" />
<metadata
id="metadata8380">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect1-3"
style="stroke-width:0.755906;stroke-linejoin:round;filter:url(#filter2)"
d="M 31.662572,29.484143 H 254.30931 V 252.13088 H 31.662572 Z"
sodipodi:nodetypes="ccccc"
transform="matrix(0.91809316,0,0,0.91809316,8.0575784,8.0575784)" />
<path
id="rect1"
style="fill:#ffffff;stroke:#000000;stroke-width:5;stroke-linejoin:round;stroke-dasharray:none"
d="M 20,18 H 217.95764 V 215.95764 H 20 Z"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 2.9 KiB

BIN
icons/page_dark.png 100644

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 3.1 KiB

Wyświetl plik

@ -5,6 +5,7 @@
import atexit # to save svg file on exit
import time # to measure time of code block, use time.monotonic() instead of time.time()
import traceback
from datetime import datetime
from contextlib import contextmanager # to measure time of with block
@ -246,6 +247,18 @@ class Debug(object):
if self.enabled:
self.raw_log("completed %s, duration = %s", label, time.monotonic() - start)
def log_exception(self):
if self.enabled:
self.raw_log(traceback.format_exc())
@contextmanager
def log_exceptions(self):
try:
yield
except Exception:
self.log_exception()
raise
# global debug object
debug = Debug()

Wyświetl plik

@ -7,6 +7,7 @@ import wx
from ..gui.simulator import SimulatorWindow
from ..stitch_plan import stitch_groups_to_stitch_plan
from ..svg import convert_length
from ..utils.svg_data import get_pagecolor
from .base import InkstitchExtension
@ -37,5 +38,33 @@ class Simulator(InkstitchExtension):
app.SetTopWindow(simulator)
simulator.Show()
simulator.load(stitch_plan)
simulator.set_page_specs(self.get_page_specs(stitch_plan))
simulator.go()
app.MainLoop()
def get_page_specs(self, stitch_plan):
svg = self.document.getroot()
width = svg.get('width', 0)
height = svg.get('height', 0)
page_color = "white"
desk_color = "white"
border_color = "black"
show_page_shadow = "true"
named_view = svg.namedview
if named_view is not None:
page_color = named_view.get('pagecolor', page_color)
desk_color = named_view.get('inkscape:deskcolor', desk_color)
border_color = named_view.get('bordercolor', border_color)
show_page_shadow = named_view.get('inkscape:showpageshadow', show_page_shadow) in ['true', 'yes', 'y', '1', '2']
return {
"width": convert_length(width),
"height": convert_length(height),
"x": stitch_plan.bounding_box[0],
"y": stitch_plan.bounding_box[1],
"page_color": page_color,
"desk_color": desk_color,
"border_color": border_color,
"show_page_shadow": show_page_shadow
}

Wyświetl plik

@ -7,6 +7,7 @@ import time
import wx
from numpy import split
from ...debug.debug import debug
from ...i18n import _
from ...svg import PIXELS_PER_MM
from ...utils.settings import global_settings
@ -59,6 +60,9 @@ class DrawingPanel(wx.Panel):
self.width = 0
self.height = 0
self.loaded = False
self.page_specs = {}
self.show_page = True
self.background_color = None
# desired simulation speed in stitches per second
self.speed = 16
@ -122,6 +126,34 @@ class DrawingPanel(wx.Panel):
self.draw_stitches(canvas)
self.draw_scale(canvas)
def draw_page(self, canvas):
self._update_background_color()
if not self.page_specs or not self.show_page:
return
with debug.log_exceptions():
border_color = wx.Colour(self.page_specs['border_color'])
if self.page_specs['show_page_shadow']:
canvas.SetPen(wx.TRANSPARENT_PEN)
canvas.SetBrush(canvas.CreateBrush(wx.Brush(wx.Colour(border_color.Red(), border_color.Green(), border_color.Blue(), alpha=65))))
canvas.DrawRoundedRectangle(
(-self.page_specs['x'] + 4) * self.PIXEL_DENSITY, (-self.page_specs['y'] + 4) * self.PIXEL_DENSITY,
self.page_specs['width'] * self.PIXEL_DENSITY, self.page_specs['height'] * self.PIXEL_DENSITY,
1 * self.PIXEL_DENSITY
)
pen = canvas.CreatePen(
wx.GraphicsPenInfo(wx.Colour(border_color)).Width(1 * self.PIXEL_DENSITY).Join(wx.JOIN_MITER)
)
canvas.SetPen(pen)
canvas.SetBrush(wx.Brush(wx.Colour(self.background_color or self.page_specs['page_color'])))
canvas.DrawRectangle(
-self.page_specs['x'] * self.PIXEL_DENSITY, -self.page_specs['y'] * self.PIXEL_DENSITY,
self.page_specs['width'] * self.PIXEL_DENSITY, self.page_specs['height'] * self.PIXEL_DENSITY
)
def draw_stitches(self, canvas):
canvas.BeginLayer(1)
@ -130,6 +162,8 @@ class DrawingPanel(wx.Panel):
transform.Scale(self.zoom / self.PIXEL_DENSITY, self.zoom / self.PIXEL_DENSITY)
canvas.SetTransform(transform)
self.draw_page(canvas)
stitch = 0
last_stitch = None
@ -252,6 +286,28 @@ class DrawingPanel(wx.Panel):
if hasattr(self.view_panel, 'info_panel'):
self.view_panel.info_panel.update()
def set_page_specs(self, page_specs):
self.SetBackgroundColour(page_specs['desk_color'])
self.page_specs = page_specs
def set_background_color(self, color):
self.background_color = color
# this refresh is necessary for macOS
self.Refresh()
def _update_background_color(self):
if not self.page_specs:
self.SetBackgroundColour(self.background_color or "#FFFFFF")
else:
if self.show_page:
self.SetBackgroundColour(self.page_specs['desk_color'])
else:
self.SetBackgroundColour(self.background_color or self.page_specs['page_color'])
def set_show_page(self, show_page):
self.show_page = show_page
self._update_background_color()
def choose_zoom_and_pan(self, event=None):
# ignore if EVT_SIZE fired before we load the stitch plan
if not self.width and not self.height and event is not None:

Wyświetl plik

@ -30,6 +30,7 @@ class SimulatorPanel(wx.Panel):
self.cp.set_drawing_panel(self.dp)
self.vp.set_drawing_panel(self.dp)
self.vp.set_background_color(wx.Colour(background_color))
self.dp.set_background_color(wx.Colour(background_color))
dvSizer = wx.BoxSizer(wx.HORIZONTAL)
@ -93,3 +94,6 @@ class SimulatorPanel(wx.Panel):
def clear(self):
self.dp.clear()
self.cp.clear()
def set_page_specs(self, page_specs):
self.dp.set_page_specs(page_specs)

Wyświetl plik

@ -53,3 +53,6 @@ class SimulatorWindow(wx.Frame):
def go(self):
self.panel.go()
def set_page_specs(self, page_specs):
self.panel.set_page_specs(page_specs)

Wyświetl plik

@ -56,6 +56,13 @@ class ViewPanel(ScrolledPanel):
self.btnBackgroundColor.SetToolTip(_("Change background color"))
self.btnBackgroundColor.Bind(wx.EVT_COLOURPICKER_CHANGED, self.on_update_background_color)
if not self.detach_callback:
self.btnPage = wx.BitmapToggleButton(self, -1, style=self.button_style)
self.btnPage.Bind(wx.EVT_TOGGLEBUTTON, self.toggle_page)
self.btnPage.SetValue(True)
self.btnPage.SetBitmap(self.control_panel.load_icon('page'))
self.btnPage.SetToolTip(_('Show page'))
self.btnSettings = wx.BitmapToggleButton(self, -1, style=self.button_style)
self.btnSettings.SetToolTip(_('Open settings dialog'))
self.btnSettings.SetBitmap(self.control_panel.load_icon('settings'))
@ -94,6 +101,8 @@ class ViewPanel(ScrolledPanel):
settings_sizer = wx.StaticBoxSizer(wx.StaticBox(self, wx.ID_ANY, _("Settings")), wx.VERTICAL)
settings_inner_sizer = wx.BoxSizer(wx.VERTICAL)
settings_inner_sizer.Add(self.btnBackgroundColor, 0, wx.EXPAND | wx.ALL, 2)
if not self.detach_callback:
settings_inner_sizer.Add(self.btnPage, 0, wx.EXPAND | wx.ALL, 2)
settings_inner_sizer.Add(self.btnSettings, 0, wx.EXPAND | wx.ALL, 2)
if self.detach_callback:
settings_inner_sizer.Add(self.btnDetachSimulator, 0, wx.ALL, 2)
@ -109,11 +118,10 @@ class ViewPanel(ScrolledPanel):
def on_update_background_color(self, event):
self.set_background_color(event.Colour)
self.drawing_panel.set_background_color(event.Colour)
def set_background_color(self, color):
self.btnBackgroundColor.SetColour(color)
self.drawing_panel.SetBackgroundColour(color)
self.drawing_panel.Refresh()
def on_toggle_npp_shortcut(self, event):
self.btnNpp.SetValue(not self.btnNpp.GetValue())
@ -122,6 +130,11 @@ class ViewPanel(ScrolledPanel):
def toggle_npp(self, event):
self.drawing_panel.Refresh()
def toggle_page(self, event):
debug.log("toggle page")
self.drawing_panel.set_show_page(self.btnPage.GetValue())
self.drawing_panel.Refresh()
def on_marker_button(self, marker_type, event):
self.control_panel.slider.enable_marker_list(marker_type, event.GetEventObject().GetValue())
if marker_type == 'jump':