diff options
| author | Valentin Ionita <valentin.ionita1201@gmail.com> | 2019-08-19 18:38:08 +0000 |
|---|---|---|
| committer | Tavmjong Bah <tavmjong@free.fr> | 2019-08-19 18:38:08 +0000 |
| commit | daf25233fe9b7713f0b5c3c6f1b42b3fac8abb1c (patch) | |
| tree | 2143be1f81e30ef55be7a548bebe6734c3533248 /src | |
| parent | reduce usage of desktop coordinates (#341) (diff) | |
| download | inkscape-daf25233fe9b7713f0b5c3c6f1b42b3fac8abb1c.tar.gz inkscape-daf25233fe9b7713f0b5c3c6f1b42b3fac8abb1c.zip | |
Add paint server dialog. Currently handles patterns and hatches. GSOC 2019.
Diffstat (limited to 'src')
| -rw-r--r-- | src/desktop.cpp | 22 | ||||
| -rw-r--r-- | src/helper/stock-items.cpp | 49 | ||||
| -rw-r--r-- | src/io/resource.cpp | 13 | ||||
| -rw-r--r-- | src/io/resource.h | 3 | ||||
| -rw-r--r-- | src/path-prefix.h | 18 | ||||
| -rw-r--r-- | src/ui/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/ui/dialog/dialog-manager.cpp | 5 | ||||
| -rw-r--r-- | src/ui/dialog/inkscape-preferences.cpp | 11 | ||||
| -rw-r--r-- | src/ui/dialog/inkscape-preferences.h | 4 | ||||
| -rw-r--r-- | src/ui/dialog/paint-servers.cpp | 537 | ||||
| -rw-r--r-- | src/ui/dialog/paint-servers.h | 90 | ||||
| -rw-r--r-- | src/verbs.cpp | 7 | ||||
| -rw-r--r-- | src/verbs.h | 1 | ||||
| -rw-r--r-- | src/widgets/paint-selector.cpp | 31 | ||||
| -rw-r--r-- | src/widgets/paint-selector.h | 1 |
15 files changed, 730 insertions, 66 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp index 650878968..fa9f6d6d3 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -949,14 +949,14 @@ Geom::Rect SPDesktop::get_display_area(bool use_integer_viewbox) const void SPDesktop::zoom_absolute_keep_point (Geom::Point const &c, double zoom) { - zoom = CLAMP (zoom, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); + zoom = CLAMP (zoom, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); Geom::Point w = d2w( c ); // Must be before zoom changed. _current_affine.setScale( Geom::Scale(zoom, yaxisdir() * zoom) ); set_display_area( c, w ); } -void +void SPDesktop::zoom_relative_keep_point (Geom::Point const &c, double zoom) { double new_zoom = _current_affine.getZoom() * zoom; @@ -967,7 +967,7 @@ SPDesktop::zoom_relative_keep_point (Geom::Point const &c, double zoom) /** * Zoom aligning the point 'c' to the center of desktop window. */ -void +void SPDesktop::zoom_absolute_center_point (Geom::Point const &c, double zoom) { zoom = CLAMP (zoom, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); @@ -977,7 +977,7 @@ SPDesktop::zoom_absolute_center_point (Geom::Point const &c, double zoom) } -void +void SPDesktop::zoom_relative_center_point (Geom::Point const &c, double zoom) { double new_zoom = _current_affine.getZoom() * zoom; @@ -1064,7 +1064,7 @@ SPDesktop::zoom_selection() */ void SPDesktop::zoom_center_page() { - zoom_absolute_center_point(Geom::Point(doc()->getWidth().value("px")/2, doc()->getHeight().value("px")/2), this->current_zoom()); + zoom_absolute_center_point(Geom::Point(doc()->getWidth().value("px")/2, doc()->getHeight().value("px")/2), this->current_zoom()); } @@ -1144,7 +1144,7 @@ SPDesktop::rotate_absolute_keep_point (Geom::Point const &c, double rotate) } -void +void SPDesktop::rotate_relative_keep_point (Geom::Point const &c, double rotate) { Geom::Point w = d2w( c ); // Must be before rotate changed. @@ -1156,7 +1156,7 @@ SPDesktop::rotate_relative_keep_point (Geom::Point const &c, double rotate) /** * Rotate aligning the point 'c' to the center of desktop window. */ -void +void SPDesktop::rotate_absolute_center_point (Geom::Point const &c, double rotate) { _current_affine.setRotate( rotate ); @@ -1165,7 +1165,7 @@ SPDesktop::rotate_absolute_center_point (Geom::Point const &c, double rotate) } -void +void SPDesktop::rotate_relative_center_point (Geom::Point const &c, double rotate) { _current_affine.addRotate( rotate ); @@ -1198,7 +1198,7 @@ SPDesktop::flip_relative_keep_point (Geom::Point const &c, CanvasFlip flip) /** * Flip aligning the point 'c' to the center of desktop window. */ -void +void SPDesktop::flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip) { _current_affine.setFlip( flip ); @@ -1207,7 +1207,7 @@ SPDesktop::flip_absolute_center_point (Geom::Point const &c, CanvasFlip flip) } -void +void SPDesktop::flip_relative_center_point (Geom::Point const &c, CanvasFlip flip) { _current_affine.addFlip( flip ); @@ -2059,6 +2059,7 @@ SPDesktop::show_dialogs() mapVerbPreference.insert(std::make_pair ("ObjectProperties", "/dialogs/object") ); mapVerbPreference.insert(std::make_pair ("SpellCheck", "/dialogs/spellcheck") ); mapVerbPreference.insert(std::make_pair ("Symbols", "/dialogs/symbols") ); + mapVerbPreference.insert(std::make_pair ("PaintServers", "/dialogs/paint") ); mapVerbPreference.insert(std::make_pair ("ObjectsPanel", "/dialogs/objects") ); mapVerbPreference.insert(std::make_pair ("Prototype", "/dialogs/prototype") ); @@ -2119,4 +2120,3 @@ SPDesktop::show_dialogs() End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : - diff --git a/src/helper/stock-items.cpp b/src/helper/stock-items.cpp index 6ee6d832f..ca96d6b4a 100644 --- a/src/helper/stock-items.cpp +++ b/src/helper/stock-items.cpp @@ -38,7 +38,7 @@ static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *curren // FIXME: these should be merged with the icon loading code so they -// can share a common file/doc cache. This function should just +// can share a common file/doc cache. This function should just // take the dir to look in, and the file to check for, and cache // against that, rather than the existing copy/paste code seen here. @@ -89,21 +89,21 @@ sp_pattern_load_from_svg(gchar const *name, SPDocument *current_doc) } /* Try to load from document */ if (!edoc && !doc) { - gchar *patterns = g_build_filename(INKSCAPE_PATTERNSDIR, "/patterns.svg", NULL); + gchar *patterns = g_build_filename(INKSCAPE_PAINTDIR, "/patterns.svg", NULL); if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) { doc = SPDocument::createNewDoc(patterns, FALSE); } if (!doc) { - gchar *patterns = g_build_filename(CREATE_PATTERNSDIR, "/patterns.svg", NULL); - if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) { - doc = SPDocument::createNewDoc(patterns, FALSE); - } - g_free(patterns); - if (doc) { - doc->ensureUpToDate(); - } else { - edoc = TRUE; - } + gchar *patterns = g_build_filename(CREATE_PAINTDIR, "/patterns.svg", NULL); + if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) { + doc = SPDocument::createNewDoc(patterns, FALSE); + } + g_free(patterns); + if (doc) { + doc->ensureUpToDate(); + } else { + edoc = TRUE; + } } } if (!edoc && doc) { @@ -132,12 +132,12 @@ sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc) } /* Try to load from document */ if (!edoc && !doc) { - gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL); + gchar *gradients = g_build_filename(INKSCAPE_PAINTDIR, "/gradients.svg", NULL); if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) { doc = SPDocument::createNewDoc(gradients, FALSE); } if (!doc) { - gchar *gradients = g_build_filename(CREATE_GRADIENTSDIR, "/gradients.svg", NULL); + gchar *gradients = g_build_filename(CREATE_PAINTDIR, "/gradients.svg", NULL); if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) { doc = SPDocument::createNewDoc(gradients, FALSE); } @@ -171,7 +171,7 @@ sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc) SPObject *get_stock_item(gchar const *urn, gboolean stock) { g_assert(urn != nullptr); - + /* check its an inkscape URN */ if (!strncmp (urn, "urn:inkscape:", 13)) { @@ -183,11 +183,11 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) name_p++; a++; } - + if (*name_p ==':') { name_p++; } - + gchar * base = g_strndup(e, a); SPDocument *doc = SP_ACTIVE_DOCUMENT; @@ -207,7 +207,6 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) object = &child; } } - } else if (!strcmp(base,"pattern") && !stock) { for (auto& child: defs->children) @@ -219,7 +218,6 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) object = &child; } } - } else if (!strcmp(base,"gradient") && !stock) { for (auto& child: defs->children) @@ -231,11 +229,10 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) object = &child; } } - } - + if (object == nullptr) { - + if (!strcmp(base, "marker")) { object = sp_marker_load_from_svg(name_p, doc); } @@ -246,19 +243,19 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) object = sp_gradient_load_from_svg(name_p, doc); } } - + g_free(base); g_free(name); - + if (object) { object->setAttribute("inkscape:isstock", "true"); } return object; } - + else { - + SPDocument *doc = SP_ACTIVE_DOCUMENT; SPObject *object = doc->getObjectById(urn); diff --git a/src/io/resource.cpp b/src/io/resource.cpp index 9f0f0a4ae..a57d188e7 100644 --- a/src/io/resource.cpp +++ b/src/io/resource.cpp @@ -47,13 +47,12 @@ gchar *_get_path(Domain domain, Type type, char const *filename) case EXTENSIONS: temp = INKSCAPE_EXTENSIONDIR; break; case FILTERS: temp = INKSCAPE_FILTERDIR; break; case FONTS: temp = INKSCAPE_FONTSDIR; break; - case GRADIENTS: temp = INKSCAPE_GRADIENTSDIR; break; case ICONS: temp = INKSCAPE_ICONSDIR; break; case KEYS: temp = INKSCAPE_KEYSDIR; break; case MARKERS: temp = INKSCAPE_MARKERSDIR; break; case NONE: g_assert_not_reached(); break; + case PAINT: temp = INKSCAPE_PAINTDIR; break; case PALETTES: temp = INKSCAPE_PALETTESDIR; break; - case PATTERNS: temp = INKSCAPE_PATTERNSDIR; break; case SCREENS: temp = INKSCAPE_SCREENSDIR; break; case SYMBOLS: temp = INKSCAPE_SYMBOLSDIR; break; case TEMPLATES: temp = INKSCAPE_TEMPLATESDIR; break; @@ -68,9 +67,8 @@ gchar *_get_path(Domain domain, Type type, char const *filename) case CREATE: { gchar const* temp = nullptr; switch (type) { - case GRADIENTS: temp = CREATE_GRADIENTSDIR; break; + case PAINT: temp = CREATE_PAINTDIR; break; case PALETTES: temp = CREATE_PALETTESDIR; break; - case PATTERNS: temp = CREATE_PATTERNSDIR; break; default: temp = ""; } path = g_strdup(temp); @@ -84,13 +82,12 @@ gchar *_get_path(Domain domain, Type type, char const *filename) case EXTENSIONS: name = "extensions"; break; case FILTERS: name = "filters"; break; case FONTS: name = "fonts"; break; - case GRADIENTS: name = "gradients"; break; case ICONS: name = "icons"; break; case KEYS: name = "keys"; break; case MARKERS: name = "markers"; break; case NONE: name = ""; break; + case PAINT: name = "paint"; break; case PALETTES: name = "palettes"; break; - case PATTERNS: name = "patterns"; break; case SYMBOLS: name = "symbols"; break; case TEMPLATES: name = "templates"; break; case THEMES: name = "themes"; break; @@ -430,8 +427,8 @@ char *profile_path(const char *filename) int problem = errno; g_warning("Unable to create profile directory (%s) (%d)", g_strerror(problem), problem); } else { - gchar const *userDirs[] = { "keys", "templates", "icons", "extensions", "ui", - "symbols", "themes", "palettes", nullptr }; + gchar const *userDirs[] = { "keys", "templates", "icons", "extensions", "ui", + "symbols", "paint", "themes", "palettes", nullptr }; for (gchar const** name = userDirs; *name; ++name) { gchar *dir = g_build_filename(prefdir, *name, NULL); g_mkdir_with_parents(dir, mode); diff --git a/src/io/resource.h b/src/io/resource.h index e2f15c142..fc1f06681 100644 --- a/src/io/resource.h +++ b/src/io/resource.h @@ -29,13 +29,12 @@ namespace Resource { enum Type { EXTENSIONS, FONTS, - GRADIENTS, ICONS, KEYS, MARKERS, NONE, + PAINT, PALETTES, - PATTERNS, SCREENS, TEMPLATES, TUTORIALS, diff --git a/src/path-prefix.h b/src/path-prefix.h index 93af933d1..42c6d474c 100644 --- a/src/path-prefix.h +++ b/src/path-prefix.h @@ -42,13 +42,12 @@ # define INKSCAPE_EXTENSIONDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/extensions" ) # define INKSCAPE_FILTERDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/filters" ) # define INKSCAPE_FONTSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/fonts" ) -# define INKSCAPE_GRADIENTSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/gradients" ) # define INKSCAPE_KEYSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/keys" ) # define INKSCAPE_ICONSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/icons" ) # define INKSCAPE_PIXMAPSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/pixmaps" ) # define INKSCAPE_MARKERSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/markers" ) +# define INKSCAPE_PAINTDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/paint" ) # define INKSCAPE_PALETTESDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/palettes" ) -# define INKSCAPE_PATTERNSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/patterns" ) # define INKSCAPE_SCREENSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/screens" ) # define INKSCAPE_SYMBOLSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/symbols" ) # define INKSCAPE_THEMEDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/themes" ) @@ -56,9 +55,8 @@ # define INKSCAPE_TEMPLATESDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/templates" ) # define INKSCAPE_UIDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/inkscape/ui" ) //CREATE V0.1 support -# define CREATE_GRADIENTSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/gradients/gimp" ) +# define CREATE_PAINTDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/paint" ) # define CREATE_PALETTESDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/swatches" ) -# define CREATE_PATTERNSDIR BR_DATADIR( INKSCAPE_LIBPREFIX "/share/create/patterns/vector" ) #elif defined ENABLE_OSX_APP_LOCATIONS // TODO: Is ENABLE_OSX_APP_LOCATIONS still in use? # define INKSCAPE_DATADIR_REAL "Contents/Resources/share" # define INKSCAPE_ATTRRELDIR "Contents/Resources/share/inkscape/attributes" @@ -67,13 +65,12 @@ # define INKSCAPE_EXTENSIONDIR "Contents/Resources/share/inkscape/extensions" # define INKSCAPE_FILTERDIR "Contents/Resources/share/inkscape/filters" # define INKSCAPE_FONTSDIR "Contents/Resources/share/inkscape/fonts" -# define INKSCAPE_GRADIENTSDIR "Contents/Resources/share/inkscape/gradients" # define INKSCAPE_KEYSDIR "Contents/Resources/share/inkscape/keys" # define INKSCAPE_ICONSDIR "Contents/Resources/share/inkscape/icons" # define INKSCAPE_PIXMAPSDIR "Contents/Resources/share/inkscape/pixmaps" # define INKSCAPE_MARKERSDIR "Contents/Resources/share/inkscape/markers" +# define INKSCAPE_PAINTDIR "Contents/Resources/share/inkscape/paint" # define INKSCAPE_PALETTESDIR "Contents/Resources/share/inkscape/palettes" -# define INKSCAPE_PATTERNSDIR "Contents/Resources/share/inkscape/patterns" # define INKSCAPE_SCREENSDIR "Contents/Resources/share/inkscape/screens" # define INKSCAPE_SYMBOLSDIR "Contents/Resources/share/inkscape/symbols" # define INKSCAPE_THEMEDIR "Contents/Resources/share/inkscape/themes" @@ -81,9 +78,8 @@ # define INKSCAPE_TEMPLATESDIR "Contents/Resources/share/inkscape/templates" # define INKSCAPE_UIDIR "Contents/Resources/share/inkscape/ui" //CREATE V0.1 support -# define CREATE_GRADIENTSDIR "/Library/Application Support/create/gradients/gimp" +# define CREATE_PAINTDIR "/Library/Application Support/create/paint" # define CREATE_PALETTESDIR "/Library/Application Support/create/swatches" -# define CREATE_PATTERNSDIR "/Library/Application Support/create/patterns/vector" #else # define INKSCAPE_DATADIR_REAL append_inkscape_datadir() # define INKSCAPE_ATTRRELDIR append_inkscape_datadir("inkscape/attributes") @@ -93,13 +89,12 @@ # define INKSCAPE_EXTENSIONDIR append_inkscape_datadir("inkscape/extensions") # define INKSCAPE_FILTERDIR append_inkscape_datadir("inkscape/filters") # define INKSCAPE_FONTSDIR append_inkscape_datadir("inkscape/fonts") -# define INKSCAPE_GRADIENTSDIR append_inkscape_datadir("inkscape/gradients") # define INKSCAPE_KEYSDIR append_inkscape_datadir("inkscape/keys") # define INKSCAPE_ICONSDIR append_inkscape_datadir("inkscape/icons") # define INKSCAPE_PIXMAPSDIR append_inkscape_datadir("inkscape/pixmaps") # define INKSCAPE_MARKERSDIR append_inkscape_datadir("inkscape/markers") +# define INKSCAPE_PAINTDIR append_inkscape_datadir("inkscape/paint") # define INKSCAPE_PALETTESDIR append_inkscape_datadir("inkscape/palettes") -# define INKSCAPE_PATTERNSDIR append_inkscape_datadir("inkscape/patterns") # define INKSCAPE_SCREENSDIR append_inkscape_datadir("inkscape/screens") # define INKSCAPE_SYMBOLSDIR append_inkscape_datadir("inkscape/symbols") # define INKSCAPE_THEMEDIR append_inkscape_datadir("inkscape/themes") @@ -107,9 +102,8 @@ # define INKSCAPE_TEMPLATESDIR append_inkscape_datadir("inkscape/templates") # define INKSCAPE_UIDIR append_inkscape_datadir("inkscape/ui") //CREATE V0.1 support -# define CREATE_GRADIENTSDIR append_inkscape_datadir("create/gradients/gimp") +# define CREATE_PAINTDIR append_inkscape_datadir("create/paint") # define CREATE_PALETTESDIR append_inkscape_datadir("create/swatches") -# define CREATE_PATTERNSDIR append_inkscape_datadir("create/patterns/vector") #endif diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index d84ac8be4..56b0ef983 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -140,6 +140,7 @@ set(ui_SRC dialog/svg-preview.cpp dialog/swatches.cpp dialog/symbols.cpp + dialog/paint-servers.cpp dialog/template-load-tab.cpp dialog/template-widget.cpp dialog/text-edit.cpp @@ -307,6 +308,7 @@ set(ui_SRC dialog/svg-preview.h dialog/swatches.h dialog/symbols.h + dialog/paint-servers.h dialog/template-load-tab.h dialog/template-widget.h dialog/text-edit.h @@ -426,7 +428,7 @@ set(ui_SRC widget/notebook-page.h widget/object-composite-settings.h widget/page-sizer.h - widget/pages-skeleton.h + widget/pages-skeleton.h widget/panel.h widget/point.h widget/preferences-widget.h diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 0bcf7727c..474c89b4c 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -31,6 +31,7 @@ #include "ui/dialog/livepatheffect-editor.h" #include "ui/dialog/memory.h" #include "ui/dialog/messages.h" +#include "ui/dialog/paint-servers.h" #include "ui/dialog/prototype.h" #include "ui/dialog/symbols.h" #include "ui/dialog/tile.h" @@ -129,6 +130,7 @@ DialogManager::DialogManager() { registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>); registerFactory("TileDialog", &create<ArrangeDialog, FloatingBehavior>); registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>); + registerFactory("PaintServers", &create<PaintServersDialog, FloatingBehavior>); registerFactory("StyleDialog", &create<StyleDialog, FloatingBehavior>); #if HAVE_POTRACE @@ -149,7 +151,7 @@ DialogManager::DialogManager() { registerFactory("CloneTiler", &create<CloneTiler, FloatingBehavior>); registerFactory("XmlTree", &create<XmlTree, FloatingBehavior>); registerFactory("Selectors", &create<SelectorsDialog, FloatingBehavior>); - + } else { registerFactory("Prototype", &create<Prototype, DockBehavior>); @@ -175,6 +177,7 @@ DialogManager::DialogManager() { registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>); registerFactory("TileDialog", &create<ArrangeDialog, DockBehavior>); registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>); + registerFactory("PaintServers", &create<PaintServersDialog, DockBehavior>); #if HAVE_POTRACE registerFactory("Trace", &create<TraceDialog, DockBehavior>); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 1584a7662..9f05cece1 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1541,11 +1541,11 @@ void InkscapePreferences::initPageIO() _page_svgexport.add_group_header( _("SVG 2")); _svgexport_insert_text_fallback.init( _("Insert SVG 1.1 fallback in text."), "/options/svgexport/text_insertfallback", true ); _svgexport_insert_mesh_polyfill.init( _("Insert Mesh Gradient JavaScript polyfill."), "/options/svgexport/mesh_insertpolyfill", true ); - _svgexport_insert_mesh_polyfill.init( _("Insert Hatch Paint Server JavaScript polyfill."), "/options/svgexport/hatch_insertpolyfill", true ); + _svgexport_insert_hatch_polyfill.init( _("Insert Hatch Paint Server JavaScript polyfill."), "/options/svgexport/hatch_insertpolyfill", true ); _page_svgexport.add_line( false, "", _svgexport_insert_text_fallback, "", _("Adds fallback options for non-SVG 2 renderers."), false); _page_svgexport.add_line( false, "", _svgexport_insert_mesh_polyfill, "", _("Adds JavaScript polyfill to render meshes."), false); - _page_svgexport.add_line( false, "", _svgexport_insert_mesh_polyfill, "", _("Adds JavaScript polyfill to render hatches (linear and absolute paths)."), false); + _page_svgexport.add_line( false, "", _svgexport_insert_hatch_polyfill, "", _("Adds JavaScript polyfill to render hatches (linear and absolute paths)."), false); // SVG Export Options (SVG 2 -> SVG 1) _page_svgexport.add_group_header( _("SVG 2 to SVG 1.1")); @@ -2601,9 +2601,16 @@ void InkscapePreferences::initPageSystem() _sys_user_symbols_dir.init((char const *)IO::Resource::get_path(IO::Resource::USER, IO::Resource::SYMBOLS, ""), _("Open symbols folder")); + _page_system.add_line(true, _("User symbols: "), _sys_user_symbols_dir, "", _("Location of the user’s symbols"), true); + _sys_user_paint_servers_dir.init((char const *)IO::Resource::get_path(IO::Resource::USER, IO::Resource::PAINT, ""), + _("Open paint servers folder")); + + _page_system.add_line(true, _("User paint servers: "), _sys_user_paint_servers_dir, "", + _("Location of the user’s paint servers"), true); + _sys_user_palettes_dir.init((char const *)IO::Resource::get_path(IO::Resource::USER, IO::Resource::PALETTES, ""), _("Open palettes folder")); _page_system.add_line(true, _("User palettes: "), _sys_user_palettes_dir, "", _("Location of the user’s palettes"), diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 1c9fe1f7b..06ff7a51e 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -340,7 +340,7 @@ protected: UI::Widget::PrefCheckButton _markers_color_stock; UI::Widget::PrefCheckButton _markers_color_custom; UI::Widget::PrefCheckButton _markers_color_update; - + UI::Widget::PrefCheckButton _cleanup_swatches; UI::Widget::PrefSpinButton _importexport_export_res; @@ -380,6 +380,7 @@ protected: UI::Widget::PrefOpenFolder _sys_user_palettes_dir; UI::Widget::PrefOpenFolder _sys_user_templates_dir; UI::Widget::PrefOpenFolder _sys_user_symbols_dir; + UI::Widget::PrefOpenFolder _sys_user_paint_servers_dir; Gtk::Entry _sys_user_cache; Gtk::Entry _sys_data; Gtk::TextView _sys_icon; @@ -485,6 +486,7 @@ protected: // SVG Output export: UI::Widget::PrefCheckButton _svgexport_insert_text_fallback; UI::Widget::PrefCheckButton _svgexport_insert_mesh_polyfill; + UI::Widget::PrefCheckButton _svgexport_insert_hatch_polyfill; UI::Widget::PrefCheckButton _svgexport_remove_marker_auto_start_reverse; UI::Widget::PrefCheckButton _svgexport_remove_marker_context_paint; diff --git a/src/ui/dialog/paint-servers.cpp b/src/ui/dialog/paint-servers.cpp new file mode 100644 index 000000000..1de425a97 --- /dev/null +++ b/src/ui/dialog/paint-servers.cpp @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * @brief Paint Servers dialog + */ +/* Authors: + * Valentin Ionita + * + * Copyright (C) 2019 Valentin Ionita + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include <algorithm> +#include <iostream> +#include <map> +#include <utility> + +#include <giomm/listmodel.h> +#include <glibmm/regex.h> +#include <gtkmm/drawingarea.h> +#include <gtkmm/iconview.h> +#include <gtkmm/liststore.h> +#include <gtkmm/stockid.h> +#include <gtkmm/switch.h> + +#include "document.h" +#include "inkscape.h" +#include "paint-servers.h" +#include "path-prefix.h" +#include "style.h" +#include "verbs.h" + +#include "io/resource.h" +#include "object/sp-defs.h" +#include "object/sp-hatch.h" +#include "object/sp-pattern.h" +#include "object/sp-root.h" +#include "object/sp-shape.h" +#include "ui/cache/svg_preview_cache.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +static Glib::ustring const wrapper = R"=====( +<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"> + <defs id="Defs"/> + <rect id="Back" x="0" y="0" width="100px" height="100px" fill="lightgray"/> + <rect id="Rect" x="0" y="0" width="100px" height="100px" stroke="black"/> +</svg> +)====="; + +class PaintServersColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn<Glib::ustring> id; + Gtk::TreeModelColumn<Glib::ustring> paint; + Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>> pixbuf; + Gtk::TreeModelColumn<Glib::ustring> document; + + PaintServersColumns() { + add(id); + add(paint); + add(pixbuf); + add(document); + } +}; + +PaintServersColumns *PaintServersDialog::getColumns() { return new PaintServersColumns(); } + +// Constructor +PaintServersDialog::PaintServersDialog(gchar const *prefsPath) + : Inkscape::UI::Widget::Panel(prefsPath, SP_VERB_DIALOG_PAINT) + , current_store(ALLDOCS) + , desktop(SP_ACTIVE_DESKTOP) + , target_selected(true) +{ + store[ALLDOCS] = Gtk::ListStore::create(*getColumns()); + store[CURRENTDOC] = Gtk::ListStore::create(*getColumns()); + + // Grid holding the contents + Gtk::Grid *grid = Gtk::manage(new Gtk::Grid()); + grid->set_margin_start(3); + grid->set_margin_end(3); + grid->set_margin_top(3); + grid->set_row_spacing(3); + _getContents()->pack_start(*grid, Gtk::PACK_EXPAND_WIDGET); + + // Grid row 0 + Gtk::Label *file_label = Gtk::manage(new Gtk::Label(_("Server: "))); + grid->attach(*file_label, 0, 0, 1, 1); + + dropdown = Gtk::manage(new Gtk::ComboBoxText()); + dropdown->append(ALLDOCS); + dropdown->append(CURRENTDOC); + document_map[CURRENTDOC] = desktop->getDocument(); + dropdown->set_active_text(ALLDOCS); + dropdown->set_hexpand(); + grid->attach(*dropdown, 1, 0, 1, 1); + + // Grid row 1 + Gtk::Label *fill_label = Gtk::manage(new Gtk::Label(_("Change: "))); + grid->attach(*fill_label, 0, 1, 1, 1); + + target_dropdown = Gtk::manage(new Gtk::ComboBoxText()); + target_dropdown->append(FILL); + target_dropdown->append(STROKE); + target_dropdown->set_active_text(FILL); + target_dropdown->set_hexpand(); + grid->attach(*target_dropdown, 1, 1, 1, 1); + + // Grid row 2 + icon_view = Gtk::manage(new Gtk::IconView( + static_cast<Glib::RefPtr<Gtk::TreeModel>>(store[current_store]) + )); + icon_view->set_tooltip_column(0); + icon_view->set_pixbuf_column(2); + icon_view->set_size_request(200, 300); + icon_view->show_all_children(); + icon_view->set_selection_mode(Gtk::SELECTION_SINGLE); + icon_view->set_activate_on_single_click(true); + + Gtk::ScrolledWindow *scroller = Gtk::manage(new Gtk::ScrolledWindow()); + scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scroller->set_hexpand(); + scroller->set_vexpand(); + scroller->add(*icon_view); + grid->attach(*scroller, 0, 2, 2, 1); + + // Events + target_dropdown->signal_changed().connect( + sigc::mem_fun(*this, &PaintServersDialog::on_target_changed) + ); + + dropdown->signal_changed().connect( + sigc::mem_fun(*this, &PaintServersDialog::on_document_changed) + ); + + icon_view->signal_item_activated().connect( + sigc::mem_fun(*this, &PaintServersDialog::on_item_activated) + ); + + desktop->getDocument()->getDefs()->connectModified( + sigc::mem_fun(*this, &PaintServersDialog::load_current_document) + ); + + // Get wrapper document (rectangle to fill with paint server). + preview_document = SPDocument::createNewDocFromMem(wrapper.c_str(), wrapper.length(), true); + + SPObject *rect = preview_document->getObjectById("Rect"); + SPObject *defs = preview_document->getObjectById("Defs"); + if (!rect || !defs) { + std::cerr << "PaintServersDialog::PaintServersDialog: Failed to get wrapper defs or rectangle!!" << std::endl; + } + + // Set up preview document. + unsigned key = SPItem::display_key_new(1); + preview_document->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + preview_document->ensureUpToDate(); + renderDrawing.setRoot(preview_document->getRoot()->invoke_show(renderDrawing, key, SP_ITEM_SHOW_DISPLAY)); + + // Load paint servers from resource files + load_sources(); +} + +PaintServersDialog::~PaintServersDialog() = default; + +// Get url or color value. +Glib::ustring get_url(Glib::ustring paint) +{ + + Glib::MatchInfo matchInfo; + + // Paint server + static Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create(":(url\\(#([A-z0-9\\-_\\.#])*\\))"); + regex1->match(paint, matchInfo); + + if (matchInfo.matches()) { + return matchInfo.fetch(1); + } + + // Color + static Glib::RefPtr<Glib::Regex> regex2 = Glib::Regex::create(":(([A-z0-9#])*)"); + regex2->match(paint, matchInfo); + + if (matchInfo.matches()) { + return matchInfo.fetch(1); + } + + return Glib::ustring(); +} + +// This is too complicated to use selectors! +void recurse_find_paint(SPObject* in, std::vector<Glib::ustring>& list) +{ + + // Add paint servers in <defs> section. + if (dynamic_cast<SPPaintServer *>(in)) { + if (in->getId()) { + // Need to check as one can't construct Glib::ustring with nullptr. + list.push_back (Glib::ustring("url(#") + in->getId() + ")"); + } + // Don't recurse into paint servers. + return; + } + + // Add paint servers referenced by shapes. + if (dynamic_cast<SPShape *>(in)) { + list.push_back (get_url(in->style->fill.write())); + list.push_back (get_url(in->style->stroke.write())); + } + + for (auto child: in->childList(false)) { + recurse_find_paint(child, list); + } +} + +// Load paint servers from all the files associated +void PaintServersDialog::load_sources() +{ + + // Extract paints from the current file + load_document(desktop->getDocument()); + + // Extract out paints from files in share/paint. + for (auto &path : get_filenames(Inkscape::IO::Resource::PAINT, { ".svg" })) { + SPDocument *document = SPDocument::createNewDoc(path.c_str(), FALSE); + Glib::ustring document_title = Glib::ustring(document->getRoot()->title()); + + load_document(document); + } +} + +Glib::RefPtr<Gdk::Pixbuf> PaintServersDialog::get_pixbuf(SPDocument *document, Glib::ustring paint, Glib::ustring *id) +{ + + SPObject *rect = preview_document->getObjectById("Rect"); + SPObject *defs = preview_document->getObjectById("Defs"); + + Glib::RefPtr<Gdk::Pixbuf> pixbuf(nullptr); + if (paint.empty()) { + return pixbuf; + } + + // Set style on wrapper + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill", paint.c_str()); + rect->changeCSS(css, "style"); + sp_repr_css_attr_unref(css); + + // Insert paint into defs if required + Glib::MatchInfo matchInfo; + static Glib::RefPtr<Glib::Regex> regex = Glib::Regex::create("url\\(#([A-Za-z0-9#._-]*)\\)"); + regex->match(paint, matchInfo); + if (matchInfo.matches()) { + *id = matchInfo.fetch(1); + + // Delete old paint if necessary + std::vector<SPObject *> old_paints = preview_document->getObjectsBySelector("defs > *"); + for (auto paint : old_paints) { + paint->deleteObject(false); + } + + // Add new paint + SPObject *new_paint = document->getObjectById(*id); + if (!new_paint) { + std::cerr << "PaintServersDialog::load_document: cannot find paint server: " << id << std::endl; + return pixbuf; + } + + // Create a copy repr of the paint + Inkscape::XML::Document *xml_doc = preview_document->getReprDoc(); + Inkscape::XML::Node *repr = new_paint->getRepr()->duplicate(xml_doc); + defs->appendChild(repr); + } else { + // Temporary block solid color fills. + return pixbuf; + } + + preview_document->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + preview_document->ensureUpToDate(); + + Geom::OptRect dbox = dynamic_cast<SPItem *>(rect)->visualBounds(); + + if (!dbox) { + return pixbuf; + } + + double size = std::max(dbox->width(), dbox->height()); + + pixbuf = Glib::wrap(render_pixbuf(renderDrawing, 1, *dbox, size)); + + return pixbuf; +} + +// Load paint server from the given document +void PaintServersDialog::load_document(SPDocument *document) +{ + PaintServersColumns *columns = getColumns(); + Glib::ustring document_title; + if (!document->getRoot()->title()) { + document_title = CURRENTDOC; + } else { + document_title = Glib::ustring(document->getRoot()->title()); + } + bool has_server_elements = false; + + // Find all paints + std::vector<Glib::ustring> paints; + recurse_find_paint(document->getRoot(), paints); + + // Sort and remove duplicates. + std::sort(paints.begin(), paints.end()); + paints.erase(std::unique(paints.begin(), paints.end()), paints.end()); + + if (paints.size() && store.find(document_title) == store.end()) { + store[document_title] = Gtk::ListStore::create(*getColumns()); + } + + // iterating though servers + for (auto paint : paints) { + Glib::RefPtr<Gdk::Pixbuf> pixbuf(nullptr); + Glib::ustring id; + pixbuf = get_pixbuf(document, paint, &id); + if (!pixbuf) { + continue; + } + + // Save as a ListStore column + Gtk::ListStore::iterator iter = store[ALLDOCS]->append(); + (*iter)[columns->id] = id; + (*iter)[columns->paint] = paint; + (*iter)[columns->pixbuf] = pixbuf; + (*iter)[columns->document] = document_title; + + iter = store[document_title]->append(); + (*iter)[columns->id] = id; + (*iter)[columns->paint] = paint; + (*iter)[columns->pixbuf] = pixbuf; + (*iter)[columns->document] = document_title; + has_server_elements = true; + } + + if (has_server_elements && document_map.find(document_title) == document_map.end()) { + document_map[document_title] = document; + dropdown->append(document_title); + } +} + +void PaintServersDialog::load_current_document(SPObject * /*object*/, guint /*flags*/) +{ + PaintServersColumns *columns = getColumns(); + SPDocument *document = desktop->getDocument(); + Glib::RefPtr<Gtk::ListStore> current = store[CURRENTDOC]; + + std::vector<Glib::ustring> paints; + std::vector<Glib::ustring> paints_current; + std::vector<Glib::ustring> paints_missing; + recurse_find_paint(document->getDefs(), paints); + + std::sort(paints.begin(), paints.end()); + paints.erase(std::unique(paints.begin(), paints.end()), paints.end()); + + // Delete the server from the store if it doesn't exist in the current document + for (auto iter = current->children().begin(); iter != current->children().end();) { + Gtk::TreeRow server = *iter; + + if (std::find(paints.begin(), paints.end(), server[columns->paint]) == paints.end()) { + iter = current->erase(server); + } else { + paints_current.push_back(server[columns->paint]); + iter++; + } + } + + for (auto s : paints) { + if (std::find(paints_current.begin(), paints_current.end(), s) == paints_current.end()) { + std::cout << "missing " << s << std::endl; + paints_missing.push_back(s); + } + } + std::cout << std::endl; + + if (!paints_missing.size()) { + return; + } + + for (auto paint : paints_missing) { + Glib::RefPtr<Gdk::Pixbuf> pixbuf(nullptr); + Glib::ustring id; + pixbuf = get_pixbuf(document, paint, &id); + if (!pixbuf) { + continue; + } + + Gtk::ListStore::iterator iter = current->append(); + (*iter)[columns->id] = id; + (*iter)[columns->paint] = paint; + (*iter)[columns->pixbuf] = pixbuf; + (*iter)[columns->document] = CURRENTDOC; + } +} + +void PaintServersDialog::on_target_changed() +{ + target_selected = !target_selected; +} + +void PaintServersDialog::on_document_changed() +{ + current_store = dropdown->get_active_text(); + icon_view->set_model(store[current_store]); +} + +void PaintServersDialog::on_item_activated(const Gtk::TreeModel::Path& path) +{ + // Get the current selected elements + Selection *selection = desktop->getSelection(); + std::vector<SPObject*> const selected_items(selection->items().begin(), selection->items().end()); + + if (!selected_items.size()) { + return; + } + + PaintServersColumns *columns = getColumns(); + Gtk::ListStore::iterator iter = store[current_store]->get_iter(path); + Glib::ustring id = (*iter)[columns->id]; + Glib::ustring paint = (*iter)[columns->paint]; + Glib::RefPtr<Gdk::Pixbuf> pixbuf = (*iter)[columns->pixbuf]; + Glib::ustring document_title = (*iter)[columns->document]; + Glib::ustring attribute = target_selected ? "fill:" : "stroke:"; + Glib::ustring new_value(attribute + paint); + SPDocument *document = document_map[document_title]; + SPObject *paint_server = document->getObjectById(id); + SPDocument *document_target = desktop->getDocument(); + + bool paint_server_exists = false; + for (auto server : store[CURRENTDOC]->children()) { + if (server[columns->id] == id) { + paint_server_exists = true; + break; + } + } + + if (!paint_server_exists) { + // Add the paint server to the current document definition + Inkscape::XML::Document *xml_doc = document_target->getReprDoc(); + Inkscape::XML::Node *repr = paint_server->getRepr()->duplicate(xml_doc); + document_target->getDefs()->appendChild(repr); + Inkscape::GC::release(repr); + + // Add the pixbuf to the current document store + iter = store[CURRENTDOC]->append(); + (*iter)[columns->id] = id; + (*iter)[columns->paint] = paint; + (*iter)[columns->pixbuf] = pixbuf; + (*iter)[columns->document] = document_title; + } + + // Recursively find elements in groups, if any + std::vector<SPObject*> items; + for (auto item : selected_items) { + std::vector<SPObject*> current_items = extract_elements(item); + items.insert(std::end(items), std::begin(current_items), std::end(current_items)); + } + + static Glib::RefPtr<Glib::Regex> regex_url = Glib::Regex::create("url\\(#([A-z0-9\\-_\\.#])*\\)"); + + for (auto item : items) { + // FIXME - maybe the item doesn't have that attribute + Glib::ustring style = item->getAttribute("style", nullptr); + int search_start = style.find(attribute, 0); + int search_end = style.find(";", search_start) - search_start; + Glib::ustring previous_value = style.substr(search_start + 5, search_end - 5); + + // Set attribute for each selected item + style.replace(search_start, search_end, new_value); + item->setAttribute("style", style, nullptr); + + // Remove previous paint server, if it exists + if (regex_url->match(previous_value)) { + previous_value = previous_value.substr(4, previous_value.size() - 5); + std::vector<SPObject *> defs = desktop->getDocument()->getDefs()->childList(true); + auto it = find_if(defs.begin(), defs.end(), + [&previous_value](const SPObject *obj) {return previous_value.compare(obj->getId());} + ); + + // Check if it actually exists + if (it != defs.end()) { + // linear and radial gradients reference another target gradient + // remove the target gradient only if it's not referenced by + // other elements + if (dynamic_cast<SPGradient *>(*it)) { + if ((*it)->hrefList.size() && !(*it)->hrefList.front()->isReferenced()) { + (*it)->hrefList.front()->deleteObject(true, true); + } + } + + // if no other elements reference this paint server, remove it + if (!(*it)->isReferenced()) { + (*it)->deleteObject(true, true); + } + } + } + } +} + +std::vector<SPObject*> PaintServersDialog::extract_elements(SPObject* item) +{ + std::vector<SPObject*> elements; + std::vector<SPObject*> children = item->childList(false); + if (!children.size()) { + elements.push_back(item); + } else { + for (auto e : children) { + std::vector<SPObject*> current_items = extract_elements(e); + elements.insert(std::end(elements), std::begin(current_items), std::end(current_items)); + } + } + + return elements; +} + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-basic-offset:2 + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/paint-servers.h b/src/ui/dialog/paint-servers.h new file mode 100644 index 000000000..cfb42f387 --- /dev/null +++ b/src/ui/dialog/paint-servers.h @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * @brief Paint Servers dialog + */ +/* Authors: + * Valentin Ionita + * + * Copyright (C) 2019 Valentin Ionita + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_DIALOG_PAINT_SERVERS_H +#define INKSCAPE_UI_DIALOG_PAINT_SERVERS_H + +#include <glibmm/i18n.h> +#include <gtkmm.h> + +#include "display/drawing.h" +#include "ui/widget/panel.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class PaintServersColumns; // For Gtk::ListStore + +/** + * This dialog serves as a preview for different types of paint servers, + * currently only predefined. It can set the fill or stroke of the selected + * object to the to the paint server you select. + * + * Patterns and hatches are loaded from the preferences paths and displayed + * for each document, for all documents and for the current document. + */ + +class PaintServersDialog : public Inkscape::UI::Widget::Panel { + +public: + PaintServersDialog(gchar const *prefsPath = "/dialogs/paint"); + ~PaintServersDialog() override; + + static PaintServersDialog &getInstance() { return *new PaintServersDialog(); }; + PaintServersDialog(PaintServersDialog const &) = delete; + PaintServersDialog &operator=(PaintServersDialog const &) = delete; + + private: + static PaintServersColumns *getColumns(); + void load_sources(); + void load_document(SPDocument *document); + void load_current_document(SPObject *, guint); + Glib::RefPtr<Gdk::Pixbuf> get_pixbuf(SPDocument *, Glib::ustring, Glib::ustring *); + void on_target_changed(); + void on_document_changed(); + void on_item_activated(const Gtk::TreeModel::Path &path); + std::vector<SPObject *> extract_elements(SPObject *item); + + const Glib::ustring ALLDOCS = _("All paint servers"); + const Glib::ustring CURRENTDOC = _("Current document"); + const Glib::ustring FILL = _("Fill"); + const Glib::ustring STROKE = _("Stroke"); + std::map<Glib::ustring, Glib::RefPtr<Gtk::ListStore>> store; + Glib::ustring current_store; + std::map<Glib::ustring, SPDocument *> document_map; + SPDocument *preview_document; + Inkscape::Drawing renderDrawing; + Gtk::ComboBoxText *dropdown; + Gtk::IconView *icon_view; + SPDesktop *desktop; + Gtk::ComboBoxText *target_dropdown; + bool target_selected; +}; + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +#endif // SEEN INKSCAPE_UI_DIALOG_PAINT_SERVERS_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-basic-offset:2 + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 : diff --git a/src/verbs.cpp b/src/verbs.cpp index 66b85d9a9..f36ef4c90 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -78,6 +78,7 @@ #include "ui/dialog/layers.h" #include "ui/dialog/new-from-template.h" #include "ui/dialog/object-properties.h" +#include "ui/dialog/paint-servers.h" #include "ui/dialog/save-template-dialog.h" #include "ui/dialog/swatches.h" #include "ui/dialog/symbols.h" @@ -2169,6 +2170,9 @@ void DialogVerb::perform(SPAction *action, void *data) case SP_VERB_DIALOG_SYMBOLS: dt->_dlg_mgr->showDialog("Symbols"); break; + case SP_VERB_DIALOG_PAINT: + dt->_dlg_mgr->showDialog("PaintServers"); + break; case SP_VERB_DIALOG_TRANSFORM: dt->_dlg_mgr->showDialog("Transformation"); break; @@ -3096,6 +3100,9 @@ Verb *Verb::_base_verbs[] = { N_("Select colors from a swatches palette"), INKSCAPE_ICON("swatches")), new DialogVerb(SP_VERB_DIALOG_SYMBOLS, "DialogSymbols", N_("S_ymbols..."), N_("Select symbol from a symbols palette"), INKSCAPE_ICON("symbols")), + new DialogVerb(SP_VERB_DIALOG_PAINT, "DialogPaintServers", N_("_Paint Servers..."), + // FIXME missing Inkscape Paint Server Icon + N_("Select paint server from a collection"), INKSCAPE_ICON("symbols")), new DialogVerb(SP_VERB_DIALOG_TRANSFORM, "DialogTransform", N_("Transfor_m..."), N_("Precisely control objects' transformations"), INKSCAPE_ICON("dialog-transform")), new DialogVerb(SP_VERB_DIALOG_ALIGN_DISTRIBUTE, "DialogAlignDistribute", N_("_Align and Distribute..."), diff --git a/src/verbs.h b/src/verbs.h index 91bcbf9d7..bef596379 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -320,6 +320,7 @@ enum { SP_VERB_DIALOG_GLYPHS, SP_VERB_DIALOG_SWATCHES, SP_VERB_DIALOG_SYMBOLS, + SP_VERB_DIALOG_PAINT, SP_VERB_DIALOG_TRANSFORM, SP_VERB_DIALOG_ALIGN_DISTRIBUTE, SP_VERB_DIALOG_SPRAY_OPTION, diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index b640ee22f..e1a6c2b5b 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -35,6 +35,7 @@ #include "io/sys.h" +#include "object/sp-hatch.h" #include "object/sp-linear-gradient.h" #include "object/sp-mesh-gradient.h" #include "object/sp-pattern.h" @@ -83,6 +84,7 @@ static void sp_paint_selector_set_mode_gradient(SPPaintSelector *psel, SPPaintSe static void sp_paint_selector_set_mode_mesh(SPPaintSelector *psel, SPPaintSelector::Mode mode); #endif static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSelector::Mode mode); +static void sp_paint_selector_set_mode_hatch(SPPaintSelector *psel, SPPaintSelector::Mode mode); static void sp_paint_selector_set_mode_swatch(SPPaintSelector *psel, SPPaintSelector::Mode mode); static void sp_paint_selector_set_mode_unset(SPPaintSelector *psel); @@ -404,6 +406,9 @@ void SPPaintSelector::setMode(Mode mode) case MODE_PATTERN: sp_paint_selector_set_mode_pattern(this, mode); break; + case MODE_HATCH: + sp_paint_selector_set_mode_hatch(this, mode); + break; case MODE_SWATCH: sp_paint_selector_set_mode_swatch(this, mode); break; @@ -658,7 +663,7 @@ static void sp_paint_selector_set_mode_color(SPPaintSelector *psel, SPPaintSelec { using Inkscape::UI::Widget::ColorNotebook; - if ((psel->mode == SPPaintSelector::MODE_SWATCH) + if ((psel->mode == SPPaintSelector::MODE_SWATCH) || (psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR) || (psel->mode == SPPaintSelector::MODE_GRADIENT_RADIAL) ) { SPGradientSelector *gsel = getGradientFromData(psel); @@ -1197,7 +1202,7 @@ ink_pattern_menu_populate_menu(GtkWidget *combo, SPDocument *doc) // find and load patterns.svg if (patterns_doc == nullptr) { - char *patterns_source = g_build_filename(INKSCAPE_PATTERNSDIR, "patterns.svg", NULL); + char *patterns_source = g_build_filename(INKSCAPE_PAINTDIR, "patterns.svg", NULL); if (Inkscape::IO::file_test(patterns_source, G_FILE_TEST_IS_REGULAR)) { patterns_doc = SPDocument::createNewDoc(patterns_source, FALSE); } @@ -1378,6 +1383,26 @@ static void sp_paint_selector_set_mode_pattern(SPPaintSelector *psel, SPPaintSel #endif } +static void sp_paint_selector_set_mode_hatch(SPPaintSelector *psel, SPPaintSelector::Mode mode) +{ + if (mode == SPPaintSelector::MODE_HATCH) { + sp_paint_selector_set_style_buttons(psel, psel->unset); + } + + gtk_widget_set_sensitive(psel->style, TRUE); + + if (psel->mode == SPPaintSelector::MODE_HATCH) { + /* Already have hatch menu, for the moment unset */ + } else { + sp_paint_selector_clear_frame(psel); + + gtk_label_set_markup(GTK_LABEL(psel->label), _("<b>Hatch fill</b>")); + } +#ifdef SP_PS_VERBOSE + g_print("Hatch req\n"); +#endif +} + gboolean SPPaintSelector::isSeparator (GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { gboolean sep = FALSE; @@ -1534,6 +1559,8 @@ SPPaintSelector::Mode SPPaintSelector::getModeForStyle(SPStyle const & style, Fi #endif } else if (SP_IS_PATTERN(server)) { mode = MODE_PATTERN; + } else if (SP_IS_HATCH(server)) { + mode = MODE_HATCH; } else { g_warning( "file %s: line %d: Unknown paintserver", __FILE__, __LINE__ ); mode = MODE_NONE; diff --git a/src/widgets/paint-selector.h b/src/widgets/paint-selector.h index 4a6db3121..7d142f327 100644 --- a/src/widgets/paint-selector.h +++ b/src/widgets/paint-selector.h @@ -54,6 +54,7 @@ struct SPPaintSelector { MODE_GRADIENT_MESH, #endif MODE_PATTERN, + MODE_HATCH, MODE_SWATCH, MODE_UNSET } ; |
