summaryrefslogtreecommitdiffstats
path: root/share/extensions/docs/tutorial/creating-objects.rst
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:50:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:50:49 +0000
commitc853ffb5b2f75f5a889ed2e3ef89b818a736e87a (patch)
tree7d13a0883bb7936b84d6ecdd7bc332b41ed04bee /share/extensions/docs/tutorial/creating-objects.rst
parentInitial commit. (diff)
downloadinkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.tar.xz
inkscape-c853ffb5b2f75f5a889ed2e3ef89b818a736e87a.zip
Adding upstream version 1.3+ds.upstream/1.3+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/docs/tutorial/creating-objects.rst')
-rw-r--r--share/extensions/docs/tutorial/creating-objects.rst101
1 files changed, 101 insertions, 0 deletions
diff --git a/share/extensions/docs/tutorial/creating-objects.rst b/share/extensions/docs/tutorial/creating-objects.rst
new file mode 100644
index 0000000..e5d742a
--- /dev/null
+++ b/share/extensions/docs/tutorial/creating-objects.rst
@@ -0,0 +1,101 @@
+Creating objects
+================
+
+Introduction
+------------
+
+In this tutorial, we will number the nodes of a path - effectively recreate a simpler
+version of the the "Number Nodes" extension. We will create objects (in this case,
+circles) and text on the canvas, at a programmatically determined location.
+
+INX File
+--------
+
+We will use two parameters, the font size and whether the circle should be filled or not.
+The inx file looks as follows:
+
+.. code:: xml
+
+ <?xml version="1.0" encoding="UTF-8"?>
+ <inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
+ <name>My Number Nodes</name>
+ <id>org.inkscape.tutorial.my_number_nodes</id>
+ <param name="fontsize" type="string" gui-text="Font size:">20px</param>
+ <param name="filled" type="bool" gui-text="Fill dot">True</param>
+ <effect>
+ <effects-menu>
+ <submenu name="Visualize Path"/>
+ </effects-menu>
+ </effect>
+ <script>
+ <command location="inx" interpreter="python">my_number_nodes.py</command>
+ </script>
+ </inkscape-extension>
+
+Boilerplate code
+----------------
+
+Create a python file with the following contents:
+
+
+.. code:: python
+
+ import inkex
+
+ class MyNumberNodes(inkex.EffectExtension):
+
+ def add_arguments(self, pars):
+ pars.add_argument("--filled", default=True, type=inkex.Boolean)
+ pars.add_argument("--fontsize", default="20px", help="Size of node labels")
+
+ def effect(self):
+ filtered = self.svg.selection.filter_nonzero(inkex.PathElement)
+
+ for element in filtered:
+ self.process(element)
+
+ def process(self, element: inkex.PathElement):
+ """Draw the node markers and number for each node"""
+
+Processing a path
+-----------------
+
+There are three steps we have to perform:
+
+ - Figure out the locations of the path's nodes.
+ - Draw a circle at each node's location.
+ - Draw a text next to the circle.
+
+For the first step, we'll use the :attr:`~inkex.Path.end_points` attribute of the
+:class:`inkex.PathElement`'s :attr:`inkex.PathElement.path`. This attribute contains
+the end point of all path commands, which are the nodes of the path. (Note that this
+means that the start point of a closed subpath will be marked twice).
+However, before doing this, we have to apply the path's transform - otherwise, we would
+get the node coordinates of the untransformed path. Our function therefore starts with:
+
+.. code:: python
+
+ def process(self, element: inkex.PathElement):
+ """Draw the node markers and number for each node"""
+
+ # element.transform contains an object-oriented representation of the
+ # "transform" SVG attribute
+ transformed_path = element.path.transform(element.transform)
+ nodes = transformed_path.end_points
+
+Second, we'll create a group and append it after the path. In this group, all newly
+created objects will go. We can also use the ``enumerate`` function to loop over the
+nodes - this gives us both the index and the coordinates as looping variables.
+
+.. code:: python
+
+ ...
+ g = inkex.Group()
+ element.addnext(g)
+
+ for index, node in enumerate(transformed_path.end_points):
+
+ ...
+
+Third, onto creating the circles:
+