I developed some extension for inkscape and it works well. But it lacks of getting dynamic data properties. For example i want to get layer names and set to different props for each layer. As you know we can do it using custom ui for inkex.api extension but it locks the inkscape UI at running. So i decided to develop extension internally. How can i do that? please advise me.
However if you just mean a basic .inx / .py extension. The Inkscape gui should only be locked if you have 'Live Preview' checked.
What kind of layer information do you want to get ? most of it should be available. Layers are just groups with a special attribute. They behave as other objects.
Yes I do mean in the source code. If i use "custum-gui" option with tk ui, i can get dynamic ui like listing layer names on UI. But i locks the Inkscape GUI. If i use the "cutom-gui: no" option it did not lock the UI but i can not create the GUI dynamically. Only static GUI applicable. So there is one option left that is embed code into inkscape codebase. If onother option exist please infor me. Because i want to use written code rather than rewrite everyting in CPP. I will check the chat channel.
For now, as far as I know you cannot do non-blocking extensions in python. We have a way to do extensions that integrate into the loaded code, but only in cpp or equivalent.
Yes, if you use a custom gui, (I use GTK3+) then you do not have access to 'Live Preview' and the Inkscape gui is locked until you exit the custom gui.
So you can either have 'non-dynamic' basic .inx and .py with 'Live Preview'
or you can have 'dynamic-gui' with no 'Live Preview' and no access to the Inkscape gui.
The reason is, the extension system simply runs the python loop then returns. Tk or Gtk3+ are in that loop :) So the gui is destroyed when the loop ends.
You can make a custom preview window using pixbuf, but that creates other problems ( text and some filters render differently )
Plesa lead me the right direction. Is there any example for that or where have to i examine inkscape sources?
@inklinea I tried your extension and see that it is same as my extension and the difference, my extension made by not using gtk but using tk and works perfectly. Great example by the way. I guess the only way is cpp :(
The example uses a toy extension to draw grids, but can do anything, even non-blocking in the gtk main loop, and is being linked to the inkscape.so file.
You'll have to produce a so file and an inx file to place in the extensions.
Hi again. I examine the grid 2 but it seems it uses hardcoded UI like the other extensions. i guess only it runs as a dll not a script. I may not tell myself good enough. I wantto make an extension like layer manager or object manager.
I just found this post and took a look at your extension. I have a few questions:
1. How to properly build the extension??? Any special parameters to link? Any documentation on how to do that on Windows? I have some experience with CPP, but it's been a while...
2. On the inx file I don't see it referencing the binary as we do with the python extensions. Is this something that Inkscape will execute te library automatically based on the .so (or dll) name?
1/ no documentation other than "copy what's done for grid", as it needs to be compiled in the inkscape tree (no stable api) and cmake will take care of the build and link. No specificity for windows that I know of, just compile within a normal inkscape build.
2/ iirc yes if it was not broken
changeset needed to compile grid2 on master (currently broken afaict):
//XML Tree being used directly here while it shouldn't be. - Inkscape::XML::Node * current_layer = static_cast<SPDesktop *>(document)->currentLayer()->getRepr(); + Inkscape::XML::Node * current_layer = desktop->layerManager().currentLayer()->getRepr(); Inkscape::XML::Node * path = xml_doc->createElement("svg:path");
Hi all.
I developed some extension for inkscape and it works well. But it lacks of getting dynamic data properties. For example i want to get layer names and set to different props for each layer. As you know we can do it using custom ui for inkex.api extension but it locks the inkscape UI at running. So i decided to develop extension internally. How can i do that? please advise me.
When you say 'extension internally' do you mean in the Inkscape source code itself ? If so probably best to ask here https://chat.inkscape.org/channel/team_devel
However if you just mean a basic .inx / .py extension. The Inkscape gui should only be locked if you have 'Live Preview' checked.
What kind of layer information do you want to get ? most of it should be available. Layers are just groups with a special attribute. They behave as other objects.
Hi. Thank you for your answer.
Yes I do mean in the source code. If i use "custum-gui" option with tk ui, i can get dynamic ui like listing layer names on UI. But i locks the Inkscape GUI. If i use the "cutom-gui: no" option it did not lock the UI but i can not create the GUI dynamically. Only static GUI applicable. So there is one option left that is embed code into inkscape codebase. If onother option exist please infor me. Because i want to use written code rather than rewrite everyting in CPP. I will check the chat channel.
Thank you again.
For now, as far as I know you cannot do non-blocking extensions in python. We have a way to do extensions that integrate into the loaded code, but only in cpp or equivalent.
Yes, if you use a custom gui, (I use GTK3+) then you do not have access to 'Live Preview' and the Inkscape gui is locked until you exit the custom gui.
So you can either have 'non-dynamic' basic .inx and .py with 'Live Preview'
or you can have 'dynamic-gui' with no 'Live Preview' and no access to the Inkscape gui.
The reason is, the extension system simply runs the python loop then returns. Tk or Gtk3+ are in that loop :) So the gui is destroyed when the loop ends.
You can make a custom preview window using pixbuf, but that creates other problems ( text and some filters render differently )
Here is an example ( the code is horrible but that is just me ). https://inkscape.org/~inklinea/%E2%98%85funshapes
or you can command call to make a .png and preview that - super slow, cannot do realtime changes.
or maybe if you are clever https://wiki.inkscape.org/wiki/DBus - but that is far beyond my abilities.
Thank you for your answers.
@marc
Plesa lead me the right direction. Is there any example for that or where have to i examine inkscape sources?
@inklinea
I tried your extension and see that it is same as my extension and the difference, my extension made by not using gtk but using tk and works perfectly. Great example by the way. I guess the only way is cpp :(
The example is here : https://gitlab.com/inkscape/inkscape/-/tree/master/src/extension/plugins/grid2
The example uses a toy extension to draw grids, but can do anything, even non-blocking in the gtk main loop, and is being linked to the inkscape.so file.
You'll have to produce a so file and an inx file to place in the extensions.
Thank you @marc
Hi again.
I examine the grid 2 but it seems it uses hardcoded UI like the other extensions. i guess only it runs as a dll not a script. I may not tell myself good enough. I wantto make an extension like layer manager or object manager.
You can see external extension that i made and one example of what i want to make.
https://disk.yandex.com.tr/d/nhcz7c9AilK0OA
@MarcJeanmougin
I just found this post and took a look at your extension. I have a few questions:
1. How to properly build the extension??? Any special parameters to link? Any documentation on how to do that on Windows? I have some experience with CPP, but it's been a while...
2. On the inx file I don't see it referencing the binary as we do with the python extensions. Is this something that Inkscape will execute te library automatically based on the .so (or dll) name?
Thanks,
Igor
@krishnarupa
1/ no documentation other than "copy what's done for grid", as it needs to be compiled in the inkscape tree (no stable api) and cmake will take care of the build and link. No specificity for windows that I know of, just compile within a normal inkscape build.
2/ iirc yes if it was not broken
changeset needed to compile grid2 on master (currently broken afaict):
diff --git a/src/extension/plugins/grid2/grid.cpp b/src/extension/plugins/grid2/grid.cpp
index 8f40b34e9f..cb2cf1d501 100644
--- a/src/extension/plugins/grid2/grid.cpp
+++ b/src/extension/plugins/grid2/grid.cpp
@@ -17,6 +17,7 @@
#include <gtkmm/spinbutton.h>
#include "desktop.h"
+#include "layer-manager.h"
#include "document.h"
#include "selection.h"
@@ -96,7 +97,7 @@ Grid::effect (Inkscape::Extension::Effect *module, SPDesktop *desktop, Inkscape:
Geom::Rect bounding_area = Geom::Rect(Geom::Point(0,0), Geom::Point(100,100));
if (selection->isEmpty()) {
/* get page size */
- SPDocument * doc = document->doc();
+ SPDocument * doc = desktop->doc();
bounding_area = *(doc->preferredBounds());
} else {
Geom::OptRect bounds = selection->visualBounds();
@@ -104,14 +105,14 @@ Grid::effect (Inkscape::Extension::Effect *module, SPDesktop *desktop, Inkscape:
bounding_area = *bounds;
}
- gdouble doc_height = (document->doc())->getHeight().value("px");
+ gdouble doc_height = (desktop->doc())->getHeight().value("px");
Geom::Rect temprec = Geom::Rect(Geom::Point(bounding_area.min()[Geom::X], doc_height - bounding_area.min()[Geom::Y]),
Geom::Point(bounding_area.max()[Geom::X], doc_height - bounding_area.max()[Geom::Y]));
bounding_area = temprec;
}
- double scale = document->doc()->getDocumentScale().inverse()[Geom::X];
+ double scale = desktop->doc()->getDocumentScale().inverse()[Geom::X];
bounding_area *= Geom::Scale(scale);
Geom::Point spacings( scale * module->get_param_float("xspacing"),
@@ -123,10 +124,10 @@ Grid::effect (Inkscape::Extension::Effect *module, SPDesktop *desktop, Inkscape:
Glib::ustring path_data("");
path_data = build_lines(bounding_area, offsets, spacings);
- Inkscape::XML::Document * xml_doc = document->doc()->getReprDoc();
+ Inkscape::XML::Document * xml_doc = desktop->doc()->getReprDoc();
//XML Tree being used directly here while it shouldn't be.
- Inkscape::XML::Node * current_layer = static_cast<SPDesktop *>(document)->currentLayer()->getRepr();
+ Inkscape::XML::Node * current_layer = desktop->layerManager().currentLayer()->getRepr();
Inkscape::XML::Node * path = xml_doc->createElement("svg:path");
path->setAttribute("d", path_data);